diff --git a/pandora_console/extras/mr/69.sql b/pandora_console/extras/mr/69.sql index 19dfe33d6d..16d746f09a 100644 --- a/pandora_console/extras/mr/69.sql +++ b/pandora_console/extras/mr/69.sql @@ -7708,4 +7708,7 @@ UPDATE `twelcome_tip` SET url = 'https://pandorafms.com/manual/!current/start?id DELETE FROM tconfig WHERE `token` = 'legacy_database_ha'; +INSERT INTO `tconfig` (`token`, `value`) VALUES ('JWT_signature', ''); +DELETE FROM tconfig WHERE `token` = 'loginhash_pwd'; + COMMIT; \ No newline at end of file diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index b77ffabbee..e6bf3e4a2c 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -267,18 +267,6 @@ $table->data[$i][] = html_print_label_input_block( ); $table->data[$i++][] = html_print_label_input_block( - __('Auto login (hash) password'), - html_print_input_password( - 'loginhash_pwd', - io_output_password($config['loginhash_pwd']), - '', - 15, - 15, - true - ) -); - -$table->data[$i][] = html_print_label_input_block( __('Time source'), html_print_select( $sources, diff --git a/pandora_console/include/ajax/jwt.ajax.php b/pandora_console/include/ajax/jwt.ajax.php new file mode 100644 index 0000000000..810f6c3268 --- /dev/null +++ b/pandora_console/include/ajax/jwt.ajax.php @@ -0,0 +1,60 @@ +ajaxMethod($method) === true) { + $res = $class->{$method}(); + echo json_encode(['success' => true, 'data' => $res]); + } else { + echo json_encode(['success' => false, 'error' => 'Unavailable method.']); + } +} else { + echo json_encode(['success' => false, 'error' => 'Unavailable method.']); +} + +exit; diff --git a/pandora_console/include/class/JWTRepository.class.php b/pandora_console/include/class/JWTRepository.class.php index 4850fa9e47..367e596eea 100644 --- a/pandora_console/include/class/JWTRepository.class.php +++ b/pandora_console/include/class/JWTRepository.class.php @@ -33,6 +33,8 @@ use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\Signer\Key\InMemory; use Lcobucci\JWT\Token\Parser; use Lcobucci\JWT\Validation\Constraint\SignedWith; +use Lcobucci\Clock\SystemClock; +use Lcobucci\JWT\Validation\Constraint\StrictValidAt; /** * JWT Repository. @@ -40,6 +42,13 @@ use Lcobucci\JWT\Validation\Constraint\SignedWith; final class JWTRepository { + /** + * Allowed methods to be called using AJAX request. + * + * @var array + */ + public $AJAXMethods = ['create']; + /** * Signature * @@ -66,6 +75,22 @@ final class JWTRepository } + /** + * Checks if target method is available to be called using AJAX. + * + * @param string $method Target method. + * + * @return boolean True allowed, false not. + */ + public function ajaxMethod($method) + { + // Check access. + check_login(); + + return in_array($method, $this->AJAXMethods); + } + + /** * Create token * @@ -74,16 +99,20 @@ final class JWTRepository public function create(): string { global $config; - $sha = new Sha256(); - $configJWT = Configuration::forSymmetricSigner( - $sha, - InMemory::plainText($this->signature) - ); + try { + $sha = new Sha256(); + $configJWT = Configuration::forSymmetricSigner( + $sha, + InMemory::plainText($this->signature) + ); - $now = new DateTimeImmutable(); - $token = $configJWT->builder()->issuedAt($now)->canOnlyBeUsedAfter($now)->expiresAt($now->modify('+1 minute'))->withClaim('id_user', $config['id_user'])->getToken($configJWT->signer(), $configJWT->signingKey()); + $now = new DateTimeImmutable(); + $token = $configJWT->builder()->issuedAt($now)->canOnlyBeUsedAfter($now)->expiresAt($now->modify('+1 minute'))->withClaim('id_user', $config['id_user'])->getToken($configJWT->signer(), $configJWT->signingKey()); - return $token->toString(); + return $token->toString(); + } catch (Exception $e) { + return ''; + } } @@ -94,15 +123,23 @@ final class JWTRepository */ public function validate():bool { - $sha = new Sha256(); - $configJWT = Configuration::forSymmetricSigner( - $sha, - InMemory::plainText($this->signature) - ); - $signed = new SignedWith($sha, InMemory::plainText($this->signature)); - $constraints = [$signed]; - - return $configJWT->validator()->validate($this->token, ...$constraints); + try { + $sha = new Sha256(); + $configJWT = Configuration::forSymmetricSigner( + $sha, + InMemory::plainText($this->signature) + ); + $signed = new SignedWith($sha, InMemory::plainText($this->signature)); + $now = new DateTimeZone('UTC'); + $strictValid = new StrictValidAt(SystemClock::fromUTC()); + $constraints = [ + $signed, + $strictValid, + ]; + return $configJWT->validator()->validate($this->token, ...$constraints); + } catch (Exception $e) { + return false; + } } @@ -117,11 +154,23 @@ final class JWTRepository } - public function setToken(string $tokenString) + /** + * Setting token. + * + * @param string $tokenString String token to setting. + * + * @return boolean + */ + public function setToken(string $tokenString):bool { - $encoder = new JoseEncoder(); - $parser = new Parser($encoder); - $this->token = $parser->parse($tokenString); + try { + $encoder = new JoseEncoder(); + $parser = new Parser($encoder); + $this->token = $parser->parse($tokenString); + return true; + } catch (Exception $e) { + return false; + } } diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index baf09bd9fc..6e9f6aa9a9 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -207,10 +207,6 @@ function config_update_config() $error_update[] = __('Chromium config directory'); } - if (config_update_value('loginhash_pwd', (string) get_parameter('loginhash_pwd'), true, true) === false) { - $error_update[] = __('Auto login (hash) password'); - } - if (config_update_value('timesource', (string) get_parameter('timesource'), true) === false) { $error_update[] = __('Time source'); } @@ -2220,10 +2216,6 @@ function config_process_config() config_update_value('events_per_query', 5000); } - if (!isset($config['loginhash_pwd'])) { - config_update_value('loginhash_pwd', (rand(0, 1000) * rand(0, 1000)).'pandorahash', false, true); - } - if (!isset($config['trap2agent'])) { config_update_value('trap2agent', 0); } @@ -2487,6 +2479,10 @@ function config_process_config() config_update_value('number_modules_queue', 500); } + if (!isset($config['JWT_signature'])) { + config_update_value('JWT_signature', 0); + } + if (!isset($config['eastern_eggs_disabled'])) { config_update_value('eastern_eggs_disabled', 1); } diff --git a/pandora_console/include/javascript/pandora.js b/pandora_console/include/javascript/pandora.js index 2a2d7205a0..afff4e48ec 100644 --- a/pandora_console/include/javascript/pandora.js +++ b/pandora_console/include/javascript/pandora.js @@ -2736,3 +2736,32 @@ function menuTabsShowHide() { } } } + +function redirectNode(url) { + event.preventDefault(); + $.ajax({ + method: "POST", + url: "ajax.php", + dataType: "json", + data: { + page: "include/ajax/jwt.ajax", + method: "create" + }, + success: function(data) { + var $form = $("
"); + + $form.attr("method", "post"); + $form.attr("action", url); + + var $input = $("") + .attr("type", "hidden") + .attr("name", "token") + .val(data.data); + $form.append($input); + + $("body").append($form); + + $form.submit(); + } + }); +} diff --git a/pandora_console/index.php b/pandora_console/index.php index 1a70cbcd48..2ac5317691 100755 --- a/pandora_console/index.php +++ b/pandora_console/index.php @@ -755,24 +755,19 @@ if (isset($config['id_user']) === false) { header('Location: '.ui_get_full_url('index.php'.$redirect_url)); exit; // Always exit after sending location headers. - } else if (isset($_GET['loginhash']) === true || isset($_POST['loginhash']) === true) { - // Hash login process. - $loginhash_data = get_parameter('loginhash_data', ''); - $loginhash_user = str_rot13(get_parameter('loginhash_user', '')); - - if ($config['loginhash_pwd'] != '' - && $loginhash_data == md5( - $loginhash_user.io_output_password($config['loginhash_pwd']) - ) - ) { - db_logon($loginhash_user, $_SERVER['REMOTE_ADDR']); - $_SESSION['id_usuario'] = $loginhash_user; - $config['id_user'] = $loginhash_user; + } else if (isset($_POST['token']) === true && (bool) $config['JWT_signature'] !== false) { + include_once $config['homedir'].'/include/class/JWTRepository.class.php'; + $jwt = new JWTRepository($config['JWT_signature']); + if ($jwt->setToken($_POST['token']) && $jwt->validate()) { + $id_user = $jwt->payload()->get('id_user'); + db_logon($id_user, $_SERVER['REMOTE_ADDR']); + $_SESSION['id_usuario'] = $id_user; + $config['id_user'] = $id_user; } else { include_once 'general/login_page.php'; db_pandora_audit( AUDIT_LOG_USER_REGISTRATION, - 'Loginhash failed', + 'Login token failed', 'system' ); while (ob_get_length() > 0) { @@ -961,33 +956,17 @@ if (isset($config['id_user']) === false) { exit('