Skip to content

Instantly share code, notes, and snippets.

@frugan-dev
Forked from mmriis/auth.pl
Created October 31, 2016 13:44
Show Gist options
  • Save frugan-dev/ad31e55e84238fd85fdce8902a73692f to your computer and use it in GitHub Desktop.
Save frugan-dev/ad31e55e84238fd85fdce8902a73692f to your computer and use it in GitHub Desktop.

Revisions

  1. @mmriis mmriis created this gist Nov 30, 2011.
    83 changes: 83 additions & 0 deletions auth.pl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,83 @@
    #!/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";