Ctrl K
ComunidadGuías…

scripts/tests/apt-publish-test.sh

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
set -euo pipefail

ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
TMP=$(mktemp -d)
export GNUPGHOME="$TMP/gnupg"
mkdir -m 700 "$GNUPGHOME"
trap 'gpgconf --kill all 2> /dev/null || true; rm -rf "$TMP"' EXIT

fail() {
    echo "FAIL: $*" >&2
    exit 1
}

gpg --batch --quiet --passphrase '' --quick-generate-key 'Test <test@example.invalid>' ed25519 sign never 2> /dev/null
gpg --batch --quiet --export > "$TMP/keyring.gpg"
GPG_KEY_ID=$(gpg --batch --list-keys --with-colons | awk -F: '/^pub/ { print $5; exit }')
export GPG_KEY_ID
export APT_KEYRING="$TMP/keyring.gpg"
export S3_BUCKET=bucket
unset S3_ACCESS_KEY S3_SECRET_KEY GPG_PRIVATE_KEY

export FAKE_S3="$TMP/s3"
mkdir -p "$TMP/bin" "$FAKE_S3/bucket"
cat > "$TMP/bin/s3cmd" <<'FAKE'
#!/usr/bin/env bash
set -euo pipefail
cmd=$1
shift
paths=()
for arg in "$@"; do
    case "$arg" in
        --*) ;;
        *) paths+=("$arg") ;;
    esac
done
local_path() { echo "${1/s3:\/\//$FAKE_S3/}"; }
case "$cmd" in
    ls)
        [ -d "$(local_path "${paths[0]}")" ] || exit 0
        find "$(local_path "${paths[0]}")" -type f
        ;;
    sync)
        src=$(local_path "${paths[0]}")
        dest=$(local_path "${paths[1]}")
        case "${paths[1]}" in s3://*) rm -rf "$dest" ;; esac
        mkdir -p "$dest"
        cp -a "$src/." "$dest/"
        ;;
    *) exit 2 ;;
esac
FAKE
chmod +x "$TMP/bin/s3cmd"
export PATH="$TMP/bin:$PATH"

make_deb() {
    local name=$1 version=$2 dir="$TMP/build/$1-$2"
    mkdir -p "$dir/DEBIAN"
    cat > "$dir/DEBIAN/control" <<CONTROL
Package: $name
Version: $version
Architecture: amd64
Maintainer: Test <test@example.invalid>
Description: test package
CONTROL
    dpkg-deb --root-owner-group --build "$dir" "$TMP/$name-$version.deb" > /dev/null
    echo "$TMP/$name-$version.deb"
}

publish() {
    "$ROOT/debian/publish.sh" "$@" > "$TMP/publish.log" 2>&1
}

expect_refused() {
    local reason=$1
    shift
    rm -rf "$TMP/before"
    cp -a "$FAKE_S3" "$TMP/before"
    if publish "$@"; then
        fail "$reason: publish succeeded"
    fi
    grep -q 'Refusing to publish' "$TMP/publish.log" || {
        cat "$TMP/publish.log" >&2
        fail "$reason: failed for another reason"
    }
    diff -r "$TMP/before" "$FAKE_S3" > /dev/null || fail "$reason: bucket changed"
}

restore() {
    rm -rf "$FAKE_S3"
    cp -a "$TMP/good" "$FAKE_S3"
}

BUCKET="$FAKE_S3/bucket"
PACKAGES="$BUCKET/dists/stable/main/binary-amd64/Packages"
A1=$(make_deb pkg-a 1.0.0)
A2=$(make_deb pkg-a 2.0.0)
B1=$(make_deb pkg-b 1.0.0)
EVIL=$(make_deb evil 9.9.9)

publish "$A1" || { cat "$TMP/publish.log" >&2; fail 'first publish'; }
publish "$B1" || { cat "$TMP/publish.log" >&2; fail 'publish alongside a verified pool'; }
grep -q 'pool/main/p/pkg-a/pkg-a_1.0.0_amd64.deb' "$PACKAGES" || fail 'existing package dropped from the index'
grep -q 'pool/main/p/pkg-b/pkg-b_1.0.0_amd64.deb' "$PACKAGES" || fail 'new package missing from the index'
cp -a "$FAKE_S3" "$TMP/good"

mkdir -p "$BUCKET/pool/main/e/evil"
cp "$EVIL" "$BUCKET/pool/main/e/evil/evil_9.9.9_amd64.deb"
expect_refused 'unindexed pool file' "$A2"
restore

cp "$EVIL" "$BUCKET/pool/main/p/pkg-b/pkg-b_1.0.0_amd64.deb"
expect_refused 'modified indexed deb' "$A2"
restore

echo >> "$PACKAGES"
expect_refused 'modified Packages index' "$A2"
restore

sed -i 's/^Suite: .*/Suite: tampered/' "$BUCKET/dists/stable/InRelease"
expect_refused 'modified InRelease' "$A2"
restore

STORED="$TMP/stored.pgp"
gpg --batch --yes --store --output "$STORED" "$BUCKET/dists/stable/Release"

cp "$STORED" "$BUCKET/dists/stable/InRelease"
expect_refused 'unsigned OpenPGP InRelease' "$A2"
restore

cat "$STORED" "$TMP/good/bucket/dists/stable/InRelease" > "$BUCKET/dists/stable/InRelease"
expect_refused 'unsigned OpenPGP before a signed InRelease' "$A2"
restore

verify_alpha_release_on() {
    local source=$1
    (
        source <(awk '/^SUBCOMMAND=/{exit} {print}' "$ROOT/scripts/manage-release.sh")
        REPO_ROOT="$ROOT"
        curl() { cp "$source" "$TMP/alpha/InRelease"; }
        rm -rf "$TMP/alpha"
        mkdir "$TMP/alpha"
        verify_alpha_release "$APT_KEYRING" "$TMP/alpha"
    )
}

verify_alpha_release_on "$BUCKET/dists/stable/InRelease" > /dev/null 2>&1 || fail 'alpha release check refused a signed InRelease'
if verify_alpha_release_on "$STORED" > /dev/null 2>&1; then
    fail 'alpha release check accepted an unsigned InRelease'
fi

rm "$BUCKET/dists/stable/InRelease"
expect_refused 'pool without an InRelease' "$A2"
restore

printf 'Package: evil\n' > "$BUCKET/dists/stable/main/binary-amd64/Packages.xz"
publish "$A2" || { cat "$TMP/publish.log" >&2; fail 'publish with a stray index'; }
[ ! -e "$BUCKET/dists/stable/main/binary-amd64/Packages.xz" ] || fail 'stray index survived'
grep -q 'Packages.xz' "$BUCKET/dists/stable/Release" && fail 'stray index was signed'
restore

mkdir -p "$BUCKET/pool/main/p/pkg-a"
cp "$A2" "$BUCKET/pool/main/p/pkg-a/pkg-a_2.0.0_amd64.deb"
publish "$A2" || { cat "$TMP/publish.log" >&2; fail 'retry of an interrupted publish'; }
grep -q 'pkg-a_2.0.0_amd64.deb' "$PACKAGES" || fail 'retry did not index the package'
[ ! -e "$BUCKET/pool/main/p/pkg-a/pkg-a_1.0.0_amd64.deb" ] || fail 'retry kept the old version'

echo 'apt-publish-test: ok'