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