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