2026-10-13 10:33:31 +02:00
|
|
|
"""Single-request parser entrypoint, launched only inside the AppContainer."""
|
|
|
|
|
import base64
|
|
|
|
|
import json
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def attest_appcontainer():
|
|
|
|
|
import ctypes
|
|
|
|
|
from ctypes import wintypes as W
|
|
|
|
|
if sys.platform != 'win32': raise RuntimeError('Windows AppContainer required')
|
|
|
|
|
kernel=ctypes.WinDLL('kernel32',use_last_error=True)
|
|
|
|
|
advapi=ctypes.WinDLL('advapi32',use_last_error=True)
|
|
|
|
|
kernel.GetCurrentProcess.restype=W.HANDLE
|
|
|
|
|
kernel.CloseHandle.argtypes=[W.HANDLE]
|
|
|
|
|
advapi.OpenProcessToken.argtypes=[W.HANDLE,W.DWORD,ctypes.POINTER(W.HANDLE)]
|
|
|
|
|
advapi.GetTokenInformation.argtypes=[W.HANDLE,ctypes.c_int,ctypes.c_void_p,W.DWORD,ctypes.POINTER(W.DWORD)]
|
|
|
|
|
token=W.HANDLE();value=W.DWORD();length=W.DWORD()
|
|
|
|
|
if not advapi.OpenProcessToken(kernel.GetCurrentProcess(),8,ctypes.byref(token)):
|
|
|
|
|
raise RuntimeError('Process token unavailable')
|
|
|
|
|
try:
|
|
|
|
|
if not advapi.GetTokenInformation(token,29,ctypes.byref(value),4,ctypes.byref(length)) or value.value!=1:
|
|
|
|
|
raise RuntimeError('Uncontained parser process rejected')
|
|
|
|
|
# TokenCapabilities is TOKEN_GROUPS; no capability SID may be enabled.
|
|
|
|
|
advapi.GetTokenInformation(token,30,None,0,ctypes.byref(length))
|
|
|
|
|
if not 4<=length.value<=65536: raise RuntimeError('Capability token unavailable')
|
|
|
|
|
capabilities=ctypes.create_string_buffer(length.value)
|
|
|
|
|
if not advapi.GetTokenInformation(token,30,capabilities,length.value,ctypes.byref(length)) or ctypes.cast(capabilities,ctypes.POINTER(W.DWORD)).contents.value!=0:
|
|
|
|
|
raise RuntimeError('Unexpected parser process capability')
|
|
|
|
|
finally:kernel.CloseHandle(token)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
attest_appcontainer()
|
|
|
|
|
# Preserve only the broker response pipe; parser/native diagnostics cannot
|
|
|
|
|
# contaminate the protocol or leak document content through stderr.
|
|
|
|
|
response = os.fdopen(os.dup(sys.stdout.fileno()), 'w', encoding='utf-8', buffering=1)
|
|
|
|
|
sink = os.open(os.devnull, os.O_WRONLY)
|
|
|
|
|
os.dup2(sink,sys.stdout.fileno());os.dup2(sink,sys.stderr.fileno());os.close(sink)
|
|
|
|
|
# No socket listener, deployment credential or filesystem document input.
|
|
|
|
|
from engine import MAX_BYTES, inspect_content, scan_download, reference_document, embedding_features
|
|
|
|
|
request = json.loads(sys.stdin.buffer.read(MAX_BYTES*2+1))
|
|
|
|
|
data = base64.b64decode(request['data'], validate=True)
|
|
|
|
|
if len(data)>MAX_BYTES: raise ValueError('Document exceeds inspection budget')
|
|
|
|
|
route = request['route']
|
2026-10-13 16:58:15 +02:00
|
|
|
from stage_timings import collect, metadata
|
|
|
|
|
with collect(request.get('policy', {})) as timings:
|
|
|
|
|
if route == '/inspect': result = inspect_content(data, request['policy'])
|
|
|
|
|
elif route == '/scan-download': result = scan_download(data, request['policy'])
|
|
|
|
|
elif route == '/reference-document': result = reference_document(data)
|
|
|
|
|
elif route == '/embed': result = embedding_features(data)
|
|
|
|
|
else: raise ValueError('Unknown inspection operation')
|
|
|
|
|
diagnostic = metadata(timings)
|
|
|
|
|
if diagnostic is not None: result['_diagnosticStages'] = diagnostic
|
2026-10-13 10:33:31 +02:00
|
|
|
response.write(json.dumps(result, allow_nan=False))
|
|
|
|
|
response.flush()
|
|
|
|
|
response.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
try: main()
|
|
|
|
|
except Exception: sys.exit(2)
|