summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libmilter/smfi.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/libmilter/smfi.c')
-rw-r--r--contrib/sendmail/libmilter/smfi.c232
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 */
OpenPOWER on IntegriCloud