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