1/*++
2/* NAME
3/*	milter8 3
4/* SUMMARY
5/*	MTA-side Sendmail 8 Milter protocol
6/* SYNOPSIS
7/*	#include <milter8.h>
8/*
9/*	MILTER	*milter8_create(name, conn_timeout, cmd_timeout, msg_timeout,
10/*				protocol, def_action, parent)
11/*	const char *name;
12/*	int conn_timeout;
13/*	int cmd_timeout;
14/*	int msg_timeout;
15/*	const char *protocol;
16/*	const char *def_action;
17/*	MILTERS *parent;
18/*
19/*	MILTER	*milter8_receive(stream)
20/*	VSTREAM	*stream;
21/* DESCRIPTION
22/*	This module implements the MTA side of the Sendmail 8 mail
23/*	filter protocol.
24/*
25/*	milter8_create() creates a MILTER data structure with virtual
26/*	functions that implement a client for the Sendmail 8 Milter
27/*	protocol. These virtual functions are then invoked via the
28/*	milter(3) interface.  The *timeout, protocol and def_action
29/*	arguments come directly from milter_create(). The parent
30/*	argument specifies a context for content editing.
31/*
32/*	milter8_receive() receives a mail filter definition from the
33/*	specified stream. The result is zero in case of success.
34/*
35/*	Arguments:
36/* .IP name
37/*	The Milter application endpoint, either inet:host:port or
38/*	unix:/pathname.
39/* DIAGNOSTICS
40/*	Panic: interface violation.  Fatal errors: out of memory.
41/* CONFIGURATION PARAMETERS
42/*	milter8_protocol, protocol version and extensions
43/* SEE ALSO
44/*	milter(3) generic Milter interface
45/* LICENSE
46/* .ad
47/* .fi
48/*	The Secure Mailer license must be distributed with this software.
49/* AUTHOR(S)
50/*	Wietse Venema
51/*	IBM T.J. Watson Research
52/*	P.O. Box 704
53/*	Yorktown Heights, NY 10598, USA
54/*--*/
55
56/* System library. */
57
58#include <sys_defs.h>
59#include <sys/socket.h>
60#include <netinet/in.h>
61#include <arpa/inet.h>
62#include <errno.h>
63#include <stddef.h>			/* offsetof() */
64#include <stdlib.h>
65#include <string.h>
66#include <stdarg.h>
67#include <limits.h>			/* INT_MAX */
68
69#ifndef SHUT_RDWR
70#define SHUT_RDWR	2
71#endif
72
73/* Utility library. */
74
75#include <msg.h>
76#include <mymalloc.h>
77#include <split_at.h>
78#include <connect.h>
79#include <argv.h>
80#include <name_mask.h>
81#include <name_code.h>
82#include <stringops.h>
83#include <compat_va_copy.h>
84
85/* Global library. */
86
87#include <mail_params.h>
88#include <mail_proto.h>
89#include <rec_type.h>
90#include <record.h>
91#include <mime_state.h>
92#include <is_header.h>
93
94/* Postfix Milter library. */
95
96#include <milter.h>
97
98/* Application-specific. */
99
100 /*
101  * Use our own protocol definitions, so that Postfix can be built even when
102  * libmilter is not installed. This means that we must specify the libmilter
103  * protocol version in main.cf, and that we must send only the commands that
104  * are supported for that protocol version.
105  */
106
107 /*
108  * Commands from MTA to filter.
109  */
110#define SMFIC_ABORT		'A'	/* Abort */
111#define SMFIC_BODY		'B'	/* Body chunk */
112#define SMFIC_CONNECT		'C'	/* Connection information */
113#define SMFIC_MACRO		'D'	/* Define macro */
114#define SMFIC_BODYEOB		'E'	/* final body chunk (End) */
115#define SMFIC_HELO		'H'	/* HELO/EHLO */
116#define SMFIC_HEADER		'L'	/* Header */
117#define SMFIC_MAIL		'M'	/* MAIL from */
118#define SMFIC_EOH		'N'	/* EOH */
119#define SMFIC_OPTNEG		'O'	/* Option negotiation */
120#define SMFIC_QUIT		'Q'	/* QUIT */
121#define SMFIC_RCPT		'R'	/* RCPT to */
122#define SMFIC_DATA		'T'	/* DATA */
123#define SMFIC_UNKNOWN		'U'	/* Any unknown command */
124 /* Introduced with Sendmail 8.14. */
125#define SMFIC_QUIT_NC		'K'	/* Quit + new connection */
126
127static const NAME_CODE smfic_table[] = {
128    "SMFIC_ABORT", SMFIC_ABORT,
129    "SMFIC_BODY", SMFIC_BODY,
130    "SMFIC_CONNECT", SMFIC_CONNECT,
131    "SMFIC_MACRO", SMFIC_MACRO,
132    "SMFIC_BODYEOB", SMFIC_BODYEOB,
133    "SMFIC_HELO", SMFIC_HELO,
134    "SMFIC_HEADER", SMFIC_HEADER,
135    "SMFIC_MAIL", SMFIC_MAIL,
136    "SMFIC_EOH", SMFIC_EOH,
137    "SMFIC_OPTNEG", SMFIC_OPTNEG,
138    "SMFIC_QUIT", SMFIC_QUIT,
139    "SMFIC_RCPT", SMFIC_RCPT,
140    "SMFIC_DATA", SMFIC_DATA,
141    "SMFIC_UNKNOWN", SMFIC_UNKNOWN,
142    /* Introduced with Sendmail 8.14. */
143    "SMFIC_QUIT_NC", SMFIC_QUIT_NC,
144    0, 0,
145};
146
147 /*
148  * Responses from filter to MTA.
149  */
150#define SMFIR_ADDRCPT		'+'	/* add recipient */
151#define SMFIR_DELRCPT		'-'	/* remove recipient */
152#define SMFIR_ACCEPT		'a'	/* accept */
153#define SMFIR_REPLBODY		'b'	/* replace body (chunk) */
154#define SMFIR_CONTINUE		'c'	/* continue */
155#define SMFIR_DISCARD		'd'	/* discard */
156#define SMFIR_CONN_FAIL		'f'	/* cause a connection failure */
157#define SMFIR_CHGHEADER		'm'	/* change header */
158#define SMFIR_PROGRESS		'p'	/* progress */
159#define SMFIR_REJECT		'r'	/* reject */
160#define SMFIR_TEMPFAIL		't'	/* tempfail */
161#define SMFIR_SHUTDOWN		'4'	/* 421: shutdown (internal to MTA) */
162#define SMFIR_ADDHEADER		'h'	/* add header */
163#define SMFIR_INSHEADER		'i'	/* insert header */
164#define SMFIR_REPLYCODE		'y'	/* reply code etc */
165#define SMFIR_QUARANTINE	'q'	/* quarantine */
166 /* Introduced with Sendmail 8.14. */
167#define SMFIR_SKIP		's'	/* skip further events of this type */
168#define SMFIR_CHGFROM		'e'	/* change sender (incl. ESMTP args) */
169#define SMFIR_ADDRCPT_PAR	'2'	/* add recipient (incl. ESMTP args) */
170#define SMFIR_SETSYMLIST	'l'	/* set list of symbols (macros) */
171
172static const NAME_CODE smfir_table[] = {
173    "SMFIR_ADDRCPT", SMFIR_ADDRCPT,
174    "SMFIR_DELRCPT", SMFIR_DELRCPT,
175    "SMFIR_ACCEPT", SMFIR_ACCEPT,
176    "SMFIR_REPLBODY", SMFIR_REPLBODY,
177    "SMFIR_CONTINUE", SMFIR_CONTINUE,
178    "SMFIR_DISCARD", SMFIR_DISCARD,
179    "SMFIR_CONN_FAIL", SMFIR_CONN_FAIL,
180    "SMFIR_CHGHEADER", SMFIR_CHGHEADER,
181    "SMFIR_PROGRESS", SMFIR_PROGRESS,
182    "SMFIR_REJECT", SMFIR_REJECT,
183    "SMFIR_TEMPFAIL", SMFIR_TEMPFAIL,
184    "SMFIR_SHUTDOWN", SMFIR_SHUTDOWN,
185    "SMFIR_ADDHEADER", SMFIR_ADDHEADER,
186    "SMFIR_INSHEADER", SMFIR_INSHEADER,
187    "SMFIR_REPLYCODE", SMFIR_REPLYCODE,
188    "SMFIR_QUARANTINE", SMFIR_QUARANTINE,
189    /* Introduced with Sendmail 8.14. */
190    "SMFIR_SKIP", SMFIR_SKIP,
191    "SMFIR_CHGFROM", SMFIR_CHGFROM,
192    "SMFIR_ADDRCPT_PAR", SMFIR_ADDRCPT_PAR,
193    "SMFIR_SETSYMLIST", SMFIR_SETSYMLIST,
194    0, 0,
195};
196
197 /*
198  * Commands that the filter does not want to receive, and replies that the
199  * filter will not send. Plus some other random stuff.
200  */
201#define SMFIP_NOCONNECT		(1L<<0)	/* filter does not want connect info */
202#define SMFIP_NOHELO		(1L<<1)	/* filter does not want HELO info */
203#define SMFIP_NOMAIL		(1L<<2)	/* filter does not want MAIL info */
204#define SMFIP_NORCPT		(1L<<3)	/* filter does not want RCPT info */
205#define SMFIP_NOBODY		(1L<<4)	/* filter does not want body */
206#define SMFIP_NOHDRS		(1L<<5)	/* filter does not want headers */
207#define SMFIP_NOEOH		(1L<<6)	/* filter does not want EOH */
208#define SMFIP_NR_HDR		(1L<<7)	/* filter won't reply for header */
209#define SMFIP_NOHREPL		SMFIP_NR_HDR
210#define SMFIP_NOUNKNOWN 	(1L<<8)	/* filter does not want unknown cmd */
211#define SMFIP_NODATA		(1L<<9)	/* filter does not want DATA */
212 /* Introduced with Sendmail 8.14. */
213#define SMFIP_SKIP		(1L<<10)/* MTA supports SMFIR_SKIP */
214#define SMFIP_RCPT_REJ		(1L<<11)/* filter wants rejected RCPTs */
215#define SMFIP_NR_CONN		(1L<<12)/* filter won't reply for connect */
216#define SMFIP_NR_HELO		(1L<<13)/* filter won't reply for HELO */
217#define SMFIP_NR_MAIL		(1L<<14)/* filter won't reply for MAIL */
218#define SMFIP_NR_RCPT		(1L<<15)/* filter won't reply for RCPT */
219#define SMFIP_NR_DATA		(1L<<16)/* filter won't reply for DATA */
220#define SMFIP_NR_UNKN		(1L<<17)/* filter won't reply for UNKNOWN */
221#define SMFIP_NR_EOH		(1L<<18)/* filter won't reply for eoh */
222#define SMFIP_NR_BODY		(1L<<19)/* filter won't reply for body chunk */
223#define SMFIP_HDR_LEADSPC	(1L<<20)/* header value has leading space */
224
225#define SMFIP_NOSEND_MASK \
226	(SMFIP_NOCONNECT | SMFIP_NOHELO | SMFIP_NOMAIL | SMFIP_NORCPT \
227	| SMFIP_NOBODY | SMFIP_NOHDRS | SMFIP_NOEOH | SMFIP_NOUNKNOWN \
228	| SMFIP_NODATA)
229
230#define SMFIP_NOREPLY_MASK \
231	(SMFIP_NR_CONN | SMFIP_NR_HELO | SMFIP_NR_MAIL | SMFIP_NR_RCPT \
232	| SMFIP_NR_DATA | SMFIP_NR_UNKN | SMFIP_NR_HDR | SMFIP_NR_EOH | \
233	SMFIP_NR_BODY)
234
235static const NAME_MASK smfip_table[] = {
236    "SMFIP_NOCONNECT", SMFIP_NOCONNECT,
237    "SMFIP_NOHELO", SMFIP_NOHELO,
238    "SMFIP_NOMAIL", SMFIP_NOMAIL,
239    "SMFIP_NORCPT", SMFIP_NORCPT,
240    "SMFIP_NOBODY", SMFIP_NOBODY,
241    "SMFIP_NOHDRS", SMFIP_NOHDRS,
242    "SMFIP_NOEOH", SMFIP_NOEOH,
243    "SMFIP_NR_HDR", SMFIP_NR_HDR,
244    "SMFIP_NOUNKNOWN", SMFIP_NOUNKNOWN,
245    "SMFIP_NODATA", SMFIP_NODATA,
246    /* Introduced with Sendmail 8.14. */
247    "SMFIP_SKIP", SMFIP_SKIP,
248    "SMFIP_RCPT_REJ", SMFIP_RCPT_REJ,
249    "SMFIP_NR_CONN", SMFIP_NR_CONN,
250    "SMFIP_NR_HELO", SMFIP_NR_HELO,
251    "SMFIP_NR_MAIL", SMFIP_NR_MAIL,
252    "SMFIP_NR_RCPT", SMFIP_NR_RCPT,
253    "SMFIP_NR_DATA", SMFIP_NR_DATA,
254    "SMFIP_NR_UNKN", SMFIP_NR_UNKN,
255    "SMFIP_NR_EOH", SMFIP_NR_EOH,
256    "SMFIP_NR_BODY", SMFIP_NR_BODY,
257    "SMFIP_HDR_LEADSPC", SMFIP_HDR_LEADSPC,
258    0, 0,
259};
260
261 /*
262  * Options that the filter may send at initial handshake time, and message
263  * modifications that the filter may request at the end of the message body.
264  */
265#define SMFIF_ADDHDRS		(1L<<0)	/* filter may add headers */
266#define SMFIF_CHGBODY		(1L<<1)	/* filter may replace body */
267#define SMFIF_ADDRCPT		(1L<<2)	/* filter may add recipients */
268#define SMFIF_DELRCPT		(1L<<3)	/* filter may delete recipients */
269#define SMFIF_CHGHDRS		(1L<<4)	/* filter may change/delete headers */
270#define SMFIF_QUARANTINE 	(1L<<5)	/* filter may quarantine envelope */
271 /* Introduced with Sendmail 8.14. */
272#define SMFIF_CHGFROM		(1L<<6)	/* filter may replace sender */
273#define SMFIF_ADDRCPT_PAR	(1L<<7)	/* filter may add recipients + args */
274#define SMFIF_SETSYMLIST	(1L<<8)	/* filter may send macro names */
275
276static const NAME_MASK smfif_table[] = {
277    "SMFIF_ADDHDRS", SMFIF_ADDHDRS,
278    "SMFIF_CHGBODY", SMFIF_CHGBODY,
279    "SMFIF_ADDRCPT", SMFIF_ADDRCPT,
280    "SMFIF_DELRCPT", SMFIF_DELRCPT,
281    "SMFIF_CHGHDRS", SMFIF_CHGHDRS,
282    "SMFIF_QUARANTINE", SMFIF_QUARANTINE,
283    /* Introduced with Sendmail 8.14. */
284    "SMFIF_CHGFROM", SMFIF_CHGFROM,
285    "SMFIF_ADDRCPT_PAR", SMFIF_ADDRCPT_PAR,
286    "SMFIF_SETSYMLIST", SMFIF_SETSYMLIST,
287    0, 0,
288};
289
290 /*
291  * Network protocol families, used when sending CONNECT information.
292  */
293#define SMFIA_UNKNOWN		'U'	/* unknown */
294#define SMFIA_UNIX		'L'	/* unix/local */
295#define SMFIA_INET		'4'	/* inet */
296#define SMFIA_INET6		'6'	/* inet6 */
297
298 /*
299  * External macro class numbers, to identify the optional macro name lists
300  * that may be sent after the initial negotiation header.
301  */
302#define SMFIM_CONNECT	0		/* macros for connect */
303#define SMFIM_HELO	1		/* macros for HELO */
304#define SMFIM_ENVFROM	2		/* macros for MAIL */
305#define SMFIM_ENVRCPT	3		/* macros for RCPT */
306#define SMFIM_DATA	4		/* macros for DATA */
307#define SMFIM_EOM	5		/* macros for end-of-message */
308#define SMFIM_EOH	6		/* macros for end-of-header */
309
310static const NAME_CODE smfim_table[] = {
311    "SMFIM_CONNECT", SMFIM_CONNECT,
312    "SMFIM_HELO", SMFIM_HELO,
313    "SMFIM_ENVFROM", SMFIM_ENVFROM,
314    "SMFIM_ENVRCPT", SMFIM_ENVRCPT,
315    "SMFIM_DATA", SMFIM_DATA,
316    "SMFIM_EOM", SMFIM_EOM,
317    "SMFIM_EOH", SMFIM_EOH,
318    0, 0,
319};
320
321 /*
322  * Mapping from external macro class numbers to our internal MILTER_MACROS
323  * structure members, without using a switch statement.
324  */
325static const size_t milter8_macro_offsets[] = {
326    offsetof(MILTER_MACROS, conn_macros),	/* SMFIM_CONNECT */
327    offsetof(MILTER_MACROS, helo_macros),	/* SMFIM_HELO */
328    offsetof(MILTER_MACROS, mail_macros),	/* SMFIM_ENVFROM */
329    offsetof(MILTER_MACROS, rcpt_macros),	/* SMFIM_ENVRCPT */
330    offsetof(MILTER_MACROS, data_macros),	/* SMFIM_DATA */
331    offsetof(MILTER_MACROS, eod_macros),/* Note: SMFIM_EOM < SMFIM_EOH */
332    offsetof(MILTER_MACROS, eoh_macros),/* Note: SMFIM_EOH > SMFIM_EOM */
333};
334
335#define MILTER8_MACRO_PTR(__macros, __class) \
336	((char **) (((char *) (__macros)) + milter8_macro_offsets[(__class)]))
337
338 /*
339  * How much buffer space is available for sending body content.
340  */
341#define MILTER_CHUNK_SIZE	65535	/* body chunk size */
342
343/*#define msg_verbose 2*/
344
345 /*
346  * Sendmail 8 mail filter client.
347  */
348typedef struct {
349    MILTER  m;				/* parent class */
350    int     conn_timeout;		/* connect timeout */
351    int     cmd_timeout;		/* per-command timeout */
352    int     msg_timeout;		/* content inspection timeout */
353    char   *protocol;			/* protocol version/extension */
354    char   *def_action;			/* action if unavailable */
355    int     version;			/* application protocol version */
356    int     rq_mask;			/* application requests (SMFIF_*) */
357    int     ev_mask;			/* application events (SMFIP_*) */
358    int     np_mask;			/* events outside my protocol version */
359    VSTRING *buf;			/* I/O buffer */
360    VSTRING *body;			/* I/O buffer */
361    VSTREAM *fp;			/* stream or null (closed) */
362
363    /*
364     * Following fields must be reset after successful CONNECT, to avoid
365     * leakage from one use to another.
366     */
367    int     state;			/* MILTER8_STAT_mumble */
368    char   *def_reply;			/* error response or null */
369    int     skip_event_type;		/* skip operations of this type */
370} MILTER8;
371
372 /*
373  * XXX Sendmail 8 libmilter automatically closes the MTA-to-filter socket
374  * when it finds out that the SMTP client has disconnected. Because of this
375  * behavior, Postfix has to open a new MTA-to-filter socket each time an
376  * SMTP client connects.
377  */
378#define LIBMILTER_AUTO_DISCONNECT
379
380 /*
381  * Milter internal state. For the external representation we use SMTP
382  * replies (4XX X.Y.Z text, 5XX X.Y.Z text) and one-letter strings
383  * (H=quarantine, D=discard, S=shutdown).
384  */
385#define MILTER8_STAT_ERROR	1	/* error, must be non-zero */
386#define MILTER8_STAT_CLOSED	2	/* no connection */
387#define MILTER8_STAT_READY	3	/* wait for connect event */
388#define MILTER8_STAT_ENVELOPE	4	/* in envelope */
389#define MILTER8_STAT_MESSAGE	5	/* in message */
390#define MILTER8_STAT_ACCEPT_CON	6	/* accept all commands */
391#define MILTER8_STAT_ACCEPT_MSG	7	/* accept one message */
392#define MILTER8_STAT_REJECT_CON	8	/* reject all commands */
393
394 /*
395  * Protocol formatting requests. Note: the terms "long" and "short" refer to
396  * the data types manipulated by htonl(), htons() and friends. These types
397  * are network specific, not host platform specific.
398  */
399#define MILTER8_DATA_END	0	/* no more arguments */
400#define MILTER8_DATA_HLONG	1	/* host long */
401#define MILTER8_DATA_BUFFER	2	/* network-formatted buffer */
402#define MILTER8_DATA_STRING	3	/* null-terminated string */
403#define MILTER8_DATA_NSHORT	4	/* network short */
404#define MILTER8_DATA_ARGV	5	/* array of null-terminated strings */
405#define MILTER8_DATA_OCTET	6	/* byte */
406#define MILTER8_DATA_MORE	7	/* more arguments in next call */
407
408 /*
409  * We don't accept insane amounts of data.
410  */
411#define XXX_MAX_DATA	(INT_MAX / 2)
412#define XXX_TIMEOUT	10
413
414 /*
415  * We implement the protocol up to and including version 6, and configure in
416  * main.cf what protocol version we will use. The version is the first data
417  * item in the SMFIC_OPTNEG packet.
418  *
419  * We must send only events that are defined for the specified protocol
420  * version. Libmilter may disconnect when we send unexpected events.
421  *
422  * The following events are supported in all our milter protocol versions.
423  */
424#define MILTER8_V2_PROTO_MASK \
425	(SMFIP_NOCONNECT | SMFIP_NOHELO | SMFIP_NOMAIL | SMFIP_NORCPT | \
426	SMFIP_NOBODY | SMFIP_NOHDRS | SMFIP_NOEOH)
427
428 /*
429  * Events supported by later versions.
430  */
431#define MILTER8_V3_PROTO_MASK	(MILTER8_V2_PROTO_MASK | SMFIP_NOUNKNOWN)
432#define MILTER8_V4_PROTO_MASK	(MILTER8_V3_PROTO_MASK | SMFIP_NODATA)
433#define MILTER8_V6_PROTO_MASK \
434	(MILTER8_V4_PROTO_MASK | SMFIP_SKIP | SMFIP_RCPT_REJ \
435	| SMFIP_NOREPLY_MASK | SMFIP_HDR_LEADSPC)
436
437 /*
438  * What events we can send to the milter application. The milter8_protocol
439  * parameter can specify a protocol version as well as protocol extensions
440  * such as "no_header_reply", a feature that speeds up the protocol by not
441  * sending a filter reply for every individual message header.
442  *
443  * This looks unclean because the user can specify multiple protocol versions,
444  * but that is taken care of by the table that follows this one.
445  *
446  * XXX Is this still needed? Sendmail 8.14 provides a proper way to negotiate
447  * what replies the mail filter will send.
448  *
449  * XXX Keep this table in reverse numerical order. This is needed by the code
450  * that implements compatibility with older Milter protocol versions.
451  */
452static const NAME_CODE milter8_event_masks[] = {
453    "6", MILTER8_V6_PROTO_MASK,
454    "4", MILTER8_V4_PROTO_MASK,
455    "3", MILTER8_V3_PROTO_MASK,
456    "2", MILTER8_V2_PROTO_MASK,
457    "no_header_reply", SMFIP_NOHREPL,
458    0, -1,
459};
460
461 /*
462  * The following table lets us use the same milter8_protocol parameter
463  * setting to derive the protocol version number. In this case we ignore
464  * protocol extensions such as "no_header_reply", and require that exactly
465  * one version number is specified.
466  */
467static const NAME_CODE milter8_versions[] = {
468    "2", 2,
469    "3", 3,
470    "4", 4,
471    "6", 6,
472    "no_header_reply", 0,
473    0, -1,
474};
475
476/* SLMs. */
477
478#define STR(x) vstring_str(x)
479#define LEN(x) VSTRING_LEN(x)
480
481/* milter8_def_reply - set persistent response */
482
483static const char *milter8_def_reply(MILTER8 *milter, const char *reply)
484{
485    if (milter->def_reply)
486	myfree(milter->def_reply);
487    milter->def_reply = reply ? mystrdup(reply) : 0;
488    return (milter->def_reply);
489}
490
491/* milter8_conf_error - local/remote configuration error */
492
493static int milter8_conf_error(MILTER8 *milter)
494{
495    const char *reply;
496
497    /*
498     * XXX When the cleanup server closes its end of the Milter socket while
499     * editing a queue file, the SMTP server is left out of sync with the
500     * Milter. Sending an ABORT to the Milters will not restore
501     * synchronization, because there may be any number of Milter replies
502     * already in flight. Workaround: poison the socket and force the SMTP
503     * server to abandon it.
504     */
505    if (milter->fp != 0) {
506	(void) shutdown(vstream_fileno(milter->fp), SHUT_RDWR);
507	(void) vstream_fclose(milter->fp);
508	milter->fp = 0;
509    }
510    if (strcasecmp(milter->def_action, "accept") == 0) {
511	reply = 0;
512    } else if (strcasecmp(milter->def_action, "quarantine") == 0) {
513	reply = "H";
514    } else {
515	reply = "451 4.3.5 Server configuration problem - try again later";
516    }
517    milter8_def_reply(milter, reply);
518    return (milter->state = MILTER8_STAT_ERROR);
519}
520
521/* milter8_comm_error - read/write/format communication error */
522
523static int milter8_comm_error(MILTER8 *milter)
524{
525    const char *reply;
526
527    /*
528     * XXX When the cleanup server closes its end of the Milter socket while
529     * editing a queue file, the SMTP server is left out of sync with the
530     * Milter. Sending an ABORT to the Milters will not restore
531     * synchronization, because there may be any number of Milter replies
532     * already in flight. Workaround: poison the socket and force the SMTP
533     * server to abandon it.
534     */
535    if (milter->fp != 0) {
536	(void) shutdown(vstream_fileno(milter->fp), SHUT_RDWR);
537	(void) vstream_fclose(milter->fp);
538	milter->fp = 0;
539    }
540    if (strcasecmp(milter->def_action, "accept") == 0) {
541	reply = 0;
542    } else if (strcasecmp(milter->def_action, "reject") == 0) {
543	reply = "550 5.5.0 Service unavailable";
544    } else if (strcasecmp(milter->def_action, "tempfail") == 0) {
545	reply = "451 4.7.1 Service unavailable - try again later";
546    } else if (strcasecmp(milter->def_action, "quarantine") == 0) {
547	reply = "H";
548    } else {
549	msg_warn("milter %s: unrecognized default action: %s",
550		 milter->m.name, milter->def_action);
551	reply = "451 4.3.5 Server configuration problem - try again later";
552    }
553    milter8_def_reply(milter, reply);
554    return (milter->state = MILTER8_STAT_ERROR);
555}
556
557/* milter8_close_stream - close stream to milter application */
558
559static void milter8_close_stream(MILTER8 *milter)
560{
561    if (milter->fp != 0) {
562	(void) vstream_fclose(milter->fp);
563	milter->fp = 0;
564    }
565    milter->state = MILTER8_STAT_CLOSED;
566}
567
568/* milter8_read_resp - receive command code now, receive data later */
569
570static int milter8_read_resp(MILTER8 *milter, int event, unsigned char *command,
571			             ssize_t *data_len)
572{
573    UINT32_TYPE len;
574    ssize_t pkt_len;
575    const char *smfic_name;
576    int     cmd;
577
578    /*
579     * Receive the packet length.
580     */
581    if ((vstream_fread(milter->fp, (char *) &len, UINT32_SIZE))
582	!= UINT32_SIZE) {
583	smfic_name = str_name_code(smfic_table, event);
584	msg_warn("milter %s: can't read %s reply packet header: %m",
585		 milter->m.name, smfic_name != 0 ?
586		 smfic_name : "(unknown MTA event)");
587	return (milter8_comm_error(milter));
588    } else if ((pkt_len = ntohl(len)) < 1) {
589	msg_warn("milter %s: bad packet length: %ld",
590		 milter->m.name, (long) pkt_len);
591	return (milter8_comm_error(milter));
592    } else if (pkt_len > XXX_MAX_DATA) {
593	msg_warn("milter %s: unreasonable packet length: %ld > %ld",
594		 milter->m.name, (long) pkt_len, (long) XXX_MAX_DATA);
595	return (milter8_comm_error(milter));
596    }
597
598    /*
599     * Receive the command code.
600     */
601    else if ((cmd = VSTREAM_GETC(milter->fp)) == VSTREAM_EOF) {
602	msg_warn("milter %s: EOF while reading command code: %m",
603		 milter->m.name);
604	return (milter8_comm_error(milter));
605    }
606
607    /*
608     * All is well.
609     */
610    else {
611	*command = cmd;
612	*data_len = pkt_len - 1;
613	return (0);
614    }
615}
616
617static int milter8_read_data(MILTER8 *milter, ssize_t *data_len,...);
618
619/* vmilter8_read_data - read command data */
620
621static int vmilter8_read_data(MILTER8 *milter, ssize_t *data_len, va_list ap)
622{
623    const char *myname = "milter8_read_data";
624    int     arg_type;
625    UINT32_TYPE net_long;
626    UINT32_TYPE *host_long_ptr;
627    VSTRING *buf;
628    int     ch;
629
630    while ((arg_type = va_arg(ap, int)) > 0 && arg_type != MILTER8_DATA_MORE) {
631	switch (arg_type) {
632
633	    /*
634	     * Host order long.
635	     */
636	case MILTER8_DATA_HLONG:
637	    if (*data_len < UINT32_SIZE) {
638		msg_warn("milter %s: input packet too short for network long",
639			 milter->m.name);
640		return (milter8_comm_error(milter));
641	    }
642	    host_long_ptr = va_arg(ap, UINT32_TYPE *);
643	    if (vstream_fread(milter->fp, (char *) &net_long, UINT32_SIZE)
644		!= UINT32_SIZE) {
645		msg_warn("milter %s: EOF while reading network long: %m",
646			 milter->m.name);
647		return (milter8_comm_error(milter));
648	    }
649	    *data_len -= UINT32_SIZE;
650	    *host_long_ptr = ntohl(net_long);
651	    break;
652
653	    /*
654	     * Raw on-the-wire format, without explicit null terminator.
655	     */
656	case MILTER8_DATA_BUFFER:
657	    if (*data_len < 0) {
658		msg_warn("milter %s: no data in input packet", milter->m.name);
659		return (milter8_comm_error(milter));
660	    }
661	    buf = va_arg(ap, VSTRING *);
662	    VSTRING_RESET(buf);
663	    VSTRING_SPACE(buf, *data_len);
664	    if (vstream_fread(milter->fp, (char *) STR(buf), *data_len)
665		!= *data_len) {
666		msg_warn("milter %s: EOF while reading data: %m", milter->m.name);
667		return (milter8_comm_error(milter));
668	    }
669	    VSTRING_AT_OFFSET(buf, *data_len);
670	    *data_len = 0;
671	    break;
672
673	    /*
674	     * Pointer to null-terminated string.
675	     */
676	case MILTER8_DATA_STRING:
677	    if (*data_len < 1) {
678		msg_warn("milter %s: packet too short for string",
679			 milter->m.name);
680		return (milter8_comm_error(milter));
681	    }
682	    buf = va_arg(ap, VSTRING *);
683	    VSTRING_RESET(buf);
684	    for (;;) {
685		if ((ch = VSTREAM_GETC(milter->fp)) == VSTREAM_EOF) {
686		    msg_warn("%s: milter %s: EOF while reading string: %m",
687			     myname, milter->m.name);
688		    return (milter8_comm_error(milter));
689		}
690		*data_len -= 1;
691		if (ch == 0)
692		    break;
693		VSTRING_ADDCH(buf, ch);
694		if (*data_len <= 0) {
695		    msg_warn("%s: milter %s: missing string null termimator",
696			     myname, milter->m.name);
697		    return (milter8_comm_error(milter));
698		}
699	    }
700	    VSTRING_TERMINATE(buf);
701	    break;
702
703	    /*
704	     * Error.
705	     */
706	default:
707	    msg_panic("%s: unknown argument type: %d", myname, arg_type);
708	}
709    }
710
711    /*
712     * Sanity checks. We may have excess data when the sender is confused. We
713     * may have a negative count when we're confused ourselves.
714     */
715    if (arg_type != MILTER8_DATA_MORE && *data_len > 0) {
716	msg_warn("%s: left-over data %ld bytes", myname, (long) *data_len);
717	return (milter8_comm_error(milter));
718    }
719    if (*data_len < 0)
720	msg_panic("%s: bad left-over data count %ld",
721		  myname, (long) *data_len);
722    return (0);
723}
724
725/* milter8_read_data - read command data */
726
727static int milter8_read_data(MILTER8 *milter, ssize_t *data_len,...)
728{
729    va_list ap;
730    int     ret;
731
732    va_start(ap, data_len);
733    ret = vmilter8_read_data(milter, data_len, ap);
734    va_end(ap);
735    return (ret);
736}
737
738/* vmilter8_size_data - compute command data length */
739
740static ssize_t vmilter8_size_data(va_list ap)
741{
742    const char *myname = "vmilter8_size_data";
743    ssize_t data_len;
744    int     arg_type;
745    VSTRING *buf;
746    const char *str;
747    const char **cpp;
748
749    /*
750     * Compute data size.
751     */
752    for (data_len = 0; (arg_type = va_arg(ap, int)) > 0; /* void */ ) {
753	switch (arg_type) {
754
755	    /*
756	     * Host order long.
757	     */
758	case MILTER8_DATA_HLONG:
759	    (void) va_arg(ap, UINT32_TYPE);
760	    data_len += UINT32_SIZE;
761	    break;
762
763	    /*
764	     * Raw on-the-wire format.
765	     */
766	case MILTER8_DATA_BUFFER:
767	    buf = va_arg(ap, VSTRING *);
768	    data_len += LEN(buf);
769	    break;
770
771	    /*
772	     * Pointer to null-terminated string.
773	     */
774	case MILTER8_DATA_STRING:
775	    str = va_arg(ap, char *);
776	    data_len += strlen(str) + 1;
777	    break;
778
779	    /*
780	     * Array of pointers to null-terminated strings.
781	     */
782	case MILTER8_DATA_ARGV:
783	    for (cpp = va_arg(ap, const char **); *cpp; cpp++)
784		data_len += strlen(*cpp) + 1;
785	    break;
786
787	    /*
788	     * Network order short, promoted to int.
789	     */
790	case MILTER8_DATA_NSHORT:
791	    (void) va_arg(ap, unsigned);
792	    data_len += UINT16_SIZE;
793	    break;
794
795	    /*
796	     * Octet, promoted to int.
797	     */
798	case MILTER8_DATA_OCTET:
799	    (void) va_arg(ap, unsigned);
800	    data_len += 1;
801	    break;
802
803	    /*
804	     * Error.
805	     */
806	default:
807	    msg_panic("%s: bad argument type: %d", myname, arg_type);
808	}
809    }
810    va_end(ap);
811    return (data_len);
812}
813
814/* vmilter8_write_cmd - write command to Sendmail 8 Milter */
815
816static int vmilter8_write_cmd(MILTER8 *milter, int command, ssize_t data_len,
817			              va_list ap)
818{
819    const char *myname = "vmilter8_write_cmd";
820    int     arg_type;
821    UINT32_TYPE pkt_len;
822    UINT32_TYPE host_long;
823    UINT32_TYPE net_long;
824    UINT16_TYPE net_short;
825    VSTRING *buf;
826    const char *str;
827    const char **cpp;
828    char    ch;
829
830    /*
831     * Deliver the packet.
832     */
833    if ((pkt_len = 1 + data_len) < 1)
834	msg_panic("%s: bad packet length %d", myname, pkt_len);
835    pkt_len = htonl(pkt_len);
836    (void) vstream_fwrite(milter->fp, (char *) &pkt_len, UINT32_SIZE);
837    (void) VSTREAM_PUTC(command, milter->fp);
838    while ((arg_type = va_arg(ap, int)) > 0) {
839	switch (arg_type) {
840
841	    /*
842	     * Network long.
843	     */
844	case MILTER8_DATA_HLONG:
845	    host_long = va_arg(ap, UINT32_TYPE);
846	    net_long = htonl(host_long);
847	    (void) vstream_fwrite(milter->fp, (char *) &net_long, UINT32_SIZE);
848	    break;
849
850	    /*
851	     * Raw on-the-wire format.
852	     */
853	case MILTER8_DATA_BUFFER:
854	    buf = va_arg(ap, VSTRING *);
855	    (void) vstream_fwrite(milter->fp, STR(buf), LEN(buf));
856	    break;
857
858	    /*
859	     * Pointer to null-terminated string.
860	     */
861	case MILTER8_DATA_STRING:
862	    str = va_arg(ap, char *);
863	    (void) vstream_fwrite(milter->fp, str, strlen(str) + 1);
864	    break;
865
866	    /*
867	     * Octet, promoted to int.
868	     */
869	case MILTER8_DATA_OCTET:
870	    ch = va_arg(ap, unsigned);
871	    (void) vstream_fwrite(milter->fp, &ch, 1);
872	    break;
873
874	    /*
875	     * Array of pointers to null-terminated strings.
876	     */
877	case MILTER8_DATA_ARGV:
878	    for (cpp = va_arg(ap, const char **); *cpp; cpp++)
879		(void) vstream_fwrite(milter->fp, *cpp, strlen(*cpp) + 1);
880	    break;
881
882	    /*
883	     * Network order short, promoted to int.
884	     */
885	case MILTER8_DATA_NSHORT:
886	    net_short = va_arg(ap, unsigned);
887	    (void) vstream_fwrite(milter->fp, (char *) &net_short, UINT16_SIZE);
888	    break;
889
890	    /*
891	     * Error.
892	     */
893	default:
894	    msg_panic("%s: bad argument type: %d", myname, arg_type);
895	}
896
897	/*
898	 * Report errors immediately.
899	 */
900	if (vstream_ferror(milter->fp)) {
901	    msg_warn("milter %s: error writing command: %m", milter->m.name);
902	    milter8_comm_error(milter);
903	    break;
904	}
905    }
906    va_end(ap);
907    return (milter->state == MILTER8_STAT_ERROR);
908}
909
910/* milter8_write_cmd - write command to Sendmail 8 Milter */
911
912static int milter8_write_cmd(MILTER8 *milter, int command,...)
913{
914    va_list ap;
915    va_list ap2;
916    ssize_t data_len;
917    int     err;
918
919    /*
920     * Initialize argument lists.
921     */
922    va_start(ap, command);
923    VA_COPY(ap2, ap);
924
925    /*
926     * Size the command data.
927     */
928    data_len = vmilter8_size_data(ap);
929    va_end(ap);
930
931    /*
932     * Send the command and data.
933     */
934    err = vmilter8_write_cmd(milter, command, data_len, ap2);
935    va_end(ap2);
936
937    return (err);
938}
939
940/* milter8_event - report event and receive reply */
941
942static const char *milter8_event(MILTER8 *milter, int event,
943				         int skip_event_flag,
944				         int skip_reply,
945				         ARGV *macros,...)
946{
947    const char *myname = "milter8_event";
948    va_list ap;
949    va_list ap2;
950    ssize_t data_len;
951    int     err;
952    unsigned char cmd;
953    ssize_t data_size;
954    const char *smfic_name;
955    const char *smfir_name;
956    MILTERS *parent = milter->m.parent;
957    UINT32_TYPE index;
958    const char *edit_resp = 0;
959    const char *retval = 0;
960    VSTRING *body_line_buf = 0;
961    int     done = 0;
962    int     body_edit_lockout = 0;
963
964#define DONT_SKIP_REPLY	0
965
966    /*
967     * Sanity check.
968     */
969    if (milter->fp == 0 || milter->def_reply != 0) {
970	msg_warn("%s: attempt to send event %s to milter %s after error",
971		 myname,
972		 (smfic_name = str_name_code(smfic_table, event)) != 0 ?
973		 smfic_name : "(unknown MTA event)", milter->m.name);
974	return (milter->def_reply);
975    }
976
977    /*
978     * Skip this event if it doesn't exist in the protocol that I announced.
979     */
980    if ((skip_event_flag & milter->np_mask) != 0) {
981	if (msg_verbose)
982	    msg_info("skipping non-protocol event %s for milter %s",
983		     (smfic_name = str_name_code(smfic_table, event)) != 0 ?
984		     smfic_name : "(unknown MTA event)", milter->m.name);
985	return (milter->def_reply);
986    }
987
988    /*
989     * Skip further events of this type if the filter told us so.
990     */
991    if (milter->skip_event_type != 0) {
992	if (event == milter->skip_event_type) {
993	    if (msg_verbose)
994		msg_info("skipping event %s after SMFIR_SKIP from milter %s",
995		     (smfic_name = str_name_code(smfic_table, event)) != 0 ?
996			 smfic_name : "(unknown MTA event)", milter->m.name);
997	    return (milter->def_reply);
998	} else {
999	    milter->skip_event_type = 0;
1000	}
1001    }
1002
1003    /*
1004     * Send the macros for this event, even when we're not reporting the
1005     * event itself. This does not introduce a performance problem because
1006     * we're sending macros and event parameters in one VSTREAM transaction.
1007     *
1008     * XXX Is this still necessary?
1009     */
1010    if (msg_verbose) {
1011	VSTRING *buf = vstring_alloc(100);
1012
1013	if (macros) {
1014	    if (macros->argc > 0) {
1015		char  **cpp;
1016
1017		for (cpp = macros->argv; *cpp && cpp[1]; cpp += 2)
1018		    vstring_sprintf_append(buf, " %s=%s", *cpp, cpp[1]);
1019	    }
1020	}
1021	msg_info("event: %s; macros:%s",
1022		 (smfic_name = str_name_code(smfic_table, event)) != 0 ?
1023		 smfic_name : "(unknown MTA event)", *STR(buf) ?
1024		 STR(buf) : " (none)");
1025	vstring_free(buf);
1026    }
1027    if (macros) {
1028	if (milter8_write_cmd(milter, SMFIC_MACRO,
1029			      MILTER8_DATA_OCTET, event,
1030			      MILTER8_DATA_ARGV, macros->argv,
1031			      MILTER8_DATA_END) != 0)
1032	    return (milter->def_reply);
1033    }
1034
1035    /*
1036     * Skip this event if the Milter told us not to send it.
1037     */
1038    if ((skip_event_flag & milter->ev_mask) != 0) {
1039	if (msg_verbose)
1040	    msg_info("skipping event %s for milter %s",
1041		     (smfic_name = str_name_code(smfic_table, event)) != 0 ?
1042		     smfic_name : "(unknown MTA event)", milter->m.name);
1043	return (milter->def_reply);
1044    }
1045
1046    /*
1047     * Initialize argument lists.
1048     */
1049    va_start(ap, macros);
1050    VA_COPY(ap2, ap);
1051
1052    /*
1053     * Compute the command data size. This is necessary because the protocol
1054     * sends length before content.
1055     */
1056    data_len = vmilter8_size_data(ap);
1057    va_end(ap);
1058
1059    /*
1060     * Send the command and data.
1061     */
1062    err = vmilter8_write_cmd(milter, event, data_len, ap2);
1063    va_end(ap2);
1064
1065    /*
1066     * C99 requires that we finalize argument lists before returning.
1067     */
1068    if (err != 0)
1069	return (milter->def_reply);
1070
1071    /*
1072     * Special feature: don't wait for one reply per header. This allows us
1073     * to send multiple headers in one VSTREAM transaction, and improves
1074     * over-all performance.
1075     */
1076    if (skip_reply) {
1077	if (msg_verbose)
1078	    msg_info("skipping reply for event %s from milter %s",
1079		     (smfic_name = str_name_code(smfic_table, event)) != 0 ?
1080		     smfic_name : "(unknown MTA event)", milter->m.name);
1081	return (milter->def_reply);
1082    }
1083
1084    /*
1085     * Receive the reply or replies.
1086     *
1087     * Intercept all loop exits so that we can do post header/body edit
1088     * processing.
1089     *
1090     * XXX Bound the loop iteration count.
1091     *
1092     * In the end-of-body stage, the Milter may reply with one or more queue
1093     * file edit requests before it replies with its final decision: accept,
1094     * reject, etc. After a local queue file edit error (file too big, media
1095     * write error), do not close the Milter socket in the cleanup server.
1096     * Instead skip all further Milter replies until the final decision. This
1097     * way the Postfix SMTP server stays in sync with the Milter, and Postfix
1098     * doesn't have to lose the ability to handle multiple deliveries within
1099     * the same SMTP session. This requires that the Postfix SMTP server uses
1100     * something other than CLEANUP_STAT_WRITE when it loses contact with the
1101     * cleanup server.
1102     */
1103#define IN_CONNECT_EVENT(e) ((e) == SMFIC_CONNECT || (e) == SMFIC_HELO)
1104
1105    /*
1106     * XXX Don't evaluate this macro's argument multiple times. Since we use
1107     * "continue" the macro can't be enclosed in do .. while (0).
1108     */
1109#define MILTER8_EVENT_BREAK(s) { \
1110	retval = (s); \
1111	done = 1; \
1112	continue; \
1113    }
1114
1115    while (done == 0) {
1116	char   *cp;
1117	char   *rp;
1118	char    ch;
1119	char   *next;
1120
1121	if (milter8_read_resp(milter, event, &cmd, &data_size) != 0)
1122	    MILTER8_EVENT_BREAK(milter->def_reply);
1123	if (msg_verbose)
1124	    msg_info("reply: %s data %ld bytes",
1125		     (smfir_name = str_name_code(smfir_table, cmd)) != 0 ?
1126		     smfir_name : "unknown", (long) data_size);
1127
1128	/*
1129	 * Handle unfinished message body replacement first.
1130	 *
1131	 * XXX When SMFIR_REPLBODY is followed by some different request, we
1132	 * assume that the body replacement operation is complete. The queue
1133	 * file editing implementation currently does not support sending
1134	 * part 1 of the body replacement text, doing some other queue file
1135	 * updates, and then sending part 2 of the body replacement text. To
1136	 * avoid loss of data, we log an error when SMFIR_REPLBODY requests
1137	 * are alternated with other requests.
1138	 */
1139	if (body_line_buf != 0 && cmd != SMFIR_REPLBODY) {
1140	    /* In case the last body replacement line didn't end in CRLF. */
1141	    if (edit_resp == 0 && LEN(body_line_buf) > 0)
1142		edit_resp = parent->repl_body(parent->chg_context,
1143					      MILTER_BODY_LINE,
1144					      body_line_buf);
1145	    if (edit_resp == 0)
1146		edit_resp = parent->repl_body(parent->chg_context,
1147					      MILTER_BODY_END,
1148					      (VSTRING *) 0);
1149	    body_edit_lockout = 1;
1150	    vstring_free(body_line_buf);
1151	    body_line_buf = 0;
1152	}
1153	switch (cmd) {
1154
1155	    /*
1156	     * Still working on it.
1157	     */
1158	case SMFIR_PROGRESS:
1159	    if (data_size != 0)
1160		break;
1161	    continue;
1162
1163	    /*
1164	     * Decision: continue processing.
1165	     */
1166	case SMFIR_CONTINUE:
1167	    if (data_size != 0)
1168		break;
1169	    MILTER8_EVENT_BREAK(milter->def_reply);
1170
1171	    /*
1172	     * Decision: accept this message, or accept all further commands
1173	     * in this SMTP connection. This decision is final (i.e. Sendmail
1174	     * 8 changes receiver state).
1175	     */
1176	case SMFIR_ACCEPT:
1177	    if (data_size != 0)
1178		break;
1179	    if (IN_CONNECT_EVENT(event)) {
1180#ifdef LIBMILTER_AUTO_DISCONNECT
1181		milter8_close_stream(milter);
1182#endif
1183		/* No more events for this SMTP connection. */
1184		milter->state = MILTER8_STAT_ACCEPT_CON;
1185	    } else {
1186		/* No more events for this message. */
1187		milter->state = MILTER8_STAT_ACCEPT_MSG;
1188	    }
1189	    MILTER8_EVENT_BREAK(milter->def_reply);
1190
1191	    /*
1192	     * Decision: accept and silently discard this message. According
1193	     * to the milter API documentation there will be no action when
1194	     * this is requested by a connection-level function. This
1195	     * decision is final (i.e. Sendmail 8 changes receiver state).
1196	     */
1197	case SMFIR_DISCARD:
1198	    if (data_size != 0)
1199		break;
1200	    if (IN_CONNECT_EVENT(event)) {
1201		msg_warn("milter %s: DISCARD action is not allowed "
1202			 "for connect or helo", milter->m.name);
1203		MILTER8_EVENT_BREAK(milter->def_reply);
1204	    } else {
1205		/* No more events for this message. */
1206		milter->state = MILTER8_STAT_ACCEPT_MSG;
1207		MILTER8_EVENT_BREAK("D");
1208	    }
1209
1210	    /*
1211	     * Decision: reject connection, message or recipient. This
1212	     * decision is final (i.e. Sendmail 8 changes receiver state).
1213	     */
1214	case SMFIR_REJECT:
1215	    if (data_size != 0)
1216		break;
1217	    if (IN_CONNECT_EVENT(event)) {
1218#ifdef LIBMILTER_AUTO_DISCONNECT
1219		milter8_close_stream(milter);
1220#endif
1221		milter->state = MILTER8_STAT_REJECT_CON;
1222		MILTER8_EVENT_BREAK(milter8_def_reply(milter, "550 5.7.1 Command rejected"));
1223	    } else {
1224		MILTER8_EVENT_BREAK("550 5.7.1 Command rejected");
1225	    }
1226
1227	    /*
1228	     * Decision: tempfail. This decision is final (i.e. Sendmail 8
1229	     * changes receiver state).
1230	     */
1231	case SMFIR_TEMPFAIL:
1232	    if (data_size != 0)
1233		break;
1234	    if (IN_CONNECT_EVENT(event)) {
1235#ifdef LIBMILTER_AUTO_DISCONNECT
1236		milter8_close_stream(milter);
1237#endif
1238		milter->state = MILTER8_STAT_REJECT_CON;
1239		MILTER8_EVENT_BREAK(milter8_def_reply(milter,
1240			"451 4.7.1 Service unavailable - try again later"));
1241	    } else {
1242		MILTER8_EVENT_BREAK("451 4.7.1 Service unavailable - try again later");
1243	    }
1244
1245	    /*
1246	     * Decision: disconnect. This decision is final (i.e. Sendmail 8
1247	     * changes receiver state).
1248	     */
1249	case SMFIR_SHUTDOWN:
1250	    if (data_size != 0)
1251		break;
1252#ifdef LIBMILTER_AUTO_DISCONNECT
1253	    milter8_close_stream(milter);
1254#endif
1255	    milter->state = MILTER8_STAT_REJECT_CON;
1256	    MILTER8_EVENT_BREAK(milter8_def_reply(milter, "S"));
1257
1258	    /*
1259	     * Decision: "ddd d.d+.d+ text". This decision is final (i.e.
1260	     * Sendmail 8 changes receiver state). Note: the reply may be in
1261	     * multi-line SMTP format.
1262	     *
1263	     * XXX Sendmail compatibility: sendmail 8 uses the reply as a format
1264	     * string; therefore any '%' characters in the reply are doubled.
1265	     * Postfix doesn't use replies as format strings; we replace '%%'
1266	     * by '%', and remove single (i.e. invalid) '%' characters.
1267	     */
1268	case SMFIR_REPLYCODE:
1269	    if (milter8_read_data(milter, &data_size,
1270				  MILTER8_DATA_BUFFER, milter->buf,
1271				  MILTER8_DATA_END) != 0)
1272		MILTER8_EVENT_BREAK(milter->def_reply);
1273	    /* XXX Enforce this for each line of a multi-line reply. */
1274	    if ((STR(milter->buf)[0] != '4' && STR(milter->buf)[0] != '5')
1275		|| !ISDIGIT(STR(milter->buf)[1])
1276		|| !ISDIGIT(STR(milter->buf)[2])
1277		|| (STR(milter->buf)[3] != ' ' && STR(milter->buf)[3] != '-')
1278		|| (ISDIGIT(STR(milter->buf)[4])
1279		    && (STR(milter->buf)[4] != STR(milter->buf)[0]))) {
1280		msg_warn("milter %s: malformed reply: %s",
1281			 milter->m.name, STR(milter->buf));
1282		milter8_conf_error(milter);
1283		MILTER8_EVENT_BREAK(milter->def_reply);
1284	    }
1285	    if ((rp = cp = strchr(STR(milter->buf), '%')) != 0) {
1286		for (;;) {
1287		    if ((ch = *cp++) == '%')
1288			ch = *cp++;
1289		    *rp++ = ch;
1290		    if (ch == 0)
1291			break;
1292		}
1293	    }
1294	    if (var_soft_bounce) {
1295		for (cp = STR(milter->buf); /* void */ ; cp = next) {
1296		    if (cp[0] == '5') {
1297			cp[0] = '4';
1298			if (cp[4] == '5')
1299			    cp[4] = '4';
1300		    }
1301		    if ((next = strstr(cp, "\r\n")) == 0)
1302			break;
1303		    next += 2;
1304		}
1305	    }
1306	    if (IN_CONNECT_EVENT(event)) {
1307#ifdef LIBMILTER_AUTO_DISCONNECT
1308		milter8_close_stream(milter);
1309#endif
1310		milter->state = MILTER8_STAT_REJECT_CON;
1311		MILTER8_EVENT_BREAK(milter8_def_reply(milter, STR(milter->buf)));
1312	    } else {
1313		MILTER8_EVENT_BREAK(STR(milter->buf));
1314	    }
1315
1316	    /*
1317	     * Decision: quarantine. In Sendmail 8.13 this does not imply a
1318	     * transition in the receiver state (reply, reject, tempfail,
1319	     * accept, discard). We should not transition, either, otherwise
1320	     * we get out of sync.
1321	     */
1322	case SMFIR_QUARANTINE:
1323	    /* XXX What to do with the "reason" text? */
1324	    if (milter8_read_data(milter, &data_size,
1325				  MILTER8_DATA_BUFFER, milter->buf,
1326				  MILTER8_DATA_END) != 0)
1327		MILTER8_EVENT_BREAK(milter->def_reply);
1328	    milter8_def_reply(milter, "H");
1329	    continue;
1330
1331	    /*
1332	     * Decision: skip further events of this type.
1333	     */
1334	case SMFIR_SKIP:
1335	    if (data_size != 0)
1336		break;
1337	    milter->skip_event_type = event;
1338	    MILTER8_EVENT_BREAK(milter->def_reply);
1339
1340	    /*
1341	     * Modification request or error.
1342	     */
1343	default:
1344	    if (event == SMFIC_BODYEOB) {
1345		switch (cmd) {
1346
1347#define MILTER8_HDR_SPACE(m) (((m)->ev_mask & SMFIP_HDR_LEADSPC) ? "" : " ")
1348
1349		    /*
1350		     * Modification request: replace, insert or delete
1351		     * header. Index 1 means the first instance.
1352		     */
1353		case SMFIR_CHGHEADER:
1354		    if (milter8_read_data(milter, &data_size,
1355					  MILTER8_DATA_HLONG, &index,
1356					  MILTER8_DATA_STRING, milter->buf,
1357					  MILTER8_DATA_STRING, milter->body,
1358					  MILTER8_DATA_END) != 0)
1359			MILTER8_EVENT_BREAK(milter->def_reply);
1360		    /* Skip to the next request after previous edit error. */
1361		    if (edit_resp)
1362			continue;
1363		    /* XXX Sendmail 8 compatibility. */
1364		    if (index == 0)
1365			index = 1;
1366		    if ((ssize_t) index < 1) {
1367			msg_warn("milter %s: bad change header index: %ld",
1368				 milter->m.name, (long) index);
1369			milter8_conf_error(milter);
1370			MILTER8_EVENT_BREAK(milter->def_reply);
1371		    }
1372		    if (LEN(milter->buf) == 0) {
1373			msg_warn("milter %s: null change header name",
1374				 milter->m.name);
1375			milter8_conf_error(milter);
1376			MILTER8_EVENT_BREAK(milter->def_reply);
1377		    }
1378		    if (STR(milter->body)[0])
1379			edit_resp = parent->upd_header(parent->chg_context,
1380						       (ssize_t) index,
1381						       STR(milter->buf),
1382						  MILTER8_HDR_SPACE(milter),
1383						       STR(milter->body));
1384		    else
1385			edit_resp = parent->del_header(parent->chg_context,
1386						       (ssize_t) index,
1387						       STR(milter->buf));
1388		    continue;
1389
1390		    /*
1391		     * Modification request: append header.
1392		     */
1393		case SMFIR_ADDHEADER:
1394		    if (milter8_read_data(milter, &data_size,
1395					  MILTER8_DATA_STRING, milter->buf,
1396					  MILTER8_DATA_STRING, milter->body,
1397					  MILTER8_DATA_END) != 0)
1398			MILTER8_EVENT_BREAK(milter->def_reply);
1399		    /* Skip to the next request after previous edit error. */
1400		    if (edit_resp)
1401			continue;
1402		    edit_resp = parent->add_header(parent->chg_context,
1403						   STR(milter->buf),
1404						   MILTER8_HDR_SPACE(milter),
1405						   STR(milter->body));
1406		    continue;
1407
1408		    /*
1409		     * Modification request: insert header. With Sendmail 8,
1410		     * index 0 means the top-most header. We use 1-based
1411		     * indexing for consistency with header change
1412		     * operations.
1413		     */
1414		case SMFIR_INSHEADER:
1415		    if (milter8_read_data(milter, &data_size,
1416					  MILTER8_DATA_HLONG, &index,
1417					  MILTER8_DATA_STRING, milter->buf,
1418					  MILTER8_DATA_STRING, milter->body,
1419					  MILTER8_DATA_END) != 0)
1420			MILTER8_EVENT_BREAK(milter->def_reply);
1421		    /* Skip to the next request after previous edit error. */
1422		    if (edit_resp)
1423			continue;
1424		    if ((ssize_t) index + 1 < 1) {
1425			msg_warn("milter %s: bad insert header index: %ld",
1426				 milter->m.name, (long) index);
1427			milter8_conf_error(milter);
1428			MILTER8_EVENT_BREAK(milter->def_reply);
1429		    }
1430		    edit_resp = parent->ins_header(parent->chg_context,
1431						   (ssize_t) index + 1,
1432						   STR(milter->buf),
1433						   MILTER8_HDR_SPACE(milter),
1434						   STR(milter->body));
1435		    continue;
1436
1437		    /*
1438		     * Modification request: replace sender, with optional
1439		     * ESMTP args.
1440		     */
1441		case SMFIR_CHGFROM:
1442		    if (milter8_read_data(milter, &data_size,
1443					  MILTER8_DATA_STRING, milter->buf,
1444					  MILTER8_DATA_MORE) != 0)
1445			MILTER8_EVENT_BREAK(milter->def_reply);
1446		    if (data_size > 0) {
1447			if (milter8_read_data(milter, &data_size,
1448					  MILTER8_DATA_STRING, milter->body,
1449					      MILTER8_DATA_END) != 0)
1450			    MILTER8_EVENT_BREAK(milter->def_reply);
1451		    } else {
1452			VSTRING_RESET(milter->body);
1453			VSTRING_TERMINATE(milter->body);
1454		    }
1455		    /* Skip to the next request after previous edit error. */
1456		    if (edit_resp)
1457			continue;
1458		    edit_resp = parent->chg_from(parent->chg_context,
1459						 STR(milter->buf),
1460						 STR(milter->body));
1461		    continue;
1462
1463		    /*
1464		     * Modification request: append recipient.
1465		     */
1466		case SMFIR_ADDRCPT:
1467		    if (milter8_read_data(milter, &data_size,
1468					  MILTER8_DATA_STRING, milter->buf,
1469					  MILTER8_DATA_END) != 0)
1470			MILTER8_EVENT_BREAK(milter->def_reply);
1471		    /* Skip to the next request after previous edit error. */
1472		    if (edit_resp)
1473			continue;
1474		    edit_resp = parent->add_rcpt(parent->chg_context,
1475						 STR(milter->buf));
1476		    continue;
1477
1478		    /*
1479		     * Modification request: append recipient, with optional
1480		     * ESMTP args.
1481		     */
1482		case SMFIR_ADDRCPT_PAR:
1483		    if (milter8_read_data(milter, &data_size,
1484					  MILTER8_DATA_STRING, milter->buf,
1485					  MILTER8_DATA_MORE) != 0)
1486			MILTER8_EVENT_BREAK(milter->def_reply);
1487		    if (data_size > 0) {
1488			if (milter8_read_data(milter, &data_size,
1489					  MILTER8_DATA_STRING, milter->body,
1490					      MILTER8_DATA_END) != 0)
1491			    MILTER8_EVENT_BREAK(milter->def_reply);
1492		    } else {
1493			VSTRING_RESET(milter->body);
1494			VSTRING_TERMINATE(milter->body);
1495		    }
1496		    /* Skip to the next request after previous edit error. */
1497		    if (edit_resp)
1498			continue;
1499		    edit_resp = parent->add_rcpt_par(parent->chg_context,
1500						     STR(milter->buf),
1501						     STR(milter->body));
1502		    continue;
1503
1504		    /*
1505		     * Modification request: delete (expansion of) recipient.
1506		     */
1507		case SMFIR_DELRCPT:
1508		    if (milter8_read_data(milter, &data_size,
1509					  MILTER8_DATA_STRING, milter->buf,
1510					  MILTER8_DATA_END) != 0)
1511			MILTER8_EVENT_BREAK(milter->def_reply);
1512		    /* Skip to the next request after previous edit error. */
1513		    if (edit_resp)
1514			continue;
1515		    edit_resp = parent->del_rcpt(parent->chg_context,
1516						 STR(milter->buf));
1517		    continue;
1518
1519		    /*
1520		     * Modification request: replace the message body, and
1521		     * update the message size.
1522		     */
1523		case SMFIR_REPLBODY:
1524		    if (body_edit_lockout) {
1525			msg_warn("milter %s: body replacement requests can't "
1526				 "currently be mixed with other requests",
1527				 milter->m.name);
1528			milter8_conf_error(milter);
1529			MILTER8_EVENT_BREAK(milter->def_reply);
1530		    }
1531		    if (milter8_read_data(milter, &data_size,
1532					  MILTER8_DATA_BUFFER, milter->body,
1533					  MILTER8_DATA_END) != 0)
1534			MILTER8_EVENT_BREAK(milter->def_reply);
1535		    /* Skip to the next request after previous edit error. */
1536		    if (edit_resp)
1537			continue;
1538		    /* Start body replacement. */
1539		    if (body_line_buf == 0) {
1540			body_line_buf = vstring_alloc(var_line_limit);
1541			edit_resp = parent->repl_body(parent->chg_context,
1542						      MILTER_BODY_START,
1543						      (VSTRING *) 0);
1544		    }
1545		    /* Extract lines from the on-the-wire CRLF format. */
1546		    for (cp = STR(milter->body); edit_resp == 0
1547			 && cp < vstring_end(milter->body); cp++) {
1548			ch = *(unsigned char *) cp;
1549			if (ch == '\n') {
1550			    if (LEN(body_line_buf) > 0
1551				&& vstring_end(body_line_buf)[-1] == '\r')
1552				vstring_truncate(body_line_buf,
1553						 LEN(body_line_buf) - 1);
1554			    edit_resp = parent->repl_body(parent->chg_context,
1555							  MILTER_BODY_LINE,
1556							  body_line_buf);
1557			    VSTRING_RESET(body_line_buf);
1558			} else {
1559			    VSTRING_ADDCH(body_line_buf, ch);
1560			}
1561		    }
1562		    continue;
1563		}
1564	    }
1565	    msg_warn("milter %s: unexpected filter response %s after event %s",
1566		     milter->m.name,
1567		     (smfir_name = str_name_code(smfir_table, cmd)) != 0 ?
1568		     smfir_name : "(unknown filter reply)",
1569		     (smfic_name = str_name_code(smfic_table, event)) != 0 ?
1570		     smfic_name : "(unknown MTA event)");
1571	    milter8_comm_error(milter);
1572	    MILTER8_EVENT_BREAK(milter->def_reply);
1573	}
1574
1575	/*
1576	 * Get here when the reply was followed by data bytes that weren't
1577	 * supposed to be there.
1578	 */
1579	msg_warn("milter %s: reply %s was followed by %ld data bytes",
1580	milter->m.name, (smfir_name = str_name_code(smfir_table, cmd)) != 0 ?
1581		 smfir_name : "unknown", (long) data_len);
1582	milter8_comm_error(milter);
1583	MILTER8_EVENT_BREAK(milter->def_reply);
1584    }
1585
1586    /*
1587     * Clean up after aborted message body replacement.
1588     */
1589    if (body_line_buf)
1590	vstring_free(body_line_buf);
1591
1592    /*
1593     * XXX Some cleanup clients ask the cleanup server to bounce mail for
1594     * them. In that case we must override a hard reject retval result after
1595     * queue file update failure. This is not a big problem; the odds are
1596     * small that a Milter application sends a hard reject after replacing
1597     * the message body.
1598     */
1599    if (edit_resp && (retval == 0 || strchr("DS4", retval[0]) == 0))
1600	retval = edit_resp;
1601    return (retval);
1602}
1603
1604/* milter8_connect - connect to filter */
1605
1606static void milter8_connect(MILTER8 *milter)
1607{
1608    const char *myname = "milter8_connect";
1609    ssize_t data_len;
1610    unsigned char cmd;
1611    char   *transport;
1612    char   *endpoint;
1613    int     (*connect_fn) (const char *, int, int);
1614    int     fd;
1615    const UINT32_TYPE my_actions = (SMFIF_ADDHDRS | SMFIF_ADDRCPT
1616				    | SMFIF_DELRCPT | SMFIF_CHGHDRS
1617				    | SMFIF_CHGBODY
1618				    | SMFIF_QUARANTINE
1619				    | SMFIF_CHGFROM
1620				    | SMFIF_ADDRCPT_PAR
1621				    | SMFIF_SETSYMLIST
1622    );
1623    UINT32_TYPE my_version = 0;
1624    UINT32_TYPE my_events = 0;
1625    char   *saved_version;
1626    char   *cp;
1627    char   *name;
1628
1629    /*
1630     * Sanity check.
1631     */
1632    if (milter->fp != 0)
1633	msg_panic("%s: milter %s: socket is not closed",
1634		  myname, milter->m.name);
1635
1636    /*
1637     * For user friendliness reasons the milter_protocol configuration
1638     * parameter can specify both the protocol version and protocol
1639     * extensions (e.g., don't reply for each individual message header).
1640     *
1641     * The protocol version is sent as is to the milter application.
1642     *
1643     * The version and extensions determine what events we can send to the
1644     * milter application.
1645     *
1646     * We don't announce support for events that aren't defined for my protocol
1647     * version. Today's libmilter implementations don't seem to care, but we
1648     * don't want to take the risk that a future version will be more picky.
1649     */
1650    cp = saved_version = mystrdup(milter->protocol);
1651    while ((name = mystrtok(&cp, " ,\t\r\n")) != 0) {
1652	int     mask;
1653	int     vers;
1654
1655	if ((mask = name_code(milter8_event_masks,
1656			      NAME_CODE_FLAG_NONE, name)) == -1
1657	    || (vers = name_code(milter8_versions,
1658				 NAME_CODE_FLAG_NONE, name)) == -1
1659	    || (vers != 0 && my_version != 0)) {
1660	    msg_warn("milter %s: bad protocol information: %s",
1661		     milter->m.name, name);
1662	    milter8_conf_error(milter);
1663	    return;
1664	}
1665	if (vers != 0)
1666	    my_version = vers;
1667	my_events |= mask;
1668    }
1669    myfree(saved_version);
1670    if (my_events == 0 || my_version == 0) {
1671	msg_warn("milter %s: no protocol version information", milter->m.name);
1672	milter8_conf_error(milter);
1673	return;
1674    }
1675
1676    /*
1677     * Don't send events that aren't defined for my protocol version.
1678     */
1679    milter->np_mask = (SMFIP_NOSEND_MASK & ~my_events);
1680    if (msg_verbose)
1681	msg_info("%s: non-protocol events for protocol version %d: %s",
1682		 myname, my_version,
1683		 str_name_mask_opt(milter->buf, "non-protocol event mask",
1684			   smfip_table, milter->np_mask, NAME_MASK_NUMBER));
1685
1686    /*
1687     * Parse the Milter application endpoint.
1688     */
1689#define FREE_TRANSPORT_AND_BAIL_OUT(milter, milter_error) do { \
1690	myfree(transport); \
1691	milter_error(milter); \
1692	return; \
1693    } while (0);
1694
1695    transport = mystrdup(milter->m.name);
1696    if ((endpoint = split_at(transport, ':')) == 0
1697	|| *endpoint == 0 || *transport == 0) {
1698	msg_warn("Milter service needs transport:endpoint instead of \"%s\"",
1699		 milter->m.name);
1700	FREE_TRANSPORT_AND_BAIL_OUT(milter, milter8_conf_error);
1701    }
1702    if (msg_verbose)
1703	msg_info("%s: transport=%s endpoint=%s", myname, transport, endpoint);
1704    if (strcmp(transport, "inet") == 0) {
1705	connect_fn = inet_connect;
1706    } else if (strcmp(transport, "unix") == 0) {
1707	connect_fn = unix_connect;
1708    } else if (strcmp(transport, "local") == 0) {
1709	connect_fn = LOCAL_CONNECT;
1710    } else {
1711	msg_warn("invalid transport name: %s in Milter service: %s",
1712		 transport, milter->m.name);
1713	FREE_TRANSPORT_AND_BAIL_OUT(milter, milter8_conf_error);
1714    }
1715
1716    /*
1717     * Connect to the Milter application.
1718     */
1719    if ((fd = connect_fn(endpoint, BLOCKING, milter->conn_timeout)) < 0) {
1720	msg_warn("connect to Milter service %s: %m", milter->m.name);
1721	FREE_TRANSPORT_AND_BAIL_OUT(milter, milter8_comm_error);
1722    }
1723    myfree(transport);
1724    milter->fp = vstream_fdopen(fd, O_RDWR);
1725    vstream_control(milter->fp,
1726		    VSTREAM_CTL_DOUBLE,
1727		    VSTREAM_CTL_TIMEOUT, milter->cmd_timeout,
1728		    VSTREAM_CTL_END);
1729    /* Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE. */
1730    if (connect_fn == inet_connect)
1731	vstream_tweak_tcp(milter->fp);
1732
1733    /*
1734     * Open the negotiations by sending what actions the Milter may request
1735     * and what events the Milter can receive.
1736     */
1737    if (msg_verbose) {
1738	msg_info("%s: my_version=0x%lx", myname, (long) my_version);
1739	msg_info("%s: my_actions=0x%lx %s", myname, (long) my_actions,
1740		 str_name_mask_opt(milter->buf, "request mask",
1741				smfif_table, my_actions, NAME_MASK_NUMBER));
1742	msg_info("%s: my_events=0x%lx %s", myname, (long) my_events,
1743		 str_name_mask_opt(milter->buf, "event mask",
1744				 smfip_table, my_events, NAME_MASK_NUMBER));
1745    }
1746    errno = 0;
1747    if (milter8_write_cmd(milter, SMFIC_OPTNEG,
1748			  MILTER8_DATA_HLONG, my_version,
1749			  MILTER8_DATA_HLONG, my_actions,
1750			  MILTER8_DATA_HLONG, my_events,
1751			  MILTER8_DATA_END) != 0) {
1752	msg_warn("milter %s: write error in initial handshake",
1753		 milter->m.name);
1754	/* milter8_write_cmd() called milter8_comm_error() */
1755	return;
1756    }
1757
1758    /*
1759     * Receive the filter's response and verify that we are compatible.
1760     */
1761    if (milter8_read_resp(milter, SMFIC_OPTNEG, &cmd, &data_len) != 0) {
1762	msg_warn("milter %s: read error in initial handshake", milter->m.name);
1763	/* milter8_read_resp() called milter8_comm_error() */
1764	return;
1765    }
1766    if (cmd != SMFIC_OPTNEG) {
1767	msg_warn("milter %s: unexpected reply \"%c\" in initial handshake",
1768		 milter->m.name, cmd);
1769	(void) milter8_comm_error(milter);
1770	return;
1771    }
1772    if (milter8_read_data(milter, &data_len,
1773			  MILTER8_DATA_HLONG, &milter->version,
1774			  MILTER8_DATA_HLONG, &milter->rq_mask,
1775			  MILTER8_DATA_HLONG, &milter->ev_mask,
1776			  MILTER8_DATA_MORE) != 0) {
1777	msg_warn("milter %s: read error in initial handshake", milter->m.name);
1778	/* milter8_read_data() called milter8_comm_error() */
1779	return;
1780    }
1781    if (milter->version > my_version) {
1782	msg_warn("milter %s: protocol version %d conflict"
1783		 " with MTA protocol version %d",
1784		 milter->m.name, milter->version, my_version);
1785	(void) milter8_comm_error(milter);
1786	return;
1787    }
1788    if ((milter->rq_mask & my_actions) != milter->rq_mask) {
1789	msg_warn("milter %s: request mask 0x%x conflict"
1790		 " with MTA request mask 0x%lx",
1791		 milter->m.name, milter->rq_mask, (long) my_actions);
1792	(void) milter8_comm_error(milter);
1793	return;
1794    }
1795    if (milter->ev_mask & SMFIP_RCPT_REJ)
1796	milter->m.flags |= MILTER_FLAG_WANT_RCPT_REJ;
1797
1798    /*
1799     * Allow the remote application to run an older protocol version, but
1800     * don't them send events that their protocol version doesn't support.
1801     * Based on a suggestion by Kouhei Sutou.
1802     *
1803     * XXX When the Milter sends a protocol version that we don't have
1804     * information for, use the information for the next-lower protocol
1805     * version instead. This code assumes that the milter8_event_masks table
1806     * is organized in reverse numerical order.
1807     */
1808    if (milter->version < my_version) {
1809	const NAME_CODE *np;
1810	int     version;
1811
1812	for (np = milter8_event_masks; /* see below */ ; np++) {
1813	    if (np->name == 0) {
1814		msg_warn("milter %s: unexpected protocol version %d",
1815			 milter->m.name, milter->version);
1816		break;
1817	    }
1818	    if ((version = atoi(np->name)) > 0 && version <= milter->version) {
1819		milter->np_mask |= (SMFIP_NOSEND_MASK & ~np->code);
1820		if (msg_verbose)
1821		    msg_info("%s: non-protocol events for milter %s"
1822			     " protocol version %d: %s",
1823			     myname, milter->m.name, milter->version,
1824			     str_name_mask_opt(milter->buf,
1825					       "non-protocol event mask",
1826					       smfip_table, milter->np_mask,
1827					       NAME_MASK_NUMBER));
1828		break;
1829	    }
1830	}
1831    }
1832
1833    /*
1834     * Initial negotiations completed.
1835     */
1836    if (msg_verbose) {
1837	if ((milter->ev_mask & my_events) != milter->ev_mask)
1838	    msg_info("milter %s: event mask 0x%x includes features not"
1839		     " offered in MTA event mask 0x%lx",
1840		     milter->m.name, milter->ev_mask, (long) my_events);
1841	msg_info("%s: milter %s version %d",
1842		 myname, milter->m.name, milter->version);
1843	msg_info("%s: events %s", myname,
1844		 str_name_mask_opt(milter->buf, "event mask",
1845			   smfip_table, milter->ev_mask, NAME_MASK_NUMBER));
1846	msg_info("%s: requests %s", myname,
1847		 str_name_mask_opt(milter->buf, "request mask",
1848			   smfif_table, milter->rq_mask, NAME_MASK_NUMBER));
1849    }
1850    milter->state = MILTER8_STAT_READY;
1851    milter8_def_reply(milter, 0);
1852    milter->skip_event_type = 0;
1853
1854    /*
1855     * Secondary negotiations: override lists of macro names.
1856     */
1857    if (data_len > 0) {
1858	VSTRING *buf = vstring_alloc(100);
1859	UINT32_TYPE mac_type;
1860	const char *smfim_name;
1861	char  **mac_value_ptr;
1862
1863	milter->m.macros = milter_macros_alloc(MILTER_MACROS_ALLOC_EMPTY);
1864
1865	while (data_len > 0
1866	       && milter8_read_data(milter, &data_len,
1867				    MILTER8_DATA_HLONG, &mac_type,
1868				    MILTER8_DATA_STRING, buf,
1869				    MILTER8_DATA_MORE) == 0) {
1870	    smfim_name = str_name_code(smfim_table, mac_type);
1871	    if (smfim_name == 0) {
1872		msg_warn("milter %s: ignoring unknown macro type %u",
1873			 milter->m.name, (unsigned) mac_type);
1874	    } else {
1875		if (msg_verbose)
1876		    msg_info("override %s macro list with \"%s\"",
1877			     smfim_name, STR(buf));
1878		mac_value_ptr = MILTER8_MACRO_PTR(milter->m.macros, mac_type);
1879		myfree(*mac_value_ptr);
1880		*mac_value_ptr = mystrdup(STR(buf));
1881	    }
1882	}
1883	/* milter8_read_data() calls milter8_comm_error() after error. */
1884	vstring_free(buf);
1885	/* At this point the filter state is either READY or ERROR. */
1886    }
1887}
1888
1889/* milter8_conn_event - report connect event to Sendmail 8 milter */
1890
1891static const char *milter8_conn_event(MILTER *m,
1892				              const char *client_name,
1893				              const char *client_addr,
1894				              const char *client_port,
1895				              unsigned addr_family,
1896				              ARGV *macros)
1897{
1898    const char *myname = "milter8_conn_event";
1899    MILTER8 *milter = (MILTER8 *) m;
1900    int     port;
1901    int     skip_reply;
1902    const char *sm_name;
1903    char   *ptr = 0;
1904    const char *resp;
1905
1906    /*
1907     * Need a global definition for "unknown" host name or address that is
1908     * shared by smtpd, cleanup and libmilter.
1909     */
1910#define XXX_UNKNOWN	"unknown"
1911#define STR_EQ(x,y)	(strcmp((x), (y)) == 0)
1912#define STR_NE(x,y)	(strcmp((x), (y)) != 0)
1913
1914    /*
1915     * XXX Sendmail 8 libmilter closes the MTA-to-filter socket when it finds
1916     * out that the SMTP client has disconnected. Because of this, Postfix
1917     * has to open a new MTA-to-filter socket for each SMTP client.
1918     */
1919#ifdef LIBMILTER_AUTO_DISCONNECT
1920    milter8_connect(milter);
1921#endif
1922
1923    /*
1924     * Report the event.
1925     */
1926    switch (milter->state) {
1927    case MILTER8_STAT_ERROR:
1928	if (msg_verbose)
1929	    msg_info("%s: skip milter %s", myname, milter->m.name);
1930	return (milter->def_reply);
1931    case MILTER8_STAT_READY:
1932	if (msg_verbose)
1933	    msg_info("%s: milter %s: connect %s/%s",
1934		     myname, milter->m.name, client_name, client_addr);
1935	if (client_port == 0) {
1936	    port = 0;
1937	} else if (!alldig(client_port) || (port = atoi(client_port)) < 0
1938		   || port > 65535) {
1939	    msg_warn("milter %s: bad client port number %s",
1940		     milter->m.name, client_port);
1941	    port = 0;
1942	}
1943	milter->state = MILTER8_STAT_ENVELOPE;
1944	skip_reply = ((milter->ev_mask & SMFIP_NR_CONN) != 0);
1945	/* Transform unknown hostname from Postfix to Sendmail form. */
1946	sm_name = (STR_NE(client_name, XXX_UNKNOWN) ? client_name :
1947		   STR_EQ(client_addr, XXX_UNKNOWN) ? client_name :
1948		   (ptr = concatenate("[", client_addr, "]", (char *) 0)));
1949	switch (addr_family) {
1950	case AF_INET:
1951	    resp = milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
1952				 skip_reply, macros,
1953				 MILTER8_DATA_STRING, sm_name,
1954				 MILTER8_DATA_OCTET, SMFIA_INET,
1955				 MILTER8_DATA_NSHORT, htons(port),
1956				 MILTER8_DATA_STRING, client_addr,
1957				 MILTER8_DATA_END);
1958	    break;
1959#ifdef HAS_IPV6
1960	case AF_INET6:
1961	    resp = milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
1962				 skip_reply, macros,
1963				 MILTER8_DATA_STRING, sm_name,
1964				 MILTER8_DATA_OCTET, SMFIA_INET6,
1965				 MILTER8_DATA_NSHORT, htons(port),
1966				 MILTER8_DATA_STRING, client_addr,
1967				 MILTER8_DATA_END);
1968	    break;
1969#endif
1970	case AF_UNIX:
1971	    resp = milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
1972				 skip_reply, macros,
1973				 MILTER8_DATA_STRING, sm_name,
1974				 MILTER8_DATA_OCTET, SMFIA_UNIX,
1975				 MILTER8_DATA_NSHORT, htons(0),
1976				 MILTER8_DATA_STRING, client_addr,
1977				 MILTER8_DATA_END);
1978	    break;
1979	default:
1980	    resp = milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
1981				 skip_reply, macros,
1982				 MILTER8_DATA_STRING, sm_name,
1983				 MILTER8_DATA_OCTET, SMFIA_UNKNOWN,
1984				 MILTER8_DATA_END);
1985	    break;
1986	}
1987	if (ptr != 0)
1988	    myfree(ptr);
1989	return (resp);
1990    default:
1991	msg_panic("%s: milter %s: bad state %d",
1992		  myname, milter->m.name, milter->state);
1993    }
1994}
1995
1996/* milter8_helo_event - report HELO/EHLO command to Sendmail 8 milter */
1997
1998static const char *milter8_helo_event(MILTER *m, const char *helo_name,
1999				              int unused_esmtp,
2000				              ARGV *macros)
2001{
2002    const char *myname = "milter8_helo_event";
2003    MILTER8 *milter = (MILTER8 *) m;
2004    int     skip_reply;
2005
2006    /*
2007     * Report the event.
2008     */
2009    switch (milter->state) {
2010    case MILTER8_STAT_ERROR:
2011    case MILTER8_STAT_ACCEPT_CON:
2012    case MILTER8_STAT_REJECT_CON:
2013	if (msg_verbose)
2014	    msg_info("%s: skip milter %s", myname, milter->m.name);
2015	return (milter->def_reply);
2016    case MILTER8_STAT_ENVELOPE:
2017    case MILTER8_STAT_ACCEPT_MSG:
2018	/* With HELO after MAIL, smtpd(8) calls milter8_abort() next. */
2019	if (msg_verbose)
2020	    msg_info("%s: milter %s: helo %s",
2021		     myname, milter->m.name, helo_name);
2022	skip_reply = ((milter->ev_mask & SMFIP_NR_HELO) != 0);
2023	return (milter8_event(milter, SMFIC_HELO, SMFIP_NOHELO,
2024			      skip_reply, macros,
2025			      MILTER8_DATA_STRING, helo_name,
2026			      MILTER8_DATA_END));
2027    default:
2028	msg_panic("%s: milter %s: bad state %d",
2029		  myname, milter->m.name, milter->state);
2030    }
2031}
2032
2033/* milter8_mail_event - report MAIL command to Sendmail 8 milter */
2034
2035static const char *milter8_mail_event(MILTER *m, const char **argv,
2036				              ARGV *macros)
2037{
2038    const char *myname = "milter8_mail_event";
2039    MILTER8 *milter = (MILTER8 *) m;
2040    const char **cpp;
2041    int     skip_reply;
2042
2043    /*
2044     * Report the event.
2045     */
2046    switch (milter->state) {
2047    case MILTER8_STAT_ERROR:
2048    case MILTER8_STAT_ACCEPT_CON:
2049    case MILTER8_STAT_REJECT_CON:
2050	if (msg_verbose)
2051	    msg_info("%s: skip milter %s", myname, milter->m.name);
2052	return (milter->def_reply);
2053    case MILTER8_STAT_ENVELOPE:
2054	if (msg_verbose) {
2055	    VSTRING *buf = vstring_alloc(100);
2056
2057	    for (cpp = argv; *cpp; cpp++)
2058		vstring_sprintf_append(buf, " %s", *cpp);
2059	    msg_info("%s: milter %s: mail%s",
2060		     myname, milter->m.name, STR(buf));
2061	    vstring_free(buf);
2062	}
2063	skip_reply = ((milter->ev_mask & SMFIP_NR_MAIL) != 0);
2064	return (milter8_event(milter, SMFIC_MAIL, SMFIP_NOMAIL,
2065			      skip_reply, macros,
2066			      MILTER8_DATA_ARGV, argv,
2067			      MILTER8_DATA_END));
2068    default:
2069	msg_panic("%s: milter %s: bad state %d",
2070		  myname, milter->m.name, milter->state);
2071    }
2072}
2073
2074/* milter8_rcpt_event - report RCPT command to Sendmail 8 milter */
2075
2076static const char *milter8_rcpt_event(MILTER *m, const char **argv,
2077				              ARGV *macros)
2078{
2079    const char *myname = "milter8_rcpt_event";
2080    MILTER8 *milter = (MILTER8 *) m;
2081    const char **cpp;
2082    int     skip_reply;
2083
2084    /*
2085     * Report the event.
2086     */
2087    switch (milter->state) {
2088    case MILTER8_STAT_ERROR:
2089    case MILTER8_STAT_ACCEPT_CON:
2090    case MILTER8_STAT_REJECT_CON:
2091    case MILTER8_STAT_ACCEPT_MSG:
2092	if (msg_verbose)
2093	    msg_info("%s: skip milter %s", myname, milter->m.name);
2094	return (milter->def_reply);
2095    case MILTER8_STAT_ENVELOPE:
2096	if (msg_verbose) {
2097	    VSTRING *buf = vstring_alloc(100);
2098
2099	    for (cpp = argv; *cpp; cpp++)
2100		vstring_sprintf_append(buf, " %s", *cpp);
2101	    msg_info("%s: milter %s: rcpt%s",
2102		     myname, milter->m.name, STR(buf));
2103	    vstring_free(buf);
2104	}
2105	skip_reply = ((milter->ev_mask & SMFIP_NR_RCPT) != 0);
2106	return (milter8_event(milter, SMFIC_RCPT, SMFIP_NORCPT,
2107			      skip_reply, macros,
2108			      MILTER8_DATA_ARGV, argv,
2109			      MILTER8_DATA_END));
2110    default:
2111	msg_panic("%s: milter %s: bad state %d",
2112		  myname, milter->m.name, milter->state);
2113    }
2114}
2115
2116/* milter8_data_event - report DATA command to Sendmail 8 milter */
2117
2118static const char *milter8_data_event(MILTER *m, ARGV *macros)
2119{
2120    const char *myname = "milter8_data_event";
2121    MILTER8 *milter = (MILTER8 *) m;
2122    int     skip_reply;
2123
2124    /*
2125     * Report the event.
2126     */
2127    switch (milter->state) {
2128    case MILTER8_STAT_ERROR:
2129    case MILTER8_STAT_ACCEPT_CON:
2130    case MILTER8_STAT_REJECT_CON:
2131    case MILTER8_STAT_ACCEPT_MSG:
2132	if (msg_verbose)
2133	    msg_info("%s: skip milter %s", myname, milter->m.name);
2134	return (milter->def_reply);
2135    case MILTER8_STAT_ENVELOPE:
2136	if (msg_verbose)
2137	    msg_info("%s: milter %s: data command", myname, milter->m.name);
2138	skip_reply = ((milter->ev_mask & SMFIP_NR_DATA) != 0);
2139	return (milter8_event(milter, SMFIC_DATA, SMFIP_NODATA,
2140			      skip_reply, macros,
2141			      MILTER8_DATA_END));
2142    default:
2143	msg_panic("%s: milter %s: bad state %d",
2144		  myname, milter->m.name, milter->state);
2145    }
2146}
2147
2148/* milter8_unknown_event - report unknown SMTP command to Sendmail 8 milter */
2149
2150static const char *milter8_unknown_event(MILTER *m, const char *command,
2151					         ARGV *macros)
2152{
2153    const char *myname = "milter8_unknown_event";
2154    MILTER8 *milter = (MILTER8 *) m;
2155    int     skip_reply;
2156
2157    /*
2158     * Report the event.
2159     */
2160    switch (milter->state) {
2161    case MILTER8_STAT_ERROR:
2162    case MILTER8_STAT_ACCEPT_CON:
2163    case MILTER8_STAT_REJECT_CON:
2164    case MILTER8_STAT_ACCEPT_MSG:
2165	if (msg_verbose)
2166	    msg_info("%s: skip milter %s", myname, milter->m.name);
2167	return (milter->def_reply);
2168    case MILTER8_STAT_ENVELOPE:
2169	if (msg_verbose)
2170	    msg_info("%s: milter %s: unknown command: %s",
2171		     myname, milter->m.name, command);
2172	/* XXX Sendmail doesn't send macros (checked with 8.6.13). */
2173	skip_reply = ((milter->ev_mask & SMFIP_NR_UNKN) != 0);
2174	return (milter8_event(milter, SMFIC_UNKNOWN, SMFIP_NOUNKNOWN,
2175			      skip_reply, macros,
2176			      MILTER8_DATA_STRING, command,
2177			      MILTER8_DATA_END));
2178    default:
2179	msg_panic("%s: milter %s: bad state %d",
2180		  myname, milter->m.name, milter->state);
2181    }
2182}
2183
2184/* milter8_other_event - reply for other event */
2185
2186static const char *milter8_other_event(MILTER *m)
2187{
2188    const char *myname = "milter8_other_event";
2189    MILTER8 *milter = (MILTER8 *) m;
2190
2191    /*
2192     * Return the default reply.
2193     */
2194    if (msg_verbose)
2195	msg_info("%s: milter %s", myname, milter->m.name);
2196    return (milter->def_reply);
2197}
2198
2199/* milter8_abort - cancel one milter's message receiving state */
2200
2201static void milter8_abort(MILTER *m)
2202{
2203    const char *myname = "milter8_abort";
2204    MILTER8 *milter = (MILTER8 *) m;
2205
2206    /*
2207     * XXX Sendmail 8 libmilter closes the MTA-to-filter socket when it finds
2208     * out that the SMTP client has disconnected. Because of this, Postfix
2209     * has to open a new MTA-to-filter socket for each SMTP client.
2210     */
2211    switch (milter->state) {
2212    case MILTER8_STAT_CLOSED:
2213    case MILTER8_STAT_READY:
2214	return;
2215    case MILTER8_STAT_ERROR:
2216    case MILTER8_STAT_ACCEPT_CON:
2217    case MILTER8_STAT_REJECT_CON:
2218	if (msg_verbose)
2219	    msg_info("%s: skip milter %s", myname, milter->m.name);
2220	break;
2221    case MILTER8_STAT_ENVELOPE:
2222    case MILTER8_STAT_MESSAGE:
2223    case MILTER8_STAT_ACCEPT_MSG:
2224	if (msg_verbose)
2225	    msg_info("%s: abort milter %s", myname, milter->m.name);
2226	(void) milter8_write_cmd(milter, SMFIC_ABORT, MILTER8_DATA_END);
2227	if (milter->state != MILTER8_STAT_ERROR)
2228	    milter->state = MILTER8_STAT_ENVELOPE;
2229	break;
2230    default:
2231	msg_panic("%s: milter %s: bad state %d",
2232		  myname, milter->m.name, milter->state);
2233    }
2234}
2235
2236/* milter8_disc_event - report client disconnect event */
2237
2238static void milter8_disc_event(MILTER *m)
2239{
2240    const char *myname = "milter8_disc_event";
2241    MILTER8 *milter = (MILTER8 *) m;
2242
2243    /*
2244     * XXX Sendmail 8 libmilter closes the MTA-to-filter socket when it finds
2245     * out that the SMTP client has disconnected. Because of this, Postfix
2246     * has to open a new MTA-to-filter socket for each SMTP client.
2247     */
2248    switch (milter->state) {
2249    case MILTER8_STAT_CLOSED:
2250    case MILTER8_STAT_READY:
2251	return;
2252    case MILTER8_STAT_ERROR:
2253#ifdef LIBMILTER_AUTO_DISCONNECT
2254    case MILTER8_STAT_ACCEPT_CON:
2255    case MILTER8_STAT_REJECT_CON:
2256#endif
2257	if (msg_verbose)
2258	    msg_info("%s: skip quit milter %s", myname, milter->m.name);
2259	break;
2260    case MILTER8_STAT_ENVELOPE:
2261    case MILTER8_STAT_MESSAGE:
2262#ifndef LIBMILTER_AUTO_DISCONNECT
2263    case MILTER8_STAT_ACCEPT_CON:
2264    case MILTER8_STAT_REJECT_CON:
2265#endif
2266    case MILTER8_STAT_ACCEPT_MSG:
2267	if (msg_verbose)
2268	    msg_info("%s: quit milter %s", myname, milter->m.name);
2269	(void) milter8_write_cmd(milter, SMFIC_QUIT, MILTER8_DATA_END);
2270	break;
2271    }
2272#ifdef LIBMILTER_AUTO_DISCONNECT
2273    milter8_close_stream(milter);
2274#else
2275    if (milter->state != MILTER8_STAT_ERROR)
2276	milter->state = MILTER8_STAT_READY;
2277#endif
2278    milter8_def_reply(milter, 0);
2279}
2280
2281 /*
2282  * Structure to ship context across the MIME_STATE engine.
2283  */
2284typedef struct {
2285    MILTER8 *milter;			/* milter client */
2286    ARGV   *eoh_macros;			/* end-of-header macros */
2287    ARGV   *eod_macros;			/* end-of-body macros */
2288    int     first_header;		/* first header */
2289    int     first_body;			/* first body line */
2290    const char *resp;			/* milter application response */
2291} MILTER_MSG_CONTEXT;
2292
2293/* milter8_header - milter8_message call-back for message header */
2294
2295static void milter8_header(void *ptr, int unused_header_class,
2296			           const HEADER_OPTS *header_info,
2297			           VSTRING *buf, off_t unused_offset)
2298{
2299    const char *myname = "milter8_header";
2300    MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr;
2301    MILTER8 *milter = msg_ctx->milter;
2302    char   *cp;
2303    int     skip_reply;
2304
2305    /*
2306     * XXX Workaround: mime_state_update() may invoke multiple call-backs
2307     * before returning to the caller.
2308     */
2309#define MILTER8_MESSAGE_DONE(milter, msg_ctx) \
2310	((milter)->state != MILTER8_STAT_MESSAGE || (msg_ctx)->resp != 0)
2311
2312    if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
2313	return;
2314
2315    /*
2316     * XXX Sendmail compatibility. Don't expose our first (received) header
2317     * to mail filter applications. See also cleanup_milter.c for code to
2318     * ensure that header replace requests are relative to the message
2319     * content as received, that is, without our own first (received) header,
2320     * while header insert requests are relative to the message as delivered,
2321     * that is, including our own first (received) header.
2322     *
2323     * XXX But this breaks when they delete our own Received: header with
2324     * header_checks before it reaches the queue file. Even then we must not
2325     * expose the first header to mail filter applications, otherwise the
2326     * dk-filter signature will be inserted at the wrong position. It should
2327     * precede the headers that it signs.
2328     *
2329     * XXX Sendmail compatibility. It eats the first space (not tab) after the
2330     * header label and ":".
2331     */
2332    if (msg_ctx->first_header) {
2333	msg_ctx->first_header = 0;
2334	return;
2335    }
2336
2337    /*
2338     * Sendmail 8 sends multi-line headers as text separated by newline.
2339     *
2340     * We destroy the header buffer to split it into label and value. Changing
2341     * the buffer is explicitly allowed by the mime_state(3) interface.
2342     */
2343    if (msg_verbose > 1)
2344	msg_info("%s: header milter %s: %.100s",
2345		 myname, milter->m.name, STR(buf));
2346    cp = STR(buf) + (header_info ? strlen(header_info->name) :
2347		     is_header(STR(buf)));
2348    /* XXX Following matches is_header.c */
2349    while (*cp == ' ' || *cp == '\t')
2350	*cp++ = 0;
2351    if (*cp != ':')
2352	msg_panic("%s: header label not followed by ':'", myname);
2353    *cp++ = 0;
2354    /* XXX Sendmail by default eats one space (not tab) after the colon. */
2355    if ((milter->ev_mask & SMFIP_HDR_LEADSPC) == 0 && *cp == ' ')
2356	cp++;
2357    skip_reply = ((milter->ev_mask & SMFIP_NOHREPL) != 0);
2358    msg_ctx->resp =
2359	milter8_event(milter, SMFIC_HEADER, SMFIP_NOHDRS,
2360		      skip_reply, msg_ctx->eoh_macros,
2361		      MILTER8_DATA_STRING, STR(buf),
2362		      MILTER8_DATA_STRING, cp,
2363		      MILTER8_DATA_END);
2364}
2365
2366/* milter8_eoh - milter8_message call-back for end-of-header */
2367
2368static void milter8_eoh(void *ptr)
2369{
2370    const char *myname = "milter8_eoh";
2371    MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr;
2372    MILTER8 *milter = msg_ctx->milter;
2373    int     skip_reply;
2374
2375    if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
2376	return;
2377    if (msg_verbose)
2378	msg_info("%s: eoh milter %s", myname, milter->m.name);
2379    skip_reply = ((milter->ev_mask & SMFIP_NR_EOH) != 0);
2380    msg_ctx->resp =
2381	milter8_event(milter, SMFIC_EOH, SMFIP_NOEOH,
2382		      skip_reply, msg_ctx->eoh_macros,
2383		      MILTER8_DATA_END);
2384}
2385
2386/* milter8_body - milter8_message call-back for body content */
2387
2388static void milter8_body(void *ptr, int rec_type,
2389			         const char *buf, ssize_t len,
2390			         off_t offset)
2391{
2392    const char *myname = "milter8_body";
2393    MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr;
2394    MILTER8 *milter = msg_ctx->milter;
2395    ssize_t todo = len;
2396    const char *bp = buf;
2397    ssize_t space;
2398    ssize_t count;
2399    int     skip_reply;
2400
2401    if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
2402	return;
2403
2404    /*
2405     * XXX Sendmail compatibility: don't expose our first body line.
2406     */
2407    if (msg_ctx->first_body) {
2408	msg_ctx->first_body = 0;
2409	return;
2410    }
2411
2412    /*
2413     * XXX I thought I was going to delegate all the on-the-wire formatting
2414     * to a common lower layer, but unfortunately it's not practical. If we
2415     * were to do MILTER_CHUNK_SIZE buffering in a common lower layer, then
2416     * we would have to pass along call-backs and state, so that the
2417     * call-back can invoke milter8_event() with the right arguments when the
2418     * MILTER_CHUNK_SIZE buffer reaches capacity. That's just too ugly.
2419     *
2420     * To recover the cost of making an extra copy of body content from Milter
2421     * buffer to VSTREAM buffer, we could make vstream_fwrite() a little
2422     * smarter so that it does large transfers directly from the user buffer
2423     * instead of copying the data one block at a time into a VSTREAM buffer.
2424     */
2425    if (msg_verbose > 1)
2426	msg_info("%s: body milter %s: %.100s", myname, milter->m.name, buf);
2427    skip_reply = ((milter->ev_mask & SMFIP_NR_BODY) != 0);
2428    /* To append \r\n, simply redirect input to another buffer. */
2429    if (rec_type == REC_TYPE_NORM && todo == 0) {
2430	bp = "\r\n";
2431	todo = 2;
2432	rec_type = REC_TYPE_EOF;
2433    }
2434    while (todo > 0) {
2435	/* Append one REC_TYPE_NORM or REC_TYPE_CONT to body chunk buffer. */
2436	space = MILTER_CHUNK_SIZE - LEN(milter->body);
2437	if (space <= 0)
2438	    msg_panic("%s: bad buffer size: %ld",
2439		      myname, (long) LEN(milter->body));
2440	count = (todo > space ? space : todo);
2441	vstring_memcat(milter->body, bp, count);
2442	bp += count;
2443	todo -= count;
2444	/* Flush body chunk buffer when full. See also milter8_eob(). */
2445	if (LEN(milter->body) == MILTER_CHUNK_SIZE) {
2446	    msg_ctx->resp =
2447		milter8_event(milter, SMFIC_BODY, SMFIP_NOBODY,
2448			      skip_reply, msg_ctx->eod_macros,
2449			      MILTER8_DATA_BUFFER, milter->body,
2450			      MILTER8_DATA_END);
2451	    if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
2452		break;
2453	    VSTRING_RESET(milter->body);
2454	}
2455	/* To append \r\n, simply redirect input to another buffer. */
2456	if (rec_type == REC_TYPE_NORM && todo == 0) {
2457	    bp = "\r\n";
2458	    todo = 2;
2459	    rec_type = REC_TYPE_EOF;
2460	}
2461    }
2462}
2463
2464/* milter8_eob - milter8_message call-back for end-of-body */
2465
2466static void milter8_eob(void *ptr)
2467{
2468    const char *myname = "milter8_eob";
2469    MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr;
2470    MILTER8 *milter = msg_ctx->milter;
2471    int     skip_reply;
2472
2473    if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
2474	return;
2475    if (msg_verbose)
2476	msg_info("%s: eob milter %s", myname, milter->m.name);
2477
2478    /*
2479     * Flush partial body chunk buffer. See also milter8_body().
2480     *
2481     * XXX Sendmail 8 libmilter accepts SMFIC_EOB+data, and delivers it to the
2482     * application as two events: SMFIC_BODY+data followed by SMFIC_EOB. This
2483     * breaks with the PMilter 0.95 protocol re-implementation, which
2484     * delivers the SMFIC_EOB event and ignores the data. To avoid such
2485     * compatibility problems we separate the events in the client. With
2486     * this, we also prepare for a future where different event types can
2487     * have different macro lists.
2488     */
2489    if (LEN(milter->body) > 0) {
2490	skip_reply = ((milter->ev_mask & SMFIP_NR_BODY) != 0);
2491	msg_ctx->resp =
2492	    milter8_event(milter, SMFIC_BODY, SMFIP_NOBODY,
2493			  skip_reply, msg_ctx->eod_macros,
2494			  MILTER8_DATA_BUFFER, milter->body,
2495			  MILTER8_DATA_END);
2496	if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
2497	    return;
2498    }
2499    msg_ctx->resp =
2500	milter8_event(msg_ctx->milter, SMFIC_BODYEOB, 0,
2501		      DONT_SKIP_REPLY, msg_ctx->eod_macros,
2502		      MILTER8_DATA_END);
2503}
2504
2505/* milter8_message - send message content and receive reply */
2506
2507static const char *milter8_message(MILTER *m, VSTREAM *qfile,
2508				           off_t data_offset,
2509				           ARGV *eoh_macros,
2510				           ARGV *eod_macros)
2511{
2512    const char *myname = "milter8_message";
2513    MILTER8 *milter = (MILTER8 *) m;
2514    MIME_STATE *mime_state;
2515    int     rec_type;
2516    const MIME_STATE_DETAIL *detail;
2517    int     mime_errs = 0;
2518    MILTER_MSG_CONTEXT msg_ctx;
2519    VSTRING *buf;
2520    int     saved_errno;
2521
2522    switch (milter->state) {
2523    case MILTER8_STAT_ERROR:
2524    case MILTER8_STAT_ACCEPT_CON:
2525    case MILTER8_STAT_REJECT_CON:
2526    case MILTER8_STAT_ACCEPT_MSG:
2527	if (msg_verbose)
2528	    msg_info("%s: skip message to milter %s", myname, milter->m.name);
2529	return (milter->def_reply);
2530    case MILTER8_STAT_ENVELOPE:
2531	if (msg_verbose)
2532	    msg_info("%s: message to milter %s", myname, milter->m.name);
2533	if (vstream_fseek(qfile, data_offset, SEEK_SET) < 0) {
2534	    saved_errno = errno;
2535	    msg_warn("%s: vstream_fseek %s: %m", myname, VSTREAM_PATH(qfile));
2536	    /* XXX This should be available from cleanup_strerror.c. */
2537	    return (saved_errno == EFBIG ?
2538		    "552 5.3.4 Message file too big" :
2539		    "451 4.3.0 Queue file write error");
2540	}
2541	msg_ctx.milter = milter;
2542	msg_ctx.eoh_macros = eoh_macros;
2543	msg_ctx.eod_macros = eod_macros;
2544	msg_ctx.first_header = 1;
2545	msg_ctx.first_body = 1;
2546	msg_ctx.resp = 0;
2547	mime_state =
2548	    mime_state_alloc(MIME_OPT_DISABLE_MIME,
2549			     (milter->ev_mask & SMFIP_NOHDRS) ?
2550			     (MIME_STATE_HEAD_OUT) 0 : milter8_header,
2551			     (milter->ev_mask & SMFIP_NOEOH) ?
2552			     (MIME_STATE_ANY_END) 0 : milter8_eoh,
2553			     (milter->ev_mask & SMFIP_NOBODY) ?
2554			     (MIME_STATE_BODY_OUT) 0 : milter8_body,
2555			     milter8_eob,
2556			     (MIME_STATE_ERR_PRINT) 0,
2557			     (void *) &msg_ctx);
2558	buf = vstring_alloc(100);
2559	milter->state = MILTER8_STAT_MESSAGE;
2560	VSTRING_RESET(milter->body);
2561	vstream_control(milter->fp,
2562			VSTREAM_CTL_DOUBLE,
2563			VSTREAM_CTL_TIMEOUT, milter->msg_timeout,
2564			VSTREAM_CTL_END);
2565
2566	/*
2567	 * XXX When the message (not MIME body part) does not end in CRLF
2568	 * (i.e. the last record was REC_TYPE_CONT), do we send a CRLF
2569	 * terminator before triggering the end-of-body condition?
2570	 */
2571	for (;;) {
2572	    if ((rec_type = rec_get(qfile, buf, 0)) < 0) {
2573		msg_warn("%s: error reading %s: %m",
2574			 myname, VSTREAM_PATH(qfile));
2575		msg_ctx.resp = "450 4.3.0 Queue file write error";
2576		break;
2577	    }
2578	    /* Invoke the appropriate call-back routine. */
2579	    mime_errs = mime_state_update(mime_state, rec_type,
2580					  STR(buf), LEN(buf));
2581	    if (mime_errs) {
2582		detail = mime_state_detail(mime_errs);
2583		msg_warn("%s: MIME problem %s in %s",
2584			 myname, detail->text, VSTREAM_PATH(qfile));
2585		msg_ctx.resp = "450 4.3.0 Queue file write error";
2586		break;
2587	    }
2588	    if (MILTER8_MESSAGE_DONE(milter, &msg_ctx))
2589		break;
2590	    if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT)
2591		break;
2592	}
2593	mime_state_free(mime_state);
2594	vstring_free(buf);
2595	if (milter->fp)
2596	    vstream_control(milter->fp,
2597			    VSTREAM_CTL_DOUBLE,
2598			    VSTREAM_CTL_TIMEOUT, milter->cmd_timeout,
2599			    VSTREAM_CTL_END);
2600	if (milter->state == MILTER8_STAT_MESSAGE
2601	    || milter->state == MILTER8_STAT_ACCEPT_MSG)
2602	    milter->state = MILTER8_STAT_ENVELOPE;
2603	return (msg_ctx.resp);
2604    default:
2605	msg_panic("%s: milter %s: bad state %d",
2606		  myname, milter->m.name, milter->state);
2607    }
2608}
2609
2610 /*
2611  * Preliminary protocol to send/receive milter instances. This needs to be
2612  * extended with type information once we support multiple milter protocols.
2613  */
2614#define MAIL_ATTR_MILT_NAME	"milter_name"
2615#define MAIL_ATTR_MILT_VERS	"milter_version"
2616#define MAIL_ATTR_MILT_ACTS	"milter_actions"
2617#define MAIL_ATTR_MILT_EVTS	"milter_events"
2618#define MAIL_ATTR_MILT_NPTS	"milter_non_events"
2619#define MAIL_ATTR_MILT_STAT	"milter_state"
2620#define MAIL_ATTR_MILT_CONN	"milter_conn_timeout"
2621#define MAIL_ATTR_MILT_CMD	"milter_cmd_timeout"
2622#define MAIL_ATTR_MILT_MSG	"milter_msg_timeout"
2623#define MAIL_ATTR_MILT_ACT	"milter_action"
2624#define MAIL_ATTR_MILT_MAC	"milter_macro_list"
2625
2626/* milter8_active - report if this milter still wants events */
2627
2628static int milter8_active(MILTER *m)
2629{
2630    MILTER8 *milter = (MILTER8 *) m;
2631
2632    return (milter->fp != 0
2633	    && (milter->state == MILTER8_STAT_ENVELOPE
2634		|| milter->state == MILTER8_STAT_READY));
2635}
2636
2637/* milter8_send - send milter instance */
2638
2639static int milter8_send(MILTER *m, VSTREAM *stream)
2640{
2641    const char *myname = "milter8_send";
2642    MILTER8 *milter = (MILTER8 *) m;
2643
2644    if (msg_verbose)
2645	msg_info("%s: milter %s", myname, milter->m.name);
2646
2647    /*
2648     * The next read on this Milter socket happens in a different process. It
2649     * will not automatically flush the output buffer in this process.
2650     */
2651    if (milter->fp)
2652	vstream_fflush(milter->fp);
2653
2654    if (attr_print(stream, ATTR_FLAG_MORE,
2655		   ATTR_TYPE_STR, MAIL_ATTR_MILT_NAME, milter->m.name,
2656		   ATTR_TYPE_INT, MAIL_ATTR_MILT_VERS, milter->version,
2657		   ATTR_TYPE_INT, MAIL_ATTR_MILT_ACTS, milter->rq_mask,
2658		   ATTR_TYPE_INT, MAIL_ATTR_MILT_EVTS, milter->ev_mask,
2659		   ATTR_TYPE_INT, MAIL_ATTR_MILT_NPTS, milter->np_mask,
2660		   ATTR_TYPE_INT, MAIL_ATTR_MILT_STAT, milter->state,
2661		   ATTR_TYPE_INT, MAIL_ATTR_MILT_CONN, milter->conn_timeout,
2662		   ATTR_TYPE_INT, MAIL_ATTR_MILT_CMD, milter->cmd_timeout,
2663		   ATTR_TYPE_INT, MAIL_ATTR_MILT_MSG, milter->msg_timeout,
2664		   ATTR_TYPE_STR, MAIL_ATTR_MILT_ACT, milter->def_action,
2665		   ATTR_TYPE_INT, MAIL_ATTR_MILT_MAC, milter->m.macros != 0,
2666		   ATTR_TYPE_END) != 0
2667	|| (milter->m.macros != 0
2668	    && attr_print(stream, ATTR_FLAG_NONE,
2669			  ATTR_TYPE_FUNC, milter_macros_print,
2670			  (void *) milter->m.macros,
2671			  ATTR_TYPE_END) != 0)
2672	|| (milter->m.macros == 0
2673	    && attr_print(stream, ATTR_FLAG_NONE,
2674			  ATTR_TYPE_END) != 0)
2675	|| vstream_fflush(stream) != 0) {
2676	return (-1);
2677#ifdef CANT_WRITE_BEFORE_SENDING_FD
2678    } else if (attr_scan(stream, ATTR_FLAG_STRICT,
2679			 ATTR_TYPE_STR, MAIL_ATTR_DUMMY, milter->buf,
2680			 ATTR_TYPE_END) != 1) {
2681	return (-1);
2682#endif
2683    } else if (LOCAL_SEND_FD(vstream_fileno(stream),
2684			     vstream_fileno(milter->fp)) < 0) {
2685	return (-1);
2686#ifdef MUST_READ_AFTER_SENDING_FD
2687    } else if (attr_scan(stream, ATTR_FLAG_STRICT,
2688			 ATTR_TYPE_STR, MAIL_ATTR_DUMMY, milter->buf,
2689			 ATTR_TYPE_END) != 1) {
2690	return (-1);
2691#endif
2692    } else {
2693	return (0);
2694    }
2695}
2696
2697static MILTER8 *milter8_alloc(const char *, int, int, int, const char *,
2698			              const char *, MILTERS *);
2699
2700/* milter8_receive - receive milter instance */
2701
2702MILTER *milter8_receive(VSTREAM *stream, MILTERS *parent)
2703{
2704    const char *myname = "milter8_receive";
2705    static VSTRING *name_buf;
2706    static VSTRING *act_buf;
2707    MILTER8 *milter;
2708    int     version;
2709    int     rq_mask;
2710    int     ev_mask;
2711    int     np_mask;
2712    int     state;
2713    int     conn_timeout;
2714    int     cmd_timeout;
2715    int     msg_timeout;
2716    int     fd;
2717    int     has_macros;
2718    MILTER_MACROS *macros = 0;
2719
2720#define FREE_MACROS_AND_RETURN(x) do { \
2721	if (macros) \
2722	    milter_macros_free(macros); \
2723	return (x); \
2724    } while (0)
2725
2726    if (name_buf == 0) {
2727	name_buf = vstring_alloc(10);
2728	act_buf = vstring_alloc(10);
2729    }
2730    if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
2731		  ATTR_TYPE_STR, MAIL_ATTR_MILT_NAME, name_buf,
2732		  ATTR_TYPE_INT, MAIL_ATTR_MILT_VERS, &version,
2733		  ATTR_TYPE_INT, MAIL_ATTR_MILT_ACTS, &rq_mask,
2734		  ATTR_TYPE_INT, MAIL_ATTR_MILT_EVTS, &ev_mask,
2735		  ATTR_TYPE_INT, MAIL_ATTR_MILT_NPTS, &np_mask,
2736		  ATTR_TYPE_INT, MAIL_ATTR_MILT_STAT, &state,
2737		  ATTR_TYPE_INT, MAIL_ATTR_MILT_CONN, &conn_timeout,
2738		  ATTR_TYPE_INT, MAIL_ATTR_MILT_CMD, &cmd_timeout,
2739		  ATTR_TYPE_INT, MAIL_ATTR_MILT_MSG, &msg_timeout,
2740		  ATTR_TYPE_STR, MAIL_ATTR_MILT_ACT, act_buf,
2741		  ATTR_TYPE_INT, MAIL_ATTR_MILT_MAC, &has_macros,
2742		  ATTR_TYPE_END) < 10
2743	|| (has_macros != 0
2744	    && attr_scan(stream, ATTR_FLAG_STRICT,
2745			 ATTR_TYPE_FUNC, milter_macros_scan,
2746			 (void *) (macros =
2747			     milter_macros_alloc(MILTER_MACROS_ALLOC_ZERO)),
2748			 ATTR_TYPE_END) < 1)
2749	|| (has_macros == 0
2750	    && attr_scan(stream, ATTR_FLAG_STRICT,
2751			 ATTR_TYPE_END) < 0)) {
2752	FREE_MACROS_AND_RETURN(0);
2753#ifdef CANT_WRITE_BEFORE_SENDING_FD
2754    } else if (attr_print(stream, ATTR_FLAG_NONE,
2755			  ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
2756			  ATTR_TYPE_END) != 0
2757	       || vstream_fflush(stream) != 0) {
2758	FREE_MACROS_AND_RETURN(0);
2759#endif
2760    } else if ((fd = LOCAL_RECV_FD(vstream_fileno(stream))) < 0) {
2761	FREE_MACROS_AND_RETURN(0);
2762    } else {
2763#ifdef MUST_READ_AFTER_SENDING_FD
2764	(void) attr_print(stream, ATTR_FLAG_NONE,
2765			  ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
2766			  ATTR_TYPE_END);
2767#endif
2768#define NO_PROTOCOL	((char *) 0)
2769
2770	if (msg_verbose)
2771	    msg_info("%s: milter %s", myname, STR(name_buf));
2772
2773	milter = milter8_alloc(STR(name_buf), conn_timeout, cmd_timeout,
2774			    msg_timeout, NO_PROTOCOL, STR(act_buf), parent);
2775	milter->fp = vstream_fdopen(fd, O_RDWR);
2776	milter->m.macros = macros;
2777	vstream_control(milter->fp, VSTREAM_CTL_DOUBLE, VSTREAM_CTL_END);
2778	/* Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE. */
2779	vstream_tweak_sock(milter->fp);
2780	milter->version = version;
2781	milter->rq_mask = rq_mask;
2782	milter->ev_mask = ev_mask;
2783	milter->np_mask = np_mask;
2784	milter->state = state;
2785	return (&milter->m);
2786    }
2787}
2788
2789/* milter8_free - destroy Milter instance */
2790
2791static void milter8_free(MILTER *m)
2792{
2793    MILTER8 *milter = (MILTER8 *) m;
2794
2795    if (msg_verbose)
2796	msg_info("free milter %s", milter->m.name);
2797    if (milter->fp)
2798	(void) vstream_fclose(milter->fp);
2799    myfree(milter->m.name);
2800    vstring_free(milter->buf);
2801    vstring_free(milter->body);
2802    if (milter->protocol)
2803	myfree(milter->protocol);
2804    myfree(milter->def_action);
2805    if (milter->def_reply)
2806	myfree(milter->def_reply);
2807    if (milter->m.macros)
2808	milter_macros_free(milter->m.macros);
2809    myfree((char *) milter);
2810}
2811
2812/* milter8_alloc - create MTA-side Sendmail 8 Milter instance */
2813
2814static MILTER8 *milter8_alloc(const char *name, int conn_timeout,
2815			              int cmd_timeout, int msg_timeout,
2816			              const char *protocol,
2817			              const char *def_action,
2818			              MILTERS *parent)
2819{
2820    MILTER8 *milter;
2821
2822    /*
2823     * Fill in the structure.
2824     */
2825    milter = (MILTER8 *) mymalloc(sizeof(*milter));
2826    milter->m.name = mystrdup(name);
2827    milter->m.flags = 0;
2828    milter->m.next = 0;
2829    milter->m.parent = parent;
2830    milter->m.macros = 0;
2831    milter->m.conn_event = milter8_conn_event;
2832    milter->m.helo_event = milter8_helo_event;
2833    milter->m.mail_event = milter8_mail_event;
2834    milter->m.rcpt_event = milter8_rcpt_event;
2835    milter->m.data_event = milter8_data_event;	/* may be null */
2836    milter->m.message = milter8_message;
2837    milter->m.unknown_event = milter8_unknown_event;	/* may be null */
2838    milter->m.other_event = milter8_other_event;
2839    milter->m.abort = milter8_abort;
2840    milter->m.disc_event = milter8_disc_event;
2841    milter->m.active = milter8_active;
2842    milter->m.send = milter8_send;
2843    milter->m.free = milter8_free;
2844    milter->fp = 0;
2845    milter->buf = vstring_alloc(100);
2846    milter->body = vstring_alloc(100);
2847    milter->version = 0;
2848    milter->rq_mask = 0;
2849    milter->ev_mask = 0;
2850    milter->state = MILTER8_STAT_CLOSED;
2851    milter->conn_timeout = conn_timeout;
2852    milter->cmd_timeout = cmd_timeout;
2853    milter->msg_timeout = msg_timeout;
2854    milter->protocol = (protocol ? mystrdup(protocol) : 0);
2855    milter->def_action = mystrdup(def_action);
2856    milter->def_reply = 0;
2857    milter->skip_event_type = 0;
2858
2859    return (milter);
2860}
2861
2862/* milter8_create - create MTA-side Sendmail 8 Milter instance */
2863
2864MILTER *milter8_create(const char *name, int conn_timeout, int cmd_timeout,
2865		               int msg_timeout, const char *protocol,
2866		               const char *def_action, MILTERS *parent)
2867{
2868    MILTER8 *milter;
2869
2870    /*
2871     * Fill in the structure.
2872     */
2873    milter = milter8_alloc(name, conn_timeout, cmd_timeout, msg_timeout,
2874			   protocol, def_action, parent);
2875
2876    /*
2877     * XXX Sendmail 8 libmilter closes the MTA-to-filter socket when it finds
2878     * out that the SMTP client has disconnected. Because of this, Postfix
2879     * has to open a new MTA-to-filter socket for each SMTP client.
2880     */
2881#ifndef LIBMILTER_AUTO_DISCONNECT
2882    milter8_connect(milter);
2883#endif
2884    return (&milter->m);
2885}
2886