Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Re-adapt for Yubikey
Browse files Browse the repository at this point in the history
  • Loading branch information
cdujeu committed Sep 12, 2016
1 parent 5271084 commit eb47f15
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 26 deletions.
45 changes: 21 additions & 24 deletions core/src/plugins/authfront.otp/OtpAuthFrontend.php
Expand Up @@ -55,6 +55,7 @@ class OtpAuthFrontend extends AbstractAuthFrontend
private $google;
private $googleLast;

private $yubikeyEnabled;
private $yubikey1;
private $yubikey2;

Expand Down Expand Up @@ -103,10 +104,10 @@ function tryToLogUser(ServerRequestInterface &$request, ResponseInterface &$resp
} else {
$userid = InputFilter::sanitize($httpVars["userid"], InputFilter::SANITIZE_EMAILCHARS);
$this->loadConfig(UsersService::getUserById($userid));
// if there is no configuration for OTP, this means that this user don't have OTP
if(empty($this->googleEnabled) || $this->googleEnabled === false){

if( ( empty($this->googleEnabled) || $this->googleEnabled === false) && (empty($this->yubikeyEnabled) || $this->yubikeyEnabled === false)){
return false;
}else if(empty($this->google)){
}else if($this->googleEnabled && empty($this->google)){
$this->showSetupScreen($userid);
return false;
}
Expand All @@ -115,13 +116,9 @@ function tryToLogUser(ServerRequestInterface &$request, ResponseInterface &$resp
return false;
}

// load Yubico class
if (!empty($this->yubikey1)) {
require_once 'Auth/Yubico.php';
}

// cut off password and otp in pass field
$cutPassword = false;
$codeOTP = "";
if (isSet($httpVars["otp_code"]) && !empty($httpVars["otp_code"])) {
$codeOTP = $httpVars["otp_code"];
} else if (strlen($httpVars["password"]) > 6) {
Expand All @@ -132,10 +129,7 @@ function tryToLogUser(ServerRequestInterface &$request, ResponseInterface &$resp
}

//Just the Google Authenticator set
if (!empty($this->google) &&
empty($this->yubikey1) &&
empty($this->yubikey2)
) {
if (!empty($this->google) && empty($this->yubikey1) && empty($this->yubikey2) ) {
if ($this->checkGooglePass($userid, $codeOTP, $this->google, $this->googleLast)) {
$this->logDebug(__CLASS__, __FUNCTION__, "Check OTP: matched");
//return false and cut off otp from password for next authfront.
Expand All @@ -147,20 +141,13 @@ function tryToLogUser(ServerRequestInterface &$request, ResponseInterface &$resp
} else {
$this->breakAndSendError($exceptionMsg);
}
} elseif
// YubiKey1 or YubiKey2 set
(empty($this->google) &&
(!empty($this->yubikey1) || !empty($this->yubikey2))
) {
} elseif (empty($this->google) && (!empty($this->yubikey1) || !empty($this->yubikey2)) ) {
if ($this->checkYubiOTP($httpVars["otp_code"], $this->yubikey1, $this->yubikey2)) {
return false;
} else {
$this->breakAndSendError($exceptionMsg);
}
} elseif
// Both Yubikey and Google Authenticator set
// If the last character of the password is digit, it is Google Authenticator
(ctype_digit(substr($httpVars["password"], -1))) {
} elseif (ctype_digit(substr($httpVars["password"], -1))) {
if ($this->checkGooglePass($userid, $codeOTP, $this->google, $this->googleLast)) {
if ($cutPassword) {
$httpVars["password"] = substr($httpVars["password"], 0, strlen($httpVars["password"]) - 6);
Expand Down Expand Up @@ -269,8 +256,19 @@ private function loadConfig($userObject)
$this->google = $userObject->getMergedRole()->filterParameterValue("authfront.otp", "google", AJXP_REPO_SCOPE_ALL, '');
$this->googleLast = $userObject->getMergedRole()->filterParameterValue("authfront.otp", "google_last", AJXP_REPO_SCOPE_ALL, '');

$this->yubikeyEnabled = $userObject->getMergedRole()->filterParameterValue("authfront.otp", "yubikey_enabled", AJXP_REPO_SCOPE_ALL, false);
if($this->yubikeyEnabled === "false") {
$this->yubikeyEnabled = false;
}
$this->yubikey1 = $userObject->getMergedRole()->filterParameterValue("authfront.otp", "yubikey1", AJXP_REPO_SCOPE_ALL, '');
if(!empty($this->yubikey1) && strlen($this->yubikey1) > 12) {
$this->yubikey1 = substr($this->yubikey1, 0, 12);
}
$this->yubikey2 = $userObject->getMergedRole()->filterParameterValue("authfront.otp", "yubikey2", AJXP_REPO_SCOPE_ALL, '');
if(!empty($this->yubikey2) && strlen($this->yubikey2) > 12) {
$this->yubikey2 = substr($this->yubikey2, 0, 12);
}

}
if (!empty($this->pluginConf["YUBICO_CLIENT_ID"])) {
$this->yubicoClientId = trim($this->pluginConf["YUBICO_CLIENT_ID"]);
Expand Down Expand Up @@ -420,18 +418,17 @@ public function checkGooglePass($loginId, $codeOTP, $userToken, $userInvalid)
public function checkYubiOTP($otp_code, $yubikey1, $yubikey2)
{

require_once 'Auth/Yubico.php';

// yubikey generates 44 character, identity is the first 12 character
$yubi1_identity = substr($yubikey1, 0, 12);
$yubi2_identity = substr($yubikey2, 0, 12);
$otp_identity = substr($otp_code, -44, 12);
if (($otp_identity != $yubi1_identity) and ($otp_identity != $yubi2_identity)) {
// YubiKey not listed in account
return false;
}

$yotp = substr($otp_code, -44);
$otp_code = substr($otp_code, 0, strlen($otp_code) - 44);

$yubi = new Auth_Yubico($this->yubicoClientId, $this->yubicoSecretKey);
$auth = $yubi->verify($yotp);

Expand Down
5 changes: 3 additions & 2 deletions core/src/plugins/authfront.otp/manifest.xml
Expand Up @@ -22,8 +22,9 @@
description="CONF_MESSAGE[Login page will be modified to give user a OTP textbox.]" default="true"/>
<global_param group="CONF_MESSAGE[Options]" name="YUBICO_SECRET_KEY" type="string" label="CONF_MESSAGE[Yubico Secret Key]" description="CONF_MESSAGE[Yubico secret key attached to your account]" mandatory="false"/>
<global_param group="CONF_MESSAGE[Options]" name="YUBICO_CLIENT_ID" type="string" label="CONF_MESSAGE[Yubico Client ID]" description="CONF_MESSAGE[Yubico client id attached to your account]" mandatory="false"/>
<param name="yubikey1" type="string" label="CONF_MESSAGE[YubiKey 1]" description="CONF_MESSAGE[YubiKey 1]" mandatory="false"/>
<param name="yubikey2" type="string" label="CONF_MESSAGE[YubiKey 2]" description="CONF_MESSAGE[YubiKey 2]" mandatory="false"/>
<param name="yubikey_enabled" group="CONF_MESSAGE[Yubikey]" type="boolean" label="CONF_MESSAGE[Use Yubikey]" description="CONF_MESSAGE[Require a Yubikey usage by the user.]" mandatory="false" default="false" expose="true" scope="user,group"/>
<param name="yubikey1" group="CONF_MESSAGE[Yubikey]" type="string" label="CONF_MESSAGE[Your YubiKey ID]" description="CONF_MESSAGE[YubiKey ID. To add a yubikey, simply use your key button to fill this field.]" mandatory="false" expose="true" scope="user"/>
<param name="yubikey2" group="CONF_MESSAGE[Yubikey]" type="string" label="CONF_MESSAGE[Second YubiKey ID]" description="CONF_MESSAGE[YubiKey ID. To add a second yubikey, simply use your key button to fill this field.]" mandatory="false" expose="true" scope="user"/>
<param name="google_enabled_admin" group="CONF_MESSAGE[Google Authenticator]" type="boolean" label="CONF_MESSAGE[Force Google Authenticator]" description="CONF_MESSAGE[Force Google Auth usage without letting the choice to the user.]" mandatory="false" default="false" scope="user,group"/>
<param name="google_enabled" group="CONF_MESSAGE[Google Authenticator]" type="boolean" label="CONF_MESSAGE[Enable Google Authenticator]" description="CONF_MESSAGE[If you enable it for the first time, you will be able to configure Google Authenticator application next time you log in.]" mandatory="false" default="false" scope="user,group" expose="true"/>
<param name="google" group="CONF_MESSAGE[Google Authenticator]" type="string" label="CONF_MESSAGE[Google Authenticator Secret]" description="CONF_MESSAGE[Google Authenticator Secret Key.]" mandatory="false" scope="user"/>
Expand Down

0 comments on commit eb47f15

Please sign in to comment.