Files
archy/scripts/tests/package_c01_nts_fixture.py

48 lines
2.6 KiB
Python

"""Public distro dependencies and exact native artifact; no host runtime data."""
import hashlib
import io
import ipaddress
import json
from pathlib import Path
import socket
import subprocess
import sys
import tarfile
repo,previous,out=map(Path,sys.argv[1:])
out.mkdir(mode=0o700)
manifest=json.loads((previous/'native-artifact-sha256.json').read_text())
expected=manifest['usr/local/bin/archipelago']['sha256']
assert hashlib.sha256((previous/'normal-elf').read_bytes()).hexdigest()==expected
files={Path('/usr/sbin/nft'), Path('/usr/lib/x86_64-linux-gnu/libpython3.13.so.1.0')}
for binary in tuple(files):
for word in subprocess.check_output(['ldd',str(binary)],text=True).split():
if word.startswith('/'): files.add(Path(word))
hashes={}
with tarfile.open(out/'dependencies.tar','x') as archive:
for path in sorted(files):
source=path.resolve(strict=True)
for entry in (source,*source.parents):
meta=entry.stat()
assert meta.st_uid==0 and not meta.st_mode&0o022
raw=source.read_bytes();hashes[str(path)]=hashlib.sha256(raw).hexdigest()
info=tarfile.TarInfo(str(path).lstrip('/'));info.size=len(raw);info.mode=0o755
archive.addfile(info,io.BytesIO(raw))
addresses={name:sorted({str(ipaddress.ip_address(row[4][0])) for row in socket.getaddrinfo(name,4460,type=socket.SOCK_STREAM)})
for name in ('time.cloudflare.com','nts.netnod.se')}
rules=['table inet c01_nts {','chain input { type filter hook input priority 0; policy drop; iifname "lo" accept; ct state established,related accept; }',
'chain forward { type filter hook forward priority 0; policy drop; }',
'chain output { type filter hook output priority 0; policy drop; oifname "lo" accept; ct state established,related accept;']
for addr in sorted(set(sum(addresses.values(),[]))):
family='ip6' if ipaddress.ip_address(addr).version==6 else 'ip'
rules += [f'{family} daddr {addr} tcp dport 4460 accept;',f'{family} daddr {addr} udp dport 123 accept;']
rules += ['}','}']
(out/'egress.nft').write_text('\n'.join(rules)+'\n')
for name,source in [('probe.py','scripts/tests/c01_nts_disposable.py'),('c01_nts.py','scripts/c01_nts.py')]:
raw=(repo/source).read_bytes();(out/name).write_bytes(raw);hashes[source]=hashlib.sha256(raw).hexdigest()
if name=='c01_nts.py':
assert raw==(previous/'source'/source).read_bytes(), 'collector differs from native build source'
(out/'source.json').write_text(json.dumps({'files':hashes,'native_sha256':expected,'native_receipt':str(previous),
'addresses':addresses},indent=2)+'\n')
(out/'containers.conf').write_text('[containers]\nkeyring=false\n')