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