diff options
author | delthas <delthas@dille.cc> | 2022-04-20 19:16:52 +0200 |
---|---|---|
committer | delthas <delthas@dille.cc> | 2022-04-20 19:16:52 +0200 |
commit | 009982352f18c03c331aa7aee0a1c89822e32884 (patch) | |
tree | 12f577b5fd04a9ac1a3cf3f7fce71ba728e2b9d1 | |
parent | Fetch the chat history of the last opened buffer first (diff) |
Send SASL PLAIN authentication on connect
This saves one round trip by letting us send BOUNCER LISTNETWORKS right
away and speeds up startup time.
-rw-r--r-- | irc/session.go | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/irc/session.go b/irc/session.go index c4c673a..dbdf40a 100644 --- a/irc/session.go +++ b/irc/session.go @@ -16,6 +16,7 @@ import ( ) type SASLClient interface { + Early() bool Handshake() (mech string) Respond(challenge string) (res string, err error) } @@ -25,6 +26,10 @@ type SASLPlain struct { Password string } +func (auth *SASLPlain) Early() bool { + return true +} + func (auth *SASLPlain) Handshake() (mech string) { mech = "PLAIN" return @@ -175,6 +180,17 @@ func NewSession(out chan<- Message, params SessionParams) *Session { } s.out <- NewMessage("NICK", s.nick) s.out <- NewMessage("USER", s.user, "0", "*", s.real) + if s.auth != nil && s.auth.Early() { + h := s.auth.Handshake() + s.out <- NewMessage("AUTHENTICATE", h) + res, err := s.auth.Respond("+") + if err != nil { + s.out <- NewMessage("AUTHENTICATE", "*") + } else { + s.out <- NewMessage("AUTHENTICATE", res) + } + s.auth = nil + } if s.auth == nil { s.endRegistration() @@ -574,7 +590,9 @@ func (s *Session) handleUnregistered(msg Message) (Event, error) { s.out <- NewMessage("NICK", nick+"_") case rplSaslsuccess: - s.endRegistration() + if s.auth != nil { + s.endRegistration() + } default: return s.handleRegistered(msg) } @@ -647,7 +665,9 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er s.user = prefix.User s.host = prefix.Host case errNicklocked, errSaslfail, errSasltoolong, errSaslaborted, errSaslalready, rplSaslmechs: - s.endRegistration() + if s.auth != nil { + s.endRegistration() + } return ErrorEvent{ Severity: SeverityFail, Code: msg.Command, @@ -1350,6 +1370,10 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er if len(msg.Params) < 2 { return nil, msg.errNotEnoughParams(2) } + if msg.Command == errUnknowncommand && msg.Params[1] == "BOUNCER" { + // ignore any error in response to unconditional BOUNCER LISTNETWORKS + return nil, nil + } return ErrorEvent{ Severity: ReplySeverity(msg.Command), Code: msg.Command, @@ -1488,13 +1512,11 @@ func (s *Session) endRegistration() { if s.registered { return } - if _, ok := s.enabledCaps["soju.im/bouncer-networks"]; !ok { - s.out <- NewMessage("CAP", "END") - } else if s.netID == "" { + if s.netID != "" { + s.out <- NewMessage("BOUNCER", "BIND", s.netID) s.out <- NewMessage("CAP", "END") - s.out <- NewMessage("BOUNCER", "LISTNETWORKS") } else { - s.out <- NewMessage("BOUNCER", "BIND", s.netID) s.out <- NewMessage("CAP", "END") + s.out <- NewMessage("BOUNCER", "LISTNETWORKS") } } |