/** * Check for whether a login and pass match uname/active_email and hash, respectively. * * @return Array|boolean */ function authenticate($dirty_login, $p_pass, $limit_login_attempts = true) { $login = strtolower(sanitize_to_text((string) $dirty_login)); $recent_login_failure = false; $pass = (string) $p_pass; if ($limit_login_attempts) { $recent_login_failure = last_login_failure_was_recent(potential_account_id_from_login_username($login)); } if ($login != '' && $pass != '' && !$recent_login_failure) { // Allow login via username or email. // Pull the account data regardless of whether the password matches, but create an int about whether it does match or not. // matches login string against active_email or username. $sql = "SELECT account_id, account_identity, uname, player_id, accounts.confirmed as confirmed,\n\t\t CASE WHEN phash = crypt(:pass, phash) THEN 1 ELSE 0 END AS authenticated,\n\t\t CASE WHEN accounts.operational THEN 1 ELSE 0 END AS operational\n\t\t\tFROM accounts\n\t\t\tJOIN account_players ON account_id = _account_id\n\t\t\tJOIN players ON player_id = _player_id\n\t\t\tWHERE (active_email = :login\n\t\t\t\t\tOR lower(uname) = :login)"; $result = query($sql, [':login' => $login, ':pass' => $pass]); if ($result->rowCount() < 1) { // *** No record was found, user does not exist *** update_last_login_failure(potential_account_id_from_login_username($login)); return false; } else { if ($result->rowCount() > 1) { // Just for later reference, check for duplicate usernames via: //select array_accum(uname), count(*) from players group by lower(trim(uname)) having count(*) > 1; error_log('Case-insensitive duplicate username found: ' . $login); } return $result->fetch(); // Success, return results. } } else { // Update the last login failure timestamp. update_last_login_failure(potential_account_id_from_login_username($login)); return false; } }
/** * Simply store whatever authentication info is passed in. */ public static function store_auth_attempt($info) { // Simply log the attempts in the database. $additional_info = null; if ($info['additional_info']) { // Encode all the info from $_SERVER, for now. $additional_info = json_encode($info['additional_info']); } if (!$info['successful']) { // Update last login failure. update_last_login_failure(potential_account_id_from_login_username($info['username'])); } // Log the login attempt as well. query("insert into login_attempts (username, ua_string, ip, successful, additional_info) values (:username, :user_agent, :ip, :successful, :additional_info)", array(':username' => $info['username'], ':user_agent' => $info['user_agent'], ':ip' => $info['ip'], ':successful' => $info['successful'], ':additional_info' => $additional_info)); }