Vanilla 1.1.5 is a product of Lussumo. More Information: Documentation, Community Support.
Help keep Vanilla free:function newhash($oldhash, $salt) //salt = really big integer
{
$r = $oldhash;
for($i = $salt % 50; $i >= 0; $i--)
$r = sha1($r.$salt);
return $r;
}then both the input /and/ the function would be dynamic.ALTER TABLE Lum_User ADD TempPassword VARCHAR( 32 ) AFTER Password ;
SELECT UserID,Password FROM Lum_User WHERE TempPassword IS NULL LIMIT 0 , 10
UPDATE Lum_User SET TempPassword = $NewPassword WHERE UserID = $UserId
[...]
LOCK TABLES Lum_User WRITE;
ALTER TABLE Lum_User DROP Password;
ALTER TABLE Lum_User CHANGE TempPassword Password
// Only then does vanilla start using the new authenticator by changing a configuration setting
UNLOCK TABLES;
LOCK TABLES `lum_user` WRITE;
ALTER TABLE `lum_user` CHANGE `Password` `Password` VARCHAR( 64 ) NULL DEFAULT NULL;
ALTER TABLE `lum_user` CHANGE `VerificationKey` `VerificationKey` VARCHAR( 65 ) NULL DEFAULT NULL;
ALTER TABLE `lum_user` ADD `Salt` INT UNSIGNED DEFAULT '0' NOT NULL;
UNLOCK TABLES;and after that SELECT all the passwords, rehash them with a generated seed, and update. I suppose you wouldn't really need to lock the forum, but it would make it smoother for users attempting to log in during/before the passwords update.
function HashPassword($password, $salt)
{
$r = md5($password);
$cursalt = $salt;
for($i = $salt % 10000 + 100; $i >= 0; $i--)
{
$r = md5($r.(string)$cursalt);
$cursalt = ($cursalt + 67343) % 2100000000;
}
return $r;
}(you'd think php would have the decency to automatically use a library if number values got too big, or at least keep int limitations independant of machine type...)$Configuration['PASSWORD_HASH_MODULE'] = 'People/phpass_file_name.php';
$Configuration['PASSWORD_HASH_CLASS'] = 'VanillaPasswordHash';now rename People.Class.PasswordHash.php to People.Class.VanillaPasswordHash.php and replace its content with the following:<?php
/**
* Password hash
*
...copyright, yada yada yada...
*/
/**
* Password hash
...big comment...
*/
class VanillaPasswordHash {
/**
* @var Context
*/
var $Context;
/**
* @var string
*/
var $Hash;
var $phpass;
/**
* Constructor
*
*
* @param Context $Context
* @param string $Hash
* @return PasswordHash
*/
function VanillaPasswordHash(&$Context, $Hash = '') {
$this->Context =& $Context;
$this->phpass = new PasswordHash(10, 0);
$this->Hash = $Hash;
}
/**
* Create a hash from the plain text password
*
* @param string $Password
* @return string
*/
function Hash($Password) {
$this->Hash = $this->phpass->HashPassword($Password);
return $this->Hash;
}
function IsOldStyle($Hash = 0)
{
if(!$Hash) $Hash = $this->Hash;
if(!$Hash) return false;
//PHPass prefixes all its hashes with either _ or $
return !($Hash[0] == '_' || $Hash[0] == '$');
}
/**
* Check a plain text password against the hash
*
* @param string $Password
* @return boolean
*/
function Check($Password) {
//nothing there
if(!$this->Hash) return false;
//old style?
if($this->IsOldStyle()) return md5($Password) == $this->Hash;
//supah new style
return $this->phpass->CheckPassword($Password, $this->Hash);
}
/**
* @return string
*/
function __toString() {
return $this->Hash;
}
}and lastly, here is a diff for Authenticator and UserManager:--- People.Class.Authenticator_old.php Wed Sep 3 01:21:00 2008
+++ People.Class.Authenticator.php Thu Sep 4 00:49:12 2008
@@ -65,6 +65,14 @@
if(!$Credentials->PasswordHash->Check($Password)) {
return 0;
} else {
+
+ //migration...
+ if($Credentials->PasswordHash->IsOldStyle())
+ {
+ $Credentials->PasswordHash->Hash($Password);
+ $UserManager->UpdatePassword($Credentials->UserID, $Credentials->PasswordHash);
+ }
+
// Update the user's information
$this->UpdateLastVisit($Credentials->UserID, $Credentials->VerificationKey);
--- People.Class.UserManager_old.php Wed Sep 3 01:21:00 2008
+++ People.Class.UserManager.php Thu Sep 4 00:50:49 2008
@@ -500,6 +500,19 @@
return false;
}
}
+
+ //migration related
+ function UpdatePassword($UserID, $PasswordHash)
+ {
+ $s = $this->Context->ObjectFactory->NewContextObject($this->Context, 'SqlBuilder');
+ $s->SetMainTable('User', 'u');
+
+ $s->AddFieldNameValue('Password', $PasswordHash->__toString());
+ $s->AddWhere('u', 'UserID', '', $UserID, '=');
+
+ return $this->Context->Database->Update($s, 'UserManager', 'UpdatePassword',
+ 'An error occurred while attempting to update your password.');
+ }
function CheckVerificationKey($UserID, $VerificationKey) {
$UserID = ForceInt($UserID, 0);...that should work. you still need to enlarge the password field though. it's a tad redundant what with a hashing class nested in another, but this allows for easy updates of the phpass file.
patch -p1 < phpass.diff
Index: People.Class.Authenticator.php
===================================================================
--- People.Class.Authenticator.php (revision 115)
+++ People.Class.Authenticator.php (working copy)
@@ -130,6 +130,14 @@
return $UserID;
}
+ function HashPassword($Password) {
+ $PasswordHash = $this->Context->ObjectFactory->NewObject(
+ $this->Context, 'PasswordHash',
+ $this->Context->Configuration['PASSWORD_HASH_ITERATION'],
+ $this->Context->Configuration['PASSWORD_HASH_PORTABLE']);
+ return $PasswordHash->HashPassword($Password);
+ }
+
// All methods below this point are specific to this authenticator and
// should not be treated as interface methods. The only required interface
// properties and methods appear above.
Index: People.Class.UserManager.php
===================================================================
--- People.Class.UserManager.php (revision 115)
+++ People.Class.UserManager.php (working copy)
@@ -579,12 +579,19 @@
return $this->Context->Database->Select($s, $this->Name, 'GetUserSearch', 'An error occurred while retrieving search results.');
}
+ /**
+ * Create a password hash.
+ *
+ * @deprecated
+ * @param string $Password
+ * @return string
+ */
function HashPassword($Password) {
- $PasswordHash = $this->Context->ObjectFactory->NewObject(
- $this->Context, 'PasswordHash',
- $this->Context->Configuration['PASSWORD_HASH_ITERATION'],
- $this->Context->Configuration['PASSWORD_HASH_PORTABLE']);
- return $PasswordHash->HashPassword($Password);
+ if (method_exists($this->Context->Authenticator, 'HashPassword')) {
+ return $this->Context->Authenticator->HashPassword($Password);
+ } else {
+ return md5($Password);
+ }
}
function GetSearchBuilder($Search) {
// extensions/Md5authenticator/default.php
<?php
/*
Extension Name: Md5Authenticator
Extension Url: http://lussumo.com/community/?CommentID=90404
Description: Replace Vanilla Authenticator to only use md5 hash
Version: 0.1.1
Author: Damien Lebrun
Author Url: N/A
*/
global $Context;
// Check for Vanilla 1.1.5 and that we didn't already installed our authenticator
if (array_key_exists('AUTHENTICATION_CLASS', $Context->Configuration)
&& $Context->Configuration['AUTHENTICATION_MODULE'] !== 'Md5Autehnticator'
) {
AddConfigurationSetting($Context,
'AUTHENTICATION_MODULE', '../extensions/Md5authenticator/Authenticator.php');
AddConfigurationSetting($Context,
'AUTHENTICATION_CLASS', 'Md5Authenticator');
}
// extensions/Md5authenticator/Authenticator.php
<?php
if (!defined('IN_VANILLA')) exit();
global $Configuration;
include_once $Configuration['LIBRARY_PATH'] . '/People/People.Class.Authenticator.php';
class Md5Authenticator extends Authenticator {
function Md5Authenticator(&$Context) {
$this->Context = &$Context;
$this->PasswordHash = new Md5Hash($Context);
}
}
class Md5Hash {
var $Context;
function CheckPassword($User, $Password, $RegenerateHash=1) {
if ($Password && $User->Password !== '*') {
if (md5($Password) === $User->Password) {
return true;
} else if ($Password === $User->Password ) {
if ($RegenerateHash) {
$this->SetNewPassword($User, $Password);
}
return true;
}
}
return false;
}
function HashPassword($Password) {
return md5($Password);
}
function Md5Hash(&$Context) {
$this->Context =& $Context;
}
function SetNewPassword($User, $Password) {
$UserManager = $this->Context->ObjectFactory->NewContextObject(
$this->Context, 'UserManager');
$User->Password = $this->HashPassword($Password);
return $UserManager->SaveUserCredentials($User);
}
}
1 to 50 of 50