summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2023-03-06 18:55:06 -0800
committerKevin McCarthy <kevin@8t8.us>2023-03-12 19:29:32 -0700
commit216dd145d41dd079fc9676fd2eb09ad16097627d (patch)
treede5ae5a117b76991124f1438b65017c6b0ede6d0
parent5df86199463b5cf893fb6a37457fa02804d3b02a (diff)
Improve smtp oauth authentication.
Split XOAUTH2 to use two steps. This follows the microsoft.com documentation example for smtp. Since office365 is the main site using XOAUTH2 now, it's better to match their documentation. It also matches msmtp's behavior, which probably means somewhere or another needs it that way. At the same time, improve response code checking. Mutt was using smtp_get_resp() before, which returns 0 for both a ready and success response code. Make sure it's a success response code when done authenticating.
-rw-r--r--smtp.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/smtp.c b/smtp.c
index d665456d..93dee06c 100644
--- a/smtp.c
+++ b/smtp.c
@@ -849,8 +849,9 @@ fail:
/* smtp_auth_oauth: AUTH=OAUTHBEARER support. See RFC 7628 */
static int smtp_auth_oauth (CONNECTION* conn, int xoauth2)
{
- int rc = SMTP_AUTH_FAIL;
+ int rc = SMTP_AUTH_FAIL, smtp_rc;
BUFFER *bearertoken = NULL, *authline = NULL;
+ BUFFER *input_buf = NULL, *smtp_response_buf = NULL;
const char *authtype;
authtype = xoauth2 ? "XOAUTH2" : "OAUTHBEARER";
@@ -862,16 +863,41 @@ static int smtp_auth_oauth (CONNECTION* conn, int xoauth2)
bearertoken = mutt_buffer_pool_get ();
authline = mutt_buffer_pool_get ();
+ input_buf = mutt_buffer_pool_get ();
+ smtp_response_buf = mutt_buffer_pool_get ();
/* We get the access token from the smtp_oauth_refresh_command */
if (mutt_account_getoauthbearer (&conn->account, bearertoken, xoauth2))
goto cleanup;
- mutt_buffer_printf (authline, "AUTH %s %s\r\n", authtype, mutt_b2s (bearertoken));
+ if (xoauth2)
+ {
+ mutt_buffer_printf (authline, "AUTH %s\r\n", authtype);
+ if (mutt_socket_write (conn, mutt_b2s (authline)) == -1)
+ goto cleanup;
+ if (smtp_get_auth_response (conn, input_buf, &smtp_rc, smtp_response_buf) < 0)
+ goto saslcleanup;
+ if (smtp_rc != smtp_ready)
+ goto saslcleanup;
+
+ mutt_buffer_printf (authline, "%s\r\n", mutt_b2s (bearertoken));
+ }
+ else
+ {
+ mutt_buffer_printf (authline, "AUTH %s %s\r\n", authtype, mutt_b2s (bearertoken));
+ }
if (mutt_socket_write (conn, mutt_b2s (authline)) == -1)
goto cleanup;
- if (smtp_get_resp (conn) != 0)
+ if (smtp_get_auth_response (conn, input_buf, &smtp_rc, smtp_response_buf) < 0)
+ goto saslcleanup;
+ if (!smtp_success (smtp_rc))
+ goto saslcleanup;
+
+ rc = SMTP_AUTH_SUCCESS;
+
+saslcleanup:
+ if (rc != SMTP_AUTH_SUCCESS)
{
/* The error response was in SASL continuation, so continue the SASL
* to cause a failure and exit SASL input. See RFC 7628 3.2.3
@@ -879,13 +905,12 @@ static int smtp_auth_oauth (CONNECTION* conn, int xoauth2)
*/
mutt_socket_write (conn, "AQ==\r\n");
smtp_get_resp (conn);
- goto cleanup;
}
- rc = SMTP_AUTH_SUCCESS;
-
cleanup:
mutt_buffer_pool_release (&bearertoken);
mutt_buffer_pool_release (&authline);
+ mutt_buffer_pool_release (&input_buf);
+ mutt_buffer_pool_release (&smtp_response_buf);
return rc;
}