Skip to content

Commit

Permalink
fix login throttle handling
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
slingamn committed May 26, 2024
1 parent ca4b9c1 commit 218f6f2
Showing 1 changed file with 6 additions and 7 deletions.
13 changes: 6 additions & 7 deletions irc/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,6 @@ func authenticateHandler(server *Server, client *Client, msg ircmsg.Message, rb

// start new sasl session: parameter is the authentication mechanism
if session.sasl.mechanism == "" {
throttled, remainingTime := client.loginThrottle.Touch()
if throttled {
rb.Add(nil, server.name, ERR_SASLFAIL, client.Nick(),
fmt.Sprintf(client.t("Please wait at least %v and try again"), remainingTime.Round(time.Millisecond)))
return false
}

mechanism := strings.ToUpper(msg.Params[0])
_, mechanismIsEnabled := EnabledSaslMechanisms[mechanism]

Expand Down Expand Up @@ -384,6 +377,12 @@ func authScramHandler(server *Server, client *Client, session *Session, value []

// first message? if so, initialize the SCRAM conversation
if session.sasl.scramConv == nil {
if throttled, remainingTime := client.checkLoginThrottle(); throttled {
rb.Add(nil, server.name, ERR_SASLFAIL, client.Nick(),
fmt.Sprintf(client.t("Please wait at least %v and try again"), remainingTime.Round(time.Millisecond)))
continueAuth = false
return false
}
session.sasl.scramConv = server.accounts.NewScramConversation()
}

Expand Down

0 comments on commit 218f6f2

Please sign in to comment.