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