Skip to content

Commit 068220a

Browse files
committed
New Login screen
As disucessed issues with old system in Safari (OSX) and also high load due to cappebilty to stresss / "ddos" server with fast changing keys Seperated each step - Username - Password - Autenticate / Check if user needs 2FA -- Sessions set or -- Send to TWOFA Page -- Autenticate with old data + check 2FA
1 parent 8c3d792 commit 068220a

File tree

4 files changed

+246
-92
lines changed

4 files changed

+246
-92
lines changed

web/login/index.php

Lines changed: 127 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
// Main include
77
include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
88

9-
10-
$TAB = 'LOGIN';
9+
$TAB = 'login';
1110

1211
// Logout
1312
if (isset($_GET['logout'])) {
@@ -33,27 +32,24 @@
3332
exit;
3433
}
3534

36-
// Basic auth
37-
if (isset($_POST['user']) && isset($_POST['password'])) {
35+
if (!empty($_POST['user']) && !empty($_POST['password']) && !empty($_POST['twofa'])){
3836
if(isset($_SESSION['token']) && isset($_POST['token']) && $_POST['token'] == $_SESSION['token']) {
39-
$v_user = escapeshellarg($_POST['user']);
40-
$v_ip = escapeshellarg($_SERVER['REMOTE_ADDR']);
41-
if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])){
42-
if(!empty($_SERVER['HTTP_CF_CONNECTING_IP'])){
43-
$v_ip = escapeshellarg($_SERVER['HTTP_CF_CONNECTING_IP']);
44-
}
45-
}
46-
if (isset($_POST['twofa'])) {
47-
$v_twofa = escapeshellarg($_POST['twofa']);
37+
$v_user = escapeshellarg($_POST['user']);
38+
$v_ip = escapeshellarg($_SERVER['REMOTE_ADDR']);
39+
if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])){
40+
if(!empty($_SERVER['HTTP_CF_CONNECTING_IP'])){
41+
$v_ip = escapeshellarg($_SERVER['HTTP_CF_CONNECTING_IP']);
4842
}
43+
}
4944

50-
// Get user's salt
51-
$output = '';
52-
exec (HESTIA_CMD."v-get-user-salt ".$v_user." ".$v_ip." json" , $output, $return_var);
53-
$pam = json_decode(implode('', $output), true);
54-
if ( $return_var > 0 ) {
55-
sleep(5);
56-
$ERROR = "<a class=\"error\">".__('Invalid username or password')."</a>";
45+
// Get user's salt
46+
$output = '';
47+
exec (HESTIA_CMD."v-get-user-salt ".$v_user." ".$v_ip." json" , $output, $return_var);
48+
$pam = json_decode(implode('', $output), true);
49+
if ( $return_var > 0 ) {
50+
sleep(5);
51+
unset($_POST['password'], $_POST['user']);
52+
$error = "<a class=\"error\">".__('Invalid username or password')."</a>";
5753
} else {
5854
$user = $_POST['user'];
5955
$password = $_POST['password'];
@@ -87,6 +83,7 @@
8783
// Check API answer
8884
if ( $return_var > 0 ) {
8985
sleep(5);
86+
unset($_POST['password']);
9087
$ERROR = "<a class=\"error\">".__('Invalid username or password')."</a>";
9188
} else {
9289

@@ -99,29 +96,115 @@
9996

10097
// Check if 2FA is active
10198
if ($data[$_POST['user']]['TWOFA'] != '') {
102-
if (isset($v_twofa)){
103-
$v_twofa = str_replace(' ', '', $v_twofa);
104-
exec(HESTIA_CMD ."v-check-user-2fa ".$v_user." ".$v_twofa, $output, $return_var);
99+
$v_twofa = $_POST['twofa'];
100+
exec(HESTIA_CMD ."v-check-user-2fa ".$v_user." ".$v_twofa, $output, $return_var);
105101
unset($output);
106102
if ( $return_var > 0 ) {
107103
sleep(1);
108104
$ERROR = "<a class=\"error\">".__('Invalid or missing 2FA token')."</a>";
109105
}
106+
}
107+
// Define session user
108+
$_SESSION['user'] = key($data);
109+
$v_user = $_SESSION['user'];
110+
111+
// Define language
112+
$output = '';
113+
exec (HESTIA_CMD."v-list-sys-languages json", $output, $return_var);
114+
$languages = json_decode(implode('', $output), true);
115+
if (in_array($data[$v_user]['LANGUAGE'], $languages)){
116+
$_SESSION['language'] = $data[$v_user]['LANGUAGE'];
117+
} else {
118+
$_SESSION['language'] = 'en';
119+
}
120+
121+
// Regenerate session id to prevent session fixation
122+
session_regenerate_id();
123+
124+
// Redirect request to control panel interface
125+
if (!empty($_SESSION['request_uri'])) {
126+
header("Location: ".$_SESSION['request_uri']);
127+
unset($_SESSION['request_uri']);
128+
exit;
129+
} else {
130+
if ($v_user == 'admin') {
131+
header("Location: /list/user/");
110132
} else {
111-
sleep(1);
112-
$ERROR = "<a class=\"error\">".__('Invalid or missing 2FA token')."</a>";
133+
header("Location: /list/web/");
113134
}
135+
exit;
114136
}
137+
}
138+
}
139+
}
140+
} else if (!empty($_POST['user']) && !empty($_POST['password'])) {
141+
if(isset($_SESSION['token']) && isset($_POST['token']) && $_POST['token'] == $_SESSION['token']) {
142+
$v_user = escapeshellarg($_POST['user']);
143+
$v_ip = escapeshellarg($_SERVER['REMOTE_ADDR']);
144+
if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])){
145+
if(!empty($_SERVER['HTTP_CF_CONNECTING_IP'])){
146+
$v_ip = escapeshellarg($_SERVER['HTTP_CF_CONNECTING_IP']);
147+
}
148+
}
115149

