/** * I'm the controller - I run methods based on the request integer */ public function run() { if (property_exists($this->_dataObj, 'c')) { $c = (int) $this->_dataObj->c; if (array_key_exists($c, $this->_methods)) { // call the right method $this->{$this->_methods[$c]}(); } else { // Die if an unknown function bfEncrypt::reply('error', 'No Such method #err1 - ' . $c); } } else { // Die if an unknown function bfEncrypt::reply('error', 'No Such method #err2'); } }
private function checkAkeebaOutputDirectory() { try { // If using PHP 5.2 then ABORT as Akeeba stuff needs newer PHP version if (version_compare(PHP_VERSION, '5.3.0', '<')) { throw new Exception('PHP version below 5.3.0 so Akeeba Will Not Work!'); } else { require 'bfPHPFiveThreePlusOnly.php'; } // Check Akeeba Installed - Prerequisite if (!file_exists(JPATH_SITE . '/libraries/f0f/include.php') || !file_exists(JPATH_SITE . '/administrator/components/com_akeeba/engine/Factory.php') || !file_exists(JPATH_SITE . '/administrator/components/com_akeeba/engine/serverkey.php')) { bfEncrypt::reply('success', array('paths' => array())); } $returnData = array(); if (!defined('AKEEBAENGINE')) { define('AKEEBAENGINE', 1); } require_once JPATH_SITE . '/libraries/f0f/include.php'; require_once JPATH_SITE . '/administrator/components/com_akeeba/engine/Factory.php'; $serverKeyFile = JPATH_BASE . '/administrator/components/com_akeeba/engine/serverkey.php'; if (!defined('AKEEBA_SERVERKEY') && file_exists($serverKeyFile)) { include $serverKeyFile; } // Get the list of profiles $profileList = F0FModel::getTmpInstance('Profiles', 'AkeebaModel')->getProfilesList(); // for each profile foreach ($profileList as $config) { // if encrypted if (substr($config->configuration, 0, 12) == '###AES128###') { $php53 = new bfPHPFiveThreePlusOnly(); $config->configuration = $php53->getAkeebaConfig($config->configuration); } // Convert ini to useable array $data = parse_ini_string($config->configuration, TRUE); // find the folder $dir = $data['akeeba']['basic.output_directory']; $returnData[] = array('path' => $dir, 'is_writable' => is_writable($dir), 'file_exists' => file_exists($dir)); } bfEncrypt::reply('success', array('paths' => $returnData)); } catch (Exception $e) { bfEncrypt::reply('error', array('msg' => $e->getMessage())); } }
* @copyright Copyright (C) 2011, 2012, 2013, 2014, 2015 Blue Flame IT Ltd. All rights reserved. * @license GNU General Public License version 3 or later * @link https://myJoomla.com/ * @author Phil Taylor / Blue Flame IT Ltd. * * bfNetwork is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * bfNetwork is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this package. If not, see http://www.gnu.org/licenses/ */ require 'bfEncrypt.php'; /** * If we have got here then we have already passed through decrypting * the encrypted header and so we are sure we are now secure and no one * else cannot run the code below. */ if ($dataObj->ping == "???PING???") { // Woohoo bfEncrypt::reply(bfReply::SUCCESS, 1); } else { // Uh-oh! bfEncrypt::reply(bfReply::FAILURE, 0); }
/** * @param $line */ private function updateFilesFromDeepscan($line) { // reconnect to the database $this->db = JFactory::getDBO(); $this->dbPing(); bfLog::log(' =updateFilesFromDeepscan called from line ' . $line); bfLog::log(' =Marking this number of files as _encryptedAndSuspectIds= ' . count($this->_encryptedAndSuspectIds)); if (count($this->_encryptedAndSuspectIds)) { $sql = "UPDATE bf_files SET encrypted = %s, suspectcontent = %s, queued = 0 WHERE id IN(%s)"; $sql = sprintf($sql, 1, 1, implode(', ', $this->_encryptedAndSuspectIds)); $this->db->setQuery($sql); if ($this->db->query()) { bfLog::log(' = Removed success = '); } else { bfLog::log('============================================='); bfLog::log($this->db->getErrorMsg() . $sql); bfLog::log('============================================='); bfEncrypt::reply(bfReply::ERROR, $this->db->getErrorMsg()); } $this->_encryptedAndSuspectIds = array(); } bfLog::log(' =Marking this number of files as _encryptedIds = ' . count($this->_encryptedIds)); if (count($this->_encryptedIds)) { $sql = "UPDATE bf_files SET encrypted = %s, suspectcontent = %s, queued = 0 WHERE id IN(%s)"; $sql = sprintf($sql, 1, 0, implode(', ', $this->_encryptedIds)); $this->db->setQuery($sql); if ($this->db->query()) { bfLog::log(' = Removed success = '); } else { bfLog::log('============================================='); bfLog::log($this->db->getErrorMsg() . $sql); bfLog::log('============================================='); bfEncrypt::reply(bfReply::ERROR, $this->db->getErrorMsg()); } $this->_encryptedIds = array(); } bfLog::log(' =Marking this number of files as _suspectIds = ' . count($this->_suspectIds)); if (count($this->_suspectIds)) { $sql = "UPDATE bf_files SET encrypted = %s, suspectcontent = %s, queued = 0 WHERE id IN(%s)"; $sql = sprintf($sql, 0, 1, implode(', ', $this->_suspectIds)); $this->db->setQuery($sql); if ($this->db->query()) { bfLog::log(' = Removed success = '); } else { bfLog::log('============================================='); bfLog::log($this->db->getErrorMsg() . $sql); bfLog::log('============================================='); bfEncrypt::reply(bfReply::ERROR, $this->db->getErrorMsg()); } $this->_suspectIds = array(); } bfLog::log(' =Marking this number of files as NOT _notencryptedAndSuspectIds = ' . count($this->_notencryptedAndSuspectIds)); if (count($this->_notencryptedAndSuspectIds)) { $sql = "UPDATE bf_files SET encrypted = %s, suspectcontent = %s, queued = 0 WHERE id IN(%s)"; $sql = sprintf($sql, 0, 0, implode(', ', $this->_notencryptedAndSuspectIds)); $this->db->setQuery($sql); if ($this->db->query()) { bfLog::log(' = Removed success = '); } else { bfLog::log('============================================='); bfLog::log($this->db->getErrorMsg() . $sql); bfLog::log('============================================='); bfEncrypt::reply(bfReply::ERROR, $this->db->getErrorMsg()); } $this->_notencryptedAndSuspectIds = array(); } }
} catch (Exception $e) { // No need to pass back issues when looking for Akeeba or PHP versions - we will just ignore it // After all if the site is running in PHP 5.2 they have bigger issues!!! return $problems; } } private function getDiskSpace() { $data = array('free' => disk_free_space(JPATH_BASE), 'total' => disk_total_space(JPATH_BASE)); $data['used'] = $data['total'] - $data['free']; $data['percentUsed'] = sprintf('%.2f', $data['used'] / $data['total'] * 100); $data['free'] = $this->formatSize($data['free']); $data['total'] = $this->formatSize($data['total']); $data['used'] = $this->formatSize($data['used']); return json_encode($data); } private function formatSize($bytes) { $types = array('B', 'KB', 'MB', 'GB', 'TB'); for ($i = 0; $bytes >= 1024 && $i < count($types) - 1; $bytes /= 1024, $i++) { } return round($bytes, 2) . " " . $types[$i]; } public function getData() { return $this->_data; } } $data = new bfSnapshot(); bfEncrypt::reply(bfReply::SUCCESS, $data->getData());
* @link https://myJoomla.com/ * @author Phil Taylor / Blue Flame IT Ltd. * * bfNetwork is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * bfNetwork is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this package. If not, see http://www.gnu.org/licenses/ */ require 'bfEncrypt.php'; /** * If we have got here then we have already passed through decrypting * the encrypted header and so we are sure we are now secure and no one * else cannot run the code below. */ // load mini-Joomla require 'bfInitJoomla.php'; // Get some Joomla version $VERSION = new JVersion(); // Get the connector version $connectorVersion = file_get_contents('VERSION'); // Reply with all the versions bfEncrypt::reply('success', array('version' => $VERSION->getShortVersion(), 'platform' => $VERSION->PRODUCT, 'connectorversion' => $connectorVersion));
/** * Decrypt the incoming encrypted data * Will be encrypted with the public part of the key pair * * @param Crypt_Rsa $rsa * @param bool $enc * * @return mixed stdClass */ public static function decrypt($rsa, $enc = FALSE) { $start = time(); bfLog::log('Starting Decryption....'); // Create an empty class $dataObj = new stdClass(); // If its a normal encrypted request - 99.9% of our requests if ($enc === TRUE) { $header = json_decode($rsa->decrypt(base64_decode($_POST['ENCRYPTED']))); } else { // if an encrypted request, with an encrypted header, and non encrypted body 0.1% of our requests $header = json_decode($rsa->decrypt(base64_decode($_POST['ENCRYPTED_HEADER']))); } /** * If we have got here then we have already passed through decrypting * the encrypted header and so we are sure we are now secure and no one * else cannot run the code below. */ // When we get here we are DECRYPTED :-) bfLog::log('Finished Decryption.... took ' . (time() - $start) . ' seconds'); // Set the encryption key to send data back with define('RC4_KEY', $header->RC4_KEY); // attempt to ensure our tmp folder is writable if (!is_writeable(dirname(__FILE__) . '/tmp')) { @chmod(dirname(__FILE__) . '/tmp', 0755); } // Argh! if (!is_writeable(dirname(__FILE__) . '/tmp')) { @chmod(dirname(__FILE__) . '/tmp', 0777); } // Give Up! if (!is_writeable(dirname(__FILE__) . '/tmp')) { bfEncrypt::reply(bfReply::ERROR, dirname(__FILE__) . '/tmp folder not writeable'); } // attempt to ensure our folder is writable if (!is_writeable(dirname(__FILE__))) { @chmod(dirname(__FILE__), 0755); } // Argh! if (!is_writeable(dirname(__FILE__))) { @chmod(dirname(__FILE__), 0777); } // Give Up! if (!is_writeable(dirname(__FILE__))) { bfEncrypt::reply(bfReply::ERROR, dirname(__FILE__) . '/ folder not writeable'); } // check Version - do I need an upgrade before I proceed? $myVersion = file_get_contents('./VERSION'); if (!defined('_BF_IN_UPGRADE') && $myVersion != $header->REQ_CLIENT_VERSION) { // Force a client connector upgrade bfEncrypt::reply(bfReply::NEEDSCONNECTORUPGRADE, bfReply::NEEDSCONNECTORUPGRADE); } // If a fully encrypted request then return all the data if ($enc === TRUE) { return $header; } // If a partially encrypted request, then we have an encrypted header, // and some non-encrypted body // check the checksum from the encrypted part of the request to prevent // spoofing if ("ENCRYPTED_HEADER" == $header->checksum) { // get the timestamp of the request $dataObj->timestamp = $header->timestamp; // get the non encrypted vars from the request $dataObj->NOTENCRYPTED = $_POST['NOTENCRYPTED']; foreach ($dataObj->NOTENCRYPTED as $k => $v) { $dataObj->{$k} = $v; } return $dataObj; } else { // If we get here then then the KEYS are wrong, or the request are // wrong die(json_encode(array('METHOD' => 'NOTENCRYPTED', 'RESULT' => bfReply::ERROR, 'NOTENCRYPTED' => array('msg' => 'Failed Checksum 101')))); } }
/** * If not enabled, then enable the Akeeba API Frontend using a secure secret word */ private function enableAkeebaFrontendBackup() { // load mini-Joomla require 'bfInitJoomla.php'; $this->_db = JFactory::getDBO(); // Get some Joomla version $VERSION = new JVersion(); switch ($VERSION->RELEASE) { case '1.5': $params = JComponentHelper::getParams('com_akeeba'); if (!count($params->toArray())) { // send back the totals bfEncrypt::reply('success', array('akeeba_installed' => FALSE)); } $frontend_enable = $params->get('frontend_enable'); $frontend_secret_word = $params->get('frontend_secret_word'); if ($frontend_enable != 1) { $params->set('frontend_enable', 1); $saveChanges = TRUE; } $params->set('frontend_secret_word', str_replace('&', '', JUtility::getHash(JUtility::getToken(TRUE)))); $saveChanges = TRUE; $secretWord = $params->get('frontend_secret_word'); if (TRUE == $saveChanges) { $params = $params->toString(); $sql = 'UPDATE #__components SET params = \'%s\' WHERE `OPTION` = "com_akeeba"'; $sql = sprintf($sql, addslashes($params)); $this->_db->setQuery($sql); $this->_db->query(); } break; default: case '2.5': $this->_db->setQuery('SELECT extension_id, params FROM #__extensions WHERE NAME="akeeba" AND element = "com_akeeba"'); $data = $this->_db->loadObject(); if (!$data) { // send back the totals bfEncrypt::reply('success', array('akeeba_installed' => FALSE)); } $params = json_decode($data->params); if ($params->frontend_enable != 1) { $params->frontend_enable = 1; $saveChanges = TRUE; } if (!$params->frontend_secret_word || preg_match('/\\&/', $params->frontend_secret_word)) { $params->frontend_secret_word = md5(JApplication::getHash('myjoomla')); $saveChanges = TRUE; } $secretWord = $params->frontend_secret_word; if (TRUE == $saveChanges) { $params = json_encode($params); $sql = 'UPDATE #__extensions SET params = \'%s\' WHERE extension_id = %s'; $sql = sprintf($sql, addslashes($params), $data->extension_id); $this->_db->setQuery($sql); $this->_db->query(); } break; } // send back the totals bfEncrypt::reply('success', array('akeeba_installed' => TRUE, 'secret' => $secretWord)); }
/** * Returns the (cached) list of updates for every section: installed version, current * branch updates, sts/lts updates, testing updates. * * @param boolean $force Should I forcibly reload the update information, refreshing the cache? * * @return array|null The updates array, null if crap hits the fan */ public function getAllUpdates($force = FALSE) { // Get the component parameters if (version_compare(JVERSION, '3.0.0', 'ge')) { JLoader::import('cms.component.helper'); } else { JLoader::import('joomla.application.component.helper'); } $params = JComponentHelper::getParams('com_cmsupdate'); // Do I have to check for updates? if (!$force) { // Check with the specified frequency which has to be between 1 hour and 30 days $frequency = $params->get('frequency', 6); if ($frequency < 0 || $frequency > 720) { $frequency = 6; } // Get the last time we checked for updates $lastCheck = $params->get('lastcheck', 0); $nextCheckTimeStamp = $lastCheck + 3600 * $frequency; $force = $nextCheckTimeStamp <= time(); } // Do I have a cache? If not I have to force an update fetch. $cache = NULL; if (!$force) { $cacheEncoded = $params->get('updatecache', ''); if (!empty($cacheEncoded)) { $cache = json_decode($cacheEncoded, TRUE); } if (empty($cache)) { $cache = NULL; $force = TRUE; } } // If we are forced to perform an update fetch do it and refresh the cache if ($force) { // Get the update sources we are configured to use $sources = array('lts' => TRUE, 'sts' => TRUE, 'test' => TRUE, 'custom' => $params->get('customurl', '')); switch ($params->get('updatesource', 'all')) { case 'custom': $sources['lts'] = FALSE; $sources['sts'] = FALSE; $sources['testing'] = FALSE; break; case 'testing': $sources['lts'] = FALSE; $sources['sts'] = FALSE; $sources['custom'] = ''; break; case 'sts': $sources['lts'] = FALSE; $sources['test'] = FALSE; $sources['custom'] = ''; break; case 'lts': $sources['sts'] = FALSE; $sources['test'] = FALSE; $sources['custom'] = ''; break; } // Get the updates $provider = new AcuUpdateProviderJoomla(); $cache = $provider->getUpdates($sources); // JSON-encode them $cacheEncoded = json_encode($cache); // Save the cache $params->set('updatecache', $cacheEncoded); $params->set('lastcheck', time()); $component = JComponentHelper::getComponent('com_cmsupdate'); $db = JFactory::getDbo(); $query = $db->getQuery(TRUE)->update('#__extensions')->set('params' . ' = ' . $db->quote($params->toString('JSON')))->where('extension_id' . ' = ' . $db->quote($component->id)); $db->setQuery($query); if (method_exists($db, 'execute')) { $db->execute(); } else { $db->query(); } } if ($this->hasAkeebaBackup()) { $db = JFactory::getDbo(); $query = $db->getQuery(TRUE)->select('MAX(id)')->from('#__ak_stats')->where('`origin` != "restorepoint"'); $db->setQuery($query); $lastBackup = $db->loadResult(); if ($lastBackup > 0) { $query = 'SELECT * FROM #__ak_stats WHERE tag <> "restorepoint" ORDER BY `backupstart` DESC LIMIT 1 '; $db->setQuery($query); $lastBackup = $db->loadObjectList(); } } else { $lastBackup = ''; } $data = array($cache, 'Currently_Installed_Version' => JVERSION, 'PHP_VERSION' => PHP_VERSION, 'hasAkeebaBackup' => $this->hasAkeebaBackup(), 'lastBackupDetails' => $lastBackup); bfEncrypt::reply('success', array('msg' => json_encode($data))); }
throw new Exception('Could not download connector upgrade file using file_get_contents or curl functions - contact Phil for support'); } // Remember: The upgrade file DOESN'T contain any security keys! This is a good thing! // Save the Zip File if (!file_put_contents('upgrade.zip', $upgradeFileContent)) { throw new Exception('Could not auto upgrade (save upgrade file failed) - you need to install a new connector manually'); } // Load the Zip file $zip = new Bf_Zip('upgrade.zip'); // Extract the Zip file if (!$zip->extract(PCLZIP_OPT_PATH, './', PCLZIP_OPT_REMOVE_PATH, 'bfnetwork')) { throw new Exception('Could not auto upgrade (Extract Error) - you need to install a new connector manually'); } // .. @todo check each file is valid against some kind of hash to prevent modifications client side // cleanup old files $oldFiles = array('upgrade.zip', './bfViewLog.php', './bfDev.php', './bfDb.php', './bfMysql.php', './j25_30_bfnetwork.xml', './install.bfnetwork.php', './bfnetwork.xml', './bfJson.php'); foreach ($oldFiles as $file) { if (file_exists($file)) { @unlink($file); } } // cleanup if (file_exists('../j25_30_bfnetwork.xml')) { @copy('../j25_30_bfnetwork.xml', '../bfnetwork.xml'); @unlink('../j25_30_bfnetwork.xml'); } // Reply with a great big high five! bfEncrypt::reply(bfReply::SUCCESS, array('version' => file_get_contents('VERSION'))); } catch (Exception $e) { bfEncrypt::reply(bfReply::ERROR, 'EXCEPTION: ' . $e->getMessage()); }