commit
5682245739
|
@ -25,4 +25,4 @@ There are two modules. Usually, you only need the files inside "lam".
|
||||||
LAM is published under the GNU General Public License.
|
LAM is published under the GNU General Public License.
|
||||||
The complete list of licenses can be found in the copyright file.
|
The complete list of licenses can be found in the copyright file.
|
||||||
|
|
||||||
Copyright (C) 2003 - 2018 Roland Gruber <post@rolandgruber.de>
|
Copyright (C) 2003 - 2019 Roland Gruber <post@rolandgruber.de>
|
|
@ -1,4 +1,4 @@
|
||||||
This software is copyright (c) 2003 - 2018 by Roland Gruber
|
This software is copyright (c) 2003 - 2019 by Roland Gruber
|
||||||
|
|
||||||
If you purchased a copy of LDAP Account Manager Pro then the following
|
If you purchased a copy of LDAP Account Manager Pro then the following
|
||||||
files are licensed under the conditions which you accepted at purchase
|
files are licensed under the conditions which you accepted at purchase
|
||||||
|
@ -199,6 +199,29 @@ B:
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
C:
|
||||||
|
|
||||||
|
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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
|
||||||
|
|
||||||
Programs and licenses with other licenses and/or authors than the
|
Programs and licenses with other licenses and/or authors than the
|
||||||
main license and authors:
|
main license and authors:
|
||||||
|
@ -206,6 +229,7 @@ main license and authors:
|
||||||
lib/3rdParty/tcpdf/fonts/DejaVu*.ttf A Public Domain, Bitstream, Inc., Tavmjong Bah
|
lib/3rdParty/tcpdf/fonts/DejaVu*.ttf A Public Domain, Bitstream, Inc., Tavmjong Bah
|
||||||
lib/3rdParty/tcpdf/fonts/DejaVu*.z A Public Domain, Bitstream, Inc., Tavmjong Bah
|
lib/3rdParty/tcpdf/fonts/DejaVu*.z A Public Domain, Bitstream, Inc., Tavmjong Bah
|
||||||
lib/3rdParty/phpseclib B Jim Wigginton
|
lib/3rdParty/phpseclib B Jim Wigginton
|
||||||
|
lib/3rdParty/yubico/Yubico.php C 2015 Yubico AB
|
||||||
templates/lib/*jquery*.js B 2018 jQuery Foundation and other contributors
|
templates/lib/*jquery*.js B 2018 jQuery Foundation and other contributors
|
||||||
style/120_jquery-ui*.css B 2016 jQuery Foundation and other contributors
|
style/120_jquery-ui*.css B 2016 jQuery Foundation and other contributors
|
||||||
templates/lib/*jquery-dropmenu-*.js B 2010 Fred Heusschen
|
templates/lib/*jquery-dropmenu-*.js B 2010 Fred Heusschen
|
||||||
|
@ -221,4 +245,3 @@ style/610_magnific-popup.css B 2016 Dmitry Semenov
|
||||||
style/responsive/105_normalize.css B Nicolas Gallagher and Jonathan Neal
|
style/responsive/105_normalize.css B Nicolas Gallagher and Jonathan Neal
|
||||||
style/responsive/110_grid.css B
|
style/responsive/110_grid.css B
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
March 2019
|
||||||
|
- Added YubiKey as 2-factor authentication provider
|
||||||
|
|
||||||
28.12.2018 6.6
|
28.12.2018 6.6
|
||||||
- New import/export in tools menu
|
- New import/export in tools menu
|
||||||
- YubiKey support
|
- YubiKey support
|
||||||
|
|
|
@ -15,7 +15,7 @@ LAM - Readme
|
||||||
|
|
||||||
https://www.ldap-account-manager.org/
|
https://www.ldap-account-manager.org/
|
||||||
|
|
||||||
Copyright (C) 2003 - 2018 Roland Gruber <post@rolandgruber.de>
|
Copyright (C) 2003 - 2019 Roland Gruber <post@rolandgruber.de>
|
||||||
|
|
||||||
Installation and documentation:
|
Installation and documentation:
|
||||||
Please see the LAM manual in docs/manual/index.html.
|
Please see the LAM manual in docs/manual/index.html.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
This software is copyright (c) 2003 - 2018 by Roland Gruber
|
This software is copyright (c) 2003 - 2019 by Roland Gruber
|
||||||
|
|
||||||
If you purchased a copy of LDAP Account Manager Pro then the following
|
If you purchased a copy of LDAP Account Manager Pro then the following
|
||||||
files are licensed under the conditions which you accepted at purchase
|
files are licensed under the conditions which you accepted at purchase
|
||||||
|
@ -198,6 +198,29 @@ B:
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
C:
|
||||||
|
|
||||||
|
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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
|
||||||
|
|
||||||
Programs and licenses with other licenses and/or authors than the
|
Programs and licenses with other licenses and/or authors than the
|
||||||
main license and authors:
|
main license and authors:
|
||||||
|
@ -205,6 +228,7 @@ main license and authors:
|
||||||
lib/3rdParty/tcpdf/fonts/DejaVu*.ttf A Public Domain, Bitstream, Inc., Tavmjong Bah
|
lib/3rdParty/tcpdf/fonts/DejaVu*.ttf A Public Domain, Bitstream, Inc., Tavmjong Bah
|
||||||
lib/3rdParty/tcpdf/fonts/DejaVu*.z A Public Domain, Bitstream, Inc., Tavmjong Bah
|
lib/3rdParty/tcpdf/fonts/DejaVu*.z A Public Domain, Bitstream, Inc., Tavmjong Bah
|
||||||
lib/3rdParty/phpseclib B Jim Wigginton
|
lib/3rdParty/phpseclib B Jim Wigginton
|
||||||
|
lib/3rdParty/yubico/Yubico.php C 2015 Yubico AB
|
||||||
templates/lib/*jquery*.js B 2018 jQuery Foundation and other contributors
|
templates/lib/*jquery*.js B 2018 jQuery Foundation and other contributors
|
||||||
style/120_jquery-ui*.css B 2016 jQuery Foundation and other contributors
|
style/120_jquery-ui*.css B 2016 jQuery Foundation and other contributors
|
||||||
templates/lib/*jquery-dropmenu-*.js B 2010 Fred Heusschen
|
templates/lib/*jquery-dropmenu-*.js B 2010 Fred Heusschen
|
||||||
|
|
|
@ -596,11 +596,53 @@
|
||||||
<para><ulink
|
<para><ulink
|
||||||
url="https://www.privacyidea.org/">privacyIdea</ulink></para>
|
url="https://www.privacyidea.org/">privacyIdea</ulink></para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><ulink url="https://www.yubico.com/">YubiKey</ulink></para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>By default LAM will enforce to use a token and reject users that
|
<para>Configuration options:</para>
|
||||||
did not setup one. You can set this check to optional. But if a user
|
|
||||||
has setup a token then this will always be required.</para>
|
<para>privacyIDEA:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Base URL: please enter the URL of your privacyIDEA
|
||||||
|
instance</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para>YubiKey:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Base URL: please enter the URL of your YubiKey verfication
|
||||||
|
server. For YubiKey cloud this is
|
||||||
|
"https://api.yubico.com/wsapi/2.0/verify". If you run a custom
|
||||||
|
verification API such as yubiserver then enter its URL (e.g.
|
||||||
|
http://www.example.com:8000/wsapi/2.0/verify). The URL needs to
|
||||||
|
end with "/wsapi/2.0/verify".</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Client id: this is only required for YubiKey cloud. You can
|
||||||
|
register here: https://upgrade.yubico.com/getapikey/</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Secret key: this is only required for YubiKey cloud. You can
|
||||||
|
register here: https://upgrade.yubico.com/getapikey/</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para>Optional: By default LAM will enforce to use a token and reject
|
||||||
|
users that did not setup one. You can set this check to optional. But
|
||||||
|
if a user has setup a token then this will always be required.</para>
|
||||||
|
|
||||||
|
<para>Disable certificate check: This should be used on development
|
||||||
|
instances only. It skips the certificate check when connecting to
|
||||||
|
verification server.</para>
|
||||||
|
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<mediaobject>
|
<mediaobject>
|
||||||
|
|
|
@ -279,11 +279,51 @@
|
||||||
<para><ulink
|
<para><ulink
|
||||||
url="https://www.privacyidea.org/">privacyIdea</ulink></para>
|
url="https://www.privacyidea.org/">privacyIdea</ulink></para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><ulink url="https://www.yubico.com/">YubiKey</ulink></para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>By default LAM will enforce to use a token and reject users that
|
<para>privacyIDEA:</para>
|
||||||
did not setup one. You can set this check to optional. But if a user
|
|
||||||
has setup a token then this will always be required.</para>
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Base URL: please enter the URL of your privacyIDEA
|
||||||
|
instance</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para>YubiKey:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Base URL: please enter the URL of your YubiKey verfication
|
||||||
|
server. For YubiKey cloud this is
|
||||||
|
"https://api.yubico.com/wsapi/2.0/verify". If you run a custom
|
||||||
|
verification API such as yubiserver then enter its URL (e.g.
|
||||||
|
http://www.example.com:8000/wsapi/2.0/verify). The URL needs to
|
||||||
|
end with "/wsapi/2.0/verify".</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Client id: this is only required for YubiKey cloud. You can
|
||||||
|
register here: https://upgrade.yubico.com/getapikey/</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Secret key: this is only required for YubiKey cloud. You can
|
||||||
|
register here: https://upgrade.yubico.com/getapikey/</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para>Optional: By default LAM will enforce to use a token and reject
|
||||||
|
users that did not setup one. You can set this check to optional. But
|
||||||
|
if a user has setup a token then this will always be required.</para>
|
||||||
|
|
||||||
|
<para>Disable certificate check: This should be used on development
|
||||||
|
instances only. It skips the certificate check when connecting to
|
||||||
|
verification server.</para>
|
||||||
|
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<mediaobject>
|
<mediaobject>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<para><ulink
|
<para><ulink
|
||||||
url="https://www.ldap-account-manager.org/">https://www.ldap-account-manager.org/</ulink></para>
|
url="https://www.ldap-account-manager.org/">https://www.ldap-account-manager.org/</ulink></para>
|
||||||
|
|
||||||
<para>Copyright (C) 2003 - 2018 Roland Gruber
|
<para>Copyright (C) 2003 - 2019 Roland Gruber
|
||||||
<post@rolandgruber.de></para>
|
<post@rolandgruber.de></para>
|
||||||
|
|
||||||
<para><emphasis role="bold">Key features:</emphasis></para>
|
<para><emphasis role="bold">Key features:</emphasis></para>
|
||||||
|
|
|
@ -311,6 +311,10 @@ $helpArray = array (
|
||||||
"Text" => _('Protect the self service login with a captcha.')),
|
"Text" => _('Protect the self service login with a captcha.')),
|
||||||
"523" => array ("Headline" => _('Base color'),
|
"523" => array ("Headline" => _('Base color'),
|
||||||
"Text" => _('Background color for self service pages.')),
|
"Text" => _('Background color for self service pages.')),
|
||||||
|
"524" => array ("Headline" => _('Client id'),
|
||||||
|
"Text" => _('Please enter your client id for the verification API.')),
|
||||||
|
"525" => array ("Headline" => _('Secret key'),
|
||||||
|
"Text" => _('Please enter your secret key for the verification API.')),
|
||||||
"550" => array ("Headline" => _("From address"),
|
"550" => array ("Headline" => _("From address"),
|
||||||
"Text" => _("This email address will be set as sender address of all password mails. If empty the system default (php.ini) will be used.")),
|
"Text" => _("This email address will be set as sender address of all password mails. If empty the system default (php.ini) will be used.")),
|
||||||
"551" => array ("Headline" => _("Subject"),
|
"551" => array ("Headline" => _("Subject"),
|
||||||
|
|
|
@ -5,7 +5,7 @@ use \LAMConfig;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||||
Copyright (C) 2017 - 2018 Roland Gruber
|
Copyright (C) 2017 - 2019 Roland Gruber
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -53,6 +53,8 @@ interface TwoFactorProvider {
|
||||||
*/
|
*/
|
||||||
public function verify2ndFactor($user, $password, $serial, $twoFactorInput);
|
public function verify2ndFactor($user, $password, $serial, $twoFactorInput);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -223,6 +225,76 @@ class PrivacyIDEAProvider implements TwoFactorProvider {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication via YubiKeys.
|
||||||
|
*
|
||||||
|
* @author Roland Gruber
|
||||||
|
*/
|
||||||
|
class YubicoProvider implements TwoFactorProvider {
|
||||||
|
|
||||||
|
private $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param TwoFactorConfiguration $config configuration
|
||||||
|
*/
|
||||||
|
public function __construct(&$config) {
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::getSerials()
|
||||||
|
*/
|
||||||
|
public function getSerials($user, $password) {
|
||||||
|
$keyAttributeName = strtolower($this->config->twoFactorAuthenticationSerialAttributeName);
|
||||||
|
if (isset($_SESSION['selfService_clientDN'])) {
|
||||||
|
$loginDn = lamDecrypt($_SESSION['selfService_clientDN'], 'SelfService');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$loginDn = $_SESSION['ldap']->getUserName();
|
||||||
|
}
|
||||||
|
$handle = getLDAPServerHandle();
|
||||||
|
$ldapData = ldapGetDN($loginDn, array($keyAttributeName), $handle);
|
||||||
|
if (empty($ldapData[$keyAttributeName])) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
return array(implode(', ', $ldapData[$keyAttributeName]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see \LAM\LIB\TWO_FACTOR\TwoFactorProvider::verify2ndFactor()
|
||||||
|
*/
|
||||||
|
public function verify2ndFactor($user, $password, $serial, $twoFactorInput) {
|
||||||
|
include_once(__DIR__ . "/3rdParty/yubico/Yubico.php");
|
||||||
|
$serialData = $this->getSerials($user, $password);
|
||||||
|
if (empty($serialData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$serials = explode(', ', $serialData[0]);
|
||||||
|
$serialMatched = false;
|
||||||
|
foreach ($serials as $serial) {
|
||||||
|
if (strpos($twoFactorInput, $serial) === 0) {
|
||||||
|
$serialMatched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$serialMatched) {
|
||||||
|
throw new \Exception(_('YubiKey id does not match allowed list of key ids.'));
|
||||||
|
}
|
||||||
|
$url = $this->config->twoFactorAuthenticationURL;
|
||||||
|
$httpsverify = !$this->config->twoFactorAuthenticationInsecure;
|
||||||
|
$clientId = $this->config->twoFactorAuthenticationClientId;
|
||||||
|
$secretKey = $this->config->twoFactorAuthenticationSecretKey;
|
||||||
|
$auth = new \Auth_Yubico($clientId, $secretKey, $url, $httpsverify);
|
||||||
|
$auth->verify($twoFactorInput);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the correct 2 factor provider.
|
* Returns the correct 2 factor provider.
|
||||||
*/
|
*/
|
||||||
|
@ -232,6 +304,8 @@ class TwoFactorProviderService {
|
||||||
const TWO_FACTOR_NONE = 'none';
|
const TWO_FACTOR_NONE = 'none';
|
||||||
/** 2factor authentication via privacyIDEA */
|
/** 2factor authentication via privacyIDEA */
|
||||||
const TWO_FACTOR_PRIVACYIDEA = 'privacyidea';
|
const TWO_FACTOR_PRIVACYIDEA = 'privacyidea';
|
||||||
|
/** 2factor authentication via YubiKey */
|
||||||
|
const TWO_FACTOR_YUBICO = 'yubico';
|
||||||
|
|
||||||
private $config;
|
private $config;
|
||||||
|
|
||||||
|
@ -260,6 +334,9 @@ class TwoFactorProviderService {
|
||||||
if ($this->config->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA) {
|
if ($this->config->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA) {
|
||||||
return new PrivacyIDEAProvider($this->config);
|
return new PrivacyIDEAProvider($this->config);
|
||||||
}
|
}
|
||||||
|
elseif ($this->config->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
||||||
|
return new YubicoProvider($this->config);
|
||||||
|
}
|
||||||
throw new \Exception('Invalid provider: ' . $this->config->twoFactorAuthentication);
|
throw new \Exception('Invalid provider: ' . $this->config->twoFactorAuthentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,11 +347,22 @@ class TwoFactorProviderService {
|
||||||
* @return TwoFactorConfiguration configuration
|
* @return TwoFactorConfiguration configuration
|
||||||
*/
|
*/
|
||||||
private function getConfigSelfService(&$profile) {
|
private function getConfigSelfService(&$profile) {
|
||||||
$config = new TwoFactorConfiguration();
|
$tfConfig = new TwoFactorConfiguration();
|
||||||
$config->twoFactorAuthentication = $profile->twoFactorAuthentication;
|
$tfConfig->twoFactorAuthentication = $profile->twoFactorAuthentication;
|
||||||
$config->twoFactorAuthenticationInsecure = $profile->twoFactorAuthenticationInsecure;
|
$tfConfig->twoFactorAuthenticationInsecure = $profile->twoFactorAuthenticationInsecure;
|
||||||
$config->twoFactorAuthenticationURL = $profile->twoFactorAuthenticationURL;
|
$tfConfig->twoFactorAuthenticationURL = $profile->twoFactorAuthenticationURL;
|
||||||
return $config;
|
$tfConfig->twoFactorAuthenticationClientId = $profile->twoFactorAuthenticationClientId;
|
||||||
|
$tfConfig->twoFactorAuthenticationSecretKey = $profile->twoFactorAuthenticationSecretKey;
|
||||||
|
if ($tfConfig->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
||||||
|
$moduleSettings = $profile->moduleSettings;
|
||||||
|
if (!empty($moduleSettings['yubiKeyUser_attributeName'][0])) {
|
||||||
|
$tfConfig->twoFactorAuthenticationSerialAttributeName = $moduleSettings['yubiKeyUser_attributeName'][0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tfConfig->twoFactorAuthenticationSerialAttributeName = 'yubiKeyId';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $tfConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -284,11 +372,22 @@ class TwoFactorProviderService {
|
||||||
* @return TwoFactorConfiguration configuration
|
* @return TwoFactorConfiguration configuration
|
||||||
*/
|
*/
|
||||||
private function getConfigAdmin($conf) {
|
private function getConfigAdmin($conf) {
|
||||||
$config = new TwoFactorConfiguration();
|
$tfConfig = new TwoFactorConfiguration();
|
||||||
$config->twoFactorAuthentication = $conf->getTwoFactorAuthentication();
|
$tfConfig->twoFactorAuthentication = $conf->getTwoFactorAuthentication();
|
||||||
$config->twoFactorAuthenticationInsecure = $conf->getTwoFactorAuthenticationInsecure();
|
$tfConfig->twoFactorAuthenticationInsecure = $conf->getTwoFactorAuthenticationInsecure();
|
||||||
$config->twoFactorAuthenticationURL = $conf->getTwoFactorAuthenticationURL();
|
$tfConfig->twoFactorAuthenticationURL = $conf->getTwoFactorAuthenticationURL();
|
||||||
return $config;
|
$tfConfig->twoFactorAuthenticationClientId = $conf->getTwoFactorAuthenticationClientId();
|
||||||
|
$tfConfig->twoFactorAuthenticationSecretKey = $conf->getTwoFactorAuthenticationSecretKey();
|
||||||
|
if ($tfConfig->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
||||||
|
$moduleSettings = $conf->get_moduleSettings();
|
||||||
|
if (!empty($moduleSettings['yubiKeyUser_attributeName'][0])) {
|
||||||
|
$tfConfig->twoFactorAuthenticationSerialAttributeName = $moduleSettings['yubiKeyUser_attributeName'][0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tfConfig->twoFactorAuthenticationSerialAttributeName = 'yubiKeyId';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $tfConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -299,7 +398,35 @@ class TwoFactorProviderService {
|
||||||
* @author Roland Gruber
|
* @author Roland Gruber
|
||||||
*/
|
*/
|
||||||
class TwoFactorConfiguration {
|
class TwoFactorConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string provider id
|
||||||
|
*/
|
||||||
public $twoFactorAuthentication = null;
|
public $twoFactorAuthentication = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var service URL
|
||||||
|
*/
|
||||||
public $twoFactorAuthenticationURL = null;
|
public $twoFactorAuthenticationURL = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var disable certificate check
|
||||||
|
*/
|
||||||
public $twoFactorAuthenticationInsecure = false;
|
public $twoFactorAuthenticationInsecure = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var client ID for API access
|
||||||
|
*/
|
||||||
|
public $twoFactorAuthenticationClientId = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var secret key for API access
|
||||||
|
*/
|
||||||
|
public $twoFactorAuthenticationSecretKey = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LDAP attribute name that stores the token serials
|
||||||
|
*/
|
||||||
|
public $twoFactorAuthenticationSerialAttributeName = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,252 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Class for verifying Yubico One-Time-Passcodes
|
||||||
|
*
|
||||||
|
* @category Auth
|
||||||
|
* @package Auth_Yubico
|
||||||
|
* @author Simon Josefsson <simon@yubico.com>, Olov Danielson <olov@yubico.com>
|
||||||
|
* @author Roland Gruber
|
||||||
|
* @copyright 2007-2015 Yubico AB
|
||||||
|
* @copyright 2018 Roland Gruber
|
||||||
|
* @license https://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version 2.0
|
||||||
|
* @link https://www.yubico.com/
|
||||||
|
*
|
||||||
|
* Adapted for LAM.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for verifying Yubico One-Time-Passcodes
|
||||||
|
*/
|
||||||
|
class Auth_Yubico {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Yubico client ID
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $clientId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Yubico client key
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $clientKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL part of validation server
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag whether to verify HTTPS server certificates or not.
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
private $httpsVerify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* Sets up the object
|
||||||
|
*
|
||||||
|
* @param string $id The client identity
|
||||||
|
* @param string $key The client MAC key
|
||||||
|
* @param string $url URL
|
||||||
|
* @param boolean $httpsverify Flag whether to use verify HTTPS
|
||||||
|
* server certificates
|
||||||
|
*/
|
||||||
|
public function __construct($id, $key, $url, $httpsverify) {
|
||||||
|
$this->clientId = $id;
|
||||||
|
$this->clientKey = base64_decode($key);
|
||||||
|
$this->httpsVerify = $httpsverify;
|
||||||
|
$this->url = $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse input string into password, yubikey prefix,
|
||||||
|
* ciphertext, and OTP.
|
||||||
|
*
|
||||||
|
* @param string Input string to parse
|
||||||
|
* @param string Optional delimiter re-class, default is '[:]'
|
||||||
|
* @return array Keyed array with fields
|
||||||
|
*/
|
||||||
|
private function parsePasswordOTP($str, $delim = '[:]') {
|
||||||
|
if (!preg_match("/^((.*)" . $delim . ")?(([cbdefghijklnrtuv]{0,12})([cbdefghijklnrtuv]{32}))$/i", $str, $matches)) {
|
||||||
|
/* Dvorak? */
|
||||||
|
if (!preg_match("/^((.*)" . $delim . ")?(([jxe\\.uidchtnbpygk]{0,12})([jxe\\.uidchtnbpygk]{32}))$/i", $str, $matches)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ret['otp'] = strtr($matches[3], "jxe.uidchtnbpygk", "cbdefghijklnrtuv");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ret['otp'] = $matches[3];
|
||||||
|
}
|
||||||
|
$ret['password'] = $matches[2];
|
||||||
|
$ret['prefix'] = $matches[4];
|
||||||
|
$ret['ciphertext'] = $matches[5];
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify Yubico OTP against multiple URLs
|
||||||
|
* Protocol specification 2.0 is used to construct validation requests
|
||||||
|
*
|
||||||
|
* @param string $token Yubico OTP
|
||||||
|
* @param int $use_timestamp 1=>send request with ×tamp=1 to
|
||||||
|
* get timestamp and session information
|
||||||
|
* in the response
|
||||||
|
* @throws LAMException if verification failed
|
||||||
|
*/
|
||||||
|
public function verify($token, $use_timestamp = null) {
|
||||||
|
$timeout = 10;
|
||||||
|
/* Construct parameters string */
|
||||||
|
$ret = $this->parsePasswordOTP($token);
|
||||||
|
if (!$ret) {
|
||||||
|
throw new LAMException(_('Error'), 'Could not parse Yubikey OTP');
|
||||||
|
}
|
||||||
|
$params = array(
|
||||||
|
'id' => $this->clientId,
|
||||||
|
'otp' => $ret['otp'],
|
||||||
|
'nonce' => md5(uniqid(getRandomNumber()))
|
||||||
|
);
|
||||||
|
/* Take care of protocol version 2 parameters */
|
||||||
|
if ($use_timestamp) {
|
||||||
|
$params['timestamp'] = 1;
|
||||||
|
}
|
||||||
|
$params['timeout'] = $timeout;
|
||||||
|
ksort($params);
|
||||||
|
$parameters = '';
|
||||||
|
foreach ($params as $p => $v) {
|
||||||
|
$parameters .= "&" . $p . "=" . $v;
|
||||||
|
}
|
||||||
|
$parameters = ltrim($parameters, "&");
|
||||||
|
|
||||||
|
/* Generate signature. */
|
||||||
|
if ($this->clientKey != "") {
|
||||||
|
$signature = base64_encode(hash_hmac('sha1', $parameters, $this->clientKey, true));
|
||||||
|
$signature = preg_replace('/\+/', '%2B', $signature);
|
||||||
|
$parameters .= '&h=' . $signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $this->url . "?" . $parameters;
|
||||||
|
|
||||||
|
logNewMessage(LOG_DEBUG, 'Yubico url: ' . $query);
|
||||||
|
|
||||||
|
$handle = curl_init($query);
|
||||||
|
curl_setopt($handle, CURLOPT_USERAGENT, "LAM Auth Yubico");
|
||||||
|
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
if (!$this->httpsVerify) {
|
||||||
|
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, 0);
|
||||||
|
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||||
|
}
|
||||||
|
curl_setopt($handle, CURLOPT_FAILONERROR, true);
|
||||||
|
curl_setopt($handle, CURLOPT_TIMEOUT, $timeout);
|
||||||
|
|
||||||
|
/* Execute and read request. */
|
||||||
|
$this->response = null;
|
||||||
|
$str = curl_exec($handle);
|
||||||
|
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
|
||||||
|
curl_close($handle);
|
||||||
|
logNewMessage(LOG_DEBUG, 'Server answer: ' . $str);
|
||||||
|
if (is_string($str) && ($httpCode == 200) && preg_match("/status=([a-zA-Z0-9_]+)/", $str, $out)) {
|
||||||
|
$status = $out[1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are 3 cases.
|
||||||
|
*
|
||||||
|
* 1. OTP or Nonce values doesn't match - ignore
|
||||||
|
* response.
|
||||||
|
*
|
||||||
|
* 2. We have a HMAC key. If signature is invalid -
|
||||||
|
* ignore response. Return if status=OK/REPLAYED_OTP/BAD_OTP.
|
||||||
|
*
|
||||||
|
* 3. Return if status=OK or status=REPLAYED_OTP.
|
||||||
|
*/
|
||||||
|
if (!preg_match("/otp=" . $params['otp'] . "/", $str) || !preg_match("/nonce=" . $params['nonce'] . "/", $str)) {
|
||||||
|
if ($status == 'BAD_OTP') {
|
||||||
|
throw new LAMException(_('Error'), 'OTP not accepted. Maybe key is not registered.');
|
||||||
|
}
|
||||||
|
throw new LAMException(_('Error'), 'Invalid answer ' . $str);
|
||||||
|
}
|
||||||
|
elseif ($this->clientKey != "") {
|
||||||
|
/* Case 2. Verify signature first */
|
||||||
|
$rows = explode("\r\n", trim($str));
|
||||||
|
$response = array();
|
||||||
|
foreach ($rows as $val) {
|
||||||
|
/*
|
||||||
|
* '=' is also used in BASE64 encoding so we only replace the first = by # which is not
|
||||||
|
* used in BASE64
|
||||||
|
*/
|
||||||
|
$val = preg_replace('/=/', '#', $val, 1);
|
||||||
|
$row = explode("#", $val);
|
||||||
|
$response[$row[0]] = $row[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$parameters = array(
|
||||||
|
'nonce',
|
||||||
|
'otp',
|
||||||
|
'sessioncounter',
|
||||||
|
'sessionuse',
|
||||||
|
'sl',
|
||||||
|
'status',
|
||||||
|
't',
|
||||||
|
'timeout',
|
||||||
|
'timestamp'
|
||||||
|
);
|
||||||
|
sort($parameters);
|
||||||
|
$check = Null;
|
||||||
|
foreach ($parameters as $param) {
|
||||||
|
if (array_key_exists($param, $response)) {
|
||||||
|
if ($check) {
|
||||||
|
$check = $check . '&';
|
||||||
|
}
|
||||||
|
$check = $check . $param . '=' . $response[$param];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$checksignature = base64_encode(hash_hmac('sha1', utf8_encode($check), $this->clientKey, true));
|
||||||
|
|
||||||
|
if ($response['h'] == $checksignature) {
|
||||||
|
$this->checkStatus($status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new LAMException(_('Error'), 'Invalid signature, expected ' . $checksignature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Case 3. We check the status directly */
|
||||||
|
$this->checkStatus($status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new LAMException(_('Error'), 'Call to verification service failed with ' . $httpCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the status is ok.
|
||||||
|
*
|
||||||
|
* @param string $status status
|
||||||
|
* @throws LAMException invalid status
|
||||||
|
*/
|
||||||
|
private function checkStatus($status) {
|
||||||
|
if ($status == 'REPLAYED_OTP') {
|
||||||
|
throw new LAMException(_('Error'), 'OTP replay detected.');
|
||||||
|
}
|
||||||
|
elseif ($status == 'BAD_OTP') {
|
||||||
|
throw new LAMException(_('Error'), 'OTP not accepted. Maybe key is not registered.');
|
||||||
|
}
|
||||||
|
elseif ($status == 'OK') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new LAMException(_('Error'), 'Invalid status: ' . $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
|
@ -591,6 +591,8 @@ class LAMConfig {
|
||||||
|
|
||||||
private $twoFactorAuthentication = TwoFactorProviderService::TWO_FACTOR_NONE;
|
private $twoFactorAuthentication = TwoFactorProviderService::TWO_FACTOR_NONE;
|
||||||
private $twoFactorAuthenticationURL = 'https://localhost';
|
private $twoFactorAuthenticationURL = 'https://localhost';
|
||||||
|
private $twoFactorAuthenticationClientId = null;
|
||||||
|
private $twoFactorAuthenticationSecretKey = null;
|
||||||
private $twoFactorAuthenticationInsecure = false;
|
private $twoFactorAuthenticationInsecure = false;
|
||||||
private $twoFactorAuthenticationLabel = null;
|
private $twoFactorAuthenticationLabel = null;
|
||||||
private $twoFactorAuthenticationOptional = false;
|
private $twoFactorAuthenticationOptional = false;
|
||||||
|
@ -607,7 +609,7 @@ class LAMConfig {
|
||||||
'pwdResetAllowScreenPassword', 'pwdResetForcePasswordChange', 'pwdResetDefaultPasswordOutput',
|
'pwdResetAllowScreenPassword', 'pwdResetForcePasswordChange', 'pwdResetDefaultPasswordOutput',
|
||||||
'scriptUserName', 'scriptSSHKey', 'scriptSSHKeyPassword', 'twoFactorAuthentication', 'twoFactorAuthenticationURL',
|
'scriptUserName', 'scriptSSHKey', 'scriptSSHKeyPassword', 'twoFactorAuthentication', 'twoFactorAuthenticationURL',
|
||||||
'twoFactorAuthenticationInsecure', 'twoFactorAuthenticationLabel', 'twoFactorAuthenticationOptional',
|
'twoFactorAuthenticationInsecure', 'twoFactorAuthenticationLabel', 'twoFactorAuthenticationOptional',
|
||||||
'twoFactorAuthenticationCaption', 'referentialIntegrityOverlay'
|
'twoFactorAuthenticationCaption', 'twoFactorAuthenticationClientId', 'twoFactorAuthenticationSecretKey', 'referentialIntegrityOverlay'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -867,6 +869,8 @@ class LAMConfig {
|
||||||
if (!in_array("pwdResetDefaultPasswordOutput", $saved)) array_push($file_array, "\n" . "pwdResetDefaultPasswordOutput: " . $this->pwdResetDefaultPasswordOutput . "\n");
|
if (!in_array("pwdResetDefaultPasswordOutput", $saved)) array_push($file_array, "\n" . "pwdResetDefaultPasswordOutput: " . $this->pwdResetDefaultPasswordOutput . "\n");
|
||||||
if (!in_array("twoFactorAuthentication", $saved)) array_push($file_array, "\n" . "twoFactorAuthentication: " . $this->twoFactorAuthentication . "\n");
|
if (!in_array("twoFactorAuthentication", $saved)) array_push($file_array, "\n" . "twoFactorAuthentication: " . $this->twoFactorAuthentication . "\n");
|
||||||
if (!in_array("twoFactorAuthenticationURL", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationURL: " . $this->twoFactorAuthenticationURL . "\n");
|
if (!in_array("twoFactorAuthenticationURL", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationURL: " . $this->twoFactorAuthenticationURL . "\n");
|
||||||
|
if (!in_array("twoFactorAuthenticationClientId", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationClientId: " . $this->twoFactorAuthenticationClientId . "\n");
|
||||||
|
if (!in_array("twoFactorAuthenticationSecretKey", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationSecretKey: " . $this->twoFactorAuthenticationSecretKey . "\n");
|
||||||
if (!in_array("twoFactorAuthenticationInsecure", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationInsecure: " . $this->twoFactorAuthenticationInsecure . "\n");
|
if (!in_array("twoFactorAuthenticationInsecure", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationInsecure: " . $this->twoFactorAuthenticationInsecure . "\n");
|
||||||
if (!in_array("twoFactorAuthenticationLabel", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationLabel: " . $this->twoFactorAuthenticationLabel . "\n");
|
if (!in_array("twoFactorAuthenticationLabel", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationLabel: " . $this->twoFactorAuthenticationLabel . "\n");
|
||||||
if (!in_array("twoFactorAuthenticationOptional", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationOptional: " . $this->twoFactorAuthenticationOptional . "\n");
|
if (!in_array("twoFactorAuthenticationOptional", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationOptional: " . $this->twoFactorAuthenticationOptional . "\n");
|
||||||
|
@ -2151,7 +2155,7 @@ class LAMConfig {
|
||||||
/**
|
/**
|
||||||
* Returns the authentication URL.
|
* Returns the authentication URL.
|
||||||
*
|
*
|
||||||
* @return string $twoFactorAuthenticationURL authentication URL
|
* @return string authentication URL
|
||||||
*/
|
*/
|
||||||
public function getTwoFactorAuthenticationURL() {
|
public function getTwoFactorAuthenticationURL() {
|
||||||
return $this->twoFactorAuthenticationURL;
|
return $this->twoFactorAuthenticationURL;
|
||||||
|
@ -2166,10 +2170,46 @@ class LAMConfig {
|
||||||
$this->twoFactorAuthenticationURL = $twoFactorAuthenticationURL;
|
$this->twoFactorAuthenticationURL = $twoFactorAuthenticationURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the client id.
|
||||||
|
*
|
||||||
|
* @param string $clientId client id
|
||||||
|
*/
|
||||||
|
public function setTwoFactorAuthenticationClientId($clientId) {
|
||||||
|
$this->twoFactorAuthenticationClientId = $clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the client id.
|
||||||
|
*
|
||||||
|
* @return string client id
|
||||||
|
*/
|
||||||
|
public function getTwoFactorAuthenticationClientId() {
|
||||||
|
return $this->twoFactorAuthenticationClientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the secret key.
|
||||||
|
*
|
||||||
|
* @param string $secretKey secret key
|
||||||
|
*/
|
||||||
|
public function setTwoFactorAuthenticationSecretKey($secretKey) {
|
||||||
|
$this->twoFactorAuthenticationSecretKey = $secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the secret key.
|
||||||
|
*
|
||||||
|
* @return string secret key
|
||||||
|
*/
|
||||||
|
public function getTwoFactorAuthenticationSecretKey() {
|
||||||
|
return $this->twoFactorAuthenticationSecretKey;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if SSL certificate verification is turned off.
|
* Returns if SSL certificate verification is turned off.
|
||||||
*
|
*
|
||||||
* @return bool $twoFactorAuthenticationInsecure SSL certificate verification is turned off
|
* @return bool SSL certificate verification is turned off
|
||||||
*/
|
*/
|
||||||
public function getTwoFactorAuthenticationInsecure() {
|
public function getTwoFactorAuthenticationInsecure() {
|
||||||
return $this->twoFactorAuthenticationInsecure;
|
return $this->twoFactorAuthenticationInsecure;
|
||||||
|
@ -2187,7 +2227,7 @@ class LAMConfig {
|
||||||
/**
|
/**
|
||||||
* Returns the authentication label.
|
* Returns the authentication label.
|
||||||
*
|
*
|
||||||
* @return string $twoFactorAuthenticationLabel authentication label
|
* @return string authentication label
|
||||||
*/
|
*/
|
||||||
public function getTwoFactorAuthenticationLabel() {
|
public function getTwoFactorAuthenticationLabel() {
|
||||||
return $this->twoFactorAuthenticationLabel;
|
return $this->twoFactorAuthenticationLabel;
|
||||||
|
@ -2205,7 +2245,7 @@ class LAMConfig {
|
||||||
/**
|
/**
|
||||||
* Returns if 2nd factor is optional.
|
* Returns if 2nd factor is optional.
|
||||||
*
|
*
|
||||||
* @return bool $twoFactorAuthenticationOptional 2nd factor is optional
|
* @return bool 2nd factor is optional
|
||||||
*/
|
*/
|
||||||
public function getTwoFactorAuthenticationOptional() {
|
public function getTwoFactorAuthenticationOptional() {
|
||||||
return $this->twoFactorAuthenticationOptional;
|
return $this->twoFactorAuthenticationOptional;
|
||||||
|
@ -2223,7 +2263,7 @@ class LAMConfig {
|
||||||
/**
|
/**
|
||||||
* Returns the caption HTML.
|
* Returns the caption HTML.
|
||||||
*
|
*
|
||||||
* @return string $twoFactorAuthenticationCaption caption HTML
|
* @return string caption HTML
|
||||||
*/
|
*/
|
||||||
public function getTwoFactorAuthenticationCaption() {
|
public function getTwoFactorAuthenticationCaption() {
|
||||||
return $this->twoFactorAuthenticationCaption;
|
return $this->twoFactorAuthenticationCaption;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
$Id$
|
$Id$
|
||||||
|
|
||||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||||
Copyright (C) 2003 - 2017 Roland Gruber
|
Copyright (C) 2003 - 2018 Roland Gruber
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -57,7 +57,7 @@ class Ldap{
|
||||||
*
|
*
|
||||||
* @param object $config an object of class Config
|
* @param object $config an object of class Config
|
||||||
*/
|
*/
|
||||||
function __construct($config) {
|
public function __construct($config) {
|
||||||
if (is_object($config)) {
|
if (is_object($config)) {
|
||||||
$this->conf = $config;
|
$this->conf = $config;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ class Ldap{
|
||||||
* @param boolean $allowAnonymous specifies if anonymous binds are allowed
|
* @param boolean $allowAnonymous specifies if anonymous binds are allowed
|
||||||
* @return mixed if connect succeeds the 0 is returned, else false or error number
|
* @return mixed if connect succeeds the 0 is returned, else false or error number
|
||||||
*/
|
*/
|
||||||
function connect($user, $passwd, $allowAnonymous=false) {
|
public function connect($user, $passwd, $allowAnonymous=false) {
|
||||||
// close any prior connection
|
// close any prior connection
|
||||||
@$this->close();
|
@$this->close();
|
||||||
// do not allow anonymous bind
|
// do not allow anonymous bind
|
||||||
|
@ -105,7 +105,7 @@ class Ldap{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Closes connection to server */
|
/** Closes connection to server */
|
||||||
function close() {
|
public function close() {
|
||||||
if ($this->server != null) {
|
if ($this->server != null) {
|
||||||
@ldap_close($this->server);
|
@ldap_close($this->server);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ class Ldap{
|
||||||
*
|
*
|
||||||
* @return object connection handle
|
* @return object connection handle
|
||||||
*/
|
*/
|
||||||
function server() {
|
public function server() {
|
||||||
if (!$this->is_connected) {
|
if (!$this->is_connected) {
|
||||||
$data = $this->decrypt_login();
|
$data = $this->decrypt_login();
|
||||||
$this->connect($data[0], $data[1]);
|
$this->connect($data[0], $data[1]);
|
||||||
|
@ -126,14 +126,14 @@ class Ldap{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Closes connection to LDAP server before serialization */
|
/** Closes connection to LDAP server before serialization */
|
||||||
function __sleep() {
|
public function __sleep() {
|
||||||
$this->close();
|
$this->close();
|
||||||
// define which attributes to save
|
// define which attributes to save
|
||||||
return array("conf", "username", "password");
|
return array("conf", "username", "password");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reconnects to LDAP server when deserialized */
|
/** Reconnects to LDAP server when deserialized */
|
||||||
function __wakeup() {
|
public function __wakeup() {
|
||||||
$this->is_connected = false;
|
$this->is_connected = false;
|
||||||
// delete PDF files and images which are older than 15 min
|
// delete PDF files and images which are older than 15 min
|
||||||
$tmpDir = dirname(__FILE__) . '/../tmp/';
|
$tmpDir = dirname(__FILE__) . '/../tmp/';
|
||||||
|
@ -173,7 +173,7 @@ class Ldap{
|
||||||
* @param string $username LDAP user name
|
* @param string $username LDAP user name
|
||||||
* @param string $password LDAP password
|
* @param string $password LDAP password
|
||||||
*/
|
*/
|
||||||
function encrypt_login($username, $password) {
|
public function encrypt_login($username, $password) {
|
||||||
// encrypt username and password
|
// encrypt username and password
|
||||||
$this->username = base64_encode(lamEncrypt($username));
|
$this->username = base64_encode(lamEncrypt($username));
|
||||||
$this->password = base64_encode(lamEncrypt($password));
|
$this->password = base64_encode(lamEncrypt($password));
|
||||||
|
@ -184,7 +184,7 @@ class Ldap{
|
||||||
*
|
*
|
||||||
* @return array array(user name, password)
|
* @return array array(user name, password)
|
||||||
*/
|
*/
|
||||||
function decrypt_login() {
|
public function decrypt_login() {
|
||||||
// decrypt username and password
|
// decrypt username and password
|
||||||
$username = lamDecrypt(base64_decode($this->username));
|
$username = lamDecrypt(base64_decode($this->username));
|
||||||
$password = lamDecrypt(base64_decode($this->password));
|
$password = lamDecrypt(base64_decode($this->password));
|
||||||
|
@ -192,8 +192,26 @@ class Ldap{
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the LDAP user name.
|
||||||
|
*
|
||||||
|
* @return string user name
|
||||||
|
*/
|
||||||
|
public function getUserName() {
|
||||||
|
return lamDecrypt(base64_decode($this->username));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the LDAP password.
|
||||||
|
*
|
||||||
|
* @return string password
|
||||||
|
*/
|
||||||
|
public function getPassword() {
|
||||||
|
return lamDecrypt(base64_decode($this->password));
|
||||||
|
}
|
||||||
|
|
||||||
/** Closes connection to LDAP server and deletes encrypted username/password */
|
/** Closes connection to LDAP server and deletes encrypted username/password */
|
||||||
function destroy() {
|
public function destroy() {
|
||||||
$this->close();
|
$this->close();
|
||||||
$this->username="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
$this->username="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||||
$this->password="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
$this->password="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||||
|
|
|
@ -5,7 +5,7 @@ use \LAM\PDF\PDFTableRow;
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||||
Copyright (C) 2018 Roland Gruber
|
Copyright (C) 2018 - 2019 Roland Gruber
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -308,7 +308,7 @@ class yubiKeyUser extends baseModule {
|
||||||
for ($i = 0; $i < sizeof($keys); $i++) {
|
for ($i = 0; $i < sizeof($keys); $i++) {
|
||||||
$group = new htmlGroup();
|
$group = new htmlGroup();
|
||||||
$keyInput = new htmlInputField('yubiKeyId_' . $i, $keys[$i]);
|
$keyInput = new htmlInputField('yubiKeyId_' . $i, $keys[$i]);
|
||||||
$keyInput->setFieldMaxLength(16384);
|
$keyInput->setFieldMaxLength(12);
|
||||||
$group->addElement($keyInput);
|
$group->addElement($keyInput);
|
||||||
$delLink = new htmlLink('', '#', '../../graphics/del.png');
|
$delLink = new htmlLink('', '#', '../../graphics/del.png');
|
||||||
$delLink->setTitle(_('Delete'));
|
$delLink->setTitle(_('Delete'));
|
||||||
|
|
|
@ -284,7 +284,7 @@ function installPDFTemplates() {
|
||||||
$entry = $templateDir->read();
|
$entry = $templateDir->read();
|
||||||
while ($entry){
|
while ($entry){
|
||||||
$path = $basePath . '/logos/' . $entry;
|
$path = $basePath . '/logos/' . $entry;
|
||||||
if ((strpos($entry, '.') !== 1) && !is_file($path)) {
|
if ((strpos($entry, '.') !== 0) && !is_file($path)) {
|
||||||
$template = $templatePath . '/' . $entry;
|
$template = $templatePath . '/' . $entry;
|
||||||
logNewMessage(LOG_DEBUG, 'Copy template ' . $template . ' to ' . $path);
|
logNewMessage(LOG_DEBUG, 'Copy template ' . $template . ' to ' . $path);
|
||||||
@copy($template, $path);
|
@copy($template, $path);
|
||||||
|
|
|
@ -3,7 +3,7 @@ use \LAM\LIB\TWO_FACTOR\TwoFactorProviderService;
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||||
Copyright (C) 2006 - 2018 Roland Gruber
|
Copyright (C) 2006 - 2019 Roland Gruber
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -300,6 +300,38 @@ function isSelfService() {
|
||||||
return session_name() == 'SELFSERVICE';
|
return session_name() == 'SELFSERVICE';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the LDAP connection and returns the handle. No bind is done.
|
||||||
|
*
|
||||||
|
* @param selfServiceProfile $profile profile
|
||||||
|
* @return handle LDAP handle or null if connection failed
|
||||||
|
*/
|
||||||
|
function openSelfServiceLdapConnection($profile) {
|
||||||
|
$server = connectToLDAP($profile->serverURL, $profile->useTLS);
|
||||||
|
if ($server != null) {
|
||||||
|
// follow referrals
|
||||||
|
ldap_set_option($server, LDAP_OPT_REFERRALS, $profile->followReferrals);
|
||||||
|
}
|
||||||
|
return $server;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds the LDAP connections with given user and password.
|
||||||
|
*
|
||||||
|
* @param handle $handle LDAP handle
|
||||||
|
* @param selfServiceProfile profile
|
||||||
|
* @param string $userDn bind DN
|
||||||
|
* @param string $password bind password
|
||||||
|
* @return boolean binding successful
|
||||||
|
*/
|
||||||
|
function bindLdapUser($handle, $profile, $userDn, $password) {
|
||||||
|
if ($profile->useForAllOperations) {
|
||||||
|
$userDn = $profile->LDAPUser;
|
||||||
|
$password = deobfuscateText($profile->LDAPPassword);
|
||||||
|
}
|
||||||
|
return @ldap_bind($handle, $userDn, $password);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Includes all settings of a self service profile.
|
* Includes all settings of a self service profile.
|
||||||
|
@ -391,6 +423,8 @@ class selfServiceProfile {
|
||||||
public $twoFactorAuthenticationLabel = null;
|
public $twoFactorAuthenticationLabel = null;
|
||||||
public $twoFactorAuthenticationOptional = false;
|
public $twoFactorAuthenticationOptional = false;
|
||||||
public $twoFactorAuthenticationCaption = '';
|
public $twoFactorAuthenticationCaption = '';
|
||||||
|
public $twoFactorAuthenticationClientId = '';
|
||||||
|
public $twoFactorAuthenticationSecretKey = '';
|
||||||
|
|
||||||
/** provider for captcha (-/google) */
|
/** provider for captcha (-/google) */
|
||||||
public $captchaProvider = '-';
|
public $captchaProvider = '-';
|
||||||
|
@ -445,6 +479,8 @@ class selfServiceProfile {
|
||||||
$this->twoFactorAuthenticationLabel = null;
|
$this->twoFactorAuthenticationLabel = null;
|
||||||
$this->twoFactorAuthenticationOptional = false;
|
$this->twoFactorAuthenticationOptional = false;
|
||||||
$this->twoFactorAuthenticationCaption = '';
|
$this->twoFactorAuthenticationCaption = '';
|
||||||
|
$this->twoFactorAuthenticationClientId = '';
|
||||||
|
$this->twoFactorAuthenticationSecretKey = '';
|
||||||
$this->captchaProvider = '-';
|
$this->captchaProvider = '-';
|
||||||
$this->reCaptchaSiteKey = '';
|
$this->reCaptchaSiteKey = '';
|
||||||
$this->reCaptchaSecretKey = '';
|
$this->reCaptchaSecretKey = '';
|
||||||
|
|
|
@ -22,7 +22,7 @@ use \htmlGroup;
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||||
Copyright (C) 2003 - 2017 Roland Gruber
|
Copyright (C) 2003 - 2018 Roland Gruber
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -460,19 +460,29 @@ if (extension_loaded('curl')) {
|
||||||
$twoFactorOptions = array(
|
$twoFactorOptions = array(
|
||||||
_('None') => TwoFactorProviderService::TWO_FACTOR_NONE,
|
_('None') => TwoFactorProviderService::TWO_FACTOR_NONE,
|
||||||
'privacyIDEA' => TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA,
|
'privacyIDEA' => TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA,
|
||||||
|
'YubiKey' => TwoFactorProviderService::TWO_FACTOR_YUBICO,
|
||||||
);
|
);
|
||||||
$twoFactorSelect = new htmlResponsiveSelect('twoFactor', $twoFactorOptions, array($conf->getTwoFactorAuthentication()), _('Provider'), '514');
|
$twoFactorSelect = new htmlResponsiveSelect('twoFactor', $twoFactorOptions, array($conf->getTwoFactorAuthentication()), _('Provider'), '514');
|
||||||
$twoFactorSelect->setHasDescriptiveElements(true);
|
$twoFactorSelect->setHasDescriptiveElements(true);
|
||||||
$twoFactorSelect->setTableRowsToHide(array(
|
$twoFactorSelect->setTableRowsToHide(array(
|
||||||
TwoFactorProviderService::TWO_FACTOR_NONE => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel', 'twoFactorOptional', 'twoFactorCaption')
|
TwoFactorProviderService::TWO_FACTOR_NONE => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel',
|
||||||
|
'twoFactorOptional', 'twoFactorCaption', 'twoFactorClientId', 'twoFactorSecretKey'),
|
||||||
|
TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA => array('twoFactorClientId', 'twoFactorSecretKey')
|
||||||
));
|
));
|
||||||
$twoFactorSelect->setTableRowsToShow(array(
|
$twoFactorSelect->setTableRowsToShow(array(
|
||||||
TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel', 'twoFactorOptional', 'twoFactorCaption')
|
TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel',
|
||||||
|
'twoFactorOptional', 'twoFactorCaption'),
|
||||||
|
TwoFactorProviderService::TWO_FACTOR_YUBICO => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel',
|
||||||
|
'twoFactorOptional', 'twoFactorCaption', 'twoFactorClientId', 'twoFactorSecretKey'),
|
||||||
));
|
));
|
||||||
$row->add($twoFactorSelect, 12);
|
$row->add($twoFactorSelect, 12);
|
||||||
$twoFactorUrl = new htmlResponsiveInputField(_("Base URL"), 'twoFactorURL', $conf->getTwoFactorAuthenticationURL(), '515');
|
$twoFactorUrl = new htmlResponsiveInputField(_("Base URL"), 'twoFactorURL', $conf->getTwoFactorAuthenticationURL(), '515');
|
||||||
$twoFactorUrl->setRequired(true);
|
$twoFactorUrl->setRequired(true);
|
||||||
$row->add($twoFactorUrl, 12);
|
$row->add($twoFactorUrl, 12);
|
||||||
|
$twoFactorClientId = new htmlResponsiveInputField(_("Client id"), 'twoFactorClientId', $conf->getTwoFactorAuthenticationClientId(), '524');
|
||||||
|
$row->add($twoFactorClientId, 12);
|
||||||
|
$twoFactorSecretKey = new htmlResponsiveInputField(_("Secret key"), 'twoFactorSecretKey', $conf->getTwoFactorAuthenticationSecretKey(), '525');
|
||||||
|
$row->add($twoFactorSecretKey, 12);
|
||||||
$twoFactorLabel = new htmlResponsiveInputField(_("Label"), 'twoFactorLabel', $conf->getTwoFactorAuthenticationLabel(), '517');
|
$twoFactorLabel = new htmlResponsiveInputField(_("Label"), 'twoFactorLabel', $conf->getTwoFactorAuthenticationLabel(), '517');
|
||||||
$row->add($twoFactorLabel, 12);
|
$row->add($twoFactorLabel, 12);
|
||||||
$row->add(new htmlResponsiveInputCheckbox('twoFactorOptional', $conf->getTwoFactorAuthenticationOptional(), _('Optional'), '519'), 12);
|
$row->add(new htmlResponsiveInputCheckbox('twoFactorOptional', $conf->getTwoFactorAuthenticationOptional(), _('Optional'), '519'), 12);
|
||||||
|
@ -677,6 +687,8 @@ function checkInput() {
|
||||||
if (extension_loaded('curl')) {
|
if (extension_loaded('curl')) {
|
||||||
$conf->setTwoFactorAuthentication($_POST['twoFactor']);
|
$conf->setTwoFactorAuthentication($_POST['twoFactor']);
|
||||||
$conf->setTwoFactorAuthenticationURL($_POST['twoFactorURL']);
|
$conf->setTwoFactorAuthenticationURL($_POST['twoFactorURL']);
|
||||||
|
$conf->setTwoFactorAuthenticationClientId($_POST['twoFactorClientId']);
|
||||||
|
$conf->setTwoFactorAuthenticationSecretKey($_POST['twoFactorSecretKey']);
|
||||||
$conf->setTwoFactorAuthenticationInsecure(isset($_POST['twoFactorInsecure']) && ($_POST['twoFactorInsecure'] == 'on'));
|
$conf->setTwoFactorAuthenticationInsecure(isset($_POST['twoFactorInsecure']) && ($_POST['twoFactorInsecure'] == 'on'));
|
||||||
$conf->setTwoFactorAuthenticationLabel($_POST['twoFactorLabel']);
|
$conf->setTwoFactorAuthenticationLabel($_POST['twoFactorLabel']);
|
||||||
$conf->setTwoFactorAuthenticationOptional(isset($_POST['twoFactorOptional']) && ($_POST['twoFactorOptional'] == 'on'));
|
$conf->setTwoFactorAuthenticationOptional(isset($_POST['twoFactorOptional']) && ($_POST['twoFactorOptional'] == 'on'));
|
||||||
|
|
|
@ -499,6 +499,94 @@ class LAMConfigTest extends PHPUnit_Framework_TestCase {
|
||||||
$this->assertEquals($val, $this->lAMConfig->getHttpAuthentication());
|
$this->assertEquals($val, $this->lAMConfig->getHttpAuthentication());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests LAMConfig->getTwoFactorAuthentication() and LAMConfig->setTwoFactorAuthentication()
|
||||||
|
*/
|
||||||
|
public function testTwoFactorAuthentication() {
|
||||||
|
$val = '2fid';
|
||||||
|
$this->lAMConfig->setTwoFactorAuthentication($val);
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthentication());
|
||||||
|
$this->doSave();
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthentication());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests LAMConfig->getTwoFactorAuthenticationURL() and LAMConfig->setTwoFactorAuthenticationURL()
|
||||||
|
*/
|
||||||
|
public function testTwoFactorAuthenticationURL() {
|
||||||
|
$val = 'http://example.com';
|
||||||
|
$this->lAMConfig->setTwoFactorAuthenticationURL($val);
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationURL());
|
||||||
|
$this->doSave();
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests LAMConfig->getTwoFactorAuthenticationClientId() and LAMConfig->setTwoFactorAuthenticationClientId()
|
||||||
|
*/
|
||||||
|
public function testTwoFactorAuthenticationClientId() {
|
||||||
|
$val = '1234';
|
||||||
|
$this->lAMConfig->setTwoFactorAuthenticationClientId($val);
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationClientId());
|
||||||
|
$this->doSave();
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationClientId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests LAMConfig->getTwoFactorAuthenticationSecretKey() and LAMConfig->setTwoFactorAuthenticationSecretKey()
|
||||||
|
*/
|
||||||
|
public function testTwoFactorAuthenticationSecretKey() {
|
||||||
|
$val = '3333key';
|
||||||
|
$this->lAMConfig->setTwoFactorAuthenticationSecretKey($val);
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationSecretKey());
|
||||||
|
$this->doSave();
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationSecretKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests LAMConfig->getTwoFactorAuthenticationInsecure() and LAMConfig->setTwoFactorAuthenticationInsecure()
|
||||||
|
*/
|
||||||
|
public function testTwoFactorAuthenticationInsecure() {
|
||||||
|
$val = true;
|
||||||
|
$this->lAMConfig->setTwoFactorAuthenticationInsecure($val);
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationInsecure());
|
||||||
|
$this->doSave();
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationInsecure());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests LAMConfig->getTwoFactorAuthenticationLabel() and LAMConfig->setTwoFactorAuthenticationLabel()
|
||||||
|
*/
|
||||||
|
public function testTwoFactorAuthenticationLabel() {
|
||||||
|
$val = '2falabel';
|
||||||
|
$this->lAMConfig->setTwoFactorAuthenticationLabel($val);
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationLabel());
|
||||||
|
$this->doSave();
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests LAMConfig->getTwoFactorAuthenticationOptional() and LAMConfig->setTwoFactorAuthenticationOptional()
|
||||||
|
*/
|
||||||
|
public function testTwoFactorAuthenticationOptional() {
|
||||||
|
$val = true;
|
||||||
|
$this->lAMConfig->setTwoFactorAuthenticationOptional($val);
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationOptional());
|
||||||
|
$this->doSave();
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationOptional());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests LAMConfig->getTwoFactorAuthenticationCaption() and LAMConfig->setTwoFactorAuthenticationCaption()
|
||||||
|
*/
|
||||||
|
public function testTwoFactorAuthenticationCaption() {
|
||||||
|
$val = '2facaption';
|
||||||
|
$this->lAMConfig->setTwoFactorAuthenticationCaption($val);
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationCaption());
|
||||||
|
$this->doSave();
|
||||||
|
$this->assertEquals($val, $this->lAMConfig->getTwoFactorAuthenticationCaption());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests LAMConfig->getLamProMailFrom() and LAMConfig->setLamProMailFrom()
|
* Tests LAMConfig->getLamProMailFrom() and LAMConfig->setLamProMailFrom()
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue