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