[Mimedefang] Sendmail Macros in check_relay()
Martin Blapp
mb at imp.ch
Mon Jul 9 08:40:47 EDT 2007
Hi,
It was a rather easy job :-)) Here is the patch, if anyone likes to use
it.
I think you could adapt the generic mimedefang structure to have access to
some generic values.
> It's relatively cheap, but given the architecture of MIMEDefang, it's
> very difficult to get macros before the MAIL FROM: callback. If you
> do try to hack it, please be prepared for a big job.
First some filter stuff:
#
# Get the trusted nets from SpamAssassin
#
if ($Features{"SpamAssassin"}) {
$trusted_nets = $SASpamTester->{conf}->{trusted_networks};
}
#
# Regex which detects dynamic relays
#
$dynhostsregex = "(?!^server|vhost|mail|mx|static)(?:dial|ppp|^[0-9]|^user|[^\.]dynamic|^OL[0-9]{2,3}-|^(?:j|cc|cm|cp)[0-9]{5,6}|^bgp[0-9]
{3}|-cuda[0-9]-|\.upc-[a-z]\.|\.zoog0[0-9]\.|\.gig0[09]\.|^p[09]{4}-|^la02-|^YahooBB|^c906|c911|^c[ocp][0-9]{3,5]|p[0-9]{4}-|vapoajzmm\.co
m|detainment\.net|shrubalthaea\.com|\.lmndr\.com|^pcp0|^sndr|^cs24|^dyna|dsl|hsd1|^pcp[0-9]|^usen-|line|catv|client|bredband|broadband|cli
ent|dip0|securepop|pool|^ip|^pl[0-9]{3}.|^pub|port-ip|^i3ED|^chello|\.catv|cpiak|^zaqdb|cable|cust|\.fix\.|\.ipt\.|\.dyn\.|[\.\-][0-9]{1,3
}[\.\-][0-9]{1,3})";
filter_relay () {
my ($ip, $name, $load) = @_;
#
# Don't make any tests for trusted networks if SA is available
#
if ($Features{"SpamAssassin"} && $trusted_nets->contains_ip($ip)) {
return ('CONTINUE', "ok");
}
#
# DNS check if load is too high. If the load is over
# limit, we tempfail all messages from dynamic relays.
# Same procedure if the reverse dns entry of the relay
# is missing.
#
# On the MX side, this must be defined in the config:
# define(`confMILTER_MACROS_CONNECT', confMILTER_MACROS_CONNECT`, {load_avg}')
#
# And you definitly need a local mimedefang patch. See below
#
if ($load > $maxload) {
my $dyndns;
$dyndns = &checkdyndns($ip, $name);
if ($dyndns) {
md_syslog('err', "filter_relay(): tempfail $name, load ($load) too high, max: ($maxload)");
return ('TEMPFAIL', "Please try again later.");
} else {
md_syslog('err', "filter_relay(): accept $name even if there is high load ($load)");
}
}
}
#
# Returns true if the host looks like a dynamic relay or is
# equal to the ip.
#
sub checkdyndns {
my ($ip, $name) = @_;
if ($name eq "" || $name eq $ip ||
$name =~ /$dynhostsregex/i) {
return 1;
}
return 0;
}
Here is the mimedefang patch:
--- mimedefang.c Fri Feb 9 17:29:25 2007
+++ mimedefang.c Mon Jul 9 11:15:18 2007
@@ -156,6 +156,7 @@
char *dir; /* Work directory */
char *heloArg; /* HELO argument */
char *qid; /* Queue ID */
+ int load_avg; /* Load Average */
int fd; /* File for message body */
int headerFD; /* File for message headers */
int cmdFD; /* File for commands */
@@ -536,6 +537,8 @@
}
data->hostip[64] = 0;
}
+ data->load_avg = 0;
+ data->load_avg = smfi_getsymval(ctx, "{load_avg}");
/* Is host IP equivalent to loopback? If so, replace with 127.0.0.1 */
/* (We have enough room because data->hostip can hold 64 chars + nul) */
@@ -555,7 +557,7 @@
if (doRelayCheck) {
char buf2[SMALLBUF];
int n = MXRelayOK(MultiplexorSocketName, buf2, data->hostip,
- data->hostname);
+ data->hostname, data->load_avg);
if (n == MD_REJECT) {
/* Can't call smfi_setreply from connect callback */
/* set_dsn(ctx, buf2, 5); */
--- mimedefang.h Fri Feb 2 21:37:06 2007
+++ mimedefang.h Mon Jul 9 11:16:02 2007
@@ -27,7 +27,7 @@
extern int MXScanDir(char const *sockname, char const *dir);
extern int MXCommand(char const *sockname, char const *cmd, char *buf, int len);
extern int MXRelayOK(char const *sockname, char *msg,
- char const *ip, char const *name);
+ char const *ip, char const *name, int load);
extern int MXHeloOK(char const *sockname, char *msg,
char const *helo, char const *ip, char const *name);
extern int MXSenderOK(char const *sockname, char *msg,
--- utils.c Mon Jul 9 12:02:56 2007
+++ utils.c Mon Jul 9 11:25:32 2007
@@ -566,7 +566,8 @@
MXRelayOK(char const *sockname,
char *msg,
char const *ip,
- char const *name)
+ char const *name,
+ int load)
{
char cmd[SMALLBUF];
char ans[SMALLBUF];
@@ -579,7 +580,7 @@
if (!name || !*name) {
name = ip;
}
- if (percent_encode_command(1, cmd, sizeof(cmd), "relayok", ip, name, NULL) < 0) {
+ if (percent_encode_command(1, cmd, sizeof(cmd), "relayok", ip, name, load, NULL) < 0) {
return MD_TEMPFAIL;
}
if (MXCommand(sockname, cmd, ans, SMALLBUF-1) < 0) return MD_TEMPFAIL;
--- mimedefang.pl.in.orig Mon Jul 9 12:10:16 2007
+++ mimedefang.pl.in Mon Jul 9 12:11:40 2007
@@ -5219,10 +5219,11 @@
next;
}
- if ($_ =~ /^relayok (\S*)\s+(\S*)/) {
+ if ($_ =~ /^relayok (\S*)\s+(\S*)\s*(\S*)/) {
$ip = percent_decode($1);
$name = percent_decode($2);
- relay_ok($ip, $name);
+ my $load = percent_decode($3);
+ relay_ok($ip, $name, $load);
chdir($Features{'Path:SPOOLDIR'});
next;
}
@@ -6569,11 +6570,12 @@
# %ARGUMENTS:
# hostip -- IP address of relay host
# hostname -- name of relay host
+# load average -- the 1 minute load average
# %RETURNS:
# Nothing, but prints "ok 1" if we accept connection, "ok 0" if not.
#***********************************************************************
-sub relay_ok ($$) {
- my($hostip, $hostname) = @_;
+sub relay_ok ($$$) {
+ my($hostip, $hostname, $systemload) = @_;
if (!defined(&filter_relay)) {
send_filter_answer('CONTINUE', "ok",
"filter_relay", "host $hostip ($hostname)");
@@ -6583,7 +6585,7 @@
# Set up globals
$RelayAddr = $hostip;
$RelayHostname = $hostname;
- my($ok, $msg, $code, $dsn, $delay) = filter_relay($hostip, $hostname);
+ my($ok, $msg, $code, $dsn, $delay) = filter_relay($hostip, $hostname, $systemload);
send_filter_answer($ok, $msg, "filter_relay", "host $hostip ($hostname)", $code, $dsn, $delay);
}
More information about the MIMEDefang
mailing list