56 lines
4.4 KiB
Bash
56 lines
4.4 KiB
Bash
#!/usr/bin/env bash
|
|
# Local metadata-only probe. No APT changes or software installation.
|
|
set -euo pipefail
|
|
task_dir=$(mktemp -d /tmp/server-deploy-repository.XXXXXX)
|
|
chmod 700 "$task_dir"
|
|
base=https://download.docker.com/linux/ubuntu
|
|
curl --fail --silent --show-error --proto '=https' --max-time 45 --max-filesize 1048576 "$base/gpg" -o "$task_dir/docker.asc"
|
|
curl --fail --silent --show-error --proto '=https' --max-time 45 --max-filesize 1048576 "$base/dists/resolute/Release" -o "$task_dir/Release"
|
|
curl --fail --silent --show-error --proto '=https' --max-time 45 --max-filesize 65536 "$base/dists/resolute/Release.gpg" -o "$task_dir/Release.gpg"
|
|
curl --fail --silent --show-error --proto '=https' --max-time 45 --max-filesize 16777216 "$base/dists/resolute/stable/binary-amd64/Packages" -o "$task_dir/Packages"
|
|
gpg --batch --no-options --homedir "$task_dir" --with-colons --show-keys "$task_dir/docker.asc"
|
|
sha256sum "$task_dir/docker.asc"
|
|
gpg --batch --no-options --homedir "$task_dir" --dearmor --output "$task_dir/docker.gpg" "$task_dir/docker.asc"
|
|
gpgv --homedir "$task_dir" --keyring "$task_dir/docker.gpg" --status-fd 1 "$task_dir/Release.gpg" "$task_dir/Release"
|
|
head -n 12 "$task_dir/Release"
|
|
awk '/^Package: (docker-ce|docker-ce-cli|containerd.io|docker-buildx-plugin|docker-compose-plugin)$/ {name=$2} /^Version:/ && name!="" {print name, $2; name=""}' "$task_dir/Packages"
|
|
# Optional prebuilt local binary: verifies the same downloaded snapshots. This
|
|
# selects explicit fixture versions, not an installation or latest-version policy.
|
|
if [[ $# == 1 ]]; then
|
|
engine=$(awk '/^Package: docker-ce$/ {p=1} p && /^Version:/ {print $2; exit}' "$task_dir/Packages")
|
|
containerd=$(awk '/^Package: containerd.io$/ {p=1} p && /^Version:/ {print $2; exit}' "$task_dir/Packages")
|
|
buildx=$(awk '/^Package: docker-buildx-plugin$/ {p=1} p && /^Version:/ {print $2; exit}' "$task_dir/Packages")
|
|
compose=$(awk '/^Package: docker-compose-plugin$/ {p=1} p && /^Version:/ {print $2; exit}' "$task_dir/Packages")
|
|
for version in "$engine" "$containerd" "$buildx" "$compose"; do
|
|
[[ "$version" =~ ^[0-9A-Za-z.+:~_-]+$ ]] || exit 1
|
|
done
|
|
request=$(printf '{"directory":"%s","suite":"resolute","architecture":"amd64","versions":{"docker-ce":"%s","docker-ce-cli":"%s","containerd.io":"%s","docker-buildx-plugin":"%s","docker-compose-plugin":"%s"}}' "$task_dir" "$engine" "$engine" "$containerd" "$buildx" "$compose")
|
|
printf '%s\n' "$request" | "$1" verify-repository > "$task_dir/result.json"
|
|
python3 -I -c 'import json,sys; r=json.load(sys.stdin); p=sys.argv[1:]; assert r["repositoryAuthenticated"] is True; assert r["executable"] is False; assert r["packageBytesVerified"] is False; assert {x["name"]:x["version"] for x in r["lock"]["packages"]} == dict(zip(["docker-ce","docker-ce-cli","containerd.io","docker-buildx-plugin","docker-compose-plugin"],p)); assert len(r["lock"]["packages"])==5' "$engine" "$engine" "$containerd" "$buildx" "$compose" < "$task_dir/result.json"
|
|
cat "$task_dir/result.json"
|
|
if [[ -n "${DEPLOYCTL_TEST_GO:-}" ]]; then
|
|
DEPLOYCTL_REPOSITORY_FIXTURE="$task_dir" "$DEPLOYCTL_TEST_GO" test ./internal/aptrepo -run TestStagedSignatureIntegration -count=1 -v
|
|
fi
|
|
if [[ "${DEPLOYCTL_ONLINE_ARTIFACT_PROBE:-0}" == 1 ]]; then
|
|
bash scripts/probe-docker-artifacts.sh "$1" "$task_dir" "$request"
|
|
fi
|
|
cp -- "$task_dir/Packages" "$task_dir/Packages.original"
|
|
awk '/^SHA256:/ && !changed {c=substr($2,1,1); $2=(c=="0" ? "1" : "0") substr($2,2); changed=1} {print}' "$task_dir/Packages.original" > "$task_dir/Packages"
|
|
if printf '%s\n' "$request" | "$1" verify-repository > "$task_dir/rejected.json"; then
|
|
printf 'ERROR: tampered Packages accepted\n' >&2
|
|
exit 1
|
|
fi
|
|
[[ ! -s "$task_dir/rejected.json" ]]
|
|
mv -- "$task_dir/Packages.original" "$task_dir/Packages"
|
|
printf 'Tampered Packages rejected as expected.\n'
|
|
cp -- "$task_dir/Release" "$task_dir/Release.original"
|
|
awk '/^Date:/ {n=split($0,parts,":"); c=substr(parts[n],1,1); parts[n]=(c=="0" ? "1" : "0") substr(parts[n],2); line=parts[1]; for(i=2;i<=n;i++) line=line ":" parts[i]; print line; next} {print}' "$task_dir/Release.original" > "$task_dir/Release"
|
|
if printf '%s\n' "$request" | "$1" verify-repository > "$task_dir/rejected.json"; then
|
|
printf 'ERROR: tampered Release accepted\n' >&2
|
|
exit 1
|
|
fi
|
|
[[ ! -s "$task_dir/rejected.json" ]]
|
|
printf 'Tampered signed Release rejected as expected.\n'
|
|
fi
|
|
printf 'Local temporary probe directory: %s\n' "$task_dir"
|