Пример #1
0
 /**
  * Check that the user has sufficient permissions, or die in error
  *
  */
 private function _checkPermissions()
 {
     // Is frontend backup enabled?
     $febEnabled = Platform::getInstance()->get_platform_configuration_option('failure_frontend_enable', 0) != 0;
     // Is the Secret Key strong enough?
     $validKey = Platform::getInstance()->get_platform_configuration_option('frontend_secret_word', '');
     if (!\Akeeba\Engine\Util\Complexify::isStrongEnough($validKey, false)) {
         $febEnabled = false;
     }
     if (!$febEnabled) {
         @ob_end_clean();
         echo '403 ' . JText::_('ERROR_NOT_ENABLED');
         flush();
         JFactory::getApplication()->close();
     }
     // Is the key good?
     $key = $this->input->get('key', '', 'none', 2);
     $validKeyTrim = trim($validKey);
     if ($key != $validKey || empty($validKeyTrim)) {
         @ob_end_clean();
         echo '403 ' . JText::_('ERROR_INVALID_KEY');
         flush();
         JFactory::getApplication()->close();
     }
 }
Пример #2
0
 /**
  * Parses the JSON data sent by the client and executes the appropriate JSON API task
  *
  * @param   string  $json  The raw JSON data received from the remote client
  *
  * @return  string  The JSON-encoded, fully encapsulated response
  */
 public function execute($json)
 {
     // Check if we're activated
     $enabled = Platform::getInstance()->get_platform_configuration_option('frontend_enable', 0);
     // Is the Secret Key strong enough?
     $validKey = $this->serverKey();
     if (!Complexify::isStrongEnough($validKey, false)) {
         $enabled = false;
     }
     $rawEncapsulation = $this->encapsulation->getEncapsulationByCode('ENCAPSULATION_RAW');
     if (!$enabled) {
         return $this->getResponse('Access denied', 503);
     }
     // Try to JSON-decode the request's input first
     $request = @json_decode($json, true);
     if (is_null($request)) {
         return $this->getResponse('JSON decoding error', 500);
     }
     // Transform legacy requests
     if (!is_array($request)) {
         $request = array('encapsulation' => $rawEncapsulation, 'body' => $request);
     }
     // Transform partial requests
     if (!isset($request['encapsulation'])) {
         $request['encapsulation'] = $rawEncapsulation;
     }
     // Make sure we have a request body
     if (!isset($request['body'])) {
         $request['body'] = '';
     }
     try {
         $request['body'] = $this->encapsulation->decode($request['encapsulation'], $request['body']);
     } catch (\Exception $e) {
         return $this->getResponse($e->getMessage(), $e->getCode());
     }
     // Replicate the encapsulation preferences of the client for our own output
     $this->encapsulationType = $request['encapsulation'];
     // Store the client-specified key, or use the server key if none specified and the request
     // came encrypted.
     $this->password = isset($request['body']['key']) ? $request['body']['key'] : $this->serverKey();
     // Run the method
     $params = array();
     if (isset($request['body']['data'])) {
         $params = (array) $request['body']['data'];
     }
     try {
         $taskHandler = new Task($this->container);
         $data = $taskHandler->execute($request['body']['method'], $params);
     } catch (\RuntimeException $e) {
         return $this->getResponse($e->getMessage(), $e->getCode());
     }
     return $this->getResponse($data);
 }
Пример #3
0
 /**
  * Check that the user has sufficient permissions to access the front-end backup feature.
  *
  * @return  void
  */
 protected function checkPermissions()
 {
     // Is frontend backup enabled?
     $febEnabled = Platform::getInstance()->get_platform_configuration_option('frontend_enable', 0) != 0;
     // Is the Secret Key strong enough?
     $validKey = Platform::getInstance()->get_platform_configuration_option('frontend_secret_word', '');
     $validKeyTrim = trim($validKey);
     if (!Complexify::isStrongEnough($validKey, false)) {
         $febEnabled = false;
     }
     // Is the key good?
     $key = $this->input->get('key', '', 'none', 2);
     if (!$febEnabled || $key != $validKey || empty($validKeyTrim)) {
         @ob_end_clean();
         echo '403 ' . JText::_('COM_AKEEBA_COMMON_ERR_NOT_ENABLED');
         flush();
         $this->container->platform->closeApplication();
     }
 }
