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