96 lines
4.0 KiB
Bash
Executable File
96 lines
4.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# Gemeinsame Hilfsfunktionen beider Spiegel-Container: den EXTERN erzeugten
|
|
# Signing-Key aus dem read-only gemounteten $GPG_SOURCE uebernehmen und
|
|
# pruefen, ob damit unbeaufsichtigt signiert werden kann.
|
|
#
|
|
# ACHTUNG: identische Kopie in dnf-mirror/gpg-import.sh - Aenderungen bitte in
|
|
# beiden pflegen. (Getrennte Build-Kontexte je Image; ein gemeinsamer Kontext
|
|
# wuerde das Schluesselverzeichnis ./gpg in den Build-Kontext ziehen.)
|
|
|
|
# Die Dateien, die ein GnuPG-Homedir ausmachen. Bewusst eine feste Liste statt
|
|
# "cp -a .": im Quellverzeichnis liegen oft noch die Agent-Sockets
|
|
# (S.gpg-agent & Co.) und Lock-Dateien eines gpg-agent, der auf dem HOST
|
|
# lief/laeuft. Die haben im Container nichts verloren.
|
|
GPG_HOME_ENTRIES=(pubring.kbx pubring.gpg secring.gpg trustdb.gpg \
|
|
private-keys-v1.d openpgp-revocs.d public-keys.d)
|
|
|
|
import_shared_gpg() {
|
|
if [ ! -d "$GPG_SOURCE" ]; then
|
|
echo "[gpg] FEHLER: $GPG_SOURCE ist nicht gemountet - fehlt der Ordner ./gpg?" >&2
|
|
return 1
|
|
fi
|
|
|
|
rm -rf "$GNUPGHOME"
|
|
mkdir -p "$GNUPGHOME"
|
|
chmod 700 "$GNUPGHOME"
|
|
|
|
local entry copied=0
|
|
for entry in "${GPG_HOME_ENTRIES[@]}"; do
|
|
[ -e "$GPG_SOURCE/$entry" ] || continue
|
|
# Kein "|| true": schlaegt das Kopieren des Schluesselmaterials fehl,
|
|
# soll das laut und sofort auffallen statt spaeter als "Key nicht
|
|
# gefunden".
|
|
cp -a "$GPG_SOURCE/$entry" "$GNUPGHOME/"
|
|
copied=1
|
|
done
|
|
|
|
if [ "$copied" -eq 0 ]; then
|
|
echo "[gpg] FEHLER: in $GPG_SOURCE liegt kein GnuPG-Schluesselbund." >&2
|
|
echo "[gpg] Erwartet wird der INHALT eines GnuPG-Homedirs (pubring.kbx," >&2
|
|
echo "[gpg] private-keys-v1.d, ...), nicht z.B. eine exportierte .asc-Datei." >&2
|
|
echo "[gpg] Tatsaechlicher Inhalt:" >&2
|
|
ls -la "$GPG_SOURCE" >&2
|
|
return 1
|
|
fi
|
|
|
|
chmod -R go-rwx "$GNUPGHOME"
|
|
|
|
# Signiert wird unbeaufsichtigt, also nie ein Pinentry-Fenster erwarten.
|
|
echo "allow-loopback-pinentry" > "$GNUPGHOME/gpg-agent.conf"
|
|
echo "pinentry-mode loopback" > "$GNUPGHOME/gpg.conf"
|
|
}
|
|
|
|
# Listet die im Homedir tatsaechlich vorhandenen geheimen Schluessel als
|
|
# "<fingerprint> <uid>" - genau das, was als GPG_KEY_ID in die .env gehoert.
|
|
list_available_secret_keys() {
|
|
gpg --batch --list-secret-keys --with-colons 2>/dev/null | awk -F: '
|
|
$1 == "sec" { want = 1; fpr = ""; next }
|
|
$1 == "fpr" && want { fpr = $10; want = 0; next }
|
|
$1 == "uid" && fpr != "" { print " " fpr " " $10; fpr = ""; next }
|
|
'
|
|
}
|
|
|
|
# Prueft nicht nur, OB der Key da ist, sondern ob damit auch wirklich
|
|
# unbeaufsichtigt signiert werden kann - ein passphrasegeschuetzter Key faellt
|
|
# sonst erst mitten im ersten Sync-Lauf auf.
|
|
require_usable_signing_key() {
|
|
if ! gpg --batch --list-secret-keys "$GPG_KEY_ID" >/dev/null 2>&1; then
|
|
echo "[gpg] FEHLER: kein geheimer Schluessel '$GPG_KEY_ID' in ./gpg gefunden." >&2
|
|
local available
|
|
available="$(list_available_secret_keys)"
|
|
if [ -n "$available" ]; then
|
|
echo "[gpg] Vorhanden sind:" >&2
|
|
echo "$available" >&2
|
|
echo "[gpg] Einen dieser Fingerprints als GPG_KEY_ID in die .env eintragen." >&2
|
|
else
|
|
echo "[gpg] Der Schluesselbund enthaelt ueberhaupt keinen GEHEIMEN Schluessel" >&2
|
|
echo "[gpg] (nur oeffentliche?). private-keys-v1.d/ pruefen - dort muss" >&2
|
|
echo "[gpg] mindestens eine .key-Datei liegen." >&2
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
local err
|
|
err="$(printf 'signing-selftest' \
|
|
| gpg --batch --yes --local-user "$GPG_KEY_ID" --detach-sign --output /dev/null - 2>&1)" && {
|
|
echo "[gpg] Gemeinsamen Signing-Key '$GPG_KEY_ID' uebernommen, Testsignatur ok."
|
|
return 0
|
|
}
|
|
|
|
echo "[gpg] FEHLER: Schluessel '$GPG_KEY_ID' ist da, aber Signieren schlaegt fehl:" >&2
|
|
echo "$err" >&2
|
|
echo "[gpg] Haeufigste Ursache: der Key hat eine Passphrase. Unbeaufsichtigtes" >&2
|
|
echo "[gpg] Signieren braucht einen Key OHNE Passphrase (siehe README)." >&2
|
|
return 1
|
|
}
|