NeoMutt  2025-12-11-911-gd8d604
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 803 of file smtp.c.

804{
805 return smtp_auth_oauth_xoauth2(adata, method, false);
806}
static int smtp_auth_oauth_xoauth2(struct SmtpAccountData *adata, const char *method, bool xoauth2)
Authenticate an SMTP connection using OAUTHBEARER/XOAUTH2.
Definition smtp.c:765
+ 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 814 of file smtp.c.

815{
816 return smtp_auth_oauth_xoauth2(adata, method, true);
817}
+ 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 828 of file smtp.c.

829{
830 struct Buffer *buf = NULL;
831 struct ConnAccount *cac = &adata->conn->account;
832 int rc = -1;
833
834 /* Get username and password. Bail out of any can't be retrieved. */
835 if ((mutt_account_getuser(cac) < 0) || (mutt_account_getpass(cac) < 0))
836 goto error;
837
838 /* Build the initial client response. */
839 buf = buf_pool_get();
840 mutt_sasl_plain_msg(buf, "AUTH PLAIN", cac->user, cac->user, cac->pass);
841 buf_add_printf(buf, "\r\n");
842
843 /* Send request, receive response (with a check for OK code). */
844 if ((mutt_socket_send(adata->conn, buf_string(buf)) < 0) || smtp_get_resp(adata))
845 goto error;
846
847 rc = 0; // Auth was successful
848
849error:
850 if (rc != 0)
851 {
852 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
853 mutt_error(_("%s authentication failed"), "SASL");
854 }
855 buf_pool_release(&buf);
856 return rc;
857}
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:204
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 868 of file smtp.c.

869{
870 char b64[1024] = { 0 };
871 char buf[1026] = { 0 };
872
873 /* Get username and password. Bail out of any can't be retrieved. */
874 if ((mutt_account_getuser(&adata->conn->account) < 0) ||
875 (mutt_account_getpass(&adata->conn->account) < 0))
876 {
877 goto error;
878 }
879
880 /* Send the AUTH LOGIN request. */
881 if (mutt_socket_send(adata->conn, "AUTH LOGIN\r\n") < 0)
882 {
883 goto error;
884 }
885
886 /* Read the 334 VXNlcm5hbWU6 challenge ("Username:" base64-encoded) */
887 int rc = mutt_socket_readln_d(buf, sizeof(buf), adata->conn, MUTT_SOCK_LOG_FULL);
888 if ((rc < 0) || !mutt_str_equal(buf, "334 VXNlcm5hbWU6"))
889 {
890 goto error;
891 }
892
893 /* Send the username */
894 size_t len = snprintf(buf, sizeof(buf), "%s", adata->conn->account.user);
895 mutt_b64_encode(buf, len, b64, sizeof(b64));
896 snprintf(buf, sizeof(buf), "%s\r\n", b64);
897 if (mutt_socket_send(adata->conn, buf) < 0)
898 {
899 goto error;
900 }
901
902 /* Read the 334 UGFzc3dvcmQ6 challenge ("Password:" base64-encoded) */
903 rc = mutt_socket_readln_d(buf, sizeof(buf), adata->conn, MUTT_SOCK_LOG_FULL);
904 if ((rc < 0) || !mutt_str_equal(buf, "334 UGFzc3dvcmQ6"))
905 {
906 goto error;
907 }
908
909 /* Send the password */
910 len = snprintf(buf, sizeof(buf), "%s", adata->conn->account.pass);
911 mutt_b64_encode(buf, len, b64, sizeof(b64));
912 snprintf(buf, sizeof(buf), "%s\r\n", b64);
913 if (mutt_socket_send(adata->conn, buf) < 0)
914 {
915 goto error;
916 }
917
918 /* Check the final response */
919 if (smtp_get_resp(adata) < 0)
920 {
921 goto error;
922 }
923
924 /* If we got here, auth was successful. */
925 return 0;
926
927error:
928 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
929 mutt_error(_("%s authentication failed"), "LOGIN");
930 return -1;
931}
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:665
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: