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