diff options
author | gshapiro <gshapiro@FreeBSD.org> | 2002-02-17 21:56:45 +0000 |
---|---|---|
committer | gshapiro <gshapiro@FreeBSD.org> | 2002-02-17 21:56:45 +0000 |
commit | 8449595fe97f4474b9b9a7e4edee1ef35dcff393 (patch) | |
tree | e7a33b132264d449a512ddf4a8685df097669c1d /contrib/sendmail/libmilter/engine.c | |
parent | 289b381b31415647269c7520d881017e2dcb27f1 (diff) | |
download | FreeBSD-src-8449595fe97f4474b9b9a7e4edee1ef35dcff393.zip FreeBSD-src-8449595fe97f4474b9b9a7e4edee1ef35dcff393.tar.gz |
Import sendmail 8.12.2
Diffstat (limited to 'contrib/sendmail/libmilter/engine.c')
-rw-r--r-- | contrib/sendmail/libmilter/engine.c | 153 |
1 files changed, 89 insertions, 64 deletions
diff --git a/contrib/sendmail/libmilter/engine.c b/contrib/sendmail/libmilter/engine.c index 0fd48eb..aabfe6c 100644 --- a/contrib/sendmail/libmilter/engine.c +++ b/contrib/sendmail/libmilter/engine.c @@ -8,13 +8,10 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: engine.c,v 8.67.4.17 2001/01/22 19:00:16 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Id: engine.c,v 8.102 2001/12/13 17:10:00 ca Exp $") -#if _FFR_MILTER #include "libmilter.h" -#include "sendmail/useful.h" #if NETINET || NETINET6 # include <arpa/inet.h> @@ -118,13 +115,16 @@ static int dec_arg2 __P((char *, size_t, char **, char **)); ** is set in the NX_* value ** this function is coded in trans_ok(), see below. */ + #define MASK(x) (0x0001 << (x)) /* generate a bit "mask" for a state */ #define NX_INIT (MASK(ST_OPTS)) #define NX_OPTS (MASK(ST_CONN)) #define NX_CONN (MASK(ST_HELO) | MASK(ST_MAIL)) #define NX_HELO (MASK(ST_HELO) | MASK(ST_MAIL)) #define NX_MAIL (MASK(ST_RCPT) | MASK(ST_ABRT)) -#define NX_RCPT (MASK(ST_HDRS) | MASK(ST_EOHS) | MASK(ST_RCPT) | MASK(ST_ABRT)) +#define NX_RCPT (MASK(ST_HDRS) | MASK(ST_EOHS) | \ + MASK(ST_BODY) | MASK(ST_ENDM) | \ + MASK(ST_RCPT) | MASK(ST_ABRT)) #define NX_HDRS (MASK(ST_EOHS) | MASK(ST_HDRS) | MASK(ST_ABRT)) #define NX_EOHS (MASK(ST_BODY) | MASK(ST_ENDM) | MASK(ST_ABRT)) #define NX_BODY (MASK(ST_ENDM) | MASK(ST_BODY) | MASK(ST_ABRT)) @@ -172,8 +172,9 @@ static cmdfct cmds[] = #define _SMFIS_OPTIONS 22 #define _SMFIS_NOREPLY 23 #define _SMFIS_FAIL (-1) +#define _SMFIS_NONE (-2) -/* +/* ** MI_ENGINE -- receive commands and process them ** ** Parameters: @@ -208,6 +209,7 @@ mi_engine(ctx) fi_abort = ctx->ctx_smfi->xxfi_abort; mi_clr_macros(ctx, 0); fix_stm(ctx); + r = _SMFIS_NONE; do { /* call abort only if in a mail transaction */ @@ -217,17 +219,29 @@ mi_engine(ctx) if (mi_stop() == MILTER_ABRT) { if (ctx->ctx_dbg > 3) - dprintf("[%d] milter_abort\n", + sm_dprintf("[%d] milter_abort\n", (int) ctx->ctx_id); ret = MI_FAILURE; break; } + + /* + ** Notice: buf is allocated by mi_rd_cmd() and it will + ** usually be free()d after it has been used in f(). + ** However, if the function returns _SMFIS_KEEP then buf + ** contains macros and will not be free()d. + ** Hence r must be set to _SMFIS_NONE if a new buf is + ** allocated to avoid problem with housekeeping, esp. + ** if the code "break"s out of the loop. + */ + + r = _SMFIS_NONE; if ((buf = mi_rd_cmd(sd, &timeout, &cmd, &len, ctx->ctx_smfi->xxfi_name)) == NULL && cmd < SMFIC_VALIDCMD) { if (ctx->ctx_dbg > 5) - dprintf("[%d] mi_engine: mi_rd_cmd error (%x)\n", + sm_dprintf("[%d] mi_engine: mi_rd_cmd error (%x)\n", (int) ctx->ctx_id, (int) cmd); /* @@ -240,7 +254,7 @@ mi_engine(ctx) break; } if (ctx->ctx_dbg > 4) - dprintf("[%d] got cmd '%c' len %d\n", + sm_dprintf("[%d] got cmd '%c' len %d\n", (int) ctx->ctx_id, cmd, len); for (i = 0; i < ncmds; i++) { @@ -251,7 +265,7 @@ mi_engine(ctx) { /* unknown command */ if (ctx->ctx_dbg > 1) - dprintf("[%d] cmd '%c' unknown\n", + sm_dprintf("[%d] cmd '%c' unknown\n", (int) ctx->ctx_id, cmd); ret = MI_FAILURE; break; @@ -260,7 +274,7 @@ mi_engine(ctx) { /* stop for now */ if (ctx->ctx_dbg > 1) - dprintf("[%d] cmd '%c' not impl\n", + sm_dprintf("[%d] cmd '%c' not impl\n", (int) ctx->ctx_id, cmd); ret = MI_FAILURE; break; @@ -269,14 +283,14 @@ mi_engine(ctx) /* is new state ok? */ newstate = cmds[i].cm_next; if (ctx->ctx_dbg > 5) - dprintf("[%d] cur %x new %x nextmask %x\n", + sm_dprintf("[%d] cur %x new %x nextmask %x\n", (int) ctx->ctx_id, curstate, newstate, next_states[curstate]); if (newstate != ST_NONE && !trans_ok(curstate, newstate)) { if (ctx->ctx_dbg > 1) - dprintf("[%d] abort: cur %d (%x) new %d (%x) next %x\n", + sm_dprintf("[%d] abort: cur %d (%x) new %d (%x) next %x\n", (int) ctx->ctx_id, curstate, MASK(curstate), newstate, MASK(newstate), @@ -293,7 +307,11 @@ mi_engine(ctx) curstate = ST_HELO; if (!trans_ok(curstate, newstate)) + { + free(buf); + buf = NULL; continue; + } } arg.a_len = len; arg.a_buf = buf; @@ -337,7 +355,7 @@ mi_engine(ctx) else if (r == _SMFIS_ABORT) { if (ctx->ctx_dbg > 5) - dprintf("[%d] function returned abort\n", + sm_dprintf("[%d] function returned abort\n", (int) ctx->ctx_id); ret = MI_FAILURE; break; @@ -354,12 +372,12 @@ mi_engine(ctx) /* close must always be called */ if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL) (void) (*fi_close)(ctx); - if (buf != NULL) + if (r != _SMFIS_KEEP && buf != NULL) free(buf); mi_clr_macros(ctx, 0); return ret; } -/* +/* ** SENDREPLY -- send a reply to the MTA ** ** Parameters: @@ -462,7 +480,7 @@ mi_clr_macros(ctx, m) } } } -/* +/* ** ST_OPTIONNEG -- negotiate options ** ** Parameters: @@ -543,7 +561,7 @@ st_optionneg(g) return _SMFIS_OPTIONS; } -/* +/* ** ST_CONNECTINFO -- receive connection information ** ** Parameters: @@ -560,7 +578,7 @@ st_connectinfo(g) size_t l; size_t i; char *s, family; - u_short port = 0; + unsigned short port = 0; _SOCK_ADDR sockaddr; sfsistat (*fi_connect) __P((SMFICTX *, char *, _SOCK_ADDR *)); @@ -617,11 +635,11 @@ st_connectinfo(g) # if NETINET6 if (family == SMFIA_INET6) { - if (inet_pton(AF_INET6, s + i, - &sockaddr.sin6.sin6_addr) != 1) + if (mi_inet_pton(AF_INET6, s + i, + &sockaddr.sin6.sin6_addr) != 1) { smi_log(SMI_LOG_ERR, - "%s: connect[%d]: inet_pton failed", + "%s: connect[%d]: mi_inet_pton failed", g->a_ctx->ctx_smfi->xxfi_name, (int) g->a_ctx->ctx_id); return _SMFIS_ABORT; @@ -635,7 +653,7 @@ st_connectinfo(g) # if NETUNIX if (family == SMFIA_UNIX) { - if (strlcpy(sockaddr.sunix.sun_path, s + i, + if (sm_strlcpy(sockaddr.sunix.sun_path, s + i, sizeof sockaddr.sunix.sun_path) >= sizeof sockaddr.sunix.sun_path) { @@ -660,7 +678,7 @@ st_connectinfo(g) return (*fi_connect)(g->a_ctx, g->a_buf, family != SMFIA_UNKNOWN ? &sockaddr : NULL); } -/* +/* ** ST_EOH -- end of headers ** ** Parameters: @@ -683,7 +701,7 @@ st_eoh(g) return (*fi_eoh)(g->a_ctx); return SMFIS_CONTINUE; } -/* +/* ** ST_HELO -- helo/ehlo command ** ** Parameters: @@ -706,7 +724,7 @@ st_helo(g) return (*fi_helo)(g->a_ctx, g->a_buf); return SMFIS_CONTINUE; } -/* +/* ** ST_HEADER -- header line ** ** Parameters: @@ -734,24 +752,24 @@ st_header(g) return _SMFIS_ABORT; } -#define ARGV_FCT(lf, rf, idx) \ - char **argv; \ - sfsistat (*lf) __P((SMFICTX *, char **)); \ - int r; \ - \ - if (g == NULL) \ - return _SMFIS_ABORT; \ - mi_clr_macros(g->a_ctx, g->a_idx + 1); \ - if (g->a_ctx->ctx_smfi == NULL || \ - (lf = g->a_ctx->ctx_smfi->rf) == NULL) \ - return SMFIS_CONTINUE; \ +#define ARGV_FCT(lf, rf, idx) \ + char **argv; \ + sfsistat (*lf) __P((SMFICTX *, char **)); \ + int r; \ + \ + if (g == NULL) \ + return _SMFIS_ABORT; \ + mi_clr_macros(g->a_ctx, g->a_idx + 1); \ + if (g->a_ctx->ctx_smfi == NULL || \ + (lf = g->a_ctx->ctx_smfi->rf) == NULL) \ + return SMFIS_CONTINUE; \ if ((argv = dec_argv(g->a_buf, g->a_len)) == NULL) \ - return _SMFIS_ABORT; \ - r = (*lf)(g->a_ctx, argv); \ - free(argv); \ + return _SMFIS_ABORT; \ + r = (*lf)(g->a_ctx, argv); \ + free(argv); \ return r; -/* +/* ** ST_SENDER -- MAIL FROM command ** ** Parameters: @@ -767,7 +785,7 @@ st_sender(g) { ARGV_FCT(fi_envfrom, xxfi_envfrom, CI_MAIL) } -/* +/* ** ST_RCPT -- RCPT TO command ** ** Parameters: @@ -783,7 +801,7 @@ st_rcpt(g) { ARGV_FCT(fi_envrcpt, xxfi_envrcpt, CI_RCPT) } -/* +/* ** ST_MACROS -- deal with macros received from the MTA ** ** Parameters: @@ -833,7 +851,7 @@ st_macros(g) g->a_ctx->ctx_mac_buf[i] = g->a_buf; return _SMFIS_KEEP; } -/* +/* ** ST_QUIT -- quit command ** ** Parameters: @@ -849,7 +867,7 @@ st_quit(g) { return _SMFIS_NOREPLY; } -/* +/* ** ST_BODYCHUNK -- deal with a piece of the mail body ** ** Parameters: @@ -863,16 +881,17 @@ static int st_bodychunk(g) genarg *g; { - sfsistat (*fi_body) __P((SMFICTX *, u_char *, size_t)); + sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t)); if (g == NULL) return _SMFIS_ABORT; if (g->a_ctx->ctx_smfi != NULL && (fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL) - return (*fi_body)(g->a_ctx, (u_char *)g->a_buf, g->a_len); + return (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf, + g->a_len); return SMFIS_CONTINUE; } -/* +/* ** ST_BODYEND -- deal with the last piece of the mail body ** ** Parameters: @@ -890,7 +909,7 @@ st_bodyend(g) genarg *g; { sfsistat r; - sfsistat (*fi_body) __P((SMFICTX *, u_char *, size_t)); + sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t)); sfsistat (*fi_eom) __P((SMFICTX *)); if (g == NULL) @@ -907,7 +926,8 @@ st_bodyend(g) timeout.tv_sec = g->a_ctx->ctx_timeout; timeout.tv_usec = 0; sd = g->a_ctx->ctx_sd; - r = (*fi_body)(g->a_ctx, (u_char *)g->a_buf, g->a_len); + r = (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf, + g->a_len); if (r != SMFIS_CONTINUE && sendreply(r, sd, &timeout, g->a_ctx) != MI_SUCCESS) return _SMFIS_ABORT; @@ -918,7 +938,7 @@ st_bodyend(g) return (*fi_eom)(g->a_ctx); return r; } -/* +/* ** ST_ABORTFCT -- deal with aborts ** ** Parameters: @@ -941,7 +961,7 @@ st_abortfct(g) (void) (*fi_abort)(g->a_ctx); return _SMFIS_NOREPLY; } -/* +/* ** TRANS_OK -- is the state transition ok? ** ** Parameters: @@ -963,13 +983,14 @@ trans_ok(old, new) { /* is this state transition allowed? */ if ((MASK(new) & next_states[s]) != 0) - return TRUE; + return true; /* ** no: try next state; ** this works since the relevant states are ordered ** strict sequentially */ + n = s + 1; /* @@ -977,14 +998,15 @@ trans_ok(old, new) ** see fix_stm() which sets this bit for those ** states which the filter program is not interested in */ + if (bitset(NX_SKIP, next_states[n])) s = n; else - return FALSE; + return false; } while (s <= ST_LAST); - return FALSE; + return false; } -/* +/* ** FIX_STM -- add "skip" bits to the state transition table ** ** Parameters: @@ -1001,7 +1023,7 @@ static void fix_stm(ctx) SMFICTX_PTR ctx; { - u_long fl; + unsigned long fl; if (ctx == NULL || ctx->ctx_smfi == NULL) return; @@ -1021,7 +1043,7 @@ fix_stm(ctx) if (bitset(SMFIP_NOBODY, fl)) next_states[ST_BODY] |= NX_SKIP; } -/* +/* ** DEC_ARGV -- split a buffer into a list of strings, NULL terminated ** ** Parameters: @@ -1065,7 +1087,7 @@ dec_argv(buf, len) s[elem] = NULL; return s; } -/* +/* ** DEC_ARG2 -- split a buffer into two strings ** ** Parameters: @@ -1094,7 +1116,7 @@ dec_arg2(buf, len, s1, s2) *s2 = buf + i + 1; return MI_SUCCESS; } -/* +/* ** SENDOK -- is it ok for the filter to send stuff to the MTA? ** ** Parameters: @@ -1111,9 +1133,12 @@ mi_sendok(ctx, flag) int flag; { if (ctx == NULL || ctx->ctx_smfi == NULL) - return FALSE; + return false; + + /* did the milter request this operation? */ if (flag != 0 && !bitset(flag, ctx->ctx_smfi->xxfi_flags)) - return FALSE; + return false; + + /* are we in the correct state? It must be "End of Message". */ return ctx->ctx_state == ST_ENDM; } -#endif /* _FFR_MILTER */ |