Skip to content

Instantly share code, notes, and snippets.

@mabe-at
Forked from mmriis/auth.pl
Created January 18, 2018 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mabe-at/90987ee3a264923901f5dbf1df5d110a to your computer and use it in GitHub Desktop.
Save mabe-at/90987ee3a264923901f5dbf1df5d110a to your computer and use it in GitHub Desktop.
IMAP/POP3 proxy authentication script for nginx. See http://www.whatastruggle.com/nginx-as-an-imappop3-proxy-part-2.
#!/usr/bin/perl
use Digest::HMAC_MD5 qw/ hmac_md5_hex /;
use DBI;
use URI::Escape;
use CGI;
print "Content-type: text/html\n";
my $q = CGI->new;
my $auth_shared_secret = $q->http("X-NGX-Auth-Key");
# Shared secret to ensure that the request comes from nginx
if ( $auth_shared_secret ne "your secret" ) {
print "Auth-Status: Authentication failed.\n\n";
print STDERR "Wrong X-NGC-Auth-Key $auth_shared_secret";
exit(0);
}
my $dsn = "DBI:mysql:database=postfix;host=1.2.3.4";
our $dbh =
DBI->connect_cached( $dsn, 'mailproxy', 'p@ssw0rd',
{ AutoCommit => 1, mysql_auto_reconnect => 1 } );
our $auth_ok;
our $protocol_ports = {};
$protocol_ports->{'pop3'} = 110;
$protocol_ports->{'imap'} = 143;
$protocol_ports->{'smtp'} = 25;
if ( !defined $dbh || !$dbh->ping() ) {
( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
localtime(time);
$dbh =
DBI->connect_cached( $dsn, 'mailproxy', 'p@ssw0rd',
{ AutoCommit => 1, mysql_auto_reconnect => 1 } );
printf STDERR
"%4d/%02d/%02d %02d:%02d:%02d [notice] : MySQL server connection lost. Reconnecting.\n",
$year + 1900, $mon + 1, $mday, $hour, $min, $sec;
}
my $auth_method = $q->http("Auth-Method");
my $username = uri_unescape( $q->http("Auth-User") );
my $password = uri_unescape( $q->http("Auth-Pass") );
my $salt = $q->http("Auth-Salt");
our $sth = $dbh->prepare("select clear from users where email=? limit 1");
$sth->execute($username);
my $hash = $sth->fetchrow_hashref();
my $real_password = $hash->{'clear'};
# Authorize user
if (
( $auth_method eq "plain" && $password eq $real_password )
or ( $auth_method eq "cram-md5"
&& $password eq hmac_md5_hex( $salt, $real_password ) )
)
{
# Auth OK, find mail server
our $sth = $dbh->prepare(
"select destination_mailstore from transport where domain=? limit 1");
my $domain = $q->http("Auth-User");
# remove @ and everything before
$domain =~ s/^.*@//;
$sth->execute($domain);
my $hash = $sth->fetchrow_hashref();
my $mailserver = $hash->{'destination_mailstore'};
$mailserver =~ s/smtp://;
print "Auth-User: $username\n";
print "Auth-Pass: $real_password\n";
print "Auth-Status: OK\n";
print "Auth-Server: $mailserver\n";
$auth_port = $protocol_ports->{ $q->http("Auth-Protocol") };
print "Auth-Port: $auth_port\n";
}
else {
print "Auth-Status: Authentication failed.\n";
}
print "\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment