Authenticate Against MySQL with Perl - Support cyrillic in password

#!/usr/bin/perl
# Mysql external auth script, supports cyrillic charsets in password
# Features: auth and isUser work, but setPass doesn't.
# Restrictions: Username or passwords may not contain some special characters: $'"` nor line breaks
# Security considerations:
#  - character filtering may not be perfect, but the most important '$"` are filtered out by this script
# 2005-1-24 Modified by Alejandro Grijalba (SuD) http://www.latinsud.com
# Based on check_pass_null.pl script
# 2009-5-21 Modified by Dmitri Vladimirov http://www.vladimirov.org
# Based on check_mysql.pl script

################# Replace values of these variables
my $dbUser="";          # The username to connect to mysql
my $dbPass="";          # The password to connect to mysql
my $dbName="";          # The name of the database inside mysql
my $dbTable="users";            # The name of the table inside the database
my $fieldUser="username";       # The name of the field that holds jabber user names
my $fieldPass="password";       # The name of the field that holds jabber passwords
#===================================================
use Unix::Syslog qw(:macros :subs);
use Switch;
use DBI;
use Text::Iconv;

my $conv_1251_utf = Text::Iconv->new("cp1251", "utf8");
my $conv_koi8_utf = Text::Iconv->new("koi8-r", "utf8");
while(1) {
    my $buf = "";
    syslog LOG_INFO,"waiting for packet";
    my $nread = sysread STDIN,$buf,2;
    do {
        syslog LOG_INFO,"port closed";
        exit;
    } unless $nread == 2;
    my $len = unpack "n",$buf;
    $nread = sysread STDIN,$buf,$len;
    syslog LOG_INFO, sprintf("got: %s", $buf);
    my ($op,$user,$domain,$password) = split /:/,$buf;

    # Filter dangerous characters
    $user =~ s/[."\n\r'\$`]//g;
    $password =~ s/[."\n\r'\$`]//g;

    my $pass1251 = $conv_1251_utf->convert($password);
    my $passkoi8 = $conv_koi8_utf->convert($password);

    my $result;
    my $dbh = DBI->connect("DBI:mysql:$dbName", $dbUser, $dbPass) || die "Could not connect to database: $DBI::errstr";
    switch ($op) {
        case "auth" {
            my $query="SELECT COUNT(*) FROM $dbTable WHERE $fieldUser='$user' AND ($fieldPass='$password' OR $fieldPass='$pass1251' OR $fieldPass='$passkoi8');";
            #syslog LOG_INFO, sprintf("query: %s", $query);
            my $sth = $dbh->prepare($query);
            $sth->execute();
            @result = $sth->fetchrow_array();
            syslog LOG_INFO, "$user auth result: $result[0]";
        }
        case "isuser" {
            my $query="SELECT COUNT(*) FROM $dbTable WHERE $fieldUser='$user';";
            #syslog LOG_INFO, sprintf("query: %s", $query);
            my $sth = $dbh->prepare($query);
            $sth->execute();
            @result = $sth->fetchrow_array();
            syslog LOG_INFO, "$user existence result: $result[0]";
        }
        case default {
            $result=0;
        }
    }
    my $out = pack("nn",2,$result[0] ? 1 : 0);
    syswrite STDOUT, $out;
    $dbh->disconnect();
  }
closelog;

Syndicate content