NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
SMTP Authentication API

Authenticate an SMTP connection. More...

Functions

static int smtp_auth_oauth (struct SmtpAccountData *adata, const char *method)
 Authenticate an SMTP connection using OAUTHBEARER - Implements SmtpAuth::authenticate() -.
 
static int smtp_auth_xoauth2 (struct SmtpAccountData *adata, const char *method)
 Authenticate an SMTP connection using XOAUTH2 - Implements SmtpAuth::authenticate() -.
 
static int smtp_auth_plain (struct SmtpAccountData *adata, const char *method)
 Authenticate using plain text - Implements SmtpAuth::authenticate() -.
 
static int smtp_auth_login (struct SmtpAccountData *adata, const char *method)
 Authenticate using plain text - Implements SmtpAuth::authenticate() -.
 

Detailed Description

Authenticate an SMTP connection.

Parameters
adataSmtp Account data
methodUse this named method, or any available method if NULL
Return values
numResult, e.g. SMTP_AUTH_SUCCESS

Function Documentation

◆ smtp_auth_oauth()

static int smtp_auth_oauth ( struct SmtpAccountData * adata,
const char * method )
static

Authenticate an SMTP connection using OAUTHBEARER - Implements SmtpAuth::authenticate() -.

Parameters
adataSMTP Account data
methodAuthentication method (not used)
Return values
numResult, e.g. SMTP_AUTH_SUCCESS

Definition at line 807 of file smtp.c.

808{
809 return smtp_auth_oauth_xoauth2(adata, method, false);
810}
static int smtp_auth_oauth_xoauth2(struct SmtpAccountData *adata, const char *method, bool xoauth2)
Authenticate an SMTP connection using OAUTHBEARER/XOAUTH2.
Definition smtp.c:769
+ Here is the call graph for this function:

◆ smtp_auth_xoauth2()

static int smtp_auth_xoauth2 ( struct SmtpAccountData * adata,
const char * method )
static

Authenticate an SMTP connection using XOAUTH2 - Implements SmtpAuth::authenticate() -.

Parameters
adataSMTP Account data
methodAuthentication method (not used)
Return values
numResult, e.g. SMTP_AUTH_SUCCESS

Definition at line 818 of file smtp.c.

819{
820 return smtp_auth_oauth_xoauth2(adata, method, true);
821}
+ Here is the call graph for this function:

◆ smtp_auth_plain()

static int smtp_auth_plain ( struct SmtpAccountData * adata,
const char * method )
static

Authenticate using plain text - Implements SmtpAuth::authenticate() -.

Parameters
adataSMTP Account data
methodAuthentication method (not used)
Return values
0Success
<0Error, e.g. SMTP_AUTH_FAIL
Note
method is "PLAIN"

Definition at line 832 of file smtp.c.

833{
834 struct Buffer *buf = NULL;
835 struct ConnAccount *cac = &adata->conn->account;
836 int rc = -1;
837
838 /* Get username and password. Bail out of any can't be retrieved. */
839 if ((mutt_account_getuser(cac) < 0) || (mutt_account_getpass(cac) < 0))
840 goto error;
841
842 /* Build the initial client response. */
843 buf = buf_pool_get();
844 mutt_sasl_plain_msg(buf, "AUTH PLAIN", cac->user, cac->user, cac->pass);
845 buf_add_printf(buf, "\r\n");
846
847 /* Send request, receive response (with a check for OK code). */
848 if ((mutt_socket_send(adata->conn, buf_string(buf)) < 0) || smtp_get_resp(adata))
849 goto error;
850
851 rc = 0; // Auth was successful
852
853error:
854 if (rc != 0)
855 {
856 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
857 mutt_error(_("%s authentication failed"), "SASL");
858 }
859 buf_pool_release(&buf);
860 return rc;
861}
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:211
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
int mutt_account_getpass(struct ConnAccount *cac)
Fetch password into ConnAccount, if necessary.
int mutt_account_getuser(struct ConnAccount *cac)
Retrieve username into ConnAccount, if necessary.
Definition connaccount.c:51
#define mutt_error(...)
Definition logging2.h:94
#define _(a)
Definition message.h:28
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
size_t mutt_sasl_plain_msg(struct Buffer *buf, const char *cmd, const char *authz, const char *user, const char *pass)
Construct a base64 encoded SASL PLAIN message.
Definition sasl_plain.c:50
static int smtp_get_resp(struct SmtpAccountData *adata)
Read a command response from the SMTP server.
Definition smtp.c:146
#define mutt_socket_send(conn, buf)
Definition socket.h:56
String manipulation buffer.
Definition buffer.h:36
Login details for a remote server.
Definition connaccount.h:59
char user[128]
Username.
Definition connaccount.h:62
char pass[256]
Password.
Definition connaccount.h:63
struct ConnAccount account
Account details: username, password, etc.
Definition connection.h:49
struct Connection * conn
Server Connection.
Definition smtp.c:105
+ Here is the call graph for this function:

