~rjarry/aerc#282: 
Add support for CRAM-MD5 authentication

As per: https://lists.sr.ht/~rjarry/aerc-discuss/%3CD4YL8O3SL7QH.W4JIYOV5HMNE@fastmail.net%3E

My Mail server of choice (mx.sdf.org) uses "MD5 Challenge-Response" AKA CRAM-MD5. But https://git.sr.ht/~rjarry/aerc/tree/master/item/lib/send/sasl.go does not handle that, as emersion/go-sasl misses it, too.

Adding it would be trivial (10 lines from https://github.com/toorop/tmail/blob/a7b1964828ecec1f7d49aa1e318d893b39ca7d60/core/deliverd_auth.go#L99)

I'd submit a PR but I'm not a developer so I'm not confident in doing so.

Thank you -- I love aerc <3

Status
REPORTED
Submitter
~pfr
Assigned to
No-one
Submitted
3 months ago
Updated
3 months ago
Labels
No labels applied.

~rjarry 3 months ago

Hi David,

That is indeed unfortunate. Did you try with smtps:// ?

It is possible that go-sasl does not support CRAM-MD5 on purpose. I have read in a couple of places that CRAM-MD5 was deprecated in favor of the more "secure" SCRAM-SHA-256 mechanism.

It would be best to open an issue there. Feel free to tag me if you do. The patch shouldn't be complicated.

Cheers.

~pfr 3 months ago

When I try with smtps:// I get: send:: Connection Failed: smtp.DialTLS: context deadline exceed

if I try with smtps+login:// I get: send:: Connection Failed: smtp.DialTLS: tls: first record does not look like a TLS handshake

I'll open an issue over on GitHub go-sasl

~tgulacsi 3 months ago

lib/send/sasl.go misses CRAM-MD5 - it is an insecure protocol, after all (https://github.com/golang/go/issues/61952), but net/smtp implements it, and cannot remove it for backwards compatibility, so we can use it, does not need to reimplement it:

diff --git a/lib/send/sasl.go b/lib/send/sasl.go
index 01e006e3..13451ce3 100644
--- a/lib/send/sasl.go
+++ b/lib/send/sasl.go
@@ -2,6 +2,7 @@ package send
 
 import (
 	"fmt"
+	"net/smtp"
 	"net/url"
 
 	"github.com/emersion/go-sasl"
@@ -23,6 +24,10 @@ func newSaslClient(auth string, uri *url.URL) (sasl.Client, error) {
 	case "plain":
 		password, _ := uri.User.Password()
 		saslClient = sasl.NewPlainClient("", uri.User.Username(), password)
+	case "cram-md5":
+		password, _ := uri.User.Password()
+		saslClient = stdSaslClient{smtp.CRAMMD5Auth(uri.User.Username(), password)}
+
 	case "oauthbearer":
 		q := uri.Query()
 		oauth2 := &oauth2.Config{}
@@ -70,8 +75,22 @@ func newSaslClient(auth string, uri *url.URL) (sasl.Client, error) {
 			password = token.AccessToken
 		}
 		saslClient = lib.NewXoauth2Client(uri.User.Username(), password)
+
 	default:
 		return nil, fmt.Errorf("Unsupported auth mechanism %s", auth)
 	}
 	return saslClient, nil
 }
+
+type stdSaslClient struct {
+	smtp.Auth
+}
+
+var _ sasl.Client = stdSaslClient{}
+
+func (c stdSaslClient) Start() (mech string, ir []byte, err error) {
+	return c.Auth.Start(nil)
+}
+func (c stdSaslClient) Next(challenge []byte) (response []byte, err error) {
+	return c.Auth.Next(challenge, len(challenge) != 0)
+}

~pfr 3 months ago

Could someone with more knowledge and experience than me submit this patch as a PR? Is this likely to be accepted?

Register here or Log in to comment, or comment via email.