Adnan Maolood: 1 Use BOUNCER BIND to bind to bouncer networks 2 files changed, 62 insertions(+), 11 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~emersion/public-inbox/patches/31190/mbox | git am -3Learn more about email & git
Also update the client to use SASL authentication. --- client.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++------- main.go | 9 +++++--- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/client.go b/client.go index 492a75b..c1030ca 100644 --- a/client.go +++ b/client.go @@ -1,7 +1,10 @@ package main import ( + "bytes" "crypto/tls" + "encoding/base64" + "errors" "fmt" "log" "net" @@ -67,20 +70,14 @@ func dialTLS(addr string) (*client, error) { }, nil } -func (c *client) Register(nick, pass string) { - caps := []string{"draft/chathistory", "message-tags", "batch", "echo-message", "server-time", "causal.agency/passive", "soju.im/bouncer-networks"} +func (c *client) Authenticate(nick, pass, netid string) error { + caps := []string{"draft/chathistory", "sasl", "message-tags", "batch", "echo-message", "server-time", "causal.agency/passive", "soju.im/bouncer-networks"} for _, name := range caps { c.WriteMessage(&irc.Message{ Command: "CAP", Params: []string{"REQ", name}, }) } - if pass != "" { - c.WriteMessage(&irc.Message{ - Command: "PASS", - Params: []string{pass}, - }) - } c.WriteMessage(&irc.Message{ Command: "NICK", Params: []string{nick}, @@ -89,10 +86,53 @@ func (c *client) Register(nick, pass string) { Command: "USER", Params: []string{nick, "0", "*", nick}, }) + + // Wait for SASL authentication to complete +loop: + for { + msg, err := c.ReadMessage() + if err != nil { + return err + } + + switch msg.Command { + case "AUTHENTICATE": + challenge := msg.Params[0] + if challenge != "+" { + return fmt.Errorf("unexpected SASL challenge %q", challenge) + } + + var buf bytes.Buffer + buf.WriteString(nick) + buf.WriteByte(0) + buf.WriteString(nick) + buf.WriteByte(0) + buf.WriteString(pass) + payload := base64.StdEncoding.EncodeToString(buf.Bytes()) + c.WriteMessage(&irc.Message{ + Command: "AUTHENTICATE", + Params: []string{payload}, + }) + case irc.RPL_SASLSUCCESS: + break loop + case irc.ERR_NICKLOCKED, irc.ERR_SASLFAIL, irc.ERR_SASLTOOLONG, + irc.ERR_SASLABORTED, irc.ERR_SASLALREADY, irc.RPL_SASLMECHS: + return errors.New(strings.Join(msg.Params[1:], " ")) + } + } + + if netid != "" { + c.WriteMessage(&irc.Message{ + Command: "BOUNCER", + Params: []string{"BIND", netid}, + }) + } + c.WriteMessage(&irc.Message{ Command: "CAP", Params: []string{"END"}, }) + return nil } func (c *client) ReadMessage() (*message, error) { @@ -143,6 +183,14 @@ func (c *client) ReadMessage() (*message, error) { c.caps.chatHistory = ok case "soju.im/bouncer-networks": c.caps.bouncerNetworks = ok + case "sasl": + if !ok { + return nil, fmt.Errorf("server doesn't support SASL authentication") + } + c.WriteMessage(&irc.Message{ + Command: "AUTHENTICATE", + Params: []string{"PLAIN"}, + }) } } case "BATCH": diff --git a/main.go b/main.go index c05e494..26e9e23 100644 --- a/main.go +++ b/main.go @@ -107,7 +107,9 @@ func main() { defer c.Close() c.Debug = debug - c.Register(nick, pass) + if err := c.Authenticate(nick, pass, ""); err != nil { + log.Fatalf("Authentication failed: %v", err) + } waitRegistered(c) if c.caps.bouncerNetworks { @@ -122,9 +124,10 @@ func main() { log.Fatalf("Failed to connect to server: %v", err) } - // TODO: use BOUNCER BIND instead c.Debug = debug - c.Register(nick+"/"+network.name, pass) + if err := c.Authenticate(nick, pass, network.id); err != nil { + log.Fatalf("Authentication failed: %v", err) + } waitRegistered(c) networkDir := filepath.Join(outputDir, escapeFilename(network.name)) -- 2.34.2
builds.sr.ht <builds@sr.ht>chathistorysync/patches/.build.yml: SUCCESS in 30s [Use BOUNCER BIND to bind to bouncer networks][0] from [Adnan Maolood][1] [0]: https://lists.sr.ht/~emersion/public-inbox/patches/31190 [1]: mailto:me@adnano.co ✓ #737946 SUCCESS chathistorysync/patches/.build.yml https://builds.sr.ht/~emersion/job/737946