Пример #4
0
 public function execute($json)
 {
     // Check if we're activated
     $enabled = Platform::getInstance()->get_platform_configuration_option('frontend_enable', 0);
     // Is the Secret Key strong enough?
     $validKey = $this->serverKey();
     if (!\Akeeba\Engine\Util\Complexify::isStrongEnough($validKey, false)) {
         $enabled = false;
     }
     if (!$enabled) {
         $this->data = 'Access denied';
         $this->status = self::STATUS_NOT_AVAILABLE;
         $this->encapsulation = self::ENCAPSULATION_RAW;
         return $this->getResponse();
     }
     // Try to JSON-decode the request's input first
     $request = @json_decode($json, false);
     if (is_null($request)) {
         // Could not decode JSON
         $this->data = 'JSON decoding error';
         $this->status = self::STATUS_ERROR;
         $this->encapsulation = self::ENCAPSULATION_RAW;
         return $this->getResponse();
     }
     // Decode the request body
     // Request format: {encapsulation, body{ [key], [challenge], method, [data] }} or {[challenge], method, [data]}
     if (isset($request->encapsulation) && isset($request->body)) {
         if (!class_exists('\\Akeeba\\Engine\\Util\\Encrypt') && !($request->encapsulation == self::ENCAPSULATION_RAW)) {
             // Encrypted request found, but there is no encryption class available!
             $this->data = 'This server does not support encrypted requests';
             $this->status = self::STATUS_NOT_AVAILABLE;
             $this->encapsulation = self::ENCAPSULATION_RAW;
             return $this->getResponse();
         }
         // Fully specified request
         $body = '';
         switch ($request->encapsulation) {
             case self::ENCAPSULATION_AESCBC128:
                 if (!isset($body)) {
                     $request->body = base64_decode($request->body);
                     $body = Factory::getEncryption()->AESDecryptCBC($request->body, $this->serverKey(), 128);
                 }
                 break;
             case self::ENCAPSULATION_AESCBC256:
                 if (!isset($body)) {
                     $request->body = base64_decode($request->body);
                     $body = Factory::getEncryption()->AESDecryptCBC($request->body, $this->serverKey(), 256);
                 }
                 break;
             case self::ENCAPSULATION_AESCTR128:
                 if (!isset($body)) {
                     $body = Factory::getEncryption()->AESDecryptCtr($request->body, $this->serverKey(), 128);
                 }
                 break;
             case self::ENCAPSULATION_AESCTR256:
                 if (!isset($body)) {
                     $body = Factory::getEncryption()->AESDecryptCtr($request->body, $this->serverKey(), 256);
                 }
                 break;
             case self::ENCAPSULATION_RAW:
                 $body = $request->body;
                 break;
         }
         if (!empty($request->body)) {
             $authorised = true;
             $body = rtrim($body, chr(0));
             // Make sure it looks like a valid JSON string and is at least 12 characters (minimum valid message length)
             if (strlen($body) < 12 || substr($body, 0, 1) != '{' || substr($body, -1) != '}') {
                 $authorised = false;
             }
             // Try to JSON decode the body
             if ($authorised) {
                 $request->body = json_decode($body);
                 if (is_null($request->body)) {
                     $authorised = false;
                 } elseif (!is_object($request->body)) {
                     $authorised = false;
                 }
             }
             // Make sure there is a requested method
             if ($authorised) {
                 if (!isset($request->body->method) || empty($request->body->method)) {
                     $authorised = false;
                 }
             }
             if (!$authorised) {
                 // Decryption failed. The user is an impostor! Go away, hacker!
                 $this->data = 'Authentication failed';
                 $this->status = self::STATUS_NOT_AUTH;
                 $this->encapsulation = self::ENCAPSULATION_RAW;
                 return $this->getResponse();
             }
         }
     } elseif (isset($request->body)) {
         // Partially specified request, assume RAW encapsulation
         $request->encapsulation = self::ENCAPSULATION_RAW;
         $request->body = json_decode($request->body);
     } else {
         // Legacy request
         $legacyRequest = clone $request;
         $request = (object) array('encapsulation' => self::ENCAPSULATION_RAW, 'body' => null);
         $request->body = json_decode($legacyRequest);
         unset($legacyRequest);
     }
     // Authenticate the user. Do note that if an encrypted request was made, we can safely assume that
     // the user is authenticated (he already knows the server key!)
     if ($request->encapsulation == self::ENCAPSULATION_RAW) {
         $authenticated = false;
         if (isset($request->body->challenge)) {
             list($challenge, $check) = explode(':', $request->body->challenge);
             $crosscheck = strtolower(md5($challenge . $this->serverKey()));
             $authenticated = $crosscheck == $check;
         }
         if (!$authenticated) {
             // If the challenge was missing or it was wrong, don't let him go any further
             $this->data = 'Invalid login credentials';
             $this->status = self::STATUS_NOT_AUTH;
             $this->encapsulation = self::ENCAPSULATION_RAW;
             return $this->getResponse();
         }
     }
     // Replicate the encapsulation preferences of the client for our own output
     $this->encapsulation = $request->encapsulation;
     // Store the client-specified key, or use the server key if none specified and the request
     // came encrypted.
     $this->password = isset($request->body->key) ? $request->body->key : null;
     $hasKey = isset($request->body->key) || property_exists($request->body, 'key') ? !is_null($request->body->key) : false;
     if (!$hasKey && $request->encapsulation != self::ENCAPSULATION_RAW) {
         $this->password = $this->serverKey();
     }
     // Does the specified method exist?
     $method_exists = false;
     $method_name = '';
     if (isset($request->body->method)) {
         $method_name = ucfirst($request->body->method);
         $this->method_name = $method_name;
         $method_exists = method_exists($this, '_api' . $method_name);
     }
     if (!$method_exists) {
         // The requested method doesn't exist. Oops!
         $this->data = "Invalid method {$method_name}";
         $this->status = self::STATUS_INVALID_METHOD;
         $this->encapsulation = self::ENCAPSULATION_RAW;
         return $this->getResponse();
     }
     // Run the method
     $params = array();
     if (isset($request->body->data)) {
         $params = (array) $request->body->data;
     }
     $this->data = call_user_func(array($this, '_api' . $method_name), $params);
     return $this->getResponse();
 }
Пример #5
0
 /**
  * Check the strength of the Secret Word for front-end and remote backups. If it is insecure return the reason it
  * is insecure as a string. If the Secret Word is secure return an empty string.
  *
  * @return  string
  */
 public function getFrontendSecretWordError()
 {
     // Is frontend backup enabled?
     $febEnabled = Platform::getInstance()->get_platform_configuration_option('frontend_enable', 0) != 0;
     if (!$febEnabled) {
         return '';
     }
     $secretWord = Platform::getInstance()->get_platform_configuration_option('frontend_secret_word', '');
     try {
         \Akeeba\Engine\Util\Complexify::isStrongEnough($secretWord);
     } catch (RuntimeException $e) {
         // Ah, the current Secret Word is bad. Create a new one if necessary.
         $session = JFactory::getSession();
         $newSecret = $session->get('newSecretWord', null, 'akeeba.cpanel');
         if (empty($newSecret)) {
             $random = new \Akeeba\Engine\Util\RandomValue();
             $newSecret = $random->generateString(32);
             $session->set('newSecretWord', $newSecret, 'akeeba.cpanel');
         }
         return $e->getMessage();
     }
     return '';
 }
Пример #6
0
 /**
  * Check the strength of the Secret Word for front-end and remote scans. If it is insecure return the reason it
  * is insecure as a string. If the Secret Word is secure return an empty string.
  *
  * @return  string
  */
 public function getFrontendSecretWordError()
 {
     // Load the Akeeba Engine autoloader
     define('AKEEBAENGINE', 1);
     require_once JPATH_ADMINISTRATOR . '/components/com_admintools/engine/Autoloader.php';
     // Load the platform
     \Akeeba\Engine\Platform::addPlatform('filescan', JPATH_ADMINISTRATOR . '/components/com_admintools/platform/Filescan');
     // Is frontend backup enabled?
     $febEnabled = \Akeeba\Engine\Platform::getInstance()->get_platform_configuration_option('frontend_enable', 0) != 0;
     if (!$febEnabled) {
         return '';
     }
     $secretWord = \Akeeba\Engine\Platform::getInstance()->get_platform_configuration_option('frontend_secret_word', '');
     try {
         \Akeeba\Engine\Util\Complexify::isStrongEnough($secretWord);
     } catch (RuntimeException $e) {
         // Ah, the current Secret Word is bad. Create a new one if necessary.
         $session = JFactory::getSession();
         $newSecret = $session->get('newSecretWord', null, 'admintools.cpanel');
         if (empty($newSecret)) {
             $random = new \Akeeba\Engine\Util\RandomValue();
             $newSecret = $random->generateString(32);
             $session->set('newSecretWord', $newSecret, 'admintools.cpanel');
         }
         return $e->getMessage();
     }
     return '';
 }