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