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