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