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