~emersion/soju-dev

Add fallback for authentication v1 PROPOSED

gildarts: 1
 Add fallback for authentication

 1 files changed, 23 insertions(+), 2 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~emersion/soju-dev/patches/23120/mbox | git am -3
Learn more about email & git
View this thread in the archives

[RFC PATCH] Add fallback for authentication Export this patch

Prompted by conversation on IRC about enabling tools like IRCCloud
to specify information inside of the password field, since they
don't allow configuring the username field, etc.
Doesn't prevent `:` user in passwords.

This is adding a fallback for authentication to allow providing
username, client, and network inside the password field.

It splits on `:`, but only if the password fails to be recognised
initially.
---
 downstream.go | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/downstream.go b/downstream.go
index 427c9e6..82e17b2 100644
--- a/downstream.go
+++ b/downstream.go
@@ -920,6 +920,21 @@ func unmarshalUsername(rawUsername string) (username, client, network string) {
	return username, client, network
}

func unmarshalUsernameAndPassword(rawPassword string) (username, client, network, password string) {
	password = rawPassword

	i := strings.IndexAny(password, ":")

	if i >= 0 {
		username = rawPassword[:i]
		password = rawPassword[i+1:]
	}

	username, client, network = unmarshalUsername(username)

	return username, client, network, password
}

func (dc *downstreamConn) authenticate(username, password string) error {
	username, clientName, networkName := unmarshalUsername(username)

@@ -936,8 +951,14 @@ func (dc *downstreamConn) authenticate(username, password string) error {

	err = bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
	if err != nil {
		dc.logger.Printf("failed authentication for %q: wrong password: %v", username, err)
		return errAuthFailed
		_, clientName, networkName, password = unmarshalUsernameAndPassword(password)

		err2 := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
		if err2 != nil {
			dc.logger.Printf("failed authentication for %q: wrong password: %v", username, err)

			return errAuthFailed
		}
	}

	dc.user = dc.srv.getUser(username)
-- 
2.25.1
I'm still not a fan of shoe-honing the network name into the password
field. Putting it in the username or nick is already a hack.

I'd rather see clients patched to support changing the username/nick.
I don't think clients should update their settings (ie. their
configured username or nick) when the server changes it.