Shivaram Lingamneni 4 anni fa
parent
commit
938ce7e435
4 ha cambiato i file con 100 aggiunte e 36 eliminazioni
  1. 1
    15
      irc/client_lookup_set.go
  2. 22
    21
      irc/handlers.go
  3. 53
    0
      irc/strings.go
  4. 24
    0
      irc/strings_test.go

+ 1
- 15
irc/client_lookup_set.go Vedi File

@@ -18,20 +18,6 @@ import (
18 18
 	"sync"
19 19
 )
20 20
 
21
-// ExpandUserHost takes a userhost, and returns an expanded version.
22
-func ExpandUserHost(userhost string) (expanded string) {
23
-	expanded = userhost
24
-	// fill in missing wildcards for nicks
25
-	//TODO(dan): this would fail with dan@lol, fix that.
26
-	if !strings.Contains(expanded, "!") {
27
-		expanded += "!*"
28
-	}
29
-	if !strings.Contains(expanded, "@") {
30
-		expanded += "@*"
31
-	}
32
-	return
33
-}
34
-
35 21
 // ClientManager keeps track of clients by nick, enforcing uniqueness of casefolded nicks
36 22
 type ClientManager struct {
37 23
 	sync.RWMutex // tier 2
@@ -241,7 +227,7 @@ func (clients *ClientManager) AllWithCapsNotify(capabs ...caps.Capability) (sess
241 227
 func (clients *ClientManager) FindAll(userhost string) (set ClientSet) {
242 228
 	set = make(ClientSet)
243 229
 
244
-	userhost, err := Casefold(ExpandUserHost(userhost))
230
+	userhost, err := CanonicalizeMaskWildcard(userhost)
245 231
 	if err != nil {
246 232
 		return set
247 233
 	}

+ 22
- 21
irc/handlers.go Vedi File

@@ -1372,10 +1372,11 @@ func killHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
1372 1372
 // KLINE [ANDKILL] [MYSELF] [duration] <mask> [ON <server>] [reason [| oper reason]]
1373 1373
 // KLINE LIST
1374 1374
 func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
1375
+	details := client.Details()
1375 1376
 	// check oper permissions
1376 1377
 	oper := client.Oper()
1377 1378
 	if oper == nil || !oper.Class.Capabilities["oper:local_ban"] {
1378
-		rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
1379
+		rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
1379 1380
 		return false
1380 1381
 	}
1381 1382
 
@@ -1421,31 +1422,31 @@ func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
1421 1422
 
1422 1423
 	// get mask
1423 1424
 	if len(msg.Params) < currentArg+1 {
1424
-		rb.Add(nil, server.name, ERR_NEEDMOREPARAMS, client.nick, msg.Command, client.t("Not enough parameters"))
1425
+		rb.Add(nil, server.name, ERR_NEEDMOREPARAMS, details.nick, msg.Command, client.t("Not enough parameters"))
1425 1426
 		return false
1426 1427
 	}
1427
-	mask := strings.ToLower(msg.Params[currentArg])
1428
+	mask := msg.Params[currentArg]
1428 1429
 	currentArg++
1429 1430
 
1430 1431
 	// check mask
1431
-	if !strings.Contains(mask, "!") && !strings.Contains(mask, "@") {
1432
-		mask = mask + "!*@*"
1433
-	} else if !strings.Contains(mask, "@") {
1434
-		mask = mask + "@*"
1432
+	mask, err = CanonicalizeMaskWildcard(mask)
1433
+	if err != nil {
1434
+		rb.Add(nil, server.name, ERR_UNKNOWNERROR, details.nick, msg.Command, client.t("Erroneous nickname"))
1435
+		return false
1435 1436
 	}
1436 1437
 
1437 1438
 	matcher := ircmatch.MakeMatch(mask)
1438 1439
 
1439 1440
 	for _, clientMask := range client.AllNickmasks() {
1440 1441
 		if !klineMyself && matcher.Match(clientMask) {
1441
-			rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, client.t("This ban matches you. To KLINE yourself, you must use the command:  /KLINE MYSELF <arguments>"))
1442
+			rb.Add(nil, server.name, ERR_UNKNOWNERROR, details.nick, msg.Command, client.t("This ban matches you. To KLINE yourself, you must use the command:  /KLINE MYSELF <arguments>"))
1442 1443
 			return false
1443 1444
 		}
1444 1445
 	}
1445 1446
 
1446 1447
 	// check remote
1447 1448
 	if len(msg.Params) > currentArg && msg.Params[currentArg] == "ON" {
1448
-		rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, client.t("Remote servers not yet supported"))
1449
+		rb.Add(nil, server.name, ERR_UNKNOWNERROR, details.nick, msg.Command, client.t("Remote servers not yet supported"))
1449 1450
 		return false
1450 1451
 	}
1451 1452
 
@@ -1467,10 +1468,10 @@ func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
1467 1468
 	var snoDescription string
1468 1469
 	if duration != 0 {
1469 1470
 		rb.Notice(fmt.Sprintf(client.t("Added temporary (%[1]s) K-Line for %[2]s"), duration.String(), mask))
1470
-		snoDescription = fmt.Sprintf(ircfmt.Unescape("%s [%s]$r added temporary (%s) K-Line for %s"), client.nick, operName, duration.String(), mask)
1471
+		snoDescription = fmt.Sprintf(ircfmt.Unescape("%s [%s]$r added temporary (%s) K-Line for %s"), details.nick, operName, duration.String(), mask)
1471 1472
 	} else {
1472 1473
 		rb.Notice(fmt.Sprintf(client.t("Added K-Line for %s"), mask))
1473
-		snoDescription = fmt.Sprintf(ircfmt.Unescape("%s [%s]$r added K-Line for %s"), client.nick, operName, mask)
1474
+		snoDescription = fmt.Sprintf(ircfmt.Unescape("%s [%s]$r added K-Line for %s"), details.nick, operName, mask)
1474 1475
 	}
1475 1476
 	server.snomasks.Send(sno.LocalXline, snoDescription)
1476 1477
 
@@ -1501,7 +1502,7 @@ func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
1501 1502
 
1502 1503
 		// send snomask
1503 1504
 		sort.Strings(killedClientNicks)
1504
-		server.snomasks.Send(sno.LocalKills, fmt.Sprintf(ircfmt.Unescape("%s [%s] killed %d clients with a KLINE $c[grey][$r%s$c[grey]]"), client.nick, operName, len(killedClientNicks), strings.Join(killedClientNicks, ", ")))
1505
+		server.snomasks.Send(sno.LocalKills, fmt.Sprintf(ircfmt.Unescape("%s [%s] killed %d clients with a KLINE $c[grey][$r%s$c[grey]]"), details.nick, operName, len(killedClientNicks), strings.Join(killedClientNicks, ", ")))
1505 1506
 	}
1506 1507
 
1507 1508
 	return killClient
@@ -2486,31 +2487,31 @@ func unDLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *R
2486 2487
 
2487 2488
 // UNKLINE <mask>
2488 2489
 func unKLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2490
+	details := client.Details()
2489 2491
 	// check oper permissions
2490 2492
 	oper := client.Oper()
2491 2493
 	if oper == nil || !oper.Class.Capabilities["oper:local_unban"] {
2492
-		rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
2494
+		rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
2493 2495
 		return false
2494 2496
 	}
2495 2497
 
2496 2498
 	// get host
2497 2499
 	mask := msg.Params[0]
2498
-
2499
-	if !strings.Contains(mask, "!") && !strings.Contains(mask, "@") {
2500
-		mask = mask + "!*@*"
2501
-	} else if !strings.Contains(mask, "@") {
2502
-		mask = mask + "@*"
2500
+	mask, err := CanonicalizeMaskWildcard(mask)
2501
+	if err != nil {
2502
+		rb.Add(nil, server.name, ERR_UNKNOWNERROR, details.nick, msg.Command, client.t("Erroneous nickname"))
2503
+		return false
2503 2504
 	}
2504 2505
 
2505
-	err := server.klines.RemoveMask(mask)
2506
+	err = server.klines.RemoveMask(mask)
2506 2507
 
2507 2508
 	if err != nil {
2508
-		rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, fmt.Sprintf(client.t("Could not remove ban [%s]"), err.Error()))
2509
+		rb.Add(nil, server.name, ERR_UNKNOWNERROR, details.nick, msg.Command, fmt.Sprintf(client.t("Could not remove ban [%s]"), err.Error()))
2509 2510
 		return false
2510 2511
 	}
2511 2512
 
2512 2513
 	rb.Notice(fmt.Sprintf(client.t("Removed K-Line for %s"), mask))
2513
-	server.snomasks.Send(sno.LocalXline, fmt.Sprintf(ircfmt.Unescape("%s$r removed K-Line for %s"), client.nick, mask))
2514
+	server.snomasks.Send(sno.LocalXline, fmt.Sprintf(ircfmt.Unescape("%s$r removed K-Line for %s"), details.nick, mask))
2514 2515
 	return false
2515 2516
 }
2516 2517
 

+ 53
- 0
irc/strings.go Vedi File

@@ -6,6 +6,7 @@
6 6
 package irc
7 7
 
8 8
 import (
9
+	"fmt"
9 10
 	"strings"
10 11
 
11 12
 	"github.com/oragono/confusables"
@@ -157,3 +158,55 @@ func Skeleton(name string) (string, error) {
157 158
 	// pass PRECIS --- we are just further canonicalizing the skeleton.
158 159
 	return cases.Lower(language.Und).String(name), nil
159 160
 }
161
+
162
+// maps a nickmask fragment to an expanded, casefolded wildcard:
163
+// Shivaram@good-fortune -> *!shivaram@good-fortune
164
+// EDMUND -> edmund!*@*
165
+func CanonicalizeMaskWildcard(userhost string) (expanded string, err error) {
166
+	var nick, user, host string
167
+	bangIndex := strings.IndexByte(userhost, '!')
168
+	strudelIndex := strings.IndexByte(userhost, '@')
169
+
170
+	if bangIndex != -1 && bangIndex < strudelIndex {
171
+		nick = userhost[:bangIndex]
172
+		user = userhost[bangIndex+1 : strudelIndex]
173
+		host = userhost[strudelIndex+1:]
174
+	} else if bangIndex != -1 && strudelIndex == -1 {
175
+		nick = userhost[:bangIndex]
176
+		user = userhost[bangIndex+1:]
177
+	} else if bangIndex != -1 && strudelIndex < bangIndex {
178
+		// @ before !, fail
179
+		return "", errNicknameInvalid
180
+	} else if bangIndex == -1 && strudelIndex != -1 {
181
+		user = userhost[:strudelIndex]
182
+		host = userhost[strudelIndex+1:]
183
+	} else if bangIndex == -1 && strudelIndex == -1 {
184
+		nick = userhost
185
+	} else {
186
+		// shouldn't be possible
187
+		return "", errInvalidParams
188
+	}
189
+
190
+	if nick == "" {
191
+		nick = "*"
192
+	}
193
+	if nick != "*" {
194
+		nick, err = Casefold(nick)
195
+		if err != nil {
196
+			return "", err
197
+		}
198
+	}
199
+	if user == "" {
200
+		user = "*"
201
+	}
202
+	if user != "*" {
203
+		user = strings.ToLower(user)
204
+	}
205
+	if host == "" {
206
+		host = "*"
207
+	}
208
+	if host != "*" {
209
+		host = strings.ToLower(host)
210
+	}
211
+	return fmt.Sprintf("%s!%s@%s", nick, user, host), nil
212
+}

+ 24
- 0
irc/strings_test.go Vedi File

@@ -188,3 +188,27 @@ func TestSkeleton(t *testing.T) {
188 188
 	// should not raise an error:
189 189
 	skeleton("けらんぐ")
190 190
 }
191
+
192
+func TestCanonicalizeMaskWildcard(t *testing.T) {
193
+	tester := func(input, expected string, expectedErr error) {
194
+		out, err := CanonicalizeMaskWildcard(input)
195
+		if out != expected {
196
+			t.Errorf("expected %s to canonicalize to %s, instead %s", input, expected, out)
197
+		}
198
+		if err != expectedErr {
199
+			t.Errorf("expected %s to produce error %v, instead %v", input, expectedErr, err)
200
+		}
201
+	}
202
+
203
+	tester("shivaram", "shivaram!*@*", nil)
204
+	tester("slingamn!shivaram", "slingamn!shivaram@*", nil)
205
+	tester("ברוך", "ברוך!*@*", nil)
206
+	tester("hacker@monad.io", "*!hacker@monad.io", nil)
207
+	tester("Evan!hacker@monad.io", "evan!hacker@monad.io", nil)
208
+	tester("РОТАТО!Potato", "ротато!potato@*", nil)
209
+	tester("tkadich*", "tkadich*!*@*", nil)
210
+	tester("SLINGAMN!*@*", "slingamn!*@*", nil)
211
+	tester("slingamn!shivaram*", "slingamn!shivaram*@*", nil)
212
+	tester("slingamn!", "slingamn!*@*", nil)
213
+	tester("shivaram*@good-fortune", "*!shivaram*@good-fortune", nil)
214
+}

Loading…
Annulla
Salva