diff options
author | Hubert Hirtz <hubert@hirtz.pm> | 2021-09-29 21:47:11 +0200 |
---|---|---|
committer | Hubert Hirtz <hubert@hirtz.pm> | 2021-09-29 21:47:11 +0200 |
commit | 928c0a068601884260b0fb22a551d35854e6af91 (patch) | |
tree | 82d9cced626bd9da23401585bb7cb5ac458c209f /irc/session.go | |
parent | Eager registration (diff) |
Revert "Eager registration"
This reverts commit 60f9e6570e40c0a0cbb10976b0ec6a7076fdb453.
Diffstat (limited to '')
-rw-r--r-- | irc/session.go | 87 |
1 files changed, 62 insertions, 25 deletions
diff --git a/irc/session.go b/irc/session.go index ec90631..716d3fb 100644 --- a/irc/session.go +++ b/irc/session.go @@ -115,7 +115,8 @@ type Session struct { host string auth SASLClient - enabledCaps map[string]struct{} + availableCaps map[string]string + enabledCaps map[string]struct{} // ISUPPORT features casemap func(string) string @@ -143,6 +144,7 @@ func NewSession(out chan<- Message, params SessionParams) *Session { user: params.Username, real: params.RealName, auth: params.Auth, + availableCaps: map[string]string{}, enabledCaps: map[string]struct{}{}, casemap: CasemapRFC1459, chantypes: "#&", @@ -157,21 +159,9 @@ func NewSession(out chan<- Message, params SessionParams) *Session { pendingChannels: map[string]time.Time{}, } - s.out <- NewMessage("CAP", "LS", "302") // needed to advertise 302 support - for capability := range SupportedCapabilities { - s.out <- NewMessage("CAP", "REQ", capability) - } + s.out <- NewMessage("CAP", "LS", "302") s.out <- NewMessage("NICK", s.nick) s.out <- NewMessage("USER", s.user, "0", "*", s.real) - if s.auth != nil { - s.out <- NewMessage("AUTHENTICATE", s.auth.Handshake()) - resp, err := s.auth.Respond("+") - if err != nil { - panic(err) - } - s.out <- NewMessage("AUTHENTICATE", resp) - } - s.out <- NewMessage("CAP", "END") return s } @@ -476,18 +466,53 @@ func (s *Session) handleUnregistered(msg Message) Event { switch msg.Command { case "AUTHENTICATE": if s.auth != nil { - if msg.Params[0] == "+" { - // Server has processed the "AUTHENTICATE <mechanism>" message - } else { - // Unexpected AUTHENTICATE message from server, abort authentication. + res, err := s.auth.Respond(msg.Params[0]) + if err != nil { s.out <- NewMessage("AUTHENTICATE", "*") + } else { + s.out <- NewMessage("AUTHENTICATE", res) } } case rplLoggedin: + s.out <- NewMessage("CAP", "END") s.acct = msg.Params[2] s.host = ParsePrefix(msg.Params[1]).Host case errNicklocked, errSaslfail, errSasltoolong, errSaslaborted, errSaslalready, rplSaslmechs: - // Auth failed, let registration end anyway. + s.out <- NewMessage("CAP", "END") + case "CAP": + switch msg.Params[1] { + case "LS": + var willContinue bool + var ls string + + if msg.Params[2] == "*" { + willContinue = true + ls = msg.Params[3] + } else { + willContinue = false + ls = msg.Params[2] + } + + for _, c := range ParseCaps(ls) { + s.availableCaps[c.Name] = c.Value + } + + if !willContinue { + for c := range s.availableCaps { + if _, ok := SupportedCapabilities[c]; !ok { + continue + } + s.out <- NewMessage("CAP", "REQ", c) + } + + _, ok := s.availableCaps["sasl"] + if s.auth == nil || !ok { + s.out <- NewMessage("CAP", "END") + } + } + default: + return s.handleRegistered(msg) + } case errNicknameinuse: s.out <- NewMessage("NICK", msg.Params[1]+"_") case rplSaslsuccess: @@ -538,26 +563,38 @@ func (s *Session) handleRegistered(msg Message) Event { delete(s.enabledCaps, c.Name) } - if c.Name == "multi-prefix" { + if s.auth != nil && c.Name == "sasl" { + h := s.auth.Handshake() + s.out <- NewMessage("AUTHENTICATE", h) + } else if len(s.channels) != 0 && c.Name == "multi-prefix" { // TODO merge NAMES commands for channel := range s.channels { s.out <- NewMessage("NAMES", channel) } } } + case "NAK": + // do nothing case "NEW": for _, c := range ParseCaps(msg.Params[2]) { - if _, ok := SupportedCapabilities[c.Name]; ok { - s.out <- NewMessage("CAP", "REQ", c.Name) + s.availableCaps[c.Name] = c.Value + _, ok := SupportedCapabilities[c.Name] + if !ok { + continue } - // TODO authenticate if necessary + s.out <- NewMessage("CAP", "REQ", c.Name) + } + + _, ok := s.availableCaps["sasl"] + if s.acct == "" && ok { + // TODO authenticate } case "DEL": for _, c := range ParseCaps(msg.Params[2]) { + delete(s.availableCaps, c.Name) delete(s.enabledCaps, c.Name) } } - // do nothing on LS and NAK case "JOIN": nickCf := s.Casemap(msg.Prefix.Name) channelCf := s.Casemap(msg.Params[0]) @@ -710,7 +747,7 @@ func (s *Session) handleRegistered(msg Message) Event { if c, ok := s.channels[channelCf]; ok { return ModeChangeEvent{ Channel: c.Name, - Mode: strings.Join(msg.Params[1:], " "), + Mode: strings.Join(msg.Params[1:], " "), } } case "PRIVMSG", "NOTICE": |