xref: /freebsd/contrib/sendmail/src/srvrsmtp.c (revision f9218d3d4fd34f082473b3a021c6d4d109fb47cf)
1 /*
2  * Copyright (c) 1998-2003 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.21 2003/01/15 19:17:14 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, errno=%d",
1639 						  r, i, (int) timedout, errno);
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 i, qgrp;
2721 
2722 				id++;
2723 				qgrp = name2qid(id);
2724 				if (!ISVALIDQGRP(qgrp))
2725 				{
2726 					usrerr("459 4.5.4 Queue %s unknown",
2727 					       id);
2728 					break;
2729 				}
2730 				for (i = 0; i < NumQueue && Queue[i] != NULL;
2731 				     i++)
2732 					Queue[i]->qg_nextrun = (time_t) -1;
2733 				Queue[qgrp]->qg_nextrun = 0;
2734 				ok = run_work_group(Queue[qgrp]->qg_wgrp,
2735 						    RWG_FORK|RWG_FORCE);
2736 				if (ok && Errors == 0)
2737 					message("250 2.0.0 Queuing for queue group %s started", id);
2738 				break;
2739 			}
2740 
2741 			if (*id == '@')
2742 				id++;
2743 			else
2744 				*--id = '@';
2745 
2746 			new = (QUEUE_CHAR *) sm_malloc(sizeof(QUEUE_CHAR));
2747 			if (new == NULL)
2748 			{
2749 				syserr("500 5.5.0 ETRN out of memory");
2750 				break;
2751 			}
2752 			new->queue_match = id;
2753 			new->queue_negate = false;
2754 			new->queue_next = NULL;
2755 			QueueLimitRecipient = new;
2756 			ok = runqueue(true, false, false, true);
2757 			sm_free(QueueLimitRecipient); /* XXX */
2758 			QueueLimitRecipient = NULL;
2759 			if (ok && Errors == 0)
2760 				message("250 2.0.0 Queuing for node %s started", p);
2761 			break;
2762 
2763 		  case CMDHELP:		/* help -- give user info */
2764 			DELAY_CONN("HELP");
2765 			help(p, e);
2766 			break;
2767 
2768 		  case CMDNOOP:		/* noop -- do nothing */
2769 			DELAY_CONN("NOOP");
2770 			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true,
2771 					       "NOOP", e);
2772 			message("250 2.0.0 OK");
2773 			break;
2774 
2775 		  case CMDQUIT:		/* quit -- leave mail */
2776 			message("221 2.0.0 %s closing connection", MyHostName);
2777 #if PIPELINING
2778 			(void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
2779 #endif /* PIPELINING */
2780 
2781 			if (smtp.sm_nrcpts > 0)
2782 				logundelrcpts(e, "aborted by sender", 9, false);
2783 
2784 			/* arrange to ignore any current send list */
2785 			e->e_sendqueue = NULL;
2786 
2787 #if STARTTLS
2788 			/* shutdown TLS connection */
2789 			if (tls_active)
2790 			{
2791 				(void) endtls(srv_ssl, "server");
2792 				tls_active = false;
2793 			}
2794 #endif /* STARTTLS */
2795 #if SASL
2796 			if (authenticating == SASL_IS_AUTH)
2797 			{
2798 				sasl_dispose(&conn);
2799 				authenticating = SASL_NOT_AUTH;
2800 				/* XXX sasl_done(); this is a child */
2801 			}
2802 #endif /* SASL */
2803 
2804 doquit:
2805 			/* avoid future 050 messages */
2806 			disconnect(1, e);
2807 
2808 #if MILTER
2809 			/* close out milter filters */
2810 			milter_quit(e);
2811 #endif /* MILTER */
2812 
2813 			if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
2814 				logsender(e, NULL);
2815 			e->e_flags &= ~EF_LOGSENDER;
2816 
2817 			if (lognullconnection && LogLevel > 5 &&
2818 			    nullserver == NULL)
2819 			{
2820 				char *d;
2821 
2822 				d = macvalue(macid("{daemon_name}"), e);
2823 				if (d == NULL)
2824 					d = "stdin";
2825 
2826 				/*
2827 				**  even though this id is "bogus", it makes
2828 				**  it simpler to "grep" related events, e.g.,
2829 				**  timeouts for the same connection.
2830 				*/
2831 
2832 				sm_syslog(LOG_INFO, e->e_id,
2833 					  "%s did not issue MAIL/EXPN/VRFY/ETRN during connection to %s",
2834 					  CurSmtpClient, d);
2835 			}
2836 			if (tTd(93, 100))
2837 			{
2838 				/* return to handle next connection */
2839 				return;
2840 			}
2841 			finis(true, true, ExitStat);
2842 			/* NOTREACHED */
2843 
2844 		  case CMDVERB:		/* set verbose mode */
2845 			DELAY_CONN("VERB");
2846 			if (!bitset(SRV_OFFER_EXPN, features) ||
2847 			    !bitset(SRV_OFFER_VERB, features))
2848 			{
2849 				/* this would give out the same info */
2850 				message("502 5.7.0 Verbose unavailable");
2851 				break;
2852 			}
2853 			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true,
2854 					       "VERB", e);
2855 			Verbose = 1;
2856 			set_delivery_mode(SM_DELIVER, e);
2857 			message("250 2.0.0 Verbose mode");
2858 			break;
2859 
2860 #if SMTPDEBUG
2861 		  case CMDDBGQSHOW:	/* show queues */
2862 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
2863 					     "Send Queue=");
2864 			printaddr(e->e_sendqueue, true);
2865 			break;
2866 
2867 		  case CMDDBGDEBUG:	/* set debug mode */
2868 			tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
2869 			tTflag(p);
2870 			message("200 2.0.0 Debug set");
2871 			break;
2872 
2873 #else /* SMTPDEBUG */
2874 		  case CMDDBGQSHOW:	/* show queues */
2875 		  case CMDDBGDEBUG:	/* set debug mode */
2876 #endif /* SMTPDEBUG */
2877 		  case CMDLOGBOGUS:	/* bogus command */
2878 			DELAY_CONN("Bogus");
2879 			if (LogLevel > 0)
2880 				sm_syslog(LOG_CRIT, e->e_id,
2881 					  "\"%s\" command from %s (%.100s)",
2882 					  c->cmd_name, CurSmtpClient,
2883 					  anynet_ntoa(&RealHostAddr));
2884 			/* FALLTHROUGH */
2885 
2886 		  case CMDERROR:	/* unknown command */
2887 #if MAXBADCOMMANDS > 0
2888 			if (++n_badcmds > MAXBADCOMMANDS)
2889 			{
2890 				message("421 4.7.0 %s Too many bad commands; closing connection",
2891 					MyHostName);
2892 
2893 				/* arrange to ignore any current send list */
2894 				e->e_sendqueue = NULL;
2895 				goto doquit;
2896 			}
2897 #endif /* MAXBADCOMMANDS > 0 */
2898 
2899 			usrerr("500 5.5.1 Command unrecognized: \"%s\"",
2900 			       shortenstring(inp, MAXSHORTSTR));
2901 			break;
2902 
2903 		  case CMDUNIMPL:
2904 			DELAY_CONN("Unimpl");
2905 			usrerr("502 5.5.1 Command not implemented: \"%s\"",
2906 			       shortenstring(inp, MAXSHORTSTR));
2907 			break;
2908 
2909 		  default:
2910 			DELAY_CONN("default");
2911 			errno = 0;
2912 			syserr("500 5.5.0 smtp: unknown code %d", c->cmd_code);
2913 			break;
2914 		}
2915 #if SASL
2916 		}
2917 #endif /* SASL */
2918 	    }
2919 	    SM_EXCEPT(exc, "[!F]*")
2920 	    {
2921 		/*
2922 		**  The only possible exception is "E:mta.quickabort".
2923 		**  There is nothing to do except fall through and loop.
2924 		*/
2925 	    }
2926 	    SM_END_TRY
2927 	}
2928 }
2929 /*
2930 **  SMTP_DATA -- implement the SMTP DATA command.
2931 **
2932 **	Parameters:
2933 **		smtp -- status of SMTP connection.
2934 **		e -- envelope.
2935 **
2936 **	Returns:
2937 **		none.
2938 **
2939 **	Side Effects:
2940 **		possibly sends message.
2941 */
2942 
2943 static void
2944 smtp_data(smtp, e)
2945 	SMTP_T *smtp;
2946 	ENVELOPE *e;
2947 {
2948 #if MILTER
2949 	bool milteraccept;
2950 #endif /* MILTER */
2951 	bool aborting;
2952 	bool doublequeue;
2953 	ADDRESS *a;
2954 	ENVELOPE *ee;
2955 	char *id;
2956 	char *oldid;
2957 	char buf[32];
2958 
2959 	SmtpPhase = "server DATA";
2960 	if (!smtp->sm_gotmail)
2961 	{
2962 		usrerr("503 5.0.0 Need MAIL command");
2963 		return;
2964 	}
2965 	else if (smtp->sm_nrcpts <= 0)
2966 	{
2967 		usrerr("503 5.0.0 Need RCPT (recipient)");
2968 		return;
2969 	}
2970 	(void) sm_snprintf(buf, sizeof buf, "%u", smtp->sm_nrcpts);
2971 	if (rscheck("check_data", buf, NULL, e,
2972 		    RSF_RMCOMM|RSF_UNSTRUCTURED|RSF_COUNT, 3, NULL,
2973 		    e->e_id) != EX_OK)
2974 		return;
2975 
2976 	/* put back discard bit */
2977 	if (smtp->sm_discard)
2978 		e->e_flags |= EF_DISCARD;
2979 
2980 	/* check to see if we need to re-expand aliases */
2981 	/* also reset QS_BADADDR on already-diagnosted addrs */
2982 	doublequeue = false;
2983 	for (a = e->e_sendqueue; a != NULL; a = a->q_next)
2984 	{
2985 		if (QS_IS_VERIFIED(a->q_state) &&
2986 		    !bitset(EF_DISCARD, e->e_flags))
2987 		{
2988 			/* need to re-expand aliases */
2989 			doublequeue = true;
2990 		}
2991 		if (QS_IS_BADADDR(a->q_state))
2992 		{
2993 			/* make this "go away" */
2994 			a->q_state = QS_DONTSEND;
2995 		}
2996 	}
2997 
2998 	/* collect the text of the message */
2999 	SmtpPhase = "collect";
3000 	buffer_errors();
3001 
3002 #if _FFR_ADAPTIVE_EOL
3003 	/* triggers error in collect, disabled for now */
3004 	if (smtp->sm_crlf)
3005 		e->e_flags |= EF_NL_NOT_EOL;
3006 #endif /* _FFR_ADAPTIVE_EOL */
3007 
3008 	collect(InChannel, true, NULL, e);
3009 
3010 	/* redefine message size */
3011 	(void) sm_snprintf(buf, sizeof buf, "%ld", e->e_msgsize);
3012 	macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
3013 
3014 #if _FFR_CHECK_EOM
3015 	/* rscheck() will set Errors or EF_DISCARD if it trips */
3016 	(void) rscheck("check_eom", buf, NULL, e, RSF_UNSTRUCTURED|RSF_COUNT,
3017 		       3, NULL, e->e_id);
3018 #endif /* _FFR_CHECK_EOM */
3019 
3020 #if MILTER
3021 	milteraccept = true;
3022 	if (smtp->sm_milterlist && smtp->sm_milterize &&
3023 	    Errors <= 0 &&
3024 	    !bitset(EF_DISCARD, e->e_flags))
3025 	{
3026 		char state;
3027 		char *response;
3028 
3029 		response = milter_data(e, &state);
3030 		switch (state)
3031 		{
3032 		  case SMFIR_REPLYCODE:
3033 			if (MilterLogLevel > 3)
3034 				sm_syslog(LOG_INFO, e->e_id,
3035 					  "Milter: data, reject=%s",
3036 					  response);
3037 			milteraccept = false;
3038 			usrerr(response);
3039 			break;
3040 
3041 		  case SMFIR_REJECT:
3042 			milteraccept = false;
3043 			if (MilterLogLevel > 3)
3044 				sm_syslog(LOG_INFO, e->e_id,
3045 					  "Milter: data, reject=554 5.7.1 Command rejected");
3046 			usrerr("554 5.7.1 Command rejected");
3047 			break;
3048 
3049 		  case SMFIR_DISCARD:
3050 			if (MilterLogLevel > 3)
3051 				sm_syslog(LOG_INFO, e->e_id,
3052 					  "Milter: data, discard");
3053 			milteraccept = false;
3054 			e->e_flags |= EF_DISCARD;
3055 			break;
3056 
3057 		  case SMFIR_TEMPFAIL:
3058 			if (MilterLogLevel > 3)
3059 				sm_syslog(LOG_INFO, e->e_id,
3060 					  "Milter: data, reject=%s",
3061 					  MSG_TEMPFAIL);
3062 			milteraccept = false;
3063 			usrerr(MSG_TEMPFAIL);
3064 			break;
3065 		}
3066 		if (response != NULL)
3067 			sm_free(response);
3068 	}
3069 
3070 	/* Milter may have changed message size */
3071 	(void) sm_snprintf(buf, sizeof buf, "%ld", e->e_msgsize);
3072 	macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
3073 
3074 	/* abort message filters that didn't get the body & log msg is OK */
3075 	if (smtp->sm_milterlist && smtp->sm_milterize)
3076 	{
3077 		milter_abort(e);
3078 		if (milteraccept && MilterLogLevel > 9)
3079 			sm_syslog(LOG_INFO, e->e_id, "Milter accept: message");
3080 	}
3081 #endif /* MILTER */
3082 
3083 #if _FFR_QUARANTINE
3084 	/* Check if quarantining stats should be updated */
3085 	if (e->e_quarmsg != NULL)
3086 		markstats(e, NULL, STATS_QUARANTINE);
3087 #endif /* _FFR_QUARANTINE */
3088 
3089 	/*
3090 	**  If a header/body check (header checks or milter)
3091 	**  set EF_DISCARD, don't queueup the message --
3092 	**  that would lose the EF_DISCARD bit and deliver
3093 	**  the message.
3094 	*/
3095 
3096 	if (bitset(EF_DISCARD, e->e_flags))
3097 		doublequeue = false;
3098 
3099 	aborting = Errors > 0;
3100 	if (!aborting &&
3101 #if _FFR_QUARANTINE
3102 	    (QueueMode == QM_QUARANTINE || e->e_quarmsg == NULL) &&
3103 #endif /* _FFR_QUARANTINE */
3104 	    !split_by_recipient(e))
3105 		aborting = bitset(EF_FATALERRS, e->e_flags);
3106 
3107 	if (aborting)
3108 	{
3109 		/* Log who the mail would have gone to */
3110 		logundelrcpts(e, e->e_message, 8, false);
3111 		flush_errors(true);
3112 		buffer_errors();
3113 		goto abortmessage;
3114 	}
3115 
3116 	/* from now on, we have to operate silently */
3117 	buffer_errors();
3118 
3119 #if 0
3120 	/*
3121 	**  Clear message, it may contain an error from the SMTP dialogue.
3122 	**  This error must not show up in the queue.
3123 	**	Some error message should show up, e.g., alias database
3124 	**	not available, but others shouldn't, e.g., from check_rcpt.
3125 	*/
3126 
3127 	e->e_message = NULL;
3128 #endif /* 0 */
3129 
3130 	/*
3131 	**  Arrange to send to everyone.
3132 	**	If sending to multiple people, mail back
3133 	**		errors rather than reporting directly.
3134 	**	In any case, don't mail back errors for
3135 	**		anything that has happened up to
3136 	**		now (the other end will do this).
3137 	**	Truncate our transcript -- the mail has gotten
3138 	**		to us successfully, and if we have
3139 	**		to mail this back, it will be easier
3140 	**		on the reader.
3141 	**	Then send to everyone.
3142 	**	Finally give a reply code.  If an error has
3143 	**		already been given, don't mail a
3144 	**		message back.
3145 	**	We goose error returns by clearing error bit.
3146 	*/
3147 
3148 	SmtpPhase = "delivery";
3149 	(void) sm_io_setinfo(e->e_xfp, SM_BF_TRUNCATE, NULL);
3150 	id = e->e_id;
3151 
3152 #if NAMED_BIND
3153 	_res.retry = TimeOuts.res_retry[RES_TO_FIRST];
3154 	_res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
3155 #endif /* NAMED_BIND */
3156 
3157 	for (ee = e; ee != NULL; ee = ee->e_sibling)
3158 	{
3159 		/* make sure we actually do delivery */
3160 		ee->e_flags &= ~EF_CLRQUEUE;
3161 
3162 		/* from now on, operate silently */
3163 		ee->e_errormode = EM_MAIL;
3164 
3165 		if (doublequeue)
3166 		{
3167 			/* make sure it is in the queue */
3168 			queueup(ee, false, true);
3169 		}
3170 		else
3171 		{
3172 			/* send to all recipients */
3173 			sendall(ee, SM_DEFAULT);
3174 		}
3175 		ee->e_to = NULL;
3176 	}
3177 
3178 	/* put back id for SMTP logging in putoutmsg() */
3179 	oldid = CurEnv->e_id;
3180 	CurEnv->e_id = id;
3181 
3182 	/* issue success message */
3183 	message("250 2.0.0 %s Message accepted for delivery", id);
3184 	CurEnv->e_id = oldid;
3185 
3186 	/* if we just queued, poke it */
3187 	if (doublequeue)
3188 	{
3189 		bool anything_to_send = false;
3190 
3191 		sm_getla();
3192 		for (ee = e; ee != NULL; ee = ee->e_sibling)
3193 		{
3194 			if (WILL_BE_QUEUED(ee->e_sendmode))
3195 				continue;
3196 			if (shouldqueue(ee->e_msgpriority, ee->e_ctime))
3197 			{
3198 				ee->e_sendmode = SM_QUEUE;
3199 				continue;
3200 			}
3201 #if _FFR_QUARANTINE
3202 			else if (QueueMode != QM_QUARANTINE &&
3203 				 ee->e_quarmsg != NULL)
3204 			{
3205 				ee->e_sendmode = SM_QUEUE;
3206 				continue;
3207 			}
3208 #endif /* _FFR_QUARANTINE */
3209 			anything_to_send = true;
3210 
3211 			/* close all the queue files */
3212 			closexscript(ee);
3213 			if (ee->e_dfp != NULL)
3214 			{
3215 				(void) sm_io_close(ee->e_dfp, SM_TIME_DEFAULT);
3216 				ee->e_dfp = NULL;
3217 			}
3218 			unlockqueue(ee);
3219 		}
3220 		if (anything_to_send)
3221 		{
3222 #if PIPELINING
3223 			/*
3224 			**  XXX if we don't do this, we get 250 twice
3225 			**	because it is also flushed in the child.
3226 			*/
3227 
3228 			(void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
3229 #endif /* PIPELINING */
3230 			(void) doworklist(e, true, true);
3231 		}
3232 	}
3233 
3234   abortmessage:
3235 	if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
3236 		logsender(e, NULL);
3237 	e->e_flags &= ~EF_LOGSENDER;
3238 
3239 	/* clean up a bit */
3240 	smtp->sm_gotmail = false;
3241 
3242 	/*
3243 	**  Call dropenvelope if and only if the envelope is *not*
3244 	**  being processed by the child process forked by doworklist().
3245 	*/
3246 
3247 	if (aborting || bitset(EF_DISCARD, e->e_flags))
3248 		dropenvelope(e, true, false);
3249 	else
3250 	{
3251 		for (ee = e; ee != NULL; ee = ee->e_sibling)
3252 		{
3253 #if _FFR_QUARANTINE
3254 			if (!doublequeue &&
3255 			    QueueMode != QM_QUARANTINE &&
3256 			    ee->e_quarmsg != NULL)
3257 			{
3258 				dropenvelope(ee, true, false);
3259 				continue;
3260 			}
3261 #endif /* _FFR_QUARANTINE */
3262 			if (WILL_BE_QUEUED(ee->e_sendmode))
3263 				dropenvelope(ee, true, false);
3264 		}
3265 	}
3266 	sm_rpool_free(e->e_rpool);
3267 
3268 	/*
3269 	**  At this point, e == &MainEnvelope, but if we did splitting,
3270 	**  then CurEnv may point to an envelope structure that was just
3271 	**  freed with the rpool.  So reset CurEnv *before* calling
3272 	**  newenvelope.
3273 	*/
3274 
3275 	CurEnv = e;
3276 	newenvelope(e, e, sm_rpool_new_x(NULL));
3277 	e->e_flags = BlankEnvelope.e_flags;
3278 
3279 #if _FFR_QUARANTINE
3280 	/* restore connection quarantining */
3281 	if (smtp->sm_quarmsg == NULL)
3282 	{
3283 		e->e_quarmsg = NULL;
3284 		macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), "");
3285 	}
3286 	else
3287 	{
3288 		e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, smtp->sm_quarmsg);
3289 		macdefine(&e->e_macro, A_PERM,
3290 			  macid("{quarantine}"), e->e_quarmsg);
3291 	}
3292 #endif /* _FFR_QUARANTINE */
3293 }
3294 /*
3295 **  LOGUNDELRCPTS -- log undelivered (or all) recipients.
3296 **
3297 **	Parameters:
3298 **		e -- envelope.
3299 **		msg -- message for Stat=
3300 **		level -- log level.
3301 **		all -- log all recipients.
3302 **
3303 **	Returns:
3304 **		none.
3305 **
3306 **	Side Effects:
3307 **		logs undelivered (or all) recipients
3308 */
3309 
3310 void
3311 logundelrcpts(e, msg, level, all)
3312 	ENVELOPE *e;
3313 	char *msg;
3314 	int level;
3315 	bool all;
3316 {
3317 	ADDRESS *a;
3318 
3319 	if (LogLevel <= level || msg == NULL || *msg == '\0')
3320 		return;
3321 
3322 	/* Clear $h so relay= doesn't get mislogged by logdelivery() */
3323 	macdefine(&e->e_macro, A_PERM, 'h', NULL);
3324 
3325 	/* Log who the mail would have gone to */
3326 	for (a = e->e_sendqueue; a != NULL; a = a->q_next)
3327 	{
3328 		if (!QS_IS_UNDELIVERED(a->q_state) && !all)
3329 			continue;
3330 		e->e_to = a->q_paddr;
3331 		logdelivery(NULL, NULL, a->q_status, msg, NULL,
3332 			    (time_t) 0, e);
3333 	}
3334 	e->e_to = NULL;
3335 }
3336 /*
3337 **  CHECKSMTPATTACK -- check for denial-of-service attack by repetition
3338 **
3339 **	Parameters:
3340 **		pcounter -- pointer to a counter for this command.
3341 **		maxcount -- maximum value for this counter before we
3342 **			slow down.
3343 **		waitnow -- sleep now (in this routine)?
3344 **		cname -- command name for logging.
3345 **		e -- the current envelope.
3346 **
3347 **	Returns:
3348 **		time to wait.
3349 **
3350 **	Side Effects:
3351 **		Slows down if we seem to be under attack.
3352 */
3353 
3354 static time_t
3355 checksmtpattack(pcounter, maxcount, waitnow, cname, e)
3356 	volatile unsigned int *pcounter;
3357 	int maxcount;
3358 	bool waitnow;
3359 	char *cname;
3360 	ENVELOPE *e;
3361 {
3362 	if (maxcount <= 0)	/* no limit */
3363 		return (time_t) 0;
3364 
3365 	if (++(*pcounter) >= maxcount)
3366 	{
3367 		time_t s;
3368 
3369 		if (*pcounter == maxcount && LogLevel > 5)
3370 		{
3371 			sm_syslog(LOG_INFO, e->e_id,
3372 				  "%s: possible SMTP attack: command=%.40s, count=%u",
3373 				  CurSmtpClient, cname, *pcounter);
3374 		}
3375 		s = 1 << (*pcounter - maxcount);
3376 		if (s >= MAXTIMEOUT || s <= 0)
3377 			s = MAXTIMEOUT;
3378 
3379 		/* sleep at least 1 second before returning */
3380 		(void) sleep(*pcounter / maxcount);
3381 		s -= *pcounter / maxcount;
3382 		if (waitnow)
3383 		{
3384 			(void) sleep(s);
3385 			return 0;
3386 		}
3387 		return s;
3388 	}
3389 	return (time_t) 0;
3390 }
3391 /*
3392 **  SETUP_SMTPD_IO -- setup I/O fd correctly for the SMTP server
3393 **
3394 **	Parameters:
3395 **		none.
3396 **
3397 **	Returns:
3398 **		nothing.
3399 **
3400 **	Side Effects:
3401 **		may change I/O fd.
3402 */
3403 
3404 static void
3405 setup_smtpd_io()
3406 {
3407 	int inchfd, outchfd, outfd;
3408 
3409 	inchfd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
3410 	outchfd  = sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL);
3411 	outfd = sm_io_getinfo(smioout, SM_IO_WHAT_FD, NULL);
3412 	if (outchfd != outfd)
3413 	{
3414 		/* arrange for debugging output to go to remote host */
3415 		(void) dup2(outchfd, outfd);
3416 	}
3417 
3418 	/*
3419 	**  if InChannel and OutChannel are stdin/stdout
3420 	**  and connected to ttys
3421 	**  and fcntl(STDIN, F_SETFL, O_NONBLOCKING) also changes STDOUT,
3422 	**  then "chain" them together.
3423 	*/
3424 
3425 	if (inchfd == STDIN_FILENO && outchfd == STDOUT_FILENO &&
3426 	    isatty(inchfd) && isatty(outchfd))
3427 	{
3428 		int inmode, outmode;
3429 
3430 		inmode = fcntl(inchfd, F_GETFL, 0);
3431 		if (inmode == -1)
3432 		{
3433 			if (LogLevel > 11)
3434 				sm_syslog(LOG_INFO, NOQID,
3435 					"fcntl(inchfd, F_GETFL) failed: %s",
3436 					sm_errstring(errno));
3437 			return;
3438 		}
3439 		outmode = fcntl(outchfd, F_GETFL, 0);
3440 		if (outmode == -1)
3441 		{
3442 			if (LogLevel > 11)
3443 				sm_syslog(LOG_INFO, NOQID,
3444 					"fcntl(outchfd, F_GETFL) failed: %s",
3445 					sm_errstring(errno));
3446 			return;
3447 		}
3448 		if (bitset(O_NONBLOCK, inmode) ||
3449 		    bitset(O_NONBLOCK, outmode) ||
3450 		    fcntl(inchfd, F_SETFL, inmode | O_NONBLOCK) == -1)
3451 			return;
3452 		outmode = fcntl(outchfd, F_GETFL, 0);
3453 		if (outmode != -1 && bitset(O_NONBLOCK, outmode))
3454 		{
3455 			/* changing InChannel also changes OutChannel */
3456 			sm_io_automode(OutChannel, InChannel);
3457 			if (tTd(97, 4) && LogLevel > 9)
3458 				sm_syslog(LOG_INFO, NOQID,
3459 					  "set automode for I (%d)/O (%d) in SMTP server",
3460 					  inchfd, outchfd);
3461 		}
3462 
3463 		/* undo change of inchfd */
3464 		(void) fcntl(inchfd, F_SETFL, inmode);
3465 	}
3466 }
3467 /*
3468 **  SKIPWORD -- skip a fixed word.
3469 **
3470 **	Parameters:
3471 **		p -- place to start looking.
3472 **		w -- word to skip.
3473 **
3474 **	Returns:
3475 **		p following w.
3476 **		NULL on error.
3477 **
3478 **	Side Effects:
3479 **		clobbers the p data area.
3480 */
3481 
3482 static char *
3483 skipword(p, w)
3484 	register char *volatile p;
3485 	char *w;
3486 {
3487 	register char *q;
3488 	char *firstp = p;
3489 
3490 	/* find beginning of word */
3491 	SKIP_SPACE(p);
3492 	q = p;
3493 
3494 	/* find end of word */
3495 	while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p)))
3496 		p++;
3497 	while (isascii(*p) && isspace(*p))
3498 		*p++ = '\0';
3499 	if (*p != ':')
3500 	{
3501 	  syntax:
3502 		usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"",
3503 			shortenstring(firstp, MAXSHORTSTR));
3504 		return NULL;
3505 	}
3506 	*p++ = '\0';
3507 	SKIP_SPACE(p);
3508 
3509 	if (*p == '\0')
3510 		goto syntax;
3511 
3512 	/* see if the input word matches desired word */
3513 	if (sm_strcasecmp(q, w))
3514 		goto syntax;
3515 
3516 	return p;
3517 }
3518 /*
3519 **  MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
3520 **
3521 **	Parameters:
3522 **		kp -- the parameter key.
3523 **		vp -- the value of that parameter.
3524 **		e -- the envelope.
3525 **
3526 **	Returns:
3527 **		none.
3528 */
3529 
3530 static void
3531 mail_esmtp_args(kp, vp, e)
3532 	char *kp;
3533 	char *vp;
3534 	ENVELOPE *e;
3535 {
3536 	if (sm_strcasecmp(kp, "size") == 0)
3537 	{
3538 		if (vp == NULL)
3539 		{
3540 			usrerr("501 5.5.2 SIZE requires a value");
3541 			/* NOTREACHED */
3542 		}
3543 		macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), vp);
3544 		errno = 0;
3545 		e->e_msgsize = strtol(vp, (char **) NULL, 10);
3546 		if (e->e_msgsize == LONG_MAX && errno == ERANGE)
3547 		{
3548 			usrerr("552 5.2.3 Message size exceeds maximum value");
3549 			/* NOTREACHED */
3550 		}
3551 		if (e->e_msgsize < 0)
3552 		{
3553 			usrerr("552 5.2.3 Message size invalid");
3554 			/* NOTREACHED */
3555 		}
3556 	}
3557 	else if (sm_strcasecmp(kp, "body") == 0)
3558 	{
3559 		if (vp == NULL)
3560 		{
3561 			usrerr("501 5.5.2 BODY requires a value");
3562 			/* NOTREACHED */
3563 		}
3564 		else if (sm_strcasecmp(vp, "8bitmime") == 0)
3565 		{
3566 			SevenBitInput = false;
3567 		}
3568 		else if (sm_strcasecmp(vp, "7bit") == 0)
3569 		{
3570 			SevenBitInput = true;
3571 		}
3572 		else
3573 		{
3574 			usrerr("501 5.5.4 Unknown BODY type %s", vp);
3575 			/* NOTREACHED */
3576 		}
3577 		e->e_bodytype = sm_rpool_strdup_x(e->e_rpool, vp);
3578 	}
3579 	else if (sm_strcasecmp(kp, "envid") == 0)
3580 	{
3581 		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3582 		{
3583 			usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN");
3584 			/* NOTREACHED */
3585 		}
3586 		if (vp == NULL)
3587 		{
3588 			usrerr("501 5.5.2 ENVID requires a value");
3589 			/* NOTREACHED */
3590 		}
3591 		if (!xtextok(vp))
3592 		{
3593 			usrerr("501 5.5.4 Syntax error in ENVID parameter value");
3594 			/* NOTREACHED */
3595 		}
3596 		if (e->e_envid != NULL)
3597 		{
3598 			usrerr("501 5.5.0 Duplicate ENVID parameter");
3599 			/* NOTREACHED */
3600 		}
3601 		e->e_envid = sm_rpool_strdup_x(e->e_rpool, vp);
3602 		macdefine(&e->e_macro, A_PERM,
3603 			macid("{dsn_envid}"), e->e_envid);
3604 	}
3605 	else if (sm_strcasecmp(kp, "ret") == 0)
3606 	{
3607 		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3608 		{
3609 			usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN");
3610 			/* NOTREACHED */
3611 		}
3612 		if (vp == NULL)
3613 		{
3614 			usrerr("501 5.5.2 RET requires a value");
3615 			/* NOTREACHED */
3616 		}
3617 		if (bitset(EF_RET_PARAM, e->e_flags))
3618 		{
3619 			usrerr("501 5.5.0 Duplicate RET parameter");
3620 			/* NOTREACHED */
3621 		}
3622 		e->e_flags |= EF_RET_PARAM;
3623 		if (sm_strcasecmp(vp, "hdrs") == 0)
3624 			e->e_flags |= EF_NO_BODY_RETN;
3625 		else if (sm_strcasecmp(vp, "full") != 0)
3626 		{
3627 			usrerr("501 5.5.2 Bad argument \"%s\" to RET", vp);
3628 			/* NOTREACHED */
3629 		}
3630 		macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), vp);
3631 	}
3632 #if SASL
3633 	else if (sm_strcasecmp(kp, "auth") == 0)
3634 	{
3635 		int len;
3636 		char *q;
3637 		char *auth_param;	/* the value of the AUTH=x */
3638 		bool saveQuickAbort = QuickAbort;
3639 		bool saveSuprErrs = SuprErrs;
3640 		bool saveExitStat = ExitStat;
3641 		char pbuf[256];
3642 
3643 		if (vp == NULL)
3644 		{
3645 			usrerr("501 5.5.2 AUTH= requires a value");
3646 			/* NOTREACHED */
3647 		}
3648 		if (e->e_auth_param != NULL)
3649 		{
3650 			usrerr("501 5.5.0 Duplicate AUTH parameter");
3651 			/* NOTREACHED */
3652 		}
3653 		if ((q = strchr(vp, ' ')) != NULL)
3654 			len = q - vp + 1;
3655 		else
3656 			len = strlen(vp) + 1;
3657 		auth_param = xalloc(len);
3658 		(void) sm_strlcpy(auth_param, vp, len);
3659 		if (!xtextok(auth_param))
3660 		{
3661 			usrerr("501 5.5.4 Syntax error in AUTH parameter value");
3662 			/* just a warning? */
3663 			/* NOTREACHED */
3664 		}
3665 
3666 		/* XXX this might be cut off */
3667 		(void) sm_strlcpy(pbuf, xuntextify(auth_param), sizeof pbuf);
3668 		/* xalloc() the buffer instead? */
3669 
3670 		/* XXX define this always or only if trusted? */
3671 		macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), pbuf);
3672 
3673 		/*
3674 		**  call Strust_auth to find out whether
3675 		**  auth_param is acceptable (trusted)
3676 		**  we shouldn't trust it if not authenticated
3677 		**  (required by RFC, leave it to ruleset?)
3678 		*/
3679 
3680 		SuprErrs = true;
3681 		QuickAbort = false;
3682 		if (strcmp(auth_param, "<>") != 0 &&
3683 		     (rscheck("trust_auth", pbuf, NULL, e, RSF_RMCOMM,
3684 			      9, NULL, NOQID) != EX_OK || Errors > 0))
3685 		{
3686 			if (tTd(95, 8))
3687 			{
3688 				q = e->e_auth_param;
3689 				sm_dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n",
3690 					pbuf, (q == NULL) ? "" : q);
3691 			}
3692 
3693 			/* not trusted */
3694 			e->e_auth_param = "<>";
3695 # if _FFR_AUTH_PASSING
3696 			macdefine(&BlankEnvelope.e_macro, A_PERM,
3697 				  macid("{auth_author}"), NULL);
3698 # endif /* _FFR_AUTH_PASSING */
3699 		}
3700 		else
3701 		{
3702 			if (tTd(95, 8))
3703 				sm_dprintf("auth=\"%.100s\" trusted\n", pbuf);
3704 			e->e_auth_param = sm_rpool_strdup_x(e->e_rpool,
3705 							    auth_param);
3706 		}
3707 		sm_free(auth_param); /* XXX */
3708 
3709 		/* reset values */
3710 		Errors = 0;
3711 		QuickAbort = saveQuickAbort;
3712 		SuprErrs = saveSuprErrs;
3713 		ExitStat = saveExitStat;
3714 	}
3715 #endif /* SASL */
3716 #define PRTCHAR(c)	((isascii(c) && isprint(c)) ? (c) : '?')
3717 
3718 	/*
3719 	**  "by" is only accepted if DeliverByMin >= 0.
3720 	**  We maybe could add this to the list of server_features.
3721 	*/
3722 
3723 	else if (sm_strcasecmp(kp, "by") == 0 && DeliverByMin >= 0)
3724 	{
3725 		char *s;
3726 
3727 		if (vp == NULL)
3728 		{
3729 			usrerr("501 5.5.2 BY= requires a value");
3730 			/* NOTREACHED */
3731 		}
3732 		errno = 0;
3733 		e->e_deliver_by = strtol(vp, &s, 10);
3734 		if (e->e_deliver_by == LONG_MIN ||
3735 		    e->e_deliver_by == LONG_MAX ||
3736 		    e->e_deliver_by > 999999999l ||
3737 		    e->e_deliver_by < -999999999l)
3738 		{
3739 			usrerr("501 5.5.2 BY=%s out of range", vp);
3740 			/* NOTREACHED */
3741 		}
3742 		if (s == NULL || *s != ';')
3743 		{
3744 			usrerr("501 5.5.2 BY= missing ';'");
3745 			/* NOTREACHED */
3746 		}
3747 		e->e_dlvr_flag = 0;
3748 		++s;	/* XXX: spaces allowed? */
3749 		SKIP_SPACE(s);
3750 		switch (tolower(*s))
3751 		{
3752 		  case 'n':
3753 			e->e_dlvr_flag = DLVR_NOTIFY;
3754 			break;
3755 		  case 'r':
3756 			e->e_dlvr_flag = DLVR_RETURN;
3757 			if (e->e_deliver_by <= 0)
3758 			{
3759 				usrerr("501 5.5.4 mode R requires BY time > 0");
3760 				/* NOTREACHED */
3761 			}
3762 			if (DeliverByMin > 0 && e->e_deliver_by > 0 &&
3763 			    e->e_deliver_by < DeliverByMin)
3764 			{
3765 				usrerr("555 5.5.2 time %ld less than %ld",
3766 					e->e_deliver_by, (long) DeliverByMin);
3767 				/* NOTREACHED */
3768 			}
3769 			break;
3770 		  default:
3771 			usrerr("501 5.5.2 illegal by-mode '%c'", PRTCHAR(*s));
3772 			/* NOTREACHED */
3773 		}
3774 		++s;	/* XXX: spaces allowed? */
3775 		SKIP_SPACE(s);
3776 		switch (tolower(*s))
3777 		{
3778 		  case 't':
3779 			e->e_dlvr_flag |= DLVR_TRACE;
3780 			break;
3781 		  case '\0':
3782 			break;
3783 		  default:
3784 			usrerr("501 5.5.2 illegal by-trace '%c'", PRTCHAR(*s));
3785 			/* NOTREACHED */
3786 		}
3787 
3788 		/* XXX: check whether more characters follow? */
3789 	}
3790 	else
3791 	{
3792 		usrerr("555 5.5.4 %s parameter unrecognized", kp);
3793 		/* NOTREACHED */
3794 	}
3795 }
3796 /*
3797 **  RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
3798 **
3799 **	Parameters:
3800 **		a -- the address corresponding to the To: parameter.
3801 **		kp -- the parameter key.
3802 **		vp -- the value of that parameter.
3803 **		e -- the envelope.
3804 **
3805 **	Returns:
3806 **		none.
3807 */
3808 
3809 static void
3810 rcpt_esmtp_args(a, kp, vp, e)
3811 	ADDRESS *a;
3812 	char *kp;
3813 	char *vp;
3814 	ENVELOPE *e;
3815 {
3816 	if (sm_strcasecmp(kp, "notify") == 0)
3817 	{
3818 		char *p;
3819 
3820 		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3821 		{
3822 			usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
3823 			/* NOTREACHED */
3824 		}
3825 		if (vp == NULL)
3826 		{
3827 			usrerr("501 5.5.2 NOTIFY requires a value");
3828 			/* NOTREACHED */
3829 		}
3830 		a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY);
3831 		a->q_flags |= QHASNOTIFY;
3832 		macdefine(&e->e_macro, A_TEMP, macid("{dsn_notify}"), vp);
3833 
3834 		if (sm_strcasecmp(vp, "never") == 0)
3835 			return;
3836 		for (p = vp; p != NULL; vp = p)
3837 		{
3838 			p = strchr(p, ',');
3839 			if (p != NULL)
3840 				*p++ = '\0';
3841 			if (sm_strcasecmp(vp, "success") == 0)
3842 				a->q_flags |= QPINGONSUCCESS;
3843 			else if (sm_strcasecmp(vp, "failure") == 0)
3844 				a->q_flags |= QPINGONFAILURE;
3845 			else if (sm_strcasecmp(vp, "delay") == 0)
3846 				a->q_flags |= QPINGONDELAY;
3847 			else
3848 			{
3849 				usrerr("501 5.5.4 Bad argument \"%s\"  to NOTIFY",
3850 					vp);
3851 				/* NOTREACHED */
3852 			}
3853 		}
3854 	}
3855 	else if (sm_strcasecmp(kp, "orcpt") == 0)
3856 	{
3857 		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
3858 		{
3859 			usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN");
3860 			/* NOTREACHED */
3861 		}
3862 		if (vp == NULL)
3863 		{
3864 			usrerr("501 5.5.2 ORCPT requires a value");
3865 			/* NOTREACHED */
3866 		}
3867 		if (strchr(vp, ';') == NULL || !xtextok(vp))
3868 		{
3869 			usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
3870 			/* NOTREACHED */
3871 		}
3872 		if (a->q_orcpt != NULL)
3873 		{
3874 			usrerr("501 5.5.0 Duplicate ORCPT parameter");
3875 			/* NOTREACHED */
3876 		}
3877 		a->q_orcpt = sm_rpool_strdup_x(e->e_rpool, vp);
3878 	}
3879 	else
3880 	{
3881 		usrerr("555 5.5.4 %s parameter unrecognized", kp);
3882 		/* NOTREACHED */
3883 	}
3884 }
3885 /*
3886 **  PRINTVRFYADDR -- print an entry in the verify queue
3887 **
3888 **	Parameters:
3889 **		a -- the address to print.
3890 **		last -- set if this is the last one.
3891 **		vrfy -- set if this is a VRFY command.
3892 **
3893 **	Returns:
3894 **		none.
3895 **
3896 **	Side Effects:
3897 **		Prints the appropriate 250 codes.
3898 */
3899 #define OFFF	(3 + 1 + 5 + 1)	/* offset in fmt: SMTP reply + enh. code */
3900 
3901 static void
3902 printvrfyaddr(a, last, vrfy)
3903 	register ADDRESS *a;
3904 	bool last;
3905 	bool vrfy;
3906 {
3907 	char fmtbuf[30];
3908 
3909 	if (vrfy && a->q_mailer != NULL &&
3910 	    !bitnset(M_VRFY250, a->q_mailer->m_flags))
3911 		(void) sm_strlcpy(fmtbuf, "252", sizeof fmtbuf);
3912 	else
3913 		(void) sm_strlcpy(fmtbuf, "250", sizeof fmtbuf);
3914 	fmtbuf[3] = last ? ' ' : '-';
3915 	(void) sm_strlcpy(&fmtbuf[4], "2.1.5 ", sizeof fmtbuf - 4);
3916 	if (a->q_fullname == NULL)
3917 	{
3918 		if ((a->q_mailer == NULL ||
3919 		     a->q_mailer->m_addrtype == NULL ||
3920 		     sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
3921 		    strchr(a->q_user, '@') == NULL)
3922 			(void) sm_strlcpy(&fmtbuf[OFFF], "<%s@%s>",
3923 				       sizeof fmtbuf - OFFF);
3924 		else
3925 			(void) sm_strlcpy(&fmtbuf[OFFF], "<%s>",
3926 				       sizeof fmtbuf - OFFF);
3927 		message(fmtbuf, a->q_user, MyHostName);
3928 	}
3929 	else
3930 	{
3931 		if ((a->q_mailer == NULL ||
3932 		     a->q_mailer->m_addrtype == NULL ||
3933 		     sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
3934 		    strchr(a->q_user, '@') == NULL)
3935 			(void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s@%s>",
3936 				       sizeof fmtbuf - OFFF);
3937 		else
3938 			(void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s>",
3939 				       sizeof fmtbuf - OFFF);
3940 		message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
3941 	}
3942 }
3943 
3944 #if SASL
3945 /*
3946 **  SASLMECHS -- get list of possible AUTH mechanisms
3947 **
3948 **	Parameters:
3949 **		conn -- SASL connection info.
3950 **		mechlist -- output parameter for list of mechanisms.
3951 **
3952 **	Returns:
3953 **		number of mechs.
3954 */
3955 
3956 static int
3957 saslmechs(conn, mechlist)
3958 	sasl_conn_t *conn;
3959 	char **mechlist;
3960 {
3961 	int len, num, result;
3962 
3963 	/* "user" is currently unused */
3964 # if SASL >= 20000
3965 	result = sasl_listmech(conn, NULL,
3966 			       "", " ", "", (const char **) mechlist,
3967 			       (unsigned int *)&len, (unsigned int *)&num);
3968 # else /* SASL >= 20000 */
3969 	result = sasl_listmech(conn, "user", /* XXX */
3970 			       "", " ", "", mechlist,
3971 			       (unsigned int *)&len, (unsigned int *)&num);
3972 # endif /* SASL >= 20000 */
3973 	if (result != SASL_OK)
3974 	{
3975 		if (LogLevel > 9)
3976 			sm_syslog(LOG_WARNING, NOQID,
3977 				  "AUTH error: listmech=%d, num=%d",
3978 				  result, num);
3979 		num = 0;
3980 	}
3981 	if (num > 0)
3982 	{
3983 		if (LogLevel > 11)
3984 			sm_syslog(LOG_INFO, NOQID,
3985 				  "AUTH: available mech=%s, allowed mech=%s",
3986 				  *mechlist, AuthMechanisms);
3987 		*mechlist = intersect(AuthMechanisms, *mechlist, NULL);
3988 	}
3989 	else
3990 	{
3991 		*mechlist = NULL;	/* be paranoid... */
3992 		if (result == SASL_OK && LogLevel > 9)
3993 			sm_syslog(LOG_WARNING, NOQID,
3994 				  "AUTH warning: no mechanisms");
3995 	}
3996 	return num;
3997 }
3998 
3999 # if SASL >= 20000
4000 /*
4001 **  PROXY_POLICY -- define proxy policy for AUTH
4002 **
4003 **	Parameters:
4004 **		conn -- unused.
4005 **		context -- unused.
4006 **		requested_user -- authorization identity.
4007 **		rlen -- authorization identity length.
4008 **		auth_identity -- authentication identity.
4009 **		alen -- authentication identity length.
4010 **		def_realm -- default user realm.
4011 **		urlen -- user realm length.
4012 **		propctx -- unused.
4013 **
4014 **	Returns:
4015 **		ok?
4016 **
4017 **	Side Effects:
4018 **		sets {auth_authen} macro.
4019 */
4020 
4021 int
4022 proxy_policy(conn, context, requested_user, rlen, auth_identity, alen,
4023 	     def_realm, urlen, propctx)
4024 	sasl_conn_t *conn;
4025 	void *context;
4026 	const char *requested_user;
4027 	unsigned rlen;
4028 	const char *auth_identity;
4029 	unsigned alen;
4030 	const char *def_realm;
4031 	unsigned urlen;
4032 	struct propctx *propctx;
4033 {
4034 	if (auth_identity == NULL)
4035 		return SASL_FAIL;
4036 
4037 	macdefine(&BlankEnvelope.e_macro, A_TEMP,
4038 		  macid("{auth_authen}"), (char *) auth_identity);
4039 
4040 	return SASL_OK;
4041 }
4042 # else /* SASL >= 20000 */
4043 
4044 /*
4045 **  PROXY_POLICY -- define proxy policy for AUTH
4046 **
4047 **	Parameters:
4048 **		context -- unused.
4049 **		auth_identity -- authentication identity.
4050 **		requested_user -- authorization identity.
4051 **		user -- allowed user (output).
4052 **		errstr -- possible error string (output).
4053 **
4054 **	Returns:
4055 **		ok?
4056 */
4057 
4058 int
4059 proxy_policy(context, auth_identity, requested_user, user, errstr)
4060 	void *context;
4061 	const char *auth_identity;
4062 	const char *requested_user;
4063 	const char **user;
4064 	const char **errstr;
4065 {
4066 	if (user == NULL || auth_identity == NULL)
4067 		return SASL_FAIL;
4068 	*user = newstr(auth_identity);
4069 	return SASL_OK;
4070 }
4071 # endif /* SASL >= 20000 */
4072 #endif /* SASL */
4073 
4074 #if STARTTLS
4075 /*
4076 **  INITSRVTLS -- initialize server side TLS
4077 **
4078 **	Parameters:
4079 **		tls_ok -- should tls initialization be done?
4080 **
4081 **	Returns:
4082 **		succeeded?
4083 **
4084 **	Side Effects:
4085 **		sets tls_ok_srv which is a static variable in this module.
4086 **		Do NOT remove assignments to it!
4087 */
4088 
4089 bool
4090 initsrvtls(tls_ok)
4091 	bool tls_ok;
4092 {
4093 	if (!tls_ok)
4094 		return false;
4095 
4096 	/* do NOT remove assignment */
4097 	tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, true, SrvCertFile,
4098 			     SrvKeyFile, CACertPath, CACertFile, DHParams);
4099 	return tls_ok_srv;
4100 }
4101 #endif /* STARTTLS */
4102 /*
4103 **  SRVFEATURES -- get features for SMTP server
4104 **
4105 **	Parameters:
4106 **		e -- envelope (should be session context).
4107 **		clientname -- name of client.
4108 **		features -- default features for this invocation.
4109 **
4110 **	Returns:
4111 **		server features.
4112 */
4113 
4114 /* table with options: it uses just one character, how about strings? */
4115 static struct
4116 {
4117 	char		srvf_opt;
4118 	unsigned int	srvf_flag;
4119 } srv_feat_table[] =
4120 {
4121 	{ 'A',	SRV_OFFER_AUTH	},
4122 	{ 'B',	SRV_OFFER_VERB	},	/* FFR; not documented in 8.12 */
4123 	{ 'D',	SRV_OFFER_DSN	},	/* FFR; not documented in 8.12 */
4124 	{ 'E',	SRV_OFFER_ETRN	},	/* FFR; not documented in 8.12 */
4125 	{ 'L',	SRV_REQ_AUTH	},	/* FFR; not documented in 8.12 */
4126 #if PIPELINING
4127 # if _FFR_NO_PIPE
4128 	{ 'N',	SRV_NO_PIPE	},
4129 # endif /* _FFR_NO_PIPE */
4130 	{ 'P',	SRV_OFFER_PIPE	},
4131 #endif /* PIPELINING */
4132 	{ 'R',	SRV_VRFY_CLT	},	/* FFR; not documented in 8.12 */
4133 	{ 'S',	SRV_OFFER_TLS	},
4134 /*	{ 'T',	SRV_TMP_FAIL	},	*/
4135 	{ 'V',	SRV_VRFY_CLT	},
4136 	{ 'X',	SRV_OFFER_EXPN	},	/* FFR; not documented in 8.12 */
4137 /*	{ 'Y',	SRV_OFFER_VRFY	},	*/
4138 	{ '\0',	SRV_NONE	}
4139 };
4140 
4141 static unsigned int
4142 srvfeatures(e, clientname, features)
4143 	ENVELOPE *e;
4144 	char *clientname;
4145 	unsigned int features;
4146 {
4147 	int r, i, j;
4148 	char **pvp, c, opt;
4149 	char pvpbuf[PSBUFSIZE];
4150 
4151 	pvp = NULL;
4152 	r = rscap("srv_features", clientname, "", e, &pvp, pvpbuf,
4153 		  sizeof(pvpbuf));
4154 	if (r != EX_OK)
4155 		return features;
4156 	if (pvp == NULL || pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
4157 		return features;
4158 	if (pvp[1] != NULL && sm_strncasecmp(pvp[1], "temp", 4) == 0)
4159 		return SRV_TMP_FAIL;
4160 
4161 	/*
4162 	**  General rule (see sendmail.h, d_flags):
4163 	**  lower case: required/offered, upper case: Not required/available
4164 	**
4165 	**  Since we can change some features per daemon, we have both
4166 	**  cases here: turn on/off a feature.
4167 	*/
4168 
4169 	for (i = 1; pvp[i] != NULL; i++)
4170 	{
4171 		c = pvp[i][0];
4172 		j = 0;
4173 		for (;;)
4174 		{
4175 			if ((opt = srv_feat_table[j].srvf_opt) == '\0')
4176 			{
4177 				if (LogLevel > 9)
4178 					sm_syslog(LOG_WARNING, e->e_id,
4179 						  "srvfeatures: unknown feature %s",
4180 						  pvp[i]);
4181 				break;
4182 			}
4183 			if (c == opt)
4184 			{
4185 				features &= ~(srv_feat_table[j].srvf_flag);
4186 				break;
4187 			}
4188 			if (c == tolower(opt))
4189 			{
4190 				features |= srv_feat_table[j].srvf_flag;
4191 				break;
4192 			}
4193 			++j;
4194 		}
4195 	}
4196 	return features;
4197 }
4198 
4199 /*
4200 **  HELP -- implement the HELP command.
4201 **
4202 **	Parameters:
4203 **		topic -- the topic we want help for.
4204 **		e -- envelope.
4205 **
4206 **	Returns:
4207 **		none.
4208 **
4209 **	Side Effects:
4210 **		outputs the help file to message output.
4211 */
4212 #define HELPVSTR	"#vers	"
4213 #define HELPVERSION	2
4214 
4215 void
4216 help(topic, e)
4217 	char *topic;
4218 	ENVELOPE *e;
4219 {
4220 	register SM_FILE_T *hf;
4221 	register char *p;
4222 	int len;
4223 	bool noinfo;
4224 	bool first = true;
4225 	long sff = SFF_OPENASROOT|SFF_REGONLY;
4226 	char buf[MAXLINE];
4227 	char inp[MAXLINE];
4228 	static int foundvers = -1;
4229 	extern char Version[];
4230 
4231 	if (DontLockReadFiles)
4232 		sff |= SFF_NOLOCK;
4233 	if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH, DontBlameSendmail))
4234 		sff |= SFF_SAFEDIRPATH;
4235 
4236 	if (HelpFile == NULL ||
4237 	    (hf = safefopen(HelpFile, O_RDONLY, 0444, sff)) == NULL)
4238 	{
4239 		/* no help */
4240 		errno = 0;
4241 		message("502 5.3.0 Sendmail %s -- HELP not implemented",
4242 			Version);
4243 		return;
4244 	}
4245 
4246 	if (topic == NULL || *topic == '\0')
4247 	{
4248 		topic = "smtp";
4249 		noinfo = false;
4250 	}
4251 	else
4252 	{
4253 		makelower(topic);
4254 		noinfo = true;
4255 	}
4256 
4257 	len = strlen(topic);
4258 
4259 	while (sm_io_fgets(hf, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
4260 	{
4261 		if (buf[0] == '#')
4262 		{
4263 			if (foundvers < 0 &&
4264 			    strncmp(buf, HELPVSTR, strlen(HELPVSTR)) == 0)
4265 			{
4266 				int h;
4267 
4268 				if (sm_io_sscanf(buf + strlen(HELPVSTR), "%d",
4269 						 &h) == 1)
4270 					foundvers = h;
4271 			}
4272 			continue;
4273 		}
4274 		if (strncmp(buf, topic, len) == 0)
4275 		{
4276 			if (first)
4277 			{
4278 				first = false;
4279 
4280 				/* print version if no/old vers# in file */
4281 				if (foundvers < 2 && !noinfo)
4282 					message("214-2.0.0 This is Sendmail version %s", Version);
4283 			}
4284 			p = strpbrk(buf, " \t");
4285 			if (p == NULL)
4286 				p = buf + strlen(buf) - 1;
4287 			else
4288 				p++;
4289 			fixcrlf(p, true);
4290 			if (foundvers >= 2)
4291 			{
4292 				translate_dollars(p);
4293 				expand(p, inp, sizeof inp, e);
4294 				p = inp;
4295 			}
4296 			message("214-2.0.0 %s", p);
4297 			noinfo = false;
4298 		}
4299 	}
4300 
4301 	if (noinfo)
4302 		message("504 5.3.0 HELP topic \"%.10s\" unknown", topic);
4303 	else
4304 		message("214 2.0.0 End of HELP info");
4305 
4306 	if (foundvers != 0 && foundvers < HELPVERSION)
4307 	{
4308 		if (LogLevel > 1)
4309 			sm_syslog(LOG_WARNING, e->e_id,
4310 				  "%s too old (require version %d)",
4311 				  HelpFile, HELPVERSION);
4312 
4313 		/* avoid log next time */
4314 		foundvers = 0;
4315 	}
4316 
4317 	(void) sm_io_close(hf, SM_TIME_DEFAULT);
4318 }
4319