milter.c (203004) | milter.c (244833) |
---|---|
1/* 2 * Copyright (c) 1999-2009 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 */ 10 11#include <sendmail.h> 12 | 1/* 2 * Copyright (c) 1999-2009 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 */ 10 11#include <sendmail.h> 12 |
13SM_RCSID("@(#)$Id: milter.c,v 8.277 2009/11/06 00:57:06 ca Exp $") | 13SM_RCSID("@(#)$Id: milter.c,v 8.279 2012/11/16 20:25:03 ca Exp $") |
14 15#if MILTER 16# include <sm/sendmail.h> 17# include <libmilter/mfapi.h> 18# include <libmilter/mfdef.h> 19 20# include <errno.h> 21# include <sm/time.h> --- 15 unchanged lines hidden (view full) --- 37static char *milter_sysread __P((struct milter *, char *, ssize_t, time_t, 38 ENVELOPE *, const char *)); 39static char *milter_read __P((struct milter *, char *, ssize_t *, time_t, 40 ENVELOPE *, const char *)); 41static char *milter_write __P((struct milter *, int, char *, ssize_t, 42 time_t, ENVELOPE *, const char *)); 43static char *milter_send_command __P((struct milter *, int, void *, 44 ssize_t, ENVELOPE *, char *, const char *)); | 14 15#if MILTER 16# include <sm/sendmail.h> 17# include <libmilter/mfapi.h> 18# include <libmilter/mfdef.h> 19 20# include <errno.h> 21# include <sm/time.h> --- 15 unchanged lines hidden (view full) --- 37static char *milter_sysread __P((struct milter *, char *, ssize_t, time_t, 38 ENVELOPE *, const char *)); 39static char *milter_read __P((struct milter *, char *, ssize_t *, time_t, 40 ENVELOPE *, const char *)); 41static char *milter_write __P((struct milter *, int, char *, ssize_t, 42 time_t, ENVELOPE *, const char *)); 43static char *milter_send_command __P((struct milter *, int, void *, 44 ssize_t, ENVELOPE *, char *, const char *)); |
45static char *milter_command __P((int, void *, ssize_t, char **, | 45static char *milter_command __P((int, void *, ssize_t, int, |
46 ENVELOPE *, char *, const char *, bool)); 47static char *milter_body __P((struct milter *, ENVELOPE *, char *)); 48static int milter_reopen_df __P((ENVELOPE *)); 49static int milter_reset_df __P((ENVELOPE *)); 50static void milter_quit_filter __P((struct milter *, ENVELOPE *)); 51static void milter_abort_filter __P((struct milter *, ENVELOPE *)); 52static void milter_send_macros __P((struct milter *, char **, int, 53 ENVELOPE *)); --- 20 unchanged lines hidden (view full) --- 74# define SMFS_OPEN 'O' /* connected to remote milter filter */ 75# define SMFS_INMSG 'M' /* currently servicing a message */ 76# define SMFS_DONE 'D' /* done with current message */ 77# define SMFS_CLOSABLE 'Q' /* done with current connection */ 78# define SMFS_ERROR 'E' /* error state */ 79# define SMFS_READY 'R' /* ready for action */ 80# define SMFS_SKIP 'S' /* skip body */ 81 | 46 ENVELOPE *, char *, const char *, bool)); 47static char *milter_body __P((struct milter *, ENVELOPE *, char *)); 48static int milter_reopen_df __P((ENVELOPE *)); 49static int milter_reset_df __P((ENVELOPE *)); 50static void milter_quit_filter __P((struct milter *, ENVELOPE *)); 51static void milter_abort_filter __P((struct milter *, ENVELOPE *)); 52static void milter_send_macros __P((struct milter *, char **, int, 53 ENVELOPE *)); --- 20 unchanged lines hidden (view full) --- 74# define SMFS_OPEN 'O' /* connected to remote milter filter */ 75# define SMFS_INMSG 'M' /* currently servicing a message */ 76# define SMFS_DONE 'D' /* done with current message */ 77# define SMFS_CLOSABLE 'Q' /* done with current connection */ 78# define SMFS_ERROR 'E' /* error state */ 79# define SMFS_READY 'R' /* ready for action */ 80# define SMFS_SKIP 'S' /* skip body */ 81 |
82static char *MilterConnectMacros[MAXFILTERMACROS + 1]; 83static char *MilterHeloMacros[MAXFILTERMACROS + 1]; 84static char *MilterEnvFromMacros[MAXFILTERMACROS + 1]; 85static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1]; 86static char *MilterDataMacros[MAXFILTERMACROS + 1]; 87static char *MilterEOMMacros[MAXFILTERMACROS + 1]; 88static char *MilterEOHMacros[MAXFILTERMACROS + 1]; | 82/* 83** MilterMacros contains the milter macros for each milter and each stage. 84** indices are (in order): stages, milter-index, macro 85** milter-index == 0: "global" macros (not for a specific milter). 86*/ 87 88static char *MilterMacros[SMFIM_LAST + 1][MAXFILTERS + 1][MAXFILTERMACROS + 1]; |
89static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE; 90 91# define MILTER_CHECK_DONE_MSG() \ 92 if (*state == SMFIR_REPLYCODE || \ 93 *state == SMFIR_REJECT || \ 94 *state == SMFIR_DISCARD || \ 95 *state == SMFIR_TEMPFAIL) \ 96 { \ 97 /* Abort the filters to let them know we are done with msg */ \ 98 milter_abort(e); \ 99 } 100 | 89static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE; 90 91# define MILTER_CHECK_DONE_MSG() \ 92 if (*state == SMFIR_REPLYCODE || \ 93 *state == SMFIR_REJECT || \ 94 *state == SMFIR_DISCARD || \ 95 *state == SMFIR_TEMPFAIL) \ 96 { \ 97 /* Abort the filters to let them know we are done with msg */ \ 98 milter_abort(e); \ 99 } 100 |
101/* set state in case of an error */ 102# define MILTER_SET_STATE \ 103 if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \ 104 *state = SMFIR_TEMPFAIL; \ 105 else if (bitnset(SMF_TEMPDROP, m->mf_flags)) \ 106 *state = SMFIR_SHUTDOWN; \ 107 else if (bitnset(SMF_REJECT, m->mf_flags)) \ 108 *state = SMFIR_REJECT 109 110/* flow through code maybe using continue; don't wrap in do {} while */ |
|
101# define MILTER_CHECK_ERROR(initial, action) \ 102 if (!initial && tTd(71, 100)) \ 103 { \ 104 if (e->e_quarmsg == NULL) \ 105 { \ 106 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \ 107 "filter failure"); \ 108 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \ --- 5 unchanged lines hidden (view full) --- 114 if (e->e_quarmsg == NULL) \ 115 { \ 116 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \ 117 "filter failure"); \ 118 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \ 119 e->e_quarmsg); \ 120 } \ 121 } \ | 111# define MILTER_CHECK_ERROR(initial, action) \ 112 if (!initial && tTd(71, 100)) \ 113 { \ 114 if (e->e_quarmsg == NULL) \ 115 { \ 116 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \ 117 "filter failure"); \ 118 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \ --- 5 unchanged lines hidden (view full) --- 124 if (e->e_quarmsg == NULL) \ 125 { \ 126 e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \ 127 "filter failure"); \ 128 macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \ 129 e->e_quarmsg); \ 130 } \ 131 } \ |
122 else if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \ 123 *state = SMFIR_TEMPFAIL; \ 124 else if (bitnset(SMF_TEMPDROP, m->mf_flags)) \ 125 *state = SMFIR_SHUTDOWN; \ 126 else if (bitnset(SMF_REJECT, m->mf_flags)) \ 127 *state = SMFIR_REJECT; \ | 132 else MILTER_SET_STATE; \ |
128 else \ 129 action; 130 131# define MILTER_CHECK_REPLYCODE(default) \ 132 if (response == NULL || \ 133 strlen(response) + 1 != (size_t) rlen || \ 134 rlen < 3 || \ 135 (response[0] != '4' && response[0] != '5') || \ --- 1080 unchanged lines hidden (view full) --- 1216void 1217milter_setup(line) 1218 char *line; 1219{ 1220 char fcode; 1221 char *p; 1222 struct milter *m; 1223 STAB *s; | 133 else \ 134 action; 135 136# define MILTER_CHECK_REPLYCODE(default) \ 137 if (response == NULL || \ 138 strlen(response) + 1 != (size_t) rlen || \ 139 rlen < 3 || \ 140 (response[0] != '4' && response[0] != '5') || \ --- 1080 unchanged lines hidden (view full) --- 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; |
|
1224 1225 /* collect the filter name */ 1226 for (p = line; 1227 *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); 1228 p++) 1229 continue; 1230 if (*p != '\0') 1231 *p++ = '\0'; --- 86 unchanged lines hidden (view full) --- 1318 /* early check for errors */ 1319 (void) milter_open(m, true, CurEnv); 1320 1321 /* enter the filter into the symbol table */ 1322 s = stab(m->mf_name, ST_MILTER, ST_ENTER); 1323 if (s->s_milter != NULL) 1324 syserr("X%s: duplicate filter definition", m->mf_name); 1325 else | 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'; --- 86 unchanged lines hidden (view full) --- 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 { |
|
1326 s->s_milter = m; | 1333 s->s_milter = m; |
1334 m->mf_idx = ++idx; 1335 } |
|
1327} 1328 1329/* 1330** MILTER_CONFIG -- parse option list into an array and check config 1331** 1332** Called when reading configuration file. 1333** 1334** Parameters: --- 215 unchanged lines hidden (view full) --- 1550static BITMAP256 StickyMilterOpt; 1551 1552static struct milteropt 1553{ 1554 char *mo_name; /* long name of milter option */ 1555 unsigned char mo_code; /* code for option */ 1556} MilterOptTab[] = 1557{ | 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: --- 215 unchanged lines hidden (view full) --- 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{ |
1558# define MO_MACROS_CONNECT SMFIM_CONNECT 1559 { "macros.connect", MO_MACROS_CONNECT }, 1560# define MO_MACROS_HELO SMFIM_HELO 1561 { "macros.helo", MO_MACROS_HELO }, 1562# define MO_MACROS_ENVFROM SMFIM_ENVFROM 1563 { "macros.envfrom", MO_MACROS_ENVFROM }, 1564# define MO_MACROS_ENVRCPT SMFIM_ENVRCPT 1565 { "macros.envrcpt", MO_MACROS_ENVRCPT }, 1566# define MO_MACROS_DATA SMFIM_DATA 1567 { "macros.data", MO_MACROS_DATA }, 1568# define MO_MACROS_EOM SMFIM_EOM 1569 { "macros.eom", MO_MACROS_EOM }, 1570# define MO_MACROS_EOH SMFIM_EOH 1571 { "macros.eoh", MO_MACROS_EOH }, | 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 }, |
1572 1573# define MO_LOGLEVEL 0x07 1574 { "loglevel", MO_LOGLEVEL }, 1575# if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE 1576# define MO_MAXDATASIZE 0x08 1577 { "maxdatasize", MO_MAXDATASIZE }, 1578# endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */ 1579 { NULL, (unsigned char)-1 }, --- 70 unchanged lines hidden (view full) --- 1650 MilterMaxDataSize = MILTER_MDS_256K; 1651 else 1652 MilterMaxDataSize = MILTER_MDS_1M; 1653 } 1654# endif /* _FFR_MDS_NEGOTIATE */ 1655 break; 1656# endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */ 1657 | 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 }, --- 70 unchanged lines hidden (view full) --- 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 |
1658 case MO_MACROS_CONNECT: 1659 if (macros == NULL) 1660 macros = MilterConnectMacros; 1661 /* FALLTHROUGH */ | 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]; |
1662 | 1668 |
1663 case MO_MACROS_HELO: 1664 if (macros == NULL) 1665 macros = MilterHeloMacros; 1666 /* FALLTHROUGH */ 1667 1668 case MO_MACROS_ENVFROM: 1669 if (macros == NULL) 1670 macros = MilterEnvFromMacros; 1671 /* FALLTHROUGH */ 1672 1673 case MO_MACROS_ENVRCPT: 1674 if (macros == NULL) 1675 macros = MilterEnvRcptMacros; 1676 /* FALLTHROUGH */ 1677 1678 case MO_MACROS_EOH: 1679 if (macros == NULL) 1680 macros = MilterEOHMacros; 1681 /* FALLTHROUGH */ 1682 1683 case MO_MACROS_EOM: 1684 if (macros == NULL) 1685 macros = MilterEOMMacros; 1686 /* FALLTHROUGH */ 1687 1688 case MO_MACROS_DATA: 1689 if (macros == NULL) 1690 macros = MilterDataMacros; 1691 | |
1692 r = milter_set_macros(name, macros, val, nummac); 1693 if (r >= 0) 1694 nummac = r; 1695 break; 1696 1697 default: 1698 syserr("milter_set_option: invalid Milter option %s", name); 1699 break; --- 483 unchanged lines hidden (view full) --- 2183 break; 2184 2185 default: 2186 /* Invalid response to command */ 2187 if (MilterLogLevel > 0) 2188 sm_syslog(LOG_ERR, e->e_id, 2189 "milter_send_command(%s): action=%s returned bogus response %c", 2190 m->mf_name, action, rcmd); | 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; --- 483 unchanged lines hidden (view full) --- 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); |
2191 milter_error(m, e); | 2168 milter_error(m, e); /* NO ERROR CHECK? */ |
2192 break; 2193 } 2194 2195 if (*state != SMFIR_REPLYCODE && response != NULL) 2196 { 2197 sm_free(response); /* XXX */ 2198 response = NULL; 2199 } --- 13 unchanged lines hidden (view full) --- 2213** where -- description of calling function (logging). 2214** cmd_error -- did the SMTP command cause an error? 2215** 2216** Returns: 2217** response string (may be NULL) 2218*/ 2219 2220static char * | 2169 break; 2170 } 2171 2172 if (*state != SMFIR_REPLYCODE && response != NULL) 2173 { 2174 sm_free(response); /* XXX */ 2175 response = NULL; 2176 } --- 13 unchanged lines hidden (view full) --- 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 * |
2221milter_command(cmd, data, sz, macros, e, state, where, cmd_error) | 2198milter_command(cmd, data, sz, stage, e, state, where, cmd_error) |
2222 int cmd; 2223 void *data; 2224 ssize_t sz; | 2199 int cmd; 2200 void *data; 2201 ssize_t sz; |
2225 char **macros; | 2202 int stage; |
2226 ENVELOPE *e; 2227 char *state; 2228 const char *where; 2229 bool cmd_error; 2230{ 2231 int i; 2232 char command = (char) cmd; 2233 char *response = NULL; --- 15 unchanged lines hidden (view full) --- 2249 break; 2250 } 2251 2252 /* sanity check */ 2253 if (m->mf_sock < 0 || 2254 (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) 2255 continue; 2256 | 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; --- 15 unchanged lines hidden (view full) --- 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 |
2257 /* send macros (regardless of whether we send command) */ 2258 if (macros != NULL && macros[0] != NULL) | 2234 if (stage >= SMFIM_FIRST && stage <= SMFIM_LAST) |
2259 { | 2235 { |
2260 milter_send_macros(m, macros, command, e); 2261 if (m->mf_state == SMFS_ERROR) | 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) |
2262 { | 2248 { |
2263 MILTER_CHECK_ERROR(false, continue); 2264 break; | 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 } |
2265 } 2266 } 2267 2268 if (MilterLogLevel > 21) 2269 tn = curtime(); 2270 2271 /* 2272 ** send the command if --- 51 unchanged lines hidden (view full) --- 2324 i = ntohl(v); 2325 if (i < SMFIM_FIRST || i > SMFIM_LAST) 2326 return -1; 2327 offset += MILTER_LEN_BYTES; 2328 macros = NULL; 2329 2330 switch (i) 2331 { | 2255 } 2256 } 2257 2258 if (MilterLogLevel > 21) 2259 tn = curtime(); 2260 2261 /* 2262 ** send the command if --- 51 unchanged lines hidden (view full) --- 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 { |
2332 case MO_MACROS_CONNECT: 2333 if (macros == NULL) 2334 macros = MilterConnectMacros; 2335 /* FALLTHROUGH */ | 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]; |
2336 | 2331 |
2337 case MO_MACROS_HELO: 2338 if (macros == NULL) 2339 macros = MilterHeloMacros; 2340 /* FALLTHROUGH */ 2341 2342 case MO_MACROS_ENVFROM: 2343 if (macros == NULL) 2344 macros = MilterEnvFromMacros; 2345 /* FALLTHROUGH */ 2346 2347 case MO_MACROS_ENVRCPT: 2348 if (macros == NULL) 2349 macros = MilterEnvRcptMacros; 2350 /* FALLTHROUGH */ 2351 2352 case MO_MACROS_EOM: 2353 if (macros == NULL) 2354 macros = MilterEOMMacros; 2355 /* FALLTHROUGH */ 2356 2357 case MO_MACROS_EOH: 2358 if (macros == NULL) 2359 macros = MilterEOHMacros; 2360 /* FALLTHROUGH */ 2361 2362 case MO_MACROS_DATA: 2363 if (macros == NULL) 2364 macros = MilterDataMacros; 2365 | 2332 m->mf_lflags |= MI_LFLAGS_SYM(i); |
2366 len = strlen(buf + offset); 2367 if (len > 0) 2368 { 2369 r = milter_set_macros(m->mf_name, macros, 2370 buf + offset, nummac); 2371 if (r >= 0) 2372 nummac = r; | 2333 len = strlen(buf + offset); 2334 if (len > 0) 2335 { 2336 r = milter_set_macros(m->mf_name, macros, 2337 buf + offset, nummac); 2338 if (r >= 0) 2339 nummac = r; |
2340 if (tTd(64, 5)) 2341 sm_dprintf("milter_getsymlist(%s, %s)=%d\n", 2342 m->mf_name, buf + offset, r); |
|
2373 } 2374 break; 2375 2376 default: 2377 return -1; 2378 } 2379 if (len == 0) 2380 return -1; --- 1603 unchanged lines hidden (view full) --- 3984 { 3985 (void) memcpy(bp, &port, sizeof(port)); 3986 bp += sizeof(port); 3987 3988 /* include trailing '\0' */ 3989 (void) memcpy(bp, sockinfo, strlen(sockinfo) + 1); 3990 } 3991 | 2343 } 2344 break; 2345 2346 default: 2347 return -1; 2348 } 2349 if (len == 0) 2350 return -1; --- 1603 unchanged lines hidden (view full) --- 3954 { 3955 (void) memcpy(bp, &port, sizeof(port)); 3956 bp += sizeof(port); 3957 3958 /* include trailing '\0' */ 3959 (void) memcpy(bp, sockinfo, strlen(sockinfo) + 1); 3960 } 3961 |
3992 response = milter_command(SMFIC_CONNECT, buf, s, MilterConnectMacros, | 3962 response = milter_command(SMFIC_CONNECT, buf, s, SMFIM_CONNECT, |
3993 e, state, "connect", false); 3994 sm_free(buf); /* XXX */ 3995 3996 /* 3997 ** If this message connection is done for, 3998 ** close the filters. 3999 */ 4000 --- 72 unchanged lines hidden (view full) --- 4073 case SMFS_DONE: 4074 /* reset done filters */ 4075 m->mf_state = SMFS_OPEN; 4076 break; 4077 } 4078 } 4079 4080 response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1, | 3963 e, state, "connect", false); 3964 sm_free(buf); /* XXX */ 3965 3966 /* 3967 ** If this message connection is done for, 3968 ** close the filters. 3969 */ 3970 --- 72 unchanged lines hidden (view full) --- 4043 case SMFS_DONE: 4044 /* reset done filters */ 4045 m->mf_state = SMFS_OPEN; 4046 break; 4047 } 4048 } 4049 4050 response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1, |
4081 MilterHeloMacros, e, state, "helo", false); | 4051 SMFIM_EOH, e, state, "helo", false); |
4082 milter_per_connection_check(e); 4083 return response; 4084} 4085 4086/* 4087** MILTER_ENVFROM -- send SMTP MAIL command info to milter filters 4088** 4089** Parameters: --- 71 unchanged lines hidden (view full) --- 4161 (void) sm_strlcpy(bp, args[i], s - (bp - buf)); 4162 bp += strlen(bp) + 1; 4163 } 4164 4165 if (MilterLogLevel > 14) 4166 sm_syslog(LOG_INFO, e->e_id, "Milter: sender: %s", buf); 4167 4168 /* send it over */ | 4052 milter_per_connection_check(e); 4053 return response; 4054} 4055 4056/* 4057** MILTER_ENVFROM -- send SMTP MAIL command info to milter filters 4058** 4059** Parameters: --- 71 unchanged lines hidden (view full) --- 4131 (void) sm_strlcpy(bp, args[i], s - (bp - buf)); 4132 bp += strlen(bp) + 1; 4133 } 4134 4135 if (MilterLogLevel > 14) 4136 sm_syslog(LOG_INFO, e->e_id, "Milter: sender: %s", buf); 4137 4138 /* send it over */ |
4169 response = milter_command(SMFIC_MAIL, buf, s, MilterEnvFromMacros, | 4139 response = milter_command(SMFIC_MAIL, buf, s, SMFIM_ENVFROM, |
4170 e, state, "mail", false); 4171 sm_free(buf); /* XXX */ 4172 4173 /* 4174 ** If filter rejects/discards a per message command, 4175 ** abort the other filters since we are done with the 4176 ** current message. 4177 */ --- 64 unchanged lines hidden (view full) --- 4242 (void) sm_strlcpy(bp, args[i], s - (bp - buf)); 4243 bp += strlen(bp) + 1; 4244 } 4245 4246 if (MilterLogLevel > 14) 4247 sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf); 4248 4249 /* send it over */ | 4140 e, state, "mail", false); 4141 sm_free(buf); /* XXX */ 4142 4143 /* 4144 ** If filter rejects/discards a per message command, 4145 ** abort the other filters since we are done with the 4146 ** current message. 4147 */ --- 64 unchanged lines hidden (view full) --- 4212 (void) sm_strlcpy(bp, args[i], s - (bp - buf)); 4213 bp += strlen(bp) + 1; 4214 } 4215 4216 if (MilterLogLevel > 14) 4217 sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf); 4218 4219 /* send it over */ |
4250 response = milter_command(SMFIC_RCPT, buf, s, MilterEnvRcptMacros, | 4220 response = milter_command(SMFIC_RCPT, buf, s, SMFIM_ENVRCPT, |
4251 e, state, "rcpt", rcpt_error); 4252 sm_free(buf); /* XXX */ 4253 return response; 4254} 4255 4256/* 4257** MILTER_DATA_CMD -- send SMTP DATA command info to milter filters 4258** --- 9 unchanged lines hidden (view full) --- 4268milter_data_cmd(e, state) 4269 ENVELOPE *e; 4270 char *state; 4271{ 4272 if (tTd(64, 10)) 4273 sm_dprintf("milter_data_cmd\n"); 4274 4275 /* send it over */ | 4221 e, state, "rcpt", rcpt_error); 4222 sm_free(buf); /* XXX */ 4223 return response; 4224} 4225 4226/* 4227** MILTER_DATA_CMD -- send SMTP DATA command info to milter filters 4228** --- 9 unchanged lines hidden (view full) --- 4238milter_data_cmd(e, state) 4239 ENVELOPE *e; 4240 char *state; 4241{ 4242 if (tTd(64, 10)) 4243 sm_dprintf("milter_data_cmd\n"); 4244 4245 /* send it over */ |
4276 return milter_command(SMFIC_DATA, NULL, 0, MilterDataMacros, e, state, 4277 "data", false); | 4246 return milter_command(SMFIC_DATA, NULL, 0, SMFIM_DATA, 4247 e, state, "data", false); |
4278} 4279 4280/* 4281** MILTER_DATA -- send message headers/body and gather final message results 4282** 4283** Parameters: 4284** e -- current envelope. 4285** state -- return state from response. 4286** 4287** Returns: 4288** response string (may be NULL) 4289** 4290** Side effects: 4291** - Uses e->e_dfp for access to the body 4292** - Can call the various milter action routines to 4293** modify the envelope or message. 4294*/ 4295 | 4248} 4249 4250/* 4251** MILTER_DATA -- send message headers/body and gather final message results 4252** 4253** Parameters: 4254** e -- current envelope. 4255** state -- return state from response. 4256** 4257** Returns: 4258** response string (may be NULL) 4259** 4260** Side effects: 4261** - Uses e->e_dfp for access to the body 4262** - Can call the various milter action routines to 4263** modify the envelope or message. 4264*/ 4265 |
4266/* flow through code using continue; don't wrap in do {} while */ |
|
4296# define MILTER_CHECK_RESULTS() \ | 4267# define MILTER_CHECK_RESULTS() \ |
4268 if (m->mf_state == SMFS_ERROR && *state == SMFIR_CONTINUE) \ 4269 { \ 4270 MILTER_SET_STATE; \ 4271 } \ |
|
4297 if (*state == SMFIR_ACCEPT || \ 4298 m->mf_state == SMFS_DONE || \ 4299 m->mf_state == SMFS_ERROR) \ 4300 { \ 4301 if (m->mf_state != SMFS_ERROR) \ 4302 m->mf_state = SMFS_DONE; \ 4303 continue; /* to next filter */ \ 4304 } \ --- 29 unchanged lines hidden (view full) --- 4334 ** XXX: Should actually send body chunks to each filter 4335 ** a chunk at a time instead of sending the whole body to 4336 ** each filter in turn. However, only if the filters don't 4337 ** change the body. 4338 */ 4339 4340 for (i = 0; InputFilters[i] != NULL; i++) 4341 { | 4272 if (*state == SMFIR_ACCEPT || \ 4273 m->mf_state == SMFS_DONE || \ 4274 m->mf_state == SMFS_ERROR) \ 4275 { \ 4276 if (m->mf_state != SMFS_ERROR) \ 4277 m->mf_state = SMFS_DONE; \ 4278 continue; /* to next filter */ \ 4279 } \ --- 29 unchanged lines hidden (view full) --- 4309 ** XXX: Should actually send body chunks to each filter 4310 ** a chunk at a time instead of sending the whole body to 4311 ** each filter in turn. However, only if the filters don't 4312 ** change the body. 4313 */ 4314 4315 for (i = 0; InputFilters[i] != NULL; i++) 4316 { |
4317 int idx; 4318 char **macros; |
|
4342 struct milter *m = InputFilters[i]; 4343 4344 if (*state != SMFIR_CONTINUE && 4345 *state != SMFIR_ACCEPT) 4346 { 4347 /* 4348 ** A previous filter has dealt with the message, 4349 ** safe to stop processing the filters. --- 28 unchanged lines hidden (view full) --- 4378 } 4379 4380 /* check if filter wants EOH */ 4381 if (!bitset(SMFIP_NOEOH, m->mf_pflags)) 4382 { 4383 if (tTd(64, 10)) 4384 sm_dprintf("milter_data: eoh\n"); 4385 | 4319 struct milter *m = InputFilters[i]; 4320 4321 if (*state != SMFIR_CONTINUE && 4322 *state != SMFIR_ACCEPT) 4323 { 4324 /* 4325 ** A previous filter has dealt with the message, 4326 ** safe to stop processing the filters. --- 28 unchanged lines hidden (view full) --- 4355 } 4356 4357 /* check if filter wants EOH */ 4358 if (!bitset(SMFIP_NOEOH, m->mf_pflags)) 4359 { 4360 if (tTd(64, 10)) 4361 sm_dprintf("milter_data: eoh\n"); 4362 |
4386 if (MilterEOHMacros[0] != NULL) | 4363 if ((m->mf_lflags & MI_LFLAGS_SYM(SMFIM_EOH)) != 0) 4364 idx = m->mf_idx; 4365 else 4366 idx = 0; 4367 SM_ASSERT(idx >= 0 && idx <= MAXFILTERS); 4368 macros = MilterMacros[SMFIM_EOH][idx]; 4369 4370 if (macros != NULL) |
4387 { | 4371 { |
4388 milter_send_macros(m, MilterEOHMacros, 4389 SMFIC_EOH, e); | 4372 milter_send_macros(m, macros, SMFIC_EOH, e); |
4390 MILTER_CHECK_RESULTS(); 4391 } 4392 4393 /* send it over */ 4394 response = milter_send_command(m, SMFIC_EOH, NULL, 0, 4395 e, state, "eoh"); 4396 MILTER_CHECK_RESULTS(); 4397 } 4398 4399 /* check if filter wants the body */ 4400 if (!bitset(SMFIP_NOBODY, m->mf_pflags) && 4401 e->e_dfp != NULL) 4402 { 4403 rewind = true; 4404 response = milter_body(m, e, state); 4405 MILTER_CHECK_RESULTS(); 4406 } 4407 | 4373 MILTER_CHECK_RESULTS(); 4374 } 4375 4376 /* send it over */ 4377 response = milter_send_command(m, SMFIC_EOH, NULL, 0, 4378 e, state, "eoh"); 4379 MILTER_CHECK_RESULTS(); 4380 } 4381 4382 /* check if filter wants the body */ 4383 if (!bitset(SMFIP_NOBODY, m->mf_pflags) && 4384 e->e_dfp != NULL) 4385 { 4386 rewind = true; 4387 response = milter_body(m, e, state); 4388 MILTER_CHECK_RESULTS(); 4389 } 4390 |
4408 if (MilterEOMMacros[0] != NULL) | 4391 if ((m->mf_lflags & MI_LFLAGS_SYM(SMFIM_EOH)) != 0) 4392 idx = m->mf_idx; 4393 else 4394 idx = 0; 4395 SM_ASSERT(idx >= 0 && idx <= MAXFILTERS); 4396 macros = MilterMacros[SMFIM_EOM][idx]; 4397 if (macros != NULL) |
4409 { | 4398 { |
4410 milter_send_macros(m, MilterEOMMacros, 4411 SMFIC_BODYEOB, e); | 4399 milter_send_macros(m, macros, SMFIC_BODYEOB, e); |
4412 MILTER_CHECK_RESULTS(); 4413 } 4414 4415 /* send the final body chunk */ 4416 (void) milter_write(m, SMFIC_BODYEOB, NULL, 0, 4417 m->mf_timeout[SMFTO_WRITE], e, "eom"); 4418 4419 /* Get time EOM sent for timeout */ --- 309 unchanged lines hidden (view full) --- 4729 char *smtpcmd; 4730 ENVELOPE *e; 4731 char *state; 4732{ 4733 if (tTd(64, 10)) 4734 sm_dprintf("milter_unknown(%s)\n", smtpcmd); 4735 4736 return milter_command(SMFIC_UNKNOWN, smtpcmd, strlen(smtpcmd) + 1, | 4400 MILTER_CHECK_RESULTS(); 4401 } 4402 4403 /* send the final body chunk */ 4404 (void) milter_write(m, SMFIC_BODYEOB, NULL, 0, 4405 m->mf_timeout[SMFTO_WRITE], e, "eom"); 4406 4407 /* Get time EOM sent for timeout */ --- 309 unchanged lines hidden (view full) --- 4717 char *smtpcmd; 4718 ENVELOPE *e; 4719 char *state; 4720{ 4721 if (tTd(64, 10)) 4722 sm_dprintf("milter_unknown(%s)\n", smtpcmd); 4723 4724 return milter_command(SMFIC_UNKNOWN, smtpcmd, strlen(smtpcmd) + 1, |
4737 NULL, e, state, "unknown", false); | 4725 SMFIM_NOMACROS, e, state, "unknown", false); |
4738} 4739 4740/* 4741** MILTER_QUIT -- informs the filter(s) we are done and closes connection(s) 4742** 4743** Parameters: 4744** e -- current envelope. 4745** --- 48 unchanged lines hidden --- | 4726} 4727 4728/* 4729** MILTER_QUIT -- informs the filter(s) we are done and closes connection(s) 4730** 4731** Parameters: 4732** e -- current envelope. 4733** --- 48 unchanged lines hidden --- |