Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / sendmail / src / srvrsmtp.c
1 /*
2  * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
3  *      All rights reserved.
4  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5  * Copyright (c) 1988, 1993
6  *      The Regents of the University of California.  All rights reserved.
7  *
8  * By using this file, you agree to the terms and conditions set
9  * forth in the LICENSE file which can be found at the top level of
10  * the sendmail distribution.
11  *
12  */
13
14 #include <sendmail.h>
15 #if MILTER
16 # include <libmilter/mfdef.h>
17 #endif /* MILTER */
18
19 SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.829.2.22 2003/02/19 02:45:40 ca Exp $")
20
21 #if SASL || STARTTLS
22 # include <sys/time.h>
23 # include "sfsasl.h"
24 #endif /* SASL || STARTTLS */
25 #if SASL
26 # define ENC64LEN(l)    (((l) + 2) * 4 / 3 + 1)
27 static int saslmechs __P((sasl_conn_t *, char **));
28 #endif /* SASL */
29 #if STARTTLS
30 # include <sysexits.h>
31
32 static SSL_CTX  *srv_ctx = NULL;        /* TLS server context */
33 static SSL      *srv_ssl = NULL;        /* per connection context */
34
35 static bool     tls_ok_srv = false;
36
37 extern void     tls_set_verify __P((SSL_CTX *, SSL *, bool));
38 # define TLS_VERIFY_CLIENT() tls_set_verify(srv_ctx, srv_ssl, \
39                                 bitset(SRV_VRFY_CLT, features))
40 #endif /* STARTTLS */
41
42 /* server features */
43 #define SRV_NONE        0x0000  /* none... */
44 #define SRV_OFFER_TLS   0x0001  /* offer STARTTLS */
45 #define SRV_VRFY_CLT    0x0002  /* request a cert */
46 #define SRV_OFFER_AUTH  0x0004  /* offer AUTH */
47 #define SRV_OFFER_ETRN  0x0008  /* offer ETRN */
48 #define SRV_OFFER_VRFY  0x0010  /* offer VRFY (not yet used) */
49 #define SRV_OFFER_EXPN  0x0020  /* offer EXPN */
50 #define SRV_OFFER_VERB  0x0040  /* offer VERB */
51 #define SRV_OFFER_DSN   0x0080  /* offer DSN */
52 #if PIPELINING
53 # define SRV_OFFER_PIPE 0x0100  /* offer PIPELINING */
54 # if _FFR_NO_PIPE
55 #  define SRV_NO_PIPE   0x0200  /* disable PIPELINING, sleep if used */
56 # endif /* _FFR_NO_PIPE */
57 #endif /* PIPELINING */
58 #define SRV_REQ_AUTH    0x0400  /* require AUTH */
59 #define SRV_TMP_FAIL    0x1000  /* ruleset caused a temporary failure */
60
61 static unsigned int     srvfeatures __P((ENVELOPE *, char *, unsigned int));
62
63 static time_t   checksmtpattack __P((volatile unsigned int *, int, bool,
64                                      char *, ENVELOPE *));
65 static void     mail_esmtp_args __P((char *, char *, ENVELOPE *));
66 static void     printvrfyaddr __P((ADDRESS *, bool, bool));
67 static void     rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *));
68 static char     *skipword __P((char *volatile, char *));
69 static void     setup_smtpd_io __P((void));
70 extern ENVELOPE BlankEnvelope;
71
72 #define SKIP_SPACE(s)   while (isascii(*s) && isspace(*s))      \
73                                 (s)++
74
75 /*
76 **  SMTP -- run the SMTP protocol.
77 **
78 **      Parameters:
79 **              nullserver -- if non-NULL, rejection message for
80 **                      (almost) all SMTP commands.
81 **              d_flags -- daemon flags
82 **              e -- the envelope.
83 **
84 **      Returns:
85 **              never.
86 **
87 **      Side Effects:
88 **              Reads commands from the input channel and processes them.
89 */
90
91 /*
92 **  Notice: The smtp server doesn't have a session context like the client
93 **      side has (mci). Therefore some data (session oriented) is allocated
94 **      or assigned to the "wrong" structure (esp. STARTTLS, AUTH).
95 **      This should be fixed in a successor version.
96 */
97
98 struct cmd
99 {
100         char    *cmd_name;      /* command name */
101         int     cmd_code;       /* internal code, see below */
102 };
103
104 /* values for cmd_code */
105 #define CMDERROR        0       /* bad command */
106 #define CMDMAIL 1       /* mail -- designate sender */
107 #define CMDRCPT 2       /* rcpt -- designate recipient */
108 #define CMDDATA 3       /* data -- send message text */
109 #define CMDRSET 4       /* rset -- reset state */
110 #define CMDVRFY 5       /* vrfy -- verify address */
111 #define CMDEXPN 6       /* expn -- expand address */
112 #define CMDNOOP 7       /* noop -- do nothing */
113 #define CMDQUIT 8       /* quit -- close connection and die */
114 #define CMDHELO 9       /* helo -- be polite */
115 #define CMDHELP 10      /* help -- give usage info */
116 #define CMDEHLO 11      /* ehlo -- extended helo (RFC 1425) */
117 #define CMDETRN 12      /* etrn -- flush queue */
118 #if SASL
119 # define CMDAUTH        13      /* auth -- SASL authenticate */
120 #endif /* SASL */
121 #if STARTTLS
122 # define CMDSTLS        14      /* STARTTLS -- start TLS session */
123 #endif /* STARTTLS */
124 /* non-standard commands */
125 #define CMDVERB 17      /* verb -- go into verbose mode */
126 /* unimplemented commands from RFC 821 */
127 #define CMDUNIMPL       19      /* unimplemented rfc821 commands */
128 /* use this to catch and log "door handle" attempts on your system */
129 #define CMDLOGBOGUS     23      /* bogus command that should be logged */
130 /* debugging-only commands, only enabled if SMTPDEBUG is defined */
131 #define CMDDBGQSHOW     24      /* showq -- show send queue */
132 #define CMDDBGDEBUG     25      /* debug -- set debug mode */
133
134 /*
135 **  Note: If you change this list, remember to update 'helpfile'
136 */
137
138 static struct cmd       CmdTab[] =
139 {
140         { "mail",       CMDMAIL         },
141         { "rcpt",       CMDRCPT         },
142         { "data",       CMDDATA         },
143         { "rset",       CMDRSET         },
144         { "vrfy",       CMDVRFY         },
145         { "expn",       CMDEXPN         },
146         { "help",       CMDHELP         },
147         { "noop",       CMDNOOP         },
148         { "quit",       CMDQUIT         },
149         { "helo",       CMDHELO         },
150         { "ehlo",       CMDEHLO         },
151         { "etrn",       CMDETRN         },
152         { "verb",       CMDVERB         },
153         { "send",       CMDUNIMPL       },
154         { "saml",       CMDUNIMPL       },
155         { "soml",       CMDUNIMPL       },
156         { "turn",       CMDUNIMPL       },
157 #if SASL
158         { "auth",       CMDAUTH,        },
159 #endif /* SASL */
160 #if STARTTLS
161         { "starttls",   CMDSTLS,        },
162 #endif /* STARTTLS */
163     /* remaining commands are here only to trap and log attempts to use them */
164         { "showq",      CMDDBGQSHOW     },
165         { "debug",      CMDDBGDEBUG     },
166         { "wiz",        CMDLOGBOGUS     },
167
168         { NULL,         CMDERROR        }
169 };
170
171 static char     *CurSmtpClient;         /* who's at the other end of channel */
172
173 #ifndef MAXBADCOMMANDS
174 # define MAXBADCOMMANDS 25      /* maximum number of bad commands */
175 #endif /* ! MAXBADCOMMANDS */
176 #ifndef MAXNOOPCOMMANDS
177 # define MAXNOOPCOMMANDS 20     /* max "noise" commands before slowdown */
178 #endif /* ! MAXNOOPCOMMANDS */
179 #ifndef MAXHELOCOMMANDS
180 # define MAXHELOCOMMANDS 3      /* max HELO/EHLO commands before slowdown */
181 #endif /* ! MAXHELOCOMMANDS */
182 #ifndef MAXVRFYCOMMANDS
183 # define MAXVRFYCOMMANDS 6      /* max VRFY/EXPN commands before slowdown */
184 #endif /* ! MAXVRFYCOMMANDS */
185 #ifndef MAXETRNCOMMANDS
186 # define MAXETRNCOMMANDS 8      /* max ETRN commands before slowdown */
187 #endif /* ! MAXETRNCOMMANDS */
188 #ifndef MAXTIMEOUT
189 # define MAXTIMEOUT (4 * 60)    /* max timeout for bad commands */
190 #endif /* ! MAXTIMEOUT */
191
192 #if SM_HEAP_CHECK
193 static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp",
194         "@(#)$Debug: leak_smtp - trace memory leaks during SMTP processing $");
195 #endif /* SM_HEAP_CHECK */
196
197 typedef struct
198 {
199         bool    sm_gotmail;     /* mail command received */
200         unsigned int sm_nrcpts; /* number of successful RCPT commands */
201 #if _FFR_ADAPTIVE_EOL
202 WARNING: do NOT use this FFR, it is most likely broken
203         bool    sm_crlf;        /* input in CRLF form? */
204 #endif /* _FFR_ADAPTIVE_EOL */
205         bool    sm_discard;
206 #if MILTER
207         bool    sm_milterize;
208         bool    sm_milterlist;  /* any filters in the list? */
209 #endif /* MILTER */
210 #if _FFR_QUARANTINE
211         char    *sm_quarmsg;    /* carry quarantining across messages */
212 #endif /* _FFR_QUARANTINE */
213 } SMTP_T;
214
215 static void     smtp_data __P((SMTP_T *, ENVELOPE *));
216
217 #define MSG_TEMPFAIL "451 4.7.1 Please try again later"
218
219 #if MILTER
220 # define MILTER_ABORT(e)        milter_abort((e))
221
222 #if _FFR_MILTER_421
223 # define MILTER_SHUTDOWN                                                \
224                         if (strncmp(response, "421 ", 4) == 0)          \
225                         {                                               \
226                                 e->e_sendqueue = NULL;                  \
227                                 goto doquit;                            \
228                         }
229 #else /* _FFR_MILTER_421 */
230 # define MILTER_SHUTDOWN
231 #endif /* _FFR_MILTER_421 */
232
233 # define MILTER_REPLY(str)                                              \
234         {                                                               \
235                 int savelogusrerrs = LogUsrErrs;                        \
236                                                                         \
237                 switch (state)                                          \
238                 {                                                       \
239                   case SMFIR_REPLYCODE:                                 \
240                         if (MilterLogLevel > 3)                         \
241                         {                                               \
242                                 sm_syslog(LOG_INFO, e->e_id,            \
243                                           "Milter: %s=%s, reject=%s",   \
244                                           str, addr, response);         \
245                                 LogUsrErrs = false;                     \
246                         }                                               \
247                         usrerr(response);                               \
248                         MILTER_SHUTDOWN                                 \
249                         break;                                          \
250                                                                         \
251                   case SMFIR_REJECT:                                    \
252                         if (MilterLogLevel > 3)                         \
253                         {                                               \
254                                 sm_syslog(LOG_INFO, e->e_id,            \
255                                           "Milter: %s=%s, reject=550 5.7.1 Command rejected", \
256                                           str, addr);                   \
257                                 LogUsrErrs = false;                     \
258                         }                                               \
259                         usrerr("550 5.7.1 Command rejected");           \
260                         break;                                          \
261                                                                         \
262                   case SMFIR_DISCARD:                                   \
263                         if (MilterLogLevel > 3)                         \
264                                 sm_syslog(LOG_INFO, e->e_id,            \
265                                           "Milter: %s=%s, discard",     \
266                                           str, addr);                   \
267                         e->e_flags |= EF_DISCARD;                       \
268                         break;                                          \
269                                                                         \
270                   case SMFIR_TEMPFAIL:                                  \
271                         if (MilterLogLevel > 3)                         \
272                         {                                               \
273                                 sm_syslog(LOG_INFO, e->e_id,            \
274                                           "Milter: %s=%s, reject=%s",   \
275                                           str, addr, MSG_TEMPFAIL);     \
276                                 LogUsrErrs = false;                     \
277                         }                                               \
278                         usrerr(MSG_TEMPFAIL);                           \
279                         break;                                          \
280                 }                                                       \
281                 LogUsrErrs = savelogusrerrs;                            \
282                 if (response != NULL)                                   \
283                         sm_free(response); /* XXX */                    \
284         }
285
286 #else /* MILTER */
287 # define MILTER_ABORT(e)
288 #endif /* MILTER */
289
290 /* clear all SMTP state (for HELO/EHLO/RSET) */
291 #define CLEAR_STATE(cmd)                                        \
292 {                                                               \
293         /* abort milter filters */                              \
294         MILTER_ABORT(e);                                        \
295                                                                 \
296         if (smtp.sm_nrcpts > 0)                                 \
297         {                                                       \
298                 logundelrcpts(e, cmd, 10, false);               \
299                 smtp.sm_nrcpts = 0;                             \
300                 macdefine(&e->e_macro, A_PERM,                  \
301                           macid("{nrcpts}"), "0");              \
302         }                                                       \
303                                                                 \
304         e->e_sendqueue = NULL;                                  \
305         e->e_flags |= EF_CLRQUEUE;                              \
306                                                                 \
307         if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))   \
308                 logsender(e, NULL);                             \
309         e->e_flags &= ~EF_LOGSENDER;                            \
310                                                                 \
311         /* clean up a bit */                                    \
312         smtp.sm_gotmail = false;                                \
313         SuprErrs = true;                                        \
314         dropenvelope(e, true, false);                           \
315         sm_rpool_free(e->e_rpool);                              \
316         e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL));       \
317         CurEnv = e;                                             \
318 }
319
320 /* sleep to flatten out connection load */
321 #define MIN_DELAY_LOG   15      /* wait before logging this again */
322
323 /* is it worth setting the process title for 1s? */
324 #define DELAY_CONN(cmd)                                         \
325         if (DelayLA > 0 && (CurrentLA = getla()) >= DelayLA)    \
326         {                                                       \
327                 time_t dnow;                                    \
328                                                                 \
329                 sm_setproctitle(true, e,                        \
330                                 "%s: %s: delaying %s: load average: %d", \
331                                 qid_printname(e), CurSmtpClient,        \
332                                 cmd, DelayLA);  \
333                 if (LogLevel > 8 && (dnow = curtime()) > log_delay)     \
334                 {                                               \
335                         sm_syslog(LOG_INFO, e->e_id,            \
336                                   "delaying=%s, load average=%d >= %d", \
337                                   cmd, CurrentLA, DelayLA);             \
338                         log_delay = dnow + MIN_DELAY_LOG;       \
339                 }                                               \
340                 (void) sleep(1);                                \
341                 sm_setproctitle(true, e, "%s %s: %.80s",        \
342                                 qid_printname(e), CurSmtpClient, inp);  \
343         }
344
345
346 void
347 smtp(nullserver, d_flags, e)
348         char *volatile nullserver;
349         BITMAP256 d_flags;
350         register ENVELOPE *volatile e;
351 {
352         register char *volatile p;
353         register struct cmd *volatile c = NULL;
354         char *cmd;
355         auto ADDRESS *vrfyqueue;
356         ADDRESS *a;
357         volatile bool gothello;         /* helo command received */
358         bool vrfy;                      /* set if this is a vrfy command */
359         char *volatile protocol;        /* sending protocol */
360         char *volatile sendinghost;     /* sending hostname */
361         char *volatile peerhostname;    /* name of SMTP peer or "localhost" */
362         auto char *delimptr;
363         char *id;
364         volatile unsigned int n_badcmds = 0;    /* count of bad commands */
365         volatile unsigned int n_badrcpts = 0;   /* number of rejected RCPT */
366         volatile unsigned int n_verifies = 0;   /* count of VRFY/EXPN */
367         volatile unsigned int n_etrn = 0;       /* count of ETRN */
368         volatile unsigned int n_noop = 0;       /* count of NOOP/VERB/etc */
369         volatile unsigned int n_helo = 0;       /* count of HELO/EHLO */
370         bool ok;
371 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
372         volatile bool first;
373 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
374         volatile bool tempfail = false;
375         volatile time_t wt;             /* timeout after too many commands */
376         volatile time_t previous;       /* time after checksmtpattack() */
377         volatile bool lognullconnection = true;
378         register char *q;
379         SMTP_T smtp;
380         char *addr;
381         char *greetcode = "220";
382         char *hostname;                 /* my hostname ($j) */
383         QUEUE_CHAR *new;
384         int argno;
385         char *args[MAXSMTPARGS];
386         char inp[MAXLINE];
387         char cmdbuf[MAXLINE];
388 #if SASL
389         sasl_conn_t *conn;
390         volatile bool sasl_ok;
391         volatile unsigned int n_auth = 0;       /* count of AUTH commands */
392         bool ismore;
393         int result;
394         volatile int authenticating;
395         char *user;
396         char *in, *out2;
397 # if SASL >= 20000
398         char *auth_id;
399         const char *out;
400         sasl_ssf_t ext_ssf;
401 # else /* SASL >= 20000 */
402         char *out;
403         const char *errstr;
404         sasl_external_properties_t ext_ssf;
405 # endif /* SASL >= 20000 */
406         sasl_security_properties_t ssp;
407         sasl_ssf_t *ssf;
408         unsigned int inlen, out2len;
409         unsigned int outlen;
410         char *volatile auth_type;
411         char *mechlist;
412         volatile unsigned int n_mechs;
413         unsigned int len;
414 #endif /* SASL */
415 #if STARTTLS
416         int r;
417         int rfd, wfd;
418         volatile bool tls_active = false;
419 # if _FFR_SMTP_SSL
420         volatile bool smtps = false;
421 # endif /* _FFR_SMTP_SSL */
422         bool saveQuickAbort;
423         bool saveSuprErrs;
424         time_t tlsstart;
425 #endif /* STARTTLS */
426         volatile unsigned int features;
427 #if PIPELINING
428 # if _FFR_NO_PIPE
429         int np_log = 0;
430 # endif /* _FFR_NO_PIPE */
431 #endif /* PIPELINING */
432         volatile time_t log_delay = (time_t) 0;
433
434         smtp.sm_nrcpts = 0;
435 #if MILTER
436         smtp.sm_milterize = (nullserver == NULL);
437         smtp.sm_milterlist = false;
438 #endif /* MILTER */
439
440         /* setup I/O fd correctly for the SMTP server */
441         setup_smtpd_io();
442
443 #if SM_HEAP_CHECK
444         if (sm_debug_active(&DebugLeakSmtp, 1))
445         {
446                 sm_heap_newgroup();
447                 sm_dprintf("smtp() heap group #%d\n", sm_heap_group());
448         }
449 #endif /* SM_HEAP_CHECK */
450
451         /* XXX the rpool should be set when e is initialized in main() */
452         e->e_rpool = sm_rpool_new_x(NULL);
453         e->e_macro.mac_rpool = e->e_rpool;
454
455         settime(e);
456         sm_getla();
457         peerhostname = RealHostName;
458         if (peerhostname == NULL)
459                 peerhostname = "localhost";
460         CurHostName = peerhostname;
461         CurSmtpClient = macvalue('_', e);
462         if (CurSmtpClient == NULL)
463                 CurSmtpClient = CurHostName;
464
465         /* check_relay may have set discard bit, save for later */
466         smtp.sm_discard = bitset(EF_DISCARD, e->e_flags);
467
468 #if PIPELINING
469         /* auto-flush output when reading input */
470         (void) sm_io_autoflush(InChannel, OutChannel);
471 #endif /* PIPELINING */
472
473         sm_setproctitle(true, e, "server %s startup", CurSmtpClient);
474
475         /* Set default features for server. */
476         features = ((bitset(PRIV_NOETRN, PrivacyFlags) ||
477                      bitnset(D_NOETRN, d_flags)) ? SRV_NONE : SRV_OFFER_ETRN)
478                 | (bitnset(D_AUTHREQ, d_flags) ? SRV_REQ_AUTH : SRV_NONE)
479                 | (bitset(PRIV_NOEXPN, PrivacyFlags) ? SRV_NONE
480                         : (SRV_OFFER_EXPN
481                           | (bitset(PRIV_NOVERB, PrivacyFlags)
482                              ? SRV_NONE : SRV_OFFER_VERB)))
483                 | (bitset(PRIV_NORECEIPTS, PrivacyFlags) ? SRV_NONE
484                                                          : SRV_OFFER_DSN)
485 #if SASL
486                 | (bitnset(D_NOAUTH, d_flags) ? SRV_NONE : SRV_OFFER_AUTH)
487 #endif /* SASL */
488 #if PIPELINING
489                 | SRV_OFFER_PIPE
490 #endif /* PIPELINING */
491 #if STARTTLS
492                 | (bitnset(D_NOTLS, d_flags) ? SRV_NONE : SRV_OFFER_TLS)
493                 | (bitset(TLS_I_NO_VRFY, TLS_Srv_Opts) ? SRV_NONE
494                                                        : SRV_VRFY_CLT)
495 #endif /* STARTTLS */
496                 ;
497         if (nullserver == NULL)
498         {
499                 features = srvfeatures(e, CurSmtpClient, features);
500                 if (bitset(SRV_TMP_FAIL, features))
501                 {
502                         if (LogLevel > 4)
503                                 sm_syslog(LOG_ERR, NOQID,
504                                           "ERROR: srv_features=tempfail, relay=%.100s, access temporarily disabled",
505                                           CurSmtpClient);
506                         nullserver = "450 4.3.0 Please try again later.";
507                 }
508 #if PIPELINING
509 # if _FFR_NO_PIPE
510                 else if (bitset(SRV_NO_PIPE, features))
511                 {
512                         /* for consistency */
513                         features &= ~SRV_OFFER_PIPE;
514                 }
515 # endif /* _FFR_NO_PIPE */
516 #endif /* PIPELINING */
517         }
518
519         hostname = macvalue('j', e);
520 #if SASL
521         sasl_ok = bitset(SRV_OFFER_AUTH, features);
522         n_mechs = 0;
523         authenticating = SASL_NOT_AUTH;
524
525         /* SASL server new connection */
526         if (sasl_ok)
527         {
528 # if SASL >= 20000
529                 result = sasl_server_new("smtp", hostname, NULL, NULL, NULL,
530                                          NULL, 0, &conn);
531 # elif SASL > 10505
532                 /* use empty realm: only works in SASL > 1.5.5 */
533                 result = sasl_server_new("smtp", hostname, "", NULL, 0, &conn);
534 # else /* SASL >= 20000 */
535                 /* use no realm -> realm is set to hostname by SASL lib */
536                 result = sasl_server_new("smtp", hostname, NULL, NULL, 0,
537                                          &conn);
538 # endif /* SASL >= 20000 */
539                 sasl_ok = result == SASL_OK;
540                 if (!sasl_ok)
541                 {
542                         if (LogLevel > 9)
543                                 sm_syslog(LOG_WARNING, NOQID,
544                                           "AUTH error: sasl_server_new failed=%d",
545                                           result);
546                 }
547         }
548         if (sasl_ok)
549         {
550                 /*
551                 **  SASL set properties for sasl
552                 **  set local/remote IP
553                 **  XXX Cyrus SASL v1 only supports IPv4
554                 **
555                 **  XXX where exactly are these used/required?
556                 **  Kerberos_v4
557                 */
558
559 # if SASL >= 20000
560 #  if NETINET || NETINET6
561                 in = macvalue(macid("{daemon_family}"), e);
562                 if (in != NULL && (
563 #   if NETINET6
564                     strcmp(in, "inet6") == 0 ||
565 #   endif /* NETINET6 */
566                     strcmp(in, "inet") == 0))
567                 {
568                         SOCKADDR_LEN_T addrsize;
569                         SOCKADDR saddr_l;
570                         SOCKADDR saddr_r;
571                         char localip[60], remoteip[60];
572
573                         addrsize = sizeof(saddr_r);
574                         if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
575                                                       NULL),
576                                         (struct sockaddr *) &saddr_r,
577                                         &addrsize) == 0)
578                         {
579                                 if (iptostring(&saddr_r, addrsize,
580                                                remoteip, sizeof remoteip))
581                                 {
582                                         sasl_setprop(conn, SASL_IPREMOTEPORT,
583                                                      remoteip);
584                                 }
585                                 addrsize = sizeof(saddr_l);
586                                 if (getsockname(sm_io_getinfo(InChannel,
587                                                               SM_IO_WHAT_FD,
588                                                               NULL),
589                                                 (struct sockaddr *) &saddr_l,
590                                                 &addrsize) == 0)
591                                 {
592                                         if (iptostring(&saddr_l, addrsize,
593                                                        localip,
594                                                        sizeof localip))
595                                         {
596                                                 sasl_setprop(conn,
597                                                              SASL_IPLOCALPORT,
598                                                              localip);
599                                         }
600                                 }
601                         }
602                 }
603 #  endif /* NETINET || NETINET6 */
604 # else /* SASL >= 20000 */
605 #  if NETINET
606                 in = macvalue(macid("{daemon_family}"), e);
607                 if (in != NULL && strcmp(in, "inet") == 0)
608                 {
609                         SOCKADDR_LEN_T addrsize;
610                         struct sockaddr_in saddr_l;
611                         struct sockaddr_in saddr_r;
612
613                         addrsize = sizeof(struct sockaddr_in);
614                         if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
615                                                       NULL),
616                                         (struct sockaddr *)&saddr_r,
617                                         &addrsize) == 0)
618                         {
619                                 sasl_setprop(conn, SASL_IP_REMOTE, &saddr_r);
620                                 addrsize = sizeof(struct sockaddr_in);
621                                 if (getsockname(sm_io_getinfo(InChannel,
622                                                               SM_IO_WHAT_FD,
623                                                               NULL),
624                                                 (struct sockaddr *)&saddr_l,
625                                                 &addrsize) == 0)
626                                         sasl_setprop(conn, SASL_IP_LOCAL,
627                                                      &saddr_l);
628                         }
629                 }
630 #  endif /* NETINET */
631 # endif /* SASL >= 20000 */
632
633                 auth_type = NULL;
634                 mechlist = NULL;
635                 user = NULL;
636 # if 0
637                 macdefine(&BlankEnvelope.e_macro, A_PERM,
638                         macid("{auth_author}"), NULL);
639 # endif /* 0 */
640
641                 /* set properties */
642                 (void) memset(&ssp, '\0', sizeof ssp);
643
644                 /* XXX should these be options settable via .cf ? */
645                 /* ssp.min_ssf = 0; is default due to memset() */
646 # if STARTTLS
647 # endif /* STARTTLS */
648                 {
649                         ssp.max_ssf = MaxSLBits;
650                         ssp.maxbufsize = MAXOUTLEN;
651                 }
652                 ssp.security_flags = SASLOpts & SASL_SEC_MASK;
653                 sasl_ok = sasl_setprop(conn, SASL_SEC_PROPS, &ssp) == SASL_OK;
654
655                 if (sasl_ok)
656                 {
657                         /*
658                         **  external security strength factor;
659                         **      currently we have none so zero
660                         */
661
662 # if SASL >= 20000
663                         ext_ssf = 0;
664                         auth_id = NULL;
665                         sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL,
666                                                  &ext_ssf) == SASL_OK) &&
667                                    (sasl_setprop(conn, SASL_AUTH_EXTERNAL,
668                                                  auth_id) == SASL_OK));
669 # else /* SASL >= 20000 */
670                         ext_ssf.ssf = 0;
671                         ext_ssf.auth_id = NULL;
672                         sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
673                                                &ext_ssf) == SASL_OK;
674 # endif /* SASL >= 20000 */
675                 }
676                 if (sasl_ok)
677                         n_mechs = saslmechs(conn, &mechlist);
678         }
679 #endif /* SASL */
680
681 #if MILTER
682         if (smtp.sm_milterize)
683         {
684                 char state;
685
686                 /* initialize mail filter connection */
687                 smtp.sm_milterlist = milter_init(e, &state);
688                 switch (state)
689                 {
690                   case SMFIR_REJECT:
691                         if (MilterLogLevel > 3)
692                                 sm_syslog(LOG_INFO, e->e_id,
693                                           "Milter: initialization failed, rejecting commands");
694                         greetcode = "554";
695                         nullserver = "Command rejected";
696                         smtp.sm_milterize = false;
697                         break;
698
699                   case SMFIR_TEMPFAIL:
700                         if (MilterLogLevel > 3)
701                                 sm_syslog(LOG_INFO, e->e_id,
702                                           "Milter: initialization failed, temp failing commands");
703                         tempfail = true;
704                         smtp.sm_milterize = false;
705                         break;
706                 }
707         }
708
709         if (smtp.sm_milterlist && smtp.sm_milterize &&
710             !bitset(EF_DISCARD, e->e_flags))
711         {
712                 char state;
713                 char *response;
714
715                 response = milter_connect(peerhostname, RealHostAddr,
716                                           e, &state);
717                 switch (state)
718                 {
719                   case SMFIR_REPLYCODE: /* REPLYCODE shouldn't happen */
720                   case SMFIR_REJECT:
721                         if (MilterLogLevel > 3)
722                                 sm_syslog(LOG_INFO, e->e_id,
723                                           "Milter: connect: host=%s, addr=%s, rejecting commands",
724                                           peerhostname,
725                                           anynet_ntoa(&RealHostAddr));
726                         greetcode = "554";
727                         nullserver = "Command rejected";
728                         smtp.sm_milterize = false;
729                         break;
730
731                   case SMFIR_TEMPFAIL:
732                         if (MilterLogLevel > 3)
733                                 sm_syslog(LOG_INFO, e->e_id,
734                                           "Milter: connect: host=%s, addr=%s, temp failing commands",
735                                           peerhostname,
736                                           anynet_ntoa(&RealHostAddr));
737                         tempfail = true;
738                         smtp.sm_milterize = false;
739                         break;
740
741 #if _FFR_MILTER_421
742                   case SMFIR_SHUTDOWN:
743                         if (MilterLogLevel > 3)
744                                 sm_syslog(LOG_INFO, e->e_id,
745                                           "Milter: connect: host=%s, addr=%s, shutdown",
746                                           peerhostname,
747                                           anynet_ntoa(&RealHostAddr));
748                         tempfail = true;
749                         smtp.sm_milterize = false;
750                         message("421 4.7.0 %s closing connection",
751                                         MyHostName);
752
753                         /* arrange to ignore send list */
754                         e->e_sendqueue = NULL;
755                         goto doquit;
756 #endif /* _FFR_MILTER_421 */
757                 }
758                 if (response != NULL)
759
760                         sm_free(response); /* XXX */
761         }
762 #endif /* MILTER */
763
764 #if STARTTLS
765 # if _FFR_SMTP_SSL
766         /* If this an smtps connection, start TLS now */
767         smtps = bitnset(D_SMTPS, d_flags);
768         if (smtps)
769                 goto starttls;
770
771   greeting:
772
773 # endif /* _FFR_SMTP_SSL */
774 #endif /* STARTTLS */
775
776         /* output the first line, inserting "ESMTP" as second word */
777         if (*greetcode == '5')
778                 (void) sm_snprintf(inp, sizeof inp, "%s not accepting messages",
779                                    hostname);
780         else
781                 expand(SmtpGreeting, inp, sizeof inp, e);
782
783         p = strchr(inp, '\n');
784         if (p != NULL)
785                 *p++ = '\0';
786         id = strchr(inp, ' ');
787         if (id == NULL)
788                 id = &inp[strlen(inp)];
789         if (p == NULL)
790                 (void) sm_snprintf(cmdbuf, sizeof cmdbuf,
791                          "%s %%.*s ESMTP%%s", greetcode);
792         else
793                 (void) sm_snprintf(cmdbuf, sizeof cmdbuf,
794                          "%s-%%.*s ESMTP%%s", greetcode);
795         message(cmdbuf, (int) (id - inp), inp, id);
796
797         /* output remaining lines */
798         while ((id = p) != NULL && (p = strchr(id, '\n')) != NULL)
799         {
800                 *p++ = '\0';
801                 if (isascii(*id) && isspace(*id))
802                         id++;
803                 (void) sm_strlcpyn(cmdbuf, sizeof cmdbuf, 2, greetcode, "-%s");
804                 message(cmdbuf, id);
805         }
806         if (id != NULL)
807         {
808                 if (isascii(*id) && isspace(*id))
809                         id++;
810                 (void) sm_strlcpyn(cmdbuf, sizeof cmdbuf, 2, greetcode, " %s");
811                 message(cmdbuf, id);
812         }
813
814         protocol = NULL;
815         sendinghost = macvalue('s', e);
816
817 #if _FFR_QUARANTINE
818         /* If quarantining by a connect/ehlo action, save between messages */
819         if (e->e_quarmsg == NULL)
820                 smtp.sm_quarmsg = NULL;
821         else
822                 smtp.sm_quarmsg = newstr(e->e_quarmsg);
823 #endif /* _FFR_QUARANTINE */
824
825         /* sendinghost's storage must outlive the current envelope */
826         if (sendinghost != NULL)
827                 sendinghost = sm_strdup_x(sendinghost);
828 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
829         first = true;
830 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
831         gothello = false;
832         smtp.sm_gotmail = false;
833         for (;;)
834         {
835             SM_TRY
836             {
837                 QuickAbort = false;
838                 HoldErrs = false;
839                 SuprErrs = false;
840                 LogUsrErrs = false;
841                 OnlyOneError = true;
842                 e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
843
844                 /* setup for the read */
845                 e->e_to = NULL;
846                 Errors = 0;
847                 FileName = NULL;
848                 (void) sm_io_flush(smioout, SM_TIME_DEFAULT);
849
850                 /* read the input line */
851                 SmtpPhase = "server cmd read";
852                 sm_setproctitle(true, e, "server %s cmd read", CurSmtpClient);
853 #if SASL
854                 /*
855                 **  XXX SMTP AUTH requires accepting any length,
856                 **      at least for challenge/response
857                 */
858 #endif /* SASL */
859
860                 /* handle errors */
861                 if (sm_io_error(OutChannel) ||
862                     (p = sfgets(inp, sizeof inp, InChannel,
863                                 TimeOuts.to_nextcommand, SmtpPhase)) == NULL)
864                 {
865                         char *d;
866
867                         d = macvalue(macid("{daemon_name}"), e);
868                         if (d == NULL)
869                                 d = "stdin";
870                         /* end of file, just die */
871                         disconnect(1, e);
872
873 #if MILTER
874                         /* close out milter filters */
875                         milter_quit(e);
876 #endif /* MILTER */
877
878                         message("421 4.4.1 %s Lost input channel from %s",
879                                 MyHostName, CurSmtpClient);
880                         if (LogLevel > (smtp.sm_gotmail ? 1 : 19))
881                                 sm_syslog(LOG_NOTICE, e->e_id,
882                                           "lost input channel from %s to %s after %s",
883                                           CurSmtpClient, d,
884                                           (c == NULL || c->cmd_name == NULL) ? "startup" : c->cmd_name);
885                         /*
886                         **  If have not accepted mail (DATA), do not bounce
887                         **  bad addresses back to sender.
888                         */
889
890                         if (bitset(EF_CLRQUEUE, e->e_flags))
891                                 e->e_sendqueue = NULL;
892                         goto doquit;
893                 }
894
895 #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL
896                 if (first)
897                 {
898 #if _FFR_BLOCK_PROXIES
899                         size_t inplen, cmdlen;
900                         int idx;
901                         char *http_cmd;
902                         static char *http_cmds[] = { "GET", "POST",
903                                                      "CONNECT", "USER", NULL };
904
905                         inplen = strlen(inp);
906                         for (idx = 0; (http_cmd = http_cmds[idx]) != NULL;
907                              idx++)
908                         {
909                                 cmdlen = strlen(http_cmd);
910                                 if (cmdlen < inplen &&
911                                     sm_strncasecmp(inp, http_cmd, cmdlen) == 0 &&
912                                     isascii(inp[cmdlen]) && isspace(inp[cmdlen]))
913                                 {
914                                         /* Open proxy, drop it */
915                                         message("421 4.7.0 %s Rejecting open proxy %s",
916                                                 MyHostName, CurSmtpClient);
917                                         sm_syslog(LOG_INFO, e->e_id,
918                                                   "%s: probable open proxy: command=%.40s",
919                                                   CurSmtpClient, inp);
920                                         goto doquit;
921                                 }
922                         }
923 #endif /* _FFR_BLOCK_PROXIES */
924 #if _FFR_ADAPTIVE_EOL
925                         char *p;
926
927                         smtp.sm_crlf = true;
928                         p = strchr(inp, '\n');
929                         if (p == NULL || p <= inp || p[-1] != '\r')
930                         {
931                                 smtp.sm_crlf = false;
932                                 if (tTd(66, 1) && LogLevel > 8)
933                                 {
934                                         /* how many bad guys are there? */
935                                         sm_syslog(LOG_INFO, NOQID,
936                                                   "%s did not use CRLF",
937                                                   CurSmtpClient);
938                                 }
939                         }
940 #endif /* _FFR_ADAPTIVE_EOL */
941                         first = false;
942                 }
943 #endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */
944
945                 /* clean up end of line */
946                 fixcrlf(inp, true);
947
948 #if PIPELINING
949 # if _FFR_NO_PIPE
950                 /*
951                 **  if there is more input and pipelining is disabled:
952                 **      delay ... (and maybe discard the input?)
953                 **  XXX this doesn't really work, at least in tests using
954                 **  telnet SM_IO_IS_READABLE only returns 1 if there were
955                 **  more than 2 input lines available.
956                 */
957
958                 if (bitset(SRV_NO_PIPE, features) &&
959                     sm_io_getinfo(InChannel, SM_IO_IS_READABLE, NULL) > 0)
960                 {
961                         if (++np_log < 3)
962                                 sm_syslog(LOG_INFO, NOQID,
963                                           "unauthorized PIPELINING, sleeping");
964                         sleep(1);
965                 }
966
967 # endif /* _FFR_NO_PIPE */
968 #endif /* PIPELINING */
969
970 #if SASL
971                 if (authenticating == SASL_PROC_AUTH)
972                 {
973 # if 0
974                         if (*inp == '\0')
975                         {
976                                 authenticating = SASL_NOT_AUTH;
977                                 message("501 5.5.2 missing input");
978                                 continue;
979                         }
980 # endif /* 0 */
981                         if (*inp == '*' && *(inp + 1) == '\0')
982                         {
983                                 authenticating = SASL_NOT_AUTH;
984
985                                 /* rfc 2254 4. */
986                                 message("501 5.0.0 AUTH aborted");
987                                 continue;
988                         }
989
990                         /* could this be shorter? XXX */
991 # if SASL >= 20000
992                         in = xalloc(strlen(inp) + 1);
993                         result = sasl_decode64(inp, strlen(inp), in,
994                                                strlen(inp), &inlen);
995 # else /* SASL >= 20000 */
996                         out = xalloc(strlen(inp));
997                         result = sasl_decode64(inp, strlen(inp), out, &outlen);
998 # endif /* SASL >= 20000 */
999                         if (result != SASL_OK)
1000                         {
1001                                 authenticating = SASL_NOT_AUTH;
1002
1003                                 /* rfc 2254 4. */
1004                                 message("501 5.5.4 cannot decode AUTH parameter %s",
1005                                         inp);
1006 # if SASL >= 20000
1007                                 sm_free(in);
1008 # endif /* SASL >= 20000 */
1009                                 continue;
1010                         }
1011
1012 # if SASL >= 20000
1013                         result = sasl_server_step(conn, in, inlen,
1014                                                   &out, &outlen);
1015                         sm_free(in);
1016 # else /* SASL >= 20000 */
1017                         result = sasl_server_step(conn, out, outlen,
1018                                                   &out, &outlen, &errstr);
1019 # endif /* SASL >= 20000 */
1020
1021                         /* get an OK if we're done */
1022                         if (result == SASL_OK)
1023                         {
1024   authenticated:
1025                                 message("235 2.0.0 OK Authenticated");
1026                                 authenticating = SASL_IS_AUTH;
1027                                 macdefine(&BlankEnvelope.e_macro, A_TEMP,
1028                                         macid("{auth_type}"), auth_type);
1029
1030 # if SASL >= 20000
1031                                 user = macvalue(macid("{auth_authen}"), e);
1032
1033                                 /* get security strength (features) */
1034                                 result = sasl_getprop(conn, SASL_SSF,
1035                                                       (const void **) &ssf);
1036 # else /* SASL >= 20000 */
1037                                 result = sasl_getprop(conn, SASL_USERNAME,
1038                                                       (void **)&user);
1039                                 if (result != SASL_OK)
1040                                 {
1041                                         user = "";
1042                                         macdefine(&BlankEnvelope.e_macro,
1043                                                   A_PERM,
1044                                                   macid("{auth_authen}"), NULL);
1045                                 }
1046                                 else
1047                                 {
1048                                         macdefine(&BlankEnvelope.e_macro,
1049                                                   A_TEMP,
1050                                                   macid("{auth_authen}"), user);
1051                                 }
1052
1053 # if 0
1054                                 /* get realm? */
1055                                 sasl_getprop(conn, SASL_REALM, (void **) &data);
1056 # endif /* 0 */
1057
1058                                 /* get security strength (features) */
1059                                 result = sasl_getprop(conn, SASL_SSF,
1060                                                       (void **) &ssf);
1061 # endif /* SASL >= 20000 */
1062                                 if (result != SASL_OK)
1063                                 {
1064                                         macdefine(&BlankEnvelope.e_macro,
1065                                                   A_PERM,
1066                                                   macid("{auth_ssf}"), "0");
1067                                         ssf = NULL;
1068                                 }
1069                                 else
1070                                 {
1071                                         char pbuf[8];
1072
1073                                         (void) sm_snprintf(pbuf, sizeof pbuf,
1074                                                            "%u", *ssf);
1075                                         macdefine(&BlankEnvelope.e_macro,
1076                                                   A_TEMP,
1077                                                   macid("{auth_ssf}"), pbuf);
1078                                         if (tTd(95, 8))
1079                                                 sm_dprintf("AUTH auth_ssf: %u\n",
1080                                                            *ssf);
1081                                 }
1082
1083                                 /*
1084                                 **  Only switch to encrypted connection
1085                                 **  if a security layer has been negotiated
1086                                 */
1087
1088                                 if (ssf != NULL && *ssf > 0)
1089                                 {
1090                                         /*
1091                                         **  Convert I/O layer to use SASL.
1092                                         **  If the call fails, the connection
1093                                         **  is aborted.
1094                                         */
1095
1096                                         if (sfdcsasl(&InChannel, &OutChannel,
1097                                                      conn) == 0)
1098                                         {
1099                                                 /* restart dialogue */
1100                                                 n_helo = 0;
1101 # if PIPELINING
1102                                                 (void) sm_io_autoflush(InChannel,
1103                                                                        OutChannel);
1104 # endif /* PIPELINING */
1105                                         }
1106                                         else
1107                                                 syserr("503 5.3.3 SASL TLS failed");
1108                                 }
1109
1110                                 /* NULL pointer ok since it's our function */
1111                                 if (LogLevel > 8)
1112                                         sm_syslog(LOG_INFO, NOQID,
1113                                                   "AUTH=server, relay=%s, authid=%.128s, mech=%.16s, bits=%d",
1114                                                   CurSmtpClient,
1115                                                   shortenstring(user, 128),
1116                                                   auth_type, *ssf);
1117                         }
1118                         else if (result == SASL_CONTINUE)
1119                         {
1120                                 len = ENC64LEN(outlen);
1121                                 out2 = xalloc(len);
1122                                 result = sasl_encode64(out, outlen, out2, len,
1123                                                        &out2len);
1124                                 if (result != SASL_OK)
1125                                 {
1126                                         /* correct code? XXX */
1127                                         /* 454 Temp. authentication failure */
1128                                         message("454 4.5.4 Internal error: unable to encode64");
1129                                         if (LogLevel > 5)
1130                                                 sm_syslog(LOG_WARNING, e->e_id,
1131                                                           "AUTH encode64 error [%d for \"%s\"]",
1132                                                           result, out);
1133                                         /* start over? */
1134                                         authenticating = SASL_NOT_AUTH;
1135                                 }
1136                                 else
1137                                 {
1138                                         message("334 %s", out2);
1139                                         if (tTd(95, 2))
1140                                                 sm_dprintf("AUTH continue: msg='%s' len=%u\n",
1141                                                            out2, out2len);
1142                                 }
1143 # if SASL >= 20000
1144                                 sm_free(out2);
1145 # endif /* SASL >= 20000 */
1146                         }
1147                         else
1148                         {
1149                                 /* not SASL_OK or SASL_CONT */
1150                                 message("535 5.7.0 authentication failed");
1151                                 if (LogLevel > 9)
1152                                         sm_syslog(LOG_WARNING, e->e_id,
1153                                                   "AUTH failure (%s): %s (%d) %s",
1154                                                   auth_type,
1155                                                   sasl_errstring(result, NULL,
1156                                                                  NULL),
1157                                                   result,
1158 # if SASL >= 20000
1159                                                   sasl_errdetail(conn));
1160 # else /* SASL >= 20000 */
1161                                                   errstr == NULL ? "" : errstr);
1162 # endif /* SASL >= 20000 */
1163                                 authenticating = SASL_NOT_AUTH;
1164                         }
1165                 }
1166                 else
1167                 {
1168                         /* don't want to do any of this if authenticating */
1169 #endif /* SASL */
1170
1171                 /* echo command to transcript */
1172                 if (e->e_xfp != NULL)
1173                         (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
1174                                              "<<< %s\n", inp);
1175
1176                 if (LogLevel > 14)
1177                         sm_syslog(LOG_INFO, e->e_id, "<-- %s", inp);
1178
1179                 /* break off command */
1180                 for (p = inp; isascii(*p) && isspace(*p); p++)
1181                         continue;
1182                 cmd = cmdbuf;
1183                 while (*p != '\0' &&
1184                        !(isascii(*p) && isspace(*p)) &&
1185                        cmd < &cmdbuf[sizeof cmdbuf - 2])
1186                         *cmd++ = *p++;
1187                 *cmd = '\0';
1188
1189                 /* throw away leading whitespace */
1190                 SKIP_SPACE(p);
1191
1192                 /* decode command */
1193                 for (c = CmdTab; c->cmd_name != NULL; c++)
1194                 {
1195                         if (sm_strcasecmp(c->cmd_name, cmdbuf) == 0)
1196                                 break;
1197                 }
1198
1199                 /* reset errors */
1200                 errno = 0;
1201
1202                 /* check whether a "non-null" command has been used */
1203                 switch (c->cmd_code)
1204                 {
1205 #if SASL
1206                   case CMDAUTH:
1207                         /* avoid information leak; take first two words? */
1208                         q = "AUTH";
1209                         break;
1210 #endif /* SASL */
1211
1212                   case CMDMAIL:
1213                   case CMDEXPN:
1214                   case CMDVRFY:
1215                   case CMDETRN:
1216                         lognullconnection = false;
1217                         /* FALLTHROUGH */
1218                   default:
1219                         q = inp;
1220                         break;
1221                 }
1222
1223                 if (e->e_id == NULL)
1224                         sm_setproctitle(true, e, "%s: %.80s",
1225                                         CurSmtpClient, q);
1226                 else
1227                         sm_setproctitle(true, e, "%s %s: %.80s",
1228                                         qid_printname(e),
1229                                         CurSmtpClient, q);
1230
1231                 /*
1232                 **  Process command.
1233                 **
1234                 **      If we are running as a null server, return 550
1235                 **      to almost everything.
1236                 */
1237
1238                 if (nullserver != NULL || bitnset(D_ETRNONLY, d_flags))
1239                 {
1240                         switch (c->cmd_code)
1241                         {
1242                           case CMDQUIT:
1243                           case CMDHELO:
1244                           case CMDEHLO:
1245                           case CMDNOOP:
1246                           case CMDRSET:
1247                                 /* process normally */
1248                                 break;
1249
1250                           case CMDETRN:
1251                                 if (bitnset(D_ETRNONLY, d_flags) &&
1252                                     nullserver == NULL)
1253                                         break;
1254                                 DELAY_CONN("ETRN");
1255                                 /* FALLTHROUGH */
1256
1257                           default:
1258 #if MAXBADCOMMANDS > 0
1259                                 /* theoretically this could overflow */
1260                                 if (nullserver != NULL &&
1261                                     ++n_badcmds > MAXBADCOMMANDS)
1262                                 {
1263                                         message("421 4.7.0 %s Too many bad commands; closing connection",
1264                                                 MyHostName);
1265
1266                                         /* arrange to ignore send list */
1267                                         e->e_sendqueue = NULL;
1268                                         goto doquit;
1269                                 }
1270 #endif /* MAXBADCOMMANDS > 0 */
1271                                 if (nullserver != NULL)
1272                                 {
1273                                         if (ISSMTPREPLY(nullserver))
1274                                                 usrerr(nullserver);
1275                                         else
1276                                                 usrerr("550 5.0.0 %s",
1277                                                        nullserver);
1278                                 }
1279                                 else
1280                                         usrerr("452 4.4.5 Insufficient disk space; try again later");
1281                                 continue;
1282                         }
1283                 }
1284
1285                 switch (c->cmd_code)
1286                 {
1287 #if SASL
1288                   case CMDAUTH: /* sasl */
1289                         DELAY_CONN("AUTH");
1290                         if (!sasl_ok || n_mechs <= 0)
1291                         {
1292                                 message("503 5.3.3 AUTH not available");
1293                                 break;
1294                         }
1295                         if (authenticating == SASL_IS_AUTH)
1296                         {
1297                                 message("503 5.5.0 Already Authenticated");
1298                                 break;
1299                         }
1300                         if (smtp.sm_gotmail)
1301                         {
1302                                 message("503 5.5.0 AUTH not permitted during a mail transaction");
1303                                 break;
1304                         }
1305                         if (tempfail)
1306                         {
1307                                 if (LogLevel > 9)
1308                                         sm_syslog(LOG_INFO, e->e_id,
1309                                                   "SMTP AUTH command (%.100s) from %s tempfailed (due to previous checks)",
1310                                                   p, CurSmtpClient);
1311                                 usrerr("454 4.7.1 Please try again later");
1312                                 break;
1313                         }
1314
1315                         ismore = false;
1316
1317                         /* crude way to avoid crack attempts */
1318                         (void) checksmtpattack(&n_auth, n_mechs + 1, true,
1319                                                "AUTH", e);
1320
1321                         /* make sure mechanism (p) is a valid string */
1322                         for (q = p; *q != '\0' && isascii(*q); q++)
1323                         {
1324                                 if (isspace(*q))
1325                                 {
1326                                         *q = '\0';
1327                                         while (*++q != '\0' &&
1328                                                isascii(*q) && isspace(*q))
1329                                                 continue;
1330                                         *(q - 1) = '\0';
1331                                         ismore = (*q != '\0');
1332                                         break;
1333                                 }
1334                         }
1335
1336                         if (*p == '\0')
1337                         {
1338                                 message("501 5.5.2 AUTH mechanism must be specified");
1339                                 break;
1340                         }
1341
1342                         /* check whether mechanism is available */
1343                         if (iteminlist(p, mechlist, " ") == NULL)
1344                         {
1345                                 message("504 5.3.3 AUTH mechanism %.32s not available",
1346                                         p);
1347                                 break;
1348                         }
1349
1350                         if (ismore)
1351                         {
1352                                 /* could this be shorter? XXX */
1353 # if SASL >= 20000
1354                                 in = xalloc(strlen(q) + 1);
1355                                 result = sasl_decode64(q, strlen(q), in,
1356                                                        strlen(q), &inlen);
1357 # else /* SASL >= 20000 */
1358                                 in = sm_rpool_malloc(e->e_rpool, strlen(q));
1359                                 result = sasl_decode64(q, strlen(q), in,
1360                                                        &inlen);
1361 # endif /* SASL >= 20000 */
1362                                 if (result != SASL_OK)
1363                                 {
1364                                         message("501 5.5.4 cannot BASE64 decode '%s'",
1365                                                 q);
1366                                         if (LogLevel > 5)
1367                                                 sm_syslog(LOG_WARNING, e->e_id,
1368                                                           "AUTH decode64 error [%d for \"%s\"]",
1369                                                           result, q);
1370                                         /* start over? */
1371                                         authenticating = SASL_NOT_AUTH;
1372 # if SASL >= 20000
1373                                         sm_free(in);
1374 # endif /* SASL >= 20000 */
1375                                         in = NULL;
1376                                         inlen = 0;
1377                                         break;
1378                                 }
1379                         }
1380                         else
1381                         {
1382                                 in = NULL;
1383                                 inlen = 0;
1384                         }
1385
1386                         /* see if that auth type exists */
1387 # if SASL >= 20000
1388                         result = sasl_server_start(conn, p, in, inlen,
1389                                                    &out, &outlen);
1390                         if (in != NULL)
1391                                 sm_free(in);
1392 # else /* SASL >= 20000 */
1393                         result = sasl_server_start(conn, p, in, inlen,
1394                                                    &out, &outlen, &errstr);
1395 # endif /* SASL >= 20000 */
1396
1397                         if (result != SASL_OK && result != SASL_CONTINUE)
1398                         {
1399                                 message("535 5.7.0 authentication failed");
1400                                 if (LogLevel > 9)
1401                                         sm_syslog(LOG_ERR, e->e_id,
1402                                                   "AUTH failure (%s): %s (%d) %s",
1403                                                   p,
1404                                                   sasl_errstring(result, NULL,
1405                                                                  NULL),
1406                                                   result,
1407 # if SASL >= 20000
1408                                                   sasl_errdetail(conn));
1409 # else /* SASL >= 20000 */
1410                                                   errstr);
1411 # endif /* SASL >= 20000 */
1412                                 break;
1413                         }
1414                         auth_type = newstr(p);
1415
1416                         if (result == SASL_OK)
1417                         {
1418                                 /* ugly, but same code */
1419                                 goto authenticated;
1420                                 /* authenticated by the initial response */
1421                         }
1422
1423                         /* len is at least 2 */
1424                         len = ENC64LEN(outlen);
1425                         out2 = xalloc(len);
1426                         result = sasl_encode64(out, outlen, out2, len,
1427                                                &out2len);
1428
1429                         if (result != SASL_OK)
1430                         {
1431                                 message("454 4.5.4 Temporary authentication failure");
1432                                 if (LogLevel > 5)
1433                                         sm_syslog(LOG_WARNING, e->e_id,
1434                                                   "AUTH encode64 error [%d for \"%s\"]",
1435                                                   result, out);
1436
1437                                 /* start over? */
1438                                 authenticating = SASL_NOT_AUTH;
1439                         }
1440                         else
1441                         {
1442                                 message("334 %s", out2);
1443                                 authenticating = SASL_PROC_AUTH;
1444                         }
1445 # if SASL >= 20000
1446                         sm_free(out2);
1447 # endif /* SASL >= 20000 */
1448                         break;
1449 #endif /* SASL */
1450
1451 #if STARTTLS
1452                   case CMDSTLS: /* starttls */
1453                         DELAY_CONN("STARTTLS");
1454                         if (*p != '\0')
1455                         {
1456                                 message("501 5.5.2 Syntax error (no parameters allowed)");
1457                                 break;
1458                         }
1459                         if (!bitset(SRV_OFFER_TLS, features))
1460                         {
1461                                 message("503 5.5.0 TLS not available");
1462                                 break;
1463                         }
1464                         if (!tls_ok_srv)
1465                         {
1466                                 message("454 4.3.3 TLS not available after start");
1467                                 break;
1468                         }
1469                         if (smtp.sm_gotmail)
1470                         {
1471                                 message("503 5.5.0 TLS not permitted during a mail transaction");
1472                                 break;
1473                         }
1474                         if (tempfail)
1475                         {
1476                                 if (LogLevel > 9)
1477                                         sm_syslog(LOG_INFO, e->e_id,
1478                                                   "SMTP STARTTLS command (%.100s) from %s tempfailed (due to previous checks)",
1479                                                   p, CurSmtpClient);
1480                                 usrerr("454 4.7.1 Please try again later");
1481                                 break;
1482                         }
1483 # if _FFR_SMTP_SSL
1484   starttls:
1485 # endif /* _FFR_SMTP_SSL */
1486 # if TLS_NO_RSA
1487                         /*
1488                         **  XXX do we need a temp key ?
1489                         */
1490 # else /* TLS_NO_RSA */
1491 # endif /* TLS_NO_RSA */
1492
1493 # if TLS_VRFY_PER_CTX
1494                         /*
1495                         **  Note: this sets the verification globally
1496                         **  (per SSL_CTX)
1497                         **  it's ok since it applies only to one transaction
1498                         */
1499
1500                         TLS_VERIFY_CLIENT();
1501 # endif /* TLS_VRFY_PER_CTX */
1502
1503                         if (srv_ssl != NULL)
1504                                 SSL_clear(srv_ssl);
1505                         else if ((srv_ssl = SSL_new(srv_ctx)) == NULL)
1506                         {
1507                                 message("454 4.3.3 TLS not available: error generating SSL handle");
1508 # if _FFR_SMTP_SSL
1509                                 goto tls_done;
1510 # else /* _FFR_SMTP_SSL */
1511                                 break;
1512 # endif /* _FFR_SMTP_SSL */
1513                         }
1514
1515 # if !TLS_VRFY_PER_CTX
1516                         /*
1517                         **  this could be used if it were possible to set
1518                         **  verification per SSL (connection)
1519                         **  not just per SSL_CTX (global)
1520                         */
1521
1522                         TLS_VERIFY_CLIENT();
1523 # endif /* !TLS_VRFY_PER_CTX */
1524
1525                         rfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
1526                         wfd = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL);
1527
1528                         if (rfd < 0 || wfd < 0 ||
1529                             SSL_set_rfd(srv_ssl, rfd) <= 0 ||
1530                             SSL_set_wfd(srv_ssl, wfd) <= 0)
1531                         {
1532                                 message("454 4.3.3 TLS not available: error set fd");
1533                                 SSL_free(srv_ssl);
1534                                 srv_ssl = NULL;
1535 # if _FFR_SMTP_SSL
1536                                 goto tls_done;
1537 # else /* _FFR_SMTP_SSL */
1538                                 break;
1539 # endif /* _FFR_SMTP_SSL */
1540                         }
1541 # if _FFR_SMTP_SSL
1542                         if (!smtps)
1543 # endif /* _FFR_SMTP_SSL */
1544                                 message("220 2.0.0 Ready to start TLS");
1545 # if PIPELINING
1546                         (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
1547 # endif /* PIPELINING */
1548
1549                         SSL_set_accept_state(srv_ssl);
1550
1551 #  define SSL_ACC(s)    SSL_accept(s)
1552
1553                         tlsstart = curtime();
1554   ssl_retry:
1555                         if ((r = SSL_ACC(srv_ssl)) <= 0)
1556                         {
1557                                 int i;
1558                                 bool timedout;
1559                                 time_t left;
1560                                 time_t now = curtime();
1561                                 struct timeval tv;
1562
1563                                 /* what to do in this case? */
1564                                 i = SSL_get_error(srv_ssl, r);
1565
1566                                 /*
1567                                 **  For SSL_ERROR_WANT_{READ,WRITE}:
1568                                 **  There is no SSL record available yet
1569                                 **  or there is only a partial SSL record
1570                                 **  removed from the network (socket) buffer
1571                                 **  into the SSL buffer. The SSL_accept will
1572                                 **  only succeed when a full SSL record is
1573                                 **  available (assuming a "real" error
1574                                 **  doesn't happen). To handle when a "real"
1575                                 **  error does happen the select is set for
1576                                 **  exceptions too.
1577                                 **  The connection may be re-negotiated
1578                                 **  during this time so both read and write
1579                                 **  "want errors" need to be handled.
1580                                 **  A select() exception loops back so that
1581                                 **  a proper SSL error message can be gotten.
1582                                 */
1583
1584                                 left = TimeOuts.to_starttls - (now - tlsstart);
1585                                 timedout = left <= 0;
1586                                 if (!timedout)
1587                                 {
1588                                         tv.tv_sec = left;
1589                                         tv.tv_usec = 0;
1590                                 }
1591
1592                                 if (!timedout && FD_SETSIZE > 0 &&
1593                                     (rfd >= FD_SETSIZE ||
1594                                      (i == SSL_ERROR_WANT_WRITE &&
1595                                       wfd >= FD_SETSIZE)))
1596                                 {
1597                                         if (LogLevel > 5)
1598                                         {
1599                                                 sm_syslog(LOG_ERR, NOQID,
1600                                                           "STARTTLS=server, error: fd %d/%d too large",
1601                                                           rfd, wfd);
1602                                                 if (LogLevel > 8)
1603                                                         tlslogerr("server");
1604                                         }
1605                                         goto tlsfail;
1606                                 }
1607
1608                                 /* XXX what about SSL_pending() ? */
1609                                 if (!timedout && i == SSL_ERROR_WANT_READ)
1610                                 {
1611                                         fd_set ssl_maskr, ssl_maskx;
1612
1613                                         FD_ZERO(&ssl_maskr);
1614                                         FD_SET(rfd, &ssl_maskr);
1615                                         FD_ZERO(&ssl_maskx);
1616                                         FD_SET(rfd, &ssl_maskx);
1617                                         if (select(rfd + 1, &ssl_maskr, NULL,
1618                                                    &ssl_maskx, &tv) > 0)
1619                                                 goto ssl_retry;
1620                                 }
1621                                 if (!timedout && i == SSL_ERROR_WANT_WRITE)
1622                                 {
1623                                         fd_set ssl_maskw, ssl_maskx;
1624
1625                                         FD_ZERO(&ssl_maskw);
1626                                         FD_SET(wfd, &ssl_maskw);
1627                                         FD_ZERO(&ssl_maskx);
1628                                         FD_SET(rfd, &ssl_maskx);
1629                                         if (select(wfd + 1, NULL, &ssl_maskw,
1630                                                    &ssl_maskx, &tv) > 0)
1631                                                 goto ssl_retry;
1632                                 }
1633                                 if (LogLevel > 5)
1634                                 {
1635                                         sm_syslog(LOG_WARNING, NOQID,
1636                                                   "STARTTLS=server, error: accept failed=%d, SSL_error=%d, timedout=%d, errno=%d",
1637                                                   r, i, (int) timedout, errno);
1638                                         if (LogLevel > 8)
1639                                                 tlslogerr("server");
1640                                 }
1641 tlsfail:
1642                                 tls_ok_srv = false;
1643                                 SSL_free(srv_ssl);
1644                                 srv_ssl = NULL;
1645
1646                                 /*
1647                                 **  according to the next draft of
1648                                 **  RFC 2487 the connection should be dropped
1649                                 */
1650
1651                                 /* arrange to ignore any current send list */
1652                                 e->e_sendqueue = NULL;
1653                                 goto doquit;
1654                         }
1655
1656                         /* ignore return code for now, it's in {verify} */
1657                         (void) tls_get_info(srv_ssl, true,
1658                                             CurSmtpClient,
1659                                             &BlankEnvelope.e_macro,
1660                                             bitset(SRV_VRFY_CLT, features));
1661
1662                         /*
1663                         **  call Stls_client to find out whether
1664                         **  to accept the connection from the client
1665                         */
1666
1667                         saveQuickAbort = QuickAbort;
1668                         saveSuprErrs = SuprErrs;
1669                         SuprErrs = true;
1670                         QuickAbort = false;
1671                         if (rscheck("tls_client",
1672                                      macvalue(macid("{verify}"), e),
1673                                      "STARTTLS", e,
1674                                      RSF_RMCOMM|RSF_COUNT,
1675                                      5, NULL, NOQID) != EX_OK ||
1676                             Errors > 0)
1677                         {
1678                                 extern char MsgBuf[];
1679
1680                                 if (MsgBuf[0] != '\0' && ISSMTPREPLY(MsgBuf))
1681                                         nullserver = newstr(MsgBuf);
1682                                 else
1683                                         nullserver = "503 5.7.0 Authentication required.";
1684                         }
1685                         QuickAbort = saveQuickAbort;
1686                         SuprErrs = saveSuprErrs;
1687
1688                         tls_ok_srv = false;     /* don't offer STARTTLS again */
1689                         n_helo = 0;
1690 # if SASL
1691                         if (sasl_ok)
1692                         {
1693                                 char *s;
1694
1695                                 s = macvalue(macid("{cipher_bits}"), e);
1696 #  if SASL >= 20000
1697                                 if (s != NULL && (ext_ssf = atoi(s)) > 0)
1698                                 {
1699                                         auth_id = macvalue(macid("{cert_subject}"),
1700                                                                    e);
1701                                         sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL,
1702                                                                  &ext_ssf) == SASL_OK) &&
1703                                                    (sasl_setprop(conn, SASL_AUTH_EXTERNAL,
1704                                                                  auth_id) == SASL_OK));
1705 #  else /* SASL >= 20000 */
1706                                 if (s != NULL && (ext_ssf.ssf = atoi(s)) > 0)
1707                                 {
1708                                         ext_ssf.auth_id = macvalue(macid("{cert_subject}"),
1709                                                                    e);
1710                                         sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
1711                                                                &ext_ssf) == SASL_OK;
1712 #  endif /* SASL >= 20000 */
1713                                         mechlist = NULL;
1714                                         if (sasl_ok)
1715                                                 n_mechs = saslmechs(conn,
1716                                                                     &mechlist);
1717                                 }
1718                         }
1719 # endif /* SASL */
1720
1721                         /* switch to secure connection */
1722                         if (sfdctls(&InChannel, &OutChannel, srv_ssl) == 0)
1723                         {
1724                                 tls_active = true;
1725 # if PIPELINING
1726                                 (void) sm_io_autoflush(InChannel, OutChannel);
1727 # endif /* PIPELINING */
1728                         }
1729                         else
1730                         {
1731                                 /*
1732                                 **  XXX this is an internal error
1733                                 **  how to deal with it?
1734                                 **  we can't generate an error message
1735                                 **  since the other side switched to an
1736                                 **  encrypted layer, but we could not...
1737                                 **  just "hang up"?
1738                                 */
1739
1740                                 nullserver = "454 4.3.3 TLS not available: can't switch to encrypted layer";
1741                                 syserr("STARTTLS: can't switch to encrypted layer");
1742                         }
1743 # if _FFR_SMTP_SSL
1744                   tls_done:
1745                         if (smtps)
1746                         {
1747                                 if (tls_active)
1748                                         goto greeting;
1749                                 else
1750                                         goto doquit;
1751                         }
1752 # endif /* _FFR_SMTP_SSL */
1753                         break;
1754 #endif /* STARTTLS */
1755
1756                   case CMDHELO:         /* hello -- introduce yourself */
1757                   case CMDEHLO:         /* extended hello */
1758                         DELAY_CONN("EHLO");
1759                         if (c->cmd_code == CMDEHLO)
1760                         {
1761                                 protocol = "ESMTP";
1762                                 SmtpPhase = "server EHLO";
1763                         }
1764                         else
1765                         {
1766                                 protocol = "SMTP";
1767                                 SmtpPhase = "server HELO";
1768                         }
1769
1770                         /* avoid denial-of-service */
1771                         (void) checksmtpattack(&n_helo, MAXHELOCOMMANDS, true,
1772                                                "HELO/EHLO", e);
1773
1774 #if 0
1775                         /* RFC2821 4.1.4 allows duplicate HELO/EHLO */
1776                         /* check for duplicate HELO/EHLO per RFC 1651 4.2 */
1777                         if (gothello)
1778                         {
1779                                 usrerr("503 %s Duplicate HELO/EHLO",
1780                                        MyHostName);
1781                                 break;
1782                         }
1783 #endif /* 0 */
1784
1785                         /* check for valid domain name (re 1123 5.2.5) */
1786                         if (*p == '\0' && !AllowBogusHELO)
1787                         {
1788                                 usrerr("501 %s requires domain address",
1789                                         cmdbuf);
1790                                 break;
1791                         }
1792
1793                         /* check for long domain name (hides Received: info) */
1794                         if (strlen(p) > MAXNAME)
1795                         {
1796                                 usrerr("501 Invalid domain name");
1797                                 if (LogLevel > 9)
1798                                         sm_syslog(LOG_INFO, CurEnv->e_id,
1799                                                   "invalid domain name (too long) from %s",
1800                                                   CurSmtpClient);
1801                                 break;
1802                         }
1803
1804                         ok = true;
1805                         for (q = p; *q != '\0'; q++)
1806                         {
1807                                 if (!isascii(*q))
1808                                         break;
1809                                 if (isalnum(*q))
1810                                         continue;
1811                                 if (isspace(*q))
1812                                 {
1813                                         *q = '\0';
1814
1815                                         /* only complain if strict check */
1816                                         ok = AllowBogusHELO;
1817                                         break;
1818                                 }
1819                                 if (strchr("[].-_#", *q) == NULL)
1820                                         break;
1821                         }
1822
1823                         if (*q == '\0' && ok)
1824                         {
1825                                 q = "pleased to meet you";
1826                                 sendinghost = sm_strdup_x(p);
1827                         }
1828                         else if (!AllowBogusHELO)
1829                         {
1830                                 usrerr("501 Invalid domain name");
1831                                 if (LogLevel > 9)
1832                                         sm_syslog(LOG_INFO, CurEnv->e_id,
1833                                                   "invalid domain name (%s) from %.100s",
1834                                                   p, CurSmtpClient);
1835                                 break;
1836                         }
1837                         else
1838                         {
1839                                 q = "accepting invalid domain name";
1840                         }
1841
1842                         if (gothello)
1843                         {
1844                                 CLEAR_STATE(cmdbuf);
1845
1846 #if _FFR_QUARANTINE
1847                                 /* restore connection quarantining */
1848                                 if (smtp.sm_quarmsg == NULL)
1849                                 {
1850                                         e->e_quarmsg = NULL;
1851                                         macdefine(&e->e_macro, A_PERM,
1852                                                   macid("{quarantine}"), "");
1853                                 }
1854                                 else
1855                                 {
1856                                         e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
1857                                                                          smtp.sm_quarmsg);
1858                                         macdefine(&e->e_macro, A_PERM,
1859                                                   macid("{quarantine}"),
1860                                                   e->e_quarmsg);
1861                                 }
1862 #endif /* _FFR_QUARANTINE */
1863                         }
1864
1865 #if MILTER
1866                         if (smtp.sm_milterlist && smtp.sm_milterize &&
1867                             !bitset(EF_DISCARD, e->e_flags))
1868                         {
1869                                 char state;
1870                                 char *response;
1871
1872                                 response = milter_helo(p, e, &state);
1873                                 switch (state)
1874                                 {
1875                                   case SMFIR_REPLYCODE:
1876                                         if (MilterLogLevel > 3)
1877                                                 sm_syslog(LOG_INFO, e->e_id,
1878                                                           "Milter: helo=%s, reject=%s",
1879                                                           p, response);
1880                                         nullserver = newstr(response);
1881                                         smtp.sm_milterize = false;
1882                                         break;
1883
1884                                   case SMFIR_REJECT:
1885                                         if (MilterLogLevel > 3)
1886                                                 sm_syslog(LOG_INFO, e->e_id,
1887                                                           "Milter: helo=%s, reject=Command rejected",
1888                                                           p);
1889                                         nullserver = "Command rejected";
1890                                         smtp.sm_milterize = false;
1891                                         break;
1892
1893                                   case SMFIR_TEMPFAIL:
1894                                         if (MilterLogLevel > 3)
1895                                                 sm_syslog(LOG_INFO, e->e_id,
1896                                                           "Milter: helo=%s, reject=%s",
1897                                                           p, MSG_TEMPFAIL);
1898                                         tempfail = true;
1899                                         smtp.sm_milterize = false;
1900                                         break;
1901                                 }
1902                                 if (response != NULL)
1903                                         sm_free(response);
1904
1905 # if _FFR_QUARANTINE
1906                                 /*
1907                                 **  If quarantining by a connect/ehlo action,
1908                                 **  save between messages
1909                                 */
1910
1911                                 if (smtp.sm_quarmsg == NULL &&
1912                                     e->e_quarmsg != NULL)
1913                                         smtp.sm_quarmsg = newstr(e->e_quarmsg);
1914 # endif /* _FFR_QUARANTINE */
1915                         }
1916 #endif /* MILTER */
1917                         gothello = true;
1918
1919                         /* print HELO response message */
1920                         if (c->cmd_code != CMDEHLO)
1921                         {
1922                                 message("250 %s Hello %s, %s",
1923                                         MyHostName, CurSmtpClient, q);
1924                                 break;
1925                         }
1926
1927                         message("250-%s Hello %s, %s",
1928                                 MyHostName, CurSmtpClient, q);
1929
1930                         /* offer ENHSC even for nullserver */
1931                         if (nullserver != NULL)
1932                         {
1933                                 message("250 ENHANCEDSTATUSCODES");
1934                                 break;
1935                         }
1936
1937                         /*
1938                         **  print EHLO features list
1939                         **
1940                         **  Note: If you change this list,
1941                         **        remember to update 'helpfile'
1942                         */
1943
1944                         message("250-ENHANCEDSTATUSCODES");
1945 #if PIPELINING
1946                         if (bitset(SRV_OFFER_PIPE, features))
1947                                 message("250-PIPELINING");
1948 #endif /* PIPELINING */
1949                         if (bitset(SRV_OFFER_EXPN, features))
1950                         {
1951                                 message("250-EXPN");
1952                                 if (bitset(SRV_OFFER_VERB, features))
1953                                         message("250-VERB");
1954                         }
1955 #if MIME8TO7
1956                         message("250-8BITMIME");
1957 #endif /* MIME8TO7 */
1958                         if (MaxMessageSize > 0)
1959                                 message("250-SIZE %ld", MaxMessageSize);
1960                         else
1961                                 message("250-SIZE");
1962 #if DSN
1963                         if (SendMIMEErrors && bitset(SRV_OFFER_DSN, features))
1964                                 message("250-DSN");
1965 #endif /* DSN */
1966                         if (bitset(SRV_OFFER_ETRN, features))
1967                                 message("250-ETRN");
1968 #if SASL
1969                         if (sasl_ok && mechlist != NULL && *mechlist != '\0')
1970                                 message("250-AUTH %s", mechlist);
1971 #endif /* SASL */
1972 #if STARTTLS
1973                         if (tls_ok_srv &&
1974                             bitset(SRV_OFFER_TLS, features))
1975                                 message("250-STARTTLS");
1976 #endif /* STARTTLS */
1977                         if (DeliverByMin > 0)
1978                                 message("250-DELIVERBY %ld",
1979                                         (long) DeliverByMin);
1980                         else if (DeliverByMin == 0)
1981                                 message("250-DELIVERBY");
1982
1983                         /* < 0: no deliver-by */
1984
1985                         message("250 HELP");
1986                         break;
1987
1988                   case CMDMAIL:         /* mail -- designate sender */
1989                         SmtpPhase = "server MAIL";
1990                         DELAY_CONN("MAIL");
1991
1992                         /* check for validity of this command */
1993                         if (!gothello && bitset(PRIV_NEEDMAILHELO, PrivacyFlags))
1994                         {
1995                                 usrerr("503 5.0.0 Polite people say HELO first");
1996                                 break;
1997                         }
1998                         if (smtp.sm_gotmail)
1999                         {
2000                                 usrerr("503 5.5.0 Sender already specified");
2001                                 break;
2002                         }
2003 #if SASL
2004                         if (bitset(SRV_REQ_AUTH, features) &&
2005                             authenticating != SASL_IS_AUTH)
2006                         {
2007                                 usrerr("530 5.7.0 Authentication required");
2008                                 break;
2009                         }
2010 #endif /* SASL */
2011
2012                         p = skipword(p, "from");
2013                         if (p == NULL)
2014                                 break;
2015                         if (tempfail)
2016                         {
2017                                 if (LogLevel > 9)
2018                                         sm_syslog(LOG_INFO, e->e_id,
2019                                                   "SMTP MAIL command (%.100s) from %s tempfailed (due to previous checks)",
2020                                                   p, CurSmtpClient);
2021                                 usrerr(MSG_TEMPFAIL);
2022                                 break;
2023                         }
2024
2025                         /* make sure we know who the sending host is */
2026                         if (sendinghost == NULL)
2027                                 sendinghost = peerhostname;
2028
2029
2030 #if SM_HEAP_CHECK
2031                         if (sm_debug_active(&DebugLeakSmtp, 1))
2032                         {
2033                                 sm_heap_newgroup();
2034                                 sm_dprintf("smtp() heap group #%d\n",
2035                                         sm_heap_group());
2036                         }
2037 #endif /* SM_HEAP_CHECK */
2038
2039                         if (Errors > 0)
2040                                 goto undo_no_pm;
2041                         if (!gothello)
2042                         {
2043                                 auth_warning(e, "%s didn't use HELO protocol",
2044                                              CurSmtpClient);
2045                         }
2046 #ifdef PICKY_HELO_CHECK
2047                         if (sm_strcasecmp(sendinghost, peerhostname) != 0 &&
2048                             (sm_strcasecmp(peerhostname, "localhost") != 0 ||
2049                              sm_strcasecmp(sendinghost, MyHostName) != 0))
2050                         {
2051                                 auth_warning(e, "Host %s claimed to be %s",
2052                                              CurSmtpClient, sendinghost);
2053                         }
2054 #endif /* PICKY_HELO_CHECK */
2055
2056                         if (protocol == NULL)
2057                                 protocol = "SMTP";
2058                         macdefine(&e->e_macro, A_PERM, 'r', protocol);
2059                         macdefine(&e->e_macro, A_PERM, 's', sendinghost);
2060
2061                         if (Errors > 0)
2062                                 goto undo_no_pm;
2063                         smtp.sm_nrcpts = 0;
2064                         n_badrcpts = 0;
2065                         macdefine(&e->e_macro, A_PERM, macid("{ntries}"), "0");
2066                         macdefine(&e->e_macro, A_PERM, macid("{nrcpts}"), "0");
2067                         e->e_flags |= EF_CLRQUEUE;
2068                         sm_setproctitle(true, e, "%s %s: %.80s",
2069                                         qid_printname(e),
2070                                         CurSmtpClient, inp);
2071
2072                         /* do the processing */
2073                     SM_TRY
2074                     {
2075                         extern char *FullName;
2076
2077                         QuickAbort = true;
2078                         SM_FREE_CLR(FullName);
2079
2080                         /* must parse sender first */
2081                         delimptr = NULL;
2082                         setsender(p, e, &delimptr, ' ', false);
2083                         if (delimptr != NULL && *delimptr != '\0')
2084                                 *delimptr++ = '\0';
2085                         if (Errors > 0)
2086                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2087
2088                         /* Successfully set e_from, allow logging */
2089                         e->e_flags |= EF_LOGSENDER;
2090
2091                         /* put resulting triple from parseaddr() into macros */
2092                         if (e->e_from.q_mailer != NULL)
2093                                  macdefine(&e->e_macro, A_PERM,
2094                                         macid("{mail_mailer}"),
2095                                         e->e_from.q_mailer->m_name);
2096                         else
2097                                  macdefine(&e->e_macro, A_PERM,
2098                                         macid("{mail_mailer}"), NULL);
2099                         if (e->e_from.q_host != NULL)
2100                                 macdefine(&e->e_macro, A_PERM,
2101                                         macid("{mail_host}"),
2102                                         e->e_from.q_host);
2103                         else
2104                                 macdefine(&e->e_macro, A_PERM,
2105                                         macid("{mail_host}"), "localhost");
2106                         if (e->e_from.q_user != NULL)
2107                                 macdefine(&e->e_macro, A_PERM,
2108                                         macid("{mail_addr}"),
2109                                         e->e_from.q_user);
2110                         else
2111                                 macdefine(&e->e_macro, A_PERM,
2112                                         macid("{mail_addr}"), NULL);
2113                         if (Errors > 0)
2114                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2115
2116                         /* check for possible spoofing */
2117                         if (RealUid != 0 && OpMode == MD_SMTP &&
2118                             !wordinclass(RealUserName, 't') &&
2119                             (!bitnset(M_LOCALMAILER,
2120                                       e->e_from.q_mailer->m_flags) ||
2121                              strcmp(e->e_from.q_user, RealUserName) != 0))
2122                         {
2123                                 auth_warning(e, "%s owned process doing -bs",
2124                                         RealUserName);
2125                         }
2126
2127                         /* now parse ESMTP arguments */
2128                         e->e_msgsize = 0;
2129                         addr = p;
2130                         argno = 0;
2131                         args[argno++] = p;
2132                         p = delimptr;
2133                         while (p != NULL && *p != '\0')
2134                         {
2135                                 char *kp;
2136                                 char *vp = NULL;
2137                                 char *equal = NULL;
2138
2139                                 /* locate the beginning of the keyword */
2140                                 SKIP_SPACE(p);
2141                                 if (*p == '\0')
2142                                         break;
2143                                 kp = p;
2144
2145                                 /* skip to the value portion */
2146                                 while ((isascii(*p) && isalnum(*p)) || *p == '-')
2147                                         p++;
2148                                 if (*p == '=')
2149                                 {
2150                                         equal = p;
2151                                         *p++ = '\0';
2152                                         vp = p;
2153
2154                                         /* skip to the end of the value */
2155                                         while (*p != '\0' && *p != ' ' &&
2156                                                !(isascii(*p) && iscntrl(*p)) &&
2157                                                *p != '=')
2158                                                 p++;
2159                                 }
2160
2161                                 if (*p != '\0')
2162                                         *p++ = '\0';
2163
2164                                 if (tTd(19, 1))
2165                                         sm_dprintf("MAIL: got arg %s=\"%s\"\n", kp,
2166                                                 vp == NULL ? "<null>" : vp);
2167
2168                                 mail_esmtp_args(kp, vp, e);
2169                                 if (equal != NULL)
2170                                         *equal = '=';
2171                                 args[argno++] = kp;
2172                                 if (argno >= MAXSMTPARGS - 1)
2173                                         usrerr("501 5.5.4 Too many parameters");
2174                                 if (Errors > 0)
2175                                         sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2176                         }
2177                         args[argno] = NULL;
2178                         if (Errors > 0)
2179                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2180
2181 #if SASL
2182 # if _FFR_AUTH_PASSING
2183                         /* set the default AUTH= if the sender didn't */
2184                         if (e->e_auth_param == NULL)
2185                         {
2186                                 /* XXX only do this for an MSA? */
2187                                 e->e_auth_param = macvalue(macid("{auth_authen}"),
2188                                                            e);
2189                                 if (e->e_auth_param == NULL)
2190                                         e->e_auth_param = "<>";
2191
2192                                 /*
2193                                 **  XXX should we invoke Strust_auth now?
2194                                 **  authorizing as the client that just
2195                                 **  authenticated, so we'll trust implicitly
2196                                 */
2197                         }
2198 # endif /* _FFR_AUTH_PASSING */
2199 #endif /* SASL */
2200
2201                         /* do config file checking of the sender */
2202                         macdefine(&e->e_macro, A_PERM,
2203                                 macid("{addr_type}"), "e s");
2204 #if _FFR_MAIL_MACRO
2205                         /* make the "real" sender address available */
2206                         macdefine(&e->e_macro, A_TEMP, macid("{mail_from}"),
2207                                   e->e_from.q_paddr);
2208 #endif /* _FFR_MAIL_MACRO */
2209                         if (rscheck("check_mail", addr,
2210                                     NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
2211                                     NULL, e->e_id) != EX_OK ||
2212                             Errors > 0)
2213                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2214                         macdefine(&e->e_macro, A_PERM,
2215                                   macid("{addr_type}"), NULL);
2216
2217                         if (MaxMessageSize > 0 &&
2218                             (e->e_msgsize > MaxMessageSize ||
2219                              e->e_msgsize < 0))
2220                         {
2221                                 usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
2222                                         MaxMessageSize);
2223                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2224                         }
2225
2226                         /*
2227                         **  XXX always check whether there is at least one fs
2228                         **  with enough space?
2229                         **  However, this may not help much: the queue group
2230                         **  selection may later on select a FS that hasn't
2231                         **  enough space.
2232                         */
2233
2234                         if ((NumFileSys == 1 || NumQueue == 1) &&
2235                             !enoughdiskspace(e->e_msgsize, e)
2236 #if _FFR_ANY_FREE_FS
2237                             && !filesys_free(e->e_msgsize)
2238 #endif /* _FFR_ANY_FREE_FS */
2239                            )
2240                         {
2241                                 /*
2242                                 **  We perform this test again when the
2243                                 **  queue directory is selected, in collect.
2244                                 */
2245
2246                                 usrerr("452 4.4.5 Insufficient disk space; try again later");
2247                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2248                         }
2249                         if (Errors > 0)
2250                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2251
2252                         LogUsrErrs = true;
2253 #if MILTER
2254                         if (smtp.sm_milterlist && smtp.sm_milterize &&
2255                             !bitset(EF_DISCARD, e->e_flags))
2256                         {
2257                                 char state;
2258                                 char *response;
2259
2260                                 response = milter_envfrom(args, e, &state);
2261                                 MILTER_REPLY("from");
2262                         }
2263 #endif /* MILTER */
2264                         if (Errors > 0)
2265                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2266
2267                         message("250 2.1.0 Sender ok");
2268                         smtp.sm_gotmail = true;
2269                     }
2270                     SM_EXCEPT(exc, "[!F]*")
2271                     {
2272                         /*
2273                         **  An error occurred while processing a MAIL command.
2274                         **  Jump to the common error handling code.
2275                         */
2276
2277                         sm_exc_free(exc);
2278                         goto undo_no_pm;
2279                     }
2280                     SM_END_TRY
2281                         break;
2282
2283                   undo_no_pm:
2284                         e->e_flags &= ~EF_PM_NOTIFY;
2285                   undo:
2286                         break;
2287
2288                   case CMDRCPT:         /* rcpt -- designate recipient */
2289                         DELAY_CONN("RCPT");
2290                         if (!smtp.sm_gotmail)
2291                         {
2292                                 usrerr("503 5.0.0 Need MAIL before RCPT");
2293                                 break;
2294                         }
2295                         SmtpPhase = "server RCPT";
2296                     SM_TRY
2297                     {
2298                         QuickAbort = true;
2299                         LogUsrErrs = true;
2300
2301                         /* limit flooding of our machine */
2302                         if (MaxRcptPerMsg > 0 &&
2303                             smtp.sm_nrcpts >= MaxRcptPerMsg)
2304                         {
2305                                 /* sleep(1); / * slow down? */
2306                                 usrerr("452 4.5.3 Too many recipients");
2307                                 goto rcpt_done;
2308                         }
2309
2310                         if (e->e_sendmode != SM_DELIVER)
2311                                 e->e_flags |= EF_VRFYONLY;
2312
2313 #if MILTER
2314                         /*
2315                         **  If the filter will be deleting recipients,
2316                         **  don't expand them at RCPT time (in the call
2317                         **  to recipient()).  If they are expanded, it
2318                         **  is impossible for removefromlist() to figure
2319                         **  out the expanded members of the original
2320                         **  recipient and mark them as QS_DONTSEND.
2321                         */
2322
2323                         if (milter_can_delrcpts())
2324                                 e->e_flags |= EF_VRFYONLY;
2325 #endif /* MILTER */
2326
2327                         p = skipword(p, "to");
2328                         if (p == NULL)
2329                                 goto rcpt_done;
2330                         macdefine(&e->e_macro, A_PERM,
2331                                 macid("{addr_type}"), "e r");
2332                         a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr,
2333                                       e, true);
2334                         macdefine(&e->e_macro, A_PERM,
2335                                 macid("{addr_type}"), NULL);
2336                         if (BadRcptThrottle > 0 &&
2337                             n_badrcpts >= BadRcptThrottle)
2338                         {
2339                                 if (LogLevel > 5 &&
2340                                     n_badrcpts == BadRcptThrottle)
2341                                 {
2342                                         sm_syslog(LOG_INFO, e->e_id,
2343                                                   "%s: Possible SMTP RCPT flood, throttling.",
2344                                                   CurSmtpClient);
2345
2346                                         /* To avoid duplicated message */
2347                                         n_badrcpts++;
2348                                 }
2349
2350                                 /*
2351                                 **  Don't use exponential backoff for now.
2352                                 **  Some servers will open more connections
2353                                 **  and actually overload the receiver even
2354                                 **  more.
2355                                 */
2356
2357                                 (void) sleep(1);
2358                         }
2359                         if (Errors > 0)
2360                                 goto rcpt_done;
2361                         if (a == NULL)
2362                         {
2363                                 usrerr("501 5.0.0 Missing recipient");
2364                                 goto rcpt_done;
2365                         }
2366
2367                         if (delimptr != NULL && *delimptr != '\0')
2368                                 *delimptr++ = '\0';
2369
2370                         /* put resulting triple from parseaddr() into macros */
2371                         if (a->q_mailer != NULL)
2372                                 macdefine(&e->e_macro, A_PERM,
2373                                         macid("{rcpt_mailer}"),
2374                                         a->q_mailer->m_name);
2375                         else
2376                                 macdefine(&e->e_macro, A_PERM,
2377                                         macid("{rcpt_mailer}"), NULL);
2378                         if (a->q_host != NULL)
2379                                 macdefine(&e->e_macro, A_PERM,
2380                                         macid("{rcpt_host}"), a->q_host);
2381                         else
2382                                 macdefine(&e->e_macro, A_PERM,
2383                                         macid("{rcpt_host}"), "localhost");
2384                         if (a->q_user != NULL)
2385                                 macdefine(&e->e_macro, A_PERM,
2386                                         macid("{rcpt_addr}"), a->q_user);
2387                         else
2388                                 macdefine(&e->e_macro, A_PERM,
2389                                         macid("{rcpt_addr}"), NULL);
2390                         if (Errors > 0)
2391                                 goto rcpt_done;
2392
2393                         /* now parse ESMTP arguments */
2394                         addr = p;
2395                         argno = 0;
2396                         args[argno++] = p;
2397                         p = delimptr;
2398                         while (p != NULL && *p != '\0')
2399                         {
2400                                 char *kp;
2401                                 char *vp = NULL;
2402                                 char *equal = NULL;
2403
2404                                 /* locate the beginning of the keyword */
2405                                 SKIP_SPACE(p);
2406                                 if (*p == '\0')
2407                                         break;
2408                                 kp = p;
2409
2410                                 /* skip to the value portion */
2411                                 while ((isascii(*p) && isalnum(*p)) || *p == '-')
2412                                         p++;
2413                                 if (*p == '=')
2414                                 {
2415                                         equal = p;
2416                                         *p++ = '\0';
2417                                         vp = p;
2418
2419                                         /* skip to the end of the value */
2420                                         while (*p != '\0' && *p != ' ' &&
2421                                                !(isascii(*p) && iscntrl(*p)) &&
2422                                                *p != '=')
2423                                                 p++;
2424                                 }
2425
2426                                 if (*p != '\0')
2427                                         *p++ = '\0';
2428
2429                                 if (tTd(19, 1))
2430                                         sm_dprintf("RCPT: got arg %s=\"%s\"\n", kp,
2431                                                 vp == NULL ? "<null>" : vp);
2432
2433                                 rcpt_esmtp_args(a, kp, vp, e);
2434                                 if (equal != NULL)
2435                                         *equal = '=';
2436                                 args[argno++] = kp;
2437                                 if (argno >= MAXSMTPARGS - 1)
2438                                         usrerr("501 5.5.4 Too many parameters");
2439                                 if (Errors > 0)
2440                                         break;
2441                         }
2442                         args[argno] = NULL;
2443                         if (Errors > 0)
2444                                 goto rcpt_done;
2445
2446                         /* do config file checking of the recipient */
2447                         macdefine(&e->e_macro, A_PERM,
2448                                 macid("{addr_type}"), "e r");
2449                         if (rscheck("check_rcpt", addr,
2450                                     NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
2451                                     NULL, e->e_id) != EX_OK ||
2452                             Errors > 0)
2453                                 goto rcpt_done;
2454                         macdefine(&e->e_macro, A_PERM,
2455                                 macid("{addr_type}"), NULL);
2456
2457                         /* If discarding, don't bother to verify user */
2458                         if (bitset(EF_DISCARD, e->e_flags))
2459                                 a->q_state = QS_VERIFIED;
2460
2461 #if MILTER
2462                         if (smtp.sm_milterlist && smtp.sm_milterize &&
2463                             !bitset(EF_DISCARD, e->e_flags))
2464                         {
2465                                 char state;
2466                                 char *response;
2467
2468                                 response = milter_envrcpt(args, e, &state);
2469                                 MILTER_REPLY("to");
2470                         }
2471 #endif /* MILTER */
2472
2473                         macdefine(&e->e_macro, A_PERM,
2474                                 macid("{rcpt_mailer}"), NULL);
2475                         macdefine(&e->e_macro, A_PERM,
2476                                 macid("{rcpt_host}"), NULL);
2477                         macdefine(&e->e_macro, A_PERM,
2478                                 macid("{rcpt_addr}"), NULL);
2479                         macdefine(&e->e_macro, A_PERM,
2480                                 macid("{dsn_notify}"), NULL);
2481                         if (Errors > 0)
2482                                 goto rcpt_done;
2483
2484                         /* save in recipient list after ESMTP mods */
2485                         a = recipient(a, &e->e_sendqueue, 0, e);
2486                         if (Errors > 0)
2487                                 goto rcpt_done;
2488
2489                         /* no errors during parsing, but might be a duplicate */
2490                         e->e_to = a->q_paddr;
2491                         if (!QS_IS_BADADDR(a->q_state))
2492                         {
2493                                 if (smtp.sm_nrcpts == 0)
2494                                         initsys(e);
2495                                 message("250 2.1.5 Recipient ok%s",
2496                                         QS_IS_QUEUEUP(a->q_state) ?
2497                                                 " (will queue)" : "");
2498                                 smtp.sm_nrcpts++;
2499                         }
2500                         else
2501                         {
2502                                 /* punt -- should keep message in ADDRESS.... */
2503                                 usrerr("550 5.1.1 Addressee unknown");
2504                         }
2505                     rcpt_done:
2506                         if (Errors > 0)
2507                                 ++n_badrcpts;
2508                     }
2509                     SM_EXCEPT(exc, "[!F]*")
2510                     {
2511                         /* An exception occurred while processing RCPT */
2512                         e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY);
2513                         ++n_badrcpts;
2514                     }
2515                     SM_END_TRY
2516                         break;
2517
2518                   case CMDDATA:         /* data -- text of mail */
2519                         DELAY_CONN("DATA");
2520                         smtp_data(&smtp, e);
2521                         break;
2522
2523                   case CMDRSET:         /* rset -- reset state */
2524                         if (tTd(94, 100))
2525                                 message("451 4.0.0 Test failure");
2526                         else
2527                                 message("250 2.0.0 Reset state");
2528                         CLEAR_STATE(cmdbuf);
2529 #if _FFR_QUARANTINE
2530                         /* restore connection quarantining */
2531                         if (smtp.sm_quarmsg == NULL)
2532                         {
2533                                 e->e_quarmsg = NULL;
2534                                 macdefine(&e->e_macro, A_PERM,
2535                                           macid("{quarantine}"), "");
2536                         }
2537                         else
2538                         {
2539                                 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
2540                                                                  smtp.sm_quarmsg);
2541                                 macdefine(&e->e_macro, A_PERM,
2542                                           macid("{quarantine}"), e->e_quarmsg);
2543                         }
2544 #endif /* _FFR_QUARANTINE */
2545                         break;
2546
2547                   case CMDVRFY:         /* vrfy -- verify address */
2548                   case CMDEXPN:         /* expn -- expand address */
2549                         vrfy = c->cmd_code == CMDVRFY;
2550                         DELAY_CONN(vrfy ? "VRFY" : "EXPN");
2551                         if (tempfail)
2552                         {
2553                                 if (LogLevel > 9)
2554                                         sm_syslog(LOG_INFO, e->e_id,
2555                                                   "SMTP %s command (%.100s) from %s tempfailed (due to previous checks)",
2556                                                   vrfy ? "VRFY" : "EXPN",
2557                                                   p, CurSmtpClient);
2558
2559                                 /* RFC 821 doesn't allow 4xy reply code */
2560                                 usrerr("550 5.7.1 Please try again later");
2561                                 break;
2562                         }
2563                         wt = checksmtpattack(&n_verifies, MAXVRFYCOMMANDS,
2564                                              false, vrfy ? "VRFY" : "EXPN", e);
2565                         previous = curtime();
2566                         if ((vrfy && bitset(PRIV_NOVRFY, PrivacyFlags)) ||
2567                             (!vrfy && !bitset(SRV_OFFER_EXPN, features)))
2568                         {
2569                                 if (vrfy)
2570                                         message("252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
2571                                 else
2572                                         message("502 5.7.0 Sorry, we do not allow this operation");
2573                                 if (LogLevel > 5)
2574                                         sm_syslog(LOG_INFO, e->e_id,
2575                                                   "%s: %s [rejected]",
2576                                                   CurSmtpClient,
2577                                                   shortenstring(inp, MAXSHORTSTR));
2578                                 break;
2579                         }
2580                         else if (!gothello &&
2581                                  bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO,
2582                                                 PrivacyFlags))
2583                         {
2584                                 usrerr("503 5.0.0 I demand that you introduce yourself first");
2585                                 break;
2586                         }
2587                         if (Errors > 0)
2588                                 break;
2589                         if (LogLevel > 5)
2590                                 sm_syslog(LOG_INFO, e->e_id, "%s: %s",
2591                                           CurSmtpClient,
2592                                           shortenstring(inp, MAXSHORTSTR));
2593                     SM_TRY
2594                     {
2595                         QuickAbort = true;
2596                         vrfyqueue = NULL;
2597                         if (vrfy)
2598                                 e->e_flags |= EF_VRFYONLY;
2599                         while (*p != '\0' && isascii(*p) && isspace(*p))
2600                                 p++;
2601                         if (*p == '\0')
2602                         {
2603                                 usrerr("501 5.5.2 Argument required");
2604                         }
2605                         else
2606                         {
2607                                 /* do config file checking of the address */
2608                                 if (rscheck(vrfy ? "check_vrfy" : "check_expn",
2609                                             p, NULL, e, RSF_RMCOMM,
2610                                             3, NULL, NOQID) != EX_OK ||
2611                                     Errors > 0)
2612                                         sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2613                                 (void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
2614                         }
2615                         if (wt > 0)
2616                         {
2617                                 time_t t;
2618
2619                                 t = wt - (curtime() - previous);
2620                                 if (t > 0)
2621                                         (void) sleep(t);
2622                         }
2623                         if (Errors > 0)
2624                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2625                         if (vrfyqueue == NULL)
2626                         {
2627                                 usrerr("554 5.5.2 Nothing to %s", vrfy ? "VRFY" : "EXPN");
2628                         }
2629                         while (vrfyqueue != NULL)
2630                         {
2631                                 if (!QS_IS_UNDELIVERED(vrfyqueue->q_state))
2632                                 {
2633                                         vrfyqueue = vrfyqueue->q_next;
2634                                         continue;
2635                                 }
2636
2637                                 /* see if there is more in the vrfy list */
2638                                 a = vrfyqueue;
2639                                 while ((a = a->q_next) != NULL &&
2640                                        (!QS_IS_UNDELIVERED(a->q_state)))
2641                                         continue;
2642                                 printvrfyaddr(vrfyqueue, a == NULL, vrfy);
2643                                 vrfyqueue = a;
2644                         }
2645                     }
2646                     SM_EXCEPT(exc, "[!F]*")
2647                     {
2648                         /*
2649                         **  An exception occurred while processing VRFY/EXPN
2650                         */
2651
2652                         sm_exc_free(exc);
2653                         goto undo;
2654                     }
2655                     SM_END_TRY
2656                         break;
2657
2658                   case CMDETRN:         /* etrn -- force queue flush */
2659                         DELAY_CONN("ETRN");
2660
2661                         /* Don't leak queue information via debug flags */
2662                         if (!bitset(SRV_OFFER_ETRN, features) || UseMSP ||
2663                             (RealUid != 0 && RealUid != TrustedUid &&
2664                              OpMode == MD_SMTP))
2665                         {
2666                                 /* different message for MSA ? */
2667                                 message("502 5.7.0 Sorry, we do not allow this operation");
2668                                 if (LogLevel > 5)
2669                                         sm_syslog(LOG_INFO, e->e_id,
2670                                                   "%s: %s [rejected]",
2671                                                   CurSmtpClient,
2672                                                   shortenstring(inp, MAXSHORTSTR));
2673                                 break;
2674                         }
2675                         if (tempfail)
2676                         {
2677                                 if (LogLevel > 9)
2678                                         sm_syslog(LOG_INFO, e->e_id,
2679                                                   "SMTP ETRN command (%.100s) from %s tempfailed (due to previous checks)",
2680                                                   p, CurSmtpClient);
2681                                 usrerr(MSG_TEMPFAIL);
2682                                 break;
2683                         }
2684
2685                         if (strlen(p) <= 0)
2686                         {
2687                                 usrerr("500 5.5.2 Parameter required");
2688                                 break;
2689                         }
2690
2691                         /* crude way to avoid denial-of-service attacks */
2692                         (void) checksmtpattack(&n_etrn, MAXETRNCOMMANDS, true,
2693                                              "ETRN", e);
2694
2695                         /*
2696                         **  Do config file checking of the parameter.
2697                         **  Even though we have srv_features now, we still
2698                         **  need this ruleset because the former is called
2699                         **  when the connection has been established, while
2700                         **  this ruleset is called when the command is
2701                         **  actually issued and therefore has all information
2702                         **  available to make a decision.
2703                         */
2704
2705                         if (rscheck("check_etrn", p, NULL, e,
2706                                     RSF_RMCOMM, 3, NULL, NOQID) != EX_OK ||
2707                             Errors > 0)
2708                                 break;
2709
2710                         if (LogLevel > 5)
2711                                 sm_syslog(LOG_INFO, e->e_id,
2712                                           "%s: ETRN %s", CurSmtpClient,
2713                                           shortenstring(p, MAXSHORTSTR));
2714
2715                         id = p;
2716                         if (*id == '#')
2717                         {
2718                                 int i, qgrp;
2719
2720                                 id++;
2721                                 qgrp = name2qid(id);
2722                                 if (!ISVALIDQGRP(qgrp))
2723                                 {
2724                                         usrerr("459 4.5.4 Queue %s unknown",
2725                                                id);
2726                                         break;
2727                                 }
2728                                 for (i = 0; i < NumQueue && Queue[i] != NULL;
2729                                      i++)
2730                                         Queue[i]->qg_nextrun = (time_t) -1;
2731                                 Queue[qgrp]->qg_nextrun = 0;
2732                                 ok = run_work_group(Queue[qgrp]->qg_wgrp,
2733                                                     RWG_FORK|RWG_FORCE);
2734                                 if (ok && Errors == 0)
2735                                         message("250 2.0.0 Queuing for queue group %s started", id);
2736                                 break;
2737                         }
2738
2739                         if (*id == '@')
2740                                 id++;
2741                         else
2742                                 *--id = '@';
2743
2744                         new = (QUEUE_CHAR *) sm_malloc(sizeof(QUEUE_CHAR));
2745                         if (new == NULL)
2746                         {
2747                                 syserr("500 5.5.0 ETRN out of memory");
2748                                 break;
2749                         }
2750                         new->queue_match = id;
2751                         new->queue_negate = false;
2752                         new->queue_next = NULL;
2753                         QueueLimitRecipient = new;
2754                         ok = runqueue(true, false, false, true);
2755                         sm_free(QueueLimitRecipient); /* XXX */
2756                         QueueLimitRecipient = NULL;
2757                         if (ok && Errors == 0)
2758                                 message("250 2.0.0 Queuing for node %s started", p);
2759                         break;
2760
2761                   case CMDHELP:         /* help -- give user info */
2762                         DELAY_CONN("HELP");
2763                         help(p, e);
2764                         break;
2765
2766                   case CMDNOOP:         /* noop -- do nothing */
2767                         DELAY_CONN("NOOP");
2768                         (void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true,
2769                                                "NOOP", e);
2770                         message("250 2.0.0 OK");
2771                         break;
2772
2773                   case CMDQUIT:         /* quit -- leave mail */
2774                         message("221 2.0.0 %s closing connection", MyHostName);
2775 #if PIPELINING
2776                         (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
2777 #endif /* PIPELINING */
2778
2779                         if (smtp.sm_nrcpts > 0)
2780                                 logundelrcpts(e, "aborted by sender", 9, false);
2781
2782                         /* arrange to ignore any current send list */
2783                         e->e_sendqueue = NULL;
2784
2785 #if STARTTLS
2786                         /* shutdown TLS connection */
2787                         if (tls_active)
2788                         {
2789                                 (void) endtls(srv_ssl, "server");
2790                                 tls_active = false;
2791                         }
2792 #endif /* STARTTLS */
2793 #if SASL
2794                         if (authenticating == SASL_IS_AUTH)
2795                         {
2796                                 sasl_dispose(&conn);
2797                                 authenticating = SASL_NOT_AUTH;
2798                                 /* XXX sasl_done(); this is a child */
2799                         }
2800 #endif /* SASL */
2801
2802 doquit:
2803                         /* avoid future 050 messages */
2804                         disconnect(1, e);
2805
2806 #if MILTER
2807                         /* close out milter filters */
2808                         milter_quit(e);
2809 #endif /* MILTER */
2810
2811                         if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
2812                                 logsender(e, NULL);
2813                         e->e_flags &= ~EF_LOGSENDER;
2814
2815                         if (lognullconnection && LogLevel > 5 &&
2816                             nullserver == NULL)
2817                         {
2818                                 char *d;
2819
2820                                 d = macvalue(macid("{daemon_name}"), e);
2821                                 if (d == NULL)
2822                                         d = "stdin";
2823
2824                                 /*
2825                                 **  even though this id is "bogus", it makes
2826                                 **  it simpler to "grep" related events, e.g.,
2827                                 **  timeouts for the same connection.
2828                                 */
2829
2830                                 sm_syslog(LOG_INFO, e->e_id,
2831                                           "%s did not issue MAIL/EXPN/VRFY/ETRN during connection to %s",
2832                                           CurSmtpClient, d);
2833                         }
2834                         if (tTd(93, 100))
2835                         {
2836                                 /* return to handle next connection */
2837                                 return;
2838                         }
2839                         finis(true, true, ExitStat);
2840                         /* NOTREACHED */
2841
2842                   case CMDVERB:         /* set verbose mode */
2843                         DELAY_CONN("VERB");
2844                         if (!bitset(SRV_OFFER_EXPN, features) ||
2845                             !bitset(SRV_OFFER_VERB, features))
2846                         {
2847                                 /* this would give out the same info */
2848                                 message("502 5.7.0 Verbose unavailable");
2849                                 break;
2850                         }
2851                         (void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true,
2852                                                "VERB", e);
2853                         Verbose = 1;
2854                         set_delivery_mode(SM_DELIVER, e);
2855                         message("250 2.0.0 Verbose mode");
2856                         break;
2857
2858 #if SMTPDEBUG
2859                   case CMDDBGQSHOW:     /* show queues */
2860                         (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
2861                                              "Send Queue=");
2862                         printaddr(e->e_sendqueue, true);
2863                         break;
2864
2865                   case CMDDBGDEBUG:     /* set debug mode */
2866                         tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
2867                         tTflag(p);
2868                         message("200 2.0.0 Debug set");
2869                         break;
2870
2871 #else /* SMTPDEBUG */
2872                   case CMDDBGQSHOW:     /* show queues */
2873                   case CMDDBGDEBUG:     /* set debug mode */
2874 #endif /* SMTPDEBUG */
2875                   case CMDLOGBOGUS:     /* bogus command */
2876                         DELAY_CONN("Bogus");
2877                         if (LogLevel > 0)
2878                                 sm_syslog(LOG_CRIT, e->e_id,
2879                                           "\"%s\" command from %s (%.100s)",
2880                                           c->cmd_name, CurSmtpClient,
2881                                           anynet_ntoa(&RealHostAddr));
2882                         /* FALLTHROUGH */
2883
2884                   case CMDERROR:        /* unknown command */
2885 #if MAXBADCOMMANDS > 0
2886                         if (++n_badcmds > MAXBADCOMMANDS)
2887                         {
2888                                 message("421 4.7.0 %s Too many bad commands; closing connection",
2889                                         MyHostName);
2890
2891                                 /* arrange to ignore any current send list */
2892                                 e->e_sendqueue = NULL;
2893                                 goto doquit;
2894                         }
2895 #endif /* MAXBADCOMMANDS > 0 */
2896
2897                         usrerr("500 5.5.1 Command unrecognized: \"%s\"",
2898                                shortenstring(inp, MAXSHORTSTR));
2899                         break;
2900
2901                   case CMDUNIMPL:
2902                         DELAY_CONN("Unimpl");
2903                         usrerr("502 5.5.1 Command not implemented: \"%s\"",
2904                                shortenstring(inp, MAXSHORTSTR));
2905                         break;
2906
2907                   default:
2908                         DELAY_CONN("default");
2909                         errno = 0;
2910                         syserr("500 5.5.0 smtp: unknown code %d", c->cmd_code);
2911                         break;
2912                 }
2913 #if SASL
2914                 }
2915 #endif /* SASL */
2916             }
2917             SM_EXCEPT(exc, "[!F]*")
2918             {
2919                 /*
2920                 **  The only possible exception is "E:mta.quickabort".
2921                 **  There is nothing to do except fall through and loop.
2922                 */
2923             }
2924             SM_END_TRY
2925         }
2926 }
2927 /*
2928 **  SMTP_DATA -- implement the SMTP DATA command.
2929 **
2930 **      Parameters:
2931 **              smtp -- status of SMTP connection.
2932 **              e -- envelope.
2933 **
2934 **      Returns:
2935 **              none.
2936 **
2937 **      Side Effects:
2938 **              possibly sends message.
2939 */
2940
2941 static void
2942 smtp_data(smtp, e)
2943         SMTP_T *smtp;
2944         ENVELOPE *e;
2945 {
2946 #if MILTER
2947         bool milteraccept;
2948 #endif /* MILTER */
2949         bool aborting;
2950         bool doublequeue;
2951         ADDRESS *a;
2952         ENVELOPE *ee;
2953         char *id;
2954         char *oldid;
2955         char buf[32];
2956
2957         SmtpPhase = "server DATA";
2958         if (!smtp->sm_gotmail)
2959         {
2960                 usrerr("503 5.0.0 Need MAIL command");
2961                 return;
2962         }
2963         else if (smtp->sm_nrcpts <= 0)
2964         {
2965                 usrerr("503 5.0.0 Need RCPT (recipient)");
2966                 return;
2967         }
2968         (void) sm_snprintf(buf, sizeof buf, "%u", smtp->sm_nrcpts);
2969         if (rscheck("check_data", buf, NULL, e,
2970                     RSF_RMCOMM|RSF_UNSTRUCTURED|RSF_COUNT, 3, NULL,
2971                     e->e_id) != EX_OK)
2972                 return;
2973
2974         /* put back discard bit */
2975         if (smtp->sm_discard)
2976                 e->e_flags |= EF_DISCARD;
2977
2978         /* check to see if we need to re-expand aliases */
2979         /* also reset QS_BADADDR on already-diagnosted addrs */
2980         doublequeue = false;
2981         for (a = e->e_sendqueue; a != NULL; a = a->q_next)
2982         {
2983                 if (QS_IS_VERIFIED(a->q_state) &&
2984                     !bitset(EF_DISCARD, e->e_flags))
2985                 {
2986                         /* need to re-expand aliases */
2987                         doublequeue = true;
2988                 }
2989                 if (QS_IS_BADADDR(a->q_state))
2990                 {
2991                         /* make this "go away" */
2992                         a->q_state = QS_DONTSEND;
2993                 }
2994         }
2995
2996         /* collect the text of the message */
2997         SmtpPhase = "collect";
2998         buffer_errors();
2999
3000 #if _FFR_ADAPTIVE_EOL
3001         /* triggers error in collect, disabled for now */
3002         if (smtp->sm_crlf)
3003                 e->e_flags |= EF_NL_NOT_EOL;
3004 #endif /* _FFR_ADAPTIVE_EOL */
3005
3006         collect(InChannel, true, NULL, e);
3007
3008         /* redefine message size */
3009         (void) sm_snprintf(buf, sizeof buf, "%ld", e->e_msgsize);
3010         macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
3011
3012 #if _FFR_CHECK_EOM
3013         /* rscheck() will set Errors or EF_DISCARD if it trips */
3014         (void) rscheck("check_eom", buf, NULL, e, RSF_UNSTRUCTURED|RSF_COUNT,
3015                        3, NULL, e->e_id);
3016 #endif /* _FFR_CHECK_EOM */
3017
3018 #if MILTER
3019         milteraccept = true;
3020         if (smtp->sm_milterlist && smtp->sm_milterize &&
3021             Errors <= 0 &&
3022             !bitset(EF_DISCARD, e->e_flags))
3023         {
3024                 char state;
3025                 char *response;
3026
3027                 response = milter_data(e, &state);
3028                 switch (state)
3029                 {
3030                   case SMFIR_REPLYCODE:
3031                         if (MilterLogLevel > 3)
3032                                 sm_syslog(LOG_INFO, e->e_id,
3033                                           "Milter: data, reject=%s",
3034                                           response);
3035                         milteraccept = false;
3036                         usrerr(response);
3037                         break;
3038
3039                   case SMFIR_REJECT:
3040                         milteraccept = false;
3041                         if (MilterLogLevel > 3)
3042                                 sm_syslog(LOG_INFO, e->e_id,
3043                                           "Milter: data, reject=554 5.7.1 Command rejected");
3044                         usrerr("554 5.7.1 Command rejected");
3045                         break;
3046
3047                   case SMFIR_DISCARD:
3048                         if (MilterLogLevel > 3)
3049                                 sm_syslog(LOG_INFO, e->e_id,
3050                                           "Milter: data, discard");
3051                         milteraccept = false;
3052                         e->e_flags |= EF_DISCARD;
3053                         break;
3054
3055                   case SMFIR_TEMPFAIL:
3056                         if (MilterLogLevel > 3)
3057                                 sm_syslog(LOG_INFO, e->e_id,
3058                                           "Milter: data, reject=%s",
3059                                           MSG_TEMPFAIL);
3060                         milteraccept = false;
3061                         usrerr(MSG_TEMPFAIL);
3062                         break;
3063                 }
3064                 if (response != NULL)
3065                         sm_free(response);
3066         }
3067
3068         /* Milter may have changed message size */
3069         (void) sm_snprintf(buf, sizeof buf, "%ld", e->e_msgsize);
3070         macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
3071
3072         /* abort message filters that didn't get the body & log msg is OK */
3073         if (smtp->sm_milterlist && smtp->sm_milterize)
3074         {
3075                 milter_abort(e);
3076                 if (milteraccept && MilterLogLevel > 9)
3077                         sm_syslog(LOG_INFO, e->e_id, "Milter accept: message");
3078         }
3079 #endif /* MILTER */
3080
3081 #if _FFR_QUARANTINE
3082         /* Check if quarantining stats should be updated */
3083         if (e->e_quarmsg != NULL)
3084                 markstats(e, NULL, STATS_QUARANTINE);
3085 #endif /* _FFR_QUARANTINE */
3086
3087         /*
3088         **  If a header/body check (header checks or milter)
3089         **  set EF_DISCARD, don't queueup the message --
3090         **  that would lose the EF_DISCARD bit and deliver
3091         **  the message.
3092         */
3093
3094         if (bitset(EF_DISCARD, e->e_flags))
3095                 doublequeue = false;
3096
3097         aborting = Errors > 0;
3098         if (!aborting &&
3099 #if _FFR_QUARANTINE
3100             (QueueMode == QM_QUARANTINE || e->e_quarmsg == NULL) &&
3101 #endif /* _FFR_QUARANTINE */
3102             !split_by_recipient(e))
3103                 aborting = bitset(EF_FATALERRS, e->e_flags);
3104
3105         if (aborting)
3106         {
3107                 /* Log who the mail would have gone to */
3108                 logundelrcpts(e, e->e_message, 8, false);
3109                 flush_errors(true);
3110                 buffer_errors();
3111                 goto abortmessage;
3112         }
3113
3114         /* from now on, we have to operate silently */
3115         buffer_errors();
3116
3117 #if 0
3118         /*
3119         **  Clear message, it may contain an error from the SMTP dialogue.
3120         **  This error must not show up in the queue.
3121         **      Some error message should show up, e.g., alias database
3122         **      not available, but others shouldn't, e.g., from check_rcpt.
3123         */
3124
3125         e->e_message = NULL;
3126 #endif /* 0 */
3127
3128         /*
3129         **  Arrange to send to everyone.
3130         **      If sending to multiple people, mail back
3131         **              errors rather than reporting directly.
3132         **      In any case, don't mail back errors for
3133         **              anything that has happened up to
3134         **              now (the other end will do this).
3135         **      Truncate our transcript -- the mail has gotten
3136         **              to us successfully, and if we have
3137         **              to mail this back, it will be easier
3138         **              on the reader.
3139         **      Then send to everyone.
3140         **      Finally give a reply code.  If an error has
3141         **              already been given, don't mail a
3142         **              message back.
3143         **      We goose error returns by clearing error bit.
3144         */
3145
3146         SmtpPhase = "delivery";
3147         (void) sm_io_setinfo(e->e_xfp, SM_BF_TRUNCATE, NULL);
3148         id = e->e_id;
3149
3150 #if NAMED_BIND
3151         _res.retry = TimeOuts.res_retry[RES_TO_FIRST];
3152         _res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
3153 #endif /* NAMED_BIND */
3154
3155         for (ee = e; ee != NULL; ee = ee->e_sibling)
3156         {
3157                 /* make sure we actually do delivery */
3158                 ee->e_flags &= ~EF_CLRQUEUE;
3159
3160                 /* from now on, operate silently */
3161                 ee->e_errormode = EM_MAIL;
3162
3163                 if (doublequeue)
3164                 {
3165                         /* make sure it is in the queue */
3166                         queueup(ee, false, true);
3167                 }
3168                 else
3169                 {
3170                         /* send to all recipients */
3171                         sendall(ee, SM_DEFAULT);
3172                 }
3173                 ee->e_to = NULL;
3174         }
3175
3176         /* put back id for SMTP logging in putoutmsg() */
3177         oldid = CurEnv->e_id;
3178         CurEnv->e_id = id;
3179
3180         /* issue success message */
3181         message("250 2.0.0 %s Message accepted for delivery", id);
3182         CurEnv->e_id = oldid;
3183
3184         /* if we just queued, poke it */
3185         if (doublequeue)
3186         {
3187                 bool anything_to_send = false;
3188
3189                 sm_getla();
3190                 for (ee = e; ee != NULL; ee = ee->e_sibling)
3191                 {
3192                         if (WILL_BE_QUEUED(ee->e_sendmode))
3193                                 continue;
3194                         if (shouldqueue(ee->e_msgpriority, ee->e_ctime))
3195                         {
3196                                 ee->e_sendmode = SM_QUEUE;
3197                                 continue;
3198                         }
3199 #if _FFR_QUARANTINE
3200                         else if (QueueMode != QM_QUARANTINE &&
3201                                  ee->e_quarmsg != NULL)
3202                         {
3203                                 ee->e_sendmode = SM_QUEUE;
3204                                 continue;
3205                         }
3206 #endif /* _FFR_QUARANTINE */
3207                         anything_to_send = true;
3208
3209                         /* close all the queue files */
3210                         closexscript(ee);
3211                         if (ee->e_dfp != NULL)
3212                         {
3213                                 (void) sm_io_close(ee->e_dfp, SM_TIME_DEFAULT);
3214                                 ee->e_dfp = NULL;
3215                         }
3216                         unlockqueue(ee);
3217                 }
3218                 if (anything_to_send)
3219                 {
3220 #if PIPELINING
3221                         /*
3222                         **  XXX if we don't do this, we get 250 twice
3223                         **      because it is also flushed in the child.
3224                         */
3225
3226                         (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
3227 #endif /* PIPELINING */
3228                         (void) doworklist(e, true, true);
3229                 }
3230         }
3231
3232   abortmessage:
3233         if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
3234                 logsender(e, NULL);
3235         e->e_flags &= ~EF_LOGSENDER;
3236
3237         /* clean up a bit */
3238         smtp->sm_gotmail = false;
3239
3240         /*
3241         **  Call dropenvelope if and only if the envelope is *not*
3242         **  being processed by the child process forked by doworklist().
3243         */
3244
3245         if (aborting || bitset(EF_DISCARD, e->e_flags))
3246                 dropenvelope(e, true, false);
3247         else
3248         {
3249                 for (ee = e; ee != NULL; ee = ee->e_sibling)
3250                 {
3251 #if _FFR_QUARANTINE
3252                         if (!doublequeue &&
3253                             QueueMode != QM_QUARANTINE &&
3254                             ee->e_quarmsg != NULL)
3255                         {
3256                                 dropenvelope(ee, true, false);
3257                                 continue;
3258                         }
3259 #endif /* _FFR_QUARANTINE */
3260                         if (WILL_BE_QUEUED(ee->e_sendmode))
3261                                 dropenvelope(ee, true, false);
3262                 }
3263         }
3264         sm_rpool_free(e->e_rpool);
3265
3266         /*
3267         **  At this point, e == &MainEnvelope, but if we did splitting,
3268         **  then CurEnv may point to an envelope structure that was just
3269         **  freed with the rpool.  So reset CurEnv *before* calling
3270         **  newenvelope.
3271         */
3272
3273         CurEnv = e;
3274         newenvelope(e, e, sm_rpool_new_x(NULL));
3275         e->e_flags = BlankEnvelope.e_flags;
3276
3277 #if _FFR_QUARANTINE
3278         /* restore connection quarantining */
3279         if (smtp->sm_quarmsg == NULL)
3280         {
3281                 e->e_quarmsg = NULL;
3282                 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), "");
3283         }
3284         else
3285         {
3286                 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, smtp->sm_quarmsg);
3287                 macdefine(&e->e_macro, A_PERM,
3288                           macid("{quarantine}"), e->e_quarmsg);
3289         }
3290 #endif /* _FFR_QUARANTINE */
3291 }
3292 /*
3293 **  LOGUNDELRCPTS -- log undelivered (or all) recipients.
3294 **
3295 **      Parameters:
3296 **              e -- envelope.
3297 **              msg -- message for Stat=
3298 **              level -- log level.
3299 **              all -- log all recipients.
3300 **
3301 **      Returns:
3302 **              none.
3303 **
3304 **      Side Effects:
3305 **              logs undelivered (or all) recipients
3306 */
3307
3308 void
3309 logundelrcpts(e, msg, level, all)
3310         ENVELOPE *e;
3311         char *msg;
3312         int level;
3313         bool all;
3314 {
3315         ADDRESS *a;
3316
3317         if (LogLevel <= level || msg == NULL || *msg == '\0')
3318                 return;
3319
3320         /* Clear $h so relay= doesn't get mislogged by logdelivery() */
3321         macdefine(&e->e_macro, A_PERM, 'h', NULL);
3322
3323         /* Log who the mail would have gone to */
3324         for (a = e->e_sendqueue; a != NULL; a = a->q_next)
3325         {
3326                 if (!QS_IS_UNDELIVERED(a->q_state) && !all)
3327                         continue;
3328                 e->e_to = a->q_paddr;
3329                 logdelivery(NULL, NULL, a->q_status, msg, NULL,
3330                             (time_t) 0, e);
3331         }
3332         e->e_to = NULL;
3333 }
3334 /*
3335 **  CHECKSMTPATTACK -- check for denial-of-service attack by repetition
3336 **
3337 **      Parameters:
3338 **              pcounter -- pointer to a counter for this command.
3339 **              maxcount -- maximum value for this counter before we
3340 **                      slow down.
3341 **              waitnow -- sleep now (in this routine)?
3342 **              cname -- command name for logging.
3343 **              e -- the current envelope.
3344 **
3345 **      Returns:
3346 **              time to wait.
3347 **
3348 **      Side Effects:
3349 **              Slows down if we seem to be under attack.
3350 */
3351
3352 static time_t
3353 checksmtpattack(pcounter, maxcount, waitnow, cname, e)
3354         volatile unsigned int *pcounter;
3355         int maxcount;
3356         bool waitnow;
3357         char *cname;
3358         ENVELOPE *e;
3359 {
3360         if (maxcount <= 0)      /* no limit */
3361                 return (time_t) 0;
3362
3363         if (++(*pcounter) >= maxcount)
3364         {
3365                 time_t s;
3366
3367                 if (*pcounter == maxcount && LogLevel > 5)
3368                 {
3369                         sm_syslog(LOG_INFO, e->e_id,
3370                                   "%s: possible SMTP attack: command=%.40s, count=%u",
3371                                   CurSmtpClient, cname, *pcounter);
3372                 }
3373                 s = 1 << (*pcounter - maxcount);
3374                 if (s >= MAXTIMEOUT || s <= 0)
3375                         s = MAXTIMEOUT;
3376
3377                 /* sleep at least 1 second before returning */
3378                 (void) sleep(*pcounter / maxcount);
3379                 s -= *pcounter / maxcount;
3380                 if (waitnow)
3381                 {
3382                         (void) sleep(s);
3383                         return 0;
3384                 }
3385                 return s;
3386         }
3387         return (time_t) 0;
3388 }
3389 /*
3390 **  SETUP_SMTPD_IO -- setup I/O fd correctly for the SMTP server
3391 **
3392 **      Parameters:
3393 **              none.
3394 **
3395 **      Returns:
3396 **              nothing.
3397 **
3398 **      Side Effects:
3399 **              may change I/O fd.
3400 */
3401
3402 static void
3403 setup_smtpd_io()
3404 {
3405         int inchfd, outchfd, outfd;
3406
3407         inchfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
3408         outchfd  = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL);
3409         outfd = sm_io_getinfo(smioout, SM_IO_WHAT_FD, NULL);
3410         if (outchfd != outfd)
3411         {
3412                 /* arrange for debugging output to go to remote host */
3413                 (void) dup2(outchfd, outfd);
3414         }
3415
3416         /*
3417         **  if InChannel and OutChannel are stdin/stdout
3418         **  and connected to ttys
3419         **  and fcntl(STDIN, F_SETFL, O_NONBLOCKING) also changes STDOUT,
3420         **  then "chain" them together.
3421         */
3422
3423         if (inchfd == STDIN_FILENO && outchfd == STDOUT_FILENO &&
3424             isatty(inchfd) && isatty(outchfd))
3425         {
3426                 int inmode, outmode;
3427
3428                 inmode = fcntl(inchfd, F_GETFL, 0);
3429                 if (inmode == -1)
3430                 {
3431                         if (LogLevel > 11)
3432                                 sm_syslog(LOG_INFO, NOQID,
3433                                         "fcntl(inchfd, F_GETFL) failed: %s",
3434                                         sm_errstring(errno));
3435                         return;
3436                 }
3437                 outmode = fcntl(outchfd, F_GETFL, 0);
3438                 if (outmode == -1)
3439                 {
3440                         if (LogLevel > 11)
3441                                 sm_syslog(LOG_INFO, NOQID,
3442                                         "fcntl(outchfd, F_GETFL) failed: %s",
3443                                         sm_errstring(errno));
3444                         return;
3445                 }
3446                 if (bitset(O_NONBLOCK, inmode) ||
3447                     bitset(O_NONBLOCK, outmode) ||
3448                     fcntl(inchfd, F_SETFL, inmode | O_NONBLOCK) == -1)
3449                         return;
3450                 outmode = fcntl(outchfd, F_GETFL, 0);
3451                 if (outmode != -1 && bitset(O_NONBLOCK, outmode))
3452                 {
3453                         /* changing InChannel also changes OutChannel */
3454                         sm_io_automode(OutChannel, InChannel);
3455                         if (tTd(97, 4) && LogLevel > 9)
3456                                 sm_syslog(LOG_INFO, NOQID,
3457                                           "set automode for I (%d)/O (%d) in SMTP server",
3458                                           inchfd, outchfd);
3459                 }
3460
3461                 /* undo change of inchfd */
3462                 (void) fcntl(inchfd, F_SETFL, inmode);
3463         }
3464 }
3465 /*
3466 **  SKIPWORD -- skip a fixed word.
3467 **
3468 **      Parameters:
3469 **              p -- place to start looking.
3470 **              w -- word to skip.
3471 **
3472 **      Returns:
3473 **              p following w.
3474 **              NULL on error.
3475 **
3476 **      Side Effects:
3477 **              clobbers the p data area.
3478 */
3479
3480 static char *
3481 skipword(p, w)
3482         register char *volatile p;
3483         char *w;
3484 {
3485         register char *q;
3486         char *firstp = p;
3487
3488         /* find beginning of word */
3489         SKIP_SPACE(p);
3490         q = p;
3491
3492         /* find end of word */
3493         while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p)))
3494                 p++;
3495         while (isascii(*p) && isspace(*p))
3496                 *p++ = '\0';
3497         if (*p != ':')
3498         {
3499           syntax:
3500                 usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"",
3501                         shortenstring(firstp, MAXSHORTSTR));
3502                 return NULL;
3503         }
3504         *p++ = '\0';
3505         SKIP_SPACE(p);
3506
3507         if (*p == '\0')
3508                 goto syntax;
3509
3510         /* see if the input word matches desired word */
3511         if (sm_strcasecmp(q, w))
3512                 goto syntax;
3513
3514         return p;
3515 }
3516 /*
3517 **  MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
3518 **
3519 **      Parameters:
3520 **              kp -- the parameter key.
3521 **              vp -- the value of that parameter.
3522 **              e -- the envelope.
3523 **
3524 **      Returns:
3525 **              none.
3526 */
3527
3528 static void
3529 mail_esmtp_args(kp, vp, e)
3530         char *kp;
3531         char *vp;
3532         ENVELOPE *e;
3533 {
3534         if (sm_strcasecmp(kp, "size") == 0)
3535         {
3536                 if (vp == NULL)
3537                 {
3538                         usrerr("501 5.5.2 SIZE requires a value");
3539                         /* NOTREACHED */
3540                 }
3541                 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), vp);
3542                 errno = 0;
3543                 e->e_msgsize = strtol(vp, (char **) NULL, 10);
3544                 if (e->e_msgsize == LONG_MAX && errno == ERANGE)
3545                 {
3546                         usrerr("552 5.2.3 Message size exceeds maximum value");
3547                         /* NOTREACHED */
3548                 }
3549                 if (e->e_msgsize < 0)
3550                 {
3551                         usrerr("552 5.2.3 Message size invalid");
3552                         /* NOTREACHED */
3553                 }
3554         }
3555         else if (sm_strcasecmp(kp, "body") == 0)
3556         {
3557                 if (vp == NULL)
3558                 {
3559                         usrerr("501 5.5.2 BODY requires a value");
3560                         /* NOTREACHED */
3561                 }
3562                 else if (sm_strcasecmp(vp, "8bitmime") == 0)
3563                 {
3564                         SevenBitInput = false;
3565                 }
3566                 else if (sm_strcasecmp(vp, "7bit") == 0)
3567                 {
3568                         SevenBitInput = true;
3569                 }
3570                 else
3571                 {
3572                         usrerr("501 5.5.4 Unknown BODY type %s", vp);
3573                         /* NOTREACHED */
3574                 }
3575                 e->e_bodytype = sm_rpool_strdup_x(e->e_rpool, vp);
3576         }
3577         else if (sm_strcasecmp(kp, "envid") == 0)
3578         {
3579                 if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3580                 {
3581                         usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN");
3582                         /* NOTREACHED */
3583                 }
3584                 if (vp == NULL)
3585                 {
3586                         usrerr("501 5.5.2 ENVID requires a value");
3587                         /* NOTREACHED */
3588                 }
3589                 if (!xtextok(vp))
3590                 {
3591                         usrerr("501 5.5.4 Syntax error in ENVID parameter value");
3592                         /* NOTREACHED */
3593                 }
3594                 if (e->e_envid != NULL)
3595                 {
3596                         usrerr("501 5.5.0 Duplicate ENVID parameter");
3597                         /* NOTREACHED */
3598                 }
3599                 e->e_envid = sm_rpool_strdup_x(e->e_rpool, vp);
3600                 macdefine(&e->e_macro, A_PERM,
3601                         macid("{dsn_envid}"), e->e_envid);
3602         }
3603         else if (sm_strcasecmp(kp, "ret") == 0)
3604         {
3605                 if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3606                 {
3607                         usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN");
3608                         /* NOTREACHED */
3609                 }
3610                 if (vp == NULL)
3611                 {
3612                         usrerr("501 5.5.2 RET requires a value");
3613                         /* NOTREACHED */
3614                 }
3615                 if (bitset(EF_RET_PARAM, e->e_flags))
3616                 {
3617                         usrerr("501 5.5.0 Duplicate RET parameter");
3618                         /* NOTREACHED */
3619                 }
3620                 e->e_flags |= EF_RET_PARAM;
3621                 if (sm_strcasecmp(vp, "hdrs") == 0)
3622                         e->e_flags |= EF_NO_BODY_RETN;
3623                 else if (sm_strcasecmp(vp, "full") != 0)
3624                 {
3625                         usrerr("501 5.5.2 Bad argument \"%s\" to RET", vp);
3626                         /* NOTREACHED */
3627                 }
3628                 macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), vp);
3629         }
3630 #if SASL
3631         else if (sm_strcasecmp(kp, "auth") == 0)
3632         {
3633                 int len;
3634                 char *q;
3635                 char *auth_param;       /* the value of the AUTH=x */
3636                 bool saveQuickAbort = QuickAbort;
3637                 bool saveSuprErrs = SuprErrs;
3638                 bool saveExitStat = ExitStat;
3639                 char pbuf[256];
3640
3641                 if (vp == NULL)
3642                 {
3643                         usrerr("501 5.5.2 AUTH= requires a value");
3644                         /* NOTREACHED */
3645                 }
3646                 if (e->e_auth_param != NULL)
3647                 {
3648                         usrerr("501 5.5.0 Duplicate AUTH parameter");
3649                         /* NOTREACHED */
3650                 }
3651                 if ((q = strchr(vp, ' ')) != NULL)
3652                         len = q - vp + 1;
3653                 else
3654                         len = strlen(vp) + 1;
3655                 auth_param = xalloc(len);
3656                 (void) sm_strlcpy(auth_param, vp, len);
3657                 if (!xtextok(auth_param))
3658                 {
3659                         usrerr("501 5.5.4 Syntax error in AUTH parameter value");
3660                         /* just a warning? */
3661                         /* NOTREACHED */
3662                 }
3663
3664                 /* XXX this might be cut off */
3665                 (void) sm_strlcpy(pbuf, xuntextify(auth_param), sizeof pbuf);
3666                 /* xalloc() the buffer instead? */
3667
3668                 /* XXX define this always or only if trusted? */
3669                 macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), pbuf);
3670
3671                 /*
3672                 **  call Strust_auth to find out whether
3673                 **  auth_param is acceptable (trusted)
3674                 **  we shouldn't trust it if not authenticated
3675                 **  (required by RFC, leave it to ruleset?)
3676                 */
3677
3678                 SuprErrs = true;
3679                 QuickAbort = false;
3680                 if (strcmp(auth_param, "<>") != 0 &&
3681                      (rscheck("trust_auth", pbuf, NULL, e, RSF_RMCOMM,
3682                               9, NULL, NOQID) != EX_OK || Errors > 0))
3683                 {
3684                         if (tTd(95, 8))
3685                         {
3686                                 q = e->e_auth_param;
3687                                 sm_dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n",
3688                                         pbuf, (q == NULL) ? "" : q);
3689                         }
3690
3691                         /* not trusted */
3692                         e->e_auth_param = "<>";
3693 # if _FFR_AUTH_PASSING
3694                         macdefine(&BlankEnvelope.e_macro, A_PERM,
3695                                   macid("{auth_author}"), NULL);
3696 # endif /* _FFR_AUTH_PASSING */
3697                 }
3698                 else
3699                 {
3700                         if (tTd(95, 8))
3701                                 sm_dprintf("auth=\"%.100s\" trusted\n", pbuf);
3702                         e->e_auth_param = sm_rpool_strdup_x(e->e_rpool,
3703                                                             auth_param);
3704                 }
3705                 sm_free(auth_param); /* XXX */
3706
3707                 /* reset values */
3708                 Errors = 0;
3709                 QuickAbort = saveQuickAbort;
3710                 SuprErrs = saveSuprErrs;
3711                 ExitStat = saveExitStat;
3712         }
3713 #endif /* SASL */
3714 #define PRTCHAR(c)      ((isascii(c) && isprint(c)) ? (c) : '?')
3715
3716         /*
3717         **  "by" is only accepted if DeliverByMin >= 0.
3718         **  We maybe could add this to the list of server_features.
3719         */
3720
3721         else if (sm_strcasecmp(kp, "by") == 0 && DeliverByMin >= 0)
3722         {
3723                 char *s;
3724
3725                 if (vp == NULL)
3726                 {
3727                         usrerr("501 5.5.2 BY= requires a value");
3728                         /* NOTREACHED */
3729                 }
3730                 errno = 0;
3731                 e->e_deliver_by = strtol(vp, &s, 10);
3732                 if (e->e_deliver_by == LONG_MIN ||
3733                     e->e_deliver_by == LONG_MAX ||
3734                     e->e_deliver_by > 999999999l ||
3735                     e->e_deliver_by < -999999999l)
3736                 {
3737                         usrerr("501 5.5.2 BY=%s out of range", vp);
3738                         /* NOTREACHED */
3739                 }
3740                 if (s == NULL || *s != ';')
3741                 {
3742                         usrerr("501 5.5.2 BY= missing ';'");
3743                         /* NOTREACHED */
3744                 }
3745                 e->e_dlvr_flag = 0;
3746                 ++s;    /* XXX: spaces allowed? */
3747                 SKIP_SPACE(s);
3748                 switch (tolower(*s))
3749                 {
3750                   case 'n':
3751                         e->e_dlvr_flag = DLVR_NOTIFY;
3752                         break;
3753                   case 'r':
3754                         e->e_dlvr_flag = DLVR_RETURN;
3755                         if (e->e_deliver_by <= 0)
3756                         {
3757                                 usrerr("501 5.5.4 mode R requires BY time > 0");
3758                                 /* NOTREACHED */
3759                         }
3760                         if (DeliverByMin > 0 && e->e_deliver_by > 0 &&
3761                             e->e_deliver_by < DeliverByMin)
3762                         {
3763                                 usrerr("555 5.5.2 time %ld less than %ld",
3764                                         e->e_deliver_by, (long) DeliverByMin);
3765                                 /* NOTREACHED */
3766                         }
3767                         break;
3768                   default:
3769                         usrerr("501 5.5.2 illegal by-mode '%c'", PRTCHAR(*s));
3770                         /* NOTREACHED */
3771                 }
3772                 ++s;    /* XXX: spaces allowed? */
3773                 SKIP_SPACE(s);
3774                 switch (tolower(*s))
3775                 {
3776                   case 't':
3777                         e->e_dlvr_flag |= DLVR_TRACE;
3778                         break;
3779                   case '\0':
3780                         break;
3781                   default:
3782                         usrerr("501 5.5.2 illegal by-trace '%c'", PRTCHAR(*s));
3783                         /* NOTREACHED */
3784                 }
3785
3786                 /* XXX: check whether more characters follow? */
3787         }
3788         else
3789         {
3790                 usrerr("555 5.5.4 %s parameter unrecognized", kp);
3791                 /* NOTREACHED */
3792         }
3793 }
3794 /*
3795 **  RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
3796 **
3797 **      Parameters:
3798 **              a -- the address corresponding to the To: parameter.
3799 **              kp -- the parameter key.
3800 **              vp -- the value of that parameter.
3801 **              e -- the envelope.
3802 **
3803 **      Returns:
3804 **              none.
3805 */
3806
3807 static void
3808 rcpt_esmtp_args(a, kp, vp, e)
3809         ADDRESS *a;
3810         char *kp;
3811         char *vp;
3812         ENVELOPE *e;
3813 {
3814         if (sm_strcasecmp(kp, "notify") == 0)
3815         {
3816                 char *p;
3817
3818                 if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3819                 {
3820                         usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
3821                         /* NOTREACHED */
3822                 }
3823                 if (vp == NULL)
3824                 {
3825                         usrerr("501 5.5.2 NOTIFY requires a value");
3826                         /* NOTREACHED */
3827                 }
3828                 a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY);
3829                 a->q_flags |= QHASNOTIFY;
3830                 macdefine(&e->e_macro, A_TEMP, macid("{dsn_notify}"), vp);
3831
3832                 if (sm_strcasecmp(vp, "never") == 0)
3833                         return;
3834                 for (p = vp; p != NULL; vp = p)
3835                 {
3836                         p = strchr(p, ',');
3837                         if (p != NULL)
3838                                 *p++ = '\0';
3839                         if (sm_strcasecmp(vp, "success") == 0)
3840                                 a->q_flags |= QPINGONSUCCESS;
3841                         else if (sm_strcasecmp(vp, "failure") == 0)
3842                                 a->q_flags |= QPINGONFAILURE;
3843                         else if (sm_strcasecmp(vp, "delay") == 0)
3844                                 a->q_flags |= QPINGONDELAY;
3845                         else
3846                         {
3847                                 usrerr("501 5.5.4 Bad argument \"%s\"  to NOTIFY",
3848                                         vp);
3849                                 /* NOTREACHED */
3850                         }
3851                 }
3852         }
3853         else if (sm_strcasecmp(kp, "orcpt") == 0)
3854         {
3855                 if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3856                 {
3857                         usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN");
3858                         /* NOTREACHED */
3859                 }
3860                 if (vp == NULL)
3861                 {
3862                         usrerr("501 5.5.2 ORCPT requires a value");
3863                         /* NOTREACHED */
3864                 }
3865                 if (strchr(vp, ';') == NULL || !xtextok(vp))
3866                 {
3867                         usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
3868                         /* NOTREACHED */
3869                 }
3870                 if (a->q_orcpt != NULL)
3871                 {
3872                         usrerr("501 5.5.0 Duplicate ORCPT parameter");
3873                         /* NOTREACHED */
3874                 }
3875                 a->q_orcpt = sm_rpool_strdup_x(e->e_rpool, vp);
3876         }
3877         else
3878         {
3879                 usrerr("555 5.5.4 %s parameter unrecognized", kp);
3880                 /* NOTREACHED */
3881         }
3882 }
3883 /*
3884 **  PRINTVRFYADDR -- print an entry in the verify queue
3885 **
3886 **      Parameters:
3887 **              a -- the address to print.
3888 **              last -- set if this is the last one.
3889 **              vrfy -- set if this is a VRFY command.
3890 **
3891 **      Returns:
3892 **              none.
3893 **
3894 **      Side Effects:
3895 **              Prints the appropriate 250 codes.
3896 */
3897 #define OFFF    (3 + 1 + 5 + 1) /* offset in fmt: SMTP reply + enh. code */
3898
3899 static void
3900 printvrfyaddr(a, last, vrfy)
3901         register ADDRESS *a;
3902         bool last;
3903         bool vrfy;
3904 {
3905         char fmtbuf[30];
3906
3907         if (vrfy && a->q_mailer != NULL &&
3908             !bitnset(M_VRFY250, a->q_mailer->m_flags))
3909                 (void) sm_strlcpy(fmtbuf, "252", sizeof fmtbuf);
3910         else
3911                 (void) sm_strlcpy(fmtbuf, "250", sizeof fmtbuf);
3912         fmtbuf[3] = last ? ' ' : '-';
3913         (void) sm_strlcpy(&fmtbuf[4], "2.1.5 ", sizeof fmtbuf - 4);
3914         if (a->q_fullname == NULL)
3915         {
3916                 if ((a->q_mailer == NULL ||
3917                      a->q_mailer->m_addrtype == NULL ||
3918                      sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
3919                     strchr(a->q_user, '@') == NULL)
3920                         (void) sm_strlcpy(&fmtbuf[OFFF], "<%s@%s>",
3921                                        sizeof fmtbuf - OFFF);
3922                 else
3923                         (void) sm_strlcpy(&fmtbuf[OFFF], "<%s>",
3924                                        sizeof fmtbuf - OFFF);
3925                 message(fmtbuf, a->q_user, MyHostName);
3926         }
3927         else
3928         {
3929                 if ((a->q_mailer == NULL ||
3930                      a->q_mailer->m_addrtype == NULL ||
3931                      sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
3932                     strchr(a->q_user, '@') == NULL)
3933                         (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s@%s>",
3934                                        sizeof fmtbuf - OFFF);
3935                 else
3936                         (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s>",
3937                                        sizeof fmtbuf - OFFF);
3938                 message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
3939         }
3940 }
3941
3942 #if SASL
3943 /*
3944 **  SASLMECHS -- get list of possible AUTH mechanisms
3945 **
3946 **      Parameters:
3947 **              conn -- SASL connection info.
3948 **              mechlist -- output parameter for list of mechanisms.
3949 **
3950 **      Returns:
3951 **              number of mechs.
3952 */
3953
3954 static int
3955 saslmechs(conn, mechlist)
3956         sasl_conn_t *conn;
3957         char **mechlist;
3958 {
3959         int len, num, result;
3960
3961         /* "user" is currently unused */
3962 # if SASL >= 20000
3963         result = sasl_listmech(conn, NULL,
3964                                "", " ", "", (const char **) mechlist,
3965                                (unsigned int *)&len, (unsigned int *)&num);
3966 # else /* SASL >= 20000 */
3967         result = sasl_listmech(conn, "user", /* XXX */
3968                                "", " ", "", mechlist,
3969                                (unsigned int *)&len, (unsigned int *)&num);
3970 # endif /* SASL >= 20000 */
3971         if (result != SASL_OK)
3972         {
3973                 if (LogLevel > 9)
3974                         sm_syslog(LOG_WARNING, NOQID,
3975                                   "AUTH error: listmech=%d, num=%d",
3976                                   result, num);
3977                 num = 0;
3978         }
3979         if (num > 0)
3980         {
3981                 if (LogLevel > 11)
3982                         sm_syslog(LOG_INFO, NOQID,
3983                                   "AUTH: available mech=%s, allowed mech=%s",
3984                                   *mechlist, AuthMechanisms);
3985                 *mechlist = intersect(AuthMechanisms, *mechlist, NULL);
3986         }
3987         else
3988         {
3989                 *mechlist = NULL;       /* be paranoid... */
3990                 if (result == SASL_OK && LogLevel > 9)
3991                         sm_syslog(LOG_WARNING, NOQID,
3992                                   "AUTH warning: no mechanisms");
3993         }
3994         return num;
3995 }
3996
3997 # if SASL >= 20000
3998 /*
3999 **  PROXY_POLICY -- define proxy policy for AUTH
4000 **
4001 **      Parameters:
4002 **              conn -- unused.
4003 **              context -- unused.
4004 **              requested_user -- authorization identity.
4005 **              rlen -- authorization identity length.
4006 **              auth_identity -- authentication identity.
4007 **              alen -- authentication identity length.
4008 **              def_realm -- default user realm.
4009 **              urlen -- user realm length.
4010 **              propctx -- unused.
4011 **
4012 **      Returns:
4013 **              ok?
4014 **
4015 **      Side Effects:
4016 **              sets {auth_authen} macro.
4017 */
4018
4019 int
4020 proxy_policy(conn, context, requested_user, rlen, auth_identity, alen,
4021              def_realm, urlen, propctx)
4022         sasl_conn_t *conn;
4023         void *context;
4024         const char *requested_user;
4025         unsigned rlen;
4026         const char *auth_identity;
4027         unsigned alen;
4028         const char *def_realm;
4029         unsigned urlen;
4030         struct propctx *propctx;
4031 {
4032         if (auth_identity == NULL)
4033                 return SASL_FAIL;
4034
4035         macdefine(&BlankEnvelope.e_macro, A_TEMP,
4036                   macid("{auth_authen}"), (char *) auth_identity);
4037
4038         return SASL_OK;
4039 }
4040 # else /* SASL >= 20000 */
4041
4042 /*
4043 **  PROXY_POLICY -- define proxy policy for AUTH
4044 **
4045 **      Parameters:
4046 **              context -- unused.
4047 **              auth_identity -- authentication identity.
4048 **              requested_user -- authorization identity.
4049 **              user -- allowed user (output).
4050 **              errstr -- possible error string (output).
4051 **
4052 **      Returns:
4053 **              ok?
4054 */
4055
4056 int
4057 proxy_policy(context, auth_identity, requested_user, user, errstr)
4058         void *context;
4059         const char *auth_identity;
4060         const char *requested_user;
4061         const char **user;
4062         const char **errstr;
4063 {
4064         if (user == NULL || auth_identity == NULL)
4065                 return SASL_FAIL;
4066         *user = newstr(auth_identity);
4067         return SASL_OK;
4068 }
4069 # endif /* SASL >= 20000 */
4070 #endif /* SASL */
4071
4072 #if STARTTLS
4073 /*
4074 **  INITSRVTLS -- initialize server side TLS
4075 **
4076 **      Parameters:
4077 **              tls_ok -- should tls initialization be done?
4078 **
4079 **      Returns:
4080 **              succeeded?
4081 **
4082 **      Side Effects:
4083 **              sets tls_ok_srv which is a static variable in this module.
4084 **              Do NOT remove assignments to it!
4085 */
4086
4087 bool
4088 initsrvtls(tls_ok)
4089         bool tls_ok;
4090 {
4091         if (!tls_ok)
4092                 return false;
4093
4094         /* do NOT remove assignment */
4095         tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, true, SrvCertFile,
4096                              SrvKeyFile, CACertPath, CACertFile, DHParams);
4097         return tls_ok_srv;
4098 }
4099 #endif /* STARTTLS */
4100 /*
4101 **  SRVFEATURES -- get features for SMTP server
4102 **
4103 **      Parameters:
4104 **              e -- envelope (should be session context).
4105 **              clientname -- name of client.
4106 **              features -- default features for this invocation.
4107 **
4108 **      Returns:
4109 **              server features.
4110 */
4111
4112 /* table with options: it uses just one character, how about strings? */
4113 static struct
4114 {
4115         char            srvf_opt;
4116         unsigned int    srvf_flag;
4117 } srv_feat_table[] =
4118 {
4119         { 'A',  SRV_OFFER_AUTH  },
4120         { 'B',  SRV_OFFER_VERB  },      /* FFR; not documented in 8.12 */
4121         { 'D',  SRV_OFFER_DSN   },      /* FFR; not documented in 8.12 */
4122         { 'E',  SRV_OFFER_ETRN  },      /* FFR; not documented in 8.12 */
4123         { 'L',  SRV_REQ_AUTH    },      /* FFR; not documented in 8.12 */
4124 #if PIPELINING
4125 # if _FFR_NO_PIPE
4126         { 'N',  SRV_NO_PIPE     },
4127 # endif /* _FFR_NO_PIPE */
4128         { 'P',  SRV_OFFER_PIPE  },
4129 #endif /* PIPELINING */
4130         { 'R',  SRV_VRFY_CLT    },      /* FFR; not documented in 8.12 */
4131         { 'S',  SRV_OFFER_TLS   },
4132 /*      { 'T',  SRV_TMP_FAIL    },      */
4133         { 'V',  SRV_VRFY_CLT    },
4134         { 'X',  SRV_OFFER_EXPN  },      /* FFR; not documented in 8.12 */
4135 /*      { 'Y',  SRV_OFFER_VRFY  },      */
4136         { '\0', SRV_NONE        }
4137 };
4138
4139 static unsigned int
4140 srvfeatures(e, clientname, features)
4141         ENVELOPE *e;
4142         char *clientname;
4143         unsigned int features;
4144 {
4145         int r, i, j;
4146         char **pvp, c, opt;
4147         char pvpbuf[PSBUFSIZE];
4148
4149         pvp = NULL;
4150         r = rscap("srv_features", clientname, "", e, &pvp, pvpbuf,
4151                   sizeof(pvpbuf));
4152         if (r != EX_OK)
4153                 return features;
4154         if (pvp == NULL || pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
4155                 return features;
4156         if (pvp[1] != NULL && sm_strncasecmp(pvp[1], "temp", 4) == 0)
4157                 return SRV_TMP_FAIL;
4158
4159         /*
4160         **  General rule (see sendmail.h, d_flags):
4161         **  lower case: required/offered, upper case: Not required/available
4162         **
4163         **  Since we can change some features per daemon, we have both
4164         **  cases here: turn on/off a feature.
4165         */
4166
4167         for (i = 1; pvp[i] != NULL; i++)
4168         {
4169                 c = pvp[i][0];
4170                 j = 0;
4171                 for (;;)
4172                 {
4173                         if ((opt = srv_feat_table[j].srvf_opt) == '\0')
4174                         {
4175                                 if (LogLevel > 9)
4176                                         sm_syslog(LOG_WARNING, e->e_id,
4177                                                   "srvfeatures: unknown feature %s",
4178                                                   pvp[i]);
4179                                 break;
4180                         }
4181                         if (c == opt)
4182                         {
4183                                 features &= ~(srv_feat_table[j].srvf_flag);
4184                                 break;
4185                         }
4186                         if (c == tolower(opt))
4187                         {
4188                                 features |= srv_feat_table[j].srvf_flag;
4189                                 break;
4190                         }
4191                         ++j;
4192                 }
4193         }
4194         return features;
4195 }
4196
4197 /*
4198 **  HELP -- implement the HELP command.
4199 **
4200 **      Parameters:
4201 **              topic -- the topic we want help for.
4202 **              e -- envelope.
4203 **
4204 **      Returns:
4205 **              none.
4206 **
4207 **      Side Effects:
4208 **              outputs the help file to message output.
4209 */
4210 #define HELPVSTR        "#vers  "
4211 #define HELPVERSION     2
4212
4213 void
4214 help(topic, e)
4215         char *topic;
4216         ENVELOPE *e;
4217 {
4218         register SM_FILE_T *hf;
4219         register char *p;
4220         int len;
4221         bool noinfo;
4222         bool first = true;
4223         long sff = SFF_OPENASROOT|SFF_REGONLY;
4224         char buf[MAXLINE];
4225         char inp[MAXLINE];
4226         static int foundvers = -1;
4227         extern char Version[];
4228
4229         if (DontLockReadFiles)
4230                 sff |= SFF_NOLOCK;
4231         if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH, DontBlameSendmail))
4232                 sff |= SFF_SAFEDIRPATH;
4233
4234         if (HelpFile == NULL ||
4235             (hf = safefopen(HelpFile, O_RDONLY, 0444, sff)) == NULL)
4236         {
4237                 /* no help */
4238                 errno = 0;
4239                 message("502 5.3.0 Sendmail %s -- HELP not implemented",
4240                         Version);
4241                 return;
4242         }
4243
4244         if (topic == NULL || *topic == '\0')
4245         {
4246                 topic = "smtp";
4247                 noinfo = false;
4248         }
4249         else
4250         {
4251                 makelower(topic);
4252                 noinfo = true;
4253         }
4254
4255         len = strlen(topic);
4256
4257         while (sm_io_fgets(hf, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
4258         {
4259                 if (buf[0] == '#')
4260                 {
4261                         if (foundvers < 0 &&
4262                             strncmp(buf, HELPVSTR, strlen(HELPVSTR)) == 0)
4263                         {
4264                                 int h;
4265
4266                                 if (sm_io_sscanf(buf + strlen(HELPVSTR), "%d",
4267                                                  &h) == 1)
4268                                         foundvers = h;
4269                         }
4270                         continue;
4271                 }
4272                 if (strncmp(buf, topic, len) == 0)
4273                 {
4274                         if (first)
4275                         {
4276                                 first = false;
4277
4278                                 /* print version if no/old vers# in file */
4279                                 if (foundvers < 2 && !noinfo)
4280                                         message("214-2.0.0 This is Sendmail version %s", Version);
4281                         }
4282                         p = strpbrk(buf, " \t");
4283                         if (p == NULL)
4284                                 p = buf + strlen(buf) - 1;
4285                         else
4286                                 p++;
4287                         fixcrlf(p, true);
4288                         if (foundvers >= 2)
4289                         {
4290                                 translate_dollars(p);
4291                                 expand(p, inp, sizeof inp, e);
4292                                 p = inp;
4293                         }
4294                         message("214-2.0.0 %s", p);
4295                         noinfo = false;
4296                 }
4297         }
4298
4299         if (noinfo)
4300                 message("504 5.3.0 HELP topic \"%.10s\" unknown", topic);
4301         else
4302                 message("214 2.0.0 End of HELP info");
4303
4304         if (foundvers != 0 && foundvers < HELPVERSION)
4305         {
4306                 if (LogLevel > 1)
4307                         sm_syslog(LOG_WARNING, e->e_id,
4308                                   "%s too old (require version %d)",
4309                                   HelpFile, HELPVERSION);
4310
4311                 /* avoid log next time */
4312                 foundvers = 0;
4313         }
4314
4315         (void) sm_io_close(hf, SM_TIME_DEFAULT);
4316 }