ba64342702
phpMyAdmin login was broken because phpmyadmin_install.sh never wired the private phpMyAdmin copy into the web server: no Apache Alias was registered via DirectAdmin CustomBuild, so the SSO redirect target was unreachable. Add configure_apache_alias()/apply_apache_alias() (Alias + Directory blocks, ./build rewrite_confs, httpd reload), detect the real Apache group instead of hardcoding diradmin:diradmin, stop silently swallowing chown/chmod failures, and verify an optional SHA256 for the downloaded phpMyAdmin tarball. Extend phpmyadmin_health_check.sh to detect a missing/incorrect Apache alias and to probe HTTP reachability. Security hardening: scope temporary phpMyAdmin SSO MySQL roles to 127.0.0.1 instead of '%', tighten SSO ticket file permissions to 0640 (they contain a plaintext MySQL password), and log MySQL connection failures for diagnosis instead of swallowing them silently. Bump version to 1.2.12 and rebuild the release archive.
169 lines
6.9 KiB
Bash
169 lines
6.9 KiB
Bash
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
SCRIPT="$PLUGIN_DIR/scripts/setup/phpmyadmin_install.sh"
|
|
TMP_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
grep -Fq 'PHPMYADMIN_VERSION="${PHPMYADMIN_VERSION:-5.2.3}"' "$SCRIPT" \
|
|
|| fail "phpMyAdmin default version is not 5.2.3"
|
|
grep -Fq 'PHPMYADMIN_TARBALL_URL="${PHPMYADMIN_TARBALL_URL:-https://files.phpmyadmin.net/phpMyAdmin/5.2.3/phpMyAdmin-5.2.3-all-languages.tar.gz}"' "$SCRIPT" \
|
|
|| fail "phpMyAdmin tarball URL is not the explicit 5.2.3 URL"
|
|
|
|
mkdir -p "$TMP_DIR/phpMyAdmin-source"
|
|
cat > "$TMP_DIR/phpMyAdmin-source/index.php" <<'PHP'
|
|
<?php
|
|
echo 'private phpMyAdmin';
|
|
PHP
|
|
|
|
CUSTOMBUILD_DIR="$TMP_DIR/custombuild"
|
|
mkdir -p "$CUSTOMBUILD_DIR"
|
|
|
|
PHPMYADMIN_PRIVATE_DIR="$TMP_DIR/alt-mysql-phpmyadmin" \
|
|
PHPMYADMIN_SOURCE_DIR="$TMP_DIR/phpMyAdmin-source" \
|
|
PHPMYADMIN_INSTALL_ASSUME_ROOT=1 \
|
|
CUSTOMBUILD_DIR="$CUSTOMBUILD_DIR" \
|
|
bash "$SCRIPT" >/dev/null
|
|
|
|
PRIVATE_DIR="$TMP_DIR/alt-mysql-phpmyadmin"
|
|
CONFIG_INC="$PRIVATE_DIR/config.inc.php"
|
|
SIGNON_SCRIPT="$PRIVATE_DIR/da_signon.php"
|
|
SIGNON_URL_PAGE="$PRIVATE_DIR/da_login.php"
|
|
TICKET_DIR="$PRIVATE_DIR/runtime/tickets"
|
|
SESSION_DIR="$TMP_DIR/sessions"
|
|
ALIAS_CONF="$CUSTOMBUILD_DIR/custom/ap2/conf/extra/httpd-alias.conf"
|
|
|
|
[ -r "$PRIVATE_DIR/index.php" ] || fail "private phpMyAdmin copy was not installed"
|
|
[ -r "$CONFIG_INC" ] || fail "private phpMyAdmin config was not created"
|
|
[ -r "$SIGNON_SCRIPT" ] || fail "signon script was not created"
|
|
[ -r "$SIGNON_URL_PAGE" ] || fail "phpMyAdmin SignonURL page was not created"
|
|
[ -d "$TICKET_DIR" ] || fail "phpMyAdmin ticket directory was not created"
|
|
|
|
[ -r "$ALIAS_CONF" ] || fail "Apache alias config was not created"
|
|
grep -Fq "# BEGIN ALT_MYSQL_PHPMYADMIN" "$ALIAS_CONF" || fail "Apache alias block marker missing"
|
|
grep -Fq "Alias /alt-mysql-phpmyadmin ${PRIVATE_DIR}" "$ALIAS_CONF" || fail "Apache alias does not point at private phpMyAdmin dir"
|
|
grep -Fq "# END ALT_MYSQL_PHPMYADMIN" "$ALIAS_CONF" || fail "Apache alias end marker missing"
|
|
|
|
PHPMYADMIN_PRIVATE_DIR="$TMP_DIR/alt-mysql-phpmyadmin" \
|
|
PHPMYADMIN_SOURCE_DIR="$TMP_DIR/phpMyAdmin-source" \
|
|
PHPMYADMIN_INSTALL_ASSUME_ROOT=1 \
|
|
CUSTOMBUILD_DIR="$CUSTOMBUILD_DIR" \
|
|
bash "$SCRIPT" >/dev/null
|
|
|
|
BEGIN_COUNT="$(grep -Fc "# BEGIN ALT_MYSQL_PHPMYADMIN" "$ALIAS_CONF" || true)"
|
|
[ "$BEGIN_COUNT" -eq 1 ] || fail "Apache alias block was duplicated on re-run (found $BEGIN_COUNT times)"
|
|
|
|
SERVER_JSON="$(php -r '
|
|
$_SERVER["HTTPS"] = "on";
|
|
$_SERVER["HTTP_HOST"] = "panel.example.test";
|
|
$cfg=[];
|
|
include $argv[1];
|
|
echo json_encode($cfg["Servers"][1] ?? []);
|
|
' "$CONFIG_INC")"
|
|
php -r '
|
|
$server = json_decode($argv[1], true);
|
|
if (($server["host"] ?? "") !== "127.0.0.1") {
|
|
fwrite(STDERR, "host mismatch\n");
|
|
exit(2);
|
|
}
|
|
if ((string)($server["port"] ?? "") !== "33033") {
|
|
fwrite(STDERR, "port mismatch\n");
|
|
exit(3);
|
|
}
|
|
if (($server["socket"] ?? "not-empty") !== "") {
|
|
fwrite(STDERR, "socket mismatch\n");
|
|
exit(4);
|
|
}
|
|
if (($server["SignonURL"] ?? "") !== "https://panel.example.test/alt-mysql-phpmyadmin/da_login.php") {
|
|
fwrite(STDERR, "SignonURL mismatch\n");
|
|
exit(5);
|
|
}
|
|
if (($server["LogoutURL"] ?? "") !== "https://panel.example.test/alt-mysql-phpmyadmin/da_login.php") {
|
|
fwrite(STDERR, "LogoutURL mismatch\n");
|
|
exit(6);
|
|
}
|
|
' "$SERVER_JSON" || fail "phpMyAdmin config does not target alt-mariadb TCP endpoint"
|
|
grep -Fq 'return [$username, $password];' "$SIGNON_SCRIPT" \
|
|
|| fail "signon script should return username/password only"
|
|
php -d display_errors=1 -r 'set_error_handler(static function($errno, $errstr) { fwrite(STDERR, $errstr . "\n"); exit(9); }); $cfg=[]; include $argv[1]; include $argv[2];' "$CONFIG_INC" "$SIGNON_SCRIPT" \
|
|
|| fail "phpMyAdmin config and signon script cannot be loaded in one PHP process"
|
|
|
|
mkdir -p "$SESSION_DIR"
|
|
cat > "$TICKET_DIR/0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.json" <<'JSON'
|
|
{"version":1,"expires_at":4102444800,"auth":{"user":"da_tmp_phpmyadmin_test","password":"secret","db":"user_db"},"route":"/database/structure","db":"user_db"}
|
|
JSON
|
|
php -d display_errors=1 -d session.save_path="$SESSION_DIR" -r '
|
|
$_GET["ticket"] = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
|
|
$_COOKIE["DA_MYSQL_PHPMYADMIN"] = "tickettest";
|
|
$_SERVER["HTTPS"] = "on";
|
|
$_SERVER["HTTP_HOST"] = "panel.example.test";
|
|
include $argv[1];
|
|
' "$SIGNON_URL_PAGE" >/tmp/altmysql-da-login-test.out 2>/tmp/altmysql-da-login-test.err \
|
|
|| fail "da_login.php did not accept a valid ticket"
|
|
[ ! -e "$TICKET_DIR/0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.json" ] \
|
|
|| fail "da_login.php did not consume the SSO ticket"
|
|
php -d session.save_path="$SESSION_DIR" -r '
|
|
session_name("DA_MYSQL_PHPMYADMIN");
|
|
session_id("tickettest");
|
|
session_start();
|
|
$auth = $_SESSION["DA_MYSQL_PHPMYADMIN_AUTH"] ?? [];
|
|
if (($auth["user"] ?? "") !== "da_tmp_phpmyadmin_test") {
|
|
fwrite(STDERR, "session user mismatch\n");
|
|
exit(2);
|
|
}
|
|
if (($auth["password"] ?? "") !== "secret") {
|
|
fwrite(STDERR, "session password mismatch\n");
|
|
exit(3);
|
|
}
|
|
if (($auth["db"] ?? "") !== "user_db") {
|
|
fwrite(STDERR, "session db mismatch\n");
|
|
exit(4);
|
|
}
|
|
' || fail "da_login.php did not create the phpMyAdmin signon session"
|
|
php -d session.save_path="$SESSION_DIR" -r '
|
|
session_name("DA_MYSQL_PHPMYADMIN");
|
|
session_id("tickettest");
|
|
session_start();
|
|
$_SESSION["DA_MYSQL_PHPMYADMIN_AUTH"] = [
|
|
"user" => "da_tmp_phpmyadmin_test",
|
|
"password" => "secret",
|
|
"db" => "user_db",
|
|
];
|
|
session_write_close();
|
|
|
|
session_name("phpmyadmin");
|
|
session_id("pmaactive");
|
|
session_start();
|
|
$_SESSION["unrelated"] = "active phpMyAdmin session";
|
|
$_COOKIE["DA_MYSQL_PHPMYADMIN"] = "tickettest";
|
|
include $argv[1];
|
|
[$username, $password] = get_login_credentials("ignored");
|
|
if ($username !== "da_tmp_phpmyadmin_test") {
|
|
fwrite(STDERR, "signon user mismatch with active phpMyAdmin session\n");
|
|
exit(2);
|
|
}
|
|
if ($password !== "secret") {
|
|
fwrite(STDERR, "signon password mismatch with active phpMyAdmin session\n");
|
|
exit(3);
|
|
}
|
|
' "$SIGNON_SCRIPT" || fail "signon script cannot read SSO session while phpMyAdmin session is active"
|
|
PHPMYADMIN_PRIVATE_DIR="$PRIVATE_DIR" CUSTOMBUILD_DIR="$CUSTOMBUILD_DIR" \
|
|
bash "$PLUGIN_DIR/scripts/setup/phpmyadmin_health_check.sh" >/dev/null \
|
|
|| fail "phpMyAdmin health check should pass for SignonURL-capable config with Apache alias present"
|
|
|
|
EMPTY_CUSTOMBUILD_DIR="$TMP_DIR/custombuild-empty"
|
|
mkdir -p "$EMPTY_CUSTOMBUILD_DIR"
|
|
HEALTH_OUTPUT="$(PHPMYADMIN_PRIVATE_DIR="$PRIVATE_DIR" CUSTOMBUILD_DIR="$EMPTY_CUSTOMBUILD_DIR" \
|
|
bash "$PLUGIN_DIR/scripts/setup/phpmyadmin_health_check.sh" 2>&1)" \
|
|
&& fail "phpMyAdmin health check should fail when the Apache alias is missing"
|
|
echo "$HEALTH_OUTPUT" | grep -Fqi "alias" \
|
|
|| fail "phpMyAdmin health check failure message should mention the missing Apache alias (got: $HEALTH_OUTPUT)"
|
|
|
|
echo "phpmyadmin_install_test: OK"
|