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