1 /* 2 * Copyright (c) 1999-2009, 2012, 2013 Proofpoint, 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.281 2013-11-22 20:51:56 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 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 *, const char *)); 65 static void milter_addrcpt __P((char *, ssize_t, ENVELOPE *, const char *)); 66 static void milter_addrcpt_par __P((char *, ssize_t, ENVELOPE *, const char *)); 67 static void milter_delrcpt __P((char *, ssize_t, ENVELOPE *, const char *)); 68 static int milter_replbody __P((char *, ssize_t, bool, ENVELOPE *, const char *)); 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_OK_SELECT(m->mf_sock)) \ 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 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 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 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 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 718 # if NETINET 719 else if (sm_strcasecmp(p, "inet") == 0) 720 addr.sa.sa_family = AF_INET; 721 # endif 722 # if NETINET6 723 else if (sm_strcasecmp(p, "inet6") == 0) 724 addr.sa.sa_family = AF_INET6; 725 # endif 726 else 727 { 728 # ifdef EPROTONOSUPPORT 729 errno = EPROTONOSUPPORT; 730 # else 731 errno = EINVAL; 732 # endif 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 824 # if NETINET6 825 || addr.sa.sa_family == AF_INET6 826 # endif 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 902 # if NETINET6 903 struct sockaddr_in6 hid6; 904 # endif 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 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 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 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 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 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 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 != ',' && !(SM_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 == ',' || (SM_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 (SM_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 (!(SM_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 (SM_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' && (*p == ';' || (SM_ISSPACE(*p)))) 1431 p++; 1432 1433 /* p now points to field code */ 1434 fcode = *p; 1435 while (*p != '\0' && *p != ':') 1436 p++; 1437 if (*p++ != ':') 1438 { 1439 syserr("X%s, T=: `:' expected", m->mf_name); 1440 return; 1441 } 1442 while (SM_ISSPACE(*p)) 1443 p++; 1444 1445 /* p now points to the field body */ 1446 p = munchstring(p, &delimptr, ';'); 1447 tcode = -1; 1448 1449 /* install the field into the filter struct */ 1450 switch (fcode) 1451 { 1452 case 'C': 1453 tcode = SMFTO_CONNECT; 1454 break; 1455 1456 case 'S': 1457 tcode = SMFTO_WRITE; 1458 break; 1459 1460 case 'R': 1461 tcode = SMFTO_READ; 1462 break; 1463 1464 case 'E': 1465 tcode = SMFTO_EOM; 1466 break; 1467 1468 default: 1469 if (tTd(64, 5)) 1470 sm_dprintf("X%s: %c unknown\n", 1471 m->mf_name, fcode); 1472 syserr("X%s: unknown filter timeout %c", 1473 m->mf_name, fcode); 1474 break; 1475 } 1476 if (tcode >= 0) 1477 { 1478 m->mf_timeout[tcode] = convtime(p, 's'); 1479 if (tTd(64, 5)) 1480 sm_dprintf("X%s: %c=%ld\n", 1481 m->mf_name, fcode, 1482 (u_long) m->mf_timeout[tcode]); 1483 } 1484 p = delimptr; 1485 } 1486 } 1487 1488 /* 1489 ** MILTER_SET_MACROS -- set milter macros 1490 ** 1491 ** Parameters: 1492 ** name -- name of milter. 1493 ** macros -- where to store macros. 1494 ** val -- the value of the option. 1495 ** nummac -- current number of macros 1496 ** 1497 ** Returns: 1498 ** new number of macros 1499 */ 1500 1501 static int 1502 milter_set_macros(name, macros, val, nummac) 1503 char *name; 1504 char **macros; 1505 char *val; 1506 int nummac; 1507 { 1508 char *p; 1509 1510 p = newstr(val); 1511 while (*p != '\0') 1512 { 1513 char *macro; 1514 1515 /* Skip leading commas, spaces */ 1516 while (*p != '\0' && (*p == ',' || (SM_ISSPACE(*p)))) 1517 p++; 1518 1519 if (*p == '\0') 1520 break; 1521 1522 /* Find end of macro */ 1523 macro = p; 1524 while (*p != '\0' && *p != ',' && 1525 isascii(*p) && !isspace(*p)) 1526 p++; 1527 if (*p != '\0') 1528 *p++ = '\0'; 1529 1530 if (nummac >= MAXFILTERMACROS) 1531 { 1532 syserr("milter_set_option: too many macros in Milter.%s (max %d)", 1533 name, MAXFILTERMACROS); 1534 macros[nummac] = NULL; 1535 return -1; 1536 } 1537 macros[nummac++] = macro; 1538 } 1539 macros[nummac] = NULL; 1540 return nummac; 1541 } 1542 1543 /* 1544 ** MILTER_SET_OPTION -- set an individual milter option 1545 ** 1546 ** Parameters: 1547 ** name -- the name of the option. 1548 ** val -- the value of the option. 1549 ** sticky -- if set, don't let other setoptions override 1550 ** this value. 1551 ** 1552 ** Returns: 1553 ** none. 1554 */ 1555 1556 /* set if Milter sub-option is stuck */ 1557 static BITMAP256 StickyMilterOpt; 1558 1559 static struct milteropt 1560 { 1561 char *mo_name; /* long name of milter option */ 1562 unsigned char mo_code; /* code for option */ 1563 } MilterOptTab[] = 1564 { 1565 { "macros.connect", SMFIM_CONNECT }, 1566 { "macros.helo", SMFIM_HELO }, 1567 { "macros.envfrom", SMFIM_ENVFROM }, 1568 { "macros.envrcpt", SMFIM_ENVRCPT }, 1569 { "macros.data", SMFIM_DATA }, 1570 { "macros.eom", SMFIM_EOM }, 1571 { "macros.eoh", SMFIM_EOH }, 1572 1573 # define MO_LOGLEVEL 0x07 1574 { "loglevel", MO_LOGLEVEL }, 1575 # if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE 1576 # define MO_MAXDATASIZE 0x08 1577 { "maxdatasize", MO_MAXDATASIZE }, 1578 # endif 1579 { NULL, (unsigned char)-1 }, 1580 }; 1581 1582 void 1583 milter_set_option(name, val, sticky) 1584 char *name; 1585 char *val; 1586 bool sticky; 1587 { 1588 int nummac, r; 1589 struct milteropt *mo; 1590 char **macros = NULL; 1591 1592 nummac = 0; 1593 if (tTd(37, 2) || tTd(64, 5)) 1594 sm_dprintf("milter_set_option(%s = %s)", name, val); 1595 1596 if (name == NULL) 1597 { 1598 syserr("milter_set_option: invalid Milter option, must specify suboption"); 1599 return; 1600 } 1601 1602 for (mo = MilterOptTab; mo->mo_name != NULL; mo++) 1603 { 1604 if (sm_strcasecmp(mo->mo_name, name) == 0) 1605 break; 1606 } 1607 1608 if (mo->mo_name == NULL) 1609 { 1610 syserr("milter_set_option: invalid Milter option %s", name); 1611 return; 1612 } 1613 1614 /* 1615 ** See if this option is preset for us. 1616 */ 1617 1618 if (!sticky && bitnset(mo->mo_code, StickyMilterOpt)) 1619 { 1620 if (tTd(37, 2) || tTd(64,5)) 1621 sm_dprintf(" (ignored)\n"); 1622 return; 1623 } 1624 1625 if (tTd(37, 2) || tTd(64,5)) 1626 sm_dprintf("\n"); 1627 1628 switch (mo->mo_code) 1629 { 1630 case MO_LOGLEVEL: 1631 MilterLogLevel = atoi(val); 1632 break; 1633 1634 # if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE 1635 case MO_MAXDATASIZE: 1636 # if _FFR_MDS_NEGOTIATE 1637 MilterMaxDataSize = (size_t)atol(val); 1638 if (MilterMaxDataSize != MILTER_MDS_64K && 1639 MilterMaxDataSize != MILTER_MDS_256K && 1640 MilterMaxDataSize != MILTER_MDS_1M) 1641 { 1642 sm_syslog(LOG_WARNING, NOQID, 1643 "WARNING: Milter.%s=%lu, allowed are only %d, %d, and %d", 1644 name, (unsigned long) MilterMaxDataSize, 1645 MILTER_MDS_64K, MILTER_MDS_256K, 1646 MILTER_MDS_1M); 1647 if (MilterMaxDataSize < MILTER_MDS_64K) 1648 MilterMaxDataSize = MILTER_MDS_64K; 1649 else if (MilterMaxDataSize < MILTER_MDS_256K) 1650 MilterMaxDataSize = MILTER_MDS_256K; 1651 else 1652 MilterMaxDataSize = MILTER_MDS_1M; 1653 } 1654 # endif /* _FFR_MDS_NEGOTIATE */ 1655 break; 1656 # endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */ 1657 1658 case SMFIM_CONNECT: 1659 case SMFIM_HELO: 1660 case SMFIM_ENVFROM: 1661 case SMFIM_ENVRCPT: 1662 case SMFIM_EOH: 1663 case SMFIM_EOM: 1664 case SMFIM_DATA: 1665 macros = MilterMacros[mo->mo_code][0]; 1666 1667 r = milter_set_macros(name, macros, val, nummac); 1668 if (r >= 0) 1669 nummac = r; 1670 break; 1671 1672 default: 1673 syserr("milter_set_option: invalid Milter option %s", name); 1674 break; 1675 } 1676 if (sticky) 1677 setbitn(mo->mo_code, StickyMilterOpt); 1678 } 1679 1680 /* 1681 ** MILTER_REOPEN_DF -- open & truncate the data file (for replbody) 1682 ** 1683 ** Parameters: 1684 ** e -- current envelope. 1685 ** 1686 ** Returns: 1687 ** 0 if successful, -1 otherwise 1688 */ 1689 1690 static int 1691 milter_reopen_df(e) 1692 ENVELOPE *e; 1693 { 1694 char dfname[MAXPATHLEN]; 1695 1696 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname)); 1697 1698 /* 1699 ** In SuperSafe == SAFE_REALLY mode, e->e_dfp is a read-only FP so 1700 ** close and reopen writable (later close and reopen 1701 ** read only again). 1702 ** 1703 ** In SuperSafe != SAFE_REALLY mode, e->e_dfp still points at the 1704 ** buffered file I/O descriptor, still open for writing so there 1705 ** isn't any work to do here (except checking for consistency). 1706 */ 1707 1708 if (SuperSafe == SAFE_REALLY) 1709 { 1710 /* close read-only data file */ 1711 if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL) 1712 { 1713 (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 1714 e->e_flags &= ~EF_HAS_DF; 1715 } 1716 1717 /* open writable */ 1718 if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, 1719 SM_IO_RDWR_B, NULL)) == NULL) 1720 { 1721 MILTER_DF_ERROR("milter_reopen_df: sm_io_open %s: %s"); 1722 return -1; 1723 } 1724 } 1725 else if (e->e_dfp == NULL) 1726 { 1727 /* shouldn't happen */ 1728 errno = ENOENT; 1729 MILTER_DF_ERROR("milter_reopen_df: NULL e_dfp (%s: %s)"); 1730 return -1; 1731 } 1732 return 0; 1733 } 1734 1735 /* 1736 ** MILTER_RESET_DF -- re-open read-only the data file (for replbody) 1737 ** 1738 ** Parameters: 1739 ** e -- current envelope. 1740 ** 1741 ** Returns: 1742 ** 0 if successful, -1 otherwise 1743 */ 1744 1745 static int 1746 milter_reset_df(e) 1747 ENVELOPE *e; 1748 { 1749 int afd; 1750 char dfname[MAXPATHLEN]; 1751 1752 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname)); 1753 1754 if (sm_io_flush(e->e_dfp, SM_TIME_DEFAULT) != 0 || 1755 sm_io_error(e->e_dfp)) 1756 { 1757 MILTER_DF_ERROR("milter_reset_df: error writing/flushing %s: %s"); 1758 return -1; 1759 } 1760 else if (SuperSafe != SAFE_REALLY) 1761 { 1762 /* skip next few clauses */ 1763 /* EMPTY */ 1764 } 1765 else if ((afd = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_FD, NULL)) >= 0 1766 && fsync(afd) < 0) 1767 { 1768 MILTER_DF_ERROR("milter_reset_df: error sync'ing %s: %s"); 1769 return -1; 1770 } 1771 else if (sm_io_close(e->e_dfp, SM_TIME_DEFAULT) < 0) 1772 { 1773 MILTER_DF_ERROR("milter_reset_df: error closing %s: %s"); 1774 return -1; 1775 } 1776 else if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, 1777 SM_IO_RDONLY_B, NULL)) == NULL) 1778 { 1779 MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s"); 1780 return -1; 1781 } 1782 else 1783 e->e_flags |= EF_HAS_DF; 1784 return 0; 1785 } 1786 1787 /* 1788 ** MILTER_QUIT_FILTER -- close down a single filter 1789 ** 1790 ** Parameters: 1791 ** m -- milter structure of filter to close down. 1792 ** e -- current envelope. 1793 ** 1794 ** Returns: 1795 ** none 1796 */ 1797 1798 static void 1799 milter_quit_filter(m, e) 1800 struct milter *m; 1801 ENVELOPE *e; 1802 { 1803 if (tTd(64, 10)) 1804 sm_dprintf("milter_quit_filter(%s)\n", m->mf_name); 1805 if (MilterLogLevel > 18) 1806 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): quit filter", 1807 m->mf_name); 1808 1809 /* Never replace error state */ 1810 if (m->mf_state == SMFS_ERROR) 1811 return; 1812 1813 if (m->mf_sock < 0 || 1814 m->mf_state == SMFS_CLOSED || 1815 m->mf_state == SMFS_READY) 1816 { 1817 m->mf_sock = -1; 1818 m->mf_state = SMFS_CLOSED; 1819 return; 1820 } 1821 1822 (void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0, 1823 m->mf_timeout[SMFTO_WRITE], e, "quit_filter"); 1824 if (m->mf_sock >= 0) 1825 { 1826 (void) close(m->mf_sock); 1827 m->mf_sock = -1; 1828 } 1829 if (m->mf_state != SMFS_ERROR) 1830 m->mf_state = SMFS_CLOSED; 1831 } 1832 1833 /* 1834 ** MILTER_ABORT_FILTER -- tell filter to abort current message 1835 ** 1836 ** Parameters: 1837 ** m -- milter structure of filter to abort. 1838 ** e -- current envelope. 1839 ** 1840 ** Returns: 1841 ** none 1842 */ 1843 1844 static void 1845 milter_abort_filter(m, e) 1846 struct milter *m; 1847 ENVELOPE *e; 1848 { 1849 if (tTd(64, 10)) 1850 sm_dprintf("milter_abort_filter(%s)\n", m->mf_name); 1851 if (MilterLogLevel > 10) 1852 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): abort filter", 1853 m->mf_name); 1854 1855 if (m->mf_sock < 0 || 1856 m->mf_state != SMFS_INMSG) 1857 return; 1858 1859 (void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0, 1860 m->mf_timeout[SMFTO_WRITE], e, "abort_filter"); 1861 if (m->mf_state != SMFS_ERROR) 1862 m->mf_state = SMFS_DONE; 1863 } 1864 1865 /* 1866 ** MILTER_SEND_MACROS -- provide macros to the filters 1867 ** 1868 ** Parameters: 1869 ** m -- milter to send macros to. 1870 ** macros -- macros to send for filter smfi_getsymval(). 1871 ** cmd -- which command the macros are associated with. 1872 ** e -- current envelope (for macro access). 1873 ** 1874 ** Returns: 1875 ** none 1876 */ 1877 1878 static void 1879 milter_send_macros(m, macros, cmd, e) 1880 struct milter *m; 1881 char **macros; 1882 int cmd; 1883 ENVELOPE *e; 1884 { 1885 int i; 1886 int mid; 1887 char command = (char) cmd; 1888 char *v; 1889 char *buf, *bp; 1890 char exp[MAXLINE]; 1891 ssize_t s; 1892 1893 /* sanity check */ 1894 if (macros == NULL || macros[0] == NULL) 1895 return; 1896 1897 /* put together data */ 1898 s = 1; /* for the command character */ 1899 for (i = 0; macros[i] != NULL; i++) 1900 { 1901 mid = macid(macros[i]); 1902 if (mid == 0) 1903 continue; 1904 v = macvalue(mid, e); 1905 if (v == NULL) 1906 continue; 1907 expand(v, exp, sizeof(exp), e); 1908 s += strlen(macros[i]) + 1 + strlen(exp) + 1; 1909 } 1910 1911 if (s < 0) 1912 return; 1913 1914 buf = (char *) xalloc(s); 1915 bp = buf; 1916 *bp++ = command; 1917 for (i = 0; macros[i] != NULL; i++) 1918 { 1919 mid = macid(macros[i]); 1920 if (mid == 0) 1921 continue; 1922 v = macvalue(mid, e); 1923 if (v == NULL) 1924 continue; 1925 expand(v, exp, sizeof(exp), e); 1926 1927 if (tTd(64, 10)) 1928 sm_dprintf("milter_send_macros(%s, %c): %s=%s\n", 1929 m->mf_name, command, macros[i], exp); 1930 1931 (void) sm_strlcpy(bp, macros[i], s - (bp - buf)); 1932 bp += strlen(bp) + 1; 1933 (void) sm_strlcpy(bp, exp, s - (bp - buf)); 1934 bp += strlen(bp) + 1; 1935 } 1936 (void) milter_write(m, SMFIC_MACRO, buf, s, 1937 m->mf_timeout[SMFTO_WRITE], e, "send_macros"); 1938 sm_free(buf); 1939 } 1940 1941 /* 1942 ** MILTER_SEND_COMMAND -- send a command and return the response for a filter 1943 ** 1944 ** Parameters: 1945 ** m -- current milter filter 1946 ** cmd -- command to send. 1947 ** data -- optional command data. 1948 ** sz -- length of buf. 1949 ** e -- current envelope (for e->e_id). 1950 ** state -- return state word. 1951 ** 1952 ** Returns: 1953 ** response string (may be NULL) 1954 */ 1955 1956 static char * 1957 milter_send_command(m, cmd, data, sz, e, state, where) 1958 struct milter *m; 1959 int cmd; 1960 void *data; 1961 ssize_t sz; 1962 ENVELOPE *e; 1963 char *state; 1964 const char *where; 1965 { 1966 char rcmd; 1967 ssize_t rlen; 1968 unsigned long skipflag; 1969 unsigned long norespflag = 0; 1970 char command = (char) cmd; 1971 char *action; 1972 char *defresponse; 1973 char *response; 1974 1975 if (tTd(64, 10)) 1976 sm_dprintf("milter_send_command(%s): cmd %c len %ld\n", 1977 m->mf_name, (char) command, (long) sz); 1978 1979 /* find skip flag and default failure */ 1980 switch (command) 1981 { 1982 case SMFIC_CONNECT: 1983 skipflag = SMFIP_NOCONNECT; 1984 norespflag = SMFIP_NR_CONN; 1985 action = "connect"; 1986 defresponse = "554 Command rejected"; 1987 break; 1988 1989 case SMFIC_HELO: 1990 skipflag = SMFIP_NOHELO; 1991 norespflag = SMFIP_NR_HELO; 1992 action = "helo"; 1993 defresponse = "550 Command rejected"; 1994 break; 1995 1996 case SMFIC_MAIL: 1997 skipflag = SMFIP_NOMAIL; 1998 norespflag = SMFIP_NR_MAIL; 1999 action = "mail"; 2000 defresponse = "550 5.7.1 Command rejected"; 2001 break; 2002 2003 case SMFIC_RCPT: 2004 skipflag = SMFIP_NORCPT; 2005 norespflag = SMFIP_NR_RCPT; 2006 action = "rcpt"; 2007 defresponse = "550 5.7.1 Command rejected"; 2008 break; 2009 2010 case SMFIC_HEADER: 2011 skipflag = SMFIP_NOHDRS; 2012 norespflag = SMFIP_NR_HDR; 2013 action = "header"; 2014 defresponse = "550 5.7.1 Command rejected"; 2015 break; 2016 2017 case SMFIC_BODY: 2018 skipflag = SMFIP_NOBODY; 2019 norespflag = SMFIP_NR_BODY; 2020 action = "body"; 2021 defresponse = "554 5.7.1 Command rejected"; 2022 break; 2023 2024 case SMFIC_EOH: 2025 skipflag = SMFIP_NOEOH; 2026 norespflag = SMFIP_NR_EOH; 2027 action = "eoh"; 2028 defresponse = "550 5.7.1 Command rejected"; 2029 break; 2030 2031 case SMFIC_UNKNOWN: 2032 skipflag = SMFIP_NOUNKNOWN; 2033 norespflag = SMFIP_NR_UNKN; 2034 action = "unknown"; 2035 defresponse = "550 5.7.1 Command rejected"; 2036 break; 2037 2038 case SMFIC_DATA: 2039 skipflag = SMFIP_NODATA; 2040 norespflag = SMFIP_NR_DATA; 2041 action = "data"; 2042 defresponse = "550 5.7.1 Command rejected"; 2043 break; 2044 2045 case SMFIC_BODYEOB: 2046 case SMFIC_OPTNEG: 2047 case SMFIC_MACRO: 2048 case SMFIC_ABORT: 2049 case SMFIC_QUIT: 2050 /* NOTE: not handled by milter_send_command() */ 2051 /* FALLTHROUGH */ 2052 2053 default: 2054 skipflag = 0; 2055 action = "default"; 2056 defresponse = "550 5.7.1 Command rejected"; 2057 break; 2058 } 2059 2060 if (tTd(64, 10)) 2061 sm_dprintf("milter_send_command(%s): skip=%lx, pflags=%x\n", 2062 m->mf_name, skipflag, m->mf_pflags); 2063 2064 /* check if filter wants this command */ 2065 if (skipflag != 0 && bitset(skipflag, m->mf_pflags)) 2066 return NULL; 2067 2068 /* send the command to the filter */ 2069 (void) milter_write(m, command, data, sz, 2070 m->mf_timeout[SMFTO_WRITE], e, where); 2071 if (m->mf_state == SMFS_ERROR) 2072 { 2073 MILTER_CHECK_ERROR(false, return NULL); 2074 return NULL; 2075 } 2076 2077 /* check if filter sends response to this command */ 2078 if (norespflag != 0 && bitset(norespflag, m->mf_pflags)) 2079 return NULL; 2080 2081 /* get the response from the filter */ 2082 response = milter_read(m, &rcmd, &rlen, 2083 m->mf_timeout[SMFTO_READ], e, where); 2084 if (m->mf_state == SMFS_ERROR) 2085 { 2086 MILTER_CHECK_ERROR(false, return NULL); 2087 return NULL; 2088 } 2089 2090 if (tTd(64, 10)) 2091 sm_dprintf("milter_send_command(%s): returned %c\n", 2092 m->mf_name, (char) rcmd); 2093 2094 switch (rcmd) 2095 { 2096 case SMFIR_REPLYCODE: 2097 MILTER_CHECK_REPLYCODE(defresponse); 2098 if (MilterLogLevel > 10) 2099 sm_syslog(LOG_INFO, e->e_id, 2100 "milter=%s, action=%s, reject=%s", 2101 m->mf_name, action, response); 2102 *state = rcmd; 2103 break; 2104 2105 case SMFIR_REJECT: 2106 if (MilterLogLevel > 10) 2107 sm_syslog(LOG_INFO, e->e_id, 2108 "milter=%s, action=%s, reject", 2109 m->mf_name, action); 2110 *state = rcmd; 2111 break; 2112 2113 case SMFIR_DISCARD: 2114 if (MilterLogLevel > 10) 2115 sm_syslog(LOG_INFO, e->e_id, 2116 "milter=%s, action=%s, discard", 2117 m->mf_name, action); 2118 *state = rcmd; 2119 break; 2120 2121 case SMFIR_TEMPFAIL: 2122 if (MilterLogLevel > 10) 2123 sm_syslog(LOG_INFO, e->e_id, 2124 "milter=%s, action=%s, tempfail", 2125 m->mf_name, action); 2126 *state = rcmd; 2127 break; 2128 2129 case SMFIR_ACCEPT: 2130 /* this filter is done with message/connection */ 2131 if (command == SMFIC_HELO || 2132 command == SMFIC_CONNECT) 2133 m->mf_state = SMFS_CLOSABLE; 2134 else 2135 m->mf_state = SMFS_DONE; 2136 if (MilterLogLevel > 10) 2137 sm_syslog(LOG_INFO, e->e_id, 2138 "milter=%s, action=%s, accepted", 2139 m->mf_name, action); 2140 break; 2141 2142 case SMFIR_CONTINUE: 2143 /* if MAIL command is ok, filter is in message state */ 2144 if (command == SMFIC_MAIL) 2145 m->mf_state = SMFS_INMSG; 2146 if (MilterLogLevel > 12) 2147 sm_syslog(LOG_INFO, e->e_id, 2148 "milter=%s, action=%s, continue", 2149 m->mf_name, action); 2150 break; 2151 2152 case SMFIR_SKIP: 2153 if (MilterLogLevel > 12) 2154 sm_syslog(LOG_INFO, e->e_id, 2155 "milter=%s, action=%s, skip", 2156 m->mf_name, action); 2157 m->mf_state = SMFS_SKIP; 2158 break; 2159 2160 default: 2161 /* Invalid response to command */ 2162 if (MilterLogLevel > 0) 2163 sm_syslog(LOG_ERR, e->e_id, 2164 "milter_send_command(%s): action=%s returned bogus response %c", 2165 m->mf_name, action, rcmd); 2166 milter_error(m, e); /* NO ERROR CHECK? */ 2167 break; 2168 } 2169 2170 if (*state != SMFIR_REPLYCODE && response != NULL) 2171 { 2172 sm_free(response); /* XXX */ 2173 response = NULL; 2174 } 2175 return response; 2176 } 2177 2178 /* 2179 ** MILTER_COMMAND -- send a command and return the response for each filter 2180 ** 2181 ** Parameters: 2182 ** cmd -- command to send. 2183 ** data -- optional command data. 2184 ** sz -- length of buf. 2185 ** stage -- index of macros to send for filter smfi_getsymval(). 2186 ** e -- current envelope (for macro access). 2187 ** state -- return state word. 2188 ** where -- description of calling function (logging). 2189 ** cmd_error -- did the SMTP command cause an error? 2190 ** 2191 ** Returns: 2192 ** response string (may be NULL) 2193 */ 2194 2195 static char * 2196 milter_command(cmd, data, sz, stage, e, state, where, cmd_error) 2197 int cmd; 2198 void *data; 2199 ssize_t sz; 2200 int stage; 2201 ENVELOPE *e; 2202 char *state; 2203 const char *where; 2204 bool cmd_error; 2205 { 2206 int i; 2207 char command = (char) cmd; 2208 char *response = NULL; 2209 time_t tn = 0; 2210 2211 if (tTd(64, 10)) 2212 sm_dprintf("milter_command: cmd %c len %ld\n", 2213 command, (long) sz); 2214 2215 *state = SMFIR_CONTINUE; 2216 for (i = 0; InputFilters[i] != NULL; i++) 2217 { 2218 struct milter *m = InputFilters[i]; 2219 2220 /* previous problem? */ 2221 if (m->mf_state == SMFS_ERROR) 2222 { 2223 MILTER_CHECK_ERROR(false, continue); 2224 break; 2225 } 2226 2227 /* sanity check */ 2228 if (m->mf_sock < 0 || 2229 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) 2230 continue; 2231 2232 if (stage >= SMFIM_FIRST && stage <= SMFIM_LAST) 2233 { 2234 int idx; 2235 char **macros; 2236 2237 if ((m->mf_lflags & MI_LFLAGS_SYM(stage)) != 0) 2238 idx = m->mf_idx; 2239 else 2240 idx = 0; 2241 SM_ASSERT(idx >= 0 && idx <= MAXFILTERS); 2242 macros = MilterMacros[stage][idx]; 2243 2244 /* send macros (regardless of whether we send cmd) */ 2245 if (macros != NULL && macros[0] != NULL) 2246 { 2247 milter_send_macros(m, macros, command, e); 2248 if (m->mf_state == SMFS_ERROR) 2249 { 2250 MILTER_CHECK_ERROR(false, continue); 2251 break; 2252 } 2253 } 2254 } 2255 2256 if (MilterLogLevel > 21) 2257 tn = curtime(); 2258 2259 /* 2260 ** send the command if 2261 ** there is no error 2262 ** or it's RCPT and the client asked for it: 2263 ** !cmd_error || 2264 ** where == "rcpt" && m->mf_pflags & SMFIP_RCPT_REJ != 0 2265 ** negate that condition and use continue 2266 */ 2267 2268 if (cmd_error && 2269 (strcmp(where, "rcpt") != 0 || 2270 (m->mf_pflags & SMFIP_RCPT_REJ) == 0)) 2271 continue; 2272 2273 response = milter_send_command(m, command, data, sz, e, state, 2274 where); 2275 2276 if (MilterLogLevel > 21) 2277 { 2278 /* log the time it took for the command per filter */ 2279 sm_syslog(LOG_INFO, e->e_id, 2280 "Milter (%s): time command (%c), %d", 2281 m->mf_name, command, (int) (tn - curtime())); 2282 } 2283 2284 if (*state != SMFIR_CONTINUE) 2285 break; 2286 } 2287 return response; 2288 } 2289 2290 static int milter_getsymlist __P((struct milter *, char *, int, int)); 2291 2292 static int 2293 milter_getsymlist(m, buf, rlen, offset) 2294 struct milter *m; 2295 char *buf; 2296 int rlen; 2297 int offset; 2298 { 2299 int i, r, nummac; 2300 mi_int32 v; 2301 2302 SM_ASSERT(m != NULL); 2303 SM_ASSERT(buf != NULL); 2304 2305 while (offset + MILTER_LEN_BYTES < rlen) 2306 { 2307 size_t len; 2308 char **macros; 2309 2310 nummac = 0; 2311 (void) memcpy((char *) &v, buf + offset, MILTER_LEN_BYTES); 2312 i = ntohl(v); 2313 if (i < SMFIM_FIRST || i > SMFIM_LAST) 2314 return -1; 2315 offset += MILTER_LEN_BYTES; 2316 macros = NULL; 2317 2318 #define SM_M_MACRO_NAME(i) (((i) < SM_ARRAY_SIZE(MilterOptTab) && (i) >= 0) \ 2319 ? MilterOptTab[i].mo_name : "?") 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 m->mf_lflags |= MI_LFLAGS_SYM(i); 2332 len = strlen(buf + offset); 2333 r = milter_set_macros(m->mf_name, macros, buf + offset, 2334 nummac); 2335 if (r >= 0) 2336 nummac = r; 2337 if (tTd(64, 5)) 2338 sm_dprintf("milter_getsymlist(%s, %s, \"%s\")=%d\n", 2339 m->mf_name, SM_M_MACRO_NAME(i), 2340 buf + offset, r); 2341 break; 2342 2343 default: 2344 return -1; 2345 } 2346 offset += len + 1; 2347 } 2348 2349 return 0; 2350 } 2351 2352 /* 2353 ** MILTER_NEGOTIATE -- get version and flags from filter 2354 ** 2355 ** Parameters: 2356 ** m -- milter filter structure. 2357 ** e -- current envelope. 2358 ** milters -- milters structure. 2359 ** 2360 ** Returns: 2361 ** 0 on success, -1 otherwise 2362 */ 2363 2364 static int 2365 milter_negotiate(m, e, milters) 2366 struct milter *m; 2367 ENVELOPE *e; 2368 milters_T *milters; 2369 { 2370 char rcmd; 2371 mi_int32 fvers, fflags, pflags; 2372 mi_int32 mta_prot_vers, mta_prot_flags, mta_actions; 2373 ssize_t rlen; 2374 char *response; 2375 char data[MILTER_OPTLEN]; 2376 2377 /* sanity check */ 2378 if (m->mf_sock < 0 || m->mf_state != SMFS_OPEN) 2379 { 2380 if (MilterLogLevel > 0) 2381 sm_syslog(LOG_ERR, e->e_id, 2382 "Milter (%s): negotiate, impossible state", 2383 m->mf_name); 2384 milter_error(m, e); 2385 return -1; 2386 } 2387 2388 #if _FFR_MILTER_CHECK 2389 mta_prot_vers = m->mf_mta_prot_version; 2390 mta_prot_flags = m->mf_mta_prot_flags; 2391 mta_actions = m->mf_mta_actions; 2392 #else /* _FFR_MILTER_CHECK */ 2393 mta_prot_vers = SMFI_PROT_VERSION; 2394 mta_prot_flags = SMFI_CURR_PROT; 2395 mta_actions = SMFI_CURR_ACTS; 2396 #endif /* _FFR_MILTER_CHECK */ 2397 #if _FFR_MDS_NEGOTIATE 2398 if (MilterMaxDataSize == MILTER_MDS_256K) 2399 mta_prot_flags |= SMFIP_MDS_256K; 2400 else if (MilterMaxDataSize == MILTER_MDS_1M) 2401 mta_prot_flags |= SMFIP_MDS_1M; 2402 #endif /* _FFR_MDS_NEGOTIATE */ 2403 2404 fvers = htonl(mta_prot_vers); 2405 pflags = htonl(mta_prot_flags); 2406 fflags = htonl(mta_actions); 2407 (void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES); 2408 (void) memcpy(data + MILTER_LEN_BYTES, 2409 (char *) &fflags, MILTER_LEN_BYTES); 2410 (void) memcpy(data + (MILTER_LEN_BYTES * 2), 2411 (char *) &pflags, MILTER_LEN_BYTES); 2412 (void) milter_write(m, SMFIC_OPTNEG, data, sizeof(data), 2413 m->mf_timeout[SMFTO_WRITE], e, "negotiate"); 2414 2415 if (m->mf_state == SMFS_ERROR) 2416 return -1; 2417 2418 if (tTd(64, 5)) 2419 sm_dprintf("milter_negotiate(%s): send: version %lu, fflags 0x%lx, pflags 0x%lx\n", 2420 m->mf_name, (unsigned long) ntohl(fvers), 2421 (unsigned long) ntohl(fflags), 2422 (unsigned long) ntohl(pflags)); 2423 2424 response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e, 2425 "negotiate"); 2426 if (m->mf_state == SMFS_ERROR) 2427 return -1; 2428 2429 if (rcmd != SMFIC_OPTNEG) 2430 { 2431 if (tTd(64, 5)) 2432 sm_dprintf("milter_negotiate(%s): returned %c instead of %c\n", 2433 m->mf_name, rcmd, SMFIC_OPTNEG); 2434 if (MilterLogLevel > 0) 2435 sm_syslog(LOG_ERR, e->e_id, 2436 "Milter (%s): negotiate: returned %c instead of %c", 2437 m->mf_name, rcmd, SMFIC_OPTNEG); 2438 SM_FREE(response); 2439 milter_error(m, e); 2440 return -1; 2441 } 2442 2443 /* Make sure we have enough bytes for the version */ 2444 if (response == NULL || rlen < MILTER_LEN_BYTES) 2445 { 2446 if (tTd(64, 5)) 2447 sm_dprintf("milter_negotiate(%s): did not return valid info\n", 2448 m->mf_name); 2449 if (MilterLogLevel > 0) 2450 sm_syslog(LOG_ERR, e->e_id, 2451 "Milter (%s): negotiate: did not return valid info", 2452 m->mf_name); 2453 SM_FREE(response); 2454 milter_error(m, e); 2455 return -1; 2456 } 2457 2458 /* extract information */ 2459 (void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES); 2460 2461 /* Now make sure we have enough for the feature bitmap */ 2462 if (rlen < MILTER_OPTLEN) 2463 { 2464 if (tTd(64, 5)) 2465 sm_dprintf("milter_negotiate(%s): did not return enough info\n", 2466 m->mf_name); 2467 if (MilterLogLevel > 0) 2468 sm_syslog(LOG_ERR, e->e_id, 2469 "Milter (%s): negotiate: did not return enough info", 2470 m->mf_name); 2471 SM_FREE(response); 2472 milter_error(m, e); 2473 return -1; 2474 } 2475 2476 (void) memcpy((char *) &fflags, response + MILTER_LEN_BYTES, 2477 MILTER_LEN_BYTES); 2478 (void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2), 2479 MILTER_LEN_BYTES); 2480 2481 m->mf_fvers = ntohl(fvers); 2482 m->mf_fflags = ntohl(fflags); 2483 m->mf_pflags = ntohl(pflags); 2484 2485 /* check for version compatibility */ 2486 if (m->mf_fvers == 1 || 2487 m->mf_fvers > SMFI_VERSION) 2488 { 2489 if (tTd(64, 5)) 2490 sm_dprintf("milter_negotiate(%s): version %d != MTA milter version %d\n", 2491 m->mf_name, m->mf_fvers, SMFI_VERSION); 2492 if (MilterLogLevel > 0) 2493 sm_syslog(LOG_ERR, e->e_id, 2494 "Milter (%s): negotiate: version %d != MTA milter version %d", 2495 m->mf_name, m->mf_fvers, SMFI_VERSION); 2496 milter_error(m, e); 2497 goto error; 2498 } 2499 2500 /* check for filter feature mismatch */ 2501 if ((m->mf_fflags & mta_actions) != m->mf_fflags) 2502 { 2503 if (tTd(64, 5)) 2504 sm_dprintf("milter_negotiate(%s): filter abilities 0x%x != MTA milter abilities 0x%lx\n", 2505 m->mf_name, m->mf_fflags, 2506 (unsigned long) mta_actions); 2507 if (MilterLogLevel > 0) 2508 sm_syslog(LOG_ERR, e->e_id, 2509 "Milter (%s): negotiate: filter abilities 0x%x != MTA milter abilities 0x%lx", 2510 m->mf_name, m->mf_fflags, 2511 (unsigned long) mta_actions); 2512 milter_error(m, e); 2513 goto error; 2514 } 2515 2516 #if _FFR_MDS_NEGOTIATE 2517 #define MDSWARNING(sz) \ 2518 do \ 2519 { \ 2520 sm_syslog(LOG_WARNING, NOQID, \ 2521 "WARNING: Milter.maxdatasize: configured=%lu, set by milter(%s)=%d", \ 2522 (unsigned long) MilterMaxDataSize, m->mf_name, sz); \ 2523 MilterMaxDataSize = sz; \ 2524 } while (0) 2525 2526 /* use a table instead of sequence? */ 2527 if (bitset(SMFIP_MDS_1M, m->mf_pflags)) 2528 { 2529 if (MilterMaxDataSize != MILTER_MDS_1M) 2530 MDSWARNING(MILTER_MDS_1M); 2531 } 2532 else if (bitset(SMFIP_MDS_256K, m->mf_pflags)) 2533 { 2534 if (MilterMaxDataSize != MILTER_MDS_256K) 2535 MDSWARNING(MILTER_MDS_256K); 2536 } 2537 2538 /* 2539 ** Note: it is not possible to distinguish between 2540 ** - milter requested 64K 2541 ** - milter did not request anything 2542 ** as there is no SMFIP_MDS_64K flag. 2543 */ 2544 2545 else if (MilterMaxDataSize != MILTER_MDS_64K) 2546 MDSWARNING(MILTER_MDS_64K); 2547 m->mf_pflags &= ~SMFI_INTERNAL; 2548 #endif /* _FFR_MDS_NEGOTIATE */ 2549 2550 /* check for protocol feature mismatch */ 2551 if ((m->mf_pflags & mta_prot_flags) != m->mf_pflags) 2552 { 2553 if (tTd(64, 5)) 2554 sm_dprintf("milter_negotiate(%s): protocol abilities 0x%x != MTA milter abilities 0x%lx\n", 2555 m->mf_name, m->mf_pflags, 2556 (unsigned long) mta_prot_flags); 2557 if (MilterLogLevel > 0) 2558 sm_syslog(LOG_ERR, e->e_id, 2559 "Milter (%s): negotiate: protocol abilities 0x%x != MTA milter abilities 0x%lx", 2560 m->mf_name, m->mf_pflags, 2561 (unsigned long) mta_prot_flags); 2562 milter_error(m, e); 2563 goto error; 2564 } 2565 2566 if (m->mf_fvers <= 2) 2567 m->mf_pflags |= SMFIP_NOUNKNOWN; 2568 if (m->mf_fvers <= 3) 2569 m->mf_pflags |= SMFIP_NODATA; 2570 2571 if (rlen > MILTER_OPTLEN) 2572 { 2573 milter_getsymlist(m, response, rlen, MILTER_OPTLEN); 2574 } 2575 2576 if (bitset(SMFIF_DELRCPT, m->mf_fflags)) 2577 milters->mis_flags |= MIS_FL_DEL_RCPT; 2578 if (!bitset(SMFIP_NORCPT, m->mf_pflags) && 2579 !bitset(SMFIP_NR_RCPT, m->mf_pflags)) 2580 milters->mis_flags |= MIS_FL_REJ_RCPT; 2581 2582 if (tTd(64, 5)) 2583 sm_dprintf("milter_negotiate(%s): received: version %u, fflags 0x%x, pflags 0x%x\n", 2584 m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags); 2585 SM_FREE(response); 2586 return 0; 2587 2588 error: 2589 SM_FREE(response); 2590 return -1; 2591 } 2592 2593 /* 2594 ** MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands 2595 ** 2596 ** Reduce code duplication by putting these checks in one place 2597 ** 2598 ** Parameters: 2599 ** e -- current envelope. 2600 ** 2601 ** Returns: 2602 ** none 2603 */ 2604 2605 static void 2606 milter_per_connection_check(e) 2607 ENVELOPE *e; 2608 { 2609 int i; 2610 2611 /* see if we are done with any of the filters */ 2612 for (i = 0; InputFilters[i] != NULL; i++) 2613 { 2614 struct milter *m = InputFilters[i]; 2615 2616 if (m->mf_state == SMFS_CLOSABLE) 2617 milter_quit_filter(m, e); 2618 } 2619 } 2620 2621 /* 2622 ** MILTER_ERROR -- Put a milter filter into error state 2623 ** 2624 ** Parameters: 2625 ** m -- the broken filter. 2626 ** e -- current envelope. 2627 ** 2628 ** Returns: 2629 ** none 2630 */ 2631 2632 static void 2633 milter_error(m, e) 2634 struct milter *m; 2635 ENVELOPE *e; 2636 { 2637 /* 2638 ** We could send a quit here but we may have gotten here due to 2639 ** an I/O error so we don't want to try to make things worse. 2640 */ 2641 2642 if (m->mf_sock >= 0) 2643 { 2644 (void) close(m->mf_sock); 2645 m->mf_sock = -1; 2646 } 2647 m->mf_state = SMFS_ERROR; 2648 2649 if (MilterLogLevel > 0) 2650 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): to error state", 2651 m->mf_name); 2652 } 2653 2654 /* 2655 ** MILTER_HEADERS -- send headers to a single milter filter 2656 ** 2657 ** Parameters: 2658 ** m -- current filter. 2659 ** e -- current envelope. 2660 ** state -- return state from response. 2661 ** 2662 ** Returns: 2663 ** response string (may be NULL) 2664 */ 2665 2666 static char * 2667 milter_headers(m, e, state) 2668 struct milter *m; 2669 ENVELOPE *e; 2670 char *state; 2671 { 2672 char *response = NULL; 2673 HDR *h; 2674 2675 if (MilterLogLevel > 17) 2676 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, send", 2677 m->mf_name); 2678 2679 for (h = e->e_header; h != NULL; h = h->h_link) 2680 { 2681 int len_n, len_v, len_t, len_f; 2682 char *buf, *hv; 2683 2684 /* don't send over deleted headers */ 2685 if (h->h_value == NULL) 2686 { 2687 /* strip H_USER so not counted in milter_changeheader() */ 2688 h->h_flags &= ~H_USER; 2689 continue; 2690 } 2691 2692 /* skip auto-generated */ 2693 if (!bitset(H_USER, h->h_flags)) 2694 continue; 2695 2696 if (tTd(64, 10)) 2697 sm_dprintf("milter_headers: %s:%s\n", 2698 h->h_field, h->h_value); 2699 if (MilterLogLevel > 21) 2700 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): header, %s", 2701 m->mf_name, h->h_field); 2702 2703 if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags) 2704 || *(h->h_value) != ' ') 2705 hv = h->h_value; 2706 else 2707 hv = h->h_value + 1; 2708 len_f = strlen(h->h_field) + 1; 2709 len_t = len_f + strlen(hv) + 1; 2710 if (len_t < 0) 2711 continue; 2712 buf = (char *) xalloc(len_t); 2713 2714 /* 2715 ** Note: currently the call to dequote_internal_chars() 2716 ** is not required as h_field is supposed to be 7-bit US-ASCII. 2717 */ 2718 2719 len_n = dequote_internal_chars(h->h_field, buf, len_f); 2720 SM_ASSERT(len_n < len_f); 2721 len_v = dequote_internal_chars(hv, buf + len_n + 1, 2722 len_t - len_n - 1); 2723 SM_ASSERT(len_t >= len_n + 1 + len_v + 1); 2724 len_t = len_n + 1 + len_v + 1; 2725 2726 /* send it over */ 2727 response = milter_send_command(m, SMFIC_HEADER, buf, 2728 len_t, e, state, "header"); 2729 sm_free(buf); 2730 if (m->mf_state == SMFS_ERROR || 2731 m->mf_state == SMFS_DONE || 2732 *state != SMFIR_CONTINUE) 2733 break; 2734 } 2735 if (MilterLogLevel > 17) 2736 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, sent", 2737 m->mf_name); 2738 return response; 2739 } 2740 2741 /* 2742 ** MILTER_BODY -- send the body to a filter 2743 ** 2744 ** Parameters: 2745 ** m -- current filter. 2746 ** e -- current envelope. 2747 ** state -- return state from response. 2748 ** 2749 ** Returns: 2750 ** response string (may be NULL) 2751 */ 2752 2753 static char * 2754 milter_body(m, e, state) 2755 struct milter *m; 2756 ENVELOPE *e; 2757 char *state; 2758 { 2759 char bufchar = '\0'; 2760 char prevchar = '\0'; 2761 int c; 2762 char *response = NULL; 2763 char *bp; 2764 char buf[MILTER_CHUNK_SIZE]; 2765 2766 if (tTd(64, 10)) 2767 sm_dprintf("milter_body\n"); 2768 2769 if (bfrewind(e->e_dfp) < 0) 2770 { 2771 ExitStat = EX_IOERR; 2772 *state = SMFIR_TEMPFAIL; 2773 syserr("milter_body: %s/%cf%s: rewind error", 2774 qid_printqueue(e->e_qgrp, e->e_qdir), 2775 DATAFL_LETTER, e->e_id); 2776 return NULL; 2777 } 2778 2779 if (MilterLogLevel > 17) 2780 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, send", 2781 m->mf_name); 2782 bp = buf; 2783 while ((c = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT)) != SM_IO_EOF) 2784 { 2785 /* Change LF to CRLF */ 2786 if (c == '\n') 2787 { 2788 #if !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF 2789 /* Not a CRLF already? */ 2790 if (prevchar != '\r') 2791 #endif 2792 { 2793 /* Room for CR now? */ 2794 if (bp + 2 > &buf[sizeof(buf)]) 2795 { 2796 /* No room, buffer LF */ 2797 bufchar = c; 2798 2799 /* and send CR now */ 2800 c = '\r'; 2801 } 2802 else 2803 { 2804 /* Room to do it now */ 2805 *bp++ = '\r'; 2806 prevchar = '\r'; 2807 } 2808 } 2809 } 2810 *bp++ = (char) c; 2811 prevchar = c; 2812 if (bp >= &buf[sizeof(buf)]) 2813 { 2814 /* send chunk */ 2815 response = milter_send_command(m, SMFIC_BODY, buf, 2816 bp - buf, e, state, 2817 "body chunk"); 2818 bp = buf; 2819 if (bufchar != '\0') 2820 { 2821 *bp++ = bufchar; 2822 bufchar = '\0'; 2823 prevchar = bufchar; 2824 } 2825 } 2826 if (m->mf_state == SMFS_ERROR || 2827 m->mf_state == SMFS_DONE || 2828 m->mf_state == SMFS_SKIP || 2829 *state != SMFIR_CONTINUE) 2830 break; 2831 } 2832 2833 /* check for read errors */ 2834 if (sm_io_error(e->e_dfp)) 2835 { 2836 ExitStat = EX_IOERR; 2837 if (*state == SMFIR_CONTINUE || 2838 *state == SMFIR_ACCEPT || 2839 m->mf_state == SMFS_SKIP) 2840 { 2841 *state = SMFIR_TEMPFAIL; 2842 if (response != NULL) 2843 { 2844 sm_free(response); /* XXX */ 2845 response = NULL; 2846 } 2847 } 2848 syserr("milter_body: %s/%cf%s: read error", 2849 qid_printqueue(e->e_qgrp, e->e_qdir), 2850 DATAFL_LETTER, e->e_id); 2851 return response; 2852 } 2853 2854 /* send last body chunk */ 2855 if (bp > buf && 2856 m->mf_state != SMFS_ERROR && 2857 m->mf_state != SMFS_DONE && 2858 m->mf_state != SMFS_SKIP && 2859 *state == SMFIR_CONTINUE) 2860 { 2861 /* send chunk */ 2862 response = milter_send_command(m, SMFIC_BODY, buf, bp - buf, 2863 e, state, "last body chunk"); 2864 bp = buf; 2865 } 2866 if (MilterLogLevel > 17) 2867 sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, sent", 2868 m->mf_name); 2869 if (m->mf_state == SMFS_SKIP) 2870 { 2871 *state = SMFIR_CONTINUE; 2872 m->mf_state = SMFS_READY; 2873 } 2874 2875 return response; 2876 } 2877 2878 /* 2879 ** Actions 2880 */ 2881 2882 /* 2883 ** ADDLEADINGSPACE -- Add a leading space to a string 2884 ** 2885 ** Parameters: 2886 ** str -- string 2887 ** rp -- resource pool for allocations 2888 ** 2889 ** Returns: 2890 ** pointer to new string 2891 */ 2892 2893 static char *addleadingspace __P((char *, SM_RPOOL_T *)); 2894 2895 static char * 2896 addleadingspace(str, rp) 2897 char *str; 2898 SM_RPOOL_T *rp; 2899 { 2900 size_t l; 2901 char *new; 2902 2903 SM_ASSERT(str != NULL); 2904 l = strlen(str); 2905 SM_ASSERT(l + 2 > l); 2906 new = sm_rpool_malloc_x(rp, l + 2); 2907 new[0] = ' '; 2908 new[1] = '\0'; 2909 sm_strlcpy(new + 1, str, l + 1); 2910 return new; 2911 } 2912 2913 /* 2914 ** MILTER_ADDHEADER -- Add the supplied header to the message 2915 ** 2916 ** Parameters: 2917 ** m -- current filter. 2918 ** response -- encoded form of header/value. 2919 ** rlen -- length of response. 2920 ** e -- current envelope. 2921 ** 2922 ** Returns: 2923 ** none 2924 */ 2925 2926 static void 2927 milter_addheader(m, response, rlen, e) 2928 struct milter *m; 2929 char *response; 2930 ssize_t rlen; 2931 ENVELOPE *e; 2932 { 2933 int mh_v_len; 2934 char *val, *mh_value; 2935 HDR *h; 2936 2937 if (tTd(64, 10)) 2938 sm_dprintf("milter_addheader: "); 2939 2940 /* sanity checks */ 2941 if (response == NULL) 2942 { 2943 if (tTd(64, 10)) 2944 sm_dprintf("NULL response\n"); 2945 return; 2946 } 2947 2948 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 2949 { 2950 if (tTd(64, 10)) 2951 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 2952 (int) strlen(response), (int) (rlen - 1)); 2953 return; 2954 } 2955 2956 /* Find separating NUL */ 2957 val = response + strlen(response) + 1; 2958 2959 /* another sanity check */ 2960 if (strlen(response) + strlen(val) + 2 != (size_t) rlen) 2961 { 2962 if (tTd(64, 10)) 2963 sm_dprintf("didn't follow protocol (part len)\n"); 2964 return; 2965 } 2966 2967 if (*response == '\0') 2968 { 2969 if (tTd(64, 10)) 2970 sm_dprintf("empty field name\n"); 2971 return; 2972 } 2973 2974 for (h = e->e_header; h != NULL; h = h->h_link) 2975 { 2976 if (sm_strcasecmp(h->h_field, response) == 0 && 2977 !bitset(H_USER, h->h_flags) && 2978 !bitset(H_TRACE, h->h_flags)) 2979 break; 2980 } 2981 2982 mh_v_len = 0; 2983 mh_value = quote_internal_chars(val, NULL, &mh_v_len); 2984 2985 /* add to e_msgsize */ 2986 e->e_msgsize += strlen(response) + 2 + strlen(val); 2987 2988 if (h != NULL) 2989 { 2990 if (tTd(64, 10)) 2991 sm_dprintf("Replace default header %s value with %s\n", 2992 h->h_field, mh_value); 2993 if (MilterLogLevel > 8) 2994 sm_syslog(LOG_INFO, e->e_id, 2995 "Milter (%s) change: default header %s value with %s", 2996 m->mf_name, h->h_field, mh_value); 2997 if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)) 2998 h->h_value = mh_value; 2999 else 3000 { 3001 h->h_value = addleadingspace(mh_value, e->e_rpool); 3002 SM_FREE(mh_value); 3003 } 3004 h->h_flags |= H_USER; 3005 } 3006 else 3007 { 3008 if (tTd(64, 10)) 3009 sm_dprintf("Add %s: %s\n", response, mh_value); 3010 if (MilterLogLevel > 8) 3011 sm_syslog(LOG_INFO, e->e_id, 3012 "Milter (%s) add: header: %s: %s", 3013 m->mf_name, response, mh_value); 3014 addheader(newstr(response), mh_value, H_USER, e, 3015 !bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)); 3016 SM_FREE(mh_value); 3017 } 3018 } 3019 3020 /* 3021 ** MILTER_INSHEADER -- Insert the supplied header 3022 ** 3023 ** Parameters: 3024 ** m -- current filter. 3025 ** response -- encoded form of header/value. 3026 ** rlen -- length of response. 3027 ** e -- current envelope. 3028 ** 3029 ** Returns: 3030 ** none 3031 ** 3032 ** Notes: 3033 ** Unlike milter_addheader(), this does not attempt to determine 3034 ** if the header already exists in the envelope, even a 3035 ** deleted version. It just blindly inserts. 3036 */ 3037 3038 static void 3039 milter_insheader(m, response, rlen, e) 3040 struct milter *m; 3041 char *response; 3042 ssize_t rlen; 3043 ENVELOPE *e; 3044 { 3045 mi_int32 idx, i; 3046 int mh_v_len; 3047 char *field, *val, *mh_value; 3048 3049 if (tTd(64, 10)) 3050 sm_dprintf("milter_insheader: "); 3051 3052 /* sanity checks */ 3053 if (response == NULL) 3054 { 3055 if (tTd(64, 10)) 3056 sm_dprintf("NULL response\n"); 3057 return; 3058 } 3059 3060 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 3061 { 3062 if (tTd(64, 10)) 3063 sm_dprintf("didn't follow protocol (total len)\n"); 3064 return; 3065 } 3066 3067 /* decode */ 3068 (void) memcpy((char *) &i, response, MILTER_LEN_BYTES); 3069 idx = ntohl(i); 3070 field = response + MILTER_LEN_BYTES; 3071 val = field + strlen(field) + 1; 3072 3073 /* another sanity check */ 3074 if (MILTER_LEN_BYTES + strlen(field) + 1 + 3075 strlen(val) + 1 != (size_t) rlen) 3076 { 3077 if (tTd(64, 10)) 3078 sm_dprintf("didn't follow protocol (part len)\n"); 3079 return; 3080 } 3081 3082 if (*field == '\0') 3083 { 3084 if (tTd(64, 10)) 3085 sm_dprintf("empty field name\n"); 3086 return; 3087 } 3088 3089 /* add to e_msgsize */ 3090 e->e_msgsize += strlen(response) + 2 + strlen(val); 3091 3092 if (tTd(64, 10)) 3093 sm_dprintf("Insert (%d) %s: %s\n", idx, field, val); 3094 if (MilterLogLevel > 8) 3095 sm_syslog(LOG_INFO, e->e_id, 3096 "Milter (%s) insert (%d): header: %s: %s", 3097 m->mf_name, idx, field, val); 3098 mh_v_len = 0; 3099 mh_value = quote_internal_chars(val, NULL, &mh_v_len); 3100 insheader(idx, newstr(field), mh_value, H_USER, e, 3101 !bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)); 3102 SM_FREE(mh_value); 3103 } 3104 3105 /* 3106 ** MILTER_CHANGEHEADER -- Change the supplied header in the message 3107 ** 3108 ** Parameters: 3109 ** m -- current filter. 3110 ** response -- encoded form of header/index/value. 3111 ** rlen -- length of response. 3112 ** e -- current envelope. 3113 ** 3114 ** Returns: 3115 ** none 3116 */ 3117 3118 static void 3119 milter_changeheader(m, response, rlen, e) 3120 struct milter *m; 3121 char *response; 3122 ssize_t rlen; 3123 ENVELOPE *e; 3124 { 3125 mi_int32 i, index; 3126 int mh_v_len; 3127 char *field, *val, *mh_value; 3128 HDR *h, *sysheader; 3129 3130 if (tTd(64, 10)) 3131 sm_dprintf("milter_changeheader: "); 3132 3133 /* sanity checks */ 3134 if (response == NULL) 3135 { 3136 if (tTd(64, 10)) 3137 sm_dprintf("NULL response\n"); 3138 return; 3139 } 3140 3141 if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) 3142 { 3143 if (tTd(64, 10)) 3144 sm_dprintf("didn't follow protocol (total len)\n"); 3145 return; 3146 } 3147 3148 /* Find separating NUL */ 3149 (void) memcpy((char *) &i, response, MILTER_LEN_BYTES); 3150 index = ntohl(i); 3151 field = response + MILTER_LEN_BYTES; 3152 val = field + strlen(field) + 1; 3153 3154 /* another sanity check */ 3155 if (MILTER_LEN_BYTES + strlen(field) + 1 + 3156 strlen(val) + 1 != (size_t) rlen) 3157 { 3158 if (tTd(64, 10)) 3159 sm_dprintf("didn't follow protocol (part len)\n"); 3160 return; 3161 } 3162 3163 if (*field == '\0') 3164 { 3165 if (tTd(64, 10)) 3166 sm_dprintf("empty field name\n"); 3167 return; 3168 } 3169 3170 mh_v_len = 0; 3171 mh_value = quote_internal_chars(val, NULL, &mh_v_len); 3172 3173 sysheader = NULL; 3174 for (h = e->e_header; h != NULL; h = h->h_link) 3175 { 3176 if (sm_strcasecmp(h->h_field, field) == 0) 3177 { 3178 if (bitset(H_USER, h->h_flags) && --index <= 0) 3179 { 3180 sysheader = NULL; 3181 break; 3182 } 3183 else if (!bitset(H_USER, h->h_flags) && 3184 !bitset(H_TRACE, h->h_flags)) 3185 { 3186 /* 3187 ** RFC 2822: 3188 ** 27. No multiple occurrences of fields 3189 ** (except resent and received).* 3190 ** so make sure we replace any non-trace, 3191 ** non-user field. 3192 */ 3193 3194 sysheader = h; 3195 } 3196 } 3197 } 3198 3199 /* if not found as user-provided header at index, use sysheader */ 3200 if (h == NULL) 3201 h = sysheader; 3202 3203 if (h == NULL) 3204 { 3205 if (*val == '\0') 3206 { 3207 if (tTd(64, 10)) 3208 sm_dprintf("Delete (noop) %s\n", field); 3209 if (MilterLogLevel > 8) 3210 sm_syslog(LOG_INFO, e->e_id, 3211 "Milter (%s) delete (noop): header: %s" 3212 , m->mf_name, field); 3213 } 3214 else 3215 { 3216 /* treat modify value with no existing header as add */ 3217 if (tTd(64, 10)) 3218 sm_dprintf("Add %s: %s\n", field, mh_value); 3219 if (MilterLogLevel > 8) 3220 sm_syslog(LOG_INFO, e->e_id, 3221 "Milter (%s) change (add): header: %s: %s" 3222 , m->mf_name, field, mh_value); 3223 addheader(newstr(field), mh_value, H_USER, e, 3224 !bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)); 3225 } 3226 SM_FREE(mh_value); 3227 return; 3228 } 3229 3230 if (tTd(64, 10)) 3231 { 3232 if (*val == '\0') 3233 { 3234 sm_dprintf("Delete%s %s:%s\n", 3235 h == sysheader ? " (default header)" : "", 3236 field, 3237 h->h_value == NULL ? "<NULL>" : h->h_value); 3238 } 3239 else 3240 { 3241 sm_dprintf("Change%s %s: from %s to %s\n", 3242 h == sysheader ? " (default header)" : "", 3243 field, 3244 h->h_value == NULL ? "<NULL>" : h->h_value, 3245 mh_value); 3246 } 3247 } 3248 3249 if (MilterLogLevel > 8) 3250 { 3251 if (*val == '\0') 3252 { 3253 sm_syslog(LOG_INFO, e->e_id, 3254 "Milter (%s) delete: header%s %s:%s", 3255 m->mf_name, 3256 h == sysheader ? " (default header)" : "", 3257 field, 3258 h->h_value == NULL ? "<NULL>" : h->h_value); 3259 } 3260 else 3261 { 3262 sm_syslog(LOG_INFO, e->e_id, 3263 "Milter (%s) change: header%s %s: from %s to %s", 3264 m->mf_name, 3265 h == sysheader ? " (default header)" : "", 3266 field, 3267 h->h_value == NULL ? "<NULL>" : h->h_value, 3268 mh_value); 3269 } 3270 } 3271 3272 if (h != sysheader && h->h_value != NULL) 3273 { 3274 size_t l; 3275 3276 l = strlen(h->h_value); 3277 if (l > e->e_msgsize) 3278 e->e_msgsize = 0; 3279 else 3280 e->e_msgsize -= l; 3281 /* rpool, don't free: sm_free(h->h_value); XXX */ 3282 } 3283 3284 if (*val == '\0') 3285 { 3286 /* Remove "Field: " from message size */ 3287 if (h != sysheader) 3288 { 3289 size_t l; 3290 3291 l = strlen(h->h_field) + 2; 3292 if (l > e->e_msgsize) 3293 e->e_msgsize = 0; 3294 else 3295 e->e_msgsize -= l; 3296 } 3297 h->h_value = NULL; 3298 SM_FREE(mh_value); 3299 } 3300 else 3301 { 3302 if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)) 3303 h->h_value = mh_value; 3304 else 3305 { 3306 h->h_value = addleadingspace(mh_value, e->e_rpool); 3307 SM_FREE(mh_value); 3308 } 3309 h->h_flags |= H_USER; 3310 e->e_msgsize += strlen(h->h_value); 3311 } 3312 } 3313 3314 /* 3315 ** MILTER_SPLIT_RESPONSE -- Split response into fields. 3316 ** 3317 ** Parameters: 3318 ** response -- encoded repsonse. 3319 ** rlen -- length of response. 3320 ** pargc -- number of arguments (ouput) 3321 ** 3322 ** Returns: 3323 ** array of pointers to the individual strings 3324 */ 3325 3326 static char **milter_split_response __P((char *, ssize_t, int *)); 3327 3328 static char ** 3329 milter_split_response(response, rlen, pargc) 3330 char *response; 3331 ssize_t rlen; 3332 int *pargc; 3333 { 3334 char **s; 3335 size_t i; 3336 int elem, nelem; 3337 3338 SM_ASSERT(response != NULL); 3339 SM_ASSERT(pargc != NULL); 3340 *pargc = 0; 3341 if (rlen < 2 || strlen(response) >= (size_t) rlen) 3342 { 3343 if (tTd(64, 10)) 3344 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 3345 (int) strlen(response), (int) (rlen - 1)); 3346 return NULL; 3347 } 3348 3349 nelem = 0; 3350 for (i = 0; i < rlen; i++) 3351 { 3352 if (response[i] == '\0') 3353 ++nelem; 3354 } 3355 if (nelem == 0) 3356 return NULL; 3357 3358 /* last entry is only for the name */ 3359 s = (char **)malloc((nelem + 1) * (sizeof(*s))); 3360 if (s == NULL) 3361 return NULL; 3362 s[0] = response; 3363 for (i = 0, elem = 0; i < rlen && elem < nelem; i++) 3364 { 3365 if (response[i] == '\0') 3366 { 3367 ++elem; 3368 if (i + 1 >= rlen) 3369 s[elem] = NULL; 3370 else 3371 s[elem] = &(response[i + 1]); 3372 } 3373 } 3374 *pargc = nelem; 3375 3376 if (tTd(64, 10)) 3377 { 3378 for (elem = 0; elem < nelem; elem++) 3379 sm_dprintf("argv[%d]=\"%s\"\n", elem, s[elem]); 3380 } 3381 3382 /* overwrite last entry (already done above, just paranoia) */ 3383 s[elem] = NULL; 3384 return s; 3385 } 3386 3387 /* 3388 ** MILTER_CHGFROM -- Change the envelope sender address 3389 ** 3390 ** Parameters: 3391 ** response -- encoded form of recipient address. 3392 ** rlen -- length of response. 3393 ** e -- current envelope. 3394 ** mname -- name of milter. 3395 ** 3396 ** Returns: 3397 ** none 3398 */ 3399 3400 static void 3401 milter_chgfrom(response, rlen, e, mname) 3402 char *response; 3403 ssize_t rlen; 3404 ENVELOPE *e; 3405 const char *mname; 3406 { 3407 int olderrors, argc; 3408 char **argv; 3409 3410 if (tTd(64, 10)) 3411 sm_dprintf("milter_chgfrom: "); 3412 3413 /* sanity checks */ 3414 if (response == NULL) 3415 { 3416 if (tTd(64, 10)) 3417 sm_dprintf("NULL response\n"); 3418 return; 3419 } 3420 3421 if (*response == '\0' || 3422 strlen(response) + 1 > (size_t) rlen) 3423 { 3424 if (tTd(64, 10)) 3425 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 3426 (int) strlen(response), (int) (rlen - 1)); 3427 return; 3428 } 3429 3430 if (tTd(64, 10)) 3431 sm_dprintf("%s\n", response); 3432 if (MilterLogLevel > 8) 3433 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) chgfrom: %s", 3434 mname, response); 3435 argv = milter_split_response(response, rlen, &argc); 3436 if (argc < 1 || argc > 2) 3437 { 3438 if (tTd(64, 10)) 3439 sm_dprintf("didn't follow protocol argc=%d\n", argc); 3440 if (argv != NULL) 3441 free(argv); 3442 return; 3443 } 3444 3445 olderrors = Errors; 3446 setsender(argv[0], e, NULL, '\0', false); 3447 if (argc == 2) 3448 { 3449 reset_mail_esmtp_args(e); 3450 3451 /* 3452 ** need "features" here: how to get those? via e? 3453 ** "fake" it for now: allow everything. 3454 */ 3455 3456 parse_esmtp_args(e, NULL, argv[0], argv[1], "MAIL", NULL, 3457 mail_esmtp_args); 3458 } 3459 Errors = olderrors; 3460 free(argv); 3461 return; 3462 } 3463 3464 /* 3465 ** MILTER_ADDRCPT_PAR -- Add the supplied recipient to the message 3466 ** 3467 ** Parameters: 3468 ** response -- encoded form of recipient address. 3469 ** rlen -- length of response. 3470 ** e -- current envelope. 3471 ** mname -- name of milter. 3472 ** 3473 ** Returns: 3474 ** none 3475 */ 3476 3477 static void 3478 milter_addrcpt_par(response, rlen, e, mname) 3479 char *response; 3480 ssize_t rlen; 3481 ENVELOPE *e; 3482 const char *mname; 3483 { 3484 int olderrors, argc; 3485 char *delimptr; 3486 char **argv; 3487 ADDRESS *a; 3488 3489 if (tTd(64, 10)) 3490 sm_dprintf("milter_addrcpt_par: "); 3491 3492 /* sanity checks */ 3493 if (response == NULL) 3494 { 3495 if (tTd(64, 10)) 3496 sm_dprintf("NULL response\n"); 3497 return; 3498 } 3499 3500 if (tTd(64, 10)) 3501 sm_dprintf("%s\n", response); 3502 if (MilterLogLevel > 8) 3503 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) add: rcpt: %s", 3504 mname, response); 3505 3506 argv = milter_split_response(response, rlen, &argc); 3507 if (argc < 1 || argc > 2) 3508 { 3509 if (tTd(64, 10)) 3510 sm_dprintf("didn't follow protocol argc=%d\n", argc); 3511 if (argv != NULL) 3512 free(argv); 3513 return; 3514 } 3515 olderrors = Errors; 3516 3517 /* how to set ESMTP arguments? */ 3518 a = parseaddr(argv[0], NULLADDR, RF_COPYALL, ' ', &delimptr, e, true); 3519 3520 if (a != NULL && olderrors == Errors) 3521 { 3522 parse_esmtp_args(e, a, argv[0], argv[1], "RCPT", NULL, 3523 rcpt_esmtp_args); 3524 if (olderrors == Errors) 3525 a = recipient(a, &e->e_sendqueue, 0, e); 3526 else 3527 sm_dprintf("olderrors=%d, Errors=%d\n", 3528 olderrors, Errors); 3529 } 3530 else 3531 { 3532 sm_dprintf("a=%p, olderrors=%d, Errors=%d\n", 3533 (void *)a, olderrors, Errors); 3534 } 3535 3536 Errors = olderrors; 3537 free(argv); 3538 return; 3539 } 3540 3541 /* 3542 ** MILTER_ADDRCPT -- Add the supplied recipient to the message 3543 ** 3544 ** Parameters: 3545 ** response -- encoded form of recipient address. 3546 ** rlen -- length of response. 3547 ** e -- current envelope. 3548 ** mname -- name of milter. 3549 ** 3550 ** Returns: 3551 ** none 3552 */ 3553 3554 static void 3555 milter_addrcpt(response, rlen, e, mname) 3556 char *response; 3557 ssize_t rlen; 3558 ENVELOPE *e; 3559 const char *mname; 3560 { 3561 int olderrors; 3562 3563 if (tTd(64, 10)) 3564 sm_dprintf("milter_addrcpt: "); 3565 3566 /* sanity checks */ 3567 if (response == NULL) 3568 { 3569 if (tTd(64, 10)) 3570 sm_dprintf("NULL response\n"); 3571 return; 3572 } 3573 3574 if (*response == '\0' || 3575 strlen(response) + 1 != (size_t) rlen) 3576 { 3577 if (tTd(64, 10)) 3578 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 3579 (int) strlen(response), (int) (rlen - 1)); 3580 return; 3581 } 3582 3583 if (tTd(64, 10)) 3584 sm_dprintf("%s\n", response); 3585 if (MilterLogLevel > 8) 3586 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) add: rcpt: %s", 3587 mname, response); 3588 olderrors = Errors; 3589 (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e); 3590 Errors = olderrors; 3591 return; 3592 } 3593 3594 /* 3595 ** MILTER_DELRCPT -- Delete the supplied recipient from the message 3596 ** 3597 ** Parameters: 3598 ** response -- encoded form of recipient address. 3599 ** rlen -- length of response. 3600 ** e -- current envelope. 3601 ** mname -- name of milter. 3602 ** 3603 ** Returns: 3604 ** none 3605 */ 3606 3607 static void 3608 milter_delrcpt(response, rlen, e, mname) 3609 char *response; 3610 ssize_t rlen; 3611 ENVELOPE *e; 3612 const char *mname; 3613 { 3614 int r; 3615 3616 if (tTd(64, 10)) 3617 sm_dprintf("milter_delrcpt: "); 3618 3619 /* sanity checks */ 3620 if (response == NULL) 3621 { 3622 if (tTd(64, 10)) 3623 sm_dprintf("NULL response\n"); 3624 return; 3625 } 3626 3627 if (*response == '\0' || 3628 strlen(response) + 1 != (size_t) rlen) 3629 { 3630 if (tTd(64, 10)) 3631 sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n", 3632 (int) strlen(response), (int) (rlen - 1)); 3633 return; 3634 } 3635 3636 if (tTd(64, 10)) 3637 sm_dprintf("%s\n", response); 3638 r = removefromlist(response, &e->e_sendqueue, e); 3639 if (MilterLogLevel > 8) 3640 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) delete: rcpt %s, naddrs=%d", 3641 mname, response, r); 3642 return; 3643 } 3644 3645 /* 3646 ** MILTER_REPLBODY -- Replace the current data file with new body 3647 ** 3648 ** Parameters: 3649 ** response -- encoded form of new body. 3650 ** rlen -- length of response. 3651 ** newfilter -- if first time called by a new filter 3652 ** e -- current envelope. 3653 ** mname -- name of milter. 3654 ** 3655 ** Returns: 3656 ** 0 upon success, -1 upon failure 3657 */ 3658 3659 static int 3660 milter_replbody(response, rlen, newfilter, e, mname) 3661 char *response; 3662 ssize_t rlen; 3663 bool newfilter; 3664 ENVELOPE *e; 3665 const char *mname; 3666 { 3667 static char prevchar; 3668 int i; 3669 3670 if (tTd(64, 10)) 3671 sm_dprintf("milter_replbody\n"); 3672 3673 /* If a new filter, reset previous character and truncate data file */ 3674 if (newfilter) 3675 { 3676 off_t prevsize; 3677 char dfname[MAXPATHLEN]; 3678 3679 (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), 3680 sizeof(dfname)); 3681 3682 /* Reset prevchar */ 3683 prevchar = '\0'; 3684 3685 /* Get the current data file information */ 3686 prevsize = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_SIZE, NULL); 3687 if (prevsize < 0) 3688 prevsize = 0; 3689 3690 /* truncate current data file */ 3691 if (sm_io_getinfo(e->e_dfp, SM_IO_WHAT_ISTYPE, BF_FILE_TYPE)) 3692 { 3693 if (sm_io_setinfo(e->e_dfp, SM_BF_TRUNCATE, NULL) < 0) 3694 { 3695 MILTER_DF_ERROR("milter_replbody: sm_io truncate %s: %s"); 3696 return -1; 3697 } 3698 } 3699 else 3700 { 3701 int err; 3702 3703 err = sm_io_error(e->e_dfp); 3704 (void) sm_io_flush(e->e_dfp, SM_TIME_DEFAULT); 3705 3706 /* 3707 ** Clear error if tried to fflush() 3708 ** a read-only file pointer and 3709 ** there wasn't a previous error. 3710 */ 3711 3712 if (err == 0) 3713 sm_io_clearerr(e->e_dfp); 3714 3715 /* errno is set implicitly by fseek() before return */ 3716 err = sm_io_seek(e->e_dfp, SM_TIME_DEFAULT, 3717 0, SEEK_SET); 3718 if (err < 0) 3719 { 3720 MILTER_DF_ERROR("milter_replbody: sm_io_seek %s: %s"); 3721 return -1; 3722 } 3723 # if NOFTRUNCATE 3724 /* XXX: Not much we can do except rewind it */ 3725 errno = EINVAL; 3726 MILTER_DF_ERROR("milter_replbody: ftruncate not available on this platform (%s:%s)"); 3727 return -1; 3728 # else /* NOFTRUNCATE */ 3729 err = ftruncate(sm_io_getinfo(e->e_dfp, 3730 SM_IO_WHAT_FD, NULL), 3731 0); 3732 if (err < 0) 3733 { 3734 MILTER_DF_ERROR("milter_replbody: sm_io ftruncate %s: %s"); 3735 return -1; 3736 } 3737 # endif /* NOFTRUNCATE */ 3738 } 3739 3740 if (prevsize > e->e_msgsize) 3741 e->e_msgsize = 0; 3742 else 3743 e->e_msgsize -= prevsize; 3744 } 3745 3746 if (newfilter && MilterLogLevel > 8) 3747 sm_syslog(LOG_INFO, e->e_id, "Milter (%s) message: body replaced", 3748 mname); 3749 3750 if (response == NULL) 3751 { 3752 /* Flush the buffered '\r' */ 3753 if (prevchar == '\r') 3754 { 3755 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, prevchar); 3756 e->e_msgsize++; 3757 } 3758 return 0; 3759 } 3760 3761 for (i = 0; i < rlen; i++) 3762 { 3763 /* Buffered char from last chunk */ 3764 if (i == 0 && prevchar == '\r') 3765 { 3766 /* Not CRLF, output prevchar */ 3767 if (response[i] != '\n') 3768 { 3769 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, 3770 prevchar); 3771 e->e_msgsize++; 3772 } 3773 prevchar = '\0'; 3774 } 3775 3776 /* Turn CRLF into LF */ 3777 if (response[i] == '\r') 3778 { 3779 /* check if at end of chunk */ 3780 if (i + 1 < rlen) 3781 { 3782 /* If LF, strip CR */ 3783 if (response[i + 1] == '\n') 3784 i++; 3785 } 3786 else 3787 { 3788 /* check next chunk */ 3789 prevchar = '\r'; 3790 continue; 3791 } 3792 } 3793 (void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, response[i]); 3794 e->e_msgsize++; 3795 } 3796 return 0; 3797 } 3798 3799 /* 3800 ** MTA callouts 3801 */ 3802 3803 /* 3804 ** MILTER_INIT -- open and negotiate with all of the filters 3805 ** 3806 ** Parameters: 3807 ** e -- current envelope. 3808 ** state -- return state from response. 3809 ** milters -- milters structure. 3810 ** 3811 ** Returns: 3812 ** true iff at least one filter is active 3813 */ 3814 3815 /* ARGSUSED */ 3816 bool 3817 milter_init(e, state, milters) 3818 ENVELOPE *e; 3819 char *state; 3820 milters_T *milters; 3821 { 3822 int i; 3823 3824 if (tTd(64, 10)) 3825 sm_dprintf("milter_init\n"); 3826 3827 memset(milters, '\0', sizeof(*milters)); 3828 *state = SMFIR_CONTINUE; 3829 if (InputFilters[0] == NULL) 3830 { 3831 if (MilterLogLevel > 10) 3832 sm_syslog(LOG_INFO, e->e_id, 3833 "Milter: no active filter"); 3834 return false; 3835 } 3836 3837 for (i = 0; InputFilters[i] != NULL; i++) 3838 { 3839 struct milter *m = InputFilters[i]; 3840 3841 m->mf_sock = milter_open(m, false, e); 3842 if (m->mf_state == SMFS_ERROR) 3843 { 3844 MILTER_CHECK_ERROR(true, continue); 3845 break; 3846 } 3847 3848 if (m->mf_sock < 0 || 3849 milter_negotiate(m, e, milters) < 0 || 3850 m->mf_state == SMFS_ERROR) 3851 { 3852 if (tTd(64, 5)) 3853 sm_dprintf("milter_init(%s): failed to %s\n", 3854 m->mf_name, 3855 m->mf_sock < 0 ? "open" : 3856 "negotiate"); 3857 if (MilterLogLevel > 0) 3858 sm_syslog(LOG_ERR, e->e_id, 3859 "Milter (%s): init failed to %s", 3860 m->mf_name, 3861 m->mf_sock < 0 ? "open" : 3862 "negotiate"); 3863 3864 /* if negotiation failure, close socket */ 3865 milter_error(m, e); 3866 MILTER_CHECK_ERROR(true, continue); 3867 continue; 3868 } 3869 if (MilterLogLevel > 9) 3870 sm_syslog(LOG_INFO, e->e_id, 3871 "Milter (%s): init success to %s", 3872 m->mf_name, 3873 m->mf_sock < 0 ? "open" : "negotiate"); 3874 } 3875 3876 /* 3877 ** If something temp/perm failed with one of the filters, 3878 ** we won't be using any of them, so clear any existing 3879 ** connections. 3880 */ 3881 3882 if (*state != SMFIR_CONTINUE) 3883 milter_quit(e); 3884 3885 return true; 3886 } 3887 3888 /* 3889 ** MILTER_CONNECT -- send connection info to milter filters 3890 ** 3891 ** Parameters: 3892 ** hostname -- hostname of remote machine. 3893 ** addr -- address of remote machine. 3894 ** e -- current envelope. 3895 ** state -- return state from response. 3896 ** 3897 ** Returns: 3898 ** response string (may be NULL) 3899 */ 3900 3901 char * 3902 milter_connect(hostname, addr, e, state) 3903 char *hostname; 3904 SOCKADDR addr; 3905 ENVELOPE *e; 3906 char *state; 3907 { 3908 char family; 3909 unsigned short port; 3910 char *buf, *bp; 3911 char *response; 3912 char *sockinfo = NULL; 3913 ssize_t s; 3914 # if NETINET6 3915 char buf6[INET6_ADDRSTRLEN]; 3916 # endif 3917 3918 if (tTd(64, 10)) 3919 sm_dprintf("milter_connect(%s)\n", hostname); 3920 if (MilterLogLevel > 9) 3921 sm_syslog(LOG_INFO, e->e_id, "Milter: connect to filters"); 3922 3923 /* gather data */ 3924 switch (addr.sa.sa_family) 3925 { 3926 # if NETUNIX 3927 case AF_UNIX: 3928 family = SMFIA_UNIX; 3929 port = htons(0); 3930 sockinfo = addr.sunix.sun_path; 3931 break; 3932 # endif /* NETUNIX */ 3933 3934 # if NETINET 3935 case AF_INET: 3936 family = SMFIA_INET; 3937 port = addr.sin.sin_port; 3938 sockinfo = (char *) inet_ntoa(addr.sin.sin_addr); 3939 break; 3940 # endif /* NETINET */ 3941 3942 # if NETINET6 3943 case AF_INET6: 3944 if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr)) 3945 family = SMFIA_INET; 3946 else 3947 family = SMFIA_INET6; 3948 port = addr.sin6.sin6_port; 3949 sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6, 3950 sizeof(buf6)); 3951 if (sockinfo == NULL) 3952 sockinfo = ""; 3953 break; 3954 # endif /* NETINET6 */ 3955 3956 default: 3957 family = SMFIA_UNKNOWN; 3958 break; 3959 } 3960 3961 s = strlen(hostname) + 1 + sizeof(family); 3962 if (family != SMFIA_UNKNOWN) 3963 s += sizeof(port) + strlen(sockinfo) + 1; 3964 3965 buf = (char *) xalloc(s); 3966 bp = buf; 3967 3968 /* put together data */ 3969 (void) memcpy(bp, hostname, strlen(hostname)); 3970 bp += strlen(hostname); 3971 *bp++ = '\0'; 3972 (void) memcpy(bp, &family, sizeof(family)); 3973 bp += sizeof(family); 3974 if (family != SMFIA_UNKNOWN) 3975 { 3976 (void) memcpy(bp, &port, sizeof(port)); 3977 bp += sizeof(port); 3978 3979 /* include trailing '\0' */ 3980 (void) memcpy(bp, sockinfo, strlen(sockinfo) + 1); 3981 } 3982 3983 response = milter_command(SMFIC_CONNECT, buf, s, SMFIM_CONNECT, 3984 e, state, "connect", false); 3985 sm_free(buf); /* XXX */ 3986 3987 /* 3988 ** If this message connection is done for, 3989 ** close the filters. 3990 */ 3991 3992 if (*state != SMFIR_CONTINUE) 3993 { 3994 if (MilterLogLevel > 9) 3995 sm_syslog(LOG_INFO, e->e_id, "Milter: connect, ending"); 3996 milter_quit(e); 3997 } 3998 else 3999 milter_per_connection_check(e); 4000 4001 #if !_FFR_MILTER_CONNECT_REPLYCODE 4002 /* 4003 ** SMFIR_REPLYCODE can't work with connect due to 4004 ** the requirements of SMTP. Therefore, ignore the 4005 ** reply code text but keep the state it would reflect. 4006 */ 4007 4008 if (*state == SMFIR_REPLYCODE) 4009 { 4010 if (response != NULL && 4011 *response == '4') 4012 { 4013 if (strncmp(response, "421 ", 4) == 0) 4014 *state = SMFIR_SHUTDOWN; 4015 else 4016 *state = SMFIR_TEMPFAIL; 4017 } 4018 else 4019 *state = SMFIR_REJECT; 4020 if (response != NULL) 4021 { 4022 sm_free(response); /* XXX */ 4023 response = NULL; 4024 } 4025 } 4026 #endif /* !_FFR_MILTER_CONNECT_REPLYCODE */ 4027 return response; 4028 } 4029 4030 /* 4031 ** MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters 4032 ** 4033 ** Parameters: 4034 ** helo -- argument to SMTP HELO/EHLO command. 4035 ** e -- current envelope. 4036 ** state -- return state from response. 4037 ** 4038 ** Returns: 4039 ** response string (may be NULL) 4040 */ 4041 4042 char * 4043 milter_helo(helo, e, state) 4044 char *helo; 4045 ENVELOPE *e; 4046 char *state; 4047 { 4048 int i; 4049 char *response; 4050 4051 if (tTd(64, 10)) 4052 sm_dprintf("milter_helo(%s)\n", helo); 4053 4054 /* HELO/EHLO can come at any point */ 4055 for (i = 0; InputFilters[i] != NULL; i++) 4056 { 4057 struct milter *m = InputFilters[i]; 4058 4059 switch (m->mf_state) 4060 { 4061 case SMFS_INMSG: 4062 /* abort in message filters */ 4063 milter_abort_filter(m, e); 4064 /* FALLTHROUGH */ 4065 4066 case SMFS_DONE: 4067 /* reset done filters */ 4068 m->mf_state = SMFS_OPEN; 4069 break; 4070 } 4071 } 4072 4073 response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1, 4074 SMFIM_HELO, e, state, "helo", false); 4075 milter_per_connection_check(e); 4076 return response; 4077 } 4078 4079 /* 4080 ** MILTER_ENVFROM -- send SMTP MAIL command info to milter filters 4081 ** 4082 ** Parameters: 4083 ** args -- SMTP MAIL command args (args[0] == sender). 4084 ** e -- current envelope. 4085 ** state -- return state from response. 4086 ** 4087 ** Returns: 4088 ** response string (may be NULL) 4089 */ 4090 4091 char * 4092 milter_envfrom(args, e, state) 4093 char **args; 4094 ENVELOPE *e; 4095 char *state; 4096 { 4097 int i; 4098 char *buf, *bp; 4099 char *response; 4100 ssize_t s; 4101 4102 if (tTd(64, 10)) 4103 { 4104 sm_dprintf("milter_envfrom:"); 4105 for (i = 0; args[i] != NULL; i++) 4106 sm_dprintf(" %s", args[i]); 4107 sm_dprintf("\n"); 4108 } 4109 4110 /* sanity check */ 4111 if (args[0] == NULL) 4112 { 4113 *state = SMFIR_REJECT; 4114 if (MilterLogLevel > 10) 4115 sm_syslog(LOG_INFO, e->e_id, 4116 "Milter: reject, no sender"); 4117 return NULL; 4118 } 4119 4120 /* new message, so ... */ 4121 for (i = 0; InputFilters[i] != NULL; i++) 4122 { 4123 struct milter *m = InputFilters[i]; 4124 4125 switch (m->mf_state) 4126 { 4127 case SMFS_INMSG: 4128 /* abort in message filters */ 4129 milter_abort_filter(m, e); 4130 /* FALLTHROUGH */ 4131 4132 case SMFS_DONE: 4133 /* reset done filters */ 4134 m->mf_state = SMFS_OPEN; 4135 break; 4136 } 4137 } 4138 4139 /* put together data */ 4140 s = 0; 4141 for (i = 0; args[i] != NULL; i++) 4142 s += strlen(args[i]) + 1; 4143 4144 if (s < 0) 4145 { 4146 *state = SMFIR_TEMPFAIL; 4147 return NULL; 4148 } 4149 4150 buf = (char *) xalloc(s); 4151 bp = buf; 4152 for (i = 0; args[i] != NULL; i++) 4153 { 4154 (void) sm_strlcpy(bp, args[i], s - (bp - buf)); 4155 bp += strlen(bp) + 1; 4156 } 4157 4158 if (MilterLogLevel > 14) 4159 sm_syslog(LOG_INFO, e->e_id, "Milter: sender: %s", buf); 4160 4161 /* send it over */ 4162 response = milter_command(SMFIC_MAIL, buf, s, SMFIM_ENVFROM, 4163 e, state, "mail", false); 4164 sm_free(buf); /* XXX */ 4165 4166 /* 4167 ** If filter rejects/discards a per message command, 4168 ** abort the other filters since we are done with the 4169 ** current message. 4170 */ 4171 4172 MILTER_CHECK_DONE_MSG(); 4173 if (MilterLogLevel > 10 && *state == SMFIR_REJECT) 4174 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, sender"); 4175 return response; 4176 } 4177 4178 /* 4179 ** MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters 4180 ** 4181 ** Parameters: 4182 ** args -- SMTP RCPT command args (args[0] == recipient). 4183 ** e -- current envelope. 4184 ** state -- return state from response. 4185 ** rcpt_error -- does RCPT have an error? 4186 ** 4187 ** Returns: 4188 ** response string (may be NULL) 4189 */ 4190 4191 char * 4192 milter_envrcpt(args, e, state, rcpt_error) 4193 char **args; 4194 ENVELOPE *e; 4195 char *state; 4196 bool rcpt_error; 4197 { 4198 int i; 4199 char *buf, *bp; 4200 char *response; 4201 ssize_t s; 4202 4203 if (tTd(64, 10)) 4204 { 4205 sm_dprintf("milter_envrcpt:"); 4206 for (i = 0; args[i] != NULL; i++) 4207 sm_dprintf(" %s", args[i]); 4208 sm_dprintf("\n"); 4209 } 4210 4211 /* sanity check */ 4212 if (args[0] == NULL) 4213 { 4214 *state = SMFIR_REJECT; 4215 if (MilterLogLevel > 10) 4216 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, no rcpt"); 4217 return NULL; 4218 } 4219 4220 /* put together data */ 4221 s = 0; 4222 for (i = 0; args[i] != NULL; i++) 4223 s += strlen(args[i]) + 1; 4224 4225 if (s < 0) 4226 { 4227 *state = SMFIR_TEMPFAIL; 4228 return NULL; 4229 } 4230 4231 buf = (char *) xalloc(s); 4232 bp = buf; 4233 for (i = 0; args[i] != NULL; i++) 4234 { 4235 (void) sm_strlcpy(bp, args[i], s - (bp - buf)); 4236 bp += strlen(bp) + 1; 4237 } 4238 4239 if (MilterLogLevel > 14) 4240 sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf); 4241 4242 /* send it over */ 4243 response = milter_command(SMFIC_RCPT, buf, s, SMFIM_ENVRCPT, 4244 e, state, "rcpt", rcpt_error); 4245 sm_free(buf); /* XXX */ 4246 return response; 4247 } 4248 4249 /* 4250 ** MILTER_DATA_CMD -- send SMTP DATA command info to milter filters 4251 ** 4252 ** Parameters: 4253 ** e -- current envelope. 4254 ** state -- return state from response. 4255 ** 4256 ** Returns: 4257 ** response string (may be NULL) 4258 */ 4259 4260 char * 4261 milter_data_cmd(e, state) 4262 ENVELOPE *e; 4263 char *state; 4264 { 4265 if (tTd(64, 10)) 4266 sm_dprintf("milter_data_cmd\n"); 4267 4268 /* send it over */ 4269 return milter_command(SMFIC_DATA, NULL, 0, SMFIM_DATA, 4270 e, state, "data", false); 4271 } 4272 4273 /* 4274 ** MILTER_DATA -- send message headers/body and gather final message results 4275 ** 4276 ** Parameters: 4277 ** e -- current envelope. 4278 ** state -- return state from response. 4279 ** 4280 ** Returns: 4281 ** response string (may be NULL) 4282 ** 4283 ** Side effects: 4284 ** - Uses e->e_dfp for access to the body 4285 ** - Can call the various milter action routines to 4286 ** modify the envelope or message. 4287 */ 4288 4289 /* flow through code using continue; don't wrap in do {} while */ 4290 # define MILTER_CHECK_RESULTS() \ 4291 if (m->mf_state == SMFS_ERROR && *state == SMFIR_CONTINUE) \ 4292 { \ 4293 MILTER_SET_STATE; \ 4294 } \ 4295 if (*state == SMFIR_ACCEPT || \ 4296 m->mf_state == SMFS_DONE || \ 4297 m->mf_state == SMFS_ERROR) \ 4298 { \ 4299 if (m->mf_state != SMFS_ERROR) \ 4300 m->mf_state = SMFS_DONE; \ 4301 continue; /* to next filter */ \ 4302 } \ 4303 if (*state != SMFIR_CONTINUE) \ 4304 { \ 4305 m->mf_state = SMFS_DONE; \ 4306 goto finishup; \ 4307 } 4308 4309 char * 4310 milter_data(e, state) 4311 ENVELOPE *e; 4312 char *state; 4313 { 4314 bool replbody = false; /* milter_replbody() called? */ 4315 bool replfailed = false; /* milter_replbody() failed? */ 4316 bool rewind = false; /* rewind data file? */ 4317 bool dfopen = false; /* data file open for writing? */ 4318 bool newfilter; /* reset on each new filter */ 4319 char rcmd; 4320 int i; 4321 int save_errno; 4322 char *response = NULL; 4323 time_t eomsent; 4324 ssize_t rlen; 4325 4326 if (tTd(64, 10)) 4327 sm_dprintf("milter_data\n"); 4328 4329 *state = SMFIR_CONTINUE; 4330 4331 /* 4332 ** XXX: Should actually send body chunks to each filter 4333 ** a chunk at a time instead of sending the whole body to 4334 ** each filter in turn. However, only if the filters don't 4335 ** change the body. 4336 */ 4337 4338 for (i = 0; InputFilters[i] != NULL; i++) 4339 { 4340 int idx; 4341 char **macros; 4342 struct milter *m = InputFilters[i]; 4343 4344 if (*state != SMFIR_CONTINUE && 4345 *state != SMFIR_ACCEPT) 4346 { 4347 /* 4348 ** A previous filter has dealt with the message, 4349 ** safe to stop processing the filters. 4350 */ 4351 4352 break; 4353 } 4354 4355 /* Now reset state for later evaluation */ 4356 *state = SMFIR_CONTINUE; 4357 newfilter = true; 4358 4359 /* previous problem? */ 4360 if (m->mf_state == SMFS_ERROR) 4361 { 4362 MILTER_CHECK_ERROR(false, continue); 4363 break; 4364 } 4365 4366 /* sanity checks */ 4367 if (m->mf_sock < 0 || 4368 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) 4369 continue; 4370 4371 m->mf_state = SMFS_INMSG; 4372 4373 /* check if filter wants the headers */ 4374 if (!bitset(SMFIP_NOHDRS, m->mf_pflags)) 4375 { 4376 response = milter_headers(m, e, state); 4377 MILTER_CHECK_RESULTS(); 4378 } 4379 4380 /* check if filter wants EOH */ 4381 if (!bitset(SMFIP_NOEOH, m->mf_pflags)) 4382 { 4383 if (tTd(64, 10)) 4384 sm_dprintf("milter_data: eoh\n"); 4385 4386 if ((m->mf_lflags & MI_LFLAGS_SYM(SMFIM_EOH)) != 0) 4387 idx = m->mf_idx; 4388 else 4389 idx = 0; 4390 SM_ASSERT(idx >= 0 && idx <= MAXFILTERS); 4391 macros = MilterMacros[SMFIM_EOH][idx]; 4392 4393 if (macros != NULL) 4394 { 4395 milter_send_macros(m, macros, SMFIC_EOH, e); 4396 MILTER_CHECK_RESULTS(); 4397 } 4398 4399 /* send it over */ 4400 response = milter_send_command(m, SMFIC_EOH, NULL, 0, 4401 e, state, "eoh"); 4402 MILTER_CHECK_RESULTS(); 4403 } 4404 4405 /* check if filter wants the body */ 4406 if (!bitset(SMFIP_NOBODY, m->mf_pflags) && 4407 e->e_dfp != NULL) 4408 { 4409 rewind = true; 4410 response = milter_body(m, e, state); 4411 MILTER_CHECK_RESULTS(); 4412 } 4413 4414 if ((m->mf_lflags & MI_LFLAGS_SYM(SMFIM_EOH)) != 0) 4415 idx = m->mf_idx; 4416 else 4417 idx = 0; 4418 SM_ASSERT(idx >= 0 && idx <= MAXFILTERS); 4419 macros = MilterMacros[SMFIM_EOM][idx]; 4420 if (macros != NULL) 4421 { 4422 milter_send_macros(m, macros, SMFIC_BODYEOB, e); 4423 MILTER_CHECK_RESULTS(); 4424 } 4425 4426 /* send the final body chunk */ 4427 (void) milter_write(m, SMFIC_BODYEOB, NULL, 0, 4428 m->mf_timeout[SMFTO_WRITE], e, "eom"); 4429 4430 /* Get time EOM sent for timeout */ 4431 eomsent = curtime(); 4432 4433 /* deal with the possibility of multiple responses */ 4434 while (*state == SMFIR_CONTINUE) 4435 { 4436 /* Check total timeout from EOM to final ACK/NAK */ 4437 if (m->mf_timeout[SMFTO_EOM] > 0 && 4438 curtime() - eomsent >= m->mf_timeout[SMFTO_EOM]) 4439 { 4440 if (tTd(64, 5)) 4441 sm_dprintf("milter_data(%s): EOM ACK/NAK timeout\n", 4442 m->mf_name); 4443 if (MilterLogLevel > 0) 4444 sm_syslog(LOG_ERR, e->e_id, 4445 "milter_data(%s): EOM ACK/NAK timeout", 4446 m->mf_name); 4447 milter_error(m, e); 4448 MILTER_CHECK_ERROR(false, break); 4449 break; 4450 } 4451 4452 response = milter_read(m, &rcmd, &rlen, 4453 m->mf_timeout[SMFTO_READ], e, 4454 "eom"); 4455 if (m->mf_state == SMFS_ERROR) 4456 break; 4457 4458 if (tTd(64, 10)) 4459 sm_dprintf("milter_data(%s): state %c\n", 4460 m->mf_name, (char) rcmd); 4461 4462 switch (rcmd) 4463 { 4464 case SMFIR_REPLYCODE: 4465 MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected"); 4466 if (MilterLogLevel > 12) 4467 sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject=%s", 4468 m->mf_name, response); 4469 *state = rcmd; 4470 m->mf_state = SMFS_DONE; 4471 break; 4472 4473 case SMFIR_REJECT: /* log msg at end of function */ 4474 if (MilterLogLevel > 12) 4475 sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject", 4476 m->mf_name); 4477 *state = rcmd; 4478 m->mf_state = SMFS_DONE; 4479 break; 4480 4481 case SMFIR_DISCARD: 4482 if (MilterLogLevel > 12) 4483 sm_syslog(LOG_INFO, e->e_id, "milter=%s, discard", 4484 m->mf_name); 4485 *state = rcmd; 4486 m->mf_state = SMFS_DONE; 4487 break; 4488 4489 case SMFIR_TEMPFAIL: 4490 if (MilterLogLevel > 12) 4491 sm_syslog(LOG_INFO, e->e_id, "milter=%s, tempfail", 4492 m->mf_name); 4493 *state = rcmd; 4494 m->mf_state = SMFS_DONE; 4495 break; 4496 4497 case SMFIR_CONTINUE: 4498 case SMFIR_ACCEPT: 4499 /* this filter is done with message */ 4500 if (replfailed) 4501 *state = SMFIR_TEMPFAIL; 4502 else 4503 *state = SMFIR_ACCEPT; 4504 m->mf_state = SMFS_DONE; 4505 break; 4506 4507 case SMFIR_PROGRESS: 4508 break; 4509 4510 case SMFIR_QUARANTINE: 4511 if (!bitset(SMFIF_QUARANTINE, m->mf_fflags)) 4512 { 4513 if (MilterLogLevel > 9) 4514 sm_syslog(LOG_WARNING, e->e_id, 4515 "milter_data(%s): lied about quarantining, honoring request anyway", 4516 m->mf_name); 4517 } 4518 if (response == NULL) 4519 response = newstr(""); 4520 if (MilterLogLevel > 3) 4521 sm_syslog(LOG_INFO, e->e_id, 4522 "milter=%s, quarantine=%s", 4523 m->mf_name, response); 4524 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, 4525 response); 4526 macdefine(&e->e_macro, A_PERM, 4527 macid("{quarantine}"), e->e_quarmsg); 4528 break; 4529 4530 case SMFIR_ADDHEADER: 4531 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags)) 4532 { 4533 if (MilterLogLevel > 9) 4534 sm_syslog(LOG_WARNING, e->e_id, 4535 "milter_data(%s): lied about adding headers, honoring request anyway", 4536 m->mf_name); 4537 } 4538 milter_addheader(m, response, rlen, e); 4539 break; 4540 4541 case SMFIR_INSHEADER: 4542 if (!bitset(SMFIF_ADDHDRS, m->mf_fflags)) 4543 { 4544 if (MilterLogLevel > 9) 4545 sm_syslog(LOG_WARNING, e->e_id, 4546 "milter_data(%s): lied about adding headers, honoring request anyway", 4547 m->mf_name); 4548 } 4549 milter_insheader(m, response, rlen, e); 4550 break; 4551 4552 case SMFIR_CHGHEADER: 4553 if (!bitset(SMFIF_CHGHDRS, m->mf_fflags)) 4554 { 4555 if (MilterLogLevel > 9) 4556 sm_syslog(LOG_WARNING, e->e_id, 4557 "milter_data(%s): lied about changing headers, honoring request anyway", 4558 m->mf_name); 4559 } 4560 milter_changeheader(m, response, rlen, e); 4561 break; 4562 4563 case SMFIR_CHGFROM: 4564 if (!bitset(SMFIF_CHGFROM, m->mf_fflags)) 4565 { 4566 if (MilterLogLevel > 9) 4567 sm_syslog(LOG_WARNING, e->e_id, 4568 "milter_data(%s) lied about changing sender, honoring request anyway", 4569 m->mf_name); 4570 } 4571 milter_chgfrom(response, rlen, e, m->mf_name); 4572 break; 4573 4574 case SMFIR_ADDRCPT: 4575 if (!bitset(SMFIF_ADDRCPT, m->mf_fflags)) 4576 { 4577 if (MilterLogLevel > 9) 4578 sm_syslog(LOG_WARNING, e->e_id, 4579 "milter_data(%s) lied about adding recipients, honoring request anyway", 4580 m->mf_name); 4581 } 4582 milter_addrcpt(response, rlen, e, m->mf_name); 4583 break; 4584 4585 case SMFIR_ADDRCPT_PAR: 4586 if (!bitset(SMFIF_ADDRCPT_PAR, m->mf_fflags)) 4587 { 4588 if (MilterLogLevel > 9) 4589 sm_syslog(LOG_WARNING, e->e_id, 4590 "milter_data(%s) lied about adding recipients with parameters, honoring request anyway", 4591 m->mf_name); 4592 } 4593 milter_addrcpt_par(response, rlen, e, m->mf_name); 4594 break; 4595 4596 case SMFIR_DELRCPT: 4597 if (!bitset(SMFIF_DELRCPT, m->mf_fflags)) 4598 { 4599 if (MilterLogLevel > 9) 4600 sm_syslog(LOG_WARNING, e->e_id, 4601 "milter_data(%s): lied about removing recipients, honoring request anyway", 4602 m->mf_name); 4603 } 4604 milter_delrcpt(response, rlen, e, m->mf_name); 4605 break; 4606 4607 case SMFIR_REPLBODY: 4608 if (!bitset(SMFIF_MODBODY, m->mf_fflags)) 4609 { 4610 if (MilterLogLevel > 0) 4611 sm_syslog(LOG_ERR, e->e_id, 4612 "milter_data(%s): lied about replacing body, rejecting request and tempfailing message", 4613 m->mf_name); 4614 replfailed = true; 4615 break; 4616 } 4617 4618 /* already failed in attempt */ 4619 if (replfailed) 4620 break; 4621 4622 if (!dfopen) 4623 { 4624 if (milter_reopen_df(e) < 0) 4625 { 4626 replfailed = true; 4627 break; 4628 } 4629 dfopen = true; 4630 rewind = true; 4631 } 4632 4633 if (milter_replbody(response, rlen, newfilter, 4634 e, m->mf_name) < 0) 4635 replfailed = true; 4636 newfilter = false; 4637 replbody = true; 4638 break; 4639 4640 default: 4641 /* Invalid response to command */ 4642 if (MilterLogLevel > 0) 4643 sm_syslog(LOG_ERR, e->e_id, 4644 "milter_data(%s): returned bogus response %c", 4645 m->mf_name, rcmd); 4646 milter_error(m, e); 4647 break; 4648 } 4649 if (rcmd != SMFIR_REPLYCODE && response != NULL) 4650 { 4651 sm_free(response); /* XXX */ 4652 response = NULL; 4653 } 4654 4655 if (m->mf_state == SMFS_ERROR) 4656 break; 4657 } 4658 4659 if (replbody && !replfailed) 4660 { 4661 /* flush possible buffered character */ 4662 milter_replbody(NULL, 0, !replbody, e, m->mf_name); 4663 replbody = false; 4664 } 4665 4666 if (m->mf_state == SMFS_ERROR) 4667 { 4668 MILTER_CHECK_ERROR(false, continue); 4669 goto finishup; 4670 } 4671 } 4672 4673 finishup: 4674 /* leave things in the expected state if we touched it */ 4675 if (replfailed) 4676 { 4677 if (*state == SMFIR_CONTINUE || 4678 *state == SMFIR_ACCEPT) 4679 { 4680 *state = SMFIR_TEMPFAIL; 4681 SM_FREE(response); 4682 } 4683 4684 if (dfopen) 4685 { 4686 (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); 4687 e->e_dfp = NULL; 4688 e->e_flags &= ~EF_HAS_DF; 4689 dfopen = false; 4690 } 4691 rewind = false; 4692 } 4693 4694 if ((dfopen && milter_reset_df(e) < 0) || 4695 (rewind && bfrewind(e->e_dfp) < 0)) 4696 { 4697 save_errno = errno; 4698 ExitStat = EX_IOERR; 4699 4700 /* 4701 ** If filter told us to keep message but we had 4702 ** an error, we can't really keep it, tempfail it. 4703 */ 4704 4705 if (*state == SMFIR_CONTINUE || *state == SMFIR_ACCEPT) 4706 { 4707 *state = SMFIR_TEMPFAIL; 4708 SM_FREE(response); 4709 } 4710 4711 errno = save_errno; 4712 syserr("milter_data: %s/%cf%s: read error", 4713 qid_printqueue(e->e_qgrp, e->e_qdir), 4714 DATAFL_LETTER, e->e_id); 4715 } 4716 4717 MILTER_CHECK_DONE_MSG(); 4718 if (MilterLogLevel > 10 && *state == SMFIR_REJECT) 4719 sm_syslog(LOG_INFO, e->e_id, "Milter: reject, data"); 4720 return response; 4721 } 4722 4723 /* 4724 ** MILTER_UNKNOWN -- send any unrecognized or unimplemented command 4725 ** string to milter filters 4726 ** 4727 ** Parameters: 4728 ** smtpcmd -- the string itself. 4729 ** e -- current envelope. 4730 ** state -- return state from response. 4731 ** 4732 ** 4733 ** Returns: 4734 ** response string (may be NULL) 4735 */ 4736 4737 char * 4738 milter_unknown(smtpcmd, e, state) 4739 char *smtpcmd; 4740 ENVELOPE *e; 4741 char *state; 4742 { 4743 if (tTd(64, 10)) 4744 sm_dprintf("milter_unknown(%s)\n", smtpcmd); 4745 4746 return milter_command(SMFIC_UNKNOWN, smtpcmd, strlen(smtpcmd) + 1, 4747 SMFIM_NOMACROS, e, state, "unknown", false); 4748 } 4749 4750 /* 4751 ** MILTER_QUIT -- informs the filter(s) we are done and closes connection(s) 4752 ** 4753 ** Parameters: 4754 ** e -- current envelope. 4755 ** 4756 ** Returns: 4757 ** none 4758 */ 4759 4760 void 4761 milter_quit(e) 4762 ENVELOPE *e; 4763 { 4764 int i; 4765 4766 if (tTd(64, 10)) 4767 sm_dprintf("milter_quit(%s)\n", e->e_id); 4768 4769 for (i = 0; InputFilters[i] != NULL; i++) 4770 milter_quit_filter(InputFilters[i], e); 4771 } 4772 4773 /* 4774 ** MILTER_ABORT -- informs the filter(s) that we are aborting current message 4775 ** 4776 ** Parameters: 4777 ** e -- current envelope. 4778 ** 4779 ** Returns: 4780 ** none 4781 */ 4782 4783 void 4784 milter_abort(e) 4785 ENVELOPE *e; 4786 { 4787 int i; 4788 4789 if (tTd(64, 10)) 4790 sm_dprintf("milter_abort\n"); 4791 4792 for (i = 0; InputFilters[i] != NULL; i++) 4793 { 4794 struct milter *m = InputFilters[i]; 4795 4796 /* sanity checks */ 4797 if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG) 4798 continue; 4799 4800 milter_abort_filter(m, e); 4801 } 4802 } 4803 #endif /* MILTER */ 4804