In case it might be of interest, here's the code we're using
for caching the results of md_check_against_smtp_sender.


[...in filter_initialize...]
# location of cache files for md_check_against_smtp_server results lookups
$cachedir="/var/spool/MIMEDefang/smtpcheck";

    if (! -d "$cachedir") {
        mkdir "$cachedir", 0775;
    }
[...]



# strip an email address down to the bare minimum, no optional text
# parts and no <>
sub address_strip ($) {
        my ($a) = @_;
        $a = "" if (!defined($a));
        $a =~ s/^[<\[]//;
        $a =~ s/[>\]]$//;
        return ($a);
}

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# %PROCEDURE: writedb
# %ARGUMENTS: (database filename), (keystring), (value)
# %RETURNS: 0 if database write failed, 1 if success
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sub writedb($$$) {
    my ($dbfile, $key, $val) = @_;
    my ($db); 
    if (tie (%db, "DB_File", $dbfile, O_RDWR|O_CREAT, 0775, $DB_HASH)) {
        # insert new val
        $db{$key} = "$val";
        untie %db;
        return 1;
    } else {
        md_syslog('warning', "Couldn't tie/write DB \'$dbfile\': $!");
        return 0;
    }
}

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# %PROCEDURE: cache_write
# %ARGUMENTS: username, server, code
# %RETURNS: 0 if database write failed, 1 if success
# %DESCRIPTION: Basically a wrapper for writedb. (We use writedb
#  elsewhere, that's why. :-)
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sub cache_write ($$$) {
    my ($luser, $server, $code)[EMAIL PROTECTED];
    my $dbfile="$cachedir/$server.cache.db";
    my $tstamp=rfc2822_date;
    md_syslog('debug', "cache_write: adding $luser:$code to cache for $server with 
stamp $tstamp");
    return writedb($dbfile, $luser, "$code|$tstamp");
}

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# %PROCEDURE: cache_check
# %ARGUMENTS: username, servername (fqdn)
# %RETURNS: CONTINUE if [EMAIL PROTECTED] is cached known good
#           REJECT if [EMAIL PROTECTED] is cached known bad
#           TEMPFAIL if [EMAIL PROTECTED] is not cached
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sub cache_check ($$) {
    my ($luser, $server)[EMAIL PROTECTED];
    my $dbfile="$cachedir/$server.cache.db";
    return 'TEMPFAIL' unless (my $h = &opendb_read($dbfile));
    my $rval = $h->{$luser};
    closedb($dbfile);
    return 'TEMPFAIL' unless $rval;
    my ($test, $tstamp) = split (/\|/, $rval, 2);
    if ($test =~ /REJECT/) {
        # previous lookup returned negative result
        md_syslog('debug', "cache_check: lookup succeeded: REJECT $luser on $server, 
record dated $tstamp");
        return 'REJECT';
    } else {
        # valid users we've already seen and added to the local cache
        md_syslog('debug', "cache_check: lookup succeeded: ACCEPT $luser on $server, 
record dated $tstamp");
        return 'CONTINUE';
    }
}

[ and then, in filter_recipient...]
    my $relay="";
    my ($code, $msg, $smtp_code, $smtp_dsn, $delay) = ('CONTINUE', 'ok', '250', 
'2.1.5', '0');
    my $lusername="";
    my $testsender="[EMAIL PROTECTED]";
    my ($recipient, $sender, $ip, $hostname, $first, $helo, $rcpt_mailer, $rcpt_host, 
$rcpt_addr) = @_;
    my $cacheadd=0;

    # normalize $recipient into local username part and hostname part
    my $rcpt = address_strip($recipient);
    if ($rcpt =~ /^(.+)\@([\w_.]+)$/) {
        $lusername = $1;
        $relay = $2;
        # is this a host we know to accept mail for?
        if ($relay =~ /$Cw_hosts/i ) { 
            # find actual relay
            my $end_server = relayget($relay);
            # if relay is not localhost, then check deliverability on the end-server
            if ($end_server) {
                # first check local cache
                if (($code = cache_check($lusername, $end_server)) =~ /TEMPFAIL/) { 
                    # means recipient is not in local cache
                    ($code, $msg) = md_check_against_smtp_server($testsender, 
$recipient, $helo, $end_server);
                    $cacheadd=1;
                }
                if ($code =~ /TEMPFAIL/) { 
                    md_syslog('warning', "rcpt check on $lusername against $end_server 
FAILED: \'$code\', \'$msg\'"); 
                    ($code, $msg, $smtp_code, $smtp_dsn, $delay) = ('TEMPFAIL', 
"Unable to verify LUser", "451", "4.3.0", $delay);
                } else { 
                    $cacheadd && cache_write($lusername, $end_server, $code);
                    if ($code =~/CONTINUE/) { # we got verification from the end-server
                        md_syslog('debug', "rcpt check on $lusername against 
$end_server succeeded:\'$code\', \'$msg\'");
                        ($code, $msg, $smtp_code, $smtp_dsn, $delay) = ('CONTINUE', 
"ok", "251", "2.1.5", $delay);
                    } else { # must be a bad user
                        md_syslog('info', "rcpt check on $lusername against 
$end_server rejected with \'$code\', \'$msg\'");
                        ($code, $msg, $smtp_code, $smtp_dsn, $delay) = ('REJECT', 
"$recipient... LUser unknown", "550", "5.1.1", $delay);
                    }
                }
            } else {
                # must be a valid alias for this host
                md_syslog('debug', "filter_recipient: no relay information found for 
$relay");
            }
        } else {
            md_syslog('debug', "\$relay \'$relay\' not in \$Cw_hosts");
            ($code, $msg, $smtp_code, $smtp_dsn, $delay) = ('REJECT', "$relay: cannot 
relay", "550", "5.1.1", $delay);
        }
    } else {
        md_syslog('warning', "bad RCPT value \'$rcpt\' from \'$recipient\'");
        ($code, $msg, $smtp_code, $smtp_dsn, $delay) = ('REJECT', "$rcpt: invalid", 
"550", "5.1.1", $delay);
    }
    return ("$code", "$msg", "$smtp_code", "$smtp_dsn", $delay);
}



        Cheers,
                Ole
-- 
Ole Craig * UNIX, linux, SMTP-fu; news, web; SGI martyr * CS Computing
Facility, UMass * <www.cs.umass.edu/~olc/pgppubkey.txt> for public key

   Need a seasoned *NIX admin in the Denver/Boulder area? Hire me!
_______________________________________________
Visit http://www.mimedefang.org and http://www.canit.ca
MIMEDefang mailing list
[EMAIL PROTECTED]
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang

Reply via email to