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