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