xref: /freebsd/contrib/sendmail/src/srvrsmtp.c (revision 77a0943ded95b9e6438f7db70c4a28e4d93946d4)
1 /*
2  * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
3  *	All rights reserved.
4  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5  * Copyright (c) 1988, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * By using this file, you agree to the terms and conditions set
9  * forth in the LICENSE file which can be found at the top level of
10  * the sendmail distribution.
11  *
12  */
13 
14 
15 #include <sendmail.h>
16 
17 #ifndef lint
18 # if SMTP
19 static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.58 2000/09/21 21:52:18 ca Exp $ (with SMTP)";
20 # else /* SMTP */
21 static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.58 2000/09/21 21:52:18 ca 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)
31 static 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 
42 static SSL	*srv_ssl = NULL;
43 static SSL_CTX	*srv_ctx = NULL;
44 #  if !TLS_NO_RSA
45 static RSA	*rsa = NULL;
46 #  endif /* !TLS_NO_RSA */
47 static bool	tls_ok = FALSE;
48 static 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 
54 static time_t	checksmtpattack __P((volatile int *, int, bool,
55 				     char *, ENVELOPE *));
56 static void	mail_esmtp_args __P((char *, char *, ENVELOPE *));
57 static void	printvrfyaddr __P((ADDRESS *, bool, bool));
58 static void	rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *));
59 static int	runinchild __P((char *, ENVELOPE *));
60 static char	*skipword __P((char *volatile, char *));
61 extern 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 
79 struct 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 
122 static 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 
157 static bool	OneXact = FALSE;	/* one xaction only this run */
158 static 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 
172 void
173 smtp(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) != EX_OK
380 		    || 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)
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 = 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);
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) != EX_OK ||
1071 			    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 = 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 						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 && 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) != EX_OK ||
1524 			    Errors > 0)
1525 				goto undo_subproc_no_pm;
1526 
1527 			if (MaxMessageSize > 0 &&
1528 			   (e->e_msgsize > MaxMessageSize || e->e_msgsize < 0))
1529 			{
1530 				usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
1531 					MaxMessageSize);
1532 				goto undo_subproc_no_pm;
1533 			}
1534 
1535 			if (!enoughdiskspace(e->e_msgsize, TRUE))
1536 			{
1537 				usrerr("452 4.4.5 Insufficient disk space; try again later");
1538 				goto undo_subproc_no_pm;
1539 			}
1540 			if (Errors > 0)
1541 				goto undo_subproc_no_pm;
1542 
1543 # if _FFR_MILTER
1544 			LogUsrErrs = TRUE;
1545 			if (milterize && !bitset(EF_DISCARD, e->e_flags))
1546 			{
1547 				char state;
1548 				char *response;
1549 
1550 				response = milter_envfrom(args, e, &state);
1551 				switch (state)
1552 				{
1553 				  case SMFIR_REPLYCODE:
1554 					usrerr(response);
1555 					break;
1556 
1557 				  case SMFIR_REJECT:
1558 					usrerr("550 5.7.1 Command rejected");
1559 					break;
1560 
1561 				  case SMFIR_DISCARD:
1562 					e->e_flags |= EF_DISCARD;
1563 					break;
1564 
1565 				  case SMFIR_TEMPFAIL:
1566 					usrerr("451 4.7.1 Please try again later");
1567 					break;
1568 				}
1569 				if (response != NULL)
1570 					free(response);
1571 			}
1572 # endif /* _FFR_MILTER */
1573 			if (Errors > 0)
1574 				goto undo_subproc_no_pm;
1575 
1576 			message("250 2.1.0 Sender ok");
1577 			gotmail = TRUE;
1578 			break;
1579 
1580 		  case CMDRCPT:		/* rcpt -- designate recipient */
1581 			if (!gotmail)
1582 			{
1583 				usrerr("503 5.0.0 Need MAIL before RCPT");
1584 				break;
1585 			}
1586 			SmtpPhase = "server RCPT";
1587 			if (setjmp(TopFrame) > 0)
1588 			{
1589 				e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY);
1590 				break;
1591 			}
1592 			QuickAbort = TRUE;
1593 			LogUsrErrs = TRUE;
1594 
1595 			/* limit flooding of our machine */
1596 			if (MaxRcptPerMsg > 0 && nrcpts >= MaxRcptPerMsg)
1597 			{
1598 				usrerr("452 4.5.3 Too many recipients");
1599 				break;
1600 			}
1601 
1602 			if (e->e_sendmode != SM_DELIVER)
1603 				e->e_flags |= EF_VRFYONLY;
1604 
1605 # if _FFR_MILTER
1606 			/*
1607 			**  If the filter will be deleting recipients,
1608 			**  don't expand them at RCPT time (in the call
1609 			**  to recipient()).  If they are expanded, it
1610 			**  is impossible for removefromlist() to figure
1611 			**  out the expanded members of the original
1612 			**  recipient and mark them as QS_DONTSEND.
1613 			*/
1614 
1615 			if (milter_can_delrcpts())
1616 				e->e_flags |= EF_VRFYONLY;
1617 # endif /* _FFR_MILTER */
1618 
1619 			p = skipword(p, "to");
1620 			if (p == NULL)
1621 				break;
1622 # if _FFR_ADDR_TYPE
1623 			define(macid("{addr_type}", NULL), "e r", e);
1624 # endif /* _FFR_ADDR_TYPE */
1625 			a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr, e);
1626 #if _FFR_ADDR_TYPE
1627 			define(macid("{addr_type}", NULL), NULL, e);
1628 #endif /* _FFR_ADDR_TYPE */
1629 			if (Errors > 0)
1630 				break;
1631 			if (a == NULL)
1632 			{
1633 				usrerr("501 5.0.0 Missing recipient");
1634 				break;
1635 			}
1636 
1637 			if (delimptr != NULL && *delimptr != '\0')
1638 				*delimptr++ = '\0';
1639 
1640 			/* put resulting triple from parseaddr() into macros */
1641 			if (a->q_mailer != NULL)
1642 				define(macid("{rcpt_mailer}", NULL),
1643 				       a->q_mailer->m_name, e);
1644 			else
1645 				define(macid("{rcpt_mailer}", NULL),
1646 				       NULL, e);
1647 			if (a->q_host != NULL)
1648 				define(macid("{rcpt_host}", NULL),
1649 				       a->q_host, e);
1650 			else
1651 				define(macid("{rcpt_host}", NULL),
1652 				       "localhost", e);
1653 			if (a->q_user != NULL)
1654 				define(macid("{rcpt_addr}", NULL),
1655 				       a->q_user, e);
1656 			else
1657 				define(macid("{rcpt_addr}", NULL),
1658 				       NULL, e);
1659 			if (Errors > 0)
1660 				break;
1661 
1662 			/* now parse ESMTP arguments */
1663 			addr = p;
1664 			argno = 0;
1665 			args[argno++] = p;
1666 			p = delimptr;
1667 			while (p != NULL && *p != '\0')
1668 			{
1669 				char *kp;
1670 				char *vp = NULL;
1671 				char *equal = NULL;
1672 
1673 				/* locate the beginning of the keyword */
1674 				while (isascii(*p) && isspace(*p))
1675 					p++;
1676 				if (*p == '\0')
1677 					break;
1678 				kp = p;
1679 
1680 				/* skip to the value portion */
1681 				while ((isascii(*p) && isalnum(*p)) || *p == '-')
1682 					p++;
1683 				if (*p == '=')
1684 				{
1685 					equal = p;
1686 					*p++ = '\0';
1687 					vp = p;
1688 
1689 					/* skip to the end of the value */
1690 					while (*p != '\0' && *p != ' ' &&
1691 					       !(isascii(*p) && iscntrl(*p)) &&
1692 					       *p != '=')
1693 						p++;
1694 				}
1695 
1696 				if (*p != '\0')
1697 					*p++ = '\0';
1698 
1699 				if (tTd(19, 1))
1700 					dprintf("RCPT: got arg %s=\"%s\"\n", kp,
1701 						vp == NULL ? "<null>" : vp);
1702 
1703 				rcpt_esmtp_args(a, kp, vp, e);
1704 				if (equal != NULL)
1705 					*equal = '=';
1706 				args[argno++] = kp;
1707 				if (argno >= MAXSMTPARGS - 1)
1708 					usrerr("501 5.5.4 Too many parameters");
1709 				if (Errors > 0)
1710 					break;
1711 			}
1712 			args[argno] = NULL;
1713 			if (Errors > 0)
1714 				break;
1715 
1716 			/* do config file checking of the recipient */
1717 			if (rscheck("check_rcpt", addr,
1718 				    NULL, e, TRUE, TRUE, 4) != EX_OK ||
1719 			    Errors > 0)
1720 				break;
1721 
1722 # if _FFR_MILTER
1723 			if (milterize && !bitset(EF_DISCARD, e->e_flags))
1724 			{
1725 				char state;
1726 				char *response;
1727 
1728 				response = milter_envrcpt(args, e, &state);
1729 				switch (state)
1730 				{
1731 				  case SMFIR_REPLYCODE:
1732 					usrerr(response);
1733 					break;
1734 
1735 				  case SMFIR_REJECT:
1736 					usrerr("550 5.7.1 Command rejected");
1737 					break;
1738 
1739 				  case SMFIR_DISCARD:
1740 					e->e_flags |= EF_DISCARD;
1741 					break;
1742 
1743 				  case SMFIR_TEMPFAIL:
1744 					usrerr("451 4.7.1 Please try again later");
1745 					break;
1746 				}
1747 				if (response != NULL)
1748 					free(response);
1749 			}
1750 # endif /* _FFR_MILTER */
1751 
1752 			define(macid("{rcpt_mailer}", NULL), NULL, e);
1753 			define(macid("{rcpt_relay}", NULL), NULL, e);
1754 			define(macid("{rcpt_addr}", NULL), NULL, e);
1755 			define(macid("{dsn_notify}", NULL), NULL, e);
1756 			if (Errors > 0)
1757 				break;
1758 
1759 			/* save in recipient list after ESMTP mods */
1760 			a = recipient(a, &e->e_sendqueue, 0, e);
1761 			if (Errors > 0)
1762 				break;
1763 
1764 			/* no errors during parsing, but might be a duplicate */
1765 			e->e_to = a->q_paddr;
1766 			if (!QS_IS_BADADDR(a->q_state))
1767 			{
1768 				if (e->e_queuedir == NOQDIR)
1769 					initsys(e);
1770 				message("250 2.1.5 Recipient ok%s",
1771 					QS_IS_QUEUEUP(a->q_state) ?
1772 						" (will queue)" : "");
1773 				nrcpts++;
1774 			}
1775 			else
1776 			{
1777 				/* punt -- should keep message in ADDRESS.... */
1778 				usrerr("550 5.1.1 Addressee unknown");
1779 			}
1780 			break;
1781 
1782 		  case CMDDATA:		/* data -- text of mail */
1783 			SmtpPhase = "server DATA";
1784 			if (!gotmail)
1785 			{
1786 				usrerr("503 5.0.0 Need MAIL command");
1787 				break;
1788 			}
1789 			else if (nrcpts <= 0)
1790 			{
1791 				usrerr("503 5.0.0 Need RCPT (recipient)");
1792 				break;
1793 			}
1794 
1795 			/* put back discard bit */
1796 			if (discard)
1797 				e->e_flags |= EF_DISCARD;
1798 
1799 			/* check to see if we need to re-expand aliases */
1800 			/* also reset QS_BADADDR on already-diagnosted addrs */
1801 			doublequeue = FALSE;
1802 			for (a = e->e_sendqueue; a != NULL; a = a->q_next)
1803 			{
1804 				if (QS_IS_VERIFIED(a->q_state) &&
1805 				    !bitset(EF_DISCARD, e->e_flags))
1806 				{
1807 					/* need to re-expand aliases */
1808 					doublequeue = TRUE;
1809 				}
1810 				if (QS_IS_BADADDR(a->q_state))
1811 				{
1812 					/* make this "go away" */
1813 					a->q_state = QS_DONTSEND;
1814 				}
1815 			}
1816 
1817 			/* collect the text of the message */
1818 			SmtpPhase = "collect";
1819 			buffer_errors();
1820 			collect(InChannel, TRUE, NULL, e);
1821 
1822 # if _FFR_MILTER
1823 			if (milterize &&
1824 			    Errors <= 0 &&
1825 			    !bitset(EF_DISCARD, e->e_flags))
1826 			{
1827 				char state;
1828 				char *response;
1829 
1830 				response = milter_data(e, &state);
1831 				switch (state)
1832 				{
1833 				  case SMFIR_REPLYCODE:
1834 					usrerr(response);
1835 					break;
1836 
1837 				  case SMFIR_REJECT:
1838 					usrerr("554 5.7.1 Command rejected");
1839 					break;
1840 
1841 				  case SMFIR_DISCARD:
1842 					e->e_flags |= EF_DISCARD;
1843 					break;
1844 
1845 				  case SMFIR_TEMPFAIL:
1846 					usrerr("451 4.7.1 Please try again later");
1847 					break;
1848 				}
1849 				if (response != NULL)
1850 					free(response);
1851 			}
1852 
1853 			/* abort message filters that didn't get the body */
1854 			if (milterize)
1855 				milter_abort(e);
1856 # endif /* _FFR_MILTER */
1857 
1858 			/* redefine message size */
1859 			if ((q = macvalue(macid("{msg_size}", NULL), e))
1860 			    != NULL)
1861 				free(q);
1862 			snprintf(inp, sizeof inp, "%ld", e->e_msgsize);
1863 			define(macid("{msg_size}", NULL), newstr(inp), e);
1864 			if (Errors > 0)
1865 			{
1866 				/* Log who the mail would have gone to */
1867 				if (LogLevel > 8 &&
1868 				    e->e_message != NULL)
1869 				{
1870 					for (a = e->e_sendqueue;
1871 					     a != NULL;
1872 					     a = a->q_next)
1873 					{
1874 						if (!QS_IS_UNDELIVERED(a->q_state))
1875 							continue;
1876 
1877 						e->e_to = a->q_paddr;
1878 						logdelivery(NULL, NULL,
1879 							    a->q_status,
1880 							    e->e_message,
1881 							    NULL,
1882 							    (time_t) 0, e);
1883 					}
1884 					e->e_to = NULL;
1885 				}
1886 				flush_errors(TRUE);
1887 				buffer_errors();
1888 				goto abortmessage;
1889 			}
1890 
1891 			/* make sure we actually do delivery */
1892 			e->e_flags &= ~EF_CLRQUEUE;
1893 
1894 			/* from now on, we have to operate silently */
1895 			buffer_errors();
1896 			e->e_errormode = EM_MAIL;
1897 
1898 			/*
1899 			**  Arrange to send to everyone.
1900 			**	If sending to multiple people, mail back
1901 			**		errors rather than reporting directly.
1902 			**	In any case, don't mail back errors for
1903 			**		anything that has happened up to
1904 			**		now (the other end will do this).
1905 			**	Truncate our transcript -- the mail has gotten
1906 			**		to us successfully, and if we have
1907 			**		to mail this back, it will be easier
1908 			**		on the reader.
1909 			**	Then send to everyone.
1910 			**	Finally give a reply code.  If an error has
1911 			**		already been given, don't mail a
1912 			**		message back.
1913 			**	We goose error returns by clearing error bit.
1914 			*/
1915 
1916 			SmtpPhase = "delivery";
1917 			(void) bftruncate(e->e_xfp);
1918 			id = e->e_id;
1919 
1920 			/*
1921 			**  If a header/body check (header checks or milter)
1922 			**  set EF_DISCARD, don't queueup the message --
1923 			**  that would lose the EF_DISCARD bit and deliver
1924 			**  the message.
1925 			*/
1926 
1927 			if (bitset(EF_DISCARD, e->e_flags))
1928 				doublequeue = FALSE;
1929 
1930 			if (doublequeue)
1931 			{
1932 				/* make sure it is in the queue */
1933 				queueup(e, FALSE);
1934 			}
1935 			else
1936 			{
1937 				/* send to all recipients */
1938 # if NAMED_BIND
1939 				_res.retry = TimeOuts.res_retry[RES_TO_FIRST];
1940 				_res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
1941 # endif /* NAMED_BIND */
1942 				sendall(e, SM_DEFAULT);
1943 			}
1944 			e->e_to = NULL;
1945 
1946 			/* issue success message */
1947 			message("250 2.0.0 %s Message accepted for delivery", id);
1948 
1949 			/* if we just queued, poke it */
1950 			if (doublequeue &&
1951 			    e->e_sendmode != SM_QUEUE &&
1952 			    e->e_sendmode != SM_DEFER)
1953 			{
1954 				CurrentLA = sm_getla(e);
1955 
1956 				if (!shouldqueue(e->e_msgpriority, e->e_ctime))
1957 				{
1958 					/* close all the queue files */
1959 					closexscript(e);
1960 					if (e->e_dfp != NULL)
1961 						(void) bfclose(e->e_dfp);
1962 					e->e_dfp = NULL;
1963 					unlockqueue(e);
1964 
1965 					(void) dowork(e->e_queuedir, id,
1966 						      TRUE, TRUE, e);
1967 				}
1968 			}
1969 
1970   abortmessage:
1971 			if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
1972 				logsender(e, NULL);
1973 			e->e_flags &= ~EF_LOGSENDER;
1974 
1975 			/* if in a child, pop back to our parent */
1976 			if (InChild)
1977 				finis(TRUE, ExitStat);
1978 
1979 			/* clean up a bit */
1980 			gotmail = FALSE;
1981 			dropenvelope(e, TRUE);
1982 			CurEnv = e = newenvelope(e, CurEnv);
1983 			e->e_flags = BlankEnvelope.e_flags;
1984 			break;
1985 
1986 		  case CMDRSET:		/* rset -- reset state */
1987 # if _FFR_MILTER
1988 			/* abort milter filters */
1989 			milter_abort(e);
1990 # endif /* _FFR_MILTER */
1991 
1992 			if (tTd(94, 100))
1993 				message("451 4.0.0 Test failure");
1994 			else
1995 				message("250 2.0.0 Reset state");
1996 
1997 			/* arrange to ignore any current send list */
1998 			e->e_sendqueue = NULL;
1999 			e->e_flags |= EF_CLRQUEUE;
2000 
2001 			if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
2002 				logsender(e, NULL);
2003 			e->e_flags &= ~EF_LOGSENDER;
2004 
2005 			if (InChild)
2006 				finis(TRUE, ExitStat);
2007 
2008 			/* clean up a bit */
2009 			gotmail = FALSE;
2010 			SuprErrs = TRUE;
2011 			dropenvelope(e, TRUE);
2012 			CurEnv = e = newenvelope(e, CurEnv);
2013 			break;
2014 
2015 		  case CMDVRFY:		/* vrfy -- verify address */
2016 		  case CMDEXPN:		/* expn -- expand address */
2017 			if (tempfail)
2018 			{
2019 				if (LogLevel > 9)
2020 					sm_syslog(LOG_INFO, e->e_id,
2021 						  "SMTP %s command (%.100s) from %.100s tempfailed (due to previous checks)",
2022 						  c->cmd_code == CMDVRFY ? "VRFY" : "EXPN",
2023 						  p, CurSmtpClient);
2024 				usrerr("550 5.7.1 Please try again later");
2025 				break;
2026 			}
2027 			wt = checksmtpattack(&nverifies, MAXVRFYCOMMANDS, FALSE,
2028 				c->cmd_code == CMDVRFY ? "VRFY" : "EXPN", e);
2029 			previous = curtime();
2030 			vrfy = c->cmd_code == CMDVRFY;
2031 			if (bitset(vrfy ? PRIV_NOVRFY : PRIV_NOEXPN,
2032 						PrivacyFlags))
2033 			{
2034 				if (vrfy)
2035 					message("252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
2036 				else
2037 					message("502 5.7.0 Sorry, we do not allow this operation");
2038 				if (LogLevel > 5)
2039 					sm_syslog(LOG_INFO, e->e_id,
2040 						  "%.100s: %s [rejected]",
2041 						  CurSmtpClient,
2042 						  shortenstring(inp, MAXSHORTSTR));
2043 				break;
2044 			}
2045 			else if (!gothello &&
2046 				 bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO,
2047 						PrivacyFlags))
2048 			{
2049 				usrerr("503 5.0.0 I demand that you introduce yourself first");
2050 				break;
2051 			}
2052 			if (runinchild(vrfy ? "SMTP-VRFY" : "SMTP-EXPN", e) > 0)
2053 				break;
2054 			if (Errors > 0)
2055 				goto undo_subproc;
2056 			if (LogLevel > 5)
2057 				sm_syslog(LOG_INFO, e->e_id,
2058 					  "%.100s: %s",
2059 					  CurSmtpClient,
2060 					  shortenstring(inp, MAXSHORTSTR));
2061 			if (setjmp(TopFrame) > 0)
2062 				goto undo_subproc;
2063 			QuickAbort = TRUE;
2064 			vrfyqueue = NULL;
2065 			if (vrfy)
2066 				e->e_flags |= EF_VRFYONLY;
2067 			while (*p != '\0' && isascii(*p) && isspace(*p))
2068 				p++;
2069 			if (*p == '\0')
2070 			{
2071 				usrerr("501 5.5.2 Argument required");
2072 			}
2073 			else
2074 			{
2075 				/* do config file checking of the address */
2076 				if (rscheck(vrfy ? "check_vrfy" : "check_expn",
2077 					    p, NULL, e, TRUE, FALSE, 4)
2078 				    != EX_OK || Errors > 0)
2079 					goto undo_subproc;
2080 				(void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
2081 			}
2082 			if (wt > 0)
2083 				(void) sleep(wt - (curtime() - previous));
2084 			if (Errors > 0)
2085 				goto undo_subproc;
2086 			if (vrfyqueue == NULL)
2087 			{
2088 				usrerr("554 5.5.2 Nothing to %s", vrfy ? "VRFY" : "EXPN");
2089 			}
2090 			while (vrfyqueue != NULL)
2091 			{
2092 				if (!QS_IS_UNDELIVERED(vrfyqueue->q_state))
2093 				{
2094 					vrfyqueue = vrfyqueue->q_next;
2095 					continue;
2096 				}
2097 
2098 				/* see if there is more in the vrfy list */
2099 				a = vrfyqueue;
2100 				while ((a = a->q_next) != NULL &&
2101 				       (!QS_IS_UNDELIVERED(a->q_state)))
2102 					continue;
2103 				printvrfyaddr(vrfyqueue, a == NULL, vrfy);
2104 				vrfyqueue = a;
2105 			}
2106 			if (InChild)
2107 				finis(TRUE, ExitStat);
2108 			break;
2109 
2110 		  case CMDETRN:		/* etrn -- force queue flush */
2111 			if (bitset(PRIV_NOETRN, PrivacyFlags) ||
2112 			    bitnset(D_NOETRN, d_flags))
2113 			{
2114 				/* different message for MSA ? */
2115 				message("502 5.7.0 Sorry, we do not allow this operation");
2116 				if (LogLevel > 5)
2117 					sm_syslog(LOG_INFO, e->e_id,
2118 						  "%.100s: %s [rejected]",
2119 						  CurSmtpClient,
2120 						  shortenstring(inp, MAXSHORTSTR));
2121 				break;
2122 			}
2123 			if (tempfail)
2124 			{
2125 				if (LogLevel > 9)
2126 					sm_syslog(LOG_INFO, e->e_id,
2127 						  "SMTP ETRN command (%.100s) from %.100s tempfailed (due to previous checks)",
2128 						  p, CurSmtpClient);
2129 				usrerr("451 4.7.1 Please try again later");
2130 				break;
2131 			}
2132 
2133 			if (strlen(p) <= 0)
2134 			{
2135 				usrerr("500 5.5.2 Parameter required");
2136 				break;
2137 			}
2138 
2139 			/* crude way to avoid denial-of-service attacks */
2140 			(void) checksmtpattack(&n_etrn, MAXETRNCOMMANDS, TRUE,
2141 					     "ETRN", e);
2142 
2143 			/* do config file checking of the parameter */
2144 			if (rscheck("check_etrn", p, NULL, e, TRUE, FALSE, 4)
2145 			    != EX_OK || Errors > 0)
2146 				break;
2147 
2148 			if (LogLevel > 5)
2149 				sm_syslog(LOG_INFO, e->e_id,
2150 					  "%.100s: ETRN %s",
2151 					  CurSmtpClient,
2152 					  shortenstring(p, MAXSHORTSTR));
2153 
2154 			id = p;
2155 			if (*id == '@')
2156 				id++;
2157 			else
2158 				*--id = '@';
2159 
2160 			if ((new = (QUEUE_CHAR *)malloc(sizeof(QUEUE_CHAR))) == NULL)
2161 			{
2162 				syserr("500 5.5.0 ETRN out of memory");
2163 				break;
2164 			}
2165 			new->queue_match = id;
2166 			new->queue_next = NULL;
2167 			QueueLimitRecipient = new;
2168 			ok = runqueue(TRUE, FALSE);
2169 			free(QueueLimitRecipient);
2170 			QueueLimitRecipient = NULL;
2171 			if (ok && Errors == 0)
2172 				message("250 2.0.0 Queuing for node %s started", p);
2173 			break;
2174 
2175 		  case CMDHELP:		/* help -- give user info */
2176 			help(p, e);
2177 			break;
2178 
2179 		  case CMDNOOP:		/* noop -- do nothing */
2180 			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, TRUE,
2181 					       "NOOP", e);
2182 			message("250 2.0.0 OK");
2183 			break;
2184 
2185 		  case CMDQUIT:		/* quit -- leave mail */
2186 			message("221 2.0.0 %s closing connection", MyHostName);
2187 
2188 			/* arrange to ignore any current send list */
2189 			e->e_sendqueue = NULL;
2190 
2191 # if STARTTLS
2192 			/* shutdown TLS connection */
2193 			if (tls_active)
2194 			{
2195 				(void) endtls(srv_ssl, "server");
2196 				tls_active = FALSE;
2197 			}
2198 # endif /* STARTTLS */
2199 # if SASL
2200 			if (authenticating == SASL_IS_AUTH)
2201 			{
2202 				sasl_dispose(&conn);
2203 				authenticating = SASL_NOT_AUTH;
2204 			}
2205 # endif /* SASL */
2206 
2207 doquit:
2208 			/* avoid future 050 messages */
2209 			disconnect(1, e);
2210 
2211 # if _FFR_MILTER
2212 			/* close out milter filters */
2213 			milter_quit(e);
2214 # endif /* _FFR_MILTER */
2215 
2216 			if (InChild)
2217 				ExitStat = EX_QUIT;
2218 
2219 			if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
2220 				logsender(e, NULL);
2221 			e->e_flags &= ~EF_LOGSENDER;
2222 
2223 			if (lognullconnection && LogLevel > 5)
2224 			{
2225 				char *d;
2226 
2227 				d = macvalue(macid("{daemon_name}", NULL), e);
2228 				if (d == NULL)
2229 					d = "stdin";
2230 				sm_syslog(LOG_INFO, NULL,
2231 					 "%.100s did not issue MAIL/EXPN/VRFY/ETRN during connection to %s",
2232 					  CurSmtpClient, d);
2233 			}
2234 			finis(TRUE, ExitStat);
2235 			/* NOTREACHED */
2236 
2237 		  case CMDVERB:		/* set verbose mode */
2238 			if (bitset(PRIV_NOEXPN, PrivacyFlags) ||
2239 			    bitset(PRIV_NOVERB, PrivacyFlags))
2240 			{
2241 				/* this would give out the same info */
2242 				message("502 5.7.0 Verbose unavailable");
2243 				break;
2244 			}
2245 			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, TRUE,
2246 					       "VERB", e);
2247 			Verbose = 1;
2248 			set_delivery_mode(SM_DELIVER, e);
2249 			message("250 2.0.0 Verbose mode");
2250 			break;
2251 
2252 		  case CMDONEX:		/* doing one transaction only */
2253 			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, TRUE,
2254 					       "ONEX", e);
2255 			OneXact = TRUE;
2256 			message("250 2.0.0 Only one transaction");
2257 			break;
2258 
2259 		  case CMDXUSR:		/* initial (user) submission */
2260 			(void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, TRUE,
2261 					       "XUSR", e);
2262 			define(macid("{daemon_flags}", NULL), "c u", CurEnv);
2263 			message("250 2.0.0 Initial submission");
2264 			break;
2265 
2266 # if SMTPDEBUG
2267 		  case CMDDBGQSHOW:	/* show queues */
2268 			printf("Send Queue=");
2269 			printaddr(e->e_sendqueue, TRUE);
2270 			break;
2271 
2272 		  case CMDDBGDEBUG:	/* set debug mode */
2273 			tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
2274 			tTflag(p);
2275 			message("200 2.0.0 Debug set");
2276 			break;
2277 
2278 # else /* SMTPDEBUG */
2279 		  case CMDDBGQSHOW:	/* show queues */
2280 		  case CMDDBGDEBUG:	/* set debug mode */
2281 # endif /* SMTPDEBUG */
2282 		  case CMDLOGBOGUS:	/* bogus command */
2283 			if (LogLevel > 0)
2284 				sm_syslog(LOG_CRIT, e->e_id,
2285 					  "\"%s\" command from %.100s (%.100s)",
2286 					  c->cmd_name, CurSmtpClient,
2287 					  anynet_ntoa(&RealHostAddr));
2288 			/* FALLTHROUGH */
2289 
2290 		  case CMDERROR:	/* unknown command */
2291 			if (++badcommands > MAXBADCOMMANDS)
2292 			{
2293 				message("421 4.7.0 %s Too many bad commands; closing connection",
2294 					MyHostName);
2295 
2296 				/* arrange to ignore any current send list */
2297 				e->e_sendqueue = NULL;
2298 				goto doquit;
2299 			}
2300 
2301 			usrerr("500 5.5.1 Command unrecognized: \"%s\"",
2302 			       shortenstring(inp, MAXSHORTSTR));
2303 			break;
2304 
2305 		  case CMDUNIMPL:
2306 			usrerr("502 5.5.1 Command not implemented: \"%s\"",
2307 			       shortenstring(inp, MAXSHORTSTR));
2308 			break;
2309 
2310 		  default:
2311 			errno = 0;
2312 			syserr("500 5.5.0 smtp: unknown code %d", c->cmd_code);
2313 			break;
2314 		}
2315 # if SASL
2316 		}
2317 # endif /* SASL */
2318 	}
2319 
2320 }
2321 /*
2322 **  CHECKSMTPATTACK -- check for denial-of-service attack by repetition
2323 **
2324 **	Parameters:
2325 **		pcounter -- pointer to a counter for this command.
2326 **		maxcount -- maximum value for this counter before we
2327 **			slow down.
2328 **		waitnow -- sleep now (in this routine)?
2329 **		cname -- command name for logging.
2330 **		e -- the current envelope.
2331 **
2332 **	Returns:
2333 **		none.
2334 **
2335 **	Side Effects:
2336 **		Slows down if we seem to be under attack.
2337 */
2338 
2339 static time_t
2340 checksmtpattack(pcounter, maxcount, waitnow, cname, e)
2341 	volatile int *pcounter;
2342 	int maxcount;
2343 	bool waitnow;
2344 	char *cname;
2345 	ENVELOPE *e;
2346 {
2347 	if (++(*pcounter) >= maxcount)
2348 	{
2349 		time_t s;
2350 
2351 		if (*pcounter == maxcount && LogLevel > 5)
2352 		{
2353 			sm_syslog(LOG_INFO, e->e_id,
2354 				  "%.100s: %.40s attack?",
2355 				  CurSmtpClient, cname);
2356 		}
2357 		s = 1 << (*pcounter - maxcount);
2358 		if (s >= MAXTIMEOUT)
2359 			s = MAXTIMEOUT;
2360 		/* sleep at least 1 second before returning */
2361 		(void) sleep(*pcounter / maxcount);
2362 		s -= *pcounter / maxcount;
2363 		if (waitnow)
2364 		{
2365 			(void) sleep(s);
2366 			return(0);
2367 		}
2368 		return(s);
2369 	}
2370 	return((time_t) 0);
2371 }
2372 /*
2373 **  SKIPWORD -- skip a fixed word.
2374 **
2375 **	Parameters:
2376 **		p -- place to start looking.
2377 **		w -- word to skip.
2378 **
2379 **	Returns:
2380 **		p following w.
2381 **		NULL on error.
2382 **
2383 **	Side Effects:
2384 **		clobbers the p data area.
2385 */
2386 
2387 static char *
2388 skipword(p, w)
2389 	register char *volatile p;
2390 	char *w;
2391 {
2392 	register char *q;
2393 	char *firstp = p;
2394 
2395 	/* find beginning of word */
2396 	while (isascii(*p) && isspace(*p))
2397 		p++;
2398 	q = p;
2399 
2400 	/* find end of word */
2401 	while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p)))
2402 		p++;
2403 	while (isascii(*p) && isspace(*p))
2404 		*p++ = '\0';
2405 	if (*p != ':')
2406 	{
2407 	  syntax:
2408 		usrerr("501 5.5.2 Syntax error in parameters scanning \"%s\"",
2409 			shortenstring(firstp, MAXSHORTSTR));
2410 		return NULL;
2411 	}
2412 	*p++ = '\0';
2413 	while (isascii(*p) && isspace(*p))
2414 		p++;
2415 
2416 	if (*p == '\0')
2417 		goto syntax;
2418 
2419 	/* see if the input word matches desired word */
2420 	if (strcasecmp(q, w))
2421 		goto syntax;
2422 
2423 	return p;
2424 }
2425 /*
2426 **  MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
2427 **
2428 **	Parameters:
2429 **		kp -- the parameter key.
2430 **		vp -- the value of that parameter.
2431 **		e -- the envelope.
2432 **
2433 **	Returns:
2434 **		none.
2435 */
2436 
2437 static void
2438 mail_esmtp_args(kp, vp, e)
2439 	char *kp;
2440 	char *vp;
2441 	ENVELOPE *e;
2442 {
2443 	if (strcasecmp(kp, "size") == 0)
2444 	{
2445 		if (vp == NULL)
2446 		{
2447 			usrerr("501 5.5.2 SIZE requires a value");
2448 			/* NOTREACHED */
2449 		}
2450 		define(macid("{msg_size}", NULL), newstr(vp), e);
2451   		e->e_msgsize = strtol(vp, (char **) NULL, 10);
2452 		if (e->e_msgsize == LONG_MAX && errno == ERANGE)
2453 		{
2454 			usrerr("552 5.2.3 Message size exceeds maximum value");
2455 			/* NOTREACHED */
2456 		}
2457 	}
2458 	else if (strcasecmp(kp, "body") == 0)
2459 	{
2460 		if (vp == NULL)
2461 		{
2462 			usrerr("501 5.5.2 BODY requires a value");
2463 			/* NOTREACHED */
2464 		}
2465 		else if (strcasecmp(vp, "8bitmime") == 0)
2466 		{
2467 			SevenBitInput = FALSE;
2468 		}
2469 		else if (strcasecmp(vp, "7bit") == 0)
2470 		{
2471 			SevenBitInput = TRUE;
2472 		}
2473 		else
2474 		{
2475 			usrerr("501 5.5.4 Unknown BODY type %s",
2476 				vp);
2477 			/* NOTREACHED */
2478 		}
2479 		e->e_bodytype = newstr(vp);
2480 	}
2481 	else if (strcasecmp(kp, "envid") == 0)
2482 	{
2483 		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
2484 		{
2485 			usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN");
2486 			/* NOTREACHED */
2487 		}
2488 		if (vp == NULL)
2489 		{
2490 			usrerr("501 5.5.2 ENVID requires a value");
2491 			/* NOTREACHED */
2492 		}
2493 		if (!xtextok(vp))
2494 		{
2495 			usrerr("501 5.5.4 Syntax error in ENVID parameter value");
2496 			/* NOTREACHED */
2497 		}
2498 		if (e->e_envid != NULL)
2499 		{
2500 			usrerr("501 5.5.0 Duplicate ENVID parameter");
2501 			/* NOTREACHED */
2502 		}
2503 		e->e_envid = newstr(vp);
2504 		define(macid("{dsn_envid}", NULL), newstr(vp), e);
2505 	}
2506 	else if (strcasecmp(kp, "ret") == 0)
2507 	{
2508 		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
2509 		{
2510 			usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN");
2511 			/* NOTREACHED */
2512 		}
2513 		if (vp == NULL)
2514 		{
2515 			usrerr("501 5.5.2 RET requires a value");
2516 			/* NOTREACHED */
2517 		}
2518 		if (bitset(EF_RET_PARAM, e->e_flags))
2519 		{
2520 			usrerr("501 5.5.0 Duplicate RET parameter");
2521 			/* NOTREACHED */
2522 		}
2523 		e->e_flags |= EF_RET_PARAM;
2524 		if (strcasecmp(vp, "hdrs") == 0)
2525 			e->e_flags |= EF_NO_BODY_RETN;
2526 		else if (strcasecmp(vp, "full") != 0)
2527 		{
2528 			usrerr("501 5.5.2 Bad argument \"%s\" to RET", vp);
2529 			/* NOTREACHED */
2530 		}
2531 		define(macid("{dsn_ret}", NULL), newstr(vp), e);
2532 	}
2533 # if SASL
2534 	else if (strcasecmp(kp, "auth") == 0)
2535 	{
2536 		int len;
2537 		char *q;
2538 		char *auth_param;	/* the value of the AUTH=x */
2539 		bool saveQuickAbort = QuickAbort;
2540 		bool saveSuprErrs = SuprErrs;
2541 		char pbuf[256];
2542 
2543 		if (vp == NULL)
2544 		{
2545 			usrerr("501 5.5.2 AUTH= requires a value");
2546 			/* NOTREACHED */
2547 		}
2548 		if (e->e_auth_param != NULL)
2549 		{
2550 			usrerr("501 5.5.0 Duplicate AUTH parameter");
2551 			/* NOTREACHED */
2552 		}
2553 		if ((q = strchr(vp, ' ')) != NULL)
2554 			len = q - vp + 1;
2555 		else
2556 			len = strlen(vp) + 1;
2557 		auth_param = xalloc(len);
2558 		(void) strlcpy(auth_param, vp, len);
2559 		if (!xtextok(auth_param))
2560 		{
2561 			usrerr("501 5.5.4 Syntax error in AUTH parameter value");
2562 			/* just a warning? */
2563 			/* NOTREACHED */
2564 		}
2565 
2566 		/* XXX this might be cut off */
2567 		snprintf(pbuf, sizeof pbuf, "%s", xuntextify(auth_param));
2568 		/* xalloc() the buffer instead? */
2569 
2570 		/* XXX define this always or only if trusted? */
2571 		define(macid("{auth_author}", NULL), newstr(pbuf), e);
2572 
2573 		/*
2574 		**  call Strust_auth to find out whether
2575 		**  auth_param is acceptable (trusted)
2576 		**  we shouldn't trust it if not authenticated
2577 		**  (required by RFC, leave it to ruleset?)
2578 		*/
2579 
2580 		SuprErrs = TRUE;
2581 		QuickAbort = FALSE;
2582 		if (strcmp(auth_param, "<>") != 0 &&
2583 		     (rscheck("trust_auth", pbuf, NULL, e, TRUE, FALSE, 10)
2584 		      != EX_OK || Errors > 0))
2585 		{
2586 			if (tTd(95, 8))
2587 			{
2588 				q = e->e_auth_param;
2589 				dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n",
2590 					pbuf, (q == NULL) ? "" : q);
2591 			}
2592 			/* not trusted */
2593 			e->e_auth_param = newstr("<>");
2594 		}
2595 		else
2596 		{
2597 			if (tTd(95, 8))
2598 				dprintf("auth=\"%.100s\" trusted\n", pbuf);
2599 			e->e_auth_param = newstr(auth_param);
2600 		}
2601 		free(auth_param);
2602 		/* reset values */
2603 		Errors = 0;
2604 		QuickAbort = saveQuickAbort;
2605 		SuprErrs = saveSuprErrs;
2606 	}
2607 # endif /* SASL */
2608 	else
2609 	{
2610 		usrerr("555 5.5.4 %s parameter unrecognized", kp);
2611 		/* NOTREACHED */
2612 	}
2613 }
2614 /*
2615 **  RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
2616 **
2617 **	Parameters:
2618 **		a -- the address corresponding to the To: parameter.
2619 **		kp -- the parameter key.
2620 **		vp -- the value of that parameter.
2621 **		e -- the envelope.
2622 **
2623 **	Returns:
2624 **		none.
2625 */
2626 
2627 static void
2628 rcpt_esmtp_args(a, kp, vp, e)
2629 	ADDRESS *a;
2630 	char *kp;
2631 	char *vp;
2632 	ENVELOPE *e;
2633 {
2634 	if (strcasecmp(kp, "notify") == 0)
2635 	{
2636 		char *p;
2637 
2638 		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
2639 		{
2640 			usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
2641 			/* NOTREACHED */
2642 		}
2643 		if (vp == NULL)
2644 		{
2645 			usrerr("501 5.5.2 NOTIFY requires a value");
2646 			/* NOTREACHED */
2647 		}
2648 		a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY);
2649 		a->q_flags |= QHASNOTIFY;
2650 		define(macid("{dsn_notify}", NULL), newstr(vp), e);
2651 
2652 		if (strcasecmp(vp, "never") == 0)
2653 			return;
2654 		for (p = vp; p != NULL; vp = p)
2655 		{
2656 			p = strchr(p, ',');
2657 			if (p != NULL)
2658 				*p++ = '\0';
2659 			if (strcasecmp(vp, "success") == 0)
2660 				a->q_flags |= QPINGONSUCCESS;
2661 			else if (strcasecmp(vp, "failure") == 0)
2662 				a->q_flags |= QPINGONFAILURE;
2663 			else if (strcasecmp(vp, "delay") == 0)
2664 				a->q_flags |= QPINGONDELAY;
2665 			else
2666 			{
2667 				usrerr("501 5.5.4 Bad argument \"%s\"  to NOTIFY",
2668 					vp);
2669 				/* NOTREACHED */
2670 			}
2671 		}
2672 	}
2673 	else if (strcasecmp(kp, "orcpt") == 0)
2674 	{
2675 		if (bitset(PRIV_NORECEIPTS, PrivacyFlags))
2676 		{
2677 			usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN");
2678 			/* NOTREACHED */
2679 		}
2680 		if (vp == NULL)
2681 		{
2682 			usrerr("501 5.5.2 ORCPT requires a value");
2683 			/* NOTREACHED */
2684 		}
2685 		if (strchr(vp, ';') == NULL || !xtextok(vp))
2686 		{
2687 			usrerr("501 5.5.4 Syntax error in ORCPT parameter value");
2688 			/* NOTREACHED */
2689 		}
2690 		if (a->q_orcpt != NULL)
2691 		{
2692 			usrerr("501 5.5.0 Duplicate ORCPT parameter");
2693 			/* NOTREACHED */
2694 		}
2695 		a->q_orcpt = newstr(vp);
2696 	}
2697 	else
2698 	{
2699 		usrerr("555 5.5.4 %s parameter unrecognized", kp);
2700 		/* NOTREACHED */
2701 	}
2702 }
2703 /*
2704 **  PRINTVRFYADDR -- print an entry in the verify queue
2705 **
2706 **	Parameters:
2707 **		a -- the address to print
2708 **		last -- set if this is the last one.
2709 **		vrfy -- set if this is a VRFY command.
2710 **
2711 **	Returns:
2712 **		none.
2713 **
2714 **	Side Effects:
2715 **		Prints the appropriate 250 codes.
2716 */
2717 #define OFFF	(3 + 1 + 5 + 1)	/* offset in fmt: SMTP reply + enh. code */
2718 
2719 static void
2720 printvrfyaddr(a, last, vrfy)
2721 	register ADDRESS *a;
2722 	bool last;
2723 	bool vrfy;
2724 {
2725 	char fmtbuf[30];
2726 
2727 	if (vrfy && a->q_mailer != NULL &&
2728 	    !bitnset(M_VRFY250, a->q_mailer->m_flags))
2729 		(void) strlcpy(fmtbuf, "252", sizeof fmtbuf);
2730 	else
2731 		(void) strlcpy(fmtbuf, "250", sizeof fmtbuf);
2732 	fmtbuf[3] = last ? ' ' : '-';
2733 	(void) strlcpy(&fmtbuf[4], "2.1.5 ", sizeof fmtbuf - 4);
2734 	if (a->q_fullname == NULL)
2735 	{
2736 		if ((a->q_mailer == NULL ||
2737 		     a->q_mailer->m_addrtype == NULL ||
2738 		     strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
2739 		    strchr(a->q_user, '@') == NULL)
2740 			(void) strlcpy(&fmtbuf[OFFF], "<%s@%s>",
2741 				       sizeof fmtbuf - OFFF);
2742 		else
2743 			(void) strlcpy(&fmtbuf[OFFF], "<%s>",
2744 				       sizeof fmtbuf - OFFF);
2745 		message(fmtbuf, a->q_user, MyHostName);
2746 	}
2747 	else
2748 	{
2749 		if ((a->q_mailer == NULL ||
2750 		     a->q_mailer->m_addrtype == NULL ||
2751 		     strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
2752 		    strchr(a->q_user, '@') == NULL)
2753 			(void) strlcpy(&fmtbuf[OFFF], "%s <%s@%s>",
2754 				       sizeof fmtbuf - OFFF);
2755 		else
2756 			(void) strlcpy(&fmtbuf[OFFF], "%s <%s>",
2757 				       sizeof fmtbuf - OFFF);
2758 		message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
2759 	}
2760 }
2761 /*
2762 **  RUNINCHILD -- return twice -- once in the child, then in the parent again
2763 **
2764 **	Parameters:
2765 **		label -- a string used in error messages
2766 **
2767 **	Returns:
2768 **		RIC_INCHILD in the child
2769 **		RIC_INPARENT in the parent
2770 **		RIC_TEMPFAIL tempfail condition
2771 **
2772 **	Side Effects:
2773 **		none.
2774 */
2775 
2776 static int
2777 runinchild(label, e)
2778 	char *label;
2779 	register ENVELOPE *e;
2780 {
2781 	pid_t childpid;
2782 
2783 	if (!OneXact)
2784 	{
2785 		extern int NumQueues;
2786 
2787 		/*
2788 		**  advance state of PRNG
2789 		**  this is necessary because otherwise all child processes
2790 		**  will produce the same PRN sequence and hence the selection
2791 		**  of a queue directory is not "really" random.
2792 		*/
2793 		if (NumQueues > 1)
2794 			(void) get_random();
2795 
2796 		/*
2797 		**  Disable child process reaping, in case ETRN has preceded
2798 		**  MAIL command, and then fork.
2799 		*/
2800 
2801 		(void) blocksignal(SIGCHLD);
2802 
2803 		childpid = dofork();
2804 		if (childpid < 0)
2805 		{
2806 			syserr("451 4.3.0 %s: cannot fork", label);
2807 			(void) releasesignal(SIGCHLD);
2808 			return RIC_INPARENT;
2809 		}
2810 		if (childpid > 0)
2811 		{
2812 			auto int st;
2813 
2814 			/* parent -- wait for child to complete */
2815 			sm_setproctitle(TRUE, e, "server %s child wait",
2816 					CurSmtpClient);
2817 			st = waitfor(childpid);
2818 			if (st == -1)
2819 				syserr("451 4.3.0 %s: lost child", label);
2820 			else if (!WIFEXITED(st))
2821 			{
2822 				syserr("451 4.3.0 %s: died on signal %d",
2823 				       label, st & 0177);
2824 				return RIC_TEMPFAIL;
2825 			}
2826 
2827 			/* if exited on a QUIT command, complete the process */
2828 			if (WEXITSTATUS(st) == EX_QUIT)
2829 			{
2830 				disconnect(1, e);
2831 				finis(TRUE, ExitStat);
2832 			}
2833 
2834 			/* restore the child signal */
2835 			(void) releasesignal(SIGCHLD);
2836 
2837 			return RIC_INPARENT;
2838 		}
2839 		else
2840 		{
2841 			/* child */
2842 			InChild = TRUE;
2843 			QuickAbort = FALSE;
2844 			clearstats();
2845 			clearenvelope(e, FALSE);
2846 			assign_queueid(e);
2847 			(void) setsignal(SIGCHLD, SIG_DFL);
2848 			(void) releasesignal(SIGCHLD);
2849 		}
2850 	}
2851 	return RIC_INCHILD;
2852 }
2853 
2854 # if SASL
2855 
2856 /*
2857 **  SASLMECHS -- get list of possible AUTH mechanisms
2858 **
2859 **	Parameters:
2860 **		conn -- SASL connection info
2861 **		mechlist -- output parameter for list of mechanisms
2862 **
2863 **	Returns:
2864 **		number of mechs
2865 */
2866 
2867 static int
2868 saslmechs(conn, mechlist)
2869 	sasl_conn_t *conn;
2870 	char **mechlist;
2871 {
2872 	int len, num, result;
2873 
2874 	/* "user" is currently unused */
2875 	result = sasl_listmech(conn, "user", /* XXX */
2876 			       "", " ", "", mechlist,
2877 			       (u_int *)&len, (u_int *)&num);
2878 	if (result == SASL_OK && num > 0)
2879 	{
2880 		if (LogLevel > 11)
2881 			sm_syslog(LOG_INFO, NOQID,
2882 				  "SASL: available mech=%s, allowed mech=%s",
2883 				  *mechlist, AuthMechanisms);
2884 		*mechlist = intersect(AuthMechanisms, *mechlist);
2885 	}
2886 	else
2887 	{
2888 		if (LogLevel > 9)
2889 			sm_syslog(LOG_WARNING, NOQID,
2890 				  "SASL error: listmech=%d, num=%d",
2891 				  result, num);
2892 	}
2893 	return num;
2894 }
2895 
2896 /*
2897 **  PROXY_POLICY -- define proxy policy for AUTH
2898 **
2899 **	Parameters:
2900 **		conntext -- unused
2901 **		auth_identity -- authentication identity
2902 **		requested_user -- authorization identity
2903 **		user -- allowed user (output)
2904 **		errstr -- possible error string (output)
2905 **
2906 **	Returns:
2907 **		ok?
2908 */
2909 
2910 int
2911 proxy_policy(context, auth_identity, requested_user, user, errstr)
2912 	void *context;
2913 	const char *auth_identity;
2914 	const char *requested_user;
2915 	const char **user;
2916 	const char **errstr;
2917 {
2918 	if (user == NULL || auth_identity == NULL)
2919 		return SASL_FAIL;
2920 	*user = newstr(auth_identity);
2921 	return SASL_OK;
2922 }
2923 
2924 # endif /* SASL */
2925 
2926 # if STARTTLS
2927 #  if !TLS_NO_RSA
2928 RSA *rsa_tmp;	/* temporary RSA key */
2929 static RSA * tmp_rsa_key __P((SSL *, int, int));
2930 #  endif /* !TLS_NO_RSA */
2931 
2932 # if !NO_DH
2933 static DH *get_dh512 __P((void));
2934 
2935 static unsigned char dh512_p[] =
2936 {
2937 	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
2938 	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
2939 	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
2940 	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
2941 	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
2942 	0x47,0x74,0xE8,0x33
2943 };
2944 static unsigned char dh512_g[] =
2945 {
2946 	0x02
2947 };
2948 
2949 static DH *
2950 get_dh512()
2951 {
2952 	DH *dh = NULL;
2953 
2954 	if ((dh = DH_new()) == NULL)
2955 		return(NULL);
2956 	dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
2957 	dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
2958 	if ((dh->p == NULL) || (dh->g == NULL))
2959 		return(NULL);
2960 	return(dh);
2961 }
2962 # endif /* !NO_DH */
2963 
2964 /*
2965 **  TLS_RAND_INIT -- initialize STARTTLS random generator
2966 **
2967 **	Parameters:
2968 **		randfile -- name of file with random data
2969 **		logl -- loglevel
2970 **
2971 **	Returns:
2972 **		success/failure
2973 **
2974 **	Side Effects:
2975 **		initializes PRNG for tls library.
2976 */
2977 
2978 #define MIN_RAND_BYTES	16	/* 128 bits */
2979 
2980 bool
2981 tls_rand_init(randfile, logl)
2982 	char *randfile;
2983 	int logl;
2984 {
2985 # ifndef HASURANDOMDEV
2986 	/* not required if /dev/urandom exists, OpenSSL does it internally */
2987 
2988 #define RF_OK		0	/* randfile OK */
2989 #define RF_MISS		1	/* randfile == NULL || *randfile == '\0' */
2990 #define RF_UNKNOWN	2	/* unknown prefix for randfile */
2991 
2992 #define RI_NONE		0	/* no init yet */
2993 #define RI_SUCCESS	1	/* init was successful */
2994 #define RI_FAIL		2	/* init failed */
2995 
2996 	bool ok;
2997 	int randdef;
2998 	static int done = RI_NONE;
2999 
3000 	/*
3001 	**  initialize PRNG
3002 	*/
3003 
3004 	/* did we try this before? if yes: return old value */
3005 	if (done != RI_NONE)
3006 		return done == RI_SUCCESS;
3007 
3008 	/* set default values */
3009 	ok = FALSE;
3010 	done = RI_FAIL;
3011 	randdef = (randfile == NULL || *randfile == '\0') ? RF_MISS : RF_OK;
3012 #   if EGD
3013 	if (randdef == RF_OK && strncasecmp(randfile, "egd:", 4) == 0)
3014 	{
3015 		randfile += 4;
3016 		if (RAND_egd(randfile) < 0)
3017 		{
3018 			sm_syslog(LOG_WARNING, NOQID,
3019 				  "TLS: RAND_egd(%s) failed: random number generator not seeded",
3020 				   randfile);
3021 		}
3022 		else
3023 			ok = TRUE;
3024 	}
3025 	else
3026 #   endif /* EGD */
3027 	if (randdef == RF_OK && strncasecmp(randfile, "file:", 5) == 0)
3028 	{
3029 		int fd;
3030 		long sff;
3031 		struct stat st;
3032 
3033 		randfile += 5;
3034 		sff = SFF_SAFEDIRPATH | SFF_NOWLINK
3035 		      | SFF_NOGWFILES | SFF_NOWWFILES
3036 		      | SFF_NOGRFILES | SFF_NOWRFILES
3037 		      | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
3038 		if ((fd = safeopen(randfile, O_RDONLY, 0, sff)) >= 0)
3039 		{
3040 			if (fstat(fd, &st) < 0)
3041 			{
3042 				if (LogLevel > logl)
3043 					sm_syslog(LOG_ERR, NOQID,
3044 						  "TLS: can't fstat(%s)",
3045 						  randfile);
3046 			}
3047 			else
3048 			{
3049 				bool use, problem;
3050 
3051 				use = TRUE;
3052 				problem = FALSE;
3053 				if (st.st_mtime + 600 < curtime())
3054 				{
3055 					use = bitnset(DBS_INSUFFICIENTENTROPY,
3056 						      DontBlameSendmail);
3057 					problem = TRUE;
3058 					if (LogLevel > logl)
3059 						sm_syslog(LOG_ERR, NOQID,
3060 							  "TLS: RandFile %s too old: %s",
3061 							  randfile,
3062 							  use ? "unsafe" :
3063 								"unusable");
3064 				}
3065 				if (use && st.st_size < MIN_RAND_BYTES)
3066 				{
3067 					use = bitnset(DBS_INSUFFICIENTENTROPY,
3068 						      DontBlameSendmail);
3069 					problem = TRUE;
3070 					if (LogLevel > logl)
3071 						sm_syslog(LOG_ERR, NOQID,
3072 							  "TLS: size(%s) < %d: %s",
3073 							  randfile,
3074 							  MIN_RAND_BYTES,
3075 							  use ? "unsafe" :
3076 								"unusable");
3077 				}
3078 				if (use)
3079 					ok = RAND_load_file(randfile, -1) >=
3080 					     MIN_RAND_BYTES;
3081 				if (use && !ok)
3082 				{
3083 					if (LogLevel > logl)
3084 						sm_syslog(LOG_WARNING,
3085 							  NOQID,
3086 							  "TLS: RAND_load_file(%s) failed: random number generator not seeded",
3087 							  randfile);
3088 				}
3089 				if (problem)
3090 					ok = FALSE;
3091 			}
3092 			if (ok || bitnset(DBS_INSUFFICIENTENTROPY,
3093 					  DontBlameSendmail))
3094 			{
3095 				/* add this even if fstat() failed */
3096 				RAND_seed((void *) &st, sizeof st);
3097 			}
3098 			(void) close(fd);
3099 		}
3100 		else
3101 		{
3102 			if (LogLevel > logl)
3103 				sm_syslog(LOG_WARNING, NOQID,
3104 					  "TLS: Warning: safeopen(%s) failed",
3105 					  randfile);
3106 		}
3107 	}
3108 	else if (randdef == RF_OK)
3109 	{
3110 		if (LogLevel > logl)
3111 			sm_syslog(LOG_WARNING, NOQID,
3112 				  "TLS: Error: no proper random file definition %s",
3113 				  randfile);
3114 		randdef = RF_UNKNOWN;
3115 	}
3116 	if (randdef == RF_MISS)
3117 	{
3118 		if (LogLevel > logl)
3119 			sm_syslog(LOG_WARNING, NOQID,
3120 				  "TLS: Error: missing random file definition");
3121 	}
3122 	if (!ok && bitnset(DBS_INSUFFICIENTENTROPY, DontBlameSendmail))
3123 	{
3124 		int i;
3125 		long r;
3126 		unsigned char buf[MIN_RAND_BYTES];
3127 
3128 		/* assert((MIN_RAND_BYTES % sizeof(long)) == 0); */
3129 		for (i = 0; i <= sizeof(buf) - sizeof(long); i += sizeof(long))
3130 		{
3131 			r = get_random();
3132 			(void) memcpy(buf + i, (void *) &r, sizeof(long));
3133 		}
3134 		RAND_seed(buf, sizeof buf);
3135 		if (LogLevel > logl)
3136 			sm_syslog(LOG_WARNING, NOQID,
3137 				  "TLS: Warning: random number generator not properly seeded");
3138 		ok = TRUE;
3139 	}
3140 	done = ok ? RI_SUCCESS : RI_FAIL;
3141 	return ok;
3142 # else /* !HASURANDOMDEV */
3143 	return TRUE;
3144 # endif /* !HASURANDOMDEV */
3145 }
3146 
3147 /*
3148 **  status in initialization
3149 **  these flags keep track of the status of the initialization
3150 **  i.e., whether a file exists (_EX) and whether it can be used (_OK)
3151 **  [due to permissions]
3152 */
3153 #define TLS_S_NONE	0x00000000	/* none yet  */
3154 #define TLS_S_CERT_EX	0x00000001	/* CERT file exists */
3155 #define TLS_S_CERT_OK	0x00000002	/* CERT file is ok */
3156 #define TLS_S_KEY_EX	0x00000004	/* KEY file exists */
3157 #define TLS_S_KEY_OK	0x00000008	/* KEY file is ok */
3158 #define TLS_S_CERTP_EX	0x00000010	/* CA CERT PATH exists */
3159 #define TLS_S_CERTP_OK	0x00000020	/* CA CERT PATH is ok */
3160 #define TLS_S_CERTF_EX	0x00000040	/* CA CERT FILE exists */
3161 #define TLS_S_CERTF_OK	0x00000080	/* CA CERT FILE is ok */
3162 
3163 # if _FFR_TLS_1
3164 #define TLS_S_CERT2_EX	0x00001000	/* 2nd CERT file exists */
3165 #define TLS_S_CERT2_OK	0x00002000	/* 2nd CERT file is ok */
3166 #define TLS_S_KEY2_EX	0x00004000	/* 2nd KEY file exists */
3167 #define TLS_S_KEY2_OK	0x00008000	/* 2nd KEY file is ok */
3168 # endif /* _FFR_TLS_1 */
3169 
3170 #define TLS_S_DH_OK	0x00200000	/* DH cert is ok */
3171 #define TLS_S_DHPAR_EX	0x00400000	/* DH param file exists */
3172 #define TLS_S_DHPAR_OK	0x00800000	/* DH param file is ok to use */
3173 
3174 /*
3175 **  TLS_OK_F -- can var be an absolute filename?
3176 **
3177 **	Parameters:
3178 **		var -- filename
3179 **		fn -- what is the filename used for?
3180 **
3181 **	Returns:
3182 **		ok?
3183 */
3184 
3185 static bool
3186 tls_ok_f(var, fn)
3187 	char *var;
3188 	char *fn;
3189 {
3190 	/* must be absolute pathname */
3191 	if (var != NULL && *var == '/')
3192 		return TRUE;
3193 	if (LogLevel > 12)
3194 		sm_syslog(LOG_WARNING, NOQID, "TLS: file %s missing", fn);
3195 	return FALSE;
3196 }
3197 
3198 /*
3199 **  TLS_SAFE_F -- is a file safe to use?
3200 **
3201 **	Parameters:
3202 **		var -- filename
3203 **		sff -- flags for safefile()
3204 **
3205 **	Returns:
3206 **		ok?
3207 */
3208 
3209 static bool
3210 tls_safe_f(var, sff)
3211 	char *var;
3212 	long sff;
3213 {
3214 	int ret;
3215 
3216 	if ((ret = safefile(var, RunAsUid, RunAsGid, RunAsUserName, sff,
3217 			    S_IRUSR, NULL)) == 0)
3218 		return TRUE;
3219 	if (LogLevel > 7)
3220 		sm_syslog(LOG_WARNING, NOQID, "TLS: file %s unsafe: %s",
3221 			  var, errstring(ret));
3222 	return FALSE;
3223 }
3224 
3225 /*
3226 **  TLS_OK_F -- macro to simplify calls to tls_ok_f
3227 **
3228 **	Parameters:
3229 **		var -- filename
3230 **		fn -- what is the filename used for?
3231 **		req -- is the file required?
3232 **		st -- status bit to set if ok
3233 **
3234 **	Side Effects:
3235 **		uses r, ok; may change ok and status.
3236 **
3237 */
3238 
3239 #define TLS_OK_F(var, fn, req, st) if (ok) \
3240 	{ \
3241 		r = tls_ok_f(var, fn); \
3242 		if (r) \
3243 			status |= st; \
3244 		else if (req) \
3245 			ok = FALSE; \
3246 	}
3247 
3248 /*
3249 **  TLS_UNR -- macro to return whether a file should be unreadable
3250 **
3251 **	Parameters:
3252 **		bit -- flag to test
3253 **		req -- flags
3254 **
3255 **	Returns:
3256 **		0/SFF_NORFILES
3257 */
3258 #define TLS_UNR(bit, req)	(bitset(bit, req) ? SFF_NORFILES : 0)
3259 
3260 /*
3261 **  TLS_SAFE_F -- macro to simplify calls to tls_safe_f
3262 **
3263 **	Parameters:
3264 **		var -- filename
3265 **		sff -- flags for safefile()
3266 **		req -- is the file required?
3267 **		ex -- does the file exist?
3268 **		st -- status bit to set if ok
3269 **
3270 **	Side Effects:
3271 **		uses r, ok, ex; may change ok and status.
3272 **
3273 */
3274 
3275 #define TLS_SAFE_F(var, sff, req, ex, st) if (ex && ok) \
3276 	{ \
3277 		r = tls_safe_f(var, sff); \
3278 		if (r) \
3279 			status |= st;	\
3280 		else if (req) \
3281 			ok = FALSE;	\
3282 	}
3283 
3284 /*
3285 **  INITTLS -- initialize TLS
3286 **
3287 **	Parameters:
3288 **		ctx -- pointer to context
3289 **		req -- requirements for initialization (see sendmail.h)
3290 **		srv -- server side?
3291 **		certfile -- filename of certificate
3292 **		keyfile -- filename of private key
3293 **		cacertpath -- path to CAs
3294 **		cacertfile -- file with CA
3295 **		dhparam -- parameters for DH
3296 **
3297 **	Returns:
3298 **		succeeded?
3299 */
3300 
3301 bool
3302 inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
3303 	SSL_CTX **ctx;
3304 	u_long req;
3305 	bool srv;
3306 	char *certfile, *keyfile, *cacertpath, *cacertfile, *dhparam;
3307 {
3308 # if !NO_DH
3309 	static DH *dh = NULL;
3310 # endif /* !NO_DH */
3311 	int r;
3312 	bool ok;
3313 	long sff, status;
3314 	char *who;
3315 # if _FFR_TLS_1
3316 	char *cf2, *kf2;
3317 # endif /* _FFR_TLS_1 */
3318 
3319 	status = TLS_S_NONE;
3320 	who = srv ? "srv" : "clt";
3321 	if (ctx == NULL)
3322 		syserr("TLS: %s:inittls: ctx == NULL", who);
3323 
3324 	/* already initialized? (we could re-init...) */
3325 	if (*ctx != NULL)
3326 		return TRUE;
3327 
3328 	/* PRNG seeded? */
3329 	if (!tls_rand_init(RandFile, 10))
3330 		return FALSE;
3331 
3332 	/* let's start with the assumption it will work */
3333 	ok = TRUE;
3334 
3335 # if _FFR_TLS_1
3336 	/*
3337 	**  look for a second filename: it must be separated by a ','
3338 	**  no blanks allowed (they won't be skipped).
3339 	**  we change a global variable here! this change will be undone
3340 	**  before return from the function but only if it returns TRUE.
3341 	**  this isn't a problem since in a failure case this function
3342 	**  won't be called again with the same (overwritten) values.
3343 	**  otherwise each return must be replaced with a goto endinittls.
3344 	*/
3345 	cf2 = NULL;
3346 	kf2 = NULL;
3347 	if (certfile != NULL && (cf2 = strchr(certfile, ',')) != NULL)
3348 	{
3349 		*cf2++ = '\0';
3350 		if (keyfile != NULL && (kf2 = strchr(keyfile, ',')) != NULL)
3351 			*kf2++ = '\0';
3352 	}
3353 # endif /* _FFR_TLS_1 */
3354 
3355 	/*
3356 	**  what do we require from the client?
3357 	**  must it have CERTs?
3358 	**  introduce an option and decide based on that
3359 	*/
3360 
3361 	TLS_OK_F(certfile, "CertFile", bitset(TLS_I_CERT_EX, req),
3362 		 TLS_S_CERT_EX);
3363 	TLS_OK_F(keyfile, "KeyFile", bitset(TLS_I_KEY_EX, req),
3364 		 TLS_S_KEY_EX);
3365 	TLS_OK_F(cacertpath, "CACERTPath", bitset(TLS_I_CERTP_EX, req),
3366 		 TLS_S_CERTP_EX);
3367 	TLS_OK_F(cacertfile, "CACERTFile", bitset(TLS_I_CERTF_EX, req),
3368 		 TLS_S_CERTF_EX);
3369 
3370 # if _FFR_TLS_1
3371 	if (cf2 != NULL)
3372 	{
3373 		TLS_OK_F(cf2, "CertFile", bitset(TLS_I_CERT_EX, req),
3374 			 TLS_S_CERT2_EX);
3375 	}
3376 	if (kf2 != NULL)
3377 	{
3378 		TLS_OK_F(kf2, "KeyFile", bitset(TLS_I_KEY_EX, req),
3379 			 TLS_S_KEY2_EX);
3380 	}
3381 # endif /* _FFR_TLS_1 */
3382 
3383 	/*
3384 	**  valid values for dhparam are (only the first char is checked)
3385 	**  none	no parameters: don't use DH
3386 	**  512		generate 512 bit parameters (fixed)
3387 	**  1024	generate 1024 bit parameters
3388 	**  /file/name	read parameters from /file/name
3389 	**  default is: 1024 for server, 512 for client (OK? XXX)
3390 	*/
3391 	if (bitset(TLS_I_TRY_DH, req))
3392 	{
3393 		if (dhparam != NULL)
3394 		{
3395 			char c = *dhparam;
3396 
3397 			if (c == '1')
3398 				req |= TLS_I_DH1024;
3399 			else if (c == '5')
3400 				req |= TLS_I_DH512;
3401 			else if (c != 'n' && c != 'N' && c != '/')
3402 			{
3403 				if (LogLevel > 12)
3404 					sm_syslog(LOG_WARNING, NOQID,
3405 						  "TLS: error: illegal value '%s' for DHParam",
3406 						  dhparam);
3407 				dhparam = NULL;
3408 			}
3409 		}
3410 		if (dhparam == NULL)
3411 			dhparam = srv ? "1" : "5";
3412 		else if (*dhparam == '/')
3413 		{
3414 			TLS_OK_F(dhparam, "DHParameters",
3415 				 bitset(TLS_I_DHPAR_EX, req),
3416 				 TLS_S_DHPAR_EX);
3417 		}
3418 	}
3419 	if (!ok)
3420 		return ok;
3421 
3422 	/* certfile etc. must be "safe". */
3423 	sff = SFF_REGONLY | SFF_SAFEDIRPATH | SFF_NOWLINK
3424 	     | SFF_NOGWFILES | SFF_NOWWFILES
3425 	     | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
3426 	if (DontLockReadFiles)
3427 		sff |= SFF_NOLOCK;
3428 
3429 	TLS_SAFE_F(certfile, sff | TLS_UNR(TLS_I_CERT_UNR, req),
3430 		   bitset(TLS_I_CERT_EX, req),
3431 		   bitset(TLS_S_CERT_EX, status), TLS_S_CERT_OK);
3432 	TLS_SAFE_F(keyfile, sff | TLS_UNR(TLS_I_KEY_UNR, req),
3433 		   bitset(TLS_I_KEY_EX, req),
3434 		   bitset(TLS_S_KEY_EX, status), TLS_S_KEY_OK);
3435 	TLS_SAFE_F(cacertfile, sff | TLS_UNR(TLS_I_CERTF_UNR, req),
3436 		   bitset(TLS_I_CERTF_EX, req),
3437 		   bitset(TLS_S_CERTF_EX, status), TLS_S_CERTF_OK);
3438 	TLS_SAFE_F(dhparam, sff | TLS_UNR(TLS_I_DHPAR_UNR, req),
3439 		   bitset(TLS_I_DHPAR_EX, req),
3440 		   bitset(TLS_S_DHPAR_EX, status), TLS_S_DHPAR_OK);
3441 	if (!ok)
3442 		return ok;
3443 # if _FFR_TLS_1
3444 	if (cf2 != NULL)
3445 	{
3446 		TLS_SAFE_F(cf2, sff | TLS_UNR(TLS_I_CERT_UNR, req),
3447 			   bitset(TLS_I_CERT_EX, req),
3448 			   bitset(TLS_S_CERT2_EX, status), TLS_S_CERT2_OK);
3449 	}
3450 	if (kf2 != NULL)
3451 	{
3452 		TLS_SAFE_F(kf2, sff | TLS_UNR(TLS_I_KEY_UNR, req),
3453 			   bitset(TLS_I_KEY_EX, req),
3454 			   bitset(TLS_S_KEY2_EX, status), TLS_S_KEY2_OK);
3455 	}
3456 # endif /* _FFR_TLS_1 */
3457 
3458 	/* create a method and a new context */
3459 	if (srv)
3460 	{
3461 		if ((*ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
3462 		{
3463 			if (LogLevel > 7)
3464 				sm_syslog(LOG_WARNING, NOQID,
3465 					  "TLS: error: SSL_CTX_new(SSLv23_server_method()) failed");
3466 			return FALSE;
3467 		}
3468 	}
3469 	else
3470 	{
3471 		if ((*ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
3472 		{
3473 			if (LogLevel > 7)
3474 				sm_syslog(LOG_WARNING, NOQID,
3475 					  "TLS: error: SSL_CTX_new(SSLv23_client_method()) failed");
3476 			return FALSE;
3477 		}
3478 	}
3479 
3480 #  if TLS_NO_RSA
3481 	/* turn off backward compatibility, required for no-rsa */
3482 	SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2);
3483 #  endif /* TLS_NO_RSA */
3484 
3485 
3486 #  if !TLS_NO_RSA
3487 	/*
3488 	**  Create a temporary RSA key
3489 	**  XXX  Maybe we shouldn't create this always (even though it
3490 	**  is only at startup).
3491 	**  It is a time-consuming operation and it is not always necessary.
3492 	**  maybe we should do it only on demand...
3493 	*/
3494 	if (bitset(TLS_I_RSA_TMP, req) &&
3495 	    (rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL,
3496 					NULL)) == NULL
3497 	   )
3498 	{
3499 		if (LogLevel > 7)
3500 		{
3501 			sm_syslog(LOG_WARNING, NOQID,
3502 				  "TLS: error: %s: RSA_generate_key failed",
3503 				  who);
3504 			if (LogLevel > 9)
3505 				tlslogerr();
3506 		}
3507 		return FALSE;
3508 	}
3509 #  endif /* !TLS_NO_RSA */
3510 
3511 	/*
3512 	**  load private key
3513 	**  XXX change this for DSA-only version
3514 	*/
3515 	if (bitset(TLS_S_KEY_OK, status) &&
3516 	    SSL_CTX_use_PrivateKey_file(*ctx, keyfile,
3517 					 SSL_FILETYPE_PEM) <= 0)
3518 	{
3519 		if (LogLevel > 7)
3520 		{
3521 			sm_syslog(LOG_WARNING, NOQID,
3522 				  "TLS: error: %s: SSL_CTX_use_PrivateKey_file(%s) failed",
3523 				  who, keyfile);
3524 			if (LogLevel > 9)
3525 				tlslogerr();
3526 		}
3527 		if (bitset(TLS_I_USE_KEY, req))
3528 			return FALSE;
3529 	}
3530 
3531 	/* get the certificate file */
3532 	if (bitset(TLS_S_CERT_OK, status) &&
3533 	    SSL_CTX_use_certificate_file(*ctx, certfile,
3534 					 SSL_FILETYPE_PEM) <= 0)
3535 	{
3536 		if (LogLevel > 7)
3537 		{
3538 			sm_syslog(LOG_WARNING, NOQID,
3539 				  "TLS: error: %s: SSL_CTX_use_certificate_file(%s) failed",
3540 				  who, certfile);
3541 			if (LogLevel > 9)
3542 				tlslogerr();
3543 		}
3544 		if (bitset(TLS_I_USE_CERT, req))
3545 			return FALSE;
3546 	}
3547 
3548 	/* check the private key */
3549 	if (bitset(TLS_S_KEY_OK, status) &&
3550 	    (r = SSL_CTX_check_private_key(*ctx)) <= 0)
3551 	{
3552 		/* Private key does not match the certificate public key */
3553 		if (LogLevel > 5)
3554 		{
3555 			sm_syslog(LOG_WARNING, NOQID,
3556 				  "TLS: error: %s: SSL_CTX_check_private_key failed(%s): %d",
3557 				  who, keyfile, r);
3558 			if (LogLevel > 9)
3559 				tlslogerr();
3560 		}
3561 		if (bitset(TLS_I_USE_KEY, req))
3562 			return FALSE;
3563 	}
3564 
3565 # if _FFR_TLS_1
3566 	/* XXX this code is pretty much duplicated from above! */
3567 
3568 	/* load private key */
3569 	if (bitset(TLS_S_KEY2_OK, status) &&
3570 	    SSL_CTX_use_PrivateKey_file(*ctx, kf2, SSL_FILETYPE_PEM) <= 0)
3571 	{
3572 		if (LogLevel > 7)
3573 		{
3574 			sm_syslog(LOG_WARNING, NOQID,
3575 				  "TLS: error: %s: SSL_CTX_use_PrivateKey_file(%s) failed",
3576 				  who, kf2);
3577 			if (LogLevel > 9)
3578 				tlslogerr();
3579 		}
3580 	}
3581 
3582 	/* get the certificate file */
3583 	if (bitset(TLS_S_CERT2_OK, status) &&
3584 	    SSL_CTX_use_certificate_file(*ctx, cf2, SSL_FILETYPE_PEM) <= 0)
3585 	{
3586 		if (LogLevel > 7)
3587 		{
3588 			sm_syslog(LOG_WARNING, NOQID,
3589 				  "TLS: error: %s: SSL_CTX_use_certificate_file(%s) failed",
3590 				  who, cf2);
3591 			if (LogLevel > 9)
3592 				tlslogerr();
3593 		}
3594 	}
3595 
3596 	/* we should also check the private key: */
3597 	if (bitset(TLS_S_KEY2_OK, status) &&
3598 	    (r = SSL_CTX_check_private_key(*ctx)) <= 0)
3599 	{
3600 		/* Private key does not match the certificate public key */
3601 		if (LogLevel > 5)
3602 		{
3603 			sm_syslog(LOG_WARNING, NOQID,
3604 				  "TLS: error: %s: SSL_CTX_check_private_key 2 failed: %d",
3605 				  who, r);
3606 			if (LogLevel > 9)
3607 				tlslogerr();
3608 		}
3609 	}
3610 # endif /* _FFR_TLS_1 */
3611 
3612 	/* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */
3613 	SSL_CTX_set_options(*ctx, SSL_OP_ALL);	/* XXX bug compatibility? */
3614 
3615 # if !NO_DH
3616 	/* Diffie-Hellman initialization */
3617 	if (bitset(TLS_I_TRY_DH, req))
3618 	{
3619 		if (bitset(TLS_S_DHPAR_OK, status))
3620 		{
3621 			BIO *bio;
3622 
3623 			if ((bio = BIO_new_file(dhparam, "r")) != NULL)
3624 			{
3625 				dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3626 				BIO_free(bio);
3627 				if (dh == NULL && LogLevel > 7)
3628 				{
3629 					u_long err;
3630 
3631 					err = ERR_get_error();
3632 					sm_syslog(LOG_WARNING, NOQID,
3633 						  "TLS: error: %s: cannot read DH parameters(%s): %s",
3634 						  who, dhparam,
3635 						  ERR_error_string(err, NULL));
3636 					if (LogLevel > 9)
3637 						tlslogerr();
3638 				}
3639 			}
3640 			else
3641 			{
3642 				if (LogLevel > 5)
3643 				{
3644 					sm_syslog(LOG_WARNING, NOQID,
3645 						  "TLS: error: %s: BIO_new_file(%s) failed",
3646 						  who, dhparam);
3647 					if (LogLevel > 9)
3648 						tlslogerr();
3649 				}
3650 			}
3651 		}
3652 		if (dh == NULL && bitset(TLS_I_DH1024, req))
3653 		{
3654 			DSA *dsa;
3655 
3656 			/* this takes a while! (7-130s on a 450MHz AMD K6-2) */
3657 			dsa = DSA_generate_parameters(1024, NULL, 0, NULL,
3658 						      NULL, 0, NULL);
3659 			dh = DSA_dup_DH(dsa);
3660 			DSA_free(dsa);
3661 		}
3662 		else
3663 		if (dh == NULL && bitset(TLS_I_DH512, req))
3664 			dh = get_dh512();
3665 
3666 		if (dh == NULL)
3667 		{
3668 			if (LogLevel > 9)
3669 			{
3670 				u_long err;
3671 
3672 				err = ERR_get_error();
3673 				sm_syslog(LOG_WARNING, NOQID,
3674 					  "TLS: error: %s: cannot read or set DH parameters(%s): %s",
3675 					  who, dhparam,
3676 					  ERR_error_string(err, NULL));
3677 			}
3678 			if (bitset(TLS_I_REQ_DH, req))
3679 				return FALSE;
3680 		}
3681 		else
3682 		{
3683 			SSL_CTX_set_tmp_dh(*ctx, dh);
3684 
3685 			/* important to avoid small subgroup attacks */
3686 			SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_DH_USE);
3687 			if (LogLevel > 12)
3688 				sm_syslog(LOG_INFO, NOQID,
3689 					  "TLS: %s: Diffie-Hellman init, key=%d bit (%c)",
3690 					  who, 8 * DH_size(dh), *dhparam);
3691 			DH_free(dh);
3692 		}
3693 	}
3694 # endif /* !NO_DH */
3695 
3696 
3697 	/* XXX do we need this cache here? */
3698 	if (bitset(TLS_I_CACHE, req))
3699 		SSL_CTX_sess_set_cache_size(*ctx, 128);
3700 	/* timeout? SSL_CTX_set_timeout(*ctx, TimeOut...); */
3701 
3702 	/* load certificate locations and default CA paths */
3703 	if (bitset(TLS_S_CERTP_EX, status) && bitset(TLS_S_CERTF_EX, status))
3704 	{
3705 		if ((r = SSL_CTX_load_verify_locations(*ctx, cacertfile,
3706 						       cacertpath)) == 1)
3707 		{
3708 #  if !TLS_NO_RSA
3709 			if (bitset(TLS_I_RSA_TMP, req))
3710 				SSL_CTX_set_tmp_rsa_callback(*ctx, tmp_rsa_key);
3711 #  endif /* !TLS_NO_RSA */
3712 
3713 			/* ask to verify the peer */
3714 			SSL_CTX_set_verify(*ctx, SSL_VERIFY_PEER, NULL);
3715 
3716 			/* install verify callback */
3717 			SSL_CTX_set_cert_verify_callback(*ctx, tls_verify_cb,
3718 							 NULL);
3719 			SSL_CTX_set_client_CA_list(*ctx,
3720 				SSL_load_client_CA_file(cacertfile));
3721 		}
3722 		else
3723 		{
3724 			/*
3725 			**  can't load CA data; do we care?
3726 			**  the data is necessary to authenticate the client,
3727 			**  which in turn would be necessary
3728 			**  if we want to allow relaying based on it.
3729 			*/
3730 			if (LogLevel > 5)
3731 			{
3732 				sm_syslog(LOG_WARNING, NOQID,
3733 					  "TLS: error: %s: %d load verify locs %s, %s",
3734 					  who, r, cacertpath, cacertfile);
3735 				if (LogLevel > 9)
3736 					tlslogerr();
3737 			}
3738 			if (bitset(TLS_I_VRFY_LOC, req))
3739 				return FALSE;
3740 		}
3741 	}
3742 
3743 	/* XXX: make this dependent on an option? */
3744 	if (tTd(96, 9))
3745 		SSL_CTX_set_info_callback(*ctx, apps_ssl_info_cb);
3746 
3747 #  if _FFR_TLS_1
3748 	/*
3749 	**  XXX install our own cipher list: option?
3750 	*/
3751 	if (CipherList != NULL && *CipherList != '\0')
3752 	{
3753 		if (SSL_CTX_set_cipher_list(*ctx, CipherList) <= 0)
3754 		{
3755 			if (LogLevel > 7)
3756 			{
3757 				sm_syslog(LOG_WARNING, NOQID,
3758 					  "TLS: error: %s: SSL_CTX_set_cipher_list(%s) failed, list ignored",
3759 					  who, CipherList);
3760 
3761 				if (LogLevel > 9)
3762 					tlslogerr();
3763 			}
3764 			/* failure if setting to this list is required? */
3765 		}
3766 	}
3767 #  endif /* _FFR_TLS_1 */
3768 	if (LogLevel > 12)
3769 		sm_syslog(LOG_INFO, NOQID, "TLS: init(%s)=%d", who, ok);
3770 
3771 # if _FFR_TLS_1
3772 #  if 0
3773 	/*
3774 	**  this label is required if we want to have a "clean" exit
3775 	**  see the comments above at the initialization of cf2
3776 	*/
3777     endinittls:
3778 #  endif /* 0 */
3779 
3780 	/* undo damage to global variables */
3781 	if (cf2 != NULL)
3782 		*--cf2 = ',';
3783 	if (kf2 != NULL)
3784 		*--kf2 = ',';
3785 # endif /* _FFR_TLS_1 */
3786 
3787 	return ok;
3788 }
3789 /*
3790 **  INITSRVTLS -- initialize server side TLS
3791 **
3792 **	Parameters:
3793 **		none.
3794 **
3795 **	Returns:
3796 **		succeeded?
3797 */
3798 
3799 bool
3800 initsrvtls()
3801 {
3802 
3803 	tls_ok = inittls(&srv_ctx, TLS_I_SRV, TRUE, SrvCERTfile, Srvkeyfile,
3804 			 CACERTpath, CACERTfile, DHParams);
3805 	return tls_ok;
3806 }
3807 /*
3808 **  TLS_GET_INFO -- get information about TLS connection
3809 **
3810 **	Parameters:
3811 **		ssl -- SSL connection structure
3812 **		e -- current envelope
3813 **		srv -- server or client
3814 **		host -- hostname of other side
3815 **
3816 **	Returns:
3817 **		result of authentication.
3818 **
3819 **	Side Effects:
3820 **		sets ${cipher}, ${tls_version}, ${verify}, ${cipher_bits},
3821 **		${cert}
3822 */
3823 
3824 int
3825 tls_get_info(ssl, e, srv, host)
3826 	SSL *ssl;
3827 	ENVELOPE *e;
3828 	bool srv;
3829 	char *host;
3830 {
3831 	SSL_CIPHER *c;
3832 	int b, r;
3833 	char *s;
3834 	char bitstr[16];
3835 	X509 *cert;
3836 
3837 	c = SSL_get_current_cipher(ssl);
3838 	define(macid("{cipher}", NULL), newstr(SSL_CIPHER_get_name(c)), e);
3839 	b = SSL_CIPHER_get_bits(c, &r);
3840 	(void) snprintf(bitstr, sizeof bitstr, "%d", b);
3841 	define(macid("{cipher_bits}", NULL), newstr(bitstr), e);
3842 # if _FFR_TLS_1
3843 	(void) snprintf(bitstr, sizeof bitstr, "%d", r);
3844 	define(macid("{alg_bits}", NULL), newstr(bitstr), e);
3845 # endif /* _FFR_TLS_1 */
3846 	s = SSL_CIPHER_get_version(c);
3847 	if (s == NULL)
3848 		s = "UNKNOWN";
3849 	define(macid("{tls_version}", NULL), newstr(s), e);
3850 
3851 	cert = SSL_get_peer_certificate(ssl);
3852 	if (LogLevel >= 14)
3853 		sm_syslog(LOG_INFO, e->e_id,
3854 			  "TLS: get_verify in %s: %ld get_peer: 0x%lx",
3855 			  srv ? "srv" : "clt",
3856 			  SSL_get_verify_result(ssl), (u_long) cert);
3857 	if (cert != NULL)
3858 	{
3859 		char buf[MAXNAME];
3860 
3861 		X509_NAME_oneline(X509_get_subject_name(cert),
3862 				  buf, sizeof buf);
3863 		define(macid("{cert_subject}", NULL),
3864 			       newstr(xtextify(buf, "<>\")")), e);
3865 		X509_NAME_oneline(X509_get_issuer_name(cert),
3866 				  buf, sizeof buf);
3867 		define(macid("{cert_issuer}", NULL),
3868 		       newstr(xtextify(buf, "<>\")")), e);
3869 # if _FFR_TLS_1
3870 		X509_NAME_get_text_by_NID(X509_get_subject_name(cert),
3871 					  NID_commonName, buf, sizeof buf);
3872 		define(macid("{cn_subject}", NULL),
3873 		       newstr(xtextify(buf, "<>\")")), e);
3874 		X509_NAME_get_text_by_NID(X509_get_issuer_name(cert),
3875 					  NID_commonName, buf, sizeof buf);
3876 		define(macid("{cn_issuer}", NULL),
3877 		       newstr(xtextify(buf, "<>\")")), e);
3878 # endif /* _FFR_TLS_1 */
3879 	}
3880 	else
3881 	{
3882 		define(macid("{cert_subject}", NULL), "", e);
3883 		define(macid("{cert_issuer}", NULL), "", e);
3884 # if _FFR_TLS_1
3885 		define(macid("{cn_subject}", NULL), "", e);
3886 		define(macid("{cn_issuer}", NULL), "", e);
3887 # endif /* _FFR_TLS_1 */
3888 	}
3889 	switch(SSL_get_verify_result(ssl))
3890 	{
3891 	  case X509_V_OK:
3892 		if (cert != NULL)
3893 		{
3894 			s = "OK";
3895 			r = TLS_AUTH_OK;
3896 		}
3897 		else
3898 		{
3899 			s = "NO";
3900 			r = TLS_AUTH_NO;
3901 		}
3902 		break;
3903 	  default:
3904 		s = "FAIL";
3905 		r = TLS_AUTH_FAIL;
3906 		break;
3907 	}
3908 	define(macid("{verify}", NULL), newstr(s), e);
3909 	if (cert != NULL)
3910 		X509_free(cert);
3911 
3912 	/* do some logging */
3913 	if (LogLevel > 9)
3914 	{
3915 		char *vers, *s1, *s2, *bits;
3916 
3917 		vers = macvalue(macid("{tls_version}", NULL), e);
3918 		bits = macvalue(macid("{cipher_bits}", NULL), e);
3919 		s1 = macvalue(macid("{verify}", NULL), e);
3920 		s2 = macvalue(macid("{cipher}", NULL), e);
3921 		sm_syslog(LOG_INFO, NOQID,
3922 			  "TLS: connection %s %.64s, version=%.16s, verify=%.16s, cipher=%.64s, bits=%.6s",
3923 			  srv ? "from" : "to",
3924 			  host == NULL ? "none" : host,
3925 			  vers == NULL ? "none" : vers,
3926 			  s1 == NULL ? "none" : s1,
3927 			  s2 == NULL ? "none" : s2,
3928 			  bits == NULL ? "0" : bits);
3929 		if (LogLevel > 11)
3930 		{
3931 			/*
3932 			**  maybe run xuntextify on the strings?
3933 			**  that is easier to read but makes it maybe a bit
3934 			**  more complicated to figure out the right values
3935 			**  for the access map...
3936 			*/
3937 			s1 = macvalue(macid("{cert_subject}", NULL), e);
3938 			s2 = macvalue(macid("{cert_issuer}", NULL), e);
3939 			sm_syslog(LOG_INFO, NOQID,
3940 				  "TLS: %s cert subject:%.128s, cert issuer=%.128s",
3941 				  srv ? "client" : "server",
3942 				  s1 == NULL ? "none" : s1,
3943 				  s2 == NULL ? "none" : s2);
3944 		}
3945 	}
3946 
3947 	return r;
3948 }
3949 
3950 # if !TLS_NO_RSA
3951 /*
3952 **  TMP_RSA_KEY -- return temporary RSA key
3953 **
3954 **	Parameters:
3955 **		s -- SSL connection structure
3956 **		export --
3957 **		keylength --
3958 **
3959 **	Returns:
3960 **		temporary RSA key.
3961 */
3962 
3963 /* ARGUSED0 */
3964 static RSA *
3965 tmp_rsa_key(s, export, keylength)
3966 	SSL *s;
3967 	int export;
3968 	int keylength;
3969 {
3970 	return rsa_tmp;
3971 }
3972 # endif /* !TLS_NO_RSA */
3973 /*
3974 **  APPS_SSL_INFO_CB -- info callback for TLS connections
3975 **
3976 **	Parameters:
3977 **		s -- SSL connection structure
3978 **		where --
3979 **		ret --
3980 **
3981 **	Returns:
3982 **		none.
3983 */
3984 
3985 void
3986 apps_ssl_info_cb(s, where, ret)
3987 	SSL *s;
3988 	int where;
3989 	int ret;
3990 {
3991 	char *str;
3992 	int w;
3993 	BIO *bio_err = NULL;
3994 
3995 	if (LogLevel > 14)
3996 		sm_syslog(LOG_INFO, NOQID,
3997 			  "info_callback where 0x%x ret %d", where, ret);
3998 
3999 	w = where & ~SSL_ST_MASK;
4000 	if (bio_err == NULL)
4001 		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
4002 
4003 	if (w & SSL_ST_CONNECT)
4004 		str = "SSL_connect";
4005 	else if (w & SSL_ST_ACCEPT)
4006 		str = "SSL_accept";
4007 	else
4008 		str = "undefined";
4009 
4010 	if (where & SSL_CB_LOOP)
4011 	{
4012 		if (LogLevel > 12)
4013 			sm_syslog(LOG_NOTICE, NOQID,
4014 			"%s:%s\n", str, SSL_state_string_long(s));
4015 	}
4016 	else if (where & SSL_CB_ALERT)
4017 	{
4018 		str = (where & SSL_CB_READ) ? "read" : "write";
4019 		if (LogLevel > 12)
4020 			sm_syslog(LOG_NOTICE, NOQID,
4021 		"SSL3 alert %s:%s:%s\n",
4022 			   str, SSL_alert_type_string_long(ret),
4023 			   SSL_alert_desc_string_long(ret));
4024 	}
4025 	else if (where & SSL_CB_EXIT)
4026 	{
4027 		if (ret == 0)
4028 		{
4029 			if (LogLevel > 7)
4030 				sm_syslog(LOG_WARNING, NOQID,
4031 					"%s:failed in %s\n",
4032 					str, SSL_state_string_long(s));
4033 		}
4034 		else if (ret < 0)
4035 		{
4036 			if (LogLevel > 7)
4037 				sm_syslog(LOG_WARNING, NOQID,
4038 					"%s:error in %s\n",
4039 					str, SSL_state_string_long(s));
4040 		}
4041 	}
4042 }
4043 /*
4044 **  TLS_VERIFY_LOG -- log verify error for TLS certificates
4045 **
4046 **	Parameters:
4047 **		ok -- verify ok?
4048 **		ctx -- x509 context
4049 **
4050 **	Returns:
4051 **		0 -- fatal error
4052 **		1 -- ok
4053 */
4054 
4055 static int
4056 tls_verify_log(ok, ctx)
4057 	int ok;
4058 	X509_STORE_CTX *ctx;
4059 {
4060 	SSL *ssl;
4061 	X509 *cert;
4062 	int reason, depth;
4063 	char buf[512];
4064 
4065 	cert = X509_STORE_CTX_get_current_cert(ctx);
4066 	reason = X509_STORE_CTX_get_error(ctx);
4067 	depth = X509_STORE_CTX_get_error_depth(ctx);
4068 	ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx,
4069 			SSL_get_ex_data_X509_STORE_CTX_idx());
4070 
4071 	if (ssl == NULL)
4072 	{
4073 		/* internal error */
4074 		sm_syslog(LOG_ERR, NOQID,
4075 			  "TLS: internal error: tls_verify_cb: ssl == NULL");
4076 		return 0;
4077 	}
4078 
4079 	X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof buf);
4080 	sm_syslog(LOG_INFO, NOQID,
4081 		  "TLS cert verify: depth=%d %s, state=%d, reason=%s\n",
4082 		  depth, buf, ok, X509_verify_cert_error_string(reason));
4083 	return 1;
4084 }
4085 
4086 /*
4087 **  TLS_VERIFY_CB -- verify callback for TLS certificates
4088 **
4089 **	Parameters:
4090 **		ctx -- x509 context
4091 **
4092 **	Returns:
4093 **		accept connection?
4094 **		currently: always yes.
4095 */
4096 
4097 static int
4098 tls_verify_cb(ctx)
4099 	X509_STORE_CTX *ctx;
4100 {
4101 	int ok;
4102 
4103 	ok = X509_verify_cert(ctx);
4104 	if (ok == 0)
4105 	{
4106 		if (LogLevel > 13)
4107 			return tls_verify_log(ok, ctx);
4108 		return 1;	/* override it */
4109 	}
4110 	return ok;
4111 }
4112 
4113 
4114 /*
4115 **  TLSLOGERR -- log the errors from the TLS error stack
4116 **
4117 **	Parameters:
4118 **		none.
4119 **
4120 **	Returns:
4121 **		none.
4122 */
4123 
4124 void
4125 tlslogerr()
4126 {
4127 	unsigned long l;
4128 	int line, flags;
4129 	unsigned long es;
4130 	char *file, *data;
4131 	char buf[256];
4132 #define CP (const char **)
4133 
4134 	es = CRYPTO_thread_id();
4135 	while ((l = ERR_get_error_line_data(CP &file, &line, CP &data, &flags))
4136 		!= 0)
4137 	{
4138 		sm_syslog(LOG_WARNING, NOQID,
4139 			 "TLS: %lu:%s:%s:%d:%s\n", es, ERR_error_string(l, buf),
4140 			 file, line, (flags & ERR_TXT_STRING) ? data : "");
4141 	}
4142 }
4143 
4144 # endif /* STARTTLS */
4145 #endif /* SMTP */
4146 /*
4147 **  HELP -- implement the HELP command.
4148 **
4149 **	Parameters:
4150 **		topic -- the topic we want help for.
4151 **		e -- envelope
4152 **
4153 **	Returns:
4154 **		none.
4155 **
4156 **	Side Effects:
4157 **		outputs the help file to message output.
4158 */
4159 #define HELPVSTR	"#vers	"
4160 #define HELPVERSION	2
4161 
4162 void
4163 help(topic, e)
4164 	char *topic;
4165 	ENVELOPE *e;
4166 {
4167 	register FILE *hf;
4168 	register char *p;
4169 	int len;
4170 	bool noinfo;
4171 	bool first = TRUE;
4172 	long sff = SFF_OPENASROOT|SFF_REGONLY;
4173 	char buf[MAXLINE];
4174 	char inp[MAXLINE];
4175 	static int foundvers = -1;
4176 	extern char Version[];
4177 
4178 	if (DontLockReadFiles)
4179 		sff |= SFF_NOLOCK;
4180 	if (!bitnset(DBS_HELPFILEINUNSAFEDIRPATH, DontBlameSendmail))
4181 		sff |= SFF_SAFEDIRPATH;
4182 
4183 	if (HelpFile == NULL ||
4184 	    (hf = safefopen(HelpFile, O_RDONLY, 0444, sff)) == NULL)
4185 	{
4186 		/* no help */
4187 		errno = 0;
4188 		message("502 5.3.0 Sendmail %s -- HELP not implemented",
4189 			Version);
4190 		return;
4191 	}
4192 
4193 	if (topic == NULL || *topic == '\0')
4194 	{
4195 		topic = "smtp";
4196 		noinfo = FALSE;
4197 	}
4198 	else
4199 	{
4200 		makelower(topic);
4201 		noinfo = TRUE;
4202 	}
4203 
4204 	len = strlen(topic);
4205 
4206 	while (fgets(buf, sizeof buf, hf) != NULL)
4207 	{
4208 		if (buf[0] == '#')
4209 		{
4210 			if (foundvers < 0 &&
4211 			    strncmp(buf, HELPVSTR, strlen(HELPVSTR)) == 0)
4212 			{
4213 				int h;
4214 
4215 				if (sscanf(buf + strlen(HELPVSTR), "%d",
4216 					   &h) == 1)
4217 					foundvers = h;
4218 			}
4219 			continue;
4220 		}
4221 		if (strncmp(buf, topic, len) == 0)
4222 		{
4223 			if (first)
4224 			{
4225 				first = FALSE;
4226 
4227 				/* print version if no/old vers# in file */
4228 				if (foundvers < 2 && !noinfo)
4229 					message("214-2.0.0 This is Sendmail version %s", Version);
4230 			}
4231 			p = strpbrk(buf, " \t");
4232 			if (p == NULL)
4233 				p = buf + strlen(buf) - 1;
4234 			else
4235 				p++;
4236 			fixcrlf(p, TRUE);
4237 			if (foundvers >= 2)
4238 			{
4239 				translate_dollars(p);
4240 				expand(p, inp, sizeof inp, e);
4241 				p = inp;
4242 			}
4243 			message("214-2.0.0 %s", p);
4244 			noinfo = FALSE;
4245 		}
4246 	}
4247 
4248 	if (noinfo)
4249 		message("504 5.3.0 HELP topic \"%.10s\" unknown", topic);
4250 	else
4251 		message("214 2.0.0 End of HELP info");
4252 
4253 	if (foundvers != 0 && foundvers < HELPVERSION)
4254 	{
4255 		if (LogLevel > 1)
4256 			sm_syslog(LOG_WARNING, e->e_id,
4257 				  "%s too old (require version %d)",
4258 				  HelpFile, HELPVERSION);
4259 
4260 		/* avoid log next time */
4261 		foundvers = 0;
4262 	}
4263 
4264 	(void) fclose(hf);
4265 }
4266