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