Add login-otp plugin
This commit is contained in:
parent
4355aaa96f
commit
00721402e0
|
@ -118,19 +118,25 @@ class Adminer {
|
|||
*/
|
||||
function loginForm() {
|
||||
global $drivers;
|
||||
?>
|
||||
<table cellspacing="0">
|
||||
<tr><th><?php echo lang('System'); ?><td><?php echo html_select("auth[driver]", $drivers, DRIVER) . "\n"; ?>
|
||||
<tr><th><?php echo lang('Server'); ?><td><input name="auth[server]" value="<?php echo h(SERVER); ?>" title="hostname[:port]" placeholder="localhost" autocapitalize="off">
|
||||
<tr><th><?php echo lang('Username'); ?><td><input name="auth[username]" id="username" value="<?php echo h($_GET["username"]); ?>" autocapitalize="off">
|
||||
<tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
|
||||
<tr><th><?php echo lang('Database'); ?><td><input name="auth[db]" value="<?php echo h($_GET["db"]); ?>" autocapitalize="off">
|
||||
</table>
|
||||
<?php
|
||||
echo script("focus(qs('#username'));");
|
||||
echo "<table cellspacing='0'>\n";
|
||||
echo $this->loginFormField('driver', '<tr><th>' . lang('System') . '<td>' . html_select("auth[driver]", $drivers, DRIVER) . "\n");
|
||||
echo $this->loginFormField('server', '<tr><th>' . lang('Server') . '<td><input name="auth[server]" value="' . h(SERVER) . '" title="hostname[:port]" placeholder="localhost" autocapitalize="off">' . "\n");
|
||||
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td><input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocapitalize="off">' . script("focus(qs('#username'));"));
|
||||
echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td><input type="password" name="auth[password]">' . "\n");
|
||||
echo $this->loginFormField('db', '<tr><th>' . lang('Database') . '<td><input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">' . "\n");
|
||||
echo "</table>\n";
|
||||
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
|
||||
echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
|
||||
}
|
||||
|
||||
/** Get login form field
|
||||
* @param string
|
||||
* @param string HTML
|
||||
* @return string
|
||||
*/
|
||||
function loginFormField($name, $default) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
/** Authorize the user
|
||||
* @param string
|
||||
|
|
|
@ -71,17 +71,18 @@ class Adminer {
|
|||
}
|
||||
|
||||
function loginForm() {
|
||||
?>
|
||||
<table cellspacing="0">
|
||||
<tr><th><?php echo lang('Username'); ?><td><input type="hidden" name="auth[driver]" value="server"><input name="auth[username]" id="username" value="<?php echo h($_GET["username"]); ?>" autocapitalize="off">
|
||||
<tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
|
||||
</table>
|
||||
<?php
|
||||
echo script("focus(qs('#username'));");
|
||||
echo "<table cellspacing='0'>\n";
|
||||
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td><input type="hidden" name="auth[driver]" value="server"><input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocapitalize="off">' . script("focus(qs('#username'));"));
|
||||
echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td><input type="password" name="auth[password]">' . "\n");
|
||||
echo "</table>\n";
|
||||
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
|
||||
echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
|
||||
}
|
||||
|
||||
function loginFormField($name, $default) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
function login($login, $password) {
|
||||
return true;
|
||||
}
|
||||
|
|
52
plugins/login-otp.php
Normal file
52
plugins/login-otp.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/** Require One-Time Password at login
|
||||
* You can generate the secret and install it into Google Authenticator e.g. with https://github.com/sonata-project/GoogleAuthenticator
|
||||
* @link https://www.adminer.org/plugins/#use
|
||||
* @author Jakub Vrana, https://www.vrana.cz/
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
class AdminerLoginOtp {
|
||||
/** @access protected */
|
||||
var $secret;
|
||||
|
||||
/**
|
||||
* @param string decoded secret, e.g. base32_decode("SECRET")
|
||||
*/
|
||||
function __construct($secret) {
|
||||
$this->secret = $secret;
|
||||
if ($_POST["auth"]) {
|
||||
$_SESSION["otp"] = (string) $_POST["auth"]["otp"];
|
||||
}
|
||||
}
|
||||
|
||||
function loginFormField($name, $default) {
|
||||
if ($name == 'password') {
|
||||
return $default . "<tr><th><acronym title='One Time Password' lang='en'>OTP</acronym><td><input type='number' name='auth[otp]' value='" . h($_SESSION["otp"]) . "' size='6' autocomplete='off'>\n";
|
||||
}
|
||||
}
|
||||
|
||||
function login($login, $password) {
|
||||
if (isset($_SESSION["otp"])) {
|
||||
$timeSlot = floor(time() / 30);
|
||||
foreach (array(0, -1, 1) as $skew) {
|
||||
if ($_SESSION["otp"] == $this->getOtp($timeSlot + $skew)) {
|
||||
restart_session();
|
||||
unset($_SESSION["otp"]);
|
||||
stop_session();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return 'Invalid OTP.';
|
||||
}
|
||||
}
|
||||
|
||||
function getOtp($timeSlot) {
|
||||
$data = str_pad(pack('N', $timeSlot), 8, "\0", STR_PAD_LEFT);
|
||||
$hash = hash_hmac('sha1', $data, $this->secret, true);
|
||||
$offset = ord(substr($hash, -1)) & 0xF;
|
||||
$unpacked = unpack('N', substr($hash, $offset, 4));
|
||||
return ($unpacked[1] & 0x7FFFFFFF) % 1e6;
|
||||
}
|
||||
}
|
|
@ -160,6 +160,11 @@ class AdminerPlugin extends Adminer {
|
|||
return $this->_applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function loginFormField($name, $default) {
|
||||
$args = func_get_args();
|
||||
return $this->_applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function login($login, $password) {
|
||||
$args = func_get_args();
|
||||
return $this->_applyPlugin(__FUNCTION__, $args);
|
||||
|
|
Loading…
Reference in a new issue