diff options
Diffstat (limited to 'contrib/sendmail/libmilter/smfi.c')
-rw-r--r-- | contrib/sendmail/libmilter/smfi.c | 613 |
1 files changed, 0 insertions, 613 deletions
diff --git a/contrib/sendmail/libmilter/smfi.c b/contrib/sendmail/libmilter/smfi.c deleted file mode 100644 index 032a6acb288fa..0000000000000 --- a/contrib/sendmail/libmilter/smfi.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: smfi.c,v 8.64 2002/04/30 22:22:02 msk Exp $") -#include <sm/varargs.h> -#include "libmilter.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 -** -** Parameters: -** ctx -- Opaque context structure -** headerf -- Header field name -** headerv -- Header field value -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_addheader(ctx, headerf, headerv) - SMFICTX *ctx; - char *headerf; - char *headerv; -{ - /* do we want to copy the stuff or have a special mi_wr_cmd call? */ - size_t len, l1, l2; - int r; - char *buf; - struct timeval timeout; - - if (headerf == NULL || *headerf == '\0' || headerv == NULL) - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_ADDHDRS)) - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - l1 = strlen(headerf); - l2 = strlen(headerv); - len = l1 + l2 + 2; - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; - (void) memcpy(buf, headerf, l1 + 1); - (void) memcpy(buf + l1 + 1, headerv, l2 + 1); - r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_ADDHEADER, buf, len); - free(buf); - return r; -} - -/* -** SMFI_CHGHEADER -- send a changed header to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** headerf -- Header field name -** hdridx -- Header index value -** headerv -- Header field value -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_chgheader(ctx, headerf, hdridx, headerv) - SMFICTX *ctx; - char *headerf; - mi_int32 hdridx; - char *headerv; -{ - /* do we want to copy the stuff or have a special mi_wr_cmd call? */ - size_t len, l1, l2; - int r; - mi_int32 v; - char *buf; - struct timeval timeout; - - if (headerf == NULL || *headerf == '\0') - return MI_FAILURE; - if (hdridx < 0) - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_CHGHDRS)) - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - if (headerv == NULL) - headerv = ""; - l1 = strlen(headerf); - l2 = strlen(headerv); - len = l1 + l2 + 2 + MILTER_LEN_BYTES; - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; - v = htonl(hdridx); - (void) memcpy(&(buf[0]), (void *) &v, MILTER_LEN_BYTES); - (void) memcpy(buf + MILTER_LEN_BYTES, headerf, l1 + 1); - (void) memcpy(buf + MILTER_LEN_BYTES + l1 + 1, headerv, l2 + 1); - r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_CHGHEADER, buf, len); - free(buf); - return r; -} - -/* -** SMFI_ADDRCPT -- send an additional recipient to the MTA -** -** Parameters: -** ctx -- Opaque context structure -** rcpt -- recipient address -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_addrcpt(ctx, rcpt) - SMFICTX *ctx; - char *rcpt; -{ - size_t len; - struct timeval timeout; - - if (rcpt == NULL || *rcpt == '\0') - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_ADDRCPT)) - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - 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: -** ctx -- Opaque context structure -** rcpt -- recipient address -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_delrcpt(ctx, rcpt) - SMFICTX *ctx; - char *rcpt; -{ - size_t len; - struct timeval timeout; - - if (rcpt == NULL || *rcpt == '\0') - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_DELRCPT)) - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - 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: -** ctx -- Opaque context structure -** bodyp -- body chunk -** bodylen -- length of body chunk -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_replacebody(ctx, bodyp, bodylen) - SMFICTX *ctx; - unsigned char *bodyp; - int bodylen; -{ - int len, off, r; - struct timeval timeout; - - if (bodylen < 0 || - (bodyp == NULL && bodylen > 0)) - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_CHGBODY)) - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - - /* split body chunk if necessary */ - off = 0; - while (bodylen > 0) - { - len = (bodylen >= MILTER_CHUNK_SIZE) ? MILTER_CHUNK_SIZE : - bodylen; - if ((r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_REPLBODY, - (char *) (bodyp + off), len)) != MI_SUCCESS) - return r; - off += len; - bodylen -= len; - } - 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: -** s -- string with possible enhanced status code. -** delim -- delim for enhanced status code. -** -** Returns: -** 0 -- no enhanced status code. -** >4 -- length of enhanced status code. -** -** Side Effects: -** none. -*/ - -static int -myisenhsc(s, delim) - const char *s; - int delim; -{ - int l, h; - - if (s == NULL) - return 0; - if (!((*s == '2' || *s == '4' || *s == '5') && s[1] == '.')) - return 0; - h = 0; - l = 2; - while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h])) - ++h; - if (h == 0 || s[l + h] != '.') - return 0; - l += h + 1; - h = 0; - while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h])) - ++h; - if (h == 0 || s[l + h] != delim) - return 0; - return l + h; -} - -/* -** SMFI_SETREPLY -- set the 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. -** message -- The text part of the SMTP reply. -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_setreply(ctx, rcode, xcode, message) - SMFICTX *ctx; - char *rcode; - char *xcode; - char *message; -{ - size_t len; - char *buf; - - if (rcode == NULL || ctx == NULL) - return MI_FAILURE; - - /* ### <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; - 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; - 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) - break; - - /* this text, reply codes, \r\n */ - len += tl + 2 + rlen; - if (++args > MAXREPLIES) - break; - - /* XXX check also for unprintable chars? */ - if (strpbrk(txt, "\r\n") != NULL) - break; - } - SM_VA_END(ap); - if (txt != NULL) - return MI_FAILURE; - - /* trailing '\0' */ - ++len; - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; /* oops */ - (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: -** ctx -- Opaque context structure -** privatedata -- pointer to private data -** -** Returns: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_setpriv(ctx, privatedata) - SMFICTX *ctx; - void *privatedata; -{ - if (ctx == NULL) - return MI_FAILURE; - ctx->ctx_privdata = privatedata; - return MI_SUCCESS; -} - -/* -** SMFI_GETPRIV -- get private data -** -** Parameters: -** ctx -- Opaque context structure -** -** Returns: -** pointer to private data -*/ - -void * -smfi_getpriv(ctx) - SMFICTX *ctx; -{ - if (ctx == NULL) - return NULL; - return ctx->ctx_privdata; -} - -/* -** SMFI_GETSYMVAL -- get the value of a macro -** -** See explanation in mfapi.h about layout of the structures. -** -** Parameters: -** ctx -- Opaque context structure -** symname -- name of macro -** -** Returns: -** value of macro (NULL in case of failure) -*/ - -char * -smfi_getsymval(ctx, symname) - SMFICTX *ctx; - char *symname; -{ - int i; - char **s; - char one[2]; - char braces[4]; - - if (ctx == NULL || symname == NULL || *symname == '\0') - return NULL; - - if (strlen(symname) == 3 && symname[0] == '{' && symname[2] == '}') - { - one[0] = symname[1]; - one[1] = '\0'; - } - else - one[0] = '\0'; - if (strlen(symname) == 1) - { - braces[0] = '{'; - braces[1] = *symname; - braces[2] = '}'; - braces[3] = '\0'; - } - else - braces[0] = '\0'; - - /* search backwards through the macro array */ - for (i = MAX_MACROS_ENTRIES - 1 ; i >= 0; --i) - { - if ((s = ctx->ctx_mac_ptr[i]) == NULL || - ctx->ctx_mac_buf[i] == NULL) - continue; - while (s != NULL && *s != NULL) - { - if (strcmp(*s, symname) == 0) - return *++s; - if (one[0] != '\0' && strcmp(*s, one) == 0) - return *++s; - if (braces[0] != '\0' && strcmp(*s, braces) == 0) - return *++s; - ++s; /* skip over macro value */ - ++s; /* points to next macro name */ - } - } - return NULL; -} - -#if _FFR_SMFI_PROGRESS -/* -** SMFI_PROGRESS -- send "progress" message to the MTA to prevent premature -** timeouts during long milter-side operations -** -** Parameters: -** ctx -- Opaque context structure -** -** Return value: -** MI_SUCCESS/MI_FAILURE -*/ - -int -smfi_progress(ctx) - SMFICTX *ctx; -{ - struct timeval timeout; - - if (ctx == NULL) - return MI_FAILURE; - - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - - return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_PROGRESS, NULL, 0); -} -#endif /* _FFR_SMFI_PROGRESS */ |