Jelajahi Sumber

Implement 2FA token for the login page.

Raphael Schneeberger 7 tahun lalu
induk
melakukan
3b02f96440
3 mengubah file dengan 128 tambahan dan 28 penghapusan
  1. 23 0
      web/inc/2fa/active.php
  2. 69 27
      web/login/index.php
  3. 36 1
      web/templates/login.html

+ 23 - 0
web/inc/2fa/active.php

@@ -0,0 +1,23 @@
+<?php
+
+define('NO_AUTH_REQUIRED',true);
+
+// Main include
+include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
+
+if (isset($_GET['user'])) {
+    $v_user = escapeshellarg($_GET['user']);
+
+    // Get user speciefic parameters
+    exec (HESTIA_CMD . "v-list-user ".$v_user." json", $output, $return_var);
+    $data = json_decode(implode('', $output), true);
+
+    // Check if 2FA is active
+    if ($data[$_GET['user']]['TWOFA'] != '') {
+        header("HTTP/1.0 200 OK");
+        exit;
+    } else {
+        header("HTTP/1.0 404 Not Found");
+        exit;
+    }
+}

+ 69 - 27
web/login/index.php

@@ -1,3 +1,26 @@
+<!doctype html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <link rel="icon" href="/images/favicon.ico" type="image/x-icon">
+  <title>Hestia - <?=__($TAB)?></title>
+  <link rel="stylesheet" href="/css/styles.min.css?1446554103">
+  <link type="text/css" href="/css/jquery-custom-dialogs.css?1446554103" rel="stylesheet" />
+  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
+  <script>
+    //
+    //  GLOBAL SETTINGS
+    //
+    var GLOBAL = {};
+    GLOBAL.FTP_USER_PREFIX  = 'admin_';
+    GLOBAL.DB_USER_PREFIX   = 'admin_';
+    GLOBAL.DB_DBNAME_PREFIX = 'admin_';
+    GLOBAL.AJAX_URL = '';
+  </script>
+</head>
+<body class="body-<?=strtolower($TAB)?> lang-<?=$_SESSION['language']?>">
+root@web02:/usr/local/hestia/web# nano mail/index.php ^C
+root@web02:/usr/local/hestia/web# cat login/index.php
 <?php
 
 define('NO_AUTH_REQUIRED',true);
