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