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