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