Need help debugging a custom authentication plugin for Moodle - database

I'm trying to authenticate against the user db of my website (CMS based) and it uses a slightly different approach at storing hashed passwords. It uses a randomly generated salt for each user. The salt is stored in the user db along with the hashed passwords. Hence, direct field-mapped authentication (as the External DB plugin does) won't work for me.
To start off, I just mirrored the DB plugin and modified the user_login() procedure to read the hashed password and the salt from the database and then hash the entered password again with the salt and match it up with the password in the database. Here's the code for my user_login() function
function user_login($username, $password) {
global $CFG;
$textlib = textlib_get_instance();
$extusername = $textlib->convert(stripslashes($username), 'utf-8', $this->config->extencoding);
$extpassword = $textlib->convert(stripslashes($password), 'utf-8', $this->config->extencoding);
$authdb = $this->db_init();
// normal case: use external db for passwords
// Get user data
$sql = "SELECT
*
FROM {$this->config->table}
WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."' ";
$authdb->SetFetchMode(ADODB_FETCH_ASSOC);
// No DB Connection
if ( !$rs = $authdb->Execute( $sql ) ) {
$authdb->Close();
print_error('auth_dbcantconnect','auth');
return false;
}
// No records returned
if( $rs->EOF ) {
$rs->Close();
$authdb->Close();
return false;
}
// Get password
$db_password = $rs->fields['user_password'];
$salt = $rs->fields['user_salt'];
// Close DB Conn
$rs->Close();
$authdb->Close();
// Return match
return sha1( $extpassword . $salt ) == $db_password;
}
But when I try to login, username / passwords corresponding to the website (CMS) database are failing. However, the password (for the same user) that was stored in Moodle earlier on (before I tried using this custom plugin) is getting me through.
That means, either my authentication routine is failing or moodle's internal db based auth mechanism is taking precedence over it.
I've enabled ADODB debug mode - but that isn't helping either. When I enable the debug output from Server settings, the error messages are being sent prior to the page headers. Thus the login page won't display at all.
I have all other forms of authentication turned off (except for Manual which can't be turned off) and my own.
Any ideas on how to solve this issue?

Can you confirm the order that the authentication pluggins are displayed? This will determine the order in which they are used. See..
http://docs.moodle.org/en/Manage_authentication
Either way, the behaviour you're seeing suggests that your code is returning false and the fall through logic described here...
http://moodle.org/mod/forum/discuss.php?d=102070
... and here...
http://docs.moodle.org/en/Development:Authentication_plugins
... is kicking in.
Have you tried returning "true" always from your plugin to ensure that it's being called. Then, you can start returning "true" based upon other things (hard coded usernames etc). This approach will allow you to get to the point where you are either continuing to fail or seeing more targetted failures. Are you sure, for example, that it's the user_login function and not the subsequent call to update_user_record that is failing?
Finally, are you sure you're generating the salted password in the exact same way that it was created in the first place? This would be, for me, the most likely cause of the problem. Can you take control of the creation of the salted password so that you own both creation of new users and authentication of users - this would ensure that you were in sync with how the salted password and hash were generated.

Related

Laravel 8 Fortify User UUID Login Problem

I am currently setting up a new project using Laravel 8. Out of the box, Laravel is configured to use auto-incrementing ID's for the user's ID. In the past I have overrode this by doing the following.
Updating the ID column in the user table creation migration to
$table->uuid('id');
$table->primary('id');
Adding the following trait
trait UsesUUID
{
protected static function bootUsesUUID()
{
static::creating(function ($model) {
$model->{$model->getKeyName()} = (string) Str::orderedUuid();
});
}
}
Adding the following to the user model file
use UsesUUID;
public $incrementing = false;
protected $primaryKey = 'id';
protected $keyType = 'uuid';
On this new project, I did the same as above. This seems to break the login functionality. When the email and password are entered and submitted, the form clears as though the page has been refreshed. Thing to note is there are no typical validation error messages returned as would be expected if the email and/or password is wrong.
To check that the right account is actually being found and the password is being checked properly, I added the following code to the FortifyServiceProvider boot method. The log file confirms that the user is found and the user object dump is correct too.
Fortify::authenticateUsing(function(Request $request) {
\Log::debug('running login flow...');
$user = User::where('email', $request->email)->first();
if ($user && Hash::check($request->password, $user->password)) {
\Log::debug('user found');
\Log::debug($user);
return $user;
}
\Log::debug('user not found');
return false;
});
Undoing the above changes to the user model fixes the login problem. However, it introduces a new problem that is the login will be successful but it wont be the right account that is logged in. For example, there are 3 accounts, I enter the credentials for the second or third account, but no matter what, the system will always login using the first account.
Anyone have any suggestions or ideas as to what I may be doing wrong, or if anyone has come across the same/similar issue and how you went about resolving it?
Thanks.
After digging around some more, I have found the solution.
Laravel 8 now stores sessions inside the sessions table in the database. The sessions table has got a user_id column that is a foreign key to the id column in the users table.
Looking at the migration file for the sessions table, I found that I had forgot to change the following the problem.
From
$table->foreignId('user_id')->nullable()->index();
To
$table->foreignUuid('user_id')->nullable()->index();
This is because Laravel 8 by default uses auto incrementing ID for user ID. Since I had modified the ID column to the users table to UUID, I had forgotten to update the reference in the sessions table too.

CouchDB permanent authentication key

We're moving and updating our database because it's due for it, but we have an issue concerning authentication. We'd like to connect to the database only with an authentication key.
Our old CouchDB were not using any user and all the databases were public (no users permissions or anything like it). It was working but it is not what we want.
Now, with our 'new' CouchDB, we'd like to have our connections made with an authentication key only, but it looks like there's an expiration on the sessions made and we can't find the way to have a token permanent.
For the context, I'm using couchdb-python for my tools and I found some ways to start a session and get the cookies, therefore the authentication key, but either it is via couchdb-python or the web platform (Fauxton I think it's called), the expiration time is still there and after the timeout (as shown below) the session does expire.
Below is our local.ini for it.
We tried to add both required_valid_user = false and allow_persistent_cookies = true but to no avail.
[couchdb]
uuid = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[couch_peruser]
[chttpd]
port = 5984
bind_address = 192.168.140.66
require_valid_user = false
[httpd]
[couch_httpd_auth]
require_valid_user = false
secret = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
allow_persistent_cookies = true
timeout = 600
[ssl]
[vhosts]
[admins]
admin = -xxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xx
I'm pretty sure there's something we're overlooking or that we did not understand correctly.
Is there a way to get an authentication key to be permanent?
Is there a way to get an authentication key to be permanent?
The best would just be to use password authentication. The password never changes (unless you change it, of course).
But if you insist on using a token, you can increase the session timeout to some insane value:
[couch_httpd_auth]
timeout = 99999999999999
This is untested. I don't know what the maximum value is.

