Require signed agent releases (Refs #64)
This commit is contained in:
+26
-10
@@ -5,14 +5,11 @@ import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shutil
|
||||
|
||||
|
||||
def package(source, target):
|
||||
"""Read version metadata without importing or executing release code."""
|
||||
source, target = Path(source), Path(target)
|
||||
agent = (source / "ec_agent.py").read_bytes()
|
||||
updater = (source / "ec_agent_update.py").read_bytes()
|
||||
def manifest_bytes(agent, updater, installer):
|
||||
"""Return the deterministic bytes signed by the offline release signer."""
|
||||
# Inspect source without importing or executing release code.
|
||||
versions = [node.value.value for node in ast.parse(agent).body
|
||||
if isinstance(node, ast.Assign) and any(isinstance(name, ast.Name) and name.id == "VERSION" for name in node.targets)
|
||||
and isinstance(node.value, ast.Constant) and isinstance(node.value.value, str)]
|
||||
@@ -21,14 +18,33 @@ def package(source, target):
|
||||
compile(agent, "ec_agent.py", "exec")
|
||||
compile(updater, "ec_agent_update.py", "exec")
|
||||
manifest = {"version": versions[0], "protocolVersion": 1, "platform": "debian-amd64",
|
||||
"sha256": hashlib.sha256(agent).hexdigest(), "updaterProtocolVersion": 1,
|
||||
"updaterSha256": hashlib.sha256(updater).hexdigest()}
|
||||
"sha256": hashlib.sha256(agent).hexdigest(), "updaterProtocolVersion": 2,
|
||||
"updaterSha256": hashlib.sha256(updater).hexdigest(),
|
||||
"installerSha256": hashlib.sha256(installer).hexdigest()}
|
||||
return (json.dumps(manifest, indent=2) + "\n").encode("utf-8")
|
||||
|
||||
|
||||
def package(source, target):
|
||||
"""Read version metadata without importing or executing release code."""
|
||||
source, target = Path(source), Path(target)
|
||||
agent = (source / "ec_agent.py").read_bytes()
|
||||
updater = (source / "ec_agent_update.py").read_bytes()
|
||||
installer = (source / "install.sh").read_bytes()
|
||||
manifest = manifest_bytes(agent, updater, installer)
|
||||
target.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
previous_manifest = (target / "manifest.json").read_bytes()
|
||||
except FileNotFoundError:
|
||||
previous_manifest = None
|
||||
if previous_manifest != manifest:
|
||||
# Builds never sign. Keep an offline signature only across identical
|
||||
# rebuilds; changed releases remain unsigned until reviewed and signed.
|
||||
(target / "manifest.json.sig").unlink(missing_ok=True)
|
||||
(target / "ec-agent.py").write_bytes(agent)
|
||||
(target / "ec-agent-update.py").write_bytes(updater)
|
||||
shutil.copyfile(source / "install.sh", target / "install.sh")
|
||||
(target / "install.sh").write_bytes(installer)
|
||||
temporary_manifest = target / ".manifest.json.tmp"
|
||||
temporary_manifest.write_text(json.dumps(manifest, indent=2) + "\n")
|
||||
temporary_manifest.write_bytes(manifest)
|
||||
temporary_manifest.replace(target / "manifest.json")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user