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