diff --git a/html/inc/util.inc b/html/inc/util.inc index 46c48cfd84..6bea3280c8 100644 --- a/html/inc/util.inc +++ b/html/inc/util.inc @@ -72,6 +72,11 @@ if (!defined('LDAP_HOST')) { define('LDAP_HOST', null); } +// sleep this long on any login failure +// (slow the rate of hacker attacks) +// +define('LOGIN_FAIL_SLEEP_SEC', 5); + $caching = false; // if set, we're writing to a file rather than to client $did_page_head = false; diff --git a/html/user/login_action.php b/html/user/login_action.php index 57c4cceff7..5383bff9cb 100644 --- a/html/user/login_action.php +++ b/html/user/login_action.php @@ -36,6 +36,7 @@ check_get_args(array("id", "t", "h", "key")); function login_with_email($email_addr, $passwd, $next_url, $perm) { $user = BoincUser::lookup_email_addr($email_addr); if (!$user) { + sleep(LOGIN_FAIL_SLEEP_SEC); page_head("No such account"); echo "No account with email address $email_addr exists. Please go back and try again. @@ -44,12 +45,14 @@ function login_with_email($email_addr, $passwd, $next_url, $perm) { exit; } if (substr($user->authenticator, 0, 1) == 'x'){ + sleep(LOGIN_FAIL_SLEEP_SEC); error_page("This account has been administratively disabled."); } // allow authenticator as password if ($passwd != $user->authenticator) { $passwd_hash = md5($passwd.$email_addr); if ($passwd_hash != $user->passwd_hash) { + sleep(LOGIN_FAIL_SLEEP_SEC); page_head("Password incorrect"); echo "The password you entered is incorrect. Please go back and try again.\n"; page_tail(); @@ -66,6 +69,7 @@ function login_with_email($email_addr, $passwd, $next_url, $perm) { function login_via_link($id, $t, $h) { $user = BoincUser::lookup_id($id); if (!$user) { + sleep(LOGIN_FAIL_SLEEP_SEC); error_page("Invalid user ID. Please make sure you visited the complete URL; it may have been split across lines by your email reader." @@ -75,12 +79,14 @@ function login_via_link($id, $t, $h) { $x = md5($x); $x = substr($x, 0, 16); if ($x != $h) { + sleep(LOGIN_FAIL_SLEEP_SEC); error_page("Invalid authenticator. Please make sure you visited the complete URL; it may have been split across lines by your email reader." ); } if (time() - $t > 86400) { + sleep(LOGIN_FAIL_SLEEP_SEC); error_page("Link has expired; go here to get a new login link by email." @@ -93,12 +99,14 @@ function login_via_link($id, $t, $h) { function login_with_auth($authenticator, $next_url, $perm) { $user = BoincUser::lookup_auth($authenticator); if (!$user) { + sleep(LOGIN_FAIL_SLEEP_SEC); page_head("Login failed"); echo "There is no account with that authenticator. Please try again. "; page_tail(); } else if (substr($user->authenticator, 0, 1) == 'x'){ + sleep(LOGIN_FAIL_SLEEP_SEC); error_page("This account has been administratively disabled."); } else { Header("Location: $next_url"); @@ -109,6 +117,7 @@ function login_with_auth($authenticator, $next_url, $perm) { function login_with_ldap($uid, $passwd, $next_url, $perm) { list ($ldap_user, $error_msg) = ldap_auth($uid, $passwd); if ($error_msg) { + sleep(LOGIN_FAIL_SLEEP_SEC); error_page($error_msg); } $x = ldap_email_string($uid); diff --git a/html/user/lookup_account.php b/html/user/lookup_account.php index 67e53c6613..eb52987b01 100644 --- a/html/user/lookup_account.php +++ b/html/user/lookup_account.php @@ -37,6 +37,7 @@ if (LDAP_HOST && $ldap_auth) { $passwd = get_str("passwd"); list ($ldap_user, $error_msg) = ldap_auth($ldap_uid, $passwd); if ($error_msg) { + sleep(LOGIN_FAIL_SLEEP_SEC); xml_error(ERR_BAD_USER_NAME, $error_msg); } $x = ldap_email_string($ldap_uid); @@ -55,6 +56,7 @@ if (LDAP_HOST && $ldap_auth) { $email_addr = BoincDb::escape_string($email_addr); $user = BoincUser::lookup("email_addr='$email_addr'"); if (!$user) { + sleep(LOGIN_FAIL_SLEEP_SEC); xml_error(ERR_DB_NOT_FOUND); } @@ -77,6 +79,7 @@ if (LDAP_HOST && $ldap_auth) { // if the given password hash matches (auth+email), accept it // if ($user->passwd_hash != $passwd_hash && $auth_hash != $passwd_hash) { + sleep(LOGIN_FAIL_SLEEP_SEC); xml_error(ERR_BAD_PASSWD); } }