RE: [Exim] SQL POP before SMTP method?

Top Page
Delete this message
Reply to this message
Author: Jeffrey Wheat
Date:  
To: Sheldon Hearn, Eric Renfro
CC: exim-users
Subject: RE: [Exim] SQL POP before SMTP method?
I have a different solution that I use. I simply added a small
chunk of code to courier-imap that inserts the IP address into
the mysql database table that I use for exim. Exim reads this
and allows relaying as such. I have a perl script that runs
every 5 minutes that expires addresses older than 30 minutes.
If anyone is interested in this I will share the code.

Jeffrey

> -----Original Message-----
> From: Sheldon Hearn [mailto:sheldonh@starjuice.net]
> Sent: Thursday, October 24, 2002 4:28 PM
> To: Eric Renfro
> Cc: exim-users@???
> Subject: Re: [Exim] SQL POP before SMTP method?
>
>
> --
> On (2002/10/24 12:03), Eric Renfro wrote:
>
> > Here's an added feature I would like to add to my exim setup.
> >
> > I would like to make an SQL-based POP before SMTP method, allowing
> > users who can't SMTP AUTH by other normal means, to be able
> to login
> > through POP before sending email out to anywhere.
> >
> > I haven't a clue how to start this idea, but I'm guessing
> it's somehow
> > ACL-based in exim4?
>
> Here's what I do:
>
> 1) First you create your popb4smtp database.  I use
> PostgreSQL, which is
>    overkill for something like this; MySQL would suffice, but I had
>    trouble with MySQL on SMP FreeBSD boxes about a year ago.
> The schema
>    I use is attached (schema.sql).

>
> 2) I watchdog the POP3 logs for authentication information and slap it
>    into the popb4smtp database.  My script popb4smtp-watch is
> attached.

>
>    Beware; I suspect the File::Tail module has trouble with log files
>    larger than about 40MB.  Make sure you rotate your logs regularly.

>
> 3) Just so the database doesn't grow indefinitely, I clean out values
>    from time to time with my script popb4smtp-clean
> (attached).  You can
>    decide for yourself how frequently you want to run it.

>
> 4) You can start these two scripts with something like my popb4smtp.sh
>    script, attached.

>
> 5) Now you just need to configure Exim to allow relaying from recently
>    authenticated POP3 client hosts.  Sending you my entire configure
>    file would be noisy, so the bits you're interested in are:

>
> # In the main section:
> #
> PGSQL_POPB4 = select ip from popb4smtp where
> ip='${sender_host_address}' hide pgsql_servers =
> localhost/popb4smtp/exim/XX_POPB4SMTP_RO_PASSWD_XX
>
> hostlist relay_hosts = 127.0.0.1/32 : net-pgsql;PGSQL_POPB4
>
> acl_smtp_rcpt = check_recipient
>
> # In the acl section:
>
> check_recipient:
>   [...]
>   accept    hosts    = +relay_hosts
>   deny        message    = relay not permitted

>
> I do a lot of other funky stuff with the PGSQL_POPB4 lookup, e.g.
>
> tls_advertise_hosts = net-pgsql;PGSQL_POPB4
> host_lookup = !127.0.0.1/32 : !net-pgsql;PGSQL_POPB4
> rfc1413_hosts = !127.0.0.1/32 : !net-pgsql;PGSQL_POPB4
>
> But you get the idea. :-)
>
> HTH.
>
> Ciao,
> Sheldon.
> --
> #!/usr/bin/perl -w
>
> use strict;
> use Date::Parse;
> use DBI;
> use File::Tail;
> use POSIX qw(strftime);
>
> my $DBDSN = "DBI:Pg:dbname=popb4smtp;host=localhost";
> my $DBUSER = "popb4smtp";
> my $DBPASS = "XX_POPB4SMTP_RW_PASSWD_XX";
> my $POPLOG = '/var/log/popd.log';
> my $PROGNAME = 'popb4smtp-watch';
> my $PROGLOG = '/var/log/popb4smtp.log';
> my $PIDFILE = '/var/run/popb4smtp-watch.pid';
>
> my ($dbh, $rv);
> my $line;
> my $tail;
>
> open(PID, "> $PIDFILE") or
>     die "$PROGNAME: $PIDFILE: $!\n";
> print PID "$$\n";
> close(PID);

>
> $dbh = DBI->connect($DBDSN, $DBUSER, $DBPASS, {
>     RaiseError => 1,
>     AutoCommit => 1
>     });
> $tail = File::Tail->new(
>     name => $POPLOG,
>     maxinterval => 1,
>     interval => 1,
>     ignore_nonexistant => 1
>     );

