NeoMutt  2020-06-26-30-g76c339
Teaching an old dog new tricks
DOXYGEN
smtp.c File Reference

Send email to an SMTP server. More...

#include "config.h"
#include <netdb.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "email/lib.h"
#include "conn/lib.h"
#include "smtp.h"
#include "globals.h"
#include "init.h"
#include "mutt_account.h"
#include "mutt_socket.h"
#include "progress.h"
#include "sendlib.h"
#include "config/lib.h"
#include <sasl/sasl.h>
#include <sasl/saslutil.h>
#include "options.h"
+ Include dependency graph for smtp.c:

Go to the source code of this file.

Macros

#define smtp_success(x)   ((x) / 100 == 2)
 
#define SMTP_READY   334
 
#define SMTP_CONTINUE   354
 
#define SMTP_ERR_READ   -2
 
#define SMTP_ERR_WRITE   -3
 
#define SMTP_ERR_CODE   -4
 
#define SMTP_PORT   25
 
#define SMTPS_PORT   465
 
#define SMTP_AUTH_SUCCESS   0
 
#define SMTP_AUTH_UNAVAIL   1
 
#define SMTP_AUTH_FAIL   -1
 
#define SMTP_CAP_NO_FLAGS   0
 No flags are set. More...
 
#define SMTP_CAP_STARTTLS   (1 << 0)
 Server supports STARTTLS command. More...
 
#define SMTP_CAP_AUTH   (1 << 1)
 Server supports AUTH command. More...
 
#define SMTP_CAP_DSN   (1 << 2)
 Server supports Delivery Status Notification. More...
 
#define SMTP_CAP_EIGHTBITMIME   (1 << 3)
 Server supports 8-bit MIME content. More...
 
#define SMTP_CAP_SMTPUTF8   (1 << 4)
 Server accepts UTF-8 strings. More...
 
#define SMTP_CAP_ALL   ((1 << 5) - 1)
 

Typedefs

typedef uint8_t SmtpCapFlags
 SMTP server capabilities. More...
 

Functions

static bool valid_smtp_code (char *buf, size_t buflen, int *n)
 Is the is a valid SMTP return code? More...
 
static int smtp_get_resp (struct Connection *conn)
 Read a command response from the SMTP server. More...
 
static int smtp_rcpt_to (struct Connection *conn, const struct AddressList *al)
 Set the recipient to an Address. More...
 
static int smtp_data (struct Connection *conn, const char *msgfile)
 Send data to an SMTP server. More...
 
static bool address_uses_unicode (const char *a)
 Do any addresses use Unicode. More...
 
static bool addresses_use_unicode (const struct AddressList *al)
 Do any of a list of addresses use Unicode. More...
 
static const char * smtp_get_field (enum ConnAccountField field)
 Get connection login credentials - Implements ConnAccount::get_field() More...
 
static int smtp_fill_account (struct ConnAccount *cac)
 Create ConnAccount object from SMTP Url. More...
 
static int smtp_helo (struct Connection *conn, bool esmtp)
 Say hello to an SMTP Server. More...
 
static int smtp_auth_sasl (struct Connection *conn, const char *mechlist)
 Authenticate using SASL. More...
 
static int smtp_auth_oauth (struct Connection *conn)
 Authenticate an SMTP connection using OAUTHBEARER. More...
 
static int smtp_auth_plain (struct Connection *conn)
 Authenticate using plain text. More...
 
static int smtp_auth (struct Connection *conn)
 Authenticate to an SMTP server. More...
 
static int smtp_open (struct Connection *conn, bool esmtp)
 Open an SMTP Connection. More...
 
int mutt_smtp_send (const struct AddressList *from, const struct AddressList *to, const struct AddressList *cc, const struct AddressList *bcc, const char *msgfile, bool eightbit)
 Send a message using SMTP. More...
 

Variables

struct SlistC_SmtpAuthenticators
 Config: (smtp) List of allowed authentication methods. More...
 
char * C_SmtpOauthRefreshCommand
 Config: (smtp) External command to generate OAUTH refresh token. More...
 
char * C_SmtpPass
 Config: (smtp) Password for the SMTP server. More...
 
char * C_SmtpUser
 Config: (smtp) Username for the SMTP server. More...
 
static char * AuthMechs = NULL
 
static SmtpCapFlags Capabilities
 

Detailed Description

Send email to an SMTP server.

Authors
  • Michael R. Elkins
  • Brendan Cully
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file smtp.c.

Macro Definition Documentation

◆ smtp_success

#define smtp_success (   x)    ((x) / 100 == 2)

Definition at line 68 of file smtp.c.

◆ SMTP_READY

#define SMTP_READY   334

Definition at line 69 of file smtp.c.

◆ SMTP_CONTINUE

#define SMTP_CONTINUE   354

Definition at line 70 of file smtp.c.

◆ SMTP_ERR_READ

#define SMTP_ERR_READ   -2

Definition at line 72 of file smtp.c.

◆ SMTP_ERR_WRITE

#define SMTP_ERR_WRITE   -3

Definition at line 73 of file smtp.c.

◆ SMTP_ERR_CODE

#define SMTP_ERR_CODE   -4

Definition at line 74 of file smtp.c.

◆ SMTP_PORT

#define SMTP_PORT   25

Definition at line 76 of file smtp.c.

◆ SMTPS_PORT

#define SMTPS_PORT   465

Definition at line 77 of file smtp.c.

◆ SMTP_AUTH_SUCCESS

#define SMTP_AUTH_SUCCESS   0

Definition at line 79 of file smtp.c.

◆ SMTP_AUTH_UNAVAIL

#define SMTP_AUTH_UNAVAIL   1

Definition at line 80 of file smtp.c.

