Merge branch 'feature/ticket#1579-TwoFactorAuthentication' into develop
Resolved conflicts: pandora_console/extras/pandoradb_migrate_5.1_to_6.0.mysql.sql pandora_console/extras/pandoradb_migrate_5.1_to_6.0.oracle.sql pandora_console/extras/pandoradb_migrate_5.1_to_6.0.postgreSQL.sql pandora_console/include/styles/pandora.css
This commit is contained in:
commit
15d5607787
|
@ -30,3 +30,16 @@ SET t1.id_policy_module = (
|
|||
SELECT t2.id_policy_module
|
||||
FROM tagente_modulo AS t2
|
||||
WHERE t1.id_agente_modulo = t2.id_agente_modulo);
|
||||
|
||||
/* 2014/12/10 */
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Table `tuser_double_auth`
|
||||
-- ----------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `tuser_double_auth` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`id_user` varchar(60) NOT NULL,
|
||||
`secret` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (`id_user`),
|
||||
FOREIGN KEY (`id_user`) REFERENCES tusuario(`id_user`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
|
|
@ -18,4 +18,16 @@ ALTER TABLE tlayout_data ADD COLUMN fill_color varchar(200) DEFAULT "";
|
|||
-- Table `ttag_module`
|
||||
-- ---------------------------------------------------------------------
|
||||
|
||||
ALTER TABLE tlayout_data ADD COLUMN id_policy_module NUMBER(10, 0) DEFAULT 0 NOT NULL;
|
||||
ALTER TABLE tlayout_data ADD COLUMN id_policy_module NUMBER(10, 0) DEFAULT 0 NOT NULL;
|
||||
|
||||
/* 2014/12/10 */
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Table `tuser_double_auth`
|
||||
-- ----------------------------------------------------------------------
|
||||
CREATE TABLE tuser_double_auth (
|
||||
id NUMBER(10, 0) NOT NULL PRIMARY KEY,
|
||||
id_user VARCHAR2(60) NOT NULL REFERENCES tusuario(id_user) ON DELETE CASCADE,
|
||||
secret VARCHAR2(20) NOT NULL
|
||||
);
|
||||
CREATE SEQUENCE tuser_double_auth_s INCREMENT BY 1 START WITH 1;
|
||||
CREATE OR REPLACE TRIGGER tuser_double_auth_inc BEFORE INSERT ON tuser_double_auth REFERENCING NEW AS NEW FOR EACH ROW BEGIN SELECT tuser_double_auth_s.nextval INTO :NEW.ID FROM dual; END tuser_double_auth_inc;;
|
||||
|
|
|
@ -18,4 +18,14 @@ ALTER TABLE "tlayout_data" ADD COLUMN "fill_color" varchar(200) DEFAULT "";
|
|||
-- Table `ttag_module`
|
||||
-- ---------------------------------------------------------------------
|
||||
|
||||
ALTER TABLE tlayout_data ADD COLUMN "id_policy_module" INTEGER NOT NULL DEFAULT 0;
|
||||
ALTER TABLE tlayout_data ADD COLUMN "id_policy_module" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
/* 2014/12/10 */
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Table `tuser_double_auth`
|
||||
-- ----------------------------------------------------------------------
|
||||
CREATE TABLE "tuser_double_auth" (
|
||||
"id" SERIAL NOT NULL PRIMARY KEY,
|
||||
"id_user" varchar(60) NOT NULL UNIQUE REFERENCES "tusuario"("id_user") ON DELETE CASCADE,
|
||||
"secret" varchar(20) NOT NULL
|
||||
);
|
||||
|
|
|
@ -35,6 +35,7 @@ switch ($login_screen) {
|
|||
$logo_title = __('Go to Pandora FMS Website');
|
||||
break;
|
||||
case 'logout':
|
||||
case 'double_auth':
|
||||
$logo_link = 'index.php';
|
||||
$logo_title = __('Go to Login');
|
||||
break;
|
||||
|
@ -129,6 +130,22 @@ echo '
|
|||
echo __('Your session is over. Please close your browser window to close this Pandora session.').'<br /><br />';
|
||||
echo '</p>';
|
||||
break;
|
||||
case 'double_auth':
|
||||
if (!empty ($page) && !empty ($sec)) {
|
||||
foreach ($_POST as $key => $value) {
|
||||
html_print_input_hidden ($key, $value);
|
||||
}
|
||||
}
|
||||
echo '<div class="login_double_auth_code_text">';
|
||||
echo __('Authenticator code') . '<br>';
|
||||
echo '</div>';
|
||||
echo '<div class="login_double_auth_code">';
|
||||
html_print_input_text_extended ("auth_code", '', "auth_code", '', '', '' , false, '', 'class="login login_password"', false, true);
|
||||
echo '</div>';
|
||||
echo '<div class="login_button">';
|
||||
html_print_submit_button(__("Check code") . ' >', "login_button", false, 'class="sub next_login"');
|
||||
echo '</div>';
|
||||
break;
|
||||
default:
|
||||
if (isset($error_info)) {
|
||||
echo '<h1 id="log_title">' . $error_info['title'] . '</h1>';
|
||||
|
|
|
@ -94,6 +94,15 @@ if (enterprise_installed()) {
|
|||
add_enterprise_auth_options($table, 12);
|
||||
}
|
||||
|
||||
// Enable double authentication
|
||||
$row = array();
|
||||
$row[] = __('Double authentication')
|
||||
. ui_print_help_tip(__("If this option is enabled, the users can use double authentication with their accounts"), true);
|
||||
$row[] = __('Yes').' '.html_print_radio_button('double_auth_enabled', 1, '', $config['double_auth_enabled'], true)
|
||||
.' '
|
||||
. __('No').' '.html_print_radio_button('double_auth_enabled', 0, '', $config['double_auth_enabled'], true);
|
||||
$table->data[] = $row;
|
||||
|
||||
echo '<form id="form_setup" method="post">';
|
||||
html_print_input_hidden ('update_config', 1);
|
||||
html_print_table ($table);
|
||||
|
|
|
@ -0,0 +1,522 @@
|
|||
<?php
|
||||
// Pandora FMS - http://pandorafms.com
|
||||
// ==================================================
|
||||
// Copyright (c) 2005-2010 Artica Soluciones Tecnologicas
|
||||
// Please see http://pandorafms.org for full contribution list
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation for version 2.
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
global $config;
|
||||
|
||||
// Login check
|
||||
check_login ();
|
||||
|
||||
// Security check
|
||||
$id_user = (string) get_parameter('id_user');
|
||||
if ($id_user !== $config['id_user']) {
|
||||
db_pandora_audit("ACL Violation",
|
||||
"Trying to access Double Authentication");
|
||||
echo json_encode(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the class
|
||||
require_once ($config['homedir'].'/include/auth/GAuth/Auth.php');
|
||||
|
||||
// Default lenght of the secret
|
||||
$secret_lenght = 16;
|
||||
// Default lenght of the code
|
||||
$code_lenght = 6;
|
||||
|
||||
// Generate a new secret for the user
|
||||
$generate_double_auth_secret = (bool) get_parameter('generate_double_auth_secret');
|
||||
if ($generate_double_auth_secret) {
|
||||
$gAuth = new \GAuth\Auth();
|
||||
$code = $gAuth->generateCode($secret_lenght);
|
||||
|
||||
echo json_encode($code);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the provided secret with a code provided by the user.
|
||||
// If the parameter 'save' is set to true, the secret will
|
||||
// be stored into the database.
|
||||
// The results can be true, false or 1 if the validation is true
|
||||
// but the secret can't be stored into the database.
|
||||
$validate_double_auth_code = (bool) get_parameter('validate_double_auth_code');
|
||||
if ($validate_double_auth_code) {
|
||||
$result = false;
|
||||
|
||||
$secret = (string) get_parameter('secret');
|
||||
|
||||
if (!empty($secret) && strlen($secret) === $secret_lenght) {
|
||||
$code = (string) get_parameter('code');
|
||||
|
||||
if (!empty($code) && strlen($code) === $code_lenght) {
|
||||
$save = (bool) get_parameter('save');
|
||||
|
||||
if (!empty($code)) {
|
||||
$gAuth = new \GAuth\Auth($secret);
|
||||
$result = $gAuth->validateCode($code);
|
||||
}
|
||||
|
||||
if ($result && $save) {
|
||||
// Delete the actual value (if exists)
|
||||
$where = array(
|
||||
'id_user' => $id_user
|
||||
);
|
||||
db_process_sql_delete('tuser_double_auth', $where);
|
||||
|
||||
// Insert the new value
|
||||
$values = array(
|
||||
'id_user' => $id_user,
|
||||
'secret' => $secret
|
||||
);
|
||||
$result = (bool) db_process_sql_insert('tuser_double_auth', $values);
|
||||
|
||||
if (!$result) {
|
||||
$result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the provided secret to the user
|
||||
$save_double_auth_secret = (bool) get_parameter('save_double_auth_secret');
|
||||
if ($save_double_auth_secret) {
|
||||
$result = false;
|
||||
|
||||
$secret = (string) get_parameter('secret');
|
||||
|
||||
if (strlen($secret) === $secret_lenght) {
|
||||
// Delete the actual value (if exists)
|
||||
$where = array(
|
||||
'id_user' => $id_user
|
||||
);
|
||||
db_process_sql_delete('tuser_double_auth', $where);
|
||||
// Insert the new value
|
||||
$values = array(
|
||||
'id_user' => $id_user,
|
||||
'secret' => $secret
|
||||
);
|
||||
$result = (bool) db_process_sql_insert('tuser_double_auth', $values);
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable the double auth for the user
|
||||
$deactivate_double_auth = (bool) get_parameter('deactivate_double_auth');
|
||||
if ($deactivate_double_auth) {
|
||||
$result = false;
|
||||
|
||||
// Delete the actual value (if exists)
|
||||
$where = array(
|
||||
'id_user' => $id_user
|
||||
);
|
||||
$result = db_process_sql_delete('tuser_double_auth', $where);
|
||||
|
||||
echo json_encode($result);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the info page to the container dialog
|
||||
$get_double_auth_data_page = (bool) get_parameter('get_double_auth_data_page');
|
||||
if ($get_double_auth_data_page) {
|
||||
$secret = db_get_value('secret', 'tuser_double_auth', 'id_user', $id_user);
|
||||
|
||||
if (empty($secret)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$html = '';
|
||||
$html .= "<div class=\"left_align\">";
|
||||
$html .= "<p>";
|
||||
$html .= __('This is the private code that you should use with your authenticator app') . ". ";
|
||||
$html .= __('You could enter the code manually or use the QR code to add it automatically') . ".";
|
||||
$html .= "</p>";
|
||||
$html .= "</div>";
|
||||
$html .= "<div class=\"center_align\">";
|
||||
$html .= __('Code') . ": <b>$secret</b>";
|
||||
$html .= "<br>";
|
||||
$html .= __('QR') . ": <br>";
|
||||
$html .= "<div id=\"qr-container\"></div>";
|
||||
$html .= "</div>";
|
||||
|
||||
ob_clean();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var secret = "<?php echo $secret; ?>";
|
||||
var userID = "<?php echo $config['id_user']; ?>";
|
||||
|
||||
// QR code with the secret to add it to the app
|
||||
paint_qrcode("otpauth://totp/"+userID+"?secret="+secret, $("div#qr-container").get(0), 200, 200);
|
||||
|
||||
$("div#qr-container").attr("title", "").find("canvas").remove();
|
||||
// Don't delete this timeout. It's necessary to perform the style change.
|
||||
// Chrome min. milliseconds: 1.
|
||||
// Firefox min. milliseconds: 9.
|
||||
setTimeout(function() {
|
||||
$("div#qr-container").find("img").attr("style", "");
|
||||
}, 10);
|
||||
</script>
|
||||
<?php
|
||||
$html .= ob_get_clean();
|
||||
|
||||
echo $html;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the info page to the container dialog
|
||||
$get_double_auth_info_page = (bool) get_parameter('get_double_auth_info_page');
|
||||
if ($get_double_auth_info_page) {
|
||||
$container_id = (string) get_parameter('containerID');
|
||||
|
||||
$html = '';
|
||||
$html .= "<div class=\"left_align\">";
|
||||
$html .= "<p>";
|
||||
$html .= __('You are about to activate the double authentication') . ". ";
|
||||
$html .= __('With this option enabled, your account access will be more secure,
|
||||
cause a code generated by other application will be required after the login') . ". ";
|
||||
$html .= "</p>";
|
||||
$html .= "<p>";
|
||||
$html .= __('You will need to install the app from the following link before continue') . ". ";
|
||||
$html .= "</p>";
|
||||
$html .= "</div>";
|
||||
$html .= "<br>";
|
||||
$html .= "<div class=\"center_align\">";
|
||||
$html .= html_print_button(__('Download the app'), 'google_authenticator_download', false, '', '', true);
|
||||
$html .= "</div>";
|
||||
$html .= "<br>";
|
||||
$html .= "<div class=\"center_align\">";
|
||||
$html .= html_print_button(__('Continue'), 'continue_to_generate', false, '', '', true);
|
||||
$html .= "</div>";
|
||||
|
||||
ob_clean();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
// Open the download page on click
|
||||
$("input[name=\"google_authenticator_download\"]").click(function (e) {
|
||||
e.preventDefault();
|
||||
window.open("https://support.google.com/accounts/answer/1066447");
|
||||
});
|
||||
|
||||
// Change the container content with the generation page
|
||||
$("input[name=\"continue_to_generate\"]").click(function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!confirm("<?php echo __('Are you installed the app yet?'); ?>")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var containerID = "<?php echo $container_id; ?>";
|
||||
|
||||
$("#"+containerID).html("<img src=\"<?php echo $config['homeurl']; ?>/images/spinner.gif\" />");
|
||||
|
||||
$.ajax({
|
||||
url: "<?php echo ui_get_full_url('ajax.php', false, false, false); ?>",
|
||||
type: 'POST',
|
||||
dataType: 'html',
|
||||
data: {
|
||||
page: 'include/ajax/double_auth.ajax',
|
||||
id_user: "<?php echo $config['id_user']; ?>",
|
||||
get_double_auth_generation_page: 1,
|
||||
containerID: containerID
|
||||
},
|
||||
complete: function(xhr, textStatus) {
|
||||
|
||||
},
|
||||
success: function(data, textStatus, xhr) {
|
||||
// isNaN = is not a number
|
||||
if (isNaN(data)) {
|
||||
$("#"+containerID).html(data);
|
||||
}
|
||||
// data is a number, convert it to integer to do the compare
|
||||
else if (Number(data) === -1) {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('Authentication error') . '</div></b>'; ?>");
|
||||
}
|
||||
else {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('Error') . '</div></b>'; ?>");
|
||||
}
|
||||
},
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('There was an error loading the data') . '</div></b>'; ?>");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
$html .= ob_get_clean();
|
||||
|
||||
echo $html;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the page that generates a secret for the user
|
||||
$get_double_auth_generation_page = (bool) get_parameter('get_double_auth_generation_page');
|
||||
if ($get_double_auth_generation_page) {
|
||||
$container_id = (string) get_parameter('containerID');
|
||||
|
||||
$gAuth = new \GAuth\Auth();
|
||||
$secret = $gAuth->generateCode($secret_lenght);
|
||||
|
||||
$html = '';
|
||||
$html .= "<div class=\"center_align\">";
|
||||
$html .= "<p>";
|
||||
$html .= "<b>" . __('A private code has been generated') . "</b>.";
|
||||
$html .= "</p>";
|
||||
$html .= "</div>";
|
||||
$html .= "<div class=\"left_align\">";
|
||||
$html .= "<p>";
|
||||
$html .= __('Before continue, you should create a new entry into the authenticator app') . ". ";
|
||||
$html .= __('You could enter the code manually or use the QR code to add it automatically') . ".";
|
||||
$html .= "</p>";
|
||||
$html .= "</div>";
|
||||
$html .= "<div class=\"center_align\">";
|
||||
$html .= __('Code') . ": <b>$secret</b>";
|
||||
$html .= "<br>";
|
||||
$html .= __('QR') . ": <br>";
|
||||
$html .= "<div id=\"qr-container\"></div>";
|
||||
$html .= "<br>";
|
||||
$html .= html_print_button(__('Refresh code'), 'continue_to_generate', false, '', '', true);
|
||||
$html .= " ";
|
||||
$html .= html_print_button(__('Continue'), 'continue_to_validate', false, '', '', true);
|
||||
$html .= "</div>";
|
||||
|
||||
ob_clean();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var secret = "<?php echo $secret; ?>";
|
||||
var userID = "<?php echo $config['id_user']; ?>";
|
||||
|
||||
// QR code with the secret to add it to the app
|
||||
paint_qrcode("otpauth://totp/"+userID+"?secret="+secret, $("div#qr-container").get(0), 200, 200);
|
||||
|
||||
$("div#qr-container").attr("title", "").find("canvas").remove();
|
||||
// Don't delete this timeout. It's necessary to perform the style change.
|
||||
// Chrome min. milliseconds: 1.
|
||||
// Firefox min. milliseconds: 9.
|
||||
setTimeout(function() {
|
||||
$("div#qr-container").find("img").attr("style", "");
|
||||
}, 10);
|
||||
|
||||
// Load the same page with another secret
|
||||
$("input[name=\"continue_to_generate\"]").click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var containerID = "<?php echo $container_id; ?>";
|
||||
|
||||
$("#"+containerID).html("<img src=\"<?php echo $config['homeurl']; ?>/images/spinner.gif\" />");
|
||||
|
||||
$.ajax({
|
||||
url: "<?php echo ui_get_full_url('ajax.php', false, false, false); ?>",
|
||||
type: 'POST',
|
||||
dataType: 'html',
|
||||
data: {
|
||||
page: 'include/ajax/double_auth.ajax',
|
||||
id_user: userID,
|
||||
get_double_auth_generation_page: 1,
|
||||
containerID: containerID
|
||||
},
|
||||
complete: function(xhr, textStatus) {
|
||||
|
||||
},
|
||||
success: function(data, textStatus, xhr) {
|
||||
// isNaN = is not a number
|
||||
if (isNaN(data)) {
|
||||
$("#"+containerID).html(data);
|
||||
}
|
||||
// data is a number, convert it to integer to do the compare
|
||||
else if (Number(data) === -1) {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('Authentication error') . '</div></b>'; ?>");
|
||||
}
|
||||
else {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('Error') . '</div></b>'; ?>");
|
||||
}
|
||||
},
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('There was an error loading the data') . '</div></b>'; ?>");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Load the validation page
|
||||
$("input[name=\"continue_to_validate\"]").click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!confirm("<?php echo __('Are you introduced the code in the authenticator app yet?'); ?>")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var containerID = "<?php echo $container_id; ?>";
|
||||
|
||||
$("#"+containerID).html("<img src=\"<?php echo $config['homeurl']; ?>/images/spinner.gif\" />");
|
||||
|
||||
$.ajax({
|
||||
url: "<?php echo ui_get_full_url('ajax.php', false, false, false); ?>",
|
||||
type: 'POST',
|
||||
dataType: 'html',
|
||||
data: {
|
||||
page: 'include/ajax/double_auth.ajax',
|
||||
id_user: "<?php echo $config['id_user']; ?>",
|
||||
get_double_auth_validation_page: 1,
|
||||
secret: secret,
|
||||
containerID: containerID
|
||||
},
|
||||
complete: function(xhr, textStatus) {
|
||||
|
||||
},
|
||||
success: function(data, textStatus, xhr) {
|
||||
// isNaN = is not a number
|
||||
if (isNaN(data)) {
|
||||
$("#"+containerID).html(data);
|
||||
}
|
||||
// data is a number, convert it to integer to do the compare
|
||||
else if (Number(data) === -1) {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('Authentication error') . '</div></b>'; ?>");
|
||||
}
|
||||
else {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('Error') . '</div></b>'; ?>");
|
||||
}
|
||||
},
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('There was an error loading the data') . '</div></b>'; ?>");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
$html .= ob_get_clean();
|
||||
|
||||
echo $html;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the validation page
|
||||
$get_double_auth_validation_page = (bool) get_parameter('get_double_auth_validation_page');
|
||||
if ($get_double_auth_validation_page) {
|
||||
$container_id = (string) get_parameter('containerID');
|
||||
$secret = (string) get_parameter('secret');
|
||||
|
||||
if (empty($secret) || strlen($secret) != $secret_lenght) {
|
||||
echo json_encode(false);
|
||||
return;
|
||||
}
|
||||
|
||||
$html = '';
|
||||
$html .= "<div class=\"left_align\">";
|
||||
$html .= "<p>";
|
||||
$html .= __('Introduce a code generated by the app') . ". ";
|
||||
$html .= __('If the code is valid, the double authentication will be activated') . ".";
|
||||
$html .= "</p>";
|
||||
$html .= "</div>";
|
||||
$html .= "<br>";
|
||||
$html .= "<div class=\"center_align\">";
|
||||
$html .= html_print_input_text('code', '', '', 50, $secret_lenght, true);
|
||||
$html .= "<div id=\"code_input_message\" class=\"red\"></div>";
|
||||
$html .= "<br><br>";
|
||||
$html .= "<div id=\"button-container\">";
|
||||
$html .= html_print_button(__('Validate code'), 'continue_to_validate', false, '', '', true);
|
||||
$html .= html_print_image ("images/spinner.gif", true);
|
||||
$html .= "</div>";
|
||||
$html .= "</div>";
|
||||
|
||||
ob_clean();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$("div#button-container").find("img").hide();
|
||||
|
||||
// Start the error message hiden
|
||||
$("div#code_input_message").hide();
|
||||
|
||||
var secret = "<?php echo $secret; ?>";
|
||||
|
||||
$("input#text-code").keypress(function() {
|
||||
$(this).removeClass("red").css('border-color', '#cbcbcb');
|
||||
});
|
||||
|
||||
$("input[name=\"continue_to_validate\"]").click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Hide the error message
|
||||
$("div#code_input_message").hide();
|
||||
|
||||
var containerID = "<?php echo $container_id; ?>";
|
||||
|
||||
$("input[name=\"continue_to_validate\"]").prop('enabled', false).hide();
|
||||
$("div#button-container").find("img").show();
|
||||
|
||||
$.ajax({
|
||||
url: "<?php echo ui_get_full_url('ajax.php', false, false, false); ?>",
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
page: 'include/ajax/double_auth.ajax',
|
||||
id_user: "<?php echo $config['id_user']; ?>",
|
||||
validate_double_auth_code: 1,
|
||||
save: 1,
|
||||
secret: secret,
|
||||
code: function () {
|
||||
return $("input#text-code").val();
|
||||
},
|
||||
containerID: containerID
|
||||
},
|
||||
complete: function(xhr, textStatus) {
|
||||
|
||||
},
|
||||
success: function(data, textStatus, xhr) {
|
||||
// Valid code
|
||||
if (data === true) {
|
||||
$("#"+containerID).html("<b><?php echo '<b><div class=\"green\">' . __('The code is valid, you can exit now') . '</div></b>'; ?></b>");
|
||||
}
|
||||
// Invalid code
|
||||
else if (data === false) {
|
||||
$("input[name=\"continue_to_validate\"]").prop('enabled', true).show();
|
||||
$("div#button-container").find("img").hide();
|
||||
$("input#text-code").addClass("red").css('border-color', '#c00');
|
||||
|
||||
$("div#code_input_message").html("<?php echo __('Invalid code'); ?>").show();
|
||||
}
|
||||
// Valid code but not saved
|
||||
else if (data === 1) {
|
||||
$("input[name=\"continue_to_validate\"]").prop('enabled', true).show();
|
||||
$("div#button-container").find("img").hide();
|
||||
$("input#text-code").addClass("red").css('border-color', '#c00');
|
||||
|
||||
$("div#code_input_message").html("<?php echo __('The code is valid, but it was an error saving the data'); ?>").show();
|
||||
}
|
||||
// Authentication error
|
||||
else if (data === -1) {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('Authentication error') . '</div></b>'; ?>");
|
||||
}
|
||||
// Not expected results
|
||||
else {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('Error') . '</div></b>'; ?>");
|
||||
}
|
||||
},
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
$("#"+containerID).html("<?php echo '<b><div class=\"red\">' . __('There was an error loading the data') . '</div></b>'; ?>");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
$html .= ob_get_clean();
|
||||
|
||||
echo $html;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
?>
|
|
@ -0,0 +1,356 @@
|
|||
<?php
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013 Chris Cornutt
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
namespace GAuth;
|
||||
|
||||
/**
|
||||
* A class for generating the codes compatible with the Google Authenticator
|
||||
* clients.
|
||||
*
|
||||
* NOTE: A lot of the logic from this class has been borrowed from this class:
|
||||
* http://www.idontplaydarts.com/wp-content/uploads/2011/07/ga.php_.txt
|
||||
*
|
||||
* @author Chris Cornutt <ccornutt@phpdeveloper.org>
|
||||
* @package GAuth
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
class Auth
|
||||
{
|
||||
/**
|
||||
* Internal lookup table
|
||||
* @var array
|
||||
*/
|
||||
private $lookup = array();
|
||||
|
||||
/**
|
||||
* Initialization key
|
||||
* @var string
|
||||
*/
|
||||
private $initKey = null;
|
||||
|
||||
/**
|
||||
* Seconds between key refreshes
|
||||
* @var integer
|
||||
*/
|
||||
private $refreshSeconds = 30;
|
||||
|
||||
/**
|
||||
* Length of codes to generate
|
||||
* @var integer
|
||||
*/
|
||||
private $codeLength = 6;
|
||||
|
||||
/**
|
||||
* Range plus/minus for "window of opportunity" on allowed codes
|
||||
* @var integer
|
||||
*/
|
||||
private $range = 2;
|
||||
|
||||
/**
|
||||
* Initialize the object and set up the lookup table
|
||||
* Optionally the Initialization key
|
||||
*
|
||||
* @param string $initKey Initialization key
|
||||
*/
|
||||
public function __construct($initKey = null)
|
||||
{
|
||||
$this->buildLookup();
|
||||
|
||||
if ($initKey !== null) {
|
||||
$this->setInitKey($initKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the base32 lookup table
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function buildLookup()
|
||||
{
|
||||
$lookup = array_combine(
|
||||
array_merge(range('A', 'Z'), range(2, 7)),
|
||||
range(0, 31)
|
||||
);
|
||||
$this->setLookup($lookup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current "range" value
|
||||
* @return integer Range value
|
||||
*/
|
||||
public function getRange()
|
||||
{
|
||||
return $this->range;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "range" value
|
||||
*
|
||||
* @param integer $range Range value
|
||||
* @return \GAuth\Auth instance
|
||||
*/
|
||||
public function setRange($range)
|
||||
{
|
||||
if (!is_numeric($range)) {
|
||||
throw new \InvalidArgumentException('Invalid window range');
|
||||
}
|
||||
$this->range = $range;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the initialization key for the object
|
||||
*
|
||||
* @param string $key Initialization key
|
||||
* @throws \InvalidArgumentException If hash is not valid base32
|
||||
* @return \GAuth\Auth instance
|
||||
*/
|
||||
public function setInitKey($key)
|
||||
{
|
||||
if (preg_match('/^['.implode('', array_keys($this->getLookup())).']+$/', $key) == false) {
|
||||
throw new \InvalidArgumentException('Invalid base32 hash!');
|
||||
}
|
||||
$this->initKey = $key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Initialization key
|
||||
*
|
||||
* @return string Initialization key
|
||||
*/
|
||||
public function getInitKey()
|
||||
{
|
||||
return $this->initKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the contents of the internal lookup table
|
||||
*
|
||||
* @param array $lookup Lookup data set
|
||||
* @throws \InvalidArgumentException If lookup given is not an array
|
||||
* @return \GAuth\Auth instance
|
||||
*/
|
||||
public function setLookup($lookup)
|
||||
{
|
||||
if (!is_array($lookup)) {
|
||||
throw new \InvalidArgumentException('Lookup value must be an array');
|
||||
}
|
||||
$this->lookup = $lookup;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current lookup data set
|
||||
*
|
||||
* @return array Lookup data
|
||||
*/
|
||||
public function getLookup()
|
||||
{
|
||||
return $this->lookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of seconds for code refresh currently set
|
||||
*
|
||||
* @return integer Refresh in seconds
|
||||
*/
|
||||
public function getRefresh()
|
||||
{
|
||||
return $this->refreshSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of seconds to refresh codes
|
||||
*
|
||||
* @param integer $seconds Seconds to refresh
|
||||
* @throws \InvalidArgumentException If seconds value is not numeric
|
||||
* @return \GAuth\Auth instance
|
||||
*/
|
||||
public function setRefresh($seconds)
|
||||
{
|
||||
if (!is_numeric($seconds)) {
|
||||
throw \InvalidArgumentException('Seconds must be numeric');
|
||||
}
|
||||
$this->refreshSeconds = $seconds;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current length for generated codes
|
||||
*
|
||||
* @return integer Code length
|
||||
*/
|
||||
public function getCodeLength()
|
||||
{
|
||||
return $this->codeLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length of the generated codes
|
||||
*
|
||||
* @param integer $length Code length
|
||||
* @return \GAuth\Auth instance
|
||||
*/
|
||||
public function setCodeLength($length)
|
||||
{
|
||||
$this->codeLength = $length;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the given code
|
||||
*
|
||||
* @param string $code Code entered by user
|
||||
* @param string $initKey Initialization key
|
||||
* @param string $timestamp Timestamp for calculation
|
||||
* @param integer $range Seconds before/after to validate hash against
|
||||
* @throws \InvalidArgumentException If incorrect code length
|
||||
* @return boolean Pass/fail of validation
|
||||
*/
|
||||
public function validateCode($code, $initKey = null, $timestamp = null, $range = null)
|
||||
{
|
||||
if (strlen($code) !== $this->getCodeLength()) {
|
||||
throw new \InvalidArgumentException('Incorrect code length');
|
||||
}
|
||||
|
||||
$range = ($range == null) ? $this->getRange() : $range;
|
||||
$timestamp = ($timestamp == null) ? $this->generateTimestamp() : $timestamp;
|
||||
$initKey = ($initKey == null) ? $this->getInitKey() : $initKey;
|
||||
|
||||
$binary = $this->base32_decode($initKey);
|
||||
|
||||
for ($time = ($timestamp - $range); $time <= ($timestamp + $range); $time++) {
|
||||
if ($this->generateOneTime($binary, $time) == $code) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a one-time code
|
||||
*
|
||||
* @param string $initKey Initialization key [optional]
|
||||
* @param string $timestamp Timestamp for calculation [optional]
|
||||
* @return string Geneerated code/hash
|
||||
*/
|
||||
public function generateOneTime($initKey = null, $timestamp = null)
|
||||
{
|
||||
$initKey = ($initKey == null) ? $this->getInitKey() : $initKey;
|
||||
$timestamp = ($timestamp == null) ? $this->generateTimestamp() : $timestamp;
|
||||
|
||||
$hash = hash_hmac (
|
||||
'sha1',
|
||||
pack('N*', 0) . pack('N*', $timestamp),
|
||||
$initKey,
|
||||
true
|
||||
);
|
||||
|
||||
return str_pad($this->truncateHash($hash), $this->getCodeLength(), '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a code/hash
|
||||
* Useful for making Initialization codes
|
||||
*
|
||||
* @param integer $length Length for the generated code
|
||||
* @return string Generated code
|
||||
*/
|
||||
public function generateCode($length = 16)
|
||||
{
|
||||
$lookup = implode('', array_keys($this->getLookup()));
|
||||
$code = '';
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$code .= $lookup[mt_rand(0, strlen($lookup)-1)];
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Geenrate the timestamp for the calculation
|
||||
*
|
||||
* @return integer Timestamp
|
||||
*/
|
||||
public function generateTimestamp()
|
||||
{
|
||||
return floor(microtime(true)/$this->getRefresh());
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the given hash down to just what we need
|
||||
*
|
||||
* @param string $hash Hash to truncate
|
||||
* @return string Truncated hash value
|
||||
*/
|
||||
public function truncateHash($hash)
|
||||
{
|
||||
$offset = ord($hash[19]) & 0xf;
|
||||
|
||||
return (
|
||||
((ord($hash[$offset+0]) & 0x7f) << 24 ) |
|
||||
((ord($hash[$offset+1]) & 0xff) << 16 ) |
|
||||
((ord($hash[$offset+2]) & 0xff) << 8 ) |
|
||||
(ord($hash[$offset+3]) & 0xff)
|
||||
) % pow(10, $this->getCodeLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* Base32 decoding function
|
||||
*
|
||||
* @param string base32 encoded hash
|
||||
* @throws \InvalidArgumentException When hash is not valid
|
||||
* @return string Binary value of hash
|
||||
*/
|
||||
public function base32_decode($hash)
|
||||
{
|
||||
$lookup = $this->getLookup();
|
||||
|
||||
if (preg_match('/^['.implode('', array_keys($lookup)).']+$/', $hash) == false) {
|
||||
throw new \InvalidArgumentException('Invalid base32 hash!');
|
||||
}
|
||||
|
||||
$hash = strtoupper($hash);
|
||||
$buffer = 0;
|
||||
$length = 0;
|
||||
$binary = '';
|
||||
|
||||
for ($i = 0; $i < strlen($hash); $i++) {
|
||||
$buffer = $buffer << 5;
|
||||
$buffer += $lookup[$hash[$i]];
|
||||
$length += 5;
|
||||
|
||||
if ($length >= 8) {
|
||||
$length -= 8;
|
||||
$binary .= chr(($buffer & (0xFF << $length)) >> $length);
|
||||
}
|
||||
}
|
||||
|
||||
return $binary;
|
||||
}
|
||||
}
|
|
@ -2236,4 +2236,55 @@ function print_audit_csv ($data) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the code given to surpass the 2 step authentication
|
||||
*
|
||||
* @param string User name
|
||||
* @param string Code given by the authenticator app
|
||||
*
|
||||
* @return -1 if the parameters introduced are incorrect,
|
||||
* there is a problem accessing the user secret or
|
||||
* if an exception are launched.
|
||||
* true if the code is valid.
|
||||
* false if the code is invalid.
|
||||
*/
|
||||
function validate_double_auth_code ($user, $code) {
|
||||
global $config;
|
||||
require_once ($config['homedir'].'/include/auth/GAuth/Auth.php');
|
||||
$result = false;
|
||||
|
||||
if (empty($user) || empty($code)) {
|
||||
$result = -1;
|
||||
}
|
||||
else {
|
||||
$secret = db_get_value('secret', 'tuser_double_auth', 'id_user', $user);
|
||||
|
||||
if ($secret === false) {
|
||||
$result = -1;
|
||||
}
|
||||
else if (!empty($secret)) {
|
||||
try {
|
||||
$gAuth = new \GAuth\Auth($secret);
|
||||
$result = $gAuth->validateCode($code);
|
||||
} catch (Exception $e) {
|
||||
$result = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the 2 step authentication is enabled for the user given
|
||||
*
|
||||
* @param string User name
|
||||
*
|
||||
* @return true if the user has the double auth enabled or false otherwise.
|
||||
*/
|
||||
function is_double_auth_enabled ($user) {
|
||||
$result = (bool) db_get_value('id', 'tuser_double_auth', 'id_user', $user);
|
||||
|
||||
return $result;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -321,6 +321,8 @@ function config_update_config () {
|
|||
$error_update[] = __('User');
|
||||
if (!config_update_value ('rintegria_pass', get_parameter ('rintegria_pass')))
|
||||
$error_update[] = __('Password');
|
||||
if (!config_update_value ('double_auth_enabled', get_parameter ('double_auth_enabled')))
|
||||
$error_update[] = __('Double authentication');
|
||||
/////////////
|
||||
break;
|
||||
case 'perf':
|
||||
|
|
|
@ -2820,3 +2820,17 @@ table#policy_modules td * {
|
|||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
}
|
||||
|
||||
#dialog-double_auth-container {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.center_align {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.left_align {
|
||||
text-align: left;
|
||||
}
|
|
@ -167,176 +167,291 @@ if (strlen($search) > 0) {
|
|||
$searchPage = true;
|
||||
}
|
||||
|
||||
// Login process
|
||||
if (! isset ($config['id_user']) && isset ($_GET["login"])) {
|
||||
include_once('include/functions_db.php'); //Include it to use escape_string_sql function
|
||||
|
||||
$config["auth_error"] = ""; //Set this to the error message from the authorization mechanism
|
||||
$nick = get_parameter_post ("nick"); //This is the variable with the login
|
||||
$pass = get_parameter_post ("pass"); //This is the variable with the password
|
||||
$nick = db_escape_string_sql($nick);
|
||||
$pass = db_escape_string_sql($pass);
|
||||
|
||||
// process_user_login is a virtual function which should be defined in each auth file.
|
||||
// It accepts username and password. The rest should be internal to the auth file.
|
||||
// The auth file can set $config["auth_error"] to an informative error output or reference their internal error messages to it
|
||||
// process_user_login should return false in case of errors or invalid login, the nickname if correct
|
||||
$nick_in_db = process_user_login ($nick, $pass);
|
||||
|
||||
$expired_pass = false;
|
||||
|
||||
if (($nick_in_db != false) && ((!is_user_admin($nick)
|
||||
|| $config['enable_pass_policy_admin']))
|
||||
&& (defined('PANDORA_ENTERPRISE'))
|
||||
&& ($config['enable_pass_policy'])) {
|
||||
include_once(ENTERPRISE_DIR . "/include/auth/mysql.php");
|
||||
// Login process
|
||||
if (! isset ($config['id_user'])) {
|
||||
if (isset ($_GET["login"])) {
|
||||
include_once('include/functions_db.php'); //Include it to use escape_string_sql function
|
||||
|
||||
$blocked = login_check_blocked($nick);
|
||||
|
||||
if ($blocked) {
|
||||
require_once ('general/login_page.php');
|
||||
db_pandora_audit("Password expired", "Password expired: ".$nick, $nick);
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
$config["auth_error"] = ""; //Set this to the error message from the authorization mechanism
|
||||
$nick = get_parameter_post ("nick"); //This is the variable with the login
|
||||
$pass = get_parameter_post ("pass"); //This is the variable with the password
|
||||
$nick = db_escape_string_sql($nick);
|
||||
$pass = db_escape_string_sql($pass);
|
||||
|
||||
//Since now, only the $pass variable are needed
|
||||
unset ($_GET['pass'], $_POST['pass'], $_REQUEST['pass']);
|
||||
|
||||
// If the auth_code exists, we assume the user has come through the double auth page
|
||||
if (isset ($_POST['auth_code'])) {
|
||||
$double_auth_success = false;
|
||||
|
||||
// The double authentication is activated and the user has surpassed the first step (the login).
|
||||
// Now the authentication code provided will be checked.
|
||||
if (isset ($_SESSION['prepared_login_da'])) {
|
||||
if (isset ($_SESSION['prepared_login_da']['id_user'])
|
||||
&& isset ($_SESSION['prepared_login_da']['timestamp'])) {
|
||||
|
||||
// The user has a maximum of 5 minutes to introduce the double auth code
|
||||
$dauth_period = SECONDS_2MINUTES;
|
||||
$now = time();
|
||||
$dauth_time = $_SESSION['prepared_login_da']['timestamp'];
|
||||
|
||||
if ($now - $dauth_period < $dauth_time) {
|
||||
// Nick
|
||||
$nick = $_SESSION["prepared_login_da"]['id_user'];
|
||||
// Code
|
||||
$code = (string) get_parameter_post ("auth_code");
|
||||
|
||||
if (!empty($code)) {
|
||||
$result = validate_double_auth_code($nick, $code);
|
||||
|
||||
if ($result === true) {
|
||||
// Double auth success
|
||||
$double_auth_success = true;
|
||||
}
|
||||
else {
|
||||
// Screen
|
||||
$login_screen = 'double_auth';
|
||||
// Error message
|
||||
$config["auth_error"] = __("Invalid code");
|
||||
|
||||
if (!isset($_SESSION['prepared_login_da']['attempts']))
|
||||
$_SESSION['prepared_login_da']['attempts'] = 0;
|
||||
$_SESSION['prepared_login_da']['attempts']++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Screen
|
||||
$login_screen = 'double_auth';
|
||||
// Error message
|
||||
$config["auth_error"] = __("The code shouldn't be empty");
|
||||
|
||||
if (!isset($_SESSION['prepared_login_da']['attempts']))
|
||||
$_SESSION['prepared_login_da']['attempts'] = 0;
|
||||
$_SESSION['prepared_login_da']['attempts']++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Expired login
|
||||
unset ($_SESSION['prepared_login_da']);
|
||||
|
||||
// Error message
|
||||
$config["auth_error"] = __('Expired login');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If the code doesn't exist, remove the prepared login
|
||||
unset ($_SESSION['prepared_login_da']);
|
||||
|
||||
// Error message
|
||||
$config["auth_error"] = __('Login error');
|
||||
}
|
||||
}
|
||||
// If $_SESSION['prepared_login_da'] doesn't exist, the user have to do the login again
|
||||
else {
|
||||
// Error message
|
||||
$config["auth_error"] = __('Login error');
|
||||
}
|
||||
|
||||
// Remove the authenticator code
|
||||
unset ($_POST['auth_code'], $code);
|
||||
|
||||
if (!$double_auth_success) {
|
||||
$login_failed = true;
|
||||
require_once ('general/login_page.php');
|
||||
db_pandora_audit("Logon Failed", "Invalid double auth login: "
|
||||
.$_SERVER['REMOTE_ADDR'], $_SERVER['REMOTE_ADDR']);
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
}
|
||||
|
||||
//Checks if password has expired
|
||||
$check_status = check_pass_status($nick, $pass);
|
||||
|
||||
switch ($check_status) {
|
||||
case PASSSWORD_POLICIES_FIRST_CHANGE: //first change
|
||||
case PASSSWORD_POLICIES_EXPIRED: //pass expired
|
||||
$expired_pass = true;
|
||||
login_change_password($nick);
|
||||
break;
|
||||
if (isset ($double_auth_success) && $double_auth_success) {
|
||||
// This values are true cause there are checked before complete the 2nd auth step
|
||||
$nick_in_db = $_SESSION["prepared_login_da"]['id_user'];
|
||||
$expired_pass = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (($nick_in_db !== false) && $expired_pass) {
|
||||
//login ok and password has expired
|
||||
|
||||
require_once ('general/login_page.php');
|
||||
db_pandora_audit("Password expired",
|
||||
"Password expired: " . $nick, $nick);
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
else if (($nick_in_db !== false) && (!$expired_pass)) {
|
||||
//login ok and password has not expired
|
||||
$process_login = true;
|
||||
|
||||
echo "<script type='text/javascript'>var process_login_ok = 1;</script>";
|
||||
|
||||
unset ($_GET["sec2"]);
|
||||
$_GET["sec"] = "general/logon_ok";
|
||||
$home_page ='';
|
||||
if (isset($nick)) {
|
||||
$user_info = users_get_user_by_id($nick);
|
||||
$home_page = io_safe_output($user_info['section']);
|
||||
$home_url = $user_info['data_section'];
|
||||
if ($home_page != '') {
|
||||
switch($home_page) {
|
||||
case 'Event list':
|
||||
$_GET["sec"] = "eventos";
|
||||
$_GET["sec2"] = "operation/events/events";
|
||||
break;
|
||||
case 'Group view':
|
||||
$_GET["sec"] = "estado";
|
||||
$_GET["sec2"] = "operation/agentes/group_view";
|
||||
break;
|
||||
case 'Alert detail':
|
||||
$_GET["sec"] = "estado";
|
||||
$_GET["sec2"] = "operation/agentes/alerts_status";
|
||||
break;
|
||||
case 'Tactical view':
|
||||
$_GET["sec"] = "estado";
|
||||
$_GET["sec2"] = "operation/agentes/tactical";
|
||||
break;
|
||||
case 'Default':
|
||||
$_GET["sec"] = "general/logon_ok";
|
||||
break;
|
||||
case 'Dashboard':
|
||||
$_GET["sec"] = "dashboard";
|
||||
$_GET["sec2"] = ENTERPRISE_DIR.'/dashboard/main_dashboard';
|
||||
break;
|
||||
case 'Visual console':
|
||||
$_GET["sec"] = "visualc";
|
||||
$_GET["sec2"] = "operation/visual_console/index";
|
||||
break;
|
||||
case 'Other':
|
||||
$home_url = io_safe_output($home_url);
|
||||
parse_str ($home_url, $res);
|
||||
$_GET["sec"] = $res["sec"];
|
||||
$_GET["sec2"] = $res["sec2"];
|
||||
else {
|
||||
// process_user_login is a virtual function which should be defined in each auth file.
|
||||
// It accepts username and password. The rest should be internal to the auth file.
|
||||
// The auth file can set $config["auth_error"] to an informative error output or reference their internal error messages to it
|
||||
// process_user_login should return false in case of errors or invalid login, the nickname if correct
|
||||
$nick_in_db = process_user_login ($nick, $pass);
|
||||
|
||||
$expired_pass = false;
|
||||
|
||||
if (($nick_in_db != false) && ((!is_user_admin($nick)
|
||||
|| $config['enable_pass_policy_admin']))
|
||||
&& (defined('PANDORA_ENTERPRISE'))
|
||||
&& ($config['enable_pass_policy'])) {
|
||||
include_once(ENTERPRISE_DIR . "/include/auth/mysql.php");
|
||||
|
||||
$blocked = login_check_blocked($nick);
|
||||
|
||||
if ($blocked) {
|
||||
require_once ('general/login_page.php');
|
||||
db_pandora_audit("Password expired", "Password expired: ".$nick, $nick);
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
|
||||
//Checks if password has expired
|
||||
$check_status = check_pass_status($nick, $pass);
|
||||
|
||||
switch ($check_status) {
|
||||
case PASSSWORD_POLICIES_FIRST_CHANGE: //first change
|
||||
case PASSSWORD_POLICIES_EXPIRED: //pass expired
|
||||
$expired_pass = true;
|
||||
login_change_password($nick);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$_GET["sec"] = "general/logon_ok";
|
||||
}
|
||||
}
|
||||
db_logon ($nick_in_db, $_SERVER['REMOTE_ADDR']);
|
||||
$_SESSION['id_usuario'] = $nick_in_db;
|
||||
$config['id_user'] = $nick_in_db;
|
||||
//Remove everything that might have to do with people's passwords or logins
|
||||
unset ($_GET['pass'], $pass, $_POST['pass'], $_REQUEST['pass'], $login_good);
|
||||
|
||||
$user_language = get_user_language($config['id_user']);
|
||||
|
||||
$l10n = NULL;
|
||||
if (file_exists ('./include/languages/' . $user_language . '.mo')) {
|
||||
$l10n = new gettext_reader (new CachedFileReader ('./include/languages/'.$user_language.'.mo'));
|
||||
$l10n->load_tables();
|
||||
}
|
||||
}
|
||||
else { //login wrong
|
||||
$blocked = false;
|
||||
|
||||
if ((!is_user_admin($nick) || $config['enable_pass_policy_admin']) && defined('PANDORA_ENTERPRISE')) {
|
||||
$blocked = login_check_blocked($nick);
|
||||
}
|
||||
|
||||
if (!$blocked) {
|
||||
if (defined('PANDORA_ENTERPRISE')) {
|
||||
login_check_failed($nick); //Checks failed attempts
|
||||
}
|
||||
$login_failed = true;
|
||||
if (($nick_in_db !== false) && $expired_pass) {
|
||||
//login ok and password has expired
|
||||
|
||||
require_once ('general/login_page.php');
|
||||
db_pandora_audit("Logon Failed", "Invalid login: ".$nick, $nick);
|
||||
db_pandora_audit("Password expired",
|
||||
"Password expired: " . $nick, $nick);
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
else if (($nick_in_db !== false) && (!$expired_pass)) {
|
||||
//login ok and password has not expired
|
||||
|
||||
// Double auth check
|
||||
if ((!isset ($double_auth_success) || !$double_auth_success) && is_double_auth_enabled($nick_in_db)) {
|
||||
// Store this values in the session to know if the user login was correct
|
||||
$_SESSION['prepared_login_da'] = array(
|
||||
'id_user' => $nick_in_db,
|
||||
'timestamp' => time(),
|
||||
'attempts' => 0
|
||||
);
|
||||
|
||||
// Load the page to introduce the double auth code
|
||||
$login_screen = 'double_auth';
|
||||
require_once ('general/login_page.php');
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
|
||||
//login ok and password has not expired
|
||||
$process_login = true;
|
||||
|
||||
echo "<script type='text/javascript'>var process_login_ok = 1;</script>";
|
||||
|
||||
unset ($_GET["sec2"]);
|
||||
$_GET["sec"] = "general/logon_ok";
|
||||
$home_page ='';
|
||||
if (isset($nick)) {
|
||||
$user_info = users_get_user_by_id($nick);
|
||||
$home_page = io_safe_output($user_info['section']);
|
||||
$home_url = $user_info['data_section'];
|
||||
if ($home_page != '') {
|
||||
switch($home_page) {
|
||||
case 'Event list':
|
||||
$_GET["sec"] = "eventos";
|
||||
$_GET["sec2"] = "operation/events/events";
|
||||
break;
|
||||
case 'Group view':
|
||||
$_GET["sec"] = "estado";
|
||||
$_GET["sec2"] = "operation/agentes/group_view";
|
||||
break;
|
||||
case 'Alert detail':
|
||||
$_GET["sec"] = "estado";
|
||||
$_GET["sec2"] = "operation/agentes/alerts_status";
|
||||
break;
|
||||
case 'Tactical view':
|
||||
$_GET["sec"] = "estado";
|
||||
$_GET["sec2"] = "operation/agentes/tactical";
|
||||
break;
|
||||
case 'Default':
|
||||
$_GET["sec"] = "general/logon_ok";
|
||||
break;
|
||||
case 'Dashboard':
|
||||
$_GET["sec"] = "dashboard";
|
||||
$_GET["sec2"] = ENTERPRISE_DIR.'/dashboard/main_dashboard';
|
||||
break;
|
||||
case 'Visual console':
|
||||
$_GET["sec"] = "visualc";
|
||||
$_GET["sec2"] = "operation/visual_console/index";
|
||||
break;
|
||||
case 'Other':
|
||||
$home_url = io_safe_output($home_url);
|
||||
parse_str ($home_url, $res);
|
||||
$_GET["sec"] = $res["sec"];
|
||||
$_GET["sec2"] = $res["sec2"];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$_GET["sec"] = "general/logon_ok";
|
||||
}
|
||||
}
|
||||
db_logon ($nick_in_db, $_SERVER['REMOTE_ADDR']);
|
||||
$_SESSION['id_usuario'] = $nick_in_db;
|
||||
$config['id_user'] = $nick_in_db;
|
||||
//Remove everything that might have to do with people's passwords or logins
|
||||
unset ($pass, $login_good);
|
||||
|
||||
$user_language = get_user_language($config['id_user']);
|
||||
|
||||
$l10n = NULL;
|
||||
if (file_exists ('./include/languages/' . $user_language . '.mo')) {
|
||||
$l10n = new gettext_reader (new CachedFileReader ('./include/languages/'.$user_language.'.mo'));
|
||||
$l10n->load_tables();
|
||||
}
|
||||
}
|
||||
else { //login wrong
|
||||
$blocked = false;
|
||||
|
||||
if ((!is_user_admin($nick) || $config['enable_pass_policy_admin']) && defined('PANDORA_ENTERPRISE')) {
|
||||
$blocked = login_check_blocked($nick);
|
||||
}
|
||||
|
||||
if (!$blocked) {
|
||||
if (defined('PANDORA_ENTERPRISE')) {
|
||||
login_check_failed($nick); //Checks failed attempts
|
||||
}
|
||||
$login_failed = true;
|
||||
require_once ('general/login_page.php');
|
||||
db_pandora_audit("Logon Failed", "Invalid login: ".$nick, $nick);
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
else {
|
||||
require_once ('general/login_page.php');
|
||||
db_pandora_audit("Logon Failed", "Invalid login: ".$nick, $nick);
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Hash login process
|
||||
elseif (isset ($_GET["loginhash"])) {
|
||||
$loginhash_data = get_parameter("loginhash_data", "");
|
||||
$loginhash_user = str_rot13(get_parameter("loginhash_user", ""));
|
||||
|
||||
if ($config["loginhash_pwd"] != "" && $loginhash_data == md5($loginhash_user.$config["loginhash_pwd"])) {
|
||||
db_logon ($loginhash_user, $_SERVER['REMOTE_ADDR']);
|
||||
$_SESSION['id_usuario'] = $loginhash_user;
|
||||
$config["id_user"] = $loginhash_user;
|
||||
}
|
||||
else {
|
||||
require_once ('general/login_page.php');
|
||||
db_pandora_audit("Logon Failed", "Invalid login: ".$nick, $nick);
|
||||
db_pandora_audit("Logon Failed (loginhash", "", "system");
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Hash login process
|
||||
elseif (! isset ($config['id_user']) && isset ($_GET["loginhash"])) {
|
||||
$loginhash_data = get_parameter("loginhash_data", "");
|
||||
$loginhash_user = str_rot13(get_parameter("loginhash_user", ""));
|
||||
|
||||
if ($config["loginhash_pwd"] != "" && $loginhash_data == md5($loginhash_user.$config["loginhash_pwd"])) {
|
||||
db_logon ($loginhash_user, $_SERVER['REMOTE_ADDR']);
|
||||
$_SESSION['id_usuario'] = $loginhash_user;
|
||||
$config["id_user"] = $loginhash_user;
|
||||
}
|
||||
// There is no user connected
|
||||
else {
|
||||
require_once ('general/login_page.php');
|
||||
db_pandora_audit("Logon Failed (loginhash", "", "system");
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
}
|
||||
// There is no user connected
|
||||
elseif (! isset ($config['id_user'])) {
|
||||
require_once ('general/login_page.php');
|
||||
while (@ob_end_flush ());
|
||||
exit ("</html>");
|
||||
}
|
||||
|
||||
// Log off
|
||||
if (isset ($_GET["bye"])) {
|
||||
|
|
|
@ -19,22 +19,12 @@ class User {
|
|||
private $user;
|
||||
private $logged = false;
|
||||
private $errorLogin = false;
|
||||
private $loginTime = false;
|
||||
private $logout_action = false;
|
||||
private $needDoubleAuth = false;
|
||||
private $errorDoubleAuth = false;
|
||||
|
||||
public function __construct($user = null, $password = null) {
|
||||
$this->user = $user;
|
||||
$this->errorLogin = false;
|
||||
|
||||
if (process_user_login($this->user, $password)) {
|
||||
$this->logged = true;
|
||||
$this->hackInjectConfig();
|
||||
}
|
||||
else {
|
||||
$this->logged = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getInstance() {
|
||||
public static function getInstance () {
|
||||
if (!(self::$instance instanceof self)) {
|
||||
//Check if in the session
|
||||
$system = System::getInstance();
|
||||
|
@ -51,22 +41,22 @@ class User {
|
|||
return self::$instance;
|
||||
}
|
||||
|
||||
public function hackInjectConfig() {
|
||||
//hack to compatibility with pandora
|
||||
public function saveLogin () {
|
||||
|
||||
if ($this->logged) {
|
||||
global $config;
|
||||
|
||||
$system = System::getInstance();
|
||||
|
||||
$config['id_user'] = $this->user;
|
||||
|
||||
$system->setSessionBase('id_usuario', $this->user);
|
||||
$system->setSession('user', $this);
|
||||
|
||||
if (!$this->needDoubleAuth) {
|
||||
//hack to compatibility with pandora
|
||||
global $config;
|
||||
$config['id_user'] = $this->user;
|
||||
$system->setSessionBase('id_usuario', $this->user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function isLogged() {
|
||||
public function isLogged () {
|
||||
$system = System::getInstance();
|
||||
|
||||
$autologin = $system->getRequest('autologin', false);
|
||||
|
@ -74,15 +64,13 @@ class User {
|
|||
$user = $system->getRequest('user', null);
|
||||
$password = $system->getRequest('password', null);
|
||||
|
||||
if ($this->checkLogin($user, $password)) {
|
||||
$this->hackInjectConfig();
|
||||
}
|
||||
$this->login($user, $password);
|
||||
}
|
||||
|
||||
return $this->logged;
|
||||
}
|
||||
|
||||
public function checkLogin($user = null, $password = null) {
|
||||
|
||||
public function login ($user = null, $password = null) {
|
||||
$system = System::getInstance();
|
||||
|
||||
if (($user == null) && ($password == null)) {
|
||||
|
@ -92,44 +80,126 @@ class User {
|
|||
}
|
||||
|
||||
if (!empty($user) && !empty($password)) {
|
||||
if (process_user_login($user, $password) !== false) {
|
||||
$user_in_db = process_user_login($user, $password);
|
||||
if ($user_in_db !== false) {
|
||||
|
||||
$this->logged = true;
|
||||
$this->user = $user;
|
||||
$this->user = $user_in_db;
|
||||
$this->loginTime = time();
|
||||
$this->errorLogin = false;
|
||||
|
||||
// The user login was successful, but the second step is not completed
|
||||
if ($this->isDobleAuthRequired()) {
|
||||
$this->needDoubleAuth = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
$this->logged = false;
|
||||
$this->loginTime = false;
|
||||
$this->errorLogin = true;
|
||||
$this->needDoubleAuth = false;
|
||||
$this->errorDoubleAuth = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->logged) {
|
||||
$this->hackInjectConfig();
|
||||
|
||||
if (! check_acl($system->getConfig('id_user'), 0, "AR")) {
|
||||
db_pandora_audit("ACL Violation",
|
||||
"Trying to access Agent Data view");
|
||||
require ("../general/noaccess.php");
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->saveLogin();
|
||||
|
||||
return $this->logged;
|
||||
}
|
||||
|
||||
public function logout() {
|
||||
$this->user = null;
|
||||
$this->logged = false;
|
||||
$this->errorLogin = false;
|
||||
$this->logout_action = true;
|
||||
|
||||
$system = System::getInstance();
|
||||
$system->setSession('user', null);
|
||||
|
||||
public function getLoginTime () {
|
||||
return $this->loginTime;
|
||||
}
|
||||
|
||||
public function showLogin() {
|
||||
public function isWaitingDoubleAuth () {
|
||||
return $this->needDoubleAuth;
|
||||
}
|
||||
|
||||
public function isDobleAuthRequired ($user = false) {
|
||||
if (empty($user) && !empty($this->user))
|
||||
$user = $this->user;
|
||||
|
||||
if (!empty($user))
|
||||
return (bool) db_get_value('id', 'tuser_double_auth', 'id_user', $user);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public function validateDoubleAuthCode ($user = null, $code = null) {
|
||||
|
||||
if (!$this->needDoubleAuth) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$system = System::getInstance();
|
||||
require_once ($system->getConfig('homedir').'/include/auth/GAuth/Auth.php');
|
||||
|
||||
$result = false;
|
||||
|
||||
if (empty($user)) {
|
||||
$user = $this->user;
|
||||
}
|
||||
if (empty($code)) {
|
||||
$code = $system->getRequest('auth_code', null);
|
||||
}
|
||||
|
||||
if (!empty($user) && !empty($code)) {
|
||||
$secret = db_get_value('secret', 'tuser_double_auth', 'id_user', $user);
|
||||
|
||||
if ($secret === false) {
|
||||
$result = false;
|
||||
$this->errorDoubleAuth = array(
|
||||
'title_text' => __('Double authentication failed'),
|
||||
'content_text' => __('Secret code not found') .". "
|
||||
.__('Please contact the administrator to reset your double authentication')
|
||||
);
|
||||
}
|
||||
else if (!empty($secret)) {
|
||||
try {
|
||||
$gAuth = new \GAuth\Auth($secret);
|
||||
$result = $gAuth->validateCode($code);
|
||||
|
||||
// Double auth success
|
||||
if ($result) {
|
||||
$this->needDoubleAuth = false;
|
||||
$this->saveLogin();
|
||||
}
|
||||
else {
|
||||
$result = false;
|
||||
$this->errorDoubleAuth = array(
|
||||
'title_text' => __('Double authentication failed'),
|
||||
'content_text' => __('Invalid code')
|
||||
);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$result = false;
|
||||
$this->errorDoubleAuth = array(
|
||||
'title_text' => __('Double authentication failed'),
|
||||
'content_text' => __('There was an error checking the code')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function logout () {
|
||||
$this->user = null;
|
||||
$this->logged = false;
|
||||
$this->loginTime = false;
|
||||
$this->errorLogin = false;
|
||||
$this->logout_action = true;
|
||||
$this->needDoubleAuth = false;
|
||||
$this->errorDoubleAuth = false;
|
||||
|
||||
$system = System::getInstance();
|
||||
$system->setSession('user', null);
|
||||
$system->sessionDestroy();
|
||||
}
|
||||
|
||||
public function showLoginPage () {
|
||||
global $pandora_version;
|
||||
|
||||
$ui = Ui::getInstance();
|
||||
|
@ -191,16 +261,65 @@ class User {
|
|||
$this->errorLogin = false;
|
||||
$this->logout_action = false;
|
||||
}
|
||||
|
||||
public function getIdUser() {
|
||||
|
||||
public function showDoubleAuthPage () {
|
||||
global $pandora_version;
|
||||
|
||||
$ui = Ui::getInstance();
|
||||
|
||||
$ui->createPage();
|
||||
if (!empty($this->errorDoubleAuth)) {
|
||||
$options['type'] = 'onStart';
|
||||
$options['title_text'] = $this->errorDoubleAuth['title_text'];
|
||||
$options['content_text'] = $this->errorDoubleAuth['content_text'] . "<br>";
|
||||
$ui->addDialog($options);
|
||||
}
|
||||
$left_button = $ui->createHeaderButton(
|
||||
array('icon' => 'back',
|
||||
'pos' => 'left',
|
||||
'text' => __('Logout'),
|
||||
'href' => 'index.php?action=logout'));
|
||||
$ui->createHeader('', $left_button);
|
||||
$ui->showFooter(false);
|
||||
$ui->beginContent();
|
||||
$ui->contentAddHtml('<div style="text-align: center;" class="login_logo">' .
|
||||
html_print_image ("mobile/images/pandora_mobile_console.png",
|
||||
true, array ("alt" => "logo", "border" => 0)) .
|
||||
'</div>');
|
||||
$ui->contentAddHtml('<div id="login_container">');
|
||||
$ui->beginForm();
|
||||
$ui->formAddHtml(html_print_input_hidden('action', 'double_auth', true));
|
||||
$options = array(
|
||||
'name' => 'auth_code',
|
||||
'value' => '',
|
||||
'placeholder' => __('Authenticator code'),
|
||||
'label' => __('Authenticator code')
|
||||
);
|
||||
$ui->formAddInputPassword($options);
|
||||
$options = array(
|
||||
'value' => __('Check code'),
|
||||
'icon' => 'arrow-r',
|
||||
'icon_pos' => 'right',
|
||||
'name' => 'auth_code_btn'
|
||||
);
|
||||
$ui->formAddSubmitButton($options);
|
||||
$ui->endForm();
|
||||
$ui->contentAddHtml('</div>');
|
||||
$ui->endContent();
|
||||
$ui->showPage();
|
||||
|
||||
$this->errorDoubleAuth = false;
|
||||
}
|
||||
|
||||
public function getIdUser () {
|
||||
return $this->user; //Oldies methods
|
||||
}
|
||||
|
||||
public function isInGroup($access = "AR", $id_group = 0, $name_group = false) {
|
||||
public function isInGroup ($access = "AR", $id_group = 0, $name_group = false) {
|
||||
return (bool)check_acl($this->user, $id_group, $access);
|
||||
}
|
||||
|
||||
public function getIdGroups($access = "AR", $all = false) {
|
||||
public function getIdGroups ($access = "AR", $all = false) {
|
||||
return array_keys(users_get_groups($this->user, $access, $all));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,13 +43,32 @@ $enterpriseHook = enterprise_include('mobile/operation/home.php');
|
|||
|
||||
$system = System::getInstance();
|
||||
|
||||
require_once($system->getConfig('homedir').'/include/constants.php');
|
||||
|
||||
$user = User::getInstance();
|
||||
$user->hackInjectConfig();
|
||||
$user->saveLogin();
|
||||
|
||||
$page = $system->getRequest('page', 'home');
|
||||
$action = $system->getRequest('action');
|
||||
if (!$user->isLogged()) {
|
||||
$action = 'login';
|
||||
|
||||
// The logout action has priority
|
||||
if ($action != 'logout') {
|
||||
if (!$user->isLogged()) {
|
||||
$action = 'login';
|
||||
}
|
||||
else if ($user->isWaitingDoubleAuth()) {
|
||||
$dauth_period = SECONDS_2MINUTES;
|
||||
$now = time();
|
||||
$dauth_time = $user->getLoginTime();
|
||||
|
||||
if ($now - $dauth_period < $dauth_time) {
|
||||
$action = 'double_auth';
|
||||
}
|
||||
// Expired login
|
||||
else {
|
||||
$action = 'logout';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($action != "ajax") {
|
||||
|
@ -107,11 +126,45 @@ switch ($action) {
|
|||
return;
|
||||
break;
|
||||
case 'login':
|
||||
if (!$user->checkLogin()) {
|
||||
$user->showLogin();
|
||||
if ($user->login() && $user->isLogged()) {
|
||||
if ($user->isWaitingDoubleAuth()) {
|
||||
if ($user->validateDoubleAuthCode()) {
|
||||
$user_language = get_user_language ($system->getConfig('id_user'));
|
||||
if (file_exists ('../include/languages/'.$user_language.'.mo')) {
|
||||
$l10n = new gettext_reader (new CachedFileReader('../include/languages/'.$user_language.'.mo'));
|
||||
$l10n->load_tables();
|
||||
}
|
||||
if (class_exists("HomeEnterprise"))
|
||||
$home = new HomeEnterprise();
|
||||
else
|
||||
$home = new Home();
|
||||
$home->show();
|
||||
}
|
||||
else {
|
||||
$user->showDoubleAuthPage();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$user_language = get_user_language ($system->getConfig('id_user'));
|
||||
if (file_exists ('../include/languages/'.$user_language.'.mo')) {
|
||||
$l10n = new gettext_reader (new CachedFileReader('../include/languages/'.$user_language.'.mo'));
|
||||
$l10n->load_tables();
|
||||
}
|
||||
if (class_exists("HomeEnterprise"))
|
||||
$home = new HomeEnterprise();
|
||||
else
|
||||
$home = new Home();
|
||||
$home->show();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
if ($user->isLogged()) {
|
||||
$user->showLoginPage();
|
||||
}
|
||||
break;
|
||||
case 'double_auth':
|
||||
if ($user->isLogged()) {
|
||||
if ($user->validateDoubleAuthCode()) {
|
||||
$user_language = get_user_language ($system->getConfig('id_user'));
|
||||
if (file_exists ('../include/languages/'.$user_language.'.mo')) {
|
||||
$l10n = new gettext_reader (new CachedFileReader('../include/languages/'.$user_language.'.mo'));
|
||||
|
@ -124,13 +177,16 @@ switch ($action) {
|
|||
$home->show();
|
||||
}
|
||||
else {
|
||||
$user->showLoginFail();
|
||||
$user->showDoubleAuthPage();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$user->showLoginPage();
|
||||
}
|
||||
break;
|
||||
case 'logout':
|
||||
$user->logout();
|
||||
$user->showLogin();
|
||||
$user->showLoginPage();
|
||||
break;
|
||||
default:
|
||||
if (class_exists("Enterprise")) {
|
||||
|
|
|
@ -337,6 +337,23 @@ if (!$meta) {
|
|||
$table->data[] = $data;
|
||||
}
|
||||
|
||||
// Double auth
|
||||
$double_auth_enabled = (bool) db_get_value('id', 'tuser_double_auth', 'id_user', $config['id_user']);
|
||||
$data = array();
|
||||
$data[0] = __('Double authentication');
|
||||
$data[0] .= '<br>';
|
||||
$data[0] .= html_print_checkbox('double_auth', 1, $double_auth_enabled, true);
|
||||
if ($double_auth_enabled) {
|
||||
$data[0] .= ' ';
|
||||
$data[0] .= html_print_button(__('Show information'), 'show_info', false, 'javascript:show_double_auth_info();', '', true);
|
||||
}
|
||||
// Dialog
|
||||
$data[0] .= "<div id=\"dialog-double_auth\"><div id=\"dialog-double_auth-container\"></div></div>";
|
||||
$table->colspan[count($table->data)][0] = 3;
|
||||
$table->rowclass[] = '';
|
||||
$table->rowstyle[] = 'font-weight: bold;';
|
||||
$table->data[] = $data;
|
||||
|
||||
$data = array();
|
||||
$data[0] = __('Comments');
|
||||
$table->colspan[count($table->data)][0] = 3;
|
||||
|
@ -431,6 +448,17 @@ $(document).ready (function () {
|
|||
$("#text-block_size").removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
$("input#checkbox-double_auth").change(function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.checked) {
|
||||
show_double_auth_activation();
|
||||
}
|
||||
else {
|
||||
show_double_auth_deactivation();
|
||||
}
|
||||
});
|
||||
|
||||
show_data_section();
|
||||
});
|
||||
|
@ -481,4 +509,209 @@ function show_data_section () {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function show_double_auth_info () {
|
||||
var userID = "<?php echo $config['id_user']; ?>";
|
||||
|
||||
var $loadingSpinner = $("<img src=\"<?php echo $config['homeurl']; ?>/images/spinner.gif\" />");
|
||||
var $dialogContainer = $("div#dialog-double_auth-container");
|
||||
|
||||
$dialogContainer.html($loadingSpinner);
|
||||
|
||||
// Load the info page
|
||||
var request = $.ajax({
|
||||
url: "<?php echo ui_get_full_url('ajax.php', false, false, false); ?>",
|
||||
type: 'POST',
|
||||
dataType: 'html',
|
||||
data: {
|
||||
page: 'include/ajax/double_auth.ajax',
|
||||
id_user: userID,
|
||||
get_double_auth_data_page: 1,
|
||||
containerID: $dialogContainer.prop('id')
|
||||
},
|
||||
complete: function(xhr, textStatus) {
|
||||
|
||||
},
|
||||
success: function(data, textStatus, xhr) {
|
||||
// isNaN = is not a number
|
||||
if (isNaN(data)) {
|
||||
$dialogContainer.html(data);
|
||||
}
|
||||
// data is a number, convert it to integer to do the compare
|
||||
else if (Number(data) === -1) {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"red\">' . __('Authentication error') . '</div></b>'; ?>");
|
||||
}
|
||||
else {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"red\">' . __('Error') . '</div></b>'; ?>");
|
||||
}
|
||||
},
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"red\">' . __('There was an error loading the data') . '</div></b>'; ?>");
|
||||
}
|
||||
});
|
||||
|
||||
$("div#dialog-double_auth")
|
||||
.append($dialogContainer)
|
||||
.dialog({
|
||||
resizable: true,
|
||||
draggable: true,
|
||||
modal: true,
|
||||
title: "<?php echo __('Double autentication information'); ?>",
|
||||
overlay: {
|
||||
opacity: 0.5,
|
||||
background: "black"
|
||||
},
|
||||
width: 400,
|
||||
height: 375,
|
||||
close: function(event, ui) {
|
||||
// Abort the ajax request
|
||||
if (typeof request != 'undefined')
|
||||
request.abort();
|
||||
// Remove the contained html
|
||||
$dialogContainer.empty();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
|
||||
}
|
||||
|
||||
function show_double_auth_activation () {
|
||||
var userID = "<?php echo $config['id_user']; ?>";
|
||||
|
||||
var $loadingSpinner = $("<img src=\"<?php echo $config['homeurl']; ?>/images/spinner.gif\" />");
|
||||
var $dialogContainer = $("div#dialog-double_auth-container");
|
||||
|
||||
$dialogContainer.html($loadingSpinner);
|
||||
|
||||
// Load the info page
|
||||
var request = $.ajax({
|
||||
url: "<?php echo ui_get_full_url('ajax.php', false, false, false); ?>",
|
||||
type: 'POST',
|
||||
dataType: 'html',
|
||||
data: {
|
||||
page: 'include/ajax/double_auth.ajax',
|
||||
id_user: userID,
|
||||
get_double_auth_info_page: 1,
|
||||
containerID: $dialogContainer.prop('id')
|
||||
},
|
||||
complete: function(xhr, textStatus) {
|
||||
|
||||
},
|
||||
success: function(data, textStatus, xhr) {
|
||||
// isNaN = is not a number
|
||||
if (isNaN(data)) {
|
||||
$dialogContainer.html(data);
|
||||
}
|
||||
// data is a number, convert it to integer to do the compare
|
||||
else if (Number(data) === -1) {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"red\">' . __('Authentication error') . '</div></b>'; ?>");
|
||||
}
|
||||
else {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"red\">' . __('Error') . '</div></b>'; ?>");
|
||||
}
|
||||
},
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"red\">' . __('There was an error loading the data') . '</div></b>'; ?>");
|
||||
}
|
||||
});
|
||||
|
||||
$("div#dialog-double_auth").dialog({
|
||||
resizable: true,
|
||||
draggable: true,
|
||||
modal: true,
|
||||
title: "<?php echo __('Double autentication activation'); ?>",
|
||||
overlay: {
|
||||
opacity: 0.5,
|
||||
background: "black"
|
||||
},
|
||||
width: 500,
|
||||
height: 400,
|
||||
close: function(event, ui) {
|
||||
// Abort the ajax request
|
||||
if (typeof request != 'undefined')
|
||||
request.abort();
|
||||
// Remove the contained html
|
||||
$dialogContainer.empty();
|
||||
|
||||
document.location.reload();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
function show_double_auth_deactivation () {
|
||||
var userID = "<?php echo $config['id_user']; ?>";
|
||||
|
||||
var $loadingSpinner = $("<img src=\"<?php echo $config['homeurl']; ?>/images/spinner.gif\" />");
|
||||
var $dialogContainer = $("div#dialog-double_auth-container");
|
||||
|
||||
var message = "<p><?php echo __('Are you sure?') . '<br>' . __('The double authentication will be deactivated'); ?></p>";
|
||||
var $button = $("<input type=\"button\" value=\"<?php echo __('Deactivate'); ?>\" />");
|
||||
|
||||
$dialogContainer
|
||||
.empty()
|
||||
.append(message)
|
||||
.append($button);
|
||||
|
||||
var request;
|
||||
|
||||
$button.click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
$dialogContainer.html($loadingSpinner);
|
||||
|
||||
// Deactivate the double auth
|
||||
request = $.ajax({
|
||||
url: "<?php echo ui_get_full_url('ajax.php', false, false, false); ?>",
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
page: 'include/ajax/double_auth.ajax',
|
||||
id_user: userID,
|
||||
deactivate_double_auth: 1
|
||||
},
|
||||
complete: function(xhr, textStatus) {
|
||||
|
||||
},
|
||||
success: function(data, textStatus, xhr) {
|
||||
if (data === -1) {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"red\">' . __('Authentication error') . '</div></b>'; ?>");
|
||||
}
|
||||
else if (data) {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"green\">' . __('The double autentication was deactivated successfully') . '</div></b>'; ?>");
|
||||
}
|
||||
else {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"red\">' . __('There was an error deactivating the double autentication') . '</div></b>'; ?>");
|
||||
}
|
||||
},
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
$dialogContainer.html("<?php echo '<b><div class=\"red\">' . __('There was an error deactivating the double autentication') . '</div></b>'; ?>");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$("div#dialog-double_auth").dialog({
|
||||
resizable: true,
|
||||
draggable: true,
|
||||
modal: true,
|
||||
title: "<?php echo __('Double autentication activation'); ?>",
|
||||
overlay: {
|
||||
opacity: 0.5,
|
||||
background: "black"
|
||||
},
|
||||
width: 300,
|
||||
height: 150,
|
||||
close: function(event, ui) {
|
||||
// Abort the ajax request
|
||||
if (typeof request != 'undefined')
|
||||
request.abort();
|
||||
// Remove the contained html
|
||||
$dialogContainer.empty();
|
||||
|
||||
document.location.reload();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1047,6 +1047,17 @@ CREATE TABLE tusuario_perfil (
|
|||
CREATE SEQUENCE tusuario_perfil_s INCREMENT BY 1 START WITH 1;
|
||||
CREATE OR REPLACE TRIGGER tusuario_perfil_inc BEFORE INSERT ON tusuario_perfil REFERENCING NEW AS NEW FOR EACH ROW BEGIN SELECT tusuario_perfil_s.nextval INTO :NEW.ID_UP FROM dual; END tusuario_perfil_inc;;
|
||||
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Table `tuser_double_auth`
|
||||
-- ----------------------------------------------------------------------
|
||||
CREATE TABLE tuser_double_auth (
|
||||
id NUMBER(10, 0) NOT NULL PRIMARY KEY,
|
||||
id_user VARCHAR2(60) NOT NULL REFERENCES tusuario(id_user) ON DELETE CASCADE,
|
||||
secret VARCHAR2(20) NOT NULL
|
||||
);
|
||||
CREATE SEQUENCE tuser_double_auth_s INCREMENT BY 1 START WITH 1;
|
||||
CREATE OR REPLACE TRIGGER tuser_double_auth_inc BEFORE INSERT ON tuser_double_auth REFERENCING NEW AS NEW FOR EACH ROW BEGIN SELECT tuser_double_auth_s.nextval INTO :NEW.ID FROM dual; END tuser_double_auth_inc;;
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- Table "tnews"
|
||||
-- ---------------------------------------------------------------------
|
||||
|
|
|
@ -926,6 +926,15 @@ CREATE TABLE "tusuario_perfil" (
|
|||
"tags" text NOT NULL
|
||||
);
|
||||
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Table `tuser_double_auth`
|
||||
-- ----------------------------------------------------------------------
|
||||
CREATE TABLE "tuser_double_auth" (
|
||||
"id" SERIAL NOT NULL PRIMARY KEY,
|
||||
"id_user" varchar(60) NOT NULL UNIQUE REFERENCES "tusuario"("id_user") ON DELETE CASCADE,
|
||||
"secret" varchar(20) NOT NULL
|
||||
);
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `tnews`
|
||||
-- -----------------------------------------------------
|
||||
|
|
|
@ -999,6 +999,18 @@ CREATE TABLE IF NOT EXISTS `tusuario_perfil` (
|
|||
PRIMARY KEY (`id_up`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Table `tuser_double_auth`
|
||||
-- ----------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `tuser_double_auth` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`id_user` varchar(60) NOT NULL,
|
||||
`secret` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (`id_user`),
|
||||
FOREIGN KEY (`id_user`) REFERENCES tusuario(`id_user`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Table `tnews`
|
||||
-- ----------------------------------------------------------------------
|
||||
|
|
|
@ -154,6 +154,7 @@ sub help_screen{
|
|||
help_screen_line('--add_profile_to_user', '<user_id> <profile_name> [<group_name>]', 'Add a profile in group to a user');
|
||||
help_screen_line('--disable_eacl', '', 'Disable enterprise ACL system');
|
||||
help_screen_line('--enable_eacl', '', 'Enable enterprise ACL system');
|
||||
help_screen_line('--disable_double_auth', '<user_name>', 'Disable the double authentication for the specified user');
|
||||
print "\nEVENTS:\n\n" unless $param ne '';
|
||||
help_screen_line('--create_event', "<event> <event_type> <group_name> [<agent_name> <module_name>\n\t <event_status> <severity> <template_name> <user_name> <comment> \n\t <source> <id_extra> <tags> <custom_data_json>]", 'Add event');
|
||||
help_screen_line('--validate_event', "<agent_name> <module_name> <datetime_min> <datetime_max>\n\t <user_name> <criticity> <template_name>", 'Validate events');
|
||||
|
@ -3362,6 +3363,23 @@ sub cli_enable_eacl ($$) {
|
|||
exit;
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Disable double authentication
|
||||
# Related option: --disable_double_auth
|
||||
###############################################################################
|
||||
sub cli_disable_double_auth () {
|
||||
my $user_id = @ARGV[2];
|
||||
|
||||
print_log "[INFO] Disabling double authentication for the user '$user_id'\n\n";
|
||||
|
||||
$user_id = safe_input($user_id);
|
||||
|
||||
# Delete the user secret
|
||||
my $result = db_do ($dbh, 'DELETE FROM tuser_double_auth WHERE id_user = ?', $user_id);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Enable user
|
||||
# Related option: --enable_user
|
||||
|
@ -3691,21 +3709,25 @@ sub pandora_manage_main ($$$) {
|
|||
}
|
||||
elsif ($param eq '--disable_alerts') {
|
||||
param_check($ltotal, 0);
|
||||
cli_disable_alerts ($conf, $dbh);
|
||||
}
|
||||
cli_disable_alerts ($conf, $dbh);
|
||||
}
|
||||
elsif ($param eq '--enable_alerts') {
|
||||
param_check($ltotal, 0);
|
||||
cli_enable_alerts ($conf, $dbh);
|
||||
}
|
||||
cli_enable_alerts ($conf, $dbh);
|
||||
}
|
||||
elsif ($param eq '--disable_eacl') {
|
||||
param_check($ltotal, 0);
|
||||
cli_disable_eacl ($conf, $dbh);
|
||||
}
|
||||
cli_disable_eacl ($conf, $dbh);
|
||||
}
|
||||
elsif ($param eq '--enable_eacl') {
|
||||
param_check($ltotal, 0);
|
||||
cli_enable_eacl ($conf, $dbh);
|
||||
}
|
||||
elsif ($param eq '--disable_group') {
|
||||
cli_enable_eacl ($conf, $dbh);
|
||||
}
|
||||
elsif ($param eq '--disable_double_auth') {
|
||||
param_check($ltotal, 1);
|
||||
cli_disable_double_auth();
|
||||
}
|
||||
elsif ($param eq '--disable_group') {
|
||||
param_check($ltotal, 1);
|
||||
cli_disable_group();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue