/** * Store the unfiltered SMTP password * * @param mixed $varValue * @param DataContainer $dc * * @return mixed */ public function storeSmtpPass($varValue, DataContainer $dc) { if (isset($_POST[$dc->field])) { return Input::postUnsafeRaw($dc->field); } return $varValue; }
/** * Run the controller and parse the password template */ public function run() { /** @var \BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_password'); if (\Input::post('FORM_SUBMIT') == 'tl_password') { $pw = \Input::postUnsafeRaw('password'); $cnf = \Input::postUnsafeRaw('confirm'); // The passwords do not match if ($pw != $cnf) { \Message::addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']); } elseif (utf8_strlen($pw) < \Config::get('minPasswordLength')) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], \Config::get('minPasswordLength'))); } elseif ($pw == $this->User->username) { \Message::addError($GLOBALS['TL_LANG']['ERR']['passwordName']); } else { // Make sure the password has been changed if (\Encryption::verify($pw, $this->User->password)) { \Message::addError($GLOBALS['TL_LANG']['MSC']['pw_change']); } else { $this->loadDataContainer('tl_user'); // Trigger the save_callback if (is_array($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'])) { foreach ($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $pw = $this->{$callback[0]}->{$callback[1]}($pw); } elseif (is_callable($callback)) { $pw = $callback($pw); } } } $objUser = \UserModel::findByPk($this->User->id); $objUser->pwChange = ''; $objUser->password = \Encryption::hash($pw); $objUser->save(); \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['pw_changed']); $this->redirect('' . $GLOBALS['TL_CONFIG']['backendPath'] . '/main.php'); } } $this->reload(); } $objTemplate->theme = \Backend::getTheme(); $objTemplate->messages = \Message::generate(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->title = specialchars($GLOBALS['TL_LANG']['MSC']['pw_new']); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->action = ampersand(\Environment::get('request')); $objTemplate->headline = $GLOBALS['TL_LANG']['MSC']['pw_change']; $objTemplate->submitButton = specialchars($GLOBALS['TL_LANG']['MSC']['continue']); $objTemplate->password = $GLOBALS['TL_LANG']['MSC']['password'][0]; $objTemplate->confirm = $GLOBALS['TL_LANG']['MSC']['confirm'][0]; $objTemplate->output(); }
/** * Set up the database connection */ protected function setUpDatabaseConnection() { $strDrivers = ''; $arrDrivers = array(''); if (class_exists('mysqli', false)) { $arrDrivers[] = 'MySQLi'; } if (function_exists('mysql_connect')) { $arrDrivers[] = 'MySQL'; } // If there is another driver defined, add it here as well if (\Config::get('dbDriver') != '' && !in_array(\Config::get('dbDriver'), $arrDrivers)) { $arrDrivers[] = \Config::get('dbDriver'); } foreach ($arrDrivers as $strDriver) { $strDrivers .= sprintf('<option value="%s"%s>%s</option>', $strDriver, $strDriver == \Config::get('dbDriver') ? ' selected="selected"' : '', $strDriver ?: '-'); } $this->Template->drivers = $strDrivers; $this->Template->driver = \Config::get('dbDriver'); $this->Template->host = \Config::get('dbHost'); $this->Template->user = \Config::get('dbUser'); $this->Template->pass = \Config::get('dbPass') != '' ? '*****' : ''; $this->Template->port = \Config::get('dbPort'); $this->Template->socket = \Config::get('dbSocket'); $this->Template->pconnect = \Config::get('dbPconnect'); $this->Template->dbcharset = \Config::get('dbCharset'); $this->Template->database = \Config::get('dbDatabase'); // Store the database connection parameters if (\Input::post('FORM_SUBMIT') == 'tl_database_login') { foreach (preg_grep('/^db/', array_keys($_POST)) as $strKey) { if ($strKey == 'dbPass' && \Input::postUnsafeRaw($strKey) == '*****') { continue; } // The port number must not be empty (see #7950) if ($strKey == 'dbPort' && \Input::post($strKey, true) == '') { \Input::setPost($strKey, 3306); } \Config::persist($strKey, $strKey == 'dbPass' ? \Input::postUnsafeRaw($strKey) : \Input::post($strKey, true)); } $this->reload(); } // No driver selected (see #6088) if (\Config::get('dbDriver') == '') { $this->Template->dbConnection = false; $this->outputAndExit(); } // Try to connect try { $this->import('Database'); $this->Database->listTables(); $this->Template->dbConnection = true; } catch (\Exception $e) { $this->Template->dbConnection = false; $this->Template->dbError = $e->getMessage(); $this->outputAndExit(); } }
/** * Store the install tool password */ protected function storeInstallToolPassword() { $strPassword = \Input::postUnsafeRaw('password'); // The passwords do not match if ($strPassword != \Input::postUnsafeRaw('confirm_password')) { $this->Template->passwordError = $GLOBALS['TL_LANG']['ERR']['passwordMatch']; } elseif (utf8_strlen($strPassword) < \Config::get('minPasswordLength')) { $this->Template->passwordError = sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], \Config::get('minPasswordLength')); } else { $strPassword = \Encryption::hash($strPassword); \Config::persist('installPassword', $strPassword); $this->reload(); } }
/** * Try to login the current user * * @return boolean True if the user could be logged in */ public function login() { \System::loadLanguageFile('default'); // Do not continue if username or password are missing if (empty($_POST['username']) || empty($_POST['password'])) { return false; } // Load the user object if ($this->findBy('username', \Input::post('username', true)) == false) { $blnLoaded = false; // HOOK: pass credentials to callback functions if (isset($GLOBALS['TL_HOOKS']['importUser']) && is_array($GLOBALS['TL_HOOKS']['importUser'])) { foreach ($GLOBALS['TL_HOOKS']['importUser'] as $callback) { $this->import($callback[0], 'objImport', true); $blnLoaded = $this->objImport->{$callback[1]}(\Input::post('username', true), \Input::postUnsafeRaw('password'), $this->strTable); // Load successfull if ($blnLoaded === true) { break; } } } // Return if the user still cannot be loaded if (!$blnLoaded || $this->findBy('username', \Input::post('username', true)) == false) { \Message::addError($GLOBALS['TL_LANG']['ERR']['invalidLogin']); $this->log('Could not find user "' . \Input::post('username', true) . '"', __METHOD__, TL_ACCESS); return false; } } $time = time(); // Set the user language if (\Input::post('language')) { $this->language = \Input::post('language'); } // Lock the account if there are too many login attempts if ($this->loginCount < 1) { $this->locked = $time; $this->loginCount = \Config::get('loginCount'); $this->save(); // Add a log entry and the error message, because checkAccountStatus() will not be called (see #4444) $this->log('User "' . $this->username . '" has been locked for ' . ceil(\Config::get('lockPeriod') / 60) . ' minutes', __METHOD__, TL_ACCESS); \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['accountLocked'], ceil(($this->locked + \Config::get('lockPeriod') - $time) / 60))); // Send admin notification if (\Config::get('adminEmail') != '') { $objEmail = new \Email(); $objEmail->subject = $GLOBALS['TL_LANG']['MSC']['lockedAccount'][0]; $objEmail->text = sprintf($GLOBALS['TL_LANG']['MSC']['lockedAccount'][1], $this->username, TL_MODE == 'FE' ? $this->firstname . " " . $this->lastname : $this->name, \Idna::decode(\Environment::get('base')), ceil(\Config::get('lockPeriod') / 60)); $objEmail->sendTo(\Config::get('adminEmail')); } return false; } // Check the account status if ($this->checkAccountStatus() == false) { return false; } // The password has been generated with crypt() if (\Encryption::test($this->password)) { $blnAuthenticated = \Encryption::verify(\Input::postUnsafeRaw('password'), $this->password); } else { list($strPassword, $strSalt) = explode(':', $this->password); $blnAuthenticated = $strSalt == '' ? $strPassword === sha1(\Input::postUnsafeRaw('password')) : $strPassword === sha1($strSalt . \Input::postUnsafeRaw('password')); // Store a SHA-512 encrpyted version of the password if ($blnAuthenticated) { $this->password = \Encryption::hash(\Input::postUnsafeRaw('password')); } } // HOOK: pass credentials to callback functions if (!$blnAuthenticated && isset($GLOBALS['TL_HOOKS']['checkCredentials']) && is_array($GLOBALS['TL_HOOKS']['checkCredentials'])) { foreach ($GLOBALS['TL_HOOKS']['checkCredentials'] as $callback) { $this->import($callback[0], 'objAuth', true); $blnAuthenticated = $this->objAuth->{$callback[1]}(\Input::post('username', true), \Input::postUnsafeRaw('password'), $this); // Authentication successfull if ($blnAuthenticated === true) { break; } } } // Redirect if the user could not be authenticated if (!$blnAuthenticated) { --$this->loginCount; $this->save(); \Message::addError($GLOBALS['TL_LANG']['ERR']['invalidLogin']); $this->log('Invalid password submitted for username "' . $this->username . '"', __METHOD__, TL_ACCESS); return false; } $this->setUserFromDb(); // Update the record $this->lastLogin = $this->currentLogin; $this->currentLogin = $time; $this->loginCount = \Config::get('loginCount'); $this->save(); // Generate the session $this->generateSession(); $this->log('User "' . $this->username . '" has logged in', __METHOD__, TL_ACCESS); // HOOK: post login callback if (isset($GLOBALS['TL_HOOKS']['postLogin']) && is_array($GLOBALS['TL_HOOKS']['postLogin'])) { foreach ($GLOBALS['TL_HOOKS']['postLogin'] as $callback) { $this->import($callback[0], 'objLogin', true); $this->objLogin->{$callback[1]}($this); } } return true; }
/** * Run the communication as client * * @return void */ public function run() { // If we have a ping, just do nothing if (\Input::get("act") == "ping") { // Clean output buffer while (@ob_end_clean()) { } exit; } /* --------------------------------------------------------------------- * Check if we have a old AES or a new AES with IV. * Set codifyengine keys. * Check the connection ID and refresh/delete it. */ // Check if IV was send, when send use the new AES else the old one. try { $this->objCodifyengineBasic = Factory::getEngine("aes"); $this->setCodifyengine(\Input::get("engine")); } catch (\RuntimeException $exc) { \System::log("Try to load the engine for ctoCommunication with error: " . $exc->getMessage(), __FUNCTION__ . " | " . __CLASS__, TL_ERROR); // Clean output buffer while (@ob_end_clean()) { } exit; } // Check if we have a incomming connection for handshake if (in_array(\Input::get("act"), array("CTOCOM_HELLO", "CTOCOM_START_HANDSHAKE", "CTOCOM_CHECK_HANDSHAKE", "CTOCOM_VERSION"))) { $this->objCodifyengine->setKey($GLOBALS['TL_CONFIG']['ctoCom_APIKey']); $this->objCodifyengineBasic->setKey($GLOBALS['TL_CONFIG']['ctoCom_APIKey']); $strCodifyKey = $GLOBALS['TL_CONFIG']['ctoCom_APIKey']; } else { // Use the private key from connection pool if (strlen(\Input::get("con")) != 0) { // Check if we have some data $arrConnections = \Database::getInstance()->prepare("SELECT * FROM tl_ctocom_cache WHERE uid=?")->execute(\Input::get("con"))->fetchAllAssoc(); if (count($arrConnections) == 0) { \System::log(vsprintf("Call from %s with a unknown connection ID.", \Environment::get('ip')), __FUNCTION__ . " | " . __CLASS__, TL_ERROR); // Clean output buffer while (@ob_end_clean()) { } exit; } // Check if time out isn't reached. if ($arrConnections[0]["tstamp"] + $this->intHandshakeTimeout < time()) { \Database::getInstance()->prepare("DELETE FROM tl_ctocom_cache WHERE uid=?")->execute(\Input::get("con")); \System::log(vsprintf("Call from %s with a expired connection ID.", \Environment::get('ip')), __FUNCTION__ . " | " . __CLASS__, TL_ERROR); // Clean output buffer while (@ob_end_clean()) { } exit; } // Reset timestamp \Database::getInstance()->prepare("UPDATE tl_ctocom_cache %s WHERE uid=?")->set(array("tstamp" => time()))->execute(\Input::get("con")); // Set codify key from database $this->objCodifyengineBasic->setKey($arrConnections[0]["shared_secret_key"]); $this->objCodifyengine->setKey($arrConnections[0]["shared_secret_key"]); $strCodifyKey = $arrConnections[0]["shared_secret_key"]; } else { \System::log(vsprintf("Call from %s without a connection ID.", \Environment::get('ip')), __FUNCTION__ . " | " . __CLASS__, TL_ERROR); // Clean output buffer while (@ob_end_clean()) { } exit; } } /* --------------------------------------------------------------------- * Check the API key. * Check if the API Key was send. * Check if the API key contains the RPC Call and the API Key from this * Contao Version. */ // Check if a API-Key was send if (strlen(\Input::get("apikey")) == 0) { \System::log(vsprintf("Call from %s without a API Key.", \Environment::get('ip')), __FUNCTION__ . " | " . __CLASS__, TL_ERROR); // Clean output buffer while (@ob_end_clean()) { } exit; } // Check RPC Call from get and the RPC Call from API-Key $mixVar = $this->objCodifyengineBasic->Decrypt(base64_decode(\Input::get("apikey", true))); $mixVar = trimsplit("@\\|@", $mixVar); $strApiKey = $mixVar[1]; $strAction = $mixVar[0]; if ($strAction != \Input::get("act")) { \System::log(vsprintf("Error Api Key from %s. Request action: %s | Key action: %s | Api: %s", array(\Environment::get('ip'), \Input::get("act"), $strAction, $strApiKey)), __FUNCTION__ . " | " . __CLASS__, TL_ERROR); // Clean output buffer while (@ob_end_clean()) { } exit; } if ($GLOBALS['TL_CONFIG']['ctoCom_APIKey'] != $strApiKey) { \System::log(vsprintf("Call from %s with a wrong API Key: %s", array(\Environment::get('ip'), \Input::get("apikey"))), __FUNCTION__ . " | " . __CLASS__, TL_ERROR); // Clean output buffer while (@ob_end_clean()) { } exit; } /* --------------------------------------------------------------------- * Check language settings */ if (empty($GLOBALS['TL_LANGUAGE'])) { $GLOBALS['TL_LANGUAGE'] = "en"; } /* --------------------------------------------------------------------- * Set I/O System */ if (strlen(\Input::get("format")) != 0) { if (\CtoCommunication\InputOutput\Factory::engineExist(\Input::get("format"))) { $this->setIOEngine(\Input::get("format")); } else { $this->setIOEngine(); $this->objError = new Error(); $this->objError->setLanguage("unknown_io"); $this->objError->setID(10); $this->objError->setObject(""); $this->objError->setMessage("No I/O Interface found for accept."); $this->objError->setRPC(""); $this->objError->setClass(""); $this->objError->setFunction(""); $this->generateOutput(); exit; } } else { $strAccept = $_SERVER['HTTP_ACCEPT']; $strAccept = preg_replace("/;q=\\d\\.\\d/", "", $strAccept); $arrAccept = trimsplit(",", $strAccept); $strIOEngine = false; foreach ($arrAccept as $key => $value) { $strIOEngine = \CtoCommunication\InputOutput\Factory::getEngingenameForAccept($value); if ($strIOEngine !== false) { break; } } if ($strIOEngine === false) { $this->objIOEngine = \CtoCommunication\InputOutput\Factory::getEngine('default'); $this->objError = new Error(); $this->objError->setLanguage("unknown_io"); $this->objError->setID(10); $this->objError->setObject(""); $this->objError->setMessage("No I/O Interface found for accept: {$strAccept}"); $this->objError->setRPC(""); $this->objError->setClass(""); $this->objError->setFunction(""); $this->generateOutput(); exit; } else { $this->setIOEngine($strIOEngine); } } /* --------------------------------------------------------------------- * Run RPC-Check function */ // Check if act is set $mixRPCCall = \Input::get("act"); if (strlen($mixRPCCall) == 0) { $this->objError = new Error(); $this->objError->setLanguage("rpc_missing"); $this->objError->setID(1); $this->objError->setObject(""); $this->objError->setMessage("Missing RPC Call"); $this->objError->setRPC($mixRPCCall); $this->objError->setClass(""); $this->objError->setFunction(""); $this->generateOutput(); exit; } if (!array_key_exists($mixRPCCall, $this->arrRpcList)) { $this->objError = new Error(); $this->objError->setLanguage("rpc_unknown"); $this->objError->setID(1); $this->objError->setObject(""); $this->objError->setMessage("Unknown RPC Call"); $this->objError->setRPC($mixRPCCall); $this->objError->setClass(""); $this->objError->setFunction(""); $this->generateOutput(); exit; } /* --------------------------------------------------------------------- * Build a list with parameter from the POST */ $arrParameter = array(); if ($this->arrRpcList[$mixRPCCall]["parameter"] != false && is_array($this->arrRpcList[$mixRPCCall]["parameter"])) { switch ($this->arrRpcList[$mixRPCCall]["typ"]) { // Decode post case "POST": // Decode each post $arrPostValues = array(); foreach ($_POST as $key => $value) { if (version_compare('3.2.16', VERSION . '.' . BUILD, '<=') && version_compare('3.3.0', VERSION . '.' . BUILD, '>') || version_compare('3.3.7', VERSION . '.' . BUILD, '<=')) { // Get the raw data. $mixPost = \Input::postUnsafeRaw($key); } else { // Get the raw data for older contao versions. $mixPost = \Input::postRaw($key); } $mixPost = $this->objIOEngine->InputPost($mixPost, $this->objCodifyengine); $arrPostValues[$key] = $mixPost; \Input::setPost($key, $mixPost); } // Check if all post are set foreach ($this->arrRpcList[$mixRPCCall]["parameter"] as $value) { $arrPostKey = array_keys($arrPostValues); if (!in_array($value, $arrPostKey)) { $arrParameter[$value] = null; } else { // Get the raw data. $arrParameter[$value] = $arrPostValues[$value]; } } unset($arrPostValues); break; default: break; } } /* --------------------------------------------------------------------- * Call function */ try { $strClassname = $this->arrRpcList[$mixRPCCall]["class"]; if (!class_exists($strClassname)) { $this->objError = new Error(); $this->objError->setLanguage("rpc_class_not_exists"); $this->objError->setID(4); $this->objError->setObject($value); $this->objError->setMessage("The choosen class didn`t exists."); $this->objError->setRPC($mixRPCCall); $this->objError->setClass($this->arrRpcList[$mixRPCCall]["class"]); $this->objError->setFunction($this->arrRpcList[$mixRPCCall]["function"]); $this->generateOutput(); exit; } $objReflection = new \ReflectionClass($strClassname); if ($objReflection->hasMethod("getInstance")) { $object = call_user_func_array(array($this->arrRpcList[$mixRPCCall]["class"], "getInstance"), array()); $this->mixOutput = call_user_func_array(array($object, $this->arrRpcList[$mixRPCCall]["function"]), $arrParameter); } else { $object = new $this->arrRpcList[$mixRPCCall]["class"](); $this->mixOutput = call_user_func_array(array($object, $this->arrRpcList[$mixRPCCall]["function"]), $arrParameter); } } catch (\Exception $exc) { $this->objError = new Error(); $this->objError->setLanguage("rpc_unknown_exception"); $this->objError->setID(3); $this->objError->setObject(""); $this->objError->setMessage($exc->getMessage()); $this->objError->setRPC($mixRPCCall); $this->objError->setClass($this->arrRpcList[$mixRPCCall]["class"]); $this->objError->setFunction($this->arrRpcList[$mixRPCCall]["function"]); $this->objError->setException($exc); \System::log(vsprintf("RPC Exception: %s | %s", array($exc->getMessage(), nl2br($exc->getTraceAsString()))), __CLASS__ . " | " . __FUNCTION__, TL_ERROR); $this->generateOutput(); exit; } $this->generateOutput(); exit; }