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