Skip to content

Commit 3b02f96

Browse files
committed
Implement 2FA token for the login page.
1 parent 3b95681 commit 3b02f96

File tree

3 files changed

+128
-28
lines changed

3 files changed

+128
-28
lines changed

web/inc/2fa/active.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
define('NO_AUTH_REQUIRED',true);
4+
5+
// Main include
6+
include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
7+
8+
if (isset($_GET['user'])) {
9+
$v_user = escapeshellarg($_GET['user']);
10+
11+
// Get user speciefic parameters
12+
exec (HESTIA_CMD . "v-list-user ".$v_user." json", $output, $return_var);
13+
$data = json_decode(implode('', $output), true);
14+
15+
// Check if 2FA is active
16+
if ($data[$_GET['user']]['TWOFA'] != '') {
17+
header("HTTP/1.0 200 OK");
18+
exit;
19+
} else {
20+
header("HTTP/1.0 404 Not Found");
21+
exit;
22+
}
23+
}

web/login/index.php

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<link rel="icon" href="/images/favicon.ico" type="image/x-icon">
6+
<title>Hestia - <?=__($TAB)?></title>
7+
<link rel="stylesheet" href="/css/styles.min.css?1446554103">
8+
<link type="text/css" href="/css/jquery-custom-dialogs.css?1446554103" rel="stylesheet" />
9+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
10+
<script>
11+
//
12+
// GLOBAL SETTINGS
13+
//
14+
var GLOBAL = {};
15+
GLOBAL.FTP_USER_PREFIX = 'admin_';
16+
GLOBAL.DB_USER_PREFIX = 'admin_';
17+
GLOBAL.DB_DBNAME_PREFIX = 'admin_';
18+
GLOBAL.AJAX_URL = '';
19+
</script>
20+
</head>
21+
<body class="body-<?=strtolower($TAB)?> lang-<?=$_SESSION['language']?>">
22+
root@web02:/usr/local/hestia/web# nano mail/index.php ^C
23+
root@web02:/usr/local/hestia/web# cat login/index.php
124
<?php
225

326
define('NO_AUTH_REQUIRED',true);
@@ -34,6 +57,9 @@
3457
if(isset($_SESSION['token']) && isset($_POST['token']) && $_POST['token'] == $_SESSION['token']) {
3558
$v_user = escapeshellarg($_POST['user']);
3659
$v_ip = escapeshellarg($_SERVER['REMOTE_ADDR']);
60+
if (isset($_POST['twofa'])) {
61+
$v_twofa = escapeshellarg($_POST['twofa']);
62+
}
3763

3864
// Get user's salt
3965
$output = '';
@@ -83,34 +109,50 @@
83109
exec (HESTIA_CMD . "v-list-user ".$v_user." json", $output, $return_var);
84110
$data = json_decode(implode('', $output), true);
85111

86-
// Define session user
87-
$_SESSION['user'] = key($data);
88-
$v_user = $_SESSION['user'];
89-
90-
// Get user favorites
91-
get_favourites();
92-
93-
// Define language
94-
$output = '';
95-
exec (HESTIA_CMD."v-list-sys-languages json", $output, $return_var);
96-
$languages = json_decode(implode('', $output), true);
97-
if (in_array($data[$v_user]['LANGUAGE'], $languages)){
98-
$_SESSION['language'] = $data[$v_user]['LANGUAGE'];
99-
} else {
100-
$_SESSION['language'] = 'en';
112+
// Check if 2FA is active
113+
if ($data[$_POST['user']]['TWOFA'] != '') {
114+
if (isset($v_twofa)){
115+
exec(HESTIA_CMD ."v-check-user-2fa ".$v_user." ".$v_twofa, $output, $return_var);
116+
unset($output);
117+
if ( $return_var > 0 ) {
118+
$ERROR = "<a class=\"error\">".__('Invalid or missing 2FA token')."</a>";
119+
}
120+
} else {
121+
$ERROR = "<a class=\"error\">".__('Invalid or missing 2FA token')."</a>";
122+
}
101123
}
102124

103-
// Regenerate session id to prevent session fixation
104-
session_regenerate_id();
105-
106-
// Redirect request to control panel interface
107-
if (!empty($_SESSION['request_uri'])) {
108-
header("Location: ".$_SESSION['request_uri']);
109-
unset($_SESSION['request_uri']);
110-
exit;
111-
} else {
112-
header("Location: /list/user/");
113-
exit;
125+
// Check if 2FA was successfully
126+
if ( ! isset($v_twofa) || $ERROR == '' ) {
127+
// Define session user
128+
$_SESSION['user'] = key($data);
129+
$v_user = $_SESSION['user'];
130+
131+
// Get user favorites
132+
get_favourites();
133+
134+
// Define language
135+
$output = '';
136+
exec (HESTIA_CMD."v-list-sys-languages json", $output, $return_var);
137+
$languages = json_decode(implode('', $output), true);
138+
if (in_array($data[$v_user]['LANGUAGE'], $languages)){
139+
$_SESSION['language'] = $data[$v_user]['LANGUAGE'];
140+
} else {
141+
$_SESSION['language'] = 'en';
142+
}
143+
144+
// Regenerate session id to prevent session fixation
145+
session_regenerate_id();
146+
147+
// Redirect request to control panel interface
148+
if (!empty($_SESSION['request_uri'])) {
149+
header("Location: ".$_SESSION['request_uri']);
150+
unset($_SESSION['request_uri']);
151+
exit;
152+
} else {
153+
header("Location: /list/user/");
154+
exit;
155+
}
114156
}
115157
}
116158
}
@@ -150,4 +192,4 @@
150192

151193
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$_SESSION['language'].'.php');
152194
require_once('../templates/header.html');
153-
require_once('../templates/login.html');
195+
require_once('../templates/login.html');

web/templates/login.html

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,26 @@
1010
<td style="padding: 20px 0 0 0;">
1111
<form method="post" action="/login/" >
1212
<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>">
13+
<script>
14+
function show2FA(str) {
15+
if (str.length == 0) {
16+
$('.twofa').fadeOut();
17+
return;
18+
} else {
19+
var xmlhttp = new XMLHttpRequest();
20+
xmlhttp.onreadystatechange = function() {
21+
if (this.readyState == 4 && this.status == 200) {
22+
var x = document.getElementById("twofa");
23+
$('.twofa').fadeIn();
24+
} else {
25+
$('.twofa').fadeOut();
26+
}
27+
};
28+
xmlhttp.open("GET", "/inc/2fa/active.php?user=" + str, true);
29+
xmlhttp.send();
30+
}
31+
}
32+
</script>
1333
<table class="login-box">
1434
<tr>
1535
<td syle="padding: 12px 0 0 2px;">
@@ -18,7 +38,7 @@
1838
</tr>
1939
<tr>
2040
<td>
21-
<input tabindex="1" type="text" size="20px" style="width:240px;" name="user" class="vst-input">
41+
<input tabindex="1" type="text" size="20px" style="width:240px;" name="user" class="vst-input" onfocusout="show2FA(this.value)">
2242
</td>
2343
</tr>
2444
<tr>
@@ -36,6 +56,21 @@
3656
<input tabindex="2" type="password" size="20px" style="width:240px;" name="password" class="vst-input">
3757
</td>
3858
</tr>
59+
<tr class="twofa" style="display:none;">
60+
<td style="padding-top: 12px; padding-left:2px;">
61+
<?php print __('2FA Token');?>
62+
<span style="padding:0 0 0 10px;">
63+
<a tabindex="5" class="vst-advanced" href="/reset/">
64+
<?php print __('forgot token');?>
65+
</a>
66+
</span>
67+
</td>
68+
</tr>
69+
<tr class="twofa" style="display:none;">
70+
<td>
71+
<input tabindex="3" type="text" size="20px" style="width:240px;" name="twofa" class="vst-input">
72+
</td>
73+
</tr>
3974
<tr>
4075
<td height="28px">
4176
</td>

0 commit comments

Comments
 (0)