[Raw Msg Headers][Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
policy-maxsameipsource.diff
Hello, this is a rather big diff that does three things:
1. fixes a bug when type() was used before SS->...buffer's was
initialized. (Rik proposed a better one for this)
2. introduces "maxsameipsource" policy attribute with numeric value,
which allows to set max connection limit on a per network range basis.
(Old global parameter is always checked first.)
3. improves policy debugging code to the point where it is acually
useful for non-Boolean attributes.
There is one thing that I did not figure how to do right: I'd like to
drop connection after issueing 4xx code, but I don't. This leads to
problems when the remote tries to reuse the connection. Maybe Matti
could into this please?
Index: include/policy.h
===================================================================
RCS file: /cvsroot/zmailer/include/policy.h,v
retrieving revision 1.12
diff -u -r1.12 policy.h
--- include/policy.h 2003/05/02 21:55:00 1.12
+++ include/policy.h 2003/07/11 14:01:07
@@ -89,9 +89,10 @@
#define P_A_TestRcptDnsRBL 23
#define P_A_WarnRcptDnsRBL 24
#define P_A_Filtering 25
+#define P_A_MaxSameIpSource 26
#define P_A_FirstAttr 2
-#define P_A_LastAttr 25
+#define P_A_LastAttr 26
/* Note: Attribute codes outside range 1..31 cause problems at policystate
processing! If you ever need modify these, fix the policytest.c,
and policytest.h: struct policystate { char values[]; } array,
@@ -142,7 +143,8 @@
"rcpt-dns-rbl",
"test-rcpt-dns-rbl",
"warn-rcpt-dns-rbl",
- "filtering"
+ "filtering",
+ "maxsameipsource"
};
#define KA(x) ((((x)>0)&&((x)<=P_A_LastAttr))?_KA[(x) & 0xFF]:"??")
Index: smtpserver/readpolicy.c
===================================================================
RCS file: /cvsroot/zmailer/smtpserver/readpolicy.c,v
retrieving revision 1.11
diff -u -r1.11 readpolicy.c
--- smtpserver/readpolicy.c 2003/05/02 21:55:00 1.11
+++ smtpserver/readpolicy.c 2003/07/11 14:01:07
@@ -180,6 +180,7 @@
{ "trust-whoson", P_A_TrustWhosOn },
#endif
{ "filtering", P_A_Filtering },
+ { "maxsameipsource", P_A_MaxSameIpSource },
{ NULL, 0 },
};
Index: smtpserver/policytest.c
===================================================================
RCS file: /cvsroot/zmailer/smtpserver/policytest.c,v
retrieving revision 1.75
diff -u -r1.75 policytest.c
--- smtpserver/policytest.c 2003/06/19 00:01:09 1.75
+++ smtpserver/policytest.c 2003/07/11 14:01:07
@@ -130,17 +130,25 @@
return (strcmp(value,str) == 0);
}
-static char *showresults __((char *values[]));
-static char *showresults(values)
-char *values[];
+static char *showresults __((struct policystate *state));
+static char *showresults(state)
+struct policystate *state;
{
static char buf[2000];
int i;
+ char **values=state->values;
buf[0] = '\0';
for (i = P_A_FirstAttr; i <= P_A_LastAttr; ++i) {
sprintf(buf+strlen(buf),"%s ",KA(i));
- sprintf(buf+strlen(buf),"%s ",values[i] ? values[i] : ".");
+ if (i == P_A_InboundSizeLimit )
+ sprintf(buf+strlen(buf),"%li ",state->maxinsize);
+ else if (i == P_A_OutboundSizeLimit )
+ sprintf(buf+strlen(buf),"%li ",state->maxoutsize);
+ else if (i == P_A_MaxSameIpSource )
+ sprintf(buf+strlen(buf),"%li ",state->maxsameiplimit);
+ else
+ sprintf(buf+strlen(buf),"%s ",values[i] ? values[i] : ".");
}
return buf;
}
@@ -167,6 +175,10 @@
(state->origrequest & (1<<i)) ? "" : "not ",
state->values[i]?state->values[i]:".");
}
+
+ type(NULL,0,NULL," maxinsize=%li", state->maxinsize);
+ type(NULL,0,NULL," maxoutsize=%li", state->maxoutsize);
+ type(NULL,0,NULL," maxsameiplimit=%li", state->maxsameiplimit);
}
static void mask_ip_bits __((unsigned char *, int, int));
@@ -455,6 +467,11 @@
sscanf(str+2,"%li", &state->maxoutsize);
goto nextattr;
+ } else if (str[1] == P_A_MaxSameIpSource) {
+
+ sscanf(str+2,"%li", &state->maxsameiplimit);
+ goto nextattr;
+
} else if ((str[2] != '+' && str[2] != '-') &&
!state->values[str[1] & 0xFF]) {
@@ -530,7 +547,7 @@
type(NULL,0,NULL," checkaddr(): domain of '%s'",pbuf+2);
result = resolveattributes(rel, maxrecursions, state, pbuf, 1);
if (debug) {
- type(NULL,0,NULL," Results: %s", showresults(state->values));
+ type(NULL,0,NULL," Results: %s", showresults(state));
}
return (result);
}
@@ -539,7 +556,7 @@
type(NULL,0,NULL," checkaddr(): user of '%s'",pbuf+2);
result = resolveattributes(rel, maxrecursions, state, pbuf, 1);
if (debug) {
- type(NULL,0,NULL," Results: %s", showresults(state->values));
+ type(NULL,0,NULL," Results: %s", showresults(state));
}
return (result);
} else if (pbuf[1] == P_K_IPv4)
@@ -588,7 +605,7 @@
return -1;
} else
if (debug) {
- type(NULL,0,NULL," %s", showresults(state->values));
+ type(NULL,0,NULL," Results: %s", showresults(state));
}
return 0;
}
@@ -748,6 +765,7 @@
#ifdef HAVE_WHOSON_H
state->whoson_result = whosonrc;
#endif
+ state->maxsameiplimit = -1;
return 0;
}
@@ -799,7 +817,8 @@
1 << P_A_FullTrustNet |
1 << P_A_TrustRecipients |
1 << P_A_TrustWhosOn |
- 1 << P_A_Filtering );
+ 1 << P_A_Filtering |
+ 1 << P_A_MaxSameIpSource );
if (!myaddress)
state->request |= ( 1 << P_A_TestDnsRBL |
1 << P_A_RcptDnsRBL );
@@ -833,7 +852,7 @@
}
if (debug)
- type(NULL,0,NULL," %s", showresults(state->values));
+ type(NULL,0,NULL," Results: %s", showresults(state));
return 0;
}
@@ -1336,7 +1355,7 @@
1 << P_A_FREEZENET |
1 << P_A_RELAYCUSTNET |
1 << P_A_InboundSizeLimit |
- 1 << P_A_OutboundSizeLimit );
+ 1 << P_A_OutboundSizeLimit );
state->request |= ( 1 << P_A_RcptDnsRBL ); /* bag */
check_domain(rel, state, str, len);
@@ -1830,4 +1849,12 @@
struct policystate *state;
{
return state->maxinsize;
+}
+
+long
+policysameiplimit(rel, state)
+struct policytest *rel;
+struct policystate *state;
+{
+ return state->maxsameiplimit;
}
Index: smtpserver/policytest.h
===================================================================
RCS file: /cvsroot/zmailer/smtpserver/policytest.h,v
retrieving revision 1.20
diff -u -r1.20 policytest.h
--- smtpserver/policytest.h 2003/05/05 09:29:38 1.20
+++ smtpserver/policytest.h 2003/07/11 14:01:07
@@ -44,6 +44,7 @@
char *rblmsg;
long maxinsize;
long maxoutsize;
+ long maxsameiplimit;
int islocaldomain;
#ifdef HAVE_WHOSON_H
int whoson_result;
@@ -118,6 +119,7 @@
extern int policytestaddr __((struct policytest * rel, struct policystate * ps, PolicyTest how, Usockaddr * raddr));
extern char *policymsg __((struct policytest *rel, struct policystate *ps));
extern long policyinsizelimit __((struct policytest *rel, struct policystate *ps));
+extern long policysameiplimit __((struct policytest *rel, struct policystate *ps));
extern struct policytest *policydb;
Index: smtpserver/smtpserver.c
===================================================================
RCS file: /cvsroot/zmailer/smtpserver/smtpserver.c,v
retrieving revision 1.147
diff -u -r1.147 smtpserver.c
--- smtpserver/smtpserver.c 2003/06/09 13:18:22 1.147
+++ smtpserver/smtpserver.c 2003/07/11 14:01:07
@@ -1225,6 +1225,7 @@
sameipcount = childsameip(&SS.raddr, &childcnt);
+ SS.sameipcount = sameipcount;
/* We query, and warn the remote when
the count exceeds the limit, and we
simply -- and FAST -- reject the
@@ -1357,6 +1358,13 @@
pid = getpid();
openlogfp(&SS, daemon_flg);
+
+ /* Actually all modes use this write-out buffer */
+ /* needs to go before any type()'s = [crosser] */
+ SS.sslwrbuf = emalloc(8192);
+ SS.sslwrspace = 8192;
+ SS.sslwrin = SS.sslwrout = 0;
+
#ifdef HAVE_WHOSON_H
type(NULL,0,NULL,
"connection from %s ipcnt %d childs %d ident: %s whoson: %s",
@@ -1387,7 +1395,7 @@
exit(0); /* Now exit.. */
}
if (sameipcount > MaxSameIpSource && sameipcount > 1) {
- type(&SS, -450, NULL, "Too many simultaneous connections from same IP address (%d max %d)\r\n", sameipcount, MaxSameIpSource);
+ type(&SS, -450, NULL, "Too many simultaneous connections from same IP address (%d max %d)", sameipcount, MaxSameIpSource);
type(&SS, 450, NULL, "Come again later");
typeflush(&SS);
MIBMtaEntry->ss.MaxSameIpSourceCloses ++;
@@ -1948,12 +1956,14 @@
int policystatus;
struct hostent *hostent;
int localport;
+ long maxsameip;
#ifdef USE_TRANSLATION
char lang[4];
lang[0] = '\0';
#endif
+
SS->VerboseCommand = 0;
SS->tarpit = tarpit_initial;
@@ -2082,11 +2092,6 @@
}
}
- /* Actually all modes use this write-out buffer */
- SS->sslwrbuf = emalloc(8192);
- SS->sslwrspace = 8192;
- SS->sslwrin = SS->sslwrout = 0;
-
#ifdef HAVE_OPENSSL
if (ssmtp_connected) {
if (tls_start_servertls(SS)) {
@@ -2112,6 +2117,8 @@
POLICY_SOURCEADDR,
(void *) &SS->raddr);
SS->reject_net = (SS->policyresult < 0);
+ maxsameip = policysameiplimit(policydb, &SS->policystate);
+ if (maxsameip == 0) SS->reject_net = 1; /* count=0 equivalent to reject */
if (debug) typeflush(SS);
if (SS->policyresult == 0) /* Alternates to this condition are:
Always reject, or Always freeze.. */
@@ -2149,6 +2156,12 @@
}
type(SS, -550, NULL, "If you feel we mistreat you, do contact us.");
type(SS, 550, NULL, "Ask HELP for our contact information.");
+ } else if ((maxsameip >= 0) && (SS->sameipcount > maxsameip)) {
+ smtp_tarpit(SS);
+ type(SS, -450, NULL, "%s - Too many simultaneous connections from this IP address (%li of %li)",
+ SS->myhostname, SS->sameipcount, maxsameip);
+ type(SS, 450, NULL, "Come again later");
+ MIBMtaEntry->ss.MaxSameIpSourceCloses ++;
} else
#ifdef USE_TRANSLATION
if (hdr220lines[0] == NULL) {
Index: smtpserver/smtpserver.h
===================================================================
RCS file: /cvsroot/zmailer/smtpserver/smtpserver.h,v
retrieving revision 1.81
diff -u -r1.81 smtpserver.h
--- smtpserver/smtpserver.h 2003/06/09 14:08:46 1.81
+++ smtpserver/smtpserver.h 2003/07/11 14:01:07
@@ -326,6 +326,7 @@
#endif
int unknown_cmd_count;
+ long sameipcount;
#ifdef HAVE_SASL2
char *volatile auth_type;
-
To unsubscribe from this list: send the line "unsubscribe zmailer" in
the body of a message to majordomo@nic.funet.fi