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