+ 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:
Ad Schellevis 2018-10-30 20:50:01 +01:00
parent fbb1dd39b8
commit cfb5852599
5 changed files with 107 additions and 35 deletions

View File

@ -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();
}

View 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;
}
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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"';?> />