Skip to content

Instantly share code, notes, and snippets.

@mmriis
Created November 30, 2011 11:31
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save mmriis/1408764 to your computer and use it in GitHub Desktop.
Save mmriis/1408764 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";
@wloong
Copy link

wloong commented May 17, 2013

hi

did you ngix compile with any thirty module ? Auth Digest ?

thanks for sharing

@ovizii
Copy link

ovizii commented Apr 18, 2017

Would you mind sharing the nginx.conf which calls this? I'm interested to see how the whole system looks like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment