Skip to content

Commit

Permalink
[CHANGE] Enhance overall functionality and make usage of PEAR library…
Browse files Browse the repository at this point in the history
… optional

* Make PEAR usage (of Auth/Yubico.php) optional and provide native OTP
  verification by add class YubiKeyAuth for native OTP verification
* Update EM configuration options and provide new option to enable PEAR
  Is turned off by default to avoid PHP fatal errors
* Allow multiple YubiKeys for a single backend user
* Update source for TYPO3CMS CGL compliance
  • Loading branch information
abeutel committed Sep 25, 2014
1 parent 092afac commit 5cbe09f
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 53 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# PHP Storm, other java IDE's
.idea
.idea
atlassian-ide-plugin.xml
167 changes: 167 additions & 0 deletions Classes/YubiKeyAuth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php
/***************************************************************
* Copyright notice
*
* (c) 2013 - 2014 mehrwert <typo3@mehrwert.de>
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/

/**
* Provides YubiKey authentication without dependencies to
* PEAR packages
*
* @author mehrwert <typo3@mehrwert.de>
* @package TYPO3
* @subpackage tx_sfyubikey
* @license GPL
*/
class Tx_SfYubiKey_YubiKeyAuth {

/**
* @var array
*/
protected $config = array();

/**
* Constructor for this class
*
* @param Array $extensionConfiguration
*/
public function __construct( $extensionConfiguration ) {

// Set configuration
$this->setConfig( trim($extensionConfiguration['yubikeyApiUrl']), 'yubikeyApiUrl' );
$this->setConfig( trim($extensionConfiguration['yubikeyClientId']), 'yubikeyClientId' );
$this->setConfig( trim($extensionConfiguration['yubikeyClientKey']), 'yubikeyClientKey' );

}

/**
* Do OTP check if user has been setup to do so.
*
* @param String $yubikeyOtp
* @return Boolean
*/
public function checkOtp( $yubikeyOtp ) {

$ret = FALSE;
$otp = trim( $yubikeyOtp );

// Verify if the OTP is valid ?
if ( $this->verifyOtp($otp)) {
$ret = TRUE;
}

return $ret;
}

/**
* Verify HMAC-SHA1 signatur on result received from Yubico server
*
* @param String $response Data from Yubico
* @param String $yubicoApiKey Shared API key
* @return Boolean Does the signature match ?
*/
public function verifyHmac($response, $yubicoApiKey) {
$lines = t3lib_div::trimExplode(chr(10), $response);
// Create array from data
foreach ($lines as $line) {
$lineparts = t3lib_div::trimExplode('=', $line, FALSE, 2);
$result[$lineparts[0]] = trim($lineparts[1]);
}
// Sort array Alphabetically based on keys
ksort($result);
// Grab the signature sent by server, and delete
$signatur = $result['h'];
unset($result['h']);
// Build new string to calculate hmac signature on
$datastring = '';
foreach ($result as $key => $value) {
$datastring != '' ? $datastring .= '&' : $datastring .= '';
$datastring .= $key . '=' . $value;
}
$hmac = base64_encode(hash_hmac('sha1', $datastring, base64_decode($yubicoApiKey), TRUE));
return $hmac == $signatur;
}

/**
* Call the Auth API at Yubico server
*
* @param String $otp One-time Password entered by user
* @return Boolean Is the password OK ?
*/
public function verifyOtp( $otp ) {

// Get the global API ID/KEY
$yubicoApiId = trim($this->getConfig('yubikeyClientId'));
$yubicoApiKey = trim($this->getConfig('yubikeyClientKey'));

$url = $this->getConfig('yubikeyApiUrl') . '?id=' . $yubicoApiId . '&otp=' . $otp;

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Enhanced TYPO3 Yubikey OTP Login Service');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = trim(curl_exec($ch));
curl_close($ch);

if ( $this->verifyHmac( $response, $yubicoApiKey ) ) {
if ( !preg_match('/status=([a-zA-Z0-9_]+)/', $response, $result) ) {
return FALSE;
}
if ( $result[1] == 'OK' ) {
return TRUE;
}
}
return FALSE;
}

/**
* Set configuration
*
* @param Mixed $config
* @param String $key Optional array key for config attribute
* @return void
*/
public function setConfig($config, $key = '' ) {
if ( $key != '' ) {
$this->config[$key] = $config;
} else {
$this->config = $config;
}
}

/**
* Get configuration
*
* @param String $key Optional array key for config attribute
* @return array
*/
public function getConfig( $key = '' ) {
if ( $key != '' ) {
$ret = $this->config[$key];
} else {
$ret = $this->config;
}
return $ret;
}

}