◆ SMTP_AUTH_FAIL

#define SMTP_AUTH_FAIL   -1

Definition at line 81 of file smtp.c.

◆ SMTP_CAP_NO_FLAGS

#define SMTP_CAP_NO_FLAGS   0

No flags are set.

Definition at line 88 of file smtp.c.

◆ SMTP_CAP_STARTTLS

#define SMTP_CAP_STARTTLS   (1 << 0)

Server supports STARTTLS command.

Definition at line 89 of file smtp.c.

◆ SMTP_CAP_AUTH

#define SMTP_CAP_AUTH   (1 << 1)

Server supports AUTH command.

Definition at line 90 of file smtp.c.

◆ SMTP_CAP_DSN

#define SMTP_CAP_DSN   (1 << 2)

Server supports Delivery Status Notification.

Definition at line 91 of file smtp.c.

◆ SMTP_CAP_EIGHTBITMIME

#define SMTP_CAP_EIGHTBITMIME   (1 << 3)

Server supports 8-bit MIME content.

Definition at line 92 of file smtp.c.

◆ SMTP_CAP_SMTPUTF8

#define SMTP_CAP_SMTPUTF8   (1 << 4)

Server accepts UTF-8 strings.

Definition at line 93 of file smtp.c.

◆ SMTP_CAP_ALL

#define SMTP_CAP_ALL   ((1 << 5) - 1)

Definition at line 95 of file smtp.c.

Typedef Documentation

◆ SmtpCapFlags

typedef uint8_t SmtpCapFlags

SMTP server capabilities.

Flags, e.g. SMTP_CAP_STARTTLS

Definition at line 87 of file smtp.c.

Function Documentation

◆ valid_smtp_code()

static bool valid_smtp_code ( char *  buf,
size_t  buflen,
int *  n 
)
static

Is the is a valid SMTP return code?

Parameters
[in]bufString to check
[in]buflenLength of string
[out]nNumeric value of code
Return values
trueValid number

Definition at line 108 of file smtp.c.

109 {
110  char code[4];
111 
112  if (buflen < 4)
113  return false;
114  code[0] = buf[0];
115  code[1] = buf[1];
116  code[2] = buf[2];
117  code[3] = '\0';
118  if (mutt_str_atoi(code, n) < 0)
119  return false;
120  return true;
121 }
int mutt_str_atoi(const char *str, int *dst)
Convert ASCII string to an integer.
Definition: string.c:257
int n
Definition: acutest.h:492
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_get_resp()

static int smtp_get_resp ( struct Connection conn)
static

Read a command response from the SMTP server.

Parameters
connSMTP connection
Return values
0Success (2xx code) or continue (354 code)
-1Write error, or any other response code

Definition at line 129 of file smtp.c.

130 {
131  int n;
132  char buf[1024];
133 
134  do
135  {
136  n = mutt_socket_readln(buf, sizeof(buf), conn);
137  if (n < 4)
138  {
139  /* read error, or no response code */
140  return SMTP_ERR_READ;
141  }
142  const char *s = buf + 4; /* Skip the response code and the space/dash */
143  size_t plen;
144 
145  if (mutt_istr_startswith(s, "8BITMIME"))
147  else if ((plen = mutt_istr_startswith(s, "AUTH ")))
148  {
150  FREE(&AuthMechs);
151  AuthMechs = mutt_str_dup(s + plen);
152  }
153  else if (mutt_istr_startswith(s, "DSN"))
155  else if (mutt_istr_startswith(s, "STARTTLS"))
157  else if (mutt_istr_startswith(s, "SMTPUTF8"))
159 
160  if (!valid_smtp_code(buf, n, &n))
161  return SMTP_ERR_CODE;
162 
163  } while (buf[3] == '-');
164 
165  if (smtp_success(n) || (n == SMTP_CONTINUE))
166  return 0;
167 
168  mutt_error(_("SMTP session failed: %s"), buf);
169  return -1;
170 }
#define SMTP_CAP_STARTTLS
Server supports STARTTLS command.
Definition: smtp.c:89
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
#define SMTP_CAP_SMTPUTF8
Server accepts UTF-8 strings.
Definition: smtp.c:93
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define _(a)
Definition: message.h:28
static SmtpCapFlags Capabilities
Definition: smtp.c:99
#define SMTP_ERR_READ
Definition: smtp.c:72
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:177
#define smtp_success(x)
Definition: smtp.c:68
#define mutt_socket_readln(buf, buflen, conn)
Definition: mutt_socket.h:36
#define SMTP_ERR_CODE
Definition: smtp.c:74
int n
Definition: acutest.h:492
static bool valid_smtp_code(char *buf, size_t buflen, int *n)
Is the is a valid SMTP return code?
Definition: smtp.c:108
#define mutt_error(...)
Definition: logging.h:84
#define SMTP_CONTINUE
Definition: smtp.c:70
#define SMTP_CAP_EIGHTBITMIME
Server supports 8-bit MIME content.
Definition: smtp.c:92
#define FREE(x)
Definition: memory.h:40
#define SMTP_CAP_AUTH
Server supports AUTH command.
Definition: smtp.c:90
static char * AuthMechs
Definition: smtp.c:98
#define SMTP_CAP_DSN
Server supports Delivery Status Notification.
Definition: smtp.c:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_rcpt_to()

static int smtp_rcpt_to ( struct Connection conn,
const struct AddressList *  al 
)
static

Set the recipient to an Address.

Parameters
connServer Connection
alAddressList to use
Return values
0Success
<0Error, e.g. SMTP_ERR_WRITE

Definition at line 179 of file smtp.c.

