13#endif /* ! lint */ 14 15#if _FFR_MILTER 16 17# include <sendmail.h> 18# include <errno.h> 19# include <sys/time.h> 20 21# if NETINET || NETINET6 22# include <arpa/inet.h> 23# endif /* NETINET || NETINET6 */ 24 25# define SM_FD_SET FD_SET 26# define SM_FD_ISSET FD_ISSET 27# define SM_FD_SETSIZE FD_SETSIZE 28 29static void milter_connect_timeout __P((void)); 30static void milter_error __P((struct milter *)); 31static int milter_open __P((struct milter *, bool, ENVELOPE *)); 32static void milter_parse_timeouts __P((char *, struct milter *)); 33 34static char *MilterConnectMacros[MAXFILTERMACROS + 1]; 35static char *MilterHeloMacros[MAXFILTERMACROS + 1]; 36static char *MilterEnvFromMacros[MAXFILTERMACROS + 1]; 37static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1]; 38 39# define MILTER_CHECK_DONE_MSG() \ 40 if (*state == SMFIR_REPLYCODE || \ 41 *state == SMFIR_REJECT || \ 42 *state == SMFIR_DISCARD || \ 43 *state == SMFIR_TEMPFAIL) \ 44 { \ 45 /* Abort the filters to let them know we are done with msg */ \ 46 milter_abort(e); \ 47 } 48 49# define MILTER_CHECK_ERROR(action) \ 50 if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \ 51 *state = SMFIR_TEMPFAIL; \ 52 else if (bitnset(SMF_REJECT, m->mf_flags)) \ 53 *state = SMFIR_REJECT; \ 54 else \ 55 action; 56 57# define MILTER_CHECK_REPLYCODE(default) \ 58 if (response == NULL || \ 59 strlen(response) + 1 != (size_t) rlen || \ 60 rlen < 3 || \ 61 (response[0] != '4' && response[0] != '5') || \ 62 !isascii(response[1]) || !isdigit(response[1]) || \ 63 !isascii(response[2]) || !isdigit(response[2])) \ 64 { \ 65 if (response != NULL) \ 66 sm_free(response); \ 67 response = newstr(default); \ 68 } \ 69 else \ 70 { \ 71 char *ptr = response; \ 72 \ 73 /* Check for unprotected %'s in the string */ \ 74 while (*ptr != '\0') \ 75 { \ 76 if (*ptr == '%' && *++ptr != '%') \ 77 { \ 78 sm_free(response); \ 79 response = newstr(default); \ 80 break; \ 81 } \ 82 ptr++; \ 83 } \ 84 } 85 86# define MILTER_DF_ERROR(msg) \ 87{ \ 88 int save_errno = errno; \ 89 \ 90 if (tTd(64, 5)) \ 91 { \ 92 dprintf(msg, dfname, errstring(save_errno)); \ 93 dprintf("\n"); \ 94 } \ 95 if (LogLevel > 0) \ 96 sm_syslog(LOG_ERR, e->e_id, msg, dfname, errstring(save_errno)); \ 97 if (SuperSafe) \ 98 { \ 99 if (e->e_dfp != NULL) \ 100 { \ 101 (void) fclose(e->e_dfp); \ 102 e->e_dfp = NULL; \ 103 } \ 104 e->e_flags &= ~EF_HAS_DF; \ 105 } \ 106 errno = save_errno; \ 107} 108 109/* 110** MILTER_TIMEOUT -- make sure socket is ready in time 111** 112** Parameters: 113** routine -- routine name for debug/logging 114** secs -- number of seconds in timeout 115** write -- waiting to read or write? 116** 117** Assumes 'm' is a milter structure for the current socket. 118*/ 119 120# define MILTER_TIMEOUT(routine, secs, write) \ 121{ \ 122 int ret; \ 123 int save_errno; \ 124 fd_set fds; \ 125 struct timeval tv; \ 126 \ 127 if (SM_FD_SETSIZE != 0 && m->mf_sock >= SM_FD_SETSIZE) \ 128 { \ 129 if (tTd(64, 5)) \ 130 dprintf("%s(%s): socket %d is larger than FD_SETSIZE %d\n", \ 131 routine, m->mf_name, m->mf_sock, SM_FD_SETSIZE); \ 132 if (LogLevel > 0) \ 133 sm_syslog(LOG_ERR, e->e_id, \ 134 "%s(%s): socket %d is larger than FD_SETSIZE %d\n", \ 135 routine, m->mf_name, m->mf_sock, SM_FD_SETSIZE); \ 136 milter_error(m); \ 137 return NULL; \ 138 } \ 139 \ 140 FD_ZERO(&fds); \ 141 SM_FD_SET(m->mf_sock, &fds); \ 142 tv.tv_sec = secs; \ 143 tv.tv_usec = 0; \ 144 ret = select(m->mf_sock + 1, \ 145 write ? NULL : &fds, \ 146 write ? &fds : NULL, \ 147 NULL, &tv); \ 148 \ 149 switch (ret) \ 150 { \ 151 case 0: \ 152 if (tTd(64, 5)) \ 153 dprintf("%s(%s): timeout\n", routine, m->mf_name); \ 154 if (LogLevel > 0) \ 155 sm_syslog(LOG_ERR, e->e_id, "%s(%s): timeout\n", \ 156 routine, m->mf_name); \ 157 milter_error(m); \ 158 return NULL; \ 159 \ 160 case -1: \ 161 save_errno = errno; \ 162 if (tTd(64, 5)) \ 163 dprintf("%s(%s): select: %s\n", \ 164 routine, m->mf_name, errstring(save_errno)); \ 165 if (LogLevel > 0) \ 166 sm_syslog(LOG_ERR, e->e_id, \ 167 "%s(%s): select: %s\n", \ 168 routine, m->mf_name, errstring(save_errno)); \ 169 milter_error(m); \ 170 return NULL; \ 171 \ 172 default: \ 173 if (SM_FD_ISSET(m->mf_sock, &fds)) \ 174 break; \ 175 if (tTd(64, 5)) \ 176 dprintf("%s(%s): socket not ready\n", \ 177 routine, m->mf_name); \ 178 if (LogLevel > 0) \ 179 sm_syslog(LOG_ERR, e->e_id, \ 180 "%s(%s): socket not ready\n", \ 181 m->mf_name, routine); \ 182 milter_error(m); \ 183 return NULL; \ 184 } \ 185} 186 187/* 188** Low level functions 189*/ 190 191/* 192** MILTER_READ -- read from a remote milter filter 193** 194** Parameters: 195** m -- milter to read from. 196** cmd -- return param for command read. 197** rlen -- return length of response string. 198** to -- timeout in seconds. 199** e -- current envelope. 200** 201** Returns: 202** response string (may be NULL) 203*/ 204 205static char * 206milter_sysread(m, buf, sz, to, e) 207 struct milter *m; 208 char *buf; 209 ssize_t sz; 210 time_t to; 211 ENVELOPE *e; 212{ 213 time_t readstart = 0; 214 ssize_t len, curl; 215 216 curl = 0; 217 218 if (to > 0) 219 readstart = curtime(); 220 221 for (;;) 222 { 223 if (to > 0) 224 { 225 time_t now; 226 227 now = curtime(); 228 if (now - readstart >= to) 229 { 230 if (tTd(64, 5)) 231 dprintf("milter_read(%s): timeout before data read\n", 232 m->mf_name); 233 if (LogLevel > 0) 234 sm_syslog(LOG_ERR, e->e_id, 235 "milter_read(%s): timeout before data read\n", 236 m->mf_name); 237 milter_error(m); 238 return NULL; 239 } 240 to -= now - readstart; 241 readstart = now; 242 MILTER_TIMEOUT("milter_read", to, FALSE); 243 } 244 245 len = read(m->mf_sock, buf + curl, sz - curl); 246 247 if (len < 0) 248 { 249 int save_errno = errno; 250 251 if (tTd(64, 5)) 252 dprintf("milter_read(%s): read returned %ld: %s\n", 253 m->mf_name, (long) len, 254 errstring(save_errno)); 255 if (LogLevel > 0) 256 sm_syslog(LOG_ERR, e->e_id, 257 "milter_read(%s): read returned %ld: %s", 258 m->mf_name, (long) len, 259 errstring(save_errno)); 260 milter_error(m); 261 return NULL; 262 } 263 264 curl += len; 265 if (len == 0 || curl >= sz) 266 break; 267 268 } 269 270 if (curl != sz) 271 { 272 if (tTd(64, 5)) 273 dprintf("milter_read(%s): read returned %ld, expecting %ld\n", 274 m->mf_name, (long) curl, (long) sz); 275 if (LogLevel > 0) 276 sm_syslog(LOG_ERR, e->e_id, 277 "milter_read(%s): read returned %ld, expecting %ld", 278 m->mf_name, (long) curl, (long) sz); 279 milter_error(m); 280 return NULL; 281 } 282 return buf; 283} 284 285static char * 286milter_read(m, cmd, rlen, to, e) 287 struct milter *m; 288 char *cmd; 289 ssize_t *rlen; 290 time_t to; 291 ENVELOPE *e; 292{ 293 time_t readstart = 0; 294 ssize_t expl; 295 mi_int32 i; 296 char *buf; 297 char data[MILTER_LEN_BYTES + 1]; 298 299 *rlen = 0; 300 *cmd = '\0'; 301 302 if (to > 0) 303 readstart = curtime(); 304 305 if (milter_sysread(m, data, sizeof data, to, e) == NULL) 306 return NULL; 307 308 /* reset timeout */ 309 if (to > 0) 310 { 311 time_t now; 312 313 now = curtime(); 314 if (now - readstart >= to) 315 { 316 if (tTd(64, 5)) 317 dprintf("milter_read(%s): timeout before data read\n", 318 m->mf_name); 319 if (LogLevel > 0) 320 sm_syslog(LOG_ERR, e->e_id, 321 "milter_read(%s): timeout before data read\n", 322 m->mf_name); 323 milter_error(m); 324 return NULL; 325 } 326 to -= now - readstart; 327 } 328 329 *cmd = data[MILTER_LEN_BYTES]; 330 data[MILTER_LEN_BYTES] = '\0'; 331 (void) memcpy(&i, data, MILTER_LEN_BYTES); 332 expl = ntohl(i) - 1; 333 334 if (tTd(64, 25)) 335 dprintf("milter_read(%s): expecting %ld bytes\n", 336 m->mf_name, (long) expl); 337 338 if (expl < 0) 339 { 340 if (tTd(64, 5)) 341 dprintf("milter_read(%s): read size %ld out of range\n", 342 m->mf_name, (long) expl); 343 if (LogLevel > 0) 344 sm_syslog(LOG_ERR, e->e_id, 345 "milter_read(%s): read size %ld out of range", 346 m->mf_name, (long) expl); 347 milter_error(m); 348 return NULL; 349 } 350 351 if (expl == 0) 352 return NULL; 353 354 buf = (char *)xalloc(expl); 355 356 if (milter_sysread(m, buf, expl, to, e) == NULL) 357 { 358 sm_free(buf); 359 return NULL; 360 } 361 362 if (tTd(64, 50)) 363 dprintf("milter_read(%s): Returning %*s\n", 364 m->mf_name, (int) expl, buf); 365 *rlen = expl; 366 return buf; 367} 368/* 369** MILTER_WRITE -- write to a remote milter filter 370** 371** Parameters: 372** m -- milter to read from. 373** cmd -- command to send. 374** buf -- optional command data. 375** len -- length of buf. 376** to -- timeout in seconds. 377** e -- current envelope. 378** 379** Returns: 380** buf if successful, NULL otherwise 381** Not actually used anywhere but function prototype 382** must match milter_read() 383*/ 384 385static char * 386milter_write(m, cmd, buf, len, to, e) 387 struct milter *m; 388 char cmd; 389 char *buf; 390 ssize_t len; 391 time_t to; 392 ENVELOPE *e; 393{ 394 time_t writestart = (time_t) 0; 395 ssize_t sl, i; 396 mi_int32 nl; 397 char data[MILTER_LEN_BYTES + 1]; 398 399 if (len < 0 || len > MILTER_CHUNK_SIZE) 400 { 401 if (tTd(64, 5)) 402 dprintf("milter_write(%s): length %ld out of range\n", 403 m->mf_name, (long) len); 404 if (LogLevel > 0) 405 sm_syslog(LOG_ERR, e->e_id, 406 "milter_write(%s): length %ld out of range", 407 m->mf_name, (long) len); 408 milter_error(m); 409 return NULL; 410 } 411 412 if (tTd(64, 20)) 413 dprintf("milter_write(%s): cmd %c, len %ld\n", 414 m->mf_name, cmd, (long) len); 415 416 nl = htonl(len + 1); /* add 1 for the cmd char */ 417 (void) memcpy(data, (char *) &nl, MILTER_LEN_BYTES); 418 data[MILTER_LEN_BYTES] = cmd; 419 sl = MILTER_LEN_BYTES + 1; 420 421 if (to > 0) 422 { 423 writestart = curtime(); 424 MILTER_TIMEOUT("milter_write", to, TRUE); 425 } 426 427 /* use writev() instead to send the whole stuff at once? */ 428 i = write(m->mf_sock, (void *) data, sl); 429 if (i != sl) 430 { 431 int save_errno = errno; 432 433 if (tTd(64, 5)) 434 dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n", 435 m->mf_name, cmd, (long) i, (long) sl, 436 errstring(save_errno)); 437 if (LogLevel > 0) 438 sm_syslog(LOG_ERR, e->e_id, 439 "milter_write(%s): write(%c) returned %ld, expected %ld: %s", 440 m->mf_name, cmd, (long) i, (long) sl, 441 errstring(save_errno)); 442 milter_error(m); 443 return buf; 444 } 445 446 if (len <= 0 || buf == NULL) 447 return buf; 448 449 if (tTd(64, 50)) 450 dprintf("milter_write(%s): Sending %*s\n", 451 m->mf_name, (int) len, buf); 452 453 if (to > 0) 454 { 455 time_t now; 456 457 now = curtime(); 458 if (now - writestart >= to) 459 { 460 if (tTd(64, 5)) 461 dprintf("milter_write(%s): timeout before data send\n", 462 m->mf_name); 463 if (LogLevel > 0) 464 sm_syslog(LOG_ERR, e->e_id, 465 "milter_write(%s): timeout before data send\n", 466 m->mf_name); 467 milter_error(m); 468 return NULL; 469 } 470 else 471 { 472 to -= now - writestart; 473 MILTER_TIMEOUT("milter_write", to, TRUE); 474 } 475 } 476 477 i = write(m->mf_sock, (void *) buf, len); 478 if (i != len) 479 { 480 int save_errno = errno; 481 482 if (tTd(64, 5)) 483 dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n", 484 m->mf_name, cmd, (long) i, (long) sl, 485 errstring(save_errno)); 486 if (LogLevel > 0) 487 sm_syslog(LOG_ERR, e->e_id, 488 "milter_write(%s): write(%c) returned %ld, expected %ld: %s", 489 m->mf_name, cmd, (long) i, (long) len, 490 errstring(save_errno)); 491 milter_error(m); 492 return NULL; 493 } 494 return buf; 495} 496 497/* 498** Utility functions 499*/ 500 501/* 502** MILTER_OPEN -- connect to remote milter filter 503** 504** Parameters: 505** m -- milter to connect to. 506** parseonly -- parse but don't connect. 507** e -- current envelope. 508** 509** Returns: 510** connected socket if sucessful && !parseonly, 511** 0 upon parse success if parseonly, 512** -1 otherwise. 513*/ 514 515static jmp_buf MilterConnectTimeout; 516 517static int 518milter_open(m, parseonly, e) 519 struct milter *m; 520 bool parseonly; 521 ENVELOPE *e; 522{ 523 int sock = 0; 524 SOCKADDR_LEN_T addrlen = 0; 525 int addrno = 0; 526 int save_errno; 527 char *p; 528 char *colon; 529 char *at; 530 struct hostent *hp = NULL; 531 SOCKADDR addr; 532 533 if (m->mf_conn == NULL || m->mf_conn[0] == '\0') 534 { 535 if (tTd(64, 5)) 536 dprintf("X%s: empty or missing socket information\n", 537 m->mf_name); 538 if (parseonly) 539 syserr("X%s: empty or missing socket information", 540 m->mf_name); 541 else if (LogLevel > 10) 542 sm_syslog(LOG_ERR, e->e_id, 543 "X%s: empty or missing socket information", 544 m->mf_name); 545 milter_error(m); 546 return -1; 547 } 548 549 /* protocol:filename or protocol:port@host */ 550 p = m->mf_conn; 551 colon = strchr(p, ':'); 552 if (colon != NULL) 553 { 554 *colon = '\0'; 555 556 if (*p == '\0') 557 { 558# if NETUNIX 559 /* default to AF_UNIX */ 560 addr.sa.sa_family = AF_UNIX; 561# else /* NETUNIX */ 562# if NETINET 563 /* default to AF_INET */ 564 addr.sa.sa_family = AF_INET; 565# else /* NETINET */ 566# if NETINET6 567 /* default to AF_INET6 */ 568 addr.sa.sa_family = AF_INET6; 569# else /* NETINET6 */ 570 /* no protocols available */ 571 sm_syslog(LOG_ERR, e->e_id, 572 "X%s: no valid socket protocols available", 573 m->mf_name); 574 milter_error(m); 575 return -1; 576# endif /* NETINET6 */ 577# endif /* NETINET */ 578# endif /* NETUNIX */ 579 } 580# if NETUNIX 581 else if (strcasecmp(p, "unix") == 0 || 582 strcasecmp(p, "local") == 0) 583 addr.sa.sa_family = AF_UNIX; 584# endif /* NETUNIX */ 585# if NETINET 586 else if (strcasecmp(p, "inet") == 0) 587 addr.sa.sa_family = AF_INET; 588# endif /* NETINET */ 589# if NETINET6 590 else if (strcasecmp(p, "inet6") == 0) 591 addr.sa.sa_family = AF_INET6; 592# endif /* NETINET6 */ 593 else 594 { 595# ifdef EPROTONOSUPPORT 596 errno = EPROTONOSUPPORT; 597# else /* EPROTONOSUPPORT */ 598 errno = EINVAL; 599# endif /* EPROTONOSUPPORT */ 600 if (tTd(64, 5)) 601 dprintf("X%s: unknown socket type %s\n", 602 m->mf_name, p); 603 if (parseonly) 604 syserr("X%s: unknown socket type %s", 605 m->mf_name, p); 606 else if (LogLevel > 10) 607 sm_syslog(LOG_ERR, e->e_id, 608 "X%s: unknown socket type %s", 609 m->mf_name, p); 610 milter_error(m); 611 return -1; 612 } 613 *colon++ = ':'; 614 } 615 else 616 { 617 /* default to AF_UNIX */ 618 addr.sa.sa_family = AF_UNIX; 619 colon = p; 620 } 621 622# if NETUNIX 623 if (addr.sa.sa_family == AF_UNIX) 624 { 625 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK; 626 627 at = colon; 628 if (strlen(colon) >= sizeof addr.sunix.sun_path) 629 { 630 if (tTd(64, 5)) 631 dprintf("X%s: local socket name %s too long\n", 632 m->mf_name, colon); 633 errno = EINVAL; 634 if (parseonly) 635 syserr("X%s: local socket name %s too long", 636 m->mf_name, colon); 637 else if (LogLevel > 10) 638 sm_syslog(LOG_ERR, e->e_id, 639 "X%s: local socket name %s too long", 640 m->mf_name, colon); 641 milter_error(m); 642 return -1; 643 } 644 errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, 645 S_IRUSR|S_IWUSR, NULL); 646 647 /* if just parsing .cf file, socket doesn't need to exist */ 648 if (parseonly && errno == ENOENT) 649 { 650 if (OpMode == MD_DAEMON || 651 OpMode == MD_FGDAEMON) 652 fprintf(stderr, 653 "WARNING: X%s: local socket name %s missing\n", 654 m->mf_name, colon); 655 } 656 else if (errno != 0) 657 { 658 /* if not safe, don't create */ 659 save_errno = errno; 660 if (tTd(64, 5)) 661 dprintf("X%s: local socket name %s unsafe\n", 662 m->mf_name, colon); 663 errno = save_errno; 664 if (parseonly) 665 { 666 if (OpMode == MD_DAEMON || 667 OpMode == MD_FGDAEMON || 668 OpMode == MD_SMTP) 669 syserr("X%s: local socket name %s unsafe", 670 m->mf_name, colon); 671 } 672 else if (LogLevel > 10) 673 sm_syslog(LOG_ERR, e->e_id, 674 "X%s: local socket name %s unsafe", 675 m->mf_name, colon); 676 milter_error(m); 677 return -1; 678 } 679 680 (void) strlcpy(addr.sunix.sun_path, colon, 681 sizeof addr.sunix.sun_path); 682 addrlen = sizeof (struct sockaddr_un); 683 } 684 else 685# endif /* NETUNIX */ 686# if NETINET || NETINET6 687 if (FALSE 688# if NETINET 689 || addr.sa.sa_family == AF_INET 690# endif /* NETINET */ 691# if NETINET6 692 || addr.sa.sa_family == AF_INET6 693# endif /* NETINET6 */ 694 ) 695 { 696 u_short port; 697 698 /* Parse port@host */ 699 at = strchr(colon, '@'); 700 if (at == NULL) 701 { 702 if (tTd(64, 5)) 703 dprintf("X%s: bad address %s (expected port@host)\n", 704 m->mf_name, colon); 705 if (parseonly) 706 syserr("X%s: bad address %s (expected port@host)", 707 m->mf_name, colon); 708 else if (LogLevel > 10) 709 sm_syslog(LOG_ERR, e->e_id, 710 "X%s: bad address %s (expected port@host)", 711 m->mf_name, colon); 712 milter_error(m); 713 return -1; 714 } 715 *at = '\0'; 716 if (isascii(*colon) && isdigit(*colon)) 717 port = htons((u_short) atoi(colon)); 718 else 719 { 720# ifdef NO_GETSERVBYNAME 721 if (tTd(64, 5)) 722 dprintf("X%s: invalid port number %s\n", 723 m->mf_name, colon); 724 if (parseonly) 725 syserr("X%s: invalid port number %s", 726 m->mf_name, colon); 727 else if (LogLevel > 10) 728 sm_syslog(LOG_ERR, e->e_id, 729 "X%s: invalid port number %s", 730 m->mf_name, colon); 731 milter_error(m); 732 return -1; 733# else /* NO_GETSERVBYNAME */ 734 register struct servent *sp; 735 736 sp = getservbyname(colon, "tcp"); 737 if (sp == NULL) 738 { 739 save_errno = errno; 740 if (tTd(64, 5)) 741 dprintf("X%s: unknown port name %s\n", 742 m->mf_name, colon); 743 errno = save_errno; 744 if (parseonly) 745 syserr("X%s: unknown port name %s", 746 m->mf_name, colon); 747 else if (LogLevel > 10) 748 sm_syslog(LOG_ERR, e->e_id, 749 "X%s: unknown port name %s", 750 m->mf_name, colon); 751 milter_error(m); 752 return -1; 753 } 754 port = sp->s_port; 755# endif /* NO_GETSERVBYNAME */ 756 } 757 *at++ = '@'; 758 if (*at == '[') 759 { 760 char *end; 761 762 end = strchr(at, ']'); 763 if (end != NULL) 764 { 765 bool found = FALSE; 766# if NETINET 767 unsigned long hid = INADDR_NONE; 768# endif /* NETINET */ 769# if NETINET6 770 struct sockaddr_in6 hid6; 771# endif /* NETINET6 */ 772 773 *end = '\0'; 774# if NETINET 775 if (addr.sa.sa_family == AF_INET && 776 (hid = inet_addr(&at[1])) != INADDR_NONE) 777 { 778 addr.sin.sin_addr.s_addr = hid; 779 addr.sin.sin_port = port; 780 found = TRUE; 781 } 782# endif /* NETINET */ 783# if NETINET6 784 (void) memset(&hid6, '\0', sizeof hid6); 785 if (addr.sa.sa_family == AF_INET6 && 786 inet_pton(AF_INET6, &at[1], 787 &hid6.sin6_addr) == 1) 788 { 789 addr.sin6.sin6_addr = hid6.sin6_addr; 790 addr.sin6.sin6_port = port; 791 found = TRUE; 792 } 793# endif /* NETINET6 */ 794 *end = ']'; 795 if (!found) 796 { 797 if (tTd(64, 5)) 798 dprintf("X%s: Invalid numeric domain spec \"%s\"\n", 799 m->mf_name, at); 800 if (parseonly) 801 syserr("X%s: Invalid numeric domain spec \"%s\"", 802 m->mf_name, at); 803 else if (LogLevel > 10) 804 sm_syslog(LOG_ERR, e->e_id, 805 "X%s: Invalid numeric domain spec \"%s\"", 806 m->mf_name, at); 807 milter_error(m); 808 return -1; 809 } 810 } 811 else 812 { 813 if (tTd(64, 5)) 814 dprintf("X%s: Invalid numeric domain spec \"%s\"\n", 815 m->mf_name, at); 816 if (parseonly) 817 syserr("X%s: Invalid numeric domain spec \"%s\"", 818 m->mf_name, at); 819 else if (LogLevel > 10) 820 sm_syslog(LOG_ERR, e->e_id, 821 "X%s: Invalid numeric domain spec \"%s\"", 822 m->mf_name, at); 823 milter_error(m); 824 return -1; 825 } 826 } 827 else 828 { 829 hp = sm_gethostbyname(at, addr.sa.sa_family); 830 if (hp == NULL) 831 { 832 save_errno = errno; 833 if (tTd(64, 5)) 834 dprintf("X%s: Unknown host name %s\n", 835 m->mf_name, at); 836 errno = save_errno; 837 if (parseonly) 838 syserr("X%s: Unknown host name %s", 839 m->mf_name, at); 840 else if (LogLevel > 10) 841 sm_syslog(LOG_ERR, e->e_id, 842 "X%s: Unknown host name %s", 843 m->mf_name, at); 844 milter_error(m); 845 return -1; 846 } 847 addr.sa.sa_family = hp->h_addrtype; 848 switch (hp->h_addrtype) 849 { 850# if NETINET 851 case AF_INET: 852 memmove(&addr.sin.sin_addr, 853 hp->h_addr, 854 INADDRSZ); 855 addr.sin.sin_port = port; 856 addrlen = sizeof (struct sockaddr_in); 857 addrno = 1; 858 break; 859# endif /* NETINET */ 860 861# if NETINET6 862 case AF_INET6: 863 memmove(&addr.sin6.sin6_addr, 864 hp->h_addr, 865 IN6ADDRSZ); 866 addr.sin6.sin6_port = port; 867 addrlen = sizeof (struct sockaddr_in6); 868 addrno = 1; 869 break; 870# endif /* NETINET6 */ 871 872 default: 873 if (tTd(64, 5)) 874 dprintf("X%s: Unknown protocol for %s (%d)\n", 875 m->mf_name, at, 876 hp->h_addrtype); 877 if (parseonly) 878 syserr("X%s: Unknown protocol for %s (%d)", 879 m->mf_name, at, hp->h_addrtype); 880 else if (LogLevel > 10) 881 sm_syslog(LOG_ERR, e->e_id, 882 "X%s: Unknown protocol for %s (%d)", 883 m->mf_name, at, 884 hp->h_addrtype); 885 milter_error(m); 886# if _FFR_FREEHOSTENT && NETINET6 887 freehostent(hp); 888# endif /* _FFR_FREEHOSTENT && NETINET6 */ 889 return -1; 890 } 891 } 892 } 893 else 894# endif /* NETINET || NETINET6 */ 895 { 896 if (tTd(64, 5)) 897 dprintf("X%s: unknown socket protocol\n", m->mf_name); 898 if (parseonly) 899 syserr("X%s: unknown socket protocol", m->mf_name); 900 else if (LogLevel > 10) 901 sm_syslog(LOG_ERR, e->e_id, 902 "X%s: unknown socket protocol", m->mf_name); 903 milter_error(m); 904 return -1; 905 } 906 907 /* just parsing through? */ 908 if (parseonly) 909 { 910 m->mf_state = SMFS_READY; 911# if _FFR_FREEHOSTENT && NETINET6 912 if (hp != NULL) 913 freehostent(hp); 914# endif /* _FFR_FREEHOSTENT && NETINET6 */ 915 return 0; 916 } 917 918 /* sanity check */ 919 if (m->mf_state != SMFS_READY && 920 m->mf_state != SMFS_CLOSED) 921 { 922 /* shouldn't happen */ 923 if (tTd(64, 1)) 924 dprintf("milter_open(%s): Trying to open filter in state %c\n", 925 m->mf_name, (char) m->mf_state); 926 milter_error(m); 927# if _FFR_FREEHOSTENT && NETINET6 928 if (hp != NULL) 929 freehostent(hp); 930# endif /* _FFR_FREEHOSTENT && NETINET6 */ 931 return -1; 932 } 933 934 /* nope, actually connecting */ 935 for (;;) 936 { 937 sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); 938 if (sock < 0) 939 { 940 save_errno = errno; 941 if (tTd(64, 5)) 942 dprintf("X%s: error creating socket: %s\n", 943 m->mf_name, errstring(save_errno)); 944 if (LogLevel > 0) 945 sm_syslog(LOG_ERR, e->e_id, 946 "X%s: error creating socket: %s", 947 m->mf_name, errstring(save_errno)); 948 milter_error(m); 949# if _FFR_FREEHOSTENT && NETINET6 950 if (hp != NULL) 951 freehostent(hp); 952# endif /* _FFR_FREEHOSTENT && NETINET6 */ 953 return -1; 954 } 955 956 if (setjmp(MilterConnectTimeout) == 0) 957 { 958 EVENT *ev = NULL; 959 int i; 960 961 if (m->mf_timeout[SMFTO_CONNECT] > 0) 962 ev = setevent(m->mf_timeout[SMFTO_CONNECT], 963 milter_connect_timeout, 0); 964 965 i = connect(sock, (struct sockaddr *) &addr, addrlen); 966 save_errno = errno; 967 if (ev != NULL) 968 clrevent(ev); 969 errno = save_errno; 970 if (i >= 0) 971 break; 972 } 973 974 /* couldn't connect.... try next address */ 975 save_errno = errno; 976 p = CurHostName; 977 CurHostName = at; 978 if (tTd(64, 5)) 979 dprintf("milter_open(%s): %s failed: %s\n", 980 m->mf_name, at, errstring(save_errno)); 981 if (LogLevel >= 14) 982 sm_syslog(LOG_INFO, e->e_id, 983 "milter_open(%s): %s failed: %s", 984 m->mf_name, at, errstring(save_errno)); 985 CurHostName = p; 986 (void) close(sock); 987 988 /* try next address */ 989 if (hp != NULL && hp->h_addr_list[addrno] != NULL) 990 { 991 switch (addr.sa.sa_family) 992 { 993# if NETINET 994 case AF_INET: 995 memmove(&addr.sin.sin_addr, 996 hp->h_addr_list[addrno++], 997 INADDRSZ); 998 break; 999# endif /* NETINET */ 1000 1001# if NETINET6 1002 case AF_INET6: 1003 memmove(&addr.sin6.sin6_addr, 1004 hp->h_addr_list[addrno++], 1005 IN6ADDRSZ); 1006 break; 1007# endif /* NETINET6 */ 1008 1009 default: 1010 if (tTd(64, 5)) 1011 dprintf("X%s: Unknown protocol for %s (%d)\n", 1012 m->mf_name, at, 1013 hp->h_addrtype); 1014 if (LogLevel > 0) 1015 sm_syslog(LOG_ERR, e->e_id, 1016 "X%s: Unknown protocol for %s (%d)", 1017 m->mf_name, at, 1018 hp->h_addrtype); 1019 milter_error(m); 1020# if _FFR_FREEHOSTENT && NETINET6 1021 freehostent(hp); 1022# endif /* _FFR_FREEHOSTENT && NETINET6 */ 1023 return -1; 1024 } 1025 continue; 1026 } 1027 p = CurHostName; 1028 CurHostName = at; 1029 if (tTd(64, 5)) 1030 dprintf("X%s: error connecting to filter: %s\n", 1031 m->mf_name, errstring(save_errno)); 1032 if (LogLevel > 0) 1033 sm_syslog(LOG_ERR, e->e_id, 1034 "X%s: error connecting to filter: %s", 1035 m->mf_name, errstring(save_errno)); 1036 CurHostName = p; 1037 milter_error(m); 1038# if _FFR_FREEHOSTENT && NETINET6 1039 if (hp != NULL) 1040 freehostent(hp); 1041# endif /* _FFR_FREEHOSTENT && NETINET6 */ 1042 return -1; 1043 } 1044 m->mf_state = SMFS_OPEN; 1045# if _FFR_FREEHOSTENT && NETINET6 1046 if (hp != NULL) 1047 { 1048 freehostent(hp); 1049 hp = NULL; 1050 } 1051# endif /* _FFR_FREEHOSTENT && NETINET6 */ 1052 return sock; 1053} 1054 1055static void 1056milter_connect_timeout() 1057{ 1058 /* 1059 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 1060 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 1061 ** DOING. 1062 */ 1063 1064 errno = ETIMEDOUT; 1065 longjmp(MilterConnectTimeout, 1); 1066} 1067/* 1068** MILTER_SETUP -- setup structure for a mail filter 1069** 1070** Parameters: 1071** line -- the options line. 1072** 1073** Returns: 1074** none 1075*/ 1076 1077void 1078milter_setup(line) 1079 char *line; 1080{ 1081 char fcode; 1082 register char *p; 1083 register struct milter *m; 1084 STAB *s; 1085 1086 /* collect the filter name */ 1087 for (p = line; 1088 *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); 1089 p++) 1090 continue; 1091 if (*p != '\0') 1092 *p++ = '\0'; 1093 if (line[0] == '\0') 1094 { 1095 syserr("name required for mail filter"); 1096 return; 1097 } 1098 m = (struct milter *)xalloc(sizeof *m); 1099 memset((char *) m, '\0', sizeof *m); 1100 m->mf_name = newstr(line); 1101 m->mf_state = SMFS_READY; 1102 m->mf_sock = -1;
| 13#endif /* ! lint */ 14 15#if _FFR_MILTER 16 17# include <sendmail.h> 18# include <errno.h> 19# include <sys/time.h> 20 21# if NETINET || NETINET6 22# include <arpa/inet.h> 23# endif /* NETINET || NETINET6 */ 24 25# define SM_FD_SET FD_SET 26# define SM_FD_ISSET FD_ISSET 27# define SM_FD_SETSIZE FD_SETSIZE 28 29static void milter_connect_timeout __P((void)); 30static void milter_error __P((struct milter *)); 31static int milter_open __P((struct milter *, bool, ENVELOPE *)); 32static void milter_parse_timeouts __P((char *, struct milter *)); 33 34static char *MilterConnectMacros[MAXFILTERMACROS + 1]; 35static char *MilterHeloMacros[MAXFILTERMACROS + 1]; 36static char *MilterEnvFromMacros[MAXFILTERMACROS + 1]; 37static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1]; 38 39# define MILTER_CHECK_DONE_MSG() \ 40 if (*state == SMFIR_REPLYCODE || \ 41 *state == SMFIR_REJECT || \ 42 *state == SMFIR_DISCARD || \ 43 *state == SMFIR_TEMPFAIL) \ 44 { \ 45 /* Abort the filters to let them know we are done with msg */ \ 46 milter_abort(e); \ 47 } 48 49# define MILTER_CHECK_ERROR(action) \ 50 if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \ 51 *state = SMFIR_TEMPFAIL; \ 52 else if (bitnset(SMF_REJECT, m->mf_flags)) \ 53 *state = SMFIR_REJECT; \ 54 else \ 55 action; 56 57# define MILTER_CHECK_REPLYCODE(default) \ 58 if (response == NULL || \ 59 strlen(response) + 1 != (size_t) rlen || \ 60 rlen < 3 || \ 61 (response[0] != '4' && response[0] != '5') || \ 62 !isascii(response[1]) || !isdigit(response[1]) || \ 63 !isascii(response[2]) || !isdigit(response[2])) \ 64 { \ 65 if (response != NULL) \ 66 sm_free(response); \ 67 response = newstr(default); \ 68 } \ 69 else \ 70 { \ 71 char *ptr = response; \ 72 \ 73 /* Check for unprotected %'s in the string */ \ 74 while (*ptr != '\0') \ 75 { \ 76 if (*ptr == '%' && *++ptr != '%') \ 77 { \ 78 sm_free(response); \ 79 response = newstr(default); \ 80 break; \ 81 } \ 82 ptr++; \ 83 } \ 84 } 85 86# define MILTER_DF_ERROR(msg) \ 87{ \ 88 int save_errno = errno; \ 89 \ 90 if (tTd(64, 5)) \ 91 { \ 92 dprintf(msg, dfname, errstring(save_errno)); \ 93 dprintf("\n"); \ 94 } \ 95 if (LogLevel > 0) \ 96 sm_syslog(LOG_ERR, e->e_id, msg, dfname, errstring(save_errno)); \ 97 if (SuperSafe) \ 98 { \ 99 if (e->e_dfp != NULL) \ 100 { \ 101 (void) fclose(e->e_dfp); \ 102 e->e_dfp = NULL; \ 103 } \ 104 e->e_flags &= ~EF_HAS_DF; \ 105 } \ 106 errno = save_errno; \ 107} 108 109/* 110** MILTER_TIMEOUT -- make sure socket is ready in time 111** 112** Parameters: 113** routine -- routine name for debug/logging 114** secs -- number of seconds in timeout 115** write -- waiting to read or write? 116** 117** Assumes 'm' is a milter structure for the current socket. 118*/ 119 120# define MILTER_TIMEOUT(routine, secs, write) \ 121{ \ 122 int ret; \ 123 int save_errno; \ 124 fd_set fds; \ 125 struct timeval tv; \ 126 \ 127 if (SM_FD_SETSIZE != 0 && m->mf_sock >= SM_FD_SETSIZE) \ 128 { \ 129 if (tTd(64, 5)) \ 130 dprintf("%s(%s): socket %d is larger than FD_SETSIZE %d\n", \ 131 routine, m->mf_name, m->mf_sock, SM_FD_SETSIZE); \ 132 if (LogLevel > 0) \ 133 sm_syslog(LOG_ERR, e->e_id, \ 134 "%s(%s): socket %d is larger than FD_SETSIZE %d\n", \ 135 routine, m->mf_name, m->mf_sock, SM_FD_SETSIZE); \ 136 milter_error(m); \ 137 return NULL; \ 138 } \ 139 \ 140 FD_ZERO(&fds); \ 141 SM_FD_SET(m->mf_sock, &fds); \ 142 tv.tv_sec = secs; \ 143 tv.tv_usec = 0; \ 144 ret = select(m->mf_sock + 1, \ 145 write ? NULL : &fds, \ 146 write ? &fds : NULL, \ 147 NULL, &tv); \ 148 \ 149 switch (ret) \ 150 { \ 151 case 0: \ 152 if (tTd(64, 5)) \ 153 dprintf("%s(%s): timeout\n", routine, m->mf_name); \ 154 if (LogLevel > 0) \ 155 sm_syslog(LOG_ERR, e->e_id, "%s(%s): timeout\n", \ 156 routine, m->mf_name); \ 157 milter_error(m); \ 158 return NULL; \ 159 \ 160 case -1: \ 161 save_errno = errno; \ 162 if (tTd(64, 5)) \ 163 dprintf("%s(%s): select: %s\n", \ 164 routine, m->mf_name, errstring(save_errno)); \ 165 if (LogLevel > 0) \ 166 sm_syslog(LOG_ERR, e->e_id, \ 167 "%s(%s): select: %s\n", \ 168 routine, m->mf_name, errstring(save_errno)); \ 169 milter_error(m); \ 170 return NULL; \ 171 \ 172 default: \ 173 if (SM_FD_ISSET(m->mf_sock, &fds)) \ 174 break; \ 175 if (tTd(64, 5)) \ 176 dprintf("%s(%s): socket not ready\n", \ 177 routine, m->mf_name); \ 178 if (LogLevel > 0) \ 179 sm_syslog(LOG_ERR, e->e_id, \ 180 "%s(%s): socket not ready\n", \ 181 m->mf_name, routine); \ 182 milter_error(m); \ 183 return NULL; \ 184 } \ 185} 186 187/* 188** Low level functions 189*/ 190 191/* 192** MILTER_READ -- read from a remote milter filter 193** 194** Parameters: 195** m -- milter to read from. 196** cmd -- return param for command read. 197** rlen -- return length of response string. 198** to -- timeout in seconds. 199** e -- current envelope. 200** 201** Returns: 202** response string (may be NULL) 203*/ 204 205static char * 206milter_sysread(m, buf, sz, to, e) 207 struct milter *m; 208 char *buf; 209 ssize_t sz; 210 time_t to; 211 ENVELOPE *e; 212{ 213 time_t readstart = 0; 214 ssize_t len, curl; 215 216 curl = 0; 217 218 if (to > 0) 219 readstart = curtime(); 220 221 for (;;) 222 { 223 if (to > 0) 224 { 225 time_t now; 226 227 now = curtime(); 228 if (now - readstart >= to) 229 { 230 if (tTd(64, 5)) 231 dprintf("milter_read(%s): timeout before data read\n", 232 m->mf_name); 233 if (LogLevel > 0) 234 sm_syslog(LOG_ERR, e->e_id, 235 "milter_read(%s): timeout before data read\n", 236 m->mf_name); 237 milter_error(m); 238 return NULL; 239 } 240 to -= now - readstart; 241 readstart = now; 242 MILTER_TIMEOUT("milter_read", to, FALSE); 243 } 244 245 len = read(m->mf_sock, buf + curl, sz - curl); 246 247 if (len < 0) 248 { 249 int save_errno = errno; 250 251 if (tTd(64, 5)) 252 dprintf("milter_read(%s): read returned %ld: %s\n", 253 m->mf_name, (long) len, 254 errstring(save_errno)); 255 if (LogLevel > 0) 256 sm_syslog(LOG_ERR, e->e_id, 257 "milter_read(%s): read returned %ld: %s", 258 m->mf_name, (long) len, 259 errstring(save_errno)); 260 milter_error(m); 261 return NULL; 262 } 263 264 curl += len; 265 if (len == 0 || curl >= sz) 266 break; 267 268 } 269 270 if (curl != sz) 271 { 272 if (tTd(64, 5)) 273 dprintf("milter_read(%s): read returned %ld, expecting %ld\n", 274 m->mf_name, (long) curl, (long) sz); 275 if (LogLevel > 0) 276 sm_syslog(LOG_ERR, e->e_id, 277 "milter_read(%s): read returned %ld, expecting %ld", 278 m->mf_name, (long) curl, (long) sz); 279 milter_error(m); 280 return NULL; 281 } 282 return buf; 283} 284 285static char * 286milter_read(m, cmd, rlen, to, e) 287 struct milter *m; 288 char *cmd; 289 ssize_t *rlen; 290 time_t to; 291 ENVELOPE *e; 292{ 293 time_t readstart = 0; 294 ssize_t expl; 295 mi_int32 i; 296 char *buf; 297 char data[MILTER_LEN_BYTES + 1]; 298 299 *rlen = 0; 300 *cmd = '\0'; 301 302 if (to > 0) 303 readstart = curtime(); 304 305 if (milter_sysread(m, data, sizeof data, to, e) == NULL) 306 return NULL; 307 308 /* reset timeout */ 309 if (to > 0) 310 { 311 time_t now; 312 313 now = curtime(); 314 if (now - readstart >= to) 315 { 316 if (tTd(64, 5)) 317 dprintf("milter_read(%s): timeout before data read\n", 318 m->mf_name); 319 if (LogLevel > 0) 320 sm_syslog(LOG_ERR, e->e_id, 321 "milter_read(%s): timeout before data read\n", 322 m->mf_name); 323 milter_error(m); 324 return NULL; 325 } 326 to -= now - readstart; 327 } 328 329 *cmd = data[MILTER_LEN_BYTES]; 330 data[MILTER_LEN_BYTES] = '\0'; 331 (void) memcpy(&i, data, MILTER_LEN_BYTES); 332 expl = ntohl(i) - 1; 333 334 if (tTd(64, 25)) 335 dprintf("milter_read(%s): expecting %ld bytes\n", 336 m->mf_name, (long) expl); 337 338 if (expl < 0) 339 { 340 if (tTd(64, 5)) 341 dprintf("milter_read(%s): read size %ld out of range\n", 342 m->mf_name, (long) expl); 343 if (LogLevel > 0) 344 sm_syslog(LOG_ERR, e->e_id, 345 "milter_read(%s): read size %ld out of range", 346 m->mf_name, (long) expl); 347 milter_error(m); 348 return NULL; 349 } 350 351 if (expl == 0) 352 return NULL; 353 354 buf = (char *)xalloc(expl); 355 356 if (milter_sysread(m, buf, expl, to, e) == NULL) 357 { 358 sm_free(buf); 359 return NULL; 360 } 361 362 if (tTd(64, 50)) 363 dprintf("milter_read(%s): Returning %*s\n", 364 m->mf_name, (int) expl, buf); 365 *rlen = expl; 366 return buf; 367} 368/* 369** MILTER_WRITE -- write to a remote milter filter 370** 371** Parameters: 372** m -- milter to read from. 373** cmd -- command to send. 374** buf -- optional command data. 375** len -- length of buf. 376** to -- timeout in seconds. 377** e -- current envelope. 378** 379** Returns: 380** buf if successful, NULL otherwise 381** Not actually used anywhere but function prototype 382** must match milter_read() 383*/ 384 385static char * 386milter_write(m, cmd, buf, len, to, e) 387 struct milter *m; 388 char cmd; 389 char *buf; 390 ssize_t len; 391 time_t to; 392 ENVELOPE *e; 393{ 394 time_t writestart = (time_t) 0; 395 ssize_t sl, i; 396 mi_int32 nl; 397 char data[MILTER_LEN_BYTES + 1]; 398 399 if (len < 0 || len > MILTER_CHUNK_SIZE) 400 { 401 if (tTd(64, 5)) 402 dprintf("milter_write(%s): length %ld out of range\n", 403 m->mf_name, (long) len); 404 if (LogLevel > 0) 405 sm_syslog(LOG_ERR, e->e_id, 406 "milter_write(%s): length %ld out of range", 407 m->mf_name, (long) len); 408 milter_error(m); 409 return NULL; 410 } 411 412 if (tTd(64, 20)) 413 dprintf("milter_write(%s): cmd %c, len %ld\n", 414 m->mf_name, cmd, (long) len); 415 416 nl = htonl(len + 1); /* add 1 for the cmd char */ 417 (void) memcpy(data, (char *) &nl, MILTER_LEN_BYTES); 418 data[MILTER_LEN_BYTES] = cmd; 419 sl = MILTER_LEN_BYTES + 1; 420 421 if (to > 0) 422 { 423 writestart = curtime(); 424 MILTER_TIMEOUT("milter_write", to, TRUE); 425 } 426 427 /* use writev() instead to send the whole stuff at once? */ 428 i = write(m->mf_sock, (void *) data, sl); 429 if (i != sl) 430 { 431 int save_errno = errno; 432 433 if (tTd(64, 5)) 434 dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n", 435 m->mf_name, cmd, (long) i, (long) sl, 436 errstring(save_errno)); 437 if (LogLevel > 0) 438 sm_syslog(LOG_ERR, e->e_id, 439 "milter_write(%s): write(%c) returned %ld, expected %ld: %s", 440 m->mf_name, cmd, (long) i, (long) sl, 441 errstring(save_errno)); 442 milter_error(m); 443 return buf; 444 } 445 446 if (len <= 0 || buf == NULL) 447 return buf; 448 449 if (tTd(64, 50)) 450 dprintf("milter_write(%s): Sending %*s\n", 451 m->mf_name, (int) len, buf); 452 453 if (to > 0) 454 { 455 time_t now; 456 457 now = curtime(); 458 if (now - writestart >= to) 459 { 460 if (tTd(64, 5)) 461 dprintf("milter_write(%s): timeout before data send\n", 462 m->mf_name); 463 if (LogLevel > 0) 464 sm_syslog(LOG_ERR, e->e_id, 465 "milter_write(%s): timeout before data send\n", 466 m->mf_name); 467 milter_error(m); 468 return NULL; 469 } 470 else 471 { 472 to -= now - writestart; 473 MILTER_TIMEOUT("milter_write", to, TRUE); 474 } 475 } 476 477 i = write(m->mf_sock, (void *) buf, len); 478 if (i != len) 479 { 480 int save_errno = errno; 481 482 if (tTd(64, 5)) 483 dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n", 484 m->mf_name, cmd, (long) i, (long) sl, 485 errstring(save_errno)); 486 if (LogLevel > 0) 487 sm_syslog(LOG_ERR, e->e_id, 488 "milter_write(%s): write(%c) returned %ld, expected %ld: %s", 489 m->mf_name, cmd, (long) i, (long) len, 490 errstring(save_errno)); 491 milter_error(m); 492 return NULL; 493 } 494 return buf; 495} 496 497/* 498** Utility functions 499*/ 500 501/* 502** MILTER_OPEN -- connect to remote milter filter 503** 504** Parameters: 505** m -- milter to connect to. 506** parseonly -- parse but don't connect. 507** e -- current envelope. 508** 509** Returns: 510** connected socket if sucessful && !parseonly, 511** 0 upon parse success if parseonly, 512** -1 otherwise. 513*/ 514 515static jmp_buf MilterConnectTimeout; 516 517static int 518milter_open(m, parseonly, e) 519 struct milter *m; 520 bool parseonly; 521 ENVELOPE *e; 522{ 523 int sock = 0; 524 SOCKADDR_LEN_T addrlen = 0; 525 int addrno = 0; 526 int save_errno; 527 char *p; 528 char *colon; 529 char *at; 530 struct hostent *hp = NULL; 531 SOCKADDR addr; 532 533 if (m->mf_conn == NULL || m->mf_conn[0] == '\0') 534 { 535 if (tTd(64, 5)) 536 dprintf("X%s: empty or missing socket information\n", 537 m->mf_name); 538 if (parseonly) 539 syserr("X%s: empty or missing socket information", 540 m->mf_name); 541 else if (LogLevel > 10) 542 sm_syslog(LOG_ERR, e->e_id, 543 "X%s: empty or missing socket information", 544 m->mf_name); 545 milter_error(m); 546 return -1; 547 } 548 549 /* protocol:filename or protocol:port@host */ 550 p = m->mf_conn; 551 colon = strchr(p, ':'); 552 if (colon != NULL) 553 { 554 *colon = '\0'; 555 556 if (*p == '\0') 557 { 558# if NETUNIX 559 /* default to AF_UNIX */ 560 addr.sa.sa_family = AF_UNIX; 561# else /* NETUNIX */ 562# if NETINET 563 /* default to AF_INET */ 564 addr.sa.sa_family = AF_INET; 565# else /* NETINET */ 566# if NETINET6 567 /* default to AF_INET6 */ 568 addr.sa.sa_family = AF_INET6; 569# else /* NETINET6 */ 570 /* no protocols available */ 571 sm_syslog(LOG_ERR, e->e_id, 572 "X%s: no valid socket protocols available", 573 m->mf_name); 574 milter_error(m); 575 return -1; 576# endif /* NETINET6 */ 577# endif /* NETINET */ 578# endif /* NETUNIX */ 579 } 580# if NETUNIX 581 else if (strcasecmp(p, "unix") == 0 || 582 strcasecmp(p, "local") == 0) 583 addr.sa.sa_family = AF_UNIX; 584# endif /* NETUNIX */ 585# if NETINET 586 else if (strcasecmp(p, "inet") == 0) 587 addr.sa.sa_family = AF_INET; 588# endif /* NETINET */ 589# if NETINET6 590 else if (strcasecmp(p, "inet6") == 0) 591 addr.sa.sa_family = AF_INET6; 592# endif /* NETINET6 */ 593 else 594 { 595# ifdef EPROTONOSUPPORT 596 errno = EPROTONOSUPPORT; 597# else /* EPROTONOSUPPORT */ 598 errno = EINVAL; 599# endif /* EPROTONOSUPPORT */ 600 if (tTd(64, 5)) 601 dprintf("X%s: unknown socket type %s\n", 602 m->mf_name, p); 603 if (parseonly) 604 syserr("X%s: unknown socket type %s", 605 m->mf_name, p); 606 else if (LogLevel > 10) 607 sm_syslog(LOG_ERR, e->e_id, 608 "X%s: unknown socket type %s", 609 m->mf_name, p); 610 milter_error(m); 611 return -1; 612 } 613 *colon++ = ':'; 614 } 615 else 616 { 617 /* default to AF_UNIX */ 618 addr.sa.sa_family = AF_UNIX; 619 colon = p; 620 } 621 622# if NETUNIX 623 if (addr.sa.sa_family == AF_UNIX) 624 { 625 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK; 626 627 at = colon; 628 if (strlen(colon) >= sizeof addr.sunix.sun_path) 629 { 630 if (tTd(64, 5)) 631 dprintf("X%s: local socket name %s too long\n", 632 m->mf_name, colon); 633 errno = EINVAL; 634 if (parseonly) 635 syserr("X%s: local socket name %s too long", 636 m->mf_name, colon); 637 else if (LogLevel > 10) 638 sm_syslog(LOG_ERR, e->e_id, 639 "X%s: local socket name %s too long", 640 m->mf_name, colon); 641 milter_error(m); 642 return -1; 643 } 644 errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, 645 S_IRUSR|S_IWUSR, NULL); 646 647 /* if just parsing .cf file, socket doesn't need to exist */ 648 if (parseonly && errno == ENOENT) 649 { 650 if (OpMode == MD_DAEMON || 651 OpMode == MD_FGDAEMON) 652 fprintf(stderr, 653 "WARNING: X%s: local socket name %s missing\n", 654 m->mf_name, colon); 655 } 656 else if (errno != 0) 657 { 658 /* if not safe, don't create */ 659 save_errno = errno; 660 if (tTd(64, 5)) 661 dprintf("X%s: local socket name %s unsafe\n", 662 m->mf_name, colon); 663 errno = save_errno; 664 if (parseonly) 665 { 666 if (OpMode == MD_DAEMON || 667 OpMode == MD_FGDAEMON || 668 OpMode == MD_SMTP) 669 syserr("X%s: local socket name %s unsafe", 670 m->mf_name, colon); 671 } 672 else if (LogLevel > 10) 673 sm_syslog(LOG_ERR, e->e_id, 674 "X%s: local socket name %s unsafe", 675 m->mf_name, colon); 676 milter_error(m); 677 return -1; 678 } 679 680 (void) strlcpy(addr.sunix.sun_path, colon, 681 sizeof addr.sunix.sun_path); 682 addrlen = sizeof (struct sockaddr_un); 683 } 684 else 685# endif /* NETUNIX */ 686# if NETINET || NETINET6 687 if (FALSE 688# if NETINET 689 || addr.sa.sa_family == AF_INET 690# endif /* NETINET */ 691# if NETINET6 692 || addr.sa.sa_family == AF_INET6 693# endif /* NETINET6 */ 694 ) 695 { 696 u_short port; 697 698 /* Parse port@host */ 699 at = strchr(colon, '@'); 700 if (at == NULL) 701 { 702 if (tTd(64, 5)) 703 dprintf("X%s: bad address %s (expected port@host)\n", 704 m->mf_name, colon); 705 if (parseonly) 706 syserr("X%s: bad address %s (expected port@host)", 707 m->mf_name, colon); 708 else if (LogLevel > 10) 709 sm_syslog(LOG_ERR, e->e_id, 710 "X%s: bad address %s (expected port@host)", 711 m->mf_name, colon); 712 milter_error(m); 713 return -1; 714 } 715 *at = '\0'; 716 if (isascii(*colon) && isdigit(*colon)) 717 port = htons((u_short) atoi(colon)); 718 else 719 { 720# ifdef NO_GETSERVBYNAME 721 if (tTd(64, 5)) 722 dprintf("X%s: invalid port number %s\n", 723 m->mf_name, colon); 724 if (parseonly) 725 syserr("X%s: invalid port number %s", 726 m->mf_name, colon); 727 else if (LogLevel > 10) 728 sm_syslog(LOG_ERR, e->e_id, 729 "X%s: invalid port number %s", 730 m->mf_name, colon); 731 milter_error(m); 732 return -1; 733# else /* NO_GETSERVBYNAME */ 734 register struct servent *sp; 735 736 sp = getservbyname(colon, "tcp"); 737 if (sp == NULL) 738 { 739 save_errno = errno; 740 if (tTd(64, 5)) 741 dprintf("X%s: unknown port name %s\n", 742 m->mf_name, colon); 743 errno = save_errno; 744 if (parseonly) 745 syserr("X%s: unknown port name %s", 746 m->mf_name, colon); 747 else if (LogLevel > 10) 748 sm_syslog(LOG_ERR, e->e_id, 749 "X%s: unknown port name %s", 750 m->mf_name, colon); 751 milter_error(m); 752 return -1; 753 } 754 port = sp->s_port; 755# endif /* NO_GETSERVBYNAME */ 756 } 757 *at++ = '@'; 758 if (*at == '[') 759 { 760 char *end; 761 762 end = strchr(at, ']'); 763 if (end != NULL) 764 { 765 bool found = FALSE; 766# if NETINET 767 unsigned long hid = INADDR_NONE; 768# endif /* NETINET */ 769# if NETINET6 770 struct sockaddr_in6 hid6; 771# endif /* NETINET6 */ 772 773 *end = '\0'; 774# if NETINET 775 if (addr.sa.sa_family == AF_INET && 776 (hid = inet_addr(&at[1])) != INADDR_NONE) 777 { 778 addr.sin.sin_addr.s_addr = hid; 779 addr.sin.sin_port = port; 780 found = TRUE; 781 } 782# endif /* NETINET */ 783# if NETINET6 784 (void) memset(&hid6, '\0', sizeof hid6); 785 if (addr.sa.sa_family == AF_INET6 && 786 inet_pton(AF_INET6, &at[1], 787 &hid6.sin6_addr) == 1) 788 { 789 addr.sin6.sin6_addr = hid6.sin6_addr; 790 addr.sin6.sin6_port = port; 791 found = TRUE; 792 } 793# endif /* NETINET6 */ 794 *end = ']'; 795 if (!found) 796 { 797 if (tTd(64, 5)) 798 dprintf("X%s: Invalid numeric domain spec \"%s\"\n", 799 m->mf_name, at); 800 if (parseonly) 801 syserr("X%s: Invalid numeric domain spec \"%s\"", 802 m->mf_name, at); 803 else if (LogLevel > 10) 804 sm_syslog(LOG_ERR, e->e_id, 805 "X%s: Invalid numeric domain spec \"%s\"", 806 m->mf_name, at); 807 milter_error(m); 808 return -1; 809 } 810 } 811 else 812 { 813 if (tTd(64, 5)) 814 dprintf("X%s: Invalid numeric domain spec \"%s\"\n", 815 m->mf_name, at); 816 if (parseonly) 817 syserr("X%s: Invalid numeric domain spec \"%s\"", 818 m->mf_name, at); 819 else if (LogLevel > 10) 820 sm_syslog(LOG_ERR, e->e_id, 821 "X%s: Invalid numeric domain spec \"%s\"", 822 m->mf_name, at); 823 milter_error(m); 824 return -1; 825 } 826 } 827 else 828 { 829 hp = sm_gethostbyname(at, addr.sa.sa_family); 830 if (hp == NULL) 831 { 832 save_errno = errno; 833 if (tTd(64, 5)) 834 dprintf("X%s: Unknown host name %s\n", 835 m->mf_name, at); 836 errno = save_errno; 837 if (parseonly) 838 syserr("X%s: Unknown host name %s", 839 m->mf_name, at); 840 else if (LogLevel > 10) 841 sm_syslog(LOG_ERR, e->e_id, 842 "X%s: Unknown host name %s", 843 m->mf_name, at); 844 milter_error(m); 845 return -1; 846 } 847 addr.sa.sa_family = hp->h_addrtype; 848 switch (hp->h_addrtype) 849 { 850# if NETINET 851 case AF_INET: 852 memmove(&addr.sin.sin_addr, 853 hp->h_addr, 854 INADDRSZ); 855 addr.sin.sin_port = port; 856 addrlen = sizeof (struct sockaddr_in); 857 addrno = 1; 858 break; 859# endif /* NETINET */ 860 861# if NETINET6 862 case AF_INET6: 863 memmove(&addr.sin6.sin6_addr, 864 hp->h_addr, 865 IN6ADDRSZ); 866 addr.sin6.sin6_port = port; 867 addrlen = sizeof (struct sockaddr_in6); 868 addrno = 1; 869 break; 870# endif /* NETINET6 */ 871 872 default: 873 if (tTd(64, 5)) 874 dprintf("X%s: Unknown protocol for %s (%d)\n", 875 m->mf_name, at, 876 hp->h_addrtype); 877 if (parseonly) 878 syserr("X%s: Unknown protocol for %s (%d)", 879 m->mf_name, at, hp->h_addrtype); 880 else if (LogLevel > 10) 881 sm_syslog(LOG_ERR, e->e_id, 882 "X%s: Unknown protocol for %s (%d)", 883 m->mf_name, at, 884 hp->h_addrtype); 885 milter_error(m); 886# if _FFR_FREEHOSTENT && NETINET6 887 freehostent(hp); 888# endif /* _FFR_FREEHOSTENT && NETINET6 */ 889 return -1; 890 } 891 } 892 } 893 else 894# endif /* NETINET || NETINET6 */ 895 { 896 if (tTd(64, 5)) 897 dprintf("X%s: unknown socket protocol\n", m->mf_name); 898 if (parseonly) 899 syserr("X%s: unknown socket protocol", m->mf_name); 900 else if (LogLevel > 10) 901 sm_syslog(LOG_ERR, e->e_id, 902 "X%s: unknown socket protocol", m->mf_name); 903 milter_error(m); 904 return -1; 905 } 906 907 /* just parsing through? */ 908 if (parseonly) 909 { 910 m->mf_state = SMFS_READY; 911# if _FFR_FREEHOSTENT && NETINET6 912 if (hp != NULL) 913 freehostent(hp); 914# endif /* _FFR_FREEHOSTENT && NETINET6 */ 915 return 0; 916 } 917 918 /* sanity check */ 919 if (m->mf_state != SMFS_READY && 920 m->mf_state != SMFS_CLOSED) 921 { 922 /* shouldn't happen */ 923 if (tTd(64, 1)) 924 dprintf("milter_open(%s): Trying to open filter in state %c\n", 925 m->mf_name, (char) m->mf_state); 926 milter_error(m); 927# if _FFR_FREEHOSTENT && NETINET6 928 if (hp != NULL) 929 freehostent(hp); 930# endif /* _FFR_FREEHOSTENT && NETINET6 */ 931 return -1; 932 } 933 934 /* nope, actually connecting */ 935 for (;;) 936 { 937 sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); 938 if (sock < 0) 939 { 940 save_errno = errno; 941 if (tTd(64, 5)) 942 dprintf("X%s: error creating socket: %s\n", 943 m->mf_name, errstring(save_errno)); 944 if (LogLevel > 0) 945 sm_syslog(LOG_ERR, e->e_id, 946 "X%s: error creating socket: %s", 947 m->mf_name, errstring(save_errno)); 948 milter_error(m); 949# if _FFR_FREEHOSTENT && NETINET6 950 if (hp != NULL) 951 freehostent(hp); 952# endif /* _FFR_FREEHOSTENT && NETINET6 */ 953 return -1; 954 } 955 956 if (setjmp(MilterConnectTimeout) == 0) 957 { 958 EVENT *ev = NULL; 959 int i; 960 961 if (m->mf_timeout[SMFTO_CONNECT] > 0) 962 ev = setevent(m->mf_timeout[SMFTO_CONNECT], 963 milter_connect_timeout, 0); 964 965 i = connect(sock, (struct sockaddr *) &addr, addrlen); 966 save_errno = errno; 967 if (ev != NULL) 968 clrevent(ev); 969 errno = save_errno; 970 if (i >= 0) 971 break; 972 } 973 974 /* couldn't connect.... try next address */ 975 save_errno = errno; 976 p = CurHostName; 977 CurHostName = at; 978 if (tTd(64, 5)) 979 dprintf("milter_open(%s): %s failed: %s\n", 980 m->mf_name, at, errstring(save_errno)); 981 if (LogLevel >= 14) 982 sm_syslog(LOG_INFO, e->e_id, 983 "milter_open(%s): %s failed: %s", 984 m->mf_name, at, errstring(save_errno)); 985 CurHostName = p; 986 (void) close(sock); 987 988 /* try next address */ 989 if (hp != NULL && hp->h_addr_list[addrno] != NULL) 990 { 991 switch (addr.sa.sa_family) 992 { 993# if NETINET 994 case AF_INET: 995 memmove(&addr.sin.sin_addr, 996 hp->h_addr_list[addrno++], 997 INADDRSZ); 998 break; 999# endif /* NETINET */ 1000 1001# if NETINET6 1002 case AF_INET6: 1003 memmove(&addr.sin6.sin6_addr, 1004 hp->h_addr_list[addrno++], 1005 IN6ADDRSZ); 1006 break; 1007# endif /* NETINET6 */ 1008 1009 default: 1010 if (tTd(64, 5)) 1011 dprintf("X%s: Unknown protocol for %s (%d)\n", 1012 m->mf_name, at, 1013 hp->h_addrtype); 1014 if (LogLevel > 0) 1015 sm_syslog(LOG_ERR, e->e_id, 1016 "X%s: Unknown protocol for %s (%d)", 1017 m->mf_name, at, 1018 hp->h_addrtype); 1019 milter_error(m); 1020# if _FFR_FREEHOSTENT && NETINET6 1021 freehostent(hp); 1022# endif /* _FFR_FREEHOSTENT && NETINET6 */ 1023 return -1; 1024 } 1025 continue; 1026 } 1027 p = CurHostName; 1028 CurHostName = at; 1029 if (tTd(64, 5)) 1030 dprintf("X%s: error connecting to filter: %s\n", 1031 m->mf_name, errstring(save_errno)); 1032 if (LogLevel > 0) 1033 sm_syslog(LOG_ERR, e->e_id, 1034 "X%s: error connecting to filter: %s", 1035 m->mf_name, errstring(save_errno)); 1036 CurHostName = p; 1037 milter_error(m); 1038# if _FFR_FREEHOSTENT && NETINET6 1039 if (hp != NULL) 1040 freehostent(hp); 1041# endif /* _FFR_FREEHOSTENT && NETINET6 */ 1042 return -1; 1043 } 1044 m->mf_state = SMFS_OPEN; 1045# if _FFR_FREEHOSTENT && NETINET6 1046 if (hp != NULL) 1047 { 1048 freehostent(hp); 1049 hp = NULL; 1050 } 1051# endif /* _FFR_FREEHOSTENT && NETINET6 */ 1052 return sock; 1053} 1054 1055static void 1056milter_connect_timeout() 1057{ 1058 /* 1059 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 1060 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 1061 ** DOING. 1062 */ 1063 1064 errno = ETIMEDOUT; 1065 longjmp(MilterConnectTimeout, 1); 1066} 1067/* 1068** MILTER_SETUP -- setup structure for a mail filter 1069** 1070** Parameters: 1071** line -- the options line. 1072** 1073** Returns: 1074** none 1075*/ 1076 1077void 1078milter_setup(line) 1079 char *line; 1080{ 1081 char fcode; 1082 register char *p; 1083 register struct milter *m; 1084 STAB *s; 1085 1086 /* collect the filter name */ 1087 for (p = line; 1088 *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); 1089 p++) 1090 continue; 1091 if (*p != '\0') 1092 *p++ = '\0'; 1093 if (line[0] == '\0') 1094 { 1095 syserr("name required for mail filter"); 1096 return; 1097 } 1098 m = (struct milter *)xalloc(sizeof *m); 1099 memset((char *) m, '\0', sizeof *m); 1100 m->mf_name = newstr(line); 1101 m->mf_state = SMFS_READY; 1102 m->mf_sock = -1;
|
1284 case 'S': 1285 m->mf_timeout[SMFTO_WRITE] = convtime(p, 's'); 1286 if (tTd(64, 5)) 1287 printf("X%s: %c=%ld\n", 1288 m->mf_name, fcode, 1289 (u_long) m->mf_timeout[SMFTO_WRITE]); 1290 break; 1291 1292 case 'R': 1293 m->mf_timeout[SMFTO_READ] = convtime(p, 's'); 1294 if (tTd(64, 5)) 1295 printf("X%s: %c=%ld\n", 1296 m->mf_name, fcode, 1297 (u_long) m->mf_timeout[SMFTO_READ]); 1298 break; 1299 1300 case 'E': 1301 m->mf_timeout[SMFTO_EOM] = convtime(p, 's'); 1302 if (tTd(64, 5)) 1303 printf("X%s: %c=%ld\n", 1304 m->mf_name, fcode, 1305 (u_long) m->mf_timeout[SMFTO_EOM]); 1306 break; 1307 1308 default: 1309 if (tTd(64, 5)) 1310 printf("X%s: %c unknown\n", 1311 m->mf_name, fcode); 1312 syserr("X%s: unknown filter timeout %c", 1313 m->mf_name, fcode); 1314 break; 1315 } 1316 p = delimptr; 1317 } 1318} 1319/* 1320** MILTER_SET_OPTION -- set an individual milter option 1321** 1322** Parameters: 1323** name -- the name of the option. 1324** val -- the value of the option. 1325** sticky -- if set, don't let other setoptions override 1326** this value. 1327** 1328** Returns: 1329** none. 1330*/ 1331 1332/* set if Milter sub-option is stuck */ 1333static BITMAP256 StickyMilterOpt; 1334 1335static struct milteropt 1336{ 1337 char *mo_name; /* long name of milter option */ 1338 u_char mo_code; /* code for option */ 1339} MilterOptTab[] = 1340{ 1341# define MO_MACROS_CONNECT 0x01 1342 { "macros.connect", MO_MACROS_CONNECT }, 1343# define MO_MACROS_HELO 0x02 1344 { "macros.helo", MO_MACROS_HELO }, 1345# define MO_MACROS_ENVFROM 0x03 1346 { "macros.envfrom", MO_MACROS_ENVFROM }, 1347# define MO_MACROS_ENVRCPT 0x04 1348 { "macros.envrcpt", MO_MACROS_ENVRCPT }, 1349 { NULL, 0 }, 1350}; 1351 1352void 1353milter_set_option(name, val, sticky) 1354 char *name; 1355 char *val; 1356 bool sticky; 1357{ 1358 int nummac = 0; 1359 register struct milteropt *mo; 1360 char *p; 1361 char **macros = NULL; 1362 1363 if (tTd(37, 2) || tTd(64, 5)) 1364 dprintf("milter_set_option(%s = %s)", name, val); 1365 1366 for (mo = MilterOptTab; mo->mo_name != NULL; mo++) 1367 { 1368 if (strcasecmp(mo->mo_name, name) == 0) 1369 break; 1370 } 1371 1372 if (mo->mo_name == NULL) 1373 syserr("milter_set_option: invalid Milter option %s", name); 1374 1375 /* 1376 ** See if this option is preset for us. 1377 */ 1378 1379 if (!sticky && bitnset(mo->mo_code, StickyMilterOpt)) 1380 { 1381 if (tTd(37, 2) || tTd(64,5)) 1382 dprintf(" (ignored)\n"); 1383 return; 1384 } 1385 1386 if (tTd(37, 2) || tTd(64,5)) 1387 dprintf("\n"); 1388 1389 switch (mo->mo_code) 1390 { 1391 case MO_MACROS_CONNECT: 1392 if (macros == NULL) 1393 macros = MilterConnectMacros; 1394 /* FALLTHROUGH */ 1395 1396 case MO_MACROS_HELO: 1397 if (macros == NULL) 1398 macros = MilterHeloMacros; 1399 /* FALLTHROUGH */ 1400 1401 case MO_MACROS_ENVFROM: 1402 if (macros == NULL) 1403 macros = MilterEnvFromMacros; 1404 /* FALLTHROUGH */ 1405 1406 case MO_MACROS_ENVRCPT: 1407 if (macros == NULL) 1408 macros = MilterEnvRcptMacros; 1409 1410 p = newstr(val); 1411 while (*p != '\0') 1412 { 1413 char *macro; 1414 1415 /* Skip leading commas, spaces */ 1416 while (*p != '\0' && 1417 (*p == ',' || (isascii(*p) && isspace(*p)))) 1418 p++; 1419 1420 if (*p == '\0') 1421 break; 1422 1423 /* Find end of macro */ 1424 macro = p; 1425 while (*p != '\0' && *p != ',' && 1426 isascii(*p) && !isspace(*p)) 1427 p++; 1428 if (*p != '\0') 1429 *p++ = '\0'; 1430 1431 if (nummac >= MAXFILTERMACROS) 1432 { 1433 syserr("milter_set_option: too many macros in Milter.%s (max %d)", 1434 name, MAXFILTERMACROS); 1435 macros[nummac] = NULL; 1436 break; 1437 } 1438 macros[nummac++] = macro; 1439 } 1440 macros[nummac] = NULL; 1441 break; 1442 1443 default: 1444 syserr("milter_set_option: invalid Milter option %s", name); 1445 break; 1446 } 1447 1448 if (sticky) 1449 setbitn(mo->mo_code, StickyMilterOpt); 1450} 1451/* 1452** MILTER_REOPEN_DF -- open & truncate the df file (for replbody) 1453** 1454** Parameters: 1455** e -- current envelope. 1456** 1457** Returns: 1458** 0 if succesful, -1 otherwise 1459*/ 1460 1461static int 1462milter_reopen_df(e) 1463 ENVELOPE *e; 1464{ 1465 char dfname[MAXPATHLEN]; 1466 1467 (void) strlcpy(dfname, queuename(e, 'd'), sizeof dfname); 1468 1469 /* 1470 ** In SuperSafe mode, e->e_dfp is a read-only FP so 1471 ** close and reopen writable (later close and reopen 1472 ** read only again). 1473 ** 1474 ** In !SuperSafe mode, e->e_dfp still points at the 1475 ** buffered file I/O descriptor, still open for writing 1476 ** so there isn't as much work to do, just truncate it 1477 ** and go. 1478 */ 1479 1480 if (SuperSafe) 1481 { 1482 /* close read-only df */ 1483 if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL) 1484 { 1485 (void) fclose(e->e_dfp); 1486 e->e_flags &= ~EF_HAS_DF; 1487 } 1488 1489 /* open writable */ 1490 if ((e->e_dfp = fopen(dfname, "w+")) == NULL) 1491 { 1492 MILTER_DF_ERROR("milter_reopen_df: fopen %s: %s"); 1493 return -1; 1494 } 1495 } 1496 else if (e->e_dfp == NULL) 1497 { 1498 /* shouldn't happen */ 1499 errno = ENOENT; 1500 MILTER_DF_ERROR("milter_reopen_df: NULL e_dfp (%s: %s)"); 1501 return -1; 1502 } 1503 return 0; 1504} 1505/* 1506** MILTER_RESET_DF -- re-open read-only the df file (for replbody) 1507** 1508** Parameters: 1509** e -- current envelope. 1510** 1511** Returns: 1512** 0 if succesful, -1 otherwise 1513*/ 1514 1515static int 1516milter_reset_df(e) 1517 ENVELOPE *e; 1518{ 1519 int afd; 1520 char dfname[MAXPATHLEN]; 1521 1522 (void) strlcpy(dfname, queuename(e, 'd'), sizeof dfname); 1523 1524 if (fflush(e->e_dfp) != 0 || ferror(e->e_dfp)) 1525 { 1526 MILTER_DF_ERROR("milter_reset_df: error writing/flushing %s: %s"); 1527 return -1; 1528 } 1529 else if (!SuperSafe) 1530 { 1531 /* skip next few clauses */ 1532 /* EMPTY */ 1533 } 1534 else if ((afd = fileno(e->e_dfp)) >= 0 && fsync(afd) < 0) 1535 { 1536 MILTER_DF_ERROR("milter_reset_df: error sync'ing %s: %s"); 1537 return -1; 1538 } 1539 else if (fclose(e->e_dfp) < 0) 1540 { 1541 MILTER_DF_ERROR("milter_reset_df: error closing %s: %s"); 1542 return -1; 1543 } 1544 else if ((e->e_dfp = fopen(dfname, "r")) == NULL) 1545 { 1546 MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s"); 1547 return -1; 1548 } 1549 else 1550 e->e_flags |= EF_HAS_DF; 1551 return 0; 1552} 1553/* 1554** MILTER_CAN_DELRCPTS -- can any milter filters delete recipients? 1555** 1556** Parameters: 1557** none 1558** 1559** Returns: 1560** TRUE if any filter deletes recipients, FALSE otherwise 1561*/ 1562 1563bool 1564milter_can_delrcpts() 1565{ 1566 bool can = FALSE; 1567 int i; 1568 1569 if (tTd(64, 10)) 1570 dprintf("milter_can_delrcpts:"); 1571 1572 for (i = 0; InputFilters[i] != NULL; i++) 1573 { 1574 struct milter *m = InputFilters[i]; 1575 1576 if (bitset(SMFIF_DELRCPT, m->mf_fflags)) 1577 { 1578 can = TRUE; 1579 break; 1580 } 1581 } 1582 if (tTd(64, 10)) 1583 dprintf("%s\n", can ? "TRUE" : "FALSE"); 1584 1585 return can; 1586} 1587/* 1588** MILTER_QUIT_FILTER -- close down a single filter 1589** 1590** Parameters: 1591** m -- milter structure of filter to close down. 1592** e -- current envelope. 1593** 1594** Returns: 1595** none 1596*/ 1597 1598static void 1599milter_quit_filter(m, e) 1600 struct milter *m; 1601 ENVELOPE *e; 1602{ 1603 if (tTd(64, 10)) 1604 dprintf("milter_quit_filter(%s)\n", m->mf_name); 1605 1606 /* Never replace error state */ 1607 if (m->mf_state == SMFS_ERROR) 1608 return; 1609 1610 if (m->mf_sock < 0 || 1611 m->mf_state == SMFS_CLOSED || 1612 m->mf_state == SMFS_READY) 1613 { 1614 m->mf_sock = -1; 1615 m->mf_state = SMFS_CLOSED; 1616 return; 1617 } 1618 1619 (void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0, 1620 m->mf_timeout[SMFTO_WRITE], e); 1621 if (m->mf_sock >= 0) 1622 { 1623 (void) close(m->mf_sock); 1624 m->mf_sock = -1; 1625 } 1626 if (m->mf_state != SMFS_ERROR) 1627 m->mf_state = SMFS_CLOSED; 1628} 1629/* 1630** MILTER_ABORT_FILTER -- tell filter to abort current message 1631** 1632** Parameters: 1633** m -- milter structure of filter to abort. 1634** e -- current envelope. 1635** 1636** Returns: 1637** none 1638*/ 1639 1640static void 1641milter_abort_filter(m, e) 1642 struct milter *m; 1643 ENVELOPE *e; 1644{ 1645 if (tTd(64, 10)) 1646 dprintf("milter_abort_filter(%s)\n", m->mf_name); 1647 1648 if (m->mf_sock < 0 || 1649 m->mf_state != SMFS_INMSG) 1650 return; 1651 1652 (void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0, 1653 m->mf_timeout[SMFTO_WRITE], e); 1654 if (m->mf_state != SMFS_ERROR) 1655 m->mf_state = SMFS_DONE; 1656} 1657/* 1658** MILTER_SEND_MACROS -- provide macros to the filters 1659** 1660** Parameters: 1661** m -- milter to send macros to. 1662** macros -- macros to send for filter smfi_getsymval(). 1663** cmd -- which command the macros are associated with. 1664** e -- current envelope (for macro access). 1665** 1666** Returns: 1667** none 1668*/ 1669 1670static void 1671milter_send_macros(m, macros, cmd, e) 1672 struct milter *m; 1673 char **macros; 1674 char cmd; 1675 ENVELOPE *e; 1676{ 1677 int i; 1678 int mid; 1679 char *v; 1680 char *buf, *bp; 1681 ssize_t s; 1682 1683 /* sanity check */ 1684 if (macros == NULL || macros[0] == NULL) 1685 return; 1686 1687 /* put together data */ 1688 s = 1; /* for the command character */ 1689 for (i = 0; macros[i] != NULL; i++) 1690 { 1691 mid = macid(macros[i], NULL); 1692 if (mid == 0) 1693 continue; 1694 v = macvalue(mid, e); 1695 if (v == NULL) 1696 continue; 1697 s += strlen(macros[i]) + 1 + strlen(v) + 1; 1698 } 1699 1700 buf = (char *)xalloc(s); 1701 bp = buf; 1702 *bp++ = cmd; 1703 for (i = 0; macros[i] != NULL; i++) 1704 { 1705 mid = macid(macros[i], NULL); 1706 if (mid == 0) 1707 continue; 1708 v = macvalue(mid, e); 1709 if (v == NULL) 1710 continue; 1711 1712 if (tTd(64, 10)) 1713 dprintf("milter_send_macros(%s, %c): %s=%s\n", 1714 m->mf_name, cmd, macros[i], v); 1715 1716 (void) strlcpy(bp, macros[i], s - (bp - buf)); 1717 bp += strlen(bp) + 1; 1718 (void) strlcpy(bp, v, s - (bp - buf)); 1719 bp += strlen(bp) + 1; 1720 } 1721 (void) milter_write(m, SMFIC_MACRO, buf, s, 1722 m->mf_timeout[SMFTO_WRITE], e); 1723 sm_free(buf); 1724} 1725 1726/* 1727** MILTER_SEND_COMMAND -- send a command and return the response for a filter 1728** 1729** Parameters: 1730** m -- current milter filter 1731** command -- command to send. 1732** data -- optional command data. 1733** sz -- length of buf. 1734** e -- current envelope (for e->e_id). 1735** state -- return state word. 1736** 1737** Returns: 1738** response string (may be NULL) 1739*/ 1740 1741static char * 1742milter_send_command(m, command, data, sz, e, state) 1743 struct milter *m; 1744 char command; 1745 void *data; 1746 ssize_t sz; 1747 ENVELOPE *e; 1748 char *state; 1749{ 1750 char rcmd; 1751 ssize_t rlen; 1752 u_long skipflag; 1753 char *defresponse; 1754 char *response; 1755 1756 if (tTd(64, 10)) 1757 dprintf("milter_send_command(%s): cmd %c len %ld\n", 1758 m->mf_name, (char) command, (long) sz); 1759 1760 /* find skip flag and default failure */ 1761 switch (command) 1762 { 1763 case SMFIC_CONNECT: 1764 skipflag = SMFIP_NOCONNECT; 1765 defresponse = "554 Command rejected"; 1766 break; 1767 1768 case SMFIC_HELO: 1769 skipflag = SMFIP_NOHELO; 1770 defresponse = "550 Command rejected"; 1771 break; 1772 1773 case SMFIC_MAIL: 1774 skipflag = SMFIP_NOMAIL; 1775 defresponse = "550 5.7.1 Command rejected"; 1776 break; 1777 1778 case SMFIC_RCPT: 1779 skipflag = SMFIP_NORCPT; 1780 defresponse = "550 5.7.1 Command rejected"; 1781 break; 1782 1783 case SMFIC_HEADER: 1784 skipflag = SMFIP_NOHDRS; 1785 defresponse = "550 5.7.1 Command rejected"; 1786 break; 1787 1788 case SMFIC_BODY: 1789 skipflag = SMFIP_NOBODY; 1790 defresponse = "554 5.7.1 Command rejected"; 1791 break; 1792 1793 case SMFIC_EOH: 1794 skipflag = SMFIP_NOEOH; 1795 defresponse = "550 5.7.1 Command rejected"; 1796 break; 1797 1798 case SMFIC_BODYEOB: 1799 case SMFIC_OPTNEG: 1800 case SMFIC_MACRO: 1801 case SMFIC_ABORT: 1802 case SMFIC_QUIT: 1803 /* NOTE: not handled by milter_send_command() */ 1804 /* FALLTHROUGH */ 1805 1806 default: 1807 skipflag = 0; 1808 defresponse = "550 5.7.1 Command rejected"; 1809 break; 1810 } 1811 1812 /* check if filter wants this command */ 1813 if (skipflag != 0 && 1814 bitset(skipflag, m->mf_pflags)) 1815 return NULL; 1816 1817 1818 (void) milter_write(m, command, data, sz, 1819 m->mf_timeout[SMFTO_WRITE], e); 1820 if (m->mf_state == SMFS_ERROR) 1821 { 1822 MILTER_CHECK_ERROR(/* EMPTY */;); 1823 return NULL; 1824 } 1825 1826 response = milter_read(m, &rcmd, &rlen, 1827 m->mf_timeout[SMFTO_READ], e); 1828 if (m->mf_state == SMFS_ERROR) 1829 { 1830 MILTER_CHECK_ERROR(/* EMPTY */;); 1831 return NULL; 1832 } 1833 1834 if (tTd(64, 10)) 1835 dprintf("milter_send_command(%s): returned %c\n", 1836 m->mf_name, (char) rcmd); 1837 1838 switch (rcmd) 1839 { 1840 case SMFIR_REPLYCODE: 1841 MILTER_CHECK_REPLYCODE(defresponse); 1842 /* FALLTHROUGH */ 1843 1844 case SMFIR_REJECT: 1845 case SMFIR_DISCARD: 1846 case SMFIR_TEMPFAIL: 1847 *state = rcmd; 1848 break; 1849 1850 case SMFIR_ACCEPT: 1851 /* this filter is done with message/connection */ 1852 if (command == SMFIC_HELO || 1853 command == SMFIC_CONNECT) 1854 m->mf_state = SMFS_CLOSABLE; 1855 else 1856 m->mf_state = SMFS_DONE; 1857 break; 1858 1859 case SMFIR_CONTINUE: 1860 /* if MAIL command is ok, filter is in message state */ 1861 if (command == SMFIC_MAIL) 1862 m->mf_state = SMFS_INMSG; 1863 break; 1864 1865 default: 1866 /* Invalid response to command */ 1867 if (LogLevel > 0) 1868 sm_syslog(LOG_ERR, e->e_id, 1869 "milter_send_command(%s): returned bogus response %c", 1870 m->mf_name, rcmd); 1871 milter_error(m); 1872 break; 1873 } 1874 1875 if (*state != SMFIR_REPLYCODE && 1876 response != NULL) 1877 { 1878 sm_free(response); 1879 response = NULL; 1880 } 1881 return response; 1882} 1883 1884/* 1885** MILTER_COMMAND -- send a command and return the response for each filter 1886** 1887** Parameters: 1888** command -- command to send. 1889** data -- optional command data. 1890** sz -- length of buf. 1891** macros -- macros to send for filter smfi_getsymval(). 1892** e -- current envelope (for macro access). 1893** state -- return state word. 1894** 1895** Returns: 1896** response string (may be NULL) 1897*/ 1898 1899static char * 1900milter_command(command, data, sz, macros, e, state) 1901 char command; 1902 void *data; 1903 ssize_t sz; 1904 char **macros; 1905 ENVELOPE *e; 1906 char *state; 1907{ 1908 int i; 1909 char *response = NULL; 1910 1911 if (tTd(64, 10)) 1912 dprintf("milter_command: cmd %c len %ld\n", 1913 (char) command, (long) sz); 1914 1915 *state = SMFIR_CONTINUE; 1916 for (i = 0; InputFilters[i] != NULL; i++) 1917 { 1918 struct milter *m = InputFilters[i]; 1919 1920 /* previous problem? */ 1921 if (m->mf_state == SMFS_ERROR) 1922 { 1923 MILTER_CHECK_ERROR(continue); 1924 break; 1925 } 1926 1927 /* sanity check */ 1928 if (m->mf_sock < 0 || 1929 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) 1930 continue; 1931 1932 /* send macros (regardless of whether we send command) */ 1933 if (macros != NULL && macros[0] != NULL) 1934 { 1935 milter_send_macros(m, macros, command, e); 1936 if (m->mf_state == SMFS_ERROR) 1937 { 1938 MILTER_CHECK_ERROR(continue); 1939 break; 1940 } 1941 } 1942 1943 response = milter_send_command(m, command, data, sz, e, state); 1944 if (*state != SMFIR_CONTINUE) 1945 break; 1946 } 1947 return response; 1948} 1949/* 1950** MILTER_NEGOTIATE -- get version and flags from filter 1951** 1952** Parameters: 1953** m -- milter filter structure. 1954** e -- current envelope. 1955** 1956** Returns: 1957** 0 on success, -1 otherwise 1958*/ 1959 1960static int 1961milter_negotiate(m, e) 1962 struct milter *m; 1963 ENVELOPE *e; 1964{ 1965 char rcmd; 1966 mi_int32 fvers; 1967 mi_int32 fflags; 1968 mi_int32 pflags; 1969 char *response; 1970 ssize_t rlen; 1971 char data[MILTER_OPTLEN]; 1972 1973 /* sanity check */ 1974 if (m->mf_sock < 0 || m->mf_state != SMFS_OPEN) 1975 { 1976 if (LogLevel > 0) 1977 sm_syslog(LOG_ERR, e->e_id, 1978 "milter_negotiate(%s): impossible state", 1979 m->mf_name); 1980 milter_error(m); 1981 return -1; 1982 } 1983 1984 fvers = htonl(SMFI_VERSION); 1985 fflags = htonl(SMFI_CURR_ACTS); 1986 pflags = htonl(SMFI_CURR_PROT); 1987 (void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES); 1988 (void) memcpy(data + MILTER_LEN_BYTES, 1989 (char *) &fflags, MILTER_LEN_BYTES); 1990 (void) memcpy(data + (MILTER_LEN_BYTES * 2), 1991 (char *) &pflags, MILTER_LEN_BYTES); 1992 (void) milter_write(m, SMFIC_OPTNEG, data, sizeof data, 1993 m->mf_timeout[SMFTO_WRITE], e); 1994 1995 if (m->mf_state == SMFS_ERROR) 1996 return -1; 1997 1998 response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e); 1999 if (m->mf_state == SMFS_ERROR) 2000 return -1; 2001 2002 if (rcmd != SMFIC_OPTNEG) 2003 { 2004 if (tTd(64, 5)) 2005 dprintf("milter_negotiate(%s): returned %c instead of %c\n", 2006 m->mf_name, rcmd, SMFIC_OPTNEG); 2007 if (LogLevel > 0) 2008 sm_syslog(LOG_ERR, e->e_id, 2009 "milter_negotiate(%s): returned %c instead of %c", 2010 m->mf_name, rcmd, SMFIC_OPTNEG); 2011 if (response != NULL) 2012 sm_free(response); 2013 milter_error(m); 2014 return -1; 2015 } 2016 2017 /* Make sure we have enough bytes for the version */ 2018 if (response == NULL || rlen < MILTER_LEN_BYTES) 2019 { 2020 if (tTd(64, 5)) 2021 dprintf("milter_negotiate(%s): did not return valid info\n", 2022 m->mf_name); 2023 if (LogLevel > 0) 2024 sm_syslog(LOG_ERR, e->e_id, 2025 "milter_negotiate(%s): did not return valid info", 2026 m->mf_name); 2027 if (response != NULL) 2028 sm_free(response); 2029 milter_error(m); 2030 return -1; 2031 } 2032 2033 /* extract information */ 2034 (void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES); 2035 2036 /* Now make sure we have enough for the feature bitmap */ 2037 if (rlen != MILTER_OPTLEN) 2038 { 2039 if (tTd(64, 5)) 2040 dprintf("milter_negotiate(%s): did not return enough info\n", 2041 m->mf_name); 2042 if (LogLevel > 0) 2043 sm_syslog(LOG_ERR, e->e_id, 2044 "milter_negotiate(%s): did not return enough info", 2045 m->mf_name); 2046 if (response != NULL) 2047 sm_free(response); 2048 milter_error(m); 2049 return -1; 2050 } 2051 2052 (void) memcpy((char *) &fflags, response + MILTER_LEN_BYTES, 2053 MILTER_LEN_BYTES); 2054 (void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2), 2055 MILTER_LEN_BYTES); 2056 sm_free(response); 2057 response = NULL; 2058 2059 m->mf_fvers = ntohl(fvers); 2060 m->mf_fflags = ntohl(fflags); 2061 m->mf_pflags = ntohl(pflags); 2062 2063 /* check for version compatibility */ 2064 if (m->mf_fvers == 1 || 2065 m->mf_fvers > SMFI_VERSION) 2066 { 2067 if (tTd(64, 5)) 2068 dprintf("milter_negotiate(%s): version %lu != MTA milter version %d\n", 2069 m->mf_name, m->mf_fvers, SMFI_VERSION); 2070 if (LogLevel > 0) 2071 sm_syslog(LOG_ERR, e->e_id, 2072 "milter_negotiate(%s): version %ld != MTA milter version %d", 2073 m->mf_name, m->mf_fvers, SMFI_VERSION); 2074 milter_error(m); 2075 return -1; 2076 } 2077 2078 /* check for filter feature mismatch */ 2079 if ((m->mf_fflags & SMFI_CURR_ACTS) != m->mf_fflags) 2080 { 2081 if (tTd(64, 5)) 2082 dprintf("milter_negotiate(%s): filter abilities 0x%lx != MTA milter abilities 0x%lx\n", 2083 m->mf_name, m->mf_fflags, 2084 (u_long) SMFI_CURR_ACTS); 2085 if (LogLevel > 0) 2086 sm_syslog(LOG_ERR, e->e_id, 2087 "milter_negotiate(%s): filter abilities 0x%lx != MTA milter abilities 0x%lx\n", 2088 m->mf_name, m->mf_fflags, 2089 (u_long) SMFI_CURR_ACTS); 2090 milter_error(m); 2091 return -1; 2092 } 2093 2094 /* check for protocol feature mismatch */ 2095 if ((m->mf_pflags & SMFI_CURR_PROT) != m->mf_pflags) 2096 { 2097 if (tTd(64, 5)) 2098 dprintf("milter_negotiate(%s): protocol abilities 0x%lx != MTA milter abilities 0x%lx\n", 2099 m->mf_name, m->mf_pflags, 2100 (u_long) SMFI_CURR_PROT); 2101 if (LogLevel > 0) 2102 sm_syslog(LOG_ERR, e->e_id, 2103 "milter_negotiate(%s): protocol abilities 0x%lx != MTA milter abilities 0x%lx\n", 2104 m->mf_name, m->mf_pflags, 2105 (u_long) SMFI_CURR_PROT); 2106 milter_error(m); 2107 return -1; 2108 } 2109 2110 if (tTd(64, 5)) 2111 dprintf("milter_negotiate(%s): version %lu, fflags 0x%lx, pflags 0x%lx\n", 2112 m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags); 2113 return 0; 2114} 2115/* 2116** MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands 2117** 2118** Reduce code duplication by putting these checks in one place 2119** 2120** Parameters: 2121** e -- current envelope. 2122** 2123** Returns: 2124** none 2125*/ 2126 2127static void 2128milter_per_connection_check(e) 2129 ENVELOPE *e; 2130{ 2131 int i; 2132 2133 /* see if we are done with any of the filters */ 2134 for (i = 0; InputFilters[i] != NULL; i++) 2135 { 2136 struct milter *m = InputFilters[i]; 2137 2138 if (m->mf_state == SMFS_CLOSABLE) 2139 milter_quit_filter(m, e); 2140 } 2141} 2142/* 2143** MILTER_ERROR -- Put a milter filter into error state 2144** 2145** Parameters: 2146** m -- the broken filter. 2147** 2148** Returns: 2149** none 2150*/ 2151 2152static void 2153milter_error(m) 2154 struct milter *m; 2155{ 2156 /* 2157 ** We could send a quit here but 2158 ** we may have gotten here due to 2159 ** an I/O error so we don't want 2160 ** to try to make things worse. 2161 */ 2162 2163 if (m->mf_sock >= 0) 2164 { 2165 (void) close(m->mf_sock); 2166 m->mf_sock = -1; 2167 } 2168 m->mf_state = SMFS_ERROR; 2169} 2170/* 2171** MILTER_HEADERS -- send headers to a single milter filter 2172** 2173** Parameters: 2174** m -- current filter. 2175** e -- current envelope. 2176** state -- return state from response. 2177** 2178** Returns: 2179** response string (may be NULL) 2180*/ 2181 2182static char * 2183milter_headers(m, e, state) 2184 struct milter *m; 2185 ENVELOPE *e; 2186 char *state; 2187{ 2188 char *response = NULL; 2189 HDR *h; 2190 2191 for (h = e->e_header; h != NULL; h = h->h_link) 2192 { 2193 char *buf; 2194 ssize_t s; 2195 2196 /* don't send over deleted headers */ 2197 if (h->h_value == NULL) 2198 { 2199 /* strip H_USER so not counted in milter_chgheader() */ 2200 h->h_flags &= ~H_USER; 2201 continue; 2202 } 2203 2204 /* skip auto-generated */ 2205 if (!bitset(H_USER, h->h_flags)) 2206 continue; 2207 2208 if (tTd(64, 10)) 2209 dprintf("milter_headers: %s: %s\n", 2210 h->h_field, h->h_value); 2211 2212 s = strlen(h->h_field) + 1 + 2213 strlen(h->h_value) + 1; 2214 buf = (char *) xalloc(s); 2215 snprintf(buf, s, "%s%c%s", h->h_field, '\0', h->h_value); 2216 2217 /* send it over */ 2218 response = milter_send_command(m, SMFIC_HEADER, buf, 2219 s, e, state); 2220 sm_free(buf); 2221 if (m->mf_state == SMFS_ERROR || 2222 m->mf_state == SMFS_DONE || 2223 *state != SMFIR_CONTINUE) 2224 break; 2225 } 2226 return response; 2227} 2228/* 2229** MILTER_BODY -- send the body to a filter 2230** 2231** Parameters: 2232** m -- current filter. 2233** e -- current envelope. 2234** state -- return state from response. 2235** 2236** Returns: 2237** response string (may be NULL) 2238*/ 2239 2240static char * 2241milter_body(m, e, state) 2242 struct milter *m; 2243 ENVELOPE *e; 2244 char *state; 2245{ 2246 char bufchar = '\0'; 2247 char prevchar = '\0'; 2248 int c; 2249 char *response = NULL; 2250 char *bp; 2251 char buf[MILTER_CHUNK_SIZE]; 2252 2253 if (tTd(64, 10)) 2254 dprintf("milter_body\n"); 2255 2256 if (bfrewind(e->e_dfp) < 0) 2257 { 2258 ExitStat = EX_IOERR; 2259 *state = SMFIR_TEMPFAIL; 2260 syserr("milter_body: %s/df%s: rewind error", 2261 qid_printqueue(e->e_queuedir), e->e_id); 2262 return NULL; 2263 } 2264 2265 bp = buf; 2266 while ((c = getc(e->e_dfp)) != EOF) 2267 { 2268 /* Change LF to CRLF */ 2269 if (c == '\n') 2270 { 2271 /* Not a CRLF already? */ 2272 if (prevchar != '\r') 2273 { 2274 /* Room for CR now? */ 2275 if (bp + 2 > &buf[sizeof buf]) 2276 { 2277 /* No room, buffer LF */ 2278 bufchar = c; 2279 2280 /* and send CR now */ 2281 c = '\r'; 2282 } 2283 else 2284 { 2285 /* Room to do it now */ 2286 *bp++ = '\r'; 2287 prevchar = '\r'; 2288 } 2289 } 2290 } 2291 *bp++ = (char) c; 2292 prevchar = c; 2293 if (bp >= &buf[sizeof buf]) 2294 { 2295 /* send chunk */ 2296 response = milter_send_command(m, SMFIC_BODY, buf, 2297 bp - buf, e, state); 2298 bp = buf; 2299 if (bufchar != '\0') 2300 { 2301 *bp++ = bufchar; 2302 bufchar = '\0'; 2303 prevchar = bufchar; 2304 } 2305 } 2306 if (m->mf_state == SMFS_ERROR || 2307 m->mf_state == SMFS_DONE || 2308 *state != SMFIR_CONTINUE) 2309 break; 2310 } 2311 2312 /* check for read errors */ 2313 if (ferror(e->e_dfp)) 2314 { 2315 ExitStat = EX_IOERR; 2316 if (*state == SMFIR_CONTINUE || 2317 *state == SMFIR_ACCEPT) 2318 { 2319 *state = SMFIR_TEMPFAIL; 2320 if (response != NULL) 2321 { 2322 sm_free(response); 2323 response = NULL; 2324 } 2325 } 2326 syserr("milter_body: %s/df%s: read error", 2327 qid_printqueue(e->e_queuedir), e->e_id); 2328 return response; 2329 } 2330 2331 /* send last body chunk */ 2332 if (bp > buf && 2333 m->mf_state != SMFS_ERROR && 2334 m->mf_state != SMFS_DONE && 2335 *state == SMFIR_CONTINUE) 2336 { 2337 /* send chunk */ 2338 response = milter_send_command(m, SMFIC_BODY, buf, bp - buf, 2339 e, state); 2340 bp = buf; 2341 } 2342 return response; 2343} 2344 2345/* 2346** Actions 2347*/ 2348 2349/* 2350** MILTER_ADDHEADER -- Add the supplied header to the message 2351** 2352** Parameters: 2353** response -- encoded form of header/value. 2354** rlen -- length of response. 2355** e -- current envelope. 2356** 2357** Returns: 2358** none 2359*/ 2360 2361static void 2362milter_addheader(response, rlen, e) 2363 char *response; 2364 ssize_t rlen; 2365 ENVELOPE *e; 2366{ 2367 char *val; 2368 HDR *h; 2369 2370 if (tTd(64, 10)) 2371 dprintf("milter_addheader: "); 2372 2373 /* sanity checks */ 2374 if (response == NULL) 2375 { 2376 if (tTd(64, 10)) 2377 dprintf("NULL response\n"); 2378 return; 2379 } 2380 2381 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 2382 { 2383 if (tTd(64, 10)) 2384 dprintf("didn't follow protocol (total len)\n"); 2385 return; 2386 } 2387 2388 /* Find separating NUL */ 2389 val = response + strlen(response) + 1; 2390 2391 /* another sanity check */ 2392 if (strlen(response) + strlen(val) + 2 != (size_t) rlen) 2393 { 2394 if (tTd(64, 10)) 2395 dprintf("didn't follow protocol (part len)\n"); 2396 return; 2397 } 2398 2399 if (*response == '\0') 2400 { 2401 if (tTd(64, 10)) 2402 dprintf("empty field name\n"); 2403 return; 2404 } 2405 2406 for (h = e->e_header; h != NULL; h = h->h_link) 2407 { 2408 if (strcasecmp(h->h_field, response) == 0 && 2409 !bitset(H_USER, h->h_flags) && 2410 !bitset(H_TRACE, h->h_flags)) 2411 break; 2412 } 2413 2414 /* add to e_msgsize */ 2415 e->e_msgsize += strlen(response) + 2 + strlen(val); 2416 2417 if (h != NULL) 2418 { 2419 if (tTd(64, 10)) 2420 dprintf("Replace default header %s value with %s\n", 2421 h->h_field, val); 2422 h->h_value = newstr(val); 2423 h->h_flags |= H_USER; 2424 } 2425 else 2426 { 2427 if (tTd(64, 10)) 2428 dprintf("Add %s: %s\n", response, val); 2429 addheader(newstr(response), val, H_USER, &e->e_header); 2430 } 2431} 2432/* 2433** MILTER_CHANGEHEADER -- Change the supplied header in the message 2434** 2435** Parameters: 2436** response -- encoded form of header/index/value. 2437** rlen -- length of response. 2438** e -- current envelope. 2439** 2440** Returns: 2441** none 2442*/ 2443 2444static void 2445milter_changeheader(response, rlen, e) 2446 char *response; 2447 ssize_t rlen; 2448 ENVELOPE *e; 2449{ 2450 mi_int32 i, index; 2451 char *field, *val; 2452 HDR *h, *sysheader; 2453 2454 if (tTd(64, 10)) 2455 dprintf("milter_changeheader: "); 2456 2457 /* sanity checks */ 2458 if (response == NULL) 2459 { 2460 if (tTd(64, 10)) 2461 dprintf("NULL response\n"); 2462 return; 2463 } 2464 2465 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 2466 { 2467 if (tTd(64, 10)) 2468 dprintf("didn't follow protocol (total len)\n"); 2469 return; 2470 } 2471 2472 /* Find separating NUL */ 2473 (void) memcpy((char *) &i, response, MILTER_LEN_BYTES); 2474 index = ntohl(i); 2475 field = response + MILTER_LEN_BYTES; 2476 val = field + strlen(field) + 1; 2477 2478 /* another sanity check */ 2479 if (MILTER_LEN_BYTES + strlen(field) + 1 + 2480 strlen(val) + 1 != (size_t) rlen) 2481 { 2482 if (tTd(64, 10)) 2483 dprintf("didn't follow protocol (part len)\n"); 2484 return; 2485 } 2486 2487 if (*field == '\0') 2488 { 2489 if (tTd(64, 10)) 2490 dprintf("empty field name\n"); 2491 return; 2492 } 2493 2494 sysheader = NULL; 2495 for (h = e->e_header; h != NULL; h = h->h_link) 2496 { 2497 if (strcasecmp(h->h_field, field) == 0) 2498 { 2499 if (bitset(H_USER, h->h_flags) && 2500 --index <= 0) 2501 { 2502 sysheader = NULL; 2503 break; 2504 } 2505 else if (!bitset(H_USER, h->h_flags) && 2506 !bitset(H_TRACE, h->h_flags)) 2507 { 2508 /* 2509 ** DRUMS msg-fmt draft says can only have 2510 ** multiple occurences of trace fields, 2511 ** so make sure we replace any non-trace, 2512 ** non-user field. 2513 */ 2514 2515 sysheader = h; 2516 } 2517 } 2518 } 2519 2520 /* if not found as user-provided header at index, use sysheader */ 2521 if (h == NULL) 2522 h = sysheader; 2523 2524 if (h == NULL) 2525 { 2526 if (*val == '\0') 2527 { 2528 if (tTd(64, 10)) 2529 dprintf("Delete (noop) %s:\n", field); 2530 } 2531 else 2532 { 2533 /* treat modify value with no existing header as add */ 2534 if (tTd(64, 10)) 2535 dprintf("Add %s: %s\n", field, val); 2536 2537 addheader(newstr(field), val, H_USER, &e->e_header); 2538 } 2539 return; 2540 } 2541 2542 if (tTd(64, 10)) 2543 { 2544 if (*val == '\0') 2545 { 2546 dprintf("Delete%s %s: %s\n", 2547 h == sysheader ? " (default header)" : "", 2548 field, 2549 h->h_value == NULL ? "<NULL>" : h->h_value); 2550 } 2551 else 2552 { 2553 dprintf("Change%s %s: from %s to %s\n", 2554 h == sysheader ? " (default header)" : "", 2555 field, 2556 h->h_value == NULL ? "<NULL>" : h->h_value, 2557 val); 2558 } 2559 } 2560 2561 if (h != sysheader && h->h_value != NULL) 2562 { 2563 e->e_msgsize -= strlen(h->h_value); 2564 sm_free(h->h_value); 2565 } 2566 2567 if (*val == '\0') 2568 { 2569 /* Remove "Field: " from message size */ 2570 if (h != sysheader) 2571 e->e_msgsize -= strlen(h->h_field) + 2; 2572 h->h_value = NULL; 2573 } 2574 else 2575 { 2576 h->h_value = newstr(val); 2577 h->h_flags |= H_USER; 2578 e->e_msgsize += strlen(h->h_value); 2579 } 2580} 2581/* 2582** MILTER_ADDRCPT -- Add the supplied recipient to the message 2583** 2584** Parameters: 2585** response -- encoded form of recipient address. 2586** rlen -- length of response. 2587** e -- current envelope. 2588** 2589** Returns: 2590** none 2591*/ 2592 2593static void 2594milter_addrcpt(response, rlen, e) 2595 char *response; 2596 ssize_t rlen; 2597 ENVELOPE *e; 2598{ 2599 if (tTd(64, 10)) 2600 dprintf("milter_addrcpt: "); 2601 2602 /* sanity checks */ 2603 if (response == NULL) 2604 { 2605 if (tTd(64, 10)) 2606 dprintf("NULL response\n"); 2607 return; 2608 } 2609 2610 if (*response == '\0' || 2611 strlen(response) + 1 != (size_t) rlen) 2612 { 2613 if (tTd(64, 10)) 2614 dprintf("didn't follow protocol (total len %d != rlen %d)\n", 2615 strlen(response), rlen -1); 2616 return; 2617 } 2618 2619 if (tTd(64, 10)) 2620 dprintf("%s\n", response); 2621 (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e); 2622 return; 2623} 2624/* 2625** MILTER_DELRCPT -- Delete the supplied recipient from the message 2626** 2627** Parameters: 2628** response -- encoded form of recipient address. 2629** rlen -- length of response. 2630** e -- current envelope. 2631** 2632** Returns: 2633** none 2634*/ 2635 2636static void 2637milter_delrcpt(response, rlen, e) 2638 char *response; 2639 ssize_t rlen; 2640 ENVELOPE *e; 2641{ 2642 if (tTd(64, 10)) 2643 dprintf("milter_delrcpt: "); 2644 2645 /* sanity checks */ 2646 if (response == NULL) 2647 { 2648 if (tTd(64, 10)) 2649 dprintf("NULL response\n"); 2650 return; 2651 } 2652 2653 if (*response == '\0' || 2654 strlen(response) + 1 != (size_t) rlen) 2655 { 2656 if (tTd(64, 10)) 2657 dprintf("didn't follow protocol (total len)\n"); 2658 return; 2659 } 2660 2661 if (tTd(64, 10)) 2662 dprintf("%s\n", response); 2663 (void) removefromlist(response, &e->e_sendqueue, e); 2664 return; 2665} 2666/* 2667** MILTER_REPLBODY -- Replace the current df file with new body 2668** 2669** Parameters: 2670** response -- encoded form of new body. 2671** rlen -- length of response. 2672** newfilter -- if first time called by a new filter 2673** e -- current envelope. 2674** 2675** Returns: 2676** 0 upon success, -1 upon failure 2677*/ 2678 2679static int 2680milter_replbody(response, rlen, newfilter, e) 2681 char *response; 2682 ssize_t rlen; 2683 bool newfilter; 2684 ENVELOPE *e; 2685{ 2686 static char prevchar; 2687 int i; 2688 2689 if (tTd(64, 10)) 2690 dprintf("milter_replbody\n"); 2691 2692 /* If a new filter, reset previous character and truncate df */ 2693 if (newfilter) 2694 { 2695 off_t prevsize = 0; 2696 char dfname[MAXPATHLEN]; 2697 2698 (void) strlcpy(dfname, queuename(e, 'd'), sizeof dfname); 2699 2700 /* Reset prevchar */ 2701 prevchar = '\0'; 2702 2703 /* Get the current df information */ 2704 if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL) 2705 { 2706 int afd; 2707 struct stat st; 2708 2709 afd = fileno(e->e_dfp); 2710 if (afd > 0 && fstat(afd, &st) == 0) 2711 prevsize = st.st_size; 2712 } 2713 2714 /* truncate current df file */ 2715 if (bftruncate(e->e_dfp) < 0) 2716 { 2717 MILTER_DF_ERROR("milter_reopen_df: bftruncate %s: %s"); 2718 return -1; 2719 } 2720 else 2721 { 2722 if (prevsize > e->e_msgsize) 2723 e->e_msgsize = 0; 2724 else 2725 e->e_msgsize -= prevsize; 2726 } 2727 } 2728 2729 if (response == NULL) 2730 { 2731 /* Flush the buffered '\r' */ 2732 if (prevchar == '\r') 2733 { 2734 (void) putc(prevchar, e->e_dfp); 2735 e->e_msgsize++; 2736 } 2737 return 0; 2738 } 2739 2740 for (i = 0; i < rlen; i++) 2741 { 2742 /* Buffered char from last chunk */ 2743 if (i == 0 && prevchar == '\r') 2744 { 2745 /* Not CRLF, output prevchar */ 2746 if (response[i] != '\n') 2747 { 2748 (void) putc(prevchar, e->e_dfp); 2749 e->e_msgsize++; 2750 } 2751 prevchar = '\0'; 2752 } 2753 2754 /* Turn CRLF into LF */ 2755 if (response[i] == '\r') 2756 { 2757 /* check if at end of chunk */ 2758 if (i + 1 < rlen) 2759 { 2760 /* If LF, strip CR */ 2761 if (response[i + 1] == '\n') 2762 i++; 2763 } 2764 else 2765 { 2766 /* check next chunk */ 2767 prevchar = '\r'; 2768 continue; 2769 } 2770 } 2771 (void) putc(response[i], e->e_dfp); 2772 e->e_msgsize++; 2773 } 2774 return 0; 2775} 2776 2777/* 2778** MTA callouts 2779*/ 2780 2781/* 2782** MILTER_INIT -- open and negotiate with all of the filters 2783** 2784** Parameters: 2785** e -- current envelope. 2786** state -- return state from response. 2787** 2788** Returns: 2789** none 2790*/ 2791 2792/* ARGSUSED */ 2793void 2794milter_init(e, state) 2795 ENVELOPE *e; 2796 char *state; 2797{ 2798 int i; 2799 2800 if (tTd(64, 10)) 2801 dprintf("milter_init\n"); 2802 2803 *state = SMFIR_CONTINUE; 2804 for (i = 0; InputFilters[i] != NULL; i++) 2805 { 2806 struct milter *m = InputFilters[i]; 2807 2808 m->mf_sock = milter_open(m, FALSE, e); 2809 if (m->mf_state == SMFS_ERROR) 2810 { 2811 MILTER_CHECK_ERROR(continue); 2812 break; 2813 } 2814 2815 if (m->mf_sock < 0 || 2816 milter_negotiate(m, e) < 0 || 2817 m->mf_state == SMFS_ERROR) 2818 { 2819 if (tTd(64, 5)) 2820 dprintf("milter_init(%s): failed to %s\n", 2821 m->mf_name, 2822 m->mf_sock < 0 ? "open" : "negotiate"); 2823 2824 /* if negotation failure, close socket */ 2825 milter_error(m); 2826 MILTER_CHECK_ERROR(continue); 2827 } 2828 } 2829 2830 /* 2831 ** If something temp/perm failed with one of the filters, 2832 ** we won't be using any of them, so clear any existing 2833 ** connections. 2834 */ 2835 2836 if (*state != SMFIR_CONTINUE) 2837 milter_quit(e); 2838} 2839/* 2840** MILTER_CONNECT -- send connection info to milter filters 2841** 2842** Parameters: 2843** hostname -- hostname of remote machine. 2844** addr -- address of remote machine. 2845** e -- current envelope. 2846** state -- return state from response. 2847** 2848** Returns: 2849** response string (may be NULL) 2850*/ 2851 2852char * 2853milter_connect(hostname, addr, e, state) 2854 char *hostname; 2855 SOCKADDR addr; 2856 ENVELOPE *e; 2857 char *state; 2858{ 2859 char family; 2860 u_short port; 2861 char *buf, *bp; 2862 char *response; 2863 char *sockinfo = NULL; 2864 ssize_t s; 2865# if NETINET6 2866 char buf6[INET6_ADDRSTRLEN]; 2867# endif /* NETINET6 */ 2868 2869 if (tTd(64, 10)) 2870 dprintf("milter_connect(%s)\n", hostname); 2871 2872 /* gather data */ 2873 switch (addr.sa.sa_family) 2874 { 2875# if NETUNIX 2876 case AF_UNIX: 2877 family = SMFIA_UNIX; 2878 port = htons(0); 2879 sockinfo = addr.sunix.sun_path; 2880 break; 2881# endif /* NETUNIX */ 2882 2883# if NETINET 2884 case AF_INET: 2885 family = SMFIA_INET; 2886 port = htons(addr.sin.sin_port); 2887 sockinfo = (char *) inet_ntoa(addr.sin.sin_addr); 2888 break; 2889# endif /* NETINET */ 2890 2891# if NETINET6 2892 case AF_INET6: 2893 if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr)) 2894 family = SMFIA_INET; 2895 else 2896 family = SMFIA_INET6; 2897 port = htons(addr.sin6.sin6_port); 2898 sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6, 2899 sizeof buf6); 2900 if (sockinfo == NULL) 2901 sockinfo = ""; 2902 break; 2903# endif /* NETINET6 */ 2904 2905 default: 2906 family = SMFIA_UNKNOWN; 2907 break; 2908 } 2909 2910 s = strlen(hostname) + 1 + sizeof(family); 2911 if (family != SMFIA_UNKNOWN) 2912 s += sizeof(port) + strlen(sockinfo) + 1; 2913 2914 buf = (char *)xalloc(s); 2915 bp = buf; 2916 2917 /* put together data */ 2918 (void) memcpy(bp, hostname, strlen(hostname)); 2919 bp += strlen(hostname); 2920 *bp++ = '\0'; 2921 (void) memcpy(bp, &family, sizeof family); 2922 bp += sizeof family; 2923 if (family != SMFIA_UNKNOWN) 2924 { 2925 (void) memcpy(bp, &port, sizeof port); 2926 bp += sizeof port; 2927 2928 /* include trailing '\0' */ 2929 (void) memcpy(bp, sockinfo, strlen(sockinfo) + 1); 2930 } 2931 2932 response = milter_command(SMFIC_CONNECT, buf, s, 2933 MilterConnectMacros, e, state); 2934 sm_free(buf); 2935 2936 /* 2937 ** If this message connection is done for, 2938 ** close the filters. 2939 */ 2940 2941 if (*state != SMFIR_CONTINUE) 2942 milter_quit(e); 2943 else 2944 milter_per_connection_check(e); 2945 2946 /* 2947 ** SMFIR_REPLYCODE can't work with connect due to 2948 ** the requirements of SMTP. Therefore, ignore the 2949 ** reply code text but keep the state it would reflect. 2950 */ 2951 2952 if (*state == SMFIR_REPLYCODE) 2953 { 2954 if (response != NULL && 2955 *response == '4') 2956 *state = SMFIR_TEMPFAIL; 2957 else 2958 *state = SMFIR_REJECT; 2959 if (response != NULL) 2960 { 2961 sm_free(response); 2962 response = NULL; 2963 } 2964 } 2965 return response; 2966} 2967/* 2968** MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters 2969** 2970** Parameters: 2971** helo -- argument to SMTP HELO/EHLO command. 2972** e -- current envelope. 2973** state -- return state from response. 2974** 2975** Returns: 2976** response string (may be NULL) 2977*/ 2978 2979char * 2980milter_helo(helo, e, state) 2981 char *helo; 2982 ENVELOPE *e; 2983 char *state; 2984{ 2985 int i; 2986 char *response; 2987 2988 if (tTd(64, 10)) 2989 dprintf("milter_helo(%s)\n", helo); 2990 2991 /* HELO/EHLO can come after encryption is negotiated */ 2992 for (i = 0; InputFilters[i] != NULL; i++) 2993 { 2994 struct milter *m = InputFilters[i]; 2995 2996 switch (m->mf_state) 2997 { 2998 case SMFS_INMSG: 2999 /* abort in message filters */ 3000 milter_abort_filter(m, e); 3001 /* FALLTHROUGH */ 3002 3003 case SMFS_DONE: 3004 /* reset done filters */ 3005 m->mf_state = SMFS_OPEN; 3006 break; 3007 } 3008 } 3009 3010 response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1, 3011 MilterHeloMacros, e, state); 3012 milter_per_connection_check(e); 3013 return response; 3014} 3015/* 3016** MILTER_ENVFROM -- send SMTP MAIL command info to milter filters 3017** 3018** Parameters: 3019** args -- SMTP MAIL command args (args[0] == sender). 3020** e -- current envelope. 3021** state -- return state from response. 3022** 3023** Returns: 3024** response string (may be NULL) 3025*/ 3026 3027char * 3028milter_envfrom(args, e, state) 3029 char **args; 3030 ENVELOPE *e; 3031 char *state; 3032{ 3033 int i; 3034 char *buf, *bp; 3035 char *response; 3036 ssize_t s; 3037 3038 if (tTd(64, 10)) 3039 { 3040 dprintf("milter_envfrom:"); 3041 for (i = 0; args[i] != NULL; i++) 3042 dprintf(" %s", args[i]); 3043 dprintf("\n"); 3044 } 3045 3046 /* sanity check */ 3047 if (args[0] == NULL) 3048 { 3049 *state = SMFIR_REJECT; 3050 return NULL; 3051 } 3052 3053 /* new message, so ... */ 3054 for (i = 0; InputFilters[i] != NULL; i++) 3055 { 3056 struct milter *m = InputFilters[i]; 3057 3058 switch (m->mf_state) 3059 { 3060 case SMFS_INMSG: 3061 /* abort in message filters */ 3062 milter_abort_filter(m, e); 3063 /* FALLTHROUGH */ 3064 3065 case SMFS_DONE: 3066 /* reset done filters */ 3067 m->mf_state = SMFS_OPEN; 3068 break; 3069 } 3070 } 3071 3072 /* put together data */ 3073 s = 0; 3074 for (i = 0; args[i] != NULL; i++) 3075 s += strlen(args[i]) + 1; 3076 buf = (char *)xalloc(s); 3077 bp = buf; 3078 for (i = 0; args[i] != NULL; i++) 3079 { 3080 (void) strlcpy(bp, args[i], s - (bp - buf)); 3081 bp += strlen(bp) + 1; 3082 } 3083 3084 /* send it over */ 3085 response = milter_command(SMFIC_MAIL, buf, s, 3086 MilterEnvFromMacros, e, state); 3087 sm_free(buf); 3088 3089 /* 3090 ** If filter rejects/discards a per message command, 3091 ** abort the other filters since we are done with the 3092 ** current message. 3093 */ 3094 3095 MILTER_CHECK_DONE_MSG(); 3096 return response; 3097} 3098/* 3099** MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters 3100** 3101** Parameters: 3102** args -- SMTP MAIL command args (args[0] == recipient). 3103** e -- current envelope. 3104** state -- return state from response. 3105** 3106** Returns: 3107** response string (may be NULL) 3108*/ 3109 3110char * 3111milter_envrcpt(args, e, state) 3112 char **args; 3113 ENVELOPE *e; 3114 char *state; 3115{ 3116 int i; 3117 char *buf, *bp; 3118 char *response; 3119 ssize_t s; 3120 3121 if (tTd(64, 10)) 3122 { 3123 dprintf("milter_envrcpt:"); 3124 for (i = 0; args[i] != NULL; i++) 3125 dprintf(" %s", args[i]); 3126 dprintf("\n"); 3127 } 3128 3129 /* sanity check */ 3130 if (args[0] == NULL) 3131 { 3132 *state = SMFIR_REJECT; 3133 return NULL; 3134 } 3135 3136 /* put together data */ 3137 s = 0; 3138 for (i = 0; args[i] != NULL; i++) 3139 s += strlen(args[i]) + 1; 3140 buf = (char *)xalloc(s); 3141 bp = buf; 3142 for (i = 0; args[i] != NULL; i++) 3143 { 3144 (void) strlcpy(bp, args[i], s - (bp - buf)); 3145 bp += strlen(bp) + 1; 3146 } 3147 3148 /* send it over */ 3149 response = milter_command(SMFIC_RCPT, buf, s, 3150 MilterEnvRcptMacros, e, state); 3151 sm_free(buf); 3152 return response; 3153} 3154/* 3155** MILTER_DATA -- send message headers/body and gather final message results 3156** 3157** Parameters: 3158** e -- current envelope. 3159** state -- return state from response. 3160** 3161** Returns: 3162** response string (may be NULL) 3163** 3164** Side effects: 3165** - Uses e->e_dfp for access to the body 3166** - Can call the various milter action routines to 3167** modify the envelope or message. 3168*/ 3169 3170# define MILTER_CHECK_RESULTS() \ 3171 if (*state == SMFIR_ACCEPT || \ 3172 m->mf_state == SMFS_DONE || \ 3173 m->mf_state == SMFS_ERROR) \ 3174 { \ 3175 if (m->mf_state != SMFS_ERROR) \ 3176 m->mf_state = SMFS_DONE; \ 3177 continue; /* to next filter */ \ 3178 } \ 3179 if (*state != SMFIR_CONTINUE) \ 3180 { \ 3181 m->mf_state = SMFS_DONE; \ 3182 goto finishup; \ 3183 } 3184 3185char * 3186milter_data(e, state) 3187 ENVELOPE *e; 3188 char *state; 3189{ 3190 bool replbody = FALSE; /* milter_replbody() called? */ 3191 bool replfailed = FALSE; /* milter_replbody() failed? */ 3192 bool rewind = FALSE; /* rewind df file? */ 3193 bool dfopen = FALSE; /* df open for writing? */ 3194 bool newfilter; /* reset on each new filter */ 3195 char rcmd; 3196 int i; 3197 int save_errno; 3198 char *response = NULL; 3199 time_t eomsent; 3200 ssize_t rlen; 3201 3202 if (tTd(64, 10)) 3203 dprintf("milter_data\n"); 3204 3205 *state = SMFIR_CONTINUE; 3206 3207 /* 3208 ** XXX: Should actually send body chunks to each filter 3209 ** a chunk at a time instead of sending the whole body to 3210 ** each filter in turn. However, only if the filters don't 3211 ** change the body. 3212 */ 3213 3214 for (i = 0; InputFilters[i] != NULL; i++) 3215 { 3216 struct milter *m = InputFilters[i]; 3217 3218 if (*state != SMFIR_CONTINUE && 3219 *state != SMFIR_ACCEPT) 3220 { 3221 /* 3222 ** A previous filter has dealt with the message, 3223 ** safe to stop processing the filters. 3224 */ 3225 3226 break; 3227 } 3228 3229 /* Now reset state for later evaluation */ 3230 *state = SMFIR_CONTINUE; 3231 newfilter = TRUE; 3232 3233 /* previous problem? */ 3234 if (m->mf_state == SMFS_ERROR) 3235 { 3236 MILTER_CHECK_ERROR(continue); 3237 break; 3238 } 3239 3240 /* sanity checks */ 3241 if (m->mf_sock < 0 || 3242 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) 3243 continue; 3244 3245 m->mf_state = SMFS_INMSG; 3246 3247 /* check if filter wants the headers */ 3248 if (!bitset(SMFIP_NOHDRS, m->mf_pflags)) 3249 { 3250 response = milter_headers(m, e, state); 3251 MILTER_CHECK_RESULTS(); 3252 } 3253 3254 /* check if filter wants EOH */ 3255 if (!bitset(SMFIP_NOEOH, m->mf_pflags)) 3256 { 3257 if (tTd(64, 10)) 3258 dprintf("milter_data: eoh\n"); 3259 3260 /* send it over */ 3261 response = milter_send_command(m, SMFIC_EOH, NULL, 0, 3262 e, state); 3263 MILTER_CHECK_RESULTS(); 3264 } 3265 3266 /* check if filter wants the body */ 3267 if (!bitset(SMFIP_NOBODY, m->mf_pflags) && 3268 e->e_dfp != NULL) 3269 { 3270 rewind = TRUE; 3271 response = milter_body(m, e, state); 3272 MILTER_CHECK_RESULTS(); 3273 } 3274 3275 /* send the final body chunk */ 3276 (void) milter_write(m, SMFIC_BODYEOB, NULL, 0, 3277 m->mf_timeout[SMFTO_WRITE], e); 3278 3279 /* Get time EOM sent for timeout */ 3280 eomsent = curtime(); 3281 3282 /* deal with the possibility of multiple responses */ 3283 while (*state == SMFIR_CONTINUE) 3284 { 3285 /* Check total timeout from EOM to final ACK/NAK */ 3286 if (m->mf_timeout[SMFTO_EOM] > 0 && 3287 curtime() - eomsent >= m->mf_timeout[SMFTO_EOM]) 3288 { 3289 if (tTd(64, 5)) 3290 dprintf("milter_data(%s): EOM ACK/NAK timeout\n", 3291 m->mf_name); 3292 if (LogLevel > 0) 3293 sm_syslog(LOG_ERR, e->e_id, 3294 "milter_data(%s): EOM ACK/NAK timeout\n", 3295 m->mf_name); 3296 milter_error(m); 3297 MILTER_CHECK_ERROR(continue); 3298 break; 3299 } 3300 3301 response = milter_read(m, &rcmd, &rlen, 3302 m->mf_timeout[SMFTO_READ], e); 3303 if (m->mf_state == SMFS_ERROR) 3304 break; 3305 3306 if (tTd(64, 10)) 3307 dprintf("milter_data(%s): state %c\n", 3308 m->mf_name, (char) rcmd); 3309 3310 switch (rcmd) 3311 { 3312 case SMFIR_REPLYCODE: 3313 MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected"); 3314 *state = rcmd; 3315 m->mf_state = SMFS_DONE; 3316 break; 3317 3318 case SMFIR_REJECT: 3319 case SMFIR_DISCARD: 3320 case SMFIR_TEMPFAIL: 3321 *state = rcmd; 3322 m->mf_state = SMFS_DONE; 3323 break; 3324 3325 case SMFIR_CONTINUE: 3326 case SMFIR_ACCEPT: 3327 /* this filter is done with message */ 3328 if (replfailed) 3329 *state = SMFIR_TEMPFAIL; 3330 else 3331 *state = SMFIR_ACCEPT; 3332 m->mf_state = SMFS_DONE; 3333 break; 3334 3335 case SMFIR_PROGRESS: 3336 break; 3337 3338 case SMFIR_ADDHEADER: 3339 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags)) 3340 { 3341 if (LogLevel > 9) 3342 sm_syslog(LOG_WARNING, e->e_id, 3343 "milter_data(%s): lied about adding headers, honoring request anyway", 3344 m->mf_name); 3345 } 3346 milter_addheader(response, rlen, e); 3347 break; 3348 3349 case SMFIR_CHGHEADER: 3350 if (!bitset(SMFIF_CHGHDRS, m->mf_fflags)) 3351 { 3352 if (LogLevel > 9) 3353 sm_syslog(LOG_WARNING, e->e_id, 3354 "milter_data(%s): lied about changing headers, honoring request anyway", 3355 m->mf_name); 3356 } 3357 milter_changeheader(response, rlen, e); 3358 break; 3359 3360 case SMFIR_ADDRCPT: 3361 if (!bitset(SMFIF_ADDRCPT, m->mf_fflags)) 3362 { 3363 if (LogLevel > 9) 3364 sm_syslog(LOG_WARNING, e->e_id, 3365 "milter_data(%s) lied about adding recipients, honoring request anyway", 3366 m->mf_name); 3367 } 3368 milter_addrcpt(response, rlen, e); 3369 break; 3370 3371 case SMFIR_DELRCPT: 3372 if (!bitset(SMFIF_DELRCPT, m->mf_fflags)) 3373 { 3374 if (LogLevel > 9) 3375 sm_syslog(LOG_WARNING, e->e_id, 3376 "milter_data(%s): lied about removing recipients, honoring request anyway", 3377 m->mf_name); 3378 } 3379 milter_delrcpt(response, rlen, e); 3380 break; 3381 3382 case SMFIR_REPLBODY: 3383 if (!bitset(SMFIF_MODBODY, m->mf_fflags)) 3384 { 3385 if (LogLevel > 0) 3386 sm_syslog(LOG_ERR, e->e_id, 3387 "milter_data(%s): lied about replacing body, rejecting request and tempfailing message", 3388 m->mf_name); 3389 replfailed = TRUE; 3390 break; 3391 } 3392 3393 /* already failed in attempt */ 3394 if (replfailed) 3395 break; 3396 3397 if (!dfopen) 3398 { 3399 if (milter_reopen_df(e) < 0) 3400 { 3401 replfailed = TRUE; 3402 break; 3403 } 3404 dfopen = TRUE; 3405 rewind = TRUE; 3406 } 3407 3408 if (milter_replbody(response, rlen, 3409 newfilter, e) < 0) 3410 replfailed = TRUE; 3411 newfilter = FALSE; 3412 replbody = TRUE; 3413 break; 3414 3415 default: 3416 /* Invalid response to command */ 3417 if (LogLevel > 0) 3418 sm_syslog(LOG_ERR, e->e_id, 3419 "milter_data(%s): returned bogus response %c", 3420 m->mf_name, rcmd); 3421 milter_error(m); 3422 break; 3423 } 3424 if (rcmd != SMFIR_REPLYCODE && 3425 response != NULL) 3426 { 3427 sm_free(response); 3428 response = NULL; 3429 } 3430 3431 if (m->mf_state == SMFS_ERROR) 3432 break; 3433 } 3434 3435 if (replbody && !replfailed) 3436 { 3437 /* flush possible buffered character */ 3438 milter_replbody(NULL, 0, !replbody, e); 3439 replbody = FALSE; 3440 } 3441 3442 if (m->mf_state == SMFS_ERROR) 3443 { 3444 MILTER_CHECK_ERROR(continue); 3445 goto finishup; 3446 } 3447 } 3448 3449finishup: 3450 /* leave things in the expected state if we touched it */ 3451 if (replfailed) 3452 { 3453 if (*state == SMFIR_CONTINUE || 3454 *state == SMFIR_ACCEPT) 3455 { 3456 *state = SMFIR_TEMPFAIL; 3457 if (response != NULL) 3458 { 3459 sm_free(response); 3460 response = NULL; 3461 } 3462 } 3463 3464 if (dfopen) 3465 { 3466 (void) fclose(e->e_dfp); 3467 e->e_dfp = NULL; 3468 e->e_flags &= ~EF_HAS_DF; 3469 dfopen = FALSE; 3470 } 3471 rewind = FALSE; 3472 } 3473 3474 if ((dfopen && milter_reset_df(e) < 0) || 3475 (rewind && bfrewind(e->e_dfp) < 0)) 3476 { 3477 save_errno = errno; 3478 ExitStat = EX_IOERR; 3479 3480 /* 3481 ** If filter told us to keep message but we had 3482 ** an error, we can't really keep it, tempfail it. 3483 */ 3484 3485 if (*state == SMFIR_CONTINUE || 3486 *state == SMFIR_ACCEPT) 3487 { 3488 *state = SMFIR_TEMPFAIL; 3489 if (response != NULL) 3490 { 3491 sm_free(response); 3492 response = NULL; 3493 } 3494 } 3495 3496 errno = save_errno; 3497 syserr("milter_data: %s/df%s: read error", 3498 qid_printqueue(e->e_queuedir), e->e_id); 3499 } 3500 MILTER_CHECK_DONE_MSG(); 3501 return response; 3502} 3503/* 3504** MILTER_QUIT -- informs the filter(s) we are done and closes connection(s) 3505** 3506** Parameters: 3507** e -- current envelope. 3508** 3509** Returns: 3510** none 3511*/ 3512 3513void 3514milter_quit(e) 3515 ENVELOPE *e; 3516{ 3517 int i; 3518 3519 if (tTd(64, 10)) 3520 dprintf("milter_quit\n"); 3521 3522 for (i = 0; InputFilters[i] != NULL; i++) 3523 milter_quit_filter(InputFilters[i], e); 3524} 3525/* 3526** MILTER_ABORT -- informs the filter(s) that we are aborting current message 3527** 3528** Parameters: 3529** e -- current envelope. 3530** 3531** Returns: 3532** none 3533*/ 3534 3535void 3536milter_abort(e) 3537 ENVELOPE *e; 3538{ 3539 int i; 3540 3541 if (tTd(64, 10)) 3542 dprintf("milter_abort\n"); 3543 3544 for (i = 0; InputFilters[i] != NULL; i++) 3545 { 3546 struct milter *m = InputFilters[i]; 3547 3548 /* sanity checks */ 3549 if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG) 3550 continue; 3551 3552 milter_abort_filter(m, e); 3553 } 3554} 3555#endif /* _FFR_MILTER */
| 1288 case 'S': 1289 m->mf_timeout[SMFTO_WRITE] = convtime(p, 's'); 1290 if (tTd(64, 5)) 1291 printf("X%s: %c=%ld\n", 1292 m->mf_name, fcode, 1293 (u_long) m->mf_timeout[SMFTO_WRITE]); 1294 break; 1295 1296 case 'R': 1297 m->mf_timeout[SMFTO_READ] = convtime(p, 's'); 1298 if (tTd(64, 5)) 1299 printf("X%s: %c=%ld\n", 1300 m->mf_name, fcode, 1301 (u_long) m->mf_timeout[SMFTO_READ]); 1302 break; 1303 1304 case 'E': 1305 m->mf_timeout[SMFTO_EOM] = convtime(p, 's'); 1306 if (tTd(64, 5)) 1307 printf("X%s: %c=%ld\n", 1308 m->mf_name, fcode, 1309 (u_long) m->mf_timeout[SMFTO_EOM]); 1310 break; 1311 1312 default: 1313 if (tTd(64, 5)) 1314 printf("X%s: %c unknown\n", 1315 m->mf_name, fcode); 1316 syserr("X%s: unknown filter timeout %c", 1317 m->mf_name, fcode); 1318 break; 1319 } 1320 p = delimptr; 1321 } 1322} 1323/* 1324** MILTER_SET_OPTION -- set an individual milter option 1325** 1326** Parameters: 1327** name -- the name of the option. 1328** val -- the value of the option. 1329** sticky -- if set, don't let other setoptions override 1330** this value. 1331** 1332** Returns: 1333** none. 1334*/ 1335 1336/* set if Milter sub-option is stuck */ 1337static BITMAP256 StickyMilterOpt; 1338 1339static struct milteropt 1340{ 1341 char *mo_name; /* long name of milter option */ 1342 u_char mo_code; /* code for option */ 1343} MilterOptTab[] = 1344{ 1345# define MO_MACROS_CONNECT 0x01 1346 { "macros.connect", MO_MACROS_CONNECT }, 1347# define MO_MACROS_HELO 0x02 1348 { "macros.helo", MO_MACROS_HELO }, 1349# define MO_MACROS_ENVFROM 0x03 1350 { "macros.envfrom", MO_MACROS_ENVFROM }, 1351# define MO_MACROS_ENVRCPT 0x04 1352 { "macros.envrcpt", MO_MACROS_ENVRCPT }, 1353 { NULL, 0 }, 1354}; 1355 1356void 1357milter_set_option(name, val, sticky) 1358 char *name; 1359 char *val; 1360 bool sticky; 1361{ 1362 int nummac = 0; 1363 register struct milteropt *mo; 1364 char *p; 1365 char **macros = NULL; 1366 1367 if (tTd(37, 2) || tTd(64, 5)) 1368 dprintf("milter_set_option(%s = %s)", name, val); 1369 1370 for (mo = MilterOptTab; mo->mo_name != NULL; mo++) 1371 { 1372 if (strcasecmp(mo->mo_name, name) == 0) 1373 break; 1374 } 1375 1376 if (mo->mo_name == NULL) 1377 syserr("milter_set_option: invalid Milter option %s", name); 1378 1379 /* 1380 ** See if this option is preset for us. 1381 */ 1382 1383 if (!sticky && bitnset(mo->mo_code, StickyMilterOpt)) 1384 { 1385 if (tTd(37, 2) || tTd(64,5)) 1386 dprintf(" (ignored)\n"); 1387 return; 1388 } 1389 1390 if (tTd(37, 2) || tTd(64,5)) 1391 dprintf("\n"); 1392 1393 switch (mo->mo_code) 1394 { 1395 case MO_MACROS_CONNECT: 1396 if (macros == NULL) 1397 macros = MilterConnectMacros; 1398 /* FALLTHROUGH */ 1399 1400 case MO_MACROS_HELO: 1401 if (macros == NULL) 1402 macros = MilterHeloMacros; 1403 /* FALLTHROUGH */ 1404 1405 case MO_MACROS_ENVFROM: 1406 if (macros == NULL) 1407 macros = MilterEnvFromMacros; 1408 /* FALLTHROUGH */ 1409 1410 case MO_MACROS_ENVRCPT: 1411 if (macros == NULL) 1412 macros = MilterEnvRcptMacros; 1413 1414 p = newstr(val); 1415 while (*p != '\0') 1416 { 1417 char *macro; 1418 1419 /* Skip leading commas, spaces */ 1420 while (*p != '\0' && 1421 (*p == ',' || (isascii(*p) && isspace(*p)))) 1422 p++; 1423 1424 if (*p == '\0') 1425 break; 1426 1427 /* Find end of macro */ 1428 macro = p; 1429 while (*p != '\0' && *p != ',' && 1430 isascii(*p) && !isspace(*p)) 1431 p++; 1432 if (*p != '\0') 1433 *p++ = '\0'; 1434 1435 if (nummac >= MAXFILTERMACROS) 1436 { 1437 syserr("milter_set_option: too many macros in Milter.%s (max %d)", 1438 name, MAXFILTERMACROS); 1439 macros[nummac] = NULL; 1440 break; 1441 } 1442 macros[nummac++] = macro; 1443 } 1444 macros[nummac] = NULL; 1445 break; 1446 1447 default: 1448 syserr("milter_set_option: invalid Milter option %s", name); 1449 break; 1450 } 1451 1452 if (sticky) 1453 setbitn(mo->mo_code, StickyMilterOpt); 1454} 1455/* 1456** MILTER_REOPEN_DF -- open & truncate the df file (for replbody) 1457** 1458** Parameters: 1459** e -- current envelope. 1460** 1461** Returns: 1462** 0 if succesful, -1 otherwise 1463*/ 1464 1465static int 1466milter_reopen_df(e) 1467 ENVELOPE *e; 1468{ 1469 char dfname[MAXPATHLEN]; 1470 1471 (void) strlcpy(dfname, queuename(e, 'd'), sizeof dfname); 1472 1473 /* 1474 ** In SuperSafe mode, e->e_dfp is a read-only FP so 1475 ** close and reopen writable (later close and reopen 1476 ** read only again). 1477 ** 1478 ** In !SuperSafe mode, e->e_dfp still points at the 1479 ** buffered file I/O descriptor, still open for writing 1480 ** so there isn't as much work to do, just truncate it 1481 ** and go. 1482 */ 1483 1484 if (SuperSafe) 1485 { 1486 /* close read-only df */ 1487 if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL) 1488 { 1489 (void) fclose(e->e_dfp); 1490 e->e_flags &= ~EF_HAS_DF; 1491 } 1492 1493 /* open writable */ 1494 if ((e->e_dfp = fopen(dfname, "w+")) == NULL) 1495 { 1496 MILTER_DF_ERROR("milter_reopen_df: fopen %s: %s"); 1497 return -1; 1498 } 1499 } 1500 else if (e->e_dfp == NULL) 1501 { 1502 /* shouldn't happen */ 1503 errno = ENOENT; 1504 MILTER_DF_ERROR("milter_reopen_df: NULL e_dfp (%s: %s)"); 1505 return -1; 1506 } 1507 return 0; 1508} 1509/* 1510** MILTER_RESET_DF -- re-open read-only the df file (for replbody) 1511** 1512** Parameters: 1513** e -- current envelope. 1514** 1515** Returns: 1516** 0 if succesful, -1 otherwise 1517*/ 1518 1519static int 1520milter_reset_df(e) 1521 ENVELOPE *e; 1522{ 1523 int afd; 1524 char dfname[MAXPATHLEN]; 1525 1526 (void) strlcpy(dfname, queuename(e, 'd'), sizeof dfname); 1527 1528 if (fflush(e->e_dfp) != 0 || ferror(e->e_dfp)) 1529 { 1530 MILTER_DF_ERROR("milter_reset_df: error writing/flushing %s: %s"); 1531 return -1; 1532 } 1533 else if (!SuperSafe) 1534 { 1535 /* skip next few clauses */ 1536 /* EMPTY */ 1537 } 1538 else if ((afd = fileno(e->e_dfp)) >= 0 && fsync(afd) < 0) 1539 { 1540 MILTER_DF_ERROR("milter_reset_df: error sync'ing %s: %s"); 1541 return -1; 1542 } 1543 else if (fclose(e->e_dfp) < 0) 1544 { 1545 MILTER_DF_ERROR("milter_reset_df: error closing %s: %s"); 1546 return -1; 1547 } 1548 else if ((e->e_dfp = fopen(dfname, "r")) == NULL) 1549 { 1550 MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s"); 1551 return -1; 1552 } 1553 else 1554 e->e_flags |= EF_HAS_DF; 1555 return 0; 1556} 1557/* 1558** MILTER_CAN_DELRCPTS -- can any milter filters delete recipients? 1559** 1560** Parameters: 1561** none 1562** 1563** Returns: 1564** TRUE if any filter deletes recipients, FALSE otherwise 1565*/ 1566 1567bool 1568milter_can_delrcpts() 1569{ 1570 bool can = FALSE; 1571 int i; 1572 1573 if (tTd(64, 10)) 1574 dprintf("milter_can_delrcpts:"); 1575 1576 for (i = 0; InputFilters[i] != NULL; i++) 1577 { 1578 struct milter *m = InputFilters[i]; 1579 1580 if (bitset(SMFIF_DELRCPT, m->mf_fflags)) 1581 { 1582 can = TRUE; 1583 break; 1584 } 1585 } 1586 if (tTd(64, 10)) 1587 dprintf("%s\n", can ? "TRUE" : "FALSE"); 1588 1589 return can; 1590} 1591/* 1592** MILTER_QUIT_FILTER -- close down a single filter 1593** 1594** Parameters: 1595** m -- milter structure of filter to close down. 1596** e -- current envelope. 1597** 1598** Returns: 1599** none 1600*/ 1601 1602static void 1603milter_quit_filter(m, e) 1604 struct milter *m; 1605 ENVELOPE *e; 1606{ 1607 if (tTd(64, 10)) 1608 dprintf("milter_quit_filter(%s)\n", m->mf_name); 1609 1610 /* Never replace error state */ 1611 if (m->mf_state == SMFS_ERROR) 1612 return; 1613 1614 if (m->mf_sock < 0 || 1615 m->mf_state == SMFS_CLOSED || 1616 m->mf_state == SMFS_READY) 1617 { 1618 m->mf_sock = -1; 1619 m->mf_state = SMFS_CLOSED; 1620 return; 1621 } 1622 1623 (void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0, 1624 m->mf_timeout[SMFTO_WRITE], e); 1625 if (m->mf_sock >= 0) 1626 { 1627 (void) close(m->mf_sock); 1628 m->mf_sock = -1; 1629 } 1630 if (m->mf_state != SMFS_ERROR) 1631 m->mf_state = SMFS_CLOSED; 1632} 1633/* 1634** MILTER_ABORT_FILTER -- tell filter to abort current message 1635** 1636** Parameters: 1637** m -- milter structure of filter to abort. 1638** e -- current envelope. 1639** 1640** Returns: 1641** none 1642*/ 1643 1644static void 1645milter_abort_filter(m, e) 1646 struct milter *m; 1647 ENVELOPE *e; 1648{ 1649 if (tTd(64, 10)) 1650 dprintf("milter_abort_filter(%s)\n", m->mf_name); 1651 1652 if (m->mf_sock < 0 || 1653 m->mf_state != SMFS_INMSG) 1654 return; 1655 1656 (void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0, 1657 m->mf_timeout[SMFTO_WRITE], e); 1658 if (m->mf_state != SMFS_ERROR) 1659 m->mf_state = SMFS_DONE; 1660} 1661/* 1662** MILTER_SEND_MACROS -- provide macros to the filters 1663** 1664** Parameters: 1665** m -- milter to send macros to. 1666** macros -- macros to send for filter smfi_getsymval(). 1667** cmd -- which command the macros are associated with. 1668** e -- current envelope (for macro access). 1669** 1670** Returns: 1671** none 1672*/ 1673 1674static void 1675milter_send_macros(m, macros, cmd, e) 1676 struct milter *m; 1677 char **macros; 1678 char cmd; 1679 ENVELOPE *e; 1680{ 1681 int i; 1682 int mid; 1683 char *v; 1684 char *buf, *bp; 1685 ssize_t s; 1686 1687 /* sanity check */ 1688 if (macros == NULL || macros[0] == NULL) 1689 return; 1690 1691 /* put together data */ 1692 s = 1; /* for the command character */ 1693 for (i = 0; macros[i] != NULL; i++) 1694 { 1695 mid = macid(macros[i], NULL); 1696 if (mid == 0) 1697 continue; 1698 v = macvalue(mid, e); 1699 if (v == NULL) 1700 continue; 1701 s += strlen(macros[i]) + 1 + strlen(v) + 1; 1702 } 1703 1704 buf = (char *)xalloc(s); 1705 bp = buf; 1706 *bp++ = cmd; 1707 for (i = 0; macros[i] != NULL; i++) 1708 { 1709 mid = macid(macros[i], NULL); 1710 if (mid == 0) 1711 continue; 1712 v = macvalue(mid, e); 1713 if (v == NULL) 1714 continue; 1715 1716 if (tTd(64, 10)) 1717 dprintf("milter_send_macros(%s, %c): %s=%s\n", 1718 m->mf_name, cmd, macros[i], v); 1719 1720 (void) strlcpy(bp, macros[i], s - (bp - buf)); 1721 bp += strlen(bp) + 1; 1722 (void) strlcpy(bp, v, s - (bp - buf)); 1723 bp += strlen(bp) + 1; 1724 } 1725 (void) milter_write(m, SMFIC_MACRO, buf, s, 1726 m->mf_timeout[SMFTO_WRITE], e); 1727 sm_free(buf); 1728} 1729 1730/* 1731** MILTER_SEND_COMMAND -- send a command and return the response for a filter 1732** 1733** Parameters: 1734** m -- current milter filter 1735** command -- command to send. 1736** data -- optional command data. 1737** sz -- length of buf. 1738** e -- current envelope (for e->e_id). 1739** state -- return state word. 1740** 1741** Returns: 1742** response string (may be NULL) 1743*/ 1744 1745static char * 1746milter_send_command(m, command, data, sz, e, state) 1747 struct milter *m; 1748 char command; 1749 void *data; 1750 ssize_t sz; 1751 ENVELOPE *e; 1752 char *state; 1753{ 1754 char rcmd; 1755 ssize_t rlen; 1756 u_long skipflag; 1757 char *defresponse; 1758 char *response; 1759 1760 if (tTd(64, 10)) 1761 dprintf("milter_send_command(%s): cmd %c len %ld\n", 1762 m->mf_name, (char) command, (long) sz); 1763 1764 /* find skip flag and default failure */ 1765 switch (command) 1766 { 1767 case SMFIC_CONNECT: 1768 skipflag = SMFIP_NOCONNECT; 1769 defresponse = "554 Command rejected"; 1770 break; 1771 1772 case SMFIC_HELO: 1773 skipflag = SMFIP_NOHELO; 1774 defresponse = "550 Command rejected"; 1775 break; 1776 1777 case SMFIC_MAIL: 1778 skipflag = SMFIP_NOMAIL; 1779 defresponse = "550 5.7.1 Command rejected"; 1780 break; 1781 1782 case SMFIC_RCPT: 1783 skipflag = SMFIP_NORCPT; 1784 defresponse = "550 5.7.1 Command rejected"; 1785 break; 1786 1787 case SMFIC_HEADER: 1788 skipflag = SMFIP_NOHDRS; 1789 defresponse = "550 5.7.1 Command rejected"; 1790 break; 1791 1792 case SMFIC_BODY: 1793 skipflag = SMFIP_NOBODY; 1794 defresponse = "554 5.7.1 Command rejected"; 1795 break; 1796 1797 case SMFIC_EOH: 1798 skipflag = SMFIP_NOEOH; 1799 defresponse = "550 5.7.1 Command rejected"; 1800 break; 1801 1802 case SMFIC_BODYEOB: 1803 case SMFIC_OPTNEG: 1804 case SMFIC_MACRO: 1805 case SMFIC_ABORT: 1806 case SMFIC_QUIT: 1807 /* NOTE: not handled by milter_send_command() */ 1808 /* FALLTHROUGH */ 1809 1810 default: 1811 skipflag = 0; 1812 defresponse = "550 5.7.1 Command rejected"; 1813 break; 1814 } 1815 1816 /* check if filter wants this command */ 1817 if (skipflag != 0 && 1818 bitset(skipflag, m->mf_pflags)) 1819 return NULL; 1820 1821 1822 (void) milter_write(m, command, data, sz, 1823 m->mf_timeout[SMFTO_WRITE], e); 1824 if (m->mf_state == SMFS_ERROR) 1825 { 1826 MILTER_CHECK_ERROR(/* EMPTY */;); 1827 return NULL; 1828 } 1829 1830 response = milter_read(m, &rcmd, &rlen, 1831 m->mf_timeout[SMFTO_READ], e); 1832 if (m->mf_state == SMFS_ERROR) 1833 { 1834 MILTER_CHECK_ERROR(/* EMPTY */;); 1835 return NULL; 1836 } 1837 1838 if (tTd(64, 10)) 1839 dprintf("milter_send_command(%s): returned %c\n", 1840 m->mf_name, (char) rcmd); 1841 1842 switch (rcmd) 1843 { 1844 case SMFIR_REPLYCODE: 1845 MILTER_CHECK_REPLYCODE(defresponse); 1846 /* FALLTHROUGH */ 1847 1848 case SMFIR_REJECT: 1849 case SMFIR_DISCARD: 1850 case SMFIR_TEMPFAIL: 1851 *state = rcmd; 1852 break; 1853 1854 case SMFIR_ACCEPT: 1855 /* this filter is done with message/connection */ 1856 if (command == SMFIC_HELO || 1857 command == SMFIC_CONNECT) 1858 m->mf_state = SMFS_CLOSABLE; 1859 else 1860 m->mf_state = SMFS_DONE; 1861 break; 1862 1863 case SMFIR_CONTINUE: 1864 /* if MAIL command is ok, filter is in message state */ 1865 if (command == SMFIC_MAIL) 1866 m->mf_state = SMFS_INMSG; 1867 break; 1868 1869 default: 1870 /* Invalid response to command */ 1871 if (LogLevel > 0) 1872 sm_syslog(LOG_ERR, e->e_id, 1873 "milter_send_command(%s): returned bogus response %c", 1874 m->mf_name, rcmd); 1875 milter_error(m); 1876 break; 1877 } 1878 1879 if (*state != SMFIR_REPLYCODE && 1880 response != NULL) 1881 { 1882 sm_free(response); 1883 response = NULL; 1884 } 1885 return response; 1886} 1887 1888/* 1889** MILTER_COMMAND -- send a command and return the response for each filter 1890** 1891** Parameters: 1892** command -- command to send. 1893** data -- optional command data. 1894** sz -- length of buf. 1895** macros -- macros to send for filter smfi_getsymval(). 1896** e -- current envelope (for macro access). 1897** state -- return state word. 1898** 1899** Returns: 1900** response string (may be NULL) 1901*/ 1902 1903static char * 1904milter_command(command, data, sz, macros, e, state) 1905 char command; 1906 void *data; 1907 ssize_t sz; 1908 char **macros; 1909 ENVELOPE *e; 1910 char *state; 1911{ 1912 int i; 1913 char *response = NULL; 1914 1915 if (tTd(64, 10)) 1916 dprintf("milter_command: cmd %c len %ld\n", 1917 (char) command, (long) sz); 1918 1919 *state = SMFIR_CONTINUE; 1920 for (i = 0; InputFilters[i] != NULL; i++) 1921 { 1922 struct milter *m = InputFilters[i]; 1923 1924 /* previous problem? */ 1925 if (m->mf_state == SMFS_ERROR) 1926 { 1927 MILTER_CHECK_ERROR(continue); 1928 break; 1929 } 1930 1931 /* sanity check */ 1932 if (m->mf_sock < 0 || 1933 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) 1934 continue; 1935 1936 /* send macros (regardless of whether we send command) */ 1937 if (macros != NULL && macros[0] != NULL) 1938 { 1939 milter_send_macros(m, macros, command, e); 1940 if (m->mf_state == SMFS_ERROR) 1941 { 1942 MILTER_CHECK_ERROR(continue); 1943 break; 1944 } 1945 } 1946 1947 response = milter_send_command(m, command, data, sz, e, state); 1948 if (*state != SMFIR_CONTINUE) 1949 break; 1950 } 1951 return response; 1952} 1953/* 1954** MILTER_NEGOTIATE -- get version and flags from filter 1955** 1956** Parameters: 1957** m -- milter filter structure. 1958** e -- current envelope. 1959** 1960** Returns: 1961** 0 on success, -1 otherwise 1962*/ 1963 1964static int 1965milter_negotiate(m, e) 1966 struct milter *m; 1967 ENVELOPE *e; 1968{ 1969 char rcmd; 1970 mi_int32 fvers; 1971 mi_int32 fflags; 1972 mi_int32 pflags; 1973 char *response; 1974 ssize_t rlen; 1975 char data[MILTER_OPTLEN]; 1976 1977 /* sanity check */ 1978 if (m->mf_sock < 0 || m->mf_state != SMFS_OPEN) 1979 { 1980 if (LogLevel > 0) 1981 sm_syslog(LOG_ERR, e->e_id, 1982 "milter_negotiate(%s): impossible state", 1983 m->mf_name); 1984 milter_error(m); 1985 return -1; 1986 } 1987 1988 fvers = htonl(SMFI_VERSION); 1989 fflags = htonl(SMFI_CURR_ACTS); 1990 pflags = htonl(SMFI_CURR_PROT); 1991 (void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES); 1992 (void) memcpy(data + MILTER_LEN_BYTES, 1993 (char *) &fflags, MILTER_LEN_BYTES); 1994 (void) memcpy(data + (MILTER_LEN_BYTES * 2), 1995 (char *) &pflags, MILTER_LEN_BYTES); 1996 (void) milter_write(m, SMFIC_OPTNEG, data, sizeof data, 1997 m->mf_timeout[SMFTO_WRITE], e); 1998 1999 if (m->mf_state == SMFS_ERROR) 2000 return -1; 2001 2002 response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e); 2003 if (m->mf_state == SMFS_ERROR) 2004 return -1; 2005 2006 if (rcmd != SMFIC_OPTNEG) 2007 { 2008 if (tTd(64, 5)) 2009 dprintf("milter_negotiate(%s): returned %c instead of %c\n", 2010 m->mf_name, rcmd, SMFIC_OPTNEG); 2011 if (LogLevel > 0) 2012 sm_syslog(LOG_ERR, e->e_id, 2013 "milter_negotiate(%s): returned %c instead of %c", 2014 m->mf_name, rcmd, SMFIC_OPTNEG); 2015 if (response != NULL) 2016 sm_free(response); 2017 milter_error(m); 2018 return -1; 2019 } 2020 2021 /* Make sure we have enough bytes for the version */ 2022 if (response == NULL || rlen < MILTER_LEN_BYTES) 2023 { 2024 if (tTd(64, 5)) 2025 dprintf("milter_negotiate(%s): did not return valid info\n", 2026 m->mf_name); 2027 if (LogLevel > 0) 2028 sm_syslog(LOG_ERR, e->e_id, 2029 "milter_negotiate(%s): did not return valid info", 2030 m->mf_name); 2031 if (response != NULL) 2032 sm_free(response); 2033 milter_error(m); 2034 return -1; 2035 } 2036 2037 /* extract information */ 2038 (void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES); 2039 2040 /* Now make sure we have enough for the feature bitmap */ 2041 if (rlen != MILTER_OPTLEN) 2042 { 2043 if (tTd(64, 5)) 2044 dprintf("milter_negotiate(%s): did not return enough info\n", 2045 m->mf_name); 2046 if (LogLevel > 0) 2047 sm_syslog(LOG_ERR, e->e_id, 2048 "milter_negotiate(%s): did not return enough info", 2049 m->mf_name); 2050 if (response != NULL) 2051 sm_free(response); 2052 milter_error(m); 2053 return -1; 2054 } 2055 2056 (void) memcpy((char *) &fflags, response + MILTER_LEN_BYTES, 2057 MILTER_LEN_BYTES); 2058 (void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2), 2059 MILTER_LEN_BYTES); 2060 sm_free(response); 2061 response = NULL; 2062 2063 m->mf_fvers = ntohl(fvers); 2064 m->mf_fflags = ntohl(fflags); 2065 m->mf_pflags = ntohl(pflags); 2066 2067 /* check for version compatibility */ 2068 if (m->mf_fvers == 1 || 2069 m->mf_fvers > SMFI_VERSION) 2070 { 2071 if (tTd(64, 5)) 2072 dprintf("milter_negotiate(%s): version %lu != MTA milter version %d\n", 2073 m->mf_name, m->mf_fvers, SMFI_VERSION); 2074 if (LogLevel > 0) 2075 sm_syslog(LOG_ERR, e->e_id, 2076 "milter_negotiate(%s): version %ld != MTA milter version %d", 2077 m->mf_name, m->mf_fvers, SMFI_VERSION); 2078 milter_error(m); 2079 return -1; 2080 } 2081 2082 /* check for filter feature mismatch */ 2083 if ((m->mf_fflags & SMFI_CURR_ACTS) != m->mf_fflags) 2084 { 2085 if (tTd(64, 5)) 2086 dprintf("milter_negotiate(%s): filter abilities 0x%lx != MTA milter abilities 0x%lx\n", 2087 m->mf_name, m->mf_fflags, 2088 (u_long) SMFI_CURR_ACTS); 2089 if (LogLevel > 0) 2090 sm_syslog(LOG_ERR, e->e_id, 2091 "milter_negotiate(%s): filter abilities 0x%lx != MTA milter abilities 0x%lx\n", 2092 m->mf_name, m->mf_fflags, 2093 (u_long) SMFI_CURR_ACTS); 2094 milter_error(m); 2095 return -1; 2096 } 2097 2098 /* check for protocol feature mismatch */ 2099 if ((m->mf_pflags & SMFI_CURR_PROT) != m->mf_pflags) 2100 { 2101 if (tTd(64, 5)) 2102 dprintf("milter_negotiate(%s): protocol abilities 0x%lx != MTA milter abilities 0x%lx\n", 2103 m->mf_name, m->mf_pflags, 2104 (u_long) SMFI_CURR_PROT); 2105 if (LogLevel > 0) 2106 sm_syslog(LOG_ERR, e->e_id, 2107 "milter_negotiate(%s): protocol abilities 0x%lx != MTA milter abilities 0x%lx\n", 2108 m->mf_name, m->mf_pflags, 2109 (u_long) SMFI_CURR_PROT); 2110 milter_error(m); 2111 return -1; 2112 } 2113 2114 if (tTd(64, 5)) 2115 dprintf("milter_negotiate(%s): version %lu, fflags 0x%lx, pflags 0x%lx\n", 2116 m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags); 2117 return 0; 2118} 2119/* 2120** MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands 2121** 2122** Reduce code duplication by putting these checks in one place 2123** 2124** Parameters: 2125** e -- current envelope. 2126** 2127** Returns: 2128** none 2129*/ 2130 2131static void 2132milter_per_connection_check(e) 2133 ENVELOPE *e; 2134{ 2135 int i; 2136 2137 /* see if we are done with any of the filters */ 2138 for (i = 0; InputFilters[i] != NULL; i++) 2139 { 2140 struct milter *m = InputFilters[i]; 2141 2142 if (m->mf_state == SMFS_CLOSABLE) 2143 milter_quit_filter(m, e); 2144 } 2145} 2146/* 2147** MILTER_ERROR -- Put a milter filter into error state 2148** 2149** Parameters: 2150** m -- the broken filter. 2151** 2152** Returns: 2153** none 2154*/ 2155 2156static void 2157milter_error(m) 2158 struct milter *m; 2159{ 2160 /* 2161 ** We could send a quit here but 2162 ** we may have gotten here due to 2163 ** an I/O error so we don't want 2164 ** to try to make things worse. 2165 */ 2166 2167 if (m->mf_sock >= 0) 2168 { 2169 (void) close(m->mf_sock); 2170 m->mf_sock = -1; 2171 } 2172 m->mf_state = SMFS_ERROR; 2173} 2174/* 2175** MILTER_HEADERS -- send headers to a single milter filter 2176** 2177** Parameters: 2178** m -- current filter. 2179** e -- current envelope. 2180** state -- return state from response. 2181** 2182** Returns: 2183** response string (may be NULL) 2184*/ 2185 2186static char * 2187milter_headers(m, e, state) 2188 struct milter *m; 2189 ENVELOPE *e; 2190 char *state; 2191{ 2192 char *response = NULL; 2193 HDR *h; 2194 2195 for (h = e->e_header; h != NULL; h = h->h_link) 2196 { 2197 char *buf; 2198 ssize_t s; 2199 2200 /* don't send over deleted headers */ 2201 if (h->h_value == NULL) 2202 { 2203 /* strip H_USER so not counted in milter_chgheader() */ 2204 h->h_flags &= ~H_USER; 2205 continue; 2206 } 2207 2208 /* skip auto-generated */ 2209 if (!bitset(H_USER, h->h_flags)) 2210 continue; 2211 2212 if (tTd(64, 10)) 2213 dprintf("milter_headers: %s: %s\n", 2214 h->h_field, h->h_value); 2215 2216 s = strlen(h->h_field) + 1 + 2217 strlen(h->h_value) + 1; 2218 buf = (char *) xalloc(s); 2219 snprintf(buf, s, "%s%c%s", h->h_field, '\0', h->h_value); 2220 2221 /* send it over */ 2222 response = milter_send_command(m, SMFIC_HEADER, buf, 2223 s, e, state); 2224 sm_free(buf); 2225 if (m->mf_state == SMFS_ERROR || 2226 m->mf_state == SMFS_DONE || 2227 *state != SMFIR_CONTINUE) 2228 break; 2229 } 2230 return response; 2231} 2232/* 2233** MILTER_BODY -- send the body to a filter 2234** 2235** Parameters: 2236** m -- current filter. 2237** e -- current envelope. 2238** state -- return state from response. 2239** 2240** Returns: 2241** response string (may be NULL) 2242*/ 2243 2244static char * 2245milter_body(m, e, state) 2246 struct milter *m; 2247 ENVELOPE *e; 2248 char *state; 2249{ 2250 char bufchar = '\0'; 2251 char prevchar = '\0'; 2252 int c; 2253 char *response = NULL; 2254 char *bp; 2255 char buf[MILTER_CHUNK_SIZE]; 2256 2257 if (tTd(64, 10)) 2258 dprintf("milter_body\n"); 2259 2260 if (bfrewind(e->e_dfp) < 0) 2261 { 2262 ExitStat = EX_IOERR; 2263 *state = SMFIR_TEMPFAIL; 2264 syserr("milter_body: %s/df%s: rewind error", 2265 qid_printqueue(e->e_queuedir), e->e_id); 2266 return NULL; 2267 } 2268 2269 bp = buf; 2270 while ((c = getc(e->e_dfp)) != EOF) 2271 { 2272 /* Change LF to CRLF */ 2273 if (c == '\n') 2274 { 2275 /* Not a CRLF already? */ 2276 if (prevchar != '\r') 2277 { 2278 /* Room for CR now? */ 2279 if (bp + 2 > &buf[sizeof buf]) 2280 { 2281 /* No room, buffer LF */ 2282 bufchar = c; 2283 2284 /* and send CR now */ 2285 c = '\r'; 2286 } 2287 else 2288 { 2289 /* Room to do it now */ 2290 *bp++ = '\r'; 2291 prevchar = '\r'; 2292 } 2293 } 2294 } 2295 *bp++ = (char) c; 2296 prevchar = c; 2297 if (bp >= &buf[sizeof buf]) 2298 { 2299 /* send chunk */ 2300 response = milter_send_command(m, SMFIC_BODY, buf, 2301 bp - buf, e, state); 2302 bp = buf; 2303 if (bufchar != '\0') 2304 { 2305 *bp++ = bufchar; 2306 bufchar = '\0'; 2307 prevchar = bufchar; 2308 } 2309 } 2310 if (m->mf_state == SMFS_ERROR || 2311 m->mf_state == SMFS_DONE || 2312 *state != SMFIR_CONTINUE) 2313 break; 2314 } 2315 2316 /* check for read errors */ 2317 if (ferror(e->e_dfp)) 2318 { 2319 ExitStat = EX_IOERR; 2320 if (*state == SMFIR_CONTINUE || 2321 *state == SMFIR_ACCEPT) 2322 { 2323 *state = SMFIR_TEMPFAIL; 2324 if (response != NULL) 2325 { 2326 sm_free(response); 2327 response = NULL; 2328 } 2329 } 2330 syserr("milter_body: %s/df%s: read error", 2331 qid_printqueue(e->e_queuedir), e->e_id); 2332 return response; 2333 } 2334 2335 /* send last body chunk */ 2336 if (bp > buf && 2337 m->mf_state != SMFS_ERROR && 2338 m->mf_state != SMFS_DONE && 2339 *state == SMFIR_CONTINUE) 2340 { 2341 /* send chunk */ 2342 response = milter_send_command(m, SMFIC_BODY, buf, bp - buf, 2343 e, state); 2344 bp = buf; 2345 } 2346 return response; 2347} 2348 2349/* 2350** Actions 2351*/ 2352 2353/* 2354** MILTER_ADDHEADER -- Add the supplied header to the message 2355** 2356** Parameters: 2357** response -- encoded form of header/value. 2358** rlen -- length of response. 2359** e -- current envelope. 2360** 2361** Returns: 2362** none 2363*/ 2364 2365static void 2366milter_addheader(response, rlen, e) 2367 char *response; 2368 ssize_t rlen; 2369 ENVELOPE *e; 2370{ 2371 char *val; 2372 HDR *h; 2373 2374 if (tTd(64, 10)) 2375 dprintf("milter_addheader: "); 2376 2377 /* sanity checks */ 2378 if (response == NULL) 2379 { 2380 if (tTd(64, 10)) 2381 dprintf("NULL response\n"); 2382 return; 2383 } 2384 2385 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 2386 { 2387 if (tTd(64, 10)) 2388 dprintf("didn't follow protocol (total len)\n"); 2389 return; 2390 } 2391 2392 /* Find separating NUL */ 2393 val = response + strlen(response) + 1; 2394 2395 /* another sanity check */ 2396 if (strlen(response) + strlen(val) + 2 != (size_t) rlen) 2397 { 2398 if (tTd(64, 10)) 2399 dprintf("didn't follow protocol (part len)\n"); 2400 return; 2401 } 2402 2403 if (*response == '\0') 2404 { 2405 if (tTd(64, 10)) 2406 dprintf("empty field name\n"); 2407 return; 2408 } 2409 2410 for (h = e->e_header; h != NULL; h = h->h_link) 2411 { 2412 if (strcasecmp(h->h_field, response) == 0 && 2413 !bitset(H_USER, h->h_flags) && 2414 !bitset(H_TRACE, h->h_flags)) 2415 break; 2416 } 2417 2418 /* add to e_msgsize */ 2419 e->e_msgsize += strlen(response) + 2 + strlen(val); 2420 2421 if (h != NULL) 2422 { 2423 if (tTd(64, 10)) 2424 dprintf("Replace default header %s value with %s\n", 2425 h->h_field, val); 2426 h->h_value = newstr(val); 2427 h->h_flags |= H_USER; 2428 } 2429 else 2430 { 2431 if (tTd(64, 10)) 2432 dprintf("Add %s: %s\n", response, val); 2433 addheader(newstr(response), val, H_USER, &e->e_header); 2434 } 2435} 2436/* 2437** MILTER_CHANGEHEADER -- Change the supplied header in the message 2438** 2439** Parameters: 2440** response -- encoded form of header/index/value. 2441** rlen -- length of response. 2442** e -- current envelope. 2443** 2444** Returns: 2445** none 2446*/ 2447 2448static void 2449milter_changeheader(response, rlen, e) 2450 char *response; 2451 ssize_t rlen; 2452 ENVELOPE *e; 2453{ 2454 mi_int32 i, index; 2455 char *field, *val; 2456 HDR *h, *sysheader; 2457 2458 if (tTd(64, 10)) 2459 dprintf("milter_changeheader: "); 2460 2461 /* sanity checks */ 2462 if (response == NULL) 2463 { 2464 if (tTd(64, 10)) 2465 dprintf("NULL response\n"); 2466 return; 2467 } 2468 2469 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 2470 { 2471 if (tTd(64, 10)) 2472 dprintf("didn't follow protocol (total len)\n"); 2473 return; 2474 } 2475 2476 /* Find separating NUL */ 2477 (void) memcpy((char *) &i, response, MILTER_LEN_BYTES); 2478 index = ntohl(i); 2479 field = response + MILTER_LEN_BYTES; 2480 val = field + strlen(field) + 1; 2481 2482 /* another sanity check */ 2483 if (MILTER_LEN_BYTES + strlen(field) + 1 + 2484 strlen(val) + 1 != (size_t) rlen) 2485 { 2486 if (tTd(64, 10)) 2487 dprintf("didn't follow protocol (part len)\n"); 2488 return; 2489 } 2490 2491 if (*field == '\0') 2492 { 2493 if (tTd(64, 10)) 2494 dprintf("empty field name\n"); 2495 return; 2496 } 2497 2498 sysheader = NULL; 2499 for (h = e->e_header; h != NULL; h = h->h_link) 2500 { 2501 if (strcasecmp(h->h_field, field) == 0) 2502 { 2503 if (bitset(H_USER, h->h_flags) && 2504 --index <= 0) 2505 { 2506 sysheader = NULL; 2507 break; 2508 } 2509 else if (!bitset(H_USER, h->h_flags) && 2510 !bitset(H_TRACE, h->h_flags)) 2511 { 2512 /* 2513 ** DRUMS msg-fmt draft says can only have 2514 ** multiple occurences of trace fields, 2515 ** so make sure we replace any non-trace, 2516 ** non-user field. 2517 */ 2518 2519 sysheader = h; 2520 } 2521 } 2522 } 2523 2524 /* if not found as user-provided header at index, use sysheader */ 2525 if (h == NULL) 2526 h = sysheader; 2527 2528 if (h == NULL) 2529 { 2530 if (*val == '\0') 2531 { 2532 if (tTd(64, 10)) 2533 dprintf("Delete (noop) %s:\n", field); 2534 } 2535 else 2536 { 2537 /* treat modify value with no existing header as add */ 2538 if (tTd(64, 10)) 2539 dprintf("Add %s: %s\n", field, val); 2540 2541 addheader(newstr(field), val, H_USER, &e->e_header); 2542 } 2543 return; 2544 } 2545 2546 if (tTd(64, 10)) 2547 { 2548 if (*val == '\0') 2549 { 2550 dprintf("Delete%s %s: %s\n", 2551 h == sysheader ? " (default header)" : "", 2552 field, 2553 h->h_value == NULL ? "<NULL>" : h->h_value); 2554 } 2555 else 2556 { 2557 dprintf("Change%s %s: from %s to %s\n", 2558 h == sysheader ? " (default header)" : "", 2559 field, 2560 h->h_value == NULL ? "<NULL>" : h->h_value, 2561 val); 2562 } 2563 } 2564 2565 if (h != sysheader && h->h_value != NULL) 2566 { 2567 e->e_msgsize -= strlen(h->h_value); 2568 sm_free(h->h_value); 2569 } 2570 2571 if (*val == '\0') 2572 { 2573 /* Remove "Field: " from message size */ 2574 if (h != sysheader) 2575 e->e_msgsize -= strlen(h->h_field) + 2; 2576 h->h_value = NULL; 2577 } 2578 else 2579 { 2580 h->h_value = newstr(val); 2581 h->h_flags |= H_USER; 2582 e->e_msgsize += strlen(h->h_value); 2583 } 2584} 2585/* 2586** MILTER_ADDRCPT -- Add the supplied recipient to the message 2587** 2588** Parameters: 2589** response -- encoded form of recipient address. 2590** rlen -- length of response. 2591** e -- current envelope. 2592** 2593** Returns: 2594** none 2595*/ 2596 2597static void 2598milter_addrcpt(response, rlen, e) 2599 char *response; 2600 ssize_t rlen; 2601 ENVELOPE *e; 2602{ 2603 if (tTd(64, 10)) 2604 dprintf("milter_addrcpt: "); 2605 2606 /* sanity checks */ 2607 if (response == NULL) 2608 { 2609 if (tTd(64, 10)) 2610 dprintf("NULL response\n"); 2611 return; 2612 } 2613 2614 if (*response == '\0' || 2615 strlen(response) + 1 != (size_t) rlen) 2616 { 2617 if (tTd(64, 10)) 2618 dprintf("didn't follow protocol (total len %d != rlen %d)\n", 2619 strlen(response), rlen -1); 2620 return; 2621 } 2622 2623 if (tTd(64, 10)) 2624 dprintf("%s\n", response); 2625 (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e); 2626 return; 2627} 2628/* 2629** MILTER_DELRCPT -- Delete the supplied recipient from the message 2630** 2631** Parameters: 2632** response -- encoded form of recipient address. 2633** rlen -- length of response. 2634** e -- current envelope. 2635** 2636** Returns: 2637** none 2638*/ 2639 2640static void 2641milter_delrcpt(response, rlen, e) 2642 char *response; 2643 ssize_t rlen; 2644 ENVELOPE *e; 2645{ 2646 if (tTd(64, 10)) 2647 dprintf("milter_delrcpt: "); 2648 2649 /* sanity checks */ 2650 if (response == NULL) 2651 { 2652 if (tTd(64, 10)) 2653 dprintf("NULL response\n"); 2654 return; 2655 } 2656 2657 if (*response == '\0' || 2658 strlen(response) + 1 != (size_t) rlen) 2659 { 2660 if (tTd(64, 10)) 2661 dprintf("didn't follow protocol (total len)\n"); 2662 return; 2663 } 2664 2665 if (tTd(64, 10)) 2666 dprintf("%s\n", response); 2667 (void) removefromlist(response, &e->e_sendqueue, e); 2668 return; 2669} 2670/* 2671** MILTER_REPLBODY -- Replace the current df file with new body 2672** 2673** Parameters: 2674** response -- encoded form of new body. 2675** rlen -- length of response. 2676** newfilter -- if first time called by a new filter 2677** e -- current envelope. 2678** 2679** Returns: 2680** 0 upon success, -1 upon failure 2681*/ 2682 2683static int 2684milter_replbody(response, rlen, newfilter, e) 2685 char *response; 2686 ssize_t rlen; 2687 bool newfilter; 2688 ENVELOPE *e; 2689{ 2690 static char prevchar; 2691 int i; 2692 2693 if (tTd(64, 10)) 2694 dprintf("milter_replbody\n"); 2695 2696 /* If a new filter, reset previous character and truncate df */ 2697 if (newfilter) 2698 { 2699 off_t prevsize = 0; 2700 char dfname[MAXPATHLEN]; 2701 2702 (void) strlcpy(dfname, queuename(e, 'd'), sizeof dfname); 2703 2704 /* Reset prevchar */ 2705 prevchar = '\0'; 2706 2707 /* Get the current df information */ 2708 if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL) 2709 { 2710 int afd; 2711 struct stat st; 2712 2713 afd = fileno(e->e_dfp); 2714 if (afd > 0 && fstat(afd, &st) == 0) 2715 prevsize = st.st_size; 2716 } 2717 2718 /* truncate current df file */ 2719 if (bftruncate(e->e_dfp) < 0) 2720 { 2721 MILTER_DF_ERROR("milter_reopen_df: bftruncate %s: %s"); 2722 return -1; 2723 } 2724 else 2725 { 2726 if (prevsize > e->e_msgsize) 2727 e->e_msgsize = 0; 2728 else 2729 e->e_msgsize -= prevsize; 2730 } 2731 } 2732 2733 if (response == NULL) 2734 { 2735 /* Flush the buffered '\r' */ 2736 if (prevchar == '\r') 2737 { 2738 (void) putc(prevchar, e->e_dfp); 2739 e->e_msgsize++; 2740 } 2741 return 0; 2742 } 2743 2744 for (i = 0; i < rlen; i++) 2745 { 2746 /* Buffered char from last chunk */ 2747 if (i == 0 && prevchar == '\r') 2748 { 2749 /* Not CRLF, output prevchar */ 2750 if (response[i] != '\n') 2751 { 2752 (void) putc(prevchar, e->e_dfp); 2753 e->e_msgsize++; 2754 } 2755 prevchar = '\0'; 2756 } 2757 2758 /* Turn CRLF into LF */ 2759 if (response[i] == '\r') 2760 { 2761 /* check if at end of chunk */ 2762 if (i + 1 < rlen) 2763 { 2764 /* If LF, strip CR */ 2765 if (response[i + 1] == '\n') 2766 i++; 2767 } 2768 else 2769 { 2770 /* check next chunk */ 2771 prevchar = '\r'; 2772 continue; 2773 } 2774 } 2775 (void) putc(response[i], e->e_dfp); 2776 e->e_msgsize++; 2777 } 2778 return 0; 2779} 2780 2781/* 2782** MTA callouts 2783*/ 2784 2785/* 2786** MILTER_INIT -- open and negotiate with all of the filters 2787** 2788** Parameters: 2789** e -- current envelope. 2790** state -- return state from response. 2791** 2792** Returns: 2793** none 2794*/ 2795 2796/* ARGSUSED */ 2797void 2798milter_init(e, state) 2799 ENVELOPE *e; 2800 char *state; 2801{ 2802 int i; 2803 2804 if (tTd(64, 10)) 2805 dprintf("milter_init\n"); 2806 2807 *state = SMFIR_CONTINUE; 2808 for (i = 0; InputFilters[i] != NULL; i++) 2809 { 2810 struct milter *m = InputFilters[i]; 2811 2812 m->mf_sock = milter_open(m, FALSE, e); 2813 if (m->mf_state == SMFS_ERROR) 2814 { 2815 MILTER_CHECK_ERROR(continue); 2816 break; 2817 } 2818 2819 if (m->mf_sock < 0 || 2820 milter_negotiate(m, e) < 0 || 2821 m->mf_state == SMFS_ERROR) 2822 { 2823 if (tTd(64, 5)) 2824 dprintf("milter_init(%s): failed to %s\n", 2825 m->mf_name, 2826 m->mf_sock < 0 ? "open" : "negotiate"); 2827 2828 /* if negotation failure, close socket */ 2829 milter_error(m); 2830 MILTER_CHECK_ERROR(continue); 2831 } 2832 } 2833 2834 /* 2835 ** If something temp/perm failed with one of the filters, 2836 ** we won't be using any of them, so clear any existing 2837 ** connections. 2838 */ 2839 2840 if (*state != SMFIR_CONTINUE) 2841 milter_quit(e); 2842} 2843/* 2844** MILTER_CONNECT -- send connection info to milter filters 2845** 2846** Parameters: 2847** hostname -- hostname of remote machine. 2848** addr -- address of remote machine. 2849** e -- current envelope. 2850** state -- return state from response. 2851** 2852** Returns: 2853** response string (may be NULL) 2854*/ 2855 2856char * 2857milter_connect(hostname, addr, e, state) 2858 char *hostname; 2859 SOCKADDR addr; 2860 ENVELOPE *e; 2861 char *state; 2862{ 2863 char family; 2864 u_short port; 2865 char *buf, *bp; 2866 char *response; 2867 char *sockinfo = NULL; 2868 ssize_t s; 2869# if NETINET6 2870 char buf6[INET6_ADDRSTRLEN]; 2871# endif /* NETINET6 */ 2872 2873 if (tTd(64, 10)) 2874 dprintf("milter_connect(%s)\n", hostname); 2875 2876 /* gather data */ 2877 switch (addr.sa.sa_family) 2878 { 2879# if NETUNIX 2880 case AF_UNIX: 2881 family = SMFIA_UNIX; 2882 port = htons(0); 2883 sockinfo = addr.sunix.sun_path; 2884 break; 2885# endif /* NETUNIX */ 2886 2887# if NETINET 2888 case AF_INET: 2889 family = SMFIA_INET; 2890 port = htons(addr.sin.sin_port); 2891 sockinfo = (char *) inet_ntoa(addr.sin.sin_addr); 2892 break; 2893# endif /* NETINET */ 2894 2895# if NETINET6 2896 case AF_INET6: 2897 if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr)) 2898 family = SMFIA_INET; 2899 else 2900 family = SMFIA_INET6; 2901 port = htons(addr.sin6.sin6_port); 2902 sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6, 2903 sizeof buf6); 2904 if (sockinfo == NULL) 2905 sockinfo = ""; 2906 break; 2907# endif /* NETINET6 */ 2908 2909 default: 2910 family = SMFIA_UNKNOWN; 2911 break; 2912 } 2913 2914 s = strlen(hostname) + 1 + sizeof(family); 2915 if (family != SMFIA_UNKNOWN) 2916 s += sizeof(port) + strlen(sockinfo) + 1; 2917 2918 buf = (char *)xalloc(s); 2919 bp = buf; 2920 2921 /* put together data */ 2922 (void) memcpy(bp, hostname, strlen(hostname)); 2923 bp += strlen(hostname); 2924 *bp++ = '\0'; 2925 (void) memcpy(bp, &family, sizeof family); 2926 bp += sizeof family; 2927 if (family != SMFIA_UNKNOWN) 2928 { 2929 (void) memcpy(bp, &port, sizeof port); 2930 bp += sizeof port; 2931 2932 /* include trailing '\0' */ 2933 (void) memcpy(bp, sockinfo, strlen(sockinfo) + 1); 2934 } 2935 2936 response = milter_command(SMFIC_CONNECT, buf, s, 2937 MilterConnectMacros, e, state); 2938 sm_free(buf); 2939 2940 /* 2941 ** If this message connection is done for, 2942 ** close the filters. 2943 */ 2944 2945 if (*state != SMFIR_CONTINUE) 2946 milter_quit(e); 2947 else 2948 milter_per_connection_check(e); 2949 2950 /* 2951 ** SMFIR_REPLYCODE can't work with connect due to 2952 ** the requirements of SMTP. Therefore, ignore the 2953 ** reply code text but keep the state it would reflect. 2954 */ 2955 2956 if (*state == SMFIR_REPLYCODE) 2957 { 2958 if (response != NULL && 2959 *response == '4') 2960 *state = SMFIR_TEMPFAIL; 2961 else 2962 *state = SMFIR_REJECT; 2963 if (response != NULL) 2964 { 2965 sm_free(response); 2966 response = NULL; 2967 } 2968 } 2969 return response; 2970} 2971/* 2972** MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters 2973** 2974** Parameters: 2975** helo -- argument to SMTP HELO/EHLO command. 2976** e -- current envelope. 2977** state -- return state from response. 2978** 2979** Returns: 2980** response string (may be NULL) 2981*/ 2982 2983char * 2984milter_helo(helo, e, state) 2985 char *helo; 2986 ENVELOPE *e; 2987 char *state; 2988{ 2989 int i; 2990 char *response; 2991 2992 if (tTd(64, 10)) 2993 dprintf("milter_helo(%s)\n", helo); 2994 2995 /* HELO/EHLO can come after encryption is negotiated */ 2996 for (i = 0; InputFilters[i] != NULL; i++) 2997 { 2998 struct milter *m = InputFilters[i]; 2999 3000 switch (m->mf_state) 3001 { 3002 case SMFS_INMSG: 3003 /* abort in message filters */ 3004 milter_abort_filter(m, e); 3005 /* FALLTHROUGH */ 3006 3007 case SMFS_DONE: 3008 /* reset done filters */ 3009 m->mf_state = SMFS_OPEN; 3010 break; 3011 } 3012 } 3013 3014 response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1, 3015 MilterHeloMacros, e, state); 3016 milter_per_connection_check(e); 3017 return response; 3018} 3019/* 3020** MILTER_ENVFROM -- send SMTP MAIL command info to milter filters 3021** 3022** Parameters: 3023** args -- SMTP MAIL command args (args[0] == sender). 3024** e -- current envelope. 3025** state -- return state from response. 3026** 3027** Returns: 3028** response string (may be NULL) 3029*/ 3030 3031char * 3032milter_envfrom(args, e, state) 3033 char **args; 3034 ENVELOPE *e; 3035 char *state; 3036{ 3037 int i; 3038 char *buf, *bp; 3039 char *response; 3040 ssize_t s; 3041 3042 if (tTd(64, 10)) 3043 { 3044 dprintf("milter_envfrom:"); 3045 for (i = 0; args[i] != NULL; i++) 3046 dprintf(" %s", args[i]); 3047 dprintf("\n"); 3048 } 3049 3050 /* sanity check */ 3051 if (args[0] == NULL) 3052 { 3053 *state = SMFIR_REJECT; 3054 return NULL; 3055 } 3056 3057 /* new message, so ... */ 3058 for (i = 0; InputFilters[i] != NULL; i++) 3059 { 3060 struct milter *m = InputFilters[i]; 3061 3062 switch (m->mf_state) 3063 { 3064 case SMFS_INMSG: 3065 /* abort in message filters */ 3066 milter_abort_filter(m, e); 3067 /* FALLTHROUGH */ 3068 3069 case SMFS_DONE: 3070 /* reset done filters */ 3071 m->mf_state = SMFS_OPEN; 3072 break; 3073 } 3074 } 3075 3076 /* put together data */ 3077 s = 0; 3078 for (i = 0; args[i] != NULL; i++) 3079 s += strlen(args[i]) + 1; 3080 buf = (char *)xalloc(s); 3081 bp = buf; 3082 for (i = 0; args[i] != NULL; i++) 3083 { 3084 (void) strlcpy(bp, args[i], s - (bp - buf)); 3085 bp += strlen(bp) + 1; 3086 } 3087 3088 /* send it over */ 3089 response = milter_command(SMFIC_MAIL, buf, s, 3090 MilterEnvFromMacros, e, state); 3091 sm_free(buf); 3092 3093 /* 3094 ** If filter rejects/discards a per message command, 3095 ** abort the other filters since we are done with the 3096 ** current message. 3097 */ 3098 3099 MILTER_CHECK_DONE_MSG(); 3100 return response; 3101} 3102/* 3103** MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters 3104** 3105** Parameters: 3106** args -- SMTP MAIL command args (args[0] == recipient). 3107** e -- current envelope. 3108** state -- return state from response. 3109** 3110** Returns: 3111** response string (may be NULL) 3112*/ 3113 3114char * 3115milter_envrcpt(args, e, state) 3116 char **args; 3117 ENVELOPE *e; 3118 char *state; 3119{ 3120 int i; 3121 char *buf, *bp; 3122 char *response; 3123 ssize_t s; 3124 3125 if (tTd(64, 10)) 3126 { 3127 dprintf("milter_envrcpt:"); 3128 for (i = 0; args[i] != NULL; i++) 3129 dprintf(" %s", args[i]); 3130 dprintf("\n"); 3131 } 3132 3133 /* sanity check */ 3134 if (args[0] == NULL) 3135 { 3136 *state = SMFIR_REJECT; 3137 return NULL; 3138 } 3139 3140 /* put together data */ 3141 s = 0; 3142 for (i = 0; args[i] != NULL; i++) 3143 s += strlen(args[i]) + 1; 3144 buf = (char *)xalloc(s); 3145 bp = buf; 3146 for (i = 0; args[i] != NULL; i++) 3147 { 3148 (void) strlcpy(bp, args[i], s - (bp - buf)); 3149 bp += strlen(bp) + 1; 3150 } 3151 3152 /* send it over */ 3153 response = milter_command(SMFIC_RCPT, buf, s, 3154 MilterEnvRcptMacros, e, state); 3155 sm_free(buf); 3156 return response; 3157} 3158/* 3159** MILTER_DATA -- send message headers/body and gather final message results 3160** 3161** Parameters: 3162** e -- current envelope. 3163** state -- return state from response. 3164** 3165** Returns: 3166** response string (may be NULL) 3167** 3168** Side effects: 3169** - Uses e->e_dfp for access to the body 3170** - Can call the various milter action routines to 3171** modify the envelope or message. 3172*/ 3173 3174# define MILTER_CHECK_RESULTS() \ 3175 if (*state == SMFIR_ACCEPT || \ 3176 m->mf_state == SMFS_DONE || \ 3177 m->mf_state == SMFS_ERROR) \ 3178 { \ 3179 if (m->mf_state != SMFS_ERROR) \ 3180 m->mf_state = SMFS_DONE; \ 3181 continue; /* to next filter */ \ 3182 } \ 3183 if (*state != SMFIR_CONTINUE) \ 3184 { \ 3185 m->mf_state = SMFS_DONE; \ 3186 goto finishup; \ 3187 } 3188 3189char * 3190milter_data(e, state) 3191 ENVELOPE *e; 3192 char *state; 3193{ 3194 bool replbody = FALSE; /* milter_replbody() called? */ 3195 bool replfailed = FALSE; /* milter_replbody() failed? */ 3196 bool rewind = FALSE; /* rewind df file? */ 3197 bool dfopen = FALSE; /* df open for writing? */ 3198 bool newfilter; /* reset on each new filter */ 3199 char rcmd; 3200 int i; 3201 int save_errno; 3202 char *response = NULL; 3203 time_t eomsent; 3204 ssize_t rlen; 3205 3206 if (tTd(64, 10)) 3207 dprintf("milter_data\n"); 3208 3209 *state = SMFIR_CONTINUE; 3210 3211 /* 3212 ** XXX: Should actually send body chunks to each filter 3213 ** a chunk at a time instead of sending the whole body to 3214 ** each filter in turn. However, only if the filters don't 3215 ** change the body. 3216 */ 3217 3218 for (i = 0; InputFilters[i] != NULL; i++) 3219 { 3220 struct milter *m = InputFilters[i]; 3221 3222 if (*state != SMFIR_CONTINUE && 3223 *state != SMFIR_ACCEPT) 3224 { 3225 /* 3226 ** A previous filter has dealt with the message, 3227 ** safe to stop processing the filters. 3228 */ 3229 3230 break; 3231 } 3232 3233 /* Now reset state for later evaluation */ 3234 *state = SMFIR_CONTINUE; 3235 newfilter = TRUE; 3236 3237 /* previous problem? */ 3238 if (m->mf_state == SMFS_ERROR) 3239 { 3240 MILTER_CHECK_ERROR(continue); 3241 break; 3242 } 3243 3244 /* sanity checks */ 3245 if (m->mf_sock < 0 || 3246 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) 3247 continue; 3248 3249 m->mf_state = SMFS_INMSG; 3250 3251 /* check if filter wants the headers */ 3252 if (!bitset(SMFIP_NOHDRS, m->mf_pflags)) 3253 { 3254 response = milter_headers(m, e, state); 3255 MILTER_CHECK_RESULTS(); 3256 } 3257 3258 /* check if filter wants EOH */ 3259 if (!bitset(SMFIP_NOEOH, m->mf_pflags)) 3260 { 3261 if (tTd(64, 10)) 3262 dprintf("milter_data: eoh\n"); 3263 3264 /* send it over */ 3265 response = milter_send_command(m, SMFIC_EOH, NULL, 0, 3266 e, state); 3267 MILTER_CHECK_RESULTS(); 3268 } 3269 3270 /* check if filter wants the body */ 3271 if (!bitset(SMFIP_NOBODY, m->mf_pflags) && 3272 e->e_dfp != NULL) 3273 { 3274 rewind = TRUE; 3275 response = milter_body(m, e, state); 3276 MILTER_CHECK_RESULTS(); 3277 } 3278 3279 /* send the final body chunk */ 3280 (void) milter_write(m, SMFIC_BODYEOB, NULL, 0, 3281 m->mf_timeout[SMFTO_WRITE], e); 3282 3283 /* Get time EOM sent for timeout */ 3284 eomsent = curtime(); 3285 3286 /* deal with the possibility of multiple responses */ 3287 while (*state == SMFIR_CONTINUE) 3288 { 3289 /* Check total timeout from EOM to final ACK/NAK */ 3290 if (m->mf_timeout[SMFTO_EOM] > 0 && 3291 curtime() - eomsent >= m->mf_timeout[SMFTO_EOM]) 3292 { 3293 if (tTd(64, 5)) 3294 dprintf("milter_data(%s): EOM ACK/NAK timeout\n", 3295 m->mf_name); 3296 if (LogLevel > 0) 3297 sm_syslog(LOG_ERR, e->e_id, 3298 "milter_data(%s): EOM ACK/NAK timeout\n", 3299 m->mf_name); 3300 milter_error(m); 3301 MILTER_CHECK_ERROR(continue); 3302 break; 3303 } 3304 3305 response = milter_read(m, &rcmd, &rlen, 3306 m->mf_timeout[SMFTO_READ], e); 3307 if (m->mf_state == SMFS_ERROR) 3308 break; 3309 3310 if (tTd(64, 10)) 3311 dprintf("milter_data(%s): state %c\n", 3312 m->mf_name, (char) rcmd); 3313 3314 switch (rcmd) 3315 { 3316 case SMFIR_REPLYCODE: 3317 MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected"); 3318 *state = rcmd; 3319 m->mf_state = SMFS_DONE; 3320 break; 3321 3322 case SMFIR_REJECT: 3323 case SMFIR_DISCARD: 3324 case SMFIR_TEMPFAIL: 3325 *state = rcmd; 3326 m->mf_state = SMFS_DONE; 3327 break; 3328 3329 case SMFIR_CONTINUE: 3330 case SMFIR_ACCEPT: 3331 /* this filter is done with message */ 3332 if (replfailed) 3333 *state = SMFIR_TEMPFAIL; 3334 else 3335 *state = SMFIR_ACCEPT; 3336 m->mf_state = SMFS_DONE; 3337 break; 3338 3339 case SMFIR_PROGRESS: 3340 break; 3341 3342 case SMFIR_ADDHEADER: 3343 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags)) 3344 { 3345 if (LogLevel > 9) 3346 sm_syslog(LOG_WARNING, e->e_id, 3347 "milter_data(%s): lied about adding headers, honoring request anyway", 3348 m->mf_name); 3349 } 3350 milter_addheader(response, rlen, e); 3351 break; 3352 3353 case SMFIR_CHGHEADER: 3354 if (!bitset(SMFIF_CHGHDRS, m->mf_fflags)) 3355 { 3356 if (LogLevel > 9) 3357 sm_syslog(LOG_WARNING, e->e_id, 3358 "milter_data(%s): lied about changing headers, honoring request anyway", 3359 m->mf_name); 3360 } 3361 milter_changeheader(response, rlen, e); 3362 break; 3363 3364 case SMFIR_ADDRCPT: 3365 if (!bitset(SMFIF_ADDRCPT, m->mf_fflags)) 3366 { 3367 if (LogLevel > 9) 3368 sm_syslog(LOG_WARNING, e->e_id, 3369 "milter_data(%s) lied about adding recipients, honoring request anyway", 3370 m->mf_name); 3371 } 3372 milter_addrcpt(response, rlen, e); 3373 break; 3374 3375 case SMFIR_DELRCPT: 3376 if (!bitset(SMFIF_DELRCPT, m->mf_fflags)) 3377 { 3378 if (LogLevel > 9) 3379 sm_syslog(LOG_WARNING, e->e_id, 3380 "milter_data(%s): lied about removing recipients, honoring request anyway", 3381 m->mf_name); 3382 } 3383 milter_delrcpt(response, rlen, e); 3384 break; 3385 3386 case SMFIR_REPLBODY: 3387 if (!bitset(SMFIF_MODBODY, m->mf_fflags)) 3388 { 3389 if (LogLevel > 0) 3390 sm_syslog(LOG_ERR, e->e_id, 3391 "milter_data(%s): lied about replacing body, rejecting request and tempfailing message", 3392 m->mf_name); 3393 replfailed = TRUE; 3394 break; 3395 } 3396 3397 /* already failed in attempt */ 3398 if (replfailed) 3399 break; 3400 3401 if (!dfopen) 3402 { 3403 if (milter_reopen_df(e) < 0) 3404 { 3405 replfailed = TRUE; 3406 break; 3407 } 3408 dfopen = TRUE; 3409 rewind = TRUE; 3410 } 3411 3412 if (milter_replbody(response, rlen, 3413 newfilter, e) < 0) 3414 replfailed = TRUE; 3415 newfilter = FALSE; 3416 replbody = TRUE; 3417 break; 3418 3419 default: 3420 /* Invalid response to command */ 3421 if (LogLevel > 0) 3422 sm_syslog(LOG_ERR, e->e_id, 3423 "milter_data(%s): returned bogus response %c", 3424 m->mf_name, rcmd); 3425 milter_error(m); 3426 break; 3427 } 3428 if (rcmd != SMFIR_REPLYCODE && 3429 response != NULL) 3430 { 3431 sm_free(response); 3432 response = NULL; 3433 } 3434 3435 if (m->mf_state == SMFS_ERROR) 3436 break; 3437 } 3438 3439 if (replbody && !replfailed) 3440 { 3441 /* flush possible buffered character */ 3442 milter_replbody(NULL, 0, !replbody, e); 3443 replbody = FALSE; 3444 } 3445 3446 if (m->mf_state == SMFS_ERROR) 3447 { 3448 MILTER_CHECK_ERROR(continue); 3449 goto finishup; 3450 } 3451 } 3452 3453finishup: 3454 /* leave things in the expected state if we touched it */ 3455 if (replfailed) 3456 { 3457 if (*state == SMFIR_CONTINUE || 3458 *state == SMFIR_ACCEPT) 3459 { 3460 *state = SMFIR_TEMPFAIL; 3461 if (response != NULL) 3462 { 3463 sm_free(response); 3464 response = NULL; 3465 } 3466 } 3467 3468 if (dfopen) 3469 { 3470 (void) fclose(e->e_dfp); 3471 e->e_dfp = NULL; 3472 e->e_flags &= ~EF_HAS_DF; 3473 dfopen = FALSE; 3474 } 3475 rewind = FALSE; 3476 } 3477 3478 if ((dfopen && milter_reset_df(e) < 0) || 3479 (rewind && bfrewind(e->e_dfp) < 0)) 3480 { 3481 save_errno = errno; 3482 ExitStat = EX_IOERR; 3483 3484 /* 3485 ** If filter told us to keep message but we had 3486 ** an error, we can't really keep it, tempfail it. 3487 */ 3488 3489 if (*state == SMFIR_CONTINUE || 3490 *state == SMFIR_ACCEPT) 3491 { 3492 *state = SMFIR_TEMPFAIL; 3493 if (response != NULL) 3494 { 3495 sm_free(response); 3496 response = NULL; 3497 } 3498 } 3499 3500 errno = save_errno; 3501 syserr("milter_data: %s/df%s: read error", 3502 qid_printqueue(e->e_queuedir), e->e_id); 3503 } 3504 MILTER_CHECK_DONE_MSG(); 3505 return response; 3506} 3507/* 3508** MILTER_QUIT -- informs the filter(s) we are done and closes connection(s) 3509** 3510** Parameters: 3511** e -- current envelope. 3512** 3513** Returns: 3514** none 3515*/ 3516 3517void 3518milter_quit(e) 3519 ENVELOPE *e; 3520{ 3521 int i; 3522 3523 if (tTd(64, 10)) 3524 dprintf("milter_quit\n"); 3525 3526 for (i = 0; InputFilters[i] != NULL; i++) 3527 milter_quit_filter(InputFilters[i], e); 3528} 3529/* 3530** MILTER_ABORT -- informs the filter(s) that we are aborting current message 3531** 3532** Parameters: 3533** e -- current envelope. 3534** 3535** Returns: 3536** none 3537*/ 3538 3539void 3540milter_abort(e) 3541 ENVELOPE *e; 3542{ 3543 int i; 3544 3545 if (tTd(64, 10)) 3546 dprintf("milter_abort\n"); 3547 3548 for (i = 0; InputFilters[i] != NULL; i++) 3549 { 3550 struct milter *m = InputFilters[i]; 3551 3552 /* sanity checks */ 3553 if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG) 3554 continue; 3555 3556 milter_abort_filter(m, e); 3557 } 3558} 3559#endif /* _FFR_MILTER */
|