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