Merge pull request #79 from LDAPAccountManager/yubico_multiServer
YubiKey multi server setup
This commit is contained in:
commit
1dac968a02
|
@ -1,6 +1,7 @@
|
||||||
December 2019 7.0
|
December 2019 7.0
|
||||||
- Lamdaemon can be configured with directory prefix for homedirs
|
- Lamdaemon can be configured with directory prefix for homedirs
|
||||||
- Account list filters match on substrings instead of whole value
|
- Account list filters match on substrings instead of whole value
|
||||||
|
- YubiKey: support to configure multiple verification servers
|
||||||
- Fixed bugs:
|
- Fixed bugs:
|
||||||
-> Missing CSS for Duo
|
-> Missing CSS for Duo
|
||||||
-> Editing of DNs with comma on Windows (210)
|
-> Editing of DNs with comma on Windows (210)
|
||||||
|
|
|
@ -659,7 +659,7 @@
|
||||||
|
|
||||||
<para>Configuration options:</para>
|
<para>Configuration options:</para>
|
||||||
|
|
||||||
<para>privacyIDEA:</para>
|
<para><emphasis role="bold">privacyIDEA</emphasis></para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -686,16 +686,21 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>YubiKey:</para>
|
<para><emphasis role="bold">YubiKey</emphasis></para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Base URL: please enter the URL of your YubiKey verfication
|
<para>Base URLs: please enter the URL(s) of your YubiKey
|
||||||
server. For YubiKey cloud this is
|
verification server(s). If you run a custom verification API such
|
||||||
"https://api.yubico.com/wsapi/2.0/verify". If you run a custom
|
as yubiserver then enter its URL (e.g.
|
||||||
verification API such as yubiserver then enter its URL (e.g.
|
|
||||||
http://www.example.com:8000/wsapi/2.0/verify). The URL needs to
|
http://www.example.com:8000/wsapi/2.0/verify). The URL needs to
|
||||||
end with "/wsapi/2.0/verify".</para>
|
end with "/wsapi/2.0/verify". For YubiKey cloud these are
|
||||||
|
"https://api.yubico.com/wsapi/2.0/verify",
|
||||||
|
"https://api2.yubico.com/wsapi/2.0/verify",
|
||||||
|
"https://api3.yubico.com/wsapi/2.0/verify",
|
||||||
|
"https://api4.yubico.com/wsapi/2.0/verify" and
|
||||||
|
"https://api5.yubico.com/wsapi/2.0/verify". Enter one URL per
|
||||||
|
line.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -722,7 +727,7 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>Duo:</para>
|
<para><emphasis role="bold">Duo</emphasis></para>
|
||||||
|
|
||||||
<para>This requires to register a new "Web SDK" application in your
|
<para>This requires to register a new "Web SDK" application in your
|
||||||
Duo admin panel.</para>
|
Duo admin panel.</para>
|
||||||
|
|
|
@ -331,7 +331,7 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>privacyIDEA:</para>
|
<para><emphasis role="bold">privacyIDEA</emphasis></para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -358,16 +358,21 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>YubiKey:</para>
|
<para><emphasis role="bold">YubiKey</emphasis></para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Base URL: please enter the URL of your YubiKey verfication
|
<para>Base URLs: please enter the URL(s) of your YubiKey
|
||||||
server. For YubiKey cloud this is
|
verification server(s). If you run a custom verification API such
|
||||||
"https://api.yubico.com/wsapi/2.0/verify". If you run a custom
|
as yubiserver then enter its URL (e.g.
|
||||||
verification API such as yubiserver then enter its URL (e.g.
|
|
||||||
http://www.example.com:8000/wsapi/2.0/verify). The URL needs to
|
http://www.example.com:8000/wsapi/2.0/verify). The URL needs to
|
||||||
end with "/wsapi/2.0/verify".</para>
|
end with "/wsapi/2.0/verify". For YubiKey cloud these are
|
||||||
|
"https://api.yubico.com/wsapi/2.0/verify",
|
||||||
|
"https://api2.yubico.com/wsapi/2.0/verify",
|
||||||
|
"https://api3.yubico.com/wsapi/2.0/verify",
|
||||||
|
"https://api4.yubico.com/wsapi/2.0/verify" and
|
||||||
|
"https://api5.yubico.com/wsapi/2.0/verify". Enter one URL per
|
||||||
|
line.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -394,7 +399,7 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>Duo:</para>
|
<para><emphasis role="bold">Duo</emphasis></para>
|
||||||
|
|
||||||
<para>This requires to register a new "Web SDK" application in your
|
<para>This requires to register a new "Web SDK" application in your
|
||||||
Duo admin panel.</para>
|
Duo admin panel.</para>
|
||||||
|
|
|
@ -301,6 +301,8 @@ $helpArray = array (
|
||||||
"Text" => _('You can enable 2-factor authentication here (e.g. via mobile device).')),
|
"Text" => _('You can enable 2-factor authentication here (e.g. via mobile device).')),
|
||||||
"515" => array ("Headline" => _('Base URL'),
|
"515" => array ("Headline" => _('Base URL'),
|
||||||
"Text" => _('URL of external 2-factor authentication service.')),
|
"Text" => _('URL of external 2-factor authentication service.')),
|
||||||
|
"515a" => array ("Headline" => _('Base URLs'),
|
||||||
|
"Text" => _('URLs of external 2-factor authentication service. Enter one per line.')),
|
||||||
"516" => array ("Headline" => _('Disable certificate check'),
|
"516" => array ("Headline" => _('Disable certificate check'),
|
||||||
"Text" => _('This will disable the check of the SSL certificates for the 2-factor authentication service. Not recommended for production usage.')),
|
"Text" => _('This will disable the check of the SSL certificates for the 2-factor authentication service. Not recommended for production usage.')),
|
||||||
"517" => array ("Headline" => _('Label'),
|
"517" => array ("Headline" => _('Label'),
|
||||||
|
|
|
@ -3,8 +3,8 @@ namespace LAM\LIB\TWO_FACTOR;
|
||||||
use \selfServiceProfile;
|
use \selfServiceProfile;
|
||||||
use \LAMConfig;
|
use \LAMConfig;
|
||||||
use \htmlScript;
|
use \htmlScript;
|
||||||
use \htmlInputField;
|
|
||||||
use \htmlIframe;
|
use \htmlIframe;
|
||||||
|
use \LAMException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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/)
|
||||||
|
@ -356,13 +356,22 @@ class YubicoProvider extends BaseProvider {
|
||||||
if (!$serialMatched) {
|
if (!$serialMatched) {
|
||||||
throw new \Exception(_('YubiKey id does not match allowed list of key ids.'));
|
throw new \Exception(_('YubiKey id does not match allowed list of key ids.'));
|
||||||
}
|
}
|
||||||
$url = $this->config->twoFactorAuthenticationURL;
|
$urls = $this->config->twoFactorAuthenticationURL;
|
||||||
|
shuffle($urls);
|
||||||
$httpsverify = !$this->config->twoFactorAuthenticationInsecure;
|
$httpsverify = !$this->config->twoFactorAuthenticationInsecure;
|
||||||
$clientId = $this->config->twoFactorAuthenticationClientId;
|
$clientId = $this->config->twoFactorAuthenticationClientId;
|
||||||
$secretKey = $this->config->twoFactorAuthenticationSecretKey;
|
$secretKey = $this->config->twoFactorAuthenticationSecretKey;
|
||||||
$auth = new \Auth_Yubico($clientId, $secretKey, $url, $httpsverify);
|
foreach ($urls as $url) {
|
||||||
$auth->verify($twoFactorInput);
|
try {
|
||||||
return true;
|
$auth = new \Auth_Yubico($clientId, $secretKey, $url, $httpsverify);
|
||||||
|
$auth->verify($twoFactorInput);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (LAMException $e) {
|
||||||
|
logNewMessage(LOG_DEBUG, 'Unable to verify 2FA: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -525,7 +534,12 @@ class TwoFactorProviderService {
|
||||||
$tfConfig->isSelfService = true;
|
$tfConfig->isSelfService = true;
|
||||||
$tfConfig->twoFactorAuthentication = $profile->twoFactorAuthentication;
|
$tfConfig->twoFactorAuthentication = $profile->twoFactorAuthentication;
|
||||||
$tfConfig->twoFactorAuthenticationInsecure = $profile->twoFactorAuthenticationInsecure;
|
$tfConfig->twoFactorAuthenticationInsecure = $profile->twoFactorAuthenticationInsecure;
|
||||||
$tfConfig->twoFactorAuthenticationURL = $profile->twoFactorAuthenticationURL;
|
if ($tfConfig->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
||||||
|
$tfConfig->twoFactorAuthenticationURL = explode("\r\n", $profile->twoFactorAuthenticationURL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tfConfig->twoFactorAuthenticationURL = $profile->twoFactorAuthenticationURL;
|
||||||
|
}
|
||||||
$tfConfig->twoFactorAuthenticationClientId = $profile->twoFactorAuthenticationClientId;
|
$tfConfig->twoFactorAuthenticationClientId = $profile->twoFactorAuthenticationClientId;
|
||||||
$tfConfig->twoFactorAuthenticationSecretKey = $profile->twoFactorAuthenticationSecretKey;
|
$tfConfig->twoFactorAuthenticationSecretKey = $profile->twoFactorAuthenticationSecretKey;
|
||||||
if ($tfConfig->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
if ($tfConfig->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
||||||
|
@ -559,7 +573,12 @@ class TwoFactorProviderService {
|
||||||
$tfConfig->isSelfService = false;
|
$tfConfig->isSelfService = false;
|
||||||
$tfConfig->twoFactorAuthentication = $conf->getTwoFactorAuthentication();
|
$tfConfig->twoFactorAuthentication = $conf->getTwoFactorAuthentication();
|
||||||
$tfConfig->twoFactorAuthenticationInsecure = $conf->getTwoFactorAuthenticationInsecure();
|
$tfConfig->twoFactorAuthenticationInsecure = $conf->getTwoFactorAuthenticationInsecure();
|
||||||
$tfConfig->twoFactorAuthenticationURL = $conf->getTwoFactorAuthenticationURL();
|
if ($tfConfig->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
||||||
|
$tfConfig->twoFactorAuthenticationURL = explode("\r\n", $conf->getTwoFactorAuthenticationURL());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tfConfig->twoFactorAuthenticationURL = $conf->getTwoFactorAuthenticationURL();
|
||||||
|
}
|
||||||
$tfConfig->twoFactorAuthenticationClientId = $conf->getTwoFactorAuthenticationClientId();
|
$tfConfig->twoFactorAuthenticationClientId = $conf->getTwoFactorAuthenticationClientId();
|
||||||
$tfConfig->twoFactorAuthenticationSecretKey = $conf->getTwoFactorAuthenticationSecretKey();
|
$tfConfig->twoFactorAuthenticationSecretKey = $conf->getTwoFactorAuthenticationSecretKey();
|
||||||
if ($tfConfig->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
if ($tfConfig->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
||||||
|
@ -598,7 +617,7 @@ class TwoFactorConfiguration {
|
||||||
public $twoFactorAuthentication = null;
|
public $twoFactorAuthentication = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var service URL
|
* @var string|array service URL(s)
|
||||||
*/
|
*/
|
||||||
public $twoFactorAuthenticationURL = null;
|
public $twoFactorAuthenticationURL = null;
|
||||||
|
|
||||||
|
|
|
@ -2368,7 +2368,7 @@ class LAMConfig {
|
||||||
* @return string authentication URL
|
* @return string authentication URL
|
||||||
*/
|
*/
|
||||||
public function getTwoFactorAuthenticationURL() {
|
public function getTwoFactorAuthenticationURL() {
|
||||||
return $this->twoFactorAuthenticationURL;
|
return implode("\r\n", explode(LAMConfig::LINE_SEPARATOR, $this->twoFactorAuthenticationURL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2377,7 +2377,7 @@ class LAMConfig {
|
||||||
* @param string $twoFactorAuthenticationURL authentication URL
|
* @param string $twoFactorAuthenticationURL authentication URL
|
||||||
*/
|
*/
|
||||||
public function setTwoFactorAuthenticationURL($twoFactorAuthenticationURL) {
|
public function setTwoFactorAuthenticationURL($twoFactorAuthenticationURL) {
|
||||||
$this->twoFactorAuthenticationURL = $twoFactorAuthenticationURL;
|
$this->twoFactorAuthenticationURL = implode(LAMConfig::LINE_SEPARATOR, explode("\r\n", $twoFactorAuthenticationURL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -470,16 +470,16 @@ if (extension_loaded('curl')) {
|
||||||
$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',
|
TwoFactorProviderService::TWO_FACTOR_NONE => array('twoFactorURL', 'twoFactorURLs', 'twoFactorInsecure', 'twoFactorLabel',
|
||||||
'twoFactorOptional', 'twoFactorCaption', 'twoFactorClientId', 'twoFactorSecretKey', 'twoFactorAttribute'),
|
'twoFactorOptional', 'twoFactorCaption', 'twoFactorClientId', 'twoFactorSecretKey', 'twoFactorAttribute'),
|
||||||
TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA => array('twoFactorClientId', 'twoFactorSecretKey'),
|
TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA => array('twoFactorURLs', 'twoFactorClientId', 'twoFactorSecretKey'),
|
||||||
TwoFactorProviderService::TWO_FACTOR_YUBICO => array('twoFactorAttribute'),
|
TwoFactorProviderService::TWO_FACTOR_YUBICO => array('twoFactorURL', 'twoFactorAttribute'),
|
||||||
TwoFactorProviderService::TWO_FACTOR_DUO => array('twoFactorOptional', 'twoFactorInsecure'),
|
TwoFactorProviderService::TWO_FACTOR_DUO => array('twoFactorURLs', 'twoFactorOptional', 'twoFactorInsecure'),
|
||||||
));
|
));
|
||||||
$twoFactorSelect->setTableRowsToShow(array(
|
$twoFactorSelect->setTableRowsToShow(array(
|
||||||
TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel',
|
TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel',
|
||||||
'twoFactorOptional', 'twoFactorCaption', 'twoFactorAttribute'),
|
'twoFactorOptional', 'twoFactorCaption', 'twoFactorAttribute'),
|
||||||
TwoFactorProviderService::TWO_FACTOR_YUBICO => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel',
|
TwoFactorProviderService::TWO_FACTOR_YUBICO => array('twoFactorURLs', 'twoFactorInsecure', 'twoFactorLabel',
|
||||||
'twoFactorOptional', 'twoFactorCaption', 'twoFactorClientId', 'twoFactorSecretKey'),
|
'twoFactorOptional', 'twoFactorCaption', 'twoFactorClientId', 'twoFactorSecretKey'),
|
||||||
TwoFactorProviderService::TWO_FACTOR_DUO => array('twoFactorURL', 'twoFactorLabel',
|
TwoFactorProviderService::TWO_FACTOR_DUO => array('twoFactorURL', 'twoFactorLabel',
|
||||||
'twoFactorCaption', 'twoFactorClientId', 'twoFactorSecretKey', 'twoFactorAttribute'),
|
'twoFactorCaption', 'twoFactorClientId', 'twoFactorSecretKey', 'twoFactorAttribute'),
|
||||||
|
@ -490,6 +490,9 @@ if (extension_loaded('curl')) {
|
||||||
$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);
|
||||||
|
$twoFactorUrl = new htmlResponsiveInputTextarea('twoFactorURLs', $conf->getTwoFactorAuthenticationURL(), '80', '4', _("Base URLs"), '515a');
|
||||||
|
$twoFactorUrl->setRequired(true);
|
||||||
|
$row->add($twoFactorUrl, 12);
|
||||||
$twoFactorClientId = new htmlResponsiveInputField(_("Client id"), 'twoFactorClientId', $conf->getTwoFactorAuthenticationClientId(), '524');
|
$twoFactorClientId = new htmlResponsiveInputField(_("Client id"), 'twoFactorClientId', $conf->getTwoFactorAuthenticationClientId(), '524');
|
||||||
$row->add($twoFactorClientId, 12);
|
$row->add($twoFactorClientId, 12);
|
||||||
$twoFactorSecretKey = new htmlResponsiveInputField(_("Secret key"), 'twoFactorSecretKey', $conf->getTwoFactorAuthenticationSecretKey(), '525');
|
$twoFactorSecretKey = new htmlResponsiveInputField(_("Secret key"), 'twoFactorSecretKey', $conf->getTwoFactorAuthenticationSecretKey(), '525');
|
||||||
|
@ -725,7 +728,12 @@ function checkInput() {
|
||||||
// 2-factor
|
// 2-factor
|
||||||
if (extension_loaded('curl')) {
|
if (extension_loaded('curl')) {
|
||||||
$conf->setTwoFactorAuthentication($_POST['twoFactor']);
|
$conf->setTwoFactorAuthentication($_POST['twoFactor']);
|
||||||
$conf->setTwoFactorAuthenticationURL($_POST['twoFactorURL']);
|
if ($_POST['twoFactor'] === TwoFactorProviderService::TWO_FACTOR_YUBICO) {
|
||||||
|
$conf->setTwoFactorAuthenticationURL($_POST['twoFactorURLs']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$conf->setTwoFactorAuthenticationURL($_POST['twoFactorURL']);
|
||||||
|
}
|
||||||
$conf->setTwoFactorAuthenticationClientId($_POST['twoFactorClientId']);
|
$conf->setTwoFactorAuthenticationClientId($_POST['twoFactorClientId']);
|
||||||
$conf->setTwoFactorAuthenticationSecretKey($_POST['twoFactorSecretKey']);
|
$conf->setTwoFactorAuthenticationSecretKey($_POST['twoFactorSecretKey']);
|
||||||
$conf->setTwoFactorAuthenticationInsecure(isset($_POST['twoFactorInsecure']) && ($_POST['twoFactorInsecure'] == 'on'));
|
$conf->setTwoFactorAuthenticationInsecure(isset($_POST['twoFactorInsecure']) && ($_POST['twoFactorInsecure'] == 'on'));
|
||||||
|
|
Loading…
Reference in New Issue