116-
// Check if 2FA was successfully
117-
if ( ! isset($v_twofa) || $ERROR == '' ) {
150+
// Get user's salt
151+
$output = '';
152+
exec (HESTIA_CMD."v-get-user-salt ".$v_user." ".$v_ip." json" , $output, $return_var);
153+
$pam = json_decode(implode('', $output), true);
154+
if ( $return_var > 0 ) {
155+
sleep(5);
156+
unset($_POST['password'], $_POST['user']);
157+
$error = "<a class=\"error\">".__('Invalid username or password')."</a>";
158+
} else {
159+
$user = $_POST['user'];
160+
$password = $_POST['password'];
161+
$salt = $pam[$user]['SALT'];
162+
$method = $pam[$user]['METHOD'];
163+
164+
if ($method == 'md5' ) {
165+
$hash = crypt($password, '$1$'.$salt.'$');
166+
}
167+
if ($method == 'sha-512' ) {
168+
$hash = crypt($password, '$6$rounds=5000$'.$salt.'$');
169+
$hash = str_replace('$rounds=5000','',$hash);
170+
}
171+
if ($method == 'des' ) {
172+
$hash = crypt($password, $salt);
173+
}
174+
175+
// Send hash via tmp file
176+
$v_hash = exec('mktemp -p /tmp');
177+
$fp = fopen($v_hash, "w");
178+
fwrite($fp, $hash."\n");
179+
fclose($fp);
180+
181+
// Check user hash
182+
exec(HESTIA_CMD ."v-check-user-hash ".$v_user." ".$v_hash." ".$v_ip, $output, $return_var);
183+
unset($output);
184+
185+
// Remove tmp file
186+
unlink($v_hash);
187+
188+
// Check API answer
189+
if ( $return_var > 0 ) {
190+
sleep(5);
191+
unset($_POST['password']);
192+
$ERROR = "<a class=\"error\">".__('Invalid username or password')."</a>";
193+
} else {
194+
195+
// Make root admin user
196+
if ($_POST['user'] == 'root') $v_user = 'admin';
197+
198+
// Get user speciefic parameters
199+
exec (HESTIA_CMD . "v-list-user ".$v_user." json", $output, $return_var);
200+
$data = json_decode(implode('', $output), true);
201+
202+
// Check if 2FA is active
203+
if ($data[$_POST['user']]['TWOFA'] == '') {
118204
// Define session user
119205
$_SESSION['user'] = key($data);
120206
$v_user = $_SESSION['user'];
121-
122-
// Get user favorites
123-
get_favourites();
124-
207+
125208
// Define language
126209
$output = '';
127210
exec (HESTIA_CMD."v-list-sys-languages json", $output, $return_var);
@@ -131,10 +214,10 @@
131214
} else {
132215
$_SESSION['language'] = 'en';
133216
}
134-
217+
135218
// Regenerate session id to prevent session fixation
136219
session_regenerate_id();
137-
220+
138221
// Redirect request to control panel interface
139222
if (!empty($_SESSION['request_uri'])) {
140223
header("Location: ".$_SESSION['request_uri']);
@@ -151,12 +234,11 @@
151234
}
152235
}
153236
}
154-
} else {
155-
sleep(1);
156-
$ERROR = "<a class=\"error\">".__('Invalid or missing token')."</a>";
157-
}
237+
}
158238
}
159239

240+
241+
160242
// Check system configuration
161243
load_hestia_config();
162244

@@ -183,4 +265,11 @@
183265

184266
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$_SESSION['language'].'.php');
185267
require_once('../templates/header.html');
186-
require_once('../templates/login.html');
268+
if (empty($_POST['user'])) {
269+
require_once('../templates/login.html');
270+
}else if (empty($_POST['password'])) {
271+
require_once('../templates/login_1.html');
272+
}else if (empty($_POST['twofa'])) {
273+
require_once('../templates/login_2.html');
274+
}
275+
?>

