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