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