mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-13 00:07:26 +00:00
Auth: LDAP+TOTP, closes https://github.com/opnsense/core/issues/1030
+ Add ldap+totp connector + Refactor local auth to always fetch user via getUser(), prevents different parameters for authenticate() call (less confusing, for a little overhead) + Fix settings form, a complete refactor doesn't fit my time scheme, but this doesn't make it worse then it is.
This commit is contained in:
parent
fbb1dd39b8
commit
cfb5852599
@ -123,7 +123,7 @@ class AuthenticationFactory
|
||||
if (!empty($connectors[$servers[$authserver]['type']])) {
|
||||
$authObject = $connectors[$servers[$authserver]['type']]['classHandle']->newInstance();
|
||||
}
|
||||
if ($servers[$authserver]['type'] == 'ldap') {
|
||||
if (in_array($servers[$authserver]['type'], array('ldap', 'ldap-totp'))) {
|
||||
$localUserMap = $this->fetchUserDNs();
|
||||
}
|
||||
|
||||
|
||||
81
src/opnsense/mvc/app/library/OPNsense/Auth/LDAPTOTP.php
Normal file
81
src/opnsense/mvc/app/library/OPNsense/Auth/LDAPTOTP.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
|
||||
/**
|
||||
* RFC 6238 TOTP: Time-Based One-Time Password Authenticator + LDAP
|
||||
* @package OPNsense\Auth
|
||||
*/
|
||||
class LDAPTOTP extends LDAP
|
||||
{
|
||||
use TOTP;
|
||||
|
||||
/**
|
||||
* type name in configuration
|
||||
* @return string
|
||||
*/
|
||||
public static function getType()
|
||||
{
|
||||
return 'ldap-totp';
|
||||
}
|
||||
|
||||
/**
|
||||
* user friendly description of this authenticator
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return gettext("LDAP + Timebased One Time Password");
|
||||
}
|
||||
|
||||
/**
|
||||
* set connector properties
|
||||
* @param array $config connection properties
|
||||
*/
|
||||
public function setProperties($config)
|
||||
{
|
||||
parent::setProperties($config);
|
||||
$this->setTOTPProperties($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve configuration options
|
||||
* @return array
|
||||
*/
|
||||
public function getConfigurationOptions()
|
||||
{
|
||||
$options = $this->getTOTPConfigurationOptions();
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
@ -147,13 +147,7 @@ class Local extends Base implements IAuthConnector
|
||||
*/
|
||||
public function authenticate($username, $password)
|
||||
{
|
||||
if (is_a($username, 'SimpleXMLElement')) {
|
||||
// user xml section provided
|
||||
$userObject = $username;
|
||||
} else {
|
||||
// get xml section from config
|
||||
$userObject = $this->getUser($username);
|
||||
}
|
||||
$userObject = $this->getUser($username);
|
||||
if ($userObject != null) {
|
||||
if (isset($userObject->disabled)) {
|
||||
// disabled user
|
||||
|
||||
@ -58,11 +58,6 @@ trait TOTP
|
||||
*/
|
||||
private $passwordFirst = false;
|
||||
|
||||
/**
|
||||
* @var string method accepting username and returning a simplexml user object
|
||||
*/
|
||||
private $getUserMethod = 'getUser';
|
||||
|
||||
/**
|
||||
* use graceperiod and timeWindow to calculate which moments in time we should check
|
||||
* @return array timestamps
|
||||
@ -149,8 +144,7 @@ trait TOTP
|
||||
*/
|
||||
public function authenticate($username, $password)
|
||||
{
|
||||
$getUserMethod = $this->getUserMethod;
|
||||
$userObject = $this->$getUserMethod($username);
|
||||
$userObject = $this->getUser($username);
|
||||
if ($userObject != null && !empty($userObject->otp_seed)) {
|
||||
if (strlen($password) > $this->otpLength) {
|
||||
// split otp token code and userpassword
|
||||
@ -166,7 +160,7 @@ trait TOTP
|
||||
$otp_seed = \Base32\Base32::decode($userObject->otp_seed);
|
||||
if ($this->authTOTP($otp_seed, $code)) {
|
||||
// token valid, do parents auth
|
||||
return parent::authenticate($userObject, $userPassword);
|
||||
return parent::authenticate($username, $userPassword);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$pconfig['type'] = $a_server[$id]['type'];
|
||||
$pconfig['name'] = $a_server[$id]['name'];
|
||||
|
||||
if ($pconfig['type'] == "ldap") {
|
||||
if (in_array($pconfig['type'], array("ldap", "ldap-totp"))) {
|
||||
$pconfig['ldap_caref'] = $a_server[$id]['ldap_caref'];
|
||||
$pconfig['ldap_host'] = $a_server[$id]['host'];
|
||||
$pconfig['ldap_port'] = $a_server[$id]['ldap_port'];
|
||||
@ -115,7 +115,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$pconfig[$fieldname] = null;
|
||||
}
|
||||
}
|
||||
} elseif (!empty($authCNFOptions[$pconfig['type']])) {
|
||||
}
|
||||
if (!empty($authCNFOptions[$pconfig['type']])) {
|
||||
foreach ($authCNFOptions[$pconfig['type']]['additionalFields'] as $fieldname => $field) {
|
||||
$pconfig[$fieldname] = $a_server[$id][$fieldname];
|
||||
}
|
||||
@ -132,7 +133,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
}
|
||||
if (isset($pconfig['save'])) {
|
||||
/* input validation */
|
||||
if ($pconfig['type'] == "ldap") {
|
||||
if (in_array($pconfig['type'], array("ldap", "ldap-totp"))) {
|
||||
$reqdfields = explode(" ", "name type ldap_host ldap_port ".
|
||||
"ldap_urltype ldap_protver ldap_scope ".
|
||||
"ldap_attr_user ldapauthcontainers");
|
||||
@ -171,7 +172,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$reqdfields[] = "radius_secret";
|
||||
$reqdfieldsn[] = gettext("Shared Secret");
|
||||
}
|
||||
} elseif (!empty($authCNFOptions[$pconfig['type']])) {
|
||||
}
|
||||
if (!empty($authCNFOptions[$pconfig['type']])) {
|
||||
foreach ($authCNFOptions[$pconfig['type']]['additionalFields'] as $fieldname => $field) {
|
||||
if (!empty($field['validate'])) {
|
||||
foreach ($field['validate']($pconfig[$fieldname]) as $input_error) {
|
||||
@ -213,7 +215,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$server['name'] = $pconfig['name'];
|
||||
}
|
||||
|
||||
if ($server['type'] == "ldap") {
|
||||
if (in_array($server['type'], array("ldap", "ldap-totp"))) {
|
||||
if (!empty($pconfig['ldap_caref'])) {
|
||||
$server['ldap_caref'] = $pconfig['ldap_caref'];
|
||||
}
|
||||
@ -269,7 +271,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
unset($config['system']['webgui'][$fieldname]);
|
||||
}
|
||||
}
|
||||
} elseif (!empty($authCNFOptions[$server['type']])) {
|
||||
}
|
||||
if (!empty($authCNFOptions[$server['type']])) {
|
||||
foreach ($authCNFOptions[$server['type']]['additionalFields'] as $fieldname => $field) {
|
||||
$server[$fieldname] = $pconfig[$fieldname];
|
||||
}
|
||||
@ -592,7 +595,7 @@ endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- LDAP -->
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><a id="help_for_ldap_host" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Hostname or IP address");?></td>
|
||||
<td>
|
||||
<input name="ldap_host" type="text" id="ldap_host" size="20" value="<?=$pconfig['ldap_host'];?>"/>
|
||||
@ -601,13 +604,13 @@ endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Port value");?></td>
|
||||
<td>
|
||||
<input name="ldap_port" type="text" id="ldap_port" size="5" value="<?=$pconfig['ldap_port'];?>"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Transport");?></td>
|
||||
<td>
|
||||
<select name="ldap_urltype" id="ldap_urltype" class="selectpicker" data-style="btn-default">
|
||||
@ -623,7 +626,7 @@ endif; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><a id="help_for_ldap_caref" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Peer Certificate Authority"); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
@ -647,7 +650,7 @@ endif; ?>
|
||||
endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Protocol version");?></td>
|
||||
<td>
|
||||
<select name="ldap_protver" id="ldap_protver" class="selectpicker" data-style="btn-default">
|
||||
@ -656,7 +659,7 @@ endif; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><a id="help_for_ldap_binddn" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Bind credentials");?></td>
|
||||
<td>
|
||||
<?=gettext("User DN:");?><br/>
|
||||
@ -668,7 +671,7 @@ endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Search scope");?></td>
|
||||
<td>
|
||||
<select name="ldap_scope" id="ldap_scope" class="selectpicker" data-style="btn-default">
|
||||
@ -681,13 +684,13 @@ endif; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Base DN");?></td>
|
||||
<td>
|
||||
<input name="ldap_basedn" type="text" id="ldap_basedn" size="40" value="<?=$pconfig['ldap_basedn'];?>"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><a id="help_for_ldapauthcontainers" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Authentication containers");?></td>
|
||||
<td>
|
||||
<ul class="list-inline">
|
||||
@ -701,7 +704,7 @@ endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><a id="help_for_ldap_extended_query" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Extended Query");?></td>
|
||||
<td>
|
||||
<input name="ldap_extended_query" type="text" id="ldap_extended_query" size="40" value="<?=$pconfig['ldap_extended_query'];?>"/>
|
||||
@ -712,7 +715,7 @@ endif; ?>
|
||||
</tr>
|
||||
<?php if (!isset($id)) :
|
||||
?>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Initial Template");?></td>
|
||||
<td>
|
||||
<select name="ldap_tmpltype" id="ldap_tmpltype" class="selectpicker" data-style="btn-default">
|
||||
@ -724,7 +727,7 @@ endif; ?>
|
||||
</tr>
|
||||
<?php
|
||||
endif; ?>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><a id="help_for_ldap_attr_user" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("User naming attribute");?></td>
|
||||
<td>
|
||||
<input name="ldap_attr_user" type="text" id="ldap_attr_user" size="20" value="<?=$pconfig['ldap_attr_user'];?>"/>
|
||||
@ -733,7 +736,7 @@ endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="auth_ldap auth_options hidden">
|
||||
<tr class="auth_ldap auth_ldap-totp auth_options hidden">
|
||||
<td><a id="help_for_ldap_read_properties" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext('Read properties'); ?></td>
|
||||
<td>
|
||||
<input id="ldap_read_properties" name="ldap_read_properties" type="checkbox" <?= empty($pconfig['ldap_read_properties']) ? '' : 'checked="checked"';?> />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user