_ _
| |_ ___| |_ _
| | . | | | |
|_|_|___|_|_ |
|___|
git mirror - github.com/owenewans/holy - branch master
file tests/https.sh
#!/bin/sh
set -eu
no_proxy=localhost,127.0.0.1
NO_PROXY=$no_proxy
export no_proxy NO_PROXY
bin=$1
tmp=$(mktemp -d)
server=
trap 'if test -n "$server"; then kill "$server" 2>/dev/null || :; wait "$server" 2>/dev/null || :; fi; rm -rf "$tmp"' EXIT HUP INT TERM
mkdir -p "$tmp/serve/HOLY" "$tmp/serve/DATA" "$tmp/out"
cat > "$tmp/serve/HOLY/meta" <<'EOF'
format holy-package-1
name https-fixture
version 1
release 1
os linux
arch noarch
libc nolibc
EOF
for field in files deps provides hooks origin transform; do
: > "$tmp/serve/HOLY/$field"
done
mkdir -p "$tmp/serve/DATA/usr/share/holy"
printf 'fixture\n' > "$tmp/serve/DATA/usr/share/holy/fixture.txt"
"$bin" manifest generate "$tmp/serve" --output "$tmp/file-manifest" > "$tmp/result"
cp "$tmp/file-manifest" "$tmp/serve/HOLY/files"
tar -cf "$tmp/native.tar" -C "$tmp/serve" HOLY DATA
lz4 -q "$tmp/native.tar" "$tmp/serve/native.holy"
digest=$(sha256sum "$tmp/serve/native.holy")
digest=${digest%% *}
openssl req -x509 -newkey rsa:2048 -nodes -days 1 \
-keyout "$tmp/key.pem" -out "$tmp/cert.pem" \
-subj /CN=localhost -addext subjectAltName=DNS:localhost \
> "$tmp/openssl.log" 2>&1
mkfifo "$tmp/port"
python3 -u -c '
import http.server, os, ssl, sys
os.chdir(sys.argv[1])
class Handler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
if self.path.startswith("/redirect/") or self.path in ("/redirect.holy", "/credential.holy", "/credential/current"):
userinfo = "user:pass@" if self.path.startswith("/credential") else ""
target = self.path[len("/redirect/"):] if self.path.startswith("/redirect/") else (
"current" if self.path.endswith("/current") else "native.holy")
self.send_response(302)
self.send_header("Location", f"https://{userinfo}localhost:{self.server.server_port}/{target}")
self.send_header("Content-Length", "0")
self.end_headers()
return
return super().do_GET()
server = http.server.HTTPServer(("127.0.0.1", 0), Handler)
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain(sys.argv[2], sys.argv[3])
server.socket = ctx.wrap_socket(server.socket, server_side=True)
print(server.server_port, flush=True)
server.serve_forever()
' "$tmp/serve" "$tmp/cert.pem" "$tmp/key.pem" > "$tmp/port" 2> "$tmp/server.log" &
server=$!
read -r port < "$tmp/port"
test -n "$port"
expect() {
wanted=$1
shift
rc=0
"$@" > "$tmp/result" 2> "$tmp/error" || rc=$?
test "$rc" -eq "$wanted" || { cat "$tmp/result" "$tmp/error"; exit 1; }
}
base="https://localhost:$port/"
# build a second output whose filename requires URL escaping.
sed 's/name https-fixture/name https-second/' "$tmp/serve/HOLY/meta" > "$tmp/meta"
mv "$tmp/meta" "$tmp/serve/HOLY/meta"
rm -r "$tmp/serve/DATA/usr"
: > "$tmp/serve/HOLY/files"
printf 'require parent https-second package https-fixture any any any - https-fixture fixture\n' > "$tmp/serve/HOLY/deps"
tar -cf "$tmp/second.tar" -C "$tmp/serve" HOLY DATA
lz4 -q "$tmp/second.tar" "$tmp/serve/space?#.holy"
"$bin" repo index "$tmp/serve" > "$tmp/result"
"$bin" repo seal "$tmp/serve" > "$tmp/result"
index=$(sed -n 's/^sha256 //p' "$tmp/serve/current")
expect 0 "$bin" repo mirror "$base" --sha256 "$index" --output "$tmp/mirror" --ca-file "$tmp/cert.pem"
test "$(cat "$tmp/result")" = "sealed $index"
cmp "$tmp/serve/current" "$tmp/mirror/current"
cmp "$tmp/serve/index.$index" "$tmp/mirror/index.$index"
cmp "$tmp/serve/space?#.holy" "$tmp/mirror/space?#.holy"
grep -qx 'verification digest-pinned-unsigned' "$tmp/mirror/mirror-origin"
openssl genpkey -algorithm ED25519 -out "$tmp/sign-key.pem" > "$tmp/openssl.log" 2>&1
openssl pkey -in "$tmp/sign-key.pem" -pubout -out "$tmp/sign-pub.pem" > "$tmp/openssl.log" 2>&1
openssl genpkey -algorithm ED25519 -out "$tmp/wrong-sign-key.pem" > "$tmp/openssl.log" 2>&1
openssl pkey -in "$tmp/wrong-sign-key.pem" -pubout -out "$tmp/wrong-sign-pub.pem" > "$tmp/openssl.log" 2>&1
expect 0 "$bin" repo seal "$tmp/serve" --key "$tmp/sign-key.pem"
expect 0 "$bin" repo mirror "$base" --sha256 "$index" --output "$tmp/signed-mirror" \
--public-key "$tmp/sign-pub.pem" --ca-file "$tmp/cert.pem"
expect 0 "$bin" repo verify "$tmp/signed-mirror" --key "$tmp/sign-pub.pem"
grep -qx 'verification ed25519-pinned-key' "$tmp/signed-mirror/mirror-origin"
grep -Eq '^public-key-sha256 [0-9a-f]{64}$' "$tmp/signed-mirror/mirror-origin"
expect 4 "$bin" repo mirror "$base" --sha256 "$index" --output "$tmp/wrong-sign-key" \
--public-key "$tmp/wrong-sign-pub.pem" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/wrong-sign-key/current"
cp "$tmp/serve/signature.$index" "$tmp/signature-original"
printf '\001' | dd of="$tmp/serve/signature.$index" bs=1 seek=0 conv=notrunc status=none
expect 4 "$bin" repo mirror "$base" --sha256 "$index" --output "$tmp/changed-signature" \
--public-key "$tmp/sign-pub.pem" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/changed-signature/current"
cp "$tmp/signature-original" "$tmp/serve/signature.$index"
mkdir "$tmp/signed-source-root"
expect 0 "$bin" db init --root "$tmp/signed-source-root"
printf '[source signed]\ntype holy-http\nurl "%s"\ntrust require\npublic-key "%s"\n' \
"$base" "$tmp/sign-pub.pem" > "$tmp/signed-source.conf"
expect 0 "$bin" source plan --config "$tmp/signed-source.conf" --root "$tmp/signed-source-root"
cp "$tmp/result" "$tmp/signed-source.plan"
signed_plan=$(sha256sum "$tmp/signed-source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/signed-source.plan" --sha256 "$signed_plan" --root "$tmp/signed-source-root"
expect 2 "$bin" sync signed --root "$tmp/signed-source-root" --accept-unsigned "$index" --ca-file "$tmp/cert.pem"
expect 0 "$bin" sync signed --root "$tmp/signed-source-root" --ca-file "$tmp/cert.pem"
expect 0 "$bin" search https-second --source signed --root "$tmp/signed-source-root"
grep -qx 'listed 1 packages' "$tmp/result"
mkdir "$tmp/source-root"
expect 0 "$bin" db init --root "$tmp/source-root"
printf '[source fixture]\ntype holy-http\nurl "%s"\n' "$base" > "$tmp/source.conf"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$tmp/source-root"
cp "$tmp/result" "$tmp/source.plan"
source_plan=$(sha256sum "$tmp/source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/source.plan" --sha256 "$source_plan" --root "$tmp/source-root"
expect 0 "$bin" source list --root "$tmp/source-root"
source_id=$(awk '$1 == "source" && $4 == "active" {print $2}' "$tmp/result")
test "${#source_id}" -eq 64
expect 0 "$bin" sync fixture --root "$tmp/source-root" --sha256 "$index" \
--output "$tmp/source-mirror" --ca-file "$tmp/cert.pem"
grep -qx "source-id $source_id" "$tmp/source-mirror/mirror-origin"
cmp "$tmp/serve/current" "$tmp/source-mirror/current"
expect 0 "$bin" sync fixture --root "$tmp/source-root" --sha256 "$index" \
--ca-file "$tmp/cert.pem"
cached="$tmp/source-root/var/cache/holypkg/catalogs/$source_id/$index"
test -d "$cached"
grep -qx "source-id $source_id" "$cached/mirror-origin"
grep -qx "root-path \"${cached#"$tmp/source-root"}\"" "$tmp/source-root/var/lib/holypkg/catalogs/$source_id"
expect 0 "$bin" search https-second --source fixture --root "$tmp/source-root"
grep -qx 'listed 1 packages' "$tmp/result"
expect 0 "$bin" search /usr/share/holy/fixture.txt --file --source fixture --root "$tmp/source-root"
grep -qx 'listed 1 file candidates' "$tmp/result"
grep -q '^coverage files complete index ' "$tmp/result"
expect 0 "$bin" search /usr/share/holy/missing --file --source fixture --root "$tmp/source-root"
grep -qx 'listed 0 file candidates' "$tmp/result"
expect 0 "$bin" search https-seconx --fuzzy --source fixture --root "$tmp/source-root"
grep -qx 'suggestion score 3 name "https-second"' "$tmp/result"
grep -qx 'suggested 1 of 1 packages' "$tmp/result"
expect 0 "$bin" search fixture.tzt --file --fuzzy --source fixture --root "$tmp/source-root"
grep -qx 'suggestion score 3 path "usr/share/holy/fixture.txt"' "$tmp/result"
grep -qx 'suggested 1 of 1 file candidates' "$tmp/result"
expect 0 "$bin" search /usr/share/holy/fixture.tzt --file --source fixture --root "$tmp/source-root"
grep -qx 'listed 0 file candidates' "$tmp/result"
expect 0 "$bin" search missing --file --fuzzy --source fixture --root "$tmp/source-root"
grep -qx 'suggested 0 of 0 file candidates' "$tmp/result"
cp "$cached/space?#.holy" "$tmp/cached-second"
printf corrupt >> "$cached/space?#.holy"
expect 0 "$bin" search /usr/share/holy/fixture.txt --file --source fixture --root "$tmp/source-root"
grep -qx 'listed 1 file candidates' "$tmp/result"
expect 0 "$bin" search https-fixturx --fuzzy --source fixture --root "$tmp/source-root"
grep -qx 'suggested 1 of 1 packages' "$tmp/result"
expect 6 "$bin" search https-second --source fixture --root "$tmp/source-root"
cp "$tmp/cached-second" "$cached/space?#.holy"
cp -a "$tmp/source-mirror" "$tmp/file-search-mirror"
printf corrupt >> "$tmp/file-search-mirror/space?#.holy"
expect 0 "$bin" search /usr/share/holy/fixture.txt --file --source fixture \
--catalog "$tmp/file-search-mirror" --root "$tmp/source-root"
grep -qx 'listed 1 file candidates' "$tmp/result"
expect 0 "$bin" search /usr/share/holy/missing --file --source fixture \
--catalog "$tmp/file-search-mirror" --root "$tmp/source-root"
grep -qx 'listed 0 file candidates' "$tmp/result"
printf corrupt >> "$tmp/file-search-mirror/native.holy"
expect 6 "$bin" search /usr/share/holy/fixture.txt --file --source fixture \
--catalog "$tmp/file-search-mirror" --root "$tmp/source-root"
test ! -s "$tmp/result"
expect 0 "$bin" sync fixture --root "$tmp/source-root" --sha256 "$index"
cp "$cached/native.holy" "$tmp/cached-native"
printf corrupt >> "$cached/native.holy"
expect 6 "$bin" sync fixture --root "$tmp/source-root" --sha256 "$index"
cmp "$tmp/cached-native" "$tmp/source-mirror/native.holy"
cp "$tmp/cached-native" "$cached/native.holy"
expect 0 "$bin" sync fixture --root "$tmp/source-root" --sha256 "$index"
expect 0 "$bin" source catalog bind fixture "$tmp/source-mirror" --root "$tmp/source-root"
grep -qx "catalog-bound $source_id index $index" "$tmp/result"
binding="$tmp/source-root/var/lib/holypkg/catalogs/$source_id"
test "$(stat -c %a "$binding")" = 600
grep -qx "index $index" "$binding"
expect 0 "$bin" search https-second --source fixture --root "$tmp/source-root"
grep -qx 'listed 1 packages' "$tmp/result"
expect 0 "$bin" info fixture:https-second --root "$tmp/source-root"
grep -q '^package "https-second" ' "$tmp/result"
cp "$tmp/source-mirror/native.holy" "$tmp/bound-native"
printf corrupt >> "$tmp/source-mirror/native.holy"
expect 0 "$bin" search https-second --source fixture --root "$tmp/source-root"
grep -qx 'listed 1 packages' "$tmp/result"
expect 0 "$bin" info fixture:https-second --root "$tmp/source-root"
mkdir "$tmp/selected-fetched"
expect 0 "$bin" fetch fixture:https-second --output "$tmp/selected-fetched" \
--root "$tmp/source-root"
selected_hash=$(sha256sum "$tmp/serve/space?#.holy" | cut -d ' ' -f 1)
grep -Fxq "$tmp/selected-fetched/$selected_hash.holy" "$tmp/result"
expect 6 "$bin" search https-fixture --source fixture --root "$tmp/source-root"
cp "$tmp/bound-native" "$tmp/source-mirror/native.holy"
expect 0 "$bin" search https-second --source fixture --catalog "$tmp/source-mirror" \
--root "$tmp/source-root"
grep -q '^package "https-second" ' "$tmp/result"
grep -qx 'listed 1 packages' "$tmp/result"
grep -qx "source-id $source_id" "$tmp/result"
expect 0 "$bin" search missing --source fixture --catalog "$tmp/source-mirror" \
--root "$tmp/source-root"
grep -qx 'listed 0 packages' "$tmp/result"
expect 0 "$bin" info fixture:https-second --catalog "$tmp/source-mirror" \
--root "$tmp/source-root"
grep -q '^package "https-second" ' "$tmp/result"
grep -qx "source-id $source_id" "$tmp/result"
test "$(wc -l < "$tmp/result")" -eq 2
expect 6 "$bin" info fixture:missing --catalog "$tmp/source-mirror" \
--root "$tmp/source-root"
test ! -s "$tmp/result"
expect 6 "$bin" search https-second --source wrong --catalog "$tmp/source-mirror" \
--root "$tmp/source-root"
expect 2 "$bin" info fixture:https-second --bogus --root "$tmp/source-root"
cp -a "$tmp/source-mirror" "$tmp/changed-source-mirror"
printf broken >> "$tmp/changed-source-mirror/native.holy"
expect 0 "$bin" search https-second --source fixture --catalog "$tmp/changed-source-mirror" \
--root "$tmp/source-root"
expect 0 "$bin" info fixture:https-second --catalog "$tmp/changed-source-mirror" \
--root "$tmp/source-root"
expect 6 "$bin" search https-fixture --source fixture --catalog "$tmp/changed-source-mirror" \
--root "$tmp/source-root"
expect 6 "$bin" source catalog bind fixture "$tmp/changed-source-mirror" \
--root "$tmp/source-root"
expect 0 "$bin" search https-second --source fixture --root "$tmp/source-root"
cp "$binding" "$tmp/valid-binding"
rm "$binding"
ln -s "$tmp/valid-binding" "$binding"
expect 6 "$bin" search https-second --source fixture --root "$tmp/source-root"
rm "$binding"
cp "$tmp/valid-binding" "$binding"
expect 0 "$bin" search https-second --source fixture --root "$tmp/source-root"
cp "$tmp/source-mirror/current" "$tmp/valid-current"
printf 'sha256 %064d\n' 0 > "$tmp/source-mirror/current"
expect 6 "$bin" info fixture:https-second --root "$tmp/source-root"
cp "$tmp/valid-current" "$tmp/source-mirror/current"
expect 0 "$bin" info fixture:https-second --root "$tmp/source-root"
mkdir "$tmp/serve/other"
cp "$tmp/serve/native.holy" "$tmp/serve/other/"
"$bin" repo index "$tmp/serve/other" > "$tmp/result"
"$bin" repo seal "$tmp/serve/other" > "$tmp/result"
other_index=$(sed -n 's/^sha256 //p' "$tmp/serve/other/current")
printf '[source fixture]\ntype holy-http\nurl "%s"\n[source other]\ntype holy-http\nurl "%sother/"\n' \
"$base" "$base" > "$tmp/multi.conf"
expect 0 "$bin" source plan --config "$tmp/multi.conf" --root "$tmp/source-root"
cp "$tmp/result" "$tmp/multi.plan"
multi_plan=$(sha256sum "$tmp/multi.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/multi.plan" --sha256 "$multi_plan" --root "$tmp/source-root"
expect 0 "$bin" source list --root "$tmp/source-root"
other_id=$(sed -n 's/^source \([0-9a-f]*\) "other" active$/\1/p' "$tmp/result")
test "${#other_id}" -eq 64
expect 0 "$bin" sync other --root "$tmp/source-root" --sha256 "$other_index" \
--output "$tmp/other-mirror" --ca-file "$tmp/cert.pem"
expect 0 "$bin" source catalog bind other "$tmp/other-mirror" --root "$tmp/source-root"
expect 0 "$bin" search https-fixture --root "$tmp/source-root"
grep -qx "source \"fixture\" id $source_id" "$tmp/result"
grep -qx "source \"other\" id $other_id" "$tmp/result"
test "$(sed -n 's/^source "\([^"]*\)" id .*/\1/p' "$tmp/result" | paste -sd ' ' -)" = 'fixture other'
test "$(grep -c '^package "https-fixture" ' "$tmp/result")" -eq 2
grep -qx 'searched 2 sources; unavailable 0' "$tmp/result"
expect 0 "$bin" search /usr/share/holy/fixture.txt --file --root "$tmp/source-root"
test "$(grep -c '^package "https-fixture" ' "$tmp/result")" -eq 2
grep -qx 'searched 2 sources; unavailable 0' "$tmp/result"
expect 0 "$bin" search https-fixturx --fuzzy --root "$tmp/source-root"
test "$(grep -c '^suggestion score ' "$tmp/result")" -eq 2
expect 2 "$bin" search https-fixture --catalog "$tmp/source-mirror" --root "$tmp/source-root"
mv "$tmp/source-root/var/lib/holypkg/catalogs/$other_id" "$tmp/other-binding"
expect 6 "$bin" search https-fixture --root "$tmp/source-root"
grep -qx 'source "other" coverage unavailable' "$tmp/result"
grep -qx 'searched 2 sources; unavailable 1' "$tmp/result"
mv "$tmp/other-binding" "$tmp/source-root/var/lib/holypkg/catalogs/$other_id"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$tmp/source-root"
cp "$tmp/result" "$tmp/single.plan"
single_plan=$(sha256sum "$tmp/single.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/single.plan" --sha256 "$single_plan" --root "$tmp/source-root"
expect 0 "$bin" search https-fixture --root "$tmp/source-root"
grep -qx 'searched 1 sources; unavailable 0' "$tmp/result"
! grep -q '^source "other"' "$tmp/result"
mkdir "$tmp/add-root"
expect 0 "$bin" db init --root "$tmp/add-root"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$tmp/add-root"
cp "$tmp/result" "$tmp/add-source.plan"
add_source_plan=$(sha256sum "$tmp/add-source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/add-source.plan" --sha256 "$add_source_plan" \
--root "$tmp/add-root"
expect 6 "$bin" add fixture:https-second --root "$tmp/add-root" --yes
expect 0 "$bin" source catalog bind fixture "$tmp/source-mirror" --root "$tmp/add-root"
expect 3 "$bin" add fixture:https-second --root "$tmp/add-root" < /dev/null
grep -q 'plan-set .* read-only' "$tmp/result"
test "$(cat "$tmp/add-root/var/lib/holypkg/generation")" -eq 0
expect 0 "$bin" add fixture:https-second --root "$tmp/add-root" --yes
second_hash=$(sha256sum "$tmp/serve/space?#.holy" | cut -d ' ' -f 1)
grep -qx "source-id $source_id" "$tmp/add-root/var/lib/holypkg/installed/$digest/state"
grep -qx "source-id $source_id" "$tmp/add-root/var/lib/holypkg/installed/$second_hash/state"
expect 0 "$bin" db check --all --root "$tmp/add-root"
if readelf -l "$bin" | grep -q INTERP; then
mkdir "$tmp/fault-root"
expect 0 "$bin" db init --root "$tmp/fault-root"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$tmp/fault-root"
cp "$tmp/result" "$tmp/fault-source.plan"
fault_source_plan=$(sha256sum "$tmp/fault-source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/fault-source.plan" --sha256 "$fault_source_plan" \
--root "$tmp/fault-root"
cat > "$tmp/fault.c" <<'C'
#define _POSIX_C_SOURCE 200809L
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
int renameat(int olddir, const char *oldpath, int newdir, const char *newpath)
{
int (*real_renameat)(int, const char *, int, const char *);
void *symbol = dlsym(RTLD_NEXT, "renameat");
memcpy(&real_renameat, &symbol, sizeof real_renameat);
if (!real_renameat) abort();
if (!strcmp(newpath, "generation")) { errno = ENOSPC; return -1; }
return real_renameat(olddir, oldpath, newdir, newpath);
}
C
gcc -shared -fPIC -o "$tmp/fault.so" "$tmp/fault.c" -ldl
expect 5 env LD_PRELOAD="$tmp/fault.so" "$bin" add fixture:https-second \
--catalog "$tmp/source-mirror" --root "$tmp/fault-root" --yes
journal="$tmp/fault-root/var/lib/holypkg/transactions/set-journal"
grep -qx 'format holy-set-journal-5' "$journal"
grep -qx "catalog-index $index" "$journal"
grep -qx "binding $digest=$source_id" "$journal"
grep -qx "binding $second_hash=$source_id" "$journal"
cp "$journal" "$tmp/valid-journal"
sed "s/catalog-index $index/catalog-index $(printf '%064d' 0)/" \
"$tmp/valid-journal" > "$journal"
expect 5 "$bin" db recover --finish-set --root "$tmp/fault-root"
cp "$tmp/valid-journal" "$journal"
expect 0 "$bin" db recover --finish-set --root "$tmp/fault-root"
expect 0 "$bin" db check --all --root "$tmp/fault-root"
fi
mkdir "$tmp/fetched"
expect 0 "$bin" fetch fixture:https-fixture --output "$tmp/fetched" \
--root "$tmp/source-root"
grep -Fxq "$tmp/fetched/$digest.holy" "$tmp/result"
expect 0 "$bin" fetch fixture:https-fixture --catalog "$tmp/source-mirror" \
--output "$tmp/fetched" --root "$tmp/source-root"
grep -Fxq "$tmp/fetched/$digest.holy" "$tmp/result"
cmp "$tmp/serve/native.holy" "$tmp/fetched/$digest.holy"
expect 0 "$bin" fetch fixture:https-fixture --catalog "$tmp/source-mirror" \
--extract --output "$tmp/extracted" --root "$tmp/source-root"
grep -qx 'name https-fixture' "$tmp/extracted/HOLY/meta"
expect 6 "$bin" fetch fixture:missing --catalog "$tmp/source-mirror" \
--output "$tmp/fetched" --root "$tmp/source-root"
expect 6 "$bin" fetch absent:https-fixture --catalog "$tmp/source-mirror" \
--output "$tmp/fetched" --root "$tmp/source-root"
cp "$tmp/source-mirror/mirror-origin" "$tmp/valid-origin"
sed "s/$source_id/$(printf '%064d' 0)/" "$tmp/valid-origin" > "$tmp/source-mirror/mirror-origin"
expect 6 "$bin" fetch fixture:https-fixture --catalog "$tmp/source-mirror" \
--output "$tmp/fetched" --root "$tmp/source-root"
cp "$tmp/valid-origin" "$tmp/source-mirror/mirror-origin"
mv "$tmp/source-mirror/mirror-origin" "$tmp/origin-regular"
ln -s "$tmp/origin-regular" "$tmp/source-mirror/mirror-origin"
expect 6 "$bin" fetch fixture:https-fixture --catalog "$tmp/source-mirror" \
--output "$tmp/fetched" --root "$tmp/source-root"
rm "$tmp/source-mirror/mirror-origin"
mv "$tmp/origin-regular" "$tmp/source-mirror/mirror-origin"
before_current=$(grep -c '"GET /index\.' "$tmp/server.log" || true)
expect 3 "$bin" sync fixture --root "$tmp/source-root" --ca-file "$tmp/cert.pem"
grep -q "decision-required unsigned current source=$source_id index=$index" "$tmp/error"
expect 3 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-current-preview" --ca-file "$tmp/cert.pem"
grep -q "decision-required unsigned current source=$source_id index=$index" "$tmp/error"
test ! -e "$tmp/source-current-preview"
test "$(grep -c '"GET /index\.' "$tmp/server.log" || true)" -eq "$before_current"
expect 0 "$bin" sync fixture --root "$tmp/source-root" --sha256 "$index"
expect 6 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-current-untrusted" --accept-unsigned "$index"
test ! -e "$tmp/source-current-untrusted"
expect 2 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-current-invalid-answer" --accept-unsigned bad --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-current-invalid-answer"
expect 2 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-current-two-modes" --sha256 "$index" \
--accept-unsigned "$index" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-current-two-modes"
stale=cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
expect 3 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-current-stale" --accept-unsigned "$stale" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-current-stale"
expect 0 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-current" --accept-unsigned "$index" --ca-file "$tmp/cert.pem"
grep -qx 'selection current-accepted-unsigned' "$tmp/source-current/mirror-origin"
cmp "$tmp/serve/current" "$tmp/source-current/current"
expect 0 "$bin" sync fixture --root "$tmp/source-root" \
--accept-unsigned "$index" --ca-file "$tmp/cert.pem"
grep -qx "root-path \"${cached#"$tmp/source-root"}\"" "$binding"
expect 0 "$bin" source catalog bind fixture "$tmp/source-mirror" --root "$tmp/source-root"
expect 0 "$bin" fetch fixture:https-fixture --catalog "$tmp/source-current" \
--output "$tmp/fetched" --root "$tmp/source-root"
cp "$tmp/serve/current" "$tmp/current.saved"
printf 'sha256 %s\n' "$stale" > "$tmp/serve/current"
expect 3 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-current-changed" --accept-unsigned "$index" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-current-changed"
printf 'sha256 invalid\n' > "$tmp/serve/current"
expect 4 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-current-malformed" --accept-unsigned "$index" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-current-malformed"
mv "$tmp/current.saved" "$tmp/serve/current"
expect 0 "$bin" repo solve "$tmp/source-mirror" https-second --json
grep -q '"count":2' "$tmp/result"
expect 6 "$bin" sync absent --root "$tmp/source-root" --sha256 "$index" \
--output "$tmp/source-absent" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-absent"
expect 6 "$bin" sync fixture --root "$tmp/source-root" --sha256 "$index" \
--output "$tmp/source-untrusted"
test ! -e "$tmp/source-untrusted/current"
expect 2 "$bin" sync fixture --root "$tmp/source-root" --sha256 bad \
--output "$tmp/source-invalid" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-invalid"
printf '[source fixture]\ntype holy-http\nurl "%sredirect/"\n' "$base" > "$tmp/source.conf"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$tmp/source-root"
cp "$tmp/result" "$tmp/source.plan"
source_plan=$(sha256sum "$tmp/source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/source.plan" --sha256 "$source_plan" --root "$tmp/source-root"
expect 3 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-redirect-preview" --ca-file "$tmp/cert.pem"
grep -q "index=$index" "$tmp/error"
expect 0 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-redirect" --accept-unsigned "$index" --ca-file "$tmp/cert.pem"
grep -qx 'selection current-accepted-unsigned' "$tmp/source-redirect/mirror-origin"
printf '[source fixture]\ntype holy-http\nurl "%scredential/"\n' "$base" > "$tmp/source.conf"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$tmp/source-root"
cp "$tmp/result" "$tmp/source.plan"
source_plan=$(sha256sum "$tmp/source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/source.plan" --sha256 "$source_plan" --root "$tmp/source-root"
expect 6 "$bin" sync fixture --root "$tmp/source-root" \
--output "$tmp/source-credential" --accept-unsigned "$index" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-credential"
! grep -Eq 'user|pass' "$tmp/error"
printf '[source fixture]\ntype holy-http\nurl "%s"\n' "$base" > "$tmp/source.conf"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$tmp/source-root"
cp "$tmp/result" "$tmp/source.plan"
source_plan=$(sha256sum "$tmp/source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/source.plan" --sha256 "$source_plan" --root "$tmp/source-root"
printf '[source renamed]\ntype holy-http\nurl "%s"\n' "$base" > "$tmp/source.conf"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$tmp/source-root"
cp "$tmp/result" "$tmp/source.plan"
source_plan=$(sha256sum "$tmp/source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/source.plan" --sha256 "$source_plan" --root "$tmp/source-root"
expect 0 "$bin" sync renamed --root "$tmp/source-root" --sha256 "$index" \
--output "$tmp/source-renamed" --ca-file "$tmp/cert.pem"
grep -qx "source-id $source_id" "$tmp/source-renamed/mirror-origin"
expect 0 "$bin" fetch renamed:https-fixture --catalog "$tmp/source-mirror" \
--output "$tmp/fetched" --root "$tmp/source-root"
expect 0 "$bin" info renamed:https-fixture --root "$tmp/source-root"
grep -qx "source-id $source_id" "$tmp/result"
expect 0 "$bin" fetch renamed:https-fixture --output "$tmp/fetched" \
--root "$tmp/source-root"
expect 6 "$bin" info fixture:https-fixture --root "$tmp/source-root"
expect 6 "$bin" fetch fixture:https-fixture --catalog "$tmp/source-mirror" \
--output "$tmp/fetched" --root "$tmp/source-root"
expect 6 "$bin" sync fixture --root "$tmp/source-root" --sha256 "$index" \
--output "$tmp/source-inactive" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-inactive"
printf '[source fixture]\ntype pacman\nrepo core "%s"\n' "$base" > "$tmp/source.conf"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$tmp/source-root"
cp "$tmp/result" "$tmp/source.plan"
source_plan=$(sha256sum "$tmp/source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/source.plan" --sha256 "$source_plan" --root "$tmp/source-root"
expect 6 "$bin" fetch fixture:https-fixture --catalog "$tmp/source-mirror" \
--output "$tmp/fetched" --root "$tmp/source-root"
expect 6 "$bin" sync fixture --root "$tmp/source-root" --sha256 "$index" \
--output "$tmp/source-wrong-family" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/source-wrong-family"
expect 0 "$bin" repo search "$tmp/mirror" https-second
grep -q 'listed 1 packages' "$tmp/result"
expect 0 "$bin" repo solve "$tmp/mirror" https-second --json
grep -q '"count":2' "$tmp/result"
mkdir "$tmp/mirror-fetch"
expect 0 "$bin" repo fetch "$tmp/mirror" "$digest" --output "$tmp/mirror-fetch"
cmp "$tmp/mirror-fetch/$digest.holy" "$tmp/serve/native.holy"
expect 1 "$bin" repo mirror "$base" --sha256 "$index" --output "$tmp/mirror" --ca-file "$tmp/cert.pem"
cmp "$tmp/serve/current" "$tmp/mirror/current"
expect 6 "$bin" repo mirror "$base" --sha256 "$index" --output "$tmp/untrusted"
test ! -e "$tmp/untrusted/current"
expect 2 "$bin" repo mirror "https://user:pass@localhost:$port/" --sha256 "$index" --output "$tmp/credentials"
test ! -e "$tmp/credentials"
! grep -Eq 'user|pass' "$tmp/error"
expect 2 "$bin" repo mirror "${base}?query/" --sha256 "$index" --output "$tmp/query"
test ! -e "$tmp/query"
bad_index=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
cp "$tmp/serve/index" "$tmp/serve/index.$bad_index"
expect 4 "$bin" repo mirror "$base" --sha256 "$bad_index" --output "$tmp/wrong-index" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/wrong-index/current"
mkdir "$tmp/serve/empty" "$tmp/serve/duplicate" "$tmp/serve/truncated"
printf 'format holy-index-prototype-2\n' > "$tmp/serve/empty/index"
cp "$tmp/serve/index" "$tmp/serve/duplicate/index"
tail -n 1 "$tmp/serve/index" >> "$tmp/serve/duplicate/index"
printf 'format holy-index-prototype-2\npackage "truncated\n' > "$tmp/serve/truncated/index"
for variant in empty duplicate truncated; do
sum=$(sha256sum "$tmp/serve/$variant/index")
sum=${sum%% *}
cp "$tmp/serve/$variant/index" "$tmp/serve/$variant/index.$sum"
wanted=4
test "$variant" != empty || wanted=0
expect "$wanted" "$bin" repo mirror "$base$variant/" --sha256 "$sum" \
--output "$tmp/$variant" --ca-file "$tmp/cert.pem"
if test "$wanted" -ne 0; then test ! -e "$tmp/$variant/current"; fi
done
expect 0 "$bin" repo list "$tmp/empty"
grep -qx 'listed 0 packages' "$tmp/result"
mv "$tmp/serve/space?#.holy" "$tmp/second.holy"
expect 6 "$bin" repo mirror "$base" --sha256 "$index" --output "$tmp/disappeared" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/disappeared/current"
mv "$tmp/second.holy" "$tmp/serve/space?#.holy"
cp "$tmp/serve/native.holy" "$tmp/original.holy"
printf changed > "$tmp/serve/native.holy"
expect 4 "$bin" repo mirror "$base" --sha256 "$index" --output "$tmp/changed-artifact" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/changed-artifact/current"
cp "$tmp/original.holy" "$tmp/serve/native.holy"
mkdir "$tmp/serve/claims" "$tmp/serve/oversized"
cp "$tmp/serve/index" "$tmp/serve/claims/index"
second=$(sha256sum "$tmp/serve/space?#.holy" | cut -d ' ' -f 1)
printf 'claim %s package forged any any - fixture\n' "$second" >> "$tmp/serve/claims/index"
cp "$tmp/serve/native.holy" "$tmp/serve/space?#.holy" "$tmp/serve/claims/"
truncate -s 129M "$tmp/serve/oversized/index"
for variant in claims oversized; do
sum=$(sha256sum "$tmp/serve/$variant/index" | cut -d ' ' -f 1)
cp "$tmp/serve/$variant/index" "$tmp/serve/$variant/index.$sum"
wanted=4
test "$variant" != oversized || wanted=6
expect "$wanted" "$bin" repo mirror "$base$variant/" --sha256 "$sum" \
--output "$tmp/$variant" --ca-file "$tmp/cert.pem"
test ! -e "$tmp/$variant/current"
test ! -s "$tmp/result"
done
printf 'HTTPS catalog mirror fixtures passed\n'
url="https://localhost:$port/native.holy"
"$bin" fetch "$url" --sha256 "$digest" --output "$tmp/out" \
--ca-file "$tmp/cert.pem" > "$tmp/result"
grep -qx "$tmp/out/$digest.holy" "$tmp/result"
cmp "$tmp/serve/native.holy" "$tmp/out/$digest.holy"
"$bin" fetch "https://localhost:$port/redirect.holy" --sha256 "$digest" --output "$tmp/out" \
--ca-file "$tmp/cert.pem" > "$tmp/result"
grep -qx "$tmp/out/$digest.holy" "$tmp/result"
before=$(grep -c '"GET /native.holy HTTP/' "$tmp/server.log")
if "$bin" fetch "https://localhost:$port/credential.holy" --sha256 "$digest" --output "$tmp/out" \
--ca-file "$tmp/cert.pem" > "$tmp/result" 2> "$tmp/error"; then exit 1; else test "$?" -eq 6; fi
test "$(grep -c '"GET /native.holy HTTP/' "$tmp/server.log")" -eq "$before"
test ! -s "$tmp/result"
if grep -Eq 'user|pass' "$tmp/error"; then exit 1; fi
"$bin" fetch "$url" --sha256 "$digest" --output "$tmp/out" \
--ca-file "$tmp/cert.pem" > "$tmp/result"
bad=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
if "$bin" fetch "$url" --sha256 "$bad" --output "$tmp/out" \
--ca-file "$tmp/cert.pem" > "$tmp/result" 2> "$tmp/error"; then exit 1; else test "$?" -eq 4; fi
test ! -s "$tmp/result"
test ! -e "$tmp/out/$bad.holy"
if "$bin" fetch "$url" --sha256 "$digest" --output "$tmp/out" \
> "$tmp/result" 2> "$tmp/error"; then exit 1; else test "$?" -eq 6; fi
if "$bin" fetch "https://user:pass@localhost:$port/native.holy" \
--sha256 "$digest" --output "$tmp/out" --ca-file "$tmp/cert.pem" \
> "$tmp/result" 2> "$tmp/error"; then exit 1; else test "$?" -eq 2; fi
if grep -Eq 'user|pass' "$tmp/error"; then exit 1; fi
if "$bin" fetch "http://localhost:$port/native.holy" \
--sha256 "$digest" --output "$tmp/out" \
> "$tmp/result" 2> "$tmp/error"; then exit 1; else test "$?" -eq 2; fi
printf 'not an archive\n' > "$tmp/serve/bad.holy"
invalid=$(sha256sum "$tmp/serve/bad.holy")
invalid=${invalid%% *}
if "$bin" fetch "https://localhost:$port/bad.holy" --sha256 "$invalid" \
--output "$tmp/out" --ca-file "$tmp/cert.pem" \
> "$tmp/result" 2> "$tmp/error"; then exit 1; else test "$?" -eq 2; fi
test ! -e "$tmp/out/$invalid.holy"
printf 'corrupt\n' > "$tmp/out/$digest.holy"
if "$bin" fetch "$url" --sha256 "$digest" --output "$tmp/out" \
--ca-file "$tmp/cert.pem" > "$tmp/result" 2> "$tmp/error"; then exit 1; else test "$?" -eq 4; fi
grep -qx corrupt "$tmp/out/$digest.holy"
rm "$tmp/out/$digest.holy"
printf 'outside\n' > "$tmp/victim"
ln -s "$tmp/victim" "$tmp/out/$digest.holy"
if "$bin" fetch "$url" --sha256 "$digest" --output "$tmp/out" \
--ca-file "$tmp/cert.pem" > "$tmp/result" 2> "$tmp/error"; then exit 1; else test "$?" -eq 4; fi
grep -qx outside "$tmp/victim"
rm "$tmp/out/$digest.holy"
chmod 0770 "$tmp/out"
if "$bin" fetch "$url" --sha256 "$digest" --output "$tmp/out" \
--ca-file "$tmp/cert.pem" > "$tmp/result" 2> "$tmp/error"; then exit 1; else test "$?" -eq 1; fi
test ! -e "$tmp/out/$digest.holy"
chmod 0700 "$tmp/out"
printf 'https fixtures passed\n'