37 lines
1.6 KiB
Python
37 lines
1.6 KiB
Python
#!/usr/bin/python3 -I
|
|
"""Administrator-only import of the exact application key from protected stdin."""
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
if os.geteuid() != 0 or len(sys.argv) != 1:
|
|
raise SystemExit("Root stdin import required")
|
|
secret = bytearray(sys.stdin.buffer.read(1025).strip())
|
|
try:
|
|
if len(secret) != 36 or any(v < 33 or v > 126 for v in secret):
|
|
raise SystemExit("Credential does not match the reviewed K1 profile")
|
|
root = Path("/etc/credstore.encrypted")
|
|
root.mkdir(mode=0o700, exist_ok=True)
|
|
if root.is_symlink() or root.stat().st_uid != 0 or root.stat().st_mode & 0o022:
|
|
raise SystemExit("Unsafe credential store")
|
|
path = root / "k1-application"
|
|
if path.is_symlink() or path.exists():
|
|
raise SystemExit("K1 credential already installed; explicit rotation required")
|
|
with tempfile.TemporaryDirectory(prefix=".k1-", dir=root) as directory:
|
|
staged = Path(directory) / "encrypted"
|
|
completed = subprocess.run(
|
|
["/usr/bin/systemd-creds", "encrypt", "--name=k1-application", "--with-key=host", "-", str(staged)],
|
|
input=secret, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=30,
|
|
)
|
|
if completed.returncode:
|
|
raise SystemExit("K1 credential import failed")
|
|
staged.chmod(0o600)
|
|
with staged.open("rb") as stream:
|
|
os.fsync(stream.fileno())
|
|
# Atomic publication without overwriting a concurrently installed key.
|
|
os.link(staged, path)
|
|
finally:
|
|
secret[:] = b"\0" * len(secret)
|