Преглед на файлове

tweaks to UBAN

tags/v2.5.0-rc1
Shivaram Lingamneni преди 3 години
родител
ревизия
8dd39a6e71
променени са 4 файла, в които са добавени 38 реда и са изтрити 30 реда
  1. 20
    10
      irc/connection_limits/limiter.go
  2. 3
    3
      irc/connection_limits/limiter_test.go
  3. 0
    8
      irc/help.go
  4. 15
    9
      irc/uban.go

+ 20
- 10
irc/connection_limits/limiter.go Целия файл

@@ -28,6 +28,7 @@ type CustomLimitConfig struct {
28 28
 // tuples the key-value pair of a CIDR and its custom limit/throttle values
29 29
 type customLimit struct {
30 30
 	name          [16]byte
31
+	customID      string // operator-configured identifier for a custom net
31 32
 	maxConcurrent int
32 33
 	maxPerWindow  int
33 34
 	nets          []flatip.IPNet
@@ -103,6 +104,7 @@ func (config *LimiterConfig) postprocess() (err error) {
103 104
 			maxConcurrent: customLimitConf.MaxConcurrent,
104 105
 			maxPerWindow:  customLimitConf.MaxPerWindow,
105 106
 			name:          md5.Sum([]byte(identifier)),
107
+			customID:      identifier,
106 108
 			nets:          nets,
107 109
 		})
108 110
 	}
