]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/sendmail/src/srvrsmtp.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / sendmail / src / srvrsmtp.c
1 /*
2  * Copyright (c) 1998-2010, 2012-2014 Proofpoint, 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/mfapi.h>
17 # include <libmilter/mfdef.h>
18 #endif /* MILTER */
19
20 SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.1016 2013-11-22 20:51:56 ca Exp $")
21
22 #include <sm/time.h>
23 #include <sm/fdset.h>
24
25 #if SASL || STARTTLS
26 # include "sfsasl.h"
27 #endif /* SASL || STARTTLS */
28 #if SASL
29 # define ENC64LEN(l)    (((l) + 2) * 4 / 3 + 1)
30 static int saslmechs __P((sasl_conn_t *, char **));
31 #endif /* SASL */
32 #if STARTTLS
33 # include <openssl/err.h>
34 # include <sysexits.h>
35
36 static SSL_CTX  *srv_ctx = NULL;        /* TLS server context */
37 static SSL      *srv_ssl = NULL;        /* per connection context */
38
39 static bool     tls_ok_srv = false;
40
41 # define TLS_VERIFY_CLIENT() tls_set_verify(srv_ctx, srv_ssl, \
42                                 bitset(SRV_VRFY_CLT, features))
43 #endif /* STARTTLS */
44
45 #if _FFR_DM_ONE
46 static bool     NotFirstDelivery = false;
47 #endif /* _FFR_DM_ONE */
48
49 /* server features */
50 #define SRV_NONE        0x0000  /* none... */
51 #define SRV_OFFER_TLS   0x0001  /* offer STARTTLS */
52 #define SRV_VRFY_CLT    0x0002  /* request a cert */
53 #define SRV_OFFER_AUTH  0x0004  /* offer AUTH */
54 #define SRV_OFFER_ETRN  0x0008  /* offer ETRN */
55 #define SRV_OFFER_VRFY  0x0010  /* offer VRFY (not yet used) */
56 #define SRV_OFFER_EXPN  0x0020  /* offer EXPN */
57 #define SRV_OFFER_VERB  0x0040  /* offer VERB */
58 #define SRV_OFFER_DSN   0x0080  /* offer DSN */
59 #if PIPELINING
60 # define SRV_OFFER_PIPE 0x0100  /* offer PIPELINING */
61 # if _FFR_NO_PIPE
62 #  define SRV_NO_PIPE   0x0200  /* disable PIPELINING, sleep if used */
63 # endif /* _FFR_NO_PIPE */
64 #endif /* PIPELINING */
65 #define SRV_REQ_AUTH    0x0400  /* require AUTH */
66 #define SRV_REQ_SEC     0x0800  /* require security - equiv to AuthOptions=p */
67 #define SRV_TMP_FAIL    0x1000  /* ruleset caused a temporary failure */
68
69 static unsigned int     srvfeatures __P((ENVELOPE *, char *, unsigned int));
70
71 #define STOP_ATTACK     ((time_t) -1)
72 static time_t   checksmtpattack __P((volatile unsigned int *, unsigned int,
73                                      bool, char *, ENVELOPE *));
74 static void     printvrfyaddr __P((ADDRESS *, bool, bool));
75 static char     *skipword __P((char *volatile, char *));
76 static void     setup_smtpd_io __P((void));
77
78 #if SASL
79 # if SASL >= 20000
80 static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname,
81                                 char *_remoteip, char *_localip,
82                                 char *_auth_id, sasl_ssf_t *_ext_ssf));
83
84 # define RESET_SASLCONN \
85         do                                                      \
86         {                                                       \
87                 result = reset_saslconn(&conn, AuthRealm, remoteip, \
88                                         localip, auth_id, &ext_ssf); \
89                 if (result != SASL_OK)                          \
90                         sasl_ok = false;                        \
91         } while (0)
92
93 # else /* SASL >= 20000 */
94 static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname,
95                                 struct sockaddr_in *_saddr_r,
96                                 struct sockaddr_in *_saddr_l,
97                                 sasl_external_properties_t *_ext_ssf));
98 # define RESET_SASLCONN \
99         do                                                      \
100         {                                                       \
101                 result = reset_saslconn(&conn, AuthRealm, &saddr_r, \
102                                         &saddr_l, &ext_ssf);    \
103                 if (result != SASL_OK)                          \
104                         sasl_ok = false;                        \
105         } while (0)
106
107 # endif /* SASL >= 20000 */
108 #endif /* SASL */
109
110 extern ENVELOPE BlankEnvelope;
111
112 #define NBADRCPTS                                               \
113         do                                                      \
114         {                                                       \
115                 char buf[16];                                   \
116                 (void) sm_snprintf(buf, sizeof(buf), "%d",      \
117                         BadRcptThrottle > 0 && n_badrcpts > BadRcptThrottle \
118                                 ? n_badrcpts - 1 : n_badrcpts); \
119                 macdefine(&e->e_macro, A_TEMP, macid("{nbadrcpts}"), buf); \
120         } while (0)
121
122 #define SKIP_SPACE(s)   while (isascii(*s) && isspace(*s))      \
123                                 (s)++
124
125 /*
126 **  PARSE_ESMTP_ARGS -- parse EMSTP arguments (for MAIL, RCPT)
127 **
128 **      Parameters:
129 **              e -- the envelope
130 **              addr_st -- address (RCPT only)
131 **              p -- read buffer
132 **              delimptr -- current position in read buffer
133 **              which -- MAIL/RCPT
134 **              args -- arguments (output)
135 **              esmtp_args -- function to process a single ESMTP argument
136 **
137 **      Returns:
138 **              none
139 */
140
141 void
142 parse_esmtp_args(e, addr_st, p, delimptr, which, args, esmtp_args)
143         ENVELOPE *e;
144         ADDRESS *addr_st;
145         char *p;
146         char *delimptr;
147         char *which;
148         char *args[];
149         esmtp_args_F esmtp_args;
150 {
151         int argno;
152
153         argno = 0;
154         if (args != NULL)
155                 args[argno++] = p;
156         p = delimptr;
157         while (p != NULL && *p != '\0')
158         {
159                 char *kp;
160                 char *vp = NULL;
161                 char *equal = NULL;
162
163                 /* locate the beginning of the keyword */
164                 SKIP_SPACE(p);
165                 if (*p == '\0')
166                         break;
167                 kp = p;
168
169                 /* skip to the value portion */
170                 while ((isascii(*p) && isalnum(*p)) || *p == '-')
171                         p++;
172                 if (*p == '=')
173                 {
174                         equal = p;
175                         *p++ = '\0';
176                         vp = p;
177
178                         /* skip to the end of the value */
179                         while (*p != '\0' && *p != ' ' &&
180                                !(isascii(*p) && iscntrl(*p)) &&
181                                *p != '=')
182                                 p++;
183                 }
184
185                 if (*p != '\0')
186                         *p++ = '\0';
187
188                 if (tTd(19, 1))
189                         sm_dprintf("%s: got arg %s=\"%s\"\n", which, kp,
190                                 vp == NULL ? "<null>" : vp);
191
192                 esmtp_args(addr_st, kp, vp, e);
193                 if (equal != NULL)
194                         *equal = '=';
195                 if (args != NULL)
196                         args[argno] = kp;
197                 argno++;
198                 if (argno >= MAXSMTPARGS - 1)
199                         usrerr("501 5.5.4 Too many parameters");
200                 if (Errors > 0)
201                         break;
202         }
203         if (args != NULL)
204                 args[argno] = NULL;
205 }
206
207 #if _FFR_ADD_BCC
208
209 /*
210 **  ADDRCPT -- Add a rcpt to sendq list
211 **
212 **      Parameters:
213 **              rcpt -- rcpt
214 **              sendq -- a pointer to the head of a queue to put
215 **                      these people into.
216 **              e -- the envelope in which to add these recipients.
217 **
218 **      Returns:
219 **              The number of addresses added to the list.
220 */
221
222 static int
223 addrcpt(rcpt, sendq, e)
224         char *rcpt;
225         ADDRESS **sendq;
226         ENVELOPE *e;
227 {
228         int r;
229         char *oldto;
230         ADDRESS *a;
231
232         SM_REQUIRE(rcpt != NULL);
233         SM_REQUIRE(sendq != NULL);
234         SM_REQUIRE(e != NULL);
235         oldto = e->e_to;
236         if (tTd(25, 1))
237                 sm_dprintf("addrcpt: rcpt=%s\n", rcpt);
238         r = Errors;
239         a = NULL;
240         SM_TRY
241         {
242                 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e b");
243                 a = parseaddr(rcpt, NULLADDR, RF_COPYALL, ' ', NULL, e, true);
244                 if (a == NULL)
245                         return 0;
246
247                 a->q_flags &= ~Q_PINGFLAGS;
248                 a->q_flags |= QINTBCC;
249                 a->q_owner = "<>";
250
251                 /* disable alias expansion? */
252                 a = recipient(a, sendq, 0, e);
253         }
254         SM_FINALLY
255         {
256                 e->e_to = oldto;
257                 macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL);
258         }
259         SM_END_TRY
260         if (tTd(25, 1))
261                 sm_dprintf("addrcpt: rcpt=%s, flags=%#lx\n", rcpt,
262                         a != NULL ? a->q_flags : 0);
263         Errors = r;
264         return 1;
265 }
266
267 /*
268 **  ADDBCC -- Maybe create a copy of an e-mail
269 **
270 **      Parameters:
271 **              a -- current RCPT
272 **              e -- the envelope.
273 **
274 **      Returns:
275 **              nothing
276 **
277 **      Side Effects:
278 **              rscheck() can trigger an "exception"
279 */
280
281 static void
282 addbcc(a, e)
283         ADDRESS *a;
284         ENVELOPE *e;
285 {
286         int nobcc;
287         char *newrcpt, empty[1];
288
289         if (!AddBcc)
290                 return;
291
292         nobcc = false;
293         empty[0] = '\0';
294         newrcpt = empty;
295
296         nobcc = rscheck("bcc", a->q_paddr, NULL, e, RSF_ADDR, 12, NULL, NOQID,
297                         NULL, &newrcpt);
298         if (tTd(25, 1))
299                 sm_dprintf("addbcc: nobcc=%d, Errors=%d, newrcpt=<%s>\n", nobcc, Errors, newrcpt);
300         if (nobcc != EX_OK || Errors > 0 || *newrcpt == '\0')
301                 return;
302
303         (void) addrcpt(newrcpt, &e->e_sendqueue, e);
304         return;
305 }
306 #else /* _FFR_ADD_BCC */
307 # define addbcc(a, e)
308 #endif /* _FFR_ADD_BCC */
309
310 #if _FFR_RCPTFLAGS
311 /*
312 **  RCPTMODS -- Perform rcpt modifications if requested
313 **
314 **      Parameters:
315 **              rcpt -- current RCPT
316 **              e -- the envelope.
317 **
318 **      Returns:
319 **              nothing.
320 */
321
322 void
323 rcptmods(rcpt, e)
324         ADDRESS *rcpt;
325         ENVELOPE *e;
326 {
327         char *fl;
328
329         SM_REQUIRE(rcpt != NULL);
330         SM_REQUIRE(e != NULL);
331
332         fl = macvalue(macid("{rcpt_flags}"), e);
333         if (fl == NULL || *fl == '\0')
334                 return;
335         if (tTd(25, 1))
336                 sm_dprintf("rcptmods: rcpt=%s, flags=%s\n", rcpt->q_paddr, fl);
337
338         /* parse flags */
339         for ( ; *fl != '\0'; ++fl)
340         {
341                 switch (*fl)
342                 {
343                   case 'n':
344                         rcpt->q_flags &= ~Q_PINGFLAGS;
345                         rcpt->q_flags |= QINTBCC;
346                         rcpt->q_owner = "<>";
347                         break;
348
349                   case 'N':
350                         rcpt->q_flags &= ~Q_PINGFLAGS;
351                         rcpt->q_owner = "<>";
352                         break;
353
354                   case QDYNMAILFLG:
355                         rcpt->q_flags |= QDYNMAILER;
356                         newmodmailer(rcpt, *fl);
357                         break;
358
359                   default:
360                         sm_syslog(LOG_INFO, e->e_id,
361                                   "rcpt=%s, rcpt_flags=%s, status=unknown",
362                                   rcpt->q_paddr, fl);
363                         break;
364                 }
365         }
366
367         /* reset macro to avoid confusion later on */
368         macdefine(&e->e_macro, A_PERM, macid("{rcpt_flags}"), NULL);
369
370 }
371 #else /* _FFR_RCPTFLAGS */
372 # define rcptmods(a, e)
373 #endif /* _FFR_RCPTFLAGS */
374
375 /*
376 **  SMTP -- run the SMTP protocol.
377 **
378 **      Parameters:
379 **              nullserver -- if non-NULL, rejection message for
380 **                      (almost) all SMTP commands.
381 **              d_flags -- daemon flags
382 **              e -- the envelope.
383 **
384 **      Returns:
385 **              never.
386 **
387 **      Side Effects:
388 **              Reads commands from the input channel and processes them.
389 */
390
391 /*
392 **  Notice: The smtp server doesn't have a session context like the client
393 **      side has (mci). Therefore some data (session oriented) is allocated
394 **      or assigned to the "wrong" structure (esp. STARTTLS, AUTH).
395 **      This should be fixed in a successor version.
396 */
397
398 struct cmd
399 {
400         char    *cmd_name;      /* command name */
401         int     cmd_code;       /* internal code, see below */
402 };
403
404 /* values for cmd_code */
405 #define CMDERROR        0       /* bad command */
406 #define CMDMAIL 1       /* mail -- designate sender */
407 #define CMDRCPT 2       /* rcpt -- designate recipient */
408 #define CMDDATA 3       /* data -- send message text */
409 #define CMDRSET 4       /* rset -- reset state */
410 #define CMDVRFY 5       /* vrfy -- verify address */
411 #define CMDEXPN 6       /* expn -- expand address */
412 #define CMDNOOP 7       /* noop -- do nothing */
413 #define CMDQUIT 8       /* quit -- close connection and die */
414 #define CMDHELO 9       /* helo -- be polite */
415 #define CMDHELP 10      /* help -- give usage info */
416 #define CMDEHLO 11      /* ehlo -- extended helo (RFC 1425) */
417 #define CMDETRN 12      /* etrn -- flush queue */
418 #if SASL
419 # define CMDAUTH        13      /* auth -- SASL authenticate */
420 #endif /* SASL */
421 #if STARTTLS
422 # define CMDSTLS        14      /* STARTTLS -- start TLS session */
423 #endif /* STARTTLS */
424 /* non-standard commands */
425 #define CMDVERB 17      /* verb -- go into verbose mode */
426 /* unimplemented commands from RFC 821 */
427 #define CMDUNIMPL       19      /* unimplemented rfc821 commands */
428 /* use this to catch and log "door handle" attempts on your system */
429 #define CMDLOGBOGUS     23      /* bogus command that should be logged */
430 /* debugging-only commands, only enabled if SMTPDEBUG is defined */
431 #define CMDDBGQSHOW     24      /* showq -- show send queue */
432 #define CMDDBGDEBUG     25      /* debug -- set debug mode */
433
434 /*
435 **  Note: If you change this list, remember to update 'helpfile'
436 */
437
438 static struct cmd       CmdTab[] =
439 {
440         { "mail",       CMDMAIL         },
441         { "rcpt",       CMDRCPT         },
442         { "data",       CMDDATA         },
443         { "rset",       CMDRSET         },
444         { "vrfy",       CMDVRFY         },
445         { "expn",       CMDEXPN         },
446         { "help",       CMDHELP         },
447         { "noop",       CMDNOOP         },
448         { "quit",       CMDQUIT         },
449         { "helo",       CMDHELO         },
450         { "ehlo",       CMDEHLO         },
451         { "etrn",       CMDETRN         },
452         { "verb",       CMDVERB         },
453         { "send",       CMDUNIMPL       },
454         { "saml",       CMDUNIMPL       },
455         { "soml",       CMDUNIMPL       },
456         { "turn",       CMDUNIMPL       },
457 #if SASL
458         { "auth",       CMDAUTH,        },
459 #endif /* SASL */
460 #if STARTTLS
461         { "starttls",   CMDSTLS,        },
462 #endif /* STARTTLS */
463     /* remaining commands are here only to trap and log attempts to use them */
464         { "showq",      CMDDBGQSHOW     },
465         { "debug",      CMDDBGDEBUG     },
466         { "wiz",        CMDLOGBOGUS     },
467
468         { NULL,         CMDERROR        }
469 };
470
471 static char     *CurSmtpClient;         /* who's at the other end of channel */
472
473 #ifndef MAXBADCOMMANDS
474 # define MAXBADCOMMANDS 25      /* maximum number of bad commands */
475 #endif /* ! MAXBADCOMMANDS */
476 #ifndef MAXHELOCOMMANDS
477 # define MAXHELOCOMMANDS 3      /* max HELO/EHLO commands before slowdown */
478 #endif /* ! MAXHELOCOMMANDS */
479 #ifndef MAXVRFYCOMMANDS
480 # define MAXVRFYCOMMANDS 6      /* max VRFY/EXPN commands before slowdown */
481 #endif /* ! MAXVRFYCOMMANDS */
482 #ifndef MAXETRNCOMMANDS
483 # define MAXETRNCOMMANDS 8      /* max ETRN commands before slowdown */
484 #endif /* ! MAXETRNCOMMANDS */
485 #ifndef MAXTIMEOUT
486 # define MAXTIMEOUT (4 * 60)    /* max timeout for bad commands */
487 #endif /* ! MAXTIMEOUT */
488
489 /*
490 **  Maximum shift value to compute timeout for bad commands.
491 **  This introduces an upper limit of 2^MAXSHIFT for the timeout.
492 */
493
494 #ifndef MAXSHIFT
495 # define MAXSHIFT 8
496 #endif /* ! MAXSHIFT */
497 #if MAXSHIFT > 31
498  ERROR _MAXSHIFT > 31 is invalid
499 #endif /* MAXSHIFT */
500
501
502 #if MAXBADCOMMANDS > 0
503 # define STOP_IF_ATTACK(r)      do              \
504         {                                       \
505                 if ((r) == STOP_ATTACK)         \
506                         goto stopattack;        \
507         } while (0)
508
509 #else /* MAXBADCOMMANDS > 0 */
510 # define STOP_IF_ATTACK(r)      r
511 #endif /* MAXBADCOMMANDS > 0 */
512
513
514 #if SM_HEAP_CHECK
515 static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp",
516         "@(#)$Debug: leak_smtp - trace memory leaks during SMTP processing $");
517 #endif /* SM_HEAP_CHECK */
518
519 typedef struct
520 {
521         bool            sm_gotmail;     /* mail command received */
522         unsigned int    sm_nrcpts;      /* number of successful RCPT commands */
523         bool            sm_discard;
524 #if MILTER
525         bool            sm_milterize;
526         bool            sm_milterlist;  /* any filters in the list? */
527         milters_T       sm_milters;
528
529         /* e_nrcpts from envelope before recipient() call */
530         unsigned int    sm_e_nrcpts_orig;
531 #endif /* MILTER */
532         char            *sm_quarmsg;    /* carry quarantining across messages */
533 } SMTP_T;
534
535 static bool     smtp_data __P((SMTP_T *, ENVELOPE *));
536
537 #define MSG_TEMPFAIL "451 4.3.2 Please try again later"
538
539 #if MILTER
540 # define MILTER_ABORT(e)        milter_abort((e))
541
542 # define MILTER_REPLY(str)                                              \
543         {                                                               \
544                 int savelogusrerrs = LogUsrErrs;                        \
545                                                                         \
546                 milter_cmd_fail = true;                                 \
547                 switch (state)                                          \
548                 {                                                       \
549                   case SMFIR_SHUTDOWN:                                  \
550                         if (MilterLogLevel > 3)                         \
551                         {                                               \
552                                 sm_syslog(LOG_INFO, e->e_id,            \
553                                           "Milter: %s=%s, reject=421, errormode=4",     \
554                                           str, addr);                   \
555                                 LogUsrErrs = false;                     \
556                         }                                               \
557                         {                                               \
558                                 bool tsave = QuickAbort;                \
559                                                                         \
560                                 QuickAbort = false;                     \
561                                 usrerr("421 4.3.0 closing connection"); \
562                                 QuickAbort = tsave;                     \
563                                 e->e_sendqueue = NULL;                  \
564                                 goto doquit;                            \
565                         }                                               \
566                         break;                                          \
567                   case SMFIR_REPLYCODE:                                 \
568                         if (MilterLogLevel > 3)                         \
569                         {                                               \
570                                 sm_syslog(LOG_INFO, e->e_id,            \
571                                           "Milter: %s=%s, reject=%s",   \
572                                           str, addr, response);         \
573                                 LogUsrErrs = false;                     \
574                         }                                               \
575                         if (strncmp(response, "421 ", 4) == 0           \
576                             || strncmp(response, "421-", 4) == 0)       \
577                         {                                               \
578                                 bool tsave = QuickAbort;                \
579                                                                         \
580                                 QuickAbort = false;                     \
581                                 usrerr(response);                       \
582                                 QuickAbort = tsave;                     \
583                                 e->e_sendqueue = NULL;                  \
584                                 goto doquit;                            \
585                         }                                               \
586                         else                                            \
587                                 usrerr(response);                       \
588                         break;                                          \
589                                                                         \
590                   case SMFIR_REJECT:                                    \
591                         if (MilterLogLevel > 3)                         \
592                         {                                               \
593                                 sm_syslog(LOG_INFO, e->e_id,            \
594                                           "Milter: %s=%s, reject=550 5.7.1 Command rejected", \
595                                           str, addr);                   \
596                                 LogUsrErrs = false;                     \
597                         }                                               \
598                         usrerr("550 5.7.1 Command rejected");           \
599                         break;                                          \
600                                                                         \
601                   case SMFIR_DISCARD:                                   \
602                         if (MilterLogLevel > 3)                         \
603                                 sm_syslog(LOG_INFO, e->e_id,            \
604                                           "Milter: %s=%s, discard",     \
605                                           str, addr);                   \
606                         e->e_flags |= EF_DISCARD;                       \
607                         milter_cmd_fail = false;                        \
608                         break;                                          \
609                                                                         \
610                   case SMFIR_TEMPFAIL:                                  \
611                         if (MilterLogLevel > 3)                         \
612                         {                                               \
613                                 sm_syslog(LOG_INFO, e->e_id,            \
614                                           "Milter: %s=%s, reject=%s",   \
615                                           str, addr, MSG_TEMPFAIL);     \
616                                 LogUsrErrs = false;                     \
617                         }                                               \
618                         usrerr(MSG_TEMPFAIL);                           \
619                         break;                                          \
620                   default:                                              \
621                         milter_cmd_fail = false;                        \
622                         break;                                          \
623                 }                                                       \
624                 LogUsrErrs = savelogusrerrs;                            \
625                 if (response != NULL)                                   \
626                         sm_free(response); /* XXX */                    \
627         }
628
629 #else /* MILTER */
630 # define MILTER_ABORT(e)
631 #endif /* MILTER */
632
633 /* clear all SMTP state (for HELO/EHLO/RSET) */
634 #define CLEAR_STATE(cmd)                                        \
635 do                                                              \
636 {                                                               \
637         /* abort milter filters */                              \
638         MILTER_ABORT(e);                                        \
639                                                                 \
640         if (smtp.sm_nrcpts > 0)                                 \
641         {                                                       \
642                 logundelrcpts(e, cmd, 10, false);               \
643                 smtp.sm_nrcpts = 0;                             \
644                 macdefine(&e->e_macro, A_PERM,                  \
645                           macid("{nrcpts}"), "0");              \
646         }                                                       \
647                                                                 \
648         e->e_sendqueue = NULL;                                  \
649         e->e_flags |= EF_CLRQUEUE;                              \
650                                                                 \
651         if (tTd(92, 2))                                         \
652                 sm_dprintf("CLEAR_STATE: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",\
653                         e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel);\
654         if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))   \
655                 logsender(e, NULL);                             \
656         e->e_flags &= ~EF_LOGSENDER;                            \
657                                                                 \
658         /* clean up a bit */                                    \
659         smtp.sm_gotmail = false;                                \
660         SuprErrs = true;                                        \
661         (void) dropenvelope(e, true, false);                    \
662         sm_rpool_free(e->e_rpool);                              \
663         e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL));       \
664         CurEnv = e;                                             \
665         e->e_features = features;                               \
666                                                                 \
667         /* put back discard bit */                              \
668         if (smtp.sm_discard)                                    \
669                 e->e_flags |= EF_DISCARD;                       \
670                                                                 \
671         /* restore connection quarantining */                   \
672         if (smtp.sm_quarmsg == NULL)                            \
673         {                                                       \
674                 e->e_quarmsg = NULL;                            \
675                 macdefine(&e->e_macro, A_PERM,                  \
676                         macid("{quarantine}"), "");             \
677         }                                                       \
678         else                                                    \
679         {                                                       \
680                 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,    \
681                                                 smtp.sm_quarmsg);       \
682                 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"),   \
683                           e->e_quarmsg);                        \
684         }                                                       \
685 } while (0)
686
687 /* sleep to flatten out connection load */
688 #define MIN_DELAY_LOG   15      /* wait before logging this again */
689
690 /* is it worth setting the process title for 1s? */
691 #define DELAY_CONN(cmd)                                         \
692         if (DelayLA > 0 && (CurrentLA = getla()) >= DelayLA)    \
693         {                                                       \
694                 time_t dnow;                                    \
695                                                                 \
696                 sm_setproctitle(true, e,                        \
697                                 "%s: %s: delaying %s: load average: %d", \
698                                 qid_printname(e), CurSmtpClient,        \
699                                 cmd, DelayLA);  \
700                 if (LogLevel > 8 && (dnow = curtime()) > log_delay)     \
701                 {                                               \
702                         sm_syslog(LOG_INFO, e->e_id,            \
703                                   "delaying=%s, load average=%d >= %d", \
704                                   cmd, CurrentLA, DelayLA);             \
705                         log_delay = dnow + MIN_DELAY_LOG;       \
706                 }                                               \
707                 (void) sleep(1);                                \
708                 sm_setproctitle(true, e, "%s %s: %.80s",        \
709                                 qid_printname(e), CurSmtpClient, inp);  \
710         }
711
712 /*
713 **  Determine the correct protocol keyword to use in the
714 **  Received: header, following RFC 3848.
715 */
716
717 #if !STARTTLS
718 # define tls_active     false
719 #endif
720 #if SASL
721 # define auth_active    (authenticating == SASL_IS_AUTH)
722 #else
723 # define auth_active    false
724 #endif
725 #define GET_PROTOCOL()                                  \
726         (auth_active                                    \
727             ? (tls_active ? "ESMTPSA" : "ESMTPA")       \
728             : (tls_active ? "ESMTPS"  : "ESMTP"))
729
730 static bool SevenBitInput_Saved;        /* saved version of SevenBitInput */
731
732 void
733 smtp(nullserver, d_flags, e)
734         char *volatile nullserver;
735         BITMAP256 d_flags;
736         register ENVELOPE *volatile e;
737 {
738         register char *volatile p;
739         register struct cmd *volatile c = NULL;
740         char *cmd;
741         auto ADDRESS *vrfyqueue;
742         ADDRESS *a;
743         volatile bool gothello;         /* helo command received */
744         bool vrfy;                      /* set if this is a vrfy command */
745         char *volatile protocol;        /* sending protocol */
746         char *volatile sendinghost;     /* sending hostname */
747         char *volatile peerhostname;    /* name of SMTP peer or "localhost" */
748         auto char *delimptr;
749         char *id;
750         volatile unsigned int n_badcmds = 0;    /* count of bad commands */
751         volatile unsigned int n_badrcpts = 0;   /* number of rejected RCPT */
752         volatile unsigned int n_verifies = 0;   /* count of VRFY/EXPN */
753         volatile unsigned int n_etrn = 0;       /* count of ETRN */
754         volatile unsigned int n_noop = 0;       /* count of NOOP/VERB/etc */
755         volatile unsigned int n_helo = 0;       /* count of HELO/EHLO */
756         bool ok;
757         volatile bool first;
758         volatile bool tempfail = false;
759         volatile time_t wt;             /* timeout after too many commands */
760         volatile time_t previous;       /* time after checksmtpattack() */
761         volatile bool lognullconnection = true;
762         register char *q;
763         SMTP_T smtp;
764         char *addr;
765         char *greetcode = "220";
766         const char *greetmsg = "not accepting messages";
767         char *hostname;                 /* my hostname ($j) */
768         QUEUE_CHAR *new;
769         char *args[MAXSMTPARGS];
770         char inp[MAXINPLINE];
771 #if MAXINPLINE < MAXLINE
772  ERROR _MAXINPLINE must NOT be less than _MAXLINE: MAXINPLINE < MAXLINE
773 #endif /* MAXINPLINE < MAXLINE */
774         char cmdbuf[MAXLINE];
775 #if SASL
776         sasl_conn_t *conn;
777         volatile bool sasl_ok;
778         volatile unsigned int n_auth = 0;       /* count of AUTH commands */
779         bool ismore;
780         int result;
781         volatile int authenticating;
782         char *user;
783         char *in, *out2;
784 # if SASL >= 20000
785         char *auth_id = NULL;
786         const char *out;
787         sasl_ssf_t ext_ssf;
788         char localip[60], remoteip[60];
789 # else /* SASL >= 20000 */
790         char *out;
791         const char *errstr;
792         sasl_external_properties_t ext_ssf;
793         struct sockaddr_in saddr_l;
794         struct sockaddr_in saddr_r;
795 # endif /* SASL >= 20000 */
796         sasl_security_properties_t ssp;
797         sasl_ssf_t *ssf;
798         unsigned int inlen, out2len;
799         unsigned int outlen;
800         char *volatile auth_type;
801         char *mechlist;
802         volatile unsigned int n_mechs;
803         unsigned int len;
804 #else /* SASL */
805 #endif /* SASL */
806         int r;
807 #if STARTTLS
808         int rfd, wfd;
809         volatile bool tls_active = false;
810         volatile bool smtps = bitnset(D_SMTPS, d_flags);
811         bool saveQuickAbort;
812         bool saveSuprErrs;
813         time_t tlsstart;
814 #endif /* STARTTLS */
815         volatile unsigned int features;
816 #if PIPELINING
817 # if _FFR_NO_PIPE
818         int np_log = 0;
819 # endif /* _FFR_NO_PIPE */
820 #endif /* PIPELINING */
821         volatile time_t log_delay = (time_t) 0;
822 #if MILTER
823         volatile bool milter_cmd_done, milter_cmd_safe;
824         volatile bool milter_rcpt_added, milter_cmd_fail;
825         ADDRESS addr_st;
826 # define p_addr_st      &addr_st
827 #else /* MILTER */
828 # define p_addr_st      NULL
829 #endif /* MILTER */
830         size_t inplen;
831 #if _FFR_BADRCPT_SHUTDOWN
832         int n_badrcpts_adj;
833 #endif /* _FFR_BADRCPT_SHUTDOWN */
834
835         SevenBitInput_Saved = SevenBitInput;
836         smtp.sm_nrcpts = 0;
837 #if MILTER
838         smtp.sm_milterize = (nullserver == NULL);
839         smtp.sm_milterlist = false;
840         addr = NULL;
841 #endif /* MILTER */
842
843         /* setup I/O fd correctly for the SMTP server */
844         setup_smtpd_io();
845
846 #if SM_HEAP_CHECK
847         if (sm_debug_active(&DebugLeakSmtp, 1))
848         {
849                 sm_heap_newgroup();
850                 sm_dprintf("smtp() heap group #%d\n", sm_heap_group());
851         }
852 #endif /* SM_HEAP_CHECK */
853
854         /* XXX the rpool should be set when e is initialized in main() */
855         e->e_rpool = sm_rpool_new_x(NULL);
856         e->e_macro.mac_rpool = e->e_rpool;
857
858         settime(e);
859         sm_getla();
860         peerhostname = RealHostName;
861         if (peerhostname == NULL)
862                 peerhostname = "localhost";
863         CurHostName = peerhostname;
864         CurSmtpClient = macvalue('_', e);
865         if (CurSmtpClient == NULL)
866                 CurSmtpClient = CurHostName;
867
868         /* check_relay may have set discard bit, save for later */
869         smtp.sm_discard = bitset(EF_DISCARD, e->e_flags);
870
871 #if PIPELINING
872         /* auto-flush output when reading input */
873         (void) sm_io_autoflush(InChannel, OutChannel);
874 #endif /* PIPELINING */
875
876         sm_setproctitle(true, e, "server %s startup", CurSmtpClient);
877
878         /* Set default features for server. */
879         features = ((bitset(PRIV_NOETRN, PrivacyFlags) ||
880                      bitnset(D_NOETRN, d_flags)) ? SRV_NONE : SRV_OFFER_ETRN)
881                 | (bitnset(D_AUTHREQ, d_flags) ? SRV_REQ_AUTH : SRV_NONE)
882                 | (bitset(PRIV_NOEXPN, PrivacyFlags) ? SRV_NONE
883                         : (SRV_OFFER_EXPN
884                           | (bitset(PRIV_NOVERB, PrivacyFlags)
885                              ? SRV_NONE : SRV_OFFER_VERB)))
886                 | ((bitset(PRIV_NORECEIPTS, PrivacyFlags) || !SendMIMEErrors)
887                          ? SRV_NONE : SRV_OFFER_DSN)
888 #if SASL
889                 | (bitnset(D_NOAUTH, d_flags) ? SRV_NONE : SRV_OFFER_AUTH)
890                 | (bitset(SASL_SEC_NOPLAINTEXT, SASLOpts) ? SRV_REQ_SEC
891                                                           : SRV_NONE)
892 #endif /* SASL */
893 #if PIPELINING
894                 | SRV_OFFER_PIPE
895 #endif /* PIPELINING */
896 #if STARTTLS
897                 | (bitnset(D_NOTLS, d_flags) ? SRV_NONE : SRV_OFFER_TLS)
898                 | (bitset(TLS_I_NO_VRFY, TLS_Srv_Opts) ? SRV_NONE
899                                                        : SRV_VRFY_CLT)
900 #endif /* STARTTLS */
901                 ;
902         if (nullserver == NULL)
903         {
904                 features = srvfeatures(e, CurSmtpClient, features);
905                 if (bitset(SRV_TMP_FAIL, features))
906                 {
907                         if (LogLevel > 4)
908                                 sm_syslog(LOG_ERR, NOQID,
909                                           "ERROR: srv_features=tempfail, relay=%.100s, access temporarily disabled",
910                                           CurSmtpClient);
911                         nullserver = "450 4.3.0 Please try again later.";
912                 }
913                 else
914                 {
915 #if PIPELINING
916 # if _FFR_NO_PIPE
917                         if (bitset(SRV_NO_PIPE, features))
918                         {
919                                 /* for consistency */
920                                 features &= ~SRV_OFFER_PIPE;
921                         }
922 # endif /* _FFR_NO_PIPE */
923 #endif /* PIPELINING */
924 #if SASL
925                         if (bitset(SRV_REQ_SEC, features))
926                                 SASLOpts |= SASL_SEC_NOPLAINTEXT;
927                         else
928                                 SASLOpts &= ~SASL_SEC_NOPLAINTEXT;
929 #endif /* SASL */
930                 }
931         }
932         else if (strncmp(nullserver, "421 ", 4) == 0)
933         {
934                 message(nullserver);
935                 goto doquit;
936         }
937
938         e->e_features = features;
939         hostname = macvalue('j', e);
940 #if SASL
941         if (AuthRealm == NULL)
942                 AuthRealm = hostname;
943         sasl_ok = bitset(SRV_OFFER_AUTH, features);
944         n_mechs = 0;
945         authenticating = SASL_NOT_AUTH;
946
947         /* SASL server new connection */
948         if (sasl_ok)
949         {
950 # if SASL >= 20000
951                 result = sasl_server_new("smtp", AuthRealm, NULL, NULL, NULL,
952                                          NULL, 0, &conn);
953 # elif SASL > 10505
954                 /* use empty realm: only works in SASL > 1.5.5 */
955                 result = sasl_server_new("smtp", AuthRealm, "", NULL, 0, &conn);
956 # else /* SASL >= 20000 */
957                 /* use no realm -> realm is set to hostname by SASL lib */
958                 result = sasl_server_new("smtp", AuthRealm, NULL, NULL, 0,
959                                          &conn);
960 # endif /* SASL >= 20000 */
961                 sasl_ok = result == SASL_OK;
962                 if (!sasl_ok)
963                 {
964                         if (LogLevel > 9)
965                                 sm_syslog(LOG_WARNING, NOQID,
966                                           "AUTH error: sasl_server_new failed=%d",
967                                           result);
968                 }
969         }
970         if (sasl_ok)
971         {
972                 /*
973                 **  SASL set properties for sasl
974                 **  set local/remote IP
975                 **  XXX Cyrus SASL v1 only supports IPv4
976                 **
977                 **  XXX where exactly are these used/required?
978                 **  Kerberos_v4
979                 */
980
981 # if SASL >= 20000
982                 localip[0] = remoteip[0] = '\0';
983 #  if NETINET || NETINET6
984                 in = macvalue(macid("{daemon_family}"), e);
985                 if (in != NULL && (
986 #   if NETINET6
987                     strcmp(in, "inet6") == 0 ||
988 #   endif /* NETINET6 */
989                     strcmp(in, "inet") == 0))
990                 {
991                         SOCKADDR_LEN_T addrsize;
992                         SOCKADDR saddr_l;
993                         SOCKADDR saddr_r;
994
995                         addrsize = sizeof(saddr_r);
996                         if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
997                                                       NULL),
998                                         (struct sockaddr *) &saddr_r,
999                                         &addrsize) == 0)
1000                         {
1001                                 if (iptostring(&saddr_r, addrsize,
1002                                                remoteip, sizeof(remoteip)))
1003                                 {
1004                                         sasl_setprop(conn, SASL_IPREMOTEPORT,
1005                                                      remoteip);
1006                                 }
1007                                 addrsize = sizeof(saddr_l);
1008                                 if (getsockname(sm_io_getinfo(InChannel,
1009                                                               SM_IO_WHAT_FD,
1010                                                               NULL),
1011                                                 (struct sockaddr *) &saddr_l,
1012                                                 &addrsize) == 0)
1013                                 {
1014                                         if (iptostring(&saddr_l, addrsize,
1015                                                        localip,
1016                                                        sizeof(localip)))
1017                                         {
1018                                                 sasl_setprop(conn,
1019                                                              SASL_IPLOCALPORT,
1020                                                              localip);
1021                                         }
1022                                 }
1023                         }
1024                 }
1025 #  endif /* NETINET || NETINET6 */
1026 # else /* SASL >= 20000 */
1027 #  if NETINET
1028                 in = macvalue(macid("{daemon_family}"), e);
1029                 if (in != NULL && strcmp(in, "inet") == 0)
1030                 {
1031                         SOCKADDR_LEN_T addrsize;
1032
1033                         addrsize = sizeof(struct sockaddr_in);
1034                         if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
1035                                                       NULL),
1036                                         (struct sockaddr *)&saddr_r,
1037                                         &addrsize) == 0)
1038                         {
1039                                 sasl_setprop(conn, SASL_IP_REMOTE, &saddr_r);
1040                                 addrsize = sizeof(struct sockaddr_in);
1041                                 if (getsockname(sm_io_getinfo(InChannel,
1042                                                               SM_IO_WHAT_FD,
1043                                                               NULL),
1044                                                 (struct sockaddr *)&saddr_l,
1045                                                 &addrsize) == 0)
1046                                         sasl_setprop(conn, SASL_IP_LOCAL,
1047                                                      &saddr_l);
1048                         }
1049                 }
1050 #  endif /* NETINET */
1051 # endif /* SASL >= 20000 */
1052
1053                 auth_type = NULL;
1054                 mechlist = NULL;
1055                 user = NULL;
1056 # if 0
1057                 macdefine(&BlankEnvelope.e_macro, A_PERM,
1058                         macid("{auth_author}"), NULL);
1059 # endif /* 0 */
1060
1061                 /* set properties */
1062                 (void) memset(&ssp, '\0', sizeof(ssp));
1063
1064                 /* XXX should these be options settable via .cf ? */
1065                 /* ssp.min_ssf = 0; is default due to memset() */
1066                 ssp.max_ssf = MaxSLBits;
1067                 ssp.maxbufsize = MAXOUTLEN;
1068                 ssp.security_flags = SASLOpts & SASL_SEC_MASK;
1069                 sasl_ok = sasl_setprop(conn, SASL_SEC_PROPS, &ssp) == SASL_OK;
1070
1071                 if (sasl_ok)
1072                 {
1073                         /*
1074                         **  external security strength factor;
1075                         **      currently we have none so zero
1076                         */
1077
1078 # if SASL >= 20000
1079                         ext_ssf = 0;
1080                         auth_id = NULL;
1081                         sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL,
1082                                                  &ext_ssf) == SASL_OK) &&
1083                                    (sasl_setprop(conn, SASL_AUTH_EXTERNAL,
1084                                                  auth_id) == SASL_OK));
1085 # else /* SASL >= 20000 */
1086                         ext_ssf.ssf = 0;
1087                         ext_ssf.auth_id = NULL;
1088                         sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
1089                                                &ext_ssf) == SASL_OK;
1090 # endif /* SASL >= 20000 */
1091                 }
1092                 if (sasl_ok)
1093                         n_mechs = saslmechs(conn, &mechlist);
1094         }
1095 #endif /* SASL */
1096
1097         (void) set_tls_rd_tmo(TimeOuts.to_nextcommand);
1098
1099 #if MILTER
1100         if (smtp.sm_milterize)
1101         {
1102                 char state;
1103
1104                 /* initialize mail filter connection */
1105                 smtp.sm_milterlist = milter_init(e, &state, &smtp.sm_milters);
1106                 switch (state)
1107                 {
1108                   case SMFIR_REJECT:
1109                         if (MilterLogLevel > 3)
1110                                 sm_syslog(LOG_INFO, e->e_id,
1111                                           "Milter: initialization failed, rejecting commands");
1112                         greetcode = "554";
1113                         nullserver = "Command rejected";
1114                         smtp.sm_milterize = false;
1115                         break;
1116
1117                   case SMFIR_TEMPFAIL:
1118                         if (MilterLogLevel > 3)
1119                                 sm_syslog(LOG_INFO, e->e_id,
1120                                           "Milter: initialization failed, temp failing commands");
1121                         tempfail = true;
1122                         smtp.sm_milterize = false;
1123                         break;
1124
1125                   case SMFIR_SHUTDOWN:
1126                         if (MilterLogLevel > 3)
1127                                 sm_syslog(LOG_INFO, e->e_id,
1128                                           "Milter: initialization failed, closing connection");
1129                         tempfail = true;
1130                         smtp.sm_milterize = false;
1131                         message("421 4.7.0 %s closing connection",
1132                                         MyHostName);
1133
1134                         /* arrange to ignore send list */
1135                         e->e_sendqueue = NULL;
1136                         lognullconnection = false;
1137                         goto doquit;
1138                 }
1139         }
1140
1141         if (smtp.sm_milterlist && smtp.sm_milterize &&
1142             !bitset(EF_DISCARD, e->e_flags))
1143         {
1144                 char state;
1145                 char *response;
1146
1147                 q = macvalue(macid("{client_name}"), e);
1148                 SM_ASSERT(q != NULL || OpMode == MD_SMTP);
1149                 if (q == NULL)
1150                         q = "localhost";
1151                 response = milter_connect(q, RealHostAddr, e, &state);
1152                 switch (state)
1153                 {
1154 #if _FFR_MILTER_CONNECT_REPLYCODE
1155                   case SMFIR_REPLYCODE:
1156                         if (*response == '5')
1157                         {
1158                                 if (MilterLogLevel > 3)
1159                                         sm_syslog(LOG_INFO, e->e_id,
1160                                                   "Milter: connect: host=%s, addr=%s, reject=%s",
1161                                                   peerhostname,
1162                                                   anynet_ntoa(&RealHostAddr),
1163                                                   response);
1164                                 greetcode = "554"; /* Required by 2821 3.1 */
1165                                 nullserver = newstr(response);
1166                                 if (strlen(nullserver) > 4)
1167                                 {
1168                                         int skip;
1169
1170                                         greetmsg = nullserver + 4;
1171
1172                                         /* skip over enhanced status code */
1173                                         skip = isenhsc(greetmsg, ' ');
1174                                         if (skip > 0)
1175                                                 greetmsg += skip + 1;
1176                                 }
1177                                 smtp.sm_milterize = false;
1178                                 break;
1179                         }
1180                         else if (strncmp(response, "421 ", 4) == 0)
1181                         {
1182                                 int skip;
1183                                 const char *msg = response + 4;
1184
1185                                 if (MilterLogLevel > 3)
1186                                         sm_syslog(LOG_INFO, e->e_id,
1187                                                   "Milter: connect: host=%s, addr=%s, shutdown=%s",
1188                                                   peerhostname,
1189                                                   anynet_ntoa(&RealHostAddr),
1190                                                   response);
1191                                 tempfail = true;
1192                                 smtp.sm_milterize = false;
1193
1194                                 /* skip over enhanced status code */
1195                                 skip = isenhsc(msg, ' ');
1196                                 if (skip > 0)
1197                                         msg += skip + 1;
1198                                 message("421 %s %s", MyHostName, msg);
1199
1200                                 /* arrange to ignore send list */
1201                                 e->e_sendqueue = NULL;
1202                                 goto doquit;
1203                         }
1204                         else
1205                         {
1206                                 if (MilterLogLevel > 3)
1207                                         sm_syslog(LOG_INFO, e->e_id,
1208                                                   "Milter: connect: host=%s, addr=%s, temp failing commands=%s",
1209                                                   peerhostname,
1210                                                   anynet_ntoa(&RealHostAddr),
1211                                                   response);
1212                                 /*tempfail = true;*/
1213                                 smtp.sm_milterize = false;
1214                                 nullserver = newstr(response);
1215                                 break;
1216                         }
1217
1218 #else /* _FFR_MILTER_CONNECT_REPLYCODE */
1219                   case SMFIR_REPLYCODE: /* REPLYCODE shouldn't happen */
1220 #endif /* _FFR_MILTER_CONNECT_REPLYCODE */
1221                   case SMFIR_REJECT:
1222                         if (MilterLogLevel > 3)
1223                                 sm_syslog(LOG_INFO, e->e_id,
1224                                           "Milter: connect: host=%s, addr=%s, rejecting commands",
1225                                           peerhostname,
1226                                           anynet_ntoa(&RealHostAddr));
1227                         greetcode = "554";
1228                         nullserver = "Command rejected";
1229                         smtp.sm_milterize = false;
1230                         break;
1231
1232                   case SMFIR_TEMPFAIL:
1233                         if (MilterLogLevel > 3)
1234                                 sm_syslog(LOG_INFO, e->e_id,
1235                                           "Milter: connect: host=%s, addr=%s, temp failing commands",
1236                                           peerhostname,
1237                                           anynet_ntoa(&RealHostAddr));
1238                         tempfail = true;
1239                         smtp.sm_milterize = false;
1240                         break;
1241
1242                   case SMFIR_SHUTDOWN:
1243                         if (MilterLogLevel > 3)
1244                                 sm_syslog(LOG_INFO, e->e_id,
1245                                           "Milter: connect: host=%s, addr=%s, shutdown",
1246                                           peerhostname,
1247                                           anynet_ntoa(&RealHostAddr));
1248                         tempfail = true;
1249                         smtp.sm_milterize = false;
1250                         message("421 4.7.0 %s closing connection",
1251                                         MyHostName);
1252
1253                         /* arrange to ignore send list */
1254                         e->e_sendqueue = NULL;
1255                         goto doquit;
1256                 }
1257                 if (response != NULL)
1258                         sm_free(response);
1259         }
1260 #endif /* MILTER */
1261
1262         /*
1263         **  Broken proxies and SMTP slammers
1264         **  push data without waiting, catch them
1265         */
1266
1267         if (
1268 #if STARTTLS
1269             !smtps &&
1270 #endif /* STARTTLS */
1271             *greetcode == '2' && nullserver == NULL)
1272         {
1273                 time_t msecs = 0;
1274                 char **pvp;
1275                 char pvpbuf[PSBUFSIZE];
1276
1277                 /* Ask the rulesets how long to pause */
1278                 pvp = NULL;
1279                 r = rscap("greet_pause", peerhostname,
1280                           anynet_ntoa(&RealHostAddr), e,
1281                           &pvp, pvpbuf, sizeof(pvpbuf));
1282                 if (r == EX_OK && pvp != NULL && pvp[0] != NULL &&
1283                     (pvp[0][0] & 0377) == CANONNET && pvp[1] != NULL)
1284                 {
1285                         msecs = strtol(pvp[1], NULL, 10);
1286                 }
1287
1288                 if (msecs > 0)
1289                 {
1290                         int fd;
1291                         fd_set readfds;
1292                         struct timeval timeout;
1293                         struct timeval bp, ep, tp; /* {begin,end,total}pause */
1294                         int eoftest;
1295
1296                         /* pause for a moment */
1297                         timeout.tv_sec = msecs / 1000;
1298                         timeout.tv_usec = (msecs % 1000) * 1000;
1299
1300                         /* Obey RFC 2821: 4.3.5.2: 220 timeout of 5 minutes */
1301                         if (timeout.tv_sec >= 300)
1302                         {
1303                                 timeout.tv_sec = 300;
1304                                 timeout.tv_usec = 0;
1305                         }
1306
1307                         /* check if data is on the socket during the pause */
1308                         fd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
1309                         FD_ZERO(&readfds);
1310                         SM_FD_SET(fd, &readfds);
1311                         gettimeofday(&bp, NULL);
1312                         if (select(fd + 1, FDSET_CAST &readfds,
1313                             NULL, NULL, &timeout) > 0 &&
1314                             FD_ISSET(fd, &readfds) &&
1315                             (eoftest = sm_io_getc(InChannel, SM_TIME_DEFAULT))
1316                             != SM_IO_EOF)
1317                         {
1318                                 sm_io_ungetc(InChannel, SM_TIME_DEFAULT,
1319                                              eoftest);
1320                                 gettimeofday(&ep, NULL);
1321                                 timersub(&ep, &bp, &tp);
1322                                 greetcode = "554";
1323                                 nullserver = "Command rejected";
1324                                 sm_syslog(LOG_INFO, e->e_id,
1325                                           "rejecting commands from %s [%s] due to pre-greeting traffic after %d seconds",
1326                                           peerhostname,
1327                                           anynet_ntoa(&RealHostAddr),
1328                                           (int) tp.tv_sec +
1329                                                 (tp.tv_usec >= 500000 ? 1 : 0)
1330                                          );
1331                         }
1332                 }
1333         }
1334
1335 #if STARTTLS
1336         /* If this an smtps connection, start TLS now */
1337         if (smtps)
1338         {
1339                 Errors = 0;
1340                 goto starttls;
1341         }
1342
1343   greeting:
1344
1345 #endif /* STARTTLS */
1346
1347         /* output the first line, inserting "ESMTP" as second word */
1348         if (*greetcode == '5')
1349                 (void) sm_snprintf(inp, sizeof(inp), "%s %s", hostname,
1350                                    greetmsg);
1351         else
1352                 expand(SmtpGreeting, inp, sizeof(inp), e);
1353
1354         p = strchr(inp, '\n');
1355         if (p != NULL)
1356                 *p++ = '\0';
1357         id = strchr(inp, ' ');
1358         if (id == NULL)
1359                 id = &inp[strlen(inp)];
1360         if (p == NULL)
1361                 (void) sm_snprintf(cmdbuf, sizeof(cmdbuf),
1362                          "%s %%.*s ESMTP%%s", greetcode);
1363         else
1364                 (void) sm_snprintf(cmdbuf, sizeof(cmdbuf),
1365                          "%s-%%.*s ESMTP%%s", greetcode);
1366         message(cmdbuf, (int) (id - inp), inp, id);
1367
1368         /* output remaining lines */
1369         while ((id = p) != NULL && (p = strchr(id, '\n')) != NULL)
1370         {
1371                 *p++ = '\0';
1372                 if (isascii(*id) && isspace(*id))
1373                         id++;
1374                 (void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, "-%s");
1375                 message(cmdbuf, id);
1376         }
1377         if (id != NULL)
1378         {
1379                 if (isascii(*id) && isspace(*id))
1380                         id++;
1381                 (void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, " %s");
1382                 message(cmdbuf, id);
1383         }
1384
1385         protocol = NULL;
1386         sendinghost = macvalue('s', e);
1387
1388         /* If quarantining by a connect/ehlo action, save between messages */
1389         if (e->e_quarmsg == NULL)
1390                 smtp.sm_quarmsg = NULL;
1391         else
1392                 smtp.sm_quarmsg = newstr(e->e_quarmsg);
1393
1394         /* sendinghost's storage must outlive the current envelope */
1395         if (sendinghost != NULL)
1396                 sendinghost = sm_strdup_x(sendinghost);
1397         first = true;
1398         gothello = false;
1399         smtp.sm_gotmail = false;
1400         for (;;)
1401         {
1402             SM_TRY
1403             {
1404                 QuickAbort = false;
1405                 HoldErrs = false;
1406                 SuprErrs = false;
1407                 LogUsrErrs = false;
1408                 OnlyOneError = true;
1409                 e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
1410 #if MILTER
1411                 milter_cmd_fail = false;
1412 #endif /* MILTER */
1413
1414                 /* setup for the read */
1415                 e->e_to = NULL;
1416                 Errors = 0;
1417                 FileName = NULL;
1418                 (void) sm_io_flush(smioout, SM_TIME_DEFAULT);
1419
1420                 /* read the input line */
1421                 SmtpPhase = "server cmd read";
1422                 sm_setproctitle(true, e, "server %s cmd read", CurSmtpClient);
1423
1424                 /* handle errors */
1425                 if (sm_io_error(OutChannel) ||
1426                     (p = sfgets(inp, sizeof(inp), InChannel,
1427                                 TimeOuts.to_nextcommand, SmtpPhase)) == NULL)
1428                 {
1429                         char *d;
1430
1431                         d = macvalue(macid("{daemon_name}"), e);
1432                         if (d == NULL)
1433                                 d = "stdin";
1434                         /* end of file, just die */
1435                         disconnect(1, e);
1436
1437 #if MILTER
1438                         /* close out milter filters */
1439                         milter_quit(e);
1440 #endif /* MILTER */
1441
1442                         message("421 4.4.1 %s Lost input channel from %s",
1443                                 MyHostName, CurSmtpClient);
1444                         if (LogLevel > (smtp.sm_gotmail ? 1 : 19))
1445                                 sm_syslog(LOG_NOTICE, e->e_id,
1446                                           "lost input channel from %s to %s after %s",
1447                                           CurSmtpClient, d,
1448                                           (c == NULL || c->cmd_name == NULL) ? "startup" : c->cmd_name);
1449                         /*
1450                         **  If have not accepted mail (DATA), do not bounce
1451                         **  bad addresses back to sender.
1452                         */
1453
1454                         if (bitset(EF_CLRQUEUE, e->e_flags))
1455                                 e->e_sendqueue = NULL;
1456                         goto doquit;
1457                 }
1458
1459                 /* also used by "proxy" check below */
1460                 inplen = strlen(inp);
1461 #if SASL
1462                 /*
1463                 **  SMTP AUTH requires accepting any length,
1464                 **  at least for challenge/response. However, not imposing
1465                 **  a limit is a bad idea (denial of service).
1466                 */
1467
1468                 if (authenticating != SASL_PROC_AUTH
1469                     && sm_strncasecmp(inp, "AUTH ", 5) != 0
1470                     && inplen > MAXLINE)
1471                 {
1472                         message("421 4.7.0 %s Command too long, possible attack %s",
1473                                 MyHostName, CurSmtpClient);
1474                         sm_syslog(LOG_INFO, e->e_id,
1475                                   "%s: SMTP violation, input too long: %lu",
1476                                   CurSmtpClient, (unsigned long) inplen);
1477                         goto doquit;
1478                 }
1479 #endif /* SASL */
1480
1481                 if (first)
1482                 {
1483                         size_t cmdlen;
1484                         int idx;
1485                         char *http_cmd;
1486                         static char *http_cmds[] = { "GET", "POST",
1487                                                      "CONNECT", "USER", NULL };
1488
1489                         for (idx = 0; (http_cmd = http_cmds[idx]) != NULL;
1490                              idx++)
1491                         {
1492                                 cmdlen = strlen(http_cmd);
1493                                 if (cmdlen < inplen &&
1494                                     sm_strncasecmp(inp, http_cmd, cmdlen) == 0 &&
1495                                     isascii(inp[cmdlen]) && isspace(inp[cmdlen]))
1496                                 {
1497                                         /* Open proxy, drop it */
1498                                         message("421 4.7.0 %s Rejecting open proxy %s",
1499                                                 MyHostName, CurSmtpClient);
1500                                         sm_syslog(LOG_INFO, e->e_id,
1501                                                   "%s: probable open proxy: command=%.40s",
1502                                                   CurSmtpClient, inp);
1503                                         goto doquit;
1504                                 }
1505                         }
1506                         first = false;
1507                 }
1508
1509                 /* clean up end of line */
1510                 fixcrlf(inp, true);
1511
1512 #if PIPELINING
1513 # if _FFR_NO_PIPE
1514                 /*
1515                 **  if there is more input and pipelining is disabled:
1516                 **      delay ... (and maybe discard the input?)
1517                 **  XXX this doesn't really work, at least in tests using
1518                 **  telnet SM_IO_IS_READABLE only returns 1 if there were
1519                 **  more than 2 input lines available.
1520                 */
1521
1522                 if (bitset(SRV_NO_PIPE, features) &&
1523                     sm_io_getinfo(InChannel, SM_IO_IS_READABLE, NULL) > 0)
1524                 {
1525                         if (++np_log < 3)
1526                                 sm_syslog(LOG_INFO, NOQID,
1527                                           "unauthorized PIPELINING, sleeping, relay=%.100s",
1528                                            CurSmtpClient);
1529                         sleep(1);
1530                 }
1531
1532 # endif /* _FFR_NO_PIPE */
1533 #endif /* PIPELINING */
1534
1535 #if SASL
1536                 if (authenticating == SASL_PROC_AUTH)
1537                 {
1538 # if 0
1539                         if (*inp == '\0')
1540                         {
1541                                 authenticating = SASL_NOT_AUTH;
1542                                 message("501 5.5.2 missing input");
1543                                 RESET_SASLCONN;
1544                                 continue;
1545                         }
1546 # endif /* 0 */
1547                         if (*inp == '*' && *(inp + 1) == '\0')
1548                         {
1549                                 authenticating = SASL_NOT_AUTH;
1550
1551                                 /* RFC 2554 4. */
1552                                 message("501 5.0.0 AUTH aborted");
1553                                 RESET_SASLCONN;
1554                                 continue;
1555                         }
1556
1557                         /* could this be shorter? XXX */
1558 # if SASL >= 20000
1559                         in = xalloc(strlen(inp) + 1);
1560                         result = sasl_decode64(inp, strlen(inp), in,
1561                                                strlen(inp), &inlen);
1562 # else /* SASL >= 20000 */
1563                         out = xalloc(strlen(inp));
1564                         result = sasl_decode64(inp, strlen(inp), out, &outlen);
1565 # endif /* SASL >= 20000 */
1566                         if (result != SASL_OK)
1567                         {
1568                                 authenticating = SASL_NOT_AUTH;
1569
1570                                 /* RFC 2554 4. */
1571                                 message("501 5.5.4 cannot decode AUTH parameter %s",
1572                                         inp);
1573 # if SASL >= 20000
1574                                 sm_free(in);
1575 # endif /* SASL >= 20000 */
1576                                 RESET_SASLCONN;
1577                                 continue;
1578                         }
1579
1580 # if SASL >= 20000
1581                         result = sasl_server_step(conn, in, inlen,
1582                                                   &out, &outlen);
1583                         sm_free(in);
1584 # else /* SASL >= 20000 */
1585                         result = sasl_server_step(conn, out, outlen,
1586                                                   &out, &outlen, &errstr);
1587 # endif /* SASL >= 20000 */
1588
1589                         /* get an OK if we're done */
1590                         if (result == SASL_OK)
1591                         {
1592   authenticated:
1593                                 message("235 2.0.0 OK Authenticated");
1594                                 authenticating = SASL_IS_AUTH;
1595                                 macdefine(&BlankEnvelope.e_macro, A_TEMP,
1596                                         macid("{auth_type}"), auth_type);
1597
1598 # if SASL >= 20000
1599                                 user = macvalue(macid("{auth_authen}"), e);
1600
1601                                 /* get security strength (features) */
1602                                 result = sasl_getprop(conn, SASL_SSF,
1603                                                       (const void **) &ssf);
1604 # else /* SASL >= 20000 */
1605                                 result = sasl_getprop(conn, SASL_USERNAME,
1606                                                       (void **)&user);
1607                                 if (result != SASL_OK)
1608                                 {
1609                                         user = "";
1610                                         macdefine(&BlankEnvelope.e_macro,
1611                                                   A_PERM,
1612                                                   macid("{auth_authen}"), NULL);
1613                                 }
1614                                 else
1615                                 {
1616                                         macdefine(&BlankEnvelope.e_macro,
1617                                                   A_TEMP,
1618                                                   macid("{auth_authen}"),
1619                                                   xtextify(user, "<>\")"));
1620                                 }
1621
1622 # if 0
1623                                 /* get realm? */
1624                                 sasl_getprop(conn, SASL_REALM, (void **) &data);
1625 # endif /* 0 */
1626
1627                                 /* get security strength (features) */
1628                                 result = sasl_getprop(conn, SASL_SSF,
1629                                                       (void **) &ssf);
1630 # endif /* SASL >= 20000 */
1631                                 if (result != SASL_OK)
1632                                 {
1633                                         macdefine(&BlankEnvelope.e_macro,
1634                                                   A_PERM,
1635                                                   macid("{auth_ssf}"), "0");
1636                                         ssf = NULL;
1637                                 }
1638                                 else
1639                                 {
1640                                         char pbuf[8];
1641
1642                                         (void) sm_snprintf(pbuf, sizeof(pbuf),
1643                                                            "%u", *ssf);
1644                                         macdefine(&BlankEnvelope.e_macro,
1645                                                   A_TEMP,
1646                                                   macid("{auth_ssf}"), pbuf);
1647                                         if (tTd(95, 8))
1648                                                 sm_dprintf("AUTH auth_ssf: %u\n",
1649                                                            *ssf);
1650                                 }
1651
1652                                 protocol = GET_PROTOCOL();
1653
1654                                 /*
1655                                 **  Only switch to encrypted connection
1656                                 **  if a security layer has been negotiated
1657                                 */
1658
1659                                 if (ssf != NULL && *ssf > 0)
1660                                 {
1661                                         int tmo;
1662
1663                                         /*
1664                                         **  Convert I/O layer to use SASL.
1665                                         **  If the call fails, the connection
1666                                         **  is aborted.
1667                                         */
1668
1669                                         tmo = TimeOuts.to_datablock * 1000;
1670                                         if (sfdcsasl(&InChannel, &OutChannel,
1671                                                      conn, tmo) == 0)
1672                                         {
1673                                                 /* restart dialogue */
1674                                                 n_helo = 0;
1675 # if PIPELINING
1676                                                 (void) sm_io_autoflush(InChannel,
1677                                                                        OutChannel);
1678 # endif /* PIPELINING */
1679                                         }
1680                                         else
1681                                                 syserr("503 5.3.3 SASL TLS failed");
1682                                 }
1683
1684                                 /* NULL pointer ok since it's our function */
1685                                 if (LogLevel > 8)
1686                                         sm_syslog(LOG_INFO, NOQID,
1687                                                   "AUTH=server, relay=%s, authid=%.128s, mech=%.16s, bits=%d",
1688                                                   CurSmtpClient,
1689                                                   shortenstring(user, 128),
1690                                                   auth_type, *ssf);
1691                         }
1692                         else if (result == SASL_CONTINUE)
1693                         {
1694                                 len = ENC64LEN(outlen);
1695                                 out2 = xalloc(len);
1696                                 result = sasl_encode64(out, outlen, out2, len,
1697                                                        &out2len);
1698                                 if (result != SASL_OK)
1699                                 {
1700                                         /* correct code? XXX */
1701                                         /* 454 Temp. authentication failure */
1702                                         message("454 4.5.4 Internal error: unable to encode64");
1703                                         if (LogLevel > 5)
1704                                                 sm_syslog(LOG_WARNING, e->e_id,
1705                                                           "AUTH encode64 error [%d for \"%s\"], relay=%.100s",
1706                                                           result, out,
1707                                                           CurSmtpClient);
1708                                         /* start over? */
1709                                         authenticating = SASL_NOT_AUTH;
1710                                 }
1711                                 else
1712                                 {
1713                                         message("334 %s", out2);
1714                                         if (tTd(95, 2))
1715                                                 sm_dprintf("AUTH continue: msg='%s' len=%u\n",
1716                                                            out2, out2len);
1717                                 }
1718 # if SASL >= 20000
1719                                 sm_free(out2);
1720 # endif /* SASL >= 20000 */
1721                         }
1722                         else
1723                         {
1724                                 /* not SASL_OK or SASL_CONT */
1725                                 message("535 5.7.0 authentication failed");
1726                                 if (LogLevel > 9)
1727                                         sm_syslog(LOG_WARNING, e->e_id,
1728                                                   "AUTH failure (%s): %s (%d) %s, relay=%.100s",
1729                                                   auth_type,
1730                                                   sasl_errstring(result, NULL,
1731                                                                  NULL),
1732                                                   result,
1733 # if SASL >= 20000
1734                                                   sasl_errdetail(conn),
1735 # else /* SASL >= 20000 */
1736                                                   errstr == NULL ? "" : errstr,
1737 # endif /* SASL >= 20000 */
1738                                                   CurSmtpClient);
1739                                 RESET_SASLCONN;
1740                                 authenticating = SASL_NOT_AUTH;
1741                         }
1742                 }
1743                 else
1744                 {
1745                         /* don't want to do any of this if authenticating */
1746 #endif /* SASL */
1747
1748                 /* echo command to transcript */
1749                 if (e->e_xfp != NULL)
1750                         (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
1751                                              "<<< %s\n", inp);
1752
1753                 if (LogLevel > 14)
1754                         sm_syslog(LOG_INFO, e->e_id, "<-- %s", inp);
1755
1756                 /* break off command */
1757                 for (p = inp; isascii(*p) && isspace(*p); p++)
1758                         continue;
1759                 cmd = cmdbuf;
1760                 while (*p != '\0' &&
1761                        !(isascii(*p) && isspace(*p)) &&
1762                        cmd < &cmdbuf[sizeof(cmdbuf) - 2])
1763                         *cmd++ = *p++;
1764                 *cmd = '\0';
1765
1766                 /* throw away leading whitespace */
1767                 SKIP_SPACE(p);
1768
1769                 /* decode command */
1770                 for (c = CmdTab; c->cmd_name != NULL; c++)
1771                 {
1772                         if (sm_strcasecmp(c->cmd_name, cmdbuf) == 0)
1773                                 break;
1774                 }
1775
1776                 /* reset errors */
1777                 errno = 0;
1778
1779                 /* check whether a "non-null" command has been used */
1780                 switch (c->cmd_code)
1781                 {
1782 #if SASL
1783                   case CMDAUTH:
1784                         /* avoid information leak; take first two words? */
1785                         q = "AUTH";
1786                         break;
1787 #endif /* SASL */
1788
1789                   case CMDMAIL:
1790                   case CMDEXPN:
1791                   case CMDVRFY:
1792                   case CMDETRN:
1793                         lognullconnection = false;
1794                         /* FALLTHROUGH */
1795                   default:
1796                         q = inp;
1797                         break;
1798                 }
1799
1800                 if (e->e_id == NULL)
1801                         sm_setproctitle(true, e, "%s: %.80s",
1802                                         CurSmtpClient, q);
1803                 else
1804                         sm_setproctitle(true, e, "%s %s: %.80s",
1805                                         qid_printname(e),
1806                                         CurSmtpClient, q);
1807
1808                 /*
1809                 **  Process command.
1810                 **
1811                 **      If we are running as a null server, return 550
1812                 **      to almost everything.
1813                 */
1814
1815                 if (nullserver != NULL || bitnset(D_ETRNONLY, d_flags))
1816                 {
1817                         switch (c->cmd_code)
1818                         {
1819                           case CMDQUIT:
1820                           case CMDHELO:
1821                           case CMDEHLO:
1822                           case CMDNOOP:
1823                           case CMDRSET:
1824                           case CMDERROR:
1825                                 /* process normally */
1826                                 break;
1827
1828                           case CMDETRN:
1829                                 if (bitnset(D_ETRNONLY, d_flags) &&
1830                                     nullserver == NULL)
1831                                         break;
1832                                 DELAY_CONN("ETRN");
1833                                 /* FALLTHROUGH */
1834
1835                           default:
1836 #if MAXBADCOMMANDS > 0
1837                                 /* theoretically this could overflow */
1838                                 if (nullserver != NULL &&
1839                                     ++n_badcmds > MAXBADCOMMANDS)
1840                                 {
1841                                         message("421 4.7.0 %s Too many bad commands; closing connection",
1842                                                 MyHostName);
1843
1844                                         /* arrange to ignore send list */
1845                                         e->e_sendqueue = NULL;
1846                                         goto doquit;
1847                                 }
1848 #endif /* MAXBADCOMMANDS > 0 */
1849                                 if (nullserver != NULL)
1850                                 {
1851                                         if (ISSMTPREPLY(nullserver))
1852                                                 usrerr(nullserver);
1853                                         else
1854                                                 usrerr("550 5.0.0 %s",
1855                                                        nullserver);
1856                                 }
1857                                 else
1858                                         usrerr("452 4.4.5 Insufficient disk space; try again later");
1859                                 continue;
1860                         }
1861                 }
1862
1863                 switch (c->cmd_code)
1864                 {
1865 #if SASL
1866                   case CMDAUTH: /* sasl */
1867                         DELAY_CONN("AUTH");
1868                         if (!sasl_ok || n_mechs <= 0)
1869                         {
1870                                 message("503 5.3.3 AUTH not available");
1871                                 break;
1872                         }
1873                         if (authenticating == SASL_IS_AUTH)
1874                         {
1875                                 message("503 5.5.0 Already Authenticated");
1876                                 break;
1877                         }
1878                         if (smtp.sm_gotmail)
1879                         {
1880                                 message("503 5.5.0 AUTH not permitted during a mail transaction");
1881                                 break;
1882                         }
1883                         if (tempfail)
1884                         {
1885                                 if (LogLevel > 9)
1886                                         sm_syslog(LOG_INFO, e->e_id,
1887                                                   "SMTP AUTH command (%.100s) from %s tempfailed (due to previous checks)",
1888                                                   p, CurSmtpClient);
1889                                 usrerr("454 4.3.0 Please try again later");
1890                                 break;
1891                         }
1892
1893                         ismore = false;
1894
1895                         /* crude way to avoid crack attempts */
1896                         STOP_IF_ATTACK(checksmtpattack(&n_auth, n_mechs + 1,
1897                                                         true, "AUTH", e));
1898
1899                         /* make sure mechanism (p) is a valid string */
1900                         for (q = p; *q != '\0' && isascii(*q); q++)
1901                         {
1902                                 if (isspace(*q))
1903                                 {
1904                                         *q = '\0';
1905                                         while (*++q != '\0' &&
1906                                                isascii(*q) && isspace(*q))
1907                                                 continue;
1908                                         *(q - 1) = '\0';
1909                                         ismore = (*q != '\0');
1910                                         break;
1911                                 }
1912                         }
1913
1914                         if (*p == '\0')
1915                         {
1916                                 message("501 5.5.2 AUTH mechanism must be specified");
1917                                 break;
1918                         }
1919
1920                         /* check whether mechanism is available */
1921                         if (iteminlist(p, mechlist, " ") == NULL)
1922                         {
1923                                 message("504 5.3.3 AUTH mechanism %.32s not available",
1924                                         p);
1925                                 break;
1926                         }
1927
1928                         /*
1929                         **  RFC 2554 4.
1930                         **  Unlike a zero-length client answer to a
1931                         **  334 reply, a zero- length initial response
1932                         **  is sent as a single equals sign ("=").
1933                         */
1934
1935                         if (ismore && *q == '=' && *(q + 1) == '\0')
1936                         {
1937                                 /* will be free()d, don't use in=""; */
1938                                 in = xalloc(1);
1939                                 *in = '\0';
1940                                 inlen = 0;
1941                         }
1942                         else if (ismore)
1943                         {
1944                                 /* could this be shorter? XXX */
1945 # if SASL >= 20000
1946                                 in = xalloc(strlen(q) + 1);
1947                                 result = sasl_decode64(q, strlen(q), in,
1948                                                        strlen(q), &inlen);
1949 # else /* SASL >= 20000 */
1950                                 in = sm_rpool_malloc(e->e_rpool, strlen(q));
1951                                 result = sasl_decode64(q, strlen(q), in,
1952                                                        &inlen);
1953 # endif /* SASL >= 20000 */
1954                                 if (result != SASL_OK)
1955                                 {
1956                                         message("501 5.5.4 cannot BASE64 decode '%s'",
1957                                                 q);
1958                                         if (LogLevel > 5)
1959                                                 sm_syslog(LOG_WARNING, e->e_id,
1960                                                           "AUTH decode64 error [%d for \"%s\"], relay=%.100s",
1961                                                           result, q,
1962                                                           CurSmtpClient);
1963                                         /* start over? */
1964                                         authenticating = SASL_NOT_AUTH;
1965 # if SASL >= 20000
1966                                         sm_free(in);
1967 # endif /* SASL >= 20000 */
1968                                         in = NULL;
1969                                         inlen = 0;
1970                                         break;
1971                                 }
1972                         }
1973                         else
1974                         {
1975                                 in = NULL;
1976                                 inlen = 0;
1977                         }
1978
1979                         /* see if that auth type exists */
1980 # if SASL >= 20000
1981                         result = sasl_server_start(conn, p, in, inlen,
1982                                                    &out, &outlen);
1983                         if (in != NULL)
1984                                 sm_free(in);
1985 # else /* SASL >= 20000 */
1986                         result = sasl_server_start(conn, p, in, inlen,
1987                                                    &out, &outlen, &errstr);
1988 # endif /* SASL >= 20000 */
1989
1990                         if (result != SASL_OK && result != SASL_CONTINUE)
1991                         {
1992                                 message("535 5.7.0 authentication failed");
1993                                 if (LogLevel > 9)
1994                                         sm_syslog(LOG_ERR, e->e_id,
1995                                                   "AUTH failure (%s): %s (%d) %s, relay=%.100s",
1996                                                   p,
1997                                                   sasl_errstring(result, NULL,
1998                                                                  NULL),
1999                                                   result,
2000 # if SASL >= 20000
2001                                                   sasl_errdetail(conn),
2002 # else /* SASL >= 20000 */
2003                                                   errstr,
2004 # endif /* SASL >= 20000 */
2005                                                   CurSmtpClient);
2006                                 RESET_SASLCONN;
2007                                 break;
2008                         }
2009                         auth_type = newstr(p);
2010
2011                         if (result == SASL_OK)
2012                         {
2013                                 /* ugly, but same code */
2014                                 goto authenticated;
2015                                 /* authenticated by the initial response */
2016                         }
2017
2018                         /* len is at least 2 */
2019                         len = ENC64LEN(outlen);
2020                         out2 = xalloc(len);
2021                         result = sasl_encode64(out, outlen, out2, len,
2022                                                &out2len);
2023
2024                         if (result != SASL_OK)
2025                         {
2026                                 message("454 4.5.4 Temporary authentication failure");
2027                                 if (LogLevel > 5)
2028                                         sm_syslog(LOG_WARNING, e->e_id,
2029                                                   "AUTH encode64 error [%d for \"%s\"]",
2030                                                   result, out);
2031
2032                                 /* start over? */
2033                                 authenticating = SASL_NOT_AUTH;
2034                                 RESET_SASLCONN;
2035                         }
2036                         else
2037                         {
2038                                 message("334 %s", out2);
2039                                 authenticating = SASL_PROC_AUTH;
2040                         }
2041 # if SASL >= 20000
2042                         sm_free(out2);
2043 # endif /* SASL >= 20000 */
2044                         break;
2045 #endif /* SASL */
2046
2047 #if STARTTLS
2048                   case CMDSTLS: /* starttls */
2049                         DELAY_CONN("STARTTLS");
2050                         if (*p != '\0')
2051                         {
2052                                 message("501 5.5.2 Syntax error (no parameters allowed)");
2053                                 break;
2054                         }
2055                         if (!bitset(SRV_OFFER_TLS, features))
2056                         {
2057                                 message("503 5.5.0 TLS not available");
2058                                 break;
2059                         }
2060                         if (!tls_ok_srv)
2061                         {
2062                                 message("454 4.3.3 TLS not available after start");
2063                                 break;
2064                         }
2065                         if (smtp.sm_gotmail)
2066                         {
2067                                 message("503 5.5.0 TLS not permitted during a mail transaction");
2068                                 break;
2069                         }
2070                         if (tempfail)
2071                         {
2072                                 if (LogLevel > 9)
2073                                         sm_syslog(LOG_INFO, e->e_id,
2074                                                   "SMTP STARTTLS command (%.100s) from %s tempfailed (due to previous checks)",
2075                                                   p, CurSmtpClient);
2076                                 usrerr("454 4.7.0 Please try again later");
2077                                 break;
2078                         }
2079   starttls:
2080 # if USE_OPENSSL_ENGINE
2081                         if (!SSLEngineInitialized)
2082                         {
2083                                 if (!SSL_set_engine(NULL))
2084                                 {
2085                                         sm_syslog(LOG_ERR, NOQID,
2086                                                   "STARTTLS=server, SSL_set_engine=failed");
2087                                         tls_ok_srv = false;
2088                                         message("454 4.3.3 TLS not available right now");
2089                                         break;
2090                                 }
2091                                 else
2092                                         SSLEngineInitialized = true;
2093                         }
2094 # endif /* USE_OPENSSL_ENGINE */
2095 # if TLS_NO_RSA
2096                         /*
2097                         **  XXX do we need a temp key ?
2098                         */
2099 # else /* TLS_NO_RSA */
2100 # endif /* TLS_NO_RSA */
2101
2102 # if TLS_VRFY_PER_CTX
2103                         /*
2104                         **  Note: this sets the verification globally
2105                         **  (per SSL_CTX)
2106                         **  it's ok since it applies only to one transaction
2107                         */
2108
2109                         TLS_VERIFY_CLIENT();
2110 # endif /* TLS_VRFY_PER_CTX */
2111
2112                         if (srv_ssl != NULL)
2113                                 SSL_clear(srv_ssl);
2114                         else if ((srv_ssl = SSL_new(srv_ctx)) == NULL)
2115                         {
2116                                 message("454 4.3.3 TLS not available: error generating SSL handle");
2117                                 if (LogLevel > 8)
2118                                         tlslogerr(LOG_WARNING, "server");
2119                                 goto tls_done;
2120                         }
2121
2122                         if (get_tls_se_options(e, srv_ssl, true) != 0)
2123                         {
2124                                 message("454 4.3.3 TLS not available: error setting options");
2125                                 SSL_free(srv_ssl);
2126                                 srv_ssl = NULL;
2127                                 goto tls_done;
2128                         }
2129
2130 # if !TLS_VRFY_PER_CTX
2131                         /*
2132                         **  this could be used if it were possible to set
2133                         **  verification per SSL (connection)
2134                         **  not just per SSL_CTX (global)
2135                         */
2136
2137                         TLS_VERIFY_CLIENT();
2138 # endif /* !TLS_VRFY_PER_CTX */
2139
2140                         rfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
2141                         wfd = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL);
2142
2143                         if (rfd < 0 || wfd < 0 ||
2144                             SSL_set_rfd(srv_ssl, rfd) <= 0 ||
2145                             SSL_set_wfd(srv_ssl, wfd) <= 0)
2146                         {
2147                                 message("454 4.3.3 TLS not available: error set fd");
2148                                 SSL_free(srv_ssl);
2149                                 srv_ssl = NULL;
2150                                 goto tls_done;
2151                         }
2152                         if (!smtps)
2153                                 message("220 2.0.0 Ready to start TLS");
2154 # if PIPELINING
2155                         (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
2156 # endif /* PIPELINING */
2157
2158                         SSL_set_accept_state(srv_ssl);
2159
2160                         tlsstart = curtime();
2161   ssl_retry:
2162                         if ((r = SSL_accept(srv_ssl)) <= 0)
2163                         {
2164                                 int i, ssl_err;
2165                                 int save_errno = errno;
2166
2167                                 ssl_err = SSL_get_error(srv_ssl, r);
2168                                 i = tls_retry(srv_ssl, rfd, wfd, tlsstart,
2169                                                 TimeOuts.to_starttls, ssl_err,
2170                                                 "server");
2171                                 if (i > 0)
2172                                         goto ssl_retry;
2173
2174                                 if (LogLevel > 5)
2175                                 {
2176                                         unsigned long l;
2177                                         const char *sr;
2178
2179                                         l = ERR_peek_error();
2180                                         sr = ERR_reason_error_string(l);
2181                                         sm_syslog(LOG_WARNING, NOQID,
2182                                                   "STARTTLS=server, error: accept failed=%d, reason=%s, SSL_error=%d, errno=%d, retry=%d, relay=%.100s",
2183                                                   r, sr == NULL ? "unknown"
2184                                                                 : sr,
2185                                                   ssl_err, save_errno, i,
2186                                                   CurSmtpClient);
2187                                         if (LogLevel > 9)
2188                                                 tlslogerr(LOG_WARNING, "server");
2189                                 }
2190                                 tls_ok_srv = false;
2191                                 SSL_free(srv_ssl);
2192                                 srv_ssl = NULL;
2193
2194                                 /*
2195                                 **  according to the next draft of
2196                                 **  RFC 2487 the connection should be dropped
2197                                 */
2198
2199                                 /* arrange to ignore any current send list */
2200                                 e->e_sendqueue = NULL;
2201                                 goto doquit;
2202                         }
2203
2204                         /* ignore return code for now, it's in {verify} */
2205                         (void) tls_get_info(srv_ssl, true,
2206                                             CurSmtpClient,
2207                                             &BlankEnvelope.e_macro,
2208                                             bitset(SRV_VRFY_CLT, features));
2209
2210                         /*
2211                         **  call Stls_client to find out whether
2212                         **  to accept the connection from the client
2213                         */
2214
2215                         saveQuickAbort = QuickAbort;
2216                         saveSuprErrs = SuprErrs;
2217                         SuprErrs = true;
2218                         QuickAbort = false;
2219                         if (rscheck("tls_client",
2220                                      macvalue(macid("{verify}"), e),
2221                                      "STARTTLS", e,
2222                                      RSF_RMCOMM|RSF_COUNT,
2223                                      5, NULL, NOQID, NULL, NULL) != EX_OK ||
2224                             Errors > 0)
2225                         {
2226                                 extern char MsgBuf[];
2227
2228                                 if (MsgBuf[0] != '\0' && ISSMTPREPLY(MsgBuf))
2229                                         nullserver = newstr(MsgBuf);
2230                                 else
2231                                         nullserver = "503 5.7.0 Authentication required.";
2232                         }
2233                         QuickAbort = saveQuickAbort;
2234                         SuprErrs = saveSuprErrs;
2235
2236                         tls_ok_srv = false;     /* don't offer STARTTLS again */
2237                         n_helo = 0;
2238 # if SASL
2239                         if (sasl_ok)
2240                         {
2241                                 int cipher_bits;
2242                                 bool verified;
2243                                 char *s, *v, *c;
2244
2245                                 s = macvalue(macid("{cipher_bits}"), e);
2246                                 v = macvalue(macid("{verify}"), e);
2247                                 c = macvalue(macid("{cert_subject}"), e);
2248                                 verified = (v != NULL && strcmp(v, "OK") == 0);
2249                                 if (s != NULL && (cipher_bits = atoi(s)) > 0)
2250                                 {
2251 #  if SASL >= 20000
2252                                         ext_ssf = cipher_bits;
2253                                         auth_id = verified ? c : NULL;
2254                                         sasl_ok = ((sasl_setprop(conn,
2255                                                         SASL_SSF_EXTERNAL,
2256                                                         &ext_ssf) == SASL_OK) &&
2257                                                    (sasl_setprop(conn,
2258                                                         SASL_AUTH_EXTERNAL,
2259                                                         auth_id) == SASL_OK));
2260 #  else /* SASL >= 20000 */
2261                                         ext_ssf.ssf = cipher_bits;
2262                                         ext_ssf.auth_id = verified ? c : NULL;
2263                                         sasl_ok = sasl_setprop(conn,
2264                                                         SASL_SSF_EXTERNAL,
2265                                                         &ext_ssf) == SASL_OK;
2266 #  endif /* SASL >= 20000 */
2267                                         mechlist = NULL;
2268                                         if (sasl_ok)
2269                                                 n_mechs = saslmechs(conn,
2270                                                                     &mechlist);
2271                                 }
2272                         }
2273 # endif /* SASL */
2274
2275                         /* switch to secure connection */
2276                         if (sfdctls(&InChannel, &OutChannel, srv_ssl) == 0)
2277                         {
2278                                 tls_active = true;
2279 # if PIPELINING
2280                                 (void) sm_io_autoflush(InChannel, OutChannel);
2281 # endif /* PIPELINING */
2282                         }
2283                         else
2284                         {
2285                                 /*
2286                                 **  XXX this is an internal error
2287                                 **  how to deal with it?
2288                                 **  we can't generate an error message
2289                                 **  since the other side switched to an
2290                                 **  encrypted layer, but we could not...
2291                                 **  just "hang up"?
2292                                 */
2293
2294                                 nullserver = "454 4.3.3 TLS not available: can't switch to encrypted layer";
2295                                 syserr("STARTTLS: can't switch to encrypted layer");
2296                         }
2297                   tls_done:
2298                         if (smtps)
2299                         {
2300                                 if (tls_active)
2301                                         goto greeting;
2302                                 else
2303                                         goto doquit;
2304                         }
2305                         break;
2306 #endif /* STARTTLS */
2307
2308                   case CMDHELO:         /* hello -- introduce yourself */
2309                   case CMDEHLO:         /* extended hello */
2310                         DELAY_CONN("EHLO");
2311                         if (c->cmd_code == CMDEHLO)
2312                         {
2313                                 protocol = GET_PROTOCOL();
2314                                 SmtpPhase = "server EHLO";
2315                         }
2316                         else
2317                         {
2318                                 protocol = "SMTP";
2319                                 SmtpPhase = "server HELO";
2320                         }
2321
2322                         /* avoid denial-of-service */
2323                         STOP_IF_ATTACK(checksmtpattack(&n_helo, MAXHELOCOMMANDS,
2324                                                         true, "HELO/EHLO", e));
2325
2326 #if 0
2327                         /* RFC2821 4.1.4 allows duplicate HELO/EHLO */
2328                         /* check for duplicate HELO/EHLO per RFC 1651 4.2 */
2329                         if (gothello)
2330                         {
2331                                 usrerr("503 %s Duplicate HELO/EHLO",
2332                                        MyHostName);
2333                                 break;
2334                         }
2335 #endif /* 0 */
2336
2337                         /* check for valid domain name (re 1123 5.2.5) */
2338                         if (*p == '\0' && !AllowBogusHELO)
2339                         {
2340                                 usrerr("501 %s requires domain address",
2341                                         cmdbuf);
2342                                 break;
2343                         }
2344
2345                         /* check for long domain name (hides Received: info) */
2346                         if (strlen(p) > MAXNAME)
2347                         {
2348                                 usrerr("501 Invalid domain name");
2349                                 if (LogLevel > 9)
2350                                         sm_syslog(LOG_INFO, CurEnv->e_id,
2351                                                   "invalid domain name (too long) from %s",
2352                                                   CurSmtpClient);
2353                                 break;
2354                         }
2355
2356                         ok = true;
2357                         for (q = p; *q != '\0'; q++)
2358                         {
2359                                 if (!isascii(*q))
2360                                         break;
2361                                 if (isalnum(*q))
2362                                         continue;
2363                                 if (isspace(*q))
2364                                 {
2365                                         *q = '\0';
2366
2367                                         /* only complain if strict check */
2368                                         ok = AllowBogusHELO;
2369
2370                                         /* allow trailing whitespace */
2371                                         while (!ok && *++q != '\0' &&
2372                                                isspace(*q))
2373                                                 ;
2374                                         if (*q == '\0')
2375                                                 ok = true;
2376                                         break;
2377                                 }
2378                                 if (strchr("[].-_#:", *q) == NULL)
2379                                         break;
2380                         }
2381
2382                         if (*q == '\0' && ok)
2383                         {
2384                                 q = "pleased to meet you";
2385                                 sendinghost = sm_strdup_x(p);
2386                         }
2387                         else if (!AllowBogusHELO)
2388                         {
2389                                 usrerr("501 Invalid domain name");
2390                                 if (LogLevel > 9)
2391                                         sm_syslog(LOG_INFO, CurEnv->e_id,
2392                                                   "invalid domain name (%s) from %.100s",
2393                                                   p, CurSmtpClient);
2394                                 break;
2395                         }
2396                         else
2397                         {
2398                                 q = "accepting invalid domain name";
2399                         }
2400
2401                         if (gothello || smtp.sm_gotmail)
2402                                 CLEAR_STATE(cmdbuf);
2403
2404 #if MILTER
2405                         if (smtp.sm_milterlist && smtp.sm_milterize &&
2406                             !bitset(EF_DISCARD, e->e_flags))
2407                         {
2408                                 char state;
2409                                 char *response;
2410
2411                                 response = milter_helo(p, e, &state);
2412                                 switch (state)
2413                                 {
2414                                   case SMFIR_REJECT:
2415                                         if (MilterLogLevel > 3)
2416                                                 sm_syslog(LOG_INFO, e->e_id,
2417                                                           "Milter: helo=%s, reject=Command rejected",
2418                                                           p);
2419                                         nullserver = "Command rejected";
2420                                         smtp.sm_milterize = false;
2421                                         break;
2422
2423                                   case SMFIR_TEMPFAIL:
2424                                         if (MilterLogLevel > 3)
2425                                                 sm_syslog(LOG_INFO, e->e_id,
2426                                                           "Milter: helo=%s, reject=%s",
2427                                                           p, MSG_TEMPFAIL);
2428                                         tempfail = true;
2429                                         smtp.sm_milterize = false;
2430                                         break;
2431
2432                                   case SMFIR_REPLYCODE:
2433                                         if (MilterLogLevel > 3)
2434                                                 sm_syslog(LOG_INFO, e->e_id,
2435                                                           "Milter: helo=%s, reject=%s",
2436                                                           p, response);
2437                                         if (strncmp(response, "421 ", 4) != 0
2438                                             && strncmp(response, "421-", 4) != 0)
2439                                         {
2440                                                 nullserver = newstr(response);
2441                                                 smtp.sm_milterize = false;
2442                                                 break;
2443                                         }
2444                                         /* FALLTHROUGH */
2445
2446                                   case SMFIR_SHUTDOWN:
2447                                         if (MilterLogLevel > 3 &&
2448                                             response == NULL)
2449                                                 sm_syslog(LOG_INFO, e->e_id,
2450                                                           "Milter: helo=%s, reject=421 4.7.0 %s closing connection",
2451                                                           p, MyHostName);
2452                                         tempfail = true;
2453                                         smtp.sm_milterize = false;
2454                                         if (response != NULL)
2455                                                 usrerr(response);
2456                                         else
2457                                                 message("421 4.7.0 %s closing connection",
2458                                                         MyHostName);
2459                                         /* arrange to ignore send list */
2460                                         e->e_sendqueue = NULL;
2461                                         lognullconnection = false;
2462                                         goto doquit;
2463                                 }
2464                                 if (response != NULL)
2465                                         sm_free(response);
2466
2467                                 /*
2468                                 **  If quarantining by a connect/ehlo action,
2469                                 **  save between messages
2470                                 */
2471
2472                                 if (smtp.sm_quarmsg == NULL &&
2473                                     e->e_quarmsg != NULL)
2474                                         smtp.sm_quarmsg = newstr(e->e_quarmsg);
2475                         }
2476 #endif /* MILTER */
2477                         gothello = true;
2478
2479                         /* print HELO response message */
2480                         if (c->cmd_code != CMDEHLO)
2481                         {
2482                                 message("250 %s Hello %s, %s",
2483                                         MyHostName, CurSmtpClient, q);
2484                                 break;
2485                         }
2486
2487                         message("250-%s Hello %s, %s",
2488                                 MyHostName, CurSmtpClient, q);
2489
2490                         /* offer ENHSC even for nullserver */
2491                         if (nullserver != NULL)
2492                         {
2493                                 message("250 ENHANCEDSTATUSCODES");
2494                                 break;
2495                         }
2496
2497                         /*
2498                         **  print EHLO features list
2499                         **
2500                         **  Note: If you change this list,
2501                         **        remember to update 'helpfile'
2502                         */
2503
2504                         message("250-ENHANCEDSTATUSCODES");
2505 #if PIPELINING
2506                         if (bitset(SRV_OFFER_PIPE, features))
2507                                 message("250-PIPELINING");
2508 #endif /* PIPELINING */
2509                         if (bitset(SRV_OFFER_EXPN, features))
2510                         {
2511                                 message("250-EXPN");
2512                                 if (bitset(SRV_OFFER_VERB, features))
2513                                         message("250-VERB");
2514                         }
2515 #if MIME8TO7
2516                         message("250-8BITMIME");
2517 #endif /* MIME8TO7 */
2518                         if (MaxMessageSize > 0)
2519                                 message("250-SIZE %ld", MaxMessageSize);
2520                         else
2521                                 message("250-SIZE");
2522 #if DSN
2523                         if (SendMIMEErrors && bitset(SRV_OFFER_DSN, features))
2524                                 message("250-DSN");
2525 #endif /* DSN */
2526                         if (bitset(SRV_OFFER_ETRN, features))
2527                                 message("250-ETRN");
2528 #if SASL
2529                         if (sasl_ok && mechlist != NULL && *mechlist != '\0')
2530                                 message("250-AUTH %s", mechlist);
2531 #endif /* SASL */
2532 #if STARTTLS
2533                         if (tls_ok_srv && bitset(SRV_OFFER_TLS, features))
2534                                 message("250-STARTTLS");
2535 #endif /* STARTTLS */
2536                         if (DeliverByMin > 0)
2537                                 message("250-DELIVERBY %ld",
2538                                         (long) DeliverByMin);
2539                         else if (DeliverByMin == 0)
2540                                 message("250-DELIVERBY");
2541
2542                         /* < 0: no deliver-by */
2543
2544                         message("250 HELP");
2545                         break;
2546
2547                   case CMDMAIL:         /* mail -- designate sender */
2548                         SmtpPhase = "server MAIL";
2549                         DELAY_CONN("MAIL");
2550
2551                         /* check for validity of this command */
2552                         if (!gothello && bitset(PRIV_NEEDMAILHELO, PrivacyFlags))
2553                         {
2554                                 usrerr("503 5.0.0 Polite people say HELO first");
2555                                 break;
2556                         }
2557                         if (smtp.sm_gotmail)
2558                         {
2559                                 usrerr("503 5.5.0 Sender already specified");
2560                                 break;
2561                         }
2562 #if SASL
2563                         if (bitset(SRV_REQ_AUTH, features) &&
2564                             authenticating != SASL_IS_AUTH)
2565                         {
2566                                 usrerr("530 5.7.0 Authentication required");
2567                                 break;
2568                         }
2569 #endif /* SASL */
2570
2571                         p = skipword(p, "from");
2572                         if (p == NULL)
2573                                 break;
2574                         if (tempfail)
2575                         {
2576                                 if (LogLevel > 9)
2577                                         sm_syslog(LOG_INFO, e->e_id,
2578                                                   "SMTP MAIL command (%.100s) from %s tempfailed (due to previous checks)",
2579                                                   p, CurSmtpClient);
2580                                 usrerr(MSG_TEMPFAIL);
2581                                 break;
2582                         }
2583
2584                         /* make sure we know who the sending host is */
2585                         if (sendinghost == NULL)
2586                                 sendinghost = peerhostname;
2587
2588
2589 #if SM_HEAP_CHECK
2590                         if (sm_debug_active(&DebugLeakSmtp, 1))
2591                         {
2592                                 sm_heap_newgroup();
2593                                 sm_dprintf("smtp() heap group #%d\n",
2594                                         sm_heap_group());
2595                         }
2596 #endif /* SM_HEAP_CHECK */
2597
2598                         if (Errors > 0)
2599                                 goto undo_no_pm;
2600                         if (!gothello)
2601                         {
2602                                 auth_warning(e, "%s didn't use HELO protocol",
2603                                              CurSmtpClient);
2604                         }
2605 #ifdef PICKY_HELO_CHECK
2606                         if (sm_strcasecmp(sendinghost, peerhostname) != 0 &&
2607                             (sm_strcasecmp(peerhostname, "localhost") != 0 ||
2608                              sm_strcasecmp(sendinghost, MyHostName) != 0))
2609                         {
2610                                 auth_warning(e, "Host %s claimed to be %s",
2611                                              CurSmtpClient, sendinghost);
2612                         }
2613 #endif /* PICKY_HELO_CHECK */
2614
2615                         if (protocol == NULL)
2616                                 protocol = "SMTP";
2617                         macdefine(&e->e_macro, A_PERM, 'r', protocol);
2618                         macdefine(&e->e_macro, A_PERM, 's', sendinghost);
2619
2620                         if (Errors > 0)
2621                                 goto undo_no_pm;
2622                         smtp.sm_nrcpts = 0;
2623                         n_badrcpts = 0;
2624                         macdefine(&e->e_macro, A_PERM, macid("{ntries}"), "0");
2625                         macdefine(&e->e_macro, A_PERM, macid("{nrcpts}"), "0");
2626                         macdefine(&e->e_macro, A_PERM, macid("{nbadrcpts}"),
2627                                 "0");
2628                         e->e_flags |= EF_CLRQUEUE;
2629                         sm_setproctitle(true, e, "%s %s: %.80s",
2630                                         qid_printname(e),
2631                                         CurSmtpClient, inp);
2632
2633                         /* do the processing */
2634                     SM_TRY
2635                     {
2636                         extern char *FullName;
2637
2638                         QuickAbort = true;
2639                         SM_FREE_CLR(FullName);
2640
2641                         /* must parse sender first */
2642                         delimptr = NULL;
2643                         setsender(p, e, &delimptr, ' ', false);
2644                         if (delimptr != NULL && *delimptr != '\0')
2645                                 *delimptr++ = '\0';
2646                         if (Errors > 0)
2647                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2648
2649                         /* Successfully set e_from, allow logging */
2650                         e->e_flags |= EF_LOGSENDER;
2651
2652                         /* put resulting triple from parseaddr() into macros */
2653                         if (e->e_from.q_mailer != NULL)
2654                                  macdefine(&e->e_macro, A_PERM,
2655                                         macid("{mail_mailer}"),
2656                                         e->e_from.q_mailer->m_name);
2657                         else
2658                                  macdefine(&e->e_macro, A_PERM,
2659                                         macid("{mail_mailer}"), NULL);
2660                         if (e->e_from.q_host != NULL)
2661                                 macdefine(&e->e_macro, A_PERM,
2662                                         macid("{mail_host}"),
2663                                         e->e_from.q_host);
2664                         else
2665                                 macdefine(&e->e_macro, A_PERM,
2666                                         macid("{mail_host}"), "localhost");
2667                         if (e->e_from.q_user != NULL)
2668                                 macdefine(&e->e_macro, A_PERM,
2669                                         macid("{mail_addr}"),
2670                                         e->e_from.q_user);
2671                         else
2672                                 macdefine(&e->e_macro, A_PERM,
2673                                         macid("{mail_addr}"), NULL);
2674                         if (Errors > 0)
2675                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2676
2677                         /* check for possible spoofing */
2678                         if (RealUid != 0 && OpMode == MD_SMTP &&
2679                             !wordinclass(RealUserName, 't') &&
2680                             (!bitnset(M_LOCALMAILER,
2681                                       e->e_from.q_mailer->m_flags) ||
2682                              strcmp(e->e_from.q_user, RealUserName) != 0))
2683                         {
2684                                 auth_warning(e, "%s owned process doing -bs",
2685                                         RealUserName);
2686                         }
2687
2688                         /* reset to default value */
2689                         SevenBitInput = SevenBitInput_Saved;
2690
2691                         /* now parse ESMTP arguments */
2692                         e->e_msgsize = 0;
2693                         addr = p;
2694                         parse_esmtp_args(e, NULL, p, delimptr, "MAIL", args,
2695                                         mail_esmtp_args);
2696                         if (Errors > 0)
2697                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2698
2699 #if SASL
2700 # if _FFR_AUTH_PASSING
2701                         /* set the default AUTH= if the sender didn't */
2702                         if (e->e_auth_param == NULL)
2703                         {
2704                                 /* XXX only do this for an MSA? */
2705                                 e->e_auth_param = macvalue(macid("{auth_authen}"),
2706                                                            e);
2707                                 if (e->e_auth_param == NULL)
2708                                         e->e_auth_param = "<>";
2709
2710                                 /*
2711                                 **  XXX should we invoke Strust_auth now?
2712                                 **  authorizing as the client that just
2713                                 **  authenticated, so we'll trust implicitly
2714                                 */
2715                         }
2716 # endif /* _FFR_AUTH_PASSING */
2717 #endif /* SASL */
2718
2719                         /* do config file checking of the sender */
2720                         macdefine(&e->e_macro, A_PERM,
2721                                 macid("{addr_type}"), "e s");
2722 #if _FFR_MAIL_MACRO
2723                         /* make the "real" sender address available */
2724                         macdefine(&e->e_macro, A_TEMP, macid("{mail_from}"),
2725                                   e->e_from.q_paddr);
2726 #endif /* _FFR_MAIL_MACRO */
2727                         if (rscheck("check_mail", addr,
2728                                     NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
2729                                     NULL, e->e_id, NULL, NULL) != EX_OK ||
2730                             Errors > 0)
2731                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2732                         macdefine(&e->e_macro, A_PERM,
2733                                   macid("{addr_type}"), NULL);
2734
2735                         if (MaxMessageSize > 0 &&
2736                             (e->e_msgsize > MaxMessageSize ||
2737                              e->e_msgsize < 0))
2738                         {
2739                                 usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
2740                                         MaxMessageSize);
2741                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2742                         }
2743
2744                         /*
2745                         **  XXX always check whether there is at least one fs
2746                         **  with enough space?
2747                         **  However, this may not help much: the queue group
2748                         **  selection may later on select a FS that hasn't
2749                         **  enough space.
2750                         */
2751
2752                         if ((NumFileSys == 1 || NumQueue == 1) &&
2753                             !enoughdiskspace(e->e_msgsize, e)
2754 #if _FFR_ANY_FREE_FS
2755                             && !filesys_free(e->e_msgsize)
2756 #endif /* _FFR_ANY_FREE_FS */
2757                            )
2758                         {
2759                                 /*
2760                                 **  We perform this test again when the
2761                                 **  queue directory is selected, in collect.
2762                                 */
2763
2764                                 usrerr("452 4.4.5 Insufficient disk space; try again later");
2765                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2766                         }
2767                         if (Errors > 0)
2768                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2769
2770                         LogUsrErrs = true;
2771 #if MILTER
2772                         if (smtp.sm_milterlist && smtp.sm_milterize &&
2773                             !bitset(EF_DISCARD, e->e_flags))
2774                         {
2775                                 char state;
2776                                 char *response;
2777
2778                                 response = milter_envfrom(args, e, &state);
2779                                 MILTER_REPLY("from");
2780                         }
2781 #endif /* MILTER */
2782                         if (Errors > 0)
2783                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
2784
2785                         message("250 2.1.0 Sender ok");
2786                         smtp.sm_gotmail = true;
2787                     }
2788                     SM_EXCEPT(exc, "[!F]*")
2789                     {
2790                         /*
2791                         **  An error occurred while processing a MAIL command.
2792                         **  Jump to the common error handling code.
2793                         */
2794
2795                         sm_exc_free(exc);
2796                         goto undo_no_pm;
2797                     }
2798                     SM_END_TRY
2799                         break;
2800
2801                   undo_no_pm:
2802                         e->e_flags &= ~EF_PM_NOTIFY;
2803                   undo:
2804                         break;
2805
2806                   case CMDRCPT:         /* rcpt -- designate recipient */
2807                         DELAY_CONN("RCPT");
2808                         macdefine(&e->e_macro, A_PERM,
2809                                 macid("{rcpt_mailer}"), NULL);
2810                         macdefine(&e->e_macro, A_PERM,
2811                                 macid("{rcpt_host}"), NULL);
2812                         macdefine(&e->e_macro, A_PERM,
2813                                 macid("{rcpt_addr}"), NULL);
2814 #if MILTER
2815                         (void) memset(&addr_st, '\0', sizeof(addr_st));
2816                         a = NULL;
2817                         milter_rcpt_added = false;
2818                         smtp.sm_e_nrcpts_orig = e->e_nrcpts;
2819 #endif
2820 #if _FFR_BADRCPT_SHUTDOWN
2821                         /*
2822                         **  hack to deal with hack, see below:
2823                         **  n_badrcpts is increased if limit is reached.
2824                         */
2825
2826                         n_badrcpts_adj = (BadRcptThrottle > 0 &&
2827                                           n_badrcpts > BadRcptThrottle &&
2828                                           LogLevel > 5)
2829                                           ? n_badrcpts - 1 : n_badrcpts;
2830                         if (BadRcptShutdown > 0 &&
2831                             n_badrcpts_adj >= BadRcptShutdown &&
2832                             (BadRcptShutdownGood == 0 ||
2833                              smtp.sm_nrcpts == 0 ||
2834                              (n_badrcpts_adj * 100 /
2835                               (smtp.sm_nrcpts + n_badrcpts) >=
2836                               BadRcptShutdownGood)))
2837                         {
2838                                 if (LogLevel > 5)
2839                                         sm_syslog(LOG_INFO, e->e_id,
2840                                                   "%s: Possible SMTP RCPT flood, shutting down connection.",
2841                                                   CurSmtpClient);
2842                                 message("421 4.7.0 %s Too many bad recipients; closing connection",
2843                                 MyHostName);
2844
2845                                 /* arrange to ignore any current send list */
2846                                 e->e_sendqueue = NULL;
2847                                 goto doquit;
2848                         }
2849 #endif /* _FFR_BADRCPT_SHUTDOWN */
2850                         if (BadRcptThrottle > 0 &&
2851                             n_badrcpts >= BadRcptThrottle)
2852                         {
2853                                 if (LogLevel > 5 &&
2854                                     n_badrcpts == BadRcptThrottle)
2855                                 {
2856                                         sm_syslog(LOG_INFO, e->e_id,
2857                                                   "%s: Possible SMTP RCPT flood, throttling.",
2858                                                   CurSmtpClient);
2859
2860                                         /* To avoid duplicated message */
2861                                         n_badrcpts++;
2862                                 }
2863                                 NBADRCPTS;
2864
2865                                 /*
2866                                 **  Don't use exponential backoff for now.
2867                                 **  Some systems will open more connections
2868                                 **  and actually overload the receiver even
2869                                 **  more.
2870                                 */
2871
2872                                 (void) sleep(BadRcptThrottleDelay);
2873                         }
2874                         if (!smtp.sm_gotmail)
2875                         {
2876                                 usrerr("503 5.0.0 Need MAIL before RCPT");
2877                                 break;
2878                         }
2879                         SmtpPhase = "server RCPT";
2880                     SM_TRY
2881                     {
2882                         QuickAbort = true;
2883                         LogUsrErrs = true;
2884
2885                         /* limit flooding of our machine */
2886                         if (MaxRcptPerMsg > 0 &&
2887                             smtp.sm_nrcpts >= MaxRcptPerMsg)
2888                         {
2889                                 /* sleep(1); / * slow down? */
2890                                 usrerr("452 4.5.3 Too many recipients");
2891                                 goto rcpt_done;
2892                         }
2893
2894                         if (!SM_IS_INTERACTIVE(e->e_sendmode)
2895 #if _FFR_DM_ONE
2896                             && (NotFirstDelivery || SM_DM_ONE != e->e_sendmode)
2897 #endif /* _FFR_DM_ONE */
2898                            )
2899                                 e->e_flags |= EF_VRFYONLY;
2900
2901 #if MILTER
2902                         /*
2903                         **  Do not expand recipients at RCPT time (in the call
2904                         **  to recipient()) if a milter can delete or reject
2905                         **  a RCPT.  If they are expanded, it is impossible
2906                         **  for removefromlist() to figure out the expanded
2907                         **  members of the original recipient and mark them
2908                         **  as QS_DONTSEND.
2909                         */
2910
2911                         if (!(smtp.sm_milterlist && smtp.sm_milterize &&
2912                               !bitset(EF_DISCARD, e->e_flags)) &&
2913                             (smtp.sm_milters.mis_flags &
2914                              (MIS_FL_DEL_RCPT|MIS_FL_REJ_RCPT)) != 0)
2915                                 e->e_flags |= EF_VRFYONLY;
2916                         milter_cmd_done = false;
2917                         milter_cmd_safe = false;
2918 #endif /* MILTER */
2919
2920                         p = skipword(p, "to");
2921                         if (p == NULL)
2922                                 goto rcpt_done;
2923                         macdefine(&e->e_macro, A_PERM,
2924                                 macid("{addr_type}"), "e r");
2925                         a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr,
2926                                       e, true);
2927                         macdefine(&e->e_macro, A_PERM,
2928                                 macid("{addr_type}"), NULL);
2929                         if (Errors > 0)
2930                                 goto rcpt_done;
2931                         if (a == NULL)
2932                         {
2933                                 usrerr("501 5.0.0 Missing recipient");
2934                                 goto rcpt_done;
2935                         }
2936
2937                         if (delimptr != NULL && *delimptr != '\0')
2938                                 *delimptr++ = '\0';
2939
2940                         /* put resulting triple from parseaddr() into macros */
2941                         if (a->q_mailer != NULL)
2942                                 macdefine(&e->e_macro, A_PERM,
2943                                         macid("{rcpt_mailer}"),
2944                                         a->q_mailer->m_name);
2945                         else
2946                                 macdefine(&e->e_macro, A_PERM,
2947                                         macid("{rcpt_mailer}"), NULL);
2948                         if (a->q_host != NULL)
2949                                 macdefine(&e->e_macro, A_PERM,
2950                                         macid("{rcpt_host}"), a->q_host);
2951                         else
2952                                 macdefine(&e->e_macro, A_PERM,
2953                                         macid("{rcpt_host}"), "localhost");
2954                         if (a->q_user != NULL)
2955                                 macdefine(&e->e_macro, A_PERM,
2956                                         macid("{rcpt_addr}"), a->q_user);
2957                         else
2958                                 macdefine(&e->e_macro, A_PERM,
2959                                         macid("{rcpt_addr}"), NULL);
2960                         if (Errors > 0)
2961                                 goto rcpt_done;
2962
2963                         /* now parse ESMTP arguments */
2964                         addr = p;
2965                         parse_esmtp_args(e, a, p, delimptr, "RCPT", args,
2966                                         rcpt_esmtp_args);
2967                         if (Errors > 0)
2968                                 goto rcpt_done;
2969
2970 #if MILTER
2971                         /*
2972                         **  rscheck() can trigger an "exception"
2973                         **  in which case the execution continues at
2974                         **  SM_EXCEPT(exc, "[!F]*")
2975                         **  This means milter_cmd_safe is not set
2976                         **  and hence milter is not invoked.
2977                         **  Would it be "safe" to change that, i.e., use
2978                         **  milter_cmd_safe = true;
2979                         **  here so a milter is informed (if requested)
2980                         **  about RCPTs that are rejected by check_rcpt?
2981                         */
2982 # if _FFR_MILTER_CHECK_REJECTIONS_TOO
2983                         milter_cmd_safe = true;
2984 # endif
2985 #endif
2986
2987                         /* do config file checking of the recipient */
2988                         macdefine(&e->e_macro, A_PERM,
2989                                 macid("{addr_type}"), "e r");
2990                         if (rscheck("check_rcpt", addr,
2991                                     NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
2992                                     NULL, e->e_id, p_addr_st, NULL) != EX_OK ||
2993                             Errors > 0)
2994                                 goto rcpt_done;
2995                         macdefine(&e->e_macro, A_PERM,
2996                                 macid("{addr_type}"), NULL);
2997
2998                         /* If discarding, don't bother to verify user */
2999                         if (bitset(EF_DISCARD, e->e_flags))
3000                                 a->q_state = QS_VERIFIED;
3001 #if MILTER
3002                         milter_cmd_safe = true;
3003 #endif
3004
3005                         addbcc(a, e);
3006                         rcptmods(a, e);
3007
3008                         /* save in recipient list after ESMTP mods */
3009                         a = recipient(a, &e->e_sendqueue, 0, e);
3010                         /* may trigger exception... */
3011
3012 #if MILTER
3013                         milter_rcpt_added = true;
3014 #endif
3015
3016                         if(!(Errors > 0) && QS_IS_BADADDR(a->q_state))
3017                         {
3018                                 /* punt -- should keep message in ADDRESS.... */
3019                                 usrerr("550 5.1.1 Addressee unknown");
3020                         }
3021
3022 #if MILTER
3023                 rcpt_done:
3024                         if (smtp.sm_milterlist && smtp.sm_milterize &&
3025                             !bitset(EF_DISCARD, e->e_flags))
3026                         {
3027                                 char state;
3028                                 char *response;
3029
3030                                 /* how to get the error codes? */
3031                                 if (Errors > 0)
3032                                 {
3033                                         macdefine(&e->e_macro, A_PERM,
3034                                                 macid("{rcpt_mailer}"),
3035                                                 "error");
3036                                         if (a != NULL &&
3037                                             a->q_status != NULL &&
3038                                             a->q_rstatus != NULL)
3039                                         {
3040                                                 macdefine(&e->e_macro, A_PERM,
3041                                                         macid("{rcpt_host}"),
3042                                                         a->q_status);
3043                                                 macdefine(&e->e_macro, A_PERM,
3044                                                         macid("{rcpt_addr}"),
3045                                                         a->q_rstatus);
3046                                         }
3047                                         else
3048                                         {
3049                                                 if (addr_st.q_host != NULL)
3050                                                         macdefine(&e->e_macro,
3051                                                                 A_PERM,
3052                                                                 macid("{rcpt_host}"),
3053                                                                 addr_st.q_host);
3054                                                 if (addr_st.q_user != NULL)
3055                                                         macdefine(&e->e_macro,
3056                                                                 A_PERM,
3057                                                                 macid("{rcpt_addr}"),
3058                                                                 addr_st.q_user);
3059                                         }
3060                                 }
3061
3062                                 response = milter_envrcpt(args, e, &state,
3063                                                         Errors > 0);
3064                                 milter_cmd_done = true;
3065                                 MILTER_REPLY("to");
3066                         }
3067 #endif /* MILTER */
3068
3069                         /* no errors during parsing, but might be a duplicate */
3070                         e->e_to = a->q_paddr;
3071                         if (!(Errors > 0) && !QS_IS_BADADDR(a->q_state))
3072                         {
3073                                 if (smtp.sm_nrcpts == 0)
3074                                         initsys(e);
3075                                 message("250 2.1.5 Recipient ok%s",
3076                                         QS_IS_QUEUEUP(a->q_state) ?
3077                                                 " (will queue)" : "");
3078                                 smtp.sm_nrcpts++;
3079                         }
3080
3081                         /* Is this needed? */
3082 #if !MILTER
3083                 rcpt_done:
3084 #endif /* !MILTER */
3085                 
3086                         macdefine(&e->e_macro, A_PERM,
3087                                 macid("{rcpt_mailer}"), NULL);
3088                         macdefine(&e->e_macro, A_PERM,
3089                                 macid("{rcpt_host}"), NULL);
3090                         macdefine(&e->e_macro, A_PERM,
3091                                 macid("{rcpt_addr}"), NULL);
3092                         macdefine(&e->e_macro, A_PERM,
3093                                 macid("{dsn_notify}"), NULL);
3094
3095                         if (Errors > 0)
3096                         {
3097                                 ++n_badrcpts;
3098                                 NBADRCPTS;
3099                         }
3100                     }
3101                     SM_EXCEPT(exc, "[!F]*")
3102                     {
3103                         /* An exception occurred while processing RCPT */
3104                         e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY);
3105                         ++n_badrcpts;
3106                         NBADRCPTS;
3107 #if MILTER
3108                         if (smtp.sm_milterlist && smtp.sm_milterize &&
3109                             !bitset(EF_DISCARD, e->e_flags) &&
3110                             !milter_cmd_done && milter_cmd_safe)
3111                         {
3112                                 char state;
3113                                 char *response;
3114
3115                                 macdefine(&e->e_macro, A_PERM,
3116                                         macid("{rcpt_mailer}"), "error");
3117
3118                                 /* how to get the error codes? */
3119                                 if (addr_st.q_host != NULL)
3120                                         macdefine(&e->e_macro, A_PERM,
3121                                                 macid("{rcpt_host}"),
3122                                                 addr_st.q_host);
3123                                 else if (a != NULL && a->q_status != NULL)
3124                                         macdefine(&e->e_macro, A_PERM,
3125                                                 macid("{rcpt_host}"),
3126                                                 a->q_status);
3127
3128                                 if (addr_st.q_user != NULL)
3129                                         macdefine(&e->e_macro, A_PERM,
3130                                                 macid("{rcpt_addr}"),
3131                                                 addr_st.q_user);
3132                                 else if (a != NULL && a->q_rstatus != NULL)
3133                                         macdefine(&e->e_macro, A_PERM,
3134                                                 macid("{rcpt_addr}"),
3135                                                 a->q_rstatus);
3136
3137                                 response = milter_envrcpt(args, e, &state,
3138                                                         true);
3139                                 milter_cmd_done = true;
3140                                 MILTER_REPLY("to");
3141                                 macdefine(&e->e_macro, A_PERM,
3142                                         macid("{rcpt_mailer}"), NULL);
3143                                 macdefine(&e->e_macro, A_PERM,
3144                                         macid("{rcpt_host}"), NULL);
3145                                 macdefine(&e->e_macro, A_PERM,
3146                                         macid("{rcpt_addr}"), NULL);
3147                         }
3148                         if (smtp.sm_milterlist && smtp.sm_milterize &&
3149                             milter_rcpt_added && milter_cmd_done &&
3150                             milter_cmd_fail)
3151                         {
3152                                 (void) removefromlist(addr, &e->e_sendqueue, e);
3153                                 milter_cmd_fail = false;
3154                                 if (smtp.sm_e_nrcpts_orig < e->e_nrcpts)
3155                                         e->e_nrcpts = smtp.sm_e_nrcpts_orig;
3156                         }
3157 #endif /* MILTER */
3158                     }
3159                     SM_END_TRY
3160                         break;
3161
3162                   case CMDDATA:         /* data -- text of mail */
3163                         DELAY_CONN("DATA");
3164                         if (!smtp_data(&smtp, e))
3165                                 goto doquit;
3166                         break;
3167
3168                   case CMDRSET:         /* rset -- reset state */
3169                         if (tTd(94, 100))
3170                                 message("451 4.0.0 Test failure");
3171                         else
3172                                 message("250 2.0.0 Reset state");
3173                         CLEAR_STATE(cmdbuf);
3174                         break;
3175
3176                   case CMDVRFY:         /* vrfy -- verify address */
3177                   case CMDEXPN:         /* expn -- expand address */
3178                         vrfy = c->cmd_code == CMDVRFY;
3179                         DELAY_CONN(vrfy ? "VRFY" : "EXPN");
3180                         if (tempfail)
3181                         {
3182                                 if (LogLevel > 9)
3183                                         sm_syslog(LOG_INFO, e->e_id,
3184                                                   "SMTP %s command (%.100s) from %s tempfailed (due to previous checks)",
3185                                                   vrfy ? "VRFY" : "EXPN",
3186                                                   p, CurSmtpClient);
3187
3188                                 /* RFC 821 doesn't allow 4xy reply code */
3189                                 usrerr("550 5.7.1 Please try again later");
3190                                 break;
3191                         }
3192                         wt = checksmtpattack(&n_verifies, MAXVRFYCOMMANDS,
3193                                              false, vrfy ? "VRFY" : "EXPN", e);
3194                         STOP_IF_ATTACK(wt);
3195                         previous = curtime();
3196                         if ((vrfy && bitset(PRIV_NOVRFY, PrivacyFlags)) ||
3197                             (!vrfy && !bitset(SRV_OFFER_EXPN, features)))
3198                         {
3199                                 if (vrfy)
3200                                         message("252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
3201                                 else
3202                                         message("502 5.7.0 Sorry, we do not allow this operation");
3203                                 if (LogLevel > 5)
3204                                         sm_syslog(LOG_INFO, e->e_id,
3205                                                   "%s: %s [rejected]",
3206                                                   CurSmtpClient,
3207                                                   shortenstring(inp, MAXSHORTSTR));
3208                                 break;
3209                         }
3210                         else if (!gothello &&
3211                                  bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO,
3212                                                 PrivacyFlags))
3213                         {
3214                                 usrerr("503 5.0.0 I demand that you introduce yourself first");
3215                                 break;
3216                         }
3217                         if (Errors > 0)
3218                                 break;
3219                         if (LogLevel > 5)
3220                                 sm_syslog(LOG_INFO, e->e_id, "%s: %s",
3221                                           CurSmtpClient,
3222                                           shortenstring(inp, MAXSHORTSTR));
3223                     SM_TRY
3224                     {
3225                         QuickAbort = true;
3226                         vrfyqueue = NULL;
3227                         if (vrfy)
3228                                 e->e_flags |= EF_VRFYONLY;
3229                         while (*p != '\0' && isascii(*p) && isspace(*p))
3230                                 p++;
3231                         if (*p == '\0')
3232                         {
3233                                 usrerr("501 5.5.2 Argument required");
3234                         }
3235                         else
3236                         {
3237                                 /* do config file checking of the address */
3238                                 if (rscheck(vrfy ? "check_vrfy" : "check_expn",
3239                                             p, NULL, e, RSF_RMCOMM, 3, NULL,
3240                                             NOQID, NULL, NULL) != EX_OK ||
3241                                     Errors > 0)
3242                                         sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3243                                 (void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
3244                         }
3245                         if (wt > 0)
3246                         {
3247                                 time_t t;
3248
3249                                 t = wt - (curtime() - previous);
3250                                 if (t > 0)
3251                                         (void) sleep(t);
3252                         }
3253                         if (Errors > 0)
3254                                 sm_exc_raisenew_x(&EtypeQuickAbort, 1);
3255                         if (vrfyqueue == NULL)
3256                         {
3257                                 usrerr("554 5.5.2 Nothing to %s", vrfy ? "VRFY" : "EXPN");
3258                         }
3259                         while (vrfyqueue != NULL)
3260                         {
3261                                 if (!QS_IS_UNDELIVERED(vrfyqueue->q_state))
3262                                 {
3263                                         vrfyqueue = vrfyqueue->q_next;
3264                                         continue;
3265                                 }
3266
3267                                 /* see if there is more in the vrfy list */
3268                                 a = vrfyqueue;
3269                                 while ((a = a->q_next) != NULL &&
3270                                        (!QS_IS_UNDELIVERED(a->q_state)))
3271                                         continue;
3272                                 printvrfyaddr(vrfyqueue, a == NULL, vrfy);
3273                                 vrfyqueue = a;
3274                         }
3275                     }
3276                     SM_EXCEPT(exc, "[!F]*")
3277                     {
3278                         /*
3279                         **  An exception occurred while processing VRFY/EXPN
3280                         */
3281
3282                         sm_exc_free(exc);
3283                         goto undo;
3284                     }
3285                     SM_END_TRY
3286                         break;
3287
3288                   case CMDETRN:         /* etrn -- force queue flush */
3289                         DELAY_CONN("ETRN");
3290
3291                         /* Don't leak queue information via debug flags */
3292                         if (!bitset(SRV_OFFER_ETRN, features) || UseMSP ||
3293                             (RealUid != 0 && RealUid != TrustedUid &&
3294                              OpMode == MD_SMTP))
3295                         {
3296                                 /* different message for MSA ? */
3297                                 message("502 5.7.0 Sorry, we do not allow this operation");
3298                                 if (LogLevel > 5)
3299                                         sm_syslog(LOG_INFO, e->e_id,
3300                                                   "%s: %s [rejected]",
3301                                                   CurSmtpClient,
3302                                                   shortenstring(inp, MAXSHORTSTR));
3303                                 break;
3304                         }
3305                         if (tempfail)
3306                         {
3307                                 if (LogLevel > 9)
3308                                         sm_syslog(LOG_INFO, e->e_id,
3309                                                   "SMTP ETRN command (%.100s) from %s tempfailed (due to previous checks)",
3310                                                   p, CurSmtpClient);
3311                                 usrerr(MSG_TEMPFAIL);
3312                                 break;
3313                         }
3314
3315                         if (strlen(p) <= 0)
3316                         {
3317                                 usrerr("500 5.5.2 Parameter required");
3318                                 break;
3319                         }
3320
3321                         /* crude way to avoid denial-of-service attacks */
3322                         STOP_IF_ATTACK(checksmtpattack(&n_etrn, MAXETRNCOMMANDS,
3323                                                         true, "ETRN", e));
3324
3325                         /*
3326                         **  Do config file checking of the parameter.
3327                         **  Even though we have srv_features now, we still
3328                         **  need this ruleset because the former is called
3329                         **  when the connection has been established, while
3330                         **  this ruleset is called when the command is
3331                         **  actually issued and therefore has all information
3332                         **  available to make a decision.
3333                         */
3334
3335                         if (rscheck("check_etrn", p, NULL, e, RSF_RMCOMM, 3,
3336                                     NULL, NOQID, NULL, NULL) != EX_OK ||
3337                             Errors > 0)
3338                                 break;
3339
3340                         if (LogLevel > 5)
3341                                 sm_syslog(LOG_INFO, e->e_id,
3342                                           "%s: ETRN %s", CurSmtpClient,
3343                                           shortenstring(p, MAXSHORTSTR));
3344
3345                         id = p;
3346                         if (*id == '#')
3347                         {
3348                                 int i, qgrp;
3349
3350                                 id++;
3351                                 qgrp = name2qid(id);
3352                                 if (!ISVALIDQGRP(qgrp))
3353                                 {
3354                                         usrerr("459 4.5.4 Queue %s unknown",
3355                                                id);
3356                                         break;
3357                                 }
3358                                 for (i = 0; i < NumQueue && Queue[i] != NULL;
3359                                      i++)
3360                                         Queue[i]->qg_nextrun = (time_t) -1;
3361                                 Queue[qgrp]->qg_nextrun = 0;
3362                                 ok = run_work_group(Queue[qgrp]->qg_wgrp,
3363                                                     RWG_FORK|RWG_FORCE);
3364                                 if (ok && Errors == 0)
3365                                         message("250 2.0.0 Queuing for queue group %s started", id);
3366                                 break;
3367                         }
3368
3369                         if (*id == '@')
3370                                 id++;
3371                         else
3372                                 *--id = '@';
3373
3374                         new = (QUEUE_CHAR *) sm_malloc(sizeof(QUEUE_CHAR));
3375                         if (new == NULL)
3376                         {
3377                                 syserr("500 5.5.0 ETRN out of memory");
3378                                 break;
3379                         }
3380                         new->queue_match = id;
3381                         new->queue_negate = false;
3382                         new->queue_next = NULL;
3383                         QueueLimitRecipient = new;
3384                         ok = runqueue(true, false, false, true);
3385                         sm_free(QueueLimitRecipient); /* XXX */
3386                         QueueLimitRecipient = NULL;
3387                         if (ok && Errors == 0)
3388                                 message("250 2.0.0 Queuing for node %s started", p);
3389                         break;
3390
3391                   case CMDHELP:         /* help -- give user info */
3392                         DELAY_CONN("HELP");
3393                         help(p, e);
3394                         break;
3395
3396                   case CMDNOOP:         /* noop -- do nothing */
3397                         DELAY_CONN("NOOP");
3398                         STOP_IF_ATTACK(checksmtpattack(&n_noop, MaxNOOPCommands,
3399                                                         true, "NOOP", e));
3400                         message("250 2.0.0 OK");
3401                         break;
3402
3403                   case CMDQUIT:         /* quit -- leave mail */
3404                         message("221 2.0.0 %s closing connection", MyHostName);
3405 #if PIPELINING
3406                         (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
3407 #endif /* PIPELINING */
3408
3409                         if (smtp.sm_nrcpts > 0)
3410                                 logundelrcpts(e, "aborted by sender", 9, false);
3411
3412                         /* arrange to ignore any current send list */
3413                         e->e_sendqueue = NULL;
3414
3415 #if STARTTLS
3416                         /* shutdown TLS connection */
3417                         if (tls_active)
3418                         {
3419                                 (void) endtls(srv_ssl, "server");
3420                                 tls_active = false;
3421                         }
3422 #endif /* STARTTLS */
3423 #if SASL
3424                         if (authenticating == SASL_IS_AUTH)
3425                         {
3426                                 sasl_dispose(&conn);
3427                                 authenticating = SASL_NOT_AUTH;
3428                                 /* XXX sasl_done(); this is a child */
3429                         }
3430 #endif /* SASL */
3431
3432 doquit:
3433                         /* avoid future 050 messages */
3434                         disconnect(1, e);
3435
3436 #if MILTER
3437                         /* close out milter filters */
3438                         milter_quit(e);
3439 #endif /* MILTER */
3440
3441                         if (tTd(92, 2))
3442                                 sm_dprintf("QUIT: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",
3443                                         e->e_id,
3444                                         bitset(EF_LOGSENDER, e->e_flags),
3445                                         LogLevel);
3446                         if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
3447                                 logsender(e, NULL);
3448                         e->e_flags &= ~EF_LOGSENDER;
3449
3450                         if (lognullconnection && LogLevel > 5 &&
3451                             nullserver == NULL)
3452                         {
3453                                 char *d;
3454
3455                                 d = macvalue(macid("{daemon_name}"), e);
3456                                 if (d == NULL)
3457                                         d = "stdin";
3458
3459                                 /*
3460                                 **  even though this id is "bogus", it makes
3461                                 **  it simpler to "grep" related events, e.g.,
3462                                 **  timeouts for the same connection.
3463                                 */
3464
3465                                 sm_syslog(LOG_INFO, e->e_id,
3466                                           "%s did not issue MAIL/EXPN/VRFY/ETRN during connection to %s",
3467                                           CurSmtpClient, d);
3468                         }
3469                         if (tTd(93, 100))
3470                         {
3471                                 /* return to handle next connection */
3472                                 return;
3473                         }
3474                         finis(true, true, ExitStat);
3475                         /* NOTREACHED */
3476
3477                         /* just to avoid bogus warning from some compilers */
3478                         exit(EX_OSERR);
3479
3480                   case CMDVERB:         /* set verbose mode */
3481                         DELAY_CONN("VERB");
3482                         if (!bitset(SRV_OFFER_EXPN, features) ||
3483                             !bitset(SRV_OFFER_VERB, features))
3484                         {
3485                                 /* this would give out the same info */
3486                                 message("502 5.7.0 Verbose unavailable");
3487                                 break;
3488                         }
3489                         STOP_IF_ATTACK(checksmtpattack(&n_noop, MaxNOOPCommands,
3490                                                         true, "VERB", e));
3491                         Verbose = 1;
3492                         set_delivery_mode(SM_DELIVER, e);
3493                         message("250 2.0.0 Verbose mode");
3494                         break;
3495
3496 #if SMTPDEBUG
3497                   case CMDDBGQSHOW:     /* show queues */
3498                         (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
3499                                              "Send Queue=");
3500                         printaddr(smioout, e->e_sendqueue, true);
3501                         break;
3502
3503                   case CMDDBGDEBUG:     /* set debug mode */
3504                         tTsetup(tTdvect, sizeof(tTdvect), "0-99.1");
3505                         tTflag(p);
3506                         message("200 2.0.0 Debug set");
3507                         break;
3508
3509 #else /* SMTPDEBUG */
3510                   case CMDDBGQSHOW:     /* show queues */
3511                   case CMDDBGDEBUG:     /* set debug mode */
3512 #endif /* SMTPDEBUG */
3513                   case CMDLOGBOGUS:     /* bogus command */
3514                         DELAY_CONN("Bogus");
3515                         if (LogLevel > 0)
3516                                 sm_syslog(LOG_CRIT, e->e_id,
3517                                           "\"%s\" command from %s (%.100s)",
3518                                           c->cmd_name, CurSmtpClient,
3519                                           anynet_ntoa(&RealHostAddr));
3520                         /* FALLTHROUGH */
3521
3522                   case CMDERROR:        /* unknown command */
3523 #if MAXBADCOMMANDS > 0
3524                         if (++n_badcmds > MAXBADCOMMANDS)
3525                         {
3526   stopattack:
3527                                 message("421 4.7.0 %s Too many bad commands; closing connection",
3528                                         MyHostName);
3529
3530                                 /* arrange to ignore any current send list */
3531                                 e->e_sendqueue = NULL;
3532                                 goto doquit;
3533                         }
3534 #endif /* MAXBADCOMMANDS > 0 */
3535
3536 #if MILTER && SMFI_VERSION > 2
3537                         if (smtp.sm_milterlist && smtp.sm_milterize &&
3538                             !bitset(EF_DISCARD, e->e_flags))
3539                         {
3540                                 char state;
3541                                 char *response;
3542
3543                                 if (MilterLogLevel > 9)
3544                                         sm_syslog(LOG_INFO, e->e_id,
3545                                                 "Sending \"%s\" to Milter", inp);
3546                                 response = milter_unknown(inp, e, &state);
3547                                 MILTER_REPLY("unknown");
3548                                 if (state == SMFIR_REPLYCODE ||
3549                                     state == SMFIR_REJECT ||
3550                                     state == SMFIR_TEMPFAIL ||
3551                                     state == SMFIR_SHUTDOWN)
3552                                 {
3553                                         /* MILTER_REPLY already gave an error */
3554                                         break;
3555                                 }
3556                         }
3557 #endif /* MILTER && SMFI_VERSION > 2 */
3558
3559                         usrerr("500 5.5.1 Command unrecognized: \"%s\"",
3560                                shortenstring(inp, MAXSHORTSTR));
3561                         break;
3562
3563                   case CMDUNIMPL:
3564                         DELAY_CONN("Unimpl");
3565                         usrerr("502 5.5.1 Command not implemented: \"%s\"",
3566                                shortenstring(inp, MAXSHORTSTR));
3567                         break;
3568
3569                   default:
3570                         DELAY_CONN("default");
3571                         errno = 0;
3572                         syserr("500 5.5.0 smtp: unknown code %d", c->cmd_code);
3573                         break;
3574                 }
3575 #if SASL
3576                 }
3577 #endif /* SASL */
3578             }
3579             SM_EXCEPT(exc, "[!F]*")
3580             {
3581                 /*
3582                 **  The only possible exception is "E:mta.quickabort".
3583                 **  There is nothing to do except fall through and loop.
3584                 */
3585             }
3586             SM_END_TRY
3587         }
3588 }
3589 /*
3590 **  SMTP_DATA -- implement the SMTP DATA command.
3591 **
3592 **      Parameters:
3593 **              smtp -- status of SMTP connection.
3594 **              e -- envelope.
3595 **
3596 **      Returns:
3597 **              true iff SMTP session can continue.
3598 **
3599 **      Side Effects:
3600 **              possibly sends message.
3601 */
3602
3603 static bool
3604 smtp_data(smtp, e)
3605         SMTP_T *smtp;
3606         ENVELOPE *e;
3607 {
3608 #if MILTER
3609         bool milteraccept;
3610 #endif /* MILTER */
3611         bool aborting;
3612         bool doublequeue;
3613         bool rv = true;
3614         ADDRESS *a;
3615         ENVELOPE *ee;
3616         char *id;
3617         char *oldid;
3618         unsigned int features;
3619         char buf[32];
3620
3621         SmtpPhase = "server DATA";
3622         if (!smtp->sm_gotmail)
3623         {
3624                 usrerr("503 5.0.0 Need MAIL command");
3625                 return true;
3626         }
3627         else if (smtp->sm_nrcpts <= 0)
3628         {
3629                 usrerr("503 5.0.0 Need RCPT (recipient)");
3630                 return true;
3631         }
3632         (void) sm_snprintf(buf, sizeof(buf), "%u", smtp->sm_nrcpts);
3633         if (rscheck("check_data", buf, NULL, e,
3634                     RSF_RMCOMM|RSF_UNSTRUCTURED|RSF_COUNT, 3, NULL,
3635                     e->e_id, NULL, NULL) != EX_OK)
3636                 return true;
3637
3638 #if MILTER && SMFI_VERSION > 3
3639         if (smtp->sm_milterlist && smtp->sm_milterize &&
3640             !bitset(EF_DISCARD, e->e_flags))
3641         {
3642                 char state;
3643                 char *response;
3644                 int savelogusrerrs = LogUsrErrs;
3645
3646                 response = milter_data_cmd(e, &state);
3647                 switch (state)
3648                 {
3649                   case SMFIR_REPLYCODE:
3650                         if (MilterLogLevel > 3)
3651                         {
3652                                 sm_syslog(LOG_INFO, e->e_id,
3653                                           "Milter: cmd=data, reject=%s",
3654                                           response);
3655                                 LogUsrErrs = false;
3656                         }
3657 #if _FFR_MILTER_ENHSC
3658                         if (ISSMTPCODE(response))
3659                                 (void) extenhsc(response + 4, ' ', e->e_enhsc);
3660 #endif /* _FFR_MILTER_ENHSC */
3661
3662                         usrerr(response);
3663                         if (strncmp(response, "421 ", 4) == 0
3664                             || strncmp(response, "421-", 4) == 0)
3665                         {
3666                                 e->e_sendqueue = NULL;
3667                                 return false;
3668                         }
3669                         return true;
3670
3671                   case SMFIR_REJECT:
3672                         if (MilterLogLevel > 3)
3673                         {
3674                                 sm_syslog(LOG_INFO, e->e_id,
3675                                           "Milter: cmd=data, reject=550 5.7.1 Command rejected");
3676                                 LogUsrErrs = false;
3677                         }
3678 #if _FFR_MILTER_ENHSC
3679                         (void) sm_strlcpy(e->e_enhsc, "5.7.1",
3680                                          sizeof(e->e_enhsc));
3681 #endif /* _FFR_MILTER_ENHSC */
3682                         usrerr("550 5.7.1 Command rejected");
3683                         return true;
3684
3685                   case SMFIR_DISCARD:
3686                         if (MilterLogLevel > 3)
3687                                 sm_syslog(LOG_INFO, e->e_id,
3688                                           "Milter: cmd=data, discard");
3689                         e->e_flags |= EF_DISCARD;
3690                         break;
3691
3692                   case SMFIR_TEMPFAIL:
3693                         if (MilterLogLevel > 3)
3694                         {
3695                                 sm_syslog(LOG_INFO, e->e_id,
3696                                           "Milter: cmd=data, reject=%s",
3697                                           MSG_TEMPFAIL);
3698                                 LogUsrErrs = false;
3699                         }
3700 #if _FFR_MILTER_ENHSC
3701                         (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc);
3702 #endif /* _FFR_MILTER_ENHSC */
3703                         usrerr(MSG_TEMPFAIL);
3704                         return true;
3705
3706                   case SMFIR_SHUTDOWN:
3707                         if (MilterLogLevel > 3)
3708                         {
3709                                 sm_syslog(LOG_INFO, e->e_id,
3710                                           "Milter: cmd=data, reject=421 4.7.0 %s closing connection",
3711                                           MyHostName);
3712                                 LogUsrErrs = false;
3713                         }
3714                         usrerr("421 4.7.0 %s closing connection", MyHostName);
3715                         e->e_sendqueue = NULL;
3716                         return false;
3717                 }
3718                 LogUsrErrs = savelogusrerrs;
3719                 if (response != NULL)
3720                         sm_free(response); /* XXX */
3721         }
3722 #endif /* MILTER && SMFI_VERSION > 3 */
3723
3724         /* put back discard bit */
3725         if (smtp->sm_discard)
3726                 e->e_flags |= EF_DISCARD;
3727
3728         /* check to see if we need to re-expand aliases */
3729         /* also reset QS_BADADDR on already-diagnosted addrs */
3730         doublequeue = false;
3731         for (a = e->e_sendqueue; a != NULL; a = a->q_next)
3732         {
3733                 if (QS_IS_VERIFIED(a->q_state) &&
3734                     !bitset(EF_DISCARD, e->e_flags))
3735                 {
3736                         /* need to re-expand aliases */
3737                         doublequeue = true;
3738                 }
3739                 if (QS_IS_BADADDR(a->q_state))
3740                 {
3741                         /* make this "go away" */
3742                         a->q_state = QS_DONTSEND;
3743                 }
3744         }
3745
3746         /* collect the text of the message */
3747         SmtpPhase = "collect";
3748         buffer_errors();
3749
3750         collect(InChannel, true, NULL, e, true);
3751
3752         /* redefine message size */
3753         (void) sm_snprintf(buf, sizeof(buf), "%ld", PRT_NONNEGL(e->e_msgsize));
3754         macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
3755
3756         /* rscheck() will set Errors or EF_DISCARD if it trips */
3757         (void) rscheck("check_eom", buf, NULL, e, RSF_UNSTRUCTURED|RSF_COUNT,
3758                        3, NULL, e->e_id, NULL, NULL);
3759
3760 #if MILTER
3761         milteraccept = true;
3762         if (smtp->sm_milterlist && smtp->sm_milterize &&
3763             Errors <= 0 &&
3764             !bitset(EF_DISCARD, e->e_flags))
3765         {
3766                 char state;
3767                 char *response;
3768
3769                 response = milter_data(e, &state);
3770                 switch (state)
3771                 {
3772                   case SMFIR_REPLYCODE:
3773                         if (MilterLogLevel > 3)
3774                                 sm_syslog(LOG_INFO, e->e_id,
3775                                           "Milter: data, reject=%s",
3776                                           response);
3777                         milteraccept = false;
3778 #if _FFR_MILTER_ENHSC
3779                         if (ISSMTPCODE(response))
3780                                 (void) extenhsc(response + 4, ' ', e->e_enhsc);
3781 #endif /* _FFR_MILTER_ENHSC */
3782                         usrerr(response);
3783                         if (strncmp(response, "421 ", 4) == 0
3784                             || strncmp(response, "421-", 4) == 0)
3785                                 rv = false;
3786                         break;
3787
3788                   case SMFIR_REJECT:
3789                         milteraccept = false;
3790                         if (MilterLogLevel > 3)
3791                                 sm_syslog(LOG_INFO, e->e_id,
3792                                           "Milter: data, reject=554 5.7.1 Command rejected");
3793                         usrerr("554 5.7.1 Command rejected");
3794                         break;
3795
3796                   case SMFIR_DISCARD:
3797                         if (MilterLogLevel > 3)
3798                                 sm_syslog(LOG_INFO, e->e_id,
3799                                           "Milter: data, discard");
3800                         milteraccept = false;
3801                         e->e_flags |= EF_DISCARD;
3802                         break;
3803
3804                   case SMFIR_TEMPFAIL:
3805                         if (MilterLogLevel > 3)
3806                                 sm_syslog(LOG_INFO, e->e_id,
3807                                           "Milter: data, reject=%s",
3808                                           MSG_TEMPFAIL);
3809                         milteraccept = false;
3810 #if _FFR_MILTER_ENHSC
3811                         (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc);
3812 #endif /* _FFR_MILTER_ENHSC */
3813                         usrerr(MSG_TEMPFAIL);
3814                         break;
3815
3816                   case SMFIR_SHUTDOWN:
3817                         if (MilterLogLevel > 3)
3818                                 sm_syslog(LOG_INFO, e->e_id,
3819                                           "Milter: data, reject=421 4.7.0 %s closing connection",
3820                                           MyHostName);
3821                         milteraccept = false;
3822                         usrerr("421 4.7.0 %s closing connection", MyHostName);
3823                         rv = false;
3824                         break;
3825                 }
3826                 if (response != NULL)
3827                         sm_free(response);
3828         }
3829
3830         /* Milter may have changed message size */
3831         (void) sm_snprintf(buf, sizeof(buf), "%ld", PRT_NONNEGL(e->e_msgsize));
3832         macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
3833
3834         /* abort message filters that didn't get the body & log msg is OK */
3835         if (smtp->sm_milterlist && smtp->sm_milterize)
3836         {
3837                 milter_abort(e);
3838                 if (milteraccept && MilterLogLevel > 9)
3839                         sm_syslog(LOG_INFO, e->e_id, "Milter accept: message");
3840         }
3841
3842         /*
3843         **  If SuperSafe is SAFE_REALLY_POSTMILTER, and we don't have milter or
3844         **  milter accepted message, sync it now
3845         **
3846         **  XXX This is almost a copy of the code in collect(): put it into
3847         **      a function that is called from both places?
3848         */
3849
3850         if (milteraccept && SuperSafe == SAFE_REALLY_POSTMILTER)
3851         {
3852                 int afd;
3853                 SM_FILE_T *volatile df;
3854                 char *dfname;
3855
3856                 df = e->e_dfp;
3857                 dfname = queuename(e, DATAFL_LETTER);
3858                 if (sm_io_setinfo(df, SM_BF_COMMIT, NULL) < 0
3859                     && errno != EINVAL)
3860                 {
3861                         int save_errno;
3862
3863                         save_errno = errno;
3864                         if (save_errno == EEXIST)
3865                         {
3866                                 struct stat st;
3867                                 int dfd;
3868
3869                                 if (stat(dfname, &st) < 0)
3870                                         st.st_size = -1;
3871                                 errno = EEXIST;
3872                                 syserr("@collect: bfcommit(%s): already on disk, size=%ld",
3873                                        dfname, (long) st.st_size);
3874                                 dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL);
3875                                 if (dfd >= 0)
3876                                         dumpfd(dfd, true, true);
3877                         }
3878                         errno = save_errno;
3879                         dferror(df, "bfcommit", e);
3880                         flush_errors(true);
3881                         finis(save_errno != EEXIST, true, ExitStat);
3882                 }
3883                 else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) < 0)
3884                 {
3885                         dferror(df, "sm_io_getinfo", e);
3886                         flush_errors(true);
3887                         finis(true, true, ExitStat);
3888                         /* NOTREACHED */
3889                 }
3890                 else if (fsync(afd) < 0)
3891                 {
3892                         dferror(df, "fsync", e);
3893                         flush_errors(true);
3894                         finis(true, true, ExitStat);
3895                         /* NOTREACHED */
3896                 }
3897                 else if (sm_io_close(df, SM_TIME_DEFAULT) < 0)
3898                 {
3899                         dferror(df, "sm_io_close", e);
3900                         flush_errors(true);
3901                         finis(true, true, ExitStat);
3902                         /* NOTREACHED */
3903                 }
3904
3905                 /* Now reopen the df file */
3906                 e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
3907                                         SM_IO_RDONLY, NULL);
3908                 if (e->e_dfp == NULL)
3909                 {
3910                         /* we haven't acked receipt yet, so just chuck this */
3911                         syserr("@Cannot reopen %s", dfname);
3912                         finis(true, true, ExitStat);
3913                         /* NOTREACHED */
3914                 }
3915         }
3916 #endif /* MILTER */
3917
3918         /* Check if quarantining stats should be updated */
3919         if (e->e_quarmsg != NULL)
3920                 markstats(e, NULL, STATS_QUARANTINE);
3921
3922         /*
3923         **  If a header/body check (header checks or milter)
3924         **  set EF_DISCARD, don't queueup the message --
3925         **  that would lose the EF_DISCARD bit and deliver
3926         **  the message.
3927         */
3928
3929         if (bitset(EF_DISCARD, e->e_flags))
3930                 doublequeue = false;
3931
3932         aborting = Errors > 0;
3933         if (!(aborting || bitset(EF_DISCARD, e->e_flags)) &&
3934             (QueueMode == QM_QUARANTINE || e->e_quarmsg == NULL) &&
3935             !split_by_recipient(e))
3936                 aborting = bitset(EF_FATALERRS, e->e_flags);
3937
3938         if (aborting)
3939         {
3940                 ADDRESS *q;
3941
3942                 /* Log who the mail would have gone to */
3943                 logundelrcpts(e, e->e_message, 8, false);
3944
3945                 /*
3946                 **  If something above refused the message, we still haven't
3947                 **  accepted responsibility for it.  Don't send DSNs.
3948                 */
3949
3950                 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
3951                         q->q_flags &= ~Q_PINGFLAGS;
3952
3953                 flush_errors(true);
3954                 buffer_errors();
3955                 goto abortmessage;
3956         }
3957
3958         /* from now on, we have to operate silently */
3959         buffer_errors();
3960
3961 #if 0
3962         /*
3963         **  Clear message, it may contain an error from the SMTP dialogue.
3964         **  This error must not show up in the queue.
3965         **      Some error message should show up, e.g., alias database
3966         **      not available, but others shouldn't, e.g., from check_rcpt.
3967         */
3968
3969         e->e_message = NULL;
3970 #endif /* 0 */
3971
3972         /*
3973         **  Arrange to send to everyone.
3974         **      If sending to multiple people, mail back
3975         **              errors rather than reporting directly.
3976         **      In any case, don't mail back errors for
3977         **              anything that has happened up to
3978         **              now (the other end will do this).
3979         **      Truncate our transcript -- the mail has gotten
3980         **              to us successfully, and if we have
3981         **              to mail this back, it will be easier
3982         **              on the reader.
3983         **      Then send to everyone.
3984         **      Finally give a reply code.  If an error has
3985         **              already been given, don't mail a
3986         **              message back.
3987         **      We goose error returns by clearing error bit.
3988         */
3989
3990         SmtpPhase = "delivery";
3991         (void) sm_io_setinfo(e->e_xfp, SM_BF_TRUNCATE, NULL);
3992         id = e->e_id;
3993
3994 #if NAMED_BIND
3995         _res.retry = TimeOuts.res_retry[RES_TO_FIRST];
3996         _res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
3997 #endif /* NAMED_BIND */
3998
3999 #if _FFR_PROXY
4000         if (SM_PROXY_REQ == e->e_sendmode)
4001         {
4002                 /* is proxy mode possible? */
4003                 if (e->e_sibling == NULL && e->e_nrcpts == 1
4004                     && smtp->sm_nrcpts == 1
4005                     && (a = e->e_sendqueue) != NULL && a->q_next == NULL)
4006                 {
4007                         a->q_flags &= ~(QPINGONFAILURE|QPINGONSUCCESS|
4008                                         QPINGONDELAY);
4009                         e->e_errormode = EM_QUIET;
4010                         e->e_sendmode = SM_PROXY;
4011                 }
4012                 else
4013                 {
4014                         if (tTd(87, 2))
4015                         {
4016                                 a = e->e_sendqueue;
4017                                 sm_dprintf("srv: mode=%c, e=%p, sibling=%p, nrcpts=%d, sm_nrcpts=%d, sendqueue=%p, next=%p\n",
4018                                 e->e_sendmode, e, e->e_sibling, e->e_nrcpts,
4019                                 smtp->sm_nrcpts, a,
4020                                 (a == NULL) ? (void *)0 : a->q_next);
4021                         }
4022
4023                         /* switch to interactive mode */
4024                         e->e_sendmode = SM_DELIVER;
4025                         if (LogLevel > 9)
4026                                 sm_syslog(LOG_DEBUG, e->e_id,
4027                                           "proxy mode requested but not possible");
4028                 }
4029         }
4030 #endif /* _FFR_PROXY */
4031
4032         for (ee = e; ee != NULL; ee = ee->e_sibling)
4033         {
4034                 /* make sure we actually do delivery */
4035                 ee->e_flags &= ~EF_CLRQUEUE;
4036
4037                 /* from now on, operate silently */
4038                 ee->e_errormode = EM_MAIL;
4039
4040                 if (doublequeue)
4041                 {
4042                         /* make sure it is in the queue */
4043                         queueup(ee, false, true);
4044                 }
4045                 else
4046                 {
4047                         int mode;
4048
4049                         /* send to all recipients */
4050                         mode = SM_DEFAULT;
4051 #if _FFR_DM_ONE
4052                         if (SM_DM_ONE == e->e_sendmode)
4053                         {
4054                                 if (NotFirstDelivery)
4055                                 {
4056                                         mode = SM_QUEUE;
4057                                         e->e_sendmode = SM_QUEUE;
4058                                 }
4059                                 else
4060                                 {
4061                                         mode = SM_FORK;
4062                                         NotFirstDelivery = true;
4063                                 }
4064                         }
4065 #endif /* _FFR_DM_ONE */
4066                         sendall(ee, mode);
4067                 }
4068                 ee->e_to = NULL;
4069         }
4070
4071         /* put back id for SMTP logging in putoutmsg() */
4072         oldid = CurEnv->e_id;
4073         CurEnv->e_id = id;
4074
4075 #if _FFR_PROXY
4076         a = e->e_sendqueue;
4077         if (tTd(87, 1))
4078         {
4079                 sm_dprintf("srv: mode=%c, e=%p, sibling=%p, nrcpts=%d, msg=%s, sendqueue=%p, next=%p, state=%d, SmtpError=%s, rcode=%d, renhsc=%s, text=%s\n",
4080                 e->e_sendmode, e, e->e_sibling, e->e_nrcpts, e->e_message, a,
4081                 (a == NULL) ? (void *)0 : a->q_next,
4082                 (a == NULL) ? -1 : a->q_state, SmtpError, e->e_rcode,
4083                 e->e_renhsc, e->e_text);
4084         }
4085
4086         if (SM_PROXY == e->e_sendmode && a->q_state != QS_SENT &&
4087             a->q_state != QS_VERIFIED) /* discarded! */
4088         {
4089                 char *m, *errtext;
4090                 char replycode[4];
4091                 char enhsc[10];
4092                 int offset;
4093
4094 #define NN_MSG(e)       (((e)->e_message != NULL) ? (e)->e_message : "")
4095                 m = e->e_message;
4096 #define SM_MSG_DEFERRED "Deferred: "
4097                 if (m != NULL && strncmp(SM_MSG_DEFERRED, m,
4098                                          sizeof(SM_MSG_DEFERRED) - 1) == 0)
4099                         m += sizeof(SM_MSG_DEFERRED) - 1;
4100                 offset = extsc(m, ' ', replycode, enhsc);
4101
4102                 if (tTd(87, 2))
4103                 {
4104                         sm_dprintf("srv: SmtpError=%s, rcode=%d, renhsc=%s, replycode=%s, enhsc=%s, offset=%d\n",
4105                                 SmtpError, e->e_rcode, e->e_renhsc,
4106                                 replycode, enhsc, offset);
4107                 }
4108
4109 #define DIG2CHAR(d)     ((d) + '0')
4110                 if (e->e_rcode != 0 && (replycode[0] == '\0' ||
4111                     replycode[0] == DIG2CHAR(REPLYTYPE(e->e_rcode))))
4112                 {
4113                         replycode[0] = DIG2CHAR(REPLYTYPE(e->e_rcode));
4114                         replycode[1] = DIG2CHAR(REPLYCLASS(e->e_rcode));
4115                         replycode[2] = DIG2CHAR(REPLYMINOR(e->e_rcode));
4116                         replycode[3] = '\0';
4117                         if (e->e_renhsc[0] == replycode[0])
4118                                 sm_strlcpy(enhsc, e->e_renhsc, sizeof(enhsc));
4119                         if (offset < 0)
4120                                 offset = 0;
4121                 }
4122                 if (e->e_text != NULL)
4123                 {
4124                         (void) strreplnonprt(e->e_text, '_');
4125                         errtext = e->e_text;
4126                 }
4127                 else
4128                         errtext = m + offset;
4129
4130                 if (replycode[0] != '\0' && enhsc[0] != '\0')
4131                         emessage(replycode, enhsc, "%s", errtext);
4132                 else if (replycode[0] != '\0')
4133                         emessage(replycode, smtptodsn(atoi(replycode)),
4134                                  "%s", errtext);
4135                 else if (QS_IS_TEMPFAIL(a->q_state))
4136                 {
4137                         if (m != NULL)
4138                                 message("450 4.5.1 %s", m);
4139                         else
4140                                 message("450 4.5.1 Temporary error");
4141                 }
4142                 else
4143                 {
4144                         if (m != NULL)
4145                                 message("550 5.5.1 %s", m);
4146                         else
4147                                 message("550 5.0.0 Permanent error");
4148                 }
4149         }
4150         else
4151         {
4152 #endif /* _FFR_PROXY */
4153                 /* issue success message */
4154 #if _FFR_MSG_ACCEPT
4155                 if (MessageAccept != NULL && *MessageAccept != '\0')
4156                 {
4157                         char msg[MAXLINE];
4158
4159                         expand(MessageAccept, msg, sizeof(msg), e);
4160                         message("250 2.0.0 %s", msg);
4161                 }
4162                 else
4163 #endif /* _FFR_MSG_ACCEPT */
4164                 message("250 2.0.0 %s Message accepted for delivery", id);
4165 #if _FFR_PROXY
4166         }
4167 #endif /* _FFR_PROXY */
4168         CurEnv->e_id = oldid;
4169
4170         /* if we just queued, poke it */
4171         if (doublequeue)
4172         {
4173                 bool anything_to_send = false;
4174
4175                 sm_getla();
4176                 for (ee = e; ee != NULL; ee = ee->e_sibling)
4177                 {
4178                         if (WILL_BE_QUEUED(ee->e_sendmode))
4179                                 continue;
4180                         if (shouldqueue(ee->e_msgpriority, ee->e_ctime))
4181                         {
4182                                 ee->e_sendmode = SM_QUEUE;
4183                                 continue;
4184                         }
4185                         else if (QueueMode != QM_QUARANTINE &&
4186                                  ee->e_quarmsg != NULL)
4187                         {
4188                                 ee->e_sendmode = SM_QUEUE;
4189                                 continue;
4190                         }
4191                         anything_to_send = true;
4192
4193                         /* close all the queue files */
4194                         closexscript(ee);
4195                         if (ee->e_dfp != NULL)
4196                         {
4197                                 (void) sm_io_close(ee->e_dfp, SM_TIME_DEFAULT);
4198                                 ee->e_dfp = NULL;
4199                         }
4200                         unlockqueue(ee);
4201                 }
4202                 if (anything_to_send)
4203                 {
4204 #if PIPELINING
4205                         /*
4206                         **  XXX if we don't do this, we get 250 twice
4207                         **      because it is also flushed in the child.
4208                         */
4209
4210                         (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
4211 #endif /* PIPELINING */
4212                         (void) doworklist(e, true, true);
4213                 }
4214         }
4215
4216   abortmessage:
4217         if (tTd(92, 2))
4218                 sm_dprintf("abortmessage: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",
4219                         e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel);
4220         if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
4221                 logsender(e, NULL);
4222         e->e_flags &= ~EF_LOGSENDER;
4223
4224         /* clean up a bit */
4225         smtp->sm_gotmail = false;
4226
4227         /*
4228         **  Call dropenvelope if and only if the envelope is *not*
4229         **  being processed by the child process forked by doworklist().
4230         */
4231
4232         if (aborting || bitset(EF_DISCARD, e->e_flags))
4233                 (void) dropenvelope(e, true, false);
4234         else
4235         {
4236                 for (ee = e; ee != NULL; ee = ee->e_sibling)
4237                 {
4238                         if (!doublequeue &&
4239                             QueueMode != QM_QUARANTINE &&
4240                             ee->e_quarmsg != NULL)
4241                         {
4242                                 (void) dropenvelope(ee, true, false);
4243                                 continue;
4244                         }
4245                         if (WILL_BE_QUEUED(ee->e_sendmode))
4246                                 (void) dropenvelope(ee, true, false);
4247                 }
4248         }
4249
4250         CurEnv = e;
4251         features = e->e_features;
4252         sm_rpool_free(e->e_rpool);
4253         newenvelope(e, e, sm_rpool_new_x(NULL));
4254         e->e_flags = BlankEnvelope.e_flags;
4255         e->e_features = features;
4256
4257         /* restore connection quarantining */
4258         if (smtp->sm_quarmsg == NULL)
4259         {
4260                 e->e_quarmsg = NULL;
4261                 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), "");
4262         }
4263         else
4264         {
4265                 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, smtp->sm_quarmsg);
4266                 macdefine(&e->e_macro, A_PERM,
4267                           macid("{quarantine}"), e->e_quarmsg);
4268         }
4269         return rv;
4270 }
4271 /*
4272 **  LOGUNDELRCPTS -- log undelivered (or all) recipients.
4273 **
4274 **      Parameters:
4275 **              e -- envelope.
4276 **              msg -- message for Stat=
4277 **              level -- log level.
4278 **              all -- log all recipients.
4279 **
4280 **      Returns:
4281 **              none.
4282 **
4283 **      Side Effects:
4284 **              logs undelivered (or all) recipients
4285 */
4286
4287 void
4288 logundelrcpts(e, msg, level, all)
4289         ENVELOPE *e;
4290         char *msg;
4291         int level;
4292         bool all;
4293 {
4294         ADDRESS *a;
4295
4296         if (LogLevel <= level || msg == NULL || *msg == '\0')
4297                 return;
4298
4299         /* Clear $h so relay= doesn't get mislogged by logdelivery() */
4300         macdefine(&e->e_macro, A_PERM, 'h', NULL);
4301
4302         /* Log who the mail would have gone to */
4303         for (a = e->e_sendqueue; a != NULL; a = a->q_next)
4304         {
4305                 if (!QS_IS_UNDELIVERED(a->q_state) && !all)
4306                         continue;
4307                 e->e_to = a->q_paddr;
4308                 logdelivery(NULL, NULL,
4309 #if _FFR_MILTER_ENHSC
4310                             (a->q_status == NULL && e->e_enhsc[0] != '\0')
4311                             ? e->e_enhsc :
4312 #endif /* _FFR_MILTER_ENHSC */
4313                             a->q_status,
4314                             msg, NULL, (time_t) 0, e, a, EX_OK /* ??? */);
4315         }
4316         e->e_to = NULL;
4317 }
4318 /*
4319 **  CHECKSMTPATTACK -- check for denial-of-service attack by repetition
4320 **
4321 **      Parameters:
4322 **              pcounter -- pointer to a counter for this command.
4323 **              maxcount -- maximum value for this counter before we
4324 **                      slow down.
4325 **              waitnow -- sleep now (in this routine)?
4326 **              cname -- command name for logging.
4327 **              e -- the current envelope.
4328 **
4329 **      Returns:
4330 **              time to wait,
4331 **              STOP_ATTACK if twice as many commands as allowed and
4332 **                      MaxChildren > 0.
4333 **
4334 **      Side Effects:
4335 **              Slows down if we seem to be under attack.
4336 */
4337
4338 static time_t
4339 checksmtpattack(pcounter, maxcount, waitnow, cname, e)
4340         volatile unsigned int *pcounter;
4341         unsigned int maxcount;
4342         bool waitnow;
4343         char *cname;
4344         ENVELOPE *e;
4345 {
4346         if (maxcount <= 0)      /* no limit */
4347                 return (time_t) 0;
4348
4349         if (++(*pcounter) >= maxcount)
4350         {
4351                 unsigned int shift;
4352                 time_t s;
4353
4354                 if (*pcounter == maxcount && LogLevel > 5)
4355                 {
4356                         sm_syslog(LOG_INFO, e->e_id,
4357                                   "%s: possible SMTP attack: command=%.40s, count=%u",
4358                                   CurSmtpClient, cname, *pcounter);
4359                 }
4360                 shift = *pcounter - maxcount;
4361                 s = 1 << shift;
4362                 if (shift > MAXSHIFT || s >= MAXTIMEOUT || s <= 0)
4363                         s = MAXTIMEOUT;
4364
4365 #define IS_ATTACK(s)    ((MaxChildren > 0 && *pcounter >= maxcount * 2) \
4366                                 ? STOP_ATTACK : (time_t) s)
4367
4368                 /* sleep at least 1 second before returning */
4369                 (void) sleep(*pcounter / maxcount);
4370                 s -= *pcounter / maxcount;
4371                 if (s >= MAXTIMEOUT || s < 0)
4372                         s = MAXTIMEOUT;
4373                 if (waitnow && s > 0)
4374                 {
4375                         (void) sleep(s);
4376                         return IS_ATTACK(0);
4377                 }
4378                 return IS_ATTACK(s);
4379         }
4380         return (time_t) 0;
4381 }
4382 /*
4383 **  SETUP_SMTPD_IO -- setup I/O fd correctly for the SMTP server
4384 **
4385 **      Parameters:
4386 **              none.
4387 **
4388 **      Returns:
4389 **              nothing.
4390 **
4391 **      Side Effects:
4392 **              may change I/O fd.
4393 */
4394
4395 static void
4396 setup_smtpd_io()
4397 {
4398         int inchfd, outchfd, outfd;
4399
4400         inchfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
4401         outchfd  = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL);
4402         outfd = sm_io_getinfo(smioout, SM_IO_WHAT_FD, NULL);
4403         if (outchfd != outfd)
4404         {
4405                 /* arrange for debugging output to go to remote host */
4406                 (void) dup2(outchfd, outfd);
4407         }
4408
4409         /*
4410         **  if InChannel and OutChannel are stdin/stdout
4411         **  and connected to ttys
4412         **  and fcntl(STDIN, F_SETFL, O_NONBLOCKING) also changes STDOUT,
4413         **  then "chain" them together.
4414         */
4415
4416         if (inchfd == STDIN_FILENO && outchfd == STDOUT_FILENO &&
4417             isatty(inchfd) && isatty(outchfd))
4418         {
4419                 int inmode, outmode;
4420
4421                 inmode = fcntl(inchfd, F_GETFL, 0);
4422                 if (inmode == -1)
4423                 {
4424                         if (LogLevel > 11)
4425                                 sm_syslog(LOG_INFO, NOQID,
4426                                         "fcntl(inchfd, F_GETFL) failed: %s",
4427                                         sm_errstring(errno));
4428                         return;
4429                 }
4430                 outmode = fcntl(outchfd, F_GETFL, 0);
4431                 if (outmode == -1)
4432                 {
4433                         if (LogLevel > 11)
4434                                 sm_syslog(LOG_INFO, NOQID,
4435                                         "fcntl(outchfd, F_GETFL) failed: %s",
4436                                         sm_errstring(errno));
4437                         return;
4438                 }
4439                 if (bitset(O_NONBLOCK, inmode) ||
4440                     bitset(O_NONBLOCK, outmode) ||
4441                     fcntl(inchfd, F_SETFL, inmode | O_NONBLOCK) == -1)
4442                         return;
4443                 outmode = fcntl(outchfd, F_GETFL, 0);
4444                 if (outmode != -1 && bitset(O_NONBLOCK, outmode))
4445                 {
4446                         /* changing InChannel also changes OutChannel */
4447                         sm_io_automode(OutChannel, InChannel);
4448                         if (tTd(97, 4) && LogLevel > 9)
4449                                 sm_syslog(LOG_INFO, NOQID,
4450                                           "set automode for I (%d)/O (%d) in SMTP server",
4451                                           inchfd, outchfd);
4452                 }
4453
4454                 /* undo change of inchfd */
4455                 (void) fcntl(inchfd, F_SETFL, inmode);
4456         }
4457 }
4458 /*
4459 **  SKIPWORD -- skip a fixed word.
4460 **
4461 **      Parameters:
4462 **              p -- place to start looking.
4463 **              w -- word to skip.
4464 **
4465 **      Returns:
4466 **              p following w.
4467 **              NULL on error.
4468 **
4469 **      Side Effects:
4470 **              clobbers the p data area.
4471 */
4472
4473 static char *
4474 skipword(p, w)
4475         register char *volatile p;
4476         char *w;
4477 {
4478         register char *q;
4479         char *firstp = p;
4480
4481         /* find beginning of word */
4482         SKIP_SPACE(p);
4483         q = p;
4484
4485         /* find end of word */
4486         while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p)))
4487                 p++;
4488         while (isascii(*p) && isspace(*p))
4489                 *p++ = '\0';
4490         if (*p != ':')
4491         {
4492           syntax:
4493                 usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"",
4494                         shortenstring(firstp, MAXSHORTSTR));
4495                 return NULL;
4496         }
4497         *p++ = '\0';
4498         SKIP_SPACE(p);
4499
4500         if (*p == '\0')
4501                 goto syntax;
4502
4503         /* see if the input word matches desired word */
4504         if (sm_strcasecmp(q, w))
4505                 goto syntax;
4506
4507         return p;
4508 }
4509
4510 /*
4511 **  RESET_MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
4512 **
4513 **      Parameters:
4514 **              e -- the envelope.
4515 **
4516 **      Returns:
4517 **              none.
4518 */
4519
4520 void
4521 reset_mail_esmtp_args(e)
4522         ENVELOPE *e;
4523 {
4524         /* "size": no reset */
4525
4526         /* "body" */
4527         SevenBitInput = SevenBitInput_Saved;
4528         e->e_bodytype = NULL;
4529
4530         /* "envid" */
4531         e->e_envid = NULL;
4532         macdefine(&e->e_macro, A_PERM, macid("{dsn_envid}"), NULL);
4533
4534         /* "ret" */
4535         e->e_flags &= ~(EF_RET_PARAM|EF_NO_BODY_RETN);
4536         macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), NULL);
4537
4538 #if SASL
4539         /* "auth" */
4540         macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), NULL);
4541         e->e_auth_param = "";
4542 # if _FFR_AUTH_PASSING
4543         macdefine(&BlankEnvelope.e_macro, A_PERM,
4544                                   macid("{auth_author}"), NULL);
4545 # endif /* _FFR_AUTH_PASSING */
4546 #endif /* SASL */
4547
4548         /* "by" */
4549         e->e_deliver_by = 0;
4550         e->e_dlvr_flag = 0;
4551 }
4552
4553 /*
4554 **  MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
4555 **
4556 **      Parameters:
4557 **              a -- address (unused, for compatibility with rcpt_esmtp_args)
4558 **              kp -- the parameter key.
4559 **              vp -- the value of that parameter.
4560 **              e -- the envelope.
4561 **
4562 **      Returns:
4563 **              none.
4564 */
4565
4566 void
4567 mail_esmtp_args(a, kp, vp, e)
4568         ADDRESS *a;
4569         char *kp;
4570         char *vp;
4571         ENVELOPE *e;
4572 {
4573         if (sm_strcasecmp(kp, "size") == 0)
4574         {
4575                 if (vp == NULL)
4576                 {
4577                         usrerr("501 5.5.2 SIZE requires a value");
4578                         /* NOTREACHED */
4579                 }
4580                 macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), vp);
4581                 errno = 0;
4582                 e->e_msgsize = strtol(vp, (char **) NULL, 10);
4583                 if (e->e_msgsize == LONG_MAX && errno == ERANGE)
4584                 {
4585                         usrerr("552 5.2.3 Message size exceeds maximum value");
4586                         /* NOTREACHED */
4587                 }
4588                 if (e->e_msgsize < 0)
4589                 {
4590                         usrerr("552 5.2.3 Message size invalid");
4591                         /* NOTREACHED */
4592                 }
4593         }
4594         else if (sm_strcasecmp(kp, "body") == 0)
4595         {
4596                 if (vp == NULL)
4597                 {
4598                         usrerr("501 5.5.2 BODY requires a value");
4599                         /* NOTREACHED */
4600                 }
4601                 else if (sm_strcasecmp(vp, "8bitmime") == 0)
4602                 {
4603                         SevenBitInput = false;
4604                 }
4605                 else if (sm_strcasecmp(vp, "7bit") == 0)
4606                 {
4607                         SevenBitInput = true;
4608                 }
4609                 else
4610                 {
4611                         usrerr("501 5.5.4 Unknown BODY type %s", vp);
4612                         /* NOTREACHED */
4613                 }
4614                 e->e_bodytype = sm_rpool_strdup_x(e->e_rpool, vp);
4615         }
4616         else if (sm_strcasecmp(kp, "envid") == 0)
4617         {
4618                 if (!bitset(SRV_OFFER_DSN, e->e_features))
4619                 {
4620                         usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN");
4621                         /* NOTREACHED */
4622                 }
4623                 if (vp == NULL)
4624                 {
4625                         usrerr("501 5.5.2 ENVID requires a value");
4626                         /* NOTREACHED */
4627                 }
4628                 if (!xtextok(vp))
4629                 {
4630                         usrerr("501 5.5.4 Syntax error in ENVID parameter value");
4631                         /* NOTREACHED */
4632                 }
4633                 if (e->e_envid != NULL)
4634                 {
4635                         usrerr("501 5.5.0 Duplicate ENVID parameter");
4636                         /* NOTREACHED */
4637                 }
4638                 e->e_envid = sm_rpool_strdup_x(e->e_rpool, vp);
4639                 macdefine(&e->e_macro, A_PERM,
4640                         macid("{dsn_envid}"), e->e_envid);
4641         }
4642         else if (sm_strcasecmp(kp, "ret") == 0)
4643         {
4644                 if (!bitset(SRV_OFFER_DSN, e->e_features))
4645                 {
4646                         usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN");
4647                         /* NOTREACHED */
4648                 }
4649                 if (vp == NULL)
4650                 {
4651                         usrerr("501 5.5.2 RET requires a value");
4652                         /* NOTREACHED */
4653                 }
4654                 if (bitset(EF_RET_PARAM, e->e_flags))
4655                 {
4656                         usrerr("501 5.5.0 Duplicate RET parameter");
4657                         /* NOTREACHED */
4658                 }
4659                 e->e_flags |= EF_RET_PARAM;
4660                 if (sm_strcasecmp(vp, "hdrs") == 0)
4661                         e->e_flags |= EF_NO_BODY_RETN;
4662                 else if (sm_strcasecmp(vp, "full") != 0)
4663                 {
4664                         usrerr("501 5.5.2 Bad argument \"%s\" to RET", vp);
4665                         /* NOTREACHED */
4666                 }
4667                 macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), vp);
4668         }
4669 #if SASL
4670         else if (sm_strcasecmp(kp, "auth") == 0)
4671         {
4672                 int len;
4673                 char *q;
4674                 char *auth_param;       /* the value of the AUTH=x */
4675                 bool saveQuickAbort = QuickAbort;
4676                 bool saveSuprErrs = SuprErrs;
4677                 bool saveExitStat = ExitStat;
4678
4679                 if (vp == NULL)
4680                 {
4681                         usrerr("501 5.5.2 AUTH= requires a value");
4682                         /* NOTREACHED */
4683                 }
4684                 if (e->e_auth_param != NULL)
4685                 {
4686                         usrerr("501 5.5.0 Duplicate AUTH parameter");
4687                         /* NOTREACHED */
4688                 }
4689                 if ((q = strchr(vp, ' ')) != NULL)
4690                         len = q - vp + 1;
4691                 else
4692                         len = strlen(vp) + 1;
4693                 auth_param = xalloc(len);
4694                 (void) sm_strlcpy(auth_param, vp, len);
4695                 if (!xtextok(auth_param))
4696                 {
4697                         usrerr("501 5.5.4 Syntax error in AUTH parameter value");
4698                         /* just a warning? */
4699                         /* NOTREACHED */
4700                 }
4701
4702                 /* XXX define this always or only if trusted? */
4703                 macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"),
4704                           auth_param);
4705
4706                 /*
4707                 **  call Strust_auth to find out whether
4708                 **  auth_param is acceptable (trusted)
4709                 **  we shouldn't trust it if not authenticated
4710                 **  (required by RFC, leave it to ruleset?)
4711                 */
4712
4713                 SuprErrs = true;
4714                 QuickAbort = false;
4715                 if (strcmp(auth_param, "<>") != 0 &&
4716                      (rscheck("trust_auth", auth_param, NULL, e, RSF_RMCOMM, 9,
4717                               NULL, NOQID, NULL, NULL) != EX_OK || Errors > 0))
4718                 {
4719                         if (tTd(95, 8))
4720                         {
4721                                 q = e->e_auth_param;
4722                                 sm_dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n",
4723                                         auth_param, (q == NULL) ? "" : q);
4724                         }
4725
4726                         /* not trusted */
4727                         e->e_auth_param = "<>";
4728 # if _FFR_AUTH_PASSING
4729                         macdefine(&BlankEnvelope.e_macro, A_PERM,
4730                                   macid("{auth_author}"), NULL);
4731 # endif /* _FFR_AUTH_PASSING */
4732                 }
4733                 else
4734                 {
4735                         if (tTd(95, 8))
4736                                 sm_dprintf("auth=\"%.100s\" trusted\n", auth_param);
4737                         e->e_auth_param = sm_rpool_strdup_x(e->e_rpool,
4738                                                             auth_param);
4739                 }
4740                 sm_free(auth_param); /* XXX */
4741
4742                 /* reset values */
4743                 Errors = 0;
4744                 QuickAbort = saveQuickAbort;
4745                 SuprErrs = saveSuprErrs;
4746                 ExitStat = saveExitStat;
4747         }
4748 #endif /* SASL */
4749 #define PRTCHAR(c)      ((isascii(c) && isprint(c)) ? (c) : '?')
4750
4751         /*
4752         **  "by" is only accepted if DeliverByMin >= 0.
4753         **  We maybe could add this to the list of server_features.
4754         */
4755
4756         else if (sm_strcasecmp(kp, "by") == 0 && DeliverByMin >= 0)
4757         {
4758                 char *s;
4759
4760                 if (vp == NULL)
4761                 {
4762                         usrerr("501 5.5.2 BY= requires a value");
4763                         /* NOTREACHED */
4764                 }
4765                 errno = 0;
4766                 e->e_deliver_by = strtol(vp, &s, 10);
4767                 if (e->e_deliver_by == LONG_MIN ||
4768                     e->e_deliver_by == LONG_MAX ||
4769                     e->e_deliver_by > 999999999l ||
4770                     e->e_deliver_by < -999999999l)
4771                 {
4772                         usrerr("501 5.5.2 BY=%s out of range", vp);
4773                         /* NOTREACHED */
4774                 }
4775                 if (s == NULL || *s != ';')
4776                 {
4777                         usrerr("501 5.5.2 BY= missing ';'");
4778                         /* NOTREACHED */
4779                 }
4780                 e->e_dlvr_flag = 0;
4781                 ++s;    /* XXX: spaces allowed? */
4782                 SKIP_SPACE(s);
4783                 switch (tolower(*s))
4784                 {
4785                   case 'n':
4786                         e->e_dlvr_flag = DLVR_NOTIFY;
4787                         break;
4788                   case 'r':
4789                         e->e_dlvr_flag = DLVR_RETURN;
4790                         if (e->e_deliver_by <= 0)
4791                         {
4792                                 usrerr("501 5.5.4 mode R requires BY time > 0");
4793                                 /* NOTREACHED */
4794                         }
4795                         if (DeliverByMin > 0 && e->e_deliver_by > 0 &&
4796                             e->e_deliver_by < DeliverByMin)
4797                         {
4798                                 usrerr("555 5.5.2 time %ld less than %ld",
4799                                         e->e_deliver_by, (long) DeliverByMin);
4800                                 /* NOTREACHED */
4801                         }
4802                         break;
4803                   default:
4804                         usrerr("501 5.5.2 illegal by-mode '%c'", PRTCHAR(*s));
4805                         /* NOTREACHED */
4806                 }
4807                 ++s;    /* XXX: spaces allowed? */
4808                 SKIP_SPACE(s);
4809                 switch (tolower(*s))
4810                 {
4811                   case 't':
4812                         e->e_dlvr_flag |= DLVR_TRACE;
4813                         break;
4814                   case '\0':
4815                         break;
4816                   default:
4817                         usrerr("501 5.5.2 illegal by-trace '%c'", PRTCHAR(*s));
4818                         /* NOTREACHED */
4819                 }
4820
4821                 /* XXX: check whether more characters follow? */
4822         }
4823         else
4824         {
4825                 usrerr("555 5.5.4 %s parameter unrecognized", kp);
4826                 /* NOTREACHED */
4827         }
4828 }
4829
4830 /*
4831 **  RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
4832 **
4833 **      Parameters:
4834 **              a -- the address corresponding to the To: parameter.
4835 **              kp -- the parameter key.
4836 **              vp -- the value of that parameter.
4837 **              e -- the envelope.
4838 **
4839 **      Returns:
4840 **              none.
4841 */
4842
4843 void
4844 rcpt_esmtp_args(a, kp, vp, e)
4845         ADDRESS *a;
4846         char *kp;
4847         char *vp;
4848         ENVELOPE *e;
4849 {
4850         if (sm_strcasecmp(kp, "notify") == 0)
4851         {
4852                 char *p;
4853
4854                 if (!bitset(SRV_OFFER_DSN, e->e_features))
4855                 {
4856                         usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
4857                         /* NOTREACHED */
4858                 }
4859                 if (vp == NULL)
4860                 {
4861                         usrerr("501 5.5.2 NOTIFY requires a value");
4862                         /* NOTREACHED */
4863                 }
4864                 a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY);
4865                 a->q_flags |= QHASNOTIFY;
4866                 macdefine(&e->e_macro, A_TEMP, macid("{dsn_notify}"), vp);
4867
4868                 if (sm_strcasecmp(vp, "never") == 0)
4869                         return;
4870                 for (p = vp; p != NULL; vp = p)
4871                 {
4872                         char *s;
4873
4874                         s = p = strchr(p, ',');
4875                         if (p != NULL)
4876                                 *p++ = '\0';
4877                         if (sm_strcasecmp(vp, "success") == 0)
4878                                 a->q_flags |= QPINGONSUCCESS;
4879                         else if (sm_strcasecmp(vp, "failure") == 0)
4880                                 a->q_flags |= QPINGONFAILURE;
4881                         else if (sm_strcasecmp(vp, "delay") == 0)
4882                                 a->q_flags |= QPINGONDELAY;
4883                         else
4884                         {
4885                                 usrerr("501 5.5.4 Bad argument \"%s\"  to NOTIFY",
4886                                         vp);
4887                                 /* NOTREACHED */
4888                         }
4889                         if (s != NULL)
4890                                 *s = ',';
4891                 }
4892         }
4893         else if (sm_strcasecmp(kp, "orcpt") == 0)
4894         {
4895                 char *p;
4896
4897                 if (!bitset(SRV_OFFER_DSN, e->e_features))
4898                 {
4899                         usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN");
4900                         /* NOTREACHED */
4901                 }
4902                 if (vp == NULL)
4903                 {
4904                         usrerr("501 5.5.2 ORCPT requires a value");
4905                         /* NOTREACHED */
4906                 }
4907                 if (a->q_orcpt != NULL)
4908                 {
4909                         usrerr("501 5.5.0 Duplicate ORCPT parameter");
4910                         /* NOTREACHED */
4911                 }
4912                 p = strchr(vp, ';');
4913                 if (p == NULL)
4914                 {
4915                         usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
4916                         /* NOTREACHED */
4917                 }
4918                 *p = '\0';
4919                 if (!isatom(vp) || !xtextok(p + 1))
4920                 {
4921                         *p = ';';
4922                         usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
4923                         /* NOTREACHED */
4924                 }
4925                 *p = ';';
4926                 a->q_orcpt = sm_rpool_strdup_x(e->e_rpool, vp);
4927         }
4928         else
4929         {
4930                 usrerr("555 5.5.4 %s parameter unrecognized", kp);
4931                 /* NOTREACHED */
4932         }
4933 }
4934 /*
4935 **  PRINTVRFYADDR -- print an entry in the verify queue
4936 **
4937 **      Parameters:
4938 **              a -- the address to print.
4939 **              last -- set if this is the last one.
4940 **              vrfy -- set if this is a VRFY command.
4941 **
4942 **      Returns:
4943 **              none.
4944 **
4945 **      Side Effects:
4946 **              Prints the appropriate 250 codes.
4947 */
4948 #define OFFF    (3 + 1 + 5 + 1) /* offset in fmt: SMTP reply + enh. code */
4949
4950 static void
4951 printvrfyaddr(a, last, vrfy)
4952         register ADDRESS *a;
4953         bool last;
4954         bool vrfy;
4955 {
4956         char fmtbuf[30];
4957
4958         if (vrfy && a->q_mailer != NULL &&
4959             !bitnset(M_VRFY250, a->q_mailer->m_flags))
4960                 (void) sm_strlcpy(fmtbuf, "252", sizeof(fmtbuf));
4961         else
4962                 (void) sm_strlcpy(fmtbuf, "250", sizeof(fmtbuf));
4963         fmtbuf[3] = last ? ' ' : '-';
4964         (void) sm_strlcpy(&fmtbuf[4], "2.1.5 ", sizeof(fmtbuf) - 4);
4965         if (a->q_fullname == NULL)
4966         {
4967                 if ((a->q_mailer == NULL ||
4968                      a->q_mailer->m_addrtype == NULL ||
4969                      sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
4970                     strchr(a->q_user, '@') == NULL)
4971                         (void) sm_strlcpy(&fmtbuf[OFFF], "<%s@%s>",
4972                                        sizeof(fmtbuf) - OFFF);
4973                 else
4974                         (void) sm_strlcpy(&fmtbuf[OFFF], "<%s>",
4975                                        sizeof(fmtbuf) - OFFF);
4976                 message(fmtbuf, a->q_user, MyHostName);
4977         }
4978         else
4979         {
4980                 if ((a->q_mailer == NULL ||
4981                      a->q_mailer->m_addrtype == NULL ||
4982                      sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
4983                     strchr(a->q_user, '@') == NULL)
4984                         (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s@%s>",
4985                                        sizeof(fmtbuf) - OFFF);
4986                 else
4987                         (void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s>",
4988                                        sizeof(fmtbuf) - OFFF);
4989                 message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
4990         }
4991 }
4992
4993 #if SASL
4994 /*
4995 **  SASLMECHS -- get list of possible AUTH mechanisms
4996 **
4997 **      Parameters:
4998 **              conn -- SASL connection info.
4999 **              mechlist -- output parameter for list of mechanisms.
5000 **
5001 **      Returns:
5002 **              number of mechs.
5003 */
5004
5005 static int
5006 saslmechs(conn, mechlist)
5007         sasl_conn_t *conn;
5008         char **mechlist;
5009 {
5010         int len, num, result;
5011
5012         /* "user" is currently unused */
5013 # if SASL >= 20000
5014         result = sasl_listmech(conn, NULL,
5015                                "", " ", "", (const char **) mechlist,
5016                                (unsigned int *)&len, &num);
5017 # else /* SASL >= 20000 */
5018         result = sasl_listmech(conn, "user", /* XXX */
5019                                "", " ", "", mechlist,
5020                                (unsigned int *)&len, (unsigned int *)&num);
5021 # endif /* SASL >= 20000 */
5022         if (result != SASL_OK)
5023         {
5024                 if (LogLevel > 9)
5025                         sm_syslog(LOG_WARNING, NOQID,
5026                                   "AUTH error: listmech=%d, num=%d",
5027                                   result, num);
5028                 num = 0;
5029         }
5030         if (num > 0)
5031         {
5032                 if (LogLevel > 11)
5033                         sm_syslog(LOG_INFO, NOQID,
5034                                   "AUTH: available mech=%s, allowed mech=%s",
5035                                   *mechlist, AuthMechanisms);
5036                 *mechlist = intersect(AuthMechanisms, *mechlist, NULL);
5037         }
5038         else
5039         {
5040                 *mechlist = NULL;       /* be paranoid... */
5041                 if (result == SASL_OK && LogLevel > 9)
5042                         sm_syslog(LOG_WARNING, NOQID,
5043                                   "AUTH warning: no mechanisms");
5044         }
5045         return num;
5046 }
5047
5048 # if SASL >= 20000
5049 /*
5050 **  PROXY_POLICY -- define proxy policy for AUTH
5051 **
5052 **      Parameters:
5053 **              conn -- unused.
5054 **              context -- unused.
5055 **              requested_user -- authorization identity.
5056 **              rlen -- authorization identity length.
5057 **              auth_identity -- authentication identity.
5058 **              alen -- authentication identity length.
5059 **              def_realm -- default user realm.
5060 **              urlen -- user realm length.
5061 **              propctx -- unused.
5062 **
5063 **      Returns:
5064 **              ok?
5065 **
5066 **      Side Effects:
5067 **              sets {auth_authen} macro.
5068 */
5069
5070 int
5071 proxy_policy(conn, context, requested_user, rlen, auth_identity, alen,
5072              def_realm, urlen, propctx)
5073         sasl_conn_t *conn;
5074         void *context;
5075         const char *requested_user;
5076         unsigned rlen;
5077         const char *auth_identity;
5078         unsigned alen;
5079         const char *def_realm;
5080         unsigned urlen;
5081         struct propctx *propctx;
5082 {
5083         if (auth_identity == NULL)
5084                 return SASL_FAIL;
5085
5086         macdefine(&BlankEnvelope.e_macro, A_TEMP,
5087                   macid("{auth_authen}"),
5088                   xtextify((char *) auth_identity, "=<>\")"));
5089
5090         return SASL_OK;
5091 }
5092 # else /* SASL >= 20000 */
5093
5094 /*
5095 **  PROXY_POLICY -- define proxy policy for AUTH
5096 **
5097 **      Parameters:
5098 **              context -- unused.
5099 **              auth_identity -- authentication identity.
5100 **              requested_user -- authorization identity.
5101 **              user -- allowed user (output).
5102 **              errstr -- possible error string (output).
5103 **
5104 **      Returns:
5105 **              ok?
5106 */
5107
5108 int
5109 proxy_policy(context, auth_identity, requested_user, user, errstr)
5110         void *context;
5111         const char *auth_identity;
5112         const char *requested_user;
5113         const char **user;
5114         const char **errstr;
5115 {
5116         if (user == NULL || auth_identity == NULL)
5117                 return SASL_FAIL;
5118         *user = newstr(auth_identity);
5119         return SASL_OK;
5120 }
5121 # endif /* SASL >= 20000 */
5122 #endif /* SASL */
5123
5124 #if STARTTLS
5125 /*
5126 **  INITSRVTLS -- initialize server side TLS
5127 **
5128 **      Parameters:
5129 **              tls_ok -- should tls initialization be done?
5130 **
5131 **      Returns:
5132 **              succeeded?
5133 **
5134 **      Side Effects:
5135 **              sets tls_ok_srv which is a static variable in this module.
5136 **              Do NOT remove assignments to it!
5137 */
5138
5139 bool
5140 initsrvtls(tls_ok)
5141         bool tls_ok;
5142 {
5143         if (!tls_ok)
5144                 return false;
5145
5146         /* do NOT remove assignment */
5147         tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, Srv_SSL_Options, true,
5148                              SrvCertFile, SrvKeyFile,
5149                              CACertPath, CACertFile, DHParams);
5150         return tls_ok_srv;
5151 }
5152 #endif /* STARTTLS */
5153 /*
5154 **  SRVFEATURES -- get features for SMTP server
5155 **
5156 **      Parameters:
5157 **              e -- envelope (should be session context).
5158 **              clientname -- name of client.
5159 **              features -- default features for this invocation.
5160 **
5161 **      Returns:
5162 **              server features.
5163 */
5164
5165 /* table with options: it uses just one character, how about strings? */
5166 static struct
5167 {
5168         char            srvf_opt;
5169         unsigned int    srvf_flag;
5170 } srv_feat_table[] =
5171 {
5172         { 'A',  SRV_OFFER_AUTH  },
5173         { 'B',  SRV_OFFER_VERB  },
5174         { 'C',  SRV_REQ_SEC     },
5175         { 'D',  SRV_OFFER_DSN   },
5176         { 'E',  SRV_OFFER_ETRN  },
5177         { 'L',  SRV_REQ_AUTH    },
5178 #if PIPELINING
5179 # if _FFR_NO_PIPE
5180         { 'N',  SRV_NO_PIPE     },
5181 # endif /* _FFR_NO_PIPE */
5182         { 'P',  SRV_OFFER_PIPE  },
5183 #endif /* PIPELINING */
5184         { 'R',  SRV_VRFY_CLT    },      /* same as V; not documented */
5185         { 'S',  SRV_OFFER_TLS   },
5186 /*      { 'T',  SRV_TMP_FAIL    },      */
5187         { 'V',  SRV_VRFY_CLT    },
5188         { 'X',  SRV_OFFER_EXPN  },
5189 /*      { 'Y',  SRV_OFFER_VRFY  },      */
5190         { '\0', SRV_NONE        }
5191 };
5192
5193 static unsigned int
5194 srvfeatures(e, clientname, features)
5195         ENVELOPE *e;
5196         char *clientname;
5197         unsigned int features;
5198 {
5199         int r, i, j;
5200         char **pvp, c, opt;
5201         char pvpbuf[PSBUFSIZE];
5202
5203         pvp = NULL;
5204         r = rscap("srv_features", clientname, "", e, &pvp, pvpbuf,
5205                   sizeof(pvpbuf));
5206         if (r != EX_OK)
5207                 return features;
5208         if (pvp == NULL || pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
5209                 return features;
5210         if (pvp[1] != NULL && sm_strncasecmp(pvp[1], "temp", 4) == 0)
5211                 return SRV_TMP_FAIL;
5212
5213         /*
5214         **  General rule (see sendmail.h, d_flags):
5215         **  lower case: required/offered, upper case: Not required/available
5216         **
5217         **  Since we can change some features per daemon, we have both
5218         **  cases here: turn on/off a feature.
5219         */
5220
5221         for (i = 1; pvp[i] != NULL; i++)
5222         {
5223                 c = pvp[i][0];
5224                 j = 0;
5225                 for (;;)
5226                 {
5227                         if ((opt = srv_feat_table[j].srvf_opt) == '\0')
5228                         {
5229                                 if (LogLevel > 9)
5230                                         sm_syslog(LOG_WARNING, e->e_id,
5231                                                   "srvfeatures: unknown feature %s",
5232                                                   pvp[i]);
5233                                 break;
5234                         }
5235                         if (c == opt)
5236                         {
5237                                 features &= ~(srv_feat_table[j].srvf_flag);
5238                                 break;
5239                         }
5240                         if (c == tolower(opt))
5241                         {
5242                                 features |= srv_feat_table[j].srvf_flag;
5243                                 break;
5244                         }
5245                         ++j;
5246                 }
5247         }
5248         return features;
5249 }
5250
5251 /*
5252 **  HELP -- implement the HELP command.
5253 **
5254 **      Parameters:
5255 **              topic -- the topic we want help for.
5256 **              e -- envelope.
5257 **
5258 **      Returns:
5259 **              none.
5260 **
5261 **      Side Effects:
5262 **              outputs the help file to message output.
5263 */
5264 #define HELPVSTR        "#vers  "
5265 #define HELPVERSION     2
5266
5267 void
5268 help(topic, e)
5269         char *topic;
5270         ENVELOPE *e;
5271 {
5272         register SM_FILE_T *hf;
5273         register char *p;
5274         int len;
5275         bool noinfo;
5276         bool first = true;
5277         long sff = SFF_OPENASROOT|SFF_REGONLY;
5278         char buf[MAXLINE];
5279         char inp[MAXLINE];
5280         static int foundvers = -1;
5281         extern char Version[];
5282
5283         if (DontLockReadFiles)
5284                 sff |= SFF_NOLOCK;
5285         if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH, DontBlameSendmail))
5286                 sff |= SFF_SAFEDIRPATH;
5287
5288         if (HelpFile == NULL ||
5289             (hf = safefopen(HelpFile, O_RDONLY, 0444, sff)) == NULL)
5290         {
5291                 /* no help */
5292                 errno = 0;
5293                 message("502 5.3.0 Sendmail %s -- HELP not implemented",
5294                         Version);
5295                 return;
5296         }
5297
5298         if (topic == NULL || *topic == '\0')
5299         {
5300                 topic = "smtp";
5301                 noinfo = false;
5302         }
5303         else
5304         {
5305                 makelower(topic);
5306                 noinfo = true;
5307         }
5308
5309         len = strlen(topic);
5310
5311         while (sm_io_fgets(hf, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
5312         {
5313                 if (buf[0] == '#')
5314                 {
5315                         if (foundvers < 0 &&
5316                             strncmp(buf, HELPVSTR, strlen(HELPVSTR)) == 0)
5317                         {
5318                                 int h;
5319
5320                                 if (sm_io_sscanf(buf + strlen(HELPVSTR), "%d",
5321                                                  &h) == 1)
5322                                         foundvers = h;
5323                         }
5324                         continue;
5325                 }
5326                 if (strncmp(buf, topic, len) == 0)
5327                 {
5328                         if (first)
5329                         {
5330                                 first = false;
5331
5332                                 /* print version if no/old vers# in file */
5333                                 if (foundvers < 2 && !noinfo)
5334                                         message("214-2.0.0 This is Sendmail version %s", Version);
5335                         }
5336                         p = strpbrk(buf, " \t");
5337                         if (p == NULL)
5338                                 p = buf + strlen(buf) - 1;
5339                         else
5340                                 p++;
5341                         fixcrlf(p, true);
5342                         if (foundvers >= 2)
5343                         {
5344                                 char *lbp;
5345                                 int lbs = sizeof(buf) - (p - buf);
5346
5347                                 lbp = translate_dollars(p, p, &lbs);
5348                                 expand(lbp, inp, sizeof(inp), e);
5349                                 if (p != lbp)
5350                                         sm_free(lbp);
5351                                 p = inp;
5352                         }
5353                         message("214-2.0.0 %s", p);
5354                         noinfo = false;
5355                 }
5356         }
5357
5358         if (noinfo)
5359                 message("504 5.3.0 HELP topic \"%.10s\" unknown", topic);
5360         else
5361                 message("214 2.0.0 End of HELP info");
5362
5363         if (foundvers != 0 && foundvers < HELPVERSION)
5364         {
5365                 if (LogLevel > 1)
5366                         sm_syslog(LOG_WARNING, e->e_id,
5367                                   "%s too old (require version %d)",
5368                                   HelpFile, HELPVERSION);
5369
5370                 /* avoid log next time */
5371                 foundvers = 0;
5372         }
5373
5374         (void) sm_io_close(hf, SM_TIME_DEFAULT);
5375 }
5376
5377 #if SASL
5378 /*
5379 **  RESET_SASLCONN -- reset SASL connection data
5380 **
5381 **      Parameters:
5382 **              conn -- SASL connection context
5383 **              hostname -- host name
5384 **              various connection data
5385 **
5386 **      Returns:
5387 **              SASL result
5388 */
5389
5390 static int
5391 reset_saslconn(sasl_conn_t **conn, char *hostname,
5392 # if SASL >= 20000
5393                char *remoteip, char *localip,
5394                char *auth_id, sasl_ssf_t * ext_ssf)
5395 # else /* SASL >= 20000 */
5396                struct sockaddr_in *saddr_r, struct sockaddr_in *saddr_l,
5397                sasl_external_properties_t * ext_ssf)
5398 # endif /* SASL >= 20000 */
5399 {
5400         int result;
5401
5402         sasl_dispose(conn);
5403 # if SASL >= 20000
5404         result = sasl_server_new("smtp", hostname, NULL, NULL, NULL,
5405                                  NULL, 0, conn);
5406 # elif SASL > 10505
5407         /* use empty realm: only works in SASL > 1.5.5 */
5408         result = sasl_server_new("smtp", hostname, "", NULL, 0, conn);
5409 # else /* SASL >= 20000 */
5410         /* use no realm -> realm is set to hostname by SASL lib */
5411         result = sasl_server_new("smtp", hostname, NULL, NULL, 0,
5412                                  conn);
5413 # endif /* SASL >= 20000 */
5414         if (result != SASL_OK)
5415                 return result;
5416
5417 # if SASL >= 20000
5418 #  if NETINET || NETINET6
5419         if (remoteip != NULL && *remoteip != '\0')
5420                 result = sasl_setprop(*conn, SASL_IPREMOTEPORT, remoteip);
5421         if (result != SASL_OK)
5422                 return result;
5423
5424         if (localip != NULL && *localip != '\0')
5425                 result = sasl_setprop(*conn, SASL_IPLOCALPORT, localip);
5426         if (result != SASL_OK)
5427                 return result;
5428 #  endif /* NETINET || NETINET6 */
5429
5430         result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf);
5431         if (result != SASL_OK)
5432                 return result;
5433
5434         result = sasl_setprop(*conn, SASL_AUTH_EXTERNAL, auth_id);
5435         if (result != SASL_OK)
5436                 return result;
5437 # else /* SASL >= 20000 */
5438 #  if NETINET
5439         if (saddr_r != NULL)
5440                 result = sasl_setprop(*conn, SASL_IP_REMOTE, saddr_r);
5441         if (result != SASL_OK)
5442                 return result;
5443
5444         if (saddr_l != NULL)
5445                 result = sasl_setprop(*conn, SASL_IP_LOCAL, saddr_l);
5446         if (result != SASL_OK)
5447                 return result;
5448 #  endif /* NETINET */
5449
5450         result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf);
5451         if (result != SASL_OK)
5452                 return result;
5453 # endif /* SASL >= 20000 */
5454         return SASL_OK;
5455 }
5456 #endif /* SASL */