180 {
181  if (!al)
182  return 0;
183 
184  struct Address *a = NULL;
185  TAILQ_FOREACH(a, al, entries)
186  {
187  /* weed out group mailboxes, since those are for display only */
188  if (!a->mailbox || a->group)
189  {
190  continue;
191  }
192  char buf[1024];
194  snprintf(buf, sizeof(buf), "RCPT TO:<%s> NOTIFY=%s\r\n", a->mailbox, C_DsnNotify);
195  else
196  snprintf(buf, sizeof(buf), "RCPT TO:<%s>\r\n", a->mailbox);
197  if (mutt_socket_send(conn, buf) == -1)
198  return SMTP_ERR_WRITE;
199  int rc = smtp_get_resp(conn);
200  if (rc != 0)
201  return rc;
202  }
203 
204  return 0;
205 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
static SmtpCapFlags Capabilities
Definition: smtp.c:99
#define SMTP_ERR_WRITE
Definition: smtp.c:73
static int smtp_get_resp(struct Connection *conn)
Read a command response from the SMTP server.
Definition: smtp.c:129
bool group
Group mailbox?
Definition: address.h:38
WHERE char * C_DsnNotify
Config: Request notification for message delivery or delay.
Definition: globals.h:107
#define SMTP_CAP_DSN
Server supports Delivery Status Notification.
Definition: smtp.c:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_data()

static int smtp_data ( struct Connection conn,
const char *  msgfile 
)
static

Send data to an SMTP server.

Parameters
connSMTP Connection
msgfileFilename containing data
Return values
0Success
<0Error, e.g. SMTP_ERR_WRITE

Definition at line 214 of file smtp.c.

215 {
216  char buf[1024];
217  struct Progress progress;
218  struct stat st;
219  int rc, term = 0;
220  size_t buflen = 0;
221 
222  FILE *fp = fopen(msgfile, "r");
223  if (!fp)
224  {
225  mutt_error(_("SMTP session failed: unable to open %s"), msgfile);
226  return -1;
227  }
228  stat(msgfile, &st);
229  unlink(msgfile);
230  mutt_progress_init(&progress, _("Sending message..."), MUTT_PROGRESS_NET, st.st_size);
231 
232  snprintf(buf, sizeof(buf), "DATA\r\n");
233  if (mutt_socket_send(conn, buf) == -1)
234  {
235  mutt_file_fclose(&fp);
236  return SMTP_ERR_WRITE;
237  }
238  rc = smtp_get_resp(conn);
239  if (rc != 0)
240  {
241  mutt_file_fclose(&fp);
242  return rc;
243  }
244 
245  while (fgets(buf, sizeof(buf) - 1, fp))
246  {
247  buflen = mutt_str_len(buf);
248  term = buflen && buf[buflen - 1] == '\n';
249  if (term && ((buflen == 1) || (buf[buflen - 2] != '\r')))
250  snprintf(buf + buflen - 1, sizeof(buf) - buflen + 1, "\r\n");
251  if (buf[0] == '.')
252  {
253  if (mutt_socket_send_d(conn, ".", MUTT_SOCK_LOG_FULL) == -1)
254  {
255  mutt_file_fclose(&fp);
256  return SMTP_ERR_WRITE;
257  }
258  }
259  if (mutt_socket_send_d(conn, buf, MUTT_SOCK_LOG_FULL) == -1)
260  {
261  mutt_file_fclose(&fp);
262  return SMTP_ERR_WRITE;
263  }
264  mutt_progress_update(&progress, ftell(fp), -1);
265  }
266  if (!term && buflen && (mutt_socket_send_d(conn, "\r\n", MUTT_SOCK_LOG_FULL) == -1))
267  {
268  mutt_file_fclose(&fp);
269  return SMTP_ERR_WRITE;
270  }
271  mutt_file_fclose(&fp);
272 
273  /* terminate the message body */
274  if (mutt_socket_send(conn, ".\r\n") == -1)
275  return SMTP_ERR_WRITE;
276 
277  rc = smtp_get_resp(conn);
278  if (rc != 0)
279  return rc;
280 
281  return 0;
282 }
Progress tracks bytes, according to C_NetInc.
Definition: progress.h:44
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
#define _(a)
Definition: message.h:28
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
A progress bar.
Definition: progress.h:50
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define mutt_socket_send_d(conn, buf, dbg)
Definition: mutt_socket.h:38
#define SMTP_ERR_WRITE
Definition: smtp.c:73
static int smtp_get_resp(struct Connection *conn)
Read a command response from the SMTP server.
Definition: smtp.c:129
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:153
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:639
#define mutt_error(...)
Definition: logging.h:84
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ address_uses_unicode()

static bool address_uses_unicode ( const char *  a)
static

Do any addresses use Unicode.

Parameters
aAddress list to check
Return values
trueif any of the string of addresses use 8-bit characters

Definition at line 289 of file smtp.c.

290 {
291  if (!a)
292  return false;
293 
294  while (*a)
295  {
296  if ((unsigned char) *a & (1 << 7))
297  return true;
298  a++;
299  }
300 
301  return false;
302 }
+ Here is the caller graph for this function:

◆ addresses_use_unicode()

static bool addresses_use_unicode ( const struct AddressList *  al)
static

Do any of a list of addresses use Unicode.

Parameters
alAddress list to check
Return values
trueif any use 8-bit characters

Definition at line 309 of file smtp.c.

310 {
311  if (!al)
312  {
313  return false;
314  }
315 
316  struct Address *a = NULL;
317  TAILQ_FOREACH(a, al, entries)
318  {
319  if (a->mailbox && !a->group && address_uses_unicode(a->mailbox))
320  return true;
321  }
322  return false;
323 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
static bool address_uses_unicode(const char *a)
Do any addresses use Unicode.
Definition: smtp.c:289
bool group
Group mailbox?
Definition: address.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_get_field()

static const char* smtp_get_field ( enum ConnAccountField  field)
static

Get connection login credentials - Implements ConnAccount::get_field()

Definition at line 328 of file smtp.c.

329 {
330  switch (field)
331  {
332  case MUTT_CA_LOGIN:
333  case MUTT_CA_USER:
334  return C_SmtpUser;
335  case MUTT_CA_PASS:
336  return C_SmtpPass;
337  case MUTT_CA_OAUTH_CMD:
339  case MUTT_CA_HOST:
340  default:
341  return NULL;
342  }
343 }
char * C_SmtpOauthRefreshCommand
Config: (smtp) External command to generate OAUTH refresh token.
Definition: smtp.c:64
Password.
Definition: connaccount.h:36
User name.
Definition: connaccount.h:35
OAuth refresh command.
Definition: connaccount.h:37
Login name.
Definition: connaccount.h:34
char * C_SmtpUser
Config: (smtp) Username for the SMTP server.
Definition: smtp.c:66
char * C_SmtpPass
Config: (smtp) Password for the SMTP server.
Definition: smtp.c:65
Server name.
Definition: connaccount.h:33
+ Here is the caller graph for this function:

◆ smtp_fill_account()

static int smtp_fill_account ( struct ConnAccount cac)
static

Create ConnAccount object from SMTP Url.

Parameters
cacConnAccount to populate
Return values
0Success
-1Error

Definition at line 351 of file smtp.c.

352 {
353  cac->flags = 0;
354  cac->port = 0;
355  cac->type = MUTT_ACCT_TYPE_SMTP;
356  cac->service = "smtp";
357  cac->get_field = smtp_get_field;
358 
359  struct Url *url = url_parse(C_SmtpUrl);
360  if (!url || ((url->scheme != U_SMTP) && (url->scheme != U_SMTPS)) ||
361  !url->host || (mutt_account_fromurl(cac, url) < 0))
362  {
363  url_free(&url);
364  mutt_error(_("Invalid SMTP URL: %s"), C_SmtpUrl);
365  return -1;
366  }
367 
368  if (url->scheme == U_SMTPS)
369  cac->flags |= MUTT_ACCT_SSL;
370 
371  if (cac->port == 0)
372  {
373  if (cac->flags & MUTT_ACCT_SSL)
374  cac->port = SMTPS_PORT;
375  else
376  {
377  static unsigned short SmtpPort = 0;
378  if (SmtpPort == 0)
379  {
380  struct servent *service = getservbyname("smtp", "tcp");
381  if (service)
382  SmtpPort = ntohs(service->s_port);
383  else
384  SmtpPort = SMTP_PORT;
385  mutt_debug(LL_DEBUG3, "Using default SMTP port %d\n", SmtpPort);
386  }
387  cac->port = SmtpPort;
388  }
389  }
390 
391  url_free(&url);
392  return 0;
393 }
WHERE char * C_SmtpUrl
Config: (smtp) Url of the SMTP server.
Definition: globals.h:138
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:68
#define _(a)
Definition: message.h:28
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
const char *(* get_field)(enum ConnAccountField field)
Function to get some login credentials.
Definition: connaccount.h:67
#define SMTP_PORT
Definition: smtp.c:76
unsigned short port
Port to connect to.
Definition: connaccount.h:57
static const char * smtp_get_field(enum ConnAccountField field)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: smtp.c:328
Url is smtps://.
Definition: url.h:43
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
char * host
Host.
Definition: url.h:71
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:60
#define mutt_error(...)
Definition: logging.h:84
Url is smtp://.
Definition: url.h:42
Smtp Account.
Definition: mutt_account.h:39
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define SMTPS_PORT
Definition: smtp.c:77
Log at debug level 3.
Definition: logging.h:42
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:46
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_helo()

static int smtp_helo ( struct Connection conn,
bool  esmtp 
)
static

Say hello to an SMTP Server.

Parameters
connSMTP Connection
esmtpIf true, use ESMTP
Return values
0Success
<0Error, e.g. SMTP_ERR_WRITE

Definition at line 402 of file smtp.c.

403 {
404  Capabilities = 0;
405 
406  if (!esmtp)
407  {
408  /* if TLS or AUTH are requested, use EHLO */
409  if (conn->account.flags & MUTT_ACCT_USER)
410  esmtp = true;
411 #ifdef USE_SSL
412  if (C_SslForceTls || (C_SslStarttls != MUTT_NO))
413  esmtp = true;
414 #endif
415  }
416 
417  const char *fqdn = mutt_fqdn(false);
418  if (!fqdn)
419  fqdn = NONULL(ShortHostname);
420 
421  char buf[1024];
422  snprintf(buf, sizeof(buf), "%s %s\r\n", esmtp ? "EHLO" : "HELO", fqdn);
423  /* XXX there should probably be a wrapper in mutt_socket.c that
424  * repeatedly calls conn->write until all data is sent. This
425  * currently doesn't check for a short write. */
426  if (mutt_socket_send(conn, buf) == -1)
427  return SMTP_ERR_WRITE;
428  return smtp_get_resp(conn);
429 }
#define NONULL(x)
Definition: string2.h:37
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
WHERE bool C_SslForceTls
Config: (ssl) Require TLS encryption for all connections.
Definition: globals.h:226
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:43
static SmtpCapFlags Capabilities
Definition: smtp.c:99
#define SMTP_ERR_WRITE
Definition: smtp.c:73
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
static int smtp_get_resp(struct Connection *conn)
Read a command response from the SMTP server.
Definition: smtp.c:129
const char * mutt_fqdn(bool may_hide_host)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:2536
WHERE char * ShortHostname
Short version of the hostname.
Definition: globals.h:51
WHERE unsigned char C_SslStarttls
Config: (ssl) Use STARTTLS on servers advertising the capability.
Definition: globals.h:182
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_auth_sasl()

static int smtp_auth_sasl ( struct Connection conn,
const char *  mechlist 
)
static

Authenticate using SASL.

Parameters
connSMTP Connection
mechlistList of mechanisms to use
Return values
0Success
<0Error, e.g. SMTP_AUTH_FAIL

Definition at line 439 of file smtp.c.

440 {
441  sasl_conn_t *saslconn = NULL;
442  sasl_interact_t *interaction = NULL;
443  const char *mech = NULL;
444  const char *data = NULL;
445  unsigned int len;
446  char *buf = NULL;
447  size_t bufsize = 0;
448  int rc, saslrc;
449 
450  if (mutt_sasl_client_new(conn, &saslconn) < 0)
451  return SMTP_AUTH_FAIL;
452 
453  do
454  {
455  rc = sasl_client_start(saslconn, mechlist, &interaction, &data, &len, &mech);
456  if (rc == SASL_INTERACT)
457  mutt_sasl_interact(interaction);
458  } while (rc == SASL_INTERACT);
459 
460  if ((rc != SASL_OK) && (rc != SASL_CONTINUE))
461  {
462  mutt_debug(LL_DEBUG2, "%s unavailable\n", mech);
463  sasl_dispose(&saslconn);
464  return SMTP_AUTH_UNAVAIL;
465  }
466 
467  if (!OptNoCurses)
468  mutt_message(_("Authenticating (%s)..."), mech);
469 
470  bufsize = MAX((len * 2), 1024);
471  buf = mutt_mem_malloc(bufsize);
472 
473  snprintf(buf, bufsize, "AUTH %s", mech);
474  if (len)
475  {
476  mutt_str_cat(buf, bufsize, " ");
477  if (sasl_encode64(data, len, buf + mutt_str_len(buf),
478  bufsize - mutt_str_len(buf), &len) != SASL_OK)
479  {
480  mutt_debug(LL_DEBUG1, "#1 error base64-encoding client response\n");
481  goto fail;
482  }
483  }
484  mutt_str_cat(buf, bufsize, "\r\n");
485 
486  do
487  {
488  if (mutt_socket_send(conn, buf) < 0)
489  goto fail;
490  rc = mutt_socket_readln_d(buf, bufsize, conn, MUTT_SOCK_LOG_FULL);
491  if (rc < 0)
492  goto fail;
493  if (!valid_smtp_code(buf, rc, &rc))
494  goto fail;
495 
496  if (rc != SMTP_READY)
497  break;
498 
499  if (sasl_decode64(buf + 4, strlen(buf + 4), buf, bufsize - 1, &len) != SASL_OK)
500  {
501  mutt_debug(LL_DEBUG1, "error base64-decoding server response\n");
502  goto fail;
503  }
504 
505  do
506  {
507  saslrc = sasl_client_step(saslconn, buf, len, &interaction, &data, &len);
508  if (saslrc == SASL_INTERACT)
509  mutt_sasl_interact(interaction);
510  } while (saslrc == SASL_INTERACT);
511 
512  if (len)
513  {
514  if ((len * 2) > bufsize)
515  {
516  bufsize = len * 2;
517  mutt_mem_realloc(&buf, bufsize);
518  }
519  if (sasl_encode64(data, len, buf, bufsize, &len) != SASL_OK)
520  {
521  mutt_debug(LL_DEBUG1, "#2 error base64-encoding client response\n");
522  goto fail;
523  }
524  }
525  mutt_str_copy(buf + len, "\r\n", bufsize - len);
526  } while (rc == SMTP_READY && saslrc != SASL_FAIL);
527 
528  if (smtp_success(rc))
529  {
530  mutt_sasl_setup_conn(conn, saslconn);
531  FREE(&buf);
532  return SMTP_AUTH_SUCCESS;
533  }
534 
535 fail:
536  sasl_dispose(&saslconn);
537  FREE(&buf);
538  return SMTP_AUTH_FAIL;
539 }
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
int mutt_sasl_client_new(struct Connection *conn, sasl_conn_t **saslconn)
Wrapper for sasl_client_new()
Definition: sasl.c:575
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
#define SMTP_AUTH_SUCCESS
Definition: smtp.c:79
void mutt_sasl_setup_conn(struct Connection *conn, sasl_conn_t *saslconn)
Set up an SASL connection.
Definition: sasl.c:703
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
#define MAX(a, b)
Definition: memory.h:30
Log at debug level 2.
Definition: logging.h:41
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define SMTP_READY
Definition: smtp.c:69
#define smtp_success(x)
Definition: smtp.c:68
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:390
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:639
#define SMTP_AUTH_UNAVAIL
Definition: smtp.c:80
Log at debug level 1.
Definition: logging.h:40
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:724
static bool valid_smtp_code(char *buf, size_t buflen, int *n)
Is the is a valid SMTP return code?
Definition: smtp.c:108
#define FREE(x)
Definition: memory.h:40
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
Definition: socket.c:244
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define SMTP_AUTH_FAIL
Definition: smtp.c:81
int mutt_sasl_interact(sasl_interact_t *interaction)
Perform an SASL interaction with the user.
Definition: sasl.c:670
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_auth_oauth()

static int smtp_auth_oauth ( struct Connection conn)
static

Authenticate an SMTP connection using OAUTHBEARER.

Parameters
connConnection info
Return values
numResult, e.g. SMTP_AUTH_SUCCESS

Definition at line 547 of file smtp.c.

548 {
549  mutt_message(_("Authenticating (OAUTHBEARER)..."));
550 
551  /* We get the access token from the smtp_oauth_refresh_command */
552  char *oauthbearer = mutt_account_getoauthbearer(&conn->account);
553  if (!oauthbearer)
554  return SMTP_AUTH_FAIL;
555 
556  size_t ilen = strlen(oauthbearer) + 30;
557  char *ibuf = mutt_mem_malloc(ilen);
558  snprintf(ibuf, ilen, "AUTH OAUTHBEARER %s\r\n", oauthbearer);
559 
560  int rc = mutt_socket_send(conn, ibuf);
561  FREE(&oauthbearer);
562  FREE(&ibuf);
563 
564  if (rc == -1)
565  return SMTP_AUTH_FAIL;
566  if (smtp_get_resp(conn) != 0)
567  return SMTP_AUTH_FAIL;
568 
569  return SMTP_AUTH_SUCCESS;
570 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
#define SMTP_AUTH_SUCCESS
Definition: smtp.c:79
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
static int smtp_get_resp(struct Connection *conn)
Read a command response from the SMTP server.
Definition: smtp.c:129
#define FREE(x)
Definition: memory.h:40
char * mutt_account_getoauthbearer(struct ConnAccount *cac)
Get an OAUTHBEARER token.
Definition: connaccount.c:157
#define SMTP_AUTH_FAIL
Definition: smtp.c:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_auth_plain()

static int smtp_auth_plain ( struct Connection conn)
static

Authenticate using plain text.

Parameters
connSMTP Connection
Return values
0Success
<0Error, e.g. SMTP_AUTH_FAIL

Definition at line 578 of file smtp.c.

579 {
580  char buf[1024];
581 
582  /* Get username and password. Bail out of any can't be retrieved. */
583  if ((mutt_account_getuser(&conn->account) < 0) ||
584  (mutt_account_getpass(&conn->account) < 0))
585  {
586  goto error;
587  }
588 
589  /* Build the initial client response. */
590  size_t len = mutt_sasl_plain_msg(buf, sizeof(buf), "AUTH PLAIN", conn->account.user,
591  conn->account.user, conn->account.pass);
592 
593  /* Terminate as per SMTP protocol. Bail out if there's no room left. */
594  if (snprintf(buf + len, sizeof(buf) - len, "\r\n") != 2)
595  {
596  goto error;
597  }
598 
599  /* Send request, receive response (with a check for OK code). */
600  if ((mutt_socket_send(conn, buf) < 0) || smtp_get_resp(conn))
601  {
602  goto error;
603  }
604 
605  /* If we got here, auth was successful. */
606  return 0;
607 
608 error:
609  mutt_error(_("SASL authentication failed"));
610  return -1;
611 }
int mutt_account_getuser(struct ConnAccount *cac)
Retrieve username into ConnAccount, if necessary.
Definition: connaccount.c:47
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
char user[128]
Username.
Definition: connaccount.h:55
#define _(a)
Definition: message.h:28
size_t mutt_sasl_plain_msg(char *buf, size_t buflen, const char *cmd, const char *authz, const char *user, const char *pass)
Construct a base64 encoded SASL PLAIN message.
Definition: sasl_plain.c:55
char pass[256]
Password.
Definition: connaccount.h:56
static int smtp_get_resp(struct Connection *conn)
Read a command response from the SMTP server.
Definition: smtp.c:129
#define mutt_error(...)
Definition: logging.h:84
int mutt_account_getpass(struct ConnAccount *cac)
Fetch password into ConnAccount, if necessary.
Definition: connaccount.c:110
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_auth()

static int smtp_auth ( struct Connection conn)
static

Authenticate to an SMTP server.

Parameters
connSMTP Connection
Return values
0Success
<0Error, e.g. SMTP_AUTH_FAIL

Definition at line 619 of file smtp.c.

620 {
621  int r = SMTP_AUTH_UNAVAIL;
622 
624  {
625  struct ListNode *np = NULL;
627  {
628  mutt_debug(LL_DEBUG2, "Trying method %s\n", np->data);
629 
630  if (strcmp(np->data, "oauthbearer") == 0)
631  {
632  r = smtp_auth_oauth(conn);
633  }
634  else if (strcmp(np->data, "plain") == 0)
635  {
636  r = smtp_auth_plain(conn);
637  }
638  else
639  {
640 #ifdef USE_SASL
641  r = smtp_auth_sasl(conn, np->data);
642 #else
643  mutt_error(_("SMTP authentication method %s requires SASL"), np->data);
644  continue;
645 #endif
646  }
647 
648  if ((r == SMTP_AUTH_FAIL) && (C_SmtpAuthenticators->count > 1))
649  {
650  mutt_error(_("%s authentication failed, trying next method"), np->data);
651  }
652  else if (r != SMTP_AUTH_UNAVAIL)
653  break;
654  }
655  }
656  else
657  {
658 #ifdef USE_SASL
659  r = smtp_auth_sasl(conn, AuthMechs);
660 #else
661  mutt_error(_("SMTP authentication requires SASL"));
662  r = SMTP_AUTH_UNAVAIL;
663 #endif
664  }
665 
666  if (r != SMTP_AUTH_SUCCESS)
668 
669  if (r == SMTP_AUTH_FAIL)
670  {
671  mutt_error(_("SASL authentication failed"));
672  }
673  else if (r == SMTP_AUTH_UNAVAIL)
674  {
675  mutt_error(_("No authenticators available"));
676  }
677 
678  return (r == SMTP_AUTH_SUCCESS) ? 0 : -1;
679 }
static int smtp_auth_plain(struct Connection *conn)
Authenticate using plain text.
Definition: smtp.c:578
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define _(a)
Definition: message.h:28
#define SMTP_AUTH_SUCCESS
Definition: smtp.c:79
struct Slist * C_SmtpAuthenticators
Config: (smtp) List of allowed authentication methods.
Definition: smtp.c:63
Log at debug level 2.
Definition: logging.h:41
struct ListHead head
Definition: slist.h:45
size_t count
Definition: slist.h:46
void mutt_account_unsetpass(struct ConnAccount *cac)
Unset ConnAccount&#39;s password.
Definition: connaccount.c:140
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
#define SMTP_AUTH_UNAVAIL
Definition: smtp.c:80
char * data
String.
Definition: list.h:36
static int smtp_auth_sasl(struct Connection *conn, const char *mechlist)
Authenticate using SASL.
Definition: smtp.c:439
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
A List node for strings.
Definition: list.h:34
static char * AuthMechs
Definition: smtp.c:98
#define SMTP_AUTH_FAIL
Definition: smtp.c:81
static int smtp_auth_oauth(struct Connection *conn)
Authenticate an SMTP connection using OAUTHBEARER.
Definition: smtp.c:547
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smtp_open()

static int smtp_open ( struct Connection conn,
bool  esmtp 
)
static

Open an SMTP Connection.

Parameters
connSMTP Connection
esmtpIf true, use ESMTP
Return values
0Success
-1Error

Definition at line 688 of file smtp.c.

689 {
690  int rc;
691 
692  if (mutt_socket_open(conn))
693  return -1;
694 
695  /* get greeting string */
696  rc = smtp_get_resp(conn);
697  if (rc != 0)
698  return rc;
699 
700  rc = smtp_helo(conn, esmtp);
701  if (rc != 0)
702  return rc;
703 
704 #ifdef USE_SSL
705  enum QuadOption ans = MUTT_NO;
706  if (conn->ssf)
707  ans = MUTT_NO;
708  else if (C_SslForceTls)
709  ans = MUTT_YES;
710  else if ((Capabilities & SMTP_CAP_STARTTLS) &&
712  _("Secure connection with TLS?"))) == MUTT_ABORT))
713  {
714  return -1;
715  }
716 
717  if (ans == MUTT_YES)
718  {
719  if (mutt_socket_send(conn, "STARTTLS\r\n") < 0)
720  return SMTP_ERR_WRITE;
721  rc = smtp_get_resp(conn);
722  // Clear any data after the STARTTLS acknowledgement
723  mutt_socket_empty(conn);
724  if (rc != 0)
725  return rc;
726 
727  if (mutt_ssl_starttls(conn))
728  {
729  mutt_error(_("Could not negotiate TLS connection"));
730  return -1;
731  }
732 
733  /* re-EHLO to get authentication mechanisms */
734  rc = smtp_helo(conn, esmtp);
735  if (rc != 0)
736  return rc;
737  }
738 #endif
739 
740  if (conn->account.flags & MUTT_ACCT_USER)
741  {
742  if (!(Capabilities & SMTP_CAP_AUTH))
743  {
744  mutt_error(_("SMTP server does not support authentication"));
745  return -1;
746  }
747 
748  return smtp_auth(conn);
749  }
750 
751  return 0;
752 }
static int smtp_helo(struct Connection *conn, bool esmtp)
Say hello to an SMTP Server.
Definition: smtp.c:402
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
unsigned int ssf
Security strength factor, in bits (see below)
Definition: connection.h:37
#define SMTP_CAP_STARTTLS
Server supports STARTTLS command.
Definition: smtp.c:89
User aborted the question (with Ctrl-G)
Definition: quad.h:38
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1112
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
#define _(a)
Definition: message.h:28
WHERE bool C_SslForceTls
Config: (ssl) Require TLS encryption for all connections.
Definition: globals.h:226
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:43
int mutt_socket_open(struct Connection *conn)
Simple wrapper.
Definition: socket.c:74
static int smtp_auth(struct Connection *conn)
Authenticate to an SMTP server.
Definition: smtp.c:619
static SmtpCapFlags Capabilities
Definition: smtp.c:99
#define SMTP_ERR_WRITE
Definition: smtp.c:73
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
static int smtp_get_resp(struct Connection *conn)
Read a command response from the SMTP server.
Definition: smtp.c:129
void mutt_socket_empty(struct Connection *conn)
Clear out any queued data.
Definition: socket.c:311
#define mutt_error(...)
Definition: logging.h:84
int mutt_ssl_starttls(struct Connection *conn)
Negotiate TLS over an already opened connection.
Definition: gnutls.c:1142
#define SMTP_CAP_AUTH
Server supports AUTH command.
Definition: smtp.c:90
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
WHERE unsigned char C_SslStarttls
Config: (ssl) Use STARTTLS on servers advertising the capability.
Definition: globals.h:182
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_smtp_send()

