%PDF- %PDF-
| Direktori : /proc/self/root/backups/router/usr/local/opnsense/mvc/app/library/OPNsense/Auth/ |
| Current File : //proc/self/root/backups/router/usr/local/opnsense/mvc/app/library/OPNsense/Auth/Local.php |
<?php
/*
* Copyright (C) 2015-2023 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\Auth;
use OPNsense\Core\Config;
/**
* Class Local user database connector (using legacy xml structure).
* @package OPNsense\Auth
*/
class Local extends Base implements IAuthConnector
{
/**
* type name in configuration
* @return string
*/
public static function getType()
{
return 'local';
}
/**
* set connector properties
* @param array $config connection properties
*/
public function setProperties($config)
{
// local authenticator doesn't use any additional settings.
}
/**
* unused
* @return array mixed named list of authentication properties
*/
public function getLastAuthProperties()
{
return array();
}
/**
* check if password meets policy constraints
* @param string $username username to check
* @param string $old_password current password
* @param string $new_password password to check
* @return array of unmet policy constraints
*/
public function checkPolicy($username, $old_password, $new_password)
{
$result = array();
$configObj = Config::getInstance()->object();
if (!empty($configObj->system->webgui->enable_password_policy_constraints)) {
if (!empty($configObj->system->webgui->password_policy_length)) {
if (strlen($new_password) < $configObj->system->webgui->password_policy_length) {
$result[] = sprintf(
gettext("Password must have at least %d characters"),
$configObj->system->webgui->password_policy_length
);
}
}
if (!empty($configObj->system->webgui->password_policy_complexity)) {
$pwd_has_upper = preg_match_all('/[A-Z]/', $new_password, $o) > 0;
$pwd_has_lower = preg_match_all('/[a-z]/', $new_password, $o) > 0;
$pwd_has_number = preg_match_all('/[0-9]/', $new_password, $o) > 0;
$pwd_has_special = preg_match_all('/[!@#$%^&*()\-_=+{};:,<.>]/', $new_password, $o) > 0;
if ($old_password == $new_password) {
// equal password is not allowed
$result[] = gettext("Current password equals new password");
}
if (($pwd_has_upper + $pwd_has_lower + $pwd_has_number + $pwd_has_special) < 3) {
// passwords should at least contain 3 of the 4 available character types
$result[] = gettext("Password should contain at least 3 of the 4 different character groups" .
" (lowercase, uppercase, number, special)");
} elseif (strpos($new_password, $username) !== false) {
$result[] = gettext("The username may not be a part of the password");
}
}
}
return $result;
}
/**
* check if the user should change his or her password,
* calculated by the time difference of the last pwd change
* and other criteria through checkPolicy() if password was
* given
* @param string $username username to check
* @param string $password password to check
* @return boolean
*/
public function shouldChangePassword($username, $password = null)
{
$configObj = Config::getInstance()->object();
if (!empty($configObj->system->webgui->enable_password_policy_constraints)) {
$userObject = $this->getUser($username);
if ($userObject != null) {
if (!empty($configObj->system->webgui->password_policy_duration)) {
$now = microtime(true);
$pwdChangedAt = empty($userObject->pwd_changed_at) ? 0 : $userObject->pwd_changed_at;
if (abs($now - $pwdChangedAt) / 60 / 60 / 24 >= $configObj->system->webgui->password_policy_duration) {
return true;
}
}
if (!empty($configObj->system->webgui->password_policy_compliance)) {
/* if compliance is required make sure the user has a SHA-512 hash as password */
if (strpos((string)$userObject->password, '$6$') !== 0) {
return true;
}
}
}
}
if ($password != null) {
/* not optimal, modify "old_password" to avoid equal check */
if (count($this->checkPolicy($username, '~' . $password, $password))) {
return true;
}
}
return false;
}
/**
* authenticate user against local database (in config.xml)
* @param string|SimpleXMLElement $username username (or xml object) to authenticate
* @param string $password user password
* @return bool authentication status
*/
protected function _authenticate($username, $password)
{
$userObject = $this->getUser($username);
if ($userObject != null) {
if (!empty((string)$userObject->disabled)) {
// disabled user
return false;
}
if (
!empty($userObject->expires)
&& strtotime("-1 day") > strtotime(date("m/d/Y", strtotime((string)$userObject->expires)))
) {
// expired user
return false;
}
if (password_verify($password, (string)$userObject->password)) {
// password ok, return successfully authentication
return true;
}
}
return false;
}
}