--- lmtp2nntp.c 2001/10/15 13:14:43 1.95
+++ lmtp2nntp.c 2001/10/15 14:22:12 1.96
@@ -151,6 +151,7 @@
int option_timeout_nntp_read;
int option_timeout_nntp_write;
char *option_mailfrom;
+ char *option_restrictheader;
unsigned int option_levelmask;
char *option_pidfile;
int option_killflag;
@@ -224,6 +225,7 @@
"[-m mailfrom] "
"[-n nodename] "
"[-o operationmode] "
+ "[-r restrictheader] "
"[-s size] "
"[-t name=sec[,name=sec[,...]] "
"[-u uid] "
@@ -442,6 +444,7 @@
ctx->option_timeout_nntp_read = 60;
ctx->option_timeout_nntp_write = 60;
ctx->option_mailfrom = NULL;
+ ctx->option_restrictheader = NULL;
ctx->option_levelmask = L2_LEVEL_NONE;
ctx->option_pidfile = NULL;
ctx->option_killflag = FALSE;
@@ -491,7 +494,7 @@
*/
/* read in the arguments */
- while ((i = getopt(argc, argv, "C:DKP:Va:b:c:d:g:h:l:m:n:o:s:t:u:v")) != -1) {
+ while ((i = getopt(argc, argv, "C:DKP:Va:b:c:d:g:h:l:m:n:o:r:s:t:u:v")) != -1) {
switch (i) {
case 'C': /*POD [B<-C> I<childsmax>] */
ctx->option_childsmax = atoi(optarg);
@@ -803,6 +806,22 @@
}
}
break;
+ case 'r': /*POD [B<-r> I<restrictheader>] */
+ ctx->option_restrictheader = strdup(optarg);
+ /* protect ourselfs from the substitution of backreferences.
+ * Missing varargs would cause segfaults. Rewrite capturing
+ * brackets to clustering syntax. Use poor man's s///g
+ * simulator as current str library doesn't support global
+ * substitution */
+ while (str_parse(ctx->option_restrictheader, "s/(.*?)\\((?!\\?:)(.*)/$1(?:$2/", &cp) > 0) {
+ free(ctx->option_restrictheader);
+ ctx->option_restrictheader = cp;
+ }
+ if (str_parse("<>", ctx->option_restrictheader) == -1) {
+ fprintf(stderr, "%s:Error: illegal regex \"%s\" to option -r.\n", ctx->progname, ctx->option_restrictheader);
+ CU(ERR_EXECUTION);
+ }
+ break;
case 's': /*POD [B<-s> I<size>] */
ctx->option_maxmessagesize = atoi(optarg);
if(ctx->option_maxmessagesize < 64) {
@@ -1266,6 +1285,8 @@
sa_destroy(ctx->saAltio);
if (ctx->saaAltio)
sa_addr_destroy(ctx->saaAltio);
+ if (ctx->option_restrictheader != NULL)
+ free(ctx->option_restrictheader);
if (ctx->azHeaderValuePairs != NULL)
free(ctx->azHeaderValuePairs);
if (ctx->option_pidfile != NULL)
@@ -1873,6 +1894,9 @@
int i;
int bSuccess;
char *cp;
+ int bOk;
+ char *cpRestrictheader;
+ char *cpRestrictvalue;
log1(ctx, INFO, "LMTP service executing DATA command < %s", req->msg);
@@ -2032,8 +2056,45 @@
}
}
+ /* RFC0821 4.2.1. REPLY CODES BY FUNCTION GROUPS 550 Requested action not taken: mailbox unavailable
+ * RFC1893 2. Status Codes 5.X.X Permanent Failure
+ * RFC1893 3.5 Network and Routing Status X.7.1 Delivery not authorized, message refused
+ */
+ log0(ctx, TRACE, "checking if restricted header causes reject");
+ if (ctx->option_restrictheader != NULL) {
+ bOk = FALSE;
+ cp = NULL;
+ while ((cp = argz_next(ctx->msg->azHeaders, ctx->msg->asHeaders, cp)) != NULL) {
+ cpRestrictheader = cp;
+ if ((cp = argz_next(ctx->msg->azHeaders, ctx->msg->asHeaders, cp)) == NULL)
+ break;
+ cpRestrictvalue = cp;
+ str_format(errorstring, sizeof(errorstring), "%s %s", cpRestrictheader, cpRestrictvalue);
+ if (str_parse(errorstring, ctx->option_restrictheader) <= 0) {
+ log2(ctx, TRACE, "\"%s\" matching against \"%s\" NO", errorstring, ctx->option_restrictheader);
+ }
+ else {
+ log2(ctx, TRACE, "\"%s\" matching against \"%s\": YES", errorstring, ctx->option_restrictheader);
+ bOk = TRUE;
+ break;
+ }
+ }
+ if (bOk) {
+ log0(ctx, TRACE, "restricted header found");
+ rcpt = NULL;
+ while ((rcpt = argz_next(ctx->msg->azRcpt, ctx->msg->asRcpt, rcpt)) != NULL) {
+ res.statuscode = "550";
+ res.dsncode = "5.7.1";
+ res.statusmsg = "Restricted header matched, message rejected.";
+ lmtp_response(lmtp, &res);
+ }
+ return LMTP_OK;
+ }
+ }
+
/* Optionally add command line specified Header/Value Pairs
*/
+ log0(ctx, TRACE, "adding header/value pairs");
if ((ctx->asHeaderValuePairs >= 1) && ((ctx->asHeaderValuePairs & 1) == 0)) {
cp = NULL;
while ((cp = argz_next(ctx->azHeaderValuePairs, ctx->asHeaderValuePairs, cp)) != NULL) {
|