So, bit by bit managed to dig deep enough to uncover some interesting bits.
This function:
function verify_token($database, $user, $ip, $time, $token) {
if (!password_verify($database . $user . $ip . $time . PHPMYADMIN_KEY, $token)) {
if (
!password_verify(
$database . $user . $_SERVER["SERVER_ADDR"] . "|" . $ip . $time . PHPMYADMIN_KEY,
$token
)
) {
trigger_error(
"Access denied: There is a security token mismatch " . $time,
E_USER_WARNING,
);
session_invalid();
}
}
return;
}
Portion:
if (
!password_verify(
$database . $user . $_SERVER["SERVER_ADDR"] . "|" . $ip . $time . PHPMYADMIN_KEY,
$token
)
) {
trigger_error(
"Access denied: There is a security token mismatch " . $time,
E_USER_WARNING,
);
session_invalid();
}
This portion specifically takes local server IP address. When I locally access PMA SSO, everything works, but when I access SSO via my external script - it fails check.
Of course it is good to secure as much as it is rational. In my case, users have no access to hestiacp, everything is done via third party system. Is it secure to comment out that check? To leave this function like this:
function verify_token($database, $user, $ip, $time, $token) {
if (!password_verify($database . $user . $ip . $time . PHPMYADMIN_KEY, $token)) {
trigger_error(
"Access denied: There is a security token mismatch " . $time,
E_USER_WARNING,
);
session_invalid();
}
return;
}
Actually looking more into this issue seems command:
v-delete-sys-pma-sso
Does not delete API key. It removes value in hestia.conf, turns off setting in config, deletes hestia-sso.php file, but does not delete key in keys directory. And executing manually that script, it shows up warning:
rm: cannot remove '/usr/local/hestia/data/keys/': Is a directory
Also, there is config value in hestia.conf:
PHPMYADMIN_KEY=''
Does this value should be equal to API key? Because now it is:
/* Following keys will get replaced when calling v-add-sys-pma-sso */
define("PHPMYADMIN_KEY", "xxxxVsz3wVGqt");
define("API_HOST_NAME", "xxx");
define("API_HESTIA_PORT", "8083");
define("API_KEY", "gEILYWtD5zkrFAdSFffG:xxxxxx-aPzzlT3IBCuOIlYN6eW5x-=8");
PHPMYADMIN_KEY should be the same in both hestia.conf and hestia-php-sso.
Also it is by default:
if (!password_verify($database . $user . $ip . $time . PHPMYADMIN_KEY, $token)) {
trigger_error(
"Access denied: There is a security token mismatch " . $time,
E_USER_WARNING,
);
session_invalid();
}
And $ip is by default $ip = $api->get_user_ip();
and
public function get_user_ip() {
// Saving user IPs to the session for preventing session hijacking
$user_combined_ip = [];
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["SERVER_ADDR"]) {
$user_combined_ip[] = $_SERVER["REMOTE_ADDR"];
}
if (isset($_SERVER["HTTP_CLIENT_IP"])) {
$user_combined_ip .= "|" . $_SERVER["HTTP_CLIENT_IP"];
}
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["HTTP_X_FORWARDED_FOR"]) {
$user_combined_ip[] = $_SERVER["HTTP_X_FORWARDED_FOR"];
}
}
if (isset($_SERVER["HTTP_FORWARDED_FOR"])) {
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["HTTP_FORWARDED_FOR"]) {
$user_combined_ip[] = $_SERVER["HTTP_FORWARDED_FOR"];
}
}
if (isset($_SERVER["HTTP_X_FORWARDED"])) {
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["HTTP_X_FORWARDED"]) {
$user_combined_ip[] = $_SERVER["HTTP_X_FORWARDED"];
}
}
if (isset($_SERVER["HTTP_FORWARDED"])) {
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["HTTP_FORWARDED"]) {
$user_combined_ip[] = "|" . $_SERVER["HTTP_FORWARDED"];
}
}
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
if (!empty($_SERVER["HTTP_CF_CONNECTING_IP"])) {
$user_combined_ip[] = $_SERVER["HTTP_CF_CONNECTING_IP"];
}
}
return implode("|", $user_combined_ip);
}
Make sure in both cases the IP’s are matching on both the phpmyadmin page and your own panel…
How ever if more assistance is required I happy to help but for a fee…
Finally, found where was the problem. Please ignore all my “presumptions”. I have loaded wrong key. I thought that API KEY ID == PHPMYADMIN_KEY . Issue resolved when I grabbed PHPMYADMIN_KEY from hestia.conf and generated token with it.
Damn, I almost got insane with this one. Issue closed.