Browse Source

fix login throttle handling

We were checking the login throttle at the beginning of every SASL
conversation. This had several problems:

1. Pidgin (on Windows?) tries every mechanism in order, regardless of
the CAP advertisement. It would use up the default throttle allowance
trying unsupported mechanisms like CRAM-MD5.
2. The throttle was actually checked twice for AUTHENTICATE PLAIN
(once at the start of the conversation and once in AuthenticateByPassphrase).

The general pattern here is that we should check the throttle every time we
do something "expensive" (bcrypt verification, send a reset email) or
"dangerous" (anything that could lead to a bruteforce attack on passwords).
Therefore, delete the check from the AUTHENTICATE handler, and add one at
the beginning of the SCRAM conversation to replace it.
tags/v2.14.0-rc1
Shivaram Lingamneni 1 month ago
parent
commit
218f6f2454
1 changed files with 6 additions and 7 deletions
  1. 6
    7
      irc/handlers.go

+ 6
- 7
irc/handlers.go View File

@@ -207,13 +207,6 @@ func authenticateHandler(server *Server, client *Client, msg ircmsg.Message, rb
207 207
 
208 208
 	// start new sasl session: parameter is the authentication mechanism
209 209
 	if session.sasl.mechanism == "" {
210
-		throttled, remainingTime := client.loginThrottle.Touch()
211
-		if throttled {
212
-			rb.Add(nil, server.name, ERR_SASLFAIL, client.Nick(),
213
-				fmt.Sprintf(client.t("Please wait at least %v and try again"), remainingTime.Round(time.Millisecond)))
214
-			return false
215
-		}
216
-
217 210
 		mechanism := strings.ToUpper(msg.Params[0])
218 211
 		_, mechanismIsEnabled := EnabledSaslMechanisms[mechanism]
219 212
 
@@ -384,6 +377,12 @@ func authScramHandler(server *Server, client *Client, session *Session, value []
384 377
 
385 378
 	// first message? if so, initialize the SCRAM conversation
386 379
 	if session.sasl.scramConv == nil {
380
+		if throttled, remainingTime := client.checkLoginThrottle(); throttled {
381
+			rb.Add(nil, server.name, ERR_SASLFAIL, client.Nick(),
382
+				fmt.Sprintf(client.t("Please wait at least %v and try again"), remainingTime.Round(time.Millisecond)))
383
+			continueAuth = false
384
+			return false
385
+		}
387 386
 		session.sasl.scramConv = server.accounts.NewScramConversation()
388 387
 	}
389 388
 

Loading…
Cancel
Save