◆ smtp_auth_login()

static int smtp_auth_login ( struct SmtpAccountData * adata,
const char * method )
static

Authenticate using plain text - Implements SmtpAuth::authenticate() -.

Parameters
adataSMTP Account data
methodAuthentication method (not used)
Return values
0Success
<0Error, e.g. SMTP_AUTH_FAIL
Note
method is "LOGIN"

Definition at line 872 of file smtp.c.

873{
874 char b64[1024] = { 0 };
875 char buf[1026] = { 0 };
876
877 /* Get username and password. Bail out of any can't be retrieved. */
878 if ((mutt_account_getuser(&adata->conn->account) < 0) ||
879 (mutt_account_getpass(&adata->conn->account) < 0))
880 {
881 goto error;
882 }
883
884 /* Send the AUTH LOGIN request. */
885 if (mutt_socket_send(adata->conn, "AUTH LOGIN\r\n") < 0)
886 {
887 goto error;
888 }
889
890 /* Read the 334 VXNlcm5hbWU6 challenge ("Username:" base64-encoded) */
891 int rc = mutt_socket_readln_d(buf, sizeof(buf), adata->conn, MUTT_SOCK_LOG_FULL);
892 if ((rc < 0) || !mutt_str_equal(buf, "334 VXNlcm5hbWU6"))
893 {
894 goto error;
895 }
896
897 /* Send the username */
898 size_t len = snprintf(buf, sizeof(buf), "%s", adata->conn->account.user);
899 mutt_b64_encode(buf, len, b64, sizeof(b64));
900 snprintf(buf, sizeof(buf), "%s\r\n", b64);
901 if (mutt_socket_send(adata->conn, buf) < 0)
902 {
903 goto error;
904 }
905
906 /* Read the 334 UGFzc3dvcmQ6 challenge ("Password:" base64-encoded) */
907 rc = mutt_socket_readln_d(buf, sizeof(buf), adata->conn, MUTT_SOCK_LOG_FULL);
908 if ((rc < 0) || !mutt_str_equal(buf, "334 UGFzc3dvcmQ6"))
909 {
910 goto error;
911 }
912
913 /* Send the password */
914 len = snprintf(buf, sizeof(buf), "%s", adata->conn->account.pass);
915 mutt_b64_encode(buf, len, b64, sizeof(b64));
916 snprintf(buf, sizeof(buf), "%s\r\n", b64);
917 if (mutt_socket_send(adata->conn, buf) < 0)
918 {
919 goto error;
920 }
921
922 /* Check the final response */
923 if (smtp_get_resp(adata) < 0)
924 {
925 goto error;
926 }
927
928 /* If we got here, auth was successful. */
929 return 0;
930
931error:
932 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
933 mutt_error(_("%s authentication failed"), "LOGIN");
934 return -1;
935}
size_t mutt_b64_encode(const char *in, size_t inlen, char *out, size_t outlen)
Convert raw bytes to a base64 string.
Definition base64.c:148
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
Definition socket.c:238
#define MUTT_SOCK_LOG_FULL
Log everything including full protocol.
Definition socket.h:53
+ Here is the call graph for this function: