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