commit 928c0a0
Hubert Hirtz
·
2021-09-29 19:47:11 +0000 UTC
parent 60f9e65
Revert "Eager registration" This reverts commit 60f9e6570e40c0a0cbb10976b0ec6a7076fdb453.
1 files changed,
+62,
-25
+62,
-25
1@@ -115,7 +115,8 @@ type Session struct {
2 host string
3 auth SASLClient
4
5- enabledCaps map[string]struct{}
6+ availableCaps map[string]string
7+ enabledCaps map[string]struct{}
8
9 // ISUPPORT features
10 casemap func(string) string
11@@ -143,6 +144,7 @@ func NewSession(out chan<- Message, params SessionParams) *Session {
12 user: params.Username,
13 real: params.RealName,
14 auth: params.Auth,
15+ availableCaps: map[string]string{},
16 enabledCaps: map[string]struct{}{},
17 casemap: CasemapRFC1459,
18 chantypes: "#&",
19@@ -157,21 +159,9 @@ func NewSession(out chan<- Message, params SessionParams) *Session {
20 pendingChannels: map[string]time.Time{},
21 }
22
23- s.out <- NewMessage("CAP", "LS", "302") // needed to advertise 302 support
24- for capability := range SupportedCapabilities {
25- s.out <- NewMessage("CAP", "REQ", capability)
26- }
27+ s.out <- NewMessage("CAP", "LS", "302")
28 s.out <- NewMessage("NICK", s.nick)
29 s.out <- NewMessage("USER", s.user, "0", "*", s.real)
30- if s.auth != nil {
31- s.out <- NewMessage("AUTHENTICATE", s.auth.Handshake())
32- resp, err := s.auth.Respond("+")
33- if err != nil {
34- panic(err)
35- }
36- s.out <- NewMessage("AUTHENTICATE", resp)
37- }
38- s.out <- NewMessage("CAP", "END")
39
40 return s
41 }
42@@ -476,18 +466,53 @@ func (s *Session) handleUnregistered(msg Message) Event {
43 switch msg.Command {
44 case "AUTHENTICATE":
45 if s.auth != nil {
46- if msg.Params[0] == "+" {
47- // Server has processed the "AUTHENTICATE <mechanism>" message
48- } else {
49- // Unexpected AUTHENTICATE message from server, abort authentication.
50+ res, err := s.auth.Respond(msg.Params[0])
51+ if err != nil {
52 s.out <- NewMessage("AUTHENTICATE", "*")
53+ } else {
54+ s.out <- NewMessage("AUTHENTICATE", res)
55 }
56 }
57 case rplLoggedin:
58+ s.out <- NewMessage("CAP", "END")
59 s.acct = msg.Params[2]
60 s.host = ParsePrefix(msg.Params[1]).Host
61 case errNicklocked, errSaslfail, errSasltoolong, errSaslaborted, errSaslalready, rplSaslmechs:
62- // Auth failed, let registration end anyway.
63+ s.out <- NewMessage("CAP", "END")
64+ case "CAP":
65+ switch msg.Params[1] {
66+ case "LS":
67+ var willContinue bool
68+ var ls string
69+
70+ if msg.Params[2] == "*" {
71+ willContinue = true
72+ ls = msg.Params[3]
73+ } else {
74+ willContinue = false
75+ ls = msg.Params[2]
76+ }
77+
78+ for _, c := range ParseCaps(ls) {
79+ s.availableCaps[c.Name] = c.Value
80+ }
81+
82+ if !willContinue {
83+ for c := range s.availableCaps {
84+ if _, ok := SupportedCapabilities[c]; !ok {
85+ continue
86+ }
87+ s.out <- NewMessage("CAP", "REQ", c)
88+ }
89+
90+ _, ok := s.availableCaps["sasl"]
91+ if s.auth == nil || !ok {
92+ s.out <- NewMessage("CAP", "END")
93+ }
94+ }
95+ default:
96+ return s.handleRegistered(msg)
97+ }
98 case errNicknameinuse:
99 s.out <- NewMessage("NICK", msg.Params[1]+"_")
100 case rplSaslsuccess:
101@@ -538,26 +563,38 @@ func (s *Session) handleRegistered(msg Message) Event {
102 delete(s.enabledCaps, c.Name)
103 }
104
105- if c.Name == "multi-prefix" {
106+ if s.auth != nil && c.Name == "sasl" {
107+ h := s.auth.Handshake()
108+ s.out <- NewMessage("AUTHENTICATE", h)
109+ } else if len(s.channels) != 0 && c.Name == "multi-prefix" {
110 // TODO merge NAMES commands
111 for channel := range s.channels {
112 s.out <- NewMessage("NAMES", channel)
113 }
114 }
115 }
116+ case "NAK":
117+ // do nothing
118 case "NEW":
119 for _, c := range ParseCaps(msg.Params[2]) {
120- if _, ok := SupportedCapabilities[c.Name]; ok {
121- s.out <- NewMessage("CAP", "REQ", c.Name)
122+ s.availableCaps[c.Name] = c.Value
123+ _, ok := SupportedCapabilities[c.Name]
124+ if !ok {
125+ continue
126 }
127- // TODO authenticate if necessary
128+ s.out <- NewMessage("CAP", "REQ", c.Name)
129+ }
130+
131+ _, ok := s.availableCaps["sasl"]
132+ if s.acct == "" && ok {
133+ // TODO authenticate
134 }
135 case "DEL":
136 for _, c := range ParseCaps(msg.Params[2]) {
137+ delete(s.availableCaps, c.Name)
138 delete(s.enabledCaps, c.Name)
139 }
140 }
141- // do nothing on LS and NAK
142 case "JOIN":
143 nickCf := s.Casemap(msg.Prefix.Name)
144 channelCf := s.Casemap(msg.Params[0])
145@@ -710,7 +747,7 @@ func (s *Session) handleRegistered(msg Message) Event {
146 if c, ok := s.channels[channelCf]; ok {
147 return ModeChangeEvent{
148 Channel: c.Name,
149- Mode: strings.Join(msg.Params[1:], " "),
150+ Mode: strings.Join(msg.Params[1:], " "),
151 }
152 }
153 case "PRIVMSG", "NOTICE":