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