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