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