diff --git a/PHPGuard/SSHScanner.swift b/PHPGuard/SSHScanner.swift index 56760a0..30c8f2e 100644 --- a/PHPGuard/SSHScanner.swift +++ b/PHPGuard/SSHScanner.swift @@ -19,6 +19,7 @@ enum SSHScanner { if [ -r /etc/os-release ]; then . /etc/os-release printf 'ID=%s\n' "${ID:-unknown}" + printf 'ID_LIKE=%s\n' "${ID_LIKE:-}" printf 'VERSION_ID=%s\n' "${VERSION_ID:-unknown}" printf 'VERSION_CODENAME=%s\n' "${VERSION_CODENAME:-unknown}" fi @@ -28,46 +29,199 @@ enum SSHScanner { done | sort -u printf '===FPM===\n'; systemctl list-units --all --type=service --no-legend --no-pager 2>/dev/null | grep -E 'php[0-9.]+-fpm' || true printf '===NGINX===\n'; grep -Rh 'fastcgi_pass' /etc/nginx/sites-enabled/ 2>/dev/null | sort -u || true + printf '===PACKAGE_MANAGER===\n' + if command -v dpkg-query >/dev/null 2>&1; then + package_manager=apt + elif command -v zypper >/dev/null 2>&1; then + package_manager=zypper + elif command -v apk >/dev/null 2>&1; then + package_manager=apk + elif command -v rpm >/dev/null 2>&1; then + if command -v dnf >/dev/null 2>&1; then + package_manager=dnf + elif command -v yum >/dev/null 2>&1; then + package_manager=yum + else + package_manager=rpm + fi + else + package_manager=unknown + fi + printf '%s\n' "$package_manager" + printf '===PACKAGES===\n' - dpkg-query -W \ - -f='${db:Status-Abbrev} ${binary:Package} ${Version}\n' \ - 'php*' 2>/dev/null | - awk '$1 ~ /^ii/ && $2 ~ /^php/ { print $2, $3 }' | - sort -u || true + case "$package_manager" in + apt) + dpkg-query -W \ + -f='${db:Status-Abbrev} ${binary:Package} ${Version}\n' \ + 'php*' 2>/dev/null | + awk '$1 ~ /^ii/ && $2 ~ /^php/ { print $2, $3 }' | + sort -u || true + ;; + + dnf|yum|rpm|zypper) + rpm -qa \ + --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' \ + 2>/dev/null | + awk '$1 ~ /^php/ || $1 ~ /^rh-php/' | + sort -u || true + ;; + + apk) + apk info -v 2>/dev/null | + grep -E '^php[0-9]*-' | + sort -u || true + ;; + + *) + printf 'Package manager unsupported\n' + ;; + esac printf '===PACKAGE_SOURCES===\n' - dpkg-query -W \ - -f='${db:Status-Abbrev}|${binary:Package}|${Version}|${source:Package}|${source:Version}\n' \ - 'php*' 2>/dev/null | - while IFS='|' read -r state binary version src srcversion; do - case "$state" in ii*) ;; *) continue ;; esac - case "$binary" in php*) ;; *) continue ;; esac + case "$package_manager" in + apt) + dpkg-query -W \ + -f='${db:Status-Abbrev}|${binary:Package}|${Version}|${source:Package}|${source:Version}\n' \ + 'php*' 2>/dev/null | + while IFS='|' read -r state binary version src srcversion; do + case "$state" in ii*) ;; *) continue ;; esac + case "$binary" in php*) ;; *) continue ;; esac - [ -n "$version" ] || continue - [ -n "$src" ] || src="$binary" - [ -n "$srcversion" ] || srcversion="$version" + [ -n "$version" ] || continue + [ -n "$src" ] || src="$binary" + [ -n "$srcversion" ] || srcversion="$version" + + printf '%s|%s|%s|%s\n' \ + "$binary" "$version" "$src" "$srcversion" + done + ;; + + dnf|yum|rpm|zypper) + rpm -qa \ + --queryformat '%{NAME}|%{VERSION}-%{RELEASE}|%{SOURCERPM}\n' \ + 2>/dev/null | + while IFS='|' read -r binary version source_rpm; do + case "$binary" in + php*|rh-php*) ;; + *) continue ;; + esac + + [ -n "$version" ] || continue + + printf '%s|%s|%s|%s\n' \ + "$binary" "$version" "$source_rpm" "$version" + done + ;; + + apk) + apk info -v 2>/dev/null | + while IFS= read -r entry; do + case "$entry" in php*) ;; *) continue ;; esac + + name=$(printf '%s\n' "$entry" | + sed -E 's/-[0-9]+(\.[0-9]+)+(-r[0-9]+)?$//') + + version=${entry#"$name"-} + + [ "$version" != "$entry" ] || continue + + printf '%s|%s|%s|%s\n' \ + "$name" "$version" "$name" "$version" + done + ;; + esac - printf '%s|%s|%s|%s\n' \ - "$binary" "$version" "$src" "$srcversion" - done printf '===UPDATES===\n' - if command -v apt >/dev/null 2>&1; then - apt list --upgradable 2>/dev/null | grep -E '^php[^ /]*/' || true - else - printf 'Package manager not supported\n' - fi + case "$package_manager" in + apt) + if command -v apt >/dev/null 2>&1; then + apt list --upgradable 2>/dev/null | + grep -E '^php[^ /]*/' || true + fi + ;; + + dnf) + dnf -q --cacheonly check-update 'php*' \ + 2>/dev/null || true + ;; + + yum) + yum -q -C check-update 'php*' \ + 2>/dev/null || true + ;; + + zypper) + zypper --non-interactive --no-refresh \ + list-updates 2>/dev/null | + grep -Ei '(^|[[:space:]|])php' || true + ;; + + apk) + apk version -l '<' 2>/dev/null | + grep -E '^php' || true + ;; + + *) + printf 'Update metadata unavailable\n' + ;; + esac + printf '===PACKAGE_ORIGINS===\n' - if command -v apt-cache >/dev/null 2>&1; then - dpkg-query -W -f='${Package}\n' 'php*' 2>/dev/null | grep -E '^php[0-9.-]*([a-z-]+)?$' | sort -u | while IFS= read -r pkg; do - [ -n "$pkg" ] || continue - installed=$(dpkg-query -W -f='${Version}' "$pkg" 2>/dev/null || true) - candidate=$(apt-cache policy "$pkg" 2>/dev/null | sed -n 's/^[[:space:]]*Candidate: //p' | head -1) - printf '%s installed=%s candidate=%s\n' "$pkg" "$installed" "${candidate:-unknown}" - apt-cache policy "$pkg" 2>/dev/null | grep -E 'https?://|/ubuntu |/ubuntu$' | head -3 | sed 's/^[[:space:]]*/ /' - done - else - printf 'APT metadata unavailable\n' - fi + case "$package_manager" in + apt) + if command -v apt-cache >/dev/null 2>&1; then + dpkg-query -W -f='${Package}\n' 'php*' \ + 2>/dev/null | + grep -E '^php[0-9.-]*([a-z-]+)?$' | + sort -u | + while IFS= read -r pkg; do + [ -n "$pkg" ] || continue + + installed=$(dpkg-query -W -f='${Version}' \ + "$pkg" 2>/dev/null || true) + + candidate=$(apt-cache policy "$pkg" 2>/dev/null | + sed -n 's/^[[:space:]]*Candidate: //p' | + head -1) + + printf '%s installed=%s candidate=%s\n' \ + "$pkg" "$installed" "${candidate:-unknown}" + + apt-cache policy "$pkg" 2>/dev/null | + grep -E 'https?://|/ubuntu |/ubuntu$' | + head -3 | + sed 's/^[[:space:]]*/ /' + done + else + printf 'APT metadata unavailable\n' + fi + ;; + + dnf|yum|rpm|zypper) + rpm -qa \ + --queryformat '%{NAME} installed=%{VERSION}-%{RELEASE} vendor=%{VENDOR}\n' \ + 2>/dev/null | + grep -E '^(php|rh-php)' | + sort -u || true + ;; + + apk) + printf 'Alpine repositories:\n' + + if [ -r /etc/apk/repositories ]; then + grep -v '^[[:space:]]*#' /etc/apk/repositories | + grep -v '^[[:space:]]*$' + else + printf 'Repository metadata unavailable\n' + fi + ;; + + *) + printf 'Package origins unavailable\n' + ;; + esac + printf '===DOCKER===\n' if ! command -v docker >/dev/null 2>&1; then printf 'STATUS|not-installed\n'