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