Deleted Added
full compact
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 ---