PDA

View Full Version : Some Help/Information with vB Integration Please


DarkScythe
07-20-2008, 09:10 PM
Hello,

A few weeks ago I decided to purchase a vB license for my forums. I plan to use it in conjunction with the ExpressionEngine CMS/Blog. This was after some careful consideration and lots of comparisons with competing software - I hope I made the right choice. My plan is to integrate the two programs just enough so that a user will only need to register once either on the forums, or at the CMS and have access to both. Previously, I had completed an integration that suited my needs between EE and phpBB2. However, as my luck would have it, the team decided to release phpBB3 release candidates soon after. Knowing that phpBB2 was then at the end of its line, I had to scrap that and move on. I tried to make sense of phpBB3's code, but had no luck.

Anyway, this leads me to vB. I'm looking at the code, but I'm a bit stumped at how to get access to the $password variable. One of my biggest considerations for purchasing vB was hoping its support was a little better than phpBB's support - it was pretty hit and miss for help with the code. Being that vB is closed source, I hope that everyone is a little more familiar with it.

What I did with phpBB2 was to insert an additional database call during user registration and a few other places to copy the most important user details (username/password/email) into the ExpressionEngine database and vice-versa. After all the bugs were worked out, this worked out very well, at least during my bit of testing.

I'm trying to essentially mirror this with vB, so the first step I took was to head into the registration file. part way down, I can see what I believe is the database call to update the database with the password, but I have no idea how to proceed from there - it doesn't look like that's the real password. I think it may have already been hashed somewhere, but I can't seem to locate when that happens to capture it and send it to EE's database.

If anyone can help em out with this, I'd be extremely grateful - thanks in advance.

Edit:
Now that I think about it, I may not actually need the original password. ExpressionEngine supports both MD5 and SHA1 encryption. With phpBB2, I changed its system to use SHA1 as well, to be compatible with EE since I set it to use SHA1 over MD5. However, I suppose there's little difference between using the two, and vB appears to use a salt which is better than phpBB2's implementation. Unfortunately, I don't think EE supports salts, so if I were to be able to grab the MD5 hash, it would have to be before the salt is added to it, and I can simply copy that into EE's database.. that still leaves the username/email fields though..

MoT3rror
07-21-2008, 02:54 AM
When every a password is submitted by form, it is md5 once without salt. Then the salt is added to the end and md5 again so the final password looks something like this.

md5(md5($password) . $salt)

On the register page, the password from the user is $vbulletin->GPC['password'], I believe.

Dismounted
07-21-2008, 05:46 AM
As MoT3rror has said, the password stored in the database is like so:
md5(md5($password) . $salt);
The salt is unique for every user and is stored in the database. Also, if the user has Javascript enabled when logging in, the password that is entered is md5 hashed once, and is sent through the POST variable "md5_password".

DarkScythe
07-21-2008, 01:02 PM
Thank you for the replies.

I was able to tell about the double hashing, but I couldn't figure out exactly when I could pull the password. I had found this in the registration file, which I believe is when the database actually gets updated with the password information:
// set password
$userdata->set('password', ($vbulletin->GPC['password_md5'] ? $vbulletin->GPC['password_md5'] : $vbulletin->GPC['password']));

But I have no idea which one to copy over. Are you saying that
$vbulletin->GPC['password']
is what I need to copy over (after hashing, if that's the plaintext password?)

Along those lines, I read somewhere around here that the plaintext variable would turn up empty if javascript is enabled as there's a JS that hashes it before it hits the code or something - does this mean I need to copy the md5 hash instead before the salt is added?

Also.. I can't seem to find similar database calls for the other user information such as the username/email address. When/where does this information get added? I believe I may be simply overlooking it somewhere nearby..

Another thing.. apologies for all my questions.. Is it possible to turn birthdays into a required field when registering? I don't need to make it public, but I do plan on needing that information for some access restriction.

Thanks again!

Dismounted
07-22-2008, 07:08 AM
If the user has Javascript enabled, vBulletin will hash the password field, then empty it, before being sent to the server. The first bit of code checks if the MD5 hashed password exists, if it doesn't, it uses the normal password field instead (which doesn't exist if the password is hashed).

DarkScythe
07-22-2008, 02:25 PM
Yes, that's what I remember reading, and why the above userdata set line is checking. Where is the Javascript function though, I see no mention of it around that section of code..

I did find this in the global file
// you may define this if you don't want the password in the login box to be zapped onsubmit; good for integration
$show['nopasswordempty'] = defined('DISABLE_PASSWORD_CLEARING') ? 1 : 0; // this nees to be an int for the templates

Is this what I am looking for? I could also simply copied the hashed value directly over, but it would be plain MD5, which is a little iffy.. I don't think EE has any salting mechanism built in by default, so I normally hash passwords into SHA1, if I can, before putting it in there.

As for email and username, I was apparently blind - they're set a few lines down after the password. There is another field I'd like to mandate though.. is there a way to force users to have to set their birthday during registration? I do not need it to be publicly visible, or even editable afterwards by users.

Thanks again.

--------------- Added 1216767919 at 1216767919 ---------------

Actually, from doing some more research, it seems there might be several ways of doing what I'm trying to do.. but I'm not sure of the differences between them.

At its most basic level, I'm basically re-doing what I had to do with phpBB2, that is injecting my own code into the source files to get some integration with the user tables.

However, I have also seen something about vB's plugin system which may allow me to put the code into plugins and be less invasive to the source code. (I have no idea what the difference between a plugin and a product are at the moment.. It just seems like I put my code into one of them and insert a "hook" line into the source code and it would replace that hook with whatever the linked code is.)

Lastly, vB also seems to have "datamanagers." What are these? From the manual it says they are useful for 'rapid integration of vBulletin-specific data structures and data constraints into [...] third-party applications.' I'm not entirely sure how to access this, or if it coincides with what I want to do..

If anyone can shed some light on this, I'd appreciate it.
Thanks in advance.

Dismounted
07-23-2008, 10:03 AM
Yes, that's what I remember reading, and why the above userdata set line is checking. Where is the Javascript function though, I see no mention of it around that section of code..
See the "onsubmit" attribute on the login form.
I did find this in the global file
// you may define this if you don't want the password in the login box to be zapped onsubmit; good for integration
$show['nopasswordempty'] = defined('DISABLE_PASSWORD_CLEARING') ? 1 : 0; // this nees to be an int for the templates

Is this what I am looking for? I could also simply copied the hashed value directly over, but it would be plain MD5, which is a little iffy.. I don't think EE has any salting mechanism built in by default, so I normally hash passwords into SHA1, if I can, before putting it in there.
Disabling the client-side hash would be a bad idea IMO, as then the password would be sent plain text across the "interwebz" :D. You could always SHA1 your MD5 hash.
vB also seems to have "datamanagers." What are these? From the manual it says they are useful for 'rapid integration of vBulletin-specific data structures and data constraints into [...] third-party applications.' I'm not entirely sure how to access this, or if it coincides with what I want to do..
Data managers allow you to insert data into vBulletin's system, with simple PHP function calls. See the articles section for some examples.

DarkScythe
07-23-2008, 01:47 PM
Thanks again for the informative reply.
I'm sorry, I must be a pain in the butt with all these questions, but I do appreciate the help.

I took a look at that function and I believe your talking about this one?
if (
$vbulletin->userinfo['password'] != iif($password AND !$md5password, md5(md5($password) . $vbulletin->userinfo['salt']), '') AND
$vbulletin->userinfo['password'] != iif($md5password, md5($md5password . $vbulletin->userinfo['salt']), '') AND
$vbulletin->userinfo['password'] != iif($md5password_utf, md5($md5password_utf . $vbulletin->userinfo['salt']), '')
)

That seems to compare the password against several factors in order to fully hash it. I suppose disabling client-side hashing would be a bad idea, but I don't want to replace vB's MD5 system with SHA1. I did it with phpBB but it was in a couple places so it was annoying to track down, and that also would probably break update scripts. If you mean SHA1 the MD5 hash itself, I'm not sure what that would accomplish.. the user would then have to enter the MD5 hash in order to log in to EE then, would they not?

Could I simply add an extra line into that if statement to re-encode the base $password (I assume this is the plaintext one it discards) into SHA1 and place it in another variable, then simply call that variable when I need it?

As for the datamanagers, if they're only used for putting data *into* vB, then perhaps they may come in handy when I do the reverse from EE, although is this required? With phpBB, all I needed to do was plug in a few 'required' database fields manually and I had a fully active user.

As an aside, I figured out vB has an option to force birthdays as required.. vB certainly has an exhaustive options panel compared to phpBB, I'm still not fully through that thing yet. I'm glad vB also has options for minimum username length, but there doesn't appear to be a similar one for password lengths.. the mods I've found don't seem to support the latest version.

After this, I still need to track down places where the user/admin can change their password and email.. Forgot password form, profile options, and admin panel off the top of my head - am I missing any?

Dismounted
07-24-2008, 07:51 AM
I took a look at that function and I believe your talking about this one?
if (
$vbulletin->userinfo['password'] != iif($password AND !$md5password, md5(md5($password) . $vbulletin->userinfo['salt']), '') AND
$vbulletin->userinfo['password'] != iif($md5password, md5($md5password . $vbulletin->userinfo['salt']), '') AND
$vbulletin->userinfo['password'] != iif($md5password_utf, md5($md5password_utf . $vbulletin->userinfo['salt']), '')
)
You're looking in the PHP files - the function that hashes client-side is a Javascript function - found in /clientscript/.

DarkScythe
07-24-2008, 12:36 PM
Oops, sorry.

Wow, I can't understand these javascript files at all.. I at least have a PHP book to refer to lol.
I assume this means there's no way I can modify this to also hash it into SHA1 format..

In that case, I'll just have to copy over the MD5 hash.. Does the JS hash it with or without the salt?

Dismounted
07-25-2008, 06:46 AM
Goto the vBulletin Members' Area and download a copy of vBulletin with uncompressed JS files ;).

DarkScythe
07-25-2008, 01:34 PM
Thanks - I didn't even know such a thing existed.. Took me a while to figure out where to download it from.

Anyway, I can read it now but I still can't really do anything since I don't know any Javascript.. Google finds a bunch of SHA1 JS scripts, but I wouldn't know where to begin importing that stuff as I can barely follow what's going on in the stock JS. I feel I've gone a bit over my head here..

Carnage
07-25-2008, 04:13 PM
I have integrated VB with a custom written site in the past; The way i did it was very simple.

When a user registered at the end of the registration process (once the orriginal site had verified their email address etc) I invoked the Vbulletin data manager for users, filled in the required information from the custom sites database and saved it to vb.

There are some clever tricks i pulled to get a shared login session as well, but its been a while and i can't remember them off the top of my head. (soemthing along the lines of sending and encrypted form of the login information to vbulletin as the get value on a transparent 1x1 php image and using a vb plugin to check the encrypted database against its user data and perform a user login.)

DarkScythe
07-25-2008, 05:57 PM
Thanks for the response - that's very similar to what I did with phpBB2, and what I'm trying to do with this. The problem is exporting user data FROM vB to the other program. From my work with phpBB2, I've already placed code in the proper places within EE to import the data into vB, I just need to change the database tables to reflect vB's system instead of phpBB's, although whether I can use the data manager for this or not, I've no idea yet.

If you can provide some tips with where I can locate some of the places within vB that I need to hook into for exporting username/password/email/birthday data, I'd definitely appreciate it though.

Thanks!

