public function onStartCheckPassword($nickname, $password, &$authenticatedUser) { if (common_is_email($nickname)) { $this->unauthed_user = User::getKV('email', common_canonical_email($nickname)); } else { $this->unauthed_user = User::getKV('nickname', Nickname::normalize($nickname)); } if (!$this->unauthed_user instanceof User) { // Unknown username continue processing StartCheckPassword (maybe uninitialized LDAP user etc?) return true; } $this->failed_attempts = (int) $this->unauthed_user->getPref(self::FAILED_LOGIN_IP_SECTION, $this->client_ip); switch (true) { case $this->failed_attempts >= 5: common_log(LOG_WARNING, sprintf('Multiple failed login attempts for user %s from IP %s - brute force attack?', $this->unauthed_user->getNickname(), $this->client_ip)); // 5 seconds is a good max waiting time anyway... sleep($this->failed_attempts % 5 + 1); break; case $this->failed_attempts > 0: common_debug(sprintf('Previously failed login on user %s from IP %s - sleeping %u seconds.', $this->unauthed_user->getNickname(), $this->client_ip, $this->failed_attempts)); sleep($this->failed_attempts); break; default: // No sleeping if it's our first failed attempt. } return true; }
/** * Check if a username exists and has matching password. */ function common_check_user($nickname, $password) { // empty nickname always unacceptable if (empty($nickname)) { return false; } $authenticatedUser = false; if (Event::handle('StartCheckPassword', array($nickname, $password, &$authenticatedUser))) { if (common_is_email($nickname)) { $user = User::staticGet('email', common_canonical_email($nickname)); } else { $user = User::staticGet('nickname', common_canonical_nickname($nickname)); } if (!empty($user)) { if (!empty($password)) { // never allow login with blank password if (0 == strcmp(common_munge_password($password, $user->id), $user->password)) { //internal checking passed $authenticatedUser = $user; } } } Event::handle('EndCheckPassword', array($nickname, $password, $authenticatedUser)); } return $authenticatedUser; }
/** * Check if a username exists and has matching password. */ function common_check_user($nickname, $password) { // empty nickname always unacceptable if (empty($nickname)) { return false; } $authenticatedUser = false; if (Event::handle('StartCheckPassword', array($nickname, $password, &$authenticatedUser))) { if (common_is_email($nickname)) { $user = User::getKV('email', common_canonical_email($nickname)); } else { $user = User::getKV('nickname', Nickname::normalize($nickname)); } if ($user instanceof User && !empty($password)) { if (0 == strcmp(common_munge_password($password, $user->getProfile()), $user->password)) { //internal checking passed $authenticatedUser = $user; } } } Event::handle('EndCheckPassword', array($nickname, $password, $authenticatedUser)); return $authenticatedUser; }
static function recoverPassword($nore) { // $confirm_email will be used as a fallback if our user doesn't have a confirmed email $confirm_email = null; if (common_is_email($nore)) { $user = User::getKV('email', common_canonical_email($nore)); // See if it's an unconfirmed email address if (!$user instanceof User) { // Warning: it may actually be legit to have multiple folks // who have claimed, but not yet confirmed, the same address. // We'll only send to the first one that comes up. $confirm_email = new Confirm_address(); $confirm_email->address = common_canonical_email($nore); $confirm_email->address_type = 'email'; if ($confirm_email->find(true)) { $user = User::getKV('id', $confirm_email->user_id); } } // No luck finding anyone by that email address. if (!$user instanceof User) { if (common_config('site', 'fakeaddressrecovery')) { // Return without actually doing anything! We fake address recovery // to avoid revealing which email addresses are registered with the site. return; } // TRANS: Information on password recovery form if no known e-mail address was specified. throw new ClientException(_('No user with that email address exists here.')); } } else { // This might throw a NicknameException on bad nicknames $user = User::getKV('nickname', common_canonical_nickname($nore)); if (!$user instanceof User) { // TRANS: Information on password recovery form if no known username was specified. throw new ClientException(_('No user with that nickname exists here.')); } } // Try to get an unconfirmed email address if they used a user name if (empty($user->email) && $confirm_email === null) { $confirm_email = new Confirm_address(); $confirm_email->user_id = $user->id; $confirm_email->address_type = 'email'; $confirm_email->find(); if (!$confirm_email->fetch()) { // Nothing found, so let's reset it to null $confirm_email = null; } } if (empty($user->email) && !$confirm_email instanceof Confirm_address) { // TRANS: Client error displayed on password recovery form if a user does not have a registered e-mail address. throw new ClientException(_('No registered email address for that user.')); } // Success! We have a valid user and a confirmed or unconfirmed email address $confirm = new Confirm_address(); $confirm->code = common_confirmation_code(128); $confirm->address_type = 'recover'; $confirm->user_id = $user->id; $confirm->address = $user->email ?: $confirm_email->address; if (!$confirm->insert()) { common_log_db_error($confirm, 'INSERT', __FILE__); // TRANS: Server error displayed if e-mail address confirmation fails in the database on the password recovery form. throw new ServerException(_('Error saving address confirmation.')); } // @todo FIXME: needs i18n. $body = "Hey, {$user->nickname}."; $body .= "\n\n"; $body .= 'Someone just asked for a new password ' . 'for this account on ' . common_config('site', 'name') . '.'; $body .= "\n\n"; $body .= 'If it was you, and you want to confirm, use the URL below:'; $body .= "\n\n"; $body .= "\t" . common_local_url('recoverpassword', array('code' => $confirm->code)); $body .= "\n\n"; $body .= 'If not, just ignore this message.'; $body .= "\n\n"; $body .= 'Thanks for your time, '; $body .= "\n"; $body .= common_config('site', 'name'); $body .= "\n"; $headers = _mail_prepare_headers('recoverpassword', $user->nickname, $user->nickname); // TRANS: Subject for password recovery e-mail. mail_to_user($user, _('Password recovery requested'), $body, $headers, $confirm->address); }
function recoverPassword() { $nore = $this->trimmed('nicknameoremail'); if (!$nore) { // TRANS: Form instructions for password recovery form. $this->showForm(_('Enter a nickname or email address.')); return; } try { User::recoverPassword($nore); $this->mode = 'sent'; if (common_is_email($nore) && common_config('site', 'fakeaddressrecovery')) { // TRANS: User notification when recovering password by giving email address, // regardless if the mail was sent or not (to hide registered email status). $this->msg = _('If the email address you provided was found in the database, a recovery mail with instructions has been sent there.'); } else { // TRANS: User notification after an e-mail with instructions was sent from the password recovery form. $this->msg = _('Instructions for recovering your password ' . 'have been sent to the email address registered to your ' . 'account.'); } $this->success = true; } catch (Exception $e) { $this->success = false; $this->msg = $e->getMessage(); } $this->showPage(); }