1 /* 2 * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 */ 10 11 #ifndef lint 12 static char id[] = "@(#)$Id: milter.c,v 8.50.4.53 2001/08/15 02:01:03 ca Exp $"; 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 29 static void milter_connect_timeout __P((void)); 30 static void milter_error __P((struct milter *)); 31 static int milter_open __P((struct milter *, bool, ENVELOPE *)); 32 static void milter_parse_timeouts __P((char *, struct milter *)); 33 34 static char *MilterConnectMacros[MAXFILTERMACROS + 1]; 35 static char *MilterHeloMacros[MAXFILTERMACROS + 1]; 36 static char *MilterEnvFromMacros[MAXFILTERMACROS + 1]; 37 static 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 205 static char * 206 milter_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 285 static char * 286 milter_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 385 static char * 386 milter_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 515 static jmp_buf MilterConnectTimeout; 516 517 static int 518 milter_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 1055 static void 1056 milter_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 1077 void 1078 milter_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; 1103 m->mf_timeout[SMFTO_CONNECT] = (time_t) 0; 1104 m->mf_timeout[SMFTO_WRITE] = (time_t) 10; 1105 m->mf_timeout[SMFTO_READ] = (time_t) 10; 1106 m->mf_timeout[SMFTO_EOM] = (time_t) 300; 1107 1108 /* now scan through and assign info from the fields */ 1109 while (*p != '\0') 1110 { 1111 char *delimptr; 1112 1113 while (*p != '\0' && 1114 (*p == ',' || (isascii(*p) && isspace(*p)))) 1115 p++; 1116 1117 /* p now points to field code */ 1118 fcode = *p; 1119 while (*p != '\0' && *p != '=' && *p != ',') 1120 p++; 1121 if (*p++ != '=') 1122 { 1123 syserr("X%s: `=' expected", m->mf_name); 1124 return; 1125 } 1126 while (isascii(*p) && isspace(*p)) 1127 p++; 1128 1129 /* p now points to the field body */ 1130 p = munchstring(p, &delimptr, ','); 1131 1132 /* install the field into the filter struct */ 1133 switch (fcode) 1134 { 1135 case 'S': /* socket */ 1136 if (p == NULL) 1137 m->mf_conn = NULL; 1138 else 1139 m->mf_conn = newstr(p); 1140 break; 1141 1142 case 'F': /* Milter flags configured on MTA */ 1143 for (; *p != '\0'; p++) 1144 { 1145 if (!(isascii(*p) && isspace(*p))) 1146 setbitn(bitidx(*p), m->mf_flags); 1147 } 1148 break; 1149 1150 case 'T': /* timeouts */ 1151 milter_parse_timeouts(p, m); 1152 break; 1153 1154 default: 1155 syserr("X%s: unknown filter equate %c=", 1156 m->mf_name, fcode); 1157 break; 1158 } 1159 p = delimptr; 1160 } 1161 1162 /* early check for errors */ 1163 (void) milter_open(m, TRUE, CurEnv); 1164 1165 /* enter the filter into the symbol table */ 1166 s = stab(m->mf_name, ST_MILTER, ST_ENTER); 1167 if (s->s_milter != NULL) 1168 syserr("X%s: duplicate filter definition", m->mf_name); 1169 else 1170 s->s_milter = m; 1171 } 1172 /* 1173 ** MILTER_PARSE_LIST -- parse option list into an array 1174 ** 1175 ** Called when reading configuration file. 1176 ** 1177 ** Parameters: 1178 ** spec -- the filter list. 1179 ** list -- the array to fill in. 1180 ** max -- the maximum number of entries in list. 1181 ** 1182 ** Returns: 1183 ** none 1184 */ 1185 1186 void 1187 milter_parse_list(spec, list, max) 1188 char *spec; 1189 struct milter **list; 1190 int max; 1191 { 1192 int numitems = 0; 1193 register char *p; 1194 1195 /* leave one for the NULL signifying the end of the list */ 1196 max--; 1197 1198 for (p = spec; p != NULL; ) 1199 { 1200 STAB *s; 1201 1202 while (isascii(*p) && isspace(*p)) 1203 p++; 1204 if (*p == '\0') 1205 break; 1206 spec = p; 1207 1208 if (numitems >= max) 1209 { 1210 syserr("Too many filters defined, %d max", max); 1211 if (max > 0) 1212 list[0] = NULL; 1213 return; 1214 } 1215 p = strpbrk(p, ","); 1216 if (p != NULL) 1217 *p++ = '\0'; 1218 1219 s = stab(spec, ST_MILTER, ST_FIND); 1220 if (s == NULL) 1221 { 1222 syserr("InputFilter %s not defined", spec); 1223 ExitStat = EX_CONFIG; 1224 return; 1225 } 1226 list[numitems++] = s->s_milter; 1227 } 1228 list[numitems] = NULL; 1229 } 1230 /* 1231 ** MILTER_PARSE_TIMEOUTS -- parse timeout list 1232 ** 1233 ** Called when reading configuration file. 1234 ** 1235 ** Parameters: 1236 ** spec -- the timeout list. 1237 ** m -- milter to set. 1238 ** 1239 ** Returns: 1240 ** none 1241 */ 1242 1243 static void 1244 milter_parse_timeouts(spec, m) 1245 char *spec; 1246 struct milter *m; 1247 { 1248 char fcode; 1249 register char *p; 1250 1251 p = spec; 1252 1253 /* now scan through and assign info from the fields */ 1254 while (*p != '\0') 1255 { 1256 char *delimptr; 1257 1258 while (*p != '\0' && 1259 (*p == ';' || (isascii(*p) && isspace(*p)))) 1260 p++; 1261 1262 /* p now points to field code */ 1263 fcode = *p; 1264 while (*p != '\0' && *p != ':') 1265 p++; 1266 if (*p++ != ':') 1267 { 1268 syserr("X%s, T=: `:' expected", m->mf_name); 1269 return; 1270 } 1271 while (isascii(*p) && isspace(*p)) 1272 p++; 1273 1274 /* p now points to the field body */ 1275 p = munchstring(p, &delimptr, ';'); 1276 1277 /* install the field into the filter struct */ 1278 switch (fcode) 1279 { 1280 case 'C': 1281 m->mf_timeout[SMFTO_CONNECT] = convtime(p, 's'); 1282 if (tTd(64, 5)) 1283 printf("X%s: %c=%ld\n", 1284 m->mf_name, fcode, 1285 (u_long) m->mf_timeout[SMFTO_CONNECT]); 1286 break; 1287 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 */ 1337 static BITMAP256 StickyMilterOpt; 1338 1339 static 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 1356 void 1357 milter_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 1465 static int 1466 milter_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 1519 static int 1520 milter_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 1567 bool 1568 milter_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 1602 static void 1603 milter_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 1644 static void 1645 milter_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 1674 static void 1675 milter_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 1745 static char * 1746 milter_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 1903 static char * 1904 milter_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 1964 static int 1965 milter_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 2131 static void 2132 milter_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 2156 static void 2157 milter_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 2186 static char * 2187 milter_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 2244 static char * 2245 milter_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 2365 static void 2366 milter_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 2448 static void 2449 milter_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 2597 static void 2598 milter_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 2640 static void 2641 milter_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 2683 static int 2684 milter_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 */ 2797 void 2798 milter_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 2856 char * 2857 milter_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 2983 char * 2984 milter_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 3031 char * 3032 milter_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 3114 char * 3115 milter_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 3189 char * 3190 milter_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 3453 finishup: 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 3517 void 3518 milter_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 3539 void 3540 milter_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 */ 3560