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