Check nicks on the IRC listener with the HTTP API's rule (closes #142)
check / check (push) Waiting to run
check / check (push) Waiting to run
The nick rule moves from internal/handlers to internal/service as ValidNick, and the HTTP API and both IRC listener NICK paths call it. The IRC listener used to cut a nick to 32 bytes and accept anything else, so a nick with spaces such as "bob PRIVMSG #inj :hi" made the lines built from it read as another user's PRIVMSG. It now answers a nick the rule refuses with ERR_ERRONEUSNICKNAME (432), before and after registration, and keeps the nick as it was. Model: opus-5-5
This commit was merged in pull request #152.
This commit is contained in:
@@ -71,8 +71,13 @@ func (c *Conn) handleNick(
|
||||
}
|
||||
|
||||
newNick := msg.Params[0]
|
||||
if len(newNick) > maxNickLen {
|
||||
newNick = newNick[:maxNickLen]
|
||||
if !service.ValidNick(newNick) {
|
||||
c.sendNumeric(
|
||||
irc.ErrErroneusNickname,
|
||||
newNick, "Erroneous nickname",
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
oldMask := c.hostmask()
|
||||
|
||||
@@ -27,7 +27,6 @@ const (
|
||||
pollInterval = 100 * time.Millisecond
|
||||
pingInterval = 90 * time.Second
|
||||
pongDeadline = 30 * time.Second
|
||||
maxNickLen = 32
|
||||
minPasswordLen = 8
|
||||
maxHashcashBits = 40
|
||||
)
|
||||
@@ -426,11 +425,16 @@ func (c *Conn) handlePreRegistration(
|
||||
return
|
||||
}
|
||||
|
||||
c.nick = msg.Params[0]
|
||||
if len(c.nick) > maxNickLen {
|
||||
c.nick = c.nick[:maxNickLen]
|
||||
if !service.ValidNick(msg.Params[0]) {
|
||||
c.sendNumeric(
|
||||
irc.ErrErroneusNickname,
|
||||
msg.Params[0], "Erroneous nickname",
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
c.nick = msg.Params[0]
|
||||
c.gotNick = true
|
||||
case irc.CmdUser:
|
||||
if len(msg.Params) < 4 { //nolint:mnd
|
||||
|
||||
@@ -519,6 +519,68 @@ func TestDuplicateNick(t *testing.T) {
|
||||
assertContains(t, lines, " 433 ", "ERR_NICKNAMEINUSE")
|
||||
}
|
||||
|
||||
// TestNickRefused checks that NICK, before and after
|
||||
// registration, answers a nick the HTTP API refuses with
|
||||
// ERR_ERRONEUSNICKNAME and keeps the nick as it was, and
|
||||
// that another member of the channel sees no line from it.
|
||||
func TestNickRefused(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Each is what follows "NICK " on the wire.
|
||||
refused := []string{
|
||||
":bob PRIVMSG #inj :hi", // contains spaces
|
||||
":", // empty
|
||||
strings.Repeat("a", 33), // one character too long
|
||||
"bob!x",
|
||||
"bob@x",
|
||||
"#bob",
|
||||
}
|
||||
|
||||
env := newTestEnv(t)
|
||||
|
||||
// Before registration: the 432 is addressed to the nick
|
||||
// sent first, and USER registers with that nick.
|
||||
early := env.dial(t)
|
||||
early.send("NICK early")
|
||||
|
||||
for _, param := range refused {
|
||||
lines := early.sendAndExpect("NICK "+param, " 432 ")
|
||||
assertContains(t, lines, " 432 early ", "before: "+param)
|
||||
}
|
||||
|
||||
welcome := early.sendAndExpect("USER early 0 * :Test", " 001 ")
|
||||
assertContains(t, welcome, " 001 early ", "registered as early")
|
||||
|
||||
// After registration.
|
||||
bob := env.dial(t)
|
||||
bob.register("bob")
|
||||
bob.joinAndDrain("#inj")
|
||||
|
||||
mallory := env.dial(t)
|
||||
mallory.register("mallory")
|
||||
mallory.joinAndDrain("#inj")
|
||||
|
||||
bob.readUntil(func(l string) bool {
|
||||
return strings.Contains(l, "JOIN") &&
|
||||
strings.Contains(l, "mallory")
|
||||
})
|
||||
|
||||
for _, param := range refused {
|
||||
lines := mallory.sendAndExpect("NICK "+param, " 432 ")
|
||||
assertContains(t, lines, " 432 mallory ", "after: "+param)
|
||||
}
|
||||
|
||||
mallory.send("PRIVMSG #inj :still mallory")
|
||||
|
||||
bobLines := bob.readUntil(func(l string) bool {
|
||||
return strings.Contains(l, "still mallory")
|
||||
})
|
||||
assertNotContains(t, bobLines, " NICK ", "bob sees no NICK")
|
||||
assertContains(
|
||||
t, bobLines, ":mallory!", "bob sees mallory's message",
|
||||
)
|
||||
}
|
||||
|
||||
func TestListChannels(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user