web/templates/login.html

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -17,52 +17,22 @@
1717
</td>
1818
</tr>
1919
<tr>
20-
<td style="padding: 12px 0 0 2px;">
21-
<?php print __('Username');?>
20+
<td style="padding: 12px 0 5px 2px;">
21+
<?php print __('Please login with your username');?>
2222
</td>
2323
</tr>
2424
<tr>
2525
<td>
26-
<input tabindex="1" type="text" size="20px" style="width:240px;" name="user" class="vst-input">
26+
<input tabindex="1" type="text" size="20px" style="width:240px;" name="user" class="vst-input" placeholder="<?php print __('Username');?>">
2727
</td>
2828
</tr>
2929
<tr>
30-
<td style="padding: 12px 0 0 2px;">
31-
<?php print __('Password');?>
32-
<div style="padding:0 6px 0px 14px; float:right;">
33-
<a tabindex="5" class="vst-advanced" href="/reset/">
34-
<?php print __('forgot password');?>
35-
</a>
36-
</div>
30+
<td height="10px">
3731
</td>
3832
</tr>
3933
<tr>
40-
<td>
41-
<input tabindex="2" type="password" size="20px" style="width:240px;" name="password" class="vst-input">
42-
</td>
43-
</tr>
44-
<tr class="twofa" style="display:none;">
45-
<td style="padding-top: 12px; padding-left:2px;">
46-
<?php print __('2FA Token');?>
47-
<div style="padding:0 6px 0px 14px; float:right;">
48-
<a tabindex="5" class="vst-advanced" href="/reset2fa/">
49-
<?php print __('Forgot token');?>
50-
</a>
51-
</div>
52-
</td>
53-
</tr>
54-
<tr class="twofa" style="display:none;">
55-
<td>
56-
<input tabindex="3" type="text" size="20px" style="width:240px;" name="twofa" class="vst-input">
57-
</td>
58-
</tr>
59-
<tr>
60-
<td height="28px">
61-
</td>
62-
</tr>
63-
<tr>
64-
<td style="padding: 0 0 12px 0;">
65-
<button tabindex="3" type="submit" class="button"><?php print __('Log in');?>&nbsp;&nbsp;&nbsp;<i class="fas fa-sign-in-alt"></i></button>
34+
<td style="padding: 0 0 5px 0;">
35+
<button tabindex="3" type="submit" class="button"><?php print __('Next');?>&nbsp;&nbsp;&nbsp;<i class="fas fa-sign-in-alt"></i></button>
6636
</td>
6737
</tr>
6838
</table>
@@ -80,23 +50,6 @@
8050
</tr>
8151
</table>
8252
</center>
83-
<script type="text/javascript">
84-
$(document).ready(function () {
85-
$('#form_login').on('input', 'input[name="user"]', function() {
86-
var username = this.value;
87-
$.ajax({
88-
type: 'GET',
89-
url: '/inc/2fa/active.php?user=' + username,
90-
complete: function(xhr) {
91-
if(xhr.status == '200'){
92-
$('.twofa').show();
93-
}else if(xhr.status == '404'){
94-
$('.twofa').hide();
95-
}
96-
}
97-
});
98-
});
99-
});
100-
</script>
53+
10154
</body>
10255
</html>

web/templates/login_1.html

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<center>
2+
<table class="login animated zoomIn">
3+
<tr>
4+
<td>
5+
<table>
6+
<tr>
7+
<td style="padding: 22px 30px 0 42px; height: 280px; width: 170px;">
8+
<a href="/"><img border=0 src="/images/logo.png" alt="<?=__('Hestia Control Panel');?>" style="margin: 20px; margin-top: 64px;" /></a>
9+
</td>
10+
<td style="padding: 40px 60px 0 0;">
11+
<form method="post" action="/login/" id="form_login">
12+
<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>">
13+
<input type="hidden" name="user" value="<?php echo $_POST['user']; ?>">
14+
15+
<table class="login-box">
16+
<tr>
17+
<td style="padding: 12px 0 0 2px;" class="login-welcome">
18+
<?php print __('Welcome to Hestia Control Panel');?>
19+
</td>
20+
</tr>
21+
<tr>
22+
<td style="padding: 12px 0 5px 2px;">
23+
<?php print __('Please enter your Password');?>
24+
</td>
25+
</tr>
26+
<tr>
27+
<td>
28+
<input tabindex="2" type="password" size="20px" style="width:240px;" name="password" class="vst-input" placeholder="<?php print __('Password');?>">
29+
</td>
30+
</tr>
31+
<tr>
32+
<td height="10px">
33+
</td>
34+
</tr>
35+
<tr>
36+
<td style="padding: 0 0 5px 0;">
37+
<button tabindex="3" type="submit" class="button"><?php print __('Login');?>&nbsp;&nbsp;&nbsp;<i class="fas fa-sign-in-alt"></i></button>
38+
</td>
39+
</tr>
40+
</table>
41+
</form>
42+
</td>
43+
</tr>
44+
<tr>
45+
<td colspan=2>
46+
<div class="login-bottom">
47+
<div style="height:20px"><?php if (isset($ERROR)) echo $ERROR ?></div>
48+
</div>
49+
</td>
50+
</tr>
51+
</table>
52+
</tr>
53+
</table>
54+
</center>
55+
</body>
56+
</html>

0 commit comments

Comments
 (0)