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