| Index: trunk/phase3/includes/DefaultSettings.php |
| — | — | @@ -3357,3 +3357,9 @@ |
| 3358 | 3358 | * ting this variable false. |
| 3359 | 3359 | */ |
| 3360 | 3360 | $wgUseAutomaticEditSummaries = true; |
| | 3361 | + |
| | 3362 | +/** |
| | 3363 | + * Limit password attempts to X attempts per Y seconds per IP per account. |
| | 3364 | + * Requires memcached. |
| | 3365 | + */ |
| | 3366 | +$wgPasswordAttemptThrottle = array( 5, 300 ); |
| \ No newline at end of file |
| Index: trunk/phase3/includes/specials/SpecialUserlogin.php |
| — | — | @@ -33,6 +33,7 @@ |
| 34 | 34 | const RESET_PASS = 7; |
| 35 | 35 | const ABORTED = 8; |
| 36 | 36 | const CREATE_BLOCKED = 9; |
| | 37 | + const THROTTLED = 10; |
| 37 | 38 | |
| 38 | 39 | var $mName, $mPassword, $mRetype, $mReturnTo, $mCookieCheck, $mPosted; |
| 39 | 40 | var $mAction, $mCreateaccount, $mCreateaccountMail, $mMailmypassword; |
| — | — | @@ -372,6 +373,23 @@ |
| 373 | 374 | if ( '' == $this->mName ) { |
| 374 | 375 | return self::NO_NAME; |
| 375 | 376 | } |
| | 377 | + |
| | 378 | + global $wgPasswordAttemptThrottle; |
| | 379 | + if (is_array($wgPasswordAttemptThrottle) && count($wgPasswordAttemptThrottle) >=2) { |
| | 380 | + list($count,$period) = $wgPasswordAttemptThrottle; |
| | 381 | + $key = wfMemcKey( 'password-throttle', wfGetIP(), $this->mName ); |
| | 382 | + |
| | 383 | + global $wgMemc; |
| | 384 | + $cur = $wgMemc->get($key); |
| | 385 | + if ($cur>0 && $cur<$count) { |
| | 386 | + $wgMemc->incr($key); |
| | 387 | + // Okay |
| | 388 | + } elseif ($cur>0) { |
| | 389 | + return self::THROTTLED; |
| | 390 | + } elseif (!$cur) { |
| | 391 | + $wgMemc->add( $key, 1, $period ); |
| | 392 | + } |
| | 393 | + } |
| 376 | 394 | |
| 377 | 395 | // Load $wgUser now, and check to see if we're logging in as the same name. |
| 378 | 396 | // This is necessary because loading $wgUser (say by calling getName()) calls |
| — | — | @@ -541,6 +559,9 @@ |
| 542 | 560 | case self::CREATE_BLOCKED: |
| 543 | 561 | $this->userBlockedMessage(); |
| 544 | 562 | break; |
| | 563 | + case self::THROTTLED: |
| | 564 | + $this->mainLoginForm( wfMsg( 'login-throttled' ) ); |
| | 565 | + break; |
| 545 | 566 | default: |
| 546 | 567 | throw new MWException( "Unhandled case value" ); |
| 547 | 568 | } |
| Index: trunk/phase3/languages/messages/MessagesEn.php |
| — | — | @@ -971,6 +971,7 @@ |
| 972 | 972 | You should log in and change your password now. |
| 973 | 973 | |
| 974 | 974 | You may ignore this message, if this account was created in error.', |
| | 975 | +'login-throttled' => "You have made too many recent attempts on this account's password. Please wait before trying again.", |
| 975 | 976 | 'loginlanguagelabel' => 'Language: $1', |
| 976 | 977 | 'loginlanguagelinks' => '* Deutsch|de |
| 977 | 978 | * English|en |
| Index: trunk/phase3/RELEASE-NOTES |
| — | — | @@ -79,6 +79,7 @@ |
| 80 | 80 | * (bug 15055) Talk page notifications no longer attempt to send mail when |
| 81 | 81 | user's e-mail address is invalid or unconfirmed |
| 82 | 82 | * (bug 2443) Add image name as alt-text when no caption is provided. |
| | 83 | +* (bug 12370) Add throttle on password attempts. Defaults to max 5 attempts in 5 minutes. |
| 83 | 84 | |
| 84 | 85 | === API changes in 1.14 === |
| 85 | 86 | |