From 33e1d7aca442f709f71cf4481d181844297cf308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= Date: Thu, 16 Jun 2022 16:49:09 +0200 Subject: [PATCH 01/13] DB Changes --- pandora_console/extras/mr/55.sql | 1 + pandora_console/pandoradb.sql | 1 + 2 files changed, 2 insertions(+) diff --git a/pandora_console/extras/mr/55.sql b/pandora_console/extras/mr/55.sql index 747a8da934..c01a4e3c56 100644 --- a/pandora_console/extras/mr/55.sql +++ b/pandora_console/extras/mr/55.sql @@ -37,6 +37,7 @@ ALTER TABLE `tbackup` MODIFY COLUMN `id_user` VARCHAR(255) DEFAULT ''; ALTER TABLE `tservice` ADD COLUMN `enable_sunburst` tinyint(1) NOT NULL default 0; ALTER TABLE `tdashboard` MODIFY `name` TEXT NOT NULL DEFAULT ''; +ALTER TABLE `tusuario` ADD COLUMN `api_token` VARCHAR(255) NOT NULL DEFAULT ''; SET @st_oum763 = (SELECT IF( (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'tautoconfig' AND table_schema = DATABASE() AND column_name = 'disabled') > 0, diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 5550bc5413..3b70462c80 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -1304,6 +1304,7 @@ CREATE TABLE IF NOT EXISTS `tusuario` ( `ehorus_user_level_enabled` TINYINT, `integria_user_level_user` VARCHAR(60), `integria_user_level_pass` VARCHAR(45), + `api_token` VARCHAR(255) NOT NULL DEFAULT '', CONSTRAINT `fk_filter_id` FOREIGN KEY (`id_filter`) REFERENCES tevent_filter (`id_filter`) ON DELETE SET NULL, UNIQUE KEY `id_user` (`id_user`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; From b871c1fb553b83c1c82228e8541a623210804222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= Date: Fri, 17 Jun 2022 12:13:23 +0200 Subject: [PATCH 02/13] Added token view and generation in user views --- .../godmode/users/configure_user.php | 91 +++++++++++++------ pandora_console/include/functions_api.php | 17 ++++ pandora_console/include/functions_users.php | 58 ++++++++++++ pandora_console/include/javascript/pandora.js | 19 ++++ pandora_console/operation/users/user_edit.php | 22 ++++- 5 files changed, 175 insertions(+), 32 deletions(-) diff --git a/pandora_console/godmode/users/configure_user.php b/pandora_console/godmode/users/configure_user.php index 67a269bc66..19d2d7ff0c 100644 --- a/pandora_console/godmode/users/configure_user.php +++ b/pandora_console/godmode/users/configure_user.php @@ -1,19 +1,34 @@ '; +$apiToken = '
'; +$apiToken .= '

'.__('API Token'); +$apiToken .= ui_print_help_tip( + __('The next string is your passphrase for use with the API instead user/password. Click over the string for renew the token.'), + true +).'

'; +$apiToken .= html_print_input_hidden('api_token', $user_info['api_token'], true); +$apiToken .= sprintf( + '%s', + __('Warning'), + __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), + 'user_profile_form', + $user_info['api_token'] +); +$apiToken .= '
'; $user_groups = implode(',', array_keys((users_get_groups($id, 'AR', $display_all_group)))); @@ -1402,7 +1439,7 @@ if (!$id) { $user_id_create = $user_id; } -if (is_metaconsole()) { +if (is_metaconsole() === true) { $access_or_pagination = $meta_access; } else { $access_or_pagination = $size_pagination; @@ -1418,14 +1455,14 @@ if ($id != '' && !$is_err) { echo '
- -

Extra info

'.$email.$phone.$not_login.$local_user.$session_time.'
-
+ +

Extra info

'.$email.$phone.$not_login.$local_user.$session_time.$apiToken.'
+
'.$language.$access_or_pagination.$skin.$home_screen.$default_event_filter.$double_authentication.'
'.$timezone; -if (!is_metaconsole()) { +if (is_metaconsole() === false) { echo '
diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index d2c4f11823..2e7feb5e4c 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -17707,3 +17707,20 @@ function api_set_enable_disable_discovery_task($id_task, $thrash2, $other) } } } + + +/** + * Check if token is correct. + * + * @param string $token Token for check. + * + * @return integer Id of user. If returns 0 there is not valid token. + */ +function api_token_check(string $token) +{ + if (empty($token) === true) { + return 0; + } else { + return (int) db_get_value('id_user', 'tusuario', 'api_token', $token); + } +} diff --git a/pandora_console/include/functions_users.php b/pandora_console/include/functions_users.php index f4e6e25be8..808e98d5dd 100755 --- a/pandora_console/include/functions_users.php +++ b/pandora_console/include/functions_users.php @@ -877,3 +877,61 @@ function users_get_users_group_by_group($id_group) return $users; } + + +/** + * Generates a cryptographically secure chain for use with API. + * + * @return string + */ +function api_token_generate() +{ + // Generate a cryptographically secure chain. + $generateToken = bin2hex(openssl_random_pseudo_bytes(16)); + // Check if token exists in DB. + $tokenExists = (bool) api_token_check($generateToken); + // If not exists, can be assigned. In other case, try again. + return ($tokenExists === false) ? $generateToken : api_token_generate(); +} + + +/** + * Returns User API Token + * + * @param integer $idUser Id of the user. + * + * @return string + */ +function users_get_API_token(int $idUser) +{ + $apiToken = db_get_value('api_token', 'tusuario', 'id_user', $idUser); + + return $apiToken; +} + + +/** + * Renews the API Token. + * + * @param integer $idUser Id of the user. + * + * @return boolean Return true if the token was renewed. + */ +function users_renew_API_token(int $idUser) +{ + $apiToken = api_token_generate(); + + if (empty($apiToken) === false) { + $result = db_process_sql_update( + 'tusuario', + ['api_token' => $apiToken], + ['id_user' => $idUser] + ); + + if ($result !== false) { + return true; + } + } + + return false; +} diff --git a/pandora_console/include/javascript/pandora.js b/pandora_console/include/javascript/pandora.js index eb8118a911..b12745afdf 100644 --- a/pandora_console/include/javascript/pandora.js +++ b/pandora_console/include/javascript/pandora.js @@ -2057,3 +2057,22 @@ $.fn.filterByText = function(textbox) { }); }); }; + +/** + * Confirm Dialog for API token renewal request. + * + * @param {string} title Title for show. + * @param {string} message Message for show. + * @param {string} form Form to attach renewAPIToken element. + */ +function renewAPIToken(title, message, form) { + confirmDialog({ + title: title, + message: message, + onAccept: function() { + $("#" + form) + .append("") + .submit(); + } + }); +} diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php index f76fbfff31..443e9dab82 100644 --- a/pandora_console/operation/users/user_edit.php +++ b/pandora_console/operation/users/user_edit.php @@ -80,6 +80,7 @@ if (isset($_GET['modified']) && !$view_mode) { $upd_info['id_skin'] = get_parameter('skin', $user_info['id_skin']); $upd_info['default_event_filter'] = get_parameter('event_filter', null); $upd_info['block_size'] = get_parameter('block_size', $config['block_size']); + $upd_info['api_token'] = ((bool) get_parameter('renewAPIToken') === true) ? api_token_generate() : (string) get_parameter('api_token'); $default_block_size = get_parameter('default_block_size', 0); if ($default_block_size) { @@ -111,14 +112,14 @@ if (isset($_GET['modified']) && !$view_mode) { $section = io_safe_output($upd_info['section']); - if (($section == 'Event list') || ($section == 'Group view') - || ($section == 'Alert detail') || ($section == 'Tactical view') - || ($section == 'Default') + if (($section === 'Event list') || ($section === 'Group view') + || ($section === 'Alert detail') || ($section === 'Tactical view') + || ($section === 'Default') ) { $upd_info['data_section'] = ''; - } else if ($section == 'Dashboard') { + } else if ($section === 'Dashboard') { $upd_info['data_section'] = $dashboard; - } else if ($section == 'Visual console') { + } else if ($section === 'Visual console') { $upd_info['data_section'] = $visual_console; } @@ -258,6 +259,17 @@ if (is_metaconsole() === false && is_management_allowed() === false) { $user_id = '

'.__('User ID').':

'; $user_id .= ''.$id.'
'; +$user_id .= '

'.__('API Token').':

'; +$user_id .= html_print_input_hidden('api_token', $user_info['api_token'], true); +$user_id .= sprintf( + '%s', + __('Warning'), + __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), + 'user_mod', + $user_info['api_token'] +); +$user_id .= '
'; + $full_name = '
'.html_print_input_text_extended( 'fullname', $user_info['fullname'], From 8d05accb7b9b104ab9f604d1b4456d4e59a46969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= Date: Fri, 17 Jun 2022 12:30:59 +0200 Subject: [PATCH 03/13] Improve changes --- pandora_console/godmode/users/configure_user.php | 9 +++++---- pandora_console/operation/users/user_edit.php | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pandora_console/godmode/users/configure_user.php b/pandora_console/godmode/users/configure_user.php index 19d2d7ff0c..cdeb218fa8 100644 --- a/pandora_console/godmode/users/configure_user.php +++ b/pandora_console/godmode/users/configure_user.php @@ -28,7 +28,7 @@ // Begin. global $config; -hd($_REQUEST); + check_login(); require_once $config['homedir'].'/vendor/autoload.php'; @@ -1289,16 +1289,17 @@ $session_time .= html_print_input_text( $apiToken = '
'; $apiToken .= '

'.__('API Token'); $apiToken .= ui_print_help_tip( - __('The next string is your passphrase for use with the API instead user/password. Click over the string for renew the token.'), + __('The next string is your passphrase for use with the API instead user/password.'), true ).'

'; $apiToken .= html_print_input_hidden('api_token', $user_info['api_token'], true); +$apiToken .= ''.$user_info['api_token'].'   '; $apiToken .= sprintf( - '%s', + '%s', __('Warning'), __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), 'user_profile_form', - $user_info['api_token'] + __('Renew') ); $apiToken .= '
'; diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php index 443e9dab82..bc589bc763 100644 --- a/pandora_console/operation/users/user_edit.php +++ b/pandora_console/operation/users/user_edit.php @@ -262,12 +262,13 @@ $user_id .= ''.$id.'
'; $user_id .= '

'.__('API Token').':

'; $user_id .= html_print_input_hidden('api_token', $user_info['api_token'], true); $user_id .= sprintf( - '%s', + '%s', __('Warning'), __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), - 'user_mod', - $user_info['api_token'] + 'user_profile_form', + __('Renew') ); +$user_id .= '
'.$user_info['api_token'].''; $user_id .= '
'; $full_name = '
'.html_print_input_text_extended( From cdf5485aee3eb097479926a98a9b94eba528b4ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= Date: Mon, 27 Jun 2022 18:06:51 +0200 Subject: [PATCH 04/13] Updated api checker extension --- pandora_console/extensions/api_checker.php | 128 ++++++++++++++++----- 1 file changed, 98 insertions(+), 30 deletions(-) diff --git a/pandora_console/extensions/api_checker.php b/pandora_console/extensions/api_checker.php index b4af7c77ee..ed2053036e 100755 --- a/pandora_console/extensions/api_checker.php +++ b/pandora_console/extensions/api_checker.php @@ -1,43 +1,101 @@ $url, 'result' => $result, ]; - - return $return; } +/** + * Perform API Checker + * + * @return void. + */ function extension_api_checker() { global $config; check_login(); - if (! check_acl($config['id_user'], 0, 'PM')) { + if ((bool) check_acl($config['id_user'], 0, 'PM') === false) { db_pandora_audit( AUDIT_LOG_ACL_VIOLATION, 'Trying to access Profile Management' @@ -85,11 +146,12 @@ function extension_api_checker() $return_type = io_safe_output(get_parameter('return_type', '')); $other = io_safe_output(get_parameter('other', '')); $other_mode = io_safe_output(get_parameter('other_mode', 'url_encode_separator_|')); + $token = get_parameter('token'); - $api_execute = get_parameter('api_execute', 0); + $api_execute = (bool) get_parameter('api_execute', false); $return_call_api = ''; - if ($api_execute) { + if ($api_execute === true) { $return_call_api = api_execute( $url, $ip, @@ -103,7 +165,8 @@ function extension_api_checker() urlencode($id2), $return_type, urlencode($other), - $other_mode + $other_mode, + $token ); } @@ -182,6 +245,11 @@ function extension_api_checker() $row[] = html_print_input_text('other_mode', $other_mode, '', 50, 255, true); $table2->data[] = $row; + $row = []; + $row[] = __('API Token'); + $row[] = html_print_input_text('token', $token, '', 50, 255, true); + $table2->data[] = $row; + $table3 = new stdClass(); $table3->data = []; @@ -214,7 +282,7 @@ function extension_api_checker() echo '
'; echo ''; - if ($api_execute) { + if ($api_execute === true) { echo '
'; echo ''.__('Result').''; echo __('URL').'
'; From 23f163ed2ac186c6611e42ee8b040f00c73ba9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= Date: Tue, 28 Jun 2022 17:21:18 +0200 Subject: [PATCH 05/13] Fix api checker --- pandora_console/extensions/api_checker.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pandora_console/extensions/api_checker.php b/pandora_console/extensions/api_checker.php index ed2053036e..e301f5029f 100755 --- a/pandora_console/extensions/api_checker.php +++ b/pandora_console/extensions/api_checker.php @@ -192,6 +192,11 @@ function extension_api_checker() $row[] = html_print_input_text('pandora_url', $pandora_url, '', 50, 255, true); $table->data[] = $row; + $row = []; + $row[] = __('API Token').ui_print_help_tip(__('Use API Token instead API Pass, User and Password.'), true); + $row[] = html_print_input_text('token', $token, '', 50, 255, true); + $table->data[] = $row; + $row = []; $row[] = __('API Pass'); $row[] = html_print_input_password('apipass', $apipass, '', 50, 255, true); @@ -245,11 +250,6 @@ function extension_api_checker() $row[] = html_print_input_text('other_mode', $other_mode, '', 50, 255, true); $table2->data[] = $row; - $row = []; - $row[] = __('API Token'); - $row[] = html_print_input_text('token', $token, '', 50, 255, true); - $table2->data[] = $row; - $table3 = new stdClass(); $table3->data = []; From b175ffbd3ae2cd7255bd95c50ed24dbe3dd73ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= Date: Tue, 28 Jun 2022 17:22:09 +0200 Subject: [PATCH 06/13] Fixed db change --- pandora_console/pandoradb_data.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 8f60368737..dcae30f15c 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -341,8 +341,8 @@ INSERT INTO `tmodule_inventory` (`id_module_inventory`, `id_os`, `name`, `descri -- -- Dumping data for table `tusuario` -- -INSERT INTO `tusuario` (`id_user`, `fullname`, `firstname`, `lastname`, `middlename`, `password`, `comments`, `last_connect`, `registered`, `email`, `phone`, `is_admin`, `language`, `block_size`, `section`, `data_section`, `metaconsole_access`) VALUES -('admin', 'Pandora', 'Pandora', 'Admin', '', '1da7ee7d45b96d0e1f45ee4ee23da560', 'Admin Pandora', 1232642121, 0, 'admin@example.com', '555-555-5555', 1, 'default', 0, 'Default', '', 'advanced'); +INSERT INTO `tusuario` (`id_user`, `fullname`, `firstname`, `lastname`, `middlename`, `password`, `comments`, `last_connect`, `registered`, `email`, `phone`, `is_admin`, `language`, `block_size`, `section`, `data_section`, `metaconsole_access`, `api_token`) VALUES +('admin', 'Pandora', 'Pandora', 'Admin', '', '1da7ee7d45b96d0e1f45ee4ee23da560', 'Admin Pandora', 1232642121, 0, 'admin@example.com', '555-555-5555', 1, 'default', 0, 'Default', '', 'advanced', 'pandora1234'); -- -- Dumping data for table `tusuario_perfil` From ded27ce411c22468448496ff6868b124773860cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= Date: Tue, 28 Jun 2022 17:24:22 +0200 Subject: [PATCH 07/13] Backend changes --- pandora_console/include/api.php | 30 ++++--- pandora_console/include/auth/mysql.php | 98 ++++++--------------- pandora_console/include/functions_api.php | 6 +- pandora_console/include/functions_users.php | 9 +- 4 files changed, 54 insertions(+), 89 deletions(-) diff --git a/pandora_console/include/api.php b/pandora_console/include/api.php index cb3dae8e72..c9672816a8 100644 --- a/pandora_console/include/api.php +++ b/pandora_console/include/api.php @@ -14,7 +14,7 @@ * |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______| * * ============================================================================ - * Copyright (c) 2005-2021 Artica Soluciones Tecnologicas + * Copyright (c) 2005-2022 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 @@ -74,6 +74,7 @@ $password = get_parameter('pass', ''); $user = get_parameter('user', ''); $info = get_parameter('info', ''); $raw_decode = (bool) get_parameter('raw_decode', false); +$apiToken = (string) get_parameter('token'); $other = parseOtherParameter($otherSerialize, $otherMode, $raw_decode); $apiPassword = io_output_password( @@ -84,6 +85,7 @@ $apiPassword = io_output_password( ) ); +$apiTokenValid = (isset($_GET['token']) === true && (bool) api_token_check($apiToken)); $correctLogin = false; $no_login_msg = ''; @@ -94,8 +96,8 @@ ob_clean(); // Special call without checks to retrieve version and build of the Pandora FMS // This info is avalable from the web console without login // Don't change the format, it is parsed by applications. -if ($info == 'version') { - if (!$config['MR']) { +if ($info === 'version') { + if ((bool) $config['MR'] === false) { $config['MR'] = 0; } @@ -105,6 +107,7 @@ if ($info == 'version') { if (empty($apiPassword) === true || (empty($apiPassword) === false && $api_password === $apiPassword) + || $apiTokenValid === true ) { if (enterprise_hook('metaconsole_validate_origin', [get_parameter('server_auth')]) === true || enterprise_hook('console_validate_origin', [get_parameter('server_auth')]) === true @@ -118,7 +121,14 @@ if (empty($apiPassword) === true $correctLogin = true; } else if ((bool) isInACL($ipOrigin) === true) { // External access. - $user_in_db = process_user_login($user, $password, true); + // Token is valid. Bypass the credentials. + if ($apiTokenValid === true) { + $credentials = db_get_row('tusuario', 'api_token', $apiToken); + $user = $credentials['id_user']; + $password = $credentials['password']; + } + + $user_in_db = process_user_login($user, $password, true, $apiTokenValid); if ($user_in_db !== false) { $config['id_usuario'] = $user_in_db; // Compat. @@ -144,19 +154,19 @@ if (empty($apiPassword) === true $no_login_msg = 'Incorrect given API password'; } -if ($correctLogin) { +if ($correctLogin === true) { if (($op !== 'get') && ($op !== 'set') && ($op !== 'help')) { returnError('no_set_no_get_no_help', $returnType); } else { $function_name = ''; // Check if is an extension function and get the function name. - if ($op2 == 'extension') { + if ($op2 === 'extension') { $extension_api_url = $config['homedir'].'/'.EXTENSIONS_DIR.'/'.$ext_name.'/'.$ext_name.'.api.php'; // The extension API file must exist and the extension must be // enabled. - if (file_exists($extension_api_url) - && !in_array($ext_name, extensions_get_disabled_extensions()) + if (file_exists($extension_api_url) === true + && in_array($ext_name, extensions_get_disabled_extensions()) === false ) { include_once $extension_api_url; $function_name = 'apiextension_'.$op.'_'.$ext_function; @@ -164,7 +174,7 @@ if ($correctLogin) { } else { $function_name = 'api_'.$op.'_'.$op2; - if ($op == 'set' && $id) { + if ($op === 'set' && $id) { switch ($op2) { case 'update_agent': case 'add_module_in_conf': @@ -173,7 +183,7 @@ if ($correctLogin) { $agent = agents_locate_agent($id); if ($agent !== false) { $id_os = $agent['id_os']; - if ($id_os == 100) { + if ((int) $id_os === 100) { returnError( 'not_allowed_operation_cluster', $returnType diff --git a/pandora_console/include/auth/mysql.php b/pandora_console/include/auth/mysql.php index 67053ab0be..48e0145c4a 100644 --- a/pandora_console/include/auth/mysql.php +++ b/pandora_console/include/auth/mysql.php @@ -78,7 +78,7 @@ $config['admin_can_make_admin'] = true; * @return mixed False in case of error or invalid credentials, the username in * case it's correct. */ -function process_user_login($login, $pass, $api=false) +function process_user_login($login, $pass, $api=false, $passAlreadyEncrypted=false) { global $config; @@ -114,10 +114,10 @@ function process_user_login($login, $pass, $api=false) if ($config['fallback_local_auth'] || is_user_admin($login) || $local_user === true - || strtolower($config['auth']) == 'mysql' + || strtolower($config['auth']) === 'mysql' || (bool) $user_not_login === true ) { - return process_user_login_local($login, $pass, $api); + return process_user_login_local($login, $pass, $api, $passAlreadyEncrypted); } else { return false; } @@ -128,88 +128,44 @@ function process_user_login($login, $pass, $api=false) } -function process_user_login_local($login, $pass, $api=false) +function process_user_login_local($login, $pass, $api=false, $passAlreadyEncrypted=false) { global $config, $mysql_cache; - // Connect to Database - switch ($config['dbtype']) { - case 'mysql': - if (!$api) { - $sql = sprintf( - "SELECT `id_user`, `password` - FROM `tusuario` - WHERE `id_user` = '%s' AND `not_login` = 0 - AND `disabled` = 0", - $login - ); - } else { - $sql = sprintf( - "SELECT `id_user`, `password` - FROM `tusuario` - WHERE `id_user` = '%s' - AND `disabled` = 0", - $login - ); - } - break; - - case 'postgresql': - if (!$api) { - $sql = sprintf( - 'SELECT "id_user", "password" - FROM "tusuario" - WHERE "id_user" = \'%s\' AND "not_login" = 0 - AND "disabled" = 0', - $login - ); - } else { - $sql = sprintf( - 'SELECT "id_user", "password" - FROM "tusuario" - WHERE "id_user" = \'%s\' - AND "disabled" = 0', - $login - ); - } - break; - - case 'oracle': - if (!$api) { - $sql = sprintf( - 'SELECT id_user, password - FROM tusuario - WHERE id_user = \'%s\' AND not_login = 0 - AND disabled = 0', - $login - ); - } else { - $sql = sprintf( - 'SELECT id_user, password - FROM tusuario - WHERE id_user = \'%s\' - AND disabled = 0', - $login - ); - } - break; + if ($api === false) { + $sql = sprintf( + "SELECT `id_user`, `password` + FROM `tusuario` + WHERE `id_user` = '%s' AND `not_login` = 0 + AND `disabled` = 0", + $login + ); + } else { + $sql = sprintf( + "SELECT `id_user`, `password` + FROM `tusuario` + WHERE `id_user` = '%s' + AND `disabled` = 0", + $login + ); } $row = db_get_row_sql($sql); - // Check that row exists, that password is not empty and that password is the same hash - if ($row !== false && $row['password'] !== md5('') - && $row['password'] == md5($pass) + // Check that row exists, that password is not empty and that password is the same hash. + if (($row !== false && $row['password'] !== md5('') + && (string) $row['password'] === md5($pass)) + || ($passAlreadyEncrypted === true && (string) $row['password'] === (string) $pass) ) { // Login OK // Nick could be uppercase or lowercase (select in MySQL // is not case sensitive) // We get DB nick to put in PHP Session variable, // to avoid problems with case-sensitive usernames. - // Thanks to David Muñiz for Bug discovery :) + // Thanks to David Muñiz for Bug discovery :). $filter = ['id_usuario' => $login]; $user_profile = db_get_row_filter('tusuario_perfil', $filter); - if (!users_is_admin($login) && !$user_profile) { + if ((bool) users_is_admin($login) === false && (bool) $user_profile === false) { $mysql_cache['auth_error'] = 'User does not have any profile'; $config['auth_error'] = 'User does not have any profile'; return false; @@ -217,7 +173,7 @@ function process_user_login_local($login, $pass, $api=false) return $row['id_user']; } else { - if (!user_can_login($login)) { + if (user_can_login($login) === false) { $mysql_cache['auth_error'] = 'User only can use the API.'; $config['auth_error'] = 'User only can use the API.'; } else { diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 2e7feb5e4c..29aafad983 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -17714,13 +17714,13 @@ function api_set_enable_disable_discovery_task($id_task, $thrash2, $other) * * @param string $token Token for check. * - * @return integer Id of user. If returns 0 there is not valid token. + * @return mixed Id of user. If returns 0 there is not valid token. */ function api_token_check(string $token) { if (empty($token) === true) { - return 0; + return -1; } else { - return (int) db_get_value('id_user', 'tusuario', 'api_token', $token); + return db_get_value('id_user', 'tusuario', 'api_token', $token); } } diff --git a/pandora_console/include/functions_users.php b/pandora_console/include/functions_users.php index 808e98d5dd..00a18afda5 100755 --- a/pandora_console/include/functions_users.php +++ b/pandora_console/include/functions_users.php @@ -886,6 +886,7 @@ function users_get_users_group_by_group($id_group) */ function api_token_generate() { + include_once 'functions_api.php'; // Generate a cryptographically secure chain. $generateToken = bin2hex(openssl_random_pseudo_bytes(16)); // Check if token exists in DB. @@ -898,15 +899,13 @@ function api_token_generate() /** * Returns User API Token * - * @param integer $idUser Id of the user. + * @param string $idUser Id of the user. * * @return string */ -function users_get_API_token(int $idUser) +function users_get_API_token(string $idUser) { - $apiToken = db_get_value('api_token', 'tusuario', 'id_user', $idUser); - - return $apiToken; + return db_get_value('api_token', 'tusuario', 'id_user', $idUser); } From c3dc1d820d454a1323aef8d5cdc9e8359efa3a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= Date: Tue, 28 Jun 2022 17:24:49 +0200 Subject: [PATCH 08/13] Frontend changes --- .../godmode/users/configure_user.php | 191 ++++++++++-------- pandora_console/include/javascript/pandora.js | 14 ++ pandora_console/include/styles/pandora.css | 8 + pandora_console/operation/users/user_edit.php | 81 +++++--- 4 files changed, 190 insertions(+), 104 deletions(-) diff --git a/pandora_console/godmode/users/configure_user.php b/pandora_console/godmode/users/configure_user.php index cdeb218fa8..031e87635a 100644 --- a/pandora_console/godmode/users/configure_user.php +++ b/pandora_console/godmode/users/configure_user.php @@ -44,10 +44,7 @@ require_once $config['homedir'].'/include/functions_visual_map.php'; require_once $config['homedir'].'/include/functions_custom_fields.php'; enterprise_include_once('include/functions_profile.php'); -$meta = false; -if (enterprise_installed() && defined('METACONSOLE')) { - $meta = true; -} +$meta = is_metaconsole(); $isFunctionSkins = enterprise_include_once('include/functions_skins.php'); @@ -57,11 +54,10 @@ if (ENTERPRISE_NOT_HOOK !== enterprise_include('include/functions_policies.php') $enterprise_include = true; } -if ($enterprise_include) { +if ($enterprise_include === true) { enterprise_include_once('meta/include/functions_users_meta.php'); } - if (is_metaconsole() === false) { date_default_timezone_set('UTC'); include 'include/javascript/timezonepicker/includes/parser.inc'; @@ -112,13 +108,13 @@ if (is_metaconsole() === false) { // This defines the working user. Beware with this, old code get confusses // and operates with current logged user (dangerous). $id = get_parameter('id', get_parameter('id_user', '')); -// ID given as parameter +// ID given as parameter. $pure = get_parameter('pure', 0); $user_info = get_user_info($id); $is_err = false; -if (! check_acl($config['id_user'], 0, 'UM')) { +if ((bool) check_acl($config['id_user'], 0, 'UM') === false) { db_pandora_audit( AUDIT_LOG_ACL_VIOLATION, 'Trying to access User Management' @@ -130,7 +126,7 @@ if (! check_acl($config['id_user'], 0, 'UM')) { if (is_ajax() === true) { $delete_profile = (bool) get_parameter('delete_profile'); - if ($delete_profile) { + if ($delete_profile === true) { $id2 = (string) get_parameter('id_user'); $id_up = (int) get_parameter('id_user_profile'); @@ -160,7 +156,7 @@ if (is_ajax() === true) { if ($has_profile === false && $user_is_global_admin === false) { $result = delete_user($id2); - if ($result) { + if ($result === true) { db_pandora_audit( AUDIT_LOG_USER_MANAGEMENT, __('Deleted user %s', io_safe_output($id_user)) @@ -174,7 +170,7 @@ if (is_ajax() === true) { ); // Delete the user in all the consoles. - if (defined('METACONSOLE')) { + if (is_metaconsole() === true) { $servers = metaconsole_get_servers(); foreach ($servers as $server) { // Connect to the remote console. @@ -182,7 +178,7 @@ if (is_ajax() === true) { // Delete the user. $result = delete_user($id_user); - if ($result) { + if ($result === true) { db_pandora_audit( AUDIT_LOG_USER_MANAGEMENT, __('Deleted user %s from metaconsole', io_safe_output($id_user)) @@ -193,10 +189,14 @@ if (is_ajax() === true) { metaconsole_restore_db(); // Log to the metaconsole too. - if ($result) { + if ($result === true) { db_pandora_audit( AUDIT_LOG_USER_MANAGEMENT, - __('Deleted user %s from %s', io_safe_input($id_user), io_safe_input($server['server_name'])) + __( + 'Deleted user %s from %s', + io_safe_input($id_user), + io_safe_input($server['server_name']) + ) ); } @@ -217,14 +217,8 @@ if (is_ajax() === true) { $tab = get_parameter('tab', 'user'); -if ($id) { - $header_title = ' » '.__('Update user'); -} else { - $header_title = ' » '.__('Create user'); -} - // Header. -if ($meta) { +if (is_metaconsole() === true) { user_meta_print_header(); $sec = 'advanced'; } else { @@ -255,19 +249,34 @@ if ($meta) { $buttons[$tab]['active'] = true; - ui_print_page_header( - __('User detail editor').$header_title, + ui_print_standard_header( + (empty($id) === false) ? __('Update user') : __('Create user'), 'images/gm_users.png', false, '', true, - $buttons + $buttons, + [ + [ + 'link' => '', + 'label' => __('Profiles'), + ], + [ + 'link' => ui_get_full_url('index.php?sec=gusuarios&sec2=godmode/users/user_list'), + 'label' => __('Manage users'), + ], + [ + 'link' => '', + 'label' => __('User Detail Editor'), + ], + ] ); + $sec = 'gusuarios'; } -if ($config['user_can_update_info']) { +if ((bool) $config['user_can_update_info'] === true) { $view_mode = false; } else { $view_mode = true; @@ -281,14 +290,14 @@ $renewAPIToken = (bool) get_parameter('renewAPIToken'); $status = get_parameter('status', -1); $json_profile = get_parameter('json_profile', ''); -// Reset status var if current action is not update_user -if ($new_user || $create_user || $add_profile - || $delete_profile || $update_user +// Reset status var if current action is not update_user. +if ($new_user === true || $create_user === true || $add_profile === true + || $delete_profile === true || $update_user === true ) { $status = -1; } -if ($new_user && $config['admin_can_add_user']) { +if ($new_user === true && (bool) $config['admin_can_add_user'] === true) { $user_info = []; $id = ''; $user_info['fullname'] = ''; @@ -312,29 +321,31 @@ if ($new_user && $config['admin_can_add_user']) { $user_info['section'] = ''; $user_info['data_section'] = ''; - // This attributes are inherited from global configuration + // This attributes are inherited from global configuration. $user_info['block_size'] = $config['block_size']; - if (enterprise_installed() && is_metaconsole() === true) { + if (enterprise_installed() === true && is_metaconsole() === true) { $user_info['metaconsole_agents_manager'] = 0; $user_info['metaconsole_assigned_server'] = ''; $user_info['metaconsole_access_node'] = 0; } - if ($config['ehorus_user_level_conf']) { + if ((bool) $config['ehorus_user_level_conf'] === true) { $user_info['ehorus_user_level_user'] = ''; $user_info['ehorus_user_level_pass'] = ''; $user_info['ehorus_user_level_enabled'] = true; } } -if ($create_user) { - if (! $config['admin_can_add_user']) { - ui_print_error_message(__('The current authentication scheme doesn\'t support creating users on %s', get_product_name())); +if ($create_user === true) { + if ((bool) $config['admin_can_add_user'] === false) { + ui_print_error_message( + __('The current authentication scheme doesn\'t support creating users on %s', get_product_name()) + ); return; } - if (html_print_csrf_error()) { + if (html_print_csrf_error() === true) { return; } @@ -375,20 +386,20 @@ if ($create_user) { $values['block_size'] = (int) get_parameter('block_size', $config['block_size']); $values['section'] = get_parameter('section'); - if (($values['section'] == 'Event list') || ($values['section'] == 'Group view') || ($values['section'] == 'Alert detail') || ($values['section'] == 'Tactical view') || ($values['section'] == 'Default')) { + if (($values['section'] === 'Event list') || ($values['section'] === 'Group view') || ($values['section'] === 'Alert detail') || ($values['section'] === 'Tactical view') || ($values['section'] === 'Default')) { $values['data_section'] = ''; - } else if ($values['section'] == 'Dashboard') { + } else if ($values['section'] === 'Dashboard') { $values['data_section'] = $dashboard; - } else if (io_safe_output($values['section']) == 'Visual console') { + } else if (io_safe_output($values['section']) === 'Visual console') { $values['data_section'] = $visual_console; - } else if ($values['section'] == 'Other' || io_safe_output($values['section']) == 'External link') { + } else if ($values['section'] === 'Other' || io_safe_output($values['section']) === 'External link') { $values['data_section'] = get_parameter('data_section'); } if (enterprise_installed()) { $values['force_change_pass'] = 1; $values['last_pass_change'] = date('Y/m/d H:i:s', get_system_time()); - if (defined('METACONSOLE')) { + if (is_metaconsole() === true) { $values['metaconsole_access'] = get_parameter('metaconsole_access', 'basic'); $values['metaconsole_agents_manager'] = ($user_is_admin == 1 ? 1 : get_parameter('metaconsole_agents_manager', '0')); $values['metaconsole_assigned_server'] = get_parameter('metaconsole_assigned_server', ''); @@ -402,7 +413,7 @@ if ($create_user) { $values['strict_acl'] = (bool) get_parameter('strict_acl', false); $values['session_time'] = (int) get_parameter('session_time', 0); - // eHorus user level conf + // Ehorus user level conf. if ($config['ehorus_user_level_conf']) { $values['ehorus_user_level_enabled'] = (bool) get_parameter('ehorus_user_level_enabled', false); if ($values['ehorus_user_level_enabled'] === true) { @@ -551,7 +562,7 @@ if ($create_user) { } if ($update_user) { - if (html_print_csrf_error()) { + if (html_print_csrf_error() === true) { return; } @@ -568,7 +579,9 @@ if ($update_user) { $values['timezone'] = (string) get_parameter('timezone'); $values['default_event_filter'] = (int) get_parameter('default_event_filter'); $values['default_custom_view'] = (int) get_parameter('default_custom_view'); - $values['api_token'] = ((bool) get_parameter('renewAPIToken') === true) ? api_token_generate() : (string) get_parameter('api_token'); + // API Token information. + $apiTokenRenewed = (bool) get_parameter('renewAPIToken'); + $values['api_token'] = ($apiTokenRenewed === true) ? api_token_generate() : users_get_API_token($values['id_user']); if (users_is_admin() === false && (bool) $values['is_admin'] !== false) { db_pandora_audit( @@ -580,7 +593,7 @@ if ($update_user) { exit; } - // eHorus user level conf. + // Ehorus user level conf. $values['ehorus_user_level_enabled'] = (bool) get_parameter('ehorus_user_level_enabled', false); $values['ehorus_user_level_user'] = (string) get_parameter('ehorus_user_level_user'); $values['ehorus_user_level_pass'] = (string) get_parameter('ehorus_user_level_pass'); @@ -597,17 +610,17 @@ if ($update_user) { $values['block_size'] = get_parameter('block_size', $config['block_size']); $values['section'] = get_parameter('section'); - if (($values['section'] == 'Event list') || ($values['section'] == 'Group view') || ($values['section'] == 'Alert detail') || ($values['section'] == 'Tactical view') || ($values['section'] == 'Default')) { + if (($values['section'] === 'Event list') || ($values['section'] === 'Group view') || ($values['section'] === 'Alert detail') || ($values['section'] === 'Tactical view') || ($values['section'] === 'Default')) { $values['data_section'] = ''; - } else if ($values['section'] == 'Dashboard') { + } else if ($values['section'] === 'Dashboard') { $values['data_section'] = $dashboard; - } else if (io_safe_output($values['section']) == 'Visual console') { + } else if (io_safe_output($values['section']) === 'Visual console') { $values['data_section'] = $visual_console; - } else if ($values['section'] == 'Other' || io_safe_output($values['section']) == 'External link') { + } else if ($values['section'] === 'Other' || io_safe_output($values['section']) === 'External link') { $values['data_section'] = get_parameter('data_section'); } - if (enterprise_installed() && defined('METACONSOLE')) { + if (enterprise_installed() === true && is_metaconsole() === true) { $values['metaconsole_access'] = get_parameter('metaconsole_access'); $values['metaconsole_agents_manager'] = get_parameter('metaconsole_agents_manager', '0'); $values['metaconsole_assigned_server'] = get_parameter('metaconsole_assigned_server', ''); @@ -734,7 +747,7 @@ if ($update_user) { $has_skin = true; } - if (enterprise_installed() && defined('METACONSOLE')) { + if (enterprise_installed() === true && is_metaconsole() === true) { $info .= ',"Wizard access":"'.$values['metaconsole_access'].'"}'; $has_wizard = true; } else if ($has_skin) { @@ -756,7 +769,7 @@ if ($update_user) { ui_print_result_message( $res1, - __('User info successfully updated'), + ($apiTokenRenewed === true) ? __('You have generated a new API Token.') : __('User info successfully updated'), __('Error updating user info (no change?)') ); } @@ -779,7 +792,7 @@ if ($update_user) { } foreach ($profiles as $profile) { - $count_groups = ($count_groups + 1); + $count_groups++; $arr_tags = explode(',', $profile['tags']); $count_tags = ($count_tags + count($arr_tags)); } @@ -792,7 +805,7 @@ if ($update_user) { $user_info = $values; } -if ($status != -1) { +if ((int) $status !== -1) { ui_print_result_message( $status, __('User info successfully updated'), @@ -862,12 +875,13 @@ if (!users_is_admin() && $config['id_user'] != $id && !$new_user) { } } -if (defined('METACONSOLE')) { - if ($id) { - echo '
'.__('Update User').'
'; - } else { - echo '
'.__('Create User').'
'; - } +if (is_metaconsole() === true) { + html_print_div( + [ + 'class' => 'user_form_title', + 'content' => (empty($id) === true) ? __('Create User') : __('Update User'), + ] + ); } if (!$new_user) { @@ -875,6 +889,42 @@ if (!$new_user) { $user_id .= ''.$id.''; $user_id .= html_print_input_hidden('id_user', $id, true); $user_id .= '
'; + $user_id .= '

'.__('API Token').'

'; + $user_id .= html_print_anchor( + [ + 'onClick' => sprintf( + 'javascript:renewAPIToken(\'%s\', \'%s\', \'%s\')', + __('Warning'), + __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), + 'user_profile_form', + ), + 'content' => html_print_image( + 'images/icono-refrescar.png', + true, + ['class' => 'renew_api_token_image clickable'] + ), + 'class' => 'renew_api_token_link', + ], + true + ); + + $user_id .= html_print_anchor( + [ + 'onClick' => sprintf( + 'javascript:showAPIToken(\'%s\', \'%s\')', + __('API Token'), + base64_encode(__('Your API Token is:').' 
'.users_get_API_token($id).'
 '.__('Please, avoid share this string with others.')), + ), + 'content' => html_print_image( + 'images/eye_show.png', + true, + ['class' => 'renew_api_token_image clickable'] + ), + 'class' => 'renew_api_token_link', + ], + true + ); + $user_id .= '
'; } else { $user_id = '
'.html_print_input_text_extended( 'id_user', @@ -893,7 +943,7 @@ if (!$new_user) { ).'
'; } -if (is_user_admin($id)) { +if (is_user_admin($id) === true) { $avatar = html_print_image( 'images/people_1.png', true, @@ -1286,23 +1336,6 @@ $session_time .= html_print_input_text( 'class="input_line_small"' ).'
'; -$apiToken = '
'; -$apiToken .= '

'.__('API Token'); -$apiToken .= ui_print_help_tip( - __('The next string is your passphrase for use with the API instead user/password.'), - true -).'

'; -$apiToken .= html_print_input_hidden('api_token', $user_info['api_token'], true); -$apiToken .= ''.$user_info['api_token'].'   '; -$apiToken .= sprintf( - '%s', - __('Warning'), - __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), - 'user_profile_form', - __('Renew') -); -$apiToken .= '
'; - $user_groups = implode(',', array_keys((users_get_groups($id, 'AR', $display_all_group)))); if (empty($user_groups) === false) { @@ -1457,7 +1490,7 @@ if ($id != '' && !$is_err) { echo '
-

Extra info

'.$email.$phone.$not_login.$local_user.$session_time.$apiToken.'
+

Extra info

'.$email.$phone.$not_login.$local_user.$session_time.'
'.$language.$access_or_pagination.$skin.$home_screen.$default_event_filter.$double_authentication.'
diff --git a/pandora_console/include/javascript/pandora.js b/pandora_console/include/javascript/pandora.js index b12745afdf..d6dcbed25e 100644 --- a/pandora_console/include/javascript/pandora.js +++ b/pandora_console/include/javascript/pandora.js @@ -2076,3 +2076,17 @@ function renewAPIToken(title, message, form) { } }); } + +/** + * Show Dialog for view the API token. + * + * @param {string} title Title for show. + * @param {string} message Base64 encoded message for show. + */ +function showAPIToken(title, message) { + confirmDialog({ + title: title, + message: atob(message), + hideCancelButton: true + }); +} diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 83f2a89ac2..07c58ad27c 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -9038,6 +9038,14 @@ div#err_msg_centralised { width: 75%; } +.renew_api_token_link { + margin: 3px 0.5em 0 0; + float: right; +} + +.renew_api_token_image { + width: 16px; +} @media screen and (max-width: 1369px) { .div-col { width: 50%; diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php index bc589bc763..7d12f8ec52 100644 --- a/pandora_console/operation/users/user_edit.php +++ b/pandora_console/operation/users/user_edit.php @@ -80,10 +80,12 @@ if (isset($_GET['modified']) && !$view_mode) { $upd_info['id_skin'] = get_parameter('skin', $user_info['id_skin']); $upd_info['default_event_filter'] = get_parameter('event_filter', null); $upd_info['block_size'] = get_parameter('block_size', $config['block_size']); - $upd_info['api_token'] = ((bool) get_parameter('renewAPIToken') === true) ? api_token_generate() : (string) get_parameter('api_token'); + // API Token information. + $apiTokenRenewed = (bool) get_parameter('renewAPIToken'); + $upd_info['api_token'] = ($apiTokenRenewed === true) ? api_token_generate() : users_get_API_token($config['id_user']); $default_block_size = get_parameter('default_block_size', 0); - if ($default_block_size) { + if ($default_block_size > 0) { $upd_info['block_size'] = 0; } @@ -159,17 +161,17 @@ if (isset($_GET['modified']) && !$view_mode) { } else if ($password_new !== 'NON-INIT') { $error_msg = __('Passwords didn\'t match or other problem encountered while updating passwords'); } - } else if (empty($password_new) && empty($password_confirm)) { + } else if (empty($password_new) === true && empty($password_confirm) === true) { $return = true; - } else if (empty($password_new) || empty($password_confirm)) { + } else if (empty($password_new) === true || empty($password_confirm) === true) { $return = false; } // No need to display "error" here, because when no update is needed // (no changes in data) SQL function returns 0 (FALSE), but is not an error, // just no change. Previous error message could be confussing to the user. - if ($return) { - if (!empty($password_new) && !empty($password_confirm)) { + if ($return !== false) { + if (empty($password_new) === false && empty($password_confirm) === false) { $success_msg = __('Password successfully updated'); } @@ -182,9 +184,13 @@ if (isset($_GET['modified']) && !$view_mode) { if ($return_update_user === false) { $error_msg = __('Error updating user info'); } else if ($return_update_user == true) { - $success_msg = __('User info successfully updated'); + if ($apiTokenRenewed === true) { + $success_msg = __('You have generated a new API Token.'); + } else { + $success_msg = __('User info successfully updated'); + } } else { - if (!empty($password_new) && !empty($password_confirm)) { + if (empty($password_new) === false && empty($password_confirm) === false) { $success_msg = __('Password successfully updated'); } else if ($upd_info['id_skin'] !== $user_info['id_skin']) { $success_msg = __('Skin successfully updated'); @@ -224,7 +230,7 @@ if (isset($_GET['modified']) && !$view_mode) { } // Prints action status for current message. -if ($status != -1) { +if ((int) $status !== -1) { ui_print_result_message( $status, __('User info successfully updated'), @@ -259,16 +265,41 @@ if (is_metaconsole() === false && is_management_allowed() === false) { $user_id = '

'.__('User ID').':

'; $user_id .= ''.$id.'
'; -$user_id .= '

'.__('API Token').':

'; -$user_id .= html_print_input_hidden('api_token', $user_info['api_token'], true); -$user_id .= sprintf( - '%s', - __('Warning'), - __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), - 'user_profile_form', - __('Renew') +$user_id .= '

'.__('API Token').'

'; +$user_id .= html_print_anchor( + [ + 'onClick' => sprintf( + 'javascript:renewAPIToken(\'%s\', \'%s\', \'%s\')', + __('Warning'), + __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), + 'user_profile_form', + ), + 'content' => html_print_image( + 'images/icono-refrescar.png', + true, + ['class' => 'renew_api_token_image clickable'] + ), + 'class' => 'renew_api_token_link', + ], + true +); + +$user_id .= html_print_anchor( + [ + 'onClick' => sprintf( + 'javascript:showAPIToken(\'%s\', \'%s\')', + __('API Token'), + base64_encode(__('Your API Token is:').'
'.users_get_API_token($config['id_user']).'
'.__('Please, avoid share this string with others.')), + ), + 'content' => html_print_image( + 'images/eye_show.png', + true, + ['class' => 'renew_api_token_image clickable'] + ), + 'class' => 'renew_api_token_link', + ], + true ); -$user_id .= '
'.$user_info['api_token'].''; $user_id .= '
'; $full_name = '
'.html_print_input_text_extended( @@ -288,7 +319,7 @@ $full_name = '
'.html_print_input_text_extended ).'
'; // Show "Picture" (in future versions, why not, allow users to upload it's own avatar here. -if (is_user_admin($id)) { +if (is_user_admin($id) === true) { $avatar = html_print_image('images/people_1.png', true, ['class' => 'user_avatar']); } else { $avatar = html_print_image('images/people_2.png', true, ['class' => 'user_avatar']); @@ -646,10 +677,10 @@ foreach ($timezones as $timezone_name => $tz) { } } -if (is_metaconsole()) { - echo '
'; +if (is_metaconsole() === true) { + echo ''; } else { - echo ''; + echo ''; } html_print_input_hidden('id', $id, false, false, false, 'id'); @@ -668,7 +699,7 @@ if (is_metaconsole()) { -if (!is_metaconsole()) { +if (is_metaconsole() === false) { echo '
@@ -677,10 +708,10 @@ if (!is_metaconsole()) { } echo '
-
+
'.$comments.'
-
+
'; if ($config['ehorus_enabled'] && $config['ehorus_user_level_conf']) { From 8ffc5aef97c8f599bdc96115fc470265b10e242b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= Date: Wed, 29 Jun 2022 09:14:21 +0200 Subject: [PATCH 09/13] Minor improvements --- .../godmode/users/configure_user.php | 17 ++++++++++------- pandora_console/include/functions_users.php | 8 +++++++- pandora_console/operation/users/user_edit.php | 10 ++++++++-- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/pandora_console/godmode/users/configure_user.php b/pandora_console/godmode/users/configure_user.php index 031e87635a..b2280d9446 100644 --- a/pandora_console/godmode/users/configure_user.php +++ b/pandora_console/godmode/users/configure_user.php @@ -425,11 +425,8 @@ if ($create_user === true) { } } - // Generate a new API Token if user has login capability. - if ($values['not_login'] === false) { - // Generate new API token. - $values['api_token'] = api_token_generate(); - } + // Generate new API token. + $values['api_token'] = api_token_generate(); if (empty($id) === true) { ui_print_error_message(__('User ID cannot be empty')); @@ -901,7 +898,10 @@ if (!$new_user) { 'content' => html_print_image( 'images/icono-refrescar.png', true, - ['class' => 'renew_api_token_image clickable'] + [ + 'class' => 'renew_api_token_image clickable', + 'title' => __('Renew API Token'), + ] ), 'class' => 'renew_api_token_link', ], @@ -918,7 +918,10 @@ if (!$new_user) { 'content' => html_print_image( 'images/eye_show.png', true, - ['class' => 'renew_api_token_image clickable'] + [ + 'class' => 'renew_api_token_image clickable', + 'title' => __('Show API Token'), + ] ), 'class' => 'renew_api_token_link', ], diff --git a/pandora_console/include/functions_users.php b/pandora_console/include/functions_users.php index 00a18afda5..82fc2b2362 100755 --- a/pandora_console/include/functions_users.php +++ b/pandora_console/include/functions_users.php @@ -905,7 +905,13 @@ function api_token_generate() */ function users_get_API_token(string $idUser) { - return db_get_value('api_token', 'tusuario', 'id_user', $idUser); + $output = db_get_value('api_token', 'tusuario', 'id_user', $idUser); + + if (empty($output) === true) { + $output = '<< '.__('NONE').' >>'; + } + + return $output; } diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php index 7d12f8ec52..f6ebf682f7 100644 --- a/pandora_console/operation/users/user_edit.php +++ b/pandora_console/operation/users/user_edit.php @@ -277,7 +277,10 @@ $user_id .= html_print_anchor( 'content' => html_print_image( 'images/icono-refrescar.png', true, - ['class' => 'renew_api_token_image clickable'] + [ + 'class' => 'renew_api_token_image clickable', + 'title' => __('Renew API Token'), + ] ), 'class' => 'renew_api_token_link', ], @@ -294,7 +297,10 @@ $user_id .= html_print_anchor( 'content' => html_print_image( 'images/eye_show.png', true, - ['class' => 'renew_api_token_image clickable'] + [ + 'class' => 'renew_api_token_image clickable', + 'title' => __('Show API Token'), + ] ), 'class' => 'renew_api_token_link', ], From c14842a4f9d4e88897ac89c8df32f29125e2ebbb Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 29 Dec 2022 17:20:34 +0100 Subject: [PATCH 10/13] WIP:Api auth with bearer token --- pandora_console/extensions/api_checker.php | 52 ++++++++++++------- pandora_console/include/api.php | 15 +++++- pandora_console/include/functions.php | 47 ++++++++++++++++- pandora_console/include/functions_api.php | 34 ++++++------ pandora_console/include/functions_ui.php | 8 ++- pandora_console/include/styles/pandora.css | 15 ++++++ pandora_console/operation/users/user_edit.php | 23 +++++++- 7 files changed, 153 insertions(+), 41 deletions(-) diff --git a/pandora_console/extensions/api_checker.php b/pandora_console/extensions/api_checker.php index e301f5029f..895d621178 100755 --- a/pandora_console/extensions/api_checker.php +++ b/pandora_console/extensions/api_checker.php @@ -65,42 +65,58 @@ function api_execute( string $other_mode='', string $token='' ) { + $data = []; + if (empty($url) === true) { - $url = 'http://'.$ip.$pandora_url.'/include/api.php'; - $url .= '?'; - $url .= '&op='.$op; - $url .= '&op2='.$op2; + $url = 'http://'.$ip.$pandora_url.'/include/api.php?'; + + if (empty($op) === false) { + $data['op'] = $op; + } + + if (empty($op2) === false) { + $data['op2'] = $op2; + } if (empty($id) === false) { - $url .= '&id='.$id; + $data['id'] = $id; } if (empty($id2) === false) { - $url .= '&id2='.$id2; + $data['id2'] = $id2; } if (empty($return_type) === false) { - $url .= '&return_type='.$return_type; + $data['return_type'] = $return_type; } if (empty($other) === false) { - $url .= '&other_mode='.$other_mode; - $url .= '&other='.$other; + $data['other_mode'] = $other_mode; + $data['other'] = $other; } - // If token is reported, have priority. - if (empty($token) === false) { - $url .= 'token='.$token; - } else { - $url .= 'apipass='.$apipass; - $url .= '&user='.$user; - $url .= '&pass='.$password; + // If token is not reported,use old method. + if (empty($token) === true) { + $data['apipass'] = $apipass; + $data['user'] = $user; + $data['password'] = $password; } } - $curlObj = curl_init(); + $curlObj = curl_init($url); + if (empty($data) === false) { + $url .= http_build_query($data); + } + + // set the content type json + $headers = [ + 'Content-Type: application/json', + 'Authorization: Bearer '.$token, + ]; + curl_setopt($curlObj, CURLOPT_URL, $url); - curl_setopt($curlObj, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curlObj, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curlObj, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($curlObj); curl_close($curlObj); diff --git a/pandora_console/include/api.php b/pandora_console/include/api.php index c9672816a8..aefb33aed8 100644 --- a/pandora_console/include/api.php +++ b/pandora_console/include/api.php @@ -74,7 +74,6 @@ $password = get_parameter('pass', ''); $user = get_parameter('user', ''); $info = get_parameter('info', ''); $raw_decode = (bool) get_parameter('raw_decode', false); -$apiToken = (string) get_parameter('token'); $other = parseOtherParameter($otherSerialize, $otherMode, $raw_decode); $apiPassword = io_output_password( @@ -85,7 +84,19 @@ $apiPassword = io_output_password( ) ); -$apiTokenValid = (isset($_GET['token']) === true && (bool) api_token_check($apiToken)); +// Try getting bearer token from header. +// TODO. Getting token from url will be removed. +$apiToken = (string) getBearerToken(); +if ($apiToken === false) { + // Legacy token in GET. + // TODO. Revome in future. + $apiToken = (string) get_parameter('token'); + $apiTokenValid = (isset($_GET['token']) === true && (bool) api_token_check($apiToken)); +} else { + $apiTokenValid = (bool) api_token_check($apiToken); +} + + $correctLogin = false; $no_login_msg = ''; diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index eadd275bcc..0f74004141 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -6277,7 +6277,7 @@ function arrayOutputSorting($sort, $sortField) /** * Get dowload started cookie from js and set ready cokkie for download ready comntrol. * - * @return + * @return void */ function setDownloadCookieToken() { @@ -6293,3 +6293,48 @@ function setDownloadCookieToken() ); } } + + +/** + * Get header Authorization + * */ +function getAuthorizationHeader() +{ + $headers = null; + if (isset($_SERVER['Authorization'])) { + $headers = trim($_SERVER['Authorization']); + } else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { + // Nginx or fast CGI + $headers = trim($_SERVER['HTTP_AUTHORIZATION']); + } else if (function_exists('apache_request_headers')) { + $requestHeaders = apache_request_headers(); + // Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization) + $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders)); + // print_r($requestHeaders); + if (isset($requestHeaders['Authorization'])) { + $headers = trim($requestHeaders['Authorization']); + } + } + + return $headers; +} + + +/** + * Get access token from header + * + * @return array/false Token received, false in case thre is no token. + * */ +function getBearerToken() +{ + $headers = getAuthorizationHeader(); + + // HEADER: Get the access token from the header + if (!empty($headers)) { + if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) { + return $matches[1]; + } + } + + return false; +} diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 46eb20f7c2..4e201e9c64 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -17346,23 +17346,6 @@ function api_set_enable_disable_discovery_task($id_task, $thrash2, $other) } -/** - * Check if token is correct. - * - * @param string $token Token for check. - * - * @return mixed Id of user. If returns 0 there is not valid token. - */ -function api_token_check(string $token) -{ - if (empty($token) === true) { - return -1; - } else { - return db_get_value('id_user', 'tusuario', 'api_token', $token); - } -} - - /** * Make report (PDF, CSV or XML) and send it via e-mail (this method is intended to be used by server's execution * of alert actions that involve sending reports by e-mail). @@ -17660,3 +17643,20 @@ function api_set_send_report($thrash1, $thrash2, $other, $returnType) returnData($returnType, $data, ';'); } } + + +/** + * Check if token is correct. + * + * @param string $token Token for check. + * + * @return mixed Id of user. If returns 0 there is not valid token. + */ +function api_token_check(string $token) +{ + if (empty($token) === true) { + return 0; + } else { + return db_get_value('id_user', 'tusuario', 'api_token', $token); + } +} diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 52ad703edd..798c8cf72a 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -2370,13 +2370,17 @@ function ui_print_help_tip( $return=false, $img='images/tip_help.png', $is_relative=false, - $style='' + $style='', + $blink=false ) { $output = ''; $output .= html_print_image( $img, true, - ['title' => $text], + [ + 'title' => $text, + 'class' => $blink === true ? 'blink' : '', + ], false, $is_relative && is_metaconsole() ).''; diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index feec4a48ef..c0fb182b9e 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -4678,6 +4678,21 @@ input:checked + .p-slider:before { animation: fadein 0.5s, fadeout 0.5s 7.5s; } +.blink { + animation: blink-animation 1s steps(5, start) infinite; + -webkit-animation: blink-animation 1s steps(5, start) infinite; +} +@keyframes blink-animation { + to { + visibility: hidden; + } +} +@-webkit-keyframes blink-animation { + to { + visibility: hidden; + } +} + .snackbar p, .snackbar h3 { text-align: left; diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php index 6c6e244585..12070947ea 100644 --- a/pandora_console/operation/users/user_edit.php +++ b/pandora_console/operation/users/user_edit.php @@ -290,6 +290,16 @@ $user_id .= html_print_anchor( true ); +// Check php conf for header auth. +$lines = file('/etc/httpd/conf.d/php.conf'); +$http_authorization = false; + +foreach ($lines as $l) { + if (preg_match('/SetEnvIfNoCase \^Authorization\$ \"\(\.\+\)\" HTTP_AUTHORIZATION=\$1/', $l)) { + $http_authorization = true; + } +} + $user_id .= html_print_anchor( [ 'onClick' => sprintf( @@ -309,8 +319,19 @@ $user_id .= html_print_anchor( ], true ); -$user_id .= '
'; +if ($http_authorization === false) { + $user_id .= ui_print_help_tip( + __('Directive HTTP_AUTHORIZATION=$1 is not set. Please, add it to /etc/httpd/conf.d/php.conf'), + true, + 'images/warn.png', + false, + '', + true + ); +} + +$user_id .= ''; $full_name = '
'.html_print_input_text_extended( 'fullname', $user_info['fullname'], From c608ef6fcf422719f8fd68a0c902cc5b4df12229 Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 30 Dec 2022 15:55:46 +0100 Subject: [PATCH 11/13] Api auth bearer token --- pandora_console/include/api.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pandora_console/include/api.php b/pandora_console/include/api.php index aefb33aed8..c0ee23e172 100644 --- a/pandora_console/include/api.php +++ b/pandora_console/include/api.php @@ -69,9 +69,6 @@ $id2 = get_parameter('id2'); $otherSerialize = get_parameter('other'); $otherMode = get_parameter('other_mode', 'url_encode'); $returnType = get_parameter('return_type', 'string'); -$api_password = get_parameter('apipass', ''); -$password = get_parameter('pass', ''); -$user = get_parameter('user', ''); $info = get_parameter('info', ''); $raw_decode = (bool) get_parameter('raw_decode', false); @@ -84,14 +81,16 @@ $apiPassword = io_output_password( ) ); +$apiTokenValid = false; // Try getting bearer token from header. // TODO. Getting token from url will be removed. $apiToken = (string) getBearerToken(); -if ($apiToken === false) { - // Legacy token in GET. +if (empty($apiToken) === true) { + // Legacy user/pass token. // TODO. Revome in future. - $apiToken = (string) get_parameter('token'); - $apiTokenValid = (isset($_GET['token']) === true && (bool) api_token_check($apiToken)); + $api_password = get_parameter('apipass', ''); + $user = get_parameter('user', ''); + $password = get_parameter('pass', ''); } else { $apiTokenValid = (bool) api_token_check($apiToken); } From af800fa886a195bab5e394d598b6d2e1e2a5e901 Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 30 Dec 2022 16:03:49 +0100 Subject: [PATCH 12/13] Updated MR --- pandora_console/extras/mr/55.sql | 1 - pandora_console/extras/mr/60.sql | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pandora_console/extras/mr/55.sql b/pandora_console/extras/mr/55.sql index 6be8fbe064..687678c22b 100644 --- a/pandora_console/extras/mr/55.sql +++ b/pandora_console/extras/mr/55.sql @@ -40,7 +40,6 @@ ALTER TABLE `tservice` ADD COLUMN `asynchronous` TINYINT NOT NULL DEFAULT 0; ALTER TABLE `tservice` ADD COLUMN `rca` TEXT; ALTER TABLE `tdashboard` MODIFY `name` TEXT NOT NULL DEFAULT ''; -ALTER TABLE `tusuario` ADD COLUMN `api_token` VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE `tevent_alert` ADD COLUMN `field1_recovery` TEXT AFTER `recovery_notify`; ALTER TABLE `tevent_alert` ADD COLUMN `field4_recovery` TEXT AFTER `field3_recovery`; diff --git a/pandora_console/extras/mr/60.sql b/pandora_console/extras/mr/60.sql index 7be8a0b4ef..9b2c360dbc 100644 --- a/pandora_console/extras/mr/60.sql +++ b/pandora_console/extras/mr/60.sql @@ -46,4 +46,6 @@ update `tmodule_inventory` set `code`='IyEvdXNyL2Jpbi9wZXJsCiMjIyMjIyMjIyMjIyMjI update `tmodule_inventory` set `code`='IyEvdXNyL2Jpbi9wZXJsCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgcGFuZG9yYV9wcm9kdWN0SUQucGwKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBDb3B5cmlnaHQgKGMpIDIwMTUgQm9yamEgU2FuY2hleiwgPGZib3JqYS5zYW5jaGV6QGFydGljYS5lcz4KIyAgICAgICAgICAgKGMpIDIwMTUgQXJ0aWNhIFNvbHVjaW9uZXMgVGVjbm9sb2dpY2FzIFMuTAojCiMgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgojIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiMgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IHZlcnNpb24gMi4KIwojIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAojIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiMgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQojIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiMgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQojIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEsIFVTQS4KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCiN1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgRmlsZTo6QmFzZW5hbWU7CnVzZSBIVE1MOjpFbnRpdGllcyAoKTsKCiMgQ2hlY2sgZm9yIHdtaWMKbXkgJHdtaV9jbGllbnQgPSAiL3Vzci9iaW4vcGFuZG9yYXdtaWMiOwp1bmxlc3MoLWUgJHdtaV9jbGllbnQpIHsKCXByaW50ICJbZXJyb3JdICR3bWlfY2xpZW50IG5vdCBmb3VuZC5cbiI7CglleGl0IDE7Cn0KCmlmICgkI0FSR1YgIT0gMikgewoJcHJpbnQgIlVzYWdlOiAkMCA8dGFyZ2V0IGlwPiA8dXNlcm5hbWU+IDxwYXNzd29yZD5cbiI7CglleGl0IDE7Cn0KCm15ICR0YXJnZXRfaXAgPSAkQVJHVlswXTsKbXkgJHVzZXJuYW1lID0gJEFSR1ZbMV07Cm15ICRwYXNzd29yZCA9ICRBUkdWWzJdOwoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBTVUIgcnVuX3F1ZXJ5ICgkd3FsX3F1ZXJ5KQojIFJ1bnMgdGhlIGdpdmVuIFdRTCBxdWVyeSBhbmQgcmV0dXJucyB0aGUgcmVzdWx0IGFzIGFuIGFycmF5IG9mIGhhc2hlcy4KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKc3ViIHJ1bl9xdWVyeSB7CglteSAkd3FsX3F1ZXJ5ID0gJF9bMF07CglteSBAcmVzdWx0ID0ge307CgoJJHdxbF9xdWVyeSA9fiAncy8iL1wnL2cnOwoKCSMgUnVuIHRoZSBEQ09NL1dNSSBjbGllbnQKCW15ICRvdXRwdXQgPSBgJHdtaV9jbGllbnQgLVUgJyR1c2VybmFtZSclJyRwYXNzd29yZCcgLy8kdGFyZ2V0X2lwIFwiJHdxbF9xdWVyeVwiIDI+L2Rldi9udWxsYDsKCglteSBAbGluZXMgPSBzcGxpdCgvXG4vLCAkb3V0cHV0KTsKCSMgSGVhZGVyLCBkZXNjcmlwdGlvbiwgcmVzdWx0cwoJaWYgKCQjbGluZXMgPCAyKSB7CgkJZXhpdCAxOwoJfQoJIyBEcm9wIHRoZSBoZWFkZXIKCXNoaWZ0IChAbGluZXMpOwoJCQoJIyBHZXQgY29sdW1uIG5hbWVzCglteSBAY29sdW1uX25hbWVzID0gc3BsaXQoL1x8Lywgc2hpZnQgKEBsaW5lcykpOwoKCSMgR2V0IHJvdyBkYXRhCglteSAkaWR4ID0gMDsKCWZvciAobXkgJGkgPSAwOyAkaSA8PSAkI2xpbmVzOyAkaSsrKSB7CgkJIyBDaGVjayBmb3IgZXJyb3JzCgkJaWYgKCRsaW5lc1skaV0gPX4gbS9eRVJST1IvKSB7CgkJCWV4aXQgMTsKCQl9CgoJCSMgQmxhY2sgbGlzdAoJCWlmICgkbGluZXNbJGldID1+IG0vRmlsZSAxLykgewoJCQluZXh0OwoJCX0KCQlteSBAY29sdW1uID0gc3BsaXQoL1x8LywgJGxpbmVzWyRpXSk7CgkJZm9yIChteSAkaiA9IDA7ICRqIDw9ICQjY29sdW1uX25hbWVzOyAkaisrKSB7CgkJCWlmICghIGRlZmluZWQoJGNvbHVtblskal0pKSB7CgkJCQkkcmVzdWx0WyRpZHhdLT57JGNvbHVtbl9uYW1lc1skal19ID0gIiI7CgkJCX0KCQkJZWxzZSB7CgkJCQkkcmVzdWx0WyRpZHhdLT57JGNvbHVtbl9uYW1lc1skal19ID0gJGNvbHVtblskal07CgkJCX0KCQl9CgkJCgkJJGlkeCsrOwoJfQoJCglyZXR1cm4gQHJlc3VsdDsKfQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBTVUIgcHJpbnRfbW9kdWxlZGF0YSAoJG1vZHVsZV9pdGVtLCAkbW9kdWxlX2RhdGEsIAojICRtb2R1bGVfZGVzY3JpcHRpb24sIEBkYXRhKQojIFByaW50cyBhIG1vZHVsZWRhdGEgWE1MIHRhZy4gJG1vZHVsZV9pdGVtLCAkbW9kdWxlX2RhdGEgYW5kCiMgJG1vZHVsZV9kZXNjcmlwdGlvbiBhcmUgdXNlZCB0byBpbmRleCB0aGUgaXRlbSwgZGF0YSBhbmQgZGVzY3JpcHRpb24KIyBYTUwgdGFncyByZXNwZWN0aXZlbHkuCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCnN1YiBwcmludF9tb2R1bGVkYXRhIHsKCW15IEBtb2R1bGVfaGVhZGVycyA9IEB7JF9bMF19OwoJbXkgQG1vZHVsZV91bml0cyAgID0gQHskX1sxXX07CglteSBAZGF0YSAgICAgICAgICAgPSBAeyRfWzJdfTsKCW15ICRyZXN1bHQ7Cglmb3JlYWNoIG15ICRlbGVtZW50IChAZGF0YSkgewoJCSRyZXN1bHQgPSAnJzsKCQlmb3IgKCRpPTA7ICRpPEBtb2R1bGVfaGVhZGVyczskaSsrKSB7CgkJCWlmIChkZWZpbmVkICgkZWxlbWVudC0+eyRtb2R1bGVfaGVhZGVyc1skaV19KSkgewoJCQkJJHJlc3VsdCAuPSAkZWxlbWVudC0+eyRtb2R1bGVfaGVhZGVyc1skaV19IC4gJG1vZHVsZV91bml0c1skaV0gLiAnOyc7CgkJCX0KCQkJZWxzZSB7CgkJCQkkcmVzdWx0IC49ICc7JzsKCQkJfQoJCX0KCQljaG9wKCRyZXN1bHQpOwoJCXByaW50ICRyZXN1bHQgLiAiXG4iOwkKCX0KfQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBNYWluCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpteSBAcmVzdWx0ICA9IHJ1bl9xdWVyeSgiU2VsZWN0IFNlcmlhbE51bWJlciBmcm9tIFdpbjMyX09wZXJhdGluZ1N5c3RlbSIpOwojIFJlbWVtYmVyIHRvIG1hdGNoIGxlbmdodCBvZiBib3RoIGFycmF5cyBoZWFkZXJzICYgdW5pdHMKbXkgQGhlYWRlcnMgPSAoIlNlcmlhbE51bWJlciIpOwpteSBAdW5pdHMgICA9ICgiIik7CnByaW50X21vZHVsZWRhdGEgKFxAaGVhZGVycyxcQHVuaXRzLCBcQHJlc3VsdCk7CmV4aXQgMDsKCg==' where `code`='IyEvdXNyL2Jpbi9wZXJsCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgcGFuZG9yYV9wcm9kdWN0SUQucGwKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBDb3B5cmlnaHQgKGMpIDIwMTUgQm9yamEgU2FuY2hleiwgPGZib3JqYS5zYW5jaGV6QGFydGljYS5lcz4KIyAgICAgICAgICAgKGMpIDIwMTUgQXJ0aWNhIFNvbHVjaW9uZXMgVGVjbm9sb2dpY2FzIFMuTAojCiMgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgojIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiMgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IHZlcnNpb24gMi4KIwojIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAojIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiMgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQojIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiMgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQojIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEsIFVTQS4KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCiN1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgRmlsZTo6QmFzZW5hbWU7CnVzZSBIVE1MOjpFbnRpdGllcyAoKTsKCiMgQ2hlY2sgZm9yIHdtaWMKbXkgJHdtaV9jbGllbnQgPSAid21pYyI7CmlmIChzeXN0ZW0oIiR3bWlfY2xpZW50ID4gL2Rldi9udWxsIDI+JjEiKSAhPSAyNTYpIHsKCXByaW50ICJbZXJyb3JdICR3bWlfY2xpZW50IG5vdCBmb3VuZC5cbiI7CglleGl0IDE7Cn0KCmlmICgkI0FSR1YgIT0gMikgewoJcHJpbnQgIlVzYWdlOiAkMCA8dGFyZ2V0IGlwPiA8dXNlcm5hbWU+IDxwYXNzd29yZD5cbiI7CglleGl0IDE7Cn0KCm15ICR0YXJnZXRfaXAgPSAkQVJHVlswXTsKbXkgJHVzZXJuYW1lID0gJEFSR1ZbMV07Cm15ICRwYXNzd29yZCA9ICRBUkdWWzJdOwoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBTVUIgcnVuX3F1ZXJ5ICgkd3FsX3F1ZXJ5KQojIFJ1bnMgdGhlIGdpdmVuIFdRTCBxdWVyeSBhbmQgcmV0dXJucyB0aGUgcmVzdWx0IGFzIGFuIGFycmF5IG9mIGhhc2hlcy4KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKc3ViIHJ1bl9xdWVyeSB7CglteSAkd3FsX3F1ZXJ5ID0gJF9bMF07CglteSBAcmVzdWx0ID0ge307CgoJJHdxbF9xdWVyeSA9fiAncy8iL1wnL2cnOwoKCSMgUnVuIHRoZSBEQ09NL1dNSSBjbGllbnQKCW15ICRvdXRwdXQgPSBgJHdtaV9jbGllbnQgLVUgJyR1c2VybmFtZSclJyRwYXNzd29yZCcgLy8kdGFyZ2V0X2lwIFwiJHdxbF9xdWVyeVwiIDI+L2Rldi9udWxsYDsKCglteSBAbGluZXMgPSBzcGxpdCgvXG4vLCAkb3V0cHV0KTsKCSMgSGVhZGVyLCBkZXNjcmlwdGlvbiwgcmVzdWx0cwoJaWYgKCQjbGluZXMgPCAyKSB7CgkJZXhpdCAxOwoJfQoJIyBEcm9wIHRoZSBoZWFkZXIKCXNoaWZ0IChAbGluZXMpOwoJCQoJIyBHZXQgY29sdW1uIG5hbWVzCglteSBAY29sdW1uX25hbWVzID0gc3BsaXQoL1x8Lywgc2hpZnQgKEBsaW5lcykpOwoKCSMgR2V0IHJvdyBkYXRhCglteSAkaWR4ID0gMDsKCWZvciAobXkgJGkgPSAwOyAkaSA8PSAkI2xpbmVzOyAkaSsrKSB7CgkJIyBDaGVjayBmb3IgZXJyb3JzCgkJaWYgKCRsaW5lc1skaV0gPX4gbS9eRVJST1IvKSB7CgkJCWV4aXQgMTsKCQl9CgoJCSMgQmxhY2sgbGlzdAoJCWlmICgkbGluZXNbJGldID1+IG0vRmlsZSAxLykgewoJCQluZXh0OwoJCX0KCQlteSBAY29sdW1uID0gc3BsaXQoL1x8LywgJGxpbmVzWyRpXSk7CgkJZm9yIChteSAkaiA9IDA7ICRqIDw9ICQjY29sdW1uX25hbWVzOyAkaisrKSB7CgkJCWlmICghIGRlZmluZWQoJGNvbHVtblskal0pKSB7CgkJCQkkcmVzdWx0WyRpZHhdLT57JGNvbHVtbl9uYW1lc1skal19ID0gIiI7CgkJCX0KCQkJZWxzZSB7CgkJCQkkcmVzdWx0WyRpZHhdLT57JGNvbHVtbl9uYW1lc1skal19ID0gJGNvbHVtblskal07CgkJCX0KCQl9CgkJCgkJJGlkeCsrOwoJfQoJCglyZXR1cm4gQHJlc3VsdDsKfQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBTVUIgcHJpbnRfbW9kdWxlZGF0YSAoJG1vZHVsZV9pdGVtLCAkbW9kdWxlX2RhdGEsIAojICRtb2R1bGVfZGVzY3JpcHRpb24sIEBkYXRhKQojIFByaW50cyBhIG1vZHVsZWRhdGEgWE1MIHRhZy4gJG1vZHVsZV9pdGVtLCAkbW9kdWxlX2RhdGEgYW5kCiMgJG1vZHVsZV9kZXNjcmlwdGlvbiBhcmUgdXNlZCB0byBpbmRleCB0aGUgaXRlbSwgZGF0YSBhbmQgZGVzY3JpcHRpb24KIyBYTUwgdGFncyByZXNwZWN0aXZlbHkuCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCnN1YiBwcmludF9tb2R1bGVkYXRhIHsKCW15IEBtb2R1bGVfaGVhZGVycyA9IEB7JF9bMF19OwoJbXkgQG1vZHVsZV91bml0cyAgID0gQHskX1sxXX07CglteSBAZGF0YSAgICAgICAgICAgPSBAeyRfWzJdfTsKCW15ICRyZXN1bHQ7Cglmb3JlYWNoIG15ICRlbGVtZW50IChAZGF0YSkgewoJCSRyZXN1bHQgPSAnJzsKCQlmb3IgKCRpPTA7ICRpPEBtb2R1bGVfaGVhZGVyczskaSsrKSB7CgkJCWlmIChkZWZpbmVkICgkZWxlbWVudC0+eyRtb2R1bGVfaGVhZGVyc1skaV19KSkgewoJCQkJJHJlc3VsdCAuPSAkZWxlbWVudC0+eyRtb2R1bGVfaGVhZGVyc1skaV19IC4gJG1vZHVsZV91bml0c1skaV0gLiAnOyc7CgkJCX0KCQkJZWxzZSB7CgkJCQkkcmVzdWx0IC49ICc7JzsKCQkJfQoJCX0KCQljaG9wKCRyZXN1bHQpOwoJCXByaW50ICRyZXN1bHQgLiAiXG4iOwkKCX0KfQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBNYWluCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpteSBAcmVzdWx0ICA9IHJ1bl9xdWVyeSgiU2VsZWN0IFNlcmlhbE51bWJlciBmcm9tIFdpbjMyX09wZXJhdGluZ1N5c3RlbSIpOwojIFJlbWVtYmVyIHRvIG1hdGNoIGxlbmdodCBvZiBib3RoIGFycmF5cyBoZWFkZXJzICYgdW5pdHMKbXkgQGhlYWRlcnMgPSAoIlNlcmlhbE51bWJlciIpOwpteSBAdW5pdHMgICA9ICgiIik7CnByaW50X21vZHVsZWRhdGEgKFxAaGVhZGVycyxcQHVuaXRzLCBcQHJlc3VsdCk7CmV4aXQgMDsKCg==' and `name` = 'product_ID' and `id_module_inventory`=36; +ALTER TABLE `tusuario` ADD COLUMN `api_token` VARCHAR(255) NOT NULL DEFAULT ''; + COMMIT; From 88aed19d304b178107344cae8ed50ce6ba081aff Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 30 Dec 2022 16:11:49 +0100 Subject: [PATCH 13/13] Api auth bearer token working --- pandora_console/include/auth/mysql.php | 16 ++++--- pandora_console/operation/users/user_edit.php | 43 ++++++++++--------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/pandora_console/include/auth/mysql.php b/pandora_console/include/auth/mysql.php index 9b41f10975..dffe9cb5cc 100644 --- a/pandora_console/include/auth/mysql.php +++ b/pandora_console/include/auth/mysql.php @@ -168,13 +168,17 @@ function process_user_login_local($login, $pass, $api=false, $passAlreadyEncrypt $row = db_get_row_sql($sql); - // Perform password check whether it is MD5-hashed (old hashing) or Bcrypt-hashed. - if (strlen($row['password']) === 32) { - // MD5. - $credentials_check = $row !== false && $row['password'] !== md5('') && $row['password'] == md5($pass); + if ($passAlreadyEncrypted) { + $credentials_check = $pass === $row['password']; } else { - // Bcrypt. - $credentials_check = password_verify($pass, $row['password']); + // Perform password check whether it is MD5-hashed (old hashing) or Bcrypt-hashed. + if (strlen($row['password']) === 32) { + // MD5. + $credentials_check = $row !== false && $row['password'] !== md5('') && $row['password'] == md5($pass); + } else { + // Bcrypt. + $credentials_check = password_verify($pass, $row['password']); + } } if ($credentials_check === true) { diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php index 2dd991e3b4..f77a5dfa49 100644 --- a/pandora_console/operation/users/user_edit.php +++ b/pandora_console/operation/users/user_edit.php @@ -269,26 +269,29 @@ $user_id = '

'.__('U $user_id .= ''.$id.'

'; $user_id .= '

'.__('API Token').'

'; -$user_id .= html_print_anchor( - [ - 'onClick' => sprintf( - 'javascript:renewAPIToken(\'%s\', \'%s\', \'%s\')', - __('Warning'), - __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), - 'user_profile_form', - ), - 'content' => html_print_image( - 'images/icono-refrescar.png', - true, - [ - 'class' => 'renew_api_token_image clickable', - 'title' => __('Renew API Token'), - ] - ), - 'class' => 'renew_api_token_link', - ], - true -); +if (is_management_allowed()) { + $user_id .= html_print_anchor( + [ + 'onClick' => sprintf( + 'javascript:renewAPIToken(\'%s\', \'%s\', \'%s\')', + __('Warning'), + __('The API token will be renewed. After this action, the last token you were using will not work. Are you sure?'), + 'user_profile_form', + ), + 'content' => html_print_image( + 'images/icono-refrescar.png', + true, + [ + 'class' => 'renew_api_token_image clickable', + 'title' => __('Renew API Token'), + ] + ), + 'class' => 'renew_api_token_link', + ], + true + ); +} + // Check php conf for header auth. $lines = file('/etc/httpd/conf.d/php.conf');