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":