?>
8 changes: 8 additions & 0 deletions ext_autoload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

$extensionPath = t3lib_extMgm::extPath( 'sf_yubikey' );
return array(
'tx_sfyubikey_yubikeyauth' => $extensionPath . 'Classes/YubiKeyAuth.php',
);

?>
14 changes: 10 additions & 4 deletions ext_conf_template.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
# cat=basic/enable; type=boolean; label=YubiKey auth. for backend users
# cat=basic/enable; type=boolean; label=Enable YubiKey authentication for TYPO3 backend users
yubikeyEnableBE = 1

# cat=basic/enable; type=boolean; label=YubiKey auth. for frontend users
# cat=basic/enable; type=boolean; label=Enable YubiKey authentication for TYPO3 frontent users
yubikeyEnableFE = 0

# cat=basic; type=string; label=Yubico Client ID: Get a Client ID and Client Key at https://upgrade.yubico.com/getapikey/
yubikeyClientId =

# cat=basic; type=string; label=Yubico Client Key:
yubikeyClientKey =
yubikeyClientKey =

# cat=basic/enable; type=boolean; label=Use SSL for authentication: Uses SSL to communicate with the authentication servers. If not cheked, HTTP will be used.
# cat=basic/enable; type=boolean; label=Use SSL for authentication: Uses SSL to communicate with the authentication servers. If not checked, HTTP will be used.
yubikeyUseSSL = 0

# cat=basic; type=string; label=Yubico API Url:
yubikeyApiUrl = https://api.yubico.com/wsapi/verify

# cat=basic/enable; type=boolean; label=Use Pear: Use Pear or inline class
usePear = 0

# cat=basic/enable; type=boolean; label=Devlog: Write Debug Information to devlog
devlog = 0
3 changes: 1 addition & 2 deletions ext_emconf.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
'clearCacheOnLoad' => 1,
'lockType' => '',
'author_company' => 'Skyfillers GmbH',
'version' => '0.6.0',
'version' => '0.7.0',
'constraints' => array(
'depends' => array(
'typo3' => '4.5.0-6.2.99',
Expand All @@ -39,7 +39,6 @@
'suggests' => array(
),
),
'_md5_values_when_last_written' => 'a:15:{s:9:"ChangeLog";s:4:"3147";s:10:"README.txt";s:4:"ee2d";s:21:"ext_conf_template.txt";s:4:"82a5";s:12:"ext_icon.gif";s:4:"6069";s:17:"ext_localconf.php";s:4:"0c17";s:14:"ext_tables.php";s:4:"b728";s:14:"ext_tables.sql";s:4:"5e5b";s:16:"locallang_db.xml";s:4:"1454";s:19:"doc/wizard_form.dat";s:4:"3e63";s:20:"doc/wizard_form.html";s:4:"39c4";s:14:"res/login.html";s:4:"7e00";s:18:"res/sf_yubikey.css";s:4:"95d6";s:18:"res/yubi_16x16.gif";s:4:"9346";s:30:"sv1/class.tx_sfyubikey_sv1.php";s:4:"75e9";s:15:"sv1/yubikey.php";s:4:"7506";}',
'suggests' => array(
),
);
Expand Down
4 changes: 1 addition & 3 deletions ext_tables.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
'exclude' => 0,
'label' => 'LLL:EXT:sf_yubikey/locallang_db.xml:users.tx_sfyubikey_yubikey_id',
'config' => array (
'type' => 'input',
'size' => '12',
'max' => '12',
'type' => 'text'
)
),
);
Expand Down

0 comments on commit 5cbe09f

Please sign in to comment.