getMessage()); } switch (Minz_Configuration::authType()) { case 'form': self::$login_ok = Minz_Session::param('passwordHash') === $conf->passwordHash; break; case 'http_auth': self::$login_ok = strcasecmp($current_user, httpAuthUser()) === 0; break; case 'persona': self::$login_ok = strcasecmp(Minz_Session::param('mail'), $conf->mail_login) === 0; break; case 'none': self::$login_ok = true; break; default: // TODO: extensions self::$login_ok = false; } Minz_Session::_param('loginOk', self::$login_ok); } /** * Returns if current user has access to the given scope. * * @param string $scope general (default) or admin * @return boolean true if user has corresponding access, false else. */ public static function hasAccess($scope = 'general') { $ok = self::$login_ok; switch ($scope) { case 'general': break; case 'admin': $ok &= Minz_Session::param('currentUser') === Minz_Configuration::defaultUser(); break; default: $ok = false; } return $ok; } /** * Removes all accesses for the current user. */ public static function removeAccess() { Minz_Session::_param('loginOk'); self::$login_ok = false; Minz_Session::_param('currentUser', Minz_Configuration::defaultUser()); switch (Minz_Configuration::authType()) { case 'form': Minz_Session::_param('passwordHash'); FreshRSS_FormAuth::deleteCookie(); break; case 'persona': Minz_Session::_param('mail'); break; case 'http_auth': case 'none': // Nothing to do... break; default: // TODO: extensions } } } class FreshRSS_FormAuth { public static function checkCredentials($username, $hash, $nonce, $challenge) { if (!ctype_alnum($username) || !ctype_graph($challenge) || !ctype_alnum($nonce)) { Minz_Log::debug('Invalid credential parameters:' . ' user=' . $username . ' challenge=' . $challenge . ' nonce=' . $nonce); return false; } if (!function_exists('password_verify')) { include_once(LIB_PATH . '/password_compat.php'); } return password_verify($nonce . $hash, $challenge); } public static function getCredentialsFromCookie() { $token = Minz_Session::getLongTermCookie('FreshRSS_login'); if (!ctype_alnum($token)) { return array(); } $token_file = DATA_PATH . '/tokens/' . $token . '.txt'; $mtime = @filemtime($token_file); if ($mtime + 2629744 < time()) { // Token has expired (> 1 month) or does not exist. // TODO: 1 month -> use a configuration instead @unlink($token_file); return array(); } $credentials = @file_get_contents($token_file); return $credentials === false ? array() : explode("\t", $credentials, 2); } public static function makeCookie($username, $password_hash) { do { $token = sha1(Minz_Configuration::salt() . $username . uniqid(mt_rand(), true)); $token_file = DATA_PATH . '/tokens/' . $token . '.txt'; } while (file_exists($token_file)); if (@file_put_contents($token_file, $username . "\t" . $password_hash) === false) { return false; } $expire = time() + 2629744; //1 month //TODO: Use a configuration instead Minz_Session::setLongTermCookie('FreshRSS_login', $token, $expire); return $token; } public static function deleteCookie() { $token = Minz_Session::getLongTermCookie('FreshRSS_login'); Minz_Session::deleteLongTermCookie('FreshRSS_login'); if (ctype_alnum($token)) { @unlink(DATA_PATH . '/tokens/' . $token . '.txt'); } if (rand(0, 10) === 1) { self::purgeTokens(); } } public static function purgeTokens() { $oldest = time() - 2629744; // 1 month // TODO: Use a configuration instead foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $file_info) { // $extension = $file_info->getExtension(); doesn't work in PHP < 5.3.7 $extension = pathinfo($file_info->getFilename(), PATHINFO_EXTENSION); if ($extension === 'txt' && $file_info->getMTime() < $oldest) { @unlink($file_info->getPathname()); } } } }