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