diff options
Diffstat (limited to 'contrib/sendmail/libmilter/smfi.c')
-rw-r--r-- | contrib/sendmail/libmilter/smfi.c | 232 |
1 files changed, 204 insertions, 28 deletions
diff --git a/contrib/sendmail/libmilter/smfi.c b/contrib/sendmail/libmilter/smfi.c index e034aa8..fd564d5 100644 --- a/contrib/sendmail/libmilter/smfi.c +++ b/contrib/sendmail/libmilter/smfi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,13 +8,14 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: smfi.c,v 8.28.4.6 2000/06/28 23:48:56 gshapiro Exp $"; -#endif /* ! lint */ - -#if _FFR_MILTER +#include <sm/gen.h> +SM_RCSID("@(#)$Id: smfi.c,v 8.57 2001/11/20 18:47:49 ca Exp $") +#include <sm/varargs.h> #include "libmilter.h" -#include "sendmail/useful.h" + +/* for smfi_set{ml}reply, let's be generous. 256/16 should be sufficient */ +#define MAXREPLYLEN 980 /* max. length of a reply string */ +#define MAXREPLIES 32 /* max. number of reply strings */ /* ** SMFI_ADDHEADER -- send a new header to the MTA @@ -110,7 +111,7 @@ smfi_chgheader(ctx, headerf, hdridx, headerv) free(buf); return r; } -/* +/* ** SMFI_ADDRCPT -- send an additional recipient to the MTA ** ** Parameters: @@ -138,7 +139,7 @@ smfi_addrcpt(ctx, rcpt) len = strlen(rcpt) + 1; return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_ADDRCPT, rcpt, len); } -/* +/* ** SMFI_DELRCPT -- send a recipient to be removed to the MTA ** ** Parameters: @@ -166,7 +167,7 @@ smfi_delrcpt(ctx, rcpt) len = strlen(rcpt) + 1; return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_DELRCPT, rcpt, len); } -/* +/* ** SMFI_REPLACEBODY -- send a body chunk to the MTA ** ** Parameters: @@ -181,13 +182,14 @@ smfi_delrcpt(ctx, rcpt) int smfi_replacebody(ctx, bodyp, bodylen) SMFICTX *ctx; - u_char *bodyp; + unsigned char *bodyp; int bodylen; { int len, off, r; struct timeval timeout; - if (bodyp == NULL && bodylen > 0) + if (bodylen < 0 || + (bodyp == NULL && bodylen > 0)) return MI_FAILURE; if (!mi_sendok(ctx, SMFIF_CHGBODY)) return MI_FAILURE; @@ -208,7 +210,46 @@ smfi_replacebody(ctx, bodyp, bodylen) } return MI_SUCCESS; } -/* +#if _FFR_QUARANTINE +/* +** SMFI_QUARANTINE -- quarantine an envelope +** +** Parameters: +** ctx -- Opaque context structure +** reason -- why? +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + +int +smfi_quarantine(ctx, reason) + SMFICTX *ctx; + char *reason; +{ + size_t len; + int r; + char *buf; + struct timeval timeout; + + if (reason == NULL || *reason == '\0') + return MI_FAILURE; + if (!mi_sendok(ctx, SMFIF_QUARANTINE)) + return MI_FAILURE; + timeout.tv_sec = ctx->ctx_timeout; + timeout.tv_usec = 0; + len = strlen(reason) + 1; + buf = malloc(len); + if (buf == NULL) + return MI_FAILURE; + (void) memcpy(buf, reason, len); + r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_QUARANTINE, buf, len); + free(buf); + return r; +} +#endif /* _FFR_QUARANTINE */ + +/* ** MYISENHSC -- check whether a string contains an enhanced status code ** ** Parameters: @@ -247,7 +288,8 @@ myisenhsc(s, delim) return 0; return l + h; } -/* + +/* ** SMFI_SETREPLY -- set the reply code for the next reply to the MTA ** ** Parameters: @@ -267,35 +309,170 @@ smfi_setreply(ctx, rcode, xcode, message) char *xcode; char *message; { - size_t len, l1, l2, l3; + size_t len; char *buf; if (rcode == NULL || ctx == NULL) return MI_FAILURE; - l1 = strlen(rcode) + 1; - if (l1 != 4) + + /* ### <sp> \0 */ + len = strlen(rcode) + 2; + if (len != 5) return MI_FAILURE; if ((rcode[0] != '4' && rcode[0] != '5') || !isascii(rcode[1]) || !isdigit(rcode[1]) || !isascii(rcode[2]) || !isdigit(rcode[2])) return MI_FAILURE; - l2 = xcode == NULL ? 1 : strlen(xcode) + 1; - if (xcode != NULL && !myisenhsc(xcode, '\0')) + if (xcode != NULL) + { + if (!myisenhsc(xcode, '\0')) + return MI_FAILURE; + len += strlen(xcode) + 1; + } + if (message != NULL) + { + size_t ml; + + /* XXX check also for unprintable chars? */ + if (strpbrk(message, "\r\n") != NULL) + return MI_FAILURE; + ml = strlen(message); + if (ml > MAXREPLYLEN) + return MI_FAILURE; + len += ml + 1; + } + buf = malloc(len); + if (buf == NULL) + return MI_FAILURE; /* oops */ + (void) sm_strlcpy(buf, rcode, len); + (void) sm_strlcat(buf, " ", len); + if (xcode != NULL) + (void) sm_strlcat(buf, xcode, len); + if (message != NULL) + { + if (xcode != NULL) + (void) sm_strlcat(buf, " ", len); + (void) sm_strlcat(buf, message, len); + } + if (ctx->ctx_reply != NULL) + free(ctx->ctx_reply); + ctx->ctx_reply = buf; + return MI_SUCCESS; +} + +#if _FFR_MULTILINE +/* +** SMFI_SETMLREPLY -- set multiline reply code for the next reply to the MTA +** +** Parameters: +** ctx -- Opaque context structure +** rcode -- The three-digit (RFC 821) SMTP reply code. +** xcode -- The extended (RFC 2034) reply code. +** txt, ... -- The text part of the SMTP reply, +** MUST be terminated with NULL. +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + +int +#if SM_VA_STD +smfi_setmlreply(SMFICTX *ctx, const char *rcode, const char *xcode, ...) +#else /* SM_VA_STD */ +smfi_setmlreply(ctx, rcode, xcode, va_alist) + SMFICTX *ctx; + const char *rcode; + const char *xcode; + va_dcl +#endif /* SM_VA_STD */ +{ + size_t len; + size_t rlen; + int args; + char *buf, *txt; + const char *xc; + char repl[16]; + SM_VA_LOCAL_DECL + + if (rcode == NULL || ctx == NULL) + return MI_FAILURE; + + /* ### <sp> */ + len = strlen(rcode) + 1; + if (len != 4) return MI_FAILURE; - l3 = message == NULL ? 1 : strlen(message) + 1; - len = l1 + l2 + l3; + if ((rcode[0] != '4' && rcode[0] != '5') || + !isascii(rcode[1]) || !isdigit(rcode[1]) || + !isascii(rcode[2]) || !isdigit(rcode[2])) + return MI_FAILURE; + if (xcode != NULL) + { + if (!myisenhsc(xcode, '\0')) + return MI_FAILURE; + xc = xcode; + } + else + { + if (rcode[0] == '4') + xc = "4.0.0"; + else + xc = "5.0.0"; + } + + /* add trailing space */ + len += strlen(xc) + 1; + rlen = len; + args = 0; + SM_VA_START(ap, xcode); + while ((txt = SM_VA_ARG(ap, char *)) != NULL) + { + size_t tl; + + tl = strlen(txt); + if (tl > MAXREPLYLEN) + return MI_FAILURE; + + /* this text, reply codes, \r\n */ + len += tl + 2 + rlen; + if (++args > MAXREPLIES) + return MI_FAILURE; + + /* XXX check also for unprintable chars? */ + if (strpbrk(txt, "\r\n") != NULL) + return MI_FAILURE; + } + SM_VA_END(ap); + + /* trailing '\0' */ + ++len; buf = malloc(len); if (buf == NULL) return MI_FAILURE; /* oops */ - (void) snprintf(buf, len, "%s %s %s", rcode, - xcode == NULL ? "" : xcode, - message == NULL ? "" : message); + (void) sm_strlcpyn(buf, len, 3, rcode, args == 1 ? " " : "-", xc); + (void) sm_strlcpyn(repl, sizeof repl, 4, rcode, args == 1 ? " " : "-", + xc, " "); + SM_VA_START(ap, xcode); + txt = SM_VA_ARG(ap, char *); + if (txt != NULL) + { + (void) sm_strlcat2(buf, " ", txt, len); + while ((txt = SM_VA_ARG(ap, char *)) != NULL) + { + if (--args <= 1) + repl[3] = ' '; + (void) sm_strlcat2(buf, "\r\n", repl, len); + (void) sm_strlcat(buf, txt, len); + } + } if (ctx->ctx_reply != NULL) free(ctx->ctx_reply); ctx->ctx_reply = buf; + SM_VA_END(ap); return MI_SUCCESS; } -/* +#endif /* _FFR_MULTILINE */ + +/* ** SMFI_SETPRIV -- set private data ** ** Parameters: @@ -316,7 +493,7 @@ smfi_setpriv(ctx, privatedata) ctx->ctx_privdata = privatedata; return MI_SUCCESS; } -/* +/* ** SMFI_GETPRIV -- get private data ** ** Parameters: @@ -334,7 +511,7 @@ smfi_getpriv(ctx) return NULL; return ctx->ctx_privdata; } -/* +/* ** SMFI_GETSYMVAL -- get the value of a macro ** ** See explanation in mfapi.h about layout of the structures. @@ -397,4 +574,3 @@ smfi_getsymval(ctx, symname) } return NULL; } -#endif /* _FFR_MILTER */ |