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