1 /* 2 * Copyright (c) 1999-2009, 2012, 2013 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 */ 10 11 #include <sendmail.h> 12 13 SM_RCSID("@(#)$Id: milter.c,v 8.281 2013-11-22 20:51:56 ca Exp $") 14 15 #if MILTER 16 # include <sm/sendmail.h> 17 # include <libmilter/mfapi.h> 18 # include <libmilter/mfdef.h> 19 # if _FFR_8BITENVADDR 20 # include <sm/ixlen.h> 21 # endif 22 23 # include <errno.h> 24 # include <sm/time.h> 25 # include <sys/uio.h> 26 27 # if NETINET || NETINET6 28 # include <arpa/inet.h> 29 # if MILTER_NO_NAGLE 30 # include <netinet/tcp.h> 31 # endif 32 # endif /* NETINET || NETINET6 */ 33 34 # include <sm/fdset.h> 35 36 static void milter_connect_timeout __P((int)); 37 static void milter_error __P((struct milter *, ENVELOPE *)); 38 static int milter_open __P((struct milter *, bool, ENVELOPE *)); 39 static void milter_parse_timeouts __P((char *, struct milter *)); 40 static char *milter_sysread __P((struct milter *, char *, ssize_t, time_t, 41 ENVELOPE *, const char *)); 42 static char *milter_read __P((struct milter *, char *, ssize_t *, time_t, 43 ENVELOPE *, const char *)); 44 static char *milter_write __P((struct milter *, int, char *, ssize_t, 45 time_t, ENVELOPE *, const char *)); 46 static char *milter_send_command __P((struct milter *, int, void *, 47 ssize_t, ENVELOPE *, char *, const char *)); 48 static char *milter_command __P((int, void *, ssize_t, int, 49 ENVELOPE *, char *, const char *, bool)); 50 static char *milter_body __P((struct milter *, ENVELOPE *, char *)); 51 static int milter_reopen_df __P((ENVELOPE *)); 52 static int milter_reset_df __P((ENVELOPE *)); 53 static void milter_quit_filter __P((struct milter *, ENVELOPE *)); 54 static void milter_abort_filter __P((struct milter *, ENVELOPE *)); 55 static void milter_send_macros __P((struct milter *, char **, int, 56 ENVELOPE *)); 57 static int milter_negotiate __P((struct milter *, ENVELOPE *, 58 milters_T *)); 59 static void milter_per_connection_check __P((ENVELOPE *)); 60 static char *milter_headers __P((struct milter *, ENVELOPE *, char *)); 61 static void milter_addheader __P((struct milter *, char *, ssize_t, 62 ENVELOPE *)); 63 static void milter_insheader __P((struct milter *, char *, ssize_t, 64 ENVELOPE *)); 65 static void milter_changeheader __P((struct milter *, char *, ssize_t, 66 ENVELOPE *)); 67 static void milter_chgfrom __P((char *, ssize_t, ENVELOPE *, const char *)); 68 static void milter_addrcpt __P((char *, ssize_t, ENVELOPE *, const char *)); 69 static void milter_addrcpt_par __P((char *, ssize_t, ENVELOPE *, const char *)); 70 static void milter_delrcpt __P((char *, ssize_t, ENVELOPE *, const char *)); 71 static int milter_replbody __P((char *, ssize_t, bool, ENVELOPE *, const char *)); 72 static int milter_set_macros __P((char *, char **, char *, int)); 73 74 75 /* milter states */ 76 # define SMFS_CLOSED 'C' /* closed for all further actions */ 77 # define SMFS_OPEN 'O' /* connected to remote milter filter */ 78 # define SMFS_INMSG 'M' /* currently servicing a message */ 79 # define SMFS_DONE 'D' /* done with current message */ 80 # define SMFS_CLOSABLE 'Q' /* done with current connection */ 81 # define SMFS_ERROR 'E' /* error state */ 82 # define SMFS_READY 'R' /* ready for action */ 83 # define SMFS_SKIP 'S' /* skip body */ 84 85 /* 86 ** MilterMacros contains the milter macros for each milter and each stage. 87 ** indices are (in order): stages, milter-index, macro 88 ** milter-index == 0: "global" macros (not for a specific milter). 89 */ 90 91 static char *MilterMacros[SMFIM_LAST + 1][MAXFILTERS + 1][MAXFILTERMACROS + 1]; 92 static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE; 93 94 # define MILTER_CHECK_DONE_MSG() \ 95 if (*state == SMFIR_REPLYCODE || \ 96 *state == SMFIR_REJECT || \ 97 *state == SMFIR_DISCARD || \ 98 *state == SMFIR_TEMPFAIL) \ 99 { \ 100 /* Abort the filters to let them know we are done with msg */ \ 101 milter_abort(e); \ 102 } 103 104 /* set state in case of an error */ 105 # define MILTER_SET_STATE \ 106 if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \ 107 *state = SMFIR_TEMPFAIL; \ 108 else if (bitnset(SMF_TEMPDROP, m->mf_flags)) \ 109 *state = SMFIR_SHUTDOWN; \ 110 else if (bitnset(SMF_REJECT, m->mf_flags)) \ 111 *state = SMFIR_REJECT 112 113 /* flow through code maybe using continue; don't wrap in do {} while */ 114 # define MILTER_CHECK_ERROR(initial, action) \ 115 if (!initial && tTd(71, 100)) \ 116 { \ 117 if (e->e_quarmsg == NULL) \ 118 { \ 119 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \ 120 "filter failure"); \ 121 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \ 122 e->e_quarmsg); \ 123 } \ 124 } \ 125 else if (tTd(71, 101)) \ 126 { \ 127 if (e->e_quarmsg == NULL) \ 128 { \ 129 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \ 130 "filter failure"); \ 131 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \ 132 e->e_quarmsg); \ 133 } \ 134 } \ 135 else MILTER_SET_STATE; \ 136 else \ 137 action; 138 139 # define MILTER_CHECK_REPLYCODE(default) \ 140 if (response == NULL || \ 141 strlen(response) + 1 != (size_t) rlen || \ 142 rlen < 3 || \ 143 (response[0] != '4' && response[0] != '5') || \ 144 !isascii(response[1]) || !isdigit(response[1]) || \ 145 !isascii(response[2]) || !isdigit(response[2])) \ 146 { \ 147 if (response != NULL) \ 148 sm_free(response); /* XXX */ \ 149 response = newstr(default); \ 150 } \ 151 else \ 152 { \ 153 char *ptr = response; \ 154 \ 155 /* Check for unprotected %'s in the string */ \ 156 while (*ptr != '\0') \ 157 { \ 158 if (*ptr == '%' && *++ptr != '%') \ 159 { \ 160 sm_free(response); /* XXX */ \ 161 response = newstr(default); \ 162 break; \ 163 } \ 164 ptr++; \ 165 } \ 166 } 167 168 # define MILTER_DF_ERROR(msg) \ 169 { \ 170 int save_errno = errno; \ 171 \ 172 if (tTd(64, 5)) \ 173 { \ 174 sm_dprintf(msg, dfname, sm_errstring(save_errno)); \ 175 sm_dprintf("\n"); \ 176 } \ 177 if (MilterLogLevel > 0) \ 178 sm_syslog(LOG_ERR, e->e_id, msg, dfname, sm_errstring(save_errno)); \ 179 if (SuperSafe == SAFE_REALLY) \ 180 { \ 181 SM_CLOSE_FP(e->e_dfp); \ 182 e->e_flags &= ~EF_HAS_DF; \ 183 } \ 184 errno = save_errno; \ 185 } 186 187 /* 188 ** MILTER_TIMEOUT -- make sure socket is ready in time 189 ** 190 ** Parameters: 191 ** routine -- routine name for debug/logging 192 ** secs -- number of seconds in timeout 193 ** write -- waiting to read or write? 194 ** started -- whether this is part of a previous sequence 195 ** 196 ** Assumes 'm' is a milter structure for the current socket. 197 */ 198 199 # define MILTER_TIMEOUT(routine, secs, write, started, function) \ 200 { \ 201 int ret; \ 202 int save_errno; \ 203 fd_set fds; \ 204 struct timeval tv; \ 205 \ 206 if (!SM_FD_OK_SELECT(m->mf_sock)) \ 207 { \ 208 if (tTd(64, 5)) \ 209 sm_dprintf("milter_%s(%s): socket %d is larger than FD_SETSIZE %d\n", \ 210 (routine), m->mf_name, m->mf_sock, \ 211 SM_FD_SETSIZE); \ 212 if (MilterLogLevel > 0) \ 213 sm_syslog(LOG_ERR, e->e_id, \ 214 "Milter (%s): socket(%s) %d is larger than FD_SETSIZE %d", \ 215 m->mf_name, (routine), m->mf_sock, \ 216 SM_FD_SETSIZE); \ 217 milter_error(m, e); \ 218 return NULL; \ 219 } \ 220 \ 221 do \ 222 { \ 223 FD_ZERO(&fds); \ 224 SM_FD_SET(m->mf_sock, &fds); \ 225 tv.tv_sec = (secs); \ 226 tv.tv_usec = 0; \ 227 ret = select(m->mf_sock + 1, \ 228 (write) ? NULL : &fds, \ 229 (write) ? &fds : NULL, \ 230 NULL, &tv); \ 231 } while (ret < 0 && errno == EINTR); \ 232 \ 233 switch (ret) \ 234 { \ 235 case 0: \ 236 if (tTd(64, 5)) \ 237 sm_dprintf("milter_%s(%s): timeout, where=%s\n", \ 238 (routine), m->mf_name, (function)); \ 239 if (MilterLogLevel > 0) \ 240 sm_syslog(LOG_ERR, e->e_id, \ 241 "Milter (%s): timeout %s data %s, where=%s", \ 242 m->mf_name, \ 243 started ? "during" : "before", \ 244 (routine), (function)); \ 245 milter_error(m, e); \ 246 return NULL; \ 247 \ 248 case -1: \ 249 save_errno = errno; \ 250 if (tTd(64, 5)) \ 251 sm_dprintf("milter_%s(%s): select: %s\n", (routine), \ 252 m->mf_name, sm_errstring(save_errno)); \ 253 if (MilterLogLevel > 0) \ 254 { \ 255 sm_syslog(LOG_ERR, e->e_id, \ 256 "Milter (%s): select(%s): %s", \ 257 m->mf_name, (routine), \ 258 sm_errstring(save_errno)); \ 259 } \ 260 milter_error(m, e); \ 261 return NULL; \ 262 \ 263 default: \ 264 if (SM_FD_ISSET(m->mf_sock, &fds)) \ 265 break; \ 266 if (tTd(64, 5)) \ 267 sm_dprintf("milter_%s(%s): socket not ready\n", \ 268 (routine), m->mf_name); \ 269 if (MilterLogLevel > 0) \ 270 { \ 271 sm_syslog(LOG_ERR, e->e_id, \ 272 "Milter (%s): socket(%s) not ready", \ 273 m->mf_name, (routine)); \ 274 } \ 275 milter_error(m, e); \ 276 return NULL; \ 277 } \ 278 } 279 280 /* 281 ** Low level functions 282 */ 283 284 /* 285 ** MILTER_READ -- read from a remote milter filter 286 ** 287 ** Parameters: 288 ** m -- milter to read from. 289 ** cmd -- return param for command read. 290 ** rlen -- return length of response string. 291 ** to -- timeout in seconds. 292 ** e -- current envelope. 293 ** 294 ** Returns: 295 ** response string (may be NULL) 296 */ 297 298 static char * 299 milter_sysread(m, buf, sz, to, e, where) 300 struct milter *m; 301 char *buf; 302 ssize_t sz; 303 time_t to; 304 ENVELOPE *e; 305 const char *where; 306 { 307 time_t readstart = 0; 308 ssize_t len, curl; 309 bool started = false; 310 311 curl = 0; 312 313 if (to > 0) 314 readstart = curtime(); 315 316 for (;;) 317 { 318 if (to > 0) 319 { 320 time_t now; 321 322 now = curtime(); 323 if (now - readstart >= to) 324 { 325 if (tTd(64, 5)) 326 sm_dprintf("milter_sys_read (%s): timeout %s data read in %s", 327 m->mf_name, 328 started ? "during" : "before", 329 where); 330 if (MilterLogLevel > 0) 331 sm_syslog(LOG_ERR, e->e_id, 332 "Milter (%s): timeout %s data read in %s", 333 m->mf_name, 334 started ? "during" : "before", 335 where); 336 milter_error(m, e); 337 return NULL; 338 } 339 to -= now - readstart; 340 readstart = now; 341 MILTER_TIMEOUT("read", to, false, started, where); 342 } 343 344 len = read(m->mf_sock, buf + curl, sz - curl); 345 346 if (len < 0) 347 { 348 int save_errno = errno; 349 350 if (tTd(64, 5)) 351 sm_dprintf("milter_sys_read(%s): read returned %ld: %s\n", 352 m->mf_name, (long) len, 353 sm_errstring(save_errno)); 354 if (MilterLogLevel > 0) 355 sm_syslog(LOG_ERR, e->e_id, 356 "Milter (%s): read returned %ld: %s", 357 m->mf_name, (long) len, 358 sm_errstring(save_errno)); 359 milter_error(m, e); 360 return NULL; 361 } 362 363 started = true; 364 curl += len; 365 if (len == 0 || curl >= sz) 366 break; 367 368 } 369 370 if (curl != sz) 371 { 372 if (tTd(64, 5)) 373 sm_dprintf("milter_sys_read(%s): cmd read returned %ld, expecting %ld\n", 374 m->mf_name, (long) curl, (long) sz); 375 if (MilterLogLevel > 0) 376 sm_syslog(LOG_ERR, e->e_id, 377 "milter_sys_read(%s): cmd read returned %ld, expecting %ld", 378 m->mf_name, (long) curl, (long) sz); 379 milter_error(m, e); 380 return NULL; 381 } 382 return buf; 383 } 384 385 static char * 386 milter_read(m, cmd, rlen, to, e, where) 387 struct milter *m; 388 char *cmd; 389 ssize_t *rlen; 390 time_t to; 391 ENVELOPE *e; 392 const char *where; 393 { 394 time_t readstart = 0; 395 ssize_t expl; 396 mi_int32 i; 397 # if MILTER_NO_NAGLE && defined(TCP_CORK) 398 int cork = 0; 399 # endif 400 char *buf; 401 char data[MILTER_LEN_BYTES + 1]; 402 403 if (m->mf_sock < 0) 404 { 405 if (MilterLogLevel > 0) 406 sm_syslog(LOG_ERR, e->e_id, 407 "milter_read(%s): socket closed, where=%s", 408 m->mf_name, where); 409 milter_error(m, e); 410 return NULL; 411 } 412 413 *rlen = 0; 414 *cmd = '\0'; 415 416 if (to > 0) 417 readstart = curtime(); 418 419 # if MILTER_NO_NAGLE && defined(TCP_CORK) 420 setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork, 421 sizeof(cork)); 422 # endif 423 424 if (milter_sysread(m, data, sizeof(data), to, e, where) == NULL) 425 return NULL; 426 427 # if MILTER_NO_NAGLE && defined(TCP_CORK) 428 cork = 1; 429 setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork, 430 sizeof(cork)); 431 # endif 432 433 /* reset timeout */ 434 if (to > 0) 435 { 436 time_t now; 437 438 now = curtime(); 439 if (now - readstart >= to) 440 { 441 if (tTd(64, 5)) 442 sm_dprintf("milter_read(%s): timeout before data read, where=%s\n", 443 m->mf_name, where); 444 if (MilterLogLevel > 0) 445 sm_syslog(LOG_ERR, e->e_id, 446 "Milter read(%s): timeout before data read, where=%s", 447 m->mf_name, where); 448 milter_error(m, e); 449 return NULL; 450 } 451 to -= now - readstart; 452 } 453 454 *cmd = data[MILTER_LEN_BYTES]; 455 data[MILTER_LEN_BYTES] = '\0'; 456 (void) memcpy(&i, data, MILTER_LEN_BYTES); 457 expl = ntohl(i) - 1; 458 459 if (tTd(64, 25)) 460 sm_dprintf("milter_read(%s): expecting %ld bytes\n", 461 m->mf_name, (long) expl); 462 463 if (expl < 0) 464 { 465 if (tTd(64, 5)) 466 sm_dprintf("milter_read(%s): read size %ld out of range, where=%s\n", 467 m->mf_name, (long) expl, where); 468 if (MilterLogLevel > 0) 469 sm_syslog(LOG_ERR, e->e_id, 470 "milter_read(%s): read size %ld out of range, where=%s", 471 m->mf_name, (long) expl, where); 472 milter_error(m, e); 473 return NULL; 474 } 475 476 if (expl == 0) 477 return NULL; 478 479 buf = (char *) xalloc(expl); 480 481 if (milter_sysread(m, buf, expl, to, e, where) == NULL) 482 { 483 sm_free(buf); /* XXX */ 484 return NULL; 485 } 486 487 if (tTd(64, 50)) 488 sm_dprintf("milter_read(%s): Returning %*s\n", 489 m->mf_name, (int) expl, buf); 490 *rlen = expl; 491 return buf; 492 } 493 494 /* 495 ** MILTER_WRITE -- write to a remote milter filter 496 ** 497 ** Parameters: 498 ** m -- milter to read from. 499 ** cmd -- command to send. 500 ** buf -- optional command data. 501 ** len -- length of buf. 502 ** to -- timeout in seconds. 503 ** e -- current envelope. 504 ** 505 ** Returns: 506 ** buf if successful, NULL otherwise 507 ** Not actually used anywhere but function prototype 508 ** must match milter_read() 509 */ 510 511 static char * 512 milter_write(m, cmd, buf, len, to, e, where) 513 struct milter *m; 514 int cmd; 515 char *buf; 516 ssize_t len; 517 time_t to; 518 ENVELOPE *e; 519 const char *where; 520 { 521 ssize_t sl, i; 522 int num_vectors; 523 mi_int32 nl; 524 char command = (char) cmd; 525 char data[MILTER_LEN_BYTES + 1]; 526 bool started = false; 527 struct iovec vector[2]; 528 529 /* 530 ** At most two buffers will be written, though 531 ** only one may actually be used (see num_vectors). 532 ** The first is the size/command and the second is the command data. 533 */ 534 535 if (len < 0 || len > MilterMaxDataSize) 536 { 537 if (tTd(64, 5)) 538 { 539 sm_dprintf("milter_write(%s): length %ld out of range, mds=%ld, cmd=%c\n", 540 m->mf_name, (long) len, 541 (long) MilterMaxDataSize, command); 542 sm_dprintf("milter_write(%s): buf=%s\n", 543 m->mf_name, str2prt(buf)); 544 } 545 if (MilterLogLevel > 0) 546 sm_syslog(LOG_ERR, e->e_id, 547 "milter_write(%s): length %ld out of range, cmd=%c", 548 m->mf_name, (long) len, command); 549 milter_error(m, e); 550 return NULL; 551 } 552 if (m->mf_sock < 0) 553 { 554 if (MilterLogLevel > 0) 555 sm_syslog(LOG_ERR, e->e_id, 556 "milter_write(%s): socket closed", 557 m->mf_name); 558 milter_error(m, e); 559 return NULL; 560 } 561 562 if (tTd(64, 20)) 563 sm_dprintf("milter_write(%s): cmd %c, len %ld\n", 564 m->mf_name, command, (long) len); 565 566 nl = htonl(len + 1); /* add 1 for the command char */ 567 (void) memcpy(data, (char *) &nl, MILTER_LEN_BYTES); 568 data[MILTER_LEN_BYTES] = command; 569 sl = MILTER_LEN_BYTES + 1; 570 571 /* set up the vector for the size / command */ 572 vector[0].iov_base = (void *) data; 573 vector[0].iov_len = sl; 574 575 /* 576 ** Determine if there is command data. If so, there will be two 577 ** vectors. If not, there will be only one. The vectors are set 578 ** up here and 'num_vectors' and 'sl' are set appropriately. 579 */ 580 581 /* NOTE: len<0 has already been checked for. Pedantic */ 582 if (len <= 0 || buf == NULL) 583 { 584 /* There is no command data -- only a size / command data */ 585 num_vectors = 1; 586 } 587 else 588 { 589 /* 590 ** There is both size / command and command data. 591 ** Set up the vector for the command data. 592 */ 593 594 num_vectors = 2; 595 sl += len; 596 vector[1].iov_base = (void *) buf; 597 vector[1].iov_len = len; 598 599 if (tTd(64, 50)) 600 sm_dprintf("milter_write(%s): Sending %*s\n", 601 m->mf_name, (int) len, buf); 602 } 603 604 if (to > 0) 605 MILTER_TIMEOUT("write", to, true, started, where); 606 607 /* write the vector(s) */ 608 i = writev(m->mf_sock, vector, num_vectors); 609 if (i != sl) 610 { 611 int save_errno = errno; 612 613 if (tTd(64, 5)) 614 sm_dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n", 615 m->mf_name, command, (long) i, (long) sl, 616 sm_errstring(save_errno)); 617 if (MilterLogLevel > 0) 618 sm_syslog(LOG_ERR, e->e_id, 619 "Milter (%s): write(%c) returned %ld, expected %ld: %s", 620 m->mf_name, command, (long) i, (long) sl, 621 sm_errstring(save_errno)); 622 milter_error(m, e); 623 return NULL; 624 } 625 return buf; 626 } 627 628 /* 629 ** Utility functions 630 */ 631 632 /* 633 ** MILTER_OPEN -- connect to remote milter filter 634 ** 635 ** Parameters: 636 ** m -- milter to connect to. 637 ** parseonly -- parse but don't connect. 638 ** e -- current envelope. 639 ** 640 ** Returns: 641 ** connected socket if successful && !parseonly, 642 ** 0 upon parse success if parseonly, 643 ** -1 otherwise. 644 */ 645 646 static jmp_buf MilterConnectTimeout; 647 648 static int 649 milter_open(m, parseonly, e) 650 struct milter *m; 651 bool parseonly; 652 ENVELOPE *e; 653 { 654 int sock = 0; 655 SOCKADDR_LEN_T addrlen = 0; 656 int addrno = 0; 657 int save_errno; 658 char *p; 659 char *colon; 660 char *at; 661 struct hostent *hp = NULL; 662 SOCKADDR addr; 663 664 if (SM_IS_EMPTY(m->mf_conn)) 665 { 666 if (tTd(64, 5)) 667 sm_dprintf("X%s: empty or missing socket information\n", 668 m->mf_name); 669 if (parseonly) 670 syserr("X%s: empty or missing socket information", 671 m->mf_name); 672 else if (MilterLogLevel > 0) 673 sm_syslog(LOG_ERR, e->e_id, 674 "Milter (%s): empty or missing socket information", 675 m->mf_name); 676 milter_error(m, e); 677 return -1; 678 } 679 680 /* protocol:filename or protocol:port@host */ 681 memset(&addr, '\0', sizeof(addr)); 682 p = m->mf_conn; 683 colon = strchr(p, ':'); 684 if (colon != NULL) 685 { 686 *colon = '\0'; 687 688 if (*p == '\0') 689 { 690 # if NETUNIX 691 /* default to AF_UNIX */ 692 addr.sa.sa_family = AF_UNIX; 693 # else 694 # if NETINET 695 /* default to AF_INET */ 696 addr.sa.sa_family = AF_INET; 697 # else /* NETINET */ 698 # if NETINET6 699 /* default to AF_INET6 */ 700 addr.sa.sa_family = AF_INET6; 701 # else /* NETINET6 */ 702 /* no protocols available */ 703 if (MilterLogLevel > 0) 704 sm_syslog(LOG_ERR, e->e_id, 705 "Milter (%s): no valid socket protocols available", 706 m->mf_name); 707 milter_error(m, e); 708 return -1; 709 # endif /* NETINET6 */ 710 # endif /* NETINET */ 711 # endif /* NETUNIX */ 712 } 713 # if NETUNIX 714 else if (SM_STRCASEEQ(p, "unix") || 715 SM_STRCASEEQ(p, "local")) 716 addr.sa.sa_family = AF_UNIX; 717 # endif 718 # if NETINET 719 else if (SM_STRCASEEQ(p, "inet")) 720 addr.sa.sa_family = AF_INET; 721 # endif 722 # if NETINET6 723 else if (SM_STRCASEEQ(p, "inet6")) 724 addr.sa.sa_family = AF_INET6; 725 # endif 726 else 727 { 728 # ifdef EPROTONOSUPPORT 729 errno = EPROTONOSUPPORT; 730 # else 731 errno = EINVAL; 732 # endif 733 if (tTd(64, 5)) 734 sm_dprintf("X%s: unknown socket type %s\n", 735 m->mf_name, p); 736 if (parseonly) 737 syserr("X%s: unknown socket type %s", 738 m->mf_name, p); 739 else if (MilterLogLevel > 0) 740 sm_syslog(LOG_ERR, e->e_id, 741 "Milter (%s): unknown socket type %s", 742 m->mf_name, p); 743 milter_error(m, e); 744 return -1; 745 } 746 *colon++ = ':'; 747 } 748 else 749 { 750 /* default to AF_UNIX */ 751 addr.sa.sa_family = AF_UNIX; 752 colon = p; 753 } 754 755 # if NETUNIX 756 if (addr.sa.sa_family == AF_UNIX) 757 { 758 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK; 759 760 at = colon; 761 if (strlen(colon) >= sizeof(addr.sunix.sun_path)) 762 { 763 if (tTd(64, 5)) 764 sm_dprintf("X%s: local socket name %s too long\n", 765 m->mf_name, colon); 766 errno = EINVAL; 767 if (parseonly) 768 syserr("X%s: local socket name %s too long", 769 m->mf_name, colon); 770 else if (MilterLogLevel > 0) 771 sm_syslog(LOG_ERR, e->e_id, 772 "Milter (%s): local socket name %s too long", 773 m->mf_name, colon); 774 milter_error(m, e); 775 return -1; 776 } 777 errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, 778 S_IRUSR|S_IWUSR, NULL); 779 780 /* if just parsing .cf file, socket doesn't need to exist */ 781 if (parseonly && errno == ENOENT) 782 { 783 if (OpMode == MD_DAEMON || 784 OpMode == MD_FGDAEMON) 785 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 786 "WARNING: X%s: local socket name %s missing\n", 787 m->mf_name, colon); 788 } 789 else if (errno != 0) 790 { 791 /* if not safe, don't create */ 792 save_errno = errno; 793 if (tTd(64, 5)) 794 sm_dprintf("X%s: local socket name %s unsafe\n", 795 m->mf_name, colon); 796 errno = save_errno; 797 if (parseonly) 798 { 799 if (OpMode == MD_DAEMON || 800 OpMode == MD_FGDAEMON || 801 OpMode == MD_SMTP) 802 syserr("X%s: local socket name %s unsafe", 803 m->mf_name, colon); 804 } 805 else if (MilterLogLevel > 0) 806 sm_syslog(LOG_ERR, e->e_id, 807 "Milter (%s): local socket name %s unsafe", 808 m->mf_name, colon); 809 milter_error(m, e); 810 return -1; 811 } 812 813 (void) sm_strlcpy(addr.sunix.sun_path, colon, 814 sizeof(addr.sunix.sun_path)); 815 addrlen = sizeof(struct sockaddr_un); 816 } 817 else 818 # endif /* NETUNIX */ 819 # if NETINET || NETINET6 820 if (false 821 # if NETINET 822 || addr.sa.sa_family == AF_INET 823 # endif 824 # if NETINET6 825 || addr.sa.sa_family == AF_INET6 826 # endif 827 ) 828 { 829 unsigned short port; 830 831 /* Parse port@host */ 832 at = strchr(colon, '@'); 833 if (at == NULL) 834 { 835 if (tTd(64, 5)) 836 sm_dprintf("X%s: bad address %s (expected port@host)\n", 837 m->mf_name, colon); 838 if (parseonly) 839 syserr("X%s: bad address %s (expected port@host)", 840 m->mf_name, colon); 841 else if (MilterLogLevel > 0) 842 sm_syslog(LOG_ERR, e->e_id, 843 "Milter (%s): bad address %s (expected port@host)", 844 m->mf_name, colon); 845 milter_error(m, e); 846 return -1; 847 } 848 *at = '\0'; 849 if (isascii(*colon) && isdigit(*colon)) 850 port = htons((unsigned short) atoi(colon)); 851 else 852 { 853 # ifdef NO_GETSERVBYNAME 854 if (tTd(64, 5)) 855 sm_dprintf("X%s: invalid port number %s\n", 856 m->mf_name, colon); 857 if (parseonly) 858 syserr("X%s: invalid port number %s", 859 m->mf_name, colon); 860 else if (MilterLogLevel > 0) 861 sm_syslog(LOG_ERR, e->e_id, 862 "Milter (%s): invalid port number %s", 863 m->mf_name, colon); 864 milter_error(m, e); 865 return -1; 866 # else /* NO_GETSERVBYNAME */ 867 struct servent *sp; 868 869 sp = getservbyname(colon, "tcp"); 870 if (sp == NULL) 871 { 872 save_errno = errno; 873 if (tTd(64, 5)) 874 sm_dprintf("X%s: unknown port name %s\n", 875 m->mf_name, colon); 876 errno = save_errno; 877 if (parseonly) 878 syserr("X%s: unknown port name %s", 879 m->mf_name, colon); 880 else if (MilterLogLevel > 0) 881 sm_syslog(LOG_ERR, e->e_id, 882 "Milter (%s): unknown port name %s", 883 m->mf_name, colon); 884 milter_error(m, e); 885 return -1; 886 } 887 port = sp->s_port; 888 # endif /* NO_GETSERVBYNAME */ 889 } 890 *at++ = '@'; 891 if (*at == '[') 892 { 893 char *end; 894 895 end = strchr(at, ']'); 896 if (end != NULL) 897 { 898 bool found = false; 899 # if NETINET 900 unsigned long hid = INADDR_NONE; 901 # endif 902 # if NETINET6 903 struct sockaddr_in6 hid6; 904 # endif 905 906 *end = '\0'; 907 # if NETINET 908 if (addr.sa.sa_family == AF_INET && 909 (hid = inet_addr(&at[1])) != INADDR_NONE) 910 { 911 addr.sin.sin_addr.s_addr = hid; 912 addr.sin.sin_port = port; 913 found = true; 914 } 915 # endif /* NETINET */ 916 # if NETINET6 917 (void) memset(&hid6, '\0', sizeof(hid6)); 918 if (addr.sa.sa_family == AF_INET6 && 919 anynet_pton(AF_INET6, &at[1], 920 &hid6.sin6_addr) == 1) 921 { 922 addr.sin6.sin6_addr = hid6.sin6_addr; 923 addr.sin6.sin6_port = port; 924 found = true; 925 } 926 # endif /* NETINET6 */ 927 *end = ']'; 928 if (!found) 929 { 930 if (tTd(64, 5)) 931 sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n", 932 m->mf_name, at); 933 if (parseonly) 934 syserr("X%s: Invalid numeric domain spec \"%s\"", 935 m->mf_name, at); 936 else if (MilterLogLevel > 0) 937 sm_syslog(LOG_ERR, e->e_id, 938 "Milter (%s): Invalid numeric domain spec \"%s\"", 939 m->mf_name, at); 940 milter_error(m, e); 941 return -1; 942 } 943 } 944 else 945 { 946 if (tTd(64, 5)) 947 sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n", 948 m->mf_name, at); 949 if (parseonly) 950 syserr("X%s: Invalid numeric domain spec \"%s\"", 951 m->mf_name, at); 952 else if (MilterLogLevel > 0) 953 sm_syslog(LOG_ERR, e->e_id, 954 "Milter (%s): Invalid numeric domain spec \"%s\"", 955 m->mf_name, at); 956 milter_error(m, e); 957 return -1; 958 } 959 } 960 else 961 { 962 hp = sm_gethostbyname(at, addr.sa.sa_family); 963 if (hp == NULL) 964 { 965 save_errno = errno; 966 if (tTd(64, 5)) 967 sm_dprintf("X%s: Unknown host name %s\n", 968 m->mf_name, at); 969 errno = save_errno; 970 if (parseonly) 971 syserr("X%s: Unknown host name %s", 972 m->mf_name, at); 973 else if (MilterLogLevel > 0) 974 sm_syslog(LOG_ERR, e->e_id, 975 "Milter (%s): Unknown host name %s", 976 m->mf_name, at); 977 milter_error(m, e); 978 return -1; 979 } 980 addr.sa.sa_family = hp->h_addrtype; 981 switch (hp->h_addrtype) 982 { 983 # if NETINET 984 case AF_INET: 985 memmove(&addr.sin.sin_addr, 986 hp->h_addr, INADDRSZ); 987 addr.sin.sin_port = port; 988 addrlen = sizeof(struct sockaddr_in); 989 addrno = 1; 990 break; 991 # endif /* NETINET */ 992 993 # if NETINET6 994 case AF_INET6: 995 memmove(&addr.sin6.sin6_addr, 996 hp->h_addr, IN6ADDRSZ); 997 addr.sin6.sin6_port = port; 998 addrlen = sizeof(struct sockaddr_in6); 999 addrno = 1; 1000 break; 1001 # endif /* NETINET6 */ 1002 1003 default: 1004 if (tTd(64, 5)) 1005 sm_dprintf("X%s: Unknown protocol for %s (%d)\n", 1006 m->mf_name, at, 1007 hp->h_addrtype); 1008 if (parseonly) 1009 syserr("X%s: Unknown protocol for %s (%d)", 1010 m->mf_name, at, hp->h_addrtype); 1011 else if (MilterLogLevel > 0) 1012 sm_syslog(LOG_ERR, e->e_id, 1013 "Milter (%s): Unknown protocol for %s (%d)", 1014 m->mf_name, at, 1015 hp->h_addrtype); 1016 milter_error(m, e); 1017 # if NETINET6 1018 freehostent(hp); 1019 # endif 1020 return -1; 1021 } 1022 } 1023 } 1024 else 1025 # endif /* NETINET || NETINET6 */ 1026 { 1027 if (tTd(64, 5)) 1028 sm_dprintf("X%s: unknown socket protocol\n", 1029 m->mf_name); 1030 if (parseonly) 1031 syserr("X%s: unknown socket protocol", m->mf_name); 1032 else if (MilterLogLevel > 0) 1033 sm_syslog(LOG_ERR, e->e_id, 1034 "Milter (%s): unknown socket protocol", 1035 m->mf_name); 1036 milter_error(m, e); 1037 return -1; 1038 } 1039 1040 /* just parsing through? */ 1041 if (parseonly) 1042 { 1043 m->mf_state = SMFS_READY; 1044 # if NETINET6 1045 if (hp != NULL) 1046 freehostent(hp); 1047 # endif 1048 return 0; 1049 } 1050 1051 /* sanity check */ 1052 if (m->mf_state != SMFS_READY && 1053 m->mf_state != SMFS_CLOSED) 1054 { 1055 /* shouldn't happen */ 1056 if (tTd(64, 1)) 1057 sm_dprintf("Milter (%s): Trying to open filter in state %c\n", 1058 m->mf_name, (char) m->mf_state); 1059 milter_error(m, e); 1060 # if NETINET6 1061 if (hp != NULL) 1062 freehostent(hp); 1063 # endif 1064 return -1; 1065 } 1066 1067 /* nope, actually connecting */ 1068 for (;;) 1069 { 1070 sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); 1071 if (sock < 0) 1072 { 1073 save_errno = errno; 1074 if (tTd(64, 5)) 1075 sm_dprintf("Milter (%s): error creating socket: %s\n", 1076 m->mf_name, 1077 sm_errstring(save_errno)); 1078 if (MilterLogLevel > 0) 1079 sm_syslog(LOG_ERR, e->e_id, 1080 "Milter (%s): error creating socket: %s", 1081 m->mf_name, sm_errstring(save_errno)); 1082 milter_error(m, e); 1083 # if NETINET6 1084 if (hp != NULL) 1085 freehostent(hp); 1086 # endif 1087 return -1; 1088 } 1089 1090 if (setjmp(MilterConnectTimeout) == 0) 1091 { 1092 SM_EVENT *ev = NULL; 1093 int i; 1094 1095 if (m->mf_timeout[SMFTO_CONNECT] > 0) 1096 ev = sm_setevent(m->mf_timeout[SMFTO_CONNECT], 1097 milter_connect_timeout, 0); 1098 1099 i = connect(sock, (struct sockaddr *) &addr, addrlen); 1100 save_errno = errno; 1101 if (ev != NULL) 1102 sm_clrevent(ev); 1103 errno = save_errno; 1104 if (i >= 0) 1105 break; 1106 } 1107 1108 /* couldn't connect.... try next address */ 1109 save_errno = errno; 1110 p = CurHostName; 1111 CurHostName = at; 1112 if (tTd(64, 5)) 1113 sm_dprintf("milter_open (%s): open %s failed: %s\n", 1114 m->mf_name, at, sm_errstring(save_errno)); 1115 if (MilterLogLevel > 13) 1116 sm_syslog(LOG_INFO, e->e_id, 1117 "Milter (%s): open %s failed: %s", 1118 m->mf_name, at, sm_errstring(save_errno)); 1119 CurHostName = p; 1120 (void) close(sock); 1121 1122 /* try next address */ 1123 if (hp != NULL && hp->h_addr_list[addrno] != NULL) 1124 { 1125 switch (addr.sa.sa_family) 1126 { 1127 # if NETINET 1128 case AF_INET: 1129 memmove(&addr.sin.sin_addr, 1130 hp->h_addr_list[addrno++], 1131 INADDRSZ); 1132 break; 1133 # endif /* NETINET */ 1134 1135 # if NETINET6 1136 case AF_INET6: 1137 memmove(&addr.sin6.sin6_addr, 1138 hp->h_addr_list[addrno++], 1139 IN6ADDRSZ); 1140 break; 1141 # endif /* NETINET6 */ 1142 1143 default: 1144 if (tTd(64, 5)) 1145 sm_dprintf("X%s: Unknown protocol for %s (%d)\n", 1146 m->mf_name, at, 1147 hp->h_addrtype); 1148 if (MilterLogLevel > 0) 1149 sm_syslog(LOG_ERR, e->e_id, 1150 "Milter (%s): Unknown protocol for %s (%d)", 1151 m->mf_name, at, 1152 hp->h_addrtype); 1153 milter_error(m, e); 1154 # if NETINET6 1155 freehostent(hp); 1156 # endif 1157 return -1; 1158 } 1159 continue; 1160 } 1161 p = CurHostName; 1162 CurHostName = at; 1163 if (tTd(64, 5)) 1164 sm_dprintf("X%s: error connecting to filter: %s\n", 1165 m->mf_name, sm_errstring(save_errno)); 1166 if (MilterLogLevel > 0) 1167 sm_syslog(LOG_ERR, e->e_id, 1168 "Milter (%s): error connecting to filter: %s", 1169 m->mf_name, sm_errstring(save_errno)); 1170 CurHostName = p; 1171 milter_error(m, e); 1172 # if NETINET6 1173 if (hp != NULL) 1174 freehostent(hp); 1175 # endif 1176 return -1; 1177 } 1178 m->mf_state = SMFS_OPEN; 1179 # if NETINET6 1180 if (hp != NULL) 1181 { 1182 freehostent(hp); 1183 hp = NULL; 1184 } 1185 # endif /* NETINET6 */ 1186 # if MILTER_NO_NAGLE && !defined(TCP_CORK) 1187 { 1188 int nodelay = 1; 1189 1190 setsockopt(m->mf_sock, IPPROTO_TCP, TCP_NODELAY, 1191 (char *)&nodelay, sizeof(nodelay)); 1192 } 1193 # endif /* MILTER_NO_NAGLE && !defined(TCP_CORK) */ 1194 return sock; 1195 } 1196 1197 static void 1198 milter_connect_timeout(ignore) 1199 int ignore; 1200 { 1201 /* 1202 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 1203 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 1204 ** DOING. 1205 */ 1206 1207 errno = ETIMEDOUT; 1208 longjmp(MilterConnectTimeout, 1); 1209 } 1210 1211 /* 1212 ** MILTER_SETUP -- setup structure for a mail filter 1213 ** 1214 ** Parameters: 1215 ** line -- the options line. 1216 ** 1217 ** Returns: 1218 ** none 1219 */ 1220 1221 void 1222 milter_setup(line) 1223 char *line; 1224 { 1225 char fcode; 1226 char *p; 1227 struct milter *m; 1228 STAB *s; 1229 static int idx = 0; 1230 1231 /* collect the filter name */ 1232 for (p = line; 1233 *p != '\0' && *p != ',' && !(SM_ISSPACE(*p)); 1234 p++) 1235 continue; 1236 if (*p != '\0') 1237 *p++ = '\0'; 1238 if (line[0] == '\0') 1239 { 1240 syserr("name required for mail filter"); 1241 return; 1242 } 1243 m = (struct milter *) xalloc(sizeof(*m)); 1244 memset((char *) m, '\0', sizeof(*m)); 1245 m->mf_name = newstr(line); 1246 m->mf_state = SMFS_READY; 1247 m->mf_sock = -1; 1248 m->mf_timeout[SMFTO_CONNECT] = (time_t) 300; 1249 m->mf_timeout[SMFTO_WRITE] = (time_t) 10; 1250 m->mf_timeout[SMFTO_READ] = (time_t) 10; 1251 m->mf_timeout[SMFTO_EOM] = (time_t) 300; 1252 # if _FFR_MILTER_CHECK 1253 m->mf_mta_prot_version = SMFI_PROT_VERSION; 1254 m->mf_mta_prot_flags = SMFI_CURR_PROT; 1255 m->mf_mta_actions = SMFI_CURR_ACTS; 1256 # endif /* _FFR_MILTER_CHECK */ 1257 1258 /* now scan through and assign info from the fields */ 1259 while (*p != '\0') 1260 { 1261 char *delimptr; 1262 1263 while (*p != '\0' && 1264 (*p == ',' || (SM_ISSPACE(*p)))) 1265 p++; 1266 1267 /* p now points to field code */ 1268 fcode = *p; 1269 while (*p != '\0' && *p != '=' && *p != ',') 1270 p++; 1271 if (*p++ != '=') 1272 { 1273 syserr("X%s: `=' expected", m->mf_name); 1274 /* this should not be reached, but just in case */ 1275 SM_FREE(m); 1276 return; 1277 } 1278 while (SM_ISSPACE(*p)) 1279 p++; 1280 1281 /* p now points to the field body */ 1282 p = munchstring(p, &delimptr, ','); 1283 1284 /* install the field into the filter struct */ 1285 switch (fcode) 1286 { 1287 case 'S': /* socket */ 1288 if (p == NULL) 1289 m->mf_conn = NULL; 1290 else 1291 m->mf_conn = newstr(p); 1292 break; 1293 1294 case 'F': /* Milter flags configured on MTA */ 1295 for (; *p != '\0'; p++) 1296 { 1297 if (!(SM_ISSPACE(*p))) 1298 setbitn(bitidx(*p), m->mf_flags); 1299 } 1300 break; 1301 1302 case 'T': /* timeouts */ 1303 milter_parse_timeouts(p, m); 1304 break; 1305 1306 # if _FFR_MILTER_CHECK 1307 case 'a': 1308 m->mf_mta_actions = strtoul(p, NULL, 0); 1309 break; 1310 case 'f': 1311 m->mf_mta_prot_flags = strtoul(p, NULL, 0); 1312 break; 1313 case 'v': 1314 m->mf_mta_prot_version = strtoul(p, NULL, 0); 1315 break; 1316 # endif /* _FFR_MILTER_CHECK */ 1317 1318 default: 1319 syserr("X%s: unknown filter equate %c=", 1320 m->mf_name, fcode); 1321 break; 1322 } 1323 p = delimptr; 1324 } 1325 1326 /* early check for errors */ 1327 (void) milter_open(m, true, CurEnv); 1328 1329 /* enter the filter into the symbol table */ 1330 s = stab(m->mf_name, ST_MILTER, ST_ENTER); 1331 if (s->s_milter != NULL) 1332 syserr("X%s: duplicate filter definition", m->mf_name); 1333 else 1334 { 1335 s->s_milter = m; 1336 m->mf_idx = ++idx; 1337 } 1338 } 1339 1340 /* 1341 ** MILTER_CONFIG -- parse option list into an array and check config 1342 ** 1343 ** Called when reading configuration file. 1344 ** 1345 ** Parameters: 1346 ** spec -- the filter list. 1347 ** list -- the array to fill in. 1348 ** max -- the maximum number of entries in list. 1349 ** 1350 ** Returns: 1351 ** none 1352 */ 1353 1354 void 1355 milter_config(spec, list, max) 1356 char *spec; 1357 struct milter **list; 1358 int max; 1359 { 1360 int numitems = 0; 1361 char *p; 1362 1363 /* leave one for the NULL signifying the end of the list */ 1364 max--; 1365 1366 for (p = spec; p != NULL; ) 1367 { 1368 STAB *s; 1369 1370 while (SM_ISSPACE(*p)) 1371 p++; 1372 if (*p == '\0') 1373 break; 1374 spec = p; 1375 1376 if (numitems >= max) 1377 { 1378 syserr("Too many filters defined, %d max", max); 1379 if (max > 0) 1380 list[0] = NULL; 1381 return; 1382 } 1383 p = strpbrk(p, ";,"); 1384 if (p != NULL) 1385 *p++ = '\0'; 1386 1387 s = stab(spec, ST_MILTER, ST_FIND); 1388 if (s == NULL) 1389 { 1390 syserr("InputFilter %s not defined", spec); 1391 ExitStat = EX_CONFIG; 1392 return; 1393 } 1394 list[numitems++] = s->s_milter; 1395 } 1396 list[numitems] = NULL; 1397 1398 /* if not set, set to LogLevel */ 1399 if (MilterLogLevel == -1) 1400 MilterLogLevel = LogLevel; 1401 } 1402 1403 /* 1404 ** MILTER_PARSE_TIMEOUTS -- parse timeout list 1405 ** 1406 ** Called when reading configuration file. 1407 ** 1408 ** Parameters: 1409 ** spec -- the timeout list. 1410 ** m -- milter to set. 1411 ** 1412 ** Returns: 1413 ** none 1414 */ 1415 1416 static void 1417 milter_parse_timeouts(spec, m) 1418 char *spec; 1419 struct milter *m; 1420 { 1421 char fcode; 1422 int tcode; 1423 char *p; 1424 1425 p = spec; 1426 1427 /* now scan through and assign info from the fields */ 1428 while (*p != '\0') 1429 { 1430 char *delimptr; 1431 1432 while (*p != '\0' && (*p == ';' || (SM_ISSPACE(*p)))) 1433 p++; 1434 1435 /* p now points to field code */ 1436 fcode = *p; 1437 while (*p != '\0' && *p != ':') 1438 p++; 1439 if (*p++ != ':') 1440 { 1441 syserr("X%s, T=: `:' expected", m->mf_name); 1442 return; 1443 } 1444 while (SM_ISSPACE(*p)) 1445 p++; 1446 1447 /* p now points to the field body */ 1448 p = munchstring(p, &delimptr, ';'); 1449 tcode = -1; 1450 1451 /* install the field into the filter struct */ 1452 switch (fcode) 1453 { 1454 case 'C': 1455 tcode = SMFTO_CONNECT; 1456 break; 1457 1458 case 'S': 1459 tcode = SMFTO_WRITE; 1460 break; 1461 1462 case 'R': 1463 tcode = SMFTO_READ; 1464 break; 1465 1466 case 'E': 1467 tcode = SMFTO_EOM; 1468 break; 1469 1470 default: 1471 if (tTd(64, 5)) 1472 sm_dprintf("X%s: %c unknown\n", 1473 m->mf_name, fcode); 1474 syserr("X%s: unknown filter timeout %c", 1475 m->mf_name, fcode); 1476 break; 1477 } 1478 if (tcode >= 0) 1479 { 1480 m->mf_timeout[tcode] = convtime(p, 's'); 1481 if (tTd(64, 5)) 1482 sm_dprintf("X%s: %c=%ld\n", 1483 m->mf_name, fcode, 1484 (u_long) m->mf_timeout[tcode]); 1485 } 1486 p = delimptr; 1487 } 1488 } 1489 1490 /* 1491 ** MILTER_SET_MACROS -- set milter macros 1492 ** 1493 ** Parameters: 1494 ** name -- name of milter. 1495 ** macros -- where to store macros. 1496 ** val -- the value of the option. 1497 ** nummac -- current number of macros 1498 ** 1499 ** Returns: 1500 ** new number of macros 1501 */ 1502 1503 static int 1504 milter_set_macros(name, macros, val, nummac) 1505 char *name; 1506 char **macros; 1507 char *val; 1508 int nummac; 1509 { 1510 char *p; 1511 1512 p = newstr(val); 1513 while (*p != '\0') 1514 { 1515 char *macro; 1516 1517 /* Skip leading commas, spaces */ 1518 while (*p != '\0' && (*p == ',' || (SM_ISSPACE(*p)))) 1519 p++; 1520 1521 if (*p == '\0') 1522 break; 1523 1524 /* Find end of macro */ 1525 macro = p; 1526 while (*p != '\0' && *p != ',' && 1527 isascii(*p) && !isspace(*p)) 1528 p++; 1529 if (*p != '\0') 1530 *p++ = '\0'; 1531 1532 if (nummac >= MAXFILTERMACROS) 1533 { 1534 syserr("milter_set_option: too many macros in Milter.%s (max %d)", 1535 name, MAXFILTERMACROS); 1536 macros[nummac] = NULL; 1537 return -1; 1538 } 1539 macros[nummac++] = macro; 1540 } 1541 macros[nummac] = NULL; 1542 return nummac; 1543 } 1544 1545 /* 1546 ** MILTER_SET_OPTION -- set an individual milter option 1547 ** 1548 ** Parameters: 1549 ** name -- the name of the option. 1550 ** val -- the value of the option. 1551 ** sticky -- if set, don't let other setoptions override 1552 ** this value. 1553 ** 1554 ** Returns: 1555 ** none. 1556 */ 1557 1558 /* set if Milter sub-option is stuck */ 1559 static BITMAP256 StickyMilterOpt; 1560 1561 static struct milteropt 1562 { 1563 char *mo_name; /* long name of milter option */ 1564 unsigned char mo_code; /* code for option */ 1565 } MilterOptTab[] = 1566 { 1567 { "macros.connect", SMFIM_CONNECT }, 1568 { "macros.helo", SMFIM_HELO }, 1569 { "macros.envfrom", SMFIM_ENVFROM }, 1570 { "macros.envrcpt", SMFIM_ENVRCPT }, 1571 { "macros.data", SMFIM_DATA }, 1572 { "macros.eom", SMFIM_EOM }, 1573 { "macros.eoh", SMFIM_EOH }, 1574 1575 # define MO_LOGLEVEL 0x07 1576 { "loglevel", MO_LOGLEVEL }, 1577 # if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE 1578 # define MO_MAXDATASIZE 0x08 1579 { "maxdatasize", MO_MAXDATASIZE }, 1580 # endif 1581 { NULL, (unsigned char)-1 }, 1582 }; 1583 1584 void 1585 milter_set_option(name, val, sticky) 1586 char *name; 1587 char *val; 1588 bool sticky; 1589 { 1590 int nummac, r; 1591 struct milteropt *mo; 1592 char **macros = NULL; 1593 1594 nummac = 0; 1595 if (tTd(37, 2) || tTd(64, 5)) 1596 sm_dprintf("milter_set_option(%s = %s)", name, val); 1597 1598 if (name == NULL) 1599 { 1600 syserr("milter_set_option: invalid Milter option, must specify suboption"); 1601 return; 1602 } 1603 1604 for (mo = MilterOptTab; mo->mo_name != NULL; mo++) 1605 { 1606 if (SM_STRCASEEQ(mo->mo_name, name)) 1607 break; 1608 } 1609 1610 if (mo->mo_name == NULL) 1611 { 1612 syserr("milter_set_option: invalid Milter option %s", name); 1613 return; 1614 } 1615 1616 /* 1617 ** See if this option is preset for us. 1618 */ 1619 1620 if (!sticky && bitnset(mo->mo_code, StickyMilterOpt)) 1621 { 1622 if (tTd(37, 2) || tTd(64,5)) 1623 sm_dprintf(" (ignored)\n"); 1624 return; 1625 } 1626 1627 if (tTd(37, 2) || tTd(64,5)) 1628 sm_dprintf("\n"); 1629 1630 switch (mo->mo_code) 1631 { 1632 case MO_LOGLEVEL: 1633 MilterLogLevel = atoi(val); 1634 break; 1635 1636 # if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE 1637 case MO_MAXDATASIZE: 1638 # if _FFR_MDS_NEGOTIATE 1639 MilterMaxDataSize = (size_t)atol(val); 1640 if (MilterMaxDataSize != MILTER_MDS_64K && 1641 MilterMaxDataSize != MILTER_MDS_256K && 1642 MilterMaxDataSize != MILTER_MDS_1M) 1643 { 1644 sm_syslog(LOG_WARNING, NOQID, 1645 "WARNING: Milter.%s=%lu, allowed are only %d, %d, and %d", 1646 name, (unsigned long) MilterMaxDataSize, 1647 MILTER_MDS_64K, MILTER_MDS_256K, 1648 MILTER_MDS_1M); 1649 if (MilterMaxDataSize < MILTER_MDS_64K) 1650 MilterMaxDataSize = MILTER_MDS_64K; 1651 else if (MilterMaxDataSize < MILTER_MDS_256K) 1652 MilterMaxDataSize = MILTER_MDS_256K; 1653 else 1654 MilterMaxDataSize = MILTER_MDS_1M; 1655 } 1656 # endif /* _FFR_MDS_NEGOTIATE */ 1657 break; 1658 # endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */ 1659 1660 case SMFIM_CONNECT: 1661 case SMFIM_HELO: 1662 case SMFIM_ENVFROM: 1663 case SMFIM_ENVRCPT: 1664 case SMFIM_EOH: 1665 case SMFIM_EOM: 1666 case SMFIM_DATA: 1667 macros = MilterMacros[mo->mo_code][0]; 1668 1669 r = milter_set_macros(name, macros, val, nummac); 1670 if (r >= 0) 1671 nummac = r; 1672 break; 1673 1674 default: 1675 syserr("milter_set_option: invalid Milter option %s", name); 1676 break; 1677 } 1678 if (sticky) 1679 setbitn(mo->mo_code, StickyMilterOpt); 1680 } 1681 1682 /* 1683 ** MILTER_REOPEN_DF -- open & truncate the data file (for replbody) 1684 ** 1685 ** Parameters: 1686 ** e -- current envelope. 1687 ** 1688 ** Returns: 1689 ** 0 if successful, -1 otherwise 1690 */ 1691 1692 static int 1693 milter_reopen_df(e) 1694 ENVELOPE *e; 1695 { 1696 char dfname[MAXPATHLEN]; 1697 1698 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname)); 1699 1700 /* 1701 ** In SuperSafe == SAFE_REALLY mode, e->e_dfp is a read-only FP so 1702 ** close and reopen writable (later close and reopen 1703 ** read only again). 1704 ** 1705 ** In SuperSafe != SAFE_REALLY mode, e->e_dfp still points at the 1706 ** buffered file I/O descriptor, still open for writing so there 1707 ** isn't any work to do here (except checking for consistency). 1708 */ 1709 1710 if (SuperSafe == SAFE_REALLY) 1711 { 1712 /* close read-only data file */ 1713 if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL) 1714 { 1715 SM_CLOSE_FP(e->e_dfp); 1716 e->e_flags &= ~EF_HAS_DF; 1717 } 1718 1719 /* open writable */ 1720 if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, 1721 SM_IO_RDWR_B, NULL)) == NULL) 1722 { 1723 MILTER_DF_ERROR("milter_reopen_df: sm_io_open %s: %s"); 1724 return -1; 1725 } 1726 } 1727 else if (e->e_dfp == NULL) 1728 { 1729 /* shouldn't happen */ 1730 errno = ENOENT; 1731 MILTER_DF_ERROR("milter_reopen_df: NULL e_dfp (%s: %s)"); 1732 return -1; 1733 } 1734 return 0; 1735 } 1736 1737 /* 1738 ** MILTER_RESET_DF -- re-open read-only the data file (for replbody) 1739 ** 1740 ** Parameters: 1741 ** e -- current envelope. 1742 ** 1743 ** Returns: 1744 ** 0 if successful, -1 otherwise 1745 */ 1746 1747 static int 1748 milter_reset_df(e) 1749 ENVELOPE *e; 1750 { 1751 int afd; 1752 char dfname[MAXPATHLEN]; 1753 1754 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname)); 1755 1756 if (sm_io_flush(e->e_dfp, SM_TIME_DEFAULT) != 0 || 1757 sm_io_error(e->e_dfp)) 1758 { 1759 MILTER_DF_ERROR("milter_reset_df: error writing/flushing %s: %s"); 1760 return -1; 1761 } 1762 else if (SuperSafe != SAFE_REALLY) 1763 { 1764 /* skip next few clauses */ 1765 /* EMPTY */ 1766 } 1767 else if ((afd = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_FD, NULL)) >= 0 1768 && fsync(afd) < 0) 1769 { 1770 MILTER_DF_ERROR("milter_reset_df: error sync'ing %s: %s"); 1771 return -1; 1772 } 1773 else if (sm_io_close(e->e_dfp, SM_TIME_DEFAULT) < 0) 1774 { 1775 MILTER_DF_ERROR("milter_reset_df: error closing %s: %s"); 1776 return -1; 1777 } 1778 else if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, 1779 SM_IO_RDONLY_B, NULL)) == NULL) 1780 { 1781 MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s"); 1782 return -1; 1783 } 1784 else 1785 e->e_flags |= EF_HAS_DF; 1786 return 0; 1787 } 1788 1789 /* 1790 ** MILTER_QUIT_FILTER -- close down a single filter 1791 ** 1792 ** Parameters: 1793 ** m -- milter structure of filter to close down. 1794 ** e -- current envelope. 1795 ** 1796 ** Returns: 1797 ** none 1798 */ 1799 1800 static void 1801 milter_quit_filter(m, e) 1802 struct milter *m; 1803 ENVELOPE *e; 1804 { 1805 if (tTd(64, 10)) 1806 sm_dprintf("milter_quit_filter(%s)\n", m->mf_name); 1807 if (MilterLogLevel > 18) 1808 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): quit filter", 1809 m->mf_name); 1810 1811 /* Never replace error state */ 1812 if (m->mf_state == SMFS_ERROR) 1813 return; 1814 1815 if (m->mf_sock < 0 || 1816 m->mf_state == SMFS_CLOSED || 1817 m->mf_state == SMFS_READY) 1818 { 1819 m->mf_sock = -1; 1820 m->mf_state = SMFS_CLOSED; 1821 return; 1822 } 1823 1824 (void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0, 1825 m->mf_timeout[SMFTO_WRITE], e, "quit_filter"); 1826 if (m->mf_sock >= 0) 1827 { 1828 (void) close(m->mf_sock); 1829 m->mf_sock = -1; 1830 } 1831 if (m->mf_state != SMFS_ERROR) 1832 m->mf_state = SMFS_CLOSED; 1833 } 1834 1835 /* 1836 ** MILTER_ABORT_FILTER -- tell filter to abort current message 1837 ** 1838 ** Parameters: 1839 ** m -- milter structure of filter to abort. 1840 ** e -- current envelope. 1841 ** 1842 ** Returns: 1843 ** none 1844 */ 1845 1846 static void 1847 milter_abort_filter(m, e) 1848 struct milter *m; 1849 ENVELOPE *e; 1850 { 1851 if (tTd(64, 10)) 1852 sm_dprintf("milter_abort_filter(%s)\n", m->mf_name); 1853 if (MilterLogLevel > 10) 1854 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): abort filter", 1855 m->mf_name); 1856 1857 if (m->mf_sock < 0 || 1858 m->mf_state != SMFS_INMSG) 1859 return; 1860 1861 (void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0, 1862 m->mf_timeout[SMFTO_WRITE], e, "abort_filter"); 1863 if (m->mf_state != SMFS_ERROR) 1864 m->mf_state = SMFS_DONE; 1865 } 1866 1867 /* 1868 ** MILTER_SEND_MACROS -- provide macros to the filters 1869 ** 1870 ** Parameters: 1871 ** m -- milter to send macros to. 1872 ** macros -- macros to send for filter smfi_getsymval(). 1873 ** cmd -- which command the macros are associated with. 1874 ** e -- current envelope (for macro access). 1875 ** 1876 ** Returns: 1877 ** none 1878 */ 1879 1880 static void 1881 milter_send_macros(m, macros, cmd, e) 1882 struct milter *m; 1883 char **macros; 1884 int cmd; 1885 ENVELOPE *e; 1886 { 1887 int i; 1888 int mid; 1889 char command = (char) cmd; 1890 char *v; 1891 char *buf, *bp; 1892 char exp[MAXLINE]; 1893 ssize_t s; 1894 1895 /* sanity check */ 1896 if (NULL == macros || NULL == macros[0]) 1897 return; 1898 1899 /* put together data */ 1900 s = 1; /* for the command character */ 1901 for (i = 0; macros[i] != NULL; i++) 1902 { 1903 mid = macid(macros[i]); 1904 if (mid == 0) 1905 continue; 1906 v = macvalue(mid, e); 1907 if (v == NULL) 1908 continue; 1909 expand(v, exp, sizeof(exp), e); 1910 s += strlen(macros[i]) + 1 + 1911 # if _FFR_8BITENVADDR 1912 ilenx(exp) 1913 # else 1914 strlen(exp) 1915 # endif 1916 + 1; 1917 } 1918 1919 if (s < 0) 1920 return; 1921 1922 buf = (char *) xalloc(s); 1923 bp = buf; 1924 *bp++ = command; 1925 for (i = 0; macros[i] != NULL; i++) 1926 { 1927 mid = macid(macros[i]); 1928 if (mid == 0) 1929 continue; 1930 v = macvalue(mid, e); 1931 if (v == NULL) 1932 continue; 1933 expand(v, exp, sizeof(exp), e); 1934 # if _FFR_8BITENVADDR 1935 dequote_internal_chars(exp, exp, sizeof(exp)); 1936 # endif 1937 1938 if (tTd(64, 10)) 1939 sm_dprintf("milter_send_macros(%s, %c): %s=%s\n", 1940 m->mf_name, command, macros[i], exp); 1941 1942 (void) sm_strlcpy(bp, macros[i], s - (bp - buf)); 1943 bp += strlen(bp) + 1; 1944 (void) sm_strlcpy(bp, exp, s - (bp - buf)); 1945 bp += strlen(bp) + 1; 1946 } 1947 (void) milter_write(m, SMFIC_MACRO, buf, s, 1948 m->mf_timeout[SMFTO_WRITE], e, "send_macros"); 1949 sm_free(buf); 1950 } 1951 1952 /* 1953 ** MILTER_SEND_COMMAND -- send a command and return the response for a filter 1954 ** 1955 ** Parameters: 1956 ** m -- current milter filter 1957 ** cmd -- command to send. 1958 ** data -- optional command data. 1959 ** sz -- length of buf. 1960 ** e -- current envelope (for e->e_id). 1961 ** state -- return state word. 1962 ** 1963 ** Returns: 1964 ** response string (may be NULL) 1965 */ 1966 1967 static char * 1968 milter_send_command(m, cmd, data, sz, e, state, where) 1969 struct milter *m; 1970 int cmd; 1971 void *data; 1972 ssize_t sz; 1973 ENVELOPE *e; 1974 char *state; 1975 const char *where; 1976 { 1977 char rcmd; 1978 ssize_t rlen; 1979 unsigned long skipflag; 1980 unsigned long norespflag = 0; 1981 char command = (char) cmd; 1982 char *action; 1983 char *defresponse; 1984 char *response; 1985 1986 if (tTd(64, 10)) 1987 sm_dprintf("milter_send_command(%s): cmd %c len %ld\n", 1988 m->mf_name, (char) command, (long) sz); 1989 1990 /* find skip flag and default failure */ 1991 switch (command) 1992 { 1993 case SMFIC_CONNECT: 1994 skipflag = SMFIP_NOCONNECT; 1995 norespflag = SMFIP_NR_CONN; 1996 action = "connect"; 1997 defresponse = "554 Command rejected"; 1998 break; 1999 2000 case SMFIC_HELO: 2001 skipflag = SMFIP_NOHELO; 2002 norespflag = SMFIP_NR_HELO; 2003 action = "helo"; 2004 defresponse = "550 Command rejected"; 2005 break; 2006 2007 case SMFIC_MAIL: 2008 skipflag = SMFIP_NOMAIL; 2009 norespflag = SMFIP_NR_MAIL; 2010 action = "mail"; 2011 defresponse = "550 5.7.1 Command rejected"; 2012 break; 2013 2014 case SMFIC_RCPT: 2015 skipflag = SMFIP_NORCPT; 2016 norespflag = SMFIP_NR_RCPT; 2017 action = "rcpt"; 2018 defresponse = "550 5.7.1 Command rejected"; 2019 break; 2020 2021 case SMFIC_HEADER: 2022 skipflag = SMFIP_NOHDRS; 2023 norespflag = SMFIP_NR_HDR; 2024 action = "header"; 2025 defresponse = "550 5.7.1 Command rejected"; 2026 break; 2027 2028 case SMFIC_BODY: 2029 skipflag = SMFIP_NOBODY; 2030 norespflag = SMFIP_NR_BODY; 2031 action = "body"; 2032 defresponse = "554 5.7.1 Command rejected"; 2033 break; 2034 2035 case SMFIC_EOH: 2036 skipflag = SMFIP_NOEOH; 2037 norespflag = SMFIP_NR_EOH; 2038 action = "eoh"; 2039 defresponse = "550 5.7.1 Command rejected"; 2040 break; 2041 2042 case SMFIC_UNKNOWN: 2043 skipflag = SMFIP_NOUNKNOWN; 2044 norespflag = SMFIP_NR_UNKN; 2045 action = "unknown"; 2046 defresponse = "550 5.7.1 Command rejected"; 2047 break; 2048 2049 case SMFIC_DATA: 2050 skipflag = SMFIP_NODATA; 2051 norespflag = SMFIP_NR_DATA; 2052 action = "data"; 2053 defresponse = "550 5.7.1 Command rejected"; 2054 break; 2055 2056 case SMFIC_BODYEOB: 2057 case SMFIC_OPTNEG: 2058 case SMFIC_MACRO: 2059 case SMFIC_ABORT: 2060 case SMFIC_QUIT: 2061 /* NOTE: not handled by milter_send_command() */ 2062 /* FALLTHROUGH */ 2063 2064 default: 2065 skipflag = 0; 2066 action = "default"; 2067 defresponse = "550 5.7.1 Command rejected"; 2068 break; 2069 } 2070 2071 if (tTd(64, 10)) 2072 sm_dprintf("milter_send_command(%s): skip=%lx, pflags=%x\n", 2073 m->mf_name, skipflag, m->mf_pflags); 2074 2075 /* check if filter wants this command */ 2076 if (skipflag != 0 && bitset(skipflag, m->mf_pflags)) 2077 return NULL; 2078 2079 /* send the command to the filter */ 2080 (void) milter_write(m, command, data, sz, 2081 m->mf_timeout[SMFTO_WRITE], e, where); 2082 if (m->mf_state == SMFS_ERROR) 2083 { 2084 MILTER_CHECK_ERROR(false, return NULL); 2085 return NULL; 2086 } 2087 2088 /* check if filter sends response to this command */ 2089 if (norespflag != 0 && bitset(norespflag, m->mf_pflags)) 2090 return NULL; 2091 2092 /* get the response from the filter */ 2093 response = milter_read(m, &rcmd, &rlen, 2094 m->mf_timeout[SMFTO_READ], e, where); 2095 if (m->mf_state == SMFS_ERROR) 2096 { 2097 MILTER_CHECK_ERROR(false, return NULL); 2098 return NULL; 2099 } 2100 2101 if (tTd(64, 10)) 2102 sm_dprintf("milter_send_command(%s): returned %c\n", 2103 m->mf_name, (char) rcmd); 2104 2105 switch (rcmd) 2106 { 2107 case SMFIR_REPLYCODE: 2108 MILTER_CHECK_REPLYCODE(defresponse); 2109 if (MilterLogLevel > 10) 2110 sm_syslog(LOG_INFO, e->e_id, 2111 "milter=%s, action=%s, reject=%s", 2112 m->mf_name, action, response); 2113 *state = rcmd; 2114 break; 2115 2116 case SMFIR_REJECT: 2117 if (MilterLogLevel > 10) 2118 sm_syslog(LOG_INFO, e->e_id, 2119 "milter=%s, action=%s, reject", 2120 m->mf_name, action); 2121 *state = rcmd; 2122 break; 2123 2124 case SMFIR_DISCARD: 2125 if (MilterLogLevel > 10) 2126 sm_syslog(LOG_INFO, e->e_id, 2127 "milter=%s, action=%s, discard", 2128 m->mf_name, action); 2129 *state = rcmd; 2130 break; 2131 2132 case SMFIR_TEMPFAIL: 2133 if (MilterLogLevel > 10) 2134 sm_syslog(LOG_INFO, e->e_id, 2135 "milter=%s, action=%s, tempfail", 2136 m->mf_name, action); 2137 *state = rcmd; 2138 break; 2139 2140 case SMFIR_ACCEPT: 2141 /* this filter is done with message/connection */ 2142 if (command == SMFIC_HELO || 2143 command == SMFIC_CONNECT) 2144 m->mf_state = SMFS_CLOSABLE; 2145 else 2146 m->mf_state = SMFS_DONE; 2147 if (MilterLogLevel > 10) 2148 sm_syslog(LOG_INFO, e->e_id, 2149 "milter=%s, action=%s, accepted", 2150 m->mf_name, action); 2151 break; 2152 2153 case SMFIR_CONTINUE: 2154 /* if MAIL command is ok, filter is in message state */ 2155 if (command == SMFIC_MAIL) 2156 m->mf_state = SMFS_INMSG; 2157 if (MilterLogLevel > 12) 2158 sm_syslog(LOG_INFO, e->e_id, 2159 "milter=%s, action=%s, continue", 2160 m->mf_name, action); 2161 break; 2162 2163 case SMFIR_SKIP: 2164 if (MilterLogLevel > 12) 2165 sm_syslog(LOG_INFO, e->e_id, 2166 "milter=%s, action=%s, skip", 2167 m->mf_name, action); 2168 m->mf_state = SMFS_SKIP; 2169 break; 2170 2171 default: 2172 /* Invalid response to command */ 2173 if (MilterLogLevel > 0) 2174 sm_syslog(LOG_ERR, e->e_id, 2175 "milter_send_command(%s): action=%s returned bogus response %c", 2176 m->mf_name, action, rcmd); 2177 milter_error(m, e); /* NO ERROR CHECK? */ 2178 break; 2179 } 2180 2181 if (*state != SMFIR_REPLYCODE && response != NULL) 2182 { 2183 sm_free(response); /* XXX */ 2184 response = NULL; 2185 } 2186 return response; 2187 } 2188 2189 /* 2190 ** MILTER_COMMAND -- send a command and return the response for each filter 2191 ** 2192 ** Parameters: 2193 ** cmd -- command to send. 2194 ** data -- optional command data. 2195 ** sz -- length of buf. 2196 ** stage -- index of macros to send for filter smfi_getsymval(). 2197 ** e -- current envelope (for macro access). 2198 ** state -- return state word. 2199 ** where -- description of calling function (logging). 2200 ** cmd_error -- did the SMTP command cause an error? 2201 ** 2202 ** Returns: 2203 ** response string (may be NULL) 2204 */ 2205 2206 static char * 2207 milter_command(cmd, data, sz, stage, e, state, where, cmd_error) 2208 int cmd; 2209 void *data; 2210 ssize_t sz; 2211 int stage; 2212 ENVELOPE *e; 2213 char *state; 2214 const char *where; 2215 bool cmd_error; 2216 { 2217 int i; 2218 char command = (char) cmd; 2219 char *response = NULL; 2220 time_t tn = 0; 2221 2222 if (tTd(64, 10)) 2223 sm_dprintf("milter_command: cmd %c len %ld\n", 2224 command, (long) sz); 2225 2226 *state = SMFIR_CONTINUE; 2227 for (i = 0; InputFilters[i] != NULL; i++) 2228 { 2229 struct milter *m = InputFilters[i]; 2230 2231 /* previous problem? */ 2232 if (m->mf_state == SMFS_ERROR) 2233 { 2234 MILTER_CHECK_ERROR(false, continue); 2235 break; 2236 } 2237 2238 /* sanity check */ 2239 if (m->mf_sock < 0 || 2240 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) 2241 continue; 2242 2243 if (stage >= SMFIM_FIRST && stage <= SMFIM_LAST) 2244 { 2245 int idx; 2246 char **macros; 2247 2248 if ((m->mf_lflags & MI_LFLAGS_SYM(stage)) != 0) 2249 idx = m->mf_idx; 2250 else 2251 idx = 0; 2252 SM_ASSERT(idx >= 0 && idx <= MAXFILTERS); 2253 macros = MilterMacros[stage][idx]; 2254 2255 /* send macros (regardless of whether we send cmd) */ 2256 if (macros != NULL && macros[0] != NULL) 2257 { 2258 milter_send_macros(m, macros, command, e); 2259 if (m->mf_state == SMFS_ERROR) 2260 { 2261 MILTER_CHECK_ERROR(false, continue); 2262 break; 2263 } 2264 } 2265 } 2266 2267 if (MilterLogLevel > 21) 2268 tn = curtime(); 2269 2270 /* 2271 ** send the command if 2272 ** there is no error 2273 ** or it's RCPT and the client asked for it: 2274 ** !cmd_error || 2275 ** where == "rcpt" && m->mf_pflags & SMFIP_RCPT_REJ != 0 2276 ** negate that condition and use continue 2277 */ 2278 2279 if (cmd_error && 2280 (strcmp(where, "rcpt") != 0 || 2281 (m->mf_pflags & SMFIP_RCPT_REJ) == 0)) 2282 continue; 2283 2284 response = milter_send_command(m, command, data, sz, e, state, 2285 where); 2286 2287 if (MilterLogLevel > 21) 2288 { 2289 /* log the time it took for the command per filter */ 2290 sm_syslog(LOG_INFO, e->e_id, 2291 "Milter (%s): time command (%c), %d", 2292 m->mf_name, command, (int) (tn - curtime())); 2293 } 2294 2295 if (*state != SMFIR_CONTINUE) 2296 break; 2297 } 2298 return response; 2299 } 2300 2301 static int milter_getsymlist __P((struct milter *, char *, int, int)); 2302 2303 static int 2304 milter_getsymlist(m, buf, rlen, offset) 2305 struct milter *m; 2306 char *buf; 2307 int rlen; 2308 int offset; 2309 { 2310 int i, r, nummac; 2311 mi_int32 v; 2312 2313 SM_ASSERT(m != NULL); 2314 SM_ASSERT(buf != NULL); 2315 2316 while (offset + MILTER_LEN_BYTES < rlen) 2317 { 2318 size_t len; 2319 char **macros; 2320 2321 nummac = 0; 2322 (void) memcpy((char *) &v, buf + offset, MILTER_LEN_BYTES); 2323 i = ntohl(v); 2324 if (i < SMFIM_FIRST || i > SMFIM_LAST) 2325 return -1; 2326 offset += MILTER_LEN_BYTES; 2327 macros = NULL; 2328 2329 #define SM_M_MACRO_NAME(i) (((i) < SM_ARRAY_SIZE(MilterOptTab) && (i) >= 0) \ 2330 ? MilterOptTab[i].mo_name : "?") 2331 switch (i) 2332 { 2333 case SMFIM_CONNECT: 2334 case SMFIM_HELO: 2335 case SMFIM_ENVFROM: 2336 case SMFIM_ENVRCPT: 2337 case SMFIM_EOH: 2338 case SMFIM_EOM: 2339 case SMFIM_DATA: 2340 SM_ASSERT(m->mf_idx > 0 && m->mf_idx < MAXFILTERS); 2341 macros = MilterMacros[i][m->mf_idx]; 2342 m->mf_lflags |= MI_LFLAGS_SYM(i); 2343 len = strlen(buf + offset); 2344 r = milter_set_macros(m->mf_name, macros, buf + offset, 2345 nummac); 2346 if (r >= 0) 2347 nummac = r; 2348 if (tTd(64, 5)) 2349 sm_dprintf("milter_getsymlist(%s, %s, \"%s\")=%d\n", 2350 m->mf_name, SM_M_MACRO_NAME(i), 2351 buf + offset, r); 2352 break; 2353 2354 default: 2355 return -1; 2356 } 2357 offset += len + 1; 2358 } 2359 2360 return 0; 2361 } 2362 2363 /* 2364 ** MILTER_NEGOTIATE -- get version and flags from filter 2365 ** 2366 ** Parameters: 2367 ** m -- milter filter structure. 2368 ** e -- current envelope. 2369 ** milters -- milters structure. 2370 ** 2371 ** Returns: 2372 ** 0 on success, -1 otherwise 2373 */ 2374 2375 static int 2376 milter_negotiate(m, e, milters) 2377 struct milter *m; 2378 ENVELOPE *e; 2379 milters_T *milters; 2380 { 2381 char rcmd; 2382 mi_int32 fvers, fflags, pflags; 2383 mi_int32 mta_prot_vers, mta_prot_flags, mta_actions; 2384 ssize_t rlen; 2385 char *response; 2386 char data[MILTER_OPTLEN]; 2387 2388 /* sanity check */ 2389 if (m->mf_sock < 0 || m->mf_state != SMFS_OPEN) 2390 { 2391 if (MilterLogLevel > 0) 2392 sm_syslog(LOG_ERR, e->e_id, 2393 "Milter (%s): negotiate, impossible state", 2394 m->mf_name); 2395 milter_error(m, e); 2396 return -1; 2397 } 2398 2399 # if _FFR_MILTER_CHECK 2400 mta_prot_vers = m->mf_mta_prot_version; 2401 mta_prot_flags = m->mf_mta_prot_flags; 2402 mta_actions = m->mf_mta_actions; 2403 # else /* _FFR_MILTER_CHECK */ 2404 mta_prot_vers = SMFI_PROT_VERSION; 2405 mta_prot_flags = SMFI_CURR_PROT; 2406 mta_actions = SMFI_CURR_ACTS; 2407 # endif /* _FFR_MILTER_CHECK */ 2408 # if _FFR_MDS_NEGOTIATE 2409 if (MilterMaxDataSize == MILTER_MDS_256K) 2410 mta_prot_flags |= SMFIP_MDS_256K; 2411 else if (MilterMaxDataSize == MILTER_MDS_1M) 2412 mta_prot_flags |= SMFIP_MDS_1M; 2413 # endif /* _FFR_MDS_NEGOTIATE */ 2414 2415 fvers = htonl(mta_prot_vers); 2416 pflags = htonl(mta_prot_flags); 2417 fflags = htonl(mta_actions); 2418 (void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES); 2419 (void) memcpy(data + MILTER_LEN_BYTES, 2420 (char *) &fflags, MILTER_LEN_BYTES); 2421 (void) memcpy(data + (MILTER_LEN_BYTES * 2), 2422 (char *) &pflags, MILTER_LEN_BYTES); 2423 (void) milter_write(m, SMFIC_OPTNEG, data, sizeof(data), 2424 m->mf_timeout[SMFTO_WRITE], e, "negotiate"); 2425 2426 if (m->mf_state == SMFS_ERROR) 2427 return -1; 2428 2429 if (tTd(64, 5)) 2430 sm_dprintf("milter_negotiate(%s): send: version %lu, fflags 0x%lx, pflags 0x%lx\n", 2431 m->mf_name, (unsigned long) ntohl(fvers), 2432 (unsigned long) ntohl(fflags), 2433 (unsigned long) ntohl(pflags)); 2434 2435 response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e, 2436 "negotiate"); 2437 if (m->mf_state == SMFS_ERROR) 2438 { 2439 SM_FREE(response); 2440 return -1; 2441 } 2442 2443 if (rcmd != SMFIC_OPTNEG) 2444 { 2445 if (tTd(64, 5)) 2446 sm_dprintf("milter_negotiate(%s): returned %c instead of %c\n", 2447 m->mf_name, rcmd, SMFIC_OPTNEG); 2448 if (MilterLogLevel > 0) 2449 sm_syslog(LOG_ERR, e->e_id, 2450 "Milter (%s): negotiate: returned %c instead of %c", 2451 m->mf_name, rcmd, SMFIC_OPTNEG); 2452 SM_FREE(response); 2453 milter_error(m, e); 2454 return -1; 2455 } 2456 2457 /* Make sure we have enough bytes for the version */ 2458 if (response == NULL || rlen < MILTER_LEN_BYTES) 2459 { 2460 if (tTd(64, 5)) 2461 sm_dprintf("milter_negotiate(%s): did not return valid info\n", 2462 m->mf_name); 2463 if (MilterLogLevel > 0) 2464 sm_syslog(LOG_ERR, e->e_id, 2465 "Milter (%s): negotiate: did not return valid info", 2466 m->mf_name); 2467 SM_FREE(response); 2468 milter_error(m, e); 2469 return -1; 2470 } 2471 2472 /* extract information */ 2473 (void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES); 2474 2475 /* Now make sure we have enough for the feature bitmap */ 2476 if (rlen < MILTER_OPTLEN) 2477 { 2478 if (tTd(64, 5)) 2479 sm_dprintf("milter_negotiate(%s): did not return enough info\n", 2480 m->mf_name); 2481 if (MilterLogLevel > 0) 2482 sm_syslog(LOG_ERR, e->e_id, 2483 "Milter (%s): negotiate: did not return enough info", 2484 m->mf_name); 2485 SM_FREE(response); 2486 milter_error(m, e); 2487 return -1; 2488 } 2489 2490 (void) memcpy((char *) &fflags, response + MILTER_LEN_BYTES, 2491 MILTER_LEN_BYTES); 2492 (void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2), 2493 MILTER_LEN_BYTES); 2494 2495 m->mf_fvers = ntohl(fvers); 2496 m->mf_fflags = ntohl(fflags); 2497 m->mf_pflags = ntohl(pflags); 2498 2499 /* check for version compatibility */ 2500 if (m->mf_fvers == 1 || 2501 m->mf_fvers > SMFI_VERSION) 2502 { 2503 if (tTd(64, 5)) 2504 sm_dprintf("milter_negotiate(%s): version %d != MTA milter version %d\n", 2505 m->mf_name, m->mf_fvers, SMFI_VERSION); 2506 if (MilterLogLevel > 0) 2507 sm_syslog(LOG_ERR, e->e_id, 2508 "Milter (%s): negotiate: version %d != MTA milter version %d", 2509 m->mf_name, m->mf_fvers, SMFI_VERSION); 2510 milter_error(m, e); 2511 goto error; 2512 } 2513 2514 /* check for filter feature mismatch */ 2515 if ((m->mf_fflags & mta_actions) != m->mf_fflags) 2516 { 2517 if (tTd(64, 5)) 2518 sm_dprintf("milter_negotiate(%s): filter abilities 0x%x != MTA milter abilities 0x%lx\n", 2519 m->mf_name, m->mf_fflags, 2520 (unsigned long) mta_actions); 2521 if (MilterLogLevel > 0) 2522 sm_syslog(LOG_ERR, e->e_id, 2523 "Milter (%s): negotiate: filter abilities 0x%x != MTA milter abilities 0x%lx", 2524 m->mf_name, m->mf_fflags, 2525 (unsigned long) mta_actions); 2526 milter_error(m, e); 2527 goto error; 2528 } 2529 2530 # if _FFR_MDS_NEGOTIATE 2531 # define MDSWARNING(sz) \ 2532 do \ 2533 { \ 2534 sm_syslog(LOG_WARNING, NOQID, \ 2535 "WARNING: Milter.maxdatasize: configured=%lu, set by milter(%s)=%d", \ 2536 (unsigned long) MilterMaxDataSize, m->mf_name, sz); \ 2537 MilterMaxDataSize = sz; \ 2538 } while (0) 2539 2540 /* use a table instead of sequence? */ 2541 if (bitset(SMFIP_MDS_1M, m->mf_pflags)) 2542 { 2543 if (MilterMaxDataSize != MILTER_MDS_1M) 2544 MDSWARNING(MILTER_MDS_1M); 2545 } 2546 else if (bitset(SMFIP_MDS_256K, m->mf_pflags)) 2547 { 2548 if (MilterMaxDataSize != MILTER_MDS_256K) 2549 MDSWARNING(MILTER_MDS_256K); 2550 } 2551 2552 /* 2553 ** Note: it is not possible to distinguish between 2554 ** - milter requested 64K 2555 ** - milter did not request anything 2556 ** as there is no SMFIP_MDS_64K flag. 2557 */ 2558 2559 else if (MilterMaxDataSize != MILTER_MDS_64K) 2560 MDSWARNING(MILTER_MDS_64K); 2561 m->mf_pflags &= ~SMFI_INTERNAL; 2562 # endif /* _FFR_MDS_NEGOTIATE */ 2563 2564 /* check for protocol feature mismatch */ 2565 if ((m->mf_pflags & mta_prot_flags) != m->mf_pflags) 2566 { 2567 if (tTd(64, 5)) 2568 sm_dprintf("milter_negotiate(%s): protocol abilities 0x%x != MTA milter abilities 0x%lx\n", 2569 m->mf_name, m->mf_pflags, 2570 (unsigned long) mta_prot_flags); 2571 if (MilterLogLevel > 0) 2572 sm_syslog(LOG_ERR, e->e_id, 2573 "Milter (%s): negotiate: protocol abilities 0x%x != MTA milter abilities 0x%lx", 2574 m->mf_name, m->mf_pflags, 2575 (unsigned long) mta_prot_flags); 2576 milter_error(m, e); 2577 goto error; 2578 } 2579 2580 if (m->mf_fvers <= 2) 2581 m->mf_pflags |= SMFIP_NOUNKNOWN; 2582 if (m->mf_fvers <= 3) 2583 m->mf_pflags |= SMFIP_NODATA; 2584 2585 if (rlen > MILTER_OPTLEN) 2586 { 2587 milter_getsymlist(m, response, rlen, MILTER_OPTLEN); 2588 } 2589 2590 if (bitset(SMFIF_DELRCPT, m->mf_fflags)) 2591 milters->mis_flags |= MIS_FL_DEL_RCPT; 2592 if (!bitset(SMFIP_NORCPT, m->mf_pflags) && 2593 !bitset(SMFIP_NR_RCPT, m->mf_pflags)) 2594 milters->mis_flags |= MIS_FL_REJ_RCPT; 2595 2596 if (tTd(64, 5)) 2597 sm_dprintf("milter_negotiate(%s): received: version %u, fflags 0x%x, pflags 0x%x\n", 2598 m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags); 2599 SM_FREE(response); 2600 return 0; 2601 2602 error: 2603 SM_FREE(response); 2604 return -1; 2605 } 2606 2607 /* 2608 ** MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands 2609 ** 2610 ** Reduce code duplication by putting these checks in one place 2611 ** 2612 ** Parameters: 2613 ** e -- current envelope. 2614 ** 2615 ** Returns: 2616 ** none 2617 */ 2618 2619 static void 2620 milter_per_connection_check(e) 2621 ENVELOPE *e; 2622 { 2623 int i; 2624 2625 /* see if we are done with any of the filters */ 2626 for (i = 0; InputFilters[i] != NULL; i++) 2627 { 2628 struct milter *m = InputFilters[i]; 2629 2630 if (m->mf_state == SMFS_CLOSABLE) 2631 milter_quit_filter(m, e); 2632 } 2633 } 2634 2635 /* 2636 ** MILTER_ERROR -- Put a milter filter into error state 2637 ** 2638 ** Parameters: 2639 ** m -- the broken filter. 2640 ** e -- current envelope. 2641 ** 2642 ** Returns: 2643 ** none 2644 */ 2645 2646 static void 2647 milter_error(m, e) 2648 struct milter *m; 2649 ENVELOPE *e; 2650 { 2651 /* 2652 ** We could send a quit here but we may have gotten here due to 2653 ** an I/O error so we don't want to try to make things worse. 2654 */ 2655 2656 if (m->mf_sock >= 0) 2657 { 2658 (void) close(m->mf_sock); 2659 m->mf_sock = -1; 2660 } 2661 m->mf_state = SMFS_ERROR; 2662 2663 if (MilterLogLevel > 0) 2664 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): to error state", 2665 m->mf_name); 2666 } 2667 2668 /* 2669 ** MILTER_HEADERS -- send headers to a single milter filter 2670 ** 2671 ** Parameters: 2672 ** m -- current filter. 2673 ** e -- current envelope. 2674 ** state -- return state from response. 2675 ** 2676 ** Returns: 2677 ** response string (may be NULL) 2678 */ 2679 2680 static char * 2681 milter_headers(m, e, state) 2682 struct milter *m; 2683 ENVELOPE *e; 2684 char *state; 2685 { 2686 char *response = NULL; 2687 HDR *h; 2688 2689 if (MilterLogLevel > 17) 2690 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, send", 2691 m->mf_name); 2692 2693 for (h = e->e_header; h != NULL; h = h->h_link) 2694 { 2695 int len_n, len_v, len_t, len_f; 2696 char *buf, *hv; 2697 2698 /* don't send over deleted headers */ 2699 if (h->h_value == NULL) 2700 { 2701 /* strip H_USER so not counted in milter_changeheader() */ 2702 h->h_flags &= ~H_USER; 2703 continue; 2704 } 2705 2706 /* skip auto-generated */ 2707 if (!bitset(H_USER, h->h_flags)) 2708 continue; 2709 2710 if (tTd(64, 10)) 2711 sm_dprintf("milter_headers: %s:%s\n", 2712 h->h_field, h->h_value); 2713 if (MilterLogLevel > 21) 2714 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): header, %s", 2715 m->mf_name, h->h_field); 2716 2717 if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags) 2718 || *(h->h_value) != ' ') 2719 hv = h->h_value; 2720 else 2721 hv = h->h_value + 1; 2722 len_f = strlen(h->h_field) + 1; 2723 len_t = len_f + strlen(hv) + 1; 2724 if (len_t < 0) 2725 continue; 2726 buf = (char *) xalloc(len_t); 2727 2728 /* 2729 ** Note: currently the call to dequote_internal_chars() 2730 ** is not required as h_field is supposed to be 7-bit US-ASCII. 2731 */ 2732 2733 len_n = dequote_internal_chars(h->h_field, buf, len_f); 2734 SM_ASSERT(len_n < len_f); 2735 len_v = dequote_internal_chars(hv, buf + len_n + 1, 2736 len_t - len_n - 1); 2737 SM_ASSERT(len_t >= len_n + 1 + len_v + 1); 2738 len_t = len_n + 1 + len_v + 1; 2739 2740 /* send it over */ 2741 response = milter_send_command(m, SMFIC_HEADER, buf, 2742 len_t, e, state, "header"); 2743 sm_free(buf); 2744 if (m->mf_state == SMFS_ERROR || 2745 m->mf_state == SMFS_DONE || 2746 *state != SMFIR_CONTINUE) 2747 break; 2748 } 2749 if (MilterLogLevel > 17) 2750 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, sent", 2751 m->mf_name); 2752 return response; 2753 } 2754 2755 /* 2756 ** MILTER_BODY -- send the body to a filter 2757 ** 2758 ** Parameters: 2759 ** m -- current filter. 2760 ** e -- current envelope. 2761 ** state -- return state from response. 2762 ** 2763 ** Returns: 2764 ** response string (may be NULL) 2765 */ 2766 2767 static char * 2768 milter_body(m, e, state) 2769 struct milter *m; 2770 ENVELOPE *e; 2771 char *state; 2772 { 2773 char bufchar = '\0'; 2774 char prevchar = '\0'; 2775 int c; 2776 char *response = NULL; 2777 char *bp; 2778 char buf[MILTER_CHUNK_SIZE]; 2779 2780 if (tTd(64, 10)) 2781 sm_dprintf("milter_body\n"); 2782 2783 if (bfrewind(e->e_dfp) < 0) 2784 { 2785 ExitStat = EX_IOERR; 2786 *state = SMFIR_TEMPFAIL; 2787 syserr("milter_body: %s/%cf%s: rewind error", 2788 qid_printqueue(e->e_qgrp, e->e_qdir), 2789 DATAFL_LETTER, e->e_id); 2790 return NULL; 2791 } 2792 2793 if (MilterLogLevel > 17) 2794 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, send", 2795 m->mf_name); 2796 bp = buf; 2797 while ((c = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT)) != SM_IO_EOF) 2798 { 2799 /* Change LF to CRLF */ 2800 if (c == '\n') 2801 { 2802 # if !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF 2803 /* Not a CRLF already? */ 2804 if (prevchar != '\r') 2805 # endif 2806 { 2807 /* Room for CR now? */ 2808 if (bp + 2 > &buf[sizeof(buf)]) 2809 { 2810 /* No room, buffer LF */ 2811 bufchar = c; 2812 2813 /* and send CR now */ 2814 c = '\r'; 2815 } 2816 else 2817 { 2818 /* Room to do it now */ 2819 *bp++ = '\r'; 2820 prevchar = '\r'; 2821 } 2822 } 2823 } 2824 *bp++ = (char) c; 2825 prevchar = c; 2826 if (bp >= &buf[sizeof(buf)]) 2827 { 2828 /* send chunk */ 2829 response = milter_send_command(m, SMFIC_BODY, buf, 2830 bp - buf, e, state, 2831 "body chunk"); 2832 bp = buf; 2833 if (bufchar != '\0') 2834 { 2835 *bp++ = bufchar; 2836 bufchar = '\0'; 2837 prevchar = bufchar; 2838 } 2839 } 2840 if (m->mf_state == SMFS_ERROR || 2841 m->mf_state == SMFS_DONE || 2842 m->mf_state == SMFS_SKIP || 2843 *state != SMFIR_CONTINUE) 2844 break; 2845 } 2846 2847 /* check for read errors */ 2848 if (sm_io_error(e->e_dfp)) 2849 { 2850 ExitStat = EX_IOERR; 2851 if (*state == SMFIR_CONTINUE || 2852 *state == SMFIR_ACCEPT || 2853 m->mf_state == SMFS_SKIP) 2854 { 2855 *state = SMFIR_TEMPFAIL; 2856 if (response != NULL) 2857 { 2858 sm_free(response); /* XXX */ 2859 response = NULL; 2860 } 2861 } 2862 syserr("milter_body: %s/%cf%s: read error", 2863 qid_printqueue(e->e_qgrp, e->e_qdir), 2864 DATAFL_LETTER, e->e_id); 2865 return response; 2866 } 2867 2868 /* send last body chunk */ 2869 if (bp > buf && 2870 m->mf_state != SMFS_ERROR && 2871 m->mf_state != SMFS_DONE && 2872 m->mf_state != SMFS_SKIP && 2873 *state == SMFIR_CONTINUE) 2874 { 2875 /* send chunk */ 2876 response = milter_send_command(m, SMFIC_BODY, buf, bp - buf, 2877 e, state, "last body chunk"); 2878 bp = buf; 2879 } 2880 if (MilterLogLevel > 17) 2881 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, sent", 2882 m->mf_name); 2883 if (m->mf_state == SMFS_SKIP) 2884 { 2885 *state = SMFIR_CONTINUE; 2886 m->mf_state = SMFS_READY; 2887 } 2888 2889 return response; 2890 } 2891 2892 /* 2893 ** Actions 2894 */ 2895 2896 /* 2897 ** ADDLEADINGSPACE -- Add a leading space to a string 2898 ** 2899 ** Parameters: 2900 ** str -- string 2901 ** rp -- resource pool for allocations 2902 ** 2903 ** Returns: 2904 ** pointer to new string 2905 */ 2906 2907 static char *addleadingspace __P((char *, SM_RPOOL_T *)); 2908 2909 static char * 2910 addleadingspace(str, rp) 2911 char *str; 2912 SM_RPOOL_T *rp; 2913 { 2914 size_t l; 2915 char *new; 2916 2917 SM_ASSERT(str != NULL); 2918 l = strlen(str); 2919 SM_ASSERT(l + 2 > l); 2920 new = sm_rpool_malloc_x(rp, l + 2); 2921 new[0] = ' '; 2922 new[1] = '\0'; 2923 sm_strlcpy(new + 1, str, l + 1); 2924 return new; 2925 } 2926 2927 /* 2928 ** MILTER_ADDHEADER -- Add the supplied header to the message 2929 ** 2930 ** Parameters: 2931 ** m -- current filter. 2932 ** response -- encoded form of header/value. 2933 ** rlen -- length of response. 2934 ** e -- current envelope. 2935 ** 2936 ** Returns: 2937 ** none 2938 */ 2939 2940 static void 2941 milter_addheader(m, response, rlen, e) 2942 struct milter *m; 2943 char *response; 2944 ssize_t rlen; 2945 ENVELOPE *e; 2946 { 2947 int mh_v_len; 2948 char *val, *mh_value; 2949 HDR *h; 2950 2951 if (tTd(64, 10)) 2952 sm_dprintf("milter_addheader: "); 2953 2954 /* sanity checks */ 2955 if (response == NULL) 2956 { 2957 if (tTd(64, 10)) 2958 sm_dprintf("NULL response\n"); 2959 return; 2960 } 2961 2962 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 2963 { 2964 if (tTd(64, 10)) 2965 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 2966 (int) strlen(response), (int) (rlen - 1)); 2967 return; 2968 } 2969 2970 /* Find separating NUL */ 2971 val = response + strlen(response) + 1; 2972 2973 /* another sanity check */ 2974 if (strlen(response) + strlen(val) + 2 != (size_t) rlen) 2975 { 2976 if (tTd(64, 10)) 2977 sm_dprintf("didn't follow protocol (part len)\n"); 2978 return; 2979 } 2980 2981 if (*response == '\0') 2982 { 2983 if (tTd(64, 10)) 2984 sm_dprintf("empty field name\n"); 2985 return; 2986 } 2987 2988 for (h = e->e_header; h != NULL; h = h->h_link) 2989 { 2990 if (SM_STRCASEEQ(h->h_field, response) && 2991 !bitset(H_USER, h->h_flags) && 2992 !bitset(H_TRACE, h->h_flags)) 2993 break; 2994 } 2995 2996 mh_v_len = 0; 2997 mh_value = quote_internal_chars(val, NULL, &mh_v_len, NULL); 2998 2999 /* add to e_msgsize */ 3000 e->e_msgsize += strlen(response) + 2 + strlen(val); 3001 3002 if (h != NULL) 3003 { 3004 if (tTd(64, 10)) 3005 sm_dprintf("Replace default header %s value with %s\n", 3006 h->h_field, mh_value); 3007 if (MilterLogLevel > 8) 3008 sm_syslog(LOG_INFO, e->e_id, 3009 "Milter (%s) change: default header %s value with %s", 3010 m->mf_name, h->h_field, mh_value); 3011 if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)) 3012 h->h_value = mh_value; /* XXX must be allocated from rpool? */ 3013 else 3014 { 3015 h->h_value = addleadingspace(mh_value, e->e_rpool); 3016 SM_FREE(mh_value); 3017 } 3018 h->h_flags |= H_USER; 3019 } 3020 else 3021 { 3022 if (tTd(64, 10)) 3023 sm_dprintf("Add %s: %s\n", response, mh_value); 3024 if (MilterLogLevel > 8) 3025 sm_syslog(LOG_INFO, e->e_id, 3026 "Milter (%s) add: header: %s: %s", 3027 m->mf_name, response, mh_value); 3028 addheader(newstr(response), mh_value, H_USER, e, 3029 !bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)); 3030 SM_FREE(mh_value); 3031 } 3032 } 3033 3034 /* 3035 ** MILTER_INSHEADER -- Insert the supplied header 3036 ** 3037 ** Parameters: 3038 ** m -- current filter. 3039 ** response -- encoded form of header/value. 3040 ** rlen -- length of response. 3041 ** e -- current envelope. 3042 ** 3043 ** Returns: 3044 ** none 3045 ** 3046 ** Notes: 3047 ** Unlike milter_addheader(), this does not attempt to determine 3048 ** if the header already exists in the envelope, even a 3049 ** deleted version. It just blindly inserts. 3050 */ 3051 3052 static void 3053 milter_insheader(m, response, rlen, e) 3054 struct milter *m; 3055 char *response; 3056 ssize_t rlen; 3057 ENVELOPE *e; 3058 { 3059 mi_int32 idx, i; 3060 int mh_v_len; 3061 char *field, *val, *mh_value; 3062 3063 if (tTd(64, 10)) 3064 sm_dprintf("milter_insheader: "); 3065 3066 /* sanity checks */ 3067 if (response == NULL) 3068 { 3069 if (tTd(64, 10)) 3070 sm_dprintf("NULL response\n"); 3071 return; 3072 } 3073 3074 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 3075 { 3076 if (tTd(64, 10)) 3077 sm_dprintf("didn't follow protocol (total len)\n"); 3078 return; 3079 } 3080 3081 /* decode */ 3082 (void) memcpy((char *) &i, response, MILTER_LEN_BYTES); 3083 idx = ntohl(i); 3084 field = response + MILTER_LEN_BYTES; 3085 val = field + strlen(field) + 1; 3086 3087 /* another sanity check */ 3088 if (MILTER_LEN_BYTES + strlen(field) + 1 + 3089 strlen(val) + 1 != (size_t) rlen) 3090 { 3091 if (tTd(64, 10)) 3092 sm_dprintf("didn't follow protocol (part len)\n"); 3093 return; 3094 } 3095 3096 if (*field == '\0') 3097 { 3098 if (tTd(64, 10)) 3099 sm_dprintf("empty field name\n"); 3100 return; 3101 } 3102 3103 /* add to e_msgsize */ 3104 e->e_msgsize += strlen(response) + 2 + strlen(val); 3105 3106 if (tTd(64, 10)) 3107 sm_dprintf("Insert (%d) %s: %s\n", idx, field, val); 3108 if (MilterLogLevel > 8) 3109 sm_syslog(LOG_INFO, e->e_id, 3110 "Milter (%s) insert (%d): header: %s: %s", 3111 m->mf_name, idx, field, val); 3112 mh_v_len = 0; 3113 mh_value = quote_internal_chars(val, NULL, &mh_v_len, NULL); 3114 insheader(idx, newstr(field), mh_value, H_USER, e, 3115 !bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)); 3116 SM_FREE(mh_value); 3117 } 3118 3119 /* 3120 ** MILTER_CHANGEHEADER -- Change the supplied header in the message 3121 ** 3122 ** Parameters: 3123 ** m -- current filter. 3124 ** response -- encoded form of header/index/value. 3125 ** rlen -- length of response. 3126 ** e -- current envelope. 3127 ** 3128 ** Returns: 3129 ** none 3130 */ 3131 3132 static void 3133 milter_changeheader(m, response, rlen, e) 3134 struct milter *m; 3135 char *response; 3136 ssize_t rlen; 3137 ENVELOPE *e; 3138 { 3139 mi_int32 i, index; 3140 int mh_v_len; 3141 char *field, *val, *mh_value; 3142 HDR *h, *sysheader; 3143 3144 if (tTd(64, 10)) 3145 sm_dprintf("milter_changeheader: "); 3146 3147 /* sanity checks */ 3148 if (response == NULL) 3149 { 3150 if (tTd(64, 10)) 3151 sm_dprintf("NULL response\n"); 3152 return; 3153 } 3154 3155 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 3156 { 3157 if (tTd(64, 10)) 3158 sm_dprintf("didn't follow protocol (total len)\n"); 3159 return; 3160 } 3161 3162 /* Find separating NUL */ 3163 (void) memcpy((char *) &i, response, MILTER_LEN_BYTES); 3164 index = ntohl(i); 3165 field = response + MILTER_LEN_BYTES; 3166 val = field + strlen(field) + 1; 3167 3168 /* another sanity check */ 3169 if (MILTER_LEN_BYTES + strlen(field) + 1 + 3170 strlen(val) + 1 != (size_t) rlen) 3171 { 3172 if (tTd(64, 10)) 3173 sm_dprintf("didn't follow protocol (part len)\n"); 3174 return; 3175 } 3176 3177 if (*field == '\0') 3178 { 3179 if (tTd(64, 10)) 3180 sm_dprintf("empty field name\n"); 3181 return; 3182 } 3183 3184 mh_v_len = 0; 3185 mh_value = quote_internal_chars(val, NULL, &mh_v_len, NULL); 3186 3187 sysheader = NULL; 3188 for (h = e->e_header; h != NULL; h = h->h_link) 3189 { 3190 if (SM_STRCASEEQ(h->h_field, field)) 3191 { 3192 if (bitset(H_USER, h->h_flags) && --index <= 0) 3193 { 3194 sysheader = NULL; 3195 break; 3196 } 3197 else if (!bitset(H_USER, h->h_flags) && 3198 !bitset(H_TRACE, h->h_flags)) 3199 { 3200 /* 3201 ** RFC 2822: 3202 ** 27. No multiple occurrences of fields 3203 ** (except resent and received).* 3204 ** so make sure we replace any non-trace, 3205 ** non-user field. 3206 */ 3207 3208 sysheader = h; 3209 } 3210 } 3211 } 3212 3213 /* if not found as user-provided header at index, use sysheader */ 3214 if (h == NULL) 3215 h = sysheader; 3216 3217 if (h == NULL) 3218 { 3219 if (*val == '\0') 3220 { 3221 if (tTd(64, 10)) 3222 sm_dprintf("Delete (noop) %s\n", field); 3223 if (MilterLogLevel > 8) 3224 sm_syslog(LOG_INFO, e->e_id, 3225 "Milter (%s) delete (noop): header: %s" 3226 , m->mf_name, field); 3227 } 3228 else 3229 { 3230 /* treat modify value with no existing header as add */ 3231 if (tTd(64, 10)) 3232 sm_dprintf("Add %s: %s\n", field, mh_value); 3233 if (MilterLogLevel > 8) 3234 sm_syslog(LOG_INFO, e->e_id, 3235 "Milter (%s) change (add): header: %s: %s" 3236 , m->mf_name, field, mh_value); 3237 addheader(newstr(field), mh_value, H_USER, e, 3238 !bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)); 3239 } 3240 SM_FREE(mh_value); 3241 return; 3242 } 3243 3244 if (tTd(64, 10)) 3245 { 3246 if (*val == '\0') 3247 { 3248 sm_dprintf("Delete%s %s:%s\n", 3249 h == sysheader ? " (default header)" : "", 3250 field, 3251 h->h_value == NULL ? "<NULL>" : h->h_value); 3252 } 3253 else 3254 { 3255 sm_dprintf("Change%s %s: from %s to %s\n", 3256 h == sysheader ? " (default header)" : "", 3257 field, 3258 h->h_value == NULL ? "<NULL>" : h->h_value, 3259 mh_value); 3260 } 3261 } 3262 3263 if (MilterLogLevel > 8) 3264 { 3265 if (*val == '\0') 3266 { 3267 sm_syslog(LOG_INFO, e->e_id, 3268 "Milter (%s) delete: header%s %s:%s", 3269 m->mf_name, 3270 h == sysheader ? " (default header)" : "", 3271 field, 3272 h->h_value == NULL ? "<NULL>" : h->h_value); 3273 } 3274 else 3275 { 3276 sm_syslog(LOG_INFO, e->e_id, 3277 "Milter (%s) change: header%s %s: from %s to %s", 3278 m->mf_name, 3279 h == sysheader ? " (default header)" : "", 3280 field, 3281 h->h_value == NULL ? "<NULL>" : h->h_value, 3282 mh_value); 3283 } 3284 } 3285 3286 if (h != sysheader && h->h_value != NULL) 3287 { 3288 size_t l; 3289 3290 l = strlen(h->h_value); 3291 if (l > e->e_msgsize) 3292 e->e_msgsize = 0; 3293 else 3294 e->e_msgsize -= l; 3295 /* rpool, don't free: sm_free(h->h_value); XXX */ 3296 } 3297 3298 if (*val == '\0') 3299 { 3300 /* Remove "Field: " from message size */ 3301 if (h != sysheader) 3302 { 3303 size_t l; 3304 3305 l = strlen(h->h_field) + 2; 3306 if (l > e->e_msgsize) 3307 e->e_msgsize = 0; 3308 else 3309 e->e_msgsize -= l; 3310 } 3311 h->h_value = NULL; 3312 SM_FREE(mh_value); 3313 } 3314 else 3315 { 3316 if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)) 3317 h->h_value = mh_value; /* XXX must be allocated from rpool? */ 3318 else 3319 { 3320 h->h_value = addleadingspace(mh_value, e->e_rpool); 3321 SM_FREE(mh_value); 3322 } 3323 h->h_flags |= H_USER; 3324 e->e_msgsize += strlen(h->h_value); 3325 } 3326 } 3327 3328 /* 3329 ** MILTER_SPLIT_RESPONSE -- Split response into fields. 3330 ** 3331 ** Parameters: 3332 ** response -- encoded repsonse. 3333 ** rlen -- length of response. 3334 ** pargc -- number of arguments (ouput) 3335 ** 3336 ** Returns: 3337 ** array of pointers to the individual strings 3338 */ 3339 3340 static char **milter_split_response __P((char *, ssize_t, int *)); 3341 3342 static char ** 3343 milter_split_response(response, rlen, pargc) 3344 char *response; 3345 ssize_t rlen; 3346 int *pargc; 3347 { 3348 char **s; 3349 size_t i; 3350 int elem, nelem; 3351 3352 SM_ASSERT(response != NULL); 3353 SM_ASSERT(pargc != NULL); 3354 *pargc = 0; 3355 if (rlen < 2 || strlen(response) >= (size_t) rlen) 3356 { 3357 if (tTd(64, 10)) 3358 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 3359 (int) strlen(response), (int) (rlen - 1)); 3360 return NULL; 3361 } 3362 3363 nelem = 0; 3364 for (i = 0; i < rlen; i++) 3365 { 3366 if (response[i] == '\0') 3367 ++nelem; 3368 } 3369 if (nelem == 0) 3370 return NULL; 3371 3372 /* last entry is only for the name */ 3373 s = (char **)malloc((nelem + 1) * (sizeof(*s))); 3374 if (s == NULL) 3375 return NULL; 3376 s[0] = response; 3377 for (i = 0, elem = 0; i < rlen && elem < nelem; i++) 3378 { 3379 if (response[i] == '\0') 3380 { 3381 ++elem; 3382 if (i + 1 >= rlen) 3383 s[elem] = NULL; 3384 else 3385 s[elem] = &(response[i + 1]); 3386 } 3387 } 3388 *pargc = nelem; 3389 3390 if (tTd(64, 10)) 3391 { 3392 for (elem = 0; elem < nelem; elem++) 3393 sm_dprintf("argv[%d]=\"%s\"\n", elem, s[elem]); 3394 } 3395 3396 /* overwrite last entry (already done above, just paranoia) */ 3397 s[elem] = NULL; 3398 return s; 3399 } 3400 3401 /* 3402 ** MILTER_CHGFROM -- Change the envelope sender address 3403 ** 3404 ** Parameters: 3405 ** response -- encoded form of recipient address. 3406 ** rlen -- length of response. 3407 ** e -- current envelope. 3408 ** mname -- name of milter. 3409 ** 3410 ** Returns: 3411 ** none 3412 */ 3413 3414 static void 3415 milter_chgfrom(response, rlen, e, mname) 3416 char *response; 3417 ssize_t rlen; 3418 ENVELOPE *e; 3419 const char *mname; 3420 { 3421 int olderrors, argc; 3422 char **argv; 3423 3424 if (tTd(64, 10)) 3425 sm_dprintf("milter_chgfrom: "); 3426 3427 /* sanity checks */ 3428 if (response == NULL) 3429 { 3430 if (tTd(64, 10)) 3431 sm_dprintf("NULL response\n"); 3432 return; 3433 } 3434 3435 if (*response == '\0' || 3436 strlen(response) + 1 > (size_t) rlen) 3437 { 3438 if (tTd(64, 10)) 3439 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 3440 (int) strlen(response), (int) (rlen - 1)); 3441 return; 3442 } 3443 3444 if (tTd(64, 10)) 3445 sm_dprintf("%s\n", response); 3446 if (MilterLogLevel > 8) 3447 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) chgfrom: %s", 3448 mname, response); 3449 argv = milter_split_response(response, rlen, &argc); 3450 if (argc < 1 || argc > 2) 3451 { 3452 if (tTd(64, 10)) 3453 sm_dprintf("didn't follow protocol argc=%d\n", argc); 3454 if (argv != NULL) 3455 free(argv); 3456 return; 3457 } 3458 3459 olderrors = Errors; 3460 setsender(argv[0], e, NULL, '\0', false); 3461 if (argc == 2) 3462 { 3463 reset_mail_esmtp_args(e); 3464 3465 /* 3466 ** need "features" here: how to get those? via e? 3467 ** "fake" it for now: allow everything. 3468 */ 3469 3470 parse_esmtp_args(e, NULL, argv[0], argv[1], "MAIL", NULL, 3471 mail_esmtp_args); 3472 } 3473 Errors = olderrors; 3474 free(argv); 3475 return; 3476 } 3477 3478 /* 3479 ** MILTER_ADDRCPT_PAR -- Add the supplied recipient to the message 3480 ** 3481 ** Parameters: 3482 ** response -- encoded form of recipient address. 3483 ** rlen -- length of response. 3484 ** e -- current envelope. 3485 ** mname -- name of milter. 3486 ** 3487 ** Returns: 3488 ** none 3489 */ 3490 3491 static void 3492 milter_addrcpt_par(response, rlen, e, mname) 3493 char *response; 3494 ssize_t rlen; 3495 ENVELOPE *e; 3496 const char *mname; 3497 { 3498 int olderrors, argc; 3499 char *delimptr; 3500 char **argv; 3501 ADDRESS *a; 3502 3503 if (tTd(64, 10)) 3504 sm_dprintf("milter_addrcpt_par: "); 3505 3506 /* sanity checks */ 3507 if (response == NULL) 3508 { 3509 if (tTd(64, 10)) 3510 sm_dprintf("NULL response\n"); 3511 return; 3512 } 3513 3514 if (tTd(64, 10)) 3515 sm_dprintf("%s\n", response); 3516 if (MilterLogLevel > 8) 3517 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) add: rcpt: %s", 3518 mname, response); 3519 3520 argv = milter_split_response(response, rlen, &argc); 3521 if (argc < 1 || argc > 2) 3522 { 3523 if (tTd(64, 10)) 3524 sm_dprintf("didn't follow protocol argc=%d\n", argc); 3525 if (argv != NULL) 3526 free(argv); 3527 return; 3528 } 3529 olderrors = Errors; 3530 3531 /* how to set ESMTP arguments? */ 3532 /* XXX argv[0] must be [i] */ 3533 a = parseaddr(argv[0], NULLADDR, RF_COPYALL, ' ', &delimptr, e, true); 3534 3535 if (a != NULL && olderrors == Errors) 3536 { 3537 parse_esmtp_args(e, a, argv[0], argv[1], "RCPT", NULL, 3538 rcpt_esmtp_args); 3539 if (olderrors == Errors) 3540 a = recipient(a, &e->e_sendqueue, 0, e); 3541 else 3542 sm_dprintf("olderrors=%d, Errors=%d\n", 3543 olderrors, Errors); 3544 } 3545 else 3546 { 3547 sm_dprintf("a=%p, olderrors=%d, Errors=%d\n", 3548 (void *)a, olderrors, Errors); 3549 } 3550 3551 Errors = olderrors; 3552 free(argv); 3553 return; 3554 } 3555 3556 /* 3557 ** MILTER_ADDRCPT -- Add the supplied recipient to the message 3558 ** 3559 ** Parameters: 3560 ** response -- encoded form of recipient address. 3561 ** rlen -- length of response. 3562 ** e -- current envelope. 3563 ** mname -- name of milter. 3564 ** 3565 ** Returns: 3566 ** none 3567 */ 3568 3569 static void 3570 milter_addrcpt(response, rlen, e, mname) 3571 char *response; 3572 ssize_t rlen; 3573 ENVELOPE *e; 3574 const char *mname; 3575 { 3576 int olderrors; 3577 3578 if (tTd(64, 10)) 3579 sm_dprintf("milter_addrcpt: "); 3580 3581 /* sanity checks */ 3582 if (response == NULL) 3583 { 3584 if (tTd(64, 10)) 3585 sm_dprintf("NULL response\n"); 3586 return; 3587 } 3588 3589 if (*response == '\0' || 3590 strlen(response) + 1 != (size_t) rlen) 3591 { 3592 if (tTd(64, 10)) 3593 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 3594 (int) strlen(response), (int) (rlen - 1)); 3595 return; 3596 } 3597 3598 if (tTd(64, 10)) 3599 sm_dprintf("%s\n", response); 3600 if (MilterLogLevel > 8) 3601 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) add: rcpt: %s", 3602 mname, response); 3603 olderrors = Errors; 3604 (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e); 3605 Errors = olderrors; 3606 return; 3607 } 3608 3609 /* 3610 ** MILTER_DELRCPT -- Delete the supplied recipient from the message 3611 ** 3612 ** Parameters: 3613 ** response -- encoded form of recipient address. 3614 ** rlen -- length of response. 3615 ** e -- current envelope. 3616 ** mname -- name of milter. 3617 ** 3618 ** Returns: 3619 ** none 3620 */ 3621 3622 static void 3623 milter_delrcpt(response, rlen, e, mname) 3624 char *response; 3625 ssize_t rlen; 3626 ENVELOPE *e; 3627 const char *mname; 3628 { 3629 int r; 3630 3631 if (tTd(64, 10)) 3632 sm_dprintf("milter_delrcpt: "); 3633 3634 /* sanity checks */ 3635 if (response == NULL) 3636 { 3637 if (tTd(64, 10)) 3638 sm_dprintf("NULL response\n"); 3639 return; 3640 } 3641 3642 if (*response == '\0' || 3643 strlen(response) + 1 != (size_t) rlen) 3644 { 3645 if (tTd(64, 10)) 3646 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 3647 (int) strlen(response), (int) (rlen - 1)); 3648 return; 3649 } 3650 3651 if (tTd(64, 10)) 3652 sm_dprintf("%s\n", response); 3653 r = removefromlist(response, &e->e_sendqueue, e); 3654 if (MilterLogLevel > 8) 3655 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) delete: rcpt %s, naddrs=%d", 3656 mname, response, r); 3657 return; 3658 } 3659 3660 /* 3661 ** MILTER_REPLBODY -- Replace the current data file with new body 3662 ** 3663 ** Parameters: 3664 ** response -- encoded form of new body. 3665 ** rlen -- length of response. 3666 ** newfilter -- if first time called by a new filter 3667 ** e -- current envelope. 3668 ** mname -- name of milter. 3669 ** 3670 ** Returns: 3671 ** 0 upon success, -1 upon failure 3672 */ 3673 3674 static int 3675 milter_replbody(response, rlen, newfilter, e, mname) 3676 char *response; 3677 ssize_t rlen; 3678 bool newfilter; 3679 ENVELOPE *e; 3680 const char *mname; 3681 { 3682 static char prevchar; 3683 int i; 3684 3685 if (tTd(64, 10)) 3686 sm_dprintf("milter_replbody\n"); 3687 3688 /* If a new filter, reset previous character and truncate data file */ 3689 if (newfilter) 3690 { 3691 off_t prevsize; 3692 char dfname[MAXPATHLEN]; 3693 3694 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), 3695 sizeof(dfname)); 3696 3697 /* Reset prevchar */ 3698 prevchar = '\0'; 3699 3700 /* Get the current data file information */ 3701 prevsize = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_SIZE, NULL); 3702 if (prevsize < 0) 3703 prevsize = 0; 3704 3705 /* truncate current data file */ 3706 if (sm_io_getinfo(e->e_dfp, SM_IO_WHAT_ISTYPE, BF_FILE_TYPE)) 3707 { 3708 if (sm_io_setinfo(e->e_dfp, SM_BF_TRUNCATE, NULL) < 0) 3709 { 3710 MILTER_DF_ERROR("milter_replbody: sm_io truncate %s: %s"); 3711 return -1; 3712 } 3713 } 3714 else 3715 { 3716 int err; 3717 3718 err = sm_io_error(e->e_dfp); 3719 (void) sm_io_flush(e->e_dfp, SM_TIME_DEFAULT); 3720 3721 /* 3722 ** Clear error if tried to fflush() 3723 ** a read-only file pointer and 3724 ** there wasn't a previous error. 3725 */ 3726 3727 if (err == 0) 3728 sm_io_clearerr(e->e_dfp); 3729 3730 /* errno is set implicitly by fseek() before return */ 3731 err = sm_io_seek(e->e_dfp, SM_TIME_DEFAULT, 3732 0, SEEK_SET); 3733 if (err < 0) 3734 { 3735 MILTER_DF_ERROR("milter_replbody: sm_io_seek %s: %s"); 3736 return -1; 3737 } 3738 # if NOFTRUNCATE 3739 /* XXX: Not much we can do except rewind it */ 3740 errno = EINVAL; 3741 MILTER_DF_ERROR("milter_replbody: ftruncate not available on this platform (%s:%s)"); 3742 return -1; 3743 # else /* NOFTRUNCATE */ 3744 err = ftruncate(sm_io_getinfo(e->e_dfp, 3745 SM_IO_WHAT_FD, NULL), 3746 0); 3747 if (err < 0) 3748 { 3749 MILTER_DF_ERROR("milter_replbody: sm_io ftruncate %s: %s"); 3750 return -1; 3751 } 3752 # endif /* NOFTRUNCATE */ 3753 } 3754 3755 if (prevsize > e->e_msgsize) 3756 e->e_msgsize = 0; 3757 else 3758 e->e_msgsize -= prevsize; 3759 } 3760 3761 if (newfilter && MilterLogLevel > 8) 3762 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) message: body replaced", 3763 mname); 3764 3765 if (response == NULL) 3766 { 3767 /* Flush the buffered '\r' */ 3768 if (prevchar == '\r') 3769 { 3770 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, prevchar); 3771 e->e_msgsize++; 3772 } 3773 return 0; 3774 } 3775 3776 for (i = 0; i < rlen; i++) 3777 { 3778 /* Buffered char from last chunk */ 3779 if (i == 0 && prevchar == '\r') 3780 { 3781 /* Not CRLF, output prevchar */ 3782 if (response[i] != '\n') 3783 { 3784 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, 3785 prevchar); 3786 e->e_msgsize++; 3787 } 3788 prevchar = '\0'; 3789 } 3790 3791 /* Turn CRLF into LF */ 3792 if (response[i] == '\r') 3793 { 3794 /* check if at end of chunk */ 3795 if (i + 1 < rlen) 3796 { 3797 /* If LF, strip CR */ 3798 if (response[i + 1] == '\n') 3799 i++; 3800 } 3801 else 3802 { 3803 /* check next chunk */ 3804 prevchar = '\r'; 3805 continue; 3806 } 3807 } 3808 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, response[i]); 3809 e->e_msgsize++; 3810 } 3811 return 0; 3812 } 3813 3814 /* 3815 ** MTA callouts 3816 */ 3817 3818 /* 3819 ** MILTER_INIT -- open and negotiate with all of the filters 3820 ** 3821 ** Parameters: 3822 ** e -- current envelope. 3823 ** state -- return state from response. 3824 ** milters -- milters structure. 3825 ** 3826 ** Returns: 3827 ** true iff at least one filter is active 3828 */ 3829 3830 /* ARGSUSED */ 3831 bool 3832 milter_init(e, state, milters) 3833 ENVELOPE *e; 3834 char *state; 3835 milters_T *milters; 3836 { 3837 int i; 3838 3839 if (tTd(64, 10)) 3840 sm_dprintf("milter_init\n"); 3841 3842 memset(milters, '\0', sizeof(*milters)); 3843 *state = SMFIR_CONTINUE; 3844 if (InputFilters[0] == NULL) 3845 { 3846 if (MilterLogLevel > 10) 3847 sm_syslog(LOG_INFO, e->e_id, 3848 "Milter: no active filter"); 3849 return false; 3850 } 3851 3852 for (i = 0; InputFilters[i] != NULL; i++) 3853 { 3854 struct milter *m = InputFilters[i]; 3855 3856 m->mf_sock = milter_open(m, false, e); 3857 if (m->mf_state == SMFS_ERROR) 3858 { 3859 MILTER_CHECK_ERROR(true, continue); 3860 break; 3861 } 3862 3863 if (m->mf_sock < 0 || 3864 milter_negotiate(m, e, milters) < 0 || 3865 m->mf_state == SMFS_ERROR) 3866 { 3867 if (tTd(64, 5)) 3868 sm_dprintf("milter_init(%s): failed to %s\n", 3869 m->mf_name, 3870 m->mf_sock < 0 ? "open" : 3871 "negotiate"); 3872 if (MilterLogLevel > 0) 3873 sm_syslog(LOG_ERR, e->e_id, 3874 "Milter (%s): init failed to %s", 3875 m->mf_name, 3876 m->mf_sock < 0 ? "open" : 3877 "negotiate"); 3878 3879 /* if negotiation failure, close socket */ 3880 milter_error(m, e); 3881 MILTER_CHECK_ERROR(true, continue); 3882 continue; 3883 } 3884 if (MilterLogLevel > 9) 3885 sm_syslog(LOG_INFO, e->e_id, 3886 "Milter (%s): init success to %s", 3887 m->mf_name, 3888 m->mf_sock < 0 ? "open" : "negotiate"); 3889 } 3890 3891 /* 3892 ** If something temp/perm failed with one of the filters, 3893 ** we won't be using any of them, so clear any existing 3894 ** connections. 3895 */ 3896 3897 if (*state != SMFIR_CONTINUE) 3898 milter_quit(e); 3899 3900 return true; 3901 } 3902 3903 /* 3904 ** MILTER_CONNECT -- send connection info to milter filters 3905 ** 3906 ** Parameters: 3907 ** hostname -- hostname of remote machine. 3908 ** addr -- address of remote machine. 3909 ** e -- current envelope. 3910 ** state -- return state from response. 3911 ** 3912 ** Returns: 3913 ** response string (may be NULL) 3914 */ 3915 3916 char * 3917 milter_connect(hostname, addr, e, state) 3918 char *hostname; 3919 SOCKADDR addr; 3920 ENVELOPE *e; 3921 char *state; 3922 { 3923 char family; 3924 unsigned short port; 3925 char *buf, *bp; 3926 char *response; 3927 char *sockinfo = NULL; 3928 ssize_t s; 3929 # if NETINET6 3930 char buf6[INET6_ADDRSTRLEN]; 3931 # endif 3932 3933 if (tTd(64, 10)) 3934 sm_dprintf("milter_connect(%s)\n", hostname); 3935 if (MilterLogLevel > 9) 3936 sm_syslog(LOG_INFO, e->e_id, "Milter: connect to filters"); 3937 3938 /* gather data */ 3939 switch (addr.sa.sa_family) 3940 { 3941 # if NETUNIX 3942 case AF_UNIX: 3943 family = SMFIA_UNIX; 3944 port = htons(0); 3945 sockinfo = addr.sunix.sun_path; 3946 break; 3947 # endif /* NETUNIX */ 3948 3949 # if NETINET 3950 case AF_INET: 3951 family = SMFIA_INET; 3952 port = addr.sin.sin_port; 3953 sockinfo = (char *) inet_ntoa(addr.sin.sin_addr); 3954 break; 3955 # endif /* NETINET */ 3956 3957 # if NETINET6 3958 case AF_INET6: 3959 if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr)) 3960 family = SMFIA_INET; 3961 else 3962 family = SMFIA_INET6; 3963 port = addr.sin6.sin6_port; 3964 sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6, 3965 sizeof(buf6)); 3966 if (sockinfo == NULL) 3967 sockinfo = ""; 3968 break; 3969 # endif /* NETINET6 */ 3970 3971 default: 3972 family = SMFIA_UNKNOWN; 3973 break; 3974 } 3975 3976 s = strlen(hostname) + 1 + sizeof(family); 3977 if (family != SMFIA_UNKNOWN) 3978 s += sizeof(port) + strlen(sockinfo) + 1; 3979 3980 buf = (char *) xalloc(s); 3981 bp = buf; 3982 3983 /* put together data */ 3984 (void) memcpy(bp, hostname, strlen(hostname)); 3985 bp += strlen(hostname); 3986 *bp++ = '\0'; 3987 (void) memcpy(bp, &family, sizeof(family)); 3988 bp += sizeof(family); 3989 if (family != SMFIA_UNKNOWN) 3990 { 3991 (void) memcpy(bp, &port, sizeof(port)); 3992 bp += sizeof(port); 3993 3994 /* include trailing '\0' */ 3995 (void) memcpy(bp, sockinfo, strlen(sockinfo) + 1); 3996 } 3997 3998 response = milter_command(SMFIC_CONNECT, buf, s, SMFIM_CONNECT, 3999 e, state, "connect", false); 4000 sm_free(buf); /* XXX */ 4001 4002 /* 4003 ** If this message connection is done for, 4004 ** close the filters. 4005 */ 4006 4007 if (*state != SMFIR_CONTINUE) 4008 { 4009 if (MilterLogLevel > 9) 4010 sm_syslog(LOG_INFO, e->e_id, "Milter: connect, ending"); 4011 milter_quit(e); 4012 } 4013 else 4014 milter_per_connection_check(e); 4015 4016 # if !_FFR_MILTER_CONNECT_REPLYCODE 4017 /* 4018 ** SMFIR_REPLYCODE can't work with connect due to 4019 ** the requirements of SMTP. Therefore, ignore the 4020 ** reply code text but keep the state it would reflect. 4021 */ 4022 4023 if (*state == SMFIR_REPLYCODE) 4024 { 4025 if (response != NULL && 4026 *response == '4') 4027 { 4028 if (strncmp(response, "421 ", 4) == 0) 4029 *state = SMFIR_SHUTDOWN; 4030 else 4031 *state = SMFIR_TEMPFAIL; 4032 } 4033 else 4034 *state = SMFIR_REJECT; 4035 if (response != NULL) 4036 { 4037 sm_free(response); /* XXX */ 4038 response = NULL; 4039 } 4040 } 4041 # endif /* !_FFR_MILTER_CONNECT_REPLYCODE */ 4042 return response; 4043 } 4044 4045 /* 4046 ** MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters 4047 ** 4048 ** Parameters: 4049 ** helo -- argument to SMTP HELO/EHLO command. 4050 ** e -- current envelope. 4051 ** state -- return state from response. 4052 ** 4053 ** Returns: 4054 ** response string (may be NULL) 4055 */ 4056 4057 char * 4058 milter_helo(helo, e, state) 4059 char *helo; 4060 ENVELOPE *e; 4061 char *state; 4062 { 4063 int i; 4064 char *response; 4065 4066 if (tTd(64, 10)) 4067 sm_dprintf("milter_helo(%s)\n", helo); 4068 4069 /* HELO/EHLO can come at any point */ 4070 for (i = 0; InputFilters[i] != NULL; i++) 4071 { 4072 struct milter *m = InputFilters[i]; 4073 4074 switch (m->mf_state) 4075 { 4076 case SMFS_INMSG: 4077 /* abort in message filters */ 4078 milter_abort_filter(m, e); 4079 /* FALLTHROUGH */ 4080 4081 case SMFS_DONE: 4082 /* reset done filters */ 4083 m->mf_state = SMFS_OPEN; 4084 break; 4085 } 4086 } 4087 4088 response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1, 4089 SMFIM_HELO, e, state, "helo", false); 4090 milter_per_connection_check(e); 4091 return response; 4092 } 4093 4094 /* 4095 ** MILTER_ENVFROM -- send SMTP MAIL command info to milter filters 4096 ** 4097 ** Parameters: 4098 ** args -- SMTP MAIL command args (args[0] == sender). 4099 ** e -- current envelope. 4100 ** state -- return state from response. 4101 ** 4102 ** Returns: 4103 ** response string (may be NULL) 4104 */ 4105 4106 char * 4107 milter_envfrom(args, e, state) 4108 char **args; 4109 ENVELOPE *e; 4110 char *state; 4111 { 4112 int i; 4113 char *buf, *bp; 4114 char *response; 4115 ssize_t s; 4116 4117 if (tTd(64, 10)) 4118 { 4119 sm_dprintf("milter_envfrom:"); 4120 for (i = 0; args[i] != NULL; i++) 4121 sm_dprintf(" %s", args[i]); 4122 sm_dprintf("\n"); 4123 } 4124 4125 /* sanity check */ 4126 if (args[0] == NULL) 4127 { 4128 *state = SMFIR_REJECT; 4129 if (MilterLogLevel > 10) 4130 sm_syslog(LOG_INFO, e->e_id, 4131 "Milter: reject, no sender"); 4132 return NULL; 4133 } 4134 4135 /* new message, so ... */ 4136 for (i = 0; InputFilters[i] != NULL; i++) 4137 { 4138 struct milter *m = InputFilters[i]; 4139 4140 switch (m->mf_state) 4141 { 4142 case SMFS_INMSG: 4143 /* abort in message filters */ 4144 milter_abort_filter(m, e); 4145 /* FALLTHROUGH */ 4146 4147 case SMFS_DONE: 4148 /* reset done filters */ 4149 m->mf_state = SMFS_OPEN; 4150 break; 4151 } 4152 } 4153 4154 /* put together data */ 4155 s = 0; 4156 for (i = 0; args[i] != NULL; i++) 4157 s += strlen(args[i]) + 1; 4158 4159 if (s < 0) 4160 { 4161 *state = SMFIR_TEMPFAIL; 4162 return NULL; 4163 } 4164 4165 buf = (char *) xalloc(s); 4166 bp = buf; 4167 for (i = 0; args[i] != NULL; i++) 4168 { 4169 (void) sm_strlcpy(bp, args[i], s - (bp - buf)); 4170 bp += strlen(bp) + 1; 4171 } 4172 4173 if (MilterLogLevel > 14) 4174 sm_syslog(LOG_INFO, e->e_id, "Milter: sender: %s", buf); 4175 4176 /* send it over */ 4177 response = milter_command(SMFIC_MAIL, buf, s, SMFIM_ENVFROM, 4178 e, state, "mail", false); 4179 sm_free(buf); /* XXX */ 4180 4181 /* 4182 ** If filter rejects/discards a per message command, 4183 ** abort the other filters since we are done with the 4184 ** current message. 4185 */ 4186 4187 MILTER_CHECK_DONE_MSG(); 4188 if (MilterLogLevel > 10 && *state == SMFIR_REJECT) 4189 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, sender"); 4190 return response; 4191 } 4192 4193 /* 4194 ** MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters 4195 ** 4196 ** Parameters: 4197 ** args -- SMTP RCPT command args (args[0] == recipient). 4198 ** e -- current envelope. 4199 ** state -- return state from response. 4200 ** rcpt_error -- does RCPT have an error? 4201 ** 4202 ** Returns: 4203 ** response string (may be NULL) 4204 */ 4205 4206 char * 4207 milter_envrcpt(args, e, state, rcpt_error) 4208 char **args; 4209 ENVELOPE *e; 4210 char *state; 4211 bool rcpt_error; 4212 { 4213 int i; 4214 char *buf, *bp; 4215 char *response; 4216 ssize_t s; 4217 4218 if (tTd(64, 10)) 4219 { 4220 sm_dprintf("milter_envrcpt:"); 4221 for (i = 0; args[i] != NULL; i++) 4222 sm_dprintf(" %s", args[i]); 4223 sm_dprintf("\n"); 4224 } 4225 4226 /* sanity check */ 4227 if (args[0] == NULL) 4228 { 4229 *state = SMFIR_REJECT; 4230 if (MilterLogLevel > 10) 4231 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, no rcpt"); 4232 return NULL; 4233 } 4234 4235 /* put together data */ 4236 s = 0; 4237 for (i = 0; args[i] != NULL; i++) 4238 s += strlen(args[i]) + 1; 4239 4240 if (s < 0) 4241 { 4242 *state = SMFIR_TEMPFAIL; 4243 return NULL; 4244 } 4245 4246 buf = (char *) xalloc(s); 4247 bp = buf; 4248 for (i = 0; args[i] != NULL; i++) 4249 { 4250 (void) sm_strlcpy(bp, args[i], s - (bp - buf)); 4251 bp += strlen(bp) + 1; 4252 } 4253 4254 if (MilterLogLevel > 14) 4255 sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf); 4256 4257 /* send it over */ 4258 response = milter_command(SMFIC_RCPT, buf, s, SMFIM_ENVRCPT, 4259 e, state, "rcpt", rcpt_error); 4260 sm_free(buf); /* XXX */ 4261 return response; 4262 } 4263 4264 /* 4265 ** MILTER_DATA_CMD -- send SMTP DATA command info to milter filters 4266 ** 4267 ** Parameters: 4268 ** e -- current envelope. 4269 ** state -- return state from response. 4270 ** 4271 ** Returns: 4272 ** response string (may be NULL) 4273 */ 4274 4275 char * 4276 milter_data_cmd(e, state) 4277 ENVELOPE *e; 4278 char *state; 4279 { 4280 if (tTd(64, 10)) 4281 sm_dprintf("milter_data_cmd\n"); 4282 4283 /* send it over */ 4284 return milter_command(SMFIC_DATA, NULL, 0, SMFIM_DATA, 4285 e, state, "data", false); 4286 } 4287 4288 /* 4289 ** MILTER_DATA -- send message headers/body and gather final message results 4290 ** 4291 ** Parameters: 4292 ** e -- current envelope. 4293 ** state -- return state from response. 4294 ** 4295 ** Returns: 4296 ** response string (may be NULL) 4297 ** 4298 ** Side effects: 4299 ** - Uses e->e_dfp for access to the body 4300 ** - Can call the various milter action routines to 4301 ** modify the envelope or message. 4302 */ 4303 4304 /* flow through code using continue; don't wrap in do {} while */ 4305 # define MILTER_CHECK_RESULTS() \ 4306 if (m->mf_state == SMFS_ERROR && *state == SMFIR_CONTINUE) \ 4307 { \ 4308 MILTER_SET_STATE; \ 4309 } \ 4310 if (*state == SMFIR_ACCEPT || \ 4311 m->mf_state == SMFS_DONE || \ 4312 m->mf_state == SMFS_ERROR) \ 4313 { \ 4314 if (m->mf_state != SMFS_ERROR) \ 4315 m->mf_state = SMFS_DONE; \ 4316 continue; /* to next filter */ \ 4317 } \ 4318 if (*state != SMFIR_CONTINUE) \ 4319 { \ 4320 m->mf_state = SMFS_DONE; \ 4321 goto finishup; \ 4322 } 4323 4324 char * 4325 milter_data(e, state) 4326 ENVELOPE *e; 4327 char *state; 4328 { 4329 bool replbody = false; /* milter_replbody() called? */ 4330 bool replfailed = false; /* milter_replbody() failed? */ 4331 bool rewind = false; /* rewind data file? */ 4332 bool dfopen = false; /* data file open for writing? */ 4333 bool newfilter; /* reset on each new filter */ 4334 char rcmd; 4335 int i; 4336 int save_errno; 4337 char *response = NULL; 4338 time_t eomsent; 4339 ssize_t rlen; 4340 4341 if (tTd(64, 10)) 4342 sm_dprintf("milter_data\n"); 4343 4344 *state = SMFIR_CONTINUE; 4345 4346 /* 4347 ** XXX: Should actually send body chunks to each filter 4348 ** a chunk at a time instead of sending the whole body to 4349 ** each filter in turn. However, only if the filters don't 4350 ** change the body. 4351 */ 4352 4353 for (i = 0; InputFilters[i] != NULL; i++) 4354 { 4355 int idx; 4356 char **macros; 4357 struct milter *m = InputFilters[i]; 4358 4359 if (*state != SMFIR_CONTINUE && 4360 *state != SMFIR_ACCEPT) 4361 { 4362 /* 4363 ** A previous filter has dealt with the message, 4364 ** safe to stop processing the filters. 4365 */ 4366 4367 break; 4368 } 4369 4370 /* Now reset state for later evaluation */ 4371 *state = SMFIR_CONTINUE; 4372 newfilter = true; 4373 4374 /* previous problem? */ 4375 if (m->mf_state == SMFS_ERROR) 4376 { 4377 MILTER_CHECK_ERROR(false, continue); 4378 break; 4379 } 4380 4381 /* sanity checks */ 4382 if (m->mf_sock < 0 || 4383 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) 4384 continue; 4385 4386 m->mf_state = SMFS_INMSG; 4387 4388 /* check if filter wants the headers */ 4389 if (!bitset(SMFIP_NOHDRS, m->mf_pflags)) 4390 { 4391 response = milter_headers(m, e, state); 4392 MILTER_CHECK_RESULTS(); 4393 } 4394 4395 /* check if filter wants EOH */ 4396 if (!bitset(SMFIP_NOEOH, m->mf_pflags)) 4397 { 4398 if (tTd(64, 10)) 4399 sm_dprintf("milter_data: eoh\n"); 4400 4401 if ((m->mf_lflags & MI_LFLAGS_SYM(SMFIM_EOH)) != 0) 4402 idx = m->mf_idx; 4403 else 4404 idx = 0; 4405 SM_ASSERT(idx >= 0 && idx <= MAXFILTERS); 4406 macros = MilterMacros[SMFIM_EOH][idx]; 4407 4408 if (macros != NULL) 4409 { 4410 milter_send_macros(m, macros, SMFIC_EOH, e); 4411 MILTER_CHECK_RESULTS(); 4412 } 4413 4414 /* send it over */ 4415 response = milter_send_command(m, SMFIC_EOH, NULL, 0, 4416 e, state, "eoh"); 4417 MILTER_CHECK_RESULTS(); 4418 } 4419 4420 /* check if filter wants the body */ 4421 if (!bitset(SMFIP_NOBODY, m->mf_pflags) && 4422 e->e_dfp != NULL) 4423 { 4424 rewind = true; 4425 response = milter_body(m, e, state); 4426 MILTER_CHECK_RESULTS(); 4427 } 4428 4429 if ((m->mf_lflags & MI_LFLAGS_SYM(SMFIM_EOH)) != 0) 4430 idx = m->mf_idx; 4431 else 4432 idx = 0; 4433 SM_ASSERT(idx >= 0 && idx <= MAXFILTERS); 4434 macros = MilterMacros[SMFIM_EOM][idx]; 4435 if (macros != NULL) 4436 { 4437 milter_send_macros(m, macros, SMFIC_BODYEOB, e); 4438 MILTER_CHECK_RESULTS(); 4439 } 4440 4441 /* send the final body chunk */ 4442 (void) milter_write(m, SMFIC_BODYEOB, NULL, 0, 4443 m->mf_timeout[SMFTO_WRITE], e, "eom"); 4444 4445 /* Get time EOM sent for timeout */ 4446 eomsent = curtime(); 4447 4448 /* deal with the possibility of multiple responses */ 4449 while (*state == SMFIR_CONTINUE) 4450 { 4451 /* Check total timeout from EOM to final ACK/NAK */ 4452 if (m->mf_timeout[SMFTO_EOM] > 0 && 4453 curtime() - eomsent >= m->mf_timeout[SMFTO_EOM]) 4454 { 4455 if (tTd(64, 5)) 4456 sm_dprintf("milter_data(%s): EOM ACK/NAK timeout\n", 4457 m->mf_name); 4458 if (MilterLogLevel > 0) 4459 sm_syslog(LOG_ERR, e->e_id, 4460 "milter_data(%s): EOM ACK/NAK timeout", 4461 m->mf_name); 4462 milter_error(m, e); 4463 MILTER_CHECK_ERROR(false, break); 4464 break; 4465 } 4466 4467 response = milter_read(m, &rcmd, &rlen, 4468 m->mf_timeout[SMFTO_READ], e, 4469 "eom"); 4470 if (m->mf_state == SMFS_ERROR) 4471 break; 4472 4473 if (tTd(64, 10)) 4474 sm_dprintf("milter_data(%s): state %c\n", 4475 m->mf_name, (char) rcmd); 4476 4477 switch (rcmd) 4478 { 4479 case SMFIR_REPLYCODE: 4480 MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected"); 4481 if (MilterLogLevel > 12) 4482 sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject=%s", 4483 m->mf_name, response); 4484 *state = rcmd; 4485 m->mf_state = SMFS_DONE; 4486 break; 4487 4488 case SMFIR_REJECT: /* log msg at end of function */ 4489 if (MilterLogLevel > 12) 4490 sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject", 4491 m->mf_name); 4492 *state = rcmd; 4493 m->mf_state = SMFS_DONE; 4494 break; 4495 4496 case SMFIR_DISCARD: 4497 if (MilterLogLevel > 12) 4498 sm_syslog(LOG_INFO, e->e_id, "milter=%s, discard", 4499 m->mf_name); 4500 *state = rcmd; 4501 m->mf_state = SMFS_DONE; 4502 break; 4503 4504 case SMFIR_TEMPFAIL: 4505 if (MilterLogLevel > 12) 4506 sm_syslog(LOG_INFO, e->e_id, "milter=%s, tempfail", 4507 m->mf_name); 4508 *state = rcmd; 4509 m->mf_state = SMFS_DONE; 4510 break; 4511 4512 case SMFIR_CONTINUE: 4513 case SMFIR_ACCEPT: 4514 /* this filter is done with message */ 4515 if (replfailed) 4516 *state = SMFIR_TEMPFAIL; 4517 else 4518 *state = SMFIR_ACCEPT; 4519 m->mf_state = SMFS_DONE; 4520 break; 4521 4522 case SMFIR_PROGRESS: 4523 break; 4524 4525 case SMFIR_QUARANTINE: 4526 if (!bitset(SMFIF_QUARANTINE, m->mf_fflags)) 4527 { 4528 if (MilterLogLevel > 9) 4529 sm_syslog(LOG_WARNING, e->e_id, 4530 "milter_data(%s): lied about quarantining, honoring request anyway", 4531 m->mf_name); 4532 } 4533 if (response == NULL) 4534 response = newstr(""); 4535 if (MilterLogLevel > 3) 4536 sm_syslog(LOG_INFO, e->e_id, 4537 "milter=%s, quarantine=%s", 4538 m->mf_name, response); 4539 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, 4540 response); 4541 macdefine(&e->e_macro, A_PERM, 4542 macid("{quarantine}"), e->e_quarmsg); 4543 break; 4544 4545 case SMFIR_ADDHEADER: 4546 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags)) 4547 { 4548 if (MilterLogLevel > 9) 4549 sm_syslog(LOG_WARNING, e->e_id, 4550 "milter_data(%s): lied about adding headers, honoring request anyway", 4551 m->mf_name); 4552 } 4553 milter_addheader(m, response, rlen, e); 4554 break; 4555 4556 case SMFIR_INSHEADER: 4557 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags)) 4558 { 4559 if (MilterLogLevel > 9) 4560 sm_syslog(LOG_WARNING, e->e_id, 4561 "milter_data(%s): lied about adding headers, honoring request anyway", 4562 m->mf_name); 4563 } 4564 milter_insheader(m, response, rlen, e); 4565 break; 4566 4567 case SMFIR_CHGHEADER: 4568 if (!bitset(SMFIF_CHGHDRS, m->mf_fflags)) 4569 { 4570 if (MilterLogLevel > 9) 4571 sm_syslog(LOG_WARNING, e->e_id, 4572 "milter_data(%s): lied about changing headers, honoring request anyway", 4573 m->mf_name); 4574 } 4575 milter_changeheader(m, response, rlen, e); 4576 break; 4577 4578 case SMFIR_CHGFROM: 4579 if (!bitset(SMFIF_CHGFROM, m->mf_fflags)) 4580 { 4581 if (MilterLogLevel > 9) 4582 sm_syslog(LOG_WARNING, e->e_id, 4583 "milter_data(%s) lied about changing sender, honoring request anyway", 4584 m->mf_name); 4585 } 4586 milter_chgfrom(response, rlen, e, m->mf_name); 4587 break; 4588 4589 case SMFIR_ADDRCPT: 4590 if (!bitset(SMFIF_ADDRCPT, m->mf_fflags)) 4591 { 4592 if (MilterLogLevel > 9) 4593 sm_syslog(LOG_WARNING, e->e_id, 4594 "milter_data(%s) lied about adding recipients, honoring request anyway", 4595 m->mf_name); 4596 } 4597 milter_addrcpt(response, rlen, e, m->mf_name); 4598 break; 4599 4600 case SMFIR_ADDRCPT_PAR: 4601 if (!bitset(SMFIF_ADDRCPT_PAR, m->mf_fflags)) 4602 { 4603 if (MilterLogLevel > 9) 4604 sm_syslog(LOG_WARNING, e->e_id, 4605 "milter_data(%s) lied about adding recipients with parameters, honoring request anyway", 4606 m->mf_name); 4607 } 4608 milter_addrcpt_par(response, rlen, e, m->mf_name); 4609 break; 4610 4611 case SMFIR_DELRCPT: 4612 if (!bitset(SMFIF_DELRCPT, m->mf_fflags)) 4613 { 4614 if (MilterLogLevel > 9) 4615 sm_syslog(LOG_WARNING, e->e_id, 4616 "milter_data(%s): lied about removing recipients, honoring request anyway", 4617 m->mf_name); 4618 } 4619 milter_delrcpt(response, rlen, e, m->mf_name); 4620 break; 4621 4622 case SMFIR_REPLBODY: 4623 if (!bitset(SMFIF_MODBODY, m->mf_fflags)) 4624 { 4625 if (MilterLogLevel > 0) 4626 sm_syslog(LOG_ERR, e->e_id, 4627 "milter_data(%s): lied about replacing body, rejecting request and tempfailing message", 4628 m->mf_name); 4629 replfailed = true; 4630 break; 4631 } 4632 4633 /* already failed in attempt */ 4634 if (replfailed) 4635 break; 4636 4637 if (!dfopen) 4638 { 4639 if (milter_reopen_df(e) < 0) 4640 { 4641 replfailed = true; 4642 break; 4643 } 4644 dfopen = true; 4645 rewind = true; 4646 } 4647 4648 if (milter_replbody(response, rlen, newfilter, 4649 e, m->mf_name) < 0) 4650 replfailed = true; 4651 newfilter = false; 4652 replbody = true; 4653 break; 4654 4655 default: 4656 /* Invalid response to command */ 4657 if (MilterLogLevel > 0) 4658 sm_syslog(LOG_ERR, e->e_id, 4659 "milter_data(%s): returned bogus response %c", 4660 m->mf_name, rcmd); 4661 milter_error(m, e); 4662 break; 4663 } 4664 if (rcmd != SMFIR_REPLYCODE && response != NULL) 4665 { 4666 sm_free(response); /* XXX */ 4667 response = NULL; 4668 } 4669 4670 if (m->mf_state == SMFS_ERROR) 4671 break; 4672 } 4673 4674 if (replbody && !replfailed) 4675 { 4676 /* flush possible buffered character */ 4677 milter_replbody(NULL, 0, !replbody, e, m->mf_name); 4678 replbody = false; 4679 } 4680 4681 if (m->mf_state == SMFS_ERROR) 4682 { 4683 MILTER_CHECK_ERROR(false, continue); 4684 goto finishup; 4685 } 4686 } 4687 4688 finishup: 4689 /* leave things in the expected state if we touched it */ 4690 if (replfailed) 4691 { 4692 if (*state == SMFIR_CONTINUE || 4693 *state == SMFIR_ACCEPT) 4694 { 4695 *state = SMFIR_TEMPFAIL; 4696 SM_FREE(response); 4697 } 4698 4699 if (dfopen) 4700 { 4701 SM_CLOSE_FP(e->e_dfp); 4702 e->e_flags &= ~EF_HAS_DF; 4703 dfopen = false; 4704 } 4705 rewind = false; 4706 } 4707 4708 if ((dfopen && milter_reset_df(e) < 0) || 4709 (rewind && bfrewind(e->e_dfp) < 0)) 4710 { 4711 save_errno = errno; 4712 ExitStat = EX_IOERR; 4713 4714 /* 4715 ** If filter told us to keep message but we had 4716 ** an error, we can't really keep it, tempfail it. 4717 */ 4718 4719 if (*state == SMFIR_CONTINUE || *state == SMFIR_ACCEPT) 4720 { 4721 *state = SMFIR_TEMPFAIL; 4722 SM_FREE(response); 4723 } 4724 4725 errno = save_errno; 4726 syserr("milter_data: %s/%cf%s: read error", 4727 qid_printqueue(e->e_qgrp, e->e_qdir), 4728 DATAFL_LETTER, e->e_id); 4729 } 4730 4731 MILTER_CHECK_DONE_MSG(); 4732 if (MilterLogLevel > 10 && *state == SMFIR_REJECT) 4733 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, data"); 4734 return response; 4735 } 4736 4737 /* 4738 ** MILTER_UNKNOWN -- send any unrecognized or unimplemented command 4739 ** string to milter filters 4740 ** 4741 ** Parameters: 4742 ** smtpcmd -- the string itself. 4743 ** e -- current envelope. 4744 ** state -- return state from response. 4745 ** 4746 ** 4747 ** Returns: 4748 ** response string (may be NULL) 4749 */ 4750 4751 char * 4752 milter_unknown(smtpcmd, e, state) 4753 char *smtpcmd; 4754 ENVELOPE *e; 4755 char *state; 4756 { 4757 if (tTd(64, 10)) 4758 sm_dprintf("milter_unknown(%s)\n", smtpcmd); 4759 4760 return milter_command(SMFIC_UNKNOWN, smtpcmd, strlen(smtpcmd) + 1, 4761 SMFIM_NOMACROS, e, state, "unknown", false); 4762 } 4763 4764 /* 4765 ** MILTER_QUIT -- informs the filter(s) we are done and closes connection(s) 4766 ** 4767 ** Parameters: 4768 ** e -- current envelope. 4769 ** 4770 ** Returns: 4771 ** none 4772 */ 4773 4774 void 4775 milter_quit(e) 4776 ENVELOPE *e; 4777 { 4778 int i; 4779 4780 if (tTd(64, 10)) 4781 sm_dprintf("milter_quit(%s)\n", e->e_id); 4782 4783 for (i = 0; InputFilters[i] != NULL; i++) 4784 milter_quit_filter(InputFilters[i], e); 4785 } 4786 4787 /* 4788 ** MILTER_ABORT -- informs the filter(s) that we are aborting current message 4789 ** 4790 ** Parameters: 4791 ** e -- current envelope. 4792 ** 4793 ** Returns: 4794 ** none 4795 */ 4796 4797 void 4798 milter_abort(e) 4799 ENVELOPE *e; 4800 { 4801 int i; 4802 4803 if (tTd(64, 10)) 4804 sm_dprintf("milter_abort\n"); 4805 4806 for (i = 0; InputFilters[i] != NULL; i++) 4807 { 4808 struct milter *m = InputFilters[i]; 4809 4810 /* sanity checks */ 4811 if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG) 4812 continue; 4813 4814 milter_abort_filter(m, e); 4815 } 4816 } 4817 #endif /* MILTER */ 4818