DarkScythe
07-27-2008, 03:12 PM
Anyone? :(

Dismounted
07-28-2008, 06:22 AM
If you can provide some tips with where I can locate some of the places within vB that I need to hook into for exporting username/password/email/birthday data, I'd definitely appreciate it though.

Thanks!
All the information you need is in the "user" table. The easiest way to keep this updated (IMO) would be to hook into the user data manager - as this is where any changes to (default) user information should be performed.

DarkScythe
07-28-2008, 01:05 PM
Thanks once again for the reply, Dismounted.

Isn't the user data manager for putting data into vB?
Right now, I don't need to do that, I'm trying to export data from vB into EE's database.
For putting data into vB's database, I could just set a database call to write to ti directly, no?
It seemed to work out well for phpBB, and having only 1 table to write to makes it even easier, I just need to insert into the table the required fields, which from what I can tell are basically every field without a default value of 0 in it.

My biggest problem right now is trying to import the data into EE from vB. Since I don't know any Javascript, I think it would be a pointless endeavor to try to modify the vbulletin_md5.js file to also do SHA1. Thus I'm left with trying to copy the MD5 hash instead, and just hope no one gains access to the databases, since EE does not have any funcionality to support salting of the passwords.

However, in the registration page, it seems that the rule it uses to set the password in the DB is this:
$userdata->set('password', ($vbulletin->GPC['password_md5'] ? $vbulletin->GPC['password_md5'] : $vbulletin->GPC['password']));
That seems to say to input what's in password_md5, or if it does not exist, copy what's in password, but either way they're both completely hashed with the salt, if I'm not mistaken.. so there's no way I can call the unsalted version here. (Correct me if I'm wrong here, please.) This password thing is really the biggest roadblack I have preventing me from moving ahead with this bridge.. Where can I pull up the unsalted password? Along those lines, where does the salt get added to the database?

Thanks in advance.

Dismounted
07-29-2008, 06:54 AM
Isn't the user data manager for putting data into vB?
Right now, I don't need to do that, I'm trying to export data from vB into EE's database.
For putting data into vB's database, I could just set a database call to write to ti directly, no?
It seemed to work out well for phpBB, and having only 1 table to write to makes it even easier, I just need to insert into the table the required fields, which from what I can tell are basically every field without a default value of 0 in it.
Exporting data is simple - just fetch it from the database. Adding and modifying should be done through the data manager - as there are sometimes other things to do other than just updating the field in the database.
However, in the registration page, it seems that the rule it uses to set the password in the DB is this:
$userdata->set('password', ($vbulletin->GPC['password_md5'] ? $vbulletin->GPC['password_md5'] : $vbulletin->GPC['password']));
That seems to say to input what's in password_md5, or if it does not exist, copy what's in password, but either way they're both completely hashed with the salt, if I'm not mistaken.. so there's no way I can call the unsalted version here.
You can't call the unhashed version anywhere at all - if the user has JS enabled - it will not send any unhashed passwords. That condition checks if "password_md5" is populated - if it is populated, it means the user has JS enabled and the password was sent in hashed form.
This password thing is really the biggest roadblack I have preventing me from moving ahead with this bridge.. Where can I pull up the unsalted password? Along those lines, where does the salt get added to the database?
The unsalted password cannot be pulled from the database (it simply doesn't exist). Any stored forms of a user's password is always hashed (and salted).

DarkScythe
07-29-2008, 02:00 PM
So, you're suggesting I fetch data from the database, rather than use the information present in variables during registration? For example, I was planning on hooking in around here:
($hook = vBulletinHook::fetch_hook('register_addmember_proc ess')) ? eval($hook) : false;
And making a database call out to EE's database to populate the username field with $vbulletin->GPC['username'].

You said if "password_md5" is populated, it means that the user has JS enabled and password was sent in hashed form - if that check fails (it's empty) that should mean JS was not enabled, but the regular "password" field it's setting into the database at that point is still hashed (with the salt already), just using php from elsewhere instead of JS - correct?

I know I can't pull the unstalted password from the database, I've taken a look at it. What I want to know is if I can either intercept the password before hashing so I can give it to EE (this requires editing that JS file, but I don't know how to do this) or copy the md5 hash of the password BEFORE it gets re-hashed with the salt. Does the JS hash only the password before returning it to the browser, or does it also add the salt?

My last alternative is to hack EE into supporting salts, but I've no idea how difficult that will be.. It doesn't look like there are any official hacks or mods out for that purpose.

Sorry for all the questions, I'm trying to understand how everything works here..
Thanks again.

Dismounted
07-30-2008, 06:58 AM
So, you're suggesting I fetch data from the database, rather than use the information present in variables during registration? For example, I was planning on hooking in around here:
($hook = vBulletinHook::fetch_hook('register_addmember_proc ess')) ? eval($hook) : false;
And making a database call out to EE's database to populate the username field with $vbulletin->GPC['username'].
You have to take in account if people change email addresses, etc. ;) So the best way (IMO) would be to hook into the user data manager.
You said if "password_md5" is populated, it means that the user has JS enabled and password was sent in hashed form - if that check fails (it's empty) that should mean JS was not enabled, but the regular "password" field it's setting into the database at that point is still hashed (with the salt already), just using php from elsewhere instead of JS - correct?
If "password_md5" is empty, it does mean JS was disabled and $vbulletin->GPC['password'] contains the unhashed password. It is still hashed and salted server-side.
What I want to know is if I can either intercept the password before hashing so I can give it to EE (this requires editing that JS file, but I don't know how to do this) or copy the md5 hash of the password BEFORE it gets re-hashed with the salt. Does the JS hash only the password before returning it to the browser, or does it also add the salt?
$vbulletin->GPC['password_md5'] during registration will be the single md5-hashed password.

DarkScythe
07-30-2008, 01:15 PM
You have to take in account if people change email addresses, etc. ;) So the best way (IMO) would be to hook into the user data manager.
I'm aware of this - Within EE and phpBB, I have laid out database calls in several files where these changes happen, but the biggest one to deal with first is the registration, and is why I'm focusing on this. Also, data managers are for putting data into vB's databases, as I've been told, and I don't think it will suit my needs in doing the complete opposite - pulling data off it and putting it into another database.

If "password_md5" is empty, it does mean JS was disabled and $vbulletin->GPC['password'] contains the unhashed password. It is still hashed and salted server-side.
This is interesting.. When does it get hashed if JS is otherwise disabled? Certainly, the unhashed password field can't remain in its unhashed state by the time the $userdata->set call is made, unless that call also has a hidden function to automatically hash as well as store at once.

$vbulletin->GPC['password_md5'] during registration will be the single md5-hashed password.
Similar to the question above, when does the salt get added to this hash (and when does the salt itself get entered into the database?) The only other time I believe I see the php hashing is in functions_login.php that I quoted earlier, but I don't see the registration page even requiring that file.

Am I just overlooking something very obvious here?
Thanks for all the help >_<

MoT3rror
07-31-2008, 02:52 AM
The hashing of the password and adding salt is done in the vBulletin user datamanager when I believe the pre_save() function is called or save().

DarkScythe
07-31-2008, 02:58 AM
Oh!

If that's the case, that means that $userdata->set() does not actually enter the information in the database yet?

The hook I mentioned before came right before a pre_save() call.. If that's the case, then I can actually just stick my code there and grab password_md5 (or hash the plain password) to copy it over to EE, correct?

MoT3rror
07-31-2008, 03:02 AM
I would probably just go for the password_md5. Then you can take this value over to EE and add more encryption and/or salt. It is not the best idea to store a plain text password anywhere.

DarkScythe
07-31-2008, 03:15 AM
Oh, I'm not storing the password as plain text :)

I just needed to know where I could grab the password at all before vB's salt got added to it. EE does not support salts, it only supports plain MD5 or plain SHA1 hashing (out of the box at least.) This is the reason I've been trying to look for it everywhere, I need to either copy the MD5 hash over, or find a way to SHA1 hash it and copy that over. Since vB's Javascript auto-hash kills my attempts to SHA1-hash the password, I'll have to use the MD5 instead. If Javascript is disabled though, it won't be pre-hashed, and password_md5 will be empty - which is when I would need to get the plain text password and hash it myself.

Thanks for the tip on pre_save though, I'll try to look that up and see if I can follow that a little more to figure out where the database calls are at.

MoT3rror
07-31-2008, 03:24 AM
The pre_save functions pretty much makes all the checks and gives you errors in the $userdatamanager->errors as a array. The database call can be found in save().

DarkScythe
07-31-2008, 03:36 AM
Thanks for the tips!

Kind of late now though.. I'll have to look through the code tomorrow morning.
If you have any more tips/tricks/advice that may help though, I'd appreciate it.

I'd need to grab username/password/email/salt/birthdate during registration, then password/email wherever they can be changed. I don't think users can change their username or birthdates, so that's not a problem. I'm not sure about the salt though, does that change?

Thanks again!

MoT3rror
07-31-2008, 06:06 AM
You will have to fetch the salt after the save function. The birthday of the user can be changed by the user I believe.