xref: /freebsd/contrib/sendmail/src/milter.c (revision 17d6c636720d00f77e5d098daf4c278f89d84f7b)
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.53 2001/08/15 02:01:03 ca 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 'S':		/* socket */
1136 			if (p == NULL)
1137 				m->mf_conn = NULL;
1138 			else
1139 				m->mf_conn = newstr(p);
1140 			break;
1141 
1142 		  case 'F':		/* Milter flags configured on MTA */
1143 			for (; *p != '\0'; p++)
1144 			{
1145 				if (!(isascii(*p) && isspace(*p)))
1146 					setbitn(bitidx(*p), m->mf_flags);
1147 			}
1148 			break;
1149 
1150 		  case 'T':		/* timeouts */
1151 			milter_parse_timeouts(p, m);
1152 			break;
1153 
1154 		  default:
1155 			syserr("X%s: unknown filter equate %c=",
1156 			       m->mf_name, fcode);
1157 			break;
1158 		}
1159 		p = delimptr;
1160 	}
1161 
1162 	/* early check for errors */
1163 	(void) milter_open(m, TRUE, CurEnv);
1164 
1165 	/* enter the filter into the symbol table */
1166 	s = stab(m->mf_name, ST_MILTER, ST_ENTER);
1167 	if (s->s_milter != NULL)
1168 		syserr("X%s: duplicate filter definition", m->mf_name);
1169 	else
1170 		s->s_milter = m;
1171 }
1172 /*
1173 **  MILTER_PARSE_LIST -- parse option list into an array
1174 **
1175 **	Called when reading configuration file.
1176 **
1177 **	Parameters:
1178 **		spec -- the filter list.
1179 **		list -- the array to fill in.
1180 **		max -- the maximum number of entries in list.
1181 **
1182 **	Returns:
1183 **		none
1184 */
1185 
1186 void
1187 milter_parse_list(spec, list, max)
1188 	char *spec;
1189 	struct milter **list;
1190 	int max;
1191 {
1192 	int numitems = 0;
1193 	register char *p;
1194 
1195 	/* leave one for the NULL signifying the end of the list */
1196 	max--;
1197 
1198 	for (p = spec; p != NULL; )
1199 	{
1200 		STAB *s;
1201 
1202 		while (isascii(*p) && isspace(*p))
1203 			p++;
1204 		if (*p == '\0')
1205 			break;
1206 		spec = p;
1207 
1208 		if (numitems >= max)
1209 		{
1210 			syserr("Too many filters defined, %d max", max);
1211 			if (max > 0)
1212 				list[0] = NULL;
1213 			return;
1214 		}
1215 		p = strpbrk(p, ",");
1216 		if (p != NULL)
1217 			*p++ = '\0';
1218 
1219 		s = stab(spec, ST_MILTER, ST_FIND);
1220 		if (s == NULL)
1221 		{
1222 			syserr("InputFilter %s not defined", spec);
1223 			ExitStat = EX_CONFIG;
1224 			return;
1225 		}
1226 		list[numitems++] = s->s_milter;
1227 	}
1228 	list[numitems] = NULL;
1229 }
1230 /*
1231 **  MILTER_PARSE_TIMEOUTS -- parse timeout list
1232 **
1233 **	Called when reading configuration file.
1234 **
1235 **	Parameters:
1236 **		spec -- the timeout list.
1237 **		m -- milter to set.
1238 **
1239 **	Returns:
1240 **		none
1241 */
1242 
1243 static void
1244 milter_parse_timeouts(spec, m)
1245 	char *spec;
1246 	struct milter *m;
1247 {
1248 	char fcode;
1249 	register char *p;
1250 
1251 	p = spec;
1252 
1253 	/* now scan through and assign info from the fields */
1254 	while (*p != '\0')
1255 	{
1256 		char *delimptr;
1257 
1258 		while (*p != '\0' &&
1259 		       (*p == ';' || (isascii(*p) && isspace(*p))))
1260 			p++;
1261 
1262 		/* p now points to field code */
1263 		fcode = *p;
1264 		while (*p != '\0' && *p != ':')
1265 			p++;
1266 		if (*p++ != ':')
1267 		{
1268 			syserr("X%s, T=: `:' expected", m->mf_name);
1269 			return;
1270 		}
1271 		while (isascii(*p) && isspace(*p))
1272 			p++;
1273 
1274 		/* p now points to the field body */
1275 		p = munchstring(p, &delimptr, ';');
1276 
1277 		/* install the field into the filter struct */
1278 		switch (fcode)
1279 		{
1280 		  case 'C':
1281 			m->mf_timeout[SMFTO_CONNECT] = convtime(p, 's');
1282 			if (tTd(64, 5))
1283 				printf("X%s: %c=%ld\n",
1284 				       m->mf_name, fcode,
1285 				       (u_long) m->mf_timeout[SMFTO_CONNECT]);
1286 			break;
1287 
1288 		  case 'S':
1289 			m->mf_timeout[SMFTO_WRITE] = convtime(p, 's');
1290 			if (tTd(64, 5))
1291 				printf("X%s: %c=%ld\n",
1292 				       m->mf_name, fcode,
1293 				       (u_long) m->mf_timeout[SMFTO_WRITE]);
1294 			break;
1295 
1296 		  case 'R':
1297 			m->mf_timeout[SMFTO_READ] = convtime(p, 's');
1298 			if (tTd(64, 5))
1299 				printf("X%s: %c=%ld\n",
1300 				       m->mf_name, fcode,
1301 				       (u_long) m->mf_timeout[SMFTO_READ]);
1302 			break;
1303 
1304 		  case 'E':
1305 			m->mf_timeout[SMFTO_EOM] = convtime(p, 's');
1306 			if (tTd(64, 5))
1307 				printf("X%s: %c=%ld\n",
1308 				       m->mf_name, fcode,
1309 				       (u_long) m->mf_timeout[SMFTO_EOM]);
1310 			break;
1311 
1312 		  default:
1313 			if (tTd(64, 5))
1314 				printf("X%s: %c unknown\n",
1315 				       m->mf_name, fcode);
1316 			syserr("X%s: unknown filter timeout %c",
1317 			       m->mf_name, fcode);
1318 			break;
1319 		}
1320 		p = delimptr;
1321 	}
1322 }
1323 /*
1324 **  MILTER_SET_OPTION -- set an individual milter option
1325 **
1326 **	Parameters:
1327 **		name -- the name of the option.
1328 **		val -- the value of the option.
1329 **		sticky -- if set, don't let other setoptions override
1330 **			this value.
1331 **
1332 **	Returns:
1333 **		none.
1334 */
1335 
1336 /* set if Milter sub-option is stuck */
1337 static BITMAP256	StickyMilterOpt;
1338 
1339 static struct milteropt
1340 {
1341 	char	*mo_name;	/* long name of milter option */
1342 	u_char	mo_code;	/* code for option */
1343 } MilterOptTab[] =
1344 {
1345 # define MO_MACROS_CONNECT		0x01
1346 	{ "macros.connect",		MO_MACROS_CONNECT		},
1347 # define MO_MACROS_HELO			0x02
1348 	{ "macros.helo",		MO_MACROS_HELO			},
1349 # define MO_MACROS_ENVFROM		0x03
1350 	{ "macros.envfrom",		MO_MACROS_ENVFROM		},
1351 # define MO_MACROS_ENVRCPT		0x04
1352 	{ "macros.envrcpt",		MO_MACROS_ENVRCPT		},
1353 	{ NULL,				0				},
1354 };
1355 
1356 void
1357 milter_set_option(name, val, sticky)
1358 	char *name;
1359 	char *val;
1360 	bool sticky;
1361 {
1362 	int nummac = 0;
1363 	register struct milteropt *mo;
1364 	char *p;
1365 	char **macros = NULL;
1366 
1367 	if (tTd(37, 2) || tTd(64, 5))
1368 		dprintf("milter_set_option(%s = %s)", name, val);
1369 
1370 	for (mo = MilterOptTab; mo->mo_name != NULL; mo++)
1371 	{
1372 		if (strcasecmp(mo->mo_name, name) == 0)
1373 			break;
1374 	}
1375 
1376 	if (mo->mo_name == NULL)
1377 		syserr("milter_set_option: invalid Milter option %s", name);
1378 
1379 	/*
1380 	**  See if this option is preset for us.
1381 	*/
1382 
1383 	if (!sticky && bitnset(mo->mo_code, StickyMilterOpt))
1384 	{
1385 		if (tTd(37, 2) || tTd(64,5))
1386 			dprintf(" (ignored)\n");
1387 		return;
1388 	}
1389 
1390 	if (tTd(37, 2) || tTd(64,5))
1391 		dprintf("\n");
1392 
1393 	switch (mo->mo_code)
1394 	{
1395 	  case MO_MACROS_CONNECT:
1396 		if (macros == NULL)
1397 			macros = MilterConnectMacros;
1398 		/* FALLTHROUGH */
1399 
1400 	  case MO_MACROS_HELO:
1401 		if (macros == NULL)
1402 			macros = MilterHeloMacros;
1403 		/* FALLTHROUGH */
1404 
1405 	  case MO_MACROS_ENVFROM:
1406 		if (macros == NULL)
1407 			macros = MilterEnvFromMacros;
1408 		/* FALLTHROUGH */
1409 
1410 	  case MO_MACROS_ENVRCPT:
1411 		if (macros == NULL)
1412 			macros = MilterEnvRcptMacros;
1413 
1414 		p = newstr(val);
1415 		while (*p != '\0')
1416 		{
1417 			char *macro;
1418 
1419 			/* Skip leading commas, spaces */
1420 			while (*p != '\0' &&
1421 			       (*p == ',' || (isascii(*p) && isspace(*p))))
1422 				p++;
1423 
1424 			if (*p == '\0')
1425 				break;
1426 
1427 			/* Find end of macro */
1428 			macro = p;
1429 			while (*p != '\0' && *p != ',' &&
1430 			       isascii(*p) && !isspace(*p))
1431 				p++;
1432 			if (*p != '\0')
1433 				*p++ = '\0';
1434 
1435 			if (nummac >= MAXFILTERMACROS)
1436 			{
1437 				syserr("milter_set_option: too many macros in Milter.%s (max %d)",
1438 				       name, MAXFILTERMACROS);
1439 				macros[nummac] = NULL;
1440 				break;
1441 			}
1442 			macros[nummac++] = macro;
1443 		}
1444 		macros[nummac] = NULL;
1445 		break;
1446 
1447 	  default:
1448 		syserr("milter_set_option: invalid Milter option %s", name);
1449 		break;
1450 	}
1451 
1452 	if (sticky)
1453 		setbitn(mo->mo_code, StickyMilterOpt);
1454 }
1455 /*
1456 **  MILTER_REOPEN_DF -- open & truncate the df file (for replbody)
1457 **
1458 **	Parameters:
1459 **		e -- current envelope.
1460 **
1461 **	Returns:
1462 **		0 if succesful, -1 otherwise
1463 */
1464 
1465 static int
1466 milter_reopen_df(e)
1467 	ENVELOPE *e;
1468 {
1469 	char dfname[MAXPATHLEN];
1470 
1471 	(void) strlcpy(dfname, queuename(e, 'd'), sizeof dfname);
1472 
1473 	/*
1474 	**  In SuperSafe mode, e->e_dfp is a read-only FP so
1475 	**  close and reopen writable (later close and reopen
1476 	**  read only again).
1477 	**
1478 	**  In !SuperSafe mode, e->e_dfp still points at the
1479 	**  buffered file I/O descriptor, still open for writing
1480 	**  so there isn't as much work to do, just truncate it
1481 	**  and go.
1482 	*/
1483 
1484 	if (SuperSafe)
1485 	{
1486 		/* close read-only df */
1487 		if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL)
1488 		{
1489 			(void) fclose(e->e_dfp);
1490 			e->e_flags &= ~EF_HAS_DF;
1491 		}
1492 
1493 		/* open writable */
1494 		if ((e->e_dfp = fopen(dfname, "w+")) == NULL)
1495 		{
1496 			MILTER_DF_ERROR("milter_reopen_df: fopen %s: %s");
1497 			return -1;
1498 		}
1499 	}
1500 	else if (e->e_dfp == NULL)
1501 	{
1502 		/* shouldn't happen */
1503 		errno = ENOENT;
1504 		MILTER_DF_ERROR("milter_reopen_df: NULL e_dfp (%s: %s)");
1505 		return -1;
1506 	}
1507 	return 0;
1508 }
1509 /*
1510 **  MILTER_RESET_DF -- re-open read-only the df file (for replbody)
1511 **
1512 **	Parameters:
1513 **		e -- current envelope.
1514 **
1515 **	Returns:
1516 **		0 if succesful, -1 otherwise
1517 */
1518 
1519 static int
1520 milter_reset_df(e)
1521 	ENVELOPE *e;
1522 {
1523 	int afd;
1524 	char dfname[MAXPATHLEN];
1525 
1526 	(void) strlcpy(dfname, queuename(e, 'd'), sizeof dfname);
1527 
1528 	if (fflush(e->e_dfp) != 0 || ferror(e->e_dfp))
1529 	{
1530 		MILTER_DF_ERROR("milter_reset_df: error writing/flushing %s: %s");
1531 		return -1;
1532 	}
1533 	else if (!SuperSafe)
1534 	{
1535 		/* skip next few clauses */
1536 		/* EMPTY */
1537 	}
1538 	else if ((afd = fileno(e->e_dfp)) >= 0 && fsync(afd) < 0)
1539 	{
1540 		MILTER_DF_ERROR("milter_reset_df: error sync'ing %s: %s");
1541 		return -1;
1542 	}
1543 	else if (fclose(e->e_dfp) < 0)
1544 	{
1545 		MILTER_DF_ERROR("milter_reset_df: error closing %s: %s");
1546 		return -1;
1547 	}
1548 	else if ((e->e_dfp = fopen(dfname, "r")) == NULL)
1549 	{
1550 		MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s");
1551 		return -1;
1552 	}
1553 	else
1554 		e->e_flags |= EF_HAS_DF;
1555 	return 0;
1556 }
1557 /*
1558 **  MILTER_CAN_DELRCPTS -- can any milter filters delete recipients?
1559 **
1560 **	Parameters:
1561 **		none
1562 **
1563 **	Returns:
1564 **		TRUE if any filter deletes recipients, FALSE otherwise
1565 */
1566 
1567 bool
1568 milter_can_delrcpts()
1569 {
1570 	bool can = FALSE;
1571 	int i;
1572 
1573 	if (tTd(64, 10))
1574 		dprintf("milter_can_delrcpts:");
1575 
1576 	for (i = 0; InputFilters[i] != NULL; i++)
1577 	{
1578 		struct milter *m = InputFilters[i];
1579 
1580 		if (bitset(SMFIF_DELRCPT, m->mf_fflags))
1581 		{
1582 			can = TRUE;
1583 			break;
1584 		}
1585 	}
1586 	if (tTd(64, 10))
1587 		dprintf("%s\n", can ? "TRUE" : "FALSE");
1588 
1589 	return can;
1590 }
1591 /*
1592 **  MILTER_QUIT_FILTER -- close down a single filter
1593 **
1594 **	Parameters:
1595 **		m -- milter structure of filter to close down.
1596 **		e -- current envelope.
1597 **
1598 **	Returns:
1599 **		none
1600 */
1601 
1602 static void
1603 milter_quit_filter(m, e)
1604 	struct milter *m;
1605 	ENVELOPE *e;
1606 {
1607 	if (tTd(64, 10))
1608 		dprintf("milter_quit_filter(%s)\n", m->mf_name);
1609 
1610 	/* Never replace error state */
1611 	if (m->mf_state == SMFS_ERROR)
1612 		return;
1613 
1614 	if (m->mf_sock < 0 ||
1615 	    m->mf_state == SMFS_CLOSED ||
1616 	    m->mf_state == SMFS_READY)
1617 	{
1618 		m->mf_sock = -1;
1619 		m->mf_state = SMFS_CLOSED;
1620 		return;
1621 	}
1622 
1623 	(void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0,
1624 			    m->mf_timeout[SMFTO_WRITE], e);
1625 	if (m->mf_sock >= 0)
1626 	{
1627 		(void) close(m->mf_sock);
1628 		m->mf_sock = -1;
1629 	}
1630 	if (m->mf_state != SMFS_ERROR)
1631 		m->mf_state = SMFS_CLOSED;
1632 }
1633 /*
1634 **  MILTER_ABORT_FILTER -- tell filter to abort current message
1635 **
1636 **	Parameters:
1637 **		m -- milter structure of filter to abort.
1638 **		e -- current envelope.
1639 **
1640 **	Returns:
1641 **		none
1642 */
1643 
1644 static void
1645 milter_abort_filter(m, e)
1646 	struct milter *m;
1647 	ENVELOPE *e;
1648 {
1649 	if (tTd(64, 10))
1650 		dprintf("milter_abort_filter(%s)\n", m->mf_name);
1651 
1652 	if (m->mf_sock < 0 ||
1653 	    m->mf_state != SMFS_INMSG)
1654 		return;
1655 
1656 	(void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0,
1657 			    m->mf_timeout[SMFTO_WRITE], e);
1658 	if (m->mf_state != SMFS_ERROR)
1659 		m->mf_state = SMFS_DONE;
1660 }
1661 /*
1662 **  MILTER_SEND_MACROS -- provide macros to the filters
1663 **
1664 **	Parameters:
1665 **		m -- milter to send macros to.
1666 **		macros -- macros to send for filter smfi_getsymval().
1667 **		cmd -- which command the macros are associated with.
1668 **		e -- current envelope (for macro access).
1669 **
1670 **	Returns:
1671 **		none
1672 */
1673 
1674 static void
1675 milter_send_macros(m, macros, cmd, e)
1676 	struct milter *m;
1677 	char **macros;
1678 	char cmd;
1679 	ENVELOPE *e;
1680 {
1681 	int i;
1682 	int mid;
1683 	char *v;
1684 	char *buf, *bp;
1685 	ssize_t s;
1686 
1687 	/* sanity check */
1688 	if (macros == NULL || macros[0] == NULL)
1689 		return;
1690 
1691 	/* put together data */
1692 	s = 1;			/* for the command character */
1693 	for (i = 0; macros[i] != NULL; i++)
1694 	{
1695 		mid = macid(macros[i], NULL);
1696 		if (mid == 0)
1697 			continue;
1698 		v = macvalue(mid, e);
1699 		if (v == NULL)
1700 			continue;
1701 		s += strlen(macros[i]) + 1 + strlen(v) + 1;
1702 	}
1703 
1704 	buf = (char *)xalloc(s);
1705 	bp = buf;
1706 	*bp++ = cmd;
1707 	for (i = 0; macros[i] != NULL; i++)
1708 	{
1709 		mid = macid(macros[i], NULL);
1710 		if (mid == 0)
1711 			continue;
1712 		v = macvalue(mid, e);
1713 		if (v == NULL)
1714 			continue;
1715 
1716 		if (tTd(64, 10))
1717 			dprintf("milter_send_macros(%s, %c): %s=%s\n",
1718 				m->mf_name, cmd, macros[i], v);
1719 
1720 		(void) strlcpy(bp, macros[i], s - (bp - buf));
1721 		bp += strlen(bp) + 1;
1722 		(void) strlcpy(bp, v, s - (bp - buf));
1723 		bp += strlen(bp) + 1;
1724 	}
1725 	(void) milter_write(m, SMFIC_MACRO, buf, s,
1726 			    m->mf_timeout[SMFTO_WRITE], e);
1727 	sm_free(buf);
1728 }
1729 
1730 /*
1731 **  MILTER_SEND_COMMAND -- send a command and return the response for a filter
1732 **
1733 **	Parameters:
1734 **		m -- current milter filter
1735 **		command -- command to send.
1736 **		data -- optional command data.
1737 **		sz -- length of buf.
1738 **		e -- current envelope (for e->e_id).
1739 **		state -- return state word.
1740 **
1741 **	Returns:
1742 **		response string (may be NULL)
1743 */
1744 
1745 static char *
1746 milter_send_command(m, command, data, sz, e, state)
1747 	struct milter *m;
1748 	char command;
1749 	void *data;
1750 	ssize_t sz;
1751 	ENVELOPE *e;
1752 	char *state;
1753 {
1754 	char rcmd;
1755 	ssize_t rlen;
1756 	u_long skipflag;
1757 	char *defresponse;
1758 	char *response;
1759 
1760 	if (tTd(64, 10))
1761 		dprintf("milter_send_command(%s): cmd %c len %ld\n",
1762 			m->mf_name, (char) command, (long) sz);
1763 
1764 	/* find skip flag and default failure */
1765 	switch (command)
1766 	{
1767 	  case SMFIC_CONNECT:
1768 		skipflag = SMFIP_NOCONNECT;
1769 		defresponse = "554 Command rejected";
1770 		break;
1771 
1772 	  case SMFIC_HELO:
1773 		skipflag = SMFIP_NOHELO;
1774 		defresponse = "550 Command rejected";
1775 		break;
1776 
1777 	  case SMFIC_MAIL:
1778 		skipflag = SMFIP_NOMAIL;
1779 		defresponse = "550 5.7.1 Command rejected";
1780 		break;
1781 
1782 	  case SMFIC_RCPT:
1783 		skipflag = SMFIP_NORCPT;
1784 		defresponse = "550 5.7.1 Command rejected";
1785 		break;
1786 
1787 	  case SMFIC_HEADER:
1788 		skipflag = SMFIP_NOHDRS;
1789 		defresponse = "550 5.7.1 Command rejected";
1790 		break;
1791 
1792 	  case SMFIC_BODY:
1793 		skipflag = SMFIP_NOBODY;
1794 		defresponse = "554 5.7.1 Command rejected";
1795 		break;
1796 
1797 	  case SMFIC_EOH:
1798 		skipflag = SMFIP_NOEOH;
1799 		defresponse = "550 5.7.1 Command rejected";
1800 		break;
1801 
1802 	  case SMFIC_BODYEOB:
1803 	  case SMFIC_OPTNEG:
1804 	  case SMFIC_MACRO:
1805 	  case SMFIC_ABORT:
1806 	  case SMFIC_QUIT:
1807 		/* NOTE: not handled by milter_send_command() */
1808 		/* FALLTHROUGH */
1809 
1810 	  default:
1811 		skipflag = 0;
1812 		defresponse = "550 5.7.1 Command rejected";
1813 		break;
1814 	}
1815 
1816 	/* check if filter wants this command */
1817 	if (skipflag != 0 &&
1818 	    bitset(skipflag, m->mf_pflags))
1819 		return NULL;
1820 
1821 
1822 	(void) milter_write(m, command, data, sz,
1823 			    m->mf_timeout[SMFTO_WRITE], e);
1824 	if (m->mf_state == SMFS_ERROR)
1825 	{
1826 		MILTER_CHECK_ERROR(/* EMPTY */;);
1827 		return NULL;
1828 	}
1829 
1830 	response = milter_read(m, &rcmd, &rlen,
1831 			       m->mf_timeout[SMFTO_READ], e);
1832 	if (m->mf_state == SMFS_ERROR)
1833 	{
1834 		MILTER_CHECK_ERROR(/* EMPTY */;);
1835 		return NULL;
1836 	}
1837 
1838 	if (tTd(64, 10))
1839 		dprintf("milter_send_command(%s): returned %c\n",
1840 			m->mf_name, (char) rcmd);
1841 
1842 	switch (rcmd)
1843 	{
1844 	  case SMFIR_REPLYCODE:
1845 		MILTER_CHECK_REPLYCODE(defresponse);
1846 		/* FALLTHROUGH */
1847 
1848 	  case SMFIR_REJECT:
1849 	  case SMFIR_DISCARD:
1850 	  case SMFIR_TEMPFAIL:
1851 		*state = rcmd;
1852 		break;
1853 
1854 	  case SMFIR_ACCEPT:
1855 		/* this filter is done with message/connection */
1856 		if (command == SMFIC_HELO ||
1857 		    command == SMFIC_CONNECT)
1858 			m->mf_state = SMFS_CLOSABLE;
1859 		else
1860 			m->mf_state = SMFS_DONE;
1861 		break;
1862 
1863 	  case SMFIR_CONTINUE:
1864 		/* if MAIL command is ok, filter is in message state */
1865 		if (command == SMFIC_MAIL)
1866 			m->mf_state = SMFS_INMSG;
1867 		break;
1868 
1869 	  default:
1870 		/* Invalid response to command */
1871 		if (LogLevel > 0)
1872 			sm_syslog(LOG_ERR, e->e_id,
1873 				  "milter_send_command(%s): returned bogus response %c",
1874 				  m->mf_name, rcmd);
1875 		milter_error(m);
1876 		break;
1877 	}
1878 
1879 	if (*state != SMFIR_REPLYCODE &&
1880 	    response != NULL)
1881 	{
1882 		sm_free(response);
1883 		response = NULL;
1884 	}
1885 	return response;
1886 }
1887 
1888 /*
1889 **  MILTER_COMMAND -- send a command and return the response for each filter
1890 **
1891 **	Parameters:
1892 **		command -- command to send.
1893 **		data -- optional command data.
1894 **		sz -- length of buf.
1895 **		macros -- macros to send for filter smfi_getsymval().
1896 **		e -- current envelope (for macro access).
1897 **		state -- return state word.
1898 **
1899 **	Returns:
1900 **		response string (may be NULL)
1901 */
1902 
1903 static char *
1904 milter_command(command, data, sz, macros, e, state)
1905 	char command;
1906 	void *data;
1907 	ssize_t sz;
1908 	char **macros;
1909 	ENVELOPE *e;
1910 	char *state;
1911 {
1912 	int i;
1913 	char *response = NULL;
1914 
1915 	if (tTd(64, 10))
1916 		dprintf("milter_command: cmd %c len %ld\n",
1917 			(char) command, (long) sz);
1918 
1919 	*state = SMFIR_CONTINUE;
1920 	for (i = 0; InputFilters[i] != NULL; i++)
1921 	{
1922 		struct milter *m = InputFilters[i];
1923 
1924 		/* previous problem? */
1925 		if (m->mf_state == SMFS_ERROR)
1926 		{
1927 			MILTER_CHECK_ERROR(continue);
1928 			break;
1929 		}
1930 
1931 		/* sanity check */
1932 		if (m->mf_sock < 0 ||
1933 		    (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
1934 			continue;
1935 
1936 		/* send macros (regardless of whether we send command) */
1937 		if (macros != NULL && macros[0] != NULL)
1938 		{
1939 			milter_send_macros(m, macros, command, e);
1940 			if (m->mf_state == SMFS_ERROR)
1941 			{
1942 				MILTER_CHECK_ERROR(continue);
1943 				break;
1944 			}
1945 		}
1946 
1947 		response = milter_send_command(m, command, data, sz, e, state);
1948 		if (*state != SMFIR_CONTINUE)
1949 			break;
1950 	}
1951 	return response;
1952 }
1953 /*
1954 **  MILTER_NEGOTIATE -- get version and flags from filter
1955 **
1956 **	Parameters:
1957 **		m -- milter filter structure.
1958 **		e -- current envelope.
1959 **
1960 **	Returns:
1961 **		0 on success, -1 otherwise
1962 */
1963 
1964 static int
1965 milter_negotiate(m, e)
1966 	struct milter *m;
1967 	ENVELOPE *e;
1968 {
1969 	char rcmd;
1970 	mi_int32 fvers;
1971 	mi_int32 fflags;
1972 	mi_int32 pflags;
1973 	char *response;
1974 	ssize_t rlen;
1975 	char data[MILTER_OPTLEN];
1976 
1977 	/* sanity check */
1978 	if (m->mf_sock < 0 || m->mf_state != SMFS_OPEN)
1979 	{
1980 		if (LogLevel > 0)
1981 			sm_syslog(LOG_ERR, e->e_id,
1982 				  "milter_negotiate(%s): impossible state",
1983 				  m->mf_name);
1984 		milter_error(m);
1985 		return -1;
1986 	}
1987 
1988 	fvers = htonl(SMFI_VERSION);
1989 	fflags = htonl(SMFI_CURR_ACTS);
1990 	pflags = htonl(SMFI_CURR_PROT);
1991 	(void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES);
1992 	(void) memcpy(data + MILTER_LEN_BYTES,
1993 		      (char *) &fflags, MILTER_LEN_BYTES);
1994 	(void) memcpy(data + (MILTER_LEN_BYTES * 2),
1995 		      (char *) &pflags, MILTER_LEN_BYTES);
1996 	(void) milter_write(m, SMFIC_OPTNEG, data, sizeof data,
1997 			    m->mf_timeout[SMFTO_WRITE], e);
1998 
1999 	if (m->mf_state == SMFS_ERROR)
2000 		return -1;
2001 
2002 	response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e);
2003 	if (m->mf_state == SMFS_ERROR)
2004 		return -1;
2005 
2006 	if (rcmd != SMFIC_OPTNEG)
2007 	{
2008 		if (tTd(64, 5))
2009 			dprintf("milter_negotiate(%s): returned %c instead of %c\n",
2010 				m->mf_name, rcmd, SMFIC_OPTNEG);
2011 		if (LogLevel > 0)
2012 			sm_syslog(LOG_ERR, e->e_id,
2013 				  "milter_negotiate(%s): returned %c instead of %c",
2014 				  m->mf_name, rcmd, SMFIC_OPTNEG);
2015 		if (response != NULL)
2016 			sm_free(response);
2017 		milter_error(m);
2018 		return -1;
2019 	}
2020 
2021 	/* Make sure we have enough bytes for the version */
2022 	if (response == NULL || rlen < MILTER_LEN_BYTES)
2023 	{
2024 		if (tTd(64, 5))
2025 			dprintf("milter_negotiate(%s): did not return valid info\n",
2026 				m->mf_name);
2027 		if (LogLevel > 0)
2028 			sm_syslog(LOG_ERR, e->e_id,
2029 				  "milter_negotiate(%s): did not return valid info",
2030 				  m->mf_name);
2031 		if (response != NULL)
2032 			sm_free(response);
2033 		milter_error(m);
2034 		return -1;
2035 	}
2036 
2037 	/* extract information */
2038 	(void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES);
2039 
2040 	/* Now make sure we have enough for the feature bitmap */
2041 	if (rlen != MILTER_OPTLEN)
2042 	{
2043 		if (tTd(64, 5))
2044 			dprintf("milter_negotiate(%s): did not return enough info\n",
2045 				m->mf_name);
2046 		if (LogLevel > 0)
2047 			sm_syslog(LOG_ERR, e->e_id,
2048 				  "milter_negotiate(%s): did not return enough info",
2049 				  m->mf_name);
2050 		if (response != NULL)
2051 			sm_free(response);
2052 		milter_error(m);
2053 		return -1;
2054 	}
2055 
2056 	(void) memcpy((char *) &fflags, response + MILTER_LEN_BYTES,
2057 		      MILTER_LEN_BYTES);
2058 	(void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2),
2059 		      MILTER_LEN_BYTES);
2060 	sm_free(response);
2061 	response = NULL;
2062 
2063 	m->mf_fvers = ntohl(fvers);
2064 	m->mf_fflags = ntohl(fflags);
2065 	m->mf_pflags = ntohl(pflags);
2066 
2067 	/* check for version compatibility */
2068 	if (m->mf_fvers == 1 ||
2069 	    m->mf_fvers > SMFI_VERSION)
2070 	{
2071 		if (tTd(64, 5))
2072 			dprintf("milter_negotiate(%s): version %lu != MTA milter version %d\n",
2073 				m->mf_name, m->mf_fvers, SMFI_VERSION);
2074 		if (LogLevel > 0)
2075 			sm_syslog(LOG_ERR, e->e_id,
2076 				  "milter_negotiate(%s): version %ld != MTA milter version %d",
2077 				  m->mf_name, m->mf_fvers, SMFI_VERSION);
2078 		milter_error(m);
2079 		return -1;
2080 	}
2081 
2082 	/* check for filter feature mismatch */
2083 	if ((m->mf_fflags & SMFI_CURR_ACTS) != m->mf_fflags)
2084 	{
2085 		if (tTd(64, 5))
2086 			dprintf("milter_negotiate(%s): filter abilities 0x%lx != MTA milter abilities 0x%lx\n",
2087 				m->mf_name, m->mf_fflags,
2088 				(u_long) SMFI_CURR_ACTS);
2089 		if (LogLevel > 0)
2090 			sm_syslog(LOG_ERR, e->e_id,
2091 				  "milter_negotiate(%s): filter abilities 0x%lx != MTA milter abilities 0x%lx\n",
2092 				  m->mf_name, m->mf_fflags,
2093 				  (u_long) SMFI_CURR_ACTS);
2094 		milter_error(m);
2095 		return -1;
2096 	}
2097 
2098 	/* check for protocol feature mismatch */
2099 	if ((m->mf_pflags & SMFI_CURR_PROT) != m->mf_pflags)
2100 	{
2101 		if (tTd(64, 5))
2102 			dprintf("milter_negotiate(%s): protocol abilities 0x%lx != MTA milter abilities 0x%lx\n",
2103 				m->mf_name, m->mf_pflags,
2104 				(u_long) SMFI_CURR_PROT);
2105 		if (LogLevel > 0)
2106 			sm_syslog(LOG_ERR, e->e_id,
2107 				  "milter_negotiate(%s): protocol abilities 0x%lx != MTA milter abilities 0x%lx\n",
2108 				  m->mf_name, m->mf_pflags,
2109 				  (u_long) SMFI_CURR_PROT);
2110 		milter_error(m);
2111 		return -1;
2112 	}
2113 
2114 	if (tTd(64, 5))
2115 		dprintf("milter_negotiate(%s): version %lu, fflags 0x%lx, pflags 0x%lx\n",
2116 			m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags);
2117 	return 0;
2118 }
2119 /*
2120 **  MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands
2121 **
2122 **	Reduce code duplication by putting these checks in one place
2123 **
2124 **	Parameters:
2125 **		e -- current envelope.
2126 **
2127 **	Returns:
2128 **		none
2129 */
2130 
2131 static void
2132 milter_per_connection_check(e)
2133 	ENVELOPE *e;
2134 {
2135 	int i;
2136 
2137 	/* see if we are done with any of the filters */
2138 	for (i = 0; InputFilters[i] != NULL; i++)
2139 	{
2140 		struct milter *m = InputFilters[i];
2141 
2142 		if (m->mf_state == SMFS_CLOSABLE)
2143 			milter_quit_filter(m, e);
2144 	}
2145 }
2146 /*
2147 **  MILTER_ERROR -- Put a milter filter into error state
2148 **
2149 **	Parameters:
2150 **		m -- the broken filter.
2151 **
2152 **	Returns:
2153 **		none
2154 */
2155 
2156 static void
2157 milter_error(m)
2158 	struct milter *m;
2159 {
2160 	/*
2161 	**  We could send a quit here but
2162 	**  we may have gotten here due to
2163 	**  an I/O error so we don't want
2164 	**  to try to make things worse.
2165 	*/
2166 
2167 	if (m->mf_sock >= 0)
2168 	{
2169 		(void) close(m->mf_sock);
2170 		m->mf_sock = -1;
2171 	}
2172 	m->mf_state = SMFS_ERROR;
2173 }
2174 /*
2175 **  MILTER_HEADERS -- send headers to a single milter filter
2176 **
2177 **	Parameters:
2178 **		m -- current filter.
2179 **		e -- current envelope.
2180 **		state -- return state from response.
2181 **
2182 **	Returns:
2183 **		response string (may be NULL)
2184 */
2185 
2186 static char *
2187 milter_headers(m, e, state)
2188 	struct milter *m;
2189 	ENVELOPE *e;
2190 	char *state;
2191 {
2192 	char *response = NULL;
2193 	HDR *h;
2194 
2195 	for (h = e->e_header; h != NULL; h = h->h_link)
2196 	{
2197 		char *buf;
2198 		ssize_t s;
2199 
2200 		/* don't send over deleted headers */
2201 		if (h->h_value == NULL)
2202 		{
2203 			/* strip H_USER so not counted in milter_chgheader() */
2204 			h->h_flags &= ~H_USER;
2205 			continue;
2206 		}
2207 
2208 		/* skip auto-generated */
2209 		if (!bitset(H_USER, h->h_flags))
2210 			continue;
2211 
2212 		if (tTd(64, 10))
2213 			dprintf("milter_headers: %s: %s\n",
2214 				h->h_field, h->h_value);
2215 
2216 		s = strlen(h->h_field) + 1 +
2217 			strlen(h->h_value) + 1;
2218 		buf = (char *) xalloc(s);
2219 		snprintf(buf, s, "%s%c%s", h->h_field, '\0', h->h_value);
2220 
2221 		/* send it over */
2222 		response = milter_send_command(m, SMFIC_HEADER, buf,
2223 					       s, e, state);
2224 		sm_free(buf);
2225 		if (m->mf_state == SMFS_ERROR ||
2226 		    m->mf_state == SMFS_DONE ||
2227 		    *state != SMFIR_CONTINUE)
2228 			break;
2229 	}
2230 	return response;
2231 }
2232 /*
2233 **  MILTER_BODY -- send the body to a filter
2234 **
2235 **	Parameters:
2236 **		m -- current filter.
2237 **		e -- current envelope.
2238 **		state -- return state from response.
2239 **
2240 **	Returns:
2241 **		response string (may be NULL)
2242 */
2243 
2244 static char *
2245 milter_body(m, e, state)
2246 	struct milter *m;
2247 	ENVELOPE *e;
2248 	char *state;
2249 {
2250 	char bufchar = '\0';
2251 	char prevchar = '\0';
2252 	int c;
2253 	char *response = NULL;
2254 	char *bp;
2255 	char buf[MILTER_CHUNK_SIZE];
2256 
2257 	if (tTd(64, 10))
2258 		dprintf("milter_body\n");
2259 
2260 	if (bfrewind(e->e_dfp) < 0)
2261 	{
2262 		ExitStat = EX_IOERR;
2263 		*state = SMFIR_TEMPFAIL;
2264 		syserr("milter_body: %s/df%s: rewind error",
2265 		       qid_printqueue(e->e_queuedir), e->e_id);
2266 		return NULL;
2267 	}
2268 
2269 	bp = buf;
2270 	while ((c = getc(e->e_dfp)) != EOF)
2271 	{
2272 		/*  Change LF to CRLF */
2273 		if (c == '\n')
2274 		{
2275 			/* Not a CRLF already? */
2276 			if (prevchar != '\r')
2277 			{
2278 				/* Room for CR now? */
2279 				if (bp + 2 > &buf[sizeof buf])
2280 				{
2281 					/* No room, buffer LF */
2282 					bufchar = c;
2283 
2284 					/* and send CR now */
2285 					c = '\r';
2286 				}
2287 				else
2288 				{
2289 					/* Room to do it now */
2290 					*bp++ = '\r';
2291 					prevchar = '\r';
2292 				}
2293 			}
2294 		}
2295 		*bp++ = (char) c;
2296 		prevchar = c;
2297 		if (bp >= &buf[sizeof buf])
2298 		{
2299 			/* send chunk */
2300 			response = milter_send_command(m, SMFIC_BODY, buf,
2301 						       bp - buf, e, state);
2302 			bp = buf;
2303 			if (bufchar != '\0')
2304 			{
2305 				*bp++ = bufchar;
2306 				bufchar = '\0';
2307 				prevchar = bufchar;
2308 			}
2309 		}
2310 		if (m->mf_state == SMFS_ERROR ||
2311 		    m->mf_state == SMFS_DONE ||
2312 		    *state != SMFIR_CONTINUE)
2313 			break;
2314 	}
2315 
2316 	/* check for read errors */
2317 	if (ferror(e->e_dfp))
2318 	{
2319 		ExitStat = EX_IOERR;
2320 		if (*state == SMFIR_CONTINUE ||
2321 		    *state == SMFIR_ACCEPT)
2322 		{
2323 			*state = SMFIR_TEMPFAIL;
2324 			if (response != NULL)
2325 			{
2326 				sm_free(response);
2327 				response = NULL;
2328 			}
2329 		}
2330 		syserr("milter_body: %s/df%s: read error",
2331 		       qid_printqueue(e->e_queuedir), e->e_id);
2332 		return response;
2333 	}
2334 
2335 	/* send last body chunk */
2336 	if (bp > buf &&
2337 	    m->mf_state != SMFS_ERROR &&
2338 	    m->mf_state != SMFS_DONE &&
2339 	    *state == SMFIR_CONTINUE)
2340 	{
2341 		/* send chunk */
2342 		response = milter_send_command(m, SMFIC_BODY, buf, bp - buf,
2343 					       e, state);
2344 		bp = buf;
2345 	}
2346 	return response;
2347 }
2348 
2349 /*
2350 **  Actions
2351 */
2352 
2353 /*
2354 **  MILTER_ADDHEADER -- Add the supplied header to the message
2355 **
2356 **	Parameters:
2357 **		response -- encoded form of header/value.
2358 **		rlen -- length of response.
2359 **		e -- current envelope.
2360 **
2361 **	Returns:
2362 **		none
2363 */
2364 
2365 static void
2366 milter_addheader(response, rlen, e)
2367 	char *response;
2368 	ssize_t rlen;
2369 	ENVELOPE *e;
2370 {
2371 	char *val;
2372 	HDR *h;
2373 
2374 	if (tTd(64, 10))
2375 		dprintf("milter_addheader: ");
2376 
2377 	/* sanity checks */
2378 	if (response == NULL)
2379 	{
2380 		if (tTd(64, 10))
2381 			dprintf("NULL response\n");
2382 		return;
2383 	}
2384 
2385 	if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
2386 	{
2387 		if (tTd(64, 10))
2388 			dprintf("didn't follow protocol (total len)\n");
2389 		return;
2390 	}
2391 
2392 	/* Find separating NUL */
2393 	val = response + strlen(response) + 1;
2394 
2395 	/* another sanity check */
2396 	if (strlen(response) + strlen(val) + 2 != (size_t) rlen)
2397 	{
2398 		if (tTd(64, 10))
2399 			dprintf("didn't follow protocol (part len)\n");
2400 		return;
2401 	}
2402 
2403 	if (*response == '\0')
2404 	{
2405 		if (tTd(64, 10))
2406 			dprintf("empty field name\n");
2407 		return;
2408 	}
2409 
2410 	for (h = e->e_header; h != NULL; h = h->h_link)
2411 	{
2412 		if (strcasecmp(h->h_field, response) == 0 &&
2413 		    !bitset(H_USER, h->h_flags) &&
2414 		    !bitset(H_TRACE, h->h_flags))
2415 			break;
2416 	}
2417 
2418 	/* add to e_msgsize */
2419 	e->e_msgsize += strlen(response) + 2 + strlen(val);
2420 
2421 	if (h != NULL)
2422 	{
2423 		if (tTd(64, 10))
2424 			dprintf("Replace default header %s value with %s\n",
2425 				h->h_field, val);
2426 		h->h_value = newstr(val);
2427 		h->h_flags |= H_USER;
2428 	}
2429 	else
2430 	{
2431 		if (tTd(64, 10))
2432 			dprintf("Add %s: %s\n", response, val);
2433 		addheader(newstr(response), val, H_USER, &e->e_header);
2434 	}
2435 }
2436 /*
2437 **  MILTER_CHANGEHEADER -- Change the supplied header in the message
2438 **
2439 **	Parameters:
2440 **		response -- encoded form of header/index/value.
2441 **		rlen -- length of response.
2442 **		e -- current envelope.
2443 **
2444 **	Returns:
2445 **		none
2446 */
2447 
2448 static void
2449 milter_changeheader(response, rlen, e)
2450 	char *response;
2451 	ssize_t rlen;
2452 	ENVELOPE *e;
2453 {
2454 	mi_int32 i, index;
2455 	char *field, *val;
2456 	HDR *h, *sysheader;
2457 
2458 	if (tTd(64, 10))
2459 		dprintf("milter_changeheader: ");
2460 
2461 	/* sanity checks */
2462 	if (response == NULL)
2463 	{
2464 		if (tTd(64, 10))
2465 			dprintf("NULL response\n");
2466 		return;
2467 	}
2468 
2469 	if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
2470 	{
2471 		if (tTd(64, 10))
2472 			dprintf("didn't follow protocol (total len)\n");
2473 		return;
2474 	}
2475 
2476 	/* Find separating NUL */
2477 	(void) memcpy((char *) &i, response, MILTER_LEN_BYTES);
2478 	index = ntohl(i);
2479 	field = response + MILTER_LEN_BYTES;
2480 	val = field + strlen(field) + 1;
2481 
2482 	/* another sanity check */
2483 	if (MILTER_LEN_BYTES + strlen(field) + 1 +
2484 	    strlen(val) + 1 != (size_t) rlen)
2485 	{
2486 		if (tTd(64, 10))
2487 			dprintf("didn't follow protocol (part len)\n");
2488 		return;
2489 	}
2490 
2491 	if (*field == '\0')
2492 	{
2493 		if (tTd(64, 10))
2494 			dprintf("empty field name\n");
2495 		return;
2496 	}
2497 
2498 	sysheader = NULL;
2499 	for (h = e->e_header; h != NULL; h = h->h_link)
2500 	{
2501 		if (strcasecmp(h->h_field, field) == 0)
2502 		{
2503 			if (bitset(H_USER, h->h_flags) &&
2504 			    --index <= 0)
2505 			{
2506 				sysheader = NULL;
2507 				break;
2508 			}
2509 			else if (!bitset(H_USER, h->h_flags) &&
2510 				 !bitset(H_TRACE, h->h_flags))
2511 			{
2512 				/*
2513 				**  DRUMS msg-fmt draft says can only have
2514 				**  multiple occurences of trace fields,
2515 				**  so make sure we replace any non-trace,
2516 				**  non-user field.
2517 				*/
2518 
2519 				sysheader = h;
2520 			}
2521 		}
2522 	}
2523 
2524 	/* if not found as user-provided header at index, use sysheader */
2525 	if (h == NULL)
2526 		h = sysheader;
2527 
2528 	if (h == NULL)
2529 	{
2530 		if (*val == '\0')
2531 		{
2532 			if (tTd(64, 10))
2533 				dprintf("Delete (noop) %s:\n", field);
2534 		}
2535 		else
2536 		{
2537 			/* treat modify value with no existing header as add */
2538 			if (tTd(64, 10))
2539 				dprintf("Add %s: %s\n",	field, val);
2540 
2541 			addheader(newstr(field), val, H_USER, &e->e_header);
2542 		}
2543 		return;
2544 	}
2545 
2546 	if (tTd(64, 10))
2547 	{
2548 		if (*val == '\0')
2549 		{
2550 			dprintf("Delete%s %s: %s\n",
2551 				h == sysheader ? " (default header)" : "",
2552 				field,
2553 				h->h_value == NULL ? "<NULL>" : h->h_value);
2554 		}
2555 		else
2556 		{
2557 			dprintf("Change%s %s: from %s to %s\n",
2558 				h == sysheader ? " (default header)" : "",
2559 				field,
2560 				h->h_value == NULL ? "<NULL>" : h->h_value,
2561 				val);
2562 		}
2563 	}
2564 
2565 	if (h != sysheader && h->h_value != NULL)
2566 	{
2567 		e->e_msgsize -= strlen(h->h_value);
2568 		sm_free(h->h_value);
2569 	}
2570 
2571 	if (*val == '\0')
2572 	{
2573 		/* Remove "Field: " from message size */
2574 		if (h != sysheader)
2575 			e->e_msgsize -= strlen(h->h_field) + 2;
2576 		h->h_value = NULL;
2577 	}
2578 	else
2579 	{
2580 		h->h_value = newstr(val);
2581 		h->h_flags |= H_USER;
2582 		e->e_msgsize += strlen(h->h_value);
2583 	}
2584 }
2585 /*
2586 **  MILTER_ADDRCPT -- Add the supplied recipient to the message
2587 **
2588 **	Parameters:
2589 **		response -- encoded form of recipient address.
2590 **		rlen -- length of response.
2591 **		e -- current envelope.
2592 **
2593 **	Returns:
2594 **		none
2595 */
2596 
2597 static void
2598 milter_addrcpt(response, rlen, e)
2599 	char *response;
2600 	ssize_t rlen;
2601 	ENVELOPE *e;
2602 {
2603 	if (tTd(64, 10))
2604 		dprintf("milter_addrcpt: ");
2605 
2606 	/* sanity checks */
2607 	if (response == NULL)
2608 	{
2609 		if (tTd(64, 10))
2610 			dprintf("NULL response\n");
2611 		return;
2612 	}
2613 
2614 	if (*response == '\0' ||
2615 	    strlen(response) + 1 != (size_t) rlen)
2616 	{
2617 		if (tTd(64, 10))
2618 			dprintf("didn't follow protocol (total len %d != rlen %d)\n",
2619 				strlen(response), rlen -1);
2620 		return;
2621 	}
2622 
2623 	if (tTd(64, 10))
2624 		dprintf("%s\n", response);
2625 	(void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e);
2626 	return;
2627 }
2628 /*
2629 **  MILTER_DELRCPT -- Delete the supplied recipient from the message
2630 **
2631 **	Parameters:
2632 **		response -- encoded form of recipient address.
2633 **		rlen -- length of response.
2634 **		e -- current envelope.
2635 **
2636 **	Returns:
2637 **		none
2638 */
2639 
2640 static void
2641 milter_delrcpt(response, rlen, e)
2642 	char *response;
2643 	ssize_t rlen;
2644 	ENVELOPE *e;
2645 {
2646 	if (tTd(64, 10))
2647 		dprintf("milter_delrcpt: ");
2648 
2649 	/* sanity checks */
2650 	if (response == NULL)
2651 	{
2652 		if (tTd(64, 10))
2653 			dprintf("NULL response\n");
2654 		return;
2655 	}
2656 
2657 	if (*response == '\0' ||
2658 	    strlen(response) + 1 != (size_t) rlen)
2659 	{
2660 		if (tTd(64, 10))
2661 			dprintf("didn't follow protocol (total len)\n");
2662 		return;
2663 	}
2664 
2665 	if (tTd(64, 10))
2666 		dprintf("%s\n", response);
2667 	(void) removefromlist(response, &e->e_sendqueue, e);
2668 	return;
2669 }
2670 /*
2671 **  MILTER_REPLBODY -- Replace the current df file with new body
2672 **
2673 **	Parameters:
2674 **		response -- encoded form of new body.
2675 **		rlen -- length of response.
2676 **		newfilter -- if first time called by a new filter
2677 **		e -- current envelope.
2678 **
2679 **	Returns:
2680 **		0 upon success, -1 upon failure
2681 */
2682 
2683 static int
2684 milter_replbody(response, rlen, newfilter, e)
2685 	char *response;
2686 	ssize_t rlen;
2687 	bool newfilter;
2688 	ENVELOPE *e;
2689 {
2690 	static char prevchar;
2691 	int i;
2692 
2693 	if (tTd(64, 10))
2694 		dprintf("milter_replbody\n");
2695 
2696 	/* If a new filter, reset previous character and truncate df */
2697 	if (newfilter)
2698 	{
2699 		off_t prevsize = 0;
2700 		char dfname[MAXPATHLEN];
2701 
2702 		(void) strlcpy(dfname, queuename(e, 'd'), sizeof dfname);
2703 
2704 		/* Reset prevchar */
2705 		prevchar = '\0';
2706 
2707 		/* Get the current df information */
2708 		if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL)
2709 		{
2710 			int afd;
2711 			struct stat st;
2712 
2713 			afd = fileno(e->e_dfp);
2714 			if (afd > 0 && fstat(afd, &st) == 0)
2715 				prevsize = st.st_size;
2716 		}
2717 
2718 		/* truncate current df file */
2719 		if (bftruncate(e->e_dfp) < 0)
2720 		{
2721 			MILTER_DF_ERROR("milter_reopen_df: bftruncate %s: %s");
2722 			return -1;
2723 		}
2724 		else
2725 		{
2726 			if (prevsize > e->e_msgsize)
2727 				e->e_msgsize = 0;
2728 			else
2729 				e->e_msgsize -= prevsize;
2730 		}
2731 	}
2732 
2733 	if (response == NULL)
2734 	{
2735 		/* Flush the buffered '\r' */
2736 		if (prevchar == '\r')
2737 		{
2738 			(void) putc(prevchar, e->e_dfp);
2739 			e->e_msgsize++;
2740 		}
2741 		return 0;
2742 	}
2743 
2744 	for (i = 0; i < rlen; i++)
2745 	{
2746 		/* Buffered char from last chunk */
2747 		if (i == 0 && prevchar == '\r')
2748 		{
2749 			/* Not CRLF, output prevchar */
2750 			if (response[i] != '\n')
2751 			{
2752 				(void) putc(prevchar, e->e_dfp);
2753 				e->e_msgsize++;
2754 			}
2755 			prevchar = '\0';
2756 		}
2757 
2758 		/* Turn CRLF into LF */
2759 		if (response[i] == '\r')
2760 		{
2761 			/* check if at end of chunk */
2762 			if (i + 1 < rlen)
2763 			{
2764 				/* If LF, strip CR */
2765 				if (response[i + 1] == '\n')
2766 					i++;
2767 			}
2768 			else
2769 			{
2770 				/* check next chunk */
2771 				prevchar = '\r';
2772 				continue;
2773 			}
2774 		}
2775 		(void) putc(response[i], e->e_dfp);
2776 		e->e_msgsize++;
2777 	}
2778 	return 0;
2779 }
2780 
2781 /*
2782 **  MTA callouts
2783 */
2784 
2785 /*
2786 **  MILTER_INIT -- open and negotiate with all of the filters
2787 **
2788 **	Parameters:
2789 **		e -- current envelope.
2790 **		state -- return state from response.
2791 **
2792 **	Returns:
2793 **		none
2794 */
2795 
2796 /* ARGSUSED */
2797 void
2798 milter_init(e, state)
2799 	ENVELOPE *e;
2800 	char *state;
2801 {
2802 	int i;
2803 
2804 	if (tTd(64, 10))
2805 		dprintf("milter_init\n");
2806 
2807 	*state = SMFIR_CONTINUE;
2808 	for (i = 0; InputFilters[i] != NULL; i++)
2809 	{
2810 		struct milter *m = InputFilters[i];
2811 
2812 		m->mf_sock = milter_open(m, FALSE, e);
2813 		if (m->mf_state == SMFS_ERROR)
2814 		{
2815 			MILTER_CHECK_ERROR(continue);
2816 			break;
2817 		}
2818 
2819 		if (m->mf_sock < 0 ||
2820 		    milter_negotiate(m, e) < 0 ||
2821 		    m->mf_state == SMFS_ERROR)
2822 		{
2823 			if (tTd(64, 5))
2824 				dprintf("milter_init(%s): failed to %s\n",
2825 					m->mf_name,
2826 					m->mf_sock < 0 ? "open" : "negotiate");
2827 
2828 			/* if negotation failure, close socket */
2829 			milter_error(m);
2830 			MILTER_CHECK_ERROR(continue);
2831 		}
2832 	}
2833 
2834 	/*
2835 	**  If something temp/perm failed with one of the filters,
2836 	**  we won't be using any of them, so clear any existing
2837 	**  connections.
2838 	*/
2839 
2840 	if (*state != SMFIR_CONTINUE)
2841 		milter_quit(e);
2842 }
2843 /*
2844 **  MILTER_CONNECT -- send connection info to milter filters
2845 **
2846 **	Parameters:
2847 **		hostname -- hostname of remote machine.
2848 **		addr -- address of remote machine.
2849 **		e -- current envelope.
2850 **		state -- return state from response.
2851 **
2852 **	Returns:
2853 **		response string (may be NULL)
2854 */
2855 
2856 char *
2857 milter_connect(hostname, addr, e, state)
2858 	char *hostname;
2859 	SOCKADDR addr;
2860 	ENVELOPE *e;
2861 	char *state;
2862 {
2863 	char family;
2864 	u_short port;
2865 	char *buf, *bp;
2866 	char *response;
2867 	char *sockinfo = NULL;
2868 	ssize_t s;
2869 # if NETINET6
2870 	char buf6[INET6_ADDRSTRLEN];
2871 # endif /* NETINET6 */
2872 
2873 	if (tTd(64, 10))
2874 		dprintf("milter_connect(%s)\n", hostname);
2875 
2876 	/* gather data */
2877 	switch (addr.sa.sa_family)
2878 	{
2879 # if NETUNIX
2880 	  case AF_UNIX:
2881 		family = SMFIA_UNIX;
2882 		port = htons(0);
2883 		sockinfo = addr.sunix.sun_path;
2884 		break;
2885 # endif /* NETUNIX */
2886 
2887 # if NETINET
2888 	  case AF_INET:
2889 		family = SMFIA_INET;
2890 		port = htons(addr.sin.sin_port);
2891 		sockinfo = (char *) inet_ntoa(addr.sin.sin_addr);
2892 		break;
2893 # endif /* NETINET */
2894 
2895 # if NETINET6
2896 	  case AF_INET6:
2897 		if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr))
2898 			family = SMFIA_INET;
2899 		else
2900 			family = SMFIA_INET6;
2901 		port = htons(addr.sin6.sin6_port);
2902 		sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6,
2903 				       sizeof buf6);
2904 		if (sockinfo == NULL)
2905 			sockinfo = "";
2906 		break;
2907 # endif /* NETINET6 */
2908 
2909 	  default:
2910 		family = SMFIA_UNKNOWN;
2911 		break;
2912 	}
2913 
2914 	s = strlen(hostname) + 1 + sizeof(family);
2915 	if (family != SMFIA_UNKNOWN)
2916 		s += sizeof(port) + strlen(sockinfo) + 1;
2917 
2918 	buf = (char *)xalloc(s);
2919 	bp = buf;
2920 
2921 	/* put together data */
2922 	(void) memcpy(bp, hostname, strlen(hostname));
2923 	bp += strlen(hostname);
2924 	*bp++ = '\0';
2925 	(void) memcpy(bp, &family, sizeof family);
2926 	bp += sizeof family;
2927 	if (family != SMFIA_UNKNOWN)
2928 	{
2929 		(void) memcpy(bp, &port, sizeof port);
2930 		bp += sizeof port;
2931 
2932 		/* include trailing '\0' */
2933 		(void) memcpy(bp, sockinfo, strlen(sockinfo) + 1);
2934 	}
2935 
2936 	response = milter_command(SMFIC_CONNECT, buf, s,
2937 				  MilterConnectMacros, e, state);
2938 	sm_free(buf);
2939 
2940 	/*
2941 	**  If this message connection is done for,
2942 	**  close the filters.
2943 	*/
2944 
2945 	if (*state != SMFIR_CONTINUE)
2946 		milter_quit(e);
2947 	else
2948 		milter_per_connection_check(e);
2949 
2950 	/*
2951 	**  SMFIR_REPLYCODE can't work with connect due to
2952 	**  the requirements of SMTP.  Therefore, ignore the
2953 	**  reply code text but keep the state it would reflect.
2954 	*/
2955 
2956 	if (*state == SMFIR_REPLYCODE)
2957 	{
2958 		if (response != NULL &&
2959 		    *response == '4')
2960 			*state = SMFIR_TEMPFAIL;
2961 		else
2962 			*state = SMFIR_REJECT;
2963 		if (response != NULL)
2964 		{
2965 			sm_free(response);
2966 			response = NULL;
2967 		}
2968 	}
2969 	return response;
2970 }
2971 /*
2972 **  MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters
2973 **
2974 **	Parameters:
2975 **		helo -- argument to SMTP HELO/EHLO command.
2976 **		e -- current envelope.
2977 **		state -- return state from response.
2978 **
2979 **	Returns:
2980 **		response string (may be NULL)
2981 */
2982 
2983 char *
2984 milter_helo(helo, e, state)
2985 	char *helo;
2986 	ENVELOPE *e;
2987 	char *state;
2988 {
2989 	int i;
2990 	char *response;
2991 
2992 	if (tTd(64, 10))
2993 		dprintf("milter_helo(%s)\n", helo);
2994 
2995 	/* HELO/EHLO can come after encryption is negotiated */
2996 	for (i = 0; InputFilters[i] != NULL; i++)
2997 	{
2998 		struct milter *m = InputFilters[i];
2999 
3000 		switch (m->mf_state)
3001 		{
3002 		  case SMFS_INMSG:
3003 			/* abort in message filters */
3004 			milter_abort_filter(m, e);
3005 			/* FALLTHROUGH */
3006 
3007 		  case SMFS_DONE:
3008 			/* reset done filters */
3009 			m->mf_state = SMFS_OPEN;
3010 			break;
3011 		}
3012 	}
3013 
3014 	response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1,
3015 				  MilterHeloMacros, e, state);
3016 	milter_per_connection_check(e);
3017 	return response;
3018 }
3019 /*
3020 **  MILTER_ENVFROM -- send SMTP MAIL command info to milter filters
3021 **
3022 **	Parameters:
3023 **		args -- SMTP MAIL command args (args[0] == sender).
3024 **		e -- current envelope.
3025 **		state -- return state from response.
3026 **
3027 **	Returns:
3028 **		response string (may be NULL)
3029 */
3030 
3031 char *
3032 milter_envfrom(args, e, state)
3033 	char **args;
3034 	ENVELOPE *e;
3035 	char *state;
3036 {
3037 	int i;
3038 	char *buf, *bp;
3039 	char *response;
3040 	ssize_t s;
3041 
3042 	if (tTd(64, 10))
3043 	{
3044 		dprintf("milter_envfrom:");
3045 		for (i = 0; args[i] != NULL; i++)
3046 			dprintf(" %s", args[i]);
3047 		dprintf("\n");
3048 	}
3049 
3050 	/* sanity check */
3051 	if (args[0] == NULL)
3052 	{
3053 		*state = SMFIR_REJECT;
3054 		return NULL;
3055 	}
3056 
3057 	/* new message, so ... */
3058 	for (i = 0; InputFilters[i] != NULL; i++)
3059 	{
3060 		struct milter *m = InputFilters[i];
3061 
3062 		switch (m->mf_state)
3063 		{
3064 		  case SMFS_INMSG:
3065 			/* abort in message filters */
3066 			milter_abort_filter(m, e);
3067 			/* FALLTHROUGH */
3068 
3069 		  case SMFS_DONE:
3070 			/* reset done filters */
3071 			m->mf_state = SMFS_OPEN;
3072 			break;
3073 		}
3074 	}
3075 
3076 	/* put together data */
3077 	s = 0;
3078 	for (i = 0; args[i] != NULL; i++)
3079 		s += strlen(args[i]) + 1;
3080 	buf = (char *)xalloc(s);
3081 	bp = buf;
3082 	for (i = 0; args[i] != NULL; i++)
3083 	{
3084 		(void) strlcpy(bp, args[i], s - (bp - buf));
3085 		bp += strlen(bp) + 1;
3086 	}
3087 
3088 	/* send it over */
3089 	response = milter_command(SMFIC_MAIL, buf, s,
3090 				  MilterEnvFromMacros, e, state);
3091 	sm_free(buf);
3092 
3093 	/*
3094 	**  If filter rejects/discards a per message command,
3095 	**  abort the other filters since we are done with the
3096 	**  current message.
3097 	*/
3098 
3099 	MILTER_CHECK_DONE_MSG();
3100 	return response;
3101 }
3102 /*
3103 **  MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters
3104 **
3105 **	Parameters:
3106 **		args -- SMTP MAIL command args (args[0] == recipient).
3107 **		e -- current envelope.
3108 **		state -- return state from response.
3109 **
3110 **	Returns:
3111 **		response string (may be NULL)
3112 */
3113 
3114 char *
3115 milter_envrcpt(args, e, state)
3116 	char **args;
3117 	ENVELOPE *e;
3118 	char *state;
3119 {
3120 	int i;
3121 	char *buf, *bp;
3122 	char *response;
3123 	ssize_t s;
3124 
3125 	if (tTd(64, 10))
3126 	{
3127 		dprintf("milter_envrcpt:");
3128 		for (i = 0; args[i] != NULL; i++)
3129 			dprintf(" %s", args[i]);
3130 		dprintf("\n");
3131 	}
3132 
3133 	/* sanity check */
3134 	if (args[0] == NULL)
3135 	{
3136 		*state = SMFIR_REJECT;
3137 		return NULL;
3138 	}
3139 
3140 	/* put together data */
3141 	s = 0;
3142 	for (i = 0; args[i] != NULL; i++)
3143 		s += strlen(args[i]) + 1;
3144 	buf = (char *)xalloc(s);
3145 	bp = buf;
3146 	for (i = 0; args[i] != NULL; i++)
3147 	{
3148 		(void) strlcpy(bp, args[i], s - (bp - buf));
3149 		bp += strlen(bp) + 1;
3150 	}
3151 
3152 	/* send it over */
3153 	response = milter_command(SMFIC_RCPT, buf, s,
3154 				  MilterEnvRcptMacros, e, state);
3155 	sm_free(buf);
3156 	return response;
3157 }
3158 /*
3159 **  MILTER_DATA -- send message headers/body and gather final message results
3160 **
3161 **	Parameters:
3162 **		e -- current envelope.
3163 **		state -- return state from response.
3164 **
3165 **	Returns:
3166 **		response string (may be NULL)
3167 **
3168 **	Side effects:
3169 **		- Uses e->e_dfp for access to the body
3170 **		- Can call the various milter action routines to
3171 **		  modify the envelope or message.
3172 */
3173 
3174 # define MILTER_CHECK_RESULTS() \
3175 	if (*state == SMFIR_ACCEPT || \
3176 	    m->mf_state == SMFS_DONE || \
3177 	    m->mf_state == SMFS_ERROR) \
3178 	{ \
3179 		if (m->mf_state != SMFS_ERROR) \
3180 			m->mf_state = SMFS_DONE; \
3181 		continue;	/* to next filter */ \
3182 	} \
3183 	if (*state != SMFIR_CONTINUE) \
3184 	{ \
3185 		m->mf_state = SMFS_DONE; \
3186 		goto finishup; \
3187 	}
3188 
3189 char *
3190 milter_data(e, state)
3191 	ENVELOPE *e;
3192 	char *state;
3193 {
3194 	bool replbody = FALSE;		/* milter_replbody() called? */
3195 	bool replfailed = FALSE;	/* milter_replbody() failed? */
3196 	bool rewind = FALSE;		/* rewind df file? */
3197 	bool dfopen = FALSE;		/* df open for writing? */
3198 	bool newfilter;			/* reset on each new filter */
3199 	char rcmd;
3200 	int i;
3201 	int save_errno;
3202 	char *response = NULL;
3203 	time_t eomsent;
3204 	ssize_t rlen;
3205 
3206 	if (tTd(64, 10))
3207 		dprintf("milter_data\n");
3208 
3209 	*state = SMFIR_CONTINUE;
3210 
3211 	/*
3212 	**  XXX: Should actually send body chunks to each filter
3213 	**  a chunk at a time instead of sending the whole body to
3214 	**  each filter in turn.  However, only if the filters don't
3215 	**  change the body.
3216 	*/
3217 
3218 	for (i = 0; InputFilters[i] != NULL; i++)
3219 	{
3220 		struct milter *m = InputFilters[i];
3221 
3222 		if (*state != SMFIR_CONTINUE &&
3223 		    *state != SMFIR_ACCEPT)
3224 		{
3225 			/*
3226 			**  A previous filter has dealt with the message,
3227 			**  safe to stop processing the filters.
3228 			*/
3229 
3230 			break;
3231 		}
3232 
3233 		/* Now reset state for later evaluation */
3234 		*state = SMFIR_CONTINUE;
3235 		newfilter = TRUE;
3236 
3237 		/* previous problem? */
3238 		if (m->mf_state == SMFS_ERROR)
3239 		{
3240 			MILTER_CHECK_ERROR(continue);
3241 			break;
3242 		}
3243 
3244 		/* sanity checks */
3245 		if (m->mf_sock < 0 ||
3246 		    (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
3247 			continue;
3248 
3249 		m->mf_state = SMFS_INMSG;
3250 
3251 		/* check if filter wants the headers */
3252 		if (!bitset(SMFIP_NOHDRS, m->mf_pflags))
3253 		{
3254 			response = milter_headers(m, e, state);
3255 			MILTER_CHECK_RESULTS();
3256 		}
3257 
3258 		/* check if filter wants EOH */
3259 		if (!bitset(SMFIP_NOEOH, m->mf_pflags))
3260 		{
3261 			if (tTd(64, 10))
3262 				dprintf("milter_data: eoh\n");
3263 
3264 			/* send it over */
3265 			response = milter_send_command(m, SMFIC_EOH, NULL, 0,
3266 						       e, state);
3267 			MILTER_CHECK_RESULTS();
3268 		}
3269 
3270 		/* check if filter wants the body */
3271 		if (!bitset(SMFIP_NOBODY, m->mf_pflags) &&
3272 		    e->e_dfp != NULL)
3273 		{
3274 			rewind = TRUE;
3275 			response = milter_body(m, e, state);
3276 			MILTER_CHECK_RESULTS();
3277 		}
3278 
3279 		/* send the final body chunk */
3280 		(void) milter_write(m, SMFIC_BODYEOB, NULL, 0,
3281 				    m->mf_timeout[SMFTO_WRITE], e);
3282 
3283 		/* Get time EOM sent for timeout */
3284 		eomsent = curtime();
3285 
3286 		/* deal with the possibility of multiple responses */
3287 		while (*state == SMFIR_CONTINUE)
3288 		{
3289 			/* Check total timeout from EOM to final ACK/NAK */
3290 			if (m->mf_timeout[SMFTO_EOM] > 0 &&
3291 			    curtime() - eomsent >= m->mf_timeout[SMFTO_EOM])
3292 			{
3293 				if (tTd(64, 5))
3294 					dprintf("milter_data(%s): EOM ACK/NAK timeout\n",
3295 						m->mf_name);
3296 				if (LogLevel > 0)
3297 					sm_syslog(LOG_ERR, e->e_id,
3298 						  "milter_data(%s): EOM ACK/NAK timeout\n",
3299 						  m->mf_name);
3300 				milter_error(m);
3301 				MILTER_CHECK_ERROR(continue);
3302 				break;
3303 			}
3304 
3305 			response = milter_read(m, &rcmd, &rlen,
3306 					       m->mf_timeout[SMFTO_READ], e);
3307 			if (m->mf_state == SMFS_ERROR)
3308 				break;
3309 
3310 			if (tTd(64, 10))
3311 				dprintf("milter_data(%s): state %c\n",
3312 					m->mf_name, (char) rcmd);
3313 
3314 			switch (rcmd)
3315 			{
3316 			  case SMFIR_REPLYCODE:
3317 				MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected");
3318 				*state = rcmd;
3319 				m->mf_state = SMFS_DONE;
3320 				break;
3321 
3322 			  case SMFIR_REJECT:
3323 			  case SMFIR_DISCARD:
3324 			  case SMFIR_TEMPFAIL:
3325 				*state = rcmd;
3326 				m->mf_state = SMFS_DONE;
3327 				break;
3328 
3329 			  case SMFIR_CONTINUE:
3330 			  case SMFIR_ACCEPT:
3331 				/* this filter is done with message */
3332 				if (replfailed)
3333 					*state = SMFIR_TEMPFAIL;
3334 				else
3335 					*state = SMFIR_ACCEPT;
3336 				m->mf_state = SMFS_DONE;
3337 				break;
3338 
3339 			  case SMFIR_PROGRESS:
3340 				break;
3341 
3342 			  case SMFIR_ADDHEADER:
3343 				if (!bitset(SMFIF_ADDHDRS, m->mf_fflags))
3344 				{
3345 					if (LogLevel > 9)
3346 						sm_syslog(LOG_WARNING, e->e_id,
3347 							  "milter_data(%s): lied about adding headers, honoring request anyway",
3348 							  m->mf_name);
3349 				}
3350 				milter_addheader(response, rlen, e);
3351 				break;
3352 
3353 			  case SMFIR_CHGHEADER:
3354 				if (!bitset(SMFIF_CHGHDRS, m->mf_fflags))
3355 				{
3356 					if (LogLevel > 9)
3357 						sm_syslog(LOG_WARNING, e->e_id,
3358 							  "milter_data(%s): lied about changing headers, honoring request anyway",
3359 							  m->mf_name);
3360 				}
3361 				milter_changeheader(response, rlen, e);
3362 				break;
3363 
3364 			  case SMFIR_ADDRCPT:
3365 				if (!bitset(SMFIF_ADDRCPT, m->mf_fflags))
3366 				{
3367 					if (LogLevel > 9)
3368 						sm_syslog(LOG_WARNING, e->e_id,
3369 							  "milter_data(%s) lied about adding recipients, honoring request anyway",
3370 							  m->mf_name);
3371 				}
3372 				milter_addrcpt(response, rlen, e);
3373 				break;
3374 
3375 			  case SMFIR_DELRCPT:
3376 				if (!bitset(SMFIF_DELRCPT, m->mf_fflags))
3377 				{
3378 					if (LogLevel > 9)
3379 						sm_syslog(LOG_WARNING, e->e_id,
3380 							  "milter_data(%s): lied about removing recipients, honoring request anyway",
3381 							  m->mf_name);
3382 				}
3383 				milter_delrcpt(response, rlen, e);
3384 				break;
3385 
3386 			  case SMFIR_REPLBODY:
3387 				if (!bitset(SMFIF_MODBODY, m->mf_fflags))
3388 				{
3389 					if (LogLevel > 0)
3390 						sm_syslog(LOG_ERR, e->e_id,
3391 							  "milter_data(%s): lied about replacing body, rejecting request and tempfailing message",
3392 							  m->mf_name);
3393 					replfailed = TRUE;
3394 					break;
3395 				}
3396 
3397 				/* already failed in attempt */
3398 				if (replfailed)
3399 					break;
3400 
3401 				if (!dfopen)
3402 				{
3403 					if (milter_reopen_df(e) < 0)
3404 					{
3405 						replfailed = TRUE;
3406 						break;
3407 					}
3408 					dfopen = TRUE;
3409 					rewind = TRUE;
3410 				}
3411 
3412 				if (milter_replbody(response, rlen,
3413 						    newfilter, e) < 0)
3414 					replfailed = TRUE;
3415 				newfilter = FALSE;
3416 				replbody = TRUE;
3417 				break;
3418 
3419 			  default:
3420 				/* Invalid response to command */
3421 				if (LogLevel > 0)
3422 					sm_syslog(LOG_ERR, e->e_id,
3423 						  "milter_data(%s): returned bogus response %c",
3424 						  m->mf_name, rcmd);
3425 				milter_error(m);
3426 				break;
3427 			}
3428 			if (rcmd != SMFIR_REPLYCODE &&
3429 			    response != NULL)
3430 			{
3431 				sm_free(response);
3432 				response = NULL;
3433 			}
3434 
3435 			if (m->mf_state == SMFS_ERROR)
3436 				break;
3437 		}
3438 
3439 		if (replbody && !replfailed)
3440 		{
3441 			/* flush possible buffered character */
3442 			milter_replbody(NULL, 0, !replbody, e);
3443 			replbody = FALSE;
3444 		}
3445 
3446 		if (m->mf_state == SMFS_ERROR)
3447 		{
3448 			MILTER_CHECK_ERROR(continue);
3449 			goto finishup;
3450 		}
3451 	}
3452 
3453 finishup:
3454 	/* leave things in the expected state if we touched it */
3455 	if (replfailed)
3456 	{
3457 		if (*state == SMFIR_CONTINUE ||
3458 		    *state == SMFIR_ACCEPT)
3459 		{
3460 			*state = SMFIR_TEMPFAIL;
3461 			if (response != NULL)
3462 			{
3463 				sm_free(response);
3464 				response = NULL;
3465 			}
3466 		}
3467 
3468 		if (dfopen)
3469 		{
3470 			(void) fclose(e->e_dfp);
3471 			e->e_dfp = NULL;
3472 			e->e_flags &= ~EF_HAS_DF;
3473 			dfopen = FALSE;
3474 		}
3475 		rewind = FALSE;
3476 	}
3477 
3478 	if ((dfopen && milter_reset_df(e) < 0) ||
3479 	    (rewind && bfrewind(e->e_dfp) < 0))
3480 	{
3481 		save_errno = errno;
3482 		ExitStat = EX_IOERR;
3483 
3484 		/*
3485 		**  If filter told us to keep message but we had
3486 		**  an error, we can't really keep it, tempfail it.
3487 		*/
3488 
3489 		if (*state == SMFIR_CONTINUE ||
3490 		    *state == SMFIR_ACCEPT)
3491 		{
3492 			*state = SMFIR_TEMPFAIL;
3493 			if (response != NULL)
3494 			{
3495 				sm_free(response);
3496 				response = NULL;
3497 			}
3498 		}
3499 
3500 		errno = save_errno;
3501 		syserr("milter_data: %s/df%s: read error",
3502 		       qid_printqueue(e->e_queuedir), e->e_id);
3503 	}
3504 	MILTER_CHECK_DONE_MSG();
3505 	return response;
3506 }
3507 /*
3508 **  MILTER_QUIT -- informs the filter(s) we are done and closes connection(s)
3509 **
3510 **	Parameters:
3511 **		e -- current envelope.
3512 **
3513 **	Returns:
3514 **		none
3515 */
3516 
3517 void
3518 milter_quit(e)
3519 	ENVELOPE *e;
3520 {
3521 	int i;
3522 
3523 	if (tTd(64, 10))
3524 		dprintf("milter_quit\n");
3525 
3526 	for (i = 0; InputFilters[i] != NULL; i++)
3527 		milter_quit_filter(InputFilters[i], e);
3528 }
3529 /*
3530 **  MILTER_ABORT -- informs the filter(s) that we are aborting current message
3531 **
3532 **	Parameters:
3533 **		e -- current envelope.
3534 **
3535 **	Returns:
3536 **		none
3537 */
3538 
3539 void
3540 milter_abort(e)
3541 	ENVELOPE *e;
3542 {
3543 	int i;
3544 
3545 	if (tTd(64, 10))
3546 		dprintf("milter_abort\n");
3547 
3548 	for (i = 0; InputFilters[i] != NULL; i++)
3549 	{
3550 		struct milter *m = InputFilters[i];
3551 
3552 		/* sanity checks */
3553 		if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG)
3554 			continue;
3555 
3556 		milter_abort_filter(m, e);
3557 	}
3558 }
3559 #endif /* _FFR_MILTER */
3560