@@ -124,11 +126,11 @@ type Limiter struct {
124 126
 
125 127
 // addrToKey canonicalizes `addr` to a string key, and returns
126 128
 // the relevant connection limit and throttle max-per-window values
127
-func (cl *Limiter) addrToKey(addr flatip.IP) (key limiterKey, limit int, throttle int) {
129
+func (cl *Limiter) addrToKey(addr flatip.IP) (key limiterKey, customID string, limit int, throttle int) {
128 130
 	for _, custom := range cl.config.customLimits {
129 131
 		for _, net := range custom.nets {
130 132
 			if net.Contains(addr) {
131
-				return limiterKey{maskedIP: custom.name, prefixLen: 0}, custom.maxConcurrent, custom.maxPerWindow
133
+				return limiterKey{maskedIP: custom.name, prefixLen: 0}, custom.customID, custom.maxConcurrent, custom.maxPerWindow
132 134
 			}
133 135
 		}
134 136
 	}
@@ -143,7 +145,7 @@ func (cl *Limiter) addrToKey(addr flatip.IP) (key limiterKey, limit int, throttl
143 145
 		addr = addr.Mask(prefixLen, 128)
144 146
 	}
145 147
 
146
-	return limiterKey{maskedIP: addr, prefixLen: uint8(prefixLen)}, cl.config.MaxConcurrent, cl.config.MaxPerWindow
148
+	return limiterKey{maskedIP: addr, prefixLen: uint8(prefixLen)}, "", cl.config.MaxConcurrent, cl.config.MaxPerWindow
147 149
 }
148 150
 
149 151
 // AddClient adds a client to our population if possible. If we can't, throws an error instead.
@@ -156,7 +158,7 @@ func (cl *Limiter) AddClient(addr flatip.IP) error {
156 158
 		return nil
157 159
 	}
158 160
 
159
-	addrString, maxConcurrent, maxPerWindow := cl.addrToKey(addr)
161
+	addrString, _, maxConcurrent, maxPerWindow := cl.addrToKey(addr)
160 162
 
161 163
 	// check limiter
162 164
 	var count int
@@ -200,7 +202,7 @@ func (cl *Limiter) RemoveClient(addr flatip.IP) {
200 202
 		return
201 203
 	}
202 204
 
203
-	addrString, _, _ := cl.addrToKey(addr)
205
+	addrString, _, _, _ := cl.addrToKey(addr)
204 206
 	count := cl.limiter[addrString]
205 207
 	count -= 1
206 208
 	if count < 0 {
@@ -220,7 +222,7 @@ type LimiterStatus struct {
220 222
 	ThrottleDuration time.Duration
221 223
 }
222 224
 
223
-func (cl *Limiter) Status(addr flatip.IP) (status LimiterStatus) {
225
+func (cl *Limiter) Status(addr flatip.IP) (netName string, status LimiterStatus) {
224 226
 	cl.Lock()
225 227
 	defer cl.Unlock()
226 228
 
@@ -231,12 +233,20 @@ func (cl *Limiter) Status(addr flatip.IP) (status LimiterStatus) {
231 233
 
232 234
 	status.ThrottleDuration = cl.config.Window
233 235
 
234
-	addrString, maxConcurrent, maxPerWindow := cl.addrToKey(addr)
236
+	limiterKey, customID, maxConcurrent, maxPerWindow := cl.addrToKey(addr)
235 237
 	status.MaxCount = maxConcurrent
236 238
 	status.MaxPerWindow = maxPerWindow
237 239
 
238
-	status.Count = cl.limiter[addrString]
239
-	status.Throttle = cl.throttler[addrString].Count
240
+	status.Count = cl.limiter[limiterKey]
241
+	status.Throttle = cl.throttler[limiterKey].Count
242
+
243
+	netName = customID
244
+	if netName == "" {
245
+		netName = flatip.IPNet{
246
+			IP:        limiterKey.maskedIP,
247
+			PrefixLen: limiterKey.prefixLen,
248
+		}.String()
249
+	}
240 250
 
241 251
 	return
242 252
 }
@@ -250,7 +260,7 @@ func (cl *Limiter) ResetThrottle(addr flatip.IP) {
250 260
 		return
251 261
 	}
252 262
 
253
-	addrString, _, _ := cl.addrToKey(addr)
263
+	addrString, _, _, _ := cl.addrToKey(addr)
254 264
 	delete(cl.throttler, addrString)
255 265
 }
256 266
 

+ 3
- 3
irc/connection_limits/limiter_test.go Целия файл

@@ -50,20 +50,20 @@ func TestKeying(t *testing.T) {
50 50
 	limiter.ApplyConfig(&config)
51 51
 
52 52
 	// an ipv4 /32 looks like a /128 to us after applying the 4-in-6 mapping
53
-	key, maxConc, maxWin := limiter.addrToKey(easyParseIP("1.1.1.1"))
53
+	key, _, maxConc, maxWin := limiter.addrToKey(easyParseIP("1.1.1.1"))
54 54
 	assertEqual(key.prefixLen, uint8(128), t)
55 55
 	assertEqual(key.maskedIP[12:], []byte{1, 1, 1, 1}, t)
56 56
 	assertEqual(maxConc, 4, t)
57 57
 	assertEqual(maxWin, 8, t)
58 58
 
59 59
 	testIPv6 := easyParseIP("2607:5301:201:3100::7426")
60
-	key, maxConc, maxWin = limiter.addrToKey(testIPv6)
60
+	key, _, maxConc, maxWin = limiter.addrToKey(testIPv6)
61 61
 	assertEqual(key.prefixLen, uint8(64), t)
62 62
 	assertEqual(flatip.IP(key.maskedIP), easyParseIP("2607:5301:201:3100::"), t)
63 63
 	assertEqual(maxConc, 4, t)
64 64
 	assertEqual(maxWin, 8, t)
65 65
 
66
-	key, maxConc, maxWin = limiter.addrToKey(easyParseIP("8.8.4.4"))
66
+	key, _, maxConc, maxWin = limiter.addrToKey(easyParseIP("8.8.4.4"))
67 67
 	assertEqual(key.prefixLen, uint8(0), t)
68 68
 	assertEqual([16]byte(key.maskedIP), md5.Sum([]byte("google")), t)
69 69
 	assertEqual(maxConc, 128, t)

+ 0
- 8
irc/help.go Целия файл

@@ -107,14 +107,6 @@ For instance, this would set the kill, oper, account and xline snomasks on dan:
107 107
 // Help contains the help strings distributed with the IRCd.
108 108
 var Help = map[string]HelpEntry{
109 109
 	// Commands
110
-	"acc": {
111
-		text: `ACC LS
112
-ACC REGISTER <accountname> [callback_namespace:]<callback> [cred_type] :<credential>
113
-ACC VERIFY <accountname> <auth_code>
114
-
115
-Used in account registration. See the relevant specs for more info:
116
-https://oragono.io/specs.html`,
117
-	},
118 110
 	"ambiance": {
119 111
 		text: `AMBIANCE <target> <text to be sent>
120 112
 

+ 15
- 9
irc/uban.go Целия файл

@@ -303,13 +303,12 @@ func ubanInfoHandler(client *Client, target ubanTarget, params []string, rb *Res
303 303
 
304 304
 func ubanInfoCIDR(client *Client, target ubanTarget, rb *ResponseBuffer) {
305 305
 	if target.cidr.PrefixLen == 128 {
306
-		status := client.server.connectionLimiter.Status(target.cidr.IP)
307
-		str := target.cidr.IP.String()
306
+		netName, status := client.server.connectionLimiter.Status(target.cidr.IP)
308 307
 		if status.Exempt {
309
-			rb.Notice(fmt.Sprintf(client.t("IP %s is exempt from connection limits"), str))
308
+			rb.Notice(fmt.Sprintf(client.t("IP %s is exempt from connection limits"), target.cidr.IP.String()))
310 309
 		} else {
311
-			rb.Notice(fmt.Sprintf(client.t("IP %[1]s has %[2]d active connections out of a maximum of %[3]d"), str, status.Count, status.MaxCount))
312
-			rb.Notice(fmt.Sprintf(client.t("IP %[1]s has had %[2]d connection attempts in the past %[3]v, out of a maximum of %[4]d"), str, status.Throttle, status.ThrottleDuration, status.MaxPerWindow))
310
+			rb.Notice(fmt.Sprintf(client.t("Network %[1]s has %[2]d active connections out of a maximum of %[3]d"), netName, status.Count, status.MaxCount))
311
+			rb.Notice(fmt.Sprintf(client.t("Network %[1]s has had %[2]d connection attempts in the past %[3]v, out of a maximum of %[4]d"), netName, status.Throttle, status.ThrottleDuration, status.MaxPerWindow))
313 312
 		}
314 313
 	}
315 314
 
@@ -364,15 +363,22 @@ func ubanInfoNick(client *Client, target ubanTarget, rb *ResponseBuffer) {
364 363
 	mcl := client.server.clients.Get(target.nickOrMask)
365 364
 	if mcl != nil {
366 365
 		details := mcl.Details()
366
+		sessions := mcl.Sessions()
367
+		ip := mcl.IP()
368
+		sendIPBanWarning := false
367 369
 		if details.account == "" {
368
-			rb.Notice(fmt.Sprintf(client.t("Client %[1]s is unauthenticated and connected from %[2]s"), details.nick, mcl.IP().String()))
370
+			rb.Notice(fmt.Sprintf(client.t("Client %[1]s is unauthenticated and connected from %[2]s"), details.nick, ip.String()))
371
+			sendIPBanWarning = true
369 372
 		} else {
370 373
 			rb.Notice(fmt.Sprintf(client.t("Client %[1]s is logged into account %[2]s and has %[3]d active clients (see /NICKSERV CLIENTS LIST %[4]s for more info"), details.nick, details.accountName, len(mcl.Sessions()), details.nick))
371
-			ip := mcl.IP()
372
-			if !ip.IsLoopback() {
373
-				rb.Notice(fmt.Sprintf(client.t("Client %[1]s is associated with IP %[2]s; you can ban this IP with /UBAN ADD"), details.nick, ip.String()))
374
+			if !ip.IsLoopback() && len(sessions) == 1 {
375
+				rb.Notice(fmt.Sprintf(client.t("Client %[1]s is associated with IP %[2]s"), details.nick, ip.String()))
376
+				sendIPBanWarning = true
374 377
 			}
375 378
 		}
379
+		if sendIPBanWarning {
380
+			rb.Notice(client.t("Warning: banning this IP or a network that contains it may affect other users. Use /UBAN INFO on the candidate IP or network for more information."))
381
+		}
376 382
 	} else {
377 383
 		rb.Notice(fmt.Sprintf(client.t("No client is currently using that nickname")))
378 384
 	}

Loading…
Отказ
Запис