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