32 lines
2.7 KiB
Python
32 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
from __future__ import annotations
|
|
import argparse,ast,hashlib,json
|
|
from pathlib import Path
|
|
SOURCE=(5298,"2679f03617241abf37ca547141a2a51e3f89b75fec957a1da4f13b904d931f2d");TESTS=(2496,"3760fa60e66857b24bf507f196060ec9e4d8b96ebce3843ab02fc185c0f8c0b8");NETWORK={"socket","select","selectors","subprocess","urllib","http","requests"}
|
|
def exact(path,identity):data=path.read_bytes();return (len(data),hashlib.sha256(data).hexdigest())==identity
|
|
def errors(record,root=None):
|
|
out=[];a=record.get("activation",{})
|
|
if record.get("status")!="HOST_OBSERVER_CONTRACT_COMPLETE_LIVE_REQUEST_UNFORMABLE":out.append("status")
|
|
if a.get("active") is not False or any(v is not None for k,v in a.items() if k!="active"):out.append("activation")
|
|
if any(record.get("authorizations",{}).values()) or any(record.get("implementation_boundary",{}).values()):out.append("capability")
|
|
evidence=record.get("current_evidence",{})
|
|
if any(evidence.values()):out.append("evidence promoted")
|
|
contract=record.get("observer_contract",{})
|
|
if contract.get("allowlisted_methods") != ["SOURCE_BOUND_QUERY","EXACT_PATH_METADATA"] or contract.get("error_is_absence") is not False or contract.get("maximum_result_bytes")!=4096:out.append("contract")
|
|
if not all(contract.get(k) is True for k in ("shell_forbidden","directory_enumeration_forbidden","title_launch_forbidden","app_termination_forbidden","device_write_forbidden","retry_forbidden","reconnect_forbidden")):out.append("forbidden")
|
|
if record.get("decision")!={"host_observer_contract_complete":True,"live_observer_implementation_allowed":False,"live_observation_allowed":False,"device_action_allowed":False,"next_step":"OFFLINE_SOURCE_AUDIT_FOR_ONE_NONMUTATING_TITLE_PRESENCE_PRIMITIVE"}:out.append("decision")
|
|
if root:
|
|
source=root/"tools/phase10df_title_observer_contract.py";tests=root/"tests/test_phase10df_title_observer_contract.py"
|
|
if not exact(source,SOURCE):out.append("source identity")
|
|
if not exact(tests,TESTS):out.append("test identity")
|
|
tree=ast.parse(source.read_text());imports={x.name.split('.')[0] for n in ast.walk(tree) if isinstance(n,ast.Import) for x in n.names}|{(n.module or '').split('.')[0] for n in ast.walk(tree) if isinstance(n,ast.ImportFrom)}
|
|
if imports&NETWORK:out.append("network import")
|
|
return out
|
|
def main():
|
|
p=argparse.ArgumentParser();p.add_argument("--root",type=Path,required=True);root=p.parse_args().root.resolve();record=json.loads((root/"manifests/retroarch/phase-1.0df-inactive-title-presence-observer.json").read_text());found=errors(record,root)
|
|
for item in found:print("ERROR:",item)
|
|
if found:return 1
|
|
print("Phase-1.0DF inactive title observer validation passed");return 0
|
|
if __name__=="__main__":raise SystemExit(main())
|