@@ -34,6 +57,9 @@ if (isset($_POST['user']) && isset($_POST['password'])) {
     if(isset($_SESSION['token']) && isset($_POST['token']) && $_POST['token'] == $_SESSION['token']) {
         $v_user = escapeshellarg($_POST['user']);
         $v_ip = escapeshellarg($_SERVER['REMOTE_ADDR']);
+        if (isset($_POST['twofa'])) {
+            $v_twofa = escapeshellarg($_POST['twofa']);
+        }
 
         // Get user's salt
         $output = '';
@@ -83,34 +109,50 @@ if (isset($_POST['user']) && isset($_POST['password'])) {
                 exec (HESTIA_CMD . "v-list-user ".$v_user." json", $output, $return_var);
                 $data = json_decode(implode('', $output), true);
 
-                // Define session user
-                $_SESSION['user'] = key($data);
-                $v_user = $_SESSION['user'];
-
-                // Get user favorites
-                get_favourites();
-
-                // Define language
-                $output = '';
-                exec (HESTIA_CMD."v-list-sys-languages json", $output, $return_var);
-                $languages = json_decode(implode('', $output), true);
-                if (in_array($data[$v_user]['LANGUAGE'], $languages)){
-                    $_SESSION['language'] = $data[$v_user]['LANGUAGE'];
-                } else {
-                    $_SESSION['language'] = 'en';
+                // Check if 2FA is active
+                if ($data[$_POST['user']]['TWOFA'] != '') {
+                    if (isset($v_twofa)){
+                        exec(HESTIA_CMD ."v-check-user-2fa ".$v_user." ".$v_twofa, $output, $return_var);
+                        unset($output);
+                        if ( $return_var > 0 ) {
+                            $ERROR = "<a class=\"error\">".__('Invalid or missing 2FA token')."</a>";
+                        }
+                    } else {
+                        $ERROR = "<a class=\"error\">".__('Invalid or missing 2FA token')."</a>";
+                    }
                 }
 
-                // Regenerate session id to prevent session fixation
-                session_regenerate_id();
-
-                // Redirect request to control panel interface
-                if (!empty($_SESSION['request_uri'])) {
-                    header("Location: ".$_SESSION['request_uri']);
-                    unset($_SESSION['request_uri']);
-                    exit;
-                } else {
-                    header("Location: /list/user/");
-                    exit;
+                // Check if 2FA was successfully
+                if ( ! isset($v_twofa) || $ERROR == '' ) {
+                    // Define session user
+                    $_SESSION['user'] = key($data);
+                    $v_user = $_SESSION['user'];
+
+                    // Get user favorites
+                    get_favourites();
+
+                    // Define language
+                    $output = '';
+                    exec (HESTIA_CMD."v-list-sys-languages json", $output, $return_var);
+                    $languages = json_decode(implode('', $output), true);
+                    if (in_array($data[$v_user]['LANGUAGE'], $languages)){
+                        $_SESSION['language'] = $data[$v_user]['LANGUAGE'];
+                    } else {
+                        $_SESSION['language'] = 'en';
+                    }
+
+                    // Regenerate session id to prevent session fixation
+                    session_regenerate_id();
+
+                    // Redirect request to control panel interface
+                    if (!empty($_SESSION['request_uri'])) {
+                        header("Location: ".$_SESSION['request_uri']);
+                        unset($_SESSION['request_uri']);
+                        exit;
+                    } else {
+                        header("Location: /list/user/");
+                        exit;
+                    }
                 }
             }
         }
@@ -150,4 +192,4 @@ $_SESSION['token'] = md5(uniqid(mt_rand(), true));
 
 require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$_SESSION['language'].'.php');
 require_once('../templates/header.html');
-require_once('../templates/login.html');
+require_once('../templates/login.html');

+ 36 - 1
web/templates/login.html

@@ -10,6 +10,26 @@
                                 <td style="padding: 20px 0 0 0;">
                                     <form method="post" action="/login/" >
                                     <input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>">
+                                    <script>
+                                    function show2FA(str) {
+                                        if (str.length == 0) {
+                                            $('.twofa').fadeOut();
+                                            return;
+                                        } else {
+                                            var xmlhttp = new XMLHttpRequest();
+                                            xmlhttp.onreadystatechange = function() {
+                                                if (this.readyState == 4 && this.status == 200) {
+                                                    var x = document.getElementById("twofa");
+                                                    $('.twofa').fadeIn();
+                                                } else {
+                                                    $('.twofa').fadeOut();
+                                                }
+                                            };
+                                            xmlhttp.open("GET", "/inc/2fa/active.php?user=" + str, true);
+                                            xmlhttp.send();
+                                        }
+                                    }
+                                    </script>
                                     <table class="login-box">
                                         <tr>
                                             <td syle="padding: 12px 0 0 2px;">
@@ -18,7 +38,7 @@
                                         </tr>
                                         <tr>
                                             <td>
-                                                <input tabindex="1" type="text" size="20px" style="width:240px;" name="user" class="vst-input">
+                                                <input tabindex="1" type="text" size="20px" style="width:240px;" name="user" class="vst-input" onfocusout="show2FA(this.value)">
                                             </td>
                                         </tr>
                                         <tr>
@@ -36,6 +56,21 @@
                                                 <input tabindex="2" type="password" size="20px"  style="width:240px;" name="password" class="vst-input">
                                             </td>
                                         </tr>
+                                        <tr class="twofa" style="display:none;">
+                                            <td style="padding-top: 12px; padding-left:2px;">
+                                                <?php print __('2FA Token');?>
+                                                <span style="padding:0 0 0 10px;">
+                                                    <a tabindex="5" class="vst-advanced" href="/reset/">
+                                                        <?php print __('forgot token');?>
+                                                    </a>
+                                                </span>
+                                            </td>
+                                        </tr>
+                                        <tr class="twofa" style="display:none;">
+                                            <td>
+                                                <input tabindex="3" type="text" size="20px" style="width:240px;" name="twofa" class="vst-input">
+                                            </td>
+                                        </tr>
                                         <tr>
                                             <td height="28px">
                                             </td>