NODEDC_MISSION_CORE/plugins/xgrids-k1/lab/iphone-capture/preflight.py

77 lines
2.2 KiB
Python

from __future__ import annotations
import json
import shutil
import subprocess
import sys
from pathlib import Path
def pymobiledevice3_binary() -> str:
sibling = Path(sys.executable).with_name("pymobiledevice3")
if sibling.is_file():
return str(sibling)
discovered = shutil.which("pymobiledevice3")
if discovered is None:
raise RuntimeError("pymobiledevice3 is not installed in this environment")
return discovered
def pymobiledevice3_version(binary: str) -> str:
completed = subprocess.run(
[binary, "--no-color", "version"],
check=False,
capture_output=True,
text=True,
timeout=20,
)
if completed.returncode != 0:
raise RuntimeError("pymobiledevice3 version check failed")
return completed.stdout.strip()
def usb_device_count(binary: str) -> int:
completed = subprocess.run(
[binary, "--no-color", "usbmux", "list", "--usb"],
check=False,
capture_output=True,
text=True,
timeout=20,
)
if completed.returncode != 0:
raise RuntimeError(
"USB discovery failed; unlock the iPhone and confirm Trust This Computer"
)
try:
payload = json.loads(completed.stdout)
except json.JSONDecodeError as exc:
raise RuntimeError("USB discovery returned an unexpected response") from exc
if not isinstance(payload, list):
raise RuntimeError("USB discovery returned an unexpected response")
return len(payload)
def main() -> int:
try:
binary = pymobiledevice3_binary()
version = pymobiledevice3_version(binary)
count = usb_device_count(binary)
except (OSError, RuntimeError, subprocess.SubprocessError) as exc:
print(f"BLOCKED: {exc}")
return 2
print(f"pymobiledevice3: {version}")
print(f"USB iPhone devices: {count}")
if count == 0:
print("BLOCKED: connect one unlocked iPhone with a data cable and confirm Trust")
return 2
if count > 1:
print("BLOCKED: leave exactly one trusted iPhone connected for a redacted capture")
return 2
print("READY: one trusted USB iPhone is available; no device identifier was printed")
return 0
if __name__ == "__main__":
raise SystemExit(main())