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