From e799682e107a3f33fc96e9091ff8e074ef9ef494 Mon Sep 17 00:00:00 2001 From: Denis Stoecklmeier Date: Thu, 15 Oct 2026 10:43:37 +0200 Subject: [PATCH] Inventarzugang sicher in Werkstatt-Build einbetten --- .gitignore | 1 + README.md | 10 +++++++- scripts/build-standalone.sh | 49 ++++++++++++++++++++++++++++++++++--- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index d5f9568..cf1709a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /build/ /dist/ +/.bundle-secrets/ /**/target/ __pycache__/ *.py[cod] diff --git a/README.md b/README.md index 661405c..b85e0c6 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,15 @@ bash scripts/build-release.sh Das Ergebnis liegt in `dist/csr-intake-x86_64.run`. `build/release.json` enthält Build-ID, Versionen und SHA-256-Prüfsummen der eingebetteten Programme. Die CI stellt -dieselbe `.run`-Datei bei jedem erfolgreichen Build als Artefakt bereit. +bei jedem erfolgreichen Build eine neutrale `.run`-Datei ohne Zugangsdaten als +Artefakt bereit. + +Für eine werkstattgebundene Datei können `inventory-api-key` und +`inventory-server.crt` vor dem Build in `.bundle-secrets/` abgelegt werden. Der Build +bettet sie dann zusammen mit der Serveradresse ein und setzt die fertige Datei auf +Modus `0700`. Beim ersten Start werden fehlende Konfigurationsdateien unter +`config/` angelegt; vorhandene Werte bleiben erhalten. Eine solche Datei enthält +einen lesbaren Zugangsschlüssel und darf nur wie ein Passwort weitergegeben werden. ## Projektaufbau diff --git a/scripts/build-standalone.sh b/scripts/build-standalone.sh index 92d987c..48df551 100755 --- a/scripts/build-standalone.sh +++ b/scripts/build-standalone.sh @@ -6,6 +6,7 @@ OUT=${1:-$ROOT/dist/csr-intake-x86_64.run} GUI="$ROOT/gui/target/release/intake-gui" SCANNER="$ROOT/scanner/target/release/pc-intake" MANIFEST="$ROOT/build/release.json" +BUNDLE_CONFIG=${CSR_BUNDLE_CONFIG_DIR:-$ROOT/.bundle-secrets} for file in "$GUI" "$SCANNER" "$MANIFEST"; do [[ -f $file ]] || { @@ -33,9 +34,31 @@ install -m755 "$GUI" "$TMP/app/intake-gui" install -m755 "$SCANNER" "$TMP/app/pc-intake" install -m644 "$MANIFEST" "$TMP/app/release.json" python3 "$ROOT/scripts/release-manifest.py" --verify-release "$TMP/app" + +contains_credentials=0 +if [[ -f $BUNDLE_CONFIG/inventory-api-key && -f $BUNDLE_CONFIG/inventory-server.crt ]]; then + key=$(tr -d '\r\n' < "$BUNDLE_CONFIG/inventory-api-key") + [[ -n $key && $key != *[[:space:]]* ]] || { + echo 'Bundled inventory API key is empty or malformed.' >&2 + exit 2 + } + openssl x509 -in "$BUNDLE_CONFIG/inventory-server.crt" -noout -checkend 0 >/dev/null || { + echo 'Bundled inventory certificate is invalid or expired.' >&2 + exit 2 + } + mkdir -m700 "$TMP/app/default-config" + install -m600 "$BUNDLE_CONFIG/inventory-api-key" "$TMP/app/default-config/inventory-api-key" + install -m600 "$BUNDLE_CONFIG/inventory-server.crt" "$TMP/app/default-config/inventory-server.crt" + printf '%s\n' '{"url":"https://192.168.178.17"}' > "$TMP/app/default-config/inventory.json" + chmod 600 "$TMP/app/default-config/inventory.json" + contains_credentials=1 +elif [[ -e $BUNDLE_CONFIG/inventory-api-key || -e $BUNDLE_CONFIG/inventory-server.crt ]]; then + echo 'Both inventory-api-key and inventory-server.crt are required for bundled configuration.' >&2 + exit 2 +fi ( cd "$TMP/app" - sha256sum intake-gui pc-intake release.json > SHA256SUMS + find . -type f ! -name SHA256SUMS -print0 | sort -z | xargs -0 sha256sum > SHA256SUMS ) tar -C "$TMP/app" -czf "$TMP/payload.tar.gz" . @@ -102,6 +125,18 @@ done exit 2 } +if [ -d "\$app_dir/default-config" ]; then + config_dir=\$data_dir/config + mkdir -p "\$config_dir" + chmod 700 "\$config_dir" + for name in inventory.json inventory-api-key inventory-server.crt; do + target=\$config_dir/\$name + if [ ! -e "\$target" ]; then + install -m600 "\$app_dir/default-config/\$name" "\$target" + fi + done +fi + workshop_config=\$data_dir/config/workshop.json if [ -f "\$workshop_config" ]; then keyboard_layout=\$(python3 - "\$workshop_config" <<'PY' 2>/dev/null || true @@ -127,6 +162,14 @@ EOF payload_line=$(( $(wc -l < "$TMP/launcher") + 1 )) sed -i "s/__PAYLOAD_LINE__/$payload_line/" "$TMP/launcher" cat "$TMP/launcher" "$TMP/payload.tar.gz" > "$OUT" -chmod 755 "$OUT" +if [[ $contains_credentials -eq 1 ]]; then + chmod 700 "$OUT" +else + chmod 755 "$OUT" +fi "$OUT" --check-bundle -echo "Standalone executable created: $OUT" +if [[ $contains_credentials -eq 1 ]]; then + echo "Standalone executable created with inventory configuration: $OUT" +else + echo "Standalone executable created: $OUT" +fi