From d3d7881e3b7087bc2783f4f884868cd7bab082f1 Mon Sep 17 00:00:00 2001 From: Deon George Date: Sat, 18 Jan 2025 16:42:03 +1100 Subject: [PATCH] Added additional password hashing functions --- app/Classes/LDAP/Attribute/Password.php | 62 ++- .../LDAP/Attribute/Password/Argon2i.php | 25 ++ .../LDAP/Attribute/Password/Argon2id.php | 25 ++ app/Classes/LDAP/Attribute/Password/Base.php | 56 ++- .../LDAP/Attribute/Password/Bcrypt.php | 22 + app/Classes/LDAP/Attribute/Password/Clear.php | 7 +- app/Classes/LDAP/Attribute/Password/MD5.php | 13 + app/Classes/LDAP/Attribute/Password/SHA.php | 13 + .../LDAP/Attribute/Password/SHA256.php | 13 + .../LDAP/Attribute/Password/SHA384.php | 13 + .../LDAP/Attribute/Password/SHA512.php | 13 + app/Classes/LDAP/Attribute/Password/SMD5.php | 22 + app/Classes/LDAP/Attribute/Password/SSHA.php | 19 + .../LDAP/Attribute/Password/SSHA256.php | 19 + .../LDAP/Attribute/Password/SSHA384.php | 19 + .../LDAP/Attribute/Password/SSHA512.php | 19 + app/Http/Controllers/HomeController.php | 17 +- app/helpers.php | 19 + lib/functions.php | 390 +----------------- public/css/custom.css | 2 +- .../components/attribute/password.blade.php | 4 +- .../views/components/form/select.blade.php | 2 +- resources/views/components/success.blade.php | 5 +- resources/views/components/updated.blade.php | 12 + resources/views/frames/dn.blade.php | 6 +- 25 files changed, 383 insertions(+), 434 deletions(-) create mode 100644 app/Classes/LDAP/Attribute/Password/Argon2i.php create mode 100644 app/Classes/LDAP/Attribute/Password/Argon2id.php create mode 100644 app/Classes/LDAP/Attribute/Password/Bcrypt.php create mode 100644 app/Classes/LDAP/Attribute/Password/MD5.php create mode 100644 app/Classes/LDAP/Attribute/Password/SHA.php create mode 100644 app/Classes/LDAP/Attribute/Password/SHA256.php create mode 100644 app/Classes/LDAP/Attribute/Password/SHA384.php create mode 100644 app/Classes/LDAP/Attribute/Password/SHA512.php create mode 100644 app/Classes/LDAP/Attribute/Password/SMD5.php create mode 100644 app/Classes/LDAP/Attribute/Password/SSHA.php create mode 100644 app/Classes/LDAP/Attribute/Password/SSHA256.php create mode 100644 app/Classes/LDAP/Attribute/Password/SSHA384.php create mode 100644 app/Classes/LDAP/Attribute/Password/SSHA512.php create mode 100644 resources/views/components/updated.blade.php diff --git a/app/Classes/LDAP/Attribute/Password.php b/app/Classes/LDAP/Attribute/Password.php index bacca92..66476af 100644 --- a/app/Classes/LDAP/Attribute/Password.php +++ b/app/Classes/LDAP/Attribute/Password.php @@ -6,7 +6,6 @@ use Illuminate\Contracts\View\View; use Illuminate\Support\Arr; use Illuminate\Support\Collection; -use App\Classes\LDAP\Attribute\Password\Base; use App\Classes\LDAP\Attribute; use App\Traits\MD5Updates; @@ -28,41 +27,54 @@ final class Password extends Attribute continue; $class = self::commands.preg_replace('/\.php$/','',$file); - if ($helpers->count()) - $helpers->push(''); $helpers = $helpers ->merge([$class::id()=>$class]); } - return $helpers; + return $helpers->sort(); + } + + /** + * Given an LDAP password syntax {xxx}yyyyyy, this function will return the object for xxx + * + * @param string $password + * @return Attribute\Password\Base|null + * @throws \Exception + */ + public static function hash(string $password): ?Attribute\Password\Base + { + $m = []; + preg_match('/^{([A-Z0-9]+)}(.*)$/',$password,$m); + + $hash = Arr::get($m,1,'*clear*'); + + if (($potential=static::helpers()->filter(fn($hasher)=>str_starts_with($hasher::id(),$hash)))->count() > 1) { + foreach ($potential as $item) { + if ($item::subid($password)) + return new $item; + } + + throw new \Exception(sprintf('Couldnt figure out a password hash for %s',$password)); + + } elseif (! $potential->count()) { + throw new \Exception(sprintf('Couldnt figure out a password hash for %s',$password)); + } + + return new ($potential->pop()); } /** * Return the object that will process a password * * @param string $id - * @return Base|null + * @return Attribute\Password\Base|null */ - public static function hash(string $id): ?Attribute\Password\Base + public static function hash_id(string $id): ?Attribute\Password\Base { return ($helpers=static::helpers())->has($id) ? new ($helpers->get($id)) : NULL; } - /** - * Given an LDAP password syntax {xxx}yyyyyy, this function will return xxx - * - * @param string $password - * @return string - */ - public static function hash_id(string $password): string - { - $m = []; - preg_match('/^{([A-Z]+)}(.*)$/',$password,$m); - - return Arr::get($m,1,'Clear'); - } - public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View { return view('components.attribute.password') @@ -75,11 +87,17 @@ final class Password extends Attribute public function render_item_old(int $key): ?string { - return Arr::get($this->oldValues,$key) ? str_repeat('x',8) : NULL; + $pw = Arr::get($this->oldValues,$key); + return $pw + ? (((($x=$this->hash($pw)) && ($x::id() !== '*clear*')) ? sprintf('{%s}',$x::shortid()) : '').str_repeat('*',16)) + : NULL; } public function render_item_new(int $key): ?string { - return Arr::get($this->values,$key) ? str_repeat('x',8) : NULL; + $pw = Arr::get($this->values,$key); + return $pw + ? (((($x=$this->hash($pw)) && ($x::id() !== '*clear*')) ? sprintf('{%s}',$x::shortid()) : '').str_repeat('*',16)) + : NULL; } } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password/Argon2i.php b/app/Classes/LDAP/Attribute/Password/Argon2i.php new file mode 100644 index 0000000..efe39e0 --- /dev/null +++ b/app/Classes/LDAP/Attribute/Password/Argon2i.php @@ -0,0 +1,25 @@ +password($source))); + } + + public function encode(string $password): string + { + return sprintf('{%s}%s',self::key,base64_encode(password_hash($password,PASSWORD_ARGON2I))); + } +} \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password/Argon2id.php b/app/Classes/LDAP/Attribute/Password/Argon2id.php new file mode 100644 index 0000000..db50137 --- /dev/null +++ b/app/Classes/LDAP/Attribute/Password/Argon2id.php @@ -0,0 +1,25 @@ +password($source))); + } + + public function encode(string $password): string + { + return sprintf('{%s}%s',self::key,base64_encode(password_hash($password,PASSWORD_ARGON2ID))); + } +} \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password/Base.php b/app/Classes/LDAP/Attribute/Password/Base.php index 160466d..2f86c45 100644 --- a/app/Classes/LDAP/Attribute/Password/Base.php +++ b/app/Classes/LDAP/Attribute/Password/Base.php @@ -4,11 +4,65 @@ namespace App\Classes\LDAP\Attribute\Password; abstract class Base { - abstract public function compare(string $source,string $compare): bool; + protected const subkey = ''; + abstract public function encode(string $password): string; public static function id(): string + { + return static::key.(static::subkey ? ':'.static::subkey : ''); + } + + /** + * Remove the hash {TEXT}xxxx from the password + * + * @param string $password + * @return string + */ + protected static function password(string $password): string + { + return preg_replace('/^{'.static::key.'}/','',$password); + } + + public static function shortid(): string { return static::key; } + + /** + * When multiple passwords share the same ID, this determines which hash is responsible for the presented password + * + * @param string $password + * @return bool + */ + public static function subid(string $password): bool + { + return FALSE; + } + + /** + * Compare our password to see if it is the same as that stored + * + * @param string $source Encoded source password + * @param string $compare Password entered by user + * @return bool + */ + public function compare(string $source,string $compare): bool + { + return $source === $this->encode($compare); + } + + protected function salted_hash(string $password,string $algo,int $salt_size=8,string $salt=NULL): string + { + if (is_null($salt)) + $salt = hex2bin(random_salt($salt_size)); + + return base64_encode(hash($algo,$password.$salt,true).$salt); + } + + protected function salted_salt(string $source): string + { + $hash = base64_decode(substr($source,strlen(static::key)+2)); + return substr($hash,strlen($hash)-static::salt/2); + } } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password/Bcrypt.php b/app/Classes/LDAP/Attribute/Password/Bcrypt.php new file mode 100644 index 0000000..365ff93 --- /dev/null +++ b/app/Classes/LDAP/Attribute/Password/Bcrypt.php @@ -0,0 +1,22 @@ + 8, + ]; + + public function compare(string $source,string $compare): bool + { + return password_verify($compare,base64_decode($this->password($source))); + } + + public function encode(string $password): string + { + return sprintf('{%s}%s',self::key,base64_encode(password_hash($password,PASSWORD_BCRYPT,self::options))); + } +} \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password/Clear.php b/app/Classes/LDAP/Attribute/Password/Clear.php index d4345eb..946ba2f 100644 --- a/app/Classes/LDAP/Attribute/Password/Clear.php +++ b/app/Classes/LDAP/Attribute/Password/Clear.php @@ -4,12 +4,7 @@ namespace App\Classes\LDAP\Attribute\Password; final class Clear extends Base { - public const key = 'Clear'; - - public function compare(string $source,string $compare): bool - { - return $source === $compare; - } + public const key = '*clear*'; public function encode(string $password): string { diff --git a/app/Classes/LDAP/Attribute/Password/MD5.php b/app/Classes/LDAP/Attribute/Password/MD5.php new file mode 100644 index 0000000..c460d38 --- /dev/null +++ b/app/Classes/LDAP/Attribute/Password/MD5.php @@ -0,0 +1,13 @@ +encode($compare,$this->salted_salt($source)); + } + + public function encode(string $password,string $salt=NULL): string + { + if (is_null($salt)) + $salt = hex2bin(random_salt(self::salt)); + + return sprintf('{%s}%s',self::key,$this->salted_hash($password,'md5',self::salt,$salt)); + } +} \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password/SSHA.php b/app/Classes/LDAP/Attribute/Password/SSHA.php new file mode 100644 index 0000000..4b4a982 --- /dev/null +++ b/app/Classes/LDAP/Attribute/Password/SSHA.php @@ -0,0 +1,19 @@ +encode($compare,$this->salted_salt($source)); + } + + public function encode(string $password,string $salt=NULL): string + { + return sprintf('{%s}%s',self::key,$this->salted_hash($password,'sha1',self::salt,$salt)); + } +} \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password/SSHA256.php b/app/Classes/LDAP/Attribute/Password/SSHA256.php new file mode 100644 index 0000000..d171a1a --- /dev/null +++ b/app/Classes/LDAP/Attribute/Password/SSHA256.php @@ -0,0 +1,19 @@ +encode($compare,$this->salted_salt($source)); + } + + public function encode(string $password,string $salt=NULL): string + { + return sprintf('{%s}%s',self::key,$this->salted_hash($password,'sha256',self::salt,$salt)); + } +} \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password/SSHA384.php b/app/Classes/LDAP/Attribute/Password/SSHA384.php new file mode 100644 index 0000000..d2224b9 --- /dev/null +++ b/app/Classes/LDAP/Attribute/Password/SSHA384.php @@ -0,0 +1,19 @@ +encode($compare,$this->salted_salt($source)); + } + + public function encode(string $password,string $salt=NULL): string + { + return sprintf('{%s}%s',self::key,$this->salted_hash($password,'sha384',self::salt,$salt)); + } +} \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password/SSHA512.php b/app/Classes/LDAP/Attribute/Password/SSHA512.php new file mode 100644 index 0000000..677ff01 --- /dev/null +++ b/app/Classes/LDAP/Attribute/Password/SSHA512.php @@ -0,0 +1,19 @@ +encode($compare,$this->salted_salt($source)); + } + + public function encode(string $password,string $salt=NULL): string + { + return sprintf('{%s}%s',self::key,$this->salted_hash($password,'sha512',self::salt,$salt)); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 53a9331..8e02b3d 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -99,11 +99,11 @@ class HomeController extends Controller $result = collect(); foreach ($password as $key => $value) { - $type = $password->hash_id($value); + $hash = $password->hash($value); $compare = Arr::get($request->password,$key); - //Log::debug(sprintf('comparing [%s] with [%s] type [%s]',$value,$compare,$type)); + //Log::debug(sprintf('comparing [%s] with [%s] type [%s]',$value,$compare,$hash::id()),['object'=>$hash]); - $result->push((($compare !== NULL) && Attribute\Password::hash($type)->compare($value,$compare)) ? 'OK' :'FAIL'); + $result->push((($compare !== NULL) && $hash->compare($value,$compare)) ? 'OK' :'FAIL'); } return $result; @@ -128,9 +128,15 @@ class HomeController extends Controller // We need to process and encrypt the password $passwords = []; foreach ($request->userpassword as $key => $value) { + // If the password is still the MD5 of the old password, then it hasnt changed + if (($old=Arr::get($o->userpassword,$key)) && ($value === md5($old))) { + array_push($passwords,$old); + continue; + } + if ($value) { $type = Arr::get($request->userpassword_hash,$key); - array_push($passwords,Attribute\Password::hash($type)->encode($value)); + array_push($passwords,Attribute\Password::hash_id($type)->encode($value)); } } $o->userpassword = $passwords; @@ -199,8 +205,7 @@ class HomeController extends Controller return Redirect::to('/') ->withInput() - ->with('success',__('Entry updated')) - ->with('updated',$dirty); + ->with('updated',collect($dirty)->map(fn($key,$item)=>$o->getObject($item))); } /** diff --git a/app/helpers.php b/app/helpers.php index 2dd92a0..f172adb 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -10,4 +10,23 @@ function login_attr_description(): string function login_attr_name(): string { return key(config('ldap.login.attr')); +} + +/** + * Used to generate a random salt for crypt-style passwords. Salt strings are used + * to make pre-built hash cracking dictionaries difficult to use as the hash algorithm uses + * not only the user's password but also a randomly generated string. The string is + * stored as the first N characters of the hash for reference of hashing algorithms later. + * + * @param int $length The length of the salt string to generate. + * @return string The generated salt string. + * @throws \Random\RandomException + */ +function random_salt(int $length): string +{ + $str = bin2hex(random_bytes(ceil($length/2))); + if ($length%2 === 1) + return substr($str,0,-1); + + return $str; } \ No newline at end of file diff --git a/lib/functions.php b/lib/functions.php index a06c813..d5135c8 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -670,7 +670,7 @@ function get_request($attr,$type='POST',$die=false,$default=null,$preventXSS=tru $value = isset($_POST[$attr]) ? (is_array($_POST[$attr]) ? $_POST[$attr] : (empty($_POST['nodecode'][$attr]) ? rawurldecode($_POST[$attr]) : $_POST[$attr])) : $default; break; } - + if ($die && is_null($value)) system_message(array( 'title'=>_('Generic Error'), @@ -1757,32 +1757,6 @@ function expand_dn_with_base($base,$sub_dn) { return sprintf('%s%s',$sub_dn,$base); } -/** - * Used to generate a random salt for crypt-style passwords. Salt strings are used - * to make pre-built hash cracking dictionaries difficult to use as the hash algorithm uses - * not only the user's password but also a randomly generated string. The string is - * stored as the first N characters of the hash for reference of hashing algorithms later. - * - * @param int The length of the salt string to generate. - * @return string The generated salt string. - */ -function random_salt($length) { - if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) - debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); - - $possible = '0123456789'. - 'abcdefghijklmnopqrstuvwxyz'. - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. - './'; - $str = ''; - mt_srand((double)microtime() * 1000000); - - while (strlen($str) < $length) - $str .= substr($possible,(rand()%strlen($possible)),1); - - return $str; -} - /** * Split an RDN into its attributes */ @@ -1999,368 +1973,6 @@ function draw_jpeg_photo($server,$dn,$attr_name='jpegphoto',$index,$draw_delete_ $attr_name,_('Delete photo')); } -/** - * Return the list of available password types - * - * @todo Dynamically work this list out so we only present hashes that we can encrypt - */ -function password_types() { - if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) - debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); - - return array( - ''=>'clear', - 'bcrypt'=>'bcrypt', - 'blowfish'=>'blowfish', - 'crypt'=>'crypt', - 'ext_des'=>'ext_des', - 'md5'=>'md5', - 'k5key'=>'k5key', - 'md5crypt'=>'md5crypt', - 'sha'=>'sha', - 'smd5'=>'smd5', - 'ssha'=>'ssha', - 'sha512'=>'sha512', - 'sha256crypt'=>'sha256crypt', - 'sha512crypt'=>'sha512crypt', - ); -} - -/** - * Hashes a password and returns the hash based on the specified enc_type. - * - * @param string The password to hash in clear text. - * @param string Standard LDAP encryption type which must be one of - * crypt, ext_des, md5crypt, blowfish, md5, sha, smd5, ssha, sha512, - * sha256crypt, sha512crypt, or clear. - * @return string The hashed password. - */ -function pla_password_hash($password_clear,$enc_type) { - if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) - debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); - - $enc_type = strtolower($enc_type); - - switch($enc_type) { - case 'blowfish': - if (! defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH == 0) - error(_('Your system crypt library does not support blowfish encryption.'),'error','index.php'); - - # Hardcoded to second blowfish version and set number of rounds - $new_value = sprintf('{CRYPT}%s',crypt($password_clear,'$2a$12$'.random_salt(13))); - - break; - - case 'crypt': - if ($_SESSION[APPCONFIG]->getValue('password', 'no_random_crypt_salt')) - $new_value = sprintf('{CRYPT}%s',crypt($password_clear,substr($password_clear,0,2))); - else - $new_value = sprintf('{CRYPT}%s',crypt($password_clear,random_salt(2))); - - break; - - case 'ext_des': - # Extended des crypt. see OpenBSD crypt man page. - if (! defined('CRYPT_EXT_DES') || CRYPT_EXT_DES == 0) - error(_('Your system crypt library does not support extended DES encryption.'),'error','index.php'); - - $new_value = sprintf('{CRYPT}%s',crypt($password_clear,'_'.random_salt(8))); - - break; - - case 'k5key': - $new_value = sprintf('{K5KEY}%s',$password_clear); - - system_message(array( - 'title'=>_('Unable to Encrypt Password'), - 'body'=>'phpLDAPadmin cannot encrypt K5KEY passwords', - 'type'=>'warn')); - - break; - - case 'md5': - $new_value = sprintf('{MD5}%s',base64_encode(pack('H*',md5($password_clear)))); - break; - - case 'md5crypt': - if (! defined('CRYPT_MD5') || CRYPT_MD5 == 0) - error(_('Your system crypt library does not support md5crypt encryption.'),'error','index.php'); - - $new_value = sprintf('{CRYPT}%s',crypt($password_clear,'$1$'.random_salt(9))); - - break; - - case 'sha': - # Use php 4.3.0+ sha1 function, if it is available. - if (function_exists('sha1')) - $new_value = sprintf('{SHA}%s',base64_encode(pack('H*',sha1($password_clear)))); - elseif (function_exists('mhash')) - $new_value = sprintf('{SHA}%s',base64_encode(mhash(MHASH_SHA1,$password_clear))); - else - error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php'); - - break; - - case 'ssha': - if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) { - mt_srand((double)microtime()*1000000); - $salt = mhash_keygen_s2k(MHASH_SHA1,$password_clear,substr(pack('h*',md5(mt_rand())),0,8),4); - $new_value = sprintf('{SSHA}%s',base64_encode(mhash(MHASH_SHA1,$password_clear.$salt).$salt)); - - } else { - error(_('Your PHP install does not have the mhash() or mhash_keygen_s2k() function. Cannot do S2K hashes.'),'error','index.php'); - } - - break; - - case 'bcrypt': - $options = [ - 'cost' => 8, - ]; - #Checking if password_hash() function is available. - if (function_exists('password_hash')) - $new_value = sprintf('{BCRYPT}%s',base64_encode(password_hash($password_clear, PASSWORD_BCRYPT, $options))); - else - error(_('Your PHP install does not have the password_hash() function. Cannot do BCRYPT hashes.'),'error','index.php'); - - break; - - - 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); - $new_value = sprintf('{SMD5}%s',base64_encode(mhash(MHASH_MD5,$password_clear.$salt).$salt)); - - } else { - error(_('Your PHP install does not have the mhash() or mhash_keygen_s2k() function. Cannot do S2K hashes.'),'error','index.php'); - } - - break; - - case 'sha512': - if (function_exists('openssl_digest') && function_exists('base64_encode')) { - $new_value = sprintf('{SHA512}%s', base64_encode(openssl_digest($password_clear, 'sha512', true))); - - } else { - error(_('Your PHP install doest not have the openssl_digest() or base64_encode() function. Cannot do SHA512 hashes. '),'error','index.php'); - } - - break; - - case 'sha256crypt': - if (! defined('CRYPT_SHA256') || CRYPT_SHA256 == 0) - error(_('Your system crypt library does not support sha256crypt encryption.'),'error','index.php'); - $new_value = sprintf('{CRYPT}%s',crypt($password_clear,'$5$'.random_salt(8))); - - break; - - case 'sha512crypt': - if (! defined('CRYPT_SHA512') || CRYPT_SHA512 == 0) - error(_('Your system crypt library does not support sha512crypt encryption.'),'error','index.php'); - $new_value = sprintf('{CRYPT}%s',crypt($password_clear,'$6$'.random_salt(8))); - - break; - - case 'clear': - default: - $new_value = $password_clear; - } - - return $new_value; -} - -/** - * Given a clear-text password and a hash, this function determines if the clear-text password - * is the password that was used to generate the hash. This is handy to verify a user's password - * when all that is given is the hash and a "guess". - * @param String The hash. - * @param String The password in clear text to test. - * @return Boolean True if the clear password matches the hash, and false otherwise. - */ -function password_check($cryptedpassword,$plainpassword,$attribute='userpassword') { - $plainpassword = htmlspecialchars_decode($plainpassword); - if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) - debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); - - if (in_array($attribute,array('sambalmpassword','sambantpassword'))) { - $smb = new smbHash; - - switch($attribute) { - case 'sambalmpassword': - if (strcmp($smb->lmhash($plainpassword),strtoupper($cryptedpassword)) == 0) - return true; - else - return false; - - case 'sambantpassword': - if (strcmp($smb->nthash($plainpassword),strtoupper($cryptedpassword)) == 0) - return true; - else - return false; - } - - return false; - } - - if (preg_match('/{([^}]+)}(.*)/',$cryptedpassword,$matches)) { - $cryptedpassword = $matches[2]; - $cypher = strtolower($matches[1]); - - } else { - $cypher = null; - } - - switch($cypher) { - # SSHA crypted passwords - case 'ssha': - # Check php mhash support before using it - if (function_exists('mhash')) { - $hash = base64_decode($cryptedpassword); - - # OpenLDAP uses a 4 byte salt, SunDS uses an 8 byte salt - both from char 20. - $salt = substr($hash,20); - $new_hash = base64_encode(mhash(MHASH_SHA1,$plainpassword.$salt).$salt); - - if (strcmp($cryptedpassword,$new_hash) == 0) - return true; - else - return false; - - } else { - error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php'); - } - - break; - - #BCRYPT hashed passwords - case 'bcrypt': - # Check php password_verify support before using it - if (function_exists('password_verify')) { - $hash = base64_decode($cryptedpassword); - if (password_verify($plainpassword, $hash)) { - return true; - } else { - return false; - } - - } else { - error(_('Your PHP install does not have the password_verify() function. Cannot do Bcrypt hashes.'),'error','index.php'); - } - - break; - - # Salted MD5 - case 'smd5': - # Check php mhash support before using it - if (function_exists('mhash')) { - $hash = base64_decode($cryptedpassword); - $salt = substr($hash,16); - $new_hash = base64_encode(mhash(MHASH_MD5,$plainpassword.$salt).$salt); - - if (strcmp($cryptedpassword,$new_hash) == 0) - return true; - else - return false; - - } else { - error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php'); - } - - break; - - # SHA crypted passwords - case 'sha': - if (strcasecmp(pla_password_hash($plainpassword,'sha'),'{SHA}'.$cryptedpassword) == 0) - return true; - else - return false; - - break; - - # MD5 crypted passwords - case 'md5': - if( strcasecmp(pla_password_hash($plainpassword,'md5'),'{MD5}'.$cryptedpassword) == 0) - return true; - else - return false; - - break; - - # Crypt passwords - case 'crypt': - # Check if it's blowfish crypt - if (preg_match('/^\\$2+/',$cryptedpassword)) { - - # Make sure that web server supports blowfish crypt - if (! defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH == 0) - error(_('Your system crypt library does not support blowfish encryption.'),'error','index.php'); - - list($version,$rounds,$salt_hash) = explode('$',$cryptedpassword); - - if (crypt($plainpassword,'$'.$version.'$'.$rounds.'$'.$salt_hash) == $cryptedpassword) - return true; - else - return false; - } - - # Check if it's an crypted md5 - elseif (strstr($cryptedpassword,'$1$')) { - - # Make sure that web server supports md5 crypt - if (! defined('CRYPT_MD5') || CRYPT_MD5 == 0) - error(_('Your system crypt library does not support md5crypt encryption.'),'error','index.php'); - - list($dummy,$type,$salt,$hash) = explode('$',$cryptedpassword); - - if (crypt($plainpassword,'$1$'.$salt) == $cryptedpassword) - return true; - else - return false; - } - - # Check if it's extended des crypt - elseif (strstr($cryptedpassword,'_')) { - - # Make sure that web server supports ext_des - if (! defined('CRYPT_EXT_DES') || CRYPT_EXT_DES == 0) - error(_('Your system crypt library does not support extended DES encryption.'),'error','index.php'); - - if (crypt($plainpassword,$cryptedpassword) == $cryptedpassword) - return true; - else - return false; - } - - # Password is plain crypt - else { - - if (crypt($plainpassword,$cryptedpassword) == $cryptedpassword) - return true; - else - return false; - } - - break; - - # SHA512 crypted passwords - case 'sha512': - if (strcasecmp(pla_password_hash($plainpassword,'sha512'),'{SHA512}'.$cryptedpassword) == 0) - return true; - else - return false; - - break; - - # No crypt is given assume plaintext passwords are used - default: - if ($plainpassword == $cryptedpassword) - return true; - else - return false; - } -} - /** * Detects password encryption type * diff --git a/public/css/custom.css b/public/css/custom.css index eef973f..dcdb3bb 100644 --- a/public/css/custom.css +++ b/public/css/custom.css @@ -9,7 +9,7 @@ div#userpassword .select2-container--bootstrap-5 .select2-selection { font-size: inherit; border-bottom-right-radius: unset; border-top-right-radius: unset; - width: 7em; + width: 9em; border: #444054 1px solid; background-color: #f0f0f0; } \ No newline at end of file diff --git a/resources/views/components/attribute/password.blade.php b/resources/views/components/attribute/password.blade.php index 4af4573..56f0bad 100644 --- a/resources/views/components/attribute/password.blade.php +++ b/resources/views/components/attribute/password.blade.php @@ -3,7 +3,7 @@ @foreach($o->values as $value) @if($edit)
- + ($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>$o->values->contains($value)]) name="{{ $o->name_lc }}[]" value="{{ md5($value) }}" @readonly(true)>
@@ -13,7 +13,7 @@
@else - {{ (($x=$o->hash_id($value)) && ($x !== 'Clear')) ? sprintf('{%s}',$x) : '' }}{{ str_repeat('x',8) }} + {{ (($x=$o->hash($value)) && ($x::id() !== '*clear*')) ? sprintf('{%s}',$x::shortid()) : '' }}{{ str_repeat('*',16) }} @endif @endforeach diff --git a/resources/views/components/form/select.blade.php b/resources/views/components/form/select.blade.php index c9d0953..8ebfc6c 100644 --- a/resources/views/components/form/select.blade.php +++ b/resources/views/components/form/select.blade.php @@ -1,6 +1,6 @@ @isset($name) - + @endisset