NeoMutt  2024-04-25-1-g3de005
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 771 of file smtp.c.

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

783{
784 return smtp_auth_oauth_xoauth2(adata, method, true);
785}
+ 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 796 of file smtp.c.

797{
798 struct Buffer *buf = NULL;
799 struct ConnAccount *cac = &adata->conn->account;
800 int rc = -1;
801
802 /* Get username and password. Bail out of any can't be retrieved. */
803 if ((mutt_account_getuser(cac) < 0) || (mutt_account_getpass(cac) < 0))
804 goto error;
805
806 /* Build the initial client response. */
807 buf = buf_pool_get();
808 mutt_sasl_plain_msg(buf, "AUTH PLAIN", cac->user, cac->user, cac->pass);
809 buf_add_printf(buf, "\r\n");
810
811 /* Send request, receive response (with a check for OK code). */
812 if ((mutt_socket_send(adata->conn, buf_string(buf)) < 0) || smtp_get_resp(adata))
813 goto error;
814
815 rc = 0; // Auth was successful
816
817error:
818 if (rc != 0)
819 {
820 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
821 mutt_error(_("%s authentication failed"), "SASL");
822 }
823 buf_pool_release(&buf);
824 return rc;
825}
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
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.
Definition: connaccount.c:131
int mutt_account_getuser(struct ConnAccount *cac)
Retrieve username into ConnAccount, if necessary.
Definition: connaccount.c:52
#define mutt_error(...)
Definition: logging2.h:92
#define _(a)
Definition: message.h:28
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
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:141
#define mutt_socket_send(conn, buf)
Definition: socket.h:57
String manipulation buffer.
Definition: buffer.h:36
Login details for a remote server.
Definition: connaccount.h:53
char user[128]
Username.
Definition: connaccount.h:56
char pass[256]
Password.
Definition: connaccount.h:57
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:49
struct Connection * conn
Server Connection.
Definition: smtp.c:100
+ 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 836 of file smtp.c.

837{
838 char b64[1024] = { 0 };
839 char buf[1026] = { 0 };
840
841 /* Get username and password. Bail out of any can't be retrieved. */
842 if ((mutt_account_getuser(&adata->conn->account) < 0) ||
843 (mutt_account_getpass(&adata->conn->account) < 0))
844 {
845 goto error;
846 }
847
848 /* Send the AUTH LOGIN request. */
849 if (mutt_socket_send(adata->conn, "AUTH LOGIN\r\n") < 0)
850 {
851 goto error;
852 }
853
854 /* Read the 334 VXNlcm5hbWU6 challenge ("Username:" base64-encoded) */
855 int rc = mutt_socket_readln_d(buf, sizeof(buf), adata->conn, MUTT_SOCK_LOG_FULL);
856 if ((rc < 0) || !mutt_str_equal(buf, "334 VXNlcm5hbWU6"))
857 {
858 goto error;
859 }
860
861 /* Send the username */
862 size_t len = snprintf(buf, sizeof(buf), "%s", adata->conn->account.user);
863 mutt_b64_encode(buf, len, b64, sizeof(b64));
864 snprintf(buf, sizeof(buf), "%s\r\n", b64);
865 if (mutt_socket_send(adata->conn, buf) < 0)
866 {
867 goto error;
868 }
869
870 /* Read the 334 UGFzc3dvcmQ6 challenge ("Password:" base64-encoded) */
871 rc = mutt_socket_readln_d(buf, sizeof(buf), adata->conn, MUTT_SOCK_LOG_FULL);
872 if ((rc < 0) || !mutt_str_equal(buf, "334 UGFzc3dvcmQ6"))
873 {
874 goto error;
875 }
876
877 /* Send the password */
878 len = snprintf(buf, sizeof(buf), "%s", adata->conn->account.pass);
879 mutt_b64_encode(buf, len, b64, sizeof(b64));
880 snprintf(buf, sizeof(buf), "%s\r\n", b64);
881 if (mutt_socket_send(adata->conn, buf) < 0)
882 {
883 goto error;
884 }
885
886 /* Check the final response */
887 if (smtp_get_resp(adata) < 0)
888 {
889 goto error;
890 }
891
892 /* If we got here, auth was successful. */
893 return 0;
894
895error:
896 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
897 mutt_error(_("%s authentication failed"), "LOGIN");
898 return -1;
899}
size_t mutt_b64_encode(const char *in, size_t inlen, char *out, size_t outlen)
Convert raw bytes to null-terminated base64 string.
Definition: base64.c:87
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:654
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
Definition: socket.h:54
+ Here is the call graph for this function: