Allow CAP negotiation to happen with CAP REQ

See https://ircv3.net/specs/extensions/capability-negotiation

> Upon receiving either a CAP LS or CAP REQ command during connection
> registration, the server MUST not complete registration until the
> client sends a CAP END command to indicate that capability negotiation
> has ended.

This commit should prevent soju from trying to authenticate the user
prior to having received AUTHENTICATE messages, when the client eagerly
requests capabilities with CAP REQ seeing available capabilities
beforehand with CAP LS.
This commit is contained in:
Hubert Hirtz 2021-09-19 16:47:27 +02:00 committed by Simon Ser
parent bc83d3a3ba
commit 2554c92df7

View file

@ -185,7 +185,7 @@ type downstreamConn struct {
password string // empty after authentication password string // empty after authentication
network *network // can be nil network *network // can be nil
negociatingCaps bool negotiatingCaps bool
capVersion int capVersion int
supportedCaps map[string]string supportedCaps map[string]string
caps map[string]bool caps map[string]bool
@ -717,7 +717,7 @@ func (dc *downstreamConn) handleMessageUnregistered(msg *irc.Message) error {
dc.logger.Printf("unhandled message: %v", msg) dc.logger.Printf("unhandled message: %v", msg)
return newUnknownCommandError(msg.Command) return newUnknownCommandError(msg.Command)
} }
if dc.rawUsername != "" && dc.nick != "" && !dc.negociatingCaps { if dc.rawUsername != "" && dc.nick != "" && !dc.negotiatingCaps {
return dc.register() return dc.register()
} }
return nil return nil
@ -770,7 +770,7 @@ func (dc *downstreamConn) handleCapCommand(cmd string, args []string) error {
} }
if !dc.registered { if !dc.registered {
dc.negociatingCaps = true dc.negotiatingCaps = true
} }
case "LIST": case "LIST":
var caps []string var caps []string
@ -832,8 +832,12 @@ func (dc *downstreamConn) handleCapCommand(cmd string, args []string) error {
Command: "CAP", Command: "CAP",
Params: []string{replyTo, reply, args[0]}, Params: []string{replyTo, reply, args[0]},
}) })
if !dc.registered {
dc.negotiatingCaps = true
}
case "END": case "END":
dc.negociatingCaps = false dc.negotiatingCaps = false
default: default:
return ircError{&irc.Message{ return ircError{&irc.Message{
Command: err_invalidcapcmd, Command: err_invalidcapcmd,