Repository navigation
Expand file tree
/
Copy pathverify_framework.py
More file actions
108 lines (93 loc) · 4.38 KB
/
Copy pathverify_framework.py
File metadata and controls
108 lines (93 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""Smoke-test the built framework, including offline pip bootstrap paths."""
import hashlib
import importlib.metadata
import os
import ssl
import subprocess
import sys
import tempfile
import urllib.request
from pathlib import Path
import certifi
import cffi
import objc
import requests
import xattr
import yaml
from Foundation import NSObject
from packaging.version import Version
# emSign ECC Root CA - G3, removed by certifi 2026.10.19. Other emSign roots
# remain trusted by that release and must not be rejected just by their names.
REVOKED_ROOT = "86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b"
PIP_CHECK = """
import hashlib
import ssl
import pip
from pip._vendor import certifi
if tuple(map(int, pip.__version__.split('.'))) < (26, 2, 2):
raise RuntimeError('Vulnerable pip: ' + pip.__version__)
context = ssl.create_default_context(cafile=certifi.where())
if {revoked!r} in {{hashlib.sha256(c).hexdigest() for c in context.get_ca_certs(binary_form=True)}}:
raise RuntimeError('pip still trusts the compromised emSign root')
print('Verified pip', pip.__version__, certifi.where(), flush=True)
""".format(revoked=REVOKED_ROOT)
def run(*args):
subprocess.run(args, check=True)
def check_context(context):
fingerprints = {
hashlib.sha256(cert).hexdigest()
for cert in context.get_ca_certs(binary_form=True)
}
if not fingerprints or REVOKED_ROOT in fingerprints:
raise RuntimeError("Missing CA bundle or compromised emSign root still trusted")
def main():
print(f"Verifying framework: {sys.version}", flush=True)
# Exercise native extensions as well as their package metadata. This also
# covers source builds when wheels are not yet available for a new Python.
if cffi.FFI().sizeof("int") != 4:
raise RuntimeError("CFFI native extension check failed")
if NSObject.alloc().init() is None:
raise RuntimeError("PyObjC Foundation bridge check failed")
if yaml.safe_load("enabled: true") != {"enabled": True}:
raise RuntimeError("PyYAML check failed")
with tempfile.NamedTemporaryFile(prefix="macadmins-xattr-verify-") as temporary:
attributes = xattr.xattr(temporary.name)
attributes["io.macadmins.python.verify"] = b"working"
if attributes["io.macadmins.python.verify"] != b"working":
raise RuntimeError("xattr native extension check failed")
print("Verified CFFI, PyObjC, PyYAML, and xattr", flush=True)
for package, minimum in (("certifi", "2026.10.19"), ("pip", "26.2.2")):
version = importlib.metadata.version(package)
if Version(version) < Version(minimum):
raise RuntimeError(f"{package} {version} is older than {minimum}")
print(f"Verified {package} {version}", flush=True)
if os.environ.get("SSL_CERT_FILE") != certifi.where():
raise RuntimeError("sitecustomize did not select the bundled certifi CA store")
check_context(ssl.create_default_context())
check_context(ssl.create_default_context(cafile=certifi.where()))
run(sys.executable, "-I", "-c", PIP_CHECK)
run(sys.executable, "-I", "-m", "pip", "check")
# Exercise relocated console scripts as well as python -m entry points.
run(str(Path(sys.prefix) / "bin/pip"), "--version")
run(str(Path(sys.prefix) / "bin/virtualenv"), "--version")
run(str(Path(sys.prefix) / "bin/black"), "--version")
with tempfile.TemporaryDirectory(prefix="macadmins-python-verify-") as temporary:
root = Path(temporary)
# Neither command may fetch a newer pip to hide an outdated seed wheel.
run(sys.executable, "-I", "-m", "venv", str(root / "venv"))
run(str(root / "venv/bin/python"), "-I", "-c", PIP_CHECK)
run(
sys.executable, "-I", "-m", "virtualenv",
"--no-download", "--no-periodic-update",
"--app-data", str(root / "app-data"), str(root / "virtualenv"),
)
run(str(root / "virtualenv/bin/python"), "-I", "-c", PIP_CHECK)
for url in ("https://www.python.org/", "https://pypi.org/simple/pip/"):
with urllib.request.urlopen(url, timeout=30) as response:
if response.status != 200:
raise RuntimeError(f"HTTPS check failed: {url}")
requests.get(url, timeout=30).raise_for_status()
print(f"Verified stdlib and Requests HTTPS: {url}", flush=True)
print("Framework verification passed", flush=True)
if __name__ == "__main__":
main()