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