Fix: Validate existing package repositories
This commit is contained in:
+179
-21
@@ -70,6 +70,7 @@ PANAMA_PATH="${PANAMA_PATH:-$HOME/.local/share/Panama}"
|
||||
# Kept as a named path so the hermetic contract can redirect reads after
|
||||
# sourcing this file. Normal installer execution always resets it to /etc.
|
||||
PANAMA_SYSTEM_ETC=/etc
|
||||
PANAMA_SYSTEM_FLATPAK_REPO=/var/lib/flatpak/repo
|
||||
|
||||
# Reviewed installer data and verification primitives. The config parser treats
|
||||
# every value as inert data and rejects unknown, duplicate, or missing fields.
|
||||
@@ -268,10 +269,129 @@ _ini_value() {
|
||||
}
|
||||
}
|
||||
' "$file")
|
||||
[[ ${#values[@]} -eq 1 && -n "${values[0]}" ]] || return 1
|
||||
(( ${#values[@]} > 0 )) || return 1
|
||||
[[ ${#values[@]} -eq 1 && -n "${values[0]}" ]] || return 2
|
||||
printf '%s\n' "${values[0]}"
|
||||
}
|
||||
|
||||
_ini_section_count() {
|
||||
local file="$1" wanted_section="$2"
|
||||
awk -v wanted_section="$wanted_section" '
|
||||
function trim(value) {
|
||||
sub(/^[[:space:]]+/, "", value)
|
||||
sub(/[[:space:]]+$/, "", value)
|
||||
return value
|
||||
}
|
||||
{
|
||||
sub(/\r$/, "")
|
||||
line = trim($0)
|
||||
if (line ~ /^\[[^]]+\]$/) {
|
||||
section = substr(line, 2, length(line) - 2)
|
||||
if (tolower(section) == tolower(wanted_section)) count++
|
||||
}
|
||||
}
|
||||
END { print count + 0 }
|
||||
' "$file"
|
||||
}
|
||||
|
||||
_restore_repository_file() {
|
||||
local existed="$1" backup="$2" mode="$3" destination="$4"
|
||||
if (( existed )); then
|
||||
sudo install -m "$mode" "$backup" "$destination"
|
||||
else
|
||||
sudo rm -f -- "$destination"
|
||||
fi
|
||||
}
|
||||
|
||||
# A key and its repository file form one trust root. If either activation
|
||||
# write fails after touching its target, restore both prior files or return both
|
||||
# targets to absence before reporting failure.
|
||||
_publish_repository_pair() {
|
||||
local staged_key="$1" key_destination="$2" staged_repo="$3" repo_destination="$4"
|
||||
local backup_dir key_backup repo_backup key_mode=0644 repo_mode=0644
|
||||
local key_current repo_current
|
||||
local key_existed=0 repo_existed=0 status=0 rollback_status=0
|
||||
|
||||
[[ "$key_destination" == /etc/* && "$repo_destination" == /etc/* ]] || return 1
|
||||
key_current="$PANAMA_SYSTEM_ETC${key_destination#/etc}"
|
||||
repo_current="$PANAMA_SYSTEM_ETC${repo_destination#/etc}"
|
||||
[[ ! -L "$key_current" && ! -L "$repo_current" ]] || return 1
|
||||
backup_dir="$(dirname -- "$staged_key")"
|
||||
key_backup="$backup_dir/prior-key"
|
||||
repo_backup="$backup_dir/prior-repo"
|
||||
if [[ -e "$key_current" ]]; then
|
||||
[[ -f "$key_current" ]] || return 1
|
||||
cp -- "$key_current" "$key_backup" || return 1
|
||||
key_mode="$(stat -c %a "$key_current")" || return 1
|
||||
key_existed=1
|
||||
fi
|
||||
if [[ -e "$repo_current" ]]; then
|
||||
[[ -f "$repo_current" ]] || return 1
|
||||
cp -- "$repo_current" "$repo_backup" || return 1
|
||||
repo_mode="$(stat -c %a "$repo_current")" || return 1
|
||||
repo_existed=1
|
||||
fi
|
||||
|
||||
sudo install -m 0644 "$staged_key" "$key_destination" || status=$?
|
||||
if (( status == 0 )); then
|
||||
sudo install -m 0644 "$staged_repo" "$repo_destination" || status=$?
|
||||
fi
|
||||
(( status == 0 )) && return 0
|
||||
|
||||
_restore_repository_file "$repo_existed" "$repo_backup" "$repo_mode" "$repo_destination" \
|
||||
|| rollback_status=$?
|
||||
_restore_repository_file "$key_existed" "$key_backup" "$key_mode" "$key_destination" \
|
||||
|| rollback_status=$?
|
||||
(( rollback_status == 0 )) || log "Repository activation rollback did not complete"
|
||||
return "$status"
|
||||
}
|
||||
|
||||
_terra_repository_is_trusted() {
|
||||
local repo_file baseurl enabled gpgcheck repo_gpgcheck gpgkey local_key
|
||||
repo_file="$PANAMA_SYSTEM_ETC/yum.repos.d/terra.repo"
|
||||
[[ -f "$repo_file" ]] || return 1
|
||||
baseurl="$(_ini_value "$repo_file" terra baseurl)" || return 1
|
||||
enabled="$(_ini_value "$repo_file" terra enabled)" || return 1
|
||||
gpgcheck="$(_ini_value "$repo_file" terra gpgcheck)" || return 1
|
||||
repo_gpgcheck="$(_ini_value "$repo_file" terra repo_gpgcheck)" || return 1
|
||||
gpgkey="$(_ini_value "$repo_file" terra gpgkey)" || return 1
|
||||
[[ "$baseurl" == "${INSTALLER_PROVENANCE[TERRA_BASEURL]}" \
|
||||
&& "$enabled" == 1 && "$gpgcheck" == 1 && "$repo_gpgcheck" == 1 \
|
||||
&& "$gpgkey" == 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama' ]] || return 1
|
||||
local_key="$PANAMA_SYSTEM_ETC/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama"
|
||||
[[ -f "$local_key" ]] || return 1
|
||||
key_fingerprint_matches "$PANAMA_PATH/setup/provenance/keys/terra44.asc" \
|
||||
"${INSTALLER_PROVENANCE[TERRA_FINGERPRINT]}" \
|
||||
&& key_fingerprint_matches "$local_key" \
|
||||
"${INSTALLER_PROVENANCE[TERRA_FINGERPRINT]}"
|
||||
}
|
||||
|
||||
# Status 0 is trusted, 1 is absent, and 2 is present but untrusted or malformed.
|
||||
_flathub_remote_status() {
|
||||
local config section_count url gpg_verify summary_verify disabled disabled_status
|
||||
config="$PANAMA_SYSTEM_FLATPAK_REPO/config"
|
||||
[[ -f "$config" ]] || return 1
|
||||
section_count="$(_ini_section_count "$config" 'remote "flathub"')" || return 2
|
||||
(( section_count > 0 )) || return 1
|
||||
(( section_count == 1 )) || return 2
|
||||
url="$(_ini_value "$config" 'remote "flathub"' url)" || return 2
|
||||
gpg_verify="$(_ini_value "$config" 'remote "flathub"' gpg-verify)" || return 2
|
||||
summary_verify="$(_ini_value "$config" 'remote "flathub"' gpg-verify-summary)" || return 2
|
||||
[[ "$url" == 'https://dl.flathub.org/repo/' ]] || return 2
|
||||
case "${gpg_verify,,}" in true|yes|1) ;; *) return 2 ;; esac
|
||||
case "${summary_verify,,}" in true|yes|1) ;; *) return 2 ;; esac
|
||||
disabled_status=0
|
||||
disabled="$(_ini_value "$config" 'remote "flathub"' xa.disable)" || disabled_status=$?
|
||||
if (( disabled_status == 0 )); then
|
||||
case "${disabled,,}" in true|yes|1) return 2 ;; esac
|
||||
elif (( disabled_status != 1 )); then
|
||||
return 2
|
||||
fi
|
||||
[[ -f "$PANAMA_SYSTEM_FLATPAK_REPO/flathub.trustedkeys.gpg" ]] || return 2
|
||||
key_fingerprint_matches "$PANAMA_SYSTEM_FLATPAK_REPO/flathub.trustedkeys.gpg" \
|
||||
"${INSTALLER_PROVENANCE[FLATHUB_FINGERPRINT]}" || return 2
|
||||
}
|
||||
|
||||
install_rpmfusion_repositories() {
|
||||
local work free_rpm nonfree_rpm
|
||||
require_reviewed_fedora_release || return 1
|
||||
@@ -308,16 +428,22 @@ install_rpmfusion_repositories() {
|
||||
}
|
||||
|
||||
install_terra_repository() {
|
||||
local work staged_key status
|
||||
local work staged_key staged_repo status
|
||||
require_reviewed_fedora_release || return 1
|
||||
if rpm -q terra-release >/dev/null 2>&1; then
|
||||
log "Terra repository already installed"
|
||||
return 0
|
||||
fi
|
||||
_require_policy_value TERRA_BASEURL 'https://repos.fyralabs.com/terra44' || return 1
|
||||
_require_policy_value TERRA_FINGERPRINT AE09157A4DE88B497EA1D5D300CDAB43DE226D6F || return 1
|
||||
if rpm -q terra-release >/dev/null 2>&1; then
|
||||
if _terra_repository_is_trusted; then
|
||||
log "Terra repository already installed and verified"
|
||||
return 0
|
||||
fi
|
||||
log "Installed Terra repository does not match Panama's reviewed trust policy"
|
||||
return 1
|
||||
fi
|
||||
work="$(mktemp -d)" || return 1
|
||||
chmod 0700 "$work"
|
||||
staged_key="$work/terra44.asc"
|
||||
staged_repo="$work/terra.repo"
|
||||
if ! _stage_reviewed_key "$PANAMA_PATH/setup/provenance/keys/terra44.asc" "$staged_key" \
|
||||
TERRA_FINGERPRINT AE09157A4DE88B497EA1D5D300CDAB43DE226D6F; then
|
||||
rm -rf -- "$work"
|
||||
@@ -327,6 +453,15 @@ install_terra_repository() {
|
||||
rm -rf -- "$work"
|
||||
return 1
|
||||
}
|
||||
printf '%s\n' \
|
||||
'[terra]' \
|
||||
'name=Panama reviewed Terra 44' \
|
||||
"baseurl=${INSTALLER_PROVENANCE[TERRA_BASEURL]}" \
|
||||
'enabled=1' \
|
||||
'gpgcheck=1' \
|
||||
'repo_gpgcheck=1' \
|
||||
'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama' > "$staged_repo"
|
||||
chmod 0600 "$staged_repo"
|
||||
status=0
|
||||
sudo dnf install -y \
|
||||
--repofrompath "terra,${INSTALLER_PROVENANCE[TERRA_BASEURL]}" \
|
||||
@@ -334,6 +469,12 @@ install_terra_repository() {
|
||||
--setopt=terra.repo_gpgcheck=1 \
|
||||
--setopt=terra.gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama \
|
||||
terra-release || status=$?
|
||||
if (( status == 0 )); then
|
||||
sudo install -m 0644 "$staged_repo" /etc/yum.repos.d/terra.repo || status=$?
|
||||
fi
|
||||
if (( status == 0 )) && ! _terra_repository_is_trusted; then
|
||||
status=1
|
||||
fi
|
||||
rm -rf -- "$work"
|
||||
return "$status"
|
||||
}
|
||||
@@ -363,22 +504,28 @@ configure_hyprland_repository() {
|
||||
'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland' > "$staged_repo"
|
||||
chmod 0600 "$staged_repo"
|
||||
status=0
|
||||
sudo install -m 0644 "$staged_key" /etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland \
|
||||
|| status=$?
|
||||
if (( status == 0 )); then
|
||||
sudo install -m 0644 "$staged_repo" /etc/yum.repos.d/panama-hyprland.repo \
|
||||
|| status=$?
|
||||
fi
|
||||
_publish_repository_pair \
|
||||
"$staged_key" /etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland \
|
||||
"$staged_repo" /etc/yum.repos.d/panama-hyprland.repo || status=$?
|
||||
rm -rf -- "$work"
|
||||
return "$status"
|
||||
}
|
||||
|
||||
ensure_flathub_remote() {
|
||||
local work descriptor encoded key_file url no_gpg_verify gpg_verify status
|
||||
local work descriptor encoded key_file url no_gpg_verify gpg_verify
|
||||
local status remote_status no_gpg_status gpg_status
|
||||
require_reviewed_fedora_release || return 1
|
||||
_require_policy_value FLATHUB_DESCRIPTOR_URL 'https://flathub.org/repo/flathub.flatpakrepo' || return 1
|
||||
_require_policy_value FLATHUB_DESCRIPTOR_MAX_BYTES 1048576 || return 1
|
||||
_require_policy_value FLATHUB_FINGERPRINT 6E5C05D979C76DAF93C081354184DD4D907A7CAE || return 1
|
||||
remote_status=0
|
||||
_flathub_remote_status || remote_status=$?
|
||||
if (( remote_status == 0 )); then
|
||||
return 0
|
||||
elif (( remote_status != 1 )); then
|
||||
log "Existing Flathub remote does not match Panama's reviewed trust policy"
|
||||
return 1
|
||||
fi
|
||||
work="$(mktemp -d)" || return 1
|
||||
chmod 0700 "$work"
|
||||
descriptor="$work/flathub.flatpakrepo"
|
||||
@@ -392,11 +539,22 @@ ensure_flathub_remote() {
|
||||
rm -rf -- "$work"
|
||||
return 1
|
||||
fi
|
||||
if no_gpg_verify="$(_ini_value "$descriptor" 'Flatpak Repo' NoGPGVerify)"; then
|
||||
no_gpg_status=0
|
||||
no_gpg_verify="$(_ini_value "$descriptor" 'Flatpak Repo' NoGPGVerify)" \
|
||||
|| no_gpg_status=$?
|
||||
if (( no_gpg_status == 0 )); then
|
||||
case "${no_gpg_verify,,}" in true|yes|1) rm -rf -- "$work"; return 1 ;; esac
|
||||
elif (( no_gpg_status != 1 )); then
|
||||
rm -rf -- "$work"
|
||||
return 1
|
||||
fi
|
||||
if gpg_verify="$(_ini_value "$descriptor" 'Flatpak Repo' GPGVerify)"; then
|
||||
gpg_status=0
|
||||
gpg_verify="$(_ini_value "$descriptor" 'Flatpak Repo' GPGVerify)" || gpg_status=$?
|
||||
if (( gpg_status == 0 )); then
|
||||
case "${gpg_verify,,}" in false|no|0) rm -rf -- "$work"; return 1 ;; esac
|
||||
elif (( gpg_status != 1 )); then
|
||||
rm -rf -- "$work"
|
||||
return 1
|
||||
fi
|
||||
if ! key_fingerprint_matches "$key_file" "${INSTALLER_PROVENANCE[FLATHUB_FINGERPRINT]}"; then
|
||||
rm -rf -- "$work"
|
||||
@@ -405,6 +563,9 @@ ensure_flathub_remote() {
|
||||
status=0
|
||||
sudo flatpak remote-add --if-not-exists --gpg-import="$key_file" flathub "$url" \
|
||||
|| status=$?
|
||||
if (( status == 0 )); then
|
||||
_flathub_remote_status || status=$?
|
||||
fi
|
||||
rm -rf -- "$work"
|
||||
return "$status"
|
||||
}
|
||||
@@ -436,12 +597,9 @@ install_claude_code() {
|
||||
'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama' > "$staged_repo"
|
||||
chmod 0600 "$staged_repo"
|
||||
status=0
|
||||
sudo install -m 0644 "$staged_key" /etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama \
|
||||
|| status=$?
|
||||
if (( status == 0 )); then
|
||||
sudo install -m 0644 "$staged_repo" /etc/yum.repos.d/claude-code.repo \
|
||||
|| status=$?
|
||||
fi
|
||||
_publish_repository_pair \
|
||||
"$staged_key" /etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama \
|
||||
"$staged_repo" /etc/yum.repos.d/claude-code.repo || status=$?
|
||||
if (( status == 0 )); then
|
||||
sudo dnf install -y claude-code || status=$?
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user