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