Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (c) 1999-2009 Sendmail, Inc. and its suppliers.
      3  *	All rights reserved.
      4  *
      5  * By using this file, you agree to the terms and conditions set
      6  * forth in the LICENSE file which can be found at the top level of
      7  * the sendmail distribution.
      8  *
      9  */
     10 
     11 #include <sendmail.h>
     12 
     13 SM_RCSID("@(#)$Id: milter.c,v 8.277 2009/11/06 00:57:06 ca Exp $")
     14 
     15 #if MILTER
     16 # include <sm/sendmail.h>
     17 # include <libmilter/mfapi.h>
     18 # include <libmilter/mfdef.h>
     19 
     20 # include <errno.h>
     21 # include <sm/time.h>
     22 # include <sys/uio.h>
     23 
     24 # if NETINET || NETINET6
     25 #  include <arpa/inet.h>
     26 #  if MILTER_NO_NAGLE
     27 #   include <netinet/tcp.h>
     28 #  endif /* MILTER_NO_NAGLE */
     29 # endif /* NETINET || NETINET6 */
     30 
     31 # include <sm/fdset.h>
     32 
     33 static void	milter_connect_timeout __P((int));
     34 static void	milter_error __P((struct milter *, ENVELOPE *));
     35 static int	milter_open __P((struct milter *, bool, ENVELOPE *));
     36 static void	milter_parse_timeouts __P((char *, struct milter *));
     37 static char	*milter_sysread __P((struct milter *, char *, ssize_t, time_t,
     38 			ENVELOPE *, const char *));
     39 static char	*milter_read __P((struct milter *, char *, ssize_t *, time_t,
     40 			ENVELOPE *, const char *));
     41 static char	*milter_write __P((struct milter *, int, char *, ssize_t,
     42 			time_t, ENVELOPE *, const char *));
     43 static char	*milter_send_command __P((struct milter *, int, void *,
     44 			ssize_t, ENVELOPE *, char *, const char *));
     45 static char	*milter_command __P((int, void *, ssize_t, char **,
     46 			ENVELOPE *, char *, const char *, bool));
     47 static char	*milter_body __P((struct milter *, ENVELOPE *, char *));
     48 static int	milter_reopen_df __P((ENVELOPE *));
     49 static int	milter_reset_df __P((ENVELOPE *));
     50 static void	milter_quit_filter __P((struct milter *, ENVELOPE *));
     51 static void	milter_abort_filter __P((struct milter *, ENVELOPE *));
     52 static void	milter_send_macros __P((struct milter *, char **, int,
     53 			ENVELOPE *));
     54 static int	milter_negotiate __P((struct milter *, ENVELOPE *,
     55 			milters_T *));
     56 static void	milter_per_connection_check __P((ENVELOPE *));
     57 static char	*milter_headers __P((struct milter *, ENVELOPE *, char *));
     58 static void	milter_addheader __P((struct milter *, char *, ssize_t,
     59 			ENVELOPE *));
     60 static void	milter_insheader __P((struct milter *, char *, ssize_t,
     61 			ENVELOPE *));
     62 static void	milter_changeheader __P((struct milter *, char *, ssize_t,
     63 			ENVELOPE *));
     64 static void	milter_chgfrom __P((char *, ssize_t, ENVELOPE *));
     65 static void	milter_addrcpt __P((char *, ssize_t, ENVELOPE *));
     66 static void	milter_addrcpt_par __P((char *, ssize_t, ENVELOPE *));
     67 static void	milter_delrcpt __P((char *, ssize_t, ENVELOPE *));
     68 static int	milter_replbody __P((char *, ssize_t, bool, ENVELOPE *));
     69 static int	milter_set_macros __P((char *, char **, char *, int));
     70 
     71 
     72 /* milter states */
     73 # define SMFS_CLOSED		'C'	/* closed for all further actions */
     74 # define SMFS_OPEN		'O'	/* connected to remote milter filter */
     75 # define SMFS_INMSG		'M'	/* currently servicing a message */
     76 # define SMFS_DONE		'D'	/* done with current message */
     77 # define SMFS_CLOSABLE		'Q'	/* done with current connection */
     78 # define SMFS_ERROR		'E'	/* error state */
     79 # define SMFS_READY		'R'	/* ready for action */
     80 # define SMFS_SKIP		'S'	/* skip body */
     81 
     82 static char *MilterConnectMacros[MAXFILTERMACROS + 1];
     83 static char *MilterHeloMacros[MAXFILTERMACROS + 1];
     84 static char *MilterEnvFromMacros[MAXFILTERMACROS + 1];
     85 static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1];
     86 static char *MilterDataMacros[MAXFILTERMACROS + 1];
     87 static char *MilterEOMMacros[MAXFILTERMACROS + 1];
     88 static char *MilterEOHMacros[MAXFILTERMACROS + 1];
     89 static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE;
     90 
     91 # define MILTER_CHECK_DONE_MSG() \
     92 	if (*state == SMFIR_REPLYCODE || \
     93 	    *state == SMFIR_REJECT || \
     94 	    *state == SMFIR_DISCARD || \
     95 	    *state == SMFIR_TEMPFAIL) \
     96 	{ \
     97 		/* Abort the filters to let them know we are done with msg */ \
     98 		milter_abort(e); \
     99 	}
    100 
    101 # define MILTER_CHECK_ERROR(initial, action) \
    102 	if (!initial && tTd(71, 100)) \
    103 	{ \
    104 		if (e->e_quarmsg == NULL) \
    105 		{ \
    106 			e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \
    107 							 "filter failure"); \
    108 			macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \
    109 				  e->e_quarmsg); \
    110 		} \
    111 	} \
    112 	else if (tTd(71, 101)) \
    113 	{ \
    114 		if (e->e_quarmsg == NULL) \
    115 		{ \
    116 			e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \
    117 							 "filter failure"); \
    118 			macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \
    119 				  e->e_quarmsg); \
    120 		} \
    121 	} \
    122 	else if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \
    123 		*state = SMFIR_TEMPFAIL; \
    124 	else if (bitnset(SMF_TEMPDROP, m->mf_flags)) \
    125 		*state = SMFIR_SHUTDOWN; \
    126 	else if (bitnset(SMF_REJECT, m->mf_flags)) \
    127 		*state = SMFIR_REJECT; \
    128 	else \
    129 		action;
    130 
    131 # define MILTER_CHECK_REPLYCODE(default) \
    132 	if (response == NULL || \
    133 	    strlen(response) + 1 != (size_t) rlen || \
    134 	    rlen < 3 || \
    135 	    (response[0] != '4' && response[0] != '5') || \
    136 	    !isascii(response[1]) || !isdigit(response[1]) || \
    137 	    !isascii(response[2]) || !isdigit(response[2])) \
    138 	{ \
    139 		if (response != NULL) \
    140 			sm_free(response); /* XXX */ \
    141 		response = newstr(default); \
    142 	} \
    143 	else \
    144 	{ \
    145 		char *ptr = response; \
    146  \
    147 		/* Check for unprotected %'s in the string */ \
    148 		while (*ptr != '\0') \
    149 		{ \
    150 			if (*ptr == '%' && *++ptr != '%') \
    151 			{ \
    152 				sm_free(response); /* XXX */ \
    153 				response = newstr(default); \
    154 				break; \
    155 			} \
    156 			ptr++; \
    157 		} \
    158 	}
    159 
    160 # define MILTER_DF_ERROR(msg) \
    161 { \
    162 	int save_errno = errno; \
    163  \
    164 	if (tTd(64, 5)) \
    165 	{ \
    166 		sm_dprintf(msg, dfname, sm_errstring(save_errno)); \
    167 		sm_dprintf("\n"); \
    168 	} \
    169 	if (MilterLogLevel > 0) \
    170 		sm_syslog(LOG_ERR, e->e_id, msg, dfname, sm_errstring(save_errno)); \
    171 	if (SuperSafe == SAFE_REALLY) \
    172 	{ \
    173 		if (e->e_dfp != NULL) \
    174 		{ \
    175 			(void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); \
    176 			e->e_dfp = NULL; \
    177 		} \
    178 		e->e_flags &= ~EF_HAS_DF; \
    179 	} \
    180 	errno = save_errno; \
    181 }
    182 
    183 /*
    184 **  MILTER_TIMEOUT -- make sure socket is ready in time
    185 **
    186 **	Parameters:
    187 **		routine -- routine name for debug/logging
    188 **		secs -- number of seconds in timeout
    189 **		write -- waiting to read or write?
    190 **		started -- whether this is part of a previous sequence
    191 **
    192 **	Assumes 'm' is a milter structure for the current socket.
    193 */
    194 
    195 # define MILTER_TIMEOUT(routine, secs, write, started, function) \
    196 { \
    197 	int ret; \
    198 	int save_errno; \
    199 	fd_set fds; \
    200 	struct timeval tv; \
    201  \
    202 	if (SM_FD_SETSIZE > 0 && m->mf_sock >= SM_FD_SETSIZE) \
    203 	{ \
    204 		if (tTd(64, 5)) \
    205 			sm_dprintf("milter_%s(%s): socket %d is larger than FD_SETSIZE %d\n", \
    206 				   (routine), m->mf_name, m->mf_sock, \
    207 				   SM_FD_SETSIZE); \
    208 		if (MilterLogLevel > 0) \
    209 			sm_syslog(LOG_ERR, e->e_id, \
    210 				  "Milter (%s): socket(%s) %d is larger than FD_SETSIZE %d", \
    211 				  m->mf_name, (routine), m->mf_sock, \
    212 				  SM_FD_SETSIZE); \
    213 		milter_error(m, e); \
    214 		return NULL; \
    215 	} \
    216  \
    217 	do \
    218 	{ \
    219 		FD_ZERO(&fds); \
    220 		SM_FD_SET(m->mf_sock, &fds); \
    221 		tv.tv_sec = (secs); \
    222 		tv.tv_usec = 0; \
    223 		ret = select(m->mf_sock + 1, \
    224 			     (write) ? NULL : &fds, \
    225 			     (write) ? &fds : NULL, \
    226 			     NULL, &tv); \
    227 	} while (ret < 0 && errno == EINTR); \
    228  \
    229 	switch (ret) \
    230 	{ \
    231 	  case 0: \
    232 		if (tTd(64, 5)) \
    233 			sm_dprintf("milter_%s(%s): timeout, where=%s\n", \
    234 				(routine), m->mf_name, (function)); \
    235 		if (MilterLogLevel > 0) \
    236 			sm_syslog(LOG_ERR, e->e_id, \
    237 				  "Milter (%s): timeout %s data %s, where=%s", \
    238 				  m->mf_name, \
    239 				  started ? "during" : "before", \
    240 				  (routine), (function)); \
    241 		milter_error(m, e); \
    242 		return NULL; \
    243  \
    244 	  case -1: \
    245 		save_errno = errno; \
    246 		if (tTd(64, 5)) \
    247 			sm_dprintf("milter_%s(%s): select: %s\n", (routine), \
    248 				   m->mf_name, sm_errstring(save_errno)); \
    249 		if (MilterLogLevel > 0) \
    250 		{ \
    251 			sm_syslog(LOG_ERR, e->e_id, \
    252 				  "Milter (%s): select(%s): %s", \
    253 				  m->mf_name, (routine), \
    254 				  sm_errstring(save_errno)); \
    255 		} \
    256 		milter_error(m, e); \
    257 		return NULL; \
    258  \
    259 	  default: \
    260 		if (SM_FD_ISSET(m->mf_sock, &fds)) \
    261 			break; \
    262 		if (tTd(64, 5)) \
    263 			sm_dprintf("milter_%s(%s): socket not ready\n", \
    264 				(routine), m->mf_name); \
    265 		if (MilterLogLevel > 0) \
    266 		{ \
    267 			sm_syslog(LOG_ERR, e->e_id, \
    268 				  "Milter (%s): socket(%s) not ready", \
    269 				  m->mf_name, (routine)); \
    270 		} \
    271 		milter_error(m, e); \
    272 		return NULL; \
    273 	} \
    274 }
    275 
    276 /*
    277 **  Low level functions
    278 */
    279 
    280 /*
    281 **  MILTER_READ -- read from a remote milter filter
    282 **
    283 **	Parameters:
    284 **		m -- milter to read from.
    285 **		cmd -- return param for command read.
    286 **		rlen -- return length of response string.
    287 **		to -- timeout in seconds.
    288 **		e -- current envelope.
    289 **
    290 **	Returns:
    291 **		response string (may be NULL)
    292 */
    293 
    294 static char *
    295 milter_sysread(m, buf, sz, to, e, where)
    296 	struct milter *m;
    297 	char *buf;
    298 	ssize_t sz;
    299 	time_t to;
    300 	ENVELOPE *e;
    301 	const char *where;
    302 {
    303 	time_t readstart = 0;
    304 	ssize_t len, curl;
    305 	bool started = false;
    306 
    307 	curl = 0;
    308 
    309 	if (to > 0)
    310 		readstart = curtime();
    311 
    312 	for (;;)
    313 	{
    314 		if (to > 0)
    315 		{
    316 			time_t now;
    317 
    318 			now = curtime();
    319 			if (now - readstart >= to)
    320 			{
    321 				if (tTd(64, 5))
    322 					sm_dprintf("milter_sys_read (%s): timeout %s data read in %s",
    323 						  m->mf_name,
    324 						  started ? "during" : "before",
    325 						  where);
    326 				if (MilterLogLevel > 0)
    327 					sm_syslog(LOG_ERR, e->e_id,
    328 						  "Milter (%s): timeout %s data read in %s",
    329 						  m->mf_name,
    330 						  started ? "during" : "before",
    331 						  where);
    332 				milter_error(m, e);
    333 				return NULL;
    334 			}
    335 			to -= now - readstart;
    336 			readstart = now;
    337 			MILTER_TIMEOUT("read", to, false, started, where);
    338 		}
    339 
    340 		len = read(m->mf_sock, buf + curl, sz - curl);
    341 
    342 		if (len < 0)
    343 		{
    344 			int save_errno = errno;
    345 
    346 			if (tTd(64, 5))
    347 				sm_dprintf("milter_sys_read(%s): read returned %ld: %s\n",
    348 					m->mf_name, (long) len,
    349 					sm_errstring(save_errno));
    350 			if (MilterLogLevel > 0)
    351 				sm_syslog(LOG_ERR, e->e_id,
    352 					  "Milter (%s): read returned %ld: %s",
    353 					  m->mf_name, (long) len,
    354 					  sm_errstring(save_errno));
    355 			milter_error(m, e);
    356 			return NULL;
    357 		}
    358 
    359 		started = true;
    360 		curl += len;
    361 		if (len == 0 || curl >= sz)
    362 			break;
    363 
    364 	}
    365 
    366 	if (curl != sz)
    367 	{
    368 		if (tTd(64, 5))
    369 			sm_dprintf("milter_sys_read(%s): cmd read returned %ld, expecting %ld\n",
    370 				m->mf_name, (long) curl, (long) sz);
    371 		if (MilterLogLevel > 0)
    372 			sm_syslog(LOG_ERR, e->e_id,
    373 				  "milter_sys_read(%s): cmd read returned %ld, expecting %ld",
    374 				  m->mf_name, (long) curl, (long) sz);
    375 		milter_error(m, e);
    376 		return NULL;
    377 	}
    378 	return buf;
    379 }
    380 
    381 static char *
    382 milter_read(m, cmd, rlen, to, e, where)
    383 	struct milter *m;
    384 	char *cmd;
    385 	ssize_t *rlen;
    386 	time_t to;
    387 	ENVELOPE *e;
    388 	const char *where;
    389 {
    390 	time_t readstart = 0;
    391 	ssize_t expl;
    392 	mi_int32 i;
    393 # if MILTER_NO_NAGLE && defined(TCP_CORK)
    394 	int cork = 0;
    395 # endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
    396 	char *buf;
    397 	char data[MILTER_LEN_BYTES + 1];
    398 
    399 	if (m->mf_sock < 0)
    400 	{
    401 		if (MilterLogLevel > 0)
    402 			sm_syslog(LOG_ERR, e->e_id,
    403 				  "milter_read(%s): socket closed, where=%s",
    404 				  m->mf_name, where);
    405 		milter_error(m, e);
    406 		return NULL;
    407 	}
    408 
    409 	*rlen = 0;
    410 	*cmd = '\0';
    411 
    412 	if (to > 0)
    413 		readstart = curtime();
    414 
    415 # if MILTER_NO_NAGLE && defined(TCP_CORK)
    416 	setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
    417 		   sizeof(cork));
    418 # endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
    419 
    420 	if (milter_sysread(m, data, sizeof(data), to, e, where) == NULL)
    421 		return NULL;
    422 
    423 # if MILTER_NO_NAGLE && defined(TCP_CORK)
    424 	cork = 1;
    425 	setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
    426 		   sizeof(cork));
    427 # endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
    428 
    429 	/* reset timeout */
    430 	if (to > 0)
    431 	{
    432 		time_t now;
    433 
    434 		now = curtime();
    435 		if (now - readstart >= to)
    436 		{
    437 			if (tTd(64, 5))
    438 				sm_dprintf("milter_read(%s): timeout before data read, where=%s\n",
    439 					m->mf_name, where);
    440 			if (MilterLogLevel > 0)
    441 				sm_syslog(LOG_ERR, e->e_id,
    442 					  "Milter read(%s): timeout before data read, where=%s",
    443 					  m->mf_name, where);
    444 			milter_error(m, e);
    445 			return NULL;
    446 		}
    447 		to -= now - readstart;
    448 	}
    449 
    450 	*cmd = data[MILTER_LEN_BYTES];
    451 	data[MILTER_LEN_BYTES] = '\0';
    452 	(void) memcpy(&i, data, MILTER_LEN_BYTES);
    453 	expl = ntohl(i) - 1;
    454 
    455 	if (tTd(64, 25))
    456 		sm_dprintf("milter_read(%s): expecting %ld bytes\n",
    457 			m->mf_name, (long) expl);
    458 
    459 	if (expl < 0)
    460 	{
    461 		if (tTd(64, 5))
    462 			sm_dprintf("milter_read(%s): read size %ld out of range, where=%s\n",
    463 				m->mf_name, (long) expl, where);
    464 		if (MilterLogLevel > 0)
    465 			sm_syslog(LOG_ERR, e->e_id,
    466 				  "milter_read(%s): read size %ld out of range, where=%s",
    467 				  m->mf_name, (long) expl, where);
    468 		milter_error(m, e);
    469 		return NULL;
    470 	}
    471 
    472 	if (expl == 0)
    473 		return NULL;
    474 
    475 	buf = (char *) xalloc(expl);
    476 
    477 	if (milter_sysread(m, buf, expl, to, e, where) == NULL)
    478 	{
    479 		sm_free(buf); /* XXX */
    480 		return NULL;
    481 	}
    482 
    483 	if (tTd(64, 50))
    484 		sm_dprintf("milter_read(%s): Returning %*s\n",
    485 			m->mf_name, (int) expl, buf);
    486 	*rlen = expl;
    487 	return buf;
    488 }
    489 
    490 /*
    491 **  MILTER_WRITE -- write to a remote milter filter
    492 **
    493 **	Parameters:
    494 **		m -- milter to read from.
    495 **		cmd -- command to send.
    496 **		buf -- optional command data.
    497 **		len -- length of buf.
    498 **		to -- timeout in seconds.
    499 **		e -- current envelope.
    500 **
    501 **	Returns:
    502 **		buf if successful, NULL otherwise
    503 **		Not actually used anywhere but function prototype
    504 **			must match milter_read()
    505 */
    506 
    507 static char *
    508 milter_write(m, cmd, buf, len, to, e, where)
    509 	struct milter *m;
    510 	int cmd;
    511 	char *buf;
    512 	ssize_t len;
    513 	time_t to;
    514 	ENVELOPE *e;
    515 	const char *where;
    516 {
    517 	ssize_t sl, i;
    518 	int num_vectors;
    519 	mi_int32 nl;
    520 	char command = (char) cmd;
    521 	char data[MILTER_LEN_BYTES + 1];
    522 	bool started = false;
    523 	struct iovec vector[2];
    524 
    525 	/*
    526 	**  At most two buffers will be written, though
    527 	**  only one may actually be used (see num_vectors).
    528 	**  The first is the size/command and the second is the command data.
    529 	*/
    530 
    531 	if (len < 0 || len > MilterMaxDataSize)
    532 	{
    533 		if (tTd(64, 5))
    534 		{
    535 			sm_dprintf("milter_write(%s): length %ld out of range, cmd=%c\n",
    536 				m->mf_name, (long) len, command);
    537 			sm_dprintf("milter_write(%s): buf=%s\n",
    538 				m->mf_name, str2prt(buf));
    539 		}
    540 		if (MilterLogLevel > 0)
    541 			sm_syslog(LOG_ERR, e->e_id,
    542 				  "milter_write(%s): length %ld out of range, cmd=%c",
    543 				  m->mf_name, (long) len, command);
    544 		milter_error(m, e);
    545 		return NULL;
    546 	}
    547 	if (m->mf_sock < 0)
    548 	{
    549 		if (MilterLogLevel > 0)
    550 			sm_syslog(LOG_ERR, e->e_id,
    551 				  "milter_write(%s): socket closed",
    552 				  m->mf_name);
    553 		milter_error(m, e);
    554 		return NULL;
    555 	}
    556 
    557 	if (tTd(64, 20))
    558 		sm_dprintf("milter_write(%s): cmd %c, len %ld\n",
    559 			   m->mf_name, command, (long) len);
    560 
    561 	nl = htonl(len + 1);	/* add 1 for the command char */
    562 	(void) memcpy(data, (char *) &nl, MILTER_LEN_BYTES);
    563 	data[MILTER_LEN_BYTES] = command;
    564 	sl = MILTER_LEN_BYTES + 1;
    565 
    566 	/* set up the vector for the size / command */
    567 	vector[0].iov_base = (void *) data;
    568 	vector[0].iov_len  = sl;
    569 
    570 	/*
    571 	**  Determine if there is command data.  If so, there will be two
    572 	**  vectors.  If not, there will be only one.  The vectors are set
    573 	**  up here and 'num_vectors' and 'sl' are set appropriately.
    574 	*/
    575 
    576 	/* NOTE:  len<0 has already been checked for.  Pedantic */
    577 	if (len <= 0 || buf == NULL)
    578 	{
    579 		/* There is no command data -- only a size / command data */
    580 		num_vectors = 1;
    581 	}
    582 	else
    583 	{
    584 		/*
    585 		**  There is both size / command and command data.
    586 		**  Set up the vector for the command data.
    587 		*/
    588 
    589 		num_vectors = 2;
    590 		sl += len;
    591 		vector[1].iov_base = (void *) buf;
    592 		vector[1].iov_len  = len;
    593 
    594 		if (tTd(64, 50))
    595 			sm_dprintf("milter_write(%s): Sending %*s\n",
    596 				   m->mf_name, (int) len, buf);
    597 	}
    598 
    599 	if (to > 0)
    600 		MILTER_TIMEOUT("write", to, true, started, where);
    601 
    602 	/* write the vector(s) */
    603 	i = writev(m->mf_sock, vector, num_vectors);
    604 	if (i != sl)
    605 	{
    606 		int save_errno = errno;
    607 
    608 		if (tTd(64, 5))
    609 			sm_dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n",
    610 				   m->mf_name, command, (long) i, (long) sl,
    611 				   sm_errstring(save_errno));
    612 		if (MilterLogLevel > 0)
    613 			sm_syslog(LOG_ERR, e->e_id,
    614 				  "Milter (%s): write(%c) returned %ld, expected %ld: %s",
    615 				  m->mf_name, command, (long) i, (long) sl,
    616 				  sm_errstring(save_errno));
    617 		milter_error(m, e);
    618 		return NULL;
    619 	}
    620 	return buf;
    621 }
    622 
    623 /*
    624 **  Utility functions
    625 */
    626 
    627 /*
    628 **  MILTER_OPEN -- connect to remote milter filter
    629 **
    630 **	Parameters:
    631 **		m -- milter to connect to.
    632 **		parseonly -- parse but don't connect.
    633 **		e -- current envelope.
    634 **
    635 **	Returns:
    636 **		connected socket if successful && !parseonly,
    637 **		0 upon parse success if parseonly,
    638 **		-1 otherwise.
    639 */
    640 
    641 static jmp_buf	MilterConnectTimeout;
    642 
    643 static int
    644 milter_open(m, parseonly, e)
    645 	struct milter *m;
    646 	bool parseonly;
    647 	ENVELOPE *e;
    648 {
    649 	int sock = 0;
    650 	SOCKADDR_LEN_T addrlen = 0;
    651 	int addrno = 0;
    652 	int save_errno;
    653 	char *p;
    654 	char *colon;
    655 	char *at;
    656 	struct hostent *hp = NULL;
    657 	SOCKADDR addr;
    658 
    659 	if (m->mf_conn == NULL || m->mf_conn[0] == '\0')
    660 	{
    661 		if (tTd(64, 5))
    662 			sm_dprintf("X%s: empty or missing socket information\n",
    663 				   m->mf_name);
    664 		if (parseonly)
    665 			syserr("X%s: empty or missing socket information",
    666 			       m->mf_name);
    667 		else if (MilterLogLevel > 0)
    668 			sm_syslog(LOG_ERR, e->e_id,
    669 				  "Milter (%s): empty or missing socket information",
    670 				  m->mf_name);
    671 		milter_error(m, e);
    672 		return -1;
    673 	}
    674 
    675 	/* protocol:filename or protocol:port@host */
    676 	memset(&addr, '\0', sizeof(addr));
    677 	p = m->mf_conn;
    678 	colon = strchr(p, ':');
    679 	if (colon != NULL)
    680 	{
    681 		*colon = '\0';
    682 
    683 		if (*p == '\0')
    684 		{
    685 # if NETUNIX
    686 			/* default to AF_UNIX */
    687 			addr.sa.sa_family = AF_UNIX;
    688 # else /* NETUNIX */
    689 #  if NETINET
    690 			/* default to AF_INET */
    691 			addr.sa.sa_family = AF_INET;
    692 #  else /* NETINET */
    693 #   if NETINET6
    694 			/* default to AF_INET6 */
    695 			addr.sa.sa_family = AF_INET6;
    696 #   else /* NETINET6 */
    697 			/* no protocols available */
    698 			if (MilterLogLevel > 0)
    699 				sm_syslog(LOG_ERR, e->e_id,
    700 					  "Milter (%s): no valid socket protocols available",
    701 					  m->mf_name);
    702 			milter_error(m, e);
    703 			return -1;
    704 #   endif /* NETINET6 */
    705 #  endif /* NETINET */
    706 # endif /* NETUNIX */
    707 		}
    708 # if NETUNIX
    709 		else if (sm_strcasecmp(p, "unix") == 0 ||
    710 			 sm_strcasecmp(p, "local") == 0)
    711 			addr.sa.sa_family = AF_UNIX;
    712 # endif /* NETUNIX */
    713 # if NETINET
    714 		else if (sm_strcasecmp(p, "inet") == 0)
    715 			addr.sa.sa_family = AF_INET;
    716 # endif /* NETINET */
    717 # if NETINET6
    718 		else if (sm_strcasecmp(p, "inet6") == 0)
    719 			addr.sa.sa_family = AF_INET6;
    720 # endif /* NETINET6 */
    721 		else
    722 		{
    723 # ifdef EPROTONOSUPPORT
    724 			errno = EPROTONOSUPPORT;
    725 # else /* EPROTONOSUPPORT */
    726 			errno = EINVAL;
    727 # endif /* EPROTONOSUPPORT */
    728 			if (tTd(64, 5))
    729 				sm_dprintf("X%s: unknown socket type %s\n",
    730 					m->mf_name, p);
    731 			if (parseonly)
    732 				syserr("X%s: unknown socket type %s",
    733 				       m->mf_name, p);
    734 			else if (MilterLogLevel > 0)
    735 				sm_syslog(LOG_ERR, e->e_id,
    736 					  "Milter (%s): unknown socket type %s",
    737 					  m->mf_name, p);
    738 			milter_error(m, e);
    739 			return -1;
    740 		}
    741 		*colon++ = ':';
    742 	}
    743 	else
    744 	{
    745 		/* default to AF_UNIX */
    746 		addr.sa.sa_family = AF_UNIX;
    747 		colon = p;
    748 	}
    749 
    750 # if NETUNIX
    751 	if (addr.sa.sa_family == AF_UNIX)
    752 	{
    753 		long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK;
    754 
    755 		at = colon;
    756 		if (strlen(colon) >= sizeof(addr.sunix.sun_path))
    757 		{
    758 			if (tTd(64, 5))
    759 				sm_dprintf("X%s: local socket name %s too long\n",
    760 					m->mf_name, colon);
    761 			errno = EINVAL;
    762 			if (parseonly)
    763 				syserr("X%s: local socket name %s too long",
    764 				       m->mf_name, colon);
    765 			else if (MilterLogLevel > 0)
    766 				sm_syslog(LOG_ERR, e->e_id,
    767 					  "Milter (%s): local socket name %s too long",
    768 					  m->mf_name, colon);
    769 			milter_error(m, e);
    770 			return -1;
    771 		}
    772 		errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff,
    773 				 S_IRUSR|S_IWUSR, NULL);
    774 
    775 		/* if just parsing .cf file, socket doesn't need to exist */
    776 		if (parseonly && errno == ENOENT)
    777 		{
    778 			if (OpMode == MD_DAEMON ||
    779 			    OpMode == MD_FGDAEMON)
    780 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
    781 						     "WARNING: X%s: local socket name %s missing\n",
    782 						     m->mf_name, colon);
    783 		}
    784 		else if (errno != 0)
    785 		{
    786 			/* if not safe, don't create */
    787 			save_errno = errno;
    788 			if (tTd(64, 5))
    789 				sm_dprintf("X%s: local socket name %s unsafe\n",
    790 					m->mf_name, colon);
    791 			errno = save_errno;
    792 			if (parseonly)
    793 			{
    794 				if (OpMode == MD_DAEMON ||
    795 				    OpMode == MD_FGDAEMON ||
    796 				    OpMode == MD_SMTP)
    797 					syserr("X%s: local socket name %s unsafe",
    798 					       m->mf_name, colon);
    799 			}
    800 			else if (MilterLogLevel > 0)
    801 				sm_syslog(LOG_ERR, e->e_id,
    802 					  "Milter (%s): local socket name %s unsafe",
    803 					  m->mf_name, colon);
    804 			milter_error(m, e);
    805 			return -1;
    806 		}
    807 
    808 		(void) sm_strlcpy(addr.sunix.sun_path, colon,
    809 			       sizeof(addr.sunix.sun_path));
    810 		addrlen = sizeof(struct sockaddr_un);
    811 	}
    812 	else
    813 # endif /* NETUNIX */
    814 # if NETINET || NETINET6
    815 	if (false
    816 #  if NETINET
    817 		 || addr.sa.sa_family == AF_INET
    818 #  endif /* NETINET */
    819 #  if NETINET6
    820 		 || addr.sa.sa_family == AF_INET6
    821 #  endif /* NETINET6 */
    822 		 )
    823 	{
    824 		unsigned short port;
    825 
    826 		/* Parse port@host */
    827 		at = strchr(colon, '@');
    828 		if (at == NULL)
    829 		{
    830 			if (tTd(64, 5))
    831 				sm_dprintf("X%s: bad address %s (expected port@host)\n",
    832 					m->mf_name, colon);
    833 			if (parseonly)
    834 				syserr("X%s: bad address %s (expected port@host)",
    835 				       m->mf_name, colon);
    836 			else if (MilterLogLevel > 0)
    837 				sm_syslog(LOG_ERR, e->e_id,
    838 					  "Milter (%s): bad address %s (expected port@host)",
    839 					  m->mf_name, colon);
    840 			milter_error(m, e);
    841 			return -1;
    842 		}
    843 		*at = '\0';
    844 		if (isascii(*colon) && isdigit(*colon))
    845 			port = htons((unsigned short) atoi(colon));
    846 		else
    847 		{
    848 #  ifdef NO_GETSERVBYNAME
    849 			if (tTd(64, 5))
    850 				sm_dprintf("X%s: invalid port number %s\n",
    851 					m->mf_name, colon);
    852 			if (parseonly)
    853 				syserr("X%s: invalid port number %s",
    854 				       m->mf_name, colon);
    855 			else if (MilterLogLevel > 0)
    856 				sm_syslog(LOG_ERR, e->e_id,
    857 					  "Milter (%s): invalid port number %s",
    858 					  m->mf_name, colon);
    859 			milter_error(m, e);
    860 			return -1;
    861 #  else /* NO_GETSERVBYNAME */
    862 			struct servent *sp;
    863 
    864 			sp = getservbyname(colon, "tcp");
    865 			if (sp == NULL)
    866 			{
    867 				save_errno = errno;
    868 				if (tTd(64, 5))
    869 					sm_dprintf("X%s: unknown port name %s\n",
    870 						m->mf_name, colon);
    871 				errno = save_errno;
    872 				if (parseonly)
    873 					syserr("X%s: unknown port name %s",
    874 					       m->mf_name, colon);
    875 				else if (MilterLogLevel > 0)
    876 					sm_syslog(LOG_ERR, e->e_id,
    877 						  "Milter (%s): unknown port name %s",
    878 						  m->mf_name, colon);
    879 				milter_error(m, e);
    880 				return -1;
    881 			}
    882 			port = sp->s_port;
    883 #  endif /* NO_GETSERVBYNAME */
    884 		}
    885 		*at++ = '@';
    886 		if (*at == '[')
    887 		{
    888 			char *end;
    889 
    890 			end = strchr(at, ']');
    891 			if (end != NULL)
    892 			{
    893 				bool found = false;
    894 #  if NETINET
    895 				unsigned long hid = INADDR_NONE;
    896 #  endif /* NETINET */
    897 #  if NETINET6
    898 				struct sockaddr_in6 hid6;
    899 #  endif /* NETINET6 */
    900 
    901 				*end = '\0';
    902 #  if NETINET
    903 				if (addr.sa.sa_family == AF_INET &&
    904 				    (hid = inet_addr(&at[1])) != INADDR_NONE)
    905 				{
    906 					addr.sin.sin_addr.s_addr = hid;
    907 					addr.sin.sin_port = port;
    908 					found = true;
    909 				}
    910 #  endif /* NETINET */
    911 #  if NETINET6
    912 				(void) memset(&hid6, '\0', sizeof(hid6));
    913 				if (addr.sa.sa_family == AF_INET6 &&
    914 				    anynet_pton(AF_INET6, &at[1],
    915 						&hid6.sin6_addr) == 1)
    916 				{
    917 					addr.sin6.sin6_addr = hid6.sin6_addr;
    918 					addr.sin6.sin6_port = port;
    919 					found = true;
    920 				}
    921 #  endif /* NETINET6 */
    922 				*end = ']';
    923 				if (!found)
    924 				{
    925 					if (tTd(64, 5))
    926 						sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n",
    927 							m->mf_name, at);
    928 					if (parseonly)
    929 						syserr("X%s: Invalid numeric domain spec \"%s\"",
    930 						       m->mf_name, at);
    931 					else if (MilterLogLevel > 0)
    932 						sm_syslog(LOG_ERR, e->e_id,
    933 							  "Milter (%s): Invalid numeric domain spec \"%s\"",
    934 							  m->mf_name, at);
    935 					milter_error(m, e);
    936 					return -1;
    937 				}
    938 			}
    939 			else
    940 			{
    941 				if (tTd(64, 5))
    942 					sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n",
    943 						m->mf_name, at);
    944 				if (parseonly)
    945 					syserr("X%s: Invalid numeric domain spec \"%s\"",
    946 					       m->mf_name, at);
    947 				else if (MilterLogLevel > 0)
    948 					sm_syslog(LOG_ERR, e->e_id,
    949 						  "Milter (%s): Invalid numeric domain spec \"%s\"",
    950 						  m->mf_name, at);
    951 				milter_error(m, e);
    952 				return -1;
    953 			}
    954 		}
    955 		else
    956 		{
    957 			hp = sm_gethostbyname(at, addr.sa.sa_family);
    958 			if (hp == NULL)
    959 			{
    960 				save_errno = errno;
    961 				if (tTd(64, 5))
    962 					sm_dprintf("X%s: Unknown host name %s\n",
    963 						   m->mf_name, at);
    964 				errno = save_errno;
    965 				if (parseonly)
    966 					syserr("X%s: Unknown host name %s",
    967 					       m->mf_name, at);
    968 				else if (MilterLogLevel > 0)
    969 					sm_syslog(LOG_ERR, e->e_id,
    970 						  "Milter (%s): Unknown host name %s",
    971 						  m->mf_name, at);
    972 				milter_error(m, e);
    973 				return -1;
    974 			}
    975 			addr.sa.sa_family = hp->h_addrtype;
    976 			switch (hp->h_addrtype)
    977 			{
    978 #  if NETINET
    979 			  case AF_INET:
    980 				memmove(&addr.sin.sin_addr,
    981 					hp->h_addr, INADDRSZ);
    982 				addr.sin.sin_port = port;
    983 				addrlen = sizeof(struct sockaddr_in);
    984 				addrno = 1;
    985 				break;
    986 #  endif /* NETINET */
    987 
    988 #  if NETINET6
    989 			  case AF_INET6:
    990 				memmove(&addr.sin6.sin6_addr,
    991 					hp->h_addr, IN6ADDRSZ);
    992 				addr.sin6.sin6_port = port;
    993 				addrlen = sizeof(struct sockaddr_in6);
    994 				addrno = 1;
    995 				break;
    996 #  endif /* NETINET6 */
    997 
    998 			  default:
    999 				if (tTd(64, 5))
   1000 					sm_dprintf("X%s: Unknown protocol for %s (%d)\n",
   1001 						   m->mf_name, at,
   1002 						   hp->h_addrtype);
   1003 				if (parseonly)
   1004 					syserr("X%s: Unknown protocol for %s (%d)",
   1005 					       m->mf_name, at, hp->h_addrtype);
   1006 				else if (MilterLogLevel > 0)
   1007 					sm_syslog(LOG_ERR, e->e_id,
   1008 						  "Milter (%s): Unknown protocol for %s (%d)",
   1009 						  m->mf_name, at,
   1010 						  hp->h_addrtype);
   1011 				milter_error(m, e);
   1012 #  if NETINET6
   1013 				freehostent(hp);
   1014 #  endif /* NETINET6 */
   1015 				return -1;
   1016 			}
   1017 		}
   1018 	}
   1019 	else
   1020 # endif /* NETINET || NETINET6 */
   1021 	{
   1022 		if (tTd(64, 5))
   1023 			sm_dprintf("X%s: unknown socket protocol\n",
   1024 				   m->mf_name);
   1025 		if (parseonly)
   1026 			syserr("X%s: unknown socket protocol", m->mf_name);
   1027 		else if (MilterLogLevel > 0)
   1028 			sm_syslog(LOG_ERR, e->e_id,
   1029 				  "Milter (%s): unknown socket protocol",
   1030 				  m->mf_name);
   1031 		milter_error(m, e);
   1032 		return -1;
   1033 	}
   1034 
   1035 	/* just parsing through? */
   1036 	if (parseonly)
   1037 	{
   1038 		m->mf_state = SMFS_READY;
   1039 # if NETINET6
   1040 		if (hp != NULL)
   1041 			freehostent(hp);
   1042 # endif /* NETINET6 */
   1043 		return 0;
   1044 	}
   1045 
   1046 	/* sanity check */
   1047 	if (m->mf_state != SMFS_READY &&
   1048 	    m->mf_state != SMFS_CLOSED)
   1049 	{
   1050 		/* shouldn't happen */
   1051 		if (tTd(64, 1))
   1052 			sm_dprintf("Milter (%s): Trying to open filter in state %c\n",
   1053 				   m->mf_name, (char) m->mf_state);
   1054 		milter_error(m, e);
   1055 # if NETINET6
   1056 		if (hp != NULL)
   1057 			freehostent(hp);
   1058 # endif /* NETINET6 */
   1059 		return -1;
   1060 	}
   1061 
   1062 	/* nope, actually connecting */
   1063 	for (;;)
   1064 	{
   1065 		sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
   1066 		if (sock < 0)
   1067 		{
   1068 			save_errno = errno;
   1069 			if (tTd(64, 5))
   1070 				sm_dprintf("Milter (%s): error creating socket: %s\n",
   1071 					   m->mf_name,
   1072 					   sm_errstring(save_errno));
   1073 			if (MilterLogLevel > 0)
   1074 				sm_syslog(LOG_ERR, e->e_id,
   1075 					  "Milter (%s): error creating socket: %s",
   1076 					  m->mf_name, sm_errstring(save_errno));
   1077 			milter_error(m, e);
   1078 # if NETINET6
   1079 			if (hp != NULL)
   1080 				freehostent(hp);
   1081 # endif /* NETINET6 */
   1082 			return -1;
   1083 		}
   1084 
   1085 		if (setjmp(MilterConnectTimeout) == 0)
   1086 		{
   1087 			SM_EVENT *ev = NULL;
   1088 			int i;
   1089 
   1090 			if (m->mf_timeout[SMFTO_CONNECT] > 0)
   1091 				ev = sm_setevent(m->mf_timeout[SMFTO_CONNECT],
   1092 						 milter_connect_timeout, 0);
   1093 
   1094 			i = connect(sock, (struct sockaddr *) &addr, addrlen);
   1095 			save_errno = errno;
   1096 			if (ev != NULL)
   1097 				sm_clrevent(ev);
   1098 			errno = save_errno;
   1099 			if (i >= 0)
   1100 				break;
   1101 		}
   1102 
   1103 		/* couldn't connect.... try next address */
   1104 		save_errno = errno;
   1105 		p = CurHostName;
   1106 		CurHostName = at;
   1107 		if (tTd(64, 5))
   1108 			sm_dprintf("milter_open (%s): open %s failed: %s\n",
   1109 				   m->mf_name, at, sm_errstring(save_errno));
   1110 		if (MilterLogLevel > 13)
   1111 			sm_syslog(LOG_INFO, e->e_id,
   1112 				  "Milter (%s): open %s failed: %s",
   1113 				  m->mf_name, at, sm_errstring(save_errno));
   1114 		CurHostName = p;
   1115 		(void) close(sock);
   1116 
   1117 		/* try next address */
   1118 		if (hp != NULL && hp->h_addr_list[addrno] != NULL)
   1119 		{
   1120 			switch (addr.sa.sa_family)
   1121 			{
   1122 # if NETINET
   1123 			  case AF_INET:
   1124 				memmove(&addr.sin.sin_addr,
   1125 					hp->h_addr_list[addrno++],
   1126 					INADDRSZ);
   1127 				break;
   1128 # endif /* NETINET */
   1129 
   1130 # if NETINET6
   1131 			  case AF_INET6:
   1132 				memmove(&addr.sin6.sin6_addr,
   1133 					hp->h_addr_list[addrno++],
   1134 					IN6ADDRSZ);
   1135 				break;
   1136 # endif /* NETINET6 */
   1137 
   1138 			  default:
   1139 				if (tTd(64, 5))
   1140 					sm_dprintf("X%s: Unknown protocol for %s (%d)\n",
   1141 						   m->mf_name, at,
   1142 						   hp->h_addrtype);
   1143 				if (MilterLogLevel > 0)
   1144 					sm_syslog(LOG_ERR, e->e_id,
   1145 						  "Milter (%s): Unknown protocol for %s (%d)",
   1146 						  m->mf_name, at,
   1147 						  hp->h_addrtype);
   1148 				milter_error(m, e);
   1149 # if NETINET6
   1150 				freehostent(hp);
   1151 # endif /* NETINET6 */
   1152 				return -1;
   1153 			}
   1154 			continue;
   1155 		}
   1156 		p = CurHostName;
   1157 		CurHostName = at;
   1158 		if (tTd(64, 5))
   1159 			sm_dprintf("X%s: error connecting to filter: %s\n",
   1160 				   m->mf_name, sm_errstring(save_errno));
   1161 		if (MilterLogLevel > 0)
   1162 			sm_syslog(LOG_ERR, e->e_id,
   1163 				  "Milter (%s): error connecting to filter: %s",
   1164 				  m->mf_name, sm_errstring(save_errno));
   1165 		CurHostName = p;
   1166 		milter_error(m, e);
   1167 # if NETINET6
   1168 		if (hp != NULL)
   1169 			freehostent(hp);
   1170 # endif /* NETINET6 */
   1171 		return -1;
   1172 	}
   1173 	m->mf_state = SMFS_OPEN;
   1174 # if NETINET6
   1175 	if (hp != NULL)
   1176 	{
   1177 		freehostent(hp);
   1178 		hp = NULL;
   1179 	}
   1180 # endif /* NETINET6 */
   1181 # if MILTER_NO_NAGLE && !defined(TCP_CORK)
   1182 	{
   1183 		int nodelay = 1;
   1184 
   1185 		setsockopt(m->mf_sock, IPPROTO_TCP, TCP_NODELAY,
   1186 			   (char *)&nodelay, sizeof(nodelay));
   1187 	}
   1188 # endif /* MILTER_NO_NAGLE && !defined(TCP_CORK) */
   1189 	return sock;
   1190 }
   1191 
   1192 static void
   1193 milter_connect_timeout(ignore)
   1194 	int ignore;
   1195 {
   1196 	/*
   1197 	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
   1198 	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
   1199 	**	DOING.
   1200 	*/
   1201 
   1202 	errno = ETIMEDOUT;
   1203 	longjmp(MilterConnectTimeout, 1);
   1204 }
   1205 
   1206 /*
   1207 **  MILTER_SETUP -- setup structure for a mail filter
   1208 **
   1209 **	Parameters:
   1210 **		line -- the options line.
   1211 **
   1212 **	Returns:
   1213 **		none
   1214 */
   1215 
   1216 void
   1217 milter_setup(line)
   1218 	char *line;
   1219 {
   1220 	char fcode;
   1221 	char *p;
   1222 	struct milter *m;
   1223 	STAB *s;
   1224 
   1225 	/* collect the filter name */
   1226 	for (p = line;
   1227 	     *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p));
   1228 	     p++)
   1229 		continue;
   1230 	if (*p != '\0')
   1231 		*p++ = '\0';
   1232 	if (line[0] == '\0')
   1233 	{
   1234 		syserr("name required for mail filter");
   1235 		return;
   1236 	}
   1237 	m = (struct milter *) xalloc(sizeof(*m));
   1238 	memset((char *) m, '\0', sizeof(*m));
   1239 	m->mf_name = newstr(line);
   1240 	m->mf_state = SMFS_READY;
   1241 	m->mf_sock = -1;
   1242 	m->mf_timeout[SMFTO_CONNECT] = (time_t) 300;
   1243 	m->mf_timeout[SMFTO_WRITE] = (time_t) 10;
   1244 	m->mf_timeout[SMFTO_READ] = (time_t) 10;
   1245 	m->mf_timeout[SMFTO_EOM] = (time_t) 300;
   1246 #if _FFR_MILTER_CHECK
   1247 	m->mf_mta_prot_version = SMFI_PROT_VERSION;
   1248 	m->mf_mta_prot_flags = SMFI_CURR_PROT;
   1249 	m->mf_mta_actions = SMFI_CURR_ACTS;
   1250 #endif /* _FFR_MILTER_CHECK */
   1251 
   1252 	/* now scan through and assign info from the fields */
   1253 	while (*p != '\0')
   1254 	{
   1255 		char *delimptr;
   1256 
   1257 		while (*p != '\0' &&
   1258 		       (*p == ',' || (isascii(*p) && isspace(*p))))
   1259 			p++;
   1260 
   1261 		/* p now points to field code */
   1262 		fcode = *p;
   1263 		while (*p != '\0' && *p != '=' && *p != ',')
   1264 			p++;
   1265 		if (*p++ != '=')
   1266 		{
   1267 			syserr("X%s: `=' expected", m->mf_name);
   1268 			return;
   1269 		}
   1270 		while (isascii(*p) && isspace(*p))
   1271 			p++;
   1272 
   1273 		/* p now points to the field body */
   1274 		p = munchstring(p, &delimptr, ',');
   1275 
   1276 		/* install the field into the filter struct */
   1277 		switch (fcode)
   1278 		{
   1279 		  case 'S':		/* socket */
   1280 			if (p == NULL)
   1281 				m->mf_conn = NULL;
   1282 			else
   1283 				m->mf_conn = newstr(p);
   1284 			break;
   1285 
   1286 		  case 'F':		/* Milter flags configured on MTA */
   1287 			for (; *p != '\0'; p++)
   1288 			{
   1289 				if (!(isascii(*p) && isspace(*p)))
   1290 					setbitn(bitidx(*p), m->mf_flags);
   1291 			}
   1292 			break;
   1293 
   1294 		  case 'T':		/* timeouts */
   1295 			milter_parse_timeouts(p, m);
   1296 			break;
   1297 
   1298 #if _FFR_MILTER_CHECK
   1299 		  case 'a':
   1300 			m->mf_mta_actions = strtoul(p, NULL, 0);
   1301 			break;
   1302 		  case 'f':
   1303 			m->mf_mta_prot_flags = strtoul(p, NULL, 0);
   1304 			break;
   1305 		  case 'v':
   1306 			m->mf_mta_prot_version = strtoul(p, NULL, 0);
   1307 			break;
   1308 #endif /* _FFR_MILTER_CHECK */
   1309 
   1310 		  default:
   1311 			syserr("X%s: unknown filter equate %c=",
   1312 			       m->mf_name, fcode);
   1313 			break;
   1314 		}
   1315 		p = delimptr;
   1316 	}
   1317 
   1318 	/* early check for errors */
   1319 	(void) milter_open(m, true, CurEnv);
   1320 
   1321 	/* enter the filter into the symbol table */
   1322 	s = stab(m->mf_name, ST_MILTER, ST_ENTER);
   1323 	if (s->s_milter != NULL)
   1324 		syserr("X%s: duplicate filter definition", m->mf_name);
   1325 	else
   1326 		s->s_milter = m;
   1327 }
   1328 
   1329 /*
   1330 **  MILTER_CONFIG -- parse option list into an array and check config
   1331 **
   1332 **	Called when reading configuration file.
   1333 **
   1334 **	Parameters:
   1335 **		spec -- the filter list.
   1336 **		list -- the array to fill in.
   1337 **		max -- the maximum number of entries in list.
   1338 **
   1339 **	Returns:
   1340 **		none
   1341 */
   1342 
   1343 void
   1344 milter_config(spec, list, max)
   1345 	char *spec;
   1346 	struct milter **list;
   1347 	int max;
   1348 {
   1349 	int numitems = 0;
   1350 	char *p;
   1351 
   1352 	/* leave one for the NULL signifying the end of the list */
   1353 	max--;
   1354 
   1355 	for (p = spec; p != NULL; )
   1356 	{
   1357 		STAB *s;
   1358 
   1359 		while (isascii(*p) && isspace(*p))
   1360 			p++;
   1361 		if (*p == '\0')
   1362 			break;
   1363 		spec = p;
   1364 
   1365 		if (numitems >= max)
   1366 		{
   1367 			syserr("Too many filters defined, %d max", max);
   1368 			if (max > 0)
   1369 				list[0] = NULL;
   1370 			return;
   1371 		}
   1372 		p = strpbrk(p, ";,");
   1373 		if (p != NULL)
   1374 			*p++ = '\0';
   1375 
   1376 		s = stab(spec, ST_MILTER, ST_FIND);
   1377 		if (s == NULL)
   1378 		{
   1379 			syserr("InputFilter %s not defined", spec);
   1380 			ExitStat = EX_CONFIG;
   1381 			return;
   1382 		}
   1383 		list[numitems++] = s->s_milter;
   1384 	}
   1385 	list[numitems] = NULL;
   1386 
   1387 	/* if not set, set to LogLevel */
   1388 	if (MilterLogLevel == -1)
   1389 		MilterLogLevel = LogLevel;
   1390 }
   1391 
   1392 /*
   1393 **  MILTER_PARSE_TIMEOUTS -- parse timeout list
   1394 **
   1395 **	Called when reading configuration file.
   1396 **
   1397 **	Parameters:
   1398 **		spec -- the timeout list.
   1399 **		m -- milter to set.
   1400 **
   1401 **	Returns:
   1402 **		none
   1403 */
   1404 
   1405 static void
   1406 milter_parse_timeouts(spec, m)
   1407 	char *spec;
   1408 	struct milter *m;
   1409 {
   1410 	char fcode;
   1411 	int tcode;
   1412 	char *p;
   1413 
   1414 	p = spec;
   1415 
   1416 	/* now scan through and assign info from the fields */
   1417 	while (*p != '\0')
   1418 	{
   1419 		char *delimptr;
   1420 
   1421 		while (*p != '\0' &&
   1422 		       (*p == ';' || (isascii(*p) && isspace(*p))))
   1423 			p++;
   1424 
   1425 		/* p now points to field code */
   1426 		fcode = *p;
   1427 		while (*p != '\0' && *p != ':')
   1428 			p++;
   1429 		if (*p++ != ':')
   1430 		{
   1431 			syserr("X%s, T=: `:' expected", m->mf_name);
   1432 			return;
   1433 		}
   1434 		while (isascii(*p) && isspace(*p))
   1435 			p++;
   1436 
   1437 		/* p now points to the field body */
   1438 		p = munchstring(p, &delimptr, ';');
   1439 		tcode = -1;
   1440 
   1441 		/* install the field into the filter struct */
   1442 		switch (fcode)
   1443 		{
   1444 		  case 'C':
   1445 			tcode = SMFTO_CONNECT;
   1446 			break;
   1447 
   1448 		  case 'S':
   1449 			tcode = SMFTO_WRITE;
   1450 			break;
   1451 
   1452 		  case 'R':
   1453 			tcode = SMFTO_READ;
   1454 			break;
   1455 
   1456 		  case 'E':
   1457 			tcode = SMFTO_EOM;
   1458 			break;
   1459 
   1460 		  default:
   1461 			if (tTd(64, 5))
   1462 				sm_dprintf("X%s: %c unknown\n",
   1463 					   m->mf_name, fcode);
   1464 			syserr("X%s: unknown filter timeout %c",
   1465 			       m->mf_name, fcode);
   1466 			break;
   1467 		}
   1468 		if (tcode >= 0)
   1469 		{
   1470 			m->mf_timeout[tcode] = convtime(p, 's');
   1471 			if (tTd(64, 5))
   1472 				sm_dprintf("X%s: %c=%ld\n",
   1473 					   m->mf_name, fcode,
   1474 					   (u_long) m->mf_timeout[tcode]);
   1475 		}
   1476 		p = delimptr;
   1477 	}
   1478 }
   1479 
   1480 /*
   1481 **  MILTER_SET_MACROS -- set milter macros
   1482 **
   1483 **	Parameters:
   1484 **		name -- name of milter.
   1485 **		macros -- where to store macros.
   1486 **		val -- the value of the option.
   1487 **		nummac -- current number of macros
   1488 **
   1489 **	Returns:
   1490 **		new number of macros
   1491 */
   1492 
   1493 static int
   1494 milter_set_macros(name, macros, val, nummac)
   1495 	char *name;
   1496 	char **macros;
   1497 	char *val;
   1498 	int nummac;
   1499 {
   1500 	char *p;
   1501 
   1502 	p = newstr(val);
   1503 	while (*p != '\0')
   1504 	{
   1505 		char *macro;
   1506 
   1507 		/* Skip leading commas, spaces */
   1508 		while (*p != '\0' &&
   1509 		       (*p == ',' || (isascii(*p) && isspace(*p))))
   1510 			p++;
   1511 
   1512 		if (*p == '\0')
   1513 			break;
   1514 
   1515 		/* Find end of macro */
   1516 		macro = p;
   1517 		while (*p != '\0' && *p != ',' &&
   1518 		       isascii(*p) && !isspace(*p))
   1519 			p++;
   1520 		if (*p != '\0')
   1521 			*p++ = '\0';
   1522 
   1523 		if (nummac >= MAXFILTERMACROS)
   1524 		{
   1525 			syserr("milter_set_option: too many macros in Milter.%s (max %d)",
   1526 			       name, MAXFILTERMACROS);
   1527 			macros[nummac] = NULL;
   1528 			return -1;
   1529 		}
   1530 		macros[nummac++] = macro;
   1531 	}
   1532 	macros[nummac] = NULL;
   1533 	return nummac;
   1534 }
   1535 
   1536 /*
   1537 **  MILTER_SET_OPTION -- set an individual milter option
   1538 **
   1539 **	Parameters:
   1540 **		name -- the name of the option.
   1541 **		val -- the value of the option.
   1542 **		sticky -- if set, don't let other setoptions override
   1543 **			this value.
   1544 **
   1545 **	Returns:
   1546 **		none.
   1547 */
   1548 
   1549 /* set if Milter sub-option is stuck */
   1550 static BITMAP256	StickyMilterOpt;
   1551 
   1552 static struct milteropt
   1553 {
   1554 	char		*mo_name;	/* long name of milter option */
   1555 	unsigned char	mo_code;	/* code for option */
   1556 } MilterOptTab[] =
   1557 {
   1558 # define MO_MACROS_CONNECT		SMFIM_CONNECT
   1559 	{ "macros.connect",		MO_MACROS_CONNECT		},
   1560 # define MO_MACROS_HELO			SMFIM_HELO
   1561 	{ "macros.helo",		MO_MACROS_HELO			},
   1562 # define MO_MACROS_ENVFROM		SMFIM_ENVFROM
   1563 	{ "macros.envfrom",		MO_MACROS_ENVFROM		},
   1564 # define MO_MACROS_ENVRCPT		SMFIM_ENVRCPT
   1565 	{ "macros.envrcpt",		MO_MACROS_ENVRCPT		},
   1566 # define MO_MACROS_DATA			SMFIM_DATA
   1567 	{ "macros.data",		MO_MACROS_DATA			},
   1568 # define MO_MACROS_EOM			SMFIM_EOM
   1569 	{ "macros.eom",			MO_MACROS_EOM			},
   1570 # define MO_MACROS_EOH			SMFIM_EOH
   1571 	{ "macros.eoh",			MO_MACROS_EOH			},
   1572 
   1573 # define MO_LOGLEVEL			0x07
   1574 	{ "loglevel",			MO_LOGLEVEL			},
   1575 # if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE
   1576 #  define MO_MAXDATASIZE		0x08
   1577 	{ "maxdatasize",		MO_MAXDATASIZE			},
   1578 # endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */
   1579 	{ NULL,				(unsigned char)-1		},
   1580 };
   1581 
   1582 void
   1583 milter_set_option(name, val, sticky)
   1584 	char *name;
   1585 	char *val;
   1586 	bool sticky;
   1587 {
   1588 	int nummac, r;
   1589 	struct milteropt *mo;
   1590 	char **macros = NULL;
   1591 
   1592 	nummac = 0;
   1593 	if (tTd(37, 2) || tTd(64, 5))
   1594 		sm_dprintf("milter_set_option(%s = %s)", name, val);
   1595 
   1596 	if (name == NULL)
   1597 	{
   1598 		syserr("milter_set_option: invalid Milter option, must specify suboption");
   1599 		return;
   1600 	}
   1601 
   1602 	for (mo = MilterOptTab; mo->mo_name != NULL; mo++)
   1603 	{
   1604 		if (sm_strcasecmp(mo->mo_name, name) == 0)
   1605 			break;
   1606 	}
   1607 
   1608 	if (mo->mo_name == NULL)
   1609 	{
   1610 		syserr("milter_set_option: invalid Milter option %s", name);
   1611 		return;
   1612 	}
   1613 
   1614 	/*
   1615 	**  See if this option is preset for us.
   1616 	*/
   1617 
   1618 	if (!sticky && bitnset(mo->mo_code, StickyMilterOpt))
   1619 	{
   1620 		if (tTd(37, 2) || tTd(64,5))
   1621 			sm_dprintf(" (ignored)\n");
   1622 		return;
   1623 	}
   1624 
   1625 	if (tTd(37, 2) || tTd(64,5))
   1626 		sm_dprintf("\n");
   1627 
   1628 	switch (mo->mo_code)
   1629 	{
   1630 	  case MO_LOGLEVEL:
   1631 		MilterLogLevel = atoi(val);
   1632 		break;
   1633 
   1634 # if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE
   1635 	  case MO_MAXDATASIZE:
   1636 #  if _FFR_MDS_NEGOTIATE
   1637 		MilterMaxDataSize = (size_t)atol(val);
   1638 		if (MilterMaxDataSize != MILTER_MDS_64K &&
   1639 		    MilterMaxDataSize != MILTER_MDS_256K &&
   1640 		    MilterMaxDataSize != MILTER_MDS_1M)
   1641 		{
   1642 			sm_syslog(LOG_WARNING, NOQID,
   1643 				"WARNING: Milter.%s=%d, allowed are only %d, %d, and %d",
   1644 				name, MilterMaxDataSize,
   1645 				MILTER_MDS_64K, MILTER_MDS_256K,
   1646 				MILTER_MDS_1M);
   1647 			if (MilterMaxDataSize < MILTER_MDS_64K)
   1648 				MilterMaxDataSize = MILTER_MDS_64K;
   1649 			else if (MilterMaxDataSize < MILTER_MDS_256K)
   1650 				MilterMaxDataSize = MILTER_MDS_256K;
   1651 			else
   1652 				MilterMaxDataSize = MILTER_MDS_1M;
   1653 		}
   1654 #  endif /* _FFR_MDS_NEGOTIATE */
   1655 		break;
   1656 # endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */
   1657 
   1658 	  case MO_MACROS_CONNECT:
   1659 		if (macros == NULL)
   1660 			macros = MilterConnectMacros;
   1661 		/* FALLTHROUGH */
   1662 
   1663 	  case MO_MACROS_HELO:
   1664 		if (macros == NULL)
   1665 			macros = MilterHeloMacros;
   1666 		/* FALLTHROUGH */
   1667 
   1668 	  case MO_MACROS_ENVFROM:
   1669 		if (macros == NULL)
   1670 			macros = MilterEnvFromMacros;
   1671 		/* FALLTHROUGH */
   1672 
   1673 	  case MO_MACROS_ENVRCPT:
   1674 		if (macros == NULL)
   1675 			macros = MilterEnvRcptMacros;
   1676 		/* FALLTHROUGH */
   1677 
   1678 	  case MO_MACROS_EOH:
   1679 		if (macros == NULL)
   1680 			macros = MilterEOHMacros;
   1681 		/* FALLTHROUGH */
   1682 
   1683 	  case MO_MACROS_EOM:
   1684 		if (macros == NULL)
   1685 			macros = MilterEOMMacros;
   1686 		/* FALLTHROUGH */
   1687 
   1688 	  case MO_MACROS_DATA:
   1689 		if (macros == NULL)
   1690 			macros = MilterDataMacros;
   1691 
   1692 		r = milter_set_macros(name, macros, val, nummac);
   1693 		if (r >= 0)
   1694 			nummac = r;
   1695 		break;
   1696 
   1697 	  default:
   1698 		syserr("milter_set_option: invalid Milter option %s", name);
   1699 		break;
   1700 	}
   1701 	if (sticky)
   1702 		setbitn(mo->mo_code, StickyMilterOpt);
   1703 }
   1704 
   1705 /*
   1706 **  MILTER_REOPEN_DF -- open & truncate the data file (for replbody)
   1707 **
   1708 **	Parameters:
   1709 **		e -- current envelope.
   1710 **
   1711 **	Returns:
   1712 **		0 if succesful, -1 otherwise
   1713 */
   1714 
   1715 static int
   1716 milter_reopen_df(e)
   1717 	ENVELOPE *e;
   1718 {
   1719 	char dfname[MAXPATHLEN];
   1720 
   1721 	(void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname));
   1722 
   1723 	/*
   1724 	**  In SuperSafe == SAFE_REALLY mode, e->e_dfp is a read-only FP so
   1725 	**  close and reopen writable (later close and reopen
   1726 	**  read only again).
   1727 	**
   1728 	**  In SuperSafe != SAFE_REALLY mode, e->e_dfp still points at the
   1729 	**  buffered file I/O descriptor, still open for writing so there
   1730 	**  isn't any work to do here (except checking for consistency).
   1731 	*/
   1732 
   1733 	if (SuperSafe == SAFE_REALLY)
   1734 	{
   1735 		/* close read-only data file */
   1736 		if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL)
   1737 		{
   1738 			(void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
   1739 			e->e_flags &= ~EF_HAS_DF;
   1740 		}
   1741 
   1742 		/* open writable */
   1743 		if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
   1744 					   SM_IO_RDWR_B, NULL)) == NULL)
   1745 		{
   1746 			MILTER_DF_ERROR("milter_reopen_df: sm_io_open %s: %s");
   1747 			return -1;
   1748 		}
   1749 	}
   1750 	else if (e->e_dfp == NULL)
   1751 	{
   1752 		/* shouldn't happen */
   1753 		errno = ENOENT;
   1754 		MILTER_DF_ERROR("milter_reopen_df: NULL e_dfp (%s: %s)");
   1755 		return -1;
   1756 	}
   1757 	return 0;
   1758 }
   1759 
   1760 /*
   1761 **  MILTER_RESET_DF -- re-open read-only the data file (for replbody)
   1762 **
   1763 **	Parameters:
   1764 **		e -- current envelope.
   1765 **
   1766 **	Returns:
   1767 **		0 if succesful, -1 otherwise
   1768 */
   1769 
   1770 static int
   1771 milter_reset_df(e)
   1772 	ENVELOPE *e;
   1773 {
   1774 	int afd;
   1775 	char dfname[MAXPATHLEN];
   1776 
   1777 	(void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname));
   1778 
   1779 	if (sm_io_flush(e->e_dfp, SM_TIME_DEFAULT) != 0 ||
   1780 	    sm_io_error(e->e_dfp))
   1781 	{
   1782 		MILTER_DF_ERROR("milter_reset_df: error writing/flushing %s: %s");
   1783 		return -1;
   1784 	}
   1785 	else if (SuperSafe != SAFE_REALLY)
   1786 	{
   1787 		/* skip next few clauses */
   1788 		/* EMPTY */
   1789 	}
   1790 	else if ((afd = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_FD, NULL)) >= 0
   1791 		 && fsync(afd) < 0)
   1792 	{
   1793 		MILTER_DF_ERROR("milter_reset_df: error sync'ing %s: %s");
   1794 		return -1;
   1795 	}
   1796 	else if (sm_io_close(e->e_dfp, SM_TIME_DEFAULT) < 0)
   1797 	{
   1798 		MILTER_DF_ERROR("milter_reset_df: error closing %s: %s");
   1799 		return -1;
   1800 	}
   1801 	else if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
   1802 					SM_IO_RDONLY_B, NULL)) == NULL)
   1803 	{
   1804 		MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s");
   1805 		return -1;
   1806 	}
   1807 	else
   1808 		e->e_flags |= EF_HAS_DF;
   1809 	return 0;
   1810 }
   1811 
   1812 /*
   1813 **  MILTER_QUIT_FILTER -- close down a single filter
   1814 **
   1815 **	Parameters:
   1816 **		m -- milter structure of filter to close down.
   1817 **		e -- current envelope.
   1818 **
   1819 **	Returns:
   1820 **		none
   1821 */
   1822 
   1823 static void
   1824 milter_quit_filter(m, e)
   1825 	struct milter *m;
   1826 	ENVELOPE *e;
   1827 {
   1828 	if (tTd(64, 10))
   1829 		sm_dprintf("milter_quit_filter(%s)\n", m->mf_name);
   1830 	if (MilterLogLevel > 18)
   1831 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): quit filter",
   1832 			  m->mf_name);
   1833 
   1834 	/* Never replace error state */
   1835 	if (m->mf_state == SMFS_ERROR)
   1836 		return;
   1837 
   1838 	if (m->mf_sock < 0 ||
   1839 	    m->mf_state == SMFS_CLOSED ||
   1840 	    m->mf_state == SMFS_READY)
   1841 	{
   1842 		m->mf_sock = -1;
   1843 		m->mf_state = SMFS_CLOSED;
   1844 		return;
   1845 	}
   1846 
   1847 	(void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0,
   1848 			    m->mf_timeout[SMFTO_WRITE], e, "quit_filter");
   1849 	if (m->mf_sock >= 0)
   1850 	{
   1851 		(void) close(m->mf_sock);
   1852 		m->mf_sock = -1;
   1853 	}
   1854 	if (m->mf_state != SMFS_ERROR)
   1855 		m->mf_state = SMFS_CLOSED;
   1856 }
   1857 
   1858 /*
   1859 **  MILTER_ABORT_FILTER -- tell filter to abort current message
   1860 **
   1861 **	Parameters:
   1862 **		m -- milter structure of filter to abort.
   1863 **		e -- current envelope.
   1864 **
   1865 **	Returns:
   1866 **		none
   1867 */
   1868 
   1869 static void
   1870 milter_abort_filter(m, e)
   1871 	struct milter *m;
   1872 	ENVELOPE *e;
   1873 {
   1874 	if (tTd(64, 10))
   1875 		sm_dprintf("milter_abort_filter(%s)\n", m->mf_name);
   1876 	if (MilterLogLevel > 10)
   1877 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): abort filter",
   1878 			  m->mf_name);
   1879 
   1880 	if (m->mf_sock < 0 ||
   1881 	    m->mf_state != SMFS_INMSG)
   1882 		return;
   1883 
   1884 	(void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0,
   1885 			    m->mf_timeout[SMFTO_WRITE], e, "abort_filter");
   1886 	if (m->mf_state != SMFS_ERROR)
   1887 		m->mf_state = SMFS_DONE;
   1888 }
   1889 
   1890 /*
   1891 **  MILTER_SEND_MACROS -- provide macros to the filters
   1892 **
   1893 **	Parameters:
   1894 **		m -- milter to send macros to.
   1895 **		macros -- macros to send for filter smfi_getsymval().
   1896 **		cmd -- which command the macros are associated with.
   1897 **		e -- current envelope (for macro access).
   1898 **
   1899 **	Returns:
   1900 **		none
   1901 */
   1902 
   1903 static void
   1904 milter_send_macros(m, macros, cmd, e)
   1905 	struct milter *m;
   1906 	char **macros;
   1907 	int cmd;
   1908 	ENVELOPE *e;
   1909 {
   1910 	int i;
   1911 	int mid;
   1912 	char command = (char) cmd;
   1913 	char *v;
   1914 	char *buf, *bp;
   1915 	char exp[MAXLINE];
   1916 	ssize_t s;
   1917 
   1918 	/* sanity check */
   1919 	if (macros == NULL || macros[0] == NULL)
   1920 		return;
   1921 
   1922 	/* put together data */
   1923 	s = 1;			/* for the command character */
   1924 	for (i = 0; macros[i] != NULL; i++)
   1925 	{
   1926 		mid = macid(macros[i]);
   1927 		if (mid == 0)
   1928 			continue;
   1929 		v = macvalue(mid, e);
   1930 		if (v == NULL)
   1931 			continue;
   1932 		expand(v, exp, sizeof(exp), e);
   1933 		s += strlen(macros[i]) + 1 + strlen(exp) + 1;
   1934 	}
   1935 
   1936 	if (s < 0)
   1937 		return;
   1938 
   1939 	buf = (char *) xalloc(s);
   1940 	bp = buf;
   1941 	*bp++ = command;
   1942 	for (i = 0; macros[i] != NULL; i++)
   1943 	{
   1944 		mid = macid(macros[i]);
   1945 		if (mid == 0)
   1946 			continue;
   1947 		v = macvalue(mid, e);
   1948 		if (v == NULL)
   1949 			continue;
   1950 		expand(v, exp, sizeof(exp), e);
   1951 
   1952 		if (tTd(64, 10))
   1953 			sm_dprintf("milter_send_macros(%s, %c): %s=%s\n",
   1954 				m->mf_name, command, macros[i], exp);
   1955 
   1956 		(void) sm_strlcpy(bp, macros[i], s - (bp - buf));
   1957 		bp += strlen(bp) + 1;
   1958 		(void) sm_strlcpy(bp, exp, s - (bp - buf));
   1959 		bp += strlen(bp) + 1;
   1960 	}
   1961 	(void) milter_write(m, SMFIC_MACRO, buf, s,
   1962 			    m->mf_timeout[SMFTO_WRITE], e, "send_macros");
   1963 	sm_free(buf);
   1964 }
   1965 
   1966 /*
   1967 **  MILTER_SEND_COMMAND -- send a command and return the response for a filter
   1968 **
   1969 **	Parameters:
   1970 **		m -- current milter filter
   1971 **		cmd -- command to send.
   1972 **		data -- optional command data.
   1973 **		sz -- length of buf.
   1974 **		e -- current envelope (for e->e_id).
   1975 **		state -- return state word.
   1976 **
   1977 **	Returns:
   1978 **		response string (may be NULL)
   1979 */
   1980 
   1981 static char *
   1982 milter_send_command(m, cmd, data, sz, e, state, where)
   1983 	struct milter *m;
   1984 	int cmd;
   1985 	void *data;
   1986 	ssize_t sz;
   1987 	ENVELOPE *e;
   1988 	char *state;
   1989 	const char *where;
   1990 {
   1991 	char rcmd;
   1992 	ssize_t rlen;
   1993 	unsigned long skipflag;
   1994 	unsigned long norespflag = 0;
   1995 	char command = (char) cmd;
   1996 	char *action;
   1997 	char *defresponse;
   1998 	char *response;
   1999 
   2000 	if (tTd(64, 10))
   2001 		sm_dprintf("milter_send_command(%s): cmd %c len %ld\n",
   2002 			m->mf_name, (char) command, (long) sz);
   2003 
   2004 	/* find skip flag and default failure */
   2005 	switch (command)
   2006 	{
   2007 	  case SMFIC_CONNECT:
   2008 		skipflag = SMFIP_NOCONNECT;
   2009 		norespflag = SMFIP_NR_CONN;
   2010 		action = "connect";
   2011 		defresponse = "554 Command rejected";
   2012 		break;
   2013 
   2014 	  case SMFIC_HELO:
   2015 		skipflag = SMFIP_NOHELO;
   2016 		norespflag = SMFIP_NR_HELO;
   2017 		action = "helo";
   2018 		defresponse = "550 Command rejected";
   2019 		break;
   2020 
   2021 	  case SMFIC_MAIL:
   2022 		skipflag = SMFIP_NOMAIL;
   2023 		norespflag = SMFIP_NR_MAIL;
   2024 		action = "mail";
   2025 		defresponse = "550 5.7.1 Command rejected";
   2026 		break;
   2027 
   2028 	  case SMFIC_RCPT:
   2029 		skipflag = SMFIP_NORCPT;
   2030 		norespflag = SMFIP_NR_RCPT;
   2031 		action = "rcpt";
   2032 		defresponse = "550 5.7.1 Command rejected";
   2033 		break;
   2034 
   2035 	  case SMFIC_HEADER:
   2036 		skipflag = SMFIP_NOHDRS;
   2037 		norespflag = SMFIP_NR_HDR;
   2038 		action = "header";
   2039 		defresponse = "550 5.7.1 Command rejected";
   2040 		break;
   2041 
   2042 	  case SMFIC_BODY:
   2043 		skipflag = SMFIP_NOBODY;
   2044 		norespflag = SMFIP_NR_BODY;
   2045 		action = "body";
   2046 		defresponse = "554 5.7.1 Command rejected";
   2047 		break;
   2048 
   2049 	  case SMFIC_EOH:
   2050 		skipflag = SMFIP_NOEOH;
   2051 		norespflag = SMFIP_NR_EOH;
   2052 		action = "eoh";
   2053 		defresponse = "550 5.7.1 Command rejected";
   2054 		break;
   2055 
   2056 	  case SMFIC_UNKNOWN:
   2057 		skipflag = SMFIP_NOUNKNOWN;
   2058 		norespflag = SMFIP_NR_UNKN;
   2059 		action = "unknown";
   2060 		defresponse = "550 5.7.1 Command rejected";
   2061 		break;
   2062 
   2063 	  case SMFIC_DATA:
   2064 		skipflag = SMFIP_NODATA;
   2065 		norespflag = SMFIP_NR_DATA;
   2066 		action = "data";
   2067 		defresponse = "550 5.7.1 Command rejected";
   2068 		break;
   2069 
   2070 	  case SMFIC_BODYEOB:
   2071 	  case SMFIC_OPTNEG:
   2072 	  case SMFIC_MACRO:
   2073 	  case SMFIC_ABORT:
   2074 	  case SMFIC_QUIT:
   2075 		/* NOTE: not handled by milter_send_command() */
   2076 		/* FALLTHROUGH */
   2077 
   2078 	  default:
   2079 		skipflag = 0;
   2080 		action = "default";
   2081 		defresponse = "550 5.7.1 Command rejected";
   2082 		break;
   2083 	}
   2084 
   2085 	if (tTd(64, 10))
   2086 		sm_dprintf("milter_send_command(%s): skip=%lx, pflags=%x\n",
   2087 			m->mf_name, skipflag, m->mf_pflags);
   2088 
   2089 	/* check if filter wants this command */
   2090 	if (skipflag != 0 && bitset(skipflag, m->mf_pflags))
   2091 		return NULL;
   2092 
   2093 	/* send the command to the filter */
   2094 	(void) milter_write(m, command, data, sz,
   2095 			    m->mf_timeout[SMFTO_WRITE], e, where);
   2096 	if (m->mf_state == SMFS_ERROR)
   2097 	{
   2098 		MILTER_CHECK_ERROR(false, return NULL);
   2099 		return NULL;
   2100 	}
   2101 
   2102 	/* check if filter sends response to this command */
   2103 	if (norespflag != 0 && bitset(norespflag, m->mf_pflags))
   2104 		return NULL;
   2105 
   2106 	/* get the response from the filter */
   2107 	response = milter_read(m, &rcmd, &rlen,
   2108 			       m->mf_timeout[SMFTO_READ], e, where);
   2109 	if (m->mf_state == SMFS_ERROR)
   2110 	{
   2111 		MILTER_CHECK_ERROR(false, return NULL);
   2112 		return NULL;
   2113 	}
   2114 
   2115 	if (tTd(64, 10))
   2116 		sm_dprintf("milter_send_command(%s): returned %c\n",
   2117 			   m->mf_name, (char) rcmd);
   2118 
   2119 	switch (rcmd)
   2120 	{
   2121 	  case SMFIR_REPLYCODE:
   2122 		MILTER_CHECK_REPLYCODE(defresponse);
   2123 		if (MilterLogLevel > 10)
   2124 			sm_syslog(LOG_INFO, e->e_id,
   2125 				  "milter=%s, action=%s, reject=%s",
   2126 				  m->mf_name, action, response);
   2127 		*state = rcmd;
   2128 		break;
   2129 
   2130 	  case SMFIR_REJECT:
   2131 		if (MilterLogLevel > 10)
   2132 			sm_syslog(LOG_INFO, e->e_id,
   2133 				  "milter=%s, action=%s, reject",
   2134 				  m->mf_name, action);
   2135 		*state = rcmd;
   2136 		break;
   2137 
   2138 	  case SMFIR_DISCARD:
   2139 		if (MilterLogLevel > 10)
   2140 			sm_syslog(LOG_INFO, e->e_id,
   2141 				  "milter=%s, action=%s, discard",
   2142 				  m->mf_name, action);
   2143 		*state = rcmd;
   2144 		break;
   2145 
   2146 	  case SMFIR_TEMPFAIL:
   2147 		if (MilterLogLevel > 10)
   2148 			sm_syslog(LOG_INFO, e->e_id,
   2149 				  "milter=%s, action=%s, tempfail",
   2150 				  m->mf_name, action);
   2151 		*state = rcmd;
   2152 		break;
   2153 
   2154 	  case SMFIR_ACCEPT:
   2155 		/* this filter is done with message/connection */
   2156 		if (command == SMFIC_HELO ||
   2157 		    command == SMFIC_CONNECT)
   2158 			m->mf_state = SMFS_CLOSABLE;
   2159 		else
   2160 			m->mf_state = SMFS_DONE;
   2161 		if (MilterLogLevel > 10)
   2162 			sm_syslog(LOG_INFO, e->e_id,
   2163 				  "milter=%s, action=%s, accepted",
   2164 				  m->mf_name, action);
   2165 		break;
   2166 
   2167 	  case SMFIR_CONTINUE:
   2168 		/* if MAIL command is ok, filter is in message state */
   2169 		if (command == SMFIC_MAIL)
   2170 			m->mf_state = SMFS_INMSG;
   2171 		if (MilterLogLevel > 12)
   2172 			sm_syslog(LOG_INFO, e->e_id,
   2173 				  "milter=%s, action=%s, continue",
   2174 				  m->mf_name, action);
   2175 		break;
   2176 
   2177 	  case SMFIR_SKIP:
   2178 		if (MilterLogLevel > 12)
   2179 			sm_syslog(LOG_INFO, e->e_id,
   2180 				  "milter=%s, action=%s, skip",
   2181 				  m->mf_name, action);
   2182 		m->mf_state = SMFS_SKIP;
   2183 		break;
   2184 
   2185 	  default:
   2186 		/* Invalid response to command */
   2187 		if (MilterLogLevel > 0)
   2188 			sm_syslog(LOG_ERR, e->e_id,
   2189 				  "milter_send_command(%s): action=%s returned bogus response %c",
   2190 				  m->mf_name, action, rcmd);
   2191 		milter_error(m, e);
   2192 		break;
   2193 	}
   2194 
   2195 	if (*state != SMFIR_REPLYCODE && response != NULL)
   2196 	{
   2197 		sm_free(response); /* XXX */
   2198 		response = NULL;
   2199 	}
   2200 	return response;
   2201 }
   2202 
   2203 /*
   2204 **  MILTER_COMMAND -- send a command and return the response for each filter
   2205 **
   2206 **	Parameters:
   2207 **		cmd -- command to send.
   2208 **		data -- optional command data.
   2209 **		sz -- length of buf.
   2210 **		macros -- macros to send for filter smfi_getsymval().
   2211 **		e -- current envelope (for macro access).
   2212 **		state -- return state word.
   2213 **		where -- description of calling function (logging).
   2214 **		cmd_error -- did the SMTP command cause an error?
   2215 **
   2216 **	Returns:
   2217 **		response string (may be NULL)
   2218 */
   2219 
   2220 static char *
   2221 milter_command(cmd, data, sz, macros, e, state, where, cmd_error)
   2222 	int cmd;
   2223 	void *data;
   2224 	ssize_t sz;
   2225 	char **macros;
   2226 	ENVELOPE *e;
   2227 	char *state;
   2228 	const char *where;
   2229 	bool cmd_error;
   2230 {
   2231 	int i;
   2232 	char command = (char) cmd;
   2233 	char *response = NULL;
   2234 	time_t tn = 0;
   2235 
   2236 	if (tTd(64, 10))
   2237 		sm_dprintf("milter_command: cmd %c len %ld\n",
   2238 			command, (long) sz);
   2239 
   2240 	*state = SMFIR_CONTINUE;
   2241 	for (i = 0; InputFilters[i] != NULL; i++)
   2242 	{
   2243 		struct milter *m = InputFilters[i];
   2244 
   2245 		/* previous problem? */
   2246 		if (m->mf_state == SMFS_ERROR)
   2247 		{
   2248 			MILTER_CHECK_ERROR(false, continue);
   2249 			break;
   2250 		}
   2251 
   2252 		/* sanity check */
   2253 		if (m->mf_sock < 0 ||
   2254 		    (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
   2255 			continue;
   2256 
   2257 		/* send macros (regardless of whether we send command) */
   2258 		if (macros != NULL && macros[0] != NULL)
   2259 		{
   2260 			milter_send_macros(m, macros, command, e);
   2261 			if (m->mf_state == SMFS_ERROR)
   2262 			{
   2263 				MILTER_CHECK_ERROR(false, continue);
   2264 				break;
   2265 			}
   2266 		}
   2267 
   2268 		if (MilterLogLevel > 21)
   2269 			tn = curtime();
   2270 
   2271 		/*
   2272 		**  send the command if
   2273 		**	there is no error
   2274 		**	or it's RCPT and the client asked for it:
   2275 		**	!cmd_error ||
   2276 		**	where == "rcpt" && m->mf_pflags & SMFIP_RCPT_REJ != 0
   2277 		**  negate that condition and use continue
   2278 		*/
   2279 
   2280 		if (cmd_error &&
   2281 		    (strcmp(where, "rcpt") != 0 ||
   2282 		     (m->mf_pflags & SMFIP_RCPT_REJ) == 0))
   2283 			continue;
   2284 
   2285 		response = milter_send_command(m, command, data, sz, e, state,
   2286 						where);
   2287 
   2288 		if (MilterLogLevel > 21)
   2289 		{
   2290 			/* log the time it took for the command per filter */
   2291 			sm_syslog(LOG_INFO, e->e_id,
   2292 				  "Milter (%s): time command (%c), %d",
   2293 				  m->mf_name, command, (int) (tn - curtime()));
   2294 		}
   2295 
   2296 		if (*state != SMFIR_CONTINUE)
   2297 			break;
   2298 	}
   2299 	return response;
   2300 }
   2301 
   2302 static int milter_getsymlist __P((struct milter *, char *, int, int));
   2303 
   2304 static int
   2305 milter_getsymlist(m, buf, rlen, offset)
   2306 	struct milter *m;
   2307 	char *buf;
   2308 	int rlen;
   2309 	int offset;
   2310 {
   2311 	int i, r, nummac;
   2312 	mi_int32 v;
   2313 
   2314 	SM_ASSERT(m != NULL);
   2315 	SM_ASSERT(buf != NULL);
   2316 
   2317 	while (offset + MILTER_LEN_BYTES < rlen)
   2318 	{
   2319 		size_t len;
   2320 		char **macros;
   2321 
   2322 		nummac = 0;
   2323 		(void) memcpy((char *) &v, buf + offset, MILTER_LEN_BYTES);
   2324 		i = ntohl(v);
   2325 		if (i < SMFIM_FIRST || i > SMFIM_LAST)
   2326 			return -1;
   2327 		offset += MILTER_LEN_BYTES;
   2328 		macros = NULL;
   2329 
   2330 		switch (i)
   2331 		{
   2332 		  case MO_MACROS_CONNECT:
   2333 			if (macros == NULL)
   2334 				macros = MilterConnectMacros;
   2335 			/* FALLTHROUGH */
   2336 
   2337 		  case MO_MACROS_HELO:
   2338 			if (macros == NULL)
   2339 				macros = MilterHeloMacros;
   2340 			/* FALLTHROUGH */
   2341 
   2342 		  case MO_MACROS_ENVFROM:
   2343 			if (macros == NULL)
   2344 				macros = MilterEnvFromMacros;
   2345 			/* FALLTHROUGH */
   2346 
   2347 		  case MO_MACROS_ENVRCPT:
   2348 			if (macros == NULL)
   2349 				macros = MilterEnvRcptMacros;
   2350 			/* FALLTHROUGH */
   2351 
   2352 		  case MO_MACROS_EOM:
   2353 			if (macros == NULL)
   2354 				macros = MilterEOMMacros;
   2355 			/* FALLTHROUGH */
   2356 
   2357 		  case MO_MACROS_EOH:
   2358 			if (macros == NULL)
   2359 				macros = MilterEOHMacros;
   2360 			/* FALLTHROUGH */
   2361 
   2362 		  case MO_MACROS_DATA:
   2363 			if (macros == NULL)
   2364 				macros = MilterDataMacros;
   2365 
   2366 			len = strlen(buf + offset);
   2367 			if (len > 0)
   2368 			{
   2369 				r = milter_set_macros(m->mf_name, macros,
   2370 						buf + offset, nummac);
   2371 				if (r >= 0)
   2372 					nummac = r;
   2373 			}
   2374 			break;
   2375 
   2376 		  default:
   2377 			return -1;
   2378 		}
   2379 		if (len == 0)
   2380 			return -1;
   2381 		offset += len + 1;
   2382 	}
   2383 
   2384 	return 0;
   2385 }
   2386 
   2387 /*
   2388 **  MILTER_NEGOTIATE -- get version and flags from filter
   2389 **
   2390 **	Parameters:
   2391 **		m -- milter filter structure.
   2392 **		e -- current envelope.
   2393 **		milters -- milters structure.
   2394 **
   2395 **	Returns:
   2396 **		0 on success, -1 otherwise
   2397 */
   2398 
   2399 static int
   2400 milter_negotiate(m, e, milters)
   2401 	struct milter *m;
   2402 	ENVELOPE *e;
   2403 	milters_T *milters;
   2404 {
   2405 	char rcmd;
   2406 	mi_int32 fvers, fflags, pflags;
   2407 	mi_int32 mta_prot_vers, mta_prot_flags, mta_actions;
   2408 	ssize_t rlen;
   2409 	char *response;
   2410 	char data[MILTER_OPTLEN];
   2411 
   2412 	/* sanity check */
   2413 	if (m->mf_sock < 0 || m->mf_state != SMFS_OPEN)
   2414 	{
   2415 		if (MilterLogLevel > 0)
   2416 			sm_syslog(LOG_ERR, e->e_id,
   2417 				  "Milter (%s): negotiate, impossible state",
   2418 				  m->mf_name);
   2419 		milter_error(m, e);
   2420 		return -1;
   2421 	}
   2422 
   2423 #if _FFR_MILTER_CHECK
   2424 	mta_prot_vers = m->mf_mta_prot_version;
   2425 	mta_prot_flags = m->mf_mta_prot_flags;
   2426 	mta_actions = m->mf_mta_actions;
   2427 #else /* _FFR_MILTER_CHECK */
   2428 	mta_prot_vers = SMFI_PROT_VERSION;
   2429 	mta_prot_flags = SMFI_CURR_PROT;
   2430 	mta_actions = SMFI_CURR_ACTS;
   2431 #endif /* _FFR_MILTER_CHECK */
   2432 #if _FFR_MDS_NEGOTIATE
   2433 	if (MilterMaxDataSize == MILTER_MDS_256K)
   2434 		mta_prot_flags |= SMFIP_MDS_256K;
   2435 	else if (MilterMaxDataSize == MILTER_MDS_1M)
   2436 		mta_prot_flags |= SMFIP_MDS_1M;
   2437 #endif /* _FFR_MDS_NEGOTIATE */
   2438 
   2439 	fvers = htonl(mta_prot_vers);
   2440 	pflags = htonl(mta_prot_flags);
   2441 	fflags = htonl(mta_actions);
   2442 	(void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES);
   2443 	(void) memcpy(data + MILTER_LEN_BYTES,
   2444 		      (char *) &fflags, MILTER_LEN_BYTES);
   2445 	(void) memcpy(data + (MILTER_LEN_BYTES * 2),
   2446 		      (char *) &pflags, MILTER_LEN_BYTES);
   2447 	(void) milter_write(m, SMFIC_OPTNEG, data, sizeof(data),
   2448 			    m->mf_timeout[SMFTO_WRITE], e, "negotiate");
   2449 
   2450 	if (m->mf_state == SMFS_ERROR)
   2451 		return -1;
   2452 
   2453 	if (tTd(64, 5))
   2454 		sm_dprintf("milter_negotiate(%s): send: version %lu, fflags 0x%lx, pflags 0x%lx\n",
   2455 			m->mf_name, ntohl(fvers), ntohl(fflags), ntohl(pflags));
   2456 
   2457 	response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e,
   2458 				"negotiate");
   2459 	if (m->mf_state == SMFS_ERROR)
   2460 		return -1;
   2461 
   2462 	if (rcmd != SMFIC_OPTNEG)
   2463 	{
   2464 		if (tTd(64, 5))
   2465 			sm_dprintf("milter_negotiate(%s): returned %c instead of %c\n",
   2466 				m->mf_name, rcmd, SMFIC_OPTNEG);
   2467 		if (MilterLogLevel > 0)
   2468 			sm_syslog(LOG_ERR, e->e_id,
   2469 				  "Milter (%s): negotiate: returned %c instead of %c",
   2470 				  m->mf_name, rcmd, SMFIC_OPTNEG);
   2471 		if (response != NULL)
   2472 			sm_free(response); /* XXX */
   2473 		milter_error(m, e);
   2474 		return -1;
   2475 	}
   2476 
   2477 	/* Make sure we have enough bytes for the version */
   2478 	if (response == NULL || rlen < MILTER_LEN_BYTES)
   2479 	{
   2480 		if (tTd(64, 5))
   2481 			sm_dprintf("milter_negotiate(%s): did not return valid info\n",
   2482 				m->mf_name);
   2483 		if (MilterLogLevel > 0)
   2484 			sm_syslog(LOG_ERR, e->e_id,
   2485 				  "Milter (%s): negotiate: did not return valid info",
   2486 				  m->mf_name);
   2487 		if (response != NULL)
   2488 			sm_free(response); /* XXX */
   2489 		milter_error(m, e);
   2490 		return -1;
   2491 	}
   2492 
   2493 	/* extract information */
   2494 	(void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES);
   2495 
   2496 	/* Now make sure we have enough for the feature bitmap */
   2497 	if (rlen < MILTER_OPTLEN)
   2498 	{
   2499 		if (tTd(64, 5))
   2500 			sm_dprintf("milter_negotiate(%s): did not return enough info\n",
   2501 				m->mf_name);
   2502 		if (MilterLogLevel > 0)
   2503 			sm_syslog(LOG_ERR, e->e_id,
   2504 				  "Milter (%s): negotiate: did not return enough info",
   2505 				  m->mf_name);
   2506 		if (response != NULL)
   2507 			sm_free(response); /* XXX */
   2508 		milter_error(m, e);
   2509 		return -1;
   2510 	}
   2511 
   2512 	(void) memcpy((char *) &fflags, response + MILTER_LEN_BYTES,
   2513 		      MILTER_LEN_BYTES);
   2514 	(void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2),
   2515 		      MILTER_LEN_BYTES);
   2516 
   2517 	m->mf_fvers = ntohl(fvers);
   2518 	m->mf_fflags = ntohl(fflags);
   2519 	m->mf_pflags = ntohl(pflags);
   2520 
   2521 	/* check for version compatibility */
   2522 	if (m->mf_fvers == 1 ||
   2523 	    m->mf_fvers > SMFI_VERSION)
   2524 	{
   2525 		if (tTd(64, 5))
   2526 			sm_dprintf("milter_negotiate(%s): version %d != MTA milter version %d\n",
   2527 				m->mf_name, m->mf_fvers, SMFI_VERSION);
   2528 		if (MilterLogLevel > 0)
   2529 			sm_syslog(LOG_ERR, e->e_id,
   2530 				  "Milter (%s): negotiate: version %d != MTA milter version %d",
   2531 				  m->mf_name, m->mf_fvers, SMFI_VERSION);
   2532 		milter_error(m, e);
   2533 		goto error;
   2534 	}
   2535 
   2536 	/* check for filter feature mismatch */
   2537 	if ((m->mf_fflags & mta_actions) != m->mf_fflags)
   2538 	{
   2539 		if (tTd(64, 5))
   2540 			sm_dprintf("milter_negotiate(%s): filter abilities 0x%x != MTA milter abilities 0x%lx\n",
   2541 				m->mf_name, m->mf_fflags,
   2542 				(unsigned long) mta_actions);
   2543 		if (MilterLogLevel > 0)
   2544 			sm_syslog(LOG_ERR, e->e_id,
   2545 				  "Milter (%s): negotiate: filter abilities 0x%x != MTA milter abilities 0x%lx",
   2546 				  m->mf_name, m->mf_fflags,
   2547 				  (unsigned long) mta_actions);
   2548 		milter_error(m, e);
   2549 		goto error;
   2550 	}
   2551 
   2552 #if _FFR_MDS_NEGOTIATE
   2553 	/* use a table instead of sequence? */
   2554 	if (bitset(SMFIP_MDS_1M, m->mf_pflags))
   2555 	{
   2556 		if (MilterMaxDataSize != MILTER_MDS_1M)
   2557 		{
   2558 			/* this should not happen... */
   2559 			sm_syslog(LOG_WARNING, NOQID,
   2560 				  "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d",
   2561 		    		  MilterMaxDataSize, MILTER_MDS_1M);
   2562 			MilterMaxDataSize = MILTER_MDS_1M;
   2563 		}
   2564 	}
   2565 	else if (bitset(SMFIP_MDS_256K, m->mf_pflags))
   2566 	{
   2567 		if (MilterMaxDataSize != MILTER_MDS_256K)
   2568 		{
   2569 			sm_syslog(LOG_WARNING, NOQID,
   2570 				  "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d",
   2571 		    		  MilterMaxDataSize, MILTER_MDS_256K);
   2572 			MilterMaxDataSize = MILTER_MDS_256K;
   2573 		}
   2574 	}
   2575 	else if (MilterMaxDataSize != MILTER_MDS_64K)
   2576 	{
   2577 		sm_syslog(LOG_WARNING, NOQID,
   2578 			  "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d",
   2579 	    		  MilterMaxDataSize, MILTER_MDS_64K);
   2580 		MilterMaxDataSize = MILTER_MDS_64K;
   2581 	}
   2582 	m->mf_pflags &= ~SMFI_INTERNAL;
   2583 #endif /* _FFR_MDS_NEGOTIATE */
   2584 
   2585 	/* check for protocol feature mismatch */
   2586 	if ((m->mf_pflags & mta_prot_flags) != m->mf_pflags)
   2587 	{
   2588 		if (tTd(64, 5))
   2589 			sm_dprintf("milter_negotiate(%s): protocol abilities 0x%x != MTA milter abilities 0x%lx\n",
   2590 				m->mf_name, m->mf_pflags,
   2591 				(unsigned long) mta_prot_flags);
   2592 		if (MilterLogLevel > 0)
   2593 			sm_syslog(LOG_ERR, e->e_id,
   2594 				  "Milter (%s): negotiate: protocol abilities 0x%x != MTA milter abilities 0x%lx",
   2595 				  m->mf_name, m->mf_pflags,
   2596 				  (unsigned long) mta_prot_flags);
   2597 		milter_error(m, e);
   2598 		goto error;
   2599 	}
   2600 
   2601 	if (m->mf_fvers <= 2)
   2602 		m->mf_pflags |= SMFIP_NOUNKNOWN;
   2603 	if (m->mf_fvers <= 3)
   2604 		m->mf_pflags |= SMFIP_NODATA;
   2605 
   2606 	if (rlen > MILTER_OPTLEN)
   2607 	{
   2608 		milter_getsymlist(m, response, rlen, MILTER_OPTLEN);
   2609 	}
   2610 
   2611 	if (bitset(SMFIF_DELRCPT, m->mf_fflags))
   2612 		milters->mis_flags |= MIS_FL_DEL_RCPT;
   2613 	if (!bitset(SMFIP_NORCPT, m->mf_pflags) &&
   2614 	    !bitset(SMFIP_NR_RCPT, m->mf_pflags))
   2615 		milters->mis_flags |= MIS_FL_REJ_RCPT;
   2616 
   2617 	if (tTd(64, 5))
   2618 		sm_dprintf("milter_negotiate(%s): received: version %u, fflags 0x%x, pflags 0x%x\n",
   2619 			m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags);
   2620 	return 0;
   2621 
   2622   error:
   2623 	if (response != NULL)
   2624 		sm_free(response); /* XXX */
   2625 	return -1;
   2626 }
   2627 
   2628 /*
   2629 **  MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands
   2630 **
   2631 **	Reduce code duplication by putting these checks in one place
   2632 **
   2633 **	Parameters:
   2634 **		e -- current envelope.
   2635 **
   2636 **	Returns:
   2637 **		none
   2638 */
   2639 
   2640 static void
   2641 milter_per_connection_check(e)
   2642 	ENVELOPE *e;
   2643 {
   2644 	int i;
   2645 
   2646 	/* see if we are done with any of the filters */
   2647 	for (i = 0; InputFilters[i] != NULL; i++)
   2648 	{
   2649 		struct milter *m = InputFilters[i];
   2650 
   2651 		if (m->mf_state == SMFS_CLOSABLE)
   2652 			milter_quit_filter(m, e);
   2653 	}
   2654 }
   2655 
   2656 /*
   2657 **  MILTER_ERROR -- Put a milter filter into error state
   2658 **
   2659 **	Parameters:
   2660 **		m -- the broken filter.
   2661 **		e -- current envelope.
   2662 **
   2663 **	Returns:
   2664 **		none
   2665 */
   2666 
   2667 static void
   2668 milter_error(m, e)
   2669 	struct milter *m;
   2670 	ENVELOPE *e;
   2671 {
   2672 	/*
   2673 	**  We could send a quit here but we may have gotten here due to
   2674 	**  an I/O error so we don't want to try to make things worse.
   2675 	*/
   2676 
   2677 	if (m->mf_sock >= 0)
   2678 	{
   2679 		(void) close(m->mf_sock);
   2680 		m->mf_sock = -1;
   2681 	}
   2682 	m->mf_state = SMFS_ERROR;
   2683 
   2684 	if (MilterLogLevel > 0)
   2685 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): to error state",
   2686 			  m->mf_name);
   2687 }
   2688 
   2689 /*
   2690 **  MILTER_HEADERS -- send headers to a single milter filter
   2691 **
   2692 **	Parameters:
   2693 **		m -- current filter.
   2694 **		e -- current envelope.
   2695 **		state -- return state from response.
   2696 **
   2697 **	Returns:
   2698 **		response string (may be NULL)
   2699 */
   2700 
   2701 static char *
   2702 milter_headers(m, e, state)
   2703 	struct milter *m;
   2704 	ENVELOPE *e;
   2705 	char *state;
   2706 {
   2707 	char *response = NULL;
   2708 	HDR *h;
   2709 
   2710 	if (MilterLogLevel > 17)
   2711 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, send",
   2712 			  m->mf_name);
   2713 
   2714 	for (h = e->e_header; h != NULL; h = h->h_link)
   2715 	{
   2716 		int len_n, len_v, len_t, len_f;
   2717 		char *buf, *hv;
   2718 
   2719 		/* don't send over deleted headers */
   2720 		if (h->h_value == NULL)
   2721 		{
   2722 			/* strip H_USER so not counted in milter_changeheader() */
   2723 			h->h_flags &= ~H_USER;
   2724 			continue;
   2725 		}
   2726 
   2727 		/* skip auto-generated */
   2728 		if (!bitset(H_USER, h->h_flags))
   2729 			continue;
   2730 
   2731 		if (tTd(64, 10))
   2732 			sm_dprintf("milter_headers: %s:%s\n",
   2733 				h->h_field, h->h_value);
   2734 		if (MilterLogLevel > 21)
   2735 			sm_syslog(LOG_INFO, e->e_id, "Milter (%s): header, %s",
   2736 				  m->mf_name, h->h_field);
   2737 
   2738 		if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)
   2739 		    || *(h->h_value) != ' ')
   2740 			hv = h->h_value;
   2741 		else
   2742 			hv = h->h_value + 1;
   2743 		len_f = strlen(h->h_field) + 1;
   2744 		len_t = len_f + strlen(hv) + 1;
   2745 		if (len_t < 0)
   2746 			continue;
   2747 		buf = (char *) xalloc(len_t);
   2748 
   2749 		/*
   2750 		**  Note: currently the call to dequote_internal_chars()
   2751 		**  is not required as h_field is supposed to be 7-bit US-ASCII.
   2752 		*/
   2753 
   2754 		len_n = dequote_internal_chars(h->h_field, buf, len_f);
   2755 		SM_ASSERT(len_n < len_f);
   2756 		len_v = dequote_internal_chars(hv, buf + len_n + 1,
   2757 						len_t - len_n - 1);
   2758 		SM_ASSERT(len_t >= len_n + 1 + len_v + 1);
   2759 		len_t = len_n + 1 + len_v + 1;
   2760 
   2761 		/* send it over */
   2762 		response = milter_send_command(m, SMFIC_HEADER, buf,
   2763 					       len_t, e, state, "header");
   2764 		sm_free(buf);
   2765 		if (m->mf_state == SMFS_ERROR ||
   2766 		    m->mf_state == SMFS_DONE ||
   2767 		    *state != SMFIR_CONTINUE)
   2768 			break;
   2769 	}
   2770 	if (MilterLogLevel > 17)
   2771 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, sent",
   2772 			  m->mf_name);
   2773 	return response;
   2774 }
   2775 
   2776 /*
   2777 **  MILTER_BODY -- send the body to a filter
   2778 **
   2779 **	Parameters:
   2780 **		m -- current filter.
   2781 **		e -- current envelope.
   2782 **		state -- return state from response.
   2783 **
   2784 **	Returns:
   2785 **		response string (may be NULL)
   2786 */
   2787 
   2788 static char *
   2789 milter_body(m, e, state)
   2790 	struct milter *m;
   2791 	ENVELOPE *e;
   2792 	char *state;
   2793 {
   2794 	char bufchar = '\0';
   2795 	char prevchar = '\0';
   2796 	int c;
   2797 	char *response = NULL;
   2798 	char *bp;
   2799 	char buf[MILTER_CHUNK_SIZE];
   2800 
   2801 	if (tTd(64, 10))
   2802 		sm_dprintf("milter_body\n");
   2803 
   2804 	if (bfrewind(e->e_dfp) < 0)
   2805 	{
   2806 		ExitStat = EX_IOERR;
   2807 		*state = SMFIR_TEMPFAIL;
   2808 		syserr("milter_body: %s/%cf%s: rewind error",
   2809 		       qid_printqueue(e->e_qgrp, e->e_qdir),
   2810 		       DATAFL_LETTER, e->e_id);
   2811 		return NULL;
   2812 	}
   2813 
   2814 	if (MilterLogLevel > 17)
   2815 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, send",
   2816 			  m->mf_name);
   2817 	bp = buf;
   2818 	while ((c = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT)) != SM_IO_EOF)
   2819 	{
   2820 		/*  Change LF to CRLF */
   2821 		if (c == '\n')
   2822 		{
   2823 #if !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF
   2824 			/* Not a CRLF already? */
   2825 			if (prevchar != '\r')
   2826 #endif /* !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF */
   2827 			{
   2828 				/* Room for CR now? */
   2829 				if (bp + 2 > &buf[sizeof(buf)])
   2830 				{
   2831 					/* No room, buffer LF */
   2832 					bufchar = c;
   2833 
   2834 					/* and send CR now */
   2835 					c = '\r';
   2836 				}
   2837 				else
   2838 				{
   2839 					/* Room to do it now */
   2840 					*bp++ = '\r';
   2841 					prevchar = '\r';
   2842 				}
   2843 			}
   2844 		}
   2845 		*bp++ = (char) c;
   2846 		prevchar = c;
   2847 		if (bp >= &buf[sizeof(buf)])
   2848 		{
   2849 			/* send chunk */
   2850 			response = milter_send_command(m, SMFIC_BODY, buf,
   2851 						       bp - buf, e, state,
   2852 							"body chunk");
   2853 			bp = buf;
   2854 			if (bufchar != '\0')
   2855 			{
   2856 				*bp++ = bufchar;
   2857 				bufchar = '\0';
   2858 				prevchar = bufchar;
   2859 			}
   2860 		}
   2861 		if (m->mf_state == SMFS_ERROR ||
   2862 		    m->mf_state == SMFS_DONE ||
   2863 		    m->mf_state == SMFS_SKIP ||
   2864 		    *state != SMFIR_CONTINUE)
   2865 			break;
   2866 	}
   2867 
   2868 	/* check for read errors */
   2869 	if (sm_io_error(e->e_dfp))
   2870 	{
   2871 		ExitStat = EX_IOERR;
   2872 		if (*state == SMFIR_CONTINUE ||
   2873 		    *state == SMFIR_ACCEPT ||
   2874 		    m->mf_state == SMFS_SKIP)
   2875 		{
   2876 			*state = SMFIR_TEMPFAIL;
   2877 			if (response != NULL)
   2878 			{
   2879 				sm_free(response); /* XXX */
   2880 				response = NULL;
   2881 			}
   2882 		}
   2883 		syserr("milter_body: %s/%cf%s: read error",
   2884 		       qid_printqueue(e->e_qgrp, e->e_qdir),
   2885 		       DATAFL_LETTER, e->e_id);
   2886 		return response;
   2887 	}
   2888 
   2889 	/* send last body chunk */
   2890 	if (bp > buf &&
   2891 	    m->mf_state != SMFS_ERROR &&
   2892 	    m->mf_state != SMFS_DONE &&
   2893 	    m->mf_state != SMFS_SKIP &&
   2894 	    *state == SMFIR_CONTINUE)
   2895 	{
   2896 		/* send chunk */
   2897 		response = milter_send_command(m, SMFIC_BODY, buf, bp - buf,
   2898 					       e, state, "last body chunk");
   2899 		bp = buf;
   2900 	}
   2901 	if (MilterLogLevel > 17)
   2902 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, sent",
   2903 			  m->mf_name);
   2904 	if (m->mf_state == SMFS_SKIP)
   2905 	{
   2906 		*state = SMFIR_CONTINUE;
   2907 		m->mf_state = SMFS_READY;
   2908 	}
   2909 
   2910 	return response;
   2911 }
   2912 
   2913 /*
   2914 **  Actions
   2915 */
   2916 
   2917 /*
   2918 **  ADDLEADINGSPACE -- Add a leading space to a string
   2919 **
   2920 **	Parameters:
   2921 **		str -- string
   2922 **		rp -- resource pool for allocations
   2923 **
   2924 **	Returns:
   2925 **		pointer to new string
   2926 */
   2927 
   2928 static char *addleadingspace __P((char *, SM_RPOOL_T *));
   2929 
   2930 static char *
   2931 addleadingspace(str, rp)
   2932 	char *str;
   2933 	SM_RPOOL_T *rp;
   2934 {
   2935 	size_t l;
   2936 	char *new;
   2937 
   2938 	SM_ASSERT(str != NULL);
   2939 	l = strlen(str);
   2940 	SM_ASSERT(l + 2 > l);
   2941 	new = sm_rpool_malloc_x(rp, l + 2);
   2942 	new[0] = ' ';
   2943 	new[1] = '\0';
   2944 	sm_strlcpy(new + 1, str, l + 1);
   2945 	return new;
   2946 }
   2947 
   2948 /*
   2949 **  MILTER_ADDHEADER -- Add the supplied header to the message
   2950 **
   2951 **	Parameters:
   2952 **		m -- current filter.
   2953 **		response -- encoded form of header/value.
   2954 **		rlen -- length of response.
   2955 **		e -- current envelope.
   2956 **
   2957 **	Returns:
   2958 **		none
   2959 */
   2960 
   2961 static void
   2962 milter_addheader(m, response, rlen, e)
   2963 	struct milter *m;
   2964 	char *response;
   2965 	ssize_t rlen;
   2966 	ENVELOPE *e;
   2967 {
   2968 	int mh_v_len;
   2969 	char *val, *mh_value;
   2970 	HDR *h;
   2971 
   2972 	if (tTd(64, 10))
   2973 		sm_dprintf("milter_addheader: ");
   2974 
   2975 	/* sanity checks */
   2976 	if (response == NULL)
   2977 	{
   2978 		if (tTd(64, 10))
   2979 			sm_dprintf("NULL response\n");
   2980 		return;
   2981 	}
   2982 
   2983 	if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
   2984 	{
   2985 		if (tTd(64, 10))
   2986 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
   2987 				   (int) strlen(response), (int) (rlen - 1));
   2988 		return;
   2989 	}
   2990 
   2991 	/* Find separating NUL */
   2992 	val = response + strlen(response) + 1;
   2993 
   2994 	/* another sanity check */
   2995 	if (strlen(response) + strlen(val) + 2 != (size_t) rlen)
   2996 	{
   2997 		if (tTd(64, 10))
   2998 			sm_dprintf("didn't follow protocol (part len)\n");
   2999 		return;
   3000 	}
   3001 
   3002 	if (*response == '\0')
   3003 	{
   3004 		if (tTd(64, 10))
   3005 			sm_dprintf("empty field name\n");
   3006 		return;
   3007 	}
   3008 
   3009 	for (h = e->e_header; h != NULL; h = h->h_link)
   3010 	{
   3011 		if (sm_strcasecmp(h->h_field, response) == 0 &&
   3012 		    !bitset(H_USER, h->h_flags) &&
   3013 		    !bitset(H_TRACE, h->h_flags))
   3014 			break;
   3015 	}
   3016 
   3017 	mh_v_len = 0;
   3018 	mh_value = quote_internal_chars(val, NULL, &mh_v_len);
   3019 
   3020 	/* add to e_msgsize */
   3021 	e->e_msgsize += strlen(response) + 2 + strlen(val);
   3022 
   3023 	if (h != NULL)
   3024 	{
   3025 		if (tTd(64, 10))
   3026 			sm_dprintf("Replace default header %s value with %s\n",
   3027 				   h->h_field, mh_value);
   3028 		if (MilterLogLevel > 8)
   3029 			sm_syslog(LOG_INFO, e->e_id,
   3030 				  "Milter change: default header %s value with %s",
   3031 				  h->h_field, mh_value);
   3032 		if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags))
   3033 			h->h_value = mh_value;
   3034 		else
   3035 		{
   3036 			h->h_value = addleadingspace(mh_value, e->e_rpool);
   3037 			SM_FREE(mh_value);
   3038 		}
   3039 		h->h_flags |= H_USER;
   3040 	}
   3041 	else
   3042 	{
   3043 		if (tTd(64, 10))
   3044 			sm_dprintf("Add %s: %s\n", response, mh_value);
   3045 		if (MilterLogLevel > 8)
   3046 			sm_syslog(LOG_INFO, e->e_id,
   3047 				  "Milter add: header: %s: %s",
   3048 				  response, mh_value);
   3049 		addheader(newstr(response), mh_value, H_USER, e,
   3050 			!bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
   3051 		SM_FREE(mh_value);
   3052 	}
   3053 }
   3054 
   3055 /*
   3056 **  MILTER_INSHEADER -- Insert the supplied header
   3057 **
   3058 **	Parameters:
   3059 **		m -- current filter.
   3060 **		response -- encoded form of header/value.
   3061 **		rlen -- length of response.
   3062 **		e -- current envelope.
   3063 **
   3064 **	Returns:
   3065 **		none
   3066 **
   3067 **	Notes:
   3068 **		Unlike milter_addheader(), this does not attempt to determine
   3069 **		if the header already exists in the envelope, even a
   3070 **		deleted version.  It just blindly inserts.
   3071 */
   3072 
   3073 static void
   3074 milter_insheader(m, response, rlen, e)
   3075 	struct milter *m;
   3076 	char *response;
   3077 	ssize_t rlen;
   3078 	ENVELOPE *e;
   3079 {
   3080 	mi_int32 idx, i;
   3081 	int mh_v_len;
   3082 	char *field, *val, *mh_value;
   3083 
   3084 	if (tTd(64, 10))
   3085 		sm_dprintf("milter_insheader: ");
   3086 
   3087 	/* sanity checks */
   3088 	if (response == NULL)
   3089 	{
   3090 		if (tTd(64, 10))
   3091 			sm_dprintf("NULL response\n");
   3092 		return;
   3093 	}
   3094 
   3095 	if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
   3096 	{
   3097 		if (tTd(64, 10))
   3098 			sm_dprintf("didn't follow protocol (total len)\n");
   3099 		return;
   3100 	}
   3101 
   3102 	/* decode */
   3103 	(void) memcpy((char *) &i, response, MILTER_LEN_BYTES);
   3104 	idx = ntohl(i);
   3105 	field = response + MILTER_LEN_BYTES;
   3106 	val = field + strlen(field) + 1;
   3107 
   3108 	/* another sanity check */
   3109 	if (MILTER_LEN_BYTES + strlen(field) + 1 +
   3110 	    strlen(val) + 1 != (size_t) rlen)
   3111 	{
   3112 		if (tTd(64, 10))
   3113 			sm_dprintf("didn't follow protocol (part len)\n");
   3114 		return;
   3115 	}
   3116 
   3117 	if (*field == '\0')
   3118 	{
   3119 		if (tTd(64, 10))
   3120 			sm_dprintf("empty field name\n");
   3121 		return;
   3122 	}
   3123 
   3124 	/* add to e_msgsize */
   3125 	e->e_msgsize += strlen(response) + 2 + strlen(val);
   3126 
   3127 	if (tTd(64, 10))
   3128 		sm_dprintf("Insert (%d) %s: %s\n", idx, field, val);
   3129 	if (MilterLogLevel > 8)
   3130 		sm_syslog(LOG_INFO, e->e_id,
   3131 			  "Milter insert (%d): header: %s: %s",
   3132 			  idx, field, val);
   3133 	mh_v_len = 0;
   3134 	mh_value = quote_internal_chars(val, NULL, &mh_v_len);
   3135 	insheader(idx, newstr(field), mh_value, H_USER, e,
   3136 		!bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
   3137 	SM_FREE(mh_value);
   3138 }
   3139 
   3140 /*
   3141 **  MILTER_CHANGEHEADER -- Change the supplied header in the message
   3142 **
   3143 **	Parameters:
   3144 **		m -- current filter.
   3145 **		response -- encoded form of header/index/value.
   3146 **		rlen -- length of response.
   3147 **		e -- current envelope.
   3148 **
   3149 **	Returns:
   3150 **		none
   3151 */
   3152 
   3153 static void
   3154 milter_changeheader(m, response, rlen, e)
   3155 	struct milter *m;
   3156 	char *response;
   3157 	ssize_t rlen;
   3158 	ENVELOPE *e;
   3159 {
   3160 	mi_int32 i, index;
   3161 	int mh_v_len;
   3162 	char *field, *val, *mh_value;
   3163 	HDR *h, *sysheader;
   3164 
   3165 	if (tTd(64, 10))
   3166 		sm_dprintf("milter_changeheader: ");
   3167 
   3168 	/* sanity checks */
   3169 	if (response == NULL)
   3170 	{
   3171 		if (tTd(64, 10))
   3172 			sm_dprintf("NULL response\n");
   3173 		return;
   3174 	}
   3175 
   3176 	if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
   3177 	{
   3178 		if (tTd(64, 10))
   3179 			sm_dprintf("didn't follow protocol (total len)\n");
   3180 		return;
   3181 	}
   3182 
   3183 	/* Find separating NUL */
   3184 	(void) memcpy((char *) &i, response, MILTER_LEN_BYTES);
   3185 	index = ntohl(i);
   3186 	field = response + MILTER_LEN_BYTES;
   3187 	val = field + strlen(field) + 1;
   3188 
   3189 	/* another sanity check */
   3190 	if (MILTER_LEN_BYTES + strlen(field) + 1 +
   3191 	    strlen(val) + 1 != (size_t) rlen)
   3192 	{
   3193 		if (tTd(64, 10))
   3194 			sm_dprintf("didn't follow protocol (part len)\n");
   3195 		return;
   3196 	}
   3197 
   3198 	if (*field == '\0')
   3199 	{
   3200 		if (tTd(64, 10))
   3201 			sm_dprintf("empty field name\n");
   3202 		return;
   3203 	}
   3204 
   3205 	mh_v_len = 0;
   3206 	mh_value = quote_internal_chars(val, NULL, &mh_v_len);
   3207 
   3208 	sysheader = NULL;
   3209 	for (h = e->e_header; h != NULL; h = h->h_link)
   3210 	{
   3211 		if (sm_strcasecmp(h->h_field, field) == 0)
   3212 		{
   3213 			if (bitset(H_USER, h->h_flags) && --index <= 0)
   3214 			{
   3215 				sysheader = NULL;
   3216 				break;
   3217 			}
   3218 			else if (!bitset(H_USER, h->h_flags) &&
   3219 				 !bitset(H_TRACE, h->h_flags))
   3220 			{
   3221 				/*
   3222 				**  DRUMS msg-fmt draft says can only have
   3223 				**  multiple occurences of trace fields,
   3224 				**  so make sure we replace any non-trace,
   3225 				**  non-user field.
   3226 				*/
   3227 
   3228 				sysheader = h;
   3229 			}
   3230 		}
   3231 	}
   3232 
   3233 	/* if not found as user-provided header at index, use sysheader */
   3234 	if (h == NULL)
   3235 		h = sysheader;
   3236 
   3237 	if (h == NULL)
   3238 	{
   3239 		if (*val == '\0')
   3240 		{
   3241 			if (tTd(64, 10))
   3242 				sm_dprintf("Delete (noop) %s\n", field);
   3243 			if (MilterLogLevel > 8)
   3244 				sm_syslog(LOG_INFO, e->e_id,
   3245 					"Milter delete (noop): header: %s"
   3246 					, field);
   3247 		}
   3248 		else
   3249 		{
   3250 			/* treat modify value with no existing header as add */
   3251 			if (tTd(64, 10))
   3252 				sm_dprintf("Add %s: %s\n", field, mh_value);
   3253 			if (MilterLogLevel > 8)
   3254 				sm_syslog(LOG_INFO, e->e_id,
   3255 					"Milter change (add): header: %s: %s"
   3256 					, field, mh_value);
   3257 			addheader(newstr(field), mh_value, H_USER, e,
   3258 				!bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
   3259 		}
   3260 		return;
   3261 	}
   3262 
   3263 	if (tTd(64, 10))
   3264 	{
   3265 		if (*val == '\0')
   3266 		{
   3267 			sm_dprintf("Delete%s %s:%s\n",
   3268 				   h == sysheader ? " (default header)" : "",
   3269 				   field,
   3270 				   h->h_value == NULL ? "<NULL>" : h->h_value);
   3271 		}
   3272 		else
   3273 		{
   3274 			sm_dprintf("Change%s %s: from %s to %s\n",
   3275 				   h == sysheader ? " (default header)" : "",
   3276 				   field,
   3277 				   h->h_value == NULL ? "<NULL>" : h->h_value,
   3278 				   mh_value);
   3279 		}
   3280 	}
   3281 
   3282 	if (MilterLogLevel > 8)
   3283 	{
   3284 		if (*val == '\0')
   3285 		{
   3286 			sm_syslog(LOG_INFO, e->e_id,
   3287 				  "Milter delete: header%s %s:%s",
   3288 				  h == sysheader ? " (default header)" : "",
   3289 				  field,
   3290 				  h->h_value == NULL ? "<NULL>" : h->h_value);
   3291 		}
   3292 		else
   3293 		{
   3294 			sm_syslog(LOG_INFO, e->e_id,
   3295 				  "Milter change: header%s %s: from %s to %s",
   3296 				  h == sysheader ? " (default header)" : "",
   3297 				  field,
   3298 				  h->h_value == NULL ? "<NULL>" : h->h_value,
   3299 				  mh_value);
   3300 		}
   3301 	}
   3302 
   3303 	if (h != sysheader && h->h_value != NULL)
   3304 	{
   3305 		size_t l;
   3306 
   3307 		l = strlen(h->h_value);
   3308 		if (l > e->e_msgsize)
   3309 			e->e_msgsize = 0;
   3310 		else
   3311 			e->e_msgsize -= l;
   3312 		/* rpool, don't free: sm_free(h->h_value); XXX */
   3313 	}
   3314 
   3315 	if (*val == '\0')
   3316 	{
   3317 		/* Remove "Field: " from message size */
   3318 		if (h != sysheader)
   3319 		{
   3320 			size_t l;
   3321 
   3322 			l = strlen(h->h_field) + 2;
   3323 			if (l > e->e_msgsize)
   3324 				e->e_msgsize = 0;
   3325 			else
   3326 				e->e_msgsize -= l;
   3327 		}
   3328 		h->h_value = NULL;
   3329 		SM_FREE(mh_value);
   3330 	}
   3331 	else
   3332 	{
   3333 		if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags))
   3334 			h->h_value = mh_value;
   3335 		else
   3336 		{
   3337 			h->h_value = addleadingspace(mh_value, e->e_rpool);
   3338 			SM_FREE(mh_value);
   3339 		}
   3340 		h->h_flags |= H_USER;
   3341 		e->e_msgsize += strlen(h->h_value);
   3342 	}
   3343 }
   3344 
   3345 /*
   3346 **  MILTER_SPLIT_RESPONSE -- Split response into fields.
   3347 **
   3348 **	Parameters:
   3349 **		response -- encoded repsonse.
   3350 **		rlen -- length of response.
   3351 **		pargc -- number of arguments (ouput)
   3352 **
   3353 **	Returns:
   3354 **		array of pointers to the individual strings
   3355 */
   3356 
   3357 static char **milter_split_response __P((char *, ssize_t, int *));
   3358 
   3359 static char **
   3360 milter_split_response(response, rlen, pargc)
   3361 	char *response;
   3362 	ssize_t rlen;
   3363 	int *pargc;
   3364 {
   3365 	char **s;
   3366 	size_t i;
   3367 	int elem, nelem;
   3368 
   3369 	SM_ASSERT(response != NULL);
   3370 	SM_ASSERT(pargc != NULL);
   3371 	*pargc = 0;
   3372 	if (rlen < 2 || strlen(response) >= (size_t) rlen)
   3373 	{
   3374 		if (tTd(64, 10))
   3375 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
   3376 				   (int) strlen(response), (int) (rlen - 1));
   3377 		return NULL;
   3378 	}
   3379 
   3380 	nelem = 0;
   3381 	for (i = 0; i < rlen; i++)
   3382 	{
   3383 		if (response[i] == '\0')
   3384 			++nelem;
   3385 	}
   3386 	if (nelem == 0)
   3387 		return NULL;
   3388 
   3389 	/* last entry is only for the name */
   3390 	s = (char **)malloc((nelem + 1) * (sizeof(*s)));
   3391 	if (s == NULL)
   3392 		return NULL;
   3393 	s[0] = response;
   3394 	for (i = 0, elem = 0; i < rlen && elem < nelem; i++)
   3395 	{
   3396 		if (response[i] == '\0')
   3397 		{
   3398 			++elem;
   3399 			if (i + 1 >= rlen)
   3400 				s[elem] = NULL;
   3401 			else
   3402 				s[elem] = &(response[i + 1]);
   3403 		}
   3404 	}
   3405 	*pargc = nelem;
   3406 
   3407 	if (tTd(64, 10))
   3408 	{
   3409 		for (elem = 0; elem < nelem; elem++)
   3410 			sm_dprintf("argv[%d]=\"%s\"\n", elem, s[elem]);
   3411 	}
   3412 
   3413 	/* overwrite last entry (already done above, just paranoia) */
   3414 	s[elem] = NULL;
   3415 	return s;
   3416 }
   3417 
   3418 /*
   3419 **  MILTER_CHGFROM -- Change the envelope sender address
   3420 **
   3421 **	Parameters:
   3422 **		response -- encoded form of recipient address.
   3423 **		rlen -- length of response.
   3424 **		e -- current envelope.
   3425 **
   3426 **	Returns:
   3427 **		none
   3428 */
   3429 
   3430 static void
   3431 milter_chgfrom(response, rlen, e)
   3432 	char *response;
   3433 	ssize_t rlen;
   3434 	ENVELOPE *e;
   3435 {
   3436 	int olderrors, argc;
   3437 	char **argv;
   3438 
   3439 	if (tTd(64, 10))
   3440 		sm_dprintf("milter_chgfrom: ");
   3441 
   3442 	/* sanity checks */
   3443 	if (response == NULL)
   3444 	{
   3445 		if (tTd(64, 10))
   3446 			sm_dprintf("NULL response\n");
   3447 		return;
   3448 	}
   3449 
   3450 	if (*response == '\0' ||
   3451 	    strlen(response) + 1 > (size_t) rlen)
   3452 	{
   3453 		if (tTd(64, 10))
   3454 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
   3455 				   (int) strlen(response), (int) (rlen - 1));
   3456 		return;
   3457 	}
   3458 
   3459 	if (tTd(64, 10))
   3460 		sm_dprintf("%s\n", response);
   3461 	if (MilterLogLevel > 8)
   3462 		sm_syslog(LOG_INFO, e->e_id, "Milter chgfrom: %s", response);
   3463 	argv = milter_split_response(response, rlen, &argc);
   3464 	if (argc < 1 || argc > 2)
   3465 	{
   3466 		if (tTd(64, 10))
   3467 			sm_dprintf("didn't follow protocol argc=%d\n", argc);
   3468 		return;
   3469 	}
   3470 
   3471 	olderrors = Errors;
   3472 	setsender(argv[0], e, NULL, '\0', false);
   3473 	if (argc == 2)
   3474 	{
   3475 		reset_mail_esmtp_args(e);
   3476 
   3477 		/*
   3478 		**  need "features" here: how to get those? via e?
   3479 		**  "fake" it for now: allow everything.
   3480 		*/
   3481 
   3482 		parse_esmtp_args(e, NULL, argv[0], argv[1], "MAIL", NULL,
   3483 				mail_esmtp_args);
   3484 	}
   3485 	Errors = olderrors;
   3486 	return;
   3487 }
   3488 
   3489 /*
   3490 **  MILTER_ADDRCPT_PAR -- Add the supplied recipient to the message
   3491 **
   3492 **	Parameters:
   3493 **		response -- encoded form of recipient address.
   3494 **		rlen -- length of response.
   3495 **		e -- current envelope.
   3496 **
   3497 **	Returns:
   3498 **		none
   3499 */
   3500 
   3501 static void
   3502 milter_addrcpt_par(response, rlen, e)
   3503 	char *response;
   3504 	ssize_t rlen;
   3505 	ENVELOPE *e;
   3506 {
   3507 	int olderrors, argc;
   3508 	char *delimptr;
   3509 	char **argv;
   3510 	ADDRESS *a;
   3511 
   3512 	if (tTd(64, 10))
   3513 		sm_dprintf("milter_addrcpt_par: ");
   3514 
   3515 	/* sanity checks */
   3516 	if (response == NULL)
   3517 	{
   3518 		if (tTd(64, 10))
   3519 			sm_dprintf("NULL response\n");
   3520 		return;
   3521 	}
   3522 
   3523 	if (tTd(64, 10))
   3524 		sm_dprintf("%s\n", response);
   3525 	if (MilterLogLevel > 8)
   3526 		sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
   3527 
   3528 	argv = milter_split_response(response, rlen, &argc);
   3529 	if (argc < 1 || argc > 2)
   3530 	{
   3531 		if (tTd(64, 10))
   3532 			sm_dprintf("didn't follow protocol argc=%d\n", argc);
   3533 		return;
   3534 	}
   3535 	olderrors = Errors;
   3536 
   3537 	/* how to set ESMTP arguments? */
   3538 	a = parseaddr(argv[0], NULLADDR, RF_COPYALL, ' ', &delimptr, e, true);
   3539 
   3540 	if (a != NULL && olderrors == Errors)
   3541 	{
   3542 		parse_esmtp_args(e, a, argv[0], argv[1], "RCPT", NULL,
   3543 				rcpt_esmtp_args);
   3544 		if (olderrors == Errors)
   3545 			a = recipient(a, &e->e_sendqueue, 0, e);
   3546 		else
   3547 			sm_dprintf("olderrors=%d, Errors=%d\n",
   3548 				olderrors, Errors);
   3549 	}
   3550 	else
   3551 	{
   3552 		sm_dprintf("a=%p, olderrors=%d, Errors=%d\n",
   3553 			a, olderrors, Errors);
   3554 	}
   3555 
   3556 	Errors = olderrors;
   3557 	return;
   3558 }
   3559 
   3560 /*
   3561 **  MILTER_ADDRCPT -- Add the supplied recipient to the message
   3562 **
   3563 **	Parameters:
   3564 **		response -- encoded form of recipient address.
   3565 **		rlen -- length of response.
   3566 **		e -- current envelope.
   3567 **
   3568 **	Returns:
   3569 **		none
   3570 */
   3571 
   3572 static void
   3573 milter_addrcpt(response, rlen, e)
   3574 	char *response;
   3575 	ssize_t rlen;
   3576 	ENVELOPE *e;
   3577 {
   3578 	int olderrors;
   3579 
   3580 	if (tTd(64, 10))
   3581 		sm_dprintf("milter_addrcpt: ");
   3582 
   3583 	/* sanity checks */
   3584 	if (response == NULL)
   3585 	{
   3586 		if (tTd(64, 10))
   3587 			sm_dprintf("NULL response\n");
   3588 		return;
   3589 	}
   3590 
   3591 	if (*response == '\0' ||
   3592 	    strlen(response) + 1 != (size_t) rlen)
   3593 	{
   3594 		if (tTd(64, 10))
   3595 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
   3596 				   (int) strlen(response), (int) (rlen - 1));
   3597 		return;
   3598 	}
   3599 
   3600 	if (tTd(64, 10))
   3601 		sm_dprintf("%s\n", response);
   3602 	if (MilterLogLevel > 8)
   3603 		sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
   3604 	olderrors = Errors;
   3605 	(void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e);
   3606 	Errors = olderrors;
   3607 	return;
   3608 }
   3609 
   3610 /*
   3611 **  MILTER_DELRCPT -- Delete the supplied recipient from the message
   3612 **
   3613 **	Parameters:
   3614 **		response -- encoded form of recipient address.
   3615 **		rlen -- length of response.
   3616 **		e -- current envelope.
   3617 **
   3618 **	Returns:
   3619 **		none
   3620 */
   3621 
   3622 static void
   3623 milter_delrcpt(response, rlen, e)
   3624 	char *response;
   3625 	ssize_t rlen;
   3626 	ENVELOPE *e;
   3627 {
   3628 	if (tTd(64, 10))
   3629 		sm_dprintf("milter_delrcpt: ");
   3630 
   3631 	/* sanity checks */
   3632 	if (response == NULL)
   3633 	{
   3634 		if (tTd(64, 10))
   3635 			sm_dprintf("NULL response\n");
   3636 		return;
   3637 	}
   3638 
   3639 	if (*response == '\0' ||
   3640 	    strlen(response) + 1 != (size_t) rlen)
   3641 	{
   3642 		if (tTd(64, 10))
   3643 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
   3644 				   (int) strlen(response), (int) (rlen - 1));
   3645 		return;
   3646 	}
   3647 
   3648 	if (tTd(64, 10))
   3649 		sm_dprintf("%s\n", response);
   3650 	if (MilterLogLevel > 8)
   3651 		sm_syslog(LOG_INFO, e->e_id, "Milter delete: rcpt %s",
   3652 			  response);
   3653 	(void) removefromlist(response, &e->e_sendqueue, e);
   3654 	return;
   3655 }
   3656 
   3657 /*
   3658 **  MILTER_REPLBODY -- Replace the current data file with new body
   3659 **
   3660 **	Parameters:
   3661 **		response -- encoded form of new body.
   3662 **		rlen -- length of response.
   3663 **		newfilter -- if first time called by a new filter
   3664 **		e -- current envelope.
   3665 **
   3666 **	Returns:
   3667 **		0 upon success, -1 upon failure
   3668 */
   3669 
   3670 static int
   3671 milter_replbody(response, rlen, newfilter, e)
   3672 	char *response;
   3673 	ssize_t rlen;
   3674 	bool newfilter;
   3675 	ENVELOPE *e;
   3676 {
   3677 	static char prevchar;
   3678 	int i;
   3679 
   3680 	if (tTd(64, 10))
   3681 		sm_dprintf("milter_replbody\n");
   3682 
   3683 	/* If a new filter, reset previous character and truncate data file */
   3684 	if (newfilter)
   3685 	{
   3686 		off_t prevsize;
   3687 		char dfname[MAXPATHLEN];
   3688 
   3689 		(void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER),
   3690 				  sizeof(dfname));
   3691 
   3692 		/* Reset prevchar */
   3693 		prevchar = '\0';
   3694 
   3695 		/* Get the current data file information */
   3696 		prevsize = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_SIZE, NULL);
   3697 		if (prevsize < 0)
   3698 			prevsize = 0;
   3699 
   3700 		/* truncate current data file */
   3701 		if (sm_io_getinfo(e->e_dfp, SM_IO_WHAT_ISTYPE, BF_FILE_TYPE))
   3702 		{
   3703 			if (sm_io_setinfo(e->e_dfp, SM_BF_TRUNCATE, NULL) < 0)
   3704 			{
   3705 				MILTER_DF_ERROR("milter_replbody: sm_io truncate %s: %s");
   3706 				return -1;
   3707 			}
   3708 		}
   3709 		else
   3710 		{
   3711 			int err;
   3712 
   3713 			err = sm_io_error(e->e_dfp);
   3714 			(void) sm_io_flush(e->e_dfp, SM_TIME_DEFAULT);
   3715 
   3716 			/*
   3717 			**  Clear error if tried to fflush()
   3718 			**  a read-only file pointer and
   3719 			**  there wasn't a previous error.
   3720 			*/
   3721 
   3722 			if (err == 0)
   3723 				sm_io_clearerr(e->e_dfp);
   3724 
   3725 			/* errno is set implicitly by fseek() before return */
   3726 			err = sm_io_seek(e->e_dfp, SM_TIME_DEFAULT,
   3727 					 0, SEEK_SET);
   3728 			if (err < 0)
   3729 			{
   3730 				MILTER_DF_ERROR("milter_replbody: sm_io_seek %s: %s");
   3731 				return -1;
   3732 			}
   3733 # if NOFTRUNCATE
   3734 			/* XXX: Not much we can do except rewind it */
   3735 			errno = EINVAL;
   3736 			MILTER_DF_ERROR("milter_replbody: ftruncate not available on this platform (%s:%s)");
   3737 			return -1;
   3738 # else /* NOFTRUNCATE */
   3739 			err = ftruncate(sm_io_getinfo(e->e_dfp,
   3740 						      SM_IO_WHAT_FD, NULL),
   3741 					0);
   3742 			if (err < 0)
   3743 			{
   3744 				MILTER_DF_ERROR("milter_replbody: sm_io ftruncate %s: %s");
   3745 				return -1;
   3746 			}
   3747 # endif /* NOFTRUNCATE */
   3748 		}
   3749 
   3750 		if (prevsize > e->e_msgsize)
   3751 			e->e_msgsize = 0;
   3752 		else
   3753 			e->e_msgsize -= prevsize;
   3754 	}
   3755 
   3756 	if (newfilter && MilterLogLevel > 8)
   3757 		sm_syslog(LOG_INFO, e->e_id, "Milter message: body replaced");
   3758 
   3759 	if (response == NULL)
   3760 	{
   3761 		/* Flush the buffered '\r' */
   3762 		if (prevchar == '\r')
   3763 		{
   3764 			(void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, prevchar);
   3765 			e->e_msgsize++;
   3766 		}
   3767 		return 0;
   3768 	}
   3769 
   3770 	for (i = 0; i < rlen; i++)
   3771 	{
   3772 		/* Buffered char from last chunk */
   3773 		if (i == 0 && prevchar == '\r')
   3774 		{
   3775 			/* Not CRLF, output prevchar */
   3776 			if (response[i] != '\n')
   3777 			{
   3778 				(void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT,
   3779 						  prevchar);
   3780 				e->e_msgsize++;
   3781 			}
   3782 			prevchar = '\0';
   3783 		}
   3784 
   3785 		/* Turn CRLF into LF */
   3786 		if (response[i] == '\r')
   3787 		{
   3788 			/* check if at end of chunk */
   3789 			if (i + 1 < rlen)
   3790 			{
   3791 				/* If LF, strip CR */
   3792 				if (response[i + 1] == '\n')
   3793 					i++;
   3794 			}
   3795 			else
   3796 			{
   3797 				/* check next chunk */
   3798 				prevchar = '\r';
   3799 				continue;
   3800 			}
   3801 		}
   3802 		(void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, response[i]);
   3803 		e->e_msgsize++;
   3804 	}
   3805 	return 0;
   3806 }
   3807 
   3808 /*
   3809 **  MTA callouts
   3810 */
   3811 
   3812 /*
   3813 **  MILTER_INIT -- open and negotiate with all of the filters
   3814 **
   3815 **	Parameters:
   3816 **		e -- current envelope.
   3817 **		state -- return state from response.
   3818 **		milters -- milters structure.
   3819 **
   3820 **	Returns:
   3821 **		true iff at least one filter is active
   3822 */
   3823 
   3824 /* ARGSUSED */
   3825 bool
   3826 milter_init(e, state, milters)
   3827 	ENVELOPE *e;
   3828 	char *state;
   3829 	milters_T *milters;
   3830 {
   3831 	int i;
   3832 
   3833 	if (tTd(64, 10))
   3834 		sm_dprintf("milter_init\n");
   3835 
   3836 	memset(milters, '\0', sizeof(*milters));
   3837 	*state = SMFIR_CONTINUE;
   3838 	if (InputFilters[0] == NULL)
   3839 	{
   3840 		if (MilterLogLevel > 10)
   3841 			sm_syslog(LOG_INFO, e->e_id,
   3842 				  "Milter: no active filter");
   3843 		return false;
   3844 	}
   3845 
   3846 	for (i = 0; InputFilters[i] != NULL; i++)
   3847 	{
   3848 		struct milter *m = InputFilters[i];
   3849 
   3850 		m->mf_sock = milter_open(m, false, e);
   3851 		if (m->mf_state == SMFS_ERROR)
   3852 		{
   3853 			MILTER_CHECK_ERROR(true, continue);
   3854 			break;
   3855 		}
   3856 
   3857 		if (m->mf_sock < 0 ||
   3858 		    milter_negotiate(m, e, milters) < 0 ||
   3859 		    m->mf_state == SMFS_ERROR)
   3860 		{
   3861 			if (tTd(64, 5))
   3862 				sm_dprintf("milter_init(%s): failed to %s\n",
   3863 					   m->mf_name,
   3864 					   m->mf_sock < 0 ? "open" :
   3865 							    "negotiate");
   3866 			if (MilterLogLevel > 0)
   3867 				sm_syslog(LOG_ERR, e->e_id,
   3868 					  "Milter (%s): init failed to %s",
   3869 					  m->mf_name,
   3870 					  m->mf_sock < 0 ? "open" :
   3871 							   "negotiate");
   3872 
   3873 			/* if negotiation failure, close socket */
   3874 			milter_error(m, e);
   3875 			MILTER_CHECK_ERROR(true, continue);
   3876 			continue;
   3877 		}
   3878 		if (MilterLogLevel > 9)
   3879 			sm_syslog(LOG_INFO, e->e_id,
   3880 				  "Milter (%s): init success to %s",
   3881 				  m->mf_name,
   3882 				  m->mf_sock < 0 ? "open" : "negotiate");
   3883 	}
   3884 
   3885 	/*
   3886 	**  If something temp/perm failed with one of the filters,
   3887 	**  we won't be using any of them, so clear any existing
   3888 	**  connections.
   3889 	*/
   3890 
   3891 	if (*state != SMFIR_CONTINUE)
   3892 		milter_quit(e);
   3893 
   3894 	return true;
   3895 }
   3896 
   3897 /*
   3898 **  MILTER_CONNECT -- send connection info to milter filters
   3899 **
   3900 **	Parameters:
   3901 **		hostname -- hostname of remote machine.
   3902 **		addr -- address of remote machine.
   3903 **		e -- current envelope.
   3904 **		state -- return state from response.
   3905 **
   3906 **	Returns:
   3907 **		response string (may be NULL)
   3908 */
   3909 
   3910 char *
   3911 milter_connect(hostname, addr, e, state)
   3912 	char *hostname;
   3913 	SOCKADDR addr;
   3914 	ENVELOPE *e;
   3915 	char *state;
   3916 {
   3917 	char family;
   3918 	unsigned short port;
   3919 	char *buf, *bp;
   3920 	char *response;
   3921 	char *sockinfo = NULL;
   3922 	ssize_t s;
   3923 # if NETINET6
   3924 	char buf6[INET6_ADDRSTRLEN];
   3925 # endif /* NETINET6 */
   3926 
   3927 	if (tTd(64, 10))
   3928 		sm_dprintf("milter_connect(%s)\n", hostname);
   3929 	if (MilterLogLevel > 9)
   3930 		sm_syslog(LOG_INFO, e->e_id, "Milter: connect to filters");
   3931 
   3932 	/* gather data */
   3933 	switch (addr.sa.sa_family)
   3934 	{
   3935 # if NETUNIX
   3936 	  case AF_UNIX:
   3937 		family = SMFIA_UNIX;
   3938 		port = htons(0);
   3939 		sockinfo = addr.sunix.sun_path;
   3940 		break;
   3941 # endif /* NETUNIX */
   3942 
   3943 # if NETINET
   3944 	  case AF_INET:
   3945 		family = SMFIA_INET;
   3946 		port = addr.sin.sin_port;
   3947 		sockinfo = (char *) inet_ntoa(addr.sin.sin_addr);
   3948 		break;
   3949 # endif /* NETINET */
   3950 
   3951 # if NETINET6
   3952 	  case AF_INET6:
   3953 		if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr))
   3954 			family = SMFIA_INET;
   3955 		else
   3956 			family = SMFIA_INET6;
   3957 		port = addr.sin6.sin6_port;
   3958 		sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6,
   3959 				       sizeof(buf6));
   3960 		if (sockinfo == NULL)
   3961 			sockinfo = "";
   3962 		break;
   3963 # endif /* NETINET6 */
   3964 
   3965 	  default:
   3966 		family = SMFIA_UNKNOWN;
   3967 		break;
   3968 	}
   3969 
   3970 	s = strlen(hostname) + 1 + sizeof(family);
   3971 	if (family != SMFIA_UNKNOWN)
   3972 		s += sizeof(port) + strlen(sockinfo) + 1;
   3973 
   3974 	buf = (char *) xalloc(s);
   3975 	bp = buf;
   3976 
   3977 	/* put together data */
   3978 	(void) memcpy(bp, hostname, strlen(hostname));
   3979 	bp += strlen(hostname);
   3980 	*bp++ = '\0';
   3981 	(void) memcpy(bp, &family, sizeof(family));
   3982 	bp += sizeof(family);
   3983 	if (family != SMFIA_UNKNOWN)
   3984 	{
   3985 		(void) memcpy(bp, &port, sizeof(port));
   3986 		bp += sizeof(port);
   3987 
   3988 		/* include trailing '\0' */
   3989 		(void) memcpy(bp, sockinfo, strlen(sockinfo) + 1);
   3990 	}
   3991 
   3992 	response = milter_command(SMFIC_CONNECT, buf, s, MilterConnectMacros,
   3993 				e, state, "connect", false);
   3994 	sm_free(buf); /* XXX */
   3995 
   3996 	/*
   3997 	**  If this message connection is done for,
   3998 	**  close the filters.
   3999 	*/
   4000 
   4001 	if (*state != SMFIR_CONTINUE)
   4002 	{
   4003 		if (MilterLogLevel > 9)
   4004 			sm_syslog(LOG_INFO, e->e_id, "Milter: connect, ending");
   4005 		milter_quit(e);
   4006 	}
   4007 	else
   4008 		milter_per_connection_check(e);
   4009 
   4010 	/*
   4011 	**  SMFIR_REPLYCODE can't work with connect due to
   4012 	**  the requirements of SMTP.  Therefore, ignore the
   4013 	**  reply code text but keep the state it would reflect.
   4014 	*/
   4015 
   4016 	if (*state == SMFIR_REPLYCODE)
   4017 	{
   4018 		if (response != NULL &&
   4019 		    *response == '4')
   4020 		{
   4021 			if (strncmp(response, "421 ", 4) == 0)
   4022 				*state = SMFIR_SHUTDOWN;
   4023 			else
   4024 				*state = SMFIR_TEMPFAIL;
   4025 		}
   4026 		else
   4027 			*state = SMFIR_REJECT;
   4028 		if (response != NULL)
   4029 		{
   4030 			sm_free(response); /* XXX */
   4031 			response = NULL;
   4032 		}
   4033 	}
   4034 	return response;
   4035 }
   4036 
   4037 /*
   4038 **  MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters
   4039 **
   4040 **	Parameters:
   4041 **		helo -- argument to SMTP HELO/EHLO command.
   4042 **		e -- current envelope.
   4043 **		state -- return state from response.
   4044 **
   4045 **	Returns:
   4046 **		response string (may be NULL)
   4047 */
   4048 
   4049 char *
   4050 milter_helo(helo, e, state)
   4051 	char *helo;
   4052 	ENVELOPE *e;
   4053 	char *state;
   4054 {
   4055 	int i;
   4056 	char *response;
   4057 
   4058 	if (tTd(64, 10))
   4059 		sm_dprintf("milter_helo(%s)\n", helo);
   4060 
   4061 	/* HELO/EHLO can come at any point */
   4062 	for (i = 0; InputFilters[i] != NULL; i++)
   4063 	{
   4064 		struct milter *m = InputFilters[i];
   4065 
   4066 		switch (m->mf_state)
   4067 		{
   4068 		  case SMFS_INMSG:
   4069 			/* abort in message filters */
   4070 			milter_abort_filter(m, e);
   4071 			/* FALLTHROUGH */
   4072 
   4073 		  case SMFS_DONE:
   4074 			/* reset done filters */
   4075 			m->mf_state = SMFS_OPEN;
   4076 			break;
   4077 		}
   4078 	}
   4079 
   4080 	response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1,
   4081 				  MilterHeloMacros, e, state, "helo", false);
   4082 	milter_per_connection_check(e);
   4083 	return response;
   4084 }
   4085 
   4086 /*
   4087 **  MILTER_ENVFROM -- send SMTP MAIL command info to milter filters
   4088 **
   4089 **	Parameters:
   4090 **		args -- SMTP MAIL command args (args[0] == sender).
   4091 **		e -- current envelope.
   4092 **		state -- return state from response.
   4093 **
   4094 **	Returns:
   4095 **		response string (may be NULL)
   4096 */
   4097 
   4098 char *
   4099 milter_envfrom(args, e, state)
   4100 	char **args;
   4101 	ENVELOPE *e;
   4102 	char *state;
   4103 {
   4104 	int i;
   4105 	char *buf, *bp;
   4106 	char *response;
   4107 	ssize_t s;
   4108 
   4109 	if (tTd(64, 10))
   4110 	{
   4111 		sm_dprintf("milter_envfrom:");
   4112 		for (i = 0; args[i] != NULL; i++)
   4113 			sm_dprintf(" %s", args[i]);
   4114 		sm_dprintf("\n");
   4115 	}
   4116 
   4117 	/* sanity check */
   4118 	if (args[0] == NULL)
   4119 	{
   4120 		*state = SMFIR_REJECT;
   4121 		if (MilterLogLevel > 10)
   4122 			sm_syslog(LOG_INFO, e->e_id,
   4123 				  "Milter: reject, no sender");
   4124 		return NULL;
   4125 	}
   4126 
   4127 	/* new message, so ... */
   4128 	for (i = 0; InputFilters[i] != NULL; i++)
   4129 	{
   4130 		struct milter *m = InputFilters[i];
   4131 
   4132 		switch (m->mf_state)
   4133 		{
   4134 		  case SMFS_INMSG:
   4135 			/* abort in message filters */
   4136 			milter_abort_filter(m, e);
   4137 			/* FALLTHROUGH */
   4138 
   4139 		  case SMFS_DONE:
   4140 			/* reset done filters */
   4141 			m->mf_state = SMFS_OPEN;
   4142 			break;
   4143 		}
   4144 	}
   4145 
   4146 	/* put together data */
   4147 	s = 0;
   4148 	for (i = 0; args[i] != NULL; i++)
   4149 		s += strlen(args[i]) + 1;
   4150 
   4151 	if (s < 0)
   4152 	{
   4153 		*state = SMFIR_TEMPFAIL;
   4154 		return NULL;
   4155 	}
   4156 
   4157 	buf = (char *) xalloc(s);
   4158 	bp = buf;
   4159 	for (i = 0; args[i] != NULL; i++)
   4160 	{
   4161 		(void) sm_strlcpy(bp, args[i], s - (bp - buf));
   4162 		bp += strlen(bp) + 1;
   4163 	}
   4164 
   4165 	if (MilterLogLevel > 14)
   4166 		sm_syslog(LOG_INFO, e->e_id, "Milter: sender: %s", buf);
   4167 
   4168 	/* send it over */
   4169 	response = milter_command(SMFIC_MAIL, buf, s, MilterEnvFromMacros,
   4170 				e, state, "mail", false);
   4171 	sm_free(buf); /* XXX */
   4172 
   4173 	/*
   4174 	**  If filter rejects/discards a per message command,
   4175 	**  abort the other filters since we are done with the
   4176 	**  current message.
   4177 	*/
   4178 
   4179 	MILTER_CHECK_DONE_MSG();
   4180 	if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
   4181 		sm_syslog(LOG_INFO, e->e_id, "Milter: reject, sender");
   4182 	return response;
   4183 }
   4184 
   4185 /*
   4186 **  MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters
   4187 **
   4188 **	Parameters:
   4189 **		args -- SMTP MAIL command args (args[0] == recipient).
   4190 **		e -- current envelope.
   4191 **		state -- return state from response.
   4192 **		rcpt_error -- does RCPT have an error?
   4193 **
   4194 **	Returns:
   4195 **		response string (may be NULL)
   4196 */
   4197 
   4198 char *
   4199 milter_envrcpt(args, e, state, rcpt_error)
   4200 	char **args;
   4201 	ENVELOPE *e;
   4202 	char *state;
   4203 	bool rcpt_error;
   4204 {
   4205 	int i;
   4206 	char *buf, *bp;
   4207 	char *response;
   4208 	ssize_t s;
   4209 
   4210 	if (tTd(64, 10))
   4211 	{
   4212 		sm_dprintf("milter_envrcpt:");
   4213 		for (i = 0; args[i] != NULL; i++)
   4214 			sm_dprintf(" %s", args[i]);
   4215 		sm_dprintf("\n");
   4216 	}
   4217 
   4218 	/* sanity check */
   4219 	if (args[0] == NULL)
   4220 	{
   4221 		*state = SMFIR_REJECT;
   4222 		if (MilterLogLevel > 10)
   4223 			sm_syslog(LOG_INFO, e->e_id, "Milter: reject, no rcpt");
   4224 		return NULL;
   4225 	}
   4226 
   4227 	/* put together data */
   4228 	s = 0;
   4229 	for (i = 0; args[i] != NULL; i++)
   4230 		s += strlen(args[i]) + 1;
   4231 
   4232 	if (s < 0)
   4233 	{
   4234 		*state = SMFIR_TEMPFAIL;
   4235 		return NULL;
   4236 	}
   4237 
   4238 	buf = (char *) xalloc(s);
   4239 	bp = buf;
   4240 	for (i = 0; args[i] != NULL; i++)
   4241 	{
   4242 		(void) sm_strlcpy(bp, args[i], s - (bp - buf));
   4243 		bp += strlen(bp) + 1;
   4244 	}
   4245 
   4246 	if (MilterLogLevel > 14)
   4247 		sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf);
   4248 
   4249 	/* send it over */
   4250 	response = milter_command(SMFIC_RCPT, buf, s, MilterEnvRcptMacros,
   4251 				e, state, "rcpt", rcpt_error);
   4252 	sm_free(buf); /* XXX */
   4253 	return response;
   4254 }
   4255 
   4256 /*
   4257 **  MILTER_DATA_CMD -- send SMTP DATA command info to milter filters
   4258 **
   4259 **	Parameters:
   4260 **		e -- current envelope.
   4261 **		state -- return state from response.
   4262 **
   4263 **	Returns:
   4264 **		response string (may be NULL)
   4265 */
   4266 
   4267 char *
   4268 milter_data_cmd(e, state)
   4269 	ENVELOPE *e;
   4270 	char *state;
   4271 {
   4272 	if (tTd(64, 10))
   4273 		sm_dprintf("milter_data_cmd\n");
   4274 
   4275 	/* send it over */
   4276 	return milter_command(SMFIC_DATA, NULL, 0, MilterDataMacros, e, state,
   4277 				"data", false);
   4278 }
   4279 
   4280 /*
   4281 **  MILTER_DATA -- send message headers/body and gather final message results
   4282 **
   4283 **	Parameters:
   4284 **		e -- current envelope.
   4285 **		state -- return state from response.
   4286 **
   4287 **	Returns:
   4288 **		response string (may be NULL)
   4289 **
   4290 **	Side effects:
   4291 **		- Uses e->e_dfp for access to the body
   4292 **		- Can call the various milter action routines to
   4293 **		  modify the envelope or message.
   4294 */
   4295 
   4296 # define MILTER_CHECK_RESULTS() \
   4297 	if (*state == SMFIR_ACCEPT || \
   4298 	    m->mf_state == SMFS_DONE || \
   4299 	    m->mf_state == SMFS_ERROR) \
   4300 	{ \
   4301 		if (m->mf_state != SMFS_ERROR) \
   4302 			m->mf_state = SMFS_DONE; \
   4303 		continue;	/* to next filter */ \
   4304 	} \
   4305 	if (*state != SMFIR_CONTINUE) \
   4306 	{ \
   4307 		m->mf_state = SMFS_DONE; \
   4308 		goto finishup; \
   4309 	}
   4310 
   4311 char *
   4312 milter_data(e, state)
   4313 	ENVELOPE *e;
   4314 	char *state;
   4315 {
   4316 	bool replbody = false;		/* milter_replbody() called? */
   4317 	bool replfailed = false;	/* milter_replbody() failed? */
   4318 	bool rewind = false;		/* rewind data file? */
   4319 	bool dfopen = false;		/* data file open for writing? */
   4320 	bool newfilter;			/* reset on each new filter */
   4321 	char rcmd;
   4322 	int i;
   4323 	int save_errno;
   4324 	char *response = NULL;
   4325 	time_t eomsent;
   4326 	ssize_t rlen;
   4327 
   4328 	if (tTd(64, 10))
   4329 		sm_dprintf("milter_data\n");
   4330 
   4331 	*state = SMFIR_CONTINUE;
   4332 
   4333 	/*
   4334 	**  XXX: Should actually send body chunks to each filter
   4335 	**  a chunk at a time instead of sending the whole body to
   4336 	**  each filter in turn.  However, only if the filters don't
   4337 	**  change the body.
   4338 	*/
   4339 
   4340 	for (i = 0; InputFilters[i] != NULL; i++)
   4341 	{
   4342 		struct milter *m = InputFilters[i];
   4343 
   4344 		if (*state != SMFIR_CONTINUE &&
   4345 		    *state != SMFIR_ACCEPT)
   4346 		{
   4347 			/*
   4348 			**  A previous filter has dealt with the message,
   4349 			**  safe to stop processing the filters.
   4350 			*/
   4351 
   4352 			break;
   4353 		}
   4354 
   4355 		/* Now reset state for later evaluation */
   4356 		*state = SMFIR_CONTINUE;
   4357 		newfilter = true;
   4358 
   4359 		/* previous problem? */
   4360 		if (m->mf_state == SMFS_ERROR)
   4361 		{
   4362 			MILTER_CHECK_ERROR(false, continue);
   4363 			break;
   4364 		}
   4365 
   4366 		/* sanity checks */
   4367 		if (m->mf_sock < 0 ||
   4368 		    (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
   4369 			continue;
   4370 
   4371 		m->mf_state = SMFS_INMSG;
   4372 
   4373 		/* check if filter wants the headers */
   4374 		if (!bitset(SMFIP_NOHDRS, m->mf_pflags))
   4375 		{
   4376 			response = milter_headers(m, e, state);
   4377 			MILTER_CHECK_RESULTS();
   4378 		}
   4379 
   4380 		/* check if filter wants EOH */
   4381 		if (!bitset(SMFIP_NOEOH, m->mf_pflags))
   4382 		{
   4383 			if (tTd(64, 10))
   4384 				sm_dprintf("milter_data: eoh\n");
   4385 
   4386 			if (MilterEOHMacros[0] != NULL)
   4387 			{
   4388 				milter_send_macros(m, MilterEOHMacros,
   4389 					   SMFIC_EOH, e);
   4390 				MILTER_CHECK_RESULTS();
   4391 			}
   4392 
   4393 			/* send it over */
   4394 			response = milter_send_command(m, SMFIC_EOH, NULL, 0,
   4395 						       e, state, "eoh");
   4396 			MILTER_CHECK_RESULTS();
   4397 		}
   4398 
   4399 		/* check if filter wants the body */
   4400 		if (!bitset(SMFIP_NOBODY, m->mf_pflags) &&
   4401 		    e->e_dfp != NULL)
   4402 		{
   4403 			rewind = true;
   4404 			response = milter_body(m, e, state);
   4405 			MILTER_CHECK_RESULTS();
   4406 		}
   4407 
   4408 		if (MilterEOMMacros[0] != NULL)
   4409 		{
   4410 			milter_send_macros(m, MilterEOMMacros,
   4411 					   SMFIC_BODYEOB, e);
   4412 			MILTER_CHECK_RESULTS();
   4413 		}
   4414 
   4415 		/* send the final body chunk */
   4416 		(void) milter_write(m, SMFIC_BODYEOB, NULL, 0,
   4417 				    m->mf_timeout[SMFTO_WRITE], e, "eom");
   4418 
   4419 		/* Get time EOM sent for timeout */
   4420 		eomsent = curtime();
   4421 
   4422 		/* deal with the possibility of multiple responses */
   4423 		while (*state == SMFIR_CONTINUE)
   4424 		{
   4425 			/* Check total timeout from EOM to final ACK/NAK */
   4426 			if (m->mf_timeout[SMFTO_EOM] > 0 &&
   4427 			    curtime() - eomsent >= m->mf_timeout[SMFTO_EOM])
   4428 			{
   4429 				if (tTd(64, 5))
   4430 					sm_dprintf("milter_data(%s): EOM ACK/NAK timeout\n",
   4431 						m->mf_name);
   4432 				if (MilterLogLevel > 0)
   4433 					sm_syslog(LOG_ERR, e->e_id,
   4434 						  "milter_data(%s): EOM ACK/NAK timeout",
   4435 						  m->mf_name);
   4436 				milter_error(m, e);
   4437 				MILTER_CHECK_ERROR(false, break);
   4438 				break;
   4439 			}
   4440 
   4441 			response = milter_read(m, &rcmd, &rlen,
   4442 					       m->mf_timeout[SMFTO_READ], e,
   4443 						"eom");
   4444 			if (m->mf_state == SMFS_ERROR)
   4445 				break;
   4446 
   4447 			if (tTd(64, 10))
   4448 				sm_dprintf("milter_data(%s): state %c\n",
   4449 					   m->mf_name, (char) rcmd);
   4450 
   4451 			switch (rcmd)
   4452 			{
   4453 			  case SMFIR_REPLYCODE:
   4454 				MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected");
   4455 				if (MilterLogLevel > 12)
   4456 					sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject=%s",
   4457 						  m->mf_name, response);
   4458 				*state = rcmd;
   4459 				m->mf_state = SMFS_DONE;
   4460 				break;
   4461 
   4462 			  case SMFIR_REJECT: /* log msg at end of function */
   4463 				if (MilterLogLevel > 12)
   4464 					sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject",
   4465 						  m->mf_name);
   4466 				*state = rcmd;
   4467 				m->mf_state = SMFS_DONE;
   4468 				break;
   4469 
   4470 			  case SMFIR_DISCARD:
   4471 				if (MilterLogLevel > 12)
   4472 					sm_syslog(LOG_INFO, e->e_id, "milter=%s, discard",
   4473 						  m->mf_name);
   4474 				*state = rcmd;
   4475 				m->mf_state = SMFS_DONE;
   4476 				break;
   4477 
   4478 			  case SMFIR_TEMPFAIL:
   4479 				if (MilterLogLevel > 12)
   4480 					sm_syslog(LOG_INFO, e->e_id, "milter=%s, tempfail",
   4481 						  m->mf_name);
   4482 				*state = rcmd;
   4483 				m->mf_state = SMFS_DONE;
   4484 				break;
   4485 
   4486 			  case SMFIR_CONTINUE:
   4487 			  case SMFIR_ACCEPT:
   4488 				/* this filter is done with message */
   4489 				if (replfailed)
   4490 					*state = SMFIR_TEMPFAIL;
   4491 				else
   4492 					*state = SMFIR_ACCEPT;
   4493 				m->mf_state = SMFS_DONE;
   4494 				break;
   4495 
   4496 			  case SMFIR_PROGRESS:
   4497 				break;
   4498 
   4499 			  case SMFIR_QUARANTINE:
   4500 				if (!bitset(SMFIF_QUARANTINE, m->mf_fflags))
   4501 				{
   4502 					if (MilterLogLevel > 9)
   4503 						sm_syslog(LOG_WARNING, e->e_id,
   4504 							  "milter_data(%s): lied about quarantining, honoring request anyway",
   4505 							  m->mf_name);
   4506 				}
   4507 				if (response == NULL)
   4508 					response = newstr("");
   4509 				if (MilterLogLevel > 3)
   4510 					sm_syslog(LOG_INFO, e->e_id,
   4511 						  "milter=%s, quarantine=%s",
   4512 						  m->mf_name, response);
   4513 				e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
   4514 								 response);
   4515 				macdefine(&e->e_macro, A_PERM,
   4516 					  macid("{quarantine}"), e->e_quarmsg);
   4517 				break;
   4518 
   4519 			  case SMFIR_ADDHEADER:
   4520 				if (!bitset(SMFIF_ADDHDRS, m->mf_fflags))
   4521 				{
   4522 					if (MilterLogLevel > 9)
   4523 						sm_syslog(LOG_WARNING, e->e_id,
   4524 							  "milter_data(%s): lied about adding headers, honoring request anyway",
   4525 							  m->mf_name);
   4526 				}
   4527 				milter_addheader(m, response, rlen, e);
   4528 				break;
   4529 
   4530 			  case SMFIR_INSHEADER:
   4531 				if (!bitset(SMFIF_ADDHDRS, m->mf_fflags))
   4532 				{
   4533 					if (MilterLogLevel > 9)
   4534 						sm_syslog(LOG_WARNING, e->e_id,
   4535 							  "milter_data(%s): lied about adding headers, honoring request anyway",
   4536 							  m->mf_name);
   4537 				}
   4538 				milter_insheader(m, response, rlen, e);
   4539 				break;
   4540 
   4541 			  case SMFIR_CHGHEADER:
   4542 				if (!bitset(SMFIF_CHGHDRS, m->mf_fflags))
   4543 				{
   4544 					if (MilterLogLevel > 9)
   4545 						sm_syslog(LOG_WARNING, e->e_id,
   4546 							  "milter_data(%s): lied about changing headers, honoring request anyway",
   4547 							  m->mf_name);
   4548 				}
   4549 				milter_changeheader(m, response, rlen, e);
   4550 				break;
   4551 
   4552 			  case SMFIR_CHGFROM:
   4553 				if (!bitset(SMFIF_CHGFROM, m->mf_fflags))
   4554 				{
   4555 					if (MilterLogLevel > 9)
   4556 						sm_syslog(LOG_WARNING, e->e_id,
   4557 							  "milter_data(%s) lied about changing sender, honoring request anyway",
   4558 							  m->mf_name);
   4559 				}
   4560 				milter_chgfrom(response, rlen, e);
   4561 				break;
   4562 
   4563 			  case SMFIR_ADDRCPT:
   4564 				if (!bitset(SMFIF_ADDRCPT, m->mf_fflags))
   4565 				{
   4566 					if (MilterLogLevel > 9)
   4567 						sm_syslog(LOG_WARNING, e->e_id,
   4568 							  "milter_data(%s) lied about adding recipients, honoring request anyway",
   4569 							  m->mf_name);
   4570 				}
   4571 				milter_addrcpt(response, rlen, e);
   4572 				break;
   4573 
   4574 			  case SMFIR_ADDRCPT_PAR:
   4575 				if (!bitset(SMFIF_ADDRCPT_PAR, m->mf_fflags))
   4576 				{
   4577 					if (MilterLogLevel > 9)
   4578 						sm_syslog(LOG_WARNING, e->e_id,
   4579 							  "milter_data(%s) lied about adding recipients with parameters, honoring request anyway",
   4580 							  m->mf_name);
   4581 				}
   4582 				milter_addrcpt_par(response, rlen, e);
   4583 				break;
   4584 
   4585 			  case SMFIR_DELRCPT:
   4586 				if (!bitset(SMFIF_DELRCPT, m->mf_fflags))
   4587 				{
   4588 					if (MilterLogLevel > 9)
   4589 						sm_syslog(LOG_WARNING, e->e_id,
   4590 							  "milter_data(%s): lied about removing recipients, honoring request anyway",
   4591 							  m->mf_name);
   4592 				}
   4593 				milter_delrcpt(response, rlen, e);
   4594 				break;
   4595 
   4596 			  case SMFIR_REPLBODY:
   4597 				if (!bitset(SMFIF_MODBODY, m->mf_fflags))
   4598 				{
   4599 					if (MilterLogLevel > 0)
   4600 						sm_syslog(LOG_ERR, e->e_id,
   4601 							  "milter_data(%s): lied about replacing body, rejecting request and tempfailing message",
   4602 							  m->mf_name);
   4603 					replfailed = true;
   4604 					break;
   4605 				}
   4606 
   4607 				/* already failed in attempt */
   4608 				if (replfailed)
   4609 					break;
   4610 
   4611 				if (!dfopen)
   4612 				{
   4613 					if (milter_reopen_df(e) < 0)
   4614 					{
   4615 						replfailed = true;
   4616 						break;
   4617 					}
   4618 					dfopen = true;
   4619 					rewind = true;
   4620 				}
   4621 
   4622 				if (milter_replbody(response, rlen,
   4623 						    newfilter, e) < 0)
   4624 					replfailed = true;
   4625 				newfilter = false;
   4626 				replbody = true;
   4627 				break;
   4628 
   4629 			  default:
   4630 				/* Invalid response to command */
   4631 				if (MilterLogLevel > 0)
   4632 					sm_syslog(LOG_ERR, e->e_id,
   4633 						  "milter_data(%s): returned bogus response %c",
   4634 						  m->mf_name, rcmd);
   4635 				milter_error(m, e);
   4636 				break;
   4637 			}
   4638 			if (rcmd != SMFIR_REPLYCODE && response != NULL)
   4639 			{
   4640 				sm_free(response); /* XXX */
   4641 				response = NULL;
   4642 			}
   4643 
   4644 			if (m->mf_state == SMFS_ERROR)
   4645 				break;
   4646 		}
   4647 
   4648 		if (replbody && !replfailed)
   4649 		{
   4650 			/* flush possible buffered character */
   4651 			milter_replbody(NULL, 0, !replbody, e);
   4652 			replbody = false;
   4653 		}
   4654 
   4655 		if (m->mf_state == SMFS_ERROR)
   4656 		{
   4657 			MILTER_CHECK_ERROR(false, continue);
   4658 			goto finishup;
   4659 		}
   4660 	}
   4661 
   4662 finishup:
   4663 	/* leave things in the expected state if we touched it */
   4664 	if (replfailed)
   4665 	{
   4666 		if (*state == SMFIR_CONTINUE ||
   4667 		    *state == SMFIR_ACCEPT)
   4668 		{
   4669 			*state = SMFIR_TEMPFAIL;
   4670 			SM_FREE_CLR(response);
   4671 		}
   4672 
   4673 		if (dfopen)
   4674 		{
   4675 			(void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
   4676 			e->e_dfp = NULL;
   4677 			e->e_flags &= ~EF_HAS_DF;
   4678 			dfopen = false;
   4679 		}
   4680 		rewind = false;
   4681 	}
   4682 
   4683 	if ((dfopen && milter_reset_df(e) < 0) ||
   4684 	    (rewind && bfrewind(e->e_dfp) < 0))
   4685 	{
   4686 		save_errno = errno;
   4687 		ExitStat = EX_IOERR;
   4688 
   4689 		/*
   4690 		**  If filter told us to keep message but we had
   4691 		**  an error, we can't really keep it, tempfail it.
   4692 		*/
   4693 
   4694 		if (*state == SMFIR_CONTINUE ||
   4695 		    *state == SMFIR_ACCEPT)
   4696 		{
   4697 			*state = SMFIR_TEMPFAIL;
   4698 			SM_FREE_CLR(response);
   4699 		}
   4700 
   4701 		errno = save_errno;
   4702 		syserr("milter_data: %s/%cf%s: read error",
   4703 		       qid_printqueue(e->e_qgrp, e->e_qdir),
   4704 		       DATAFL_LETTER, e->e_id);
   4705 	}
   4706 
   4707 	MILTER_CHECK_DONE_MSG();
   4708 	if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
   4709 		sm_syslog(LOG_INFO, e->e_id, "Milter: reject, data");
   4710 	return response;
   4711 }
   4712 
   4713 /*
   4714 **  MILTER_UNKNOWN -- send any unrecognized or unimplemented command
   4715 **			string to milter filters
   4716 **
   4717 **	Parameters:
   4718 **		smtpcmd -- the string itself.
   4719 **		e -- current envelope.
   4720 **		state -- return state from response.
   4721 **
   4722 **
   4723 **	Returns:
   4724 **		response string (may be NULL)
   4725 */
   4726 
   4727 char *
   4728 milter_unknown(smtpcmd, e, state)
   4729 	char *smtpcmd;
   4730 	ENVELOPE *e;
   4731 	char *state;
   4732 {
   4733 	if (tTd(64, 10))
   4734 		sm_dprintf("milter_unknown(%s)\n", smtpcmd);
   4735 
   4736 	return milter_command(SMFIC_UNKNOWN, smtpcmd, strlen(smtpcmd) + 1,
   4737 				NULL, e, state, "unknown", false);
   4738 }
   4739 
   4740 /*
   4741 **  MILTER_QUIT -- informs the filter(s) we are done and closes connection(s)
   4742 **
   4743 **	Parameters:
   4744 **		e -- current envelope.
   4745 **
   4746 **	Returns:
   4747 **		none
   4748 */
   4749 
   4750 void
   4751 milter_quit(e)
   4752 	ENVELOPE *e;
   4753 {
   4754 	int i;
   4755 
   4756 	if (tTd(64, 10))
   4757 		sm_dprintf("milter_quit(%s)\n", e->e_id);
   4758 
   4759 	for (i = 0; InputFilters[i] != NULL; i++)
   4760 		milter_quit_filter(InputFilters[i], e);
   4761 }
   4762 
   4763 /*
   4764 **  MILTER_ABORT -- informs the filter(s) that we are aborting current message
   4765 **
   4766 **	Parameters:
   4767 **		e -- current envelope.
   4768 **
   4769 **	Returns:
   4770 **		none
   4771 */
   4772 
   4773 void
   4774 milter_abort(e)
   4775 	ENVELOPE *e;
   4776 {
   4777 	int i;
   4778 
   4779 	if (tTd(64, 10))
   4780 		sm_dprintf("milter_abort\n");
   4781 
   4782 	for (i = 0; InputFilters[i] != NULL; i++)
   4783 	{
   4784 		struct milter *m = InputFilters[i];
   4785 
   4786 		/* sanity checks */
   4787 		if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG)
   4788 			continue;
   4789 
   4790 		milter_abort_filter(m, e);
   4791 	}
   4792 }
   4793 #endif /* MILTER */
   4794