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