|
@@ -150,10 +150,10 @@ func (server *Server) Run() {
|
150
|
150
|
}
|
151
|
151
|
}
|
152
|
152
|
|
153
|
|
-func (server *Server) checkBans(ipaddr net.IP) (banned bool, message string) {
|
|
153
|
+func (server *Server) checkBans(config *Config, ipaddr net.IP, checkScripts bool) (banned bool, requireSASL bool, message string) {
|
154
|
154
|
if server.Defcon() == 1 {
|
155
|
155
|
if !(ipaddr.IsLoopback() || utils.IPInNets(ipaddr, server.Config().Server.secureNets)) {
|
156
|
|
- return true, "New connections to this server are temporarily restricted"
|
|
156
|
+ return true, false, "New connections to this server are temporarily restricted"
|
157
|
157
|
}
|
158
|
158
|
}
|
159
|
159
|
|
|
@@ -161,7 +161,7 @@ func (server *Server) checkBans(ipaddr net.IP) (banned bool, message string) {
|
161
|
161
|
isBanned, info := server.dlines.CheckIP(ipaddr)
|
162
|
162
|
if isBanned {
|
163
|
163
|
server.logger.Info("connect-ip", fmt.Sprintf("Client from %v rejected by d-line", ipaddr))
|
164
|
|
- return true, info.BanMessage("You are banned from this server (%s)")
|
|
164
|
+ return true, false, info.BanMessage("You are banned from this server (%s)")
|
165
|
165
|
}
|
166
|
166
|
|
167
|
167
|
// check connection limits
|
|
@@ -169,27 +169,55 @@ func (server *Server) checkBans(ipaddr net.IP) (banned bool, message string) {
|
169
|
169
|
if err == connection_limits.ErrLimitExceeded {
|
170
|
170
|
// too many connections from one client, tell the client and close the connection
|
171
|
171
|
server.logger.Info("connect-ip", fmt.Sprintf("Client from %v rejected for connection limit", ipaddr))
|
172
|
|
- return true, "Too many clients from your network"
|
|
172
|
+ return true, false, "Too many clients from your network"
|
173
|
173
|
} else if err == connection_limits.ErrThrottleExceeded {
|
174
|
|
- duration := server.Config().Server.IPLimits.BanDuration
|
175
|
|
- if duration == 0 {
|
176
|
|
- return false, ""
|
|
174
|
+ duration := config.Server.IPLimits.BanDuration
|
|
175
|
+ if duration != 0 {
|
|
176
|
+ server.dlines.AddIP(ipaddr, duration, throttleMessage,
|
|
177
|
+ "Exceeded automated connection throttle", "auto.connection.throttler")
|
|
178
|
+ // they're DLINE'd for 15 minutes or whatever, so we can reset the connection throttle now,
|
|
179
|
+ // and once their temporary DLINE is finished they can fill up the throttler again
|
|
180
|
+ server.connectionLimiter.ResetThrottle(ipaddr)
|
177
|
181
|
}
|
178
|
|
- server.dlines.AddIP(ipaddr, duration, throttleMessage, "Exceeded automated connection throttle", "auto.connection.throttler")
|
179
|
|
- // they're DLINE'd for 15 minutes or whatever, so we can reset the connection throttle now,
|
180
|
|
- // and once their temporary DLINE is finished they can fill up the throttler again
|
181
|
|
- server.connectionLimiter.ResetThrottle(ipaddr)
|
182
|
|
-
|
183
|
|
- // this might not show up properly on some clients, but our objective here is just to close it out before it has a load impact on us
|
184
|
182
|
server.logger.Info(
|
185
|
183
|
"connect-ip",
|
186
|
184
|
fmt.Sprintf("Client from %v exceeded connection throttle, d-lining for %v", ipaddr, duration))
|
187
|
|
- return true, throttleMessage
|
|
185
|
+ return true, false, throttleMessage
|
188
|
186
|
} else if err != nil {
|
189
|
187
|
server.logger.Warning("internal", "unexpected ban result", err.Error())
|
190
|
188
|
}
|
191
|
189
|
|
192
|
|
- return false, ""
|
|
190
|
+ if checkScripts && config.Server.IPCheckScript.Enabled {
|
|
191
|
+ output, err := CheckIPBan(server.semaphores.IPCheckScript, config.Server.IPCheckScript, ipaddr)
|
|
192
|
+ if err != nil {
|
|
193
|
+ server.logger.Error("internal", "couldn't check IP ban script", ipaddr.String(), err.Error())
|
|
194
|
+ return false, false, ""
|
|
195
|
+ }
|
|
196
|
+ // TODO: currently no way to cache results other than IPBanned
|
|
197
|
+ if output.Result == IPBanned && output.CacheSeconds != 0 {
|
|
198
|
+ network, err := utils.NormalizedNetFromString(output.CacheNet)
|
|
199
|
+ if err != nil {
|
|
200
|
+ server.logger.Error("internal", "invalid dline net from IP ban script", ipaddr.String(), output.CacheNet)
|
|
201
|
+ } else {
|
|
202
|
+ dlineDuration := time.Duration(output.CacheSeconds) * time.Second
|
|
203
|
+ err := server.dlines.AddNetwork(network, dlineDuration, output.BanMessage, "", "")
|
|
204
|
+ if err != nil {
|
|
205
|
+ server.logger.Error("internal", "couldn't set dline from IP ban script", ipaddr.String(), err.Error())
|
|
206
|
+ }
|
|
207
|
+ }
|
|
208
|
+ }
|
|
209
|
+ if output.Result == IPBanned {
|
|
210
|
+ // XXX roll back IP connection/throttling addition for the IP
|
|
211
|
+ server.connectionLimiter.RemoveClient(ipaddr)
|
|
212
|
+ server.logger.Info("connect-ip", "Rejected client due to ip-check-script", ipaddr.String())
|
|
213
|
+ return true, false, output.BanMessage
|
|
214
|
+ } else if output.Result == IPRequireSASL {
|
|
215
|
+ server.logger.Info("connect-ip", "Requiring SASL from client due to ip-check-script", ipaddr.String())
|
|
216
|
+ return false, true, ""
|
|
217
|
+ }
|
|
218
|
+ }
|
|
219
|
+
|
|
220
|
+ return false, false, ""
|
193
|
221
|
}
|
194
|
222
|
|
195
|
223
|
func (server *Server) checkTorLimits() (banned bool, message string) {
|
|
@@ -214,6 +242,12 @@ func (server *Server) tryRegister(c *Client, session *Session) (exiting bool) {
|
214
|
242
|
return // whether we succeeded or failed, either way `c` is not getting registered
|
215
|
243
|
}
|
216
|
244
|
|
|
245
|
+ // XXX PROXY or WEBIRC MUST be sent as the first line of the session;
|
|
246
|
+ // if we are here at all that means we have the final value of the IP
|
|
247
|
+ if session.rawHostname == "" {
|
|
248
|
+ session.client.lookupHostname(session, false)
|
|
249
|
+ }
|
|
250
|
+
|
217
|
251
|
// try to complete registration normally
|
218
|
252
|
// XXX(#1057) username can be filled in by an ident query without the client
|
219
|
253
|
// having sent USER: check for both username and realname to ensure they did
|
|
@@ -229,7 +263,7 @@ func (server *Server) tryRegister(c *Client, session *Session) (exiting bool) {
|
229
|
263
|
// client MUST send PASS if necessary, or authenticate with SASL if necessary,
|
230
|
264
|
// before completing the other registration commands
|
231
|
265
|
config := server.Config()
|
232
|
|
- authOutcome := c.isAuthorized(server, config, session)
|
|
266
|
+ authOutcome := c.isAuthorized(server, config, session, c.requireSASL)
|
233
|
267
|
var quitMessage string
|
234
|
268
|
switch authOutcome {
|
235
|
269
|
case authFailPass:
|
|
@@ -244,12 +278,6 @@ func (server *Server) tryRegister(c *Client, session *Session) (exiting bool) {
|
244
|
278
|
return true
|
245
|
279
|
}
|
246
|
280
|
|
247
|
|
- // we have the final value of the IP address: do the hostname lookup
|
248
|
|
- // (nickmask will be set below once nickname assignment succeeds)
|
249
|
|
- if session.rawHostname == "" {
|
250
|
|
- session.client.lookupHostname(session, false)
|
251
|
|
- }
|
252
|
|
-
|
253
|
281
|
rb := NewResponseBuffer(session)
|
254
|
282
|
nickError := performNickChange(server, c, c, session, c.preregNick, rb)
|
255
|
283
|
rb.Send(true)
|
|
@@ -489,6 +517,9 @@ func (server *Server) applyConfig(config *Config) (err error) {
|
489
|
517
|
return fmt.Errorf("Cannot enable or disable relaying after launching the server, rehash aborted")
|
490
|
518
|
} else if oldConfig.Server.Relaymsg.Separators != config.Server.Relaymsg.Separators {
|
491
|
519
|
return fmt.Errorf("Cannot change relaying separators after launching the server, rehash aborted")
|
|
520
|
+ } else if oldConfig.Server.IPCheckScript.MaxConcurrency != config.Server.IPCheckScript.MaxConcurrency ||
|
|
521
|
+ oldConfig.Accounts.AuthScript.MaxConcurrency != config.Accounts.AuthScript.MaxConcurrency {
|
|
522
|
+ return fmt.Errorf("Cannot change max-concurrency for scripts after launching the server, rehash aborted")
|
492
|
523
|
}
|
493
|
524
|
}
|
494
|
525
|
|
|
@@ -513,6 +544,17 @@ func (server *Server) applyConfig(config *Config) (err error) {
|
513
|
544
|
server.logger.Debug("server", "Regenerating HELP indexes for new languages")
|
514
|
545
|
server.helpIndexManager.GenerateIndices(config.languageManager)
|
515
|
546
|
|
|
547
|
+ if initial {
|
|
548
|
+ maxIPConc := int(config.Server.IPCheckScript.MaxConcurrency)
|
|
549
|
+ if maxIPConc != 0 {
|
|
550
|
+ server.semaphores.IPCheckScript.Initialize(maxIPConc)
|
|
551
|
+ }
|
|
552
|
+ maxAuthConc := int(config.Accounts.AuthScript.MaxConcurrency)
|
|
553
|
+ if maxAuthConc != 0 {
|
|
554
|
+ server.semaphores.AuthScript.Initialize(maxAuthConc)
|
|
555
|
+ }
|
|
556
|
+ }
|
|
557
|
+
|
516
|
558
|
if oldConfig != nil {
|
517
|
559
|
// if certain features were enabled by rehash, we need to load the corresponding data
|
518
|
560
|
// from the store
|