Skip to content

Add support for AUTH PLAIN#148

Open
enndubyu wants to merge 2 commits intocorecode:masterfrom
enndubyu:feature/auth_plain
Open

Add support for AUTH PLAIN#148
enndubyu wants to merge 2 commits intocorecode:masterfrom
enndubyu:feature/auth_plain

Conversation

@enndubyu
Copy link
Copy Markdown

@enndubyu enndubyu commented Jan 13, 2026

Implements #50

I'm using dma to relay outgoing email through Oracle Cloud's smarthost service, but bumped into issue #50 due to Oracle's exclusive support for PLAIN auth.

Changes:

  1. Adds support for PLAIN auth mechanism.
  2. Log an error when there are no auth mechanisms in common with server.

@enndubyu enndubyu marked this pull request as ready for review January 21, 2026 06:56
@enndubyu enndubyu requested a review from corecode February 19, 2026 23:38
@enndubyu enndubyu force-pushed the feature/auth_plain branch from 34ec96f to 4739c31 Compare April 3, 2026 21:12
@enndubyu enndubyu force-pushed the feature/auth_plain branch from 4739c31 to 46e12ad Compare April 4, 2026 13:45
@enndubyu enndubyu force-pushed the feature/auth_plain branch from 46e12ad to 18fa793 Compare April 4, 2026 21:48
@enndubyu
Copy link
Copy Markdown
Author

enndubyu commented Apr 8, 2026