int mutt_smtp_send ( const struct AddressList *  from,
const struct AddressList *  to,
const struct AddressList *  cc,
const struct AddressList *  bcc,
const char *  msgfile,
bool  eightbit 
)

Send a message using SMTP.

Parameters
fromFrom Address
toTo Address
ccCc Address
bccBcc Address
msgfileMessage to send to the server
eightbitIf true, try for an 8-bit friendly connection
Return values
0Success
-1Error

Definition at line 765 of file smtp.c.

768 {
769  struct Connection *conn = NULL;
770  struct ConnAccount cac = { { 0 } };
771  const char *envfrom = NULL;
772  char buf[1024];
773  int rc = -1;
774 
775  /* it might be better to synthesize an envelope from from user and host
776  * but this condition is most likely arrived at accidentally */
778  envfrom = C_EnvelopeFromAddress->mailbox;
779  else if (from && !TAILQ_EMPTY(from))
780  envfrom = TAILQ_FIRST(from)->mailbox;
781  else
782  {
783  mutt_error(_("No from address given"));
784  return -1;
785  }
786 
787  if (smtp_fill_account(&cac) < 0)
788  return rc;
789 
790  conn = mutt_conn_find(&cac);
791  if (!conn)
792  return -1;
793 
794  do
795  {
796  /* send our greeting */
797  rc = smtp_open(conn, eightbit);
798  if (rc != 0)
799  break;
800  FREE(&AuthMechs);
801 
802  /* send the sender's address */
803  int len = snprintf(buf, sizeof(buf), "MAIL FROM:<%s>", envfrom);
804  if (eightbit && (Capabilities & SMTP_CAP_EIGHTBITMIME))
805  {
806  mutt_strn_cat(buf, sizeof(buf), " BODY=8BITMIME", 15);
807  len += 14;
808  }
810  len += snprintf(buf + len, sizeof(buf) - len, " RET=%s", C_DsnReturn);
812  (address_uses_unicode(envfrom) || addresses_use_unicode(to) ||
814  {
815  snprintf(buf + len, sizeof(buf) - len, " SMTPUTF8");
816  }
817  mutt_strn_cat(buf, sizeof(buf), "\r\n", 3);
818  if (mutt_socket_send(conn, buf) == -1)
819  {
820  rc = SMTP_ERR_WRITE;
821  break;
822  }
823  rc = smtp_get_resp(conn);
824  if (rc != 0)
825  break;
826 
827  /* send the recipient list */
828  if ((rc = smtp_rcpt_to(conn, to)) || (rc = smtp_rcpt_to(conn, cc)) ||
829  (rc = smtp_rcpt_to(conn, bcc)))
830  {
831  break;
832  }
833 
834  /* send the message data */
835  rc = smtp_data(conn, msgfile);
836  if (rc != 0)
837  break;
838 
839  mutt_socket_send(conn, "QUIT\r\n");
840 
841  rc = 0;
842  } while (false);
843 
844  mutt_socket_close(conn);
845  FREE(&conn);
846 
847  if (rc == SMTP_ERR_READ)
848  mutt_error(_("SMTP session failed: read error"));
849  else if (rc == SMTP_ERR_WRITE)
850  mutt_error(_("SMTP session failed: write error"));
851  else if (rc == SMTP_ERR_CODE)
852  mutt_error(_("Invalid server response"));
853 
854  return rc;
855 }
#define TAILQ_FIRST(head)
Definition: queue.h:716
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
char * mutt_strn_cat(char *d, size_t l, const char *s, size_t sl)
Concatenate two strings.
Definition: string.c:419
An open network connection (socket)
Definition: connection.h:34
#define SMTP_CAP_SMTPUTF8
Server accepts UTF-8 strings.
Definition: smtp.c:93
#define _(a)
Definition: message.h:28
char * mailbox
Mailbox and host address.
Definition: address.h:37
static int smtp_open(struct Connection *conn, bool esmtp)
Open an SMTP Connection.
Definition: smtp.c:688
static SmtpCapFlags Capabilities
Definition: smtp.c:99
struct Connection * mutt_conn_find(const struct ConnAccount *cac)
Find a connection from a list.
Definition: mutt_socket.c:86
#define SMTP_ERR_WRITE
Definition: smtp.c:73
static bool address_uses_unicode(const char *a)
Do any addresses use Unicode.
Definition: smtp.c:289
static int smtp_get_resp(struct Connection *conn)
Read a command response from the SMTP server.
Definition: smtp.c:129
#define SMTP_ERR_READ
Definition: smtp.c:72
Login details for a remote server.
Definition: connaccount.h:51
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:95
WHERE char * C_DsnReturn
Config: What to send as a notification of message delivery or delay.
Definition: globals.h:108
#define SMTP_ERR_CODE
Definition: smtp.c:74
#define mutt_error(...)
Definition: logging.h:84
WHERE struct Address * C_EnvelopeFromAddress
Config: Manually set the sender for outgoing messages.
Definition: globals.h:91
#define SMTP_CAP_EIGHTBITMIME
Server supports 8-bit MIME content.
Definition: smtp.c:92
static bool addresses_use_unicode(const struct AddressList *al)
Do any of a list of addresses use Unicode.
Definition: smtp.c:309
static int smtp_fill_account(struct ConnAccount *cac)
Create ConnAccount object from SMTP Url.
Definition: smtp.c:351
#define FREE(x)
Definition: memory.h:40
static int smtp_rcpt_to(struct Connection *conn, const struct AddressList *al)
Set the recipient to an Address.
Definition: smtp.c:179
#define TAILQ_EMPTY(head)
Definition: queue.h:714
static char * AuthMechs
Definition: smtp.c:98
static int smtp_data(struct Connection *conn, const char *msgfile)
Send data to an SMTP server.
Definition: smtp.c:214
#define SMTP_CAP_DSN
Server supports Delivery Status Notification.
Definition: smtp.c:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_SmtpAuthenticators

struct Slist* C_SmtpAuthenticators

Config: (smtp) List of allowed authentication methods.

Definition at line 63 of file smtp.c.

◆ C_SmtpOauthRefreshCommand

char* C_SmtpOauthRefreshCommand

Config: (smtp) External command to generate OAUTH refresh token.

Definition at line 64 of file smtp.c.

◆ C_SmtpPass

char* C_SmtpPass

Config: (smtp) Password for the SMTP server.

Definition at line 65 of file smtp.c.

◆ C_SmtpUser

char* C_SmtpUser

Config: (smtp) Username for the SMTP server.

Definition at line 66 of file smtp.c.

◆ AuthMechs

char* AuthMechs = NULL
static

Definition at line 98 of file smtp.c.

◆ Capabilities

SmtpCapFlags Capabilities
static

Definition at line 99 of file smtp.c.