D3 Connection issue using mvsp java api

I am trying to connect to D3 Database with MVSP java api. So far:
I have downloaded the mvapi.jar
added it in project lib folder
written the sample code for connection inside main method
String url = "jdbc:mv:d3:hostname:portNo";
Properties props = new Properties();
props.setProperty("username", "");
props.setProperty("password", "");
String account = "AGCO";
String password = "";
MVConnection connection = null;
try {
// Getting error at this point
connection = new MVConnection(url,props);
MVStatement mvStatement = connection.createStatement();
connection.logTo(account,password);
MVResultSet results = mvStatement.executeQuery(query);
}
com.tigr.mvapi.exceptions.MVException: server error with errorCode 1023.
I checked the console but I'm not able to figure out the actual cause or whether I am entering the wrong username, password.
Please suggest what I am doing wrong.
First, you have to set a breakpoint or trace which function is throwing the errors. Then check the routes, (FileName) probably you will have much more experience than I do, but keep in mind that giving the full route ("account,filename," where the last comma is important) is never a bad idea while keep you safer and is mandatory if the filename is in a different account that you are logged to.
And like always please verify these things:
You have enough licenses. Try to close any terminal you have opened for testing your queries. Yes you know is true. One connection one license. Sometimes MVSP let you two under the same IP but chek this.
MVSP service is running. See Pick D3 documentation.
Your USER and ACCOUNT are both ENABLED to access in the MVSP server otherwise you won't be able to access these files or login with the user through the API. See the documentation to enable in the MVSP.Menu account.
I hope this helps.

Create encrypted passwords

I am using a small cakephp setup, with no forgot password functionality. I want to be able to create a hashed password, using the same security hashing method and cipherseed used in the site.
Is there a way to recreate the setup in a local php file which would output a hashed password, the system would understand?
Make sure to specify that you're using the Security Component in whatever controller you're working in:
var $components = array('Security');
Then, in the action (method/function...whatever):
$myPassword = 'pizzaRules!';
$hashedPassword = Security::hash($myPassword, null, true);
The true at the end says you want to use the site's salt.

cakephp sha1 password saving in mysql

I have forgot password feature in my cakephp application. The function for this will request the email address, find this user, generate a new password, convert it to sha1 and save it to the database, emailing the contents to the user.
Anyway I am having issues, the generated sha1 password is different to the one being saved.
I have called the info to the screen to show what is happening:
TEMP PASSWORD- lHQcVp4 (FROM THE FUNCTION)
Blockquote
SHA1 PASSWORD- 0ee4ae757733f458b9e395a8457c2ef307af99f0 (FROM sha1($user['User']['tmp_password']);
Auth Password PASSWORD- 93df9bd251620d0634235c22f4ab6fe9ad5421f4 (FROM: $this->Auth->password($user['User']['tmp_password']);)
DB Record After Save PASSWORD- 13ef648db45cc62b593c3943646806af06846016 (FROM $this->User->field('password');)
I am saving the data as follows: $this->User->save($user, false)
Why would it come though differently all 3 times? I cannot work it out. Very strange.
Thankyou
sha1($user['User']['tmp_password']
This will simply hash the password and output the text
$this->Auth->password($user['User']['tmp_password']);
This hashes the password with the cakephp salt defined in core.php. This is why you see a difference
If you simply set the password value to $user['User']['password'] and call save() on it, Auth might be hashing the password again since it doesn't know you've already hashed it. Have you tried just setting the password to $user['User']['password'] and calling save() on it? Let Auth handle the hashing for you.

Resources