54 lines
2.3 KiB
Python
54 lines
2.3 KiB
Python
"""Installer-only ACL provisioning for this exact SafetyNet installation.
|
|
|
|
Run with the installed private Python. No caller-controlled grant roots exist.
|
|
Normal service startup verifies ACLs without changing them.
|
|
"""
|
|
import argparse
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
import os
|
|
import threading
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
sys.dont_write_bytecode=True
|
|
from windows_appcontainer import AppContainer, SandboxError
|
|
from windows_containment import contain_inspector
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--provision', action='store_true', help='Installer/owner only: establish read/execute ACLs')
|
|
args = parser.parse_args()
|
|
source = Path(__file__).absolute().parent
|
|
development = source.parent.name == 'apps'
|
|
installation = source.parent.parent if development else source.parent
|
|
runtime = installation / ('.runtime/windows/python' if development else 'python')
|
|
semantic = installation / ('.runtime/windows/semantic' if development else 'semantic')
|
|
if Path(sys.executable).resolve().parent != runtime.resolve():
|
|
raise SandboxError('Use the private Python belonging to this installation')
|
|
roots = [source, runtime]
|
|
if semantic.is_dir(): roots.append(semantic)
|
|
deadline = None
|
|
if args.provision:
|
|
# Installer-only: closing/killing this process terminates grant children.
|
|
# nsExec's own timeout renews on output, so enforce our own hard deadline.
|
|
containment = contain_inspector()
|
|
if containment.get('active') is not True or containment.get('killsDescendants') is not True:
|
|
raise SandboxError('Installer resource containment unavailable')
|
|
deadline = threading.Timer(240, lambda: os._exit(2))
|
|
deadline.daemon = True
|
|
deadline.start()
|
|
try:
|
|
sandbox = AppContainer(roots, provision=args.provision)
|
|
print(json.dumps({'verified': True, 'provisioned': args.provision, 'rootCount': len(roots), 'profile': sandbox.name}))
|
|
finally:
|
|
if deadline is not None: deadline.cancel()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
try: main()
|
|
except (SandboxError, OSError):
|
|
print('Approved installation ACL verification/provisioning failed.', file=sys.stderr)
|
|
raise SystemExit(1)
|