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