srvrsmtp.c revision 64562
1/*
2 * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
3 *	All rights reserved.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5 * Copyright (c) 1988, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
14
15#include <sendmail.h>
16
17#ifndef lint
18# if SMTP
19static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.40 2000/07/18 02:24:45 gshapiro Exp $ (with SMTP)";
20# else /* SMTP */
21static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.40 2000/07/18 02:24:45 gshapiro Exp $ (without SMTP)";
22# endif /* SMTP */
23#endif /* ! lint */
24
25#if SMTP
26# include "sfsasl.h"
27# if SASL
28#  define ENC64LEN(l)	(((l) + 2) * 4 / 3 + 1)
29static int saslmechs __P((sasl_conn_t *, char **));
30# endif /* SASL */
31# if STARTTLS
32#  include <sysexits.h>
33#   include <openssl/err.h>
34#   include <openssl/bio.h>
35#   include <openssl/pem.h>
36#   ifndef HASURANDOMDEV
37#    include <openssl/rand.h>
38#   endif /* !HASURANDOMDEV */
39
40static SSL	*srv_ssl = NULL;
41static SSL_CTX	*srv_ctx = NULL;
42#  if !TLS_NO_RSA
43static RSA	*rsa = NULL;
44#  endif /* !TLS_NO_RSA */
45static bool	tls_ok = FALSE;
46static int	tls_verify_cb __P((X509_STORE_CTX *));
47#  if !TLS_NO_RSA
48#   define RSA_KEYLENGTH	512
49#  endif /* !TLS_NO_RSA */
50# endif /* STARTTLS */
51
52static time_t	checksmtpattack __P((volatile int *, int, bool,
53				     char *, ENVELOPE *));
54static void	mail_esmtp_args __P((char *, char *, ENVELOPE *));
55static void	printvrfyaddr __P((ADDRESS *, bool, bool));
56static void	rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *));
57static int	runinchild __P((char *, ENVELOPE *));
58static char	*skipword __P((char *volatile, char *));
59extern ENVELOPE	BlankEnvelope;
60
61/*
62**  SMTP -- run the SMTP protocol.
63**
64**	Parameters:
65**		nullserver -- if non-NULL, rejection message for
66**			all SMTP commands.
67**		e -- the envelope.
68**
69**	Returns:
70**		never.
71**
72**	Side Effects:
73**		Reads commands from the input channel and processes
74**			them.
75*/
76
77struct cmd
78{
79	char	*cmd_name;	/* command name */
80	int	cmd_code;	/* internal code, see below */
81};
82
83/* values for cmd_code */
84# define CMDERROR	0	/* bad command */
85# define CMDMAIL	1	/* mail -- designate sender */
86# define CMDRCPT	2	/* rcpt -- designate recipient */
87# define CMDDATA	3	/* data -- send message text */
88# define CMDRSET	4	/* rset -- reset state */
89# define CMDVRFY	5	/* vrfy -- verify address */
90# define CMDEXPN	6	/* expn -- expand address */
91# define CMDNOOP	7	/* noop -- do nothing */
92# define CMDQUIT	8	/* quit -- close connection and die */
93# define CMDHELO	9	/* helo -- be polite */
94# define CMDHELP	10	/* help -- give usage info */
95# define CMDEHLO	11	/* ehlo -- extended helo (RFC 1425) */
96# define CMDETRN	12	/* etrn -- flush queue */
97# if SASL
98#  define CMDAUTH	13	/* auth -- SASL authenticate */
99# endif /* SASL */
100# if STARTTLS
101#  define CMDSTLS	14	/* STARTTLS -- start TLS session */
102# endif /* STARTTLS */
103/* non-standard commands */
104# define CMDONEX	16	/* onex -- sending one transaction only */
105# define CMDVERB	17	/* verb -- go into verbose mode */
106# define CMDXUSR	18	/* xusr -- initial (user) submission */
107/* unimplemented commands from RFC 821 */
108# define CMDUNIMPL	19	/* unimplemented rfc821 commands */
109/* use this to catch and log "door handle" attempts on your system */
110# define CMDLOGBOGUS	23	/* bogus command that should be logged */
111/* debugging-only commands, only enabled if SMTPDEBUG is defined */
112# define CMDDBGQSHOW	24	/* showq -- show send queue */
113# define CMDDBGDEBUG	25	/* debug -- set debug mode */
114
115static struct cmd	CmdTab[] =
116{
117	{ "mail",	CMDMAIL		},
118	{ "rcpt",	CMDRCPT		},
119	{ "data",	CMDDATA		},
120	{ "rset",	CMDRSET		},
121	{ "vrfy",	CMDVRFY		},
122	{ "expn",	CMDEXPN		},
123	{ "help",	CMDHELP		},
124	{ "noop",	CMDNOOP		},
125	{ "quit",	CMDQUIT		},
126	{ "helo",	CMDHELO		},
127	{ "ehlo",	CMDEHLO		},
128	{ "etrn",	CMDETRN		},
129	{ "verb",	CMDVERB		},
130	{ "onex",	CMDONEX		},
131	{ "xusr",	CMDXUSR		},
132	{ "send",	CMDUNIMPL	},
133	{ "saml",	CMDUNIMPL	},
134	{ "soml",	CMDUNIMPL	},
135	{ "turn",	CMDUNIMPL	},
136# if SASL
137	{ "auth",	CMDAUTH,	},
138# endif /* SASL */
139# if STARTTLS
140	{ "starttls",	CMDSTLS,	},
141# endif /* STARTTLS */
142    /* remaining commands are here only to trap and log attempts to use them */
143	{ "showq",	CMDDBGQSHOW	},
144	{ "debug",	CMDDBGDEBUG	},
145	{ "wiz",	CMDLOGBOGUS	},
146
147	{ NULL,		CMDERROR	}
148};
149
150static bool	OneXact = FALSE;	/* one xaction only this run */
151static char	*CurSmtpClient;		/* who's at the other end of channel */
152
153# define MAXBADCOMMANDS		25	/* maximum number of bad commands */
154# define MAXNOOPCOMMANDS	20	/* max "noise" commands before slowdown */
155# define MAXHELOCOMMANDS	3	/* max HELO/EHLO commands before slowdown */
156# define MAXVRFYCOMMANDS	6	/* max VRFY/EXPN commands before slowdown */
157# define MAXETRNCOMMANDS	8	/* max ETRN commands before slowdown */
158# define MAXTIMEOUT	(4 * 60)	/* max timeout for bad commands */
159
160/* runinchild() returns */
161# define RIC_INCHILD		0	/* in a child process */
162# define RIC_INPARENT		1	/* still in parent process */
163# define RIC_TEMPFAIL		2	/* temporary failure occurred */
164
165void
166smtp(nullserver, d_flags, e)
167	char *volatile nullserver;
168	BITMAP256 d_flags;
169	register ENVELOPE *volatile e;
170{
171	register char *volatile p;
172	register struct cmd *volatile c = NULL;
173	char *cmd;
174	auto ADDRESS *vrfyqueue;
175	ADDRESS *a;
176	volatile bool gotmail;		/* mail command received */
177	volatile bool gothello;		/* helo command received */
178	bool vrfy;			/* set if this is a vrfy command */
179	char *volatile protocol;	/* sending protocol */
180	char *volatile sendinghost;	/* sending hostname */
181	char *volatile peerhostname;	/* name of SMTP peer or "localhost" */
182	auto char *delimptr;
183	char *id;
184	volatile int nrcpts = 0;	/* number of RCPT commands */
185	int ric;
186	bool doublequeue;
187	volatile bool discard;
188	volatile int badcommands = 0;	/* count of bad commands */
189	volatile int nverifies = 0;	/* count of VRFY/EXPN commands */
190	volatile int n_etrn = 0;	/* count of ETRN commands */
191	volatile int n_noop = 0;	/* count of NOOP/VERB/ONEX etc cmds */
192	volatile int n_helo = 0;	/* count of HELO/EHLO commands */
193	volatile int delay = 1;		/* timeout for bad commands */
194	bool ok;
195	volatile bool tempfail = FALSE;
196# if _FFR_MILTER
197	volatile bool milterize = (nullserver == NULL);
198# endif /* _FFR_MILTER */
199	volatile time_t wt;		/* timeout after too many commands */
200	volatile time_t previous;	/* time after checksmtpattack() */
201	volatile bool lognullconnection = TRUE;
202	register char *q;
203	char *addr;
204	char *greetcode = "220";
205	QUEUE_CHAR *new;
206	int argno;
207	char *args[MAXSMTPARGS];
208	char inp[MAXLINE];
209	char cmdbuf[MAXLINE];
210# if SASL
211	sasl_conn_t *conn;
212	volatile bool sasl_ok;
213	volatile int n_auth = 0;	/* count of AUTH commands */
214	bool ismore;
215	int result;
216	volatile int authenticating;
217	char *hostname;
218	char *user;
219	char *in, *out, *out2;
220	const char *errstr;
221	int inlen, out2len;
222	unsigned int outlen;
223	char *volatile auth_type;
224	char *mechlist;
225	volatile int n_mechs;
226	int len;
227	sasl_security_properties_t ssp;
228	sasl_external_properties_t ext_ssf;
229#  if SFIO
230	sasl_ssf_t *ssf;
231#  endif /* SFIO */
232# endif /* SASL */
233# if STARTTLS
234	int r;
235	volatile bool usetls = TRUE;
236	volatile bool tls_active = FALSE;
237	bool saveQuickAbort;
238	bool saveSuprErrs;
239# endif /* STARTTLS */
240
241	if (fileno(OutChannel) != fileno(stdout))
242	{
243		/* arrange for debugging output to go to remote host */
244		(void) dup2(fileno(OutChannel), fileno(stdout));
245	}
246
247	settime(e);
248	(void)sm_getla(e);
249	peerhostname = RealHostName;
250	if (peerhostname == NULL)
251		peerhostname = "localhost";
252	CurHostName = peerhostname;
253	CurSmtpClient = macvalue('_', e);
254	if (CurSmtpClient == NULL)
255		CurSmtpClient = CurHostName;
256
257	/* check_relay may have set discard bit, save for later */
258	discard = bitset(EF_DISCARD, e->e_flags);
259
260	sm_setproctitle(TRUE, e, "server %s startup", CurSmtpClient);
261
262# if SASL
263	sasl_ok = FALSE;	/* SASL can't be used (yet) */
264	n_mechs = 0;
265
266	/* SASL server new connection */
267	hostname = macvalue('j', e);
268#  if SASL > 10505
269	/* use empty realm: only works in SASL > 1.5.5 */
270	result = sasl_server_new("smtp", hostname, "", NULL, 0, &conn);
271#  else /* SASL > 10505 */
272	/* use no realm -> realm is set to hostname by SASL lib */
273	result = sasl_server_new("smtp", hostname, NULL, NULL, 0, &conn);
274#  endif /* SASL > 10505 */
275	if (result == SASL_OK)
276	{
277		sasl_ok = TRUE;
278
279		/*
280		**  SASL set properties for sasl
281		**  set local/remote IP
282		**  XXX only IPv4: Cyrus SASL doesn't support anything else
283		**
284		**  XXX where exactly are these used/required?
285		**  Kerberos_v4
286		*/
287
288# if NETINET
289		in = macvalue(macid("{daemon_family}", NULL), e);
290		if (in != NULL && strcmp(in, "inet") == 0)
291		{
292			SOCKADDR_LEN_T addrsize;
293			struct sockaddr_in saddr_l;
294			struct sockaddr_in saddr_r;
295
296			addrsize = sizeof(struct sockaddr_in);
297			if (getpeername(fileno(InChannel),
298					(struct sockaddr *)&saddr_r,
299					&addrsize) == 0)
300			{
301				sasl_setprop(conn, SASL_IP_REMOTE, &saddr_r);
302				addrsize = sizeof(struct sockaddr_in);
303				if (getsockname(fileno(InChannel),
304						(struct sockaddr *)&saddr_l,
305						&addrsize) == 0)
306					sasl_setprop(conn, SASL_IP_LOCAL,
307						     &saddr_l);
308			}
309		}
310# endif /* NETINET */
311
312		authenticating = SASL_NOT_AUTH;
313		auth_type = NULL;
314		mechlist = NULL;
315		user = NULL;
316#  if 0
317		define(macid("{auth_author}", NULL), NULL, &BlankEnvelope);
318#  endif /* 0 */
319
320		/* set properties */
321		(void) memset(&ssp, '\0', sizeof ssp);
322#  if SFIO
323		/* XXX should these be options settable via .cf ? */
324		/* ssp.min_ssf = 0; is default due to memset() */
325		{
326			ssp.max_ssf = INT_MAX;
327			ssp.maxbufsize = MAXOUTLEN;
328		}
329#  endif /* SFIO */
330#  if _FFR_SASL_OPTS
331		ssp.security_flags = SASLOpts & SASL_SEC_MASK;
332#  endif /* _FFR_SASL_OPTS */
333		sasl_ok = sasl_setprop(conn, SASL_SEC_PROPS, &ssp) == SASL_OK;
334
335		if (sasl_ok)
336		{
337			/*
338			**  external security strength factor;
339			**  we have none so zero
340#   if STARTTLS
341			**  we may have to change this for STARTTLS
342			**  (dynamically)
343#   endif
344			*/
345			ext_ssf.ssf = 0;
346			ext_ssf.auth_id = NULL;
347			sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
348					       &ext_ssf) == SASL_OK;
349		}
350		if (sasl_ok)
351		{
352			n_mechs = saslmechs(conn, &mechlist);
353			sasl_ok = n_mechs > 0;
354		}
355	}
356	else
357	{
358		if (LogLevel > 9)
359			sm_syslog(LOG_WARNING, NOQID,
360				  "SASL error: sasl_server_new failed=%d",
361				  result);
362	}
363# endif /* SASL */
364
365# if STARTTLS
366#  if _FFR_TLS_O_T
367	saveQuickAbort = QuickAbort;
368	saveSuprErrs = SuprErrs;
369	SuprErrs = TRUE;
370	QuickAbort = FALSE;
371	if (rscheck("offer_tls", CurSmtpClient, "", e, TRUE, FALSE, 8) != EX_OK
372		    || Errors > 0)
373		usetls = FALSE;
374	QuickAbort = saveQuickAbort;
375	SuprErrs = saveSuprErrs;
376#  endif /* _FFR_TLS_O_T */
377# endif /* STARTTLS */
378
379# if _FFR_MILTER
380	if (milterize)
381	{
382		char state;
383
384		/* initialize mail filter connection */
385		milter_init(e, &state);
386		switch (state)
387		{
388		  case SMFIR_REJECT:
389			greetcode = "554";
390			nullserver = "Command rejected";
391			milterize = FALSE;
392			break;
393
394		  case SMFIR_TEMPFAIL:
395			tempfail = TRUE;
396			milterize = FALSE;
397			break;
398		}
399	}
400
401	if (milterize && !bitset(EF_DISCARD, e->e_flags))
402	{
403		char state;
404
405		(void) milter_connect(peerhostname, RealHostAddr,
406				      e, &state);
407		switch (state)
408		{
409		  case SMFIR_REPLYCODE:	/* REPLYCODE shouldn't happen */
410		  case SMFIR_REJECT:
411			greetcode = "554";
412			nullserver = "Command rejected";
413			milterize = FALSE;
414			break;
415
416		  case SMFIR_TEMPFAIL:
417			tempfail = TRUE;
418			milterize = FALSE;
419			break;
420		}
421	}
422# endif /* _FFR_MILTER */
423
424	/* output the first line, inserting "ESMTP" as second word */
425	expand(SmtpGreeting, inp, sizeof inp, e);
426	p = strchr(inp, '\n');
427	if (p != NULL)
428		*p++ = '\0';
429	id = strchr(inp, ' ');
430	if (id == NULL)
431		id = &inp[strlen(inp)];
432	if (p == NULL)
433		snprintf(cmdbuf, sizeof cmdbuf,
434			 "%s %%.*s ESMTP%%s", greetcode);
435	else
436		snprintf(cmdbuf, sizeof cmdbuf,
437			 "%s-%%.*s ESMTP%%s", greetcode);
438	message(cmdbuf, id - inp, inp, id);
439
440	/* output remaining lines */
441	while ((id = p) != NULL && (p = strchr(id, '\n')) != NULL)
442	{
443		*p++ = '\0';
444		if (isascii(*id) && isspace(*id))
445			id++;
446		(void) snprintf(cmdbuf, sizeof cmdbuf, "%s-%%s", greetcode);
447		message(cmdbuf, id);
448	}
449	if (id != NULL)
450	{
451		if (isascii(*id) && isspace(*id))
452			id++;
453		(void) snprintf(cmdbuf, sizeof cmdbuf, "%s %%s", greetcode);
454		message(cmdbuf, id);
455	}
456
457	protocol = NULL;
458	sendinghost = macvalue('s', e);
459	gothello = FALSE;
460	gotmail = FALSE;
461	for (;;)
462	{
463		/* arrange for backout */
464		(void) setjmp(TopFrame);
465		QuickAbort = FALSE;
466		HoldErrs = FALSE;
467		SuprErrs = FALSE;
468		LogUsrErrs = FALSE;
469		OnlyOneError = TRUE;
470		e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
471
472		/* setup for the read */
473		e->e_to = NULL;
474		Errors = 0;
475		FileName = NULL;
476		(void) fflush(stdout);
477
478		/* read the input line */
479		SmtpPhase = "server cmd read";
480		sm_setproctitle(TRUE, e, "server %s cmd read", CurSmtpClient);
481# if SASL
482		/*
483		**  SMTP AUTH requires accepting any length,
484		**  at least for challenge/response
485		**  XXX
486		*/
487# endif /* SASL */
488
489		/* handle errors */
490		if (ferror(OutChannel) ||
491		    (p = sfgets(inp, sizeof inp, InChannel,
492				TimeOuts.to_nextcommand, SmtpPhase)) == NULL)
493		{
494			char *d;
495
496			d = macvalue(macid("{daemon_name}", NULL), e);
497			if (d == NULL)
498				d = "stdin";
499			/* end of file, just die */
500			disconnect(1, e);
501
502# if _FFR_MILTER
503			/* close out milter filters */
504			milter_quit(e);
505# endif /* _FFR_MILTER */
506
507			message("421 4.4.1 %s Lost input channel from %s",
508				MyHostName, CurSmtpClient);
509			if (LogLevel > (gotmail ? 1 : 19))
510				sm_syslog(LOG_NOTICE, e->e_id,
511					  "lost input channel from %.100s to %s after %s",
512					  CurSmtpClient, d,
513					  (c == NULL || c->cmd_name == NULL) ? "startup" : c->cmd_name);
514			/*
515			**  If have not accepted mail (DATA), do not bounce
516			**  bad addresses back to sender.
517			*/
518
519			if (bitset(EF_CLRQUEUE, e->e_flags))
520				e->e_sendqueue = NULL;
521			goto doquit;
522		}
523
524		/* clean up end of line */
525		fixcrlf(inp, TRUE);
526
527# if SASL
528		if (authenticating == SASL_PROC_AUTH)
529		{
530#  if 0
531			if (*inp == '\0')
532			{
533				authenticating = SASL_NOT_AUTH;
534				message("501 5.5.2 missing input");
535				continue;
536			}
537#  endif /* 0 */
538			if (*inp == '*' && *(inp + 1) == '\0')
539			{
540				authenticating = SASL_NOT_AUTH;
541
542				/* rfc 2254 4. */
543				message("501 5.0.0 AUTH aborted");
544				continue;
545			}
546
547			/* could this be shorter? XXX */
548			out = xalloc(strlen(inp));
549			result = sasl_decode64(inp, strlen(inp), out, &outlen);
550			if (result != SASL_OK)
551			{
552				authenticating = SASL_NOT_AUTH;
553
554				/* rfc 2254 4. */
555				message("501 5.5.4 cannot decode AUTH parameter %s",
556					inp);
557				continue;
558			}
559
560			result = sasl_server_step(conn,	out, outlen,
561						  &out, &outlen, &errstr);
562
563			/* get an OK if we're done */
564			if (result == SASL_OK)
565			{
566  authenticated:
567				message("235 2.0.0 OK Authenticated");
568				authenticating = SASL_IS_AUTH;
569				define(macid("{auth_type}", NULL),
570				       newstr(auth_type), &BlankEnvelope);
571
572				result = sasl_getprop(conn, SASL_USERNAME,
573						      (void **)&user);
574				if (result != SASL_OK)
575				{
576					user = "";
577					define(macid("{auth_authen}", NULL),
578					       NULL, &BlankEnvelope);
579				}
580				else
581				{
582					define(macid("{auth_authen}", NULL),
583					       newstr(user), &BlankEnvelope);
584				}
585
586#  if 0
587				/* get realm? */
588				sasl_getprop(conn, SASL_REALM, (void **) &data);
589#  endif /* 0 */
590
591
592#  if SFIO
593				/* get security strength (features) */
594				result = sasl_getprop(conn, SASL_SSF,
595						      (void **) &ssf);
596				if (result != SASL_OK)
597				{
598					define(macid("{auth_ssf}", NULL),
599					       "0", &BlankEnvelope);
600					ssf = NULL;
601				}
602				else
603				{
604					char pbuf[8];
605
606					snprintf(pbuf, sizeof pbuf, "%u", *ssf);
607					define(macid("{auth_ssf}", NULL),
608					       newstr(pbuf), &BlankEnvelope);
609					if (tTd(95, 8))
610						dprintf("SASL auth_ssf: %u\n",
611							*ssf);
612				}
613				/*
614				**  only switch to encrypted connection
615				**  if a security layer has been negotiated
616				*/
617				if (ssf != NULL && *ssf > 0)
618				{
619					/*
620					**  convert sfio stuff to use SASL
621					**  check return values
622					**  if the call fails,
623					**  fall back to unencrypted version
624					**  unless some cf option requires
625					**  encryption then the connection must
626					**  be aborted
627					*/
628					if (sfdcsasl(InChannel, OutChannel,
629					    conn) == 0)
630					{
631						/* restart dialogue */
632						gothello = FALSE;
633						OneXact = TRUE;
634						n_helo = 0;
635					}
636					else
637						syserr("503 5.3.3 SASL TLS failed");
638					if (LogLevel > 9)
639						sm_syslog(LOG_INFO,
640							  NOQID,
641							  "SASL: connection from %.64s: mech=%.16s, id=%.64s, bits=%d",
642							  CurSmtpClient,
643							  auth_type, user,
644							  *ssf);
645				}
646#  else /* SFIO */
647				if (LogLevel > 9)
648					sm_syslog(LOG_INFO, NOQID,
649						  "SASL: connection from %.64s: mech=%.16s, id=%.64s",
650						  CurSmtpClient, auth_type,
651						  user);
652#  endif /* SFIO */
653			}
654			else if (result == SASL_CONTINUE)
655			{
656				len = ENC64LEN(outlen);
657				out2 = xalloc(len);
658				result = sasl_encode64(out, outlen, out2, len,
659						       (u_int *)&out2len);
660				if (result != SASL_OK)
661				{
662					/* correct code? XXX */
663					/* 454 Temp. authentication failure */
664					message("454 4.5.4 Internal error: unable to encode64");
665					if (LogLevel > 5)
666						sm_syslog(LOG_WARNING, e->e_id,
667							  "SASL encode64 error [%d for \"%s\"]",
668							  result, out);
669					/* start over? */
670					authenticating = SASL_NOT_AUTH;
671				}
672				else
673				{
674					message("334 %s", out2);
675					if (tTd(95, 2))
676						dprintf("SASL continue: msg='%s' len=%d\n",
677							out2, out2len);
678				}
679			}
680			else
681			{
682				/* not SASL_OK or SASL_CONT */
683				message("500 5.7.0 authentication failed");
684				if (LogLevel > 9)
685					sm_syslog(LOG_WARNING, e->e_id,
686						  "AUTH failure (%s): %s (%d)",
687						  auth_type,
688						  sasl_errstring(result, NULL,
689								 NULL),
690						  result);
691				authenticating = SASL_NOT_AUTH;
692			}
693		}
694		else
695		{
696			/* don't want to do any of this if authenticating */
697# endif /* SASL */
698
699		/* echo command to transcript */
700		if (e->e_xfp != NULL)
701			fprintf(e->e_xfp, "<<< %s\n", inp);
702
703		if (LogLevel >= 15)
704			sm_syslog(LOG_INFO, e->e_id,
705				  "<-- %s",
706				  inp);
707
708		if (e->e_id == NULL)
709			sm_setproctitle(TRUE, e, "%s: %.80s",
710					CurSmtpClient, inp);
711		else
712			sm_setproctitle(TRUE, e, "%s %s: %.80s",
713					qid_printname(e),
714					CurSmtpClient, inp);
715
716		/* break off command */
717		for (p = inp; isascii(*p) && isspace(*p); p++)
718			continue;
719		cmd = cmdbuf;
720		while (*p != '\0' &&
721		       !(isascii(*p) && isspace(*p)) &&
722		       cmd < &cmdbuf[sizeof cmdbuf - 2])
723			*cmd++ = *p++;
724		*cmd = '\0';
725
726		/* throw away leading whitespace */
727		while (isascii(*p) && isspace(*p))
728			p++;
729
730		/* decode command */
731		for (c = CmdTab; c->cmd_name != NULL; c++)
732		{
733			if (strcasecmp(c->cmd_name, cmdbuf) == 0)
734				break;
735		}
736
737		/* reset errors */
738		errno = 0;
739
740		/*
741		**  Process command.
742		**
743		**	If we are running as a null server, return 550
744		**	to everything.
745		*/
746
747		if (nullserver != NULL || bitnset(D_ETRNONLY, d_flags))
748		{
749			switch (c->cmd_code)
750			{
751			  case CMDQUIT:
752			  case CMDHELO:
753			  case CMDEHLO:
754			  case CMDNOOP:
755			  case CMDRSET:
756				/* process normally */
757				break;
758
759			  case CMDETRN:
760				if (bitnset(D_ETRNONLY, d_flags) &&
761				    nullserver == NULL)
762					break;
763				continue;
764
765			  default:
766				if (++badcommands > MAXBADCOMMANDS)
767				{
768					delay *= 2;
769					if (delay >= MAXTIMEOUT)
770						delay = MAXTIMEOUT;
771					(void) sleep(delay);
772				}
773				if (nullserver != NULL)
774				{
775					if (ISSMTPREPLY(nullserver))
776						usrerr(nullserver);
777					else
778						usrerr("550 5.0.0 %s", nullserver);
779				}
780				else
781					usrerr("452 4.4.5 Insufficient disk space; try again later");
782				continue;
783			}
784		}
785
786		/* non-null server */
787		switch (c->cmd_code)
788		{
789		  case CMDMAIL:
790		  case CMDEXPN:
791		  case CMDVRFY:
792		  case CMDETRN:
793			lognullconnection = FALSE;
794		}
795
796		switch (c->cmd_code)
797		{
798# if SASL
799		  case CMDAUTH: /* sasl */
800			if (!sasl_ok)
801			{
802				message("503 5.3.3 AUTH not available");
803				break;
804			}
805			if (authenticating == SASL_IS_AUTH)
806			{
807				message("503 5.5.0 Already Authenticated");
808				break;
809			}
810			if (gotmail)
811			{
812				message("503 5.5.0 AUTH not permitted during a mail transaction");
813				break;
814			}
815			if (tempfail)
816			{
817				if (LogLevel > 9)
818					sm_syslog(LOG_INFO, e->e_id,
819						  "SMTP AUTH command (%.100s) from %.100s tempfailed (due to previous checks)",
820						  p, CurSmtpClient);
821				usrerr("454 4.7.1 Please try again later");
822				break;
823			}
824
825			ismore = FALSE;
826
827			/* crude way to avoid crack attempts */
828			(void) checksmtpattack(&n_auth, n_mechs + 1, TRUE,
829					       "AUTH", e);
830
831			/* make sure it's a valid string */
832			for (q = p; *q != '\0' && isascii(*q); q++)
833			{
834				if (isspace(*q))
835				{
836					*q = '\0';
837					while (*++q != '\0' &&
838					       isascii(*q) && isspace(*q))
839						continue;
840					*(q - 1) = '\0';
841					ismore = (*q != '\0');
842					break;
843				}
844			}
845
846			/* check whether mechanism is available */
847			if (iteminlist(p, mechlist, " ") == NULL)
848			{
849				message("503 5.3.3 AUTH mechanism %s not available",
850					p);
851				break;
852			}
853
854			if (ismore)
855			{
856				/* could this be shorter? XXX */
857				in = xalloc(strlen(q));
858				result = sasl_decode64(q, strlen(q), in,
859						       (u_int *)&inlen);
860				if (result != SASL_OK)
861				{
862					message("501 5.5.4 cannot BASE64 decode '%s'",
863						q);
864					if (LogLevel > 5)
865						sm_syslog(LOG_WARNING, e->e_id,
866							  "SASL decode64 error [%d for \"%s\"]",
867							  result, q);
868					/* start over? */
869					authenticating = SASL_NOT_AUTH;
870					in = NULL;
871					inlen = 0;
872					break;
873				}
874#  if 0
875				if (tTd(95, 99))
876				{
877					int i;
878
879					dprintf("AUTH: more \"");
880					for (i = 0; i < inlen; i++)
881					{
882						if (isascii(in[i]) &&
883						    isprint(in[i]))
884							dprintf("%c", in[i]);
885						else
886							dprintf("_");
887					}
888					dprintf("\"\n");
889				}
890#  endif /* 0 */
891			}
892			else
893			{
894				in = NULL;
895				inlen = 0;
896			}
897
898			/* see if that auth type exists */
899			result = sasl_server_start(conn, p, in, inlen,
900						   &out, &outlen, &errstr);
901
902			if (result != SASL_OK && result != SASL_CONTINUE)
903			{
904				message("500 5.7.0 authentication failed");
905				if (LogLevel > 9)
906					sm_syslog(LOG_ERR, e->e_id,
907						  "AUTH failure (%s): %s (%d)",
908						  p,
909						  sasl_errstring(result, NULL,
910								 NULL),
911						  result);
912				break;
913			}
914			auth_type = newstr(p);
915
916			if (result == SASL_OK)
917			{
918				/* ugly, but same code */
919				goto authenticated;
920				/* authenticated by the initial response */
921			}
922
923			/* len is at least 2 */
924			len = ENC64LEN(outlen);
925			out2 = xalloc(len);
926			result = sasl_encode64(out, outlen, out2, len,
927					       (u_int *)&out2len);
928
929			if (result != SASL_OK)
930			{
931				message("454 4.5.4 Temporary authentication failure");
932				if (LogLevel > 5)
933					sm_syslog(LOG_WARNING, e->e_id,
934						  "SASL encode64 error [%d for \"%s\"]",
935						  result, out);
936
937				/* start over? */
938				authenticating = SASL_NOT_AUTH;
939			}
940			else
941			{
942				message("334 %s", out2);
943				authenticating = SASL_PROC_AUTH;
944			}
945
946			break;
947# endif /* SASL */
948
949# if STARTTLS
950		  case CMDSTLS: /* starttls */
951			if (*p != '\0')
952			{
953				message("501 5.5.2 Syntax error (no parameters allowed)");
954				break;
955			}
956			if (!usetls)
957			{
958				message("503 5.5.0 TLS not available");
959				break;
960			}
961			if (!tls_ok)
962			{
963				message("454 4.3.3 TLS not available after start");
964				break;
965			}
966			if (gotmail)
967			{
968				message("503 5.5.0 TLS not permitted during a mail transaction");
969				break;
970			}
971			if (tempfail)
972			{
973				if (LogLevel > 9)
974					sm_syslog(LOG_INFO, e->e_id,
975						  "SMTP STARTTLS command (%.100s) from %.100s tempfailed (due to previous checks)",
976						  p, CurSmtpClient);
977				usrerr("454 4.7.1 Please try again later");
978				break;
979			}
980# if TLS_NO_RSA
981			/*
982			**  XXX do we need a temp key ?
983			*/
984# else /* TLS_NO_RSA */
985			if (SSL_CTX_need_tmp_RSA(srv_ctx) &&
986			   !SSL_CTX_set_tmp_rsa(srv_ctx,
987				(rsa = RSA_generate_key(RSA_KEYLENGTH, RSA_F4,
988							NULL, NULL)))
989			  )
990			{
991				message("454 4.3.3 TLS not available: error generating RSA temp key");
992				if (rsa != NULL)
993					RSA_free(rsa);
994				break;
995			}
996# endif /* TLS_NO_RSA */
997			if (srv_ssl != NULL)
998				SSL_clear(srv_ssl);
999			else if ((srv_ssl = SSL_new(srv_ctx)) == NULL)
1000			{
1001				message("454 4.3.3 TLS not available: error generating SSL handle");
1002				break;
1003			}
1004			if (SSL_set_rfd(srv_ssl, fileno(InChannel)) <= 0 ||
1005			    SSL_set_wfd(srv_ssl, fileno(OutChannel)) <= 0)
1006			{
1007				message("454 4.3.3 TLS not available: error set fd");
1008				SSL_free(srv_ssl);
1009				srv_ssl = NULL;
1010				break;
1011			}
1012			message("220 2.0.0 Ready to start TLS");
1013			SSL_set_accept_state(srv_ssl);
1014
1015#  define SSL_ACC(s)	SSL_accept(s)
1016			if ((r = SSL_ACC(srv_ssl)) <= 0)
1017			{
1018				int i;
1019
1020				/* what to do in this case? */
1021				i = SSL_get_error(srv_ssl, r);
1022				if (LogLevel > 5)
1023				{
1024					sm_syslog(LOG_WARNING, e->e_id,
1025						  "TLS: error: accept failed=%d (%d)",
1026						  r, i);
1027					if (LogLevel > 9)
1028						tlslogerr();
1029				}
1030				tls_ok = FALSE;
1031				SSL_free(srv_ssl);
1032				srv_ssl = NULL;
1033
1034				/*
1035				**  according to the next draft of
1036				**  RFC 2487 the connection should be dropped
1037				*/
1038
1039				/* arrange to ignore any current send list */
1040				e->e_sendqueue = NULL;
1041				goto doquit;
1042			}
1043
1044			/* ignore return code for now, it's in {verify} */
1045			(void) tls_get_info(srv_ssl, &BlankEnvelope, TRUE,
1046					    CurSmtpClient);
1047
1048			/*
1049			**  call Stls_client to find out whether
1050			**  to accept the connection from the client
1051			*/
1052
1053			saveQuickAbort = QuickAbort;
1054			saveSuprErrs = SuprErrs;
1055			SuprErrs = TRUE;
1056			QuickAbort = FALSE;
1057			if (rscheck("tls_client",
1058				     macvalue(macid("{verify}", NULL), e),
1059				     "STARTTLS", e, TRUE, TRUE, 6) != EX_OK ||
1060			    Errors > 0)
1061			{
1062				extern char MsgBuf[];
1063
1064				if (MsgBuf[0] != '\0' && ISSMTPREPLY(MsgBuf))
1065					nullserver = newstr(MsgBuf);
1066				else
1067					nullserver = "503 5.7.0 Authentication required.";
1068			}
1069			QuickAbort = saveQuickAbort;
1070			SuprErrs = saveSuprErrs;
1071
1072			tls_ok = FALSE;	/* don't offer STARTTLS again */
1073			gothello = FALSE;	/* discard info */
1074			n_helo = 0;
1075			OneXact = TRUE;	/* only one xaction this run */
1076#  if SASL
1077			if (sasl_ok)
1078			{
1079				char *s;
1080
1081				if ((s = macvalue(macid("{cipher_bits}", NULL), e)) != NULL &&
1082				    (ext_ssf.ssf = atoi(s)) > 0)
1083				{
1084#  if _FFR_EXT_MECH
1085					ext_ssf.auth_id = macvalue(macid("{cert_subject}",
1086									 NULL),
1087								   e);
1088#  endif /* _FFR_EXT_MECH */
1089					sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
1090							       &ext_ssf) == SASL_OK;
1091					if (mechlist != NULL)
1092						free(mechlist);
1093					mechlist = NULL;
1094					if (sasl_ok)
1095					{
1096						n_mechs = saslmechs(conn,
1097								    &mechlist);
1098						sasl_ok = n_mechs > 0;
1099					}
1100				}
1101			}
1102#  endif /* SASL */
1103
1104			/* switch to secure connection */
1105#if SFIO
1106			r = sfdctls(InChannel, OutChannel, srv_ssl);
1107#else /* SFIO */
1108# if _FFR_TLS_TOREK
1109			r = sfdctls(&InChannel, &OutChannel, srv_ssl);
1110# endif /* _FFR_TLS_TOREK */
1111#endif /* SFIO */
1112			if (r == 0)
1113				tls_active = TRUE;
1114			else
1115			{
1116				/*
1117				**  XXX this is an internal error
1118				**  how to deal with it?
1119				**  we can't generate an error message
1120				**  since the other side switched to an
1121				**  encrypted layer, but we could not...
1122				**  just "hang up"?
1123				*/
1124				nullserver = "454 4.3.3 TLS not available: can't switch to encrypted layer";
1125				syserr("TLS: can't switch to encrypted layer");
1126			}
1127			break;
1128# endif /* STARTTLS */
1129
1130		  case CMDHELO:		/* hello -- introduce yourself */
1131		  case CMDEHLO:		/* extended hello */
1132			if (c->cmd_code == CMDEHLO)
1133			{
1134				protocol = "ESMTP";
1135				SmtpPhase = "server EHLO";
1136			}
1137			else
1138			{
1139				protocol = "SMTP";
1140				SmtpPhase = "server HELO";
1141			}
1142
1143			/* avoid denial-of-service */
1144			(void) checksmtpattack(&n_helo, MAXHELOCOMMANDS, TRUE,
1145					       "HELO/EHLO", e);
1146
1147			/* check for duplicate HELO/EHLO per RFC 1651 4.2 */
1148			if (gothello)
1149			{
1150				usrerr("503 %s Duplicate HELO/EHLO",
1151					MyHostName);
1152				break;
1153			}
1154
1155			/* check for valid domain name (re 1123 5.2.5) */
1156			if (*p == '\0' && !AllowBogusHELO)
1157			{
1158				usrerr("501 %s requires domain address",
1159					cmdbuf);
1160				break;
1161			}
1162
1163			/* check for long domain name (hides Received: info) */
1164			if (strlen(p) > MAXNAME)
1165			{
1166				usrerr("501 Invalid domain name");
1167				if (LogLevel > 9)
1168					sm_syslog(LOG_INFO, CurEnv->e_id,
1169						  "invalid domain name (too long) from %.100s",
1170						  CurSmtpClient);
1171				break;
1172			}
1173
1174			for (q = p; *q != '\0'; q++)
1175			{
1176				if (!isascii(*q))
1177					break;
1178				if (isalnum(*q))
1179					continue;
1180				if (isspace(*q))
1181				{
1182					*q = '\0';
1183					break;
1184				}
1185				if (strchr("[].-_#", *q) == NULL)
1186					break;
1187			}
1188
1189			if (*q == '\0')
1190			{
1191				q = "pleased to meet you";
1192				sendinghost = newstr(p);
1193			}
1194			else if (!AllowBogusHELO)
1195			{
1196				usrerr("501 Invalid domain name");
1197				if (LogLevel > 9)
1198					sm_syslog(LOG_INFO, CurEnv->e_id,
1199						  "invalid domain name (%.100s) from %.100s",
1200						  p, CurSmtpClient);
1201				break;
1202			}
1203			else
1204			{
1205				q = "accepting invalid domain name";
1206			}
1207
1208			gothello = TRUE;
1209
1210# if _FFR_MILTER
1211			if (milterize && !bitset(EF_DISCARD, e->e_flags))
1212			{
1213				char state;
1214				char *response;
1215
1216				response = milter_helo(p, e, &state);
1217				switch (state)
1218				{
1219				  case SMFIR_REPLYCODE:
1220					nullserver = response;
1221					milterize = FALSE;
1222					break;
1223
1224				  case SMFIR_REJECT:
1225					nullserver = "Command rejected";
1226					milterize = FALSE;
1227					break;
1228
1229				  case SMFIR_TEMPFAIL:
1230					tempfail = TRUE;
1231					milterize = FALSE;
1232					break;
1233				}
1234			}
1235# endif /* _FFR_MILTER */
1236
1237			/* print HELO response message */
1238			if (c->cmd_code != CMDEHLO)
1239			{
1240				message("250 %s Hello %s, %s",
1241					MyHostName, CurSmtpClient, q);
1242				break;
1243			}
1244
1245			message("250-%s Hello %s, %s",
1246				MyHostName, CurSmtpClient, q);
1247
1248			/* offer ENHSC even for nullserver */
1249			if (nullserver != NULL)
1250			{
1251				message("250 ENHANCEDSTATUSCODES");
1252				break;
1253			}
1254
1255			/* print EHLO features list */
1256			message("250-ENHANCEDSTATUSCODES");
1257			if (!bitset(PRIV_NOEXPN, PrivacyFlags))
1258			{
1259				message("250-EXPN");
1260				if (!bitset(PRIV_NOVERB, PrivacyFlags))
1261					message("250-VERB");
1262			}
1263# if MIME8TO7
1264			message("250-8BITMIME");
1265# endif /* MIME8TO7 */
1266			if (MaxMessageSize > 0)
1267				message("250-SIZE %ld", MaxMessageSize);
1268			else
1269				message("250-SIZE");
1270# if DSN
1271			if (SendMIMEErrors &&
1272			    !bitset(PRIV_NORECEIPTS, PrivacyFlags))
1273				message("250-DSN");
1274# endif /* DSN */
1275			message("250-ONEX");
1276			if (!bitset(PRIV_NOETRN, PrivacyFlags) &&
1277			    !bitnset(D_NOETRN, d_flags))
1278				message("250-ETRN");
1279			message("250-XUSR");
1280
1281# if SASL
1282			if (sasl_ok && mechlist != NULL && *mechlist != '\0')
1283				message("250-AUTH %s", mechlist);
1284# endif /* SASL */
1285# if STARTTLS
1286			if (tls_ok && usetls)
1287				message("250-STARTTLS");
1288# endif /* STARTTLS */
1289			message("250 HELP");
1290			break;
1291
1292		  case CMDMAIL:		/* mail -- designate sender */
1293			SmtpPhase = "server MAIL";
1294
1295			/* check for validity of this command */
1296			if (!gothello && bitset(PRIV_NEEDMAILHELO, PrivacyFlags))
1297			{
1298				usrerr("503 5.0.0 Polite people say HELO first");
1299				break;
1300			}
1301			if (gotmail)
1302			{
1303				usrerr("503 5.5.0 Sender already specified");
1304				break;
1305			}
1306			if (InChild)
1307			{
1308				errno = 0;
1309				syserr("503 5.5.0 Nested MAIL command: MAIL %s", p);
1310				finis(TRUE, ExitStat);
1311			}
1312# if SASL
1313			if (bitnset(D_AUTHREQ, d_flags) &&
1314			    authenticating != SASL_IS_AUTH)
1315			{
1316				usrerr("530 5.7.0 Authentication required");
1317				break;
1318			}
1319# endif /* SASL */
1320
1321			p = skipword(p, "from");
1322			if (p == NULL)
1323				break;
1324			if (tempfail)
1325			{
1326				if (LogLevel > 9)
1327					sm_syslog(LOG_INFO, e->e_id,
1328						  "SMTP MAIL command (%.100s) from %.100s tempfailed (due to previous checks)",
1329						  p, CurSmtpClient);
1330				usrerr("451 4.7.1 Please try again later");
1331				break;
1332			}
1333
1334			/* make sure we know who the sending host is */
1335			if (sendinghost == NULL)
1336				sendinghost = peerhostname;
1337
1338
1339			/* fork a subprocess to process this command */
1340			ric = runinchild("SMTP-MAIL", e);
1341
1342			/* Catch a problem and stop processing */
1343			if (ric == RIC_TEMPFAIL && nullserver == NULL)
1344				nullserver = "452 4.3.0 Internal software error";
1345			if (ric != RIC_INCHILD)
1346				break;
1347
1348			if (Errors > 0)
1349				goto undo_subproc_no_pm;
1350			if (!gothello)
1351			{
1352				auth_warning(e,
1353					"%s didn't use HELO protocol",
1354					CurSmtpClient);
1355			}
1356# ifdef PICKY_HELO_CHECK
1357			if (strcasecmp(sendinghost, peerhostname) != 0 &&
1358			    (strcasecmp(peerhostname, "localhost") != 0 ||
1359			     strcasecmp(sendinghost, MyHostName) != 0))
1360			{
1361				auth_warning(e, "Host %s claimed to be %s",
1362					CurSmtpClient, sendinghost);
1363			}
1364# endif /* PICKY_HELO_CHECK */
1365
1366			if (protocol == NULL)
1367				protocol = "SMTP";
1368			define('r', protocol, e);
1369			define('s', sendinghost, e);
1370
1371			if (Errors > 0)
1372				goto undo_subproc_no_pm;
1373			nrcpts = 0;
1374			define(macid("{ntries}", NULL), "0", e);
1375			e->e_flags |= EF_CLRQUEUE;
1376			sm_setproctitle(TRUE, e, "%s %s: %.80s",
1377					qid_printname(e),
1378					CurSmtpClient, inp);
1379
1380			/* child -- go do the processing */
1381			if (setjmp(TopFrame) > 0)
1382			{
1383				/* this failed -- undo work */
1384 undo_subproc_no_pm:
1385				e->e_flags &= ~EF_PM_NOTIFY;
1386 undo_subproc:
1387				if (InChild)
1388				{
1389					QuickAbort = FALSE;
1390					SuprErrs = TRUE;
1391					e->e_flags &= ~EF_FATALERRS;
1392
1393					if (LogLevel > 4 &&
1394					    bitset(EF_LOGSENDER, e->e_flags))
1395						logsender(e, NULL);
1396					e->e_flags &= ~EF_LOGSENDER;
1397
1398					finis(TRUE, ExitStat);
1399				}
1400				break;
1401			}
1402			QuickAbort = TRUE;
1403
1404			/* must parse sender first */
1405			delimptr = NULL;
1406			setsender(p, e, &delimptr, ' ', FALSE);
1407			if (delimptr != NULL && *delimptr != '\0')
1408				*delimptr++ = '\0';
1409			if (Errors > 0)
1410				goto undo_subproc_no_pm;
1411
1412			/* Successfully set e_from, allow logging */
1413			e->e_flags |= EF_LOGSENDER;
1414
1415			/* put resulting triple from parseaddr() into macros */
1416			if (e->e_from.q_mailer != NULL)
1417				 define(macid("{mail_mailer}", NULL),
1418					e->e_from.q_mailer->m_name, e);
1419			else
1420				 define(macid("{mail_mailer}", NULL),
1421					NULL, e);
1422			if (e->e_from.q_host != NULL)
1423				define(macid("{mail_host}", NULL),
1424				       e->e_from.q_host, e);
1425			else
1426				define(macid("{mail_host}", NULL),
1427				       "localhost", e);
1428			if (e->e_from.q_user != NULL)
1429				define(macid("{mail_addr}", NULL),
1430				       e->e_from.q_user, e);
1431			else
1432				define(macid("{mail_addr}", NULL),
1433				       NULL, e);
1434			if (Errors > 0)
1435			  goto undo_subproc_no_pm;
1436
1437			/* check for possible spoofing */
1438			if (RealUid != 0 && OpMode == MD_SMTP &&
1439			    !wordinclass(RealUserName, 't') &&
1440			    (!bitnset(M_LOCALMAILER,
1441				      e->e_from.q_mailer->m_flags) ||
1442			     strcmp(e->e_from.q_user, RealUserName) != 0))
1443			{
1444				auth_warning(e, "%s owned process doing -bs",
1445					RealUserName);
1446			}
1447
1448			/* now parse ESMTP arguments */
1449			e->e_msgsize = 0;
1450			addr = p;
1451			argno = 0;
1452			args[argno++] = p;
1453			p = delimptr;
1454			while (p != NULL && *p != '\0')
1455			{
1456				char *kp;
1457				char *vp = NULL;
1458				char *equal = NULL;
1459
1460				/* locate the beginning of the keyword */
1461				while (isascii(*p) && isspace(*p))
1462					p++;
1463				if (*p == '\0')
1464					break;
1465				kp = p;
1466
1467				/* skip to the value portion */
1468				while ((isascii(*p) && isalnum(*p)) || *p == '-')
1469					p++;
1470				if (*p == '=')
1471				{
1472					equal = p;
1473					*p++ = '\0';
1474					vp = p;
1475
1476					/* skip to the end of the value */
1477					while (*p != '\0' && *p != ' ' &&
1478					       !(isascii(*p) && iscntrl(*p)) &&
1479					       *p != '=')
1480						p++;
1481				}
1482
1483				if (*p != '\0')
1484					*p++ = '\0';
1485
1486				if (tTd(19, 1))
1487					dprintf("MAIL: got arg %s=\"%s\"\n", kp,
1488						vp == NULL ? "<null>" : vp);
1489
1490				mail_esmtp_args(kp, vp, e);
1491				if (equal != NULL)
1492					*equal = '=';
1493				args[argno++] = kp;
1494				if (argno >= MAXSMTPARGS - 1)
1495					usrerr("501 5.5.4 Too many parameters");
1496				if (Errors > 0)
1497					goto undo_subproc_no_pm;
1498			}
1499			args[argno] = NULL;
1500			if (Errors > 0)
1501				goto undo_subproc_no_pm;
1502
1503			/* do config file checking of the sender */
1504			if (rscheck("check_mail", addr,
1505				    NULL, e, TRUE, TRUE, 4) != EX_OK ||
1506			    Errors > 0)
1507				goto undo_subproc_no_pm;
1508
1509			if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize)
1510			{
1511				usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
1512					MaxMessageSize);
1513				goto undo_subproc_no_pm;
1514			}
1515
1516			if (!enoughdiskspace(e->e_msgsize, TRUE))
1517			{
1518				usrerr("452 4.4.5 Insufficient disk space; try again later");
1519				goto undo_subproc_no_pm;
1520			}
1521			if (Errors > 0)
1522				goto undo_subproc_no_pm;
1523
1524# if _FFR_MILTER
1525			LogUsrErrs = TRUE;
1526			if (milterize && !bitset(EF_DISCARD, e->e_flags))
1527			{
1528				char state;
1529				char *response;
1530
1531				response = milter_envfrom(args, e, &state);
1532				switch (state)
1533				{
1534				  case SMFIR_REPLYCODE:
1535					usrerr(response);
1536					break;
1537
1538				  case SMFIR_REJECT:
1539					usrerr("550 5.7.1 Command rejected");
1540					break;
1541
1542				  case SMFIR_DISCARD:
1543					e->e_flags |= EF_DISCARD;
1544					break;
1545
1546				  case SMFIR_TEMPFAIL:
1547					usrerr("451 4.7.1 Try again later");
1548					break;
1549				}
1550				if (response != NULL)
1551					free(response);
1552			}
1553# endif /* _FFR_MILTER */
1554			if (Errors > 0)
1555				goto undo_subproc_no_pm;
1556
1557			message("250 2.1.0 Sender ok");
1558			gotmail = TRUE;
1559			break;
1560
1561		  case CMDRCPT:		/* rcpt -- designate recipient */
1562			if (!gotmail)
1563			{
1564				usrerr("503 5.0.0 Need MAIL before RCPT");
1565				break;
1566			}
1567			SmtpPhase = "server RCPT";
1568			if (setjmp(TopFrame) > 0)
1569			{
1570				e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY);
1571				break;
1572			}
1573			QuickAbort = TRUE;
1574			LogUsrErrs = TRUE;
1575
1576			/* limit flooding of our machine */
1577			if (MaxRcptPerMsg > 0 && nrcpts >= MaxRcptPerMsg)
1578			{
1579				usrerr("452 4.5.3 Too many recipients");
1580				break;
1581			}
1582
1583			if (e->e_sendmode != SM_DELIVER)
1584				e->e_flags |= EF_VRFYONLY;
1585
1586# if _FFR_MILTER
1587			/*
1588			**  If the filter will be deleting recipients,
1589			**  don't expand them at RCPT time (in the call
1590			**  to recipient()).  If they are expanded, it
1591			**  is impossible for removefromlist() to figure
1592			**  out the expanded members of the original
1593			**  recipient and mark them as QS_DONTSEND.
1594			*/
1595
1596			if (milter_can_delrcpts())
1597				e->e_flags |= EF_VRFYONLY;
1598# endif /* _FFR_MILTER */
1599
1600			p = skipword(p, "to");
1601			if (p == NULL)
1602				break;
1603# if _FFR_ADDR_TYPE
1604			define(macid("{addr_type}", NULL), "e r", e);
1605# endif /* _FFR_ADDR_TYPE */
1606			a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr, e);
1607#if _FFR_ADDR_TYPE
1608			define(macid("{addr_type}", NULL), NULL, e);
1609#endif /* _FFR_ADDR_TYPE */
1610			if (Errors > 0)
1611				break;
1612			if (a == NULL)
1613			{
1614				usrerr("501 5.0.0 Missing recipient");
1615				break;
1616			}
1617
1618			if (delimptr != NULL && *delimptr != '\0')
1619				*delimptr++ = '\0';
1620
1621			/* put resulting triple from parseaddr() into macros */
1622			if (a->q_mailer != NULL)
1623				define(macid("{rcpt_mailer}", NULL),
1624				       a->q_mailer->m_name, e);
1625			else
1626				define(macid("{rcpt_mailer}", NULL),
1627				       NULL, e);
1628			if (a->q_host != NULL)
1629				define(macid("{rcpt_host}", NULL),
1630				       a->q_host, e);
1631			else
1632				define(macid("{rcpt_host}", NULL),
1633				       "localhost", e);
1634			if (a->q_user != NULL)
1635				define(macid("{rcpt_addr}", NULL),
1636				       a->q_user, e);
1637			else
1638				define(macid("{rcpt_addr}", NULL),
1639				       NULL, e);
1640			if (Errors > 0)
1641				break;
1642
1643			/* now parse ESMTP arguments */
1644			addr = p;
1645			argno = 0;
1646			args[argno++] = p;
1647			p = delimptr;
1648			while (p != NULL && *p != '\0')
1649			{
1650				char *kp;
1651				char *vp = NULL;
1652				char *equal = NULL;
1653
1654				/* locate the beginning of the keyword */
1655				while (isascii(*p) && isspace(*p))
1656					p++;
1657				if (*p == '\0')
1658					break;
1659				kp = p;
1660
1661				/* skip to the value portion */
1662				while ((isascii(*p) && isalnum(*p)) || *p == '-')
1663					p++;
1664				if (*p == '=')
1665				{
1666					equal = p;
1667					*p++ = '\0';
1668					vp = p;
1669
1670					/* skip to the end of the value */
1671					while (*p != '\0' && *p != ' ' &&
1672					       !(isascii(*p) && iscntrl(*p)) &&
1673					       *p != '=')
1674						p++;
1675				}
1676
1677				if (*p != '\0')
1678					*p++ = '\0';
1679
1680				if (tTd(19, 1))
1681					dprintf("RCPT: got arg %s=\"%s\"\n", kp,
1682						vp == NULL ? "<null>" : vp);
1683
1684				rcpt_esmtp_args(a, kp, vp, e);
1685				if (equal != NULL)
1686					*equal = '=';
1687				args[argno++] = kp;
1688				if (argno >= MAXSMTPARGS - 1)
1689					usrerr("501 5.5.4 Too many parameters");
1690				if (Errors > 0)
1691					break;
1692			}
1693			args[argno] = NULL;
1694			if (Errors > 0)
1695				break;
1696
1697			/* do config file checking of the recipient */
1698			if (rscheck("check_rcpt", addr,
1699				    NULL, e, TRUE, TRUE, 4) != EX_OK ||
1700			    Errors > 0)
1701				break;
1702
1703# if _FFR_MILTER
1704			if (milterize && !bitset(EF_DISCARD, e->e_flags))
1705			{
1706				char state;
1707				char *response;
1708
1709				response = milter_envrcpt(args, e, &state);
1710				switch (state)
1711				{
1712				  case SMFIR_REPLYCODE:
1713					usrerr(response);
1714					break;
1715
1716				  case SMFIR_REJECT:
1717					usrerr("550 5.7.1 Command rejected");
1718					break;
1719
1720				  case SMFIR_DISCARD:
1721					e->e_flags |= EF_DISCARD;
1722					break;
1723
1724				  case SMFIR_TEMPFAIL:
1725					usrerr("451 4.7.1 Try again later");
1726					break;
1727				}
1728				if (response != NULL)
1729					free(response);
1730			}
1731# endif /* _FFR_MILTER */
1732
1733			define(macid("{rcpt_mailer}", NULL), NULL, e);
1734			define(macid("{rcpt_relay}", NULL), NULL, e);
1735			define(macid("{rcpt_addr}", NULL), NULL, e);
1736			define(macid("{dsn_notify}", NULL), NULL, e);
1737			if (Errors > 0)
1738				break;
1739
1740			/* save in recipient list after ESMTP mods */
1741			a = recipient(a, &e->e_sendqueue, 0, e);
1742			if (Errors > 0)
1743				break;
1744
1745			/* no errors during parsing, but might be a duplicate */
1746			e->e_to = a->q_paddr;
1747			if (!QS_IS_BADADDR(a->q_state))
1748			{
1749				if (e->e_queuedir == NOQDIR)
1750					initsys(e);
1751				message("250 2.1.5 Recipient ok%s",
1752					QS_IS_QUEUEUP(a->q_state) ?
1753						" (will queue)" : "");
1754				nrcpts++;
1755			}
1756			else
1757			{
1758				/* punt -- should keep message in ADDRESS.... */
1759				usrerr("550 5.1.1 Addressee unknown");
1760			}
1761			break;
1762
1763		  case CMDDATA:		/* data -- text of mail */
1764			SmtpPhase = "server DATA";
1765			if (!gotmail)
1766			{
1767				usrerr("503 5.0.0 Need MAIL command");
1768				break;
1769			}
1770			else if (nrcpts <= 0)
1771			{
1772				usrerr("503 5.0.0 Need RCPT (recipient)");
1773				break;
1774			}
1775
1776			/* put back discard bit */
1777			if (discard)
1778				e->e_flags |= EF_DISCARD;
1779
1780			/* check to see if we need to re-expand aliases */
1781			/* also reset QS_BADADDR on already-diagnosted addrs */
1782			doublequeue = FALSE;
1783			for (a = e->e_sendqueue; a != NULL; a = a->q_next)
1784			{
1785				if (QS_IS_VERIFIED(a->q_state) &&
1786				    !bitset(EF_DISCARD, e->e_flags))
1787				{
1788					/* need to re-expand aliases */
1789					doublequeue = TRUE;
1790				}
1791				if (QS_IS_BADADDR(a->q_state))
1792				{
1793					/* make this "go away" */
1794					a->q_state = QS_DONTSEND;
1795				}
1796			}
1797
1798			/* collect the text of the message */
1799			SmtpPhase = "collect";
1800			buffer_errors();
1801			collect(InChannel, TRUE, NULL, e);
1802
1803# if _FFR_MILTER
1804			if (milterize &&
1805			    Errors <= 0 &&
1806			    !bitset(EF_DISCARD, e->e_flags))
1807			{
1808				char state;
1809				char *response;
1810
1811				response = milter_data(e, &state);
1812				switch (state)
1813				{
1814				  case SMFIR_REPLYCODE:
1815					usrerr(response);
1816					break;
1817
1818				  case SMFIR_REJECT:
1819					usrerr("554 5.7.1 Command rejected");
1820					break;
1821
1822				  case SMFIR_DISCARD:
1823					e->e_flags |= EF_DISCARD;
1824					break;
1825
1826				  case SMFIR_TEMPFAIL:
1827					usrerr("451 4.7.1 Try again later");
1828					break;
1829				}
1830				if (response != NULL)
1831					free(response);
1832			}
1833
1834			/* abort message filters that didn't get the body */
1835			if (milterize)
1836				milter_abort(e);
1837# endif /* _FFR_MILTER */
1838
1839			/* redefine message size */
1840			if ((q = macvalue(macid("{msg_size}", NULL), e))
1841			    != NULL)
1842				free(q);
1843			snprintf(inp, sizeof inp, "%ld", e->e_msgsize);
1844			define(macid("{msg_size}", NULL), newstr(inp), e);
1845			if (Errors > 0)
1846			{
1847				/* Log who the mail would have gone to */
1848				if (LogLevel > 8 &&
1849				    e->e_message != NULL)
1850				{
1851					for (a = e->e_sendqueue;
1852					     a != NULL;
1853					     a = a->q_next)
1854					{
1855						if (!QS_IS_UNDELIVERED(a->q_state))
1856							continue;
1857
1858						e->e_to = a->q_paddr;
1859						logdelivery(NULL, NULL,
1860							    a->q_status,
1861							    e->e_message,
1862							    NULL,
1863							    (time_t) 0, e);
1864					}
1865					e->e_to = NULL;
1866				}
1867				flush_errors(TRUE);
1868				buffer_errors();
1869				goto abortmessage;
1870			}
1871
1872			/* make sure we actually do delivery */
1873			e->e_flags &= ~EF_CLRQUEUE;
1874
1875			/* from now on, we have to operate silently */
1876			buffer_errors();
1877			e->e_errormode = EM_MAIL;
1878
1879			/*
1880			**  Arrange to send to everyone.
1881			**	If sending to multiple people, mail back
1882			**		errors rather than reporting directly.
1883			**	In any case, don't mail back errors for
1884			**		anything that has happened up to
1885			**		now (the other end will do this).
1886			**	Truncate our transcript -- the mail has gotten
1887			**		to us successfully, and if we have
1888			**		to mail this back, it will be easier
1889			**		on the reader.
1890			**	Then send to everyone.
1891			**	Finally give a reply code.  If an error has
1892			**		already been given, don't mail a
1893			**		message back.
1894			**	We goose error returns by clearing error bit.
1895			*/
1896
1897			SmtpPhase = "delivery";
1898			(void) bftruncate(e->e_xfp);
1899			id = e->e_id;
1900
1901			/*
1902			**  If a header/body check (header checks or milter)
1903			**  set EF_DISCARD, don't queueup the message --
1904			**  that would lose the EF_DISCARD bit and deliver
1905			**  the message.
1906			*/
1907
1908			if (bitset(EF_DISCARD, e->e_flags))
1909				doublequeue = FALSE;
1910
1911			if (doublequeue)
1912			{
1913				/* make sure it is in the queue */
1914				queueup(e, FALSE);
1915			}
1916			else
1917			{
1918				/* send to all recipients */
1919# if NAMED_BIND
1920				_res.retry = TimeOuts.res_retry[RES_TO_FIRST];
1921				_res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
1922# endif /* NAMED_BIND */
1923				sendall(e, SM_DEFAULT);
1924			}
1925			e->e_to = NULL;
1926
1927			/* issue success message */
1928			message("250 2.0.0 %s Message accepted for delivery", id);
1929
1930			/* if we just queued, poke it */
1931			if (doublequeue &&
1932			    e->e_sendmode != SM_QUEUE &&
1933			    e->e_sendmode != SM_DEFER)
1934			{
1935				CurrentLA = sm_getla(e);
1936
1937				if (!shouldqueue(e->e_msgpriority, e->e_ctime))
1938				{
1939					/* close all the queue files */
1940					closexscript(e);
1941					if (e->e_dfp != NULL)
1942						(void) bfclose(e->e_dfp);
1943					e->e_dfp = NULL;
1944					unlockqueue(e);
1945
1946					(void) dowork(e->e_queuedir, id,
1947						      TRUE, TRUE, e);
1948				}
1949			}
1950
1951  abortmessage:
1952			if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
1953				logsender(e, NULL);
1954			e->e_flags &= ~EF_LOGSENDER;
1955
1956			/* if in a child, pop back to our parent */
1957			if (InChild)
1958				finis(TRUE, ExitStat);
1959
1960			/* clean up a bit */
1961			gotmail = FALSE;
1962			dropenvelope(e, TRUE);
1963			CurEnv = e = newenvelope(e, CurEnv);
1964			e->e_flags = BlankEnvelope.e_flags;
1965			break;
1966
1967		  case CMDRSET:		/* rset -- reset state */
1968# if _FFR_MILTER
1969			/* abort milter filters */
1970			milter_abort(e);
1971# endif /* _FFR_MILTER */
1972
1973			if (tTd(94, 100))
1974				message("451 4.0.0 Test failure");
1975			else
1976				message("250 2.0.0 Reset state");
1977
1978			/* arrange to ignore any current send list */
1979			e->e_sendqueue = NULL;
1980			e->e_flags |= EF_CLRQUEUE;
1981
1982			if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
1983				logsender(e, NULL);
1984			e->e_flags &= ~EF_LOGSENDER;
1985
1986			if (InChild)
1987				finis(TRUE, ExitStat);
1988
1989			/* clean up a bit */
1990			gotmail = FALSE;
1991			SuprErrs = TRUE;
1992			dropenvelope(e, TRUE);
1993			CurEnv = e = newenvelope(e, CurEnv);
1994			break;
1995
1996		  case CMDVRFY:		/* vrfy -- verify address */
1997		  case CMDEXPN:		/* expn -- expand address */
1998			if (tempfail)
1999			{
2000				if (LogLevel > 9)
2001					sm_syslog(LOG_INFO, e->e_id,
2002						  "SMTP %s command (%.100s) from %.100s tempfailed (due to previous checks)",
2003						  c->cmd_code == CMDVRFY ? "VRFY" : "EXPN",
2004						  p, CurSmtpClient);
2005				usrerr("550 5.7.1 Please try again later");
2006				break;
2007			}
2008			wt = checksmtpattack(&nverifies, MAXVRFYCOMMANDS, FALSE,
2009				c->cmd_code == CMDVRFY ? "VRFY" : "EXPN", e);
2010			previous = curtime();
2011			vrfy = c->cmd_code == CMDVRFY;
2012			if (bitset(vrfy ? PRIV_NOVRFY : PRIV_NOEXPN,
2013						PrivacyFlags))
2014			{
2015				if (vrfy)
2016					message("252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
2017				else
2018					message("502 5.7.0 Sorry, we do not allow this operation");
2019				if (LogLevel > 5)
2020					sm_syslog(LOG_INFO, e->e_id,
2021						  "%.100s: %s [rejected]",
2022						  CurSmtpClient,
2023						  shortenstring(inp, MAXSHORTSTR));
2024				break;
2025			}
2026			else if (!gothello &&
2027				 bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO,
2028						PrivacyFlags))
2029			{
2030				usrerr("503 5.0.0 I demand that you introduce yourself first");
2031				break;
2032			}
2033			if (runinchild(vrfy ? "SMTP-VRFY" : "SMTP-EXPN", e) > 0)
2034				break;
2035			if (Errors > 0)
2036				goto undo_subproc;
2037			if (LogLevel > 5)
2038				sm_syslog(LOG_INFO, e->e_id,
2039					  "%.100s: %s",
2040					  CurSmtpClient,
2041					  shortenstring(inp, MAXSHORTSTR));
2042			if (setjmp(TopFrame) > 0)
2043				goto undo_subproc;
2044			QuickAbort = TRUE;
2045			vrfyqueue = NULL;
2046			if (vrfy)
2047				e->e_flags |= EF_VRFYONLY;
2048			while (*p != '\0' && isascii(*p) && isspace(*p))
2049				p++;
2050			if (*p == '\0')
2051			{
2052				usrerr("501 5.5.2 Argument required");
2053			}
2054			else
2055			{
2056				/* do config file checking of the address */
2057				if (rscheck(vrfy ? "check_vrfy" : "check_expn",
2058					    p, NULL, e, TRUE, FALSE, 4)
2059				    != EX_OK || Errors > 0)
2060					goto undo_subproc;
2061				(void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
2062			}
2063			if (wt > 0)
2064				(void) sleep(wt - (curtime() - previous));
2065			if (Errors > 0)
2066				goto undo_subproc;
2067			if (vrfyqueue == NULL)
2068			{
2069				usrerr("554 5.5.2 Nothing to %s", vrfy ? "VRFY" : "EXPN");
2070			}
2071			while (vrfyqueue != NULL)
2072			{
2073				if (!QS_IS_UNDELIVERED(vrfyqueue->q_state))
2074				{
2075					vrfyqueue = vrfyqueue->q_next;
2076					continue;
2077				}
2078
2079				/* see if there is more in the vrfy list */
2080				a = vrfyqueue;
2081				while ((a = a->q_next) != NULL &&
2082				       (!QS_IS_UNDELIVERED(vrfyqueue->q_state)))
2083					continue;
2084				printvrfyaddr(vrfyqueue, a == NULL, vrfy);
2085				vrfyqueue = a;
2086			}
2087			if (InChild)
2088				finis(TRUE, ExitStat);
2089			break;
2090
2091		  case CMDETRN:		/* etrn -- force queue flush */
2092			if (bitset(PRIV_NOETRN, PrivacyFlags) ||
2093			    bitnset(D_NOETRN, d_flags))
2094			{
2095				/* different message for MSA ? */
2096				message("502 5.7.0 Sorry, we do not allow this operation");
2097				if (LogLevel > 5)
2098					sm_syslog(LOG_INFO, e->e_id,
2099						  "%.100s: %s [rejected]",
2100						  CurSmtpClient,
2101						  shortenstring(inp, MAXSHORTSTR));
2102				break;
2103			}
2104			if (tempfail)
2105			{
2106				if (LogLevel > 9)
2107					sm_syslog(LOG_INFO, e->e_id,
2108						  "SMTP ETRN command (%.100s) from %.100s tempfailed (due to previous checks)",
2109						  p, CurSmtpClient);
2110				usrerr("451 4.7.1 Please try again later");
2111				break;
2112			}
2113
2114			if (strlen(p) <= 0)
2115			{
2116				usrerr("500 5.5.2 Parameter required");
2117				break;
2118			}
2119
2120			/* crude way to avoid denial-of-service attacks */
2121			(void) checksmtpattack(&n_etrn, MAXETRNCOMMANDS, TRUE,
2122					     "ETRN", e);
2123
2124			/* do config file checking of the parameter */
2125			if (rscheck("check_etrn", p, NULL, e, TRUE, FALSE, 4)
2126			    != EX_OK || Errors > 0)
2127				break;
2128
2129			if (LogLevel > 5)
2130				sm_syslog(LOG_INFO, e->e_id,
2131					  "%.100s: ETRN %s",
2132					  CurSmtpClient,
2133					  shortenstring(p, MAXSHORTSTR));
2134
2135			id = p;
2136			if (*id == '@')
2137				id++;
2138			else
2139				*--id = '@';
2140
2141			if ((new = (QUEUE_CHAR *)malloc(sizeof(QUEUE_CHAR))) == NULL)
2142			{
2143				syserr("500 5.5.0 ETRN out of memory");
2144				break;
2145			}
2146			new->queue_match = id;
2147			new->queue_next = NULL;
2148			QueueLimitRecipient = new;
2149			ok = runqueue(TRUE, FALSE);
2150			free(QueueLimitRecipient);
2151			QueueLimitRecipient = NULL;
2152			if (ok && Errors == 0)
2153				message("250 2.0.0 Queuing for node %s started", p);
2154			break;
2155
2156		  case CMDHELP:		/* help -- give user info */
2157			help(p, e);
2158			break;
2159
2160		  case CMDNOOP:		/* noop -- do nothing */
2161			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, TRUE,
2162					       "NOOP", e);
2163			message("250 2.0.0 OK");
2164			break;
2165
2166		  case CMDQUIT:		/* quit -- leave mail */
2167			message("221 2.0.0 %s closing connection", MyHostName);
2168
2169			/* arrange to ignore any current send list */
2170			e->e_sendqueue = NULL;
2171
2172# if STARTTLS
2173			/* shutdown TLS connection */
2174			if (tls_active)
2175			{
2176				(void) endtls(srv_ssl, "server");
2177				tls_active = FALSE;
2178			}
2179# endif /* STARTTLS */
2180# if SASL
2181			if (authenticating == SASL_IS_AUTH)
2182			{
2183				sasl_dispose(&conn);
2184				authenticating = SASL_NOT_AUTH;
2185			}
2186# endif /* SASL */
2187
2188doquit:
2189			/* avoid future 050 messages */
2190			disconnect(1, e);
2191
2192# if _FFR_MILTER
2193			/* close out milter filters */
2194			milter_quit(e);
2195# endif /* _FFR_MILTER */
2196
2197			if (InChild)
2198				ExitStat = EX_QUIT;
2199
2200			if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
2201				logsender(e, NULL);
2202			e->e_flags &= ~EF_LOGSENDER;
2203
2204			if (lognullconnection && LogLevel > 5)
2205			{
2206				char *d;
2207
2208				d = macvalue(macid("{daemon_name}", NULL), e);
2209				if (d == NULL)
2210					d = "stdin";
2211				sm_syslog(LOG_INFO, NULL,
2212					 "%.100s did not issue MAIL/EXPN/VRFY/ETRN during connection to %s",
2213					  CurSmtpClient, d);
2214			}
2215			finis(TRUE, ExitStat);
2216			/* NOTREACHED */
2217
2218		  case CMDVERB:		/* set verbose mode */
2219			if (bitset(PRIV_NOEXPN, PrivacyFlags) ||
2220			    bitset(PRIV_NOVERB, PrivacyFlags))
2221			{
2222				/* this would give out the same info */
2223				message("502 5.7.0 Verbose unavailable");
2224				break;
2225			}
2226			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, TRUE,
2227					       "VERB", e);
2228			Verbose = 1;
2229			set_delivery_mode(SM_DELIVER, e);
2230			message("250 2.0.0 Verbose mode");
2231			break;
2232
2233		  case CMDONEX:		/* doing one transaction only */
2234			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, TRUE,
2235					       "ONEX", e);
2236			OneXact = TRUE;
2237			message("250 2.0.0 Only one transaction");
2238			break;
2239
2240		  case CMDXUSR:		/* initial (user) submission */
2241			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, TRUE,
2242					       "XUSR", e);
2243			define(macid("{daemon_flags}", NULL), "c u", CurEnv);
2244			message("250 2.0.0 Initial submission");
2245			break;
2246
2247# if SMTPDEBUG
2248		  case CMDDBGQSHOW:	/* show queues */
2249			printf("Send Queue=");
2250			printaddr(e->e_sendqueue, TRUE);
2251			break;
2252
2253		  case CMDDBGDEBUG:	/* set debug mode */
2254			tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
2255			tTflag(p);
2256			message("200 2.0.0 Debug set");
2257			break;
2258
2259# else /* SMTPDEBUG */
2260		  case CMDDBGQSHOW:	/* show queues */
2261		  case CMDDBGDEBUG:	/* set debug mode */
2262# endif /* SMTPDEBUG */
2263		  case CMDLOGBOGUS:	/* bogus command */
2264			if (LogLevel > 0)
2265				sm_syslog(LOG_CRIT, e->e_id,
2266					  "\"%s\" command from %.100s (%.100s)",
2267					  c->cmd_name, CurSmtpClient,
2268					  anynet_ntoa(&RealHostAddr));
2269			/* FALLTHROUGH */
2270
2271		  case CMDERROR:	/* unknown command */
2272			if (++badcommands > MAXBADCOMMANDS)
2273			{
2274				message("421 4.7.0 %s Too many bad commands; closing connection",
2275					MyHostName);
2276
2277				/* arrange to ignore any current send list */
2278				e->e_sendqueue = NULL;
2279				goto doquit;
2280			}
2281
2282			usrerr("500 5.5.1 Command unrecognized: \"%s\"",
2283			       shortenstring(inp, MAXSHORTSTR));
2284			break;
2285
2286		  case CMDUNIMPL:
2287			usrerr("502 5.5.1 Command not implemented: \"%s\"",
2288			       shortenstring(inp, MAXSHORTSTR));
2289			break;
2290
2291		  default:
2292			errno = 0;
2293			syserr("500 5.5.0 smtp: unknown code %d", c->cmd_code);
2294			break;
2295		}
2296# if SASL
2297		}
2298# endif /* SASL */
2299	}
2300
2301}
2302/*
2303**  CHECKSMTPATTACK -- check for denial-of-service attack by repetition
2304**
2305**	Parameters:
2306**		pcounter -- pointer to a counter for this command.
2307**		maxcount -- maximum value for this counter before we
2308**			slow down.
2309**		waitnow -- sleep now (in this routine)?
2310**		cname -- command name for logging.
2311**		e -- the current envelope.
2312**
2313**	Returns:
2314**		none.
2315**
2316**	Side Effects:
2317**		Slows down if we seem to be under attack.
2318*/
2319
2320static time_t
2321checksmtpattack(pcounter, maxcount, waitnow, cname, e)
2322	volatile int *pcounter;
2323	int maxcount;
2324	bool waitnow;
2325	char *cname;
2326	ENVELOPE *e;
2327{
2328	if (++(*pcounter) >= maxcount)
2329	{
2330		time_t s;
2331
2332		if (*pcounter == maxcount && LogLevel > 5)
2333		{
2334			sm_syslog(LOG_INFO, e->e_id,
2335				  "%.100s: %.40s attack?",
2336				  CurSmtpClient, cname);
2337		}
2338		s = 1 << (*pcounter - maxcount);
2339		if (s >= MAXTIMEOUT)
2340			s = MAXTIMEOUT;
2341		/* sleep at least 1 second before returning */
2342		(void) sleep(*pcounter / maxcount);
2343		s -= *pcounter / maxcount;
2344		if (waitnow)
2345		{
2346			(void) sleep(s);
2347			return(0);
2348		}
2349		return(s);
2350	}
2351	return((time_t) 0);
2352}
2353/*
2354**  SKIPWORD -- skip a fixed word.
2355**
2356**	Parameters:
2357**		p -- place to start looking.
2358**		w -- word to skip.
2359**
2360**	Returns:
2361**		p following w.
2362**		NULL on error.
2363**
2364**	Side Effects:
2365**		clobbers the p data area.
2366*/
2367
2368static char *
2369skipword(p, w)
2370	register char *volatile p;
2371	char *w;
2372{
2373	register char *q;
2374	char *firstp = p;
2375
2376	/* find beginning of word */
2377	while (isascii(*p) && isspace(*p))
2378		p++;
2379	q = p;
2380
2381	/* find end of word */
2382	while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p)))
2383		p++;
2384	while (isascii(*p) && isspace(*p))
2385		*p++ = '\0';
2386	if (*p != ':')
2387	{
2388	  syntax:
2389		usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"",
2390			shortenstring(firstp, MAXSHORTSTR));
2391		return NULL;
2392	}
2393	*p++ = '\0';
2394	while (isascii(*p) && isspace(*p))
2395		p++;
2396
2397	if (*p == '\0')
2398		goto syntax;
2399
2400	/* see if the input word matches desired word */
2401	if (strcasecmp(q, w))
2402		goto syntax;
2403
2404	return p;
2405}
2406/*
2407**  MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
2408**
2409**	Parameters:
2410**		kp -- the parameter key.
2411**		vp -- the value of that parameter.
2412**		e -- the envelope.
2413**
2414**	Returns:
2415**		none.
2416*/
2417
2418static void
2419mail_esmtp_args(kp, vp, e)
2420	char *kp;
2421	char *vp;
2422	ENVELOPE *e;
2423{
2424	if (strcasecmp(kp, "size") == 0)
2425	{
2426		if (vp == NULL)
2427		{
2428			usrerr("501 5.5.2 SIZE requires a value");
2429			/* NOTREACHED */
2430		}
2431		define(macid("{msg_size}", NULL), newstr(vp), e);
2432# if defined(__STDC__) && !defined(BROKEN_ANSI_LIBRARY)
2433		e->e_msgsize = strtoul(vp, (char **) NULL, 10);
2434# else /* defined(__STDC__) && !defined(BROKEN_ANSI_LIBRARY) */
2435		e->e_msgsize = strtol(vp, (char **) NULL, 10);
2436# endif /* defined(__STDC__) && !defined(BROKEN_ANSI_LIBRARY) */
2437	}
2438	else if (strcasecmp(kp, "body") == 0)
2439	{
2440		if (vp == NULL)
2441		{
2442			usrerr("501 5.5.2 BODY requires a value");
2443			/* NOTREACHED */
2444		}
2445		else if (strcasecmp(vp, "8bitmime") == 0)
2446		{
2447			SevenBitInput = FALSE;
2448		}
2449		else if (strcasecmp(vp, "7bit") == 0)
2450		{
2451			SevenBitInput = TRUE;
2452		}
2453		else
2454		{
2455			usrerr("501 5.5.4 Unknown BODY type %s",
2456				vp);
2457			/* NOTREACHED */
2458		}
2459		e->e_bodytype = newstr(vp);
2460	}
2461	else if (strcasecmp(kp, "envid") == 0)
2462	{
2463		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
2464		{
2465			usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN");
2466			/* NOTREACHED */
2467		}
2468		if (vp == NULL)
2469		{
2470			usrerr("501 5.5.2 ENVID requires a value");
2471			/* NOTREACHED */
2472		}
2473		if (!xtextok(vp))
2474		{
2475			usrerr("501 5.5.4 Syntax error in ENVID parameter value");
2476			/* NOTREACHED */
2477		}
2478		if (e->e_envid != NULL)
2479		{
2480			usrerr("501 5.5.0 Duplicate ENVID parameter");
2481			/* NOTREACHED */
2482		}
2483		e->e_envid = newstr(vp);
2484		define(macid("{dsn_envid}", NULL), newstr(vp), e);
2485	}
2486	else if (strcasecmp(kp, "ret") == 0)
2487	{
2488		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
2489		{
2490			usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN");
2491			/* NOTREACHED */
2492		}
2493		if (vp == NULL)
2494		{
2495			usrerr("501 5.5.2 RET requires a value");
2496			/* NOTREACHED */
2497		}
2498		if (bitset(EF_RET_PARAM, e->e_flags))
2499		{
2500			usrerr("501 5.5.0 Duplicate RET parameter");
2501			/* NOTREACHED */
2502		}
2503		e->e_flags |= EF_RET_PARAM;
2504		if (strcasecmp(vp, "hdrs") == 0)
2505			e->e_flags |= EF_NO_BODY_RETN;
2506		else if (strcasecmp(vp, "full") != 0)
2507		{
2508			usrerr("501 5.5.2 Bad argument \"%s\" to RET", vp);
2509			/* NOTREACHED */
2510		}
2511		define(macid("{dsn_ret}", NULL), newstr(vp), e);
2512	}
2513# if SASL
2514	else if (strcasecmp(kp, "auth") == 0)
2515	{
2516		int len;
2517		char *q;
2518		char *auth_param;	/* the value of the AUTH=x */
2519		bool saveQuickAbort = QuickAbort;
2520		bool saveSuprErrs = SuprErrs;
2521		char pbuf[256];
2522
2523		if (vp == NULL)
2524		{
2525			usrerr("501 5.5.2 AUTH= requires a value");
2526			/* NOTREACHED */
2527		}
2528		if (e->e_auth_param != NULL)
2529		{
2530			usrerr("501 5.5.0 Duplicate AUTH parameter");
2531			/* NOTREACHED */
2532		}
2533		if ((q = strchr(vp, ' ')) != NULL)
2534			len = q - vp + 1;
2535		else
2536			len = strlen(vp) + 1;
2537		auth_param = xalloc(len);
2538		(void) strlcpy(auth_param, vp, len);
2539		if (!xtextok(auth_param))
2540		{
2541			usrerr("501 5.5.4 Syntax error in AUTH parameter value");
2542			/* just a warning? */
2543			/* NOTREACHED */
2544		}
2545
2546		/* XXX this might be cut off */
2547		snprintf(pbuf, sizeof pbuf, "%s", xuntextify(auth_param));
2548		/* xalloc() the buffer instead? */
2549
2550		/* XXX define this always or only if trusted? */
2551		define(macid("{auth_author}", NULL), newstr(pbuf), e);
2552
2553		/*
2554		**  call Strust_auth to find out whether
2555		**  auth_param is acceptable (trusted)
2556		**  we shouldn't trust it if not authenticated
2557		**  (required by RFC, leave it to ruleset?)
2558		*/
2559
2560		SuprErrs = TRUE;
2561		QuickAbort = FALSE;
2562		if (strcmp(auth_param, "<>") != 0 &&
2563		     (rscheck("trust_auth", pbuf, NULL, e, TRUE, FALSE, 10)
2564		      != EX_OK || Errors > 0))
2565		{
2566			if (tTd(95, 8))
2567			{
2568				q = e->e_auth_param;
2569				dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n",
2570					pbuf, (q == NULL) ? "" : q);
2571			}
2572			/* not trusted */
2573			e->e_auth_param = newstr("<>");
2574		}
2575		else
2576		{
2577			if (tTd(95, 8))
2578				dprintf("auth=\"%.100s\" trusted\n", pbuf);
2579			e->e_auth_param = newstr(auth_param);
2580		}
2581		free(auth_param);
2582		/* reset values */
2583		Errors = 0;
2584		QuickAbort = saveQuickAbort;
2585		SuprErrs = saveSuprErrs;
2586	}
2587# endif /* SASL */
2588	else
2589	{
2590		usrerr("501 5.5.4 %s parameter unrecognized", kp);
2591		/* NOTREACHED */
2592	}
2593}
2594/*
2595**  RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
2596**
2597**	Parameters:
2598**		a -- the address corresponding to the To: parameter.
2599**		kp -- the parameter key.
2600**		vp -- the value of that parameter.
2601**		e -- the envelope.
2602**
2603**	Returns:
2604**		none.
2605*/
2606
2607static void
2608rcpt_esmtp_args(a, kp, vp, e)
2609	ADDRESS *a;
2610	char *kp;
2611	char *vp;
2612	ENVELOPE *e;
2613{
2614	if (strcasecmp(kp, "notify") == 0)
2615	{
2616		char *p;
2617
2618		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
2619		{
2620			usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
2621			/* NOTREACHED */
2622		}
2623		if (vp == NULL)
2624		{
2625			usrerr("501 5.5.2 NOTIFY requires a value");
2626			/* NOTREACHED */
2627		}
2628		a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY);
2629		a->q_flags |= QHASNOTIFY;
2630		define(macid("{dsn_notify}", NULL), newstr(vp), e);
2631
2632		if (strcasecmp(vp, "never") == 0)
2633			return;
2634		for (p = vp; p != NULL; vp = p)
2635		{
2636			p = strchr(p, ',');
2637			if (p != NULL)
2638				*p++ = '\0';
2639			if (strcasecmp(vp, "success") == 0)
2640				a->q_flags |= QPINGONSUCCESS;
2641			else if (strcasecmp(vp, "failure") == 0)
2642				a->q_flags |= QPINGONFAILURE;
2643			else if (strcasecmp(vp, "delay") == 0)
2644				a->q_flags |= QPINGONDELAY;
2645			else
2646			{
2647				usrerr("501 5.5.4 Bad argument \"%s\"  to NOTIFY",
2648					vp);
2649				/* NOTREACHED */
2650			}
2651		}
2652	}
2653	else if (strcasecmp(kp, "orcpt") == 0)
2654	{
2655		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
2656		{
2657			usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN");
2658			/* NOTREACHED */
2659		}
2660		if (vp == NULL)
2661		{
2662			usrerr("501 5.5.2 ORCPT requires a value");
2663			/* NOTREACHED */
2664		}
2665		if (strchr(vp, ';') == NULL || !xtextok(vp))
2666		{
2667			usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
2668			/* NOTREACHED */
2669		}
2670		if (a->q_orcpt != NULL)
2671		{
2672			usrerr("501 5.5.0 Duplicate ORCPT parameter");
2673			/* NOTREACHED */
2674		}
2675		a->q_orcpt = newstr(vp);
2676	}
2677	else
2678	{
2679		usrerr("501 5.5.4 %s parameter unrecognized", kp);
2680		/* NOTREACHED */
2681	}
2682}
2683/*
2684**  PRINTVRFYADDR -- print an entry in the verify queue
2685**
2686**	Parameters:
2687**		a -- the address to print
2688**		last -- set if this is the last one.
2689**		vrfy -- set if this is a VRFY command.
2690**
2691**	Returns:
2692**		none.
2693**
2694**	Side Effects:
2695**		Prints the appropriate 250 codes.
2696*/
2697#define OFFF	(3 + 1 + 5 + 1)	/* offset in fmt: SMTP reply + enh. code */
2698
2699static void
2700printvrfyaddr(a, last, vrfy)
2701	register ADDRESS *a;
2702	bool last;
2703	bool vrfy;
2704{
2705	char fmtbuf[30];
2706
2707	if (vrfy && a->q_mailer != NULL &&
2708	    !bitnset(M_VRFY250, a->q_mailer->m_flags))
2709		(void) strlcpy(fmtbuf, "252", sizeof fmtbuf);
2710	else
2711		(void) strlcpy(fmtbuf, "250", sizeof fmtbuf);
2712	fmtbuf[3] = last ? ' ' : '-';
2713	(void) strlcpy(&fmtbuf[4], "2.1.5 ", sizeof fmtbuf - 4);
2714	if (a->q_fullname == NULL)
2715	{
2716		if ((a->q_mailer == NULL ||
2717		     a->q_mailer->m_addrtype == NULL ||
2718		     strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
2719		    strchr(a->q_user, '@') == NULL)
2720			(void) strlcpy(&fmtbuf[OFFF], "<%s@%s>",
2721				       sizeof fmtbuf - OFFF);
2722		else
2723			(void) strlcpy(&fmtbuf[OFFF], "<%s>",
2724				       sizeof fmtbuf - OFFF);
2725		message(fmtbuf, a->q_user, MyHostName);
2726	}
2727	else
2728	{
2729		if ((a->q_mailer == NULL ||
2730		     a->q_mailer->m_addrtype == NULL ||
2731		     strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
2732		    strchr(a->q_user, '@') == NULL)
2733			(void) strlcpy(&fmtbuf[OFFF], "%s <%s@%s>",
2734				       sizeof fmtbuf - OFFF);
2735		else
2736			(void) strlcpy(&fmtbuf[OFFF], "%s <%s>",
2737				       sizeof fmtbuf - OFFF);
2738		message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
2739	}
2740}
2741/*
2742**  RUNINCHILD -- return twice -- once in the child, then in the parent again
2743**
2744**	Parameters:
2745**		label -- a string used in error messages
2746**
2747**	Returns:
2748**		RIC_INCHILD in the child
2749**		RIC_INPARENT in the parent
2750**		RIC_TEMPFAIL tempfail condition
2751**
2752**	Side Effects:
2753**		none.
2754*/
2755
2756static int
2757runinchild(label, e)
2758	char *label;
2759	register ENVELOPE *e;
2760{
2761	pid_t childpid;
2762
2763	if (!OneXact)
2764	{
2765		extern int NumQueues;
2766
2767		/*
2768		**  advance state of PRNG
2769		**  this is necessary because otherwise all child processes
2770		**  will produce the same PRN sequence and hence the selection
2771		**  of a queue directory is not "really" random.
2772		*/
2773		if (NumQueues > 1)
2774			(void) get_random();
2775
2776		/*
2777		**  Disable child process reaping, in case ETRN has preceded
2778		**  MAIL command, and then fork.
2779		*/
2780
2781		(void) blocksignal(SIGCHLD);
2782
2783		childpid = dofork();
2784		if (childpid < 0)
2785		{
2786			syserr("451 4.3.0 %s: cannot fork", label);
2787			(void) releasesignal(SIGCHLD);
2788			return RIC_INPARENT;
2789		}
2790		if (childpid > 0)
2791		{
2792			auto int st;
2793
2794			/* parent -- wait for child to complete */
2795			sm_setproctitle(TRUE, e, "server %s child wait",
2796					CurSmtpClient);
2797			st = waitfor(childpid);
2798			if (st == -1)
2799				syserr("451 4.3.0 %s: lost child", label);
2800			else if (!WIFEXITED(st))
2801			{
2802				syserr("451 4.3.0 %s: died on signal %d",
2803				       label, st & 0177);
2804				return RIC_TEMPFAIL;
2805			}
2806
2807			/* if exited on a QUIT command, complete the process */
2808			if (WEXITSTATUS(st) == EX_QUIT)
2809			{
2810				disconnect(1, e);
2811				finis(TRUE, ExitStat);
2812			}
2813
2814			/* restore the child signal */
2815			(void) releasesignal(SIGCHLD);
2816
2817			return RIC_INPARENT;
2818		}
2819		else
2820		{
2821			/* child */
2822			InChild = TRUE;
2823			QuickAbort = FALSE;
2824			clearstats();
2825			clearenvelope(e, FALSE);
2826			assign_queueid(e);
2827			(void) setsignal(SIGCHLD, SIG_DFL);
2828			(void) releasesignal(SIGCHLD);
2829		}
2830	}
2831	return RIC_INCHILD;
2832}
2833
2834# if SASL
2835
2836/*
2837**  SASLMECHS -- get list of possible AUTH mechanisms
2838**
2839**	Parameters:
2840**		conn -- SASL connection info
2841**		mechlist -- output parameter for list of mechanisms
2842**
2843**	Returns:
2844**		number of mechs
2845*/
2846
2847static int
2848saslmechs(conn, mechlist)
2849	sasl_conn_t *conn;
2850	char **mechlist;
2851{
2852	int len, num, result;
2853
2854	/* "user" is currently unused */
2855	result = sasl_listmech(conn, "user", /* XXX */
2856			       "", " ", "", mechlist,
2857			       (u_int *)&len, (u_int *)&num);
2858	if (result == SASL_OK && num > 0)
2859	{
2860		if (LogLevel > 11)
2861			sm_syslog(LOG_INFO, NOQID,
2862				  "SASL: available mech=%s, allowed mech=%s",
2863				  *mechlist, AuthMechanisms);
2864		*mechlist = intersect(AuthMechanisms, *mechlist);
2865	}
2866	else
2867	{
2868		if (LogLevel > 9)
2869			sm_syslog(LOG_WARNING, NOQID,
2870				  "SASL error: listmech=%d, num=%d",
2871				  result, num);
2872	}
2873	return num;
2874}
2875
2876/*
2877**  PROXY_POLICY -- define proxy policy for AUTH
2878**
2879**	Parameters:
2880**		conntext -- unused
2881**		auth_identity -- authentication identity
2882**		requested_user -- authorization identity
2883**		user -- allowed user (output)
2884**		errstr -- possible error string (output)
2885**
2886**	Returns:
2887**		ok?
2888*/
2889
2890int
2891proxy_policy(context, auth_identity, requested_user, user, errstr)
2892	void *context;
2893	const char *auth_identity;
2894	const char *requested_user;
2895	const char **user;
2896	const char **errstr;
2897{
2898	if (user == NULL || auth_identity == NULL)
2899		return SASL_FAIL;
2900	*user = newstr(auth_identity);
2901	return SASL_OK;
2902}
2903
2904# endif /* SASL */
2905
2906# if STARTTLS
2907#  if !TLS_NO_RSA
2908RSA *rsa_tmp;	/* temporary RSA key */
2909static RSA * tmp_rsa_key __P((SSL *, int, int));
2910#  endif /* !TLS_NO_RSA */
2911
2912# if !NO_DH
2913static DH *get_dh512 __P((void));
2914
2915static unsigned char dh512_p[] =
2916{
2917	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
2918	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
2919	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
2920	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
2921	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
2922	0x47,0x74,0xE8,0x33
2923};
2924static unsigned char dh512_g[] =
2925{
2926	0x02
2927};
2928
2929static DH *
2930get_dh512()
2931{
2932	DH *dh = NULL;
2933
2934	if ((dh = DH_new()) == NULL)
2935		return(NULL);
2936	dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
2937	dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
2938	if ((dh->p == NULL) || (dh->g == NULL))
2939		return(NULL);
2940	return(dh);
2941}
2942# endif /* !NO_DH */
2943
2944/*
2945**  TLS_RAND_INIT -- initialize STARTTLS random generator
2946**
2947**	Parameters:
2948**		randfile -- name of file with random data
2949**		logl -- loglevel
2950**
2951**	Returns:
2952**		None. (not yet, maybe it should return success/failure?)
2953**
2954**	Side Effects:
2955**		initializes PRNG for tls library.
2956*/
2957
2958#define MIN_RAND_BYTES	16	/* 128 bits */
2959
2960void
2961tls_rand_init(randfile, logl)
2962	char *randfile;
2963	int logl;
2964{
2965#  ifndef HASURANDOMDEV
2966	/* not required if /dev/urandom exists, OpenSSL does it internally */
2967
2968#define RF_OK		0	/* randfile OK */
2969#define RF_MISS		1	/* randfile == NULL || *randfile == '\0' */
2970#define RF_UNKNOWN	2	/* unknown prefix for randfile */
2971
2972	bool ok;
2973	int randdef;
2974
2975	/*
2976	**  initialize PRNG
2977	*/
2978
2979	ok = FALSE;
2980	randdef = (randfile == NULL || *randfile == '\0') ? RF_MISS : RF_OK;
2981#   if EGD
2982	if (randdef == RF_OK && strncasecmp(randfile, "egd:", 4) == 0)
2983	{
2984		randfile += 4;
2985		if (RAND_egd(randfile) < 0)
2986		{
2987			sm_syslog(LOG_WARNING, NOQID,
2988				  "TLS: RAND_egd(%s) failed: random number generator not seeded",
2989				   randfile);
2990		}
2991		else
2992			ok = TRUE;
2993	}
2994	else
2995#   endif /* EGD */
2996	if (randdef == RF_OK && strncasecmp(randfile, "file:", 5) == 0)
2997	{
2998		int fd;
2999		long sff;
3000		struct stat st;
3001
3002		randfile += 5;
3003		sff = SFF_SAFEDIRPATH | SFF_NOWLINK
3004		      | SFF_NOGWFILES | SFF_NOWWFILES
3005		      | SFF_NOGRFILES | SFF_NOWRFILES
3006		      | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
3007		if ((fd = safeopen(randfile, O_RDONLY, 0, sff)) >= 0)
3008		{
3009			if (fstat(fd, &st) < 0)
3010			{
3011				if (LogLevel > logl)
3012					sm_syslog(LOG_ERR, NOQID,
3013						  "TLS: can't fstat(%s)",
3014						  randfile);
3015			}
3016			else
3017			{
3018				bool use, problem;
3019
3020				use = TRUE;
3021				problem = FALSE;
3022				if (st.st_mtime + 600 < curtime())
3023				{
3024					use = bitnset(DBS_INSUFFICIENTENTROPY,
3025						      DontBlameSendmail);
3026					problem = TRUE;
3027					if (LogLevel > logl)
3028						sm_syslog(LOG_ERR, NOQID,
3029							  "TLS: RandFile %s too old: %s",
3030							  randfile,
3031							  use ? "unsafe" :
3032								"unusable");
3033				}
3034				if (use && st.st_size < MIN_RAND_BYTES)
3035				{
3036					use = bitnset(DBS_INSUFFICIENTENTROPY,
3037						      DontBlameSendmail);
3038					problem = TRUE;
3039					if (LogLevel > logl)
3040						sm_syslog(LOG_ERR, NOQID,
3041							  "TLS: size(%s) < %d: %s",
3042							  randfile,
3043							  MIN_RAND_BYTES,
3044							  use ? "unsafe" :
3045								"unusable");
3046				}
3047				if (use)
3048					ok = RAND_load_file(randfile, -1) >=
3049					     MIN_RAND_BYTES;
3050				if (use && !ok)
3051				{
3052					if (LogLevel > logl)
3053						sm_syslog(LOG_WARNING,
3054							  NOQID,
3055							  "TLS: RAND_load_file(%s) failed: random number generator not seeded",
3056							  randfile);
3057				}
3058				if (problem)
3059					ok = FALSE;
3060			}
3061			if (ok || bitnset(DBS_INSUFFICIENTENTROPY,
3062					  DontBlameSendmail))
3063			{
3064				/* add this even if fstat() failed */
3065				RAND_seed((void *) &st, sizeof st);
3066			}
3067			(void) close(fd);
3068		}
3069		else
3070		{
3071			if (LogLevel > logl)
3072				sm_syslog(LOG_WARNING, NOQID,
3073					  "TLS: Warning: safeopen(%s) failed",
3074					  randfile);
3075		}
3076	}
3077	else if (randdef == RF_OK)
3078	{
3079		if (LogLevel > logl)
3080			sm_syslog(LOG_WARNING, NOQID,
3081				  "TLS: Error: no proper random file definition %s",
3082				  randfile);
3083		randdef = RF_UNKNOWN;
3084	}
3085	if (randdef == RF_MISS)
3086	{
3087		if (LogLevel > logl)
3088			sm_syslog(LOG_WARNING, NOQID,
3089				  "TLS: Error: missing random file definition");
3090	}
3091	if (!ok && bitnset(DBS_INSUFFICIENTENTROPY, DontBlameSendmail))
3092	{
3093		int i;
3094		long r;
3095		unsigned char buf[MIN_RAND_BYTES];
3096
3097		/* assert((MIN_RAND_BYTES % sizeof(long)) == 0); */
3098		for (i = 0; i <= sizeof(buf) - sizeof(long); i += sizeof(long))
3099		{
3100			r = get_random();
3101			(void) memcpy(buf + i, (void *) &r, sizeof(long));
3102		}
3103		RAND_seed(buf, sizeof buf);
3104		if (LogLevel > logl)
3105			sm_syslog(LOG_WARNING, NOQID,
3106				  "TLS: Warning: random number generator not properly seeded");
3107	}
3108#  endif /* !HASURANDOMDEV */
3109}
3110
3111/*
3112**  status in initialization
3113**  these flags keep track of the status of the initialization
3114**  i.e., whether a file exists (_EX) and whether it can be used (_OK)
3115**  [due to permissions]
3116*/
3117#define TLS_S_NONE	0x00000000	/* none yet  */
3118#define TLS_S_CERT_EX	0x00000001	/* CERT file exists */
3119#define TLS_S_CERT_OK	0x00000002	/* CERT file is ok */
3120#define TLS_S_KEY_EX	0x00000004	/* KEY file exists */
3121#define TLS_S_KEY_OK	0x00000008	/* KEY file is ok */
3122#define TLS_S_CERTP_EX	0x00000010	/* CA CERT PATH exists */
3123#define TLS_S_CERTP_OK	0x00000020	/* CA CERT PATH is ok */
3124#define TLS_S_CERTF_EX	0x00000040	/* CA CERT FILE exists */
3125#define TLS_S_CERTF_OK	0x00000080	/* CA CERT FILE is ok */
3126
3127# if _FFR_TLS_1
3128#define TLS_S_CERT2_EX	0x00001000	/* 2nd CERT file exists */
3129#define TLS_S_CERT2_OK	0x00002000	/* 2nd CERT file is ok */
3130#define TLS_S_KEY2_EX	0x00004000	/* 2nd KEY file exists */
3131#define TLS_S_KEY2_OK	0x00008000	/* 2nd KEY file is ok */
3132# endif /* _FFR_TLS_1 */
3133
3134#define TLS_S_DH_OK	0x00200000	/* DH cert is ok */
3135#define TLS_S_DHPAR_EX	0x00400000	/* DH param file exists */
3136#define TLS_S_DHPAR_OK	0x00800000	/* DH param file is ok to use */
3137
3138/*
3139**  TLS_OK_F -- can var be an absolute filename?
3140**
3141**	Parameters:
3142**		var -- filename
3143**		fn -- what is the filename used for?
3144**
3145**	Returns:
3146**		ok?
3147*/
3148
3149static bool
3150tls_ok_f(var, fn)
3151	char *var;
3152	char *fn;
3153{
3154	/* must be absolute pathname */
3155	if (var != NULL && *var == '/')
3156		return TRUE;
3157	if (LogLevel > 12)
3158		sm_syslog(LOG_WARNING, NOQID, "TLS: file %s missing", fn);
3159	return FALSE;
3160}
3161
3162/*
3163**  TLS_SAFE_F -- is a file safe to use?
3164**
3165**	Parameters:
3166**		var -- filename
3167**		sff -- flags for safefile()
3168**
3169**	Returns:
3170**		ok?
3171*/
3172
3173static bool
3174tls_safe_f(var, sff)
3175	char *var;
3176	long sff;
3177{
3178	int ret;
3179
3180	if ((ret = safefile(var, RunAsUid, RunAsGid, RunAsUserName, sff,
3181			    S_IRUSR, NULL)) == 0)
3182		return TRUE;
3183	if (LogLevel > 7)
3184		sm_syslog(LOG_WARNING, NOQID, "TLS: file %s unsafe: %s",
3185			  var, errstring(ret));
3186	return FALSE;
3187}
3188
3189/*
3190**  TLS_OK_F -- macro to simplify calls to tls_ok_f
3191**
3192**	Parameters:
3193**		var -- filename
3194**		fn -- what is the filename used for?
3195**		req -- is the file required?
3196**		st -- status bit to set if ok
3197**
3198**	Side Effects:
3199**		uses r, ok; may change ok and status.
3200**
3201*/
3202
3203#define TLS_OK_F(var, fn, req, st) if (ok) \
3204	{ \
3205		r = tls_ok_f(var, fn); \
3206		if (r) \
3207			status |= st; \
3208		else if (req) \
3209			ok = FALSE; \
3210	}
3211
3212/*
3213**  TLS_UNR -- macro to return whether a file should be unreadable
3214**
3215**	Parameters:
3216**		bit -- flag to test
3217**		req -- flags
3218**
3219**	Returns:
3220**		0/SFF_NORFILES
3221*/
3222#define TLS_UNR(bit, req)	(bitset(bit, req) ? SFF_NORFILES : 0)
3223
3224/*
3225**  TLS_SAFE_F -- macro to simplify calls to tls_safe_f
3226**
3227**	Parameters:
3228**		var -- filename
3229**		sff -- flags for safefile()
3230**		req -- is the file required?
3231**		ex -- does the file exist?
3232**		st -- status bit to set if ok
3233**
3234**	Side Effects:
3235**		uses r, ok, ex; may change ok and status.
3236**
3237*/
3238
3239#define TLS_SAFE_F(var, sff, req, ex, st) if (ex && ok) \
3240	{ \
3241		r = tls_safe_f(var, sff); \
3242		if (r) \
3243			status |= st;	\
3244		else if (req) \
3245			ok = FALSE;	\
3246	}
3247
3248/*
3249**  INITTLS -- initialize TLS
3250**
3251**	Parameters:
3252**		ctx -- pointer to context
3253**		req -- requirements for initialization (see sendmail.h)
3254**		srv -- server side?
3255**		certfile -- filename of certificate
3256**		keyfile -- filename of private key
3257**		cacertpath -- path to CAs
3258**		cacertfile -- file with CA
3259**		dhparam -- parameters for DH
3260**
3261**	Returns:
3262**		succeeded?
3263*/
3264
3265bool
3266inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
3267	SSL_CTX **ctx;
3268	u_long req;
3269	bool srv;
3270	char *certfile, *keyfile, *cacertpath, *cacertfile, *dhparam;
3271{
3272# if !NO_DH
3273	static DH *dh = NULL;
3274# endif /* !NO_DH */
3275	int r;
3276	bool ok;
3277	long sff, status;
3278	char *who;
3279# if _FFR_TLS_1
3280	char *cf2, *kf2;
3281# endif /* _FFR_TLS_1 */
3282
3283	status = TLS_S_NONE;
3284	who = srv ? "srv" : "clt";
3285	if (ctx == NULL)
3286		syserr("TLS: %s:inittls: ctx == NULL", who);
3287
3288	/* already initialized? (we could re-init...) */
3289	if (*ctx != NULL)
3290		return TRUE;
3291	ok = TRUE;
3292
3293# if _FFR_TLS_1
3294	/*
3295	**  look for a second filename: it must be separated by a ','
3296	**  no blanks allowed (they won't be skipped).
3297	**  we change a global variable here! this change will be undone
3298	**  before return from the function but only if it returns TRUE.
3299	**  this isn't a problem since in a failure case this function
3300	**  won't be called again with the same (overwritten) values.
3301	**  otherwise each return must be replaced with a goto endinittls.
3302	*/
3303	cf2 = NULL;
3304	kf2 = NULL;
3305	if (certfile != NULL && (cf2 = strchr(certfile, ',')) != NULL)
3306	{
3307		*cf2++ = '\0';
3308		if (keyfile != NULL && (kf2 = strchr(keyfile, ',')) != NULL)
3309			*kf2++ = '\0';
3310	}
3311# endif /* _FFR_TLS_1 */
3312
3313	/*
3314	**  what do we require from the client?
3315	**  must it have CERTs?
3316	**  introduce an option and decide based on that
3317	*/
3318
3319	TLS_OK_F(certfile, "CertFile", bitset(TLS_I_CERT_EX, req),
3320		 TLS_S_CERT_EX);
3321	TLS_OK_F(keyfile, "KeyFile", bitset(TLS_I_KEY_EX, req),
3322		 TLS_S_KEY_EX);
3323	TLS_OK_F(cacertpath, "CACERTPath", bitset(TLS_I_CERTP_EX, req),
3324		 TLS_S_CERTP_EX);
3325	TLS_OK_F(cacertfile, "CACERTFile", bitset(TLS_I_CERTF_EX, req),
3326		 TLS_S_CERTF_EX);
3327
3328# if _FFR_TLS_1
3329	if (cf2 != NULL)
3330	{
3331		TLS_OK_F(cf2, "CertFile", bitset(TLS_I_CERT_EX, req),
3332			 TLS_S_CERT2_EX);
3333	}
3334	if (kf2 != NULL)
3335	{
3336		TLS_OK_F(kf2, "KeyFile", bitset(TLS_I_KEY_EX, req),
3337			 TLS_S_KEY2_EX);
3338	}
3339# endif /* _FFR_TLS_1 */
3340
3341	/*
3342	**  valid values for dhparam are (only the first char is checked)
3343	**  none	no parameters: don't use DH
3344	**  512		generate 512 bit parameters (fixed)
3345	**  1024	generate 1024 bit parameters
3346	**  /file/name	read parameters from /file/name
3347	**  default is: 1024 for server, 512 for client (OK? XXX)
3348	*/
3349	if (bitset(TLS_I_TRY_DH, req))
3350	{
3351		if (dhparam != NULL)
3352		{
3353			char c = *dhparam;
3354
3355			if (c == '1')
3356				req |= TLS_I_DH1024;
3357			else if (c == '5')
3358				req |= TLS_I_DH512;
3359			else if (c != 'n' && c != 'N' && c != '/')
3360			{
3361				if (LogLevel > 12)
3362					sm_syslog(LOG_WARNING, NOQID,
3363						  "TLS: error: illegal value '%s' for DHParam",
3364						  dhparam);
3365				free(dhparam);
3366				dhparam = NULL;
3367			}
3368		}
3369		if (dhparam == NULL)
3370			dhparam = srv ? newstr("1") : newstr("5");
3371		else if (*dhparam == '/')
3372		{
3373			TLS_OK_F(dhparam, "DHParameters",
3374				 bitset(TLS_I_DHPAR_EX, req),
3375				 TLS_S_DHPAR_EX);
3376		}
3377	}
3378	if (!ok)
3379		return ok;
3380
3381	/* certfile etc. must be "safe". */
3382	sff = SFF_REGONLY | SFF_SAFEDIRPATH | SFF_NOWLINK
3383	     | SFF_NOGWFILES | SFF_NOWWFILES
3384	     | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
3385	if (DontLockReadFiles)
3386		sff |= SFF_NOLOCK;
3387
3388	TLS_SAFE_F(certfile, sff | TLS_UNR(TLS_I_CERT_UNR, req),
3389		   bitset(TLS_I_CERT_EX, req),
3390		   bitset(TLS_S_CERT_EX, status), TLS_S_CERT_OK);
3391	TLS_SAFE_F(keyfile, sff | TLS_UNR(TLS_I_KEY_UNR, req),
3392		   bitset(TLS_I_KEY_EX, req),
3393		   bitset(TLS_S_KEY_EX, status), TLS_S_KEY_OK);
3394	TLS_SAFE_F(cacertfile, sff | TLS_UNR(TLS_I_CERTF_UNR, req),
3395		   bitset(TLS_I_CERTF_EX, req),
3396		   bitset(TLS_S_CERTF_EX, status), TLS_S_CERTF_OK);
3397	TLS_SAFE_F(dhparam, sff | TLS_UNR(TLS_I_DHPAR_UNR, req),
3398		   bitset(TLS_I_DHPAR_EX, req),
3399		   bitset(TLS_S_DHPAR_EX, status), TLS_S_DHPAR_OK);
3400	if (!ok)
3401		return ok;
3402# if _FFR_TLS_1
3403	if (cf2 != NULL)
3404	{
3405		TLS_SAFE_F(cf2, sff | TLS_UNR(TLS_I_CERT_UNR, req),
3406			   bitset(TLS_I_CERT_EX, req),
3407			   bitset(TLS_S_CERT2_EX, status), TLS_S_CERT2_OK);
3408	}
3409	if (kf2 != NULL)
3410	{
3411		TLS_SAFE_F(kf2, sff | TLS_UNR(TLS_I_KEY_UNR, req),
3412			   bitset(TLS_I_KEY_EX, req),
3413			   bitset(TLS_S_KEY2_EX, status), TLS_S_KEY2_OK);
3414	}
3415# endif /* _FFR_TLS_1 */
3416
3417	/* create a method and a new context */
3418	if (srv)
3419	{
3420		if ((*ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
3421		{
3422			if (LogLevel > 7)
3423				sm_syslog(LOG_WARNING, NOQID,
3424					  "TLS: error: SSL_CTX_new(SSLv23_server_method()) failed");
3425			return FALSE;
3426		}
3427	}
3428	else
3429	{
3430		if ((*ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
3431		{
3432			if (LogLevel > 7)
3433				sm_syslog(LOG_WARNING, NOQID,
3434					  "TLS: error: SSL_CTX_new(SSLv23_client_method()) failed");
3435			return FALSE;
3436		}
3437	}
3438
3439#  if TLS_NO_RSA
3440	/* turn off backward compatibility, required for no-rsa */
3441	SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2);
3442#  endif /* TLS_NO_RSA */
3443
3444
3445#  if !TLS_NO_RSA
3446	/*
3447	**  Create a temporary RSA key
3448	**  XXX  Maybe we shouldn't create this always (even though it
3449	**  is only at startup).
3450	**  It is a time-consuming operation and it is not always necessary.
3451	**  maybe we should do it only on demand...
3452	*/
3453	if (bitset(TLS_I_RSA_TMP, req) &&
3454	    (rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL,
3455					NULL)) == NULL
3456	   )
3457	{
3458		if (LogLevel > 7)
3459		{
3460			sm_syslog(LOG_WARNING, NOQID,
3461				  "TLS: error: %s: RSA_generate_key failed",
3462				  who);
3463			if (LogLevel > 9)
3464				tlslogerr();
3465		}
3466		return FALSE;
3467	}
3468#  endif /* !TLS_NO_RSA */
3469
3470	/*
3471	**  load private key
3472	**  XXX change this for DSA-only version
3473	*/
3474	if (bitset(TLS_S_KEY_OK, status) &&
3475	    SSL_CTX_use_PrivateKey_file(*ctx, keyfile,
3476					 SSL_FILETYPE_PEM) <= 0)
3477	{
3478		if (LogLevel > 7)
3479		{
3480			sm_syslog(LOG_WARNING, NOQID,
3481				  "TLS: error: %s: SSL_CTX_use_PrivateKey_file(%s) failed",
3482				  who, keyfile);
3483			if (LogLevel > 9)
3484				tlslogerr();
3485		}
3486		if (bitset(TLS_I_USE_KEY, req))
3487			return FALSE;
3488	}
3489
3490	/* get the certificate file */
3491	if (bitset(TLS_S_CERT_OK, status) &&
3492	    SSL_CTX_use_certificate_file(*ctx, certfile,
3493					 SSL_FILETYPE_PEM) <= 0)
3494	{
3495		if (LogLevel > 7)
3496		{
3497			sm_syslog(LOG_WARNING, NOQID,
3498				  "TLS: error: %s: SSL_CTX_use_certificate_file(%s) failed",
3499				  who, certfile);
3500			if (LogLevel > 9)
3501				tlslogerr();
3502		}
3503		if (bitset(TLS_I_USE_CERT, req))
3504			return FALSE;
3505	}
3506
3507	/* check the private key */
3508	if (bitset(TLS_S_KEY_OK, status) &&
3509	    (r = SSL_CTX_check_private_key(*ctx)) <= 0)
3510	{
3511		/* Private key does not match the certificate public key */
3512		if (LogLevel > 5)
3513		{
3514			sm_syslog(LOG_WARNING, NOQID,
3515				  "TLS: error: %s: SSL_CTX_check_private_key failed(%s): %d",
3516				  who, keyfile, r);
3517			if (LogLevel > 9)
3518				tlslogerr();
3519		}
3520		if (bitset(TLS_I_USE_KEY, req))
3521			return FALSE;
3522	}
3523
3524# if _FFR_TLS_1
3525	/* XXX this code is pretty much duplicated from above! */
3526
3527	/* load private key */
3528	if (bitset(TLS_S_KEY2_OK, status) &&
3529	    SSL_CTX_use_PrivateKey_file(*ctx, kf2, SSL_FILETYPE_PEM) <= 0)
3530	{
3531		if (LogLevel > 7)
3532		{
3533			sm_syslog(LOG_WARNING, NOQID,
3534				  "TLS: error: %s: SSL_CTX_use_PrivateKey_file(%s) failed",
3535				  who, kf2);
3536			if (LogLevel > 9)
3537				tlslogerr();
3538		}
3539	}
3540
3541	/* get the certificate file */
3542	if (bitset(TLS_S_CERT2_OK, status) &&
3543	    SSL_CTX_use_certificate_file(*ctx, cf2, SSL_FILETYPE_PEM) <= 0)
3544	{
3545		if (LogLevel > 7)
3546		{
3547			sm_syslog(LOG_WARNING, NOQID,
3548				  "TLS: error: %s: SSL_CTX_use_certificate_file(%s) failed",
3549				  who, cf2);
3550			if (LogLevel > 9)
3551				tlslogerr();
3552		}
3553	}
3554
3555	/* we should also check the private key: */
3556	if (bitset(TLS_S_KEY2_OK, status) &&
3557	    (r = SSL_CTX_check_private_key(*ctx)) <= 0)
3558	{
3559		/* Private key does not match the certificate public key */
3560		if (LogLevel > 5)
3561		{
3562			sm_syslog(LOG_WARNING, NOQID,
3563				  "TLS: error: %s: SSL_CTX_check_private_key 2 failed: %d",
3564				  who, r);
3565			if (LogLevel > 9)
3566				tlslogerr();
3567		}
3568	}
3569# endif /* _FFR_TLS_1 */
3570
3571	/* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */
3572	SSL_CTX_set_options(*ctx, SSL_OP_ALL);	/* XXX bug compatibility? */
3573
3574# if !NO_DH
3575	/* Diffie-Hellman initialization */
3576	if (bitset(TLS_I_TRY_DH, req))
3577	{
3578		if (bitset(TLS_S_DHPAR_OK, status))
3579		{
3580			BIO *bio;
3581
3582			if ((bio = BIO_new_file(dhparam, "r")) != NULL)
3583			{
3584				dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3585				BIO_free(bio);
3586				if (dh == NULL && LogLevel > 7)
3587				{
3588					u_long err;
3589
3590					err = ERR_get_error();
3591					sm_syslog(LOG_WARNING, NOQID,
3592						  "TLS: error: %s: cannot read DH parameters(%s): %s",
3593						  who, dhparam,
3594						  ERR_error_string(err, NULL));
3595					if (LogLevel > 9)
3596						tlslogerr();
3597				}
3598			}
3599			else
3600			{
3601				if (LogLevel > 5)
3602				{
3603					sm_syslog(LOG_WARNING, NOQID,
3604						  "TLS: error: %s: BIO_new_file(%s) failed",
3605						  who, dhparam);
3606					if (LogLevel > 9)
3607						tlslogerr();
3608				}
3609			}
3610		}
3611		if (dh == NULL && bitset(TLS_I_DH1024, req))
3612		{
3613			DSA *dsa;
3614
3615			/* this takes a while! (7-130s on a 450MHz AMD K6-2) */
3616			dsa = DSA_generate_parameters(1024, NULL, 0, NULL,
3617						      NULL, 0, NULL);
3618			dh = DSA_dup_DH(dsa);
3619			DSA_free(dsa);
3620		}
3621		else
3622		if (dh == NULL && bitset(TLS_I_DH512, req))
3623			dh = get_dh512();
3624
3625		if (dh == NULL)
3626		{
3627			if (LogLevel > 9)
3628			{
3629				u_long err;
3630
3631				err = ERR_get_error();
3632				sm_syslog(LOG_WARNING, NOQID,
3633					  "TLS: error: %s: cannot read or set DH parameters(%s): %s",
3634					  who, dhparam,
3635					  ERR_error_string(err, NULL));
3636			}
3637			if (bitset(TLS_I_REQ_DH, req))
3638				return FALSE;
3639		}
3640		else
3641		{
3642			SSL_CTX_set_tmp_dh(*ctx, dh);
3643
3644			/* important to avoid small subgroup attacks */
3645			SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_DH_USE);
3646			if (LogLevel > 12)
3647				sm_syslog(LOG_INFO, NOQID,
3648					  "TLS: %s: Diffie-Hellman init, key=%d bit (%c)",
3649					  who, 8 * DH_size(dh), *dhparam);
3650			DH_free(dh);
3651		}
3652	}
3653# endif /* !NO_DH */
3654
3655
3656	/* XXX do we need this cache here? */
3657	if (bitset(TLS_I_CACHE, req))
3658		SSL_CTX_sess_set_cache_size(*ctx, 128);
3659	/* timeout? SSL_CTX_set_timeout(*ctx, TimeOut...); */
3660
3661	/* load certificate locations and default CA paths */
3662	if (bitset(TLS_S_CERTP_EX, status) && bitset(TLS_S_CERTF_EX, status))
3663	{
3664		if ((r = SSL_CTX_load_verify_locations(*ctx, cacertfile,
3665						       cacertpath)) == 1)
3666		{
3667#  if !TLS_NO_RSA
3668			if (bitset(TLS_I_RSA_TMP, req))
3669				SSL_CTX_set_tmp_rsa_callback(*ctx, tmp_rsa_key);
3670#  endif /* !TLS_NO_RSA */
3671
3672			/* ask to verify the peer */
3673			SSL_CTX_set_verify(*ctx, SSL_VERIFY_PEER, NULL);
3674
3675			/* install verify callback */
3676			SSL_CTX_set_cert_verify_callback(*ctx, tls_verify_cb,
3677							 NULL);
3678			SSL_CTX_set_client_CA_list(*ctx,
3679				SSL_load_client_CA_file(cacertfile));
3680		}
3681		else
3682		{
3683			/*
3684			**  can't load CA data; do we care?
3685			**  the data is necessary to authenticate the client,
3686			**  which in turn would be necessary
3687			**  if we want to allow relaying based on it.
3688			*/
3689			if (LogLevel > 5)
3690			{
3691				sm_syslog(LOG_WARNING, NOQID,
3692					  "TLS: error: %s: %d load verify locs %s, %s",
3693					  who, r, cacertpath, cacertfile);
3694				if (LogLevel > 9)
3695					tlslogerr();
3696			}
3697			if (bitset(TLS_I_VRFY_LOC, req))
3698				return FALSE;
3699		}
3700	}
3701
3702	/* XXX: make this dependent on an option? */
3703	if (tTd(96, 9))
3704		SSL_CTX_set_info_callback(*ctx, apps_ssl_info_cb);
3705
3706#  if _FFR_TLS_1
3707	/*
3708	**  XXX install our own cipher list: option?
3709	*/
3710	if (CipherList != NULL && *CipherList != '\0')
3711	{
3712		if (SSL_CTX_set_cipher_list(*ctx, CipherList) <= 0)
3713		{
3714			if (LogLevel > 7)
3715			{
3716				sm_syslog(LOG_WARNING, NOQID,
3717					  "TLS: error: %s: SSL_CTX_set_cipher_list(%s) failed, list ignored",
3718					  who, CipherList);
3719
3720				if (LogLevel > 9)
3721					tlslogerr();
3722			}
3723			/* failure if setting to this list is required? */
3724		}
3725	}
3726#  endif /* _FFR_TLS_1 */
3727	if (LogLevel > 12)
3728		sm_syslog(LOG_INFO, NOQID, "TLS: init(%s)=%d", who, ok);
3729
3730# if _FFR_TLS_1
3731#  if 0
3732	/*
3733	**  this label is required if we want to have a "clean" exit
3734	**  see the comments above at the initialization of cf2
3735	*/
3736    endinittls:
3737#  endif /* 0 */
3738
3739	/* undo damage to global variables */
3740	if (cf2 != NULL)
3741		*--cf2 = ',';
3742	if (kf2 != NULL)
3743		*--kf2 = ',';
3744# endif /* _FFR_TLS_1 */
3745
3746	return ok;
3747}
3748/*
3749**  INITSRVTLS -- initialize server side TLS
3750**
3751**	Parameters:
3752**		none.
3753**
3754**	Returns:
3755**		succeeded?
3756*/
3757
3758bool
3759initsrvtls()
3760{
3761
3762	tls_ok = inittls(&srv_ctx, TLS_I_SRV, TRUE, SrvCERTfile, Srvkeyfile,
3763			 CACERTpath, CACERTfile, DHParams);
3764	return tls_ok;
3765}
3766/*
3767**  TLS_GET_INFO -- get information about TLS connection
3768**
3769**	Parameters:
3770**		ssl -- SSL connection structure
3771**		e -- current envelope
3772**		srv -- server or client
3773**		host -- hostname of other side
3774**
3775**	Returns:
3776**		result of authentication.
3777**
3778**	Side Effects:
3779**		sets ${cipher}, ${tls_version}, ${verify}, ${cipher_bits},
3780**		${cert}
3781*/
3782
3783int
3784tls_get_info(ssl, e, srv, host)
3785	SSL *ssl;
3786	ENVELOPE *e;
3787	bool srv;
3788	char *host;
3789{
3790	SSL_CIPHER *c;
3791	int b, r;
3792	char *s;
3793	char bitstr[16];
3794	X509 *cert;
3795
3796	c = SSL_get_current_cipher(ssl);
3797	define(macid("{cipher}", NULL), newstr(SSL_CIPHER_get_name(c)), e);
3798	b = SSL_CIPHER_get_bits(c, &r);
3799	(void) snprintf(bitstr, sizeof bitstr, "%d", b);
3800	define(macid("{cipher_bits}", NULL), newstr(bitstr), e);
3801# if _FFR_TLS_1
3802	(void) snprintf(bitstr, sizeof bitstr, "%d", r);
3803	define(macid("{alg_bits}", NULL), newstr(bitstr), e);
3804# endif /* _FFR_TLS_1 */
3805	s = SSL_CIPHER_get_version(c);
3806	if (s == NULL)
3807		s = "UNKNOWN";
3808	define(macid("{tls_version}", NULL), newstr(s), e);
3809
3810	cert = SSL_get_peer_certificate(ssl);
3811	if (LogLevel >= 14)
3812		sm_syslog(LOG_INFO, e->e_id,
3813			  "TLS: get_verify in %s: %d get_peer: 0x%x",
3814			  srv ? "srv" : "clt",
3815			  SSL_get_verify_result(ssl), cert);
3816	if (cert != NULL)
3817	{
3818		char buf[MAXNAME];
3819
3820		X509_NAME_oneline(X509_get_subject_name(cert),
3821				  buf, sizeof buf);
3822		define(macid("{cert_subject}", NULL),
3823			       newstr(xtextify(buf, "<>\")")), e);
3824		X509_NAME_oneline(X509_get_issuer_name(cert),
3825				  buf, sizeof buf);
3826		define(macid("{cert_issuer}", NULL),
3827		       newstr(xtextify(buf, "<>\")")), e);
3828# if _FFR_TLS_1
3829		X509_NAME_get_text_by_NID(X509_get_subject_name(cert),
3830					  NID_commonName, buf, sizeof buf);
3831		define(macid("{cn_subject}", NULL),
3832		       newstr(xtextify(buf, "<>\")")), e);
3833		X509_NAME_get_text_by_NID(X509_get_issuer_name(cert),
3834					  NID_commonName, buf, sizeof buf);
3835		define(macid("{cn_issuer}", NULL),
3836		       newstr(xtextify(buf, "<>\")")), e);
3837# endif /* _FFR_TLS_1 */
3838	}
3839	else
3840	{
3841		define(macid("{cert_subject}", NULL), "", e);
3842		define(macid("{cert_issuer}", NULL), "", e);
3843# if _FFR_TLS_1
3844		define(macid("{cn_subject}", NULL), "", e);
3845		define(macid("{cn_issuer}", NULL), "", e);
3846# endif /* _FFR_TLS_1 */
3847	}
3848	switch(SSL_get_verify_result(ssl))
3849	{
3850	  case X509_V_OK:
3851		if (cert != NULL)
3852		{
3853			s = "OK";
3854			r = TLS_AUTH_OK;
3855		}
3856		else
3857		{
3858			s = "NO";
3859			r = TLS_AUTH_NO;
3860		}
3861		break;
3862	  default:
3863		s = "FAIL";
3864		r = TLS_AUTH_FAIL;
3865		break;
3866	}
3867	define(macid("{verify}", NULL), newstr(s), e);
3868	if (cert != NULL)
3869		X509_free(cert);
3870
3871	/* do some logging */
3872	if (LogLevel > 9)
3873	{
3874		char *vers, *s1, *s2, *bits;
3875
3876		vers = macvalue(macid("{tls_version}", NULL), e);
3877		bits = macvalue(macid("{cipher_bits}", NULL), e);
3878		s1 = macvalue(macid("{verify}", NULL), e);
3879		s2 = macvalue(macid("{cipher}", NULL), e);
3880		sm_syslog(LOG_INFO, NOQID,
3881			  "TLS: connection %s %.64s, version=%.16s, verify=%.16s, cipher=%.64s, bits=%.6s",
3882			  srv ? "from" : "to",
3883			  host == NULL ? "none" : host,
3884			  vers == NULL ? "none" : vers,
3885			  s1 == NULL ? "none" : s1,
3886			  s2 == NULL ? "none" : s2,
3887			  bits == NULL ? "0" : bits);
3888		if (LogLevel > 11)
3889		{
3890			/*
3891			**  maybe run xuntextify on the strings?
3892			**  that is easier to read but makes it maybe a bit
3893			**  more complicated to figure out the right values
3894			**  for the access map...
3895			*/
3896			s1 = macvalue(macid("{cert_subject}", NULL), e);
3897			s2 = macvalue(macid("{cert_issuer}", NULL), e);
3898			sm_syslog(LOG_INFO, NOQID,
3899				  "TLS: %s cert subject:%.128s, cert issuer=%.128s",
3900				  srv ? "client" : "server",
3901				  s1 == NULL ? "none" : s1,
3902				  s2 == NULL ? "none" : s2);
3903		}
3904	}
3905
3906	return r;
3907}
3908
3909# if !TLS_NO_RSA
3910/*
3911**  TMP_RSA_KEY -- return temporary RSA key
3912**
3913**	Parameters:
3914**		s -- SSL connection structure
3915**		export --
3916**		keylength --
3917**
3918**	Returns:
3919**		temporary RSA key.
3920*/
3921
3922/* ARGUSED0 */
3923static RSA *
3924tmp_rsa_key(s, export, keylength)
3925	SSL *s;
3926	int export;
3927	int keylength;
3928{
3929	return rsa_tmp;
3930}
3931# endif /* !TLS_NO_RSA */
3932/*
3933**  APPS_SSL_INFO_CB -- info callback for TLS connections
3934**
3935**	Parameters:
3936**		s -- SSL connection structure
3937**		where --
3938**		ret --
3939**
3940**	Returns:
3941**		none.
3942*/
3943
3944void
3945apps_ssl_info_cb(s, where, ret)
3946	SSL *s;
3947	int where;
3948	int ret;
3949{
3950	char *str;
3951	int w;
3952	BIO *bio_err = NULL;
3953
3954	if (LogLevel > 14)
3955		sm_syslog(LOG_INFO, NOQID,
3956			  "info_callback where 0x%x ret %d", where, ret);
3957
3958	w = where & ~SSL_ST_MASK;
3959	if (bio_err == NULL)
3960		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
3961
3962	if (w & SSL_ST_CONNECT)
3963		str = "SSL_connect";
3964	else if (w & SSL_ST_ACCEPT)
3965		str = "SSL_accept";
3966	else
3967		str = "undefined";
3968
3969	if (where & SSL_CB_LOOP)
3970	{
3971		if (LogLevel > 12)
3972			sm_syslog(LOG_NOTICE, NOQID,
3973			"%s:%s\n", str, SSL_state_string_long(s));
3974	}
3975	else if (where & SSL_CB_ALERT)
3976	{
3977		str = (where & SSL_CB_READ) ? "read" : "write";
3978		if (LogLevel > 12)
3979			sm_syslog(LOG_NOTICE, NOQID,
3980		"SSL3 alert %s:%s:%s\n",
3981			   str, SSL_alert_type_string_long(ret),
3982			   SSL_alert_desc_string_long(ret));
3983	}
3984	else if (where & SSL_CB_EXIT)
3985	{
3986		if (ret == 0)
3987		{
3988			if (LogLevel > 7)
3989				sm_syslog(LOG_WARNING, NOQID,
3990					"%s:failed in %s\n",
3991					str, SSL_state_string_long(s));
3992		}
3993		else if (ret < 0)
3994		{
3995			if (LogLevel > 7)
3996				sm_syslog(LOG_WARNING, NOQID,
3997					"%s:error in %s\n",
3998					str, SSL_state_string_long(s));
3999		}
4000	}
4001}
4002/*
4003**  TLS_VERIFY_LOG -- log verify error for TLS certificates
4004**
4005**	Parameters:
4006**		ok -- verify ok?
4007**		ctx -- x509 context
4008**
4009**	Returns:
4010**		0 -- fatal error
4011**		1 -- ok
4012*/
4013
4014static int
4015tls_verify_log(ok, ctx)
4016	int ok;
4017	X509_STORE_CTX *ctx;
4018{
4019	SSL *ssl;
4020	X509 *cert;
4021	int reason, depth;
4022	char buf[512];
4023
4024	cert = X509_STORE_CTX_get_current_cert(ctx);
4025	reason = X509_STORE_CTX_get_error(ctx);
4026	depth = X509_STORE_CTX_get_error_depth(ctx);
4027	ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx,
4028			SSL_get_ex_data_X509_STORE_CTX_idx());
4029
4030	if (ssl == NULL)
4031	{
4032		/* internal error */
4033		sm_syslog(LOG_ERR, NOQID,
4034			  "TLS: internal error: tls_verify_cb: ssl == NULL");
4035		return 0;
4036	}
4037
4038	X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof buf);
4039	sm_syslog(LOG_INFO, NOQID,
4040		  "TLS cert verify: depth=%d %s, state=%d, reason=%s\n",
4041		  depth, buf, ok, X509_verify_cert_error_string(reason));
4042	return 1;
4043}
4044
4045/*
4046**  TLS_VERIFY_CB -- verify callback for TLS certificates
4047**
4048**	Parameters:
4049**		ctx -- x509 context
4050**
4051**	Returns:
4052**		accept connection?
4053**		currently: always yes.
4054*/
4055
4056static int
4057tls_verify_cb(ctx)
4058	X509_STORE_CTX *ctx;
4059{
4060	int ok;
4061
4062	ok = X509_verify_cert(ctx);
4063	if (ok == 0)
4064	{
4065		if (LogLevel > 13)
4066			return tls_verify_log(ok, ctx);
4067		return 1;	/* override it */
4068	}
4069	return ok;
4070}
4071
4072
4073/*
4074**  TLSLOGERR -- log the errors from the TLS error stack
4075**
4076**	Parameters:
4077**		none.
4078**
4079**	Returns:
4080**		none.
4081*/
4082
4083void
4084tlslogerr()
4085{
4086	unsigned long l;
4087	int line, flags;
4088	unsigned long es;
4089	char *file, *data;
4090	char buf[256];
4091#define CP (const char **)
4092
4093	es = CRYPTO_thread_id();
4094	while ((l = ERR_get_error_line_data(CP &file, &line, CP &data, &flags))
4095		!= 0)
4096	{
4097		sm_syslog(LOG_WARNING, NOQID,
4098			 "TLS: %lu:%s:%s:%d:%s\n", es, ERR_error_string(l, buf),
4099			 file, line, (flags & ERR_TXT_STRING) ? data : "");
4100	}
4101}
4102
4103# endif /* STARTTLS */
4104#endif /* SMTP */
4105/*
4106**  HELP -- implement the HELP command.
4107**
4108**	Parameters:
4109**		topic -- the topic we want help for.
4110**		e -- envelope
4111**
4112**	Returns:
4113**		none.
4114**
4115**	Side Effects:
4116**		outputs the help file to message output.
4117*/
4118#define HELPVSTR	"#vers	"
4119#define HELPVERSION	2
4120
4121void
4122help(topic, e)
4123	char *topic;
4124	ENVELOPE *e;
4125{
4126	register FILE *hf;
4127	register char *p;
4128	int len;
4129	bool noinfo;
4130	bool first = TRUE;
4131	long sff = SFF_OPENASROOT|SFF_REGONLY;
4132	char buf[MAXLINE];
4133	char inp[MAXLINE];
4134	static int foundvers = -1;
4135	extern char Version[];
4136
4137	if (DontLockReadFiles)
4138		sff |= SFF_NOLOCK;
4139	if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH, DontBlameSendmail))
4140		sff |= SFF_SAFEDIRPATH;
4141
4142	if (HelpFile == NULL ||
4143	    (hf = safefopen(HelpFile, O_RDONLY, 0444, sff)) == NULL)
4144	{
4145		/* no help */
4146		errno = 0;
4147		message("502 5.3.0 Sendmail %s -- HELP not implemented",
4148			Version);
4149		return;
4150	}
4151
4152	if (topic == NULL || *topic == '\0')
4153	{
4154		topic = "smtp";
4155		noinfo = FALSE;
4156	}
4157	else
4158	{
4159		makelower(topic);
4160		noinfo = TRUE;
4161	}
4162
4163	len = strlen(topic);
4164
4165	while (fgets(buf, sizeof buf, hf) != NULL)
4166	{
4167		if (buf[0] == '#')
4168		{
4169			if (foundvers < 0 &&
4170			    strncmp(buf, HELPVSTR, strlen(HELPVSTR)) == 0)
4171			{
4172				int h;
4173
4174				if (sscanf(buf + strlen(HELPVSTR), "%d",
4175					   &h) == 1)
4176					foundvers = h;
4177			}
4178			continue;
4179		}
4180		if (strncmp(buf, topic, len) == 0)
4181		{
4182			if (first)
4183			{
4184				first = FALSE;
4185
4186				/* print version if no/old vers# in file */
4187				if (foundvers < 2 && !noinfo)
4188					message("214-2.0.0 This is Sendmail version %s", Version);
4189			}
4190			p = strpbrk(buf, " \t");
4191			if (p == NULL)
4192				p = buf + strlen(buf) - 1;
4193			else
4194				p++;
4195			fixcrlf(p, TRUE);
4196			if (foundvers >= 2)
4197			{
4198				translate_dollars(p);
4199				expand(p, inp, sizeof inp, e);
4200				p = inp;
4201			}
4202			message("214-2.0.0 %s", p);
4203			noinfo = FALSE;
4204		}
4205	}
4206
4207	if (noinfo)
4208		message("504 5.3.0 HELP topic \"%.10s\" unknown", topic);
4209	else
4210		message("214 2.0.0 End of HELP info");
4211
4212	if (foundvers != 0 && foundvers < HELPVERSION)
4213	{
4214		if (LogLevel > 1)
4215			sm_syslog(LOG_WARNING, e->e_id,
4216				  "%s too old (require version %d)",
4217				  HelpFile, HELPVERSION);
4218
4219		/* avoid log next time */
4220		foundvers = 0;
4221	}
4222
4223	(void) fclose(hf);
4224}
4225