diff --git a/doc/conf/LSattribute/LSattr_html/LSattr_html_password.docbook b/doc/conf/LSattribute/LSattr_html/LSattr_html_password.docbook
index ecbfa7ce..124675e4 100644
--- a/doc/conf/LSattribute/LSattr_html/LSattr_html_password.docbook
+++ b/doc/conf/LSattribute/LSattr_html/LSattr_html_password.docbook
@@ -44,9 +44,9 @@
isLoginPassword
Booléen définissant si le mot de passe est celui utilisé par l'utilisateur
- pour se logguer à l'annuaire LDAP. Si c'est le cas, le mot de passe saisi dans le
- formulaire sera utilisé pour une tentative de connexion de l'utilisateur afin de
- déterminer si le mot de passe a été modifié ou non. (Par défaut : Vrai)
+ pour se logguer à l'annuaire LDAP. Si c'est le cas, pour vérifier si le mot de passe
+ correspond avec un autre, une tentative de connexion de l'utilisateur à l'annuaire
+ sera faite. (Par défaut : Faux)
diff --git a/public_html/includes/class/class.LSattr_ldap_password.php b/public_html/includes/class/class.LSattr_ldap_password.php
index ef4c146c..66bc52b7 100644
--- a/public_html/includes/class/class.LSattr_ldap_password.php
+++ b/public_html/includes/class/class.LSattr_ldap_password.php
@@ -111,9 +111,11 @@ class LSattr_ldap_password extends LSattr_ldap {
*
* @retval strinf The encode password
*/
- public function encodePassword($clearPassword) {
- $encode = $this -> getConfig('ldap_options.encode', 'md5crypt', 'string');
- $encode_function = $this -> getConfig('ldap_options.encode_function');
+ public function encodePassword($clearPassword, $encode=null, $encode_function=null, $salt=null) {
+ if (is_null($encode))
+ $encode = $this -> getConfig('ldap_options.encode', 'md5crypt', 'string');
+ if (is_null($encode_function))
+ $encode_function = $this -> getConfig('ldap_options.encode_function');
if ($encode_function || $encode == 'function') {
if ( (!$encode_function) || (!is_callable($encode_function)) ) {
$encode = 'clear';
@@ -130,7 +132,9 @@ class LSattr_ldap_password extends LSattr_ldap {
return '{CRYPT}' . crypt($clearPassword,substr($clearPassword,0,2));
}
else {
- return '{CRYPT}' . crypt($clearPassword,$this -> getSalt(2));
+ if (is_null($salt))
+ $salt = $this -> getSalt(2);
+ return '{CRYPT}' . crypt($clearPassword, $salt);
}
break;
case 'ext_des':
@@ -138,7 +142,9 @@ class LSattr_ldap_password extends LSattr_ldap {
LSerror :: addErrorCode('LSattr_ldap_password_01','ext_des');
}
else {
- return '{CRYPT}' . crypt( $clearPassword, '_' . $this -> getSalt(8) );
+ if (is_null($salt))
+ $salt = $this -> getSalt(8);
+ return '{CRYPT}' . crypt( $clearPassword, '_' . $salt );
}
break;
case 'blowfish':
@@ -146,7 +152,9 @@ class LSattr_ldap_password extends LSattr_ldap {
LSerror :: addErrorCode('LSattr_ldap_password_01','blowfish');
}
else {
- return '{CRYPT}' . crypt( $clearPassword, '$2a$12$' . $this -> getSalt(13) );
+ if (is_null($salt))
+ $salt = '$2y$12$' . $this -> getSalt(22);
+ return '{CRYPT}' . crypt( $clearPassword, $salt );
}
break;
case 'sha':
@@ -191,7 +199,8 @@ class LSattr_ldap_password extends LSattr_ldap {
}
if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) {
mt_srand( (double) microtime() * 1000000 );
- $salt = mhash_keygen_s2k( $mhash_type, $clearPassword, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
+ if (is_null($salt))
+ $salt = mhash_keygen_s2k( $mhash_type, $clearPassword, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
return "{".strtoupper($encode)."}".base64_encode( mhash( $mhash_type, $clearPassword.$salt ).$salt );
}
else {
@@ -201,8 +210,9 @@ class LSattr_ldap_password extends LSattr_ldap {
case 'smd5':
if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) {
mt_srand( (double) microtime() * 1000000 );
- $salt = mhash_keygen_s2k( MHASH_MD5, $password_clear, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
- return "{SMD5}".base64_encode( mhash( MHASH_MD5, $password_clear.$salt ).$salt );
+ if (is_null($salt))
+ $salt = mhash_keygen_s2k( MHASH_MD5, $password_clear, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
+ return "{SMD5}".base64_encode( mhash( MHASH_MD5, $clearPassword.$salt ).$salt );
}
else {
LSerror :: addErrorCode('LSattr_ldap_password_01','smd5');
@@ -216,7 +226,9 @@ class LSattr_ldap_password extends LSattr_ldap {
LSerror :: addErrorCode('LSattr_ldap_password_01','md5crypt');
}
else {
- return '{CRYPT}'.crypt($clearPassword,'$1$'.$this -> getSalt().'$');
+ if (is_null($salt))
+ $salt = $this -> getSalt();
+ return '{CRYPT}'.crypt($clearPassword,'$1$'.$salt.'$');
}
break;
case 'clear':
@@ -229,6 +241,102 @@ class LSattr_ldap_password extends LSattr_ldap {
LSerror :: addErrorCode('LSattr_ldap_password_01', $encode);
return $clearPassword;
}
+
+ function verify($clearPassword, $hashedPassword=null) {
+ // If $hashedPassword is not provided, use attribute values
+ if (is_null($hashedPassword))
+ $hashedPassword = $this -> attribute -> getValue();
+
+ // If $hashedPassword is array, iter to find valid password
+ if (is_array($hashedPassword)) {
+ foreach($hashedPassword as $pwd)
+ if ($this -> verify($clearPassword, $pwd))
+ return true;
+ return false;
+ }
+ // Verify $hashedPassword is a string
+ elseif (!is_string($hashedPassword))
+ return false;
+
+ // Custom verify function configured ? If yes, use it
+ $verifyFunction = $this -> getConfig('ldap_options.verify_function', null);
+ if (!is_null($verifyFunction) && is_callable($verifyFunction))
+ return call_user_func($verifyFunction, $clearPassword, $hashedPassword);
+
+ // Custom encode function configured ? If yes, use it
+ $encodeFunction = $this -> getConfig('ldap_options.encode_function', null);
+ if (!is_null($encodeFunction) && is_callable($encodeFunction))
+ return (strcasecmp(call_user_func_array($encodeFunction, array(&$this -> attribute -> ldapObject, $clearPassword)), $hashedPassword) == 0);
+
+ // Extract cipher
+ if (preg_match('/{([^}]+)}(.*)/',$hashedPassword,$matches)) {
+ $hashedPasswordData = $matches[2];
+ $cypher = strtolower($matches[1]);
+
+ } else {
+ $cypher = null;
+ }
+
+ // Verify password according on cypher
+ switch($cypher) {
+ # SSHA crypted passwords
+ case 'ssha':
+ case 'ssha256':
+ case 'ssha512':
+ case 'smd5':
+ $data = base64_decode($hashedPasswordData);
+ # Salt = last 4 bytes
+ $salt = substr($data, -4);
+ $new_hash = $this -> encodePassword($clearPassword, $cypher, null, $salt);
+ return (strcmp($hashedPassword,$new_hash) == 0);
+ break;
+
+ # Non-salted cyphers
+ case 'sha':
+ case 'sha256':
+ case 'sha512':
+ case 'md5':
+ $new_hash = $this -> encodePassword($clearPassword, $cypher);
+ return (strcasecmp($new_hash, $hashedPassword) == 0);
+ break;
+
+ # Crypt passwords
+ case 'crypt':
+ # Check if it's blowfish crypt
+ if (preg_match('/^\\$2+/',$hashedPasswordData)) {
+ list($dummy, $version, $rounds, $salt_hash) = explode('$',$hashedPasswordData);
+ $salt = '$'.$version.'$'.$rounds.'$'.substr($salt_hash, 0, 22);
+ $new_hash = $this -> encodePassword($clearPassword, 'blowfish', null, $salt);
+ return (strcasecmp($new_hash, $hashedPassword) == 0);
+ }
+
+ # Check if it's an md5crypt
+ elseif (strstr($hashedPasswordData,'$1$')) {
+ list($dummy,$type,$salt,$hash) = explode('$',$hashedPasswordData);
+ $new_hash = $this -> encodePassword($clearPassword, 'md5crypt', null, $salt);
+ return (strcasecmp($new_hash, $hashedPassword) == 0);
+ }
+
+ # Check if it's ext_des crypt
+ elseif (strstr($hashedPasswordData,'_')) {
+ return (crypt($clearPassword,$hashedPasswordData) == $hashedPasswordData);
+ }
+
+ # Password is plain crypt
+ else {
+ return (crypt($clearPassword,$hashedPasswordData) == $hashedPasswordData);
+ }
+
+ break;
+
+ # No crypt is given
+ default:
+ # Assume is a plaintext password
+ return (strcasecmp($clearPassword, $hashedPassword) == 0);
+ }
+ // It's supposed to never append, but just in case, return false
+ return false;
+ }
/**
* Return salt (random string)
diff --git a/public_html/includes/class/class.LSformElement_password.php b/public_html/includes/class/class.LSformElement_password.php
index 90310255..f7379418 100644
--- a/public_html/includes/class/class.LSformElement_password.php
+++ b/public_html/includes/class/class.LSformElement_password.php
@@ -197,25 +197,10 @@ class LSformElement_password extends LSformElement {
return false;
}
if ($this -> isLoginPassword()) {
- return LSsession :: checkUserPwd($this -> attr_html -> attribute -> ldapObject,$pwd);
+ return LSsession :: checkUserPwd($this -> attr_html -> attribute -> ldapObject, $pwd);
}
else {
- $hash = $this -> attr_html -> attribute -> ldap -> encodePassword($pwd);
- $find=false;
- if (is_array($this -> attr_html -> attribute -> data)) {
- $data = $this -> attr_html -> attribute -> data;
- }
- elseif (!is_array($this -> attr_html -> attribute -> data) && !empty($this -> attr_html -> attribute -> data)) {
- $data = array($this -> attr_html -> attribute -> data);
- }
- else {
- return $find;
- }
- foreach($data as $val) {
- if ($hash == $val)
- $find=true;
- }
- return $find;
+ return $this -> attr_html -> attribute -> ldap -> verify($pwd);
}
}
@@ -351,7 +336,7 @@ class LSformElement_password extends LSformElement {
}
public function isLoginPassword() {
- return $this -> getParam('html_options.isLoginPassword', true);
+ return $this -> getParam('html_options.isLoginPassword', false, 'bool');
}
}