#!/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)
# Based on check_pass_null.pl script
# 2009-5-21 Modified by Dmitri Vladimirov
# 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;