/** * Restores a user session from the identity cookie. * * This method is used when automatic login ({@link allowAutoLogin}) is enabled. The user identity information is * recovered from cookie. * * @todo Verify that it's totally necessary to re-save the cookie with a new user session token * @return null */ protected function restoreFromCookie() { // If this request doesn't want to extend the user session, it is unfortunately not possible for us to restore // their user session from a cookie, because the cookie needs to be re-saved with a new user session token, // but we can't do that without also setting a new expiration date. if ($this->_dontExtendSession) { return; } // See if they have an existing identity cookie. $cookie = $this->getIdentityCookie(); if ($cookie) { $data = $this->getIdentityCookieValue($cookie); if ($data && $this->_checkUserAgentString($data[4])) { $loginName = $data[0]; $currentSessionToken = $data[1]; $uid = $data[2]; $rememberMe = $data[3]; $states = $data[5]; $currentUserAgent = craft()->request->userAgent; $this->authTimeout = craft()->config->getUserSessionDuration($rememberMe); // Get the hashed token from the db based on login name and uid. if (($sessionRow = $this->_findSessionToken($loginName, $uid)) !== false) { $dbHashedToken = $sessionRow['token']; $userId = $sessionRow['userId']; // Make sure the given session token matches what we have in the db. $checkHashedToken = craft()->security->hashData(base64_encode(serialize($currentSessionToken))); if (\CPasswordHelper::same($checkHashedToken, $dbHashedToken)) { // It's all good. if ($this->beforeLogin($loginName, $states, true)) { $this->changeIdentity($userId, $loginName, $states); if ($this->autoRenewCookie) { // Generate a new session token for the database and cookie. $newSessionToken = craft()->security->generateRandomString(32); $hashedNewToken = craft()->security->hashData(base64_encode(serialize($newSessionToken))); $this->_updateSessionToken($loginName, $dbHashedToken, $hashedNewToken); // While we're let's clean up stale sessions. $this->_cleanStaleSessions(); // Save updated info back to identity cookie. $data = array($this->getName(), $newSessionToken, $uid, $rememberMe ? 1 : 0, $currentUserAgent, $states); $this->_identityCookie = $this->saveCookie('', $data, $this->authTimeout); $this->_sessionRestoredFromCookie = true; $this->_userRow = null; } $this->afterLogin(true); } } else { Craft::log('Tried to restore session from a cookie, but the given hashed database token value does not appear to belong to the given login name. Hashed db value: ' . $dbHashedToken . ' and loginName: ' . $loginName . '.', LogLevel::Warning); // Forcing logout here clears the identity cookie helping to prevent session fixation. $this->logout(true); } } else { Craft::log('Tried to restore session from a cookie, but the given login name does not match the given uid. UID: ' . $uid . ' and loginName: ' . $loginName . '.', LogLevel::Warning); // Forcing logout here clears the identity cookie helping to prevent session fixation. $this->logout(true); } } else { Craft::log('Tried to restore session from a cookie, but it appears we the data in the cookie is invalid.', LogLevel::Warning); $this->logout(true); } } }
private function checkPasswordResetToken($user, $token) { // Saved token - Format: randomToken.generationTime $savedTokenInfo = $user->getSetting('passwordRecoveryToken', 'user'); if ($savedTokenInfo !== "") { list($generatedToken, $generationTime) = explode('.', $savedTokenInfo); if (CPasswordHelper::same($generatedToken, $token)) { // Check token generation time if ($generationTime + 24 * 60 * 60 >= time()) { return true; } } } return false; }
/** * Gets whether the CSRF token is valid for the current user or not * * @param $token * * @return bool * @throws \CException */ protected function csrfTokenValidForCurrentUser($token) { $currentUser = false; if (craft()->isInstalled() && craft()->getComponent('userSession', false)) { $currentUser = craft()->userSession->getUser(); } if ($currentUser) { $splitToken = explode('|', $token, 2); if (count($splitToken) !== 2) { return false; } list($nonce, $hashFromToken) = $splitToken; // Check that this token is for the current user $passwordHash = $currentUser->password; $userId = $currentUser->id; $hashable = implode('|', array($nonce, $userId, $passwordHash)); $expectedToken = $nonce . '|' . craft()->security->computeHMAC($hashable); return \CPasswordHelper::same($token, $expectedToken); } else { // If they're logged out, any token is fine return true; } }
/** * Validates a given password against database record * * @param string $password unhashed * @return boolean Success */ public function validatePassword($password) { if (CPasswordHelper::same($this->password, $this->hashPassword($password))) { return true; } return false; }