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