45 lines
3.0 KiB
Python
45 lines
3.0 KiB
Python
"""Build a pinned private Windows x64 inspector runtime; no machine-wide install."""
|
|||
|
|
import hashlib
|
||
|
|
import json
|
||
|
|
import shutil
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
import urllib.request
|
||
|
|
import zipfile
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
if sys.platform!='win32': raise SystemExit('Windows runtime provisioning runs on Windows only')
|
||
|
|
VERSION='3.13.16'
|
||
|
|
CHECKSUM='97dae5274cc54867065e8d5a3226e48c35017ed332a0fdb0e27d5b5821961297'
|
||
|
|
root=Path.cwd().resolve()
|
||
|
|
directory=root/'.runtime'/'windows'/'python'
|
||
|
|
directory.mkdir(parents=True,exist_ok=True)
|
||
|
|
requirements=root/'apps'/'inspector'/'requirements.lock.txt'
|
||
|
|
requirements_hash=hashlib.sha256(requirements.read_bytes()).hexdigest()
|
||
|
|
manifest=directory/'safetynet-runtime.json'
|
||
|
|
expected={'python':VERSION,'architecture':'amd64','sha256':CHECKSUM,'requirementsHash':requirements_hash}
|
||
|
|
if not manifest.exists() or json.loads(manifest.read_text())!=expected:
|
||
|
|
archive=directory.parent/f'python-{VERSION}-embed-amd64.zip'
|
||
|
|
if not archive.exists() or hashlib.sha256(archive.read_bytes()).hexdigest()!=CHECKSUM:
|
||
|
|
with urllib.request.urlopen(f'https://www.python.org/ftp/python/{VERSION}/python-{VERSION}-embed-amd64.zip',timeout=60) as response:
|
||
|
|
payload=response.read(20*1024*1024)
|
||
|
|
if hashlib.sha256(payload).hexdigest()!=CHECKSUM: raise SystemExit('Python runtime checksum mismatch')
|
||
|
|
archive.write_bytes(payload)
|
||
|
|
with zipfile.ZipFile(archive) as package:
|
||
|
|
for entry in package.infolist():
|
||
|
|
target=(directory/entry.filename).resolve()
|
||
|
|
if not target.is_relative_to(directory): raise SystemExit('Runtime archive path rejected')
|
||
|
|
if not entry.is_dir():
|
||
|
|
target.parent.mkdir(parents=True,exist_ok=True)
|
||
|
|
target.write_bytes(package.read(entry))
|
||
|
|
(directory/'python313._pth').write_text('python313.zip\n.\nLib/site-packages\n../inspector\nimport site\n')
|
||
|
|
subprocess.run([sys.executable,'-m','pip','install','--target',str(directory/'Lib'/'site-packages'),
|
||
|
|
'--platform','win_amd64','--python-version','3.13','--implementation','cp','--abi','cp313',
|
||
|
|
'--only-binary=:all:','--require-hashes','--upgrade','-r',str(requirements)],check=True)
|
||
|
|
manifest.write_text(json.dumps(expected,indent=2))
|
||
|
|
inspector=directory.parent/'inspector'
|
||
|
|
inspector.mkdir(exist_ok=True)
|
||
|
|
for name in ['engine.py','server.py','semantic.py','windows_containment.py','windows_appcontainer.py','sandbox_worker.py','provision_runtime_acl.py']:
|
||
|
|
shutil.copyfile(root/'apps'/'inspector'/name,inspector/name)
|
||
|
|
subprocess.run([str(directory/'python.exe'),'-c','import pypdf, PIL, defusedxml, yara, engine; assert engine.inspect_content(b"public", {"dlp":{"maxBytes":1024,"rules":[],"semantic":{"enabled":False}}})["decision"] == "allow"; assert yara.compile(source="rule test { condition: true }").match(data=b"test"); engine.local_ocr(); print("Bundled Windows inspector, YARA and offline ONNX OCR runtime verified.")'],check=True)
|
||
|
|
subprocess.run([str(directory/'python.exe'),str(root/'apps/inspector/provision_runtime_acl.py'),'--provision'],check=True)
|