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