>
> while ($line = $tail->read()) {
>     my ($ip, $timestr, $unixtime, $user);

>
>     if ($line =~ /^(\w+\s+\d+\s+\d+:\d+:\d+) .*
> popd\[\d+\]: Login user=(\w+) host=\[([^]]+)\]/) {
>         ($timestr, $user, $ip) = ($1, $2, $3);
>         $unixtime = str2time($timestr);
>         db_store_popauth($unixtime, $user, $ip);
>     }
> }

>
>
> sub db_store_popauth($$$)
> {
>     my ($unixtime, $user, $ip) = @_;
>     my $rv;

>
>     eval {
>         $rv = $dbh->do(qq{
>             UPDATE popb4smtp
>                SET timestamp = TIMESTAMP($unixtime),
>                    username = '$user'
>              WHERE ip = '$ip'
>             });
>         if ($rv != 1) {
>             die "no_such_row\n";
>         }
>     };
>     if ($@ eq "no_such_row\n") {
>         eval {
>             $dbh->do(qq{
>                 INSERT INTO popb4smtp
>                        (ip, username, timestamp)
>                 VALUES ('$ip', '$user',
> TIMESTAMP($unixtime))
>                 });
>             };
>         if ($@) {
>             logwarn("warning: INSERT failed: $@");
>         } else {
>             logwarn("debug: insert $ip for $user");
>         }
>     } elsif ($@) {
>         logwarn("warning: UPDATE failed: $@");
>     } else {
>         logwarn("debug: update $ip for $user");
>     }
> }

>
> sub logwarn(@)
> {
>     my (@msg) = @_;

>
>     unshift(@msg, strftime("%F %T", localtime()));
>     open(LOGFILE, ">> $PROGLOG") or
>         die "$PROGNAME: $PROGLOG: $!\n";
>     print LOGFILE join(' ', @msg), "\n";
>     close(LOGFILE);
> }
> --
> #!/usr/bin/perl -w

>
> use strict;
> use DBI;
>
> my $DBDSN = "DBI:Pg:dbname=popb4smtp;host=localhost";
> my $DBUSER = "popb4smtp";
> my $DBPASS = "XX_POPB4SMTP_RW_PASSWD_XX";
> my $PROGNAME = 'popb4smtp-clean';
> my $PIDFILE = '/var/run/popb4smtp-clean.pid';
> my $KEEPSECS = 60 * 60 * 2;
> my $FLUSHFREQ = 60 * 5;
>
> my ($dbh, $rv);
>
> open(PID, "> $PIDFILE") or
>     die "$PROGNAME: $PIDFILE: $!\n";
> print PID "$$\n";
> close(PID);

>
> $dbh = DBI->connect($DBDSN, $DBUSER, $DBPASS, {
>     RaiseError => 1,
>     AutoCommit => 1
>     });

>
> while (1) {
>     eval {
>         $rv = $dbh->do(qq{
>             DELETE FROM popb4smtp
>              WHERE age(now(), timestamp) >
>                 interval('$KEEPSECS seconds')
>             });
>     };
>     if ($@) {
>         warn "$PROGNAME: unexpected error while flushing: $@\n";
>     }
>     sleep($FLUSHFREQ);
> }
> --
> [ Content of type application/x-sh deleted ]
> --
> -- POP-before-SMTP database schema.
> --
> -- $Id: schema.sql,v 1.1 2002/08/21 12:58:47 sheldonh Exp $
> --
> -- Everything after this comment block is created with:
> --
> --      pg_dump -R -s massmail |grep -v -- -- > schema.sql
> --

>
> CREATE TABLE "popb4smtp" (
>     "ip" character varying(15) NOT NULL,
>     "hostname" character varying(80),
>     "username" character varying(32) NOT NULL,
>     "timestamp" timestamp with time zone NOT NULL,
>     Constraint "popb4smtp_pkey" Primary Key ("ip")
> );

>
>
> REVOKE ALL on "popb4smtp" from PUBLIC;
> GRANT ALL on "popb4smtp" to "root";
> GRANT ALL on "popb4smtp" to "popb4smtp";
> GRANT SELECT on "popb4smtp" to "exim";
>
> --
>
> --
>
> ## List details at
> http://www.exim.org/mailman/listinfo/exim-> users Exim details
> at http://www.exim.org/ ##
>
>
> ---
> Incoming
> mail is certified Virus Free.
> Checked by AVG anti-virus system (http://www.grisoft.com).
> Version: 6.0.404 / Virus Database: 228 - Release Date: 10/15/2002
>
>


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.408 / Virus Database: 230 - Release Date: 10/24/2002