CAPMAX
};
-#ifdef USE_SASL
static int smtp_auth (CONNECTION* conn);
+static int smtp_auth_oauth (CONNECTION* conn);
+#ifdef USE_SASL
static int smtp_auth_sasl (CONNECTION* conn, const char* mechanisms);
#endif
return -1;
}
-#ifdef USE_SASL
return smtp_auth (conn);
-#else
- mutt_error (_("SMTP authentication requires SASL"));
- mutt_sleep (1);
- return -1;
-#endif /* USE_SASL */
}
return 0;
}
-#ifdef USE_SASL
static int smtp_auth (CONNECTION* conn)
{
int r = SMTP_AUTH_UNAVAIL;
dprint (2, (debugfile, "smtp_authenticate: Trying method %s\n", method));
- r = smtp_auth_sasl (conn, method);
-
+ if (!strcmp (method, "oauthbearer"))
+ {
+ r = smtp_auth_oauth (conn);
+ }
+ else
+ {
+#ifdef USE_SASL
+ r = smtp_auth_sasl (conn, method);
+#else
+ mutt_error (_("SMTP authentication method %s requires SASL"), method);
+ mutt_sleep (1);
+ continue;
+#endif
+ }
if (r == SMTP_AUTH_FAIL && delim)
{
- mutt_error (_("%s authentication failed, trying next method"), method);
- mutt_sleep (1);
+ mutt_error (_("%s authentication failed, trying next method"), method);
+ mutt_sleep (1);
}
else if (r != SMTP_AUTH_UNAVAIL)
- break;
+ break;
}
FREE (&methods);
}
else
+ {
+#ifdef USE_SASL
r = smtp_auth_sasl (conn, AuthMechs);
+#else
+ mutt_error (_("SMTP authentication requires SASL"));
+ mutt_sleep (1);
+ r = SMTP_AUTH_UNAVAIL;
+#endif
+ }
if (r != SMTP_AUTH_SUCCESS)
mutt_account_unsetpass (&conn->account);
return r == SMTP_AUTH_SUCCESS ? 0 : -1;
}
+#ifdef USE_SASL
static int smtp_auth_sasl (CONNECTION* conn, const char* mechlist)
{
sasl_conn_t* saslconn;
return SMTP_AUTH_FAIL;
}
#endif /* USE_SASL */
+
+
+/* smtp_auth_oauth: AUTH=OAUTHBEARER support. See RFC 7628 */
+static int smtp_auth_oauth (CONNECTION* conn)
+{
+ char* ibuf = NULL;
+ char* oauth_buf = NULL;
+ int len, ilen, oalen;
+ int rc;
+
+ mutt_message _("Authenticating (OAUTHBEARER)...");
+
+ /* get auth info */
+ if (mutt_account_getlogin (&conn->account))
+ return SMTP_AUTH_FAIL;
+
+ /* We get the access token from the "smtp_pass" field */
+ if (mutt_account_getpass (&conn->account))
+ return SMTP_AUTH_FAIL;
+
+ /* Determine the length of the keyed message digest, add 50 for
+ * overhead.
+ */
+ oalen = strlen (conn->account.user) +
+ strlen (conn->account.host) +
+ strlen (conn->account.pass) + 50;
+ oauth_buf = safe_malloc (oalen);
+
+ snprintf (oauth_buf, oalen,
+ "n,a=%s,\001host=%s\001port=%d\001auth=Bearer %s\001\001",
+ conn->account.user, conn->account.host, conn->account.port,
+ conn->account.pass);
+
+ /* ibuf must be long enough to store the base64 encoding of
+ * oauth_buf, plus the additional debris.
+ */
+
+ ilen = strlen (oauth_buf) * 2 + 30;
+ ibuf = safe_malloc (ilen);
+ ibuf[0] = '\0';
+
+ safe_strcat (ibuf, ilen, "AUTH OAUTHBEARER ");
+ len = strlen(ibuf);
+
+ mutt_to_base64 ((unsigned char*) (ibuf + len),
+ (unsigned char*) oauth_buf, strlen (oauth_buf),
+ ilen - len);
+ safe_strcat (ibuf, ilen, "\r\n");
+
+ rc = mutt_socket_write (conn, ibuf);
+ FREE (&oauth_buf);
+ FREE (&ibuf);
+
+ if (rc == -1)
+ return SMTP_AUTH_FAIL;
+ if (smtp_get_resp (conn) != 0)
+ return SMTP_AUTH_FAIL;
+
+ return SMTP_AUTH_SUCCESS;
+}