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