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