OK, this should be ready to go now. The most recent revision also addresses a few issues that I noticed upon more thorough testing, namely:

  1. Inconsistent error handling logic for LOGIN and CRAM-MD5 methods:

    For CRAM-MD5 login attempts, it tries to send the message unauthenticated if the login fails for any reason other than an error during base64 encoding (in which case it will attempt to login via LOGIN if the server supports it or close the connection if it doesn't). LOGIN will attempt to send unauthenticated if base64 encoding fails or if the server returns a temporary failure, but will close the connection if the server returns a permanent failure.

    I's guessing the intended behavior was something along the lines of the following, which is now used by all three auth methods for this PR:

    • temporary failure -> move on to next available auth method
      • attempt to submit without authentication if we run out of auth methods before encountering a success or permanent failure
    • successful login -> submit message
    • permanent failure -> fail and gracefully end session
  2. Client doesn't send QUIT in any of the error cases.

    Moved the out label up a few lines in deliver_to_host() in order to comply with the RFC.

Full Changelist:

  1. Add support for PLAIN authentication.
  2. Standardize the error handling between AUTH methods.
  3. Clean up confusing log output that occurs in some authentication corner cases, e.g. when the server doesn't support any of the auth methods that dma supports.
  4. Make sure the client sends QUIT before closing connection per RFC 2821.

Test Output

I collected a bunch of test data (consisting of syslog output and SMTP session transcripts) for both the source branch of this PR and the v0.14,1 from the FreeBSD ports tree. I'm pasting just a few examples below in the interest of brevity, but the full output is available here, and includes success and failures cases for each auth method and a combined case to verify that additional auth methods are attempted after temporary failures:

Selected examples

Here are SMTP session transcripts showing a successful AUTH with each of the three methods:

PLAIN

 S: 220 nw-vm-freebsd ESMTP ready
 C: EHLO nw-vm-freebsd
 S: 250-nw-vm-freebsd
 S: 250-AUTH PLAIN
 S: 250 OK
 C: AUTH PLAIN AHRlc3R1c2VyAHRlc3RwYXNz
 S: 235 2.7.0 Authentication successful
 C: MAIL FROM:<nick@nw-vm-freebsd>
 S: 250 OK
 C: RCPT TO:<test@test.com>
 S: 250 OK
 C: DATA
 S: 354 End data with <CR><LF>.<CR><LF>
 C: Received: from nick (uid 1001)
 C: 	(envelope-from nick@nw-vm-freebsd)
 C: 	id 16d5
 C: 	by nw-vm-freebsd (DragonFly Mail Agent v0.14 on nw-vm-freebsd);
 C: 	Fri, 03 Apr 2026 05:54:22 -0700
 C: To: test@test.com
 C: Subject: test subject
 C: Date: Fri, 03 Apr 2026 05:54:22 -0700
 C: Message-Id: <69cfb87e.16d5.618085ed@nw-vm-freebsd>
 C: From: <nick@nw-vm-freebsd>
 C: 
 C: test test test
 C: .
 S: 250 Message accepted for delivery
 C: QUIT
 S: 221 Bye

LOGIN

 S: 220 nw-vm-freebsd ESMTP ready
 C: EHLO nw-vm-freebsd
 S: 250-nw-vm-freebsd
 S: 250-AUTH LOGIN
 S: 250 OK
 C: AUTH LOGIN
 S: 334 VXNlcm5hbWU6
 C: dGVzdHVzZXI=
 S: 334 UGFzc3dvcmQ6
 C: dGVzdHBhc3M=
 S: 235 2.7.0 Authentication successful
 C: MAIL FROM:<nick@nw-vm-freebsd>
 S: 250 OK
 C: RCPT TO:<test@test.com>
 S: 250 OK
 C: DATA
 S: 354 End data with <CR><LF>.<CR><LF>
 C: Received: from nick (uid 1001)
 C: 	(envelope-from nick@nw-vm-freebsd)
 C: 	id 16d3
 C: 	by nw-vm-freebsd (DragonFly Mail Agent v0.14 on nw-vm-freebsd);
 C: 	Fri, 03 Apr 2026 05:52:47 -0700
 C: To: test@test.com
 C: Subject: test subject
 C: Date: Fri, 03 Apr 2026 05:52:47 -0700
 C: Message-Id: <69cfb81f.16d3.f589f4b@nw-vm-freebsd>
 C: From: <nick@nw-vm-freebsd>
 C: 
 C: test test test
 C: .
 S: 250 Message accepted for delivery
 C: QUIT
 S: 221 Bye

CRAM-MD5

 S: 220 nw-vm-freebsd ESMTP ready
 C: EHLO nw-vm-freebsd
 S: 250-nw-vm-freebsd
 S: 250-AUTH CRAM-MD5
 S: 250 OK
 C: AUTH CRAM-MD5
 S: 334 PDE3NzU1NDQ5MjguMjY2MTJAbnctdm0tZnJlZWJzZD4=
 C: dGVzdHVzZXIgOTBhODE4ZDhkYjRkZWFhNTA4NzAzY2M3M2VmZGNhMTU=
 S: 235 2.7.0 Authentication successful
 C: MAIL FROM:<nick@nw-vm-freebsd>
 S: 250 OK
 C: RCPT TO:<test@test.com>
 S: 250 OK
 C: DATA
 S: 354 End data with <CR><LF>.<CR><LF>
 C: Received: from nick (uid 1001)
 C: 	(envelope-from nick@nw-vm-freebsd)
 C: 	id b56a
 C: 	by nw-vm-freebsd (DragonFly Mail Agent v0.14 on nw-vm-freebsd);
 C: 	Tue, 07 Apr 2026 00:33:24 -0700
 C: To: test@test.com
 C: Subject: test subject
 C: Date: Tue, 07 Apr 2026 00:33:24 -0700
 C: Message-Id: <69d4b344.b56a.1406eec2@nw-vm-freebsd>
 C: From: <nick@nw-vm-freebsd>
 C: 
 C: test test test
 C: .
 S: 250 Message accepted for delivery
 C: QUIT
 S: 221 Bye

Temporary auth failures

 S: 220 nw-vm-freebsd ESMTP ready
 C: EHLO nw-vm-freebsd
 S: 250-nw-vm-freebsd
 S: 250-AUTH PLAIN LOGIN CRAM-MD5
 S: 250 OK
 C: AUTH CRAM-MD5
 S: 454 4.7.0 Temporary authentication failure
 C: AUTH LOGIN
 S: 454 4.7.0 Temporary authentication failure
 C: AUTH PLAIN AHRlc3R1c2VyAHRlc3RwYXNz
 S: 454 4.7.0 Temporary authentication failure
 C: MAIL FROM:<nick@nw-vm-freebsd>
 S: 535 5.7.0 Authentication required
 C: QUIT
 S: 221 Bye

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants