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