The Arcive of Official vBulletin Modifications Site.It is not a VB3 engine, just a parsed copy! |
|
#1
|
|||
|
|||
phpbb3 to vb3.8 password importing
I'm hoping that someone can save me many more hours of banging my head against the wall. I've done a test impex of phpbb3 to vb3.8 and it has gone really well, except the age old problem of passwords importing. I know the official line is to just get everyone to reset their passwords, but that isn't an option for me as valid email addresses are not required at registration, so probably 75% of the email addresses on accounts are just pure nonsense meaning that password resets will not be possible.
I found lurking around on here some code to import the passwords into vb4 on first login by checking the plain text password against the phpbb database with the phpbb encoding and if it matches then to update the password in the vbulletin database, but i haven't been able to get it working with vb3.8, although i will admit i am very rusty these days. Basically what I need to do is really understand how the phpbb passwords are encoded then I can run a hopefully simple bit of code to encode the plain text password that way and then can do something along the lines of Code:
if($phpbbpw == $phpbbuserpw) { // update vb password using dm // replace vb_user.importid with 0 } else { // throw invalid login error } Code:
$getuserid = $vbulletin->db->query_first("SELECT importid FROM vb_user WHERE username = '" . $vbulletin->GPC['vb_login_username'] . "'"); $phpbbuserid = $getuserid['importuserid']; if ($phpbbuserid != '0') { $ptpassword = $vbulletin->GPC['vb_login_password']; // encode $ptpassword to phpbb standards $getphpbbpw = $vbulletin->db->query_first("SELECT user_password FROM phpbb_users WHERE user_id = '$phpbbuserid'"); $phpbbpw = $getphpbbpw['user_password']; $phpbbuserpw = encoded $ptpassword for phpbb check $phpbbuserpw against $phpbbpw for match etc } I know it isn't an ideal way of doing it, especially as I am just coding direct into login.php and not using any plugins of anything (old school here still unfortunately - plus no useful hooks anyway), but any pointers, or if anyone has been able to do this successfully before, then that would be awesome. I really don't want to have to renew a licence just to use the vb4 code i found, as that will only result in having a lot more work to do, and a whole new system to learn which tbh i cba doing when i know vb3 like the back of my hand and it does exactly what i want and need it to do. |
#2
|
|||
|
|||
I don't know anything about phpbb3, but googling for "phpbb3 password encryption" I found that there is a function in includes/functions.php (in the phpbb3 code) called phpbb_hash() that you can use to check the passwords. So you could probably grab that or at least refer to it.
Also, in vbulletin the password will normally be put through an md5 hash in the browser before it's sent, and the plain text password field will be cleared. But you can stop the plain text field being cleared by putting define('DISABLE_PASSWORD_CLEARING', 1); in your config.php. Just FYI, there is a 'login_verify_failure_password' hook that gets called when a password check failed (it's in includes/functions_login.php around line 149). I thought I'd mention it, but I don't think using hooks is all that important especially since vb3 isn't being updated any more. BTW, in the code you posted above, you have "SELECT importid" then you use $getuserid['importuserid']. I think you probably just included that code as an example, but I thought I'd mention it anyway. Anyway, I know you were probably looking for someone with more knowledge of converting phpbb3 passwords, but maybe some of this will help. |
#3
|
|||
|
|||
Cheers Kevin,
I'd forgot about the DISABLE_PASSWORD_CLEARING so thats one problem solved as I was puzzled as to why I couldn't get the $ptpassword to echo. I'll have another look at the phpbb/includes/functions.php and phpbb_hash() and see if I can see anything different in there. Yeah, I knew there was errors in my code sample, but that is just pure example code of what my vision is, but nothing has been written yet, other than grabbing the imported userid, and the phpbb password from the database. I'll be back in a bit, and let you know if I'm making any progress. I hadn't thought about looking in includes/functions_login.php for hooks either, so thats something I'll investigate further later. |
#4
|
|||
|
|||
ok, still having problems here, so open to a fresh set of eyes and maybe some more ideas.
My login.php file has had the following added to it Code:
// added for phpbb3 login $username = $vbulletin->GPC['vb_login_username']; $getimporteduserid = $vbulletin->db->query_first("SELECT importuserid FROM " . TABLE_PREFIX . "user WHERE username = '" . $username . "' LIMIT 1;"); $checkforimportedpw = $vbulletin->db->query_first("SELECT user_password FROM phpbb_users WHERE user_id = '" . $getimporteduserid['importuserid'] . "' LIMIT 1;"); if ($getimporteduserid['importuserid'] != '0') { echo ($vbulletin->GPC['vb_login_username']); echo("<br />phpbb password: "); echo ($checkforimportedpw['user_password']); //if ($checkforimportedpw == '') //{ // we need to divert to phpbb login by checking pw against the phpbb data and inserting this into the vbulletin record on successfull verification // add some phpbb code to do let us check the password include('./phpBB3Auth/controller.php'); echo("<br />"); echo ("Checking for imported PW"); echo ("<br />"); // echo ($vbulletin->GPC['vb_login_password']); echo("<br />"); $ptpassword = $vbulletin->GPC['vb_login_password']; $phpBB3id = $getimporteduserid['importuserid']; // echo($vbulletin->GPC['vb_login_md5password']); } /* } else { // we can use vbulletin's login, so ignore all the above code! } */ // end added code Code:
// can the user login? $strikes = verify_strike_status($vbulletin->GPC['vb_login_username']); if ($vbulletin->GPC['vb_login_username'] == '') { eval(standard_error(fetch_error('badlogin', $vbulletin->options['bburl'], $vbulletin->session->vars['sessionurl'], $strikes))); } phpBB3Auth/controller.php with the contents Code:
<?php // // main php file for vBulletin authentication against old phpBB3 database // (c) Hay Bouten - 2010 // (c) kerry schwab - 2010 // error_reporting(E_ALL & ~E_NOTICE); define('THIS_SCRIPT', 'controller.php'); // some basic requirements require_once('./global.php'); require_once(DIR . '/includes/functions_login.php'); //require_once(DIR . '/phpBB3Auth/phpBB3config.inc.php'); // 13-06-2010 Hay Mod - Add some phpBB3 functions library require_once(DIR . '/phpBB3Auth/phpBB3_functions.php'); global $vbulletin; // // if login form is admin or moderator login, don't use phpBB3 authentication // if(($vbulletin->GPC['logintype'] == "cplogin") || ($vbulletin->GPC['logintype'] == "modcplogin")) { return; } // // get the username and password they typed into the form // $username=$vbulletin->GPC['vb_login_username']; $password=$vbulletin->GPC['vb_login_password']; $phpBB3DbPrefix = 'phpbb_'; // // if there is no password submitted, return to vBulletin's auth // if ($password == '') { return; } // // General flow: // 1. We check if there's an 'importid' attribute for the username. // 2. If there's not one, we return control to vBulletin to log them in. // 3. If there is one, then we: // a. auth against the old IPB database // b. if the auth worked, we sync their password, then // remove the 'importid' attribute from their vB user profile. // That means next time, they skip all of this via #1 and #2. // c. if the auth fails, we just return control to vBulletin // so that they can try again. // // create a user DM object // fetch the userinfo for the username they typed in // and load it into the user DM object $userdata =& datamanager_init('User', $vbulletin, ERRTYPE_ARRAY); $userid=fetch_userid_from_username($username); if (!$userid) { // can't find this username in the vB user database return; } $userinfo=fetch_userinfo($userid); $userdata->set_existing($userinfo); // grab the old phpBB3id from the vB user table // the vB 'impex' import utility created that field when // converting from phpBB3 $phpBB3id=$userinfo['importuserid']; echo("<br />phpBB3id = " . $phpBB3id . "<br />"); // function phpBB3_auth($phpBB3id,$ptpassword) { /* require(DIR . '/phpBB3Auth/phpBB3config.inc.php'); // $ptpassword is the plain text password they typed in $conn = mysql_connect($phpBB3DbHost,$phpBB3DbUser,$phpBB3DbPass); if (!$conn) { die("Unable to connect to DB: " . mysql_error()); } if (!mysql_select_db($phpBB3DbName)) { die("Unable to select db $phpBB3DbName: " . mysql_error()); } */ $sql = sprintf("SELECT user_password, PWD_Synced FROM %susers WHERE user_id = '%s'", $phpBB3DbPrefix,mysql_real_escape_string($phpBB3id)); $result = mysql_query($sql); if (!$result) { return FALSE; } $rows=mysql_num_rows($result); if ($rows != 1) { // they either aren't in the old phpBB3 database, or they // are in there more than once. Either way, return FALSE echo("No phpbb record. <br />"); return FALSE; } $user = mysql_fetch_assoc($result); mysql_free_result($result); // // See if the password was synced before. // $pwd_synced=$user['PWD_Synced']; if ($pwd_synced==1) { return FALSE; } // // now we use phpbb_check_hash() on the plaintext password that the user typed in, // and compare it to the password hash in the phpBB3 database // $storedpw=$user['user_password']; if (phpbb_check_hash($ptpassword,$storedpw)) { // they gave the right password ! echo("Password Correct! <br />"); return TRUE; } else { echo("Password incorrect. <br />"); return FALSE; } } // try to auth the password they typed in against the // old phpBB3 user table // if(phpBB3_auth($phpBB3id,$password)) { // the password they typed in matches the one in the old // phpBB3 table, so set their vB password to the one they typed in $userdata->set('password',$password); $userdata->pre_save(); if (!empty($userdata->errors)) { // something went wrong...bail out back to vB's authentication foreach ($userdata->errors as $error ) { echo($error); echo("<br />"); // you could log these errors here if you had trouble } return; } else { $userdata->save(); // this changes the password in the old phpBB3 table to // 'SYNCED' so we don't bother syncing it again // uncomment to fix this later mark_phpBB3_synced($phpBB3id); } // return control to vB's auth, which will be able to log // them in now that the old phpBB3 password is synced to vB return; } else { // the password they typed in didn't match what was in the // old phpBB3 table, so just pass them up to vB to be authed // there echo("Password did not match phpbb table. <br />"); return; } // // // function mark_phpBB3_synced($phpBB3id) { /* require(DIR . '/phpBB3Auth/phpBB3config.inc.php'); $conn = mysql_connect($phpBB3DbHost,$phpBB3DbUser,$phpBB3DbPass); if (!$conn) { die("Unable to connect to DB: " . mysql_error()); } if (!mysql_select_db($phpBB3DbName)) { die("Unable to select db $phpBB3DbName: " . mysql_error()); } */ $sql = sprintf("UPDATE %susers SET PWD_Synced ='1' WHERE user_id='%s' ", $phpBB3DbPrefix, $phpBB3id); $result = mysql_query($sql); } // // fetch_userid_from_username. function borrowed // from some admincp code in vBulletin // function fetch_userid_from_username($username) { global $vbulletin; if ($user = $vbulletin->db->query_first("SELECT userid FROM " . TABLE_PREFIX . "user WHERE username = '" . $vbulletin->db->escape_string(trim($username)) . "'")) { return $user['userid']; } else { return false; } } ?> Code:
<?php /** * Some copied phpBB3 functions to get the password check done. * */ /** * 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; } /** * 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; } ?> When attempting to log in with an imported user, the following is output from the echos Attachment 141976 with the following normal error message Attachment 141977 For some reason, despite lots of echos in the code to try and get more info as to what is happening and why it is failing, I'm not getting anywhere quick and just banging my head against the nearest wall (which the computer is also being threatened to be launched at!). It is probably something fairly simple, but it is starting to do my head in, and I can't give up as otherwise I am doomed to be stuck with phpbb3 forever as password resets are not an option as I explained in the first post. I am open to any more pointers, suggestions, glaringly obvious errors being corrected, or otherwise. Just for info too, this is a 3.8.3 site (installed wrong version, but anything that works on 3.8.3 should work on 3.8.7 too). vB4 is not an option (expired licenses) at this time, and renewing to upgrade will only happen if the issues are solved and the users are also happy, otherwise it is an expense that cannot be warranted. I think I might have access to 4.1 but not 100% sure, plus the fact that my vb4 access, is for forum only and blogs are being considered for the site which requires 3.8.x oh, and obviously DISABLE_PASSWORD_CLEARING has been set in config.php too as otherwise it has no chance of working. |
#5
|
|||
|
|||
Update @ 14:55 GMT
I think I might have almost cracked it. Found a couple of missing functions by trial and error so added those in and it is now saying correctly that the passwords match or don't. Now I just need it to update the vb password and actually log in which it isn't doing so far. Fingers crossed I will have it working soon. Will report back again in a bit. Suggestions still greatfully accepted though --------------- Added [DATE]1351173610[/DATE] at [TIME]1351173610[/TIME] --------------- The php versions are the same, although it is on my test server not the live one. I checked that before I started for php and mysql versions in case I would hit any difficulties there. |
#6
|
|||
|
|||
OK. I deleted that post because after reading what you added above, obviuously that wasn't the issue. I just thought of that because there's an if on php version that seems to use a different password encryption for version 4.
|
#7
|
|||
|
|||
It's alive!!!!
I how have quite happily the banned message, which I expected as the permissions for the imported users have not yet been set. I'll get it all packaged up nicely and release it later too. It certainly isn't pretty code, but it works, and that is the most important thing The problem was the order of some of the checks taking place. When I moved some things around it started telling me that the entered password was correct or incorrect, so it was then just a case of getting the DM updating done in that place, so now it successfully logs in when the password is correct with the phpbb table and updates the vb password too so the vb login will then be used from that point by checking if the password updating has already taken place or not. |
|
|
X vBulletin 3.8.12 by vBS Debug Information | |
---|---|
|
|
More Information | |
Template Usage:
Phrase Groups Available:
|
Included Files:
Hooks Called:
|