Ich würde gerne die Authentifizierung von ejabberd mit Hilfe der mysql-Datenbank von phpbb 3.08. bewerkstelligen.
Da mir leider die Kenntnisse der Programmierung fehlen, hoffe ich hier auf ein paar fähige Coder, für die das wahrscheinlich kein größeres Problem darstellen sollte.
Nach einigen Recherchen bin ich auf ein Skript gestoßen, das allerdings nur mit per Crypt verschlüsselten Passwörtern in Datenbanken zurecht kommt.
Somit sollte sich die Anpassungsarbeit in Grenzen halten.
Hinzugefügt habe ich bisher:
Code: Alles auswählen
use Digest::MD5 qw(md5 md5_hex md5_base64);
Code: Alles auswählen
bei 'auth' crypt durch md5 ersetzt.
Hier das vorläufige Skript:
Code: Alles auswählen
#!/usr/bin/perl
# Mysql external auth script
# Features: auth isUser and change password
# Password is an encrypted password !!
# Settings
my $sDatabaseHost='localhost'; # The hostname of the database server
my $sDatabaseUser="*********"; # The username to connect to mysql
my $sDatabasePass='*********'; # The password to connect to mysql
my $sDatabaseName="forum"; # The name of the database contain the user table
my $sUserTable="phpbb_users"; # The name of the table containing the username and password
my $sUsernameTableField="username"; # The name of the field that holds jabber user names
my $sPasswordTableField="user_password"; # The name of the field that holds jabber passwords
# Libs
use DBI;
use DBD::mysql;
use Digest::MD5 qw(md5 md5_hex md5_base64);
while(1) {
my $sBuffer = "";
my $readBuffer = sysread STDIN,$sBuffer,2;
my $iBufferLength = unpack "n",$sBuffer;
my $readBuffer = sysread STDIN,$sBuffer,$iBufferLength;
my ($sOperation,$sUsername,$sDomain,$sPassword) = split /:/,$sBuffer;
my $bResult;
SWITCH: {
$sOperation eq 'auth' and do {
$bResult = 0;
$connect = DBI->connect('DBI:mysql:'.$sDatabaseName, $sDatabaseUser, $sDatabasePass) || die "Could not connect to database: $DBI::errstr";
$query = "SELECT $sPasswordTableField FROM $sUserTable WHERE $sUsernameTableField='$sUsername';";
$statement = $connect->prepare($query);
$statement->execute();
while ($row = $statement->fetchrow_hashref()) {
$sCryptstring = md5($sPassword,$row->{$sPasswordTableField});
if ($row->{$sPasswordTableField} eq $sCryptstring) {
$bResult = 1;
}
}
},last SWITCH;
$sOperation eq 'setpass' and do {
$connect = DBI->connect('DBI:mysql:'.$sDatabaseName, $sDatabaseUser, $sDatabasePass) || die "Could not connect to database: $DBI::errstr";
$myquery = "UPDATE $sUserTable SET $sPasswordTableField=ENCRYPT('$sPassword') WHERE $sUsernameTableField='$sUsername';";
$statement = $connect->prepare($myquery);
$statement->execute();
$bResult = 1;
},last SWITCH;
$sOperation eq 'isuser' and do {
$bResult = 0;
$connect = DBI->connect('DBI:mysql:'.$sDatabaseName, $sDatabaseUser, $sDatabasePass) || die "Could not connect to database: $DBI::errstr";
$myquery = "SELECT count(*) AS iCount FROM $sUserTable WHERE $sUsernameTableField='$sUsername';";
$statement = $connect->prepare($myquery);
$statement->execute();
$row = $statement->fetchrow_hashref();
if($row->{'iCount'} >= 1){
$bResult = 1;
}
},last SWITCH;
};
my $sOutput = pack "nn",2,$bResult ? 1 : 0;
syswrite STDOUT,$sOutput;
}
closelog;
Wirklich wichtig ist nur ein funktionierende Authentifizierung.
Es gibt übrigens noch einige andere Personen die auch Interesse an diesem Skript hätten. Das ist mir beim suchen aufgefallen...
Und zu guter Letzt noch ein paar Infos für die Coder, damit sie nicht erst ewig suchen müssen
phpbb benutzt folgende Funktionen bei der Verschlüsselung (zu finden in /includes/functions.php):
Code: Alles auswählen
/**
*
* @version Version 0.1 / slightly modified for phpBB 3.0.x (using $H$ as hash type identifier)
*
* Portable PHP password hashing framework.
*
* Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
* the public domain.
*
* There's absolutely no warranty.
*
* The homepage URL for this framework is:
*
* http://www.openwall.com/phpass/
*
* Please be sure to update the Version line if you edit this file in any way.
* It is suggested that you leave the main version number intact, but indicate
* your project name (after the slash) and add your own revision information.
*
* Please do not change the "private" password hashing method implemented in
* here, thereby making your hashes incompatible. However, if you must, please
* change the hash type identifier (the "$P$") to something different.
*
* Obviously, since this code is in the public domain, the above are not
* requirements (there can be none), but merely suggestions.
*
*
* Hash the password
*/
function phpbb_hash($password)
{
$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$random_state = unique_id();
$random = '';
$count = 6;
if (($fh = @fopen('/dev/urandom', 'rb')))
{
$random = fread($fh, $count);
fclose($fh);
}
if (strlen($random) < $count)
{
$random = '';
for ($i = 0; $i < $count; $i += 16)
{
$random_state = md5(unique_id() . $random_state);
$random .= pack('H*', md5($random_state));
}
$random = substr($random, 0, $count);
}
$hash = _hash_crypt_private($password, _hash_gensalt_private($random, $itoa64), $itoa64);
if (strlen($hash) == 34)
{
return $hash;
}
return md5($password);
}
/**
* Check for correct password
*
* @param string $password The password in plain text
* @param string $hash The stored password hash
*
* @return bool Returns true if the password is correct, false if not.
*/
function phpbb_check_hash($password, $hash)
{
$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if (strlen($hash) == 34)
{
return (_hash_crypt_private($password, $hash, $itoa64) === $hash) ? true : false;
}
return (md5($password) === $hash) ? true : false;
}
/**
* Generate salt for hash generation
*/
function _hash_gensalt_private($input, &$itoa64, $iteration_count_log2 = 6)
{
if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
{
$iteration_count_log2 = 8;
}
$output = '$H$';
$output .= $itoa64[min($iteration_count_log2 + ((PHP_VERSION >= 5) ? 5 : 3), 30)];
$output .= _hash_encode64($input, 6, $itoa64);
return $output;
}
/**
* Encode hash
*/
function _hash_encode64($input, $count, &$itoa64)
{
$output = '';
$i = 0;
do
{
$value = ord($input[$i++]);
$output .= $itoa64[$value & 0x3f];
if ($i < $count)
{
$value |= ord($input[$i]) << 8;
}
$output .= $itoa64[($value >> 6) & 0x3f];
if ($i++ >= $count)
{
break;
}
if ($i < $count)
{
$value |= ord($input[$i]) << 16;
}
$output .= $itoa64[($value >> 12) & 0x3f];
if ($i++ >= $count)
{
break;
}
$output .= $itoa64[($value >> 18) & 0x3f];
}
while ($i < $count);
return $output;
}
/**
* The crypt function/replacement
*/
function _hash_crypt_private($password, $setting, &$itoa64)
{
$output = '*';
// Check for correct hash
if (substr($setting, 0, 3) != '$H$')
{
return $output;
}
$count_log2 = strpos($itoa64, $setting[3]);
if ($count_log2 < 7 || $count_log2 > 30)
{
return $output;
}
$count = 1 << $count_log2;
$salt = substr($setting, 4, 8);
if (strlen($salt) != 8)
{
return $output;
}
/**
* We're kind of forced to use MD5 here since it's the only
* cryptographic primitive available in all versions of PHP
* currently in use. To implement our own low-level crypto
* in PHP would result in much worse performance and
* consequently in lower iteration counts and hashes that are
* quicker to crack (by non-PHP code).
*/
if (PHP_VERSION >= 5)
{
$hash = md5($salt . $password, true);
do
{
$hash = md5($hash . $password, true);
}
while (--$count);
}
else
{
$hash = pack('H*', md5($salt . $password));
do
{
$hash = pack('H*', md5($hash . $password));
}
while (--$count);
}
$output = substr($setting, 0, 12);
$output .= _hash_encode64($hash, 16, $itoa64);
return $output;
}
Nette Grüße
Andreas