|
@@ -112,6 +112,7 @@ func sendSuccessfulAccountAuth(client *Client, rb *ResponseBuffer, forNS, forSAS
|
112
|
112
|
|
113
|
113
|
// AUTHENTICATE [<mechanism>|<data>|*]
|
114
|
114
|
func authenticateHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
|
115
|
+ session := rb.session
|
115
|
116
|
config := server.Config()
|
116
|
117
|
details := client.Details()
|
117
|
118
|
|
|
@@ -128,20 +129,17 @@ func authenticateHandler(server *Server, client *Client, msg ircmsg.IrcMessage,
|
128
|
129
|
// sasl abort
|
129
|
130
|
if !server.AccountConfig().AuthenticationEnabled || len(msg.Params) == 1 && msg.Params[0] == "*" {
|
130
|
131
|
rb.Add(nil, server.name, ERR_SASLABORTED, details.nick, client.t("SASL authentication aborted"))
|
131
|
|
- client.saslInProgress = false
|
132
|
|
- client.saslMechanism = ""
|
133
|
|
- client.saslValue = ""
|
|
132
|
+ session.sasl.Clear()
|
134
|
133
|
return false
|
135
|
134
|
}
|
136
|
135
|
|
137
|
136
|
// start new sasl session
|
138
|
|
- if !client.saslInProgress {
|
|
137
|
+ if session.sasl.mechanism == "" {
|
139
|
138
|
mechanism := strings.ToUpper(msg.Params[0])
|
140
|
139
|
_, mechanismIsEnabled := EnabledSaslMechanisms[mechanism]
|
141
|
140
|
|
142
|
141
|
if mechanismIsEnabled {
|
143
|
|
- client.saslInProgress = true
|
144
|
|
- client.saslMechanism = mechanism
|
|
142
|
+ session.sasl.mechanism = mechanism
|
145
|
143
|
if !config.Server.Compatibility.SendUnprefixedSasl {
|
146
|
144
|
// normal behavior
|
147
|
145
|
rb.Add(nil, server.name, "AUTHENTICATE", "+")
|
|
@@ -162,58 +160,46 @@ func authenticateHandler(server *Server, client *Client, msg ircmsg.IrcMessage,
|
162
|
160
|
|
163
|
161
|
if len(rawData) > 400 {
|
164
|
162
|
rb.Add(nil, server.name, ERR_SASLTOOLONG, details.nick, client.t("SASL message too long"))
|
165
|
|
- client.saslInProgress = false
|
166
|
|
- client.saslMechanism = ""
|
167
|
|
- client.saslValue = ""
|
|
163
|
+ session.sasl.Clear()
|
168
|
164
|
return false
|
169
|
165
|
} else if len(rawData) == 400 {
|
170
|
|
- client.saslValue += rawData
|
171
|
166
|
// allow 4 'continuation' lines before rejecting for length
|
172
|
|
- if len(client.saslValue) > 400*4 {
|
|
167
|
+ if len(session.sasl.value) >= 400*4 {
|
173
|
168
|
rb.Add(nil, server.name, ERR_SASLFAIL, details.nick, client.t("SASL authentication failed: Passphrase too long"))
|
174
|
|
- client.saslInProgress = false
|
175
|
|
- client.saslMechanism = ""
|
176
|
|
- client.saslValue = ""
|
|
169
|
+ session.sasl.Clear()
|
177
|
170
|
return false
|
178
|
171
|
}
|
|
172
|
+ session.sasl.value += rawData
|
179
|
173
|
return false
|
180
|
174
|
}
|
181
|
175
|
if rawData != "+" {
|
182
|
|
- client.saslValue += rawData
|
|
176
|
+ session.sasl.value += rawData
|
183
|
177
|
}
|
184
|
178
|
|
185
|
179
|
var data []byte
|
186
|
180
|
var err error
|
187
|
|
- if client.saslValue != "+" {
|
188
|
|
- data, err = base64.StdEncoding.DecodeString(client.saslValue)
|
|
181
|
+ if session.sasl.value != "+" {
|
|
182
|
+ data, err = base64.StdEncoding.DecodeString(session.sasl.value)
|
189
|
183
|
if err != nil {
|
190
|
184
|
rb.Add(nil, server.name, ERR_SASLFAIL, details.nick, client.t("SASL authentication failed: Invalid b64 encoding"))
|
191
|
|
- client.saslInProgress = false
|
192
|
|
- client.saslMechanism = ""
|
193
|
|
- client.saslValue = ""
|
|
185
|
+ session.sasl.Clear()
|
194
|
186
|
return false
|
195
|
187
|
}
|
196
|
188
|
}
|
197
|
189
|
|
198
|
190
|
// call actual handler
|
199
|
|
- handler, handlerExists := EnabledSaslMechanisms[client.saslMechanism]
|
|
191
|
+ handler, handlerExists := EnabledSaslMechanisms[session.sasl.mechanism]
|
200
|
192
|
|
201
|
193
|
// like 100% not required, but it's good to be safe I guess
|
202
|
194
|
if !handlerExists {
|
203
|
195
|
rb.Add(nil, server.name, ERR_SASLFAIL, details.nick, client.t("SASL authentication failed"))
|
204
|
|
- client.saslInProgress = false
|
205
|
|
- client.saslMechanism = ""
|
206
|
|
- client.saslValue = ""
|
|
196
|
+ session.sasl.Clear()
|
207
|
197
|
return false
|
208
|
198
|
}
|
209
|
199
|
|
210
|
200
|
// let the SASL handler do its thing
|
211
|
|
- exiting := handler(server, client, client.saslMechanism, data, rb)
|
212
|
|
-
|
213
|
|
- // wait 'til SASL is done before emptying the sasl vars
|
214
|
|
- client.saslInProgress = false
|
215
|
|
- client.saslMechanism = ""
|
216
|
|
- client.saslValue = ""
|
|
201
|
+ exiting := handler(server, client, session.sasl.mechanism, data, rb)
|
|
202
|
+ session.sasl.Clear()
|
217
|
203
|
|
218
|
204
|
return exiting
|
219
|
205
|
}
|
|
@@ -270,7 +256,7 @@ func authErrorToMessage(server *Server, err error) (msg string) {
|
270
|
256
|
|
271
|
257
|
// AUTHENTICATE EXTERNAL
|
272
|
258
|
func authExternalHandler(server *Server, client *Client, mechanism string, value []byte, rb *ResponseBuffer) bool {
|
273
|
|
- if client.certfp == "" {
|
|
259
|
+ if rb.session.certfp == "" {
|
274
|
260
|
rb.Add(nil, server.name, ERR_SASLFAIL, client.nick, client.t("SASL authentication failed, you are not connecting with a certificate"))
|
275
|
261
|
return false
|
276
|
262
|
}
|
|
@@ -287,7 +273,7 @@ func authExternalHandler(server *Server, client *Client, mechanism string, value
|
287
|
273
|
}
|
288
|
274
|
|
289
|
275
|
if err == nil {
|
290
|
|
- err = server.accounts.AuthenticateByCertFP(client, authzid)
|
|
276
|
+ err = server.accounts.AuthenticateByCertFP(client, rb.session.certfp, authzid)
|
291
|
277
|
}
|
292
|
278
|
|
293
|
279
|
if err != nil {
|
|
@@ -2055,7 +2041,7 @@ func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
|
2055
|
2041
|
oper := server.GetOperator(msg.Params[0])
|
2056
|
2042
|
if oper != nil {
|
2057
|
2043
|
if oper.Fingerprint != "" {
|
2058
|
|
- if oper.Fingerprint == client.certfp {
|
|
2044
|
+ if oper.Fingerprint == rb.session.certfp {
|
2059
|
2045
|
checkPassed = true
|
2060
|
2046
|
} else {
|
2061
|
2047
|
checkFailed = true
|
|
@@ -2144,7 +2130,7 @@ func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
|
2144
|
2130
|
|
2145
|
2131
|
// check the provided password
|
2146
|
2132
|
password := []byte(msg.Params[0])
|
2147
|
|
- client.sentPassCommand = bcrypt.CompareHashAndPassword(serverPassword, password) == nil
|
|
2133
|
+ rb.session.sentPassCommand = bcrypt.CompareHashAndPassword(serverPassword, password) == nil
|
2148
|
2134
|
|
2149
|
2135
|
// if they failed the check, we'll bounce them later when they try to complete registration
|
2150
|
2136
|
return false
|
|
@@ -2523,7 +2509,7 @@ func webircHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
|
2523
|
2509
|
if 0 < len(info.Password) && bcrypt.CompareHashAndPassword(info.Password, givenPassword) != nil {
|
2524
|
2510
|
continue
|
2525
|
2511
|
}
|
2526
|
|
- if info.Fingerprint != "" && info.Fingerprint != client.certfp {
|
|
2512
|
+ if info.Fingerprint != "" && info.Fingerprint != rb.session.certfp {
|
2527
|
2513
|
continue
|
2528
|
2514
|
}
|
2529
|
2515
|
|