<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!@PERL@
use strict;
use DBI;
use Getopt::Long;
use Pod::Usage;
use Digest::MD5 qw(md5 md5_hex md5_base64);
$|=1;

=pod

=head1 NAME

basic_db_auth - Database auth helper for Squid

=cut

my $dsn = "DBI:mysql:database=squid";
my $db_user = undef;
my $db_passwd = undef;
my $db_table = "passwd";
my $db_usercol = "user";
my $db_passwdcol = "password";
my $db_cond = "enabled = 1";
my $plaintext = 0;
my $md5 = 0;
my $persist = 0;
my $isjoomla = 0;
my $debug = 0;
my $hashsalt = undef;

=pod

=head1 SYNOPSIS

basic_db_auth [options]

=head1 DESCRIPTOIN

This program verifies username &amp; password to a database

=over 8

=item	B&lt;--dsn&gt;

Database DSN. Default "DBI:mysql:database=squid"

=item	B&lt;--user&gt;

Database User

=item	B&lt;--password&gt;

Database password

=item	B&lt;--table&gt;

Database table. Default "passwd".

=item	B&lt;--usercol&gt;

Username column. Default "user".

=item	B&lt;--passwdcol&gt;

Password column. Default "password".

=item	B&lt;--cond&gt;

Condition, defaults to enabled=1. Specify 1 or "" for no condition
If you use --joomla flag, this condition will be changed to block=0

=item	B&lt;--plaintext&gt;

Database contains plain-text passwords

=item   B&lt;--md5&gt;

Database contains unsalted md5 passwords

=item	B&lt;--salt&gt;

Selects the correct salt to evaluate passwords

=item	B&lt;--persist&gt;

Keep a persistent database connection open between queries. 

=item  B&lt;--joomla&gt;

Tells helper that user database is Joomla DB.  So their unusual salt 
hashing is understood.

=back

=cut

GetOptions(
	'dsn=s' =&gt; \$dsn,
	'user=s' =&gt; \$db_user,
	'password=s' =&gt; \$db_passwd,
	'table=s' =&gt; \$db_table,
	'usercol=s' =&gt; \$db_usercol,
	'passwdcol=s' =&gt; \$db_passwdcol,
	'cond=s' =&gt; \$db_cond,
	'plaintext' =&gt; \$plaintext,
	'md5' =&gt; \$md5,
	'persist' =&gt; \$persist,
	'joomla' =&gt; \$isjoomla,
	'debug' =&gt; \$debug,
	'salt=s' =&gt; \$hashsalt,
	);

my ($_dbh, $_sth);
$db_cond = "block = 0" if $isjoomla;

sub close_db()
{
    return if !defined($_dbh);
    undef $_sth;
    $_dbh-&gt;disconnect();
    undef $_dbh;
}

sub open_db()
{
    return $_sth if defined $_sth;
    $_dbh = DBI-&gt;connect($dsn, $db_user, $db_passwd);
    if (!defined $_dbh) {
    	warn ("Could not connect to $dsn\n");
	my @driver_names = DBI-&gt;available_drivers();
	my $msg = "DSN drivers apparently installed, available:\n";
	foreach my $dn (@driver_names) {
		$msg .= "\t$dn";
	}
	warn($msg."\n");
	return undef;
    }
    my $sql_query;
    $sql_query = "SELECT $db_passwdcol FROM $db_table WHERE $db_usercol = ?" . ($db_cond ne "" ? " AND $db_cond" : "");
    $_sth = $_dbh-&gt;prepare($sql_query) || die;
    return $_sth;
}

sub check_password($$)
{
    my ($password, $key) = @_;

    if ($isjoomla){
        my $salt;
        my $key2;
        ($key2,$salt) = split (/:/, $key);
        return 1 if md5_hex($password.$salt).':'.$salt eq $key;
    }
    else{
        return 1 if defined $hashsalt &amp;&amp; crypt($password, $hashsalt) eq $key;
        return 1 if crypt($password, $key) eq $key;
        return 1 if $md5 &amp;&amp; md5_hex($password) eq $key;
        return 1 if $plaintext &amp;&amp; $password eq $key;
    }

    return 0;
}

sub query_db($) {
    my ($user) = @_;
    my ($sth) = open_db() || return undef;
    if (!$sth-&gt;execute($user)) {
	close_db();
	open_db() || return undef;
	$sth-&gt;execute($user) || return undef;;
    }
    return $sth;
}
my $status;

while (&lt;&gt;) {
    my ($user, $password) = split;
    $status = "ERR";
    $user =~ s/%(..)/pack("H*", $1)/ge;
    $password =~ s/%(..)/pack("H*", $1)/ge;

    $status = "ERR database error";
    my $sth = query_db($user) || next;
    $status = "ERR unknown login";
    my $row = $sth-&gt;fetchrow_arrayref() || next;
    $status = "ERR login failure";
    next if (!check_password($password, @$row[0]));
    $status = "OK";
} continue {
    close_db() if (!$persist);
    print $status . "\n";
}

=pod

=head1 COPYRIGHT

Copyright (C) 2007 Henrik Nordstrom &lt;henrik@henriknordstrom.net&gt;
Copyright (C) 2010 Luis Daniel Lucio Quiroz &lt;dlucio@okay.com.mx&gt; (Joomla support)
This program is free software. You may redistribute copies of it under the
terms of the GNU General Public License version 2, or (at youropinion) any
later version.

=cut
</pre></body></html>