~emersion/public-inbox

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
4 3

[PATCH chathistorysync] Use BOUNCER BIND to bind to bouncer networks

Details
Message ID
<20220416100129.5168-1-me@adnano.co>
DKIM signature
pass
Download raw message
Patch: +62 -11
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

[chathistorysync/patches/.build.yml] build success

builds.sr.ht <builds@sr.ht>
Details
Message ID
<CJBKTCOPKIN1.ZNL22IQDBG2B@cirno>
In-Reply-To
<20220416100129.5168-1-me@adnano.co> (view parent)
DKIM signature
missing
Download raw message
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]: me@adnano.co

✓ #737946 SUCCESS chathistorysync/patches/.build.yml https://builds.sr.ht/~emersion/job/737946
Details
Message ID
<CKLXLT8TCG4R.1541BROKU9RE4@nitro>
In-Reply-To
<20220416100129.5168-1-me@adnano.co> (view parent)
DKIM signature
pass
Download raw message
Does this patch need some more work before it can be accepted? Without
this patch, chathistorysync doesn't work for syncing logs from
chat.sr.ht.
Details
Message ID
<tXwv_fAVFJQEvCSt2kBzLKoTvELcCMYltWTg9kIVRCA87hVAgQhMXl42q8NAwlAnZIBc4FIv_ZvLX-O6MzrsuL5-Fj0QmGieZzf9DAq-_kY=@emersion.fr>
In-Reply-To
<20220416100129.5168-1-me@adnano.co> (view parent)
DKIM signature
pass
Download raw message
Thanks for the patch, here are a few comments.

On Saturday, April 16th, 2022 at 12:01, Adnan Maolood <me@adnano.co> wrote:

> Also update the client to use SASL authentication.

Can this patch be split into two? One to add SASL support, another one to
use BOUNCER BIND?

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

Please don't wait for SASL authentication to complete. Instead, send the
commands in bulk, and handle errors in client.ReadMessage().

IOW, send "AUTHENTICATE PLAIN", "AUTHENTICATE <payload>", "BOUNCER BIND" all
in one go.
Details
Message ID
<CKPSHUQ7S05G.1WV5R8GSW0FK9@nitro>
In-Reply-To
<tXwv_fAVFJQEvCSt2kBzLKoTvELcCMYltWTg9kIVRCA87hVAgQhMXl42q8NAwlAnZIBc4FIv_ZvLX-O6MzrsuL5-Fj0QmGieZzf9DAq-_kY=@emersion.fr> (view parent)
DKIM signature
pass
Download raw message
On Fri Jun 10, 2022 at 3:19 AM EDT, Simon Ser wrote:
> Can this patch be split into two? One to add SASL support, another one to
> use BOUNCER BIND?

Done in v2.

> Please don't wait for SASL authentication to complete. Instead, send the
> commands in bulk, and handle errors in client.ReadMessage().
>
> IOW, send "AUTHENTICATE PLAIN", "AUTHENTICATE <payload>", "BOUNCER BIND" all
> in one go.

Done in v2.
Reply to thread Export thread (mbox)