Spade
Mini Shell
totp/postinstall/actions.php000064400000003542151166040000012254
0ustar00<?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.totp
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*
* This file contains the functions used by the com_postinstall code to
deliver
* the necessary post-installation messages concerning the activation of
the
* two-factor authentication code.
*/
/**
* Checks if the plugin is enabled. If not it returns true, meaning that
the
* message concerning two factor authentication should be displayed.
*
* @return integer
*
* @since 3.2
*/
function twofactorauth_postinstall_condition()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->qn('#__extensions'))
->where($db->qn('type') . ' = ' .
$db->q('plugin'))
->where($db->qn('enabled') . ' = 1')
->where($db->qn('folder') . ' = ' .
$db->q('twofactorauth'));
$db->setQuery($query);
$enabled_plugins = $db->loadObjectList();
return count($enabled_plugins) === 0;
}
/**
* Enables the two factor authentication plugin and redirects the user to
their
* user profile page so that they can enable two factor authentication on
their
* account.
*
* @return void
*
* @since 3.2
*/
function twofactorauth_postinstall_action()
{
// Enable the plugin
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->update($db->qn('#__extensions'))
->set($db->qn('enabled') . ' = 1')
->where($db->qn('type') . ' = ' .
$db->q('plugin'))
->where($db->qn('folder') . ' = ' .
$db->q('twofactorauth'));
$db->setQuery($query);
$db->execute();
// Clean cache.
JFactory::getCache()->clean('com_plugins');
// Redirect the user to their profile editor page
$url = 'index.php?option=com_users&task=user.edit&id=' .
JFactory::getUser()->id;
JFactory::getApplication()->redirect($url);
}
totp/tmpl/form.php000064400000005773151166040000010167 0ustar00<?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.totp.tmpl
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Factory;
HTMLHelper::_('script',
'plg_twofactorauth_totp/qrcode.min.js', array('version'
=> 'auto', 'relative' => true));
$js = "
(function(document)
{
document.addEventListener('DOMContentLoaded', function()
{
var qr = qrcode(0, 'H');
qr.addData('" . $url . "');
qr.make();
document.getElementById('totp-qrcode').innerHTML =
qr.createImgTag(4);
});
})(document);
";
Factory::getDocument()->addScriptDeclaration($js);
?>
<input type="hidden"
name="jform[twofactor][totp][key]" value="<?php echo
$secret ?>" />
<div class="well">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_INTRO') ?>
</div>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_HEAD')
?>
</legend>
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_TEXT')
?>
</p>
<ul>
<li>
<a href="<?php echo
JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM1_LINK') ?>"
target="_blank" rel="noopener noreferrer">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM1')
?>
</a>
</li>
<li>
<a href="<?php echo
JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM2_LINK') ?>"
target="_blank" rel="noopener noreferrer">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM2')
?>
</a>
</li>
</ul>
<div class="alert">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_WARN')
?>
</div>
</fieldset>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_HEAD')
?>
</legend>
<div class="span6">
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_TEXT')
?>
</p>
<table class="table table-striped">
<tr>
<td>
<?php echo
JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_ACCOUNT') ?>
</td>
<td>
<?php echo $username ?>@<?php echo $hostname ?>
</td>
</tr>
<tr>
<td>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_KEY')
?>
</td>
<td>
<?php echo $secret ?>
</td>
</tr>
</table>
</div>
<div class="span6">
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_ALTTEXT')
?>
<br />
<div id="totp-qrcode"></div>
</p>
</div>
<div class="clearfix"></div>
<div class="alert alert-info">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_RESET')
?>
</div>
</fieldset>
<?php if ($new_totp): ?>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP3_HEAD')
?>
</legend>
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP3_TEXT')
?>
</p>
<div class="control-group">
<label class="control-label"
for="totpsecuritycode">
<?php echo
JText::_('PLG_TWOFACTORAUTH_TOTP_STEP3_SECURITYCODE') ?>
</label>
<div class="controls">
<input type="text" class="input-small"
name="jform[twofactor][totp][securitycode]"
id="totpsecuritycode" autocomplete="0">
</div>
</div>
</fieldset>
<?php endif; ?>
totp/totp.php000064400000017056151166040000007233 0ustar00<?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.totp
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Joomla! Two Factor Authentication using Google Authenticator TOTP Plugin
*
* @since 3.2
*/
class PlgTwofactorauthTotp extends JPlugin
{
/**
* Affects constructor behavior. If true, language files will be loaded
automatically.
*
* @var boolean
* @since 3.2
*/
protected $autoloadLanguage = true;
/**
* Method name
*
* @var string
* @since 3.2
*/
protected $methodName = 'totp';
/**
* This method returns the identification object for this two factor
* authentication plugin.
*
* @return stdClass An object with public properties method and title
*
* @since 3.2
*/
public function onUserTwofactorIdentify()
{
$section = (int) $this->params->get('section', 3);
$current_section = 0;
try
{
$app = JFactory::getApplication();
if ($app->isClient('administrator'))
{
$current_section = 2;
}
elseif ($app->isClient('site'))
{
$current_section = 1;
}
}
catch (Exception $exc)
{
$current_section = 0;
}
if (!($current_section & $section))
{
return false;
}
return (object) array(
'method' => $this->methodName,
'title' =>
JText::_('PLG_TWOFACTORAUTH_TOTP_METHOD_TITLE')
);
}
/**
* Shows the configuration page for this two factor authentication method.
*
* @param object $otpConfig The two factor auth configuration object
* @param integer $userId The numeric user ID of the user whose
form we'll display
*
* @return boolean|string False if the method is not ours, the HTML of
the configuration page otherwise
*
* @see UsersModelUser::getOtpConfig
* @since 3.2
*/
public function onUserTwofactorShowConfiguration($otpConfig, $userId =
null)
{
// Create a new TOTP class with Google Authenticator compatible settings
$totp = new FOFEncryptTotp(30, 6, 10);
if ($otpConfig->method === $this->methodName)
{
// This method is already activated. Reuse the same secret key.
$secret = $otpConfig->config['code'];
}
else
{
// This methods is not activated yet. Create a new secret key.
$secret = $totp->generateSecret();
}
// These are used by Google Authenticator to tell accounts apart
$username = JFactory::getUser($userId)->username;
$hostname = JUri::getInstance()->getHost();
// This is the URL to the QR code for Google Authenticator
$url = sprintf("otpauth://totp/%s@%s?secret=%s", $username,
$hostname, $secret);
// Is this a new TOTP setup? If so, we'll have to show the code
validation field.
$new_totp = $otpConfig->method !== 'totp';
// Start output buffering
@ob_start();
// Include the form.php from a template override. If none is found use
the default.
$path =
FOFPlatform::getInstance()->getTemplateOverridePath('plg_twofactorauth_totp',
true);
JLoader::import('joomla.filesystem.file');
if (JFile::exists($path . '/form.php'))
{
include_once $path . '/form.php';
}
else
{
include_once __DIR__ . '/tmpl/form.php';
}
// Stop output buffering and get the form contents
$html = @ob_get_clean();
// Return the form contents
return array(
'method' => $this->methodName,
'form' => $html
);
}
/**
* The save handler of the two factor configuration method's
configuration
* page.
*
* @param string $method The two factor auth method for which
we'll show the config page
*
* @return boolean|stdClass False if the method doesn't match or we
have an error, OTP config object if it succeeds
*
* @see UsersModelUser::setOtpConfig
* @since 3.2
*/
public function onUserTwofactorApplyConfiguration($method)
{
if ($method !== $this->methodName)
{
return false;
}
// Get a reference to the input data object
$input = JFactory::getApplication()->input;
// Load raw data
$rawData = $input->get('jform', array(), 'array');
if (!isset($rawData['twofactor']['totp']))
{
return false;
}
$data = $rawData['twofactor']['totp'];
// Warn if the securitycode is empty
if (array_key_exists('securitycode', $data) &&
empty($data['securitycode']))
{
try
{
$app = JFactory::getApplication();
$app->enqueueMessage(JText::_('PLG_TWOFACTORAUTH_TOTP_ERR_VALIDATIONFAILED'),
'error');
}
catch (Exception $exc)
{
// This only happens when we are in a CLI application. We cannot
// enqueue a message, so just do nothing.
}
return false;
}
// Create a new TOTP class with Google Authenticator compatible settings
$totp = new FOFEncryptTotp(30, 6, 10);
// Check the security code entered by the user (exact time slot match)
$code = $totp->getCode($data['key']);
$check = $code === $data['securitycode'];
/*
* If the check fails, test the previous 30 second slot. This allow the
* user to enter the security code when it's becoming red in Google
* Authenticator app (reaching the end of its 30 second lifetime)
*/
if (!$check)
{
$time = time() - 30;
$code = $totp->getCode($data['key'], $time);
$check = $code === $data['securitycode'];
}
/*
* If the check fails, test the next 30 second slot. This allows some
* time drift between the authentication device and the server
*/
if (!$check)
{
$time = time() + 30;
$code = $totp->getCode($data['key'], $time);
$check = $code === $data['securitycode'];
}
if (!$check)
{
// Check failed. Do not change two factor authentication settings.
return false;
}
// Check succeeded; return an OTP configuration object
$otpConfig = (object) array(
'method' => 'totp',
'config' => array(
'code' => $data['key']
),
'otep' => array()
);
return $otpConfig;
}
/**
* This method should handle any two factor authentication and report back
* to the subject.
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
*
* @return boolean True if the user is authorised with this two-factor
authentication method
*
* @since 3.2
*/
public function onUserTwofactorAuthenticate($credentials, $options)
{
// Get the OTP configuration object
$otpConfig = $options['otp_config'];
// Make sure it's an object
if (empty($otpConfig) || !is_object($otpConfig))
{
return false;
}
// Check if we have the correct method
if ($otpConfig->method !== $this->methodName)
{
return false;
}
// Check if there is a security code
if (empty($credentials['secretkey']))
{
return false;
}
// Create a new TOTP class with Google Authenticator compatible settings
$totp = new FOFEncryptTotp(30, 6, 10);
// Check the code
$code = $totp->getCode($otpConfig->config['code']);
$check = $code === $credentials['secretkey'];
/*
* If the check fails, test the previous 30 second slot. This allow the
* user to enter the security code when it's becoming red in Google
* Authenticator app (reaching the end of its 30 second lifetime)
*/
if (!$check)
{
$time = time() - 30;
$code = $totp->getCode($otpConfig->config['code'],
$time);
$check = $code === $credentials['secretkey'];
}
/*
* If the check fails, test the next 30 second slot. This allows some
* time drift between the authentication device and the server
*/
if (!$check)
{
$time = time() + 30;
$code = $totp->getCode($otpConfig->config['code'],
$time);
$check = $code === $credentials['secretkey'];
}
return $check;
}
}
totp/totp.xml000064400000002611151166040000007233 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin"
group="system" method="upgrade">
<name>plg_twofactorauth_totp</name>
<author>Joomla! Project</author>
<creationDate>August 2013</creationDate>
<copyright>Copyright (C) 2005 - 2020 Open Source Matters. All rights
reserved.</copyright>
<license>GNU General Public License version 2 or later; see
LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.2.0</version>
<description>PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION</description>
<files>
<filename plugin="totp">totp.php</filename>
<folder>postinstall</folder>
<folder>tmpl</folder>
</files>
<languages>
<language
tag="en-GB">en-GB.plg_twofactorauth_totp.ini</language>
<language
tag="en-GB">en-GB.plg_twofactorauth_totp.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="section"
type="radio"
label="PLG_TWOFACTORAUTH_TOTP_SECTION_LABEL"
description="PLG_TWOFACTORAUTH_TOTP_SECTION_DESC"
default="3"
filter="integer"
class="btn-group"
>
<option
value="1">PLG_TWOFACTORAUTH_TOTP_SECTION_SITE</option>
<option
value="2">PLG_TWOFACTORAUTH_TOTP_SECTION_ADMIN</option>
<option
value="3">PLG_TWOFACTORAUTH_TOTP_SECTION_BOTH</option>
</field>
</fieldset>
</fields>
</config>
</extension>
yubikey/tmpl/form.php000064400000002162151166040000010647 0ustar00<?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.yubikey.tmpl
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
?>
<div class="well">
<?php echo JText::_('PLG_TWOFACTORAUTH_YUBIKEY_INTRO') ?>
</div>
<?php if ($new_totp): ?>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_YUBIKEY_STEP1_HEAD')
?>
</legend>
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_YUBIKEY_STEP1_TEXT')
?>
</p>
<div class="control-group">
<label class="control-label"
for="yubikeysecuritycode">
<?php echo
JText::_('PLG_TWOFACTORAUTH_YUBIKEY_SECURITYCODE') ?>
</label>
<div class="controls">
<input type="text" class="input-medium"
name="jform[twofactor][yubikey][securitycode]"
id="yubikeysecuritycode" autocomplete="0">
</div>
</div>
</fieldset>
<?php else: ?>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_RESET_HEAD')
?>
</legend>
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_RESET_TEXT')
?>
</p>
</fieldset>
<?php endif; ?>
yubikey/yubikey.php000064400000020527151166040010010417 0ustar00<?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.yubikey
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Joomla! Two Factor Authentication using Yubikey Plugin
*
* @since 3.2
*/
class PlgTwofactorauthYubikey extends JPlugin
{
/**
* Affects constructor behavior. If true, language files will be loaded
automatically.
*
* @var boolean
* @since 3.2
*/
protected $autoloadLanguage = true;
/**
* Method name
*
* @var string
* @since 3.2
*/
protected $methodName = 'yubikey';
/**
* This method returns the identification object for this two factor
* authentication plugin.
*
* @return stdClass An object with public properties method and title
*
* @since 3.2
*/
public function onUserTwofactorIdentify()
{
$section = (int) $this->params->get('section',
3);
$current_section = 0;
try
{
$app = JFactory::getApplication();
if ($app->isClient('administrator'))
{
$current_section = 2;
}
elseif ($app->isClient('site'))
{
$current_section = 1;
}
}
catch (Exception $exc)
{
$current_section = 0;
}
if (!($current_section & $section))
{
return false;
}
return (object) array(
'method' => $this->methodName,
'title' =>
JText::_('PLG_TWOFACTORAUTH_YUBIKEY_METHOD_TITLE'),
);
}
/**
* Shows the configuration page for this two factor authentication method.
*
* @param object $otpConfig The two factor auth configuration object
* @param integer $userId The numeric user ID of the user whose
form we'll display
*
* @return boolean|string False if the method is not ours, the HTML of
the configuration page otherwise
*
* @see UsersModelUser::getOtpConfig
* @since 3.2
*/
public function onUserTwofactorShowConfiguration($otpConfig, $userId =
null)
{
if ($otpConfig->method === $this->methodName)
{
// This method is already activated. Reuse the same Yubikey ID.
$yubikey = $otpConfig->config['yubikey'];
}
else
{
// This methods is not activated yet. We'll need a Yubikey TOTP to
setup this Yubikey.
$yubikey = '';
}
// Is this a new TOTP setup? If so, we'll have to show the code
validation field.
$new_totp = $otpConfig->method !== $this->methodName;
// Start output buffering
@ob_start();
// Include the form.php from a template override. If none is found use
the default.
$path =
FOFPlatform::getInstance()->getTemplateOverridePath('plg_twofactorauth_yubikey',
true);
JLoader::import('joomla.filesystem.file');
if (JFile::exists($path . '/form.php'))
{
include_once $path . '/form.php';
}
else
{
include_once __DIR__ . '/tmpl/form.php';
}
// Stop output buffering and get the form contents
$html = @ob_get_clean();
// Return the form contents
return array(
'method' => $this->methodName,
'form' => $html,
);
}
/**
* The save handler of the two factor configuration method's
configuration
* page.
*
* @param string $method The two factor auth method for which
we'll show the config page
*
* @return boolean|stdClass False if the method doesn't match or we
have an error, OTP config object if it succeeds
*
* @see UsersModelUser::setOtpConfig
* @since 3.2
*/
public function onUserTwofactorApplyConfiguration($method)
{
if ($method !== $this->methodName)
{
return false;
}
// Get a reference to the input data object
$input = JFactory::getApplication()->input;
// Load raw data
$rawData = $input->get('jform', array(), 'array');
if (!isset($rawData['twofactor']['yubikey']))
{
return false;
}
$data = $rawData['twofactor']['yubikey'];
// Warn if the securitycode is empty
if (array_key_exists('securitycode', $data) &&
empty($data['securitycode']))
{
try
{
JFactory::getApplication()->enqueueMessage(JText::_('PLG_TWOFACTORAUTH_YUBIKEY_ERR_VALIDATIONFAILED'),
'error');
}
catch (Exception $exc)
{
// This only happens when we are in a CLI application. We cannot
// enqueue a message, so just do nothing.
}
return false;
}
// Validate the Yubikey OTP
$check = $this->validateYubikeyOtp($data['securitycode']);
if (!$check)
{
JFactory::getApplication()->enqueueMessage(JText::_('PLG_TWOFACTORAUTH_YUBIKEY_ERR_VALIDATIONFAILED'),
'error');
// Check failed. Do not change two factor authentication settings.
return false;
}
// Remove the last 32 digits and store the rest in the user configuration
parameters
$yubikey = substr($data['securitycode'], 0, -32);
// Check succeeded; return an OTP configuration object
$otpConfig = (object) array(
'method' => $this->methodName,
'config' => array(
'yubikey' => $yubikey
),
'otep' => array()
);
return $otpConfig;
}
/**
* This method should handle any two factor authentication and report back
* to the subject.
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
*
* @return boolean True if the user is authorised with this two-factor
authentication method
*
* @since 3.2
*/
public function onUserTwofactorAuthenticate($credentials, $options)
{
// Get the OTP configuration object
$otpConfig = $options['otp_config'];
// Make sure it's an object
if (empty($otpConfig) || !is_object($otpConfig))
{
return false;
}
// Check if we have the correct method
if ($otpConfig->method !== $this->methodName)
{
return false;
}
// Check if there is a security code
if (empty($credentials['secretkey']))
{
return false;
}
// Check if the Yubikey starts with the configured Yubikey user string
$yubikey_valid = $otpConfig->config['yubikey'];
$yubikey = substr($credentials['secretkey'], 0, -32);
$check = $yubikey === $yubikey_valid;
if ($check)
{
$check =
$this->validateYubikeyOtp($credentials['secretkey']);
}
return $check;
}
/**
* Validates a Yubikey OTP against the Yubikey servers
*
* @param string $otp The OTP generated by your Yubikey
*
* @return boolean True if it's a valid OTP
*
* @since 3.2
*/
public function validateYubikeyOtp($otp)
{
$server_queue = array(
'api.yubico.com',
'api2.yubico.com',
'api3.yubico.com',
'api4.yubico.com',
'api5.yubico.com',
);
shuffle($server_queue);
$gotResponse = false;
$check = false;
$token = JSession::getFormToken();
$nonce = md5($token . uniqid(mt_rand()));
while (!$gotResponse && !empty($server_queue))
{
$server = array_shift($server_queue);
$uri = new JUri('https://' . $server .
'/wsapi/2.0/verify');
// I don't see where this ID is used?
$uri->setVar('id', 1);
// The OTP we read from the user
$uri->setVar('otp', $otp);
// This prevents a REPLAYED_OTP status of the token doesn't change
// after a user submits an invalid OTP
$uri->setVar('nonce', $nonce);
// Minimum service level required: 50% (at least 50% of the YubiCloud
// servers must reply positively for the OTP to validate)
$uri->setVar('sl', 50);
// Timeou waiting for YubiCloud servers to reply: 5 seconds.
$uri->setVar('timeout', 5);
try
{
$http = JHttpFactory::getHttp();
$response = $http->get($uri->toString(), null, 6);
if (!empty($response))
{
$gotResponse = true;
}
else
{
continue;
}
}
catch (Exception $exc)
{
// No response, continue with the next server
continue;
}
}
// No server replied; we can't validate this OTP
if (!$gotResponse)
{
return false;
}
// Parse response
$lines = explode("\n", $response->body);
$data = array();
foreach ($lines as $line)
{
$line = trim($line);
$parts = explode('=', $line, 2);
if (count($parts) < 2)
{
continue;
}
$data[$parts[0]] = $parts[1];
}
// Validate the response - We need an OK message reply
if ($data['status'] !== 'OK')
{
return false;
}
// Validate the response - We need a confidence level over 50%
if ($data['sl'] < 50)
{
return false;
}
// Validate the response - The OTP must match
if ($data['otp'] !== $otp)
{
return false;
}
// Validate the response - The token must match
if ($data['nonce'] !== $nonce)
{
return false;
}
return true;
}
}
yubikey/yubikey.xml000064400000002616151166040010010427 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin"
group="system" method="upgrade">
<name>plg_twofactorauth_yubikey</name>
<author>Joomla! Project</author>
<creationDate>September 2013</creationDate>
<copyright>Copyright (C) 2005 - 2020 Open Source Matters. All rights
reserved.</copyright>
<license>GNU General Public License version 2 or later; see
LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.2.0</version>
<description>PLG_TWOFACTORAUTH_YUBIKEY_XML_DESCRIPTION</description>
<files>
<filename plugin="yubikey">yubikey.php</filename>
<folder>tmpl</folder>
</files>
<languages>
<language
tag="en-GB">en-GB.plg_twofactorauth_yubikey.ini</language>
<language
tag="en-GB">en-GB.plg_twofactorauth_yubikey.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="section"
type="radio"
label="PLG_TWOFACTORAUTH_YUBIKEY_SECTION_LABEL"
description="PLG_TWOFACTORAUTH_YUBIKEY_SECTION_DESC"
default="3"
filter="integer"
class="btn-group"
>
<option
value="1">PLG_TWOFACTORAUTH_YUBIKEY_SECTION_SITE</option>
<option
value="2">PLG_TWOFACTORAUTH_YUBIKEY_SECTION_ADMIN</option>
<option
value="3">PLG_TWOFACTORAUTH_YUBIKEY_SECTION_BOTH</option>
</field>
</fieldset>
</fields>
</config>
</extension>