/** * * @param type $username * @param type $password * @return boolean returns true if the password for the given user is correct, false otherwise. */ function confirm_user_password($username, &$password) { $getUserSecureSQL = " SELECT " . implode(",", array(COL_ID, COL_PWD, COL_SALT)) . " FROM " . TBL_USERS_SECURE . " WHERE BINARY " . COL_UNM . "=?"; // Use binary keyword to require case sensitive username match $userSecure = privQuery($getUserSecureSQL, array($username)); if (is_array($userSecure)) { $phash = oemr_password_hash($password, $userSecure[COL_SALT]); if ($phash == $userSecure[COL_PWD]) { return true; } } return false; }
public function add_initial_user() { if ($this->execute_sql("INSERT INTO groups (id, name, user) VALUES (1,'{$this->igroup}','{$this->iuser}')") == FALSE) { $this->error_message = "ERROR. Unable to add initial user group\n" . "<p>" . mysqli_error($this->dbh) . " (#" . mysqli_errno($this->dbh) . ")\n"; return FALSE; } $password_hash = "NoLongerUsed"; // This is the value to insert into the password column in the "users" table. password details are now being stored in users_secure instead. $salt = oemr_password_salt(); // Uses the functions defined in library/authentication/password_hashing.php $hash = oemr_password_hash($this->iuserpass, $salt); if ($this->execute_sql("INSERT INTO users (id, username, password, authorized, lname, fname, facility_id, calendar, cal_ui) VALUES (1,'{$this->iuser}','{$password_hash}',1,'{$this->iuname}','{$this->iufname}',3,1,3)") == FALSE) { $this->error_message = "ERROR. Unable to add initial user\n" . "<p>" . mysqli_error($this->dbh) . " (#" . mysqli_errno($this->dbh) . ")\n"; return FALSE; } // Create the new style login credentials with blowfish and salt if ($this->execute_sql("INSERT INTO users_secure (id, username, password, salt) VALUES (1,'{$this->iuser}','{$hash}','{$salt}')") == FALSE) { $this->error_message = "ERROR. Unable to add initial user login credentials\n" . "<p>" . mysqli_error($this->dbh) . " (#" . mysqli_errno($this->dbh) . ")\n"; return FALSE; } // Add the official openemr users (services) if ($this->load_file($this->additional_users, "Additional Official Users") == FALSE) { return FALSE; } return TRUE; }
/** * Setup or change a user's password * * @param type $activeUser ID of who is trying to make the change (either the user himself, or an administrator) * @param type $targetUser ID of what account's password is to be updated (for a new user this doesn't exist yet). * @param type $currentPwd the active user's current password * @param type $newPwd the new password for the target user * @param type $errMsg passed by reference to return any * @param type $create Are we creating a new user or * @param type $insert_sql SQL to run to create the row in "users" (and generate a new id) when needed. * @param type $new_username The username for a new user * @param type $newid Return by reference of the ID of a created user * @return boolean Was the password successfully updated/created? If false, then $errMsg will tell you why it failed. */ function update_password($activeUser, $targetUser, &$currentPwd, &$newPwd, &$errMsg, $create = false, $insert_sql = "", $new_username = null, &$newid = null) { $userSQL = "SELECT " . implode(",", array(COL_PWD, COL_SALT, COL_PWD_H1, COL_SALT_H1, COL_PWD_H2, COL_SALT_H2)) . " FROM " . TBL_USERS_SECURE . " WHERE " . COL_ID . "=?"; $userInfo = privQuery($userSQL, array($targetUser)); // Verify the active user's password $changingOwnPassword = $activeUser == $targetUser; // True if this is the current user changing their own password if ($changingOwnPassword) { if ($create) { $errMsg = xl("Trying to create user with existing username!"); return false; } // If this user is changing his own password, then confirm that they have the current password correct $hash_current = oemr_password_hash($currentPwd, $userInfo[COL_SALT]); if ($hash_current != $userInfo[COL_PWD]) { $errMsg = xl("Incorrect password!"); return false; } } else { // If this is an administrator changing someone else's password, then check that they have the password right $adminSQL = " SELECT " . implode(",", array(COL_PWD, COL_SALT)) . " FROM " . TBL_USERS_SECURE . " WHERE " . COL_ID . "=?"; $adminInfo = privQuery($adminSQL, array($activeUser)); $hash_admin = oemr_password_hash($currentPwd, $adminInfo[COL_SALT]); if ($hash_admin != $adminInfo[COL_PWD]) { $errMsg = xl("Incorrect password!"); return false; } if (!acl_check('admin', 'users')) { $errMsg = xl("Not authorized to manage users!"); return false; } } // End active user check //Test password validity if (strlen($newPwd) == 0) { $errMsg = xl("Empty Password Not Allowed"); return false; } if (!test_password_strength($newPwd, $errMsg)) { return false; } // End password validty checks if ($userInfo === false) { // No userInfo means either a new user, or an existing user who has not been migrated to blowfish yet // In these cases don't worry about password history if ($create) { privStatement($insert_sql, array()); $getUserID = " SELECT " . COL_ID . " FROM " . TBL_USERS . " WHERE " . COL_UNM . "=?"; $user_id = privQuery($getUserID, array($new_username)); initializePassword($new_username, $user_id[COL_ID], $newPwd); $newid = $user_id[COL_ID]; } else { $getUserNameSQL = "SELECT " . COL_UNM . " FROM " . TBL_USERS . " WHERE " . COL_ID . "=?"; $unm = privQuery($getUserNameSQL, array($targetUser)); if ($unm === false) { $errMsg = xl("Unknown user id:" . $targetUser); return false; } initializePassword($unm[COL_UNM], $targetUser, $newPwd); purgeCompatabilityPassword($unm[COL_UNM], $targetUser); } } else { // We are trying to update the password of an existing user if ($create) { $errMsg = xl("Trying to create user with existing username!"); return false; } $forbid_reuse = $GLOBALS['password_history'] != 0; if ($forbid_reuse) { // password reuse disallowed $hash_current = oemr_password_hash($newPwd, $userInfo[COL_SALT]); $hash_history1 = oemr_password_hash($newPwd, $userInfo[COL_SALT_H1]); $hash_history2 = oemr_password_hash($newPwd, $userInfo[COL_SALT_H2]); if ($hash_current == $userInfo[COL_PWD] || $hash_history1 == $userInfo[COL_PWD_H1] || $hash_history2 == $userInfo[COL_PWD_H2]) { $errMsg = xl("Reuse of three previous passwords not allowed!"); return false; } } // Everything checks out at this point, so update the password record $newSalt = oemr_password_salt(); $newHash = oemr_password_hash($newPwd, $newSalt); $updateParams = array(); $updateSQL = "UPDATE " . TBL_USERS_SECURE; $updateSQL .= " SET " . COL_PWD . "=?," . COL_SALT . "=?"; array_push($updateParams, $newHash); array_push($updateParams, $newSalt); if ($forbid_reuse) { $updateSQL .= "," . COL_PWD_H1 . "=?" . "," . COL_SALT_H1 . "=?"; array_push($updateParams, $userInfo[COL_PWD]); array_push($updateParams, $userInfo[COL_SALT]); $updateSQL .= "," . COL_PWD_H2 . "=?" . "," . COL_SALT_H2 . "=?"; array_push($updateParams, $userInfo[COL_PWD_H1]); array_push($updateParams, $userInfo[COL_SALT_H1]); } $updateSQL .= " WHERE " . COL_ID . "=?"; array_push($updateParams, $targetUser); privStatement($updateSQL, $updateParams); // If the user is changing their own password, we need to update the session if ($changingOwnPassword) { $_SESSION['authPass'] = $newHash; } } if ($GLOBALS['password_expiration_days'] != 0) { $exp_days = $GLOBALS['password_expiration_days']; $exp_date = date('Y-m-d', strtotime("+{$exp_days} days")); privStatement("update users set pwd_expiration_date=? where id=?", array($exp_date, $targetUser)); } return true; }
/** * * @param type $username * @param type $password password is passed by reference so that it can be "cleared out" * as soon as we are done with it. * @param type $provider */ function validate_user_password($username, &$password, $provider) { $ip = $_SERVER['REMOTE_ADDR']; $valid = false; $getUserSecureSQL = " SELECT " . implode(",", array(COL_ID, COL_PWD, COL_SALT)) . " FROM " . TBL_USERS_SECURE . " WHERE BINARY " . COL_UNM . "=?"; // Use binary keyword to require case sensitive username match $userSecure = privQuery($getUserSecureSQL, array($username)); if (is_array($userSecure)) { $phash = oemr_password_hash($password, $userSecure[COL_SALT]); if ($phash != $userSecure[COL_PWD]) { return false; } $valid = true; } else { if (!isset($GLOBALS['password_compatibility']) || $GLOBALS['password_compatibility']) { $getUserSQL = "select username,id, password from users where BINARY username = ?"; $userInfo = privQuery($getUserSQL, array($username)); if ($userInfo === false) { return false; } $username = $userInfo['username']; $dbPasswordLen = strlen($userInfo['password']); if ($dbPasswordLen == 32) { $phash = md5($password); $valid = $phash == $userInfo['password']; } else { if ($dbPasswordLen == 40) { $phash = sha1($password); $valid = $phash == $userInfo['password']; } } if ($valid) { $phash = initializePassword($username, $userInfo['id'], $password); purgeCompatabilityPassword($username, $userInfo['id']); $_SESSION['relogin'] = 1; } else { return false; } } } $getUserSQL = "select id, authorized, see_auth" . ", cal_ui, active " . " from users where BINARY username = ?"; $userInfo = privQuery($getUserSQL, array($username)); if ($userInfo['active'] != 1) { newEvent('login', $username, $provider, 0, "failure: {$ip}. user not active or not found in users table"); $password = ''; return false; } // Done with the cleartext password at this point! $password = ''; if ($valid) { if ($authGroup = privQuery("select * from groups where user=? and name=?", array($username, $provider))) { $_SESSION['authUser'] = $username; $_SESSION['authPass'] = $phash; $_SESSION['authGroup'] = $authGroup['name']; $_SESSION['authUserID'] = $userInfo['id']; $_SESSION['authProvider'] = $provider; $_SESSION['authId'] = $userInfo['id']; $_SESSION['cal_ui'] = $userInfo['cal_ui']; $_SESSION['userauthorized'] = $userInfo['authorized']; // Some users may be able to authorize without being providers: if ($userInfo['see_auth'] > '2') { $_SESSION['userauthorized'] = '1'; } newEvent('login', $username, $provider, 1, "success: {$ip}"); $valid = true; } else { newEvent('login', $username, $provider, 0, "failure: {$ip}. user not in group: {$provider}"); $valid = false; } } return $valid; }
if ($emailFlag) { $message = "<br><br>" . htmlspecialchars(xl("Email was sent to following address"), ENT_NOQUOTES) . ": " . htmlspecialchars($patientData['email'], ENT_NOQUOTES) . "<br><br>" . $message; } echo "<html><body onload='top.printLogPrint(window);'>" . $message . "</body></html>"; } if (isset($_REQUEST['form_save']) && $_REQUEST['form_save'] == 'SUBMIT') { require_once "{$srcdir}/authentication/common_operations.php"; $clear_pass = $_REQUEST['pwd']; $res = sqlStatement("SELECT * FROM patient_access_" . add_escape_custom($portalsite) . "site WHERE pid=?", array($pid)); $query_parameters = array($_REQUEST['uname']); $salt_clause = ""; if ($portalsite == 'on') { // For onsite portal create a blowfish based hash and salt. $new_salt = oemr_password_salt(); $salt_clause = ",portal_salt=? "; array_push($query_parameters, oemr_password_hash($clear_pass, $new_salt), $new_salt); } else { // For offsite portal still create and SHA1 hashed password // When offsite portal is updated to handle blowfish, then both portals can use the same execution path. array_push($query_parameters, SHA1($clear_pass)); } array_push($query_parameters, $pid); if (sqlNumRows($res)) { sqlStatement("UPDATE patient_access_" . add_escape_custom($portalsite) . "site SET portal_username=?,portal_pwd=?,portal_pwd_status=0 " . $salt_clause . " WHERE pid=?", $query_parameters); } else { sqlStatement("INSERT INTO patient_access_" . add_escape_custom($portalsite) . "site SET portal_username=?,portal_pwd=?,portal_pwd_status=0" . $salt_clause . " ,pid=?", $query_parameters); } // Create the message $message = messageCreate($_REQUEST['uname'], $clear_pass, $portalsite); // Email and display/print the message if (emailLogin($pid, $message)) {
} if ($auth['pid'] != $userData['pid']) { // Not sure if this is even possible, but should escape if this happens session_destroy(); header('Location: '.$landingpage.'&w'); exit; } if ( $password_update) { $code_new=$_POST['pass_new']; $code_new_confirm=$_POST['pass_new_confirm']; if(!(empty($_POST['pass_new'])) && !(empty($_POST['pass_new_confirm'])) && ($code_new == $code_new_confirm)) { $new_salt=oemr_password_salt(); $new_hash=oemr_password_hash($code_new,$new_salt); // Update the password and continue (patient is authorized) privStatement("UPDATE ".TBL_PAT_ACC_ON ." SET ".COL_POR_PWD."=?,".COL_POR_SALT."=?,".COL_POR_PWD_STAT."=1 WHERE id=?", array($new_hash,$new_salt,$auth['id']) ); $authorizedPortal = true; } } if ($auth['portal_pwd_status'] == 0) { if(!$authorizedPortal) { // Need to enter a new password in the index.php script $_SESSION['password_update'] = 1; header('Location: '.$landingpage); exit; } }