Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Authentication/Core12.php
<?php

namespace XF\Authentication;

use function
intval, is_string;

class
Core12 extends AbstractAuth
{
    protected function
getDefaultOptions()
    {
       
$config = \XF::config();

        if (!empty(
$config['auth']))
        {
            return
array_replace([
               
'algo' => PASSWORD_BCRYPT,
               
'options' => []
            ],
$config['auth']);
        }
        else
        {
            return [
               
'algo' => PASSWORD_BCRYPT,
               
'options' => [
                   
'cost' => $config['passwordIterations']
                ]
            ];
        }
    }

    protected function
getHandler()
    {
        return new
PasswordHash(\XF::config('passwordIterations'), false);
    }

    public function
generate($password)
    {
       
$options = $this->getDefaultOptions();

       
$password = $this->truncatePassword($password);

       
$hash = password_hash($password, $options['algo'], $options['options']);

        return [
           
'hash' => $hash
       
];
    }

    public function
authenticate($userId, $password)
    {
        if (!
is_string($password) || $password === '' || empty($this->data))
        {
            return
false;
        }

       
$password = $this->truncatePassword($password);

        if (
$this->isLegacyHash())
        {
            return
$this->getHandler()->CheckPassword($password, $this->data['hash']);
        }
        else
        {
            return
password_verify($password, $this->data['hash']);
        }
    }

    public function
isUpgradable()
    {
        if (!empty(
$this->data['hash']))
        {
           
$hash = $this->data['hash'];
           
$options = $this->getDefaultOptions();

            if (
$this->isLegacyHash())
            {
               
$expectedIterations = min(intval($options['options']['cost']), 30);

               
preg_match('/^\$(P|H)\$(.)/i',  $hash, $match);
               
$iterations = $this->getHandler()->reverseItoA64($match[2]) - 5; // 5 iterations removed in PHP 5    

               
return $expectedIterations !== $iterations;
            }
            else
            {
                return
password_needs_rehash($hash, $options['algo'], $options['options']);
            }
        }

        return
true;
    }

   
/**
     * Explicitly limits the password length to mitigate a potential algorithm-specific DoS.
     * Note that algorithms may have their own internal limits applied, like bcrypt's 72 byte limit.
     *
     * We limit to 4K by default as that should exceed any reasonable password length.
     *
     * @param string $password
     *
     * @return string
     */
   
protected function truncatePassword(string $password): string
   
{
        return
substr($password, 0, 4096);
    }

    public function
getAuthenticationName()
    {
        return
'XF:Core12';
    }
}