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