pairling 0.2.11 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,6 @@ import plistlib
8
8
  from pathlib import Path
9
9
 
10
10
  PAIRLING_DAEMON_LABEL = "dev.pairling.companiond"
11
- PAIRLING_GUARDIAN_LABEL = "dev.pairling.power-guardian"
12
11
  PAIRLING_CONNECTD_LABEL = "dev.pairling.connectd"
13
12
  PAIRLING_PTYBROKER_LABEL = "dev.pairling.ptybroker"
14
13
  PAIRLING_RUNTIME_PORT = "7773"
@@ -24,7 +23,7 @@ def daemon_plist(current: Path, logs: Path, python_bin: str) -> dict:
24
23
  env = {
25
24
  "PAIRLING_RUNTIME_PORT": PAIRLING_RUNTIME_PORT,
26
25
  "COMPANION_DAEMON_PORT": PAIRLING_RUNTIME_PORT,
27
- "PAIRLING_BIND_MODE": "all",
26
+ "PAIRLING_BIND_MODE": "loopback",
28
27
  "PAIRLING_APP_SUPPORT_ROOT": str(current.parent.parent),
29
28
  "PAIRLING_LOGS_ROOT": str(logs),
30
29
  "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin",
@@ -44,30 +43,6 @@ def daemon_plist(current: Path, logs: Path, python_bin: str) -> dict:
44
43
  }
45
44
 
46
45
 
47
- def guardian_plist(current: Path, logs: Path, python_bin: str) -> dict:
48
- return {
49
- "Label": PAIRLING_GUARDIAN_LABEL,
50
- "ProgramArguments": [
51
- python_bin,
52
- str(current / "guardian" / "companion-power-guardian.py"),
53
- ],
54
- "EnvironmentVariables": {
55
- "PAIRLING_RUNTIME_PORT": PAIRLING_RUNTIME_PORT,
56
- "COMPANION_DAEMON_PORT": PAIRLING_RUNTIME_PORT,
57
- "COMPANION_COORDINATOR_HOST": "pairling-mac",
58
- "COMPANION_GUARDIAN_ENFORCE": "0",
59
- "COMPANION_LOW_POWER_MODE_POLICY": "preserve",
60
- "COMPANION_POWER_INTERVAL_SECONDS": "20",
61
- "COMPANION_POWER_STATE_PATH": "/var/run/pairling-power-state.json",
62
- "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin",
63
- },
64
- "RunAtLoad": True,
65
- "KeepAlive": True,
66
- "StandardOutPath": str(logs / "power-guardian.log"),
67
- "StandardErrorPath": str(logs / "power-guardian.err"),
68
- }
69
-
70
-
71
46
  def connectd_plist(current: Path, logs: Path) -> dict:
72
47
  app_support = current.parent.parent
73
48
  return {
@@ -124,7 +99,6 @@ def main() -> int:
124
99
  parser.add_argument("--logs-root", required=True)
125
100
  parser.add_argument("--output-dir", required=True)
126
101
  parser.add_argument("--daemon-python", default="/usr/local/bin/python3")
127
- parser.add_argument("--guardian-python", default="/usr/bin/python3")
128
102
  parser.add_argument("--mirror-python", default="/usr/local/bin/python3", help=argparse.SUPPRESS)
129
103
  args = parser.parse_args()
130
104
 
@@ -134,7 +108,6 @@ def main() -> int:
134
108
 
135
109
  write_plist(out / f"{PAIRLING_DAEMON_LABEL}.plist", daemon_plist(current, logs, args.daemon_python))
136
110
  write_plist(out / f"{PAIRLING_PTYBROKER_LABEL}.plist", ptybroker_plist(current, logs, args.daemon_python))
137
- write_plist(out / f"{PAIRLING_GUARDIAN_LABEL}.plist", guardian_plist(current, logs, args.guardian_python))
138
111
  write_plist(out / f"{PAIRLING_CONNECTD_LABEL}.plist", connectd_plist(current, logs))
139
112
  return 0
140
113
 
@@ -2,7 +2,6 @@
2
2
  set -euo pipefail
3
3
 
4
4
  PAIRLING_DAEMON_LABEL="dev.pairling.companiond"
5
- PAIRLING_GUARDIAN_LABEL="dev.pairling.power-guardian"
6
5
  PAIRLING_CONNECTD_LABEL="dev.pairling.connectd"
7
6
  PAIRLING_PTYBROKER_LABEL="dev.pairling.ptybroker"
8
7
  APP_SUPPORT="${PAIRLING_APP_SUPPORT_ROOT:-${COMPANION_APP_SUPPORT_ROOT:-$HOME/Library/Application Support/Pairling}}"
@@ -10,7 +9,6 @@ LOGS_ROOT="${PAIRLING_LOGS_ROOT:-${COMPANION_LOGS_ROOT:-$HOME/Library/Logs/Pairl
10
9
  USER_PLIST="$HOME/Library/LaunchAgents/$PAIRLING_DAEMON_LABEL.plist"
11
10
  CONNECTD_USER_PLIST="$HOME/Library/LaunchAgents/$PAIRLING_CONNECTD_LABEL.plist"
12
11
  PTYBROKER_USER_PLIST="$HOME/Library/LaunchAgents/$PAIRLING_PTYBROKER_LABEL.plist"
13
- SYSTEM_PLIST="/Library/LaunchDaemons/$PAIRLING_GUARDIAN_LABEL.plist"
14
12
  # Legacy: the silent-join mint broker, removed from the product. Torn down below.
15
13
  MINTD_SYSTEM_LABEL="dev.pairling.mintd"
16
14
  MINTD_SYSTEM_PLIST="/Library/LaunchDaemons/$MINTD_SYSTEM_LABEL.plist"
@@ -137,7 +135,6 @@ bootout_user "$PAIRLING_PTYBROKER_LABEL" "$PTYBROKER_USER_PLIST"
137
135
  rm -f "$USER_PLIST"
138
136
  rm -f "$CONNECTD_USER_PLIST"
139
137
  rm -f "$PTYBROKER_USER_PLIST"
140
- bootout_system "$PAIRLING_GUARDIAN_LABEL" "$SYSTEM_PLIST"
141
138
  teardown_legacy_mintd
142
139
 
143
140
  rm -rf "$APP_SUPPORT/pair" 2>/dev/null || true
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import hashlib
5
+ import json
6
+ import sys
7
+ from pathlib import Path
8
+
9
+
10
+ def fail(message: str) -> int:
11
+ print(f"payload manifest verification failed: {message}", file=sys.stderr)
12
+ return 1
13
+
14
+
15
+ def sha256(path: Path) -> str:
16
+ digest = hashlib.sha256()
17
+ with path.open("rb") as fh:
18
+ for chunk in iter(lambda: fh.read(1024 * 1024), b""):
19
+ digest.update(chunk)
20
+ return digest.hexdigest()
21
+
22
+
23
+ def payload_file(payload_root: Path, rel: str) -> Path | None:
24
+ path = Path(rel)
25
+ if path.is_absolute() or ".." in path.parts:
26
+ return None
27
+ parts = path.parts
28
+ if not parts or parts[0] != "payload":
29
+ return None
30
+ return payload_root.joinpath(*parts[1:])
31
+
32
+
33
+ def main() -> int:
34
+ if len(sys.argv) != 3:
35
+ return fail("usage: verify-payload-manifest.py <payload-root> <payload-manifest.json>")
36
+ payload_root = Path(sys.argv[1]).resolve()
37
+ manifest_path = Path(sys.argv[2]).resolve()
38
+ try:
39
+ manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
40
+ except (OSError, json.JSONDecodeError) as exc:
41
+ return fail(f"cannot read manifest: {exc}")
42
+ if not isinstance(manifest, dict) or manifest.get("schema_version") != 1:
43
+ return fail("unsupported manifest schema")
44
+ files = manifest.get("files")
45
+ if not isinstance(files, list) or not files:
46
+ return fail("manifest has no files")
47
+ for item in files:
48
+ if not isinstance(item, dict):
49
+ return fail("manifest file entry is not an object")
50
+ rel = str(item.get("path") or "")
51
+ expected = str(item.get("sha256") or "")
52
+ if len(expected) != 64 or any(c not in "0123456789abcdef" for c in expected.lower()):
53
+ return fail(f"bad sha256 for {rel or '<missing path>'}")
54
+ target = payload_file(payload_root, rel)
55
+ if target is None:
56
+ return fail(f"bad payload path {rel!r}")
57
+ try:
58
+ resolved = target.resolve(strict=True)
59
+ except OSError:
60
+ return fail(f"missing payload file {rel}")
61
+ if payload_root not in (resolved, *resolved.parents):
62
+ return fail(f"payload path escapes root {rel!r}")
63
+ actual = sha256(resolved)
64
+ if actual.lower() != expected.lower():
65
+ return fail(f"sha256 mismatch for {rel}")
66
+ print(f"payload manifest verified: {len(files)} files")
67
+ return 0
68
+
69
+
70
+ if __name__ == "__main__":
71
+ raise SystemExit(main())
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "connectd": {
3
3
  "darwin-arm64": {
4
- "sha256": "2bd3903963b0395cc2af25c0ca88450873b8f878fa8b0fcf5b70283fde21602f",
4
+ "sha256": "29af8f7c4d4291e487804bf84e918ae58d35e258ee542c70884ab107e94b63fa",
5
5
  "team_id": "965AVD34A3"
6
6
  },
7
7
  "darwin-x64": {
8
- "sha256": "301fe95148dbc5a5144165802319d817a4a5c8f1492d0b5a11ef101f4fffbc9e",
8
+ "sha256": "6df440f47c58dc520396ed4bf8b437545b27c87d6e3787c20ce212b6a3a58f6d",
9
9
  "team_id": "965AVD34A3"
10
10
  }
11
11
  },
@@ -20,11 +20,11 @@
20
20
  },
21
21
  {
22
22
  "path": "payload/mac/SOURCE_REVISION",
23
- "sha256": "48e3c96b6c22c6c3424b1fbcebbbee0e23f0e61535ac6b487dec510a496cb6ef"
23
+ "sha256": "2828a4f7792a6e97ac014e5205bdcf361ced85eff86009de975b92da14959e2b"
24
24
  },
25
25
  {
26
26
  "path": "payload/mac/VERSION",
27
- "sha256": "bbab81dca58f2b892db293acbba7fe5731667b67876f6812e3e7b9e2253a5c51"
27
+ "sha256": "b1d246bf58dfe9d621c372fbca4fdda71a56ddd79c641b9e3b7dde08ca4d7512"
28
28
  },
29
29
  {
30
30
  "path": "payload/mac/companiond/app_attest_lan.py",
@@ -80,7 +80,7 @@
80
80
  },
81
81
  {
82
82
  "path": "payload/mac/companiond/pairling_pairing.py",
83
- "sha256": "6d6aab5cfa12daff6b83f25c6844253432dfec3f20bec30a072875a19dba23cb"
83
+ "sha256": "9b1046d54b7b1c026186e9d1f1dae4ff33de3c66f36f37b8842b2be7fcaeb36c"
84
84
  },
85
85
  {
86
86
  "path": "payload/mac/companiond/pairling_psk.py",
@@ -96,7 +96,7 @@
96
96
  },
97
97
  {
98
98
  "path": "payload/mac/companiond/pairlingd.py",
99
- "sha256": "ad3d9929966d41778de40be0ae908ea22ec49f811f9a6aceabd606aa41b6a2db"
99
+ "sha256": "0377e193d6ac49bfb55979bb4c17635caa1f2cbcb8c85c0d51447cf07939f908"
100
100
  },
101
101
  {
102
102
  "path": "payload/mac/companiond/providers/__init__.py",
@@ -148,19 +148,19 @@
148
148
  },
149
149
  {
150
150
  "path": "payload/mac/companiond/runtime_contract.py",
151
- "sha256": "70fa5b830d94bbae44b4d000d55f334c54f4be4008c9da560e34af4c0a709846"
151
+ "sha256": "903c4bef29b17454c8dde50ebaa9b7107e8d5a113f25b2a0861b18e544b7b9ee"
152
152
  },
153
153
  {
154
154
  "path": "payload/mac/companiond/runtime_manifest.py",
155
- "sha256": "72d61833a74e8171157784bee252f3e0f0bb15d77b740c2ffb2d82214d3b4933"
155
+ "sha256": "c38f2bca253b9364263593ad8443bdf4ebbb80f823a11f8a66cc0a142e944f3d"
156
156
  },
157
157
  {
158
158
  "path": "payload/mac/companiond/runtime_paths.py",
159
- "sha256": "5d6be15c373c89f1d12d142dd25bc175b688af703398d8cf4cc71f06b98ec4cc"
159
+ "sha256": "d5f0c2546e50c1fa30e9e2c043c0ef97e924cb0c92626c2885c577b9b4e613ad"
160
160
  },
161
161
  {
162
162
  "path": "payload/mac/companiond/safety_monitor.py",
163
- "sha256": "54122cd85220f5e698de36cbab0eace74bfcf3b4ed4ab3777f709378e631540a"
163
+ "sha256": "eb2aebe73214d8cafa810295f0b1a63933b5f850d3e45533108b55d2b9c4b08e"
164
164
  },
165
165
  {
166
166
  "path": "payload/mac/companiond/sentinel_notifications.py",
@@ -232,11 +232,11 @@
232
232
  },
233
233
  {
234
234
  "path": "payload/mac/connectd/internal/gateway/proxy.go",
235
- "sha256": "9d57225667f5ab025286c6714864762cbd31a8bdaf176f2b5679a26ca7144f74"
235
+ "sha256": "39d736dc16ccd2e7118605d36014d63f0bedf0b6c08fbb64ee5cf7b795869119"
236
236
  },
237
237
  {
238
238
  "path": "payload/mac/connectd/internal/gateway/proxy_test.go",
239
- "sha256": "f3a6b1974c1ccba8e5e380d18c31a5aca61458b6d4a1075865b8978e86e54209"
239
+ "sha256": "678025830386e2175fcf84adc18537bb673a97db1d29cbd7c79ef5cc1721d6f2"
240
240
  },
241
241
  {
242
242
  "path": "payload/mac/connectd/internal/runtime/config.go",
@@ -254,25 +254,17 @@
254
254
  "path": "payload/mac/connectd/internal/status/status_test.go",
255
255
  "sha256": "5d2c9601c5edf6afc0abc7d4737cc06fd4e3a53cb83c0fce4b51750c1e194366"
256
256
  },
257
- {
258
- "path": "payload/mac/guardian/companion-power-guardian.py",
259
- "sha256": "b613f57b886a88a047b9f226ae0d9c160932b114f6957b1721988363f80eeca9"
260
- },
261
- {
262
- "path": "payload/mac/guardian/guardian_contract.py",
263
- "sha256": "18f08827a61b165b21f47616bfc7a6aacf1d309672ddd83dee411415d9af10dd"
264
- },
265
257
  {
266
258
  "path": "payload/mac/install/bootstrap-first-run.sh",
267
- "sha256": "ae15dc2cbe4862fe9ec70165d8876757063d2e70aa883638967f858b53ecc18d"
259
+ "sha256": "294c74c9cd07af6d738dfbad5f125f9a142c358d659506466a4e8c3df62243c5"
268
260
  },
269
261
  {
270
262
  "path": "payload/mac/install/doctor.sh",
271
- "sha256": "1ba291c2c7def20af4ab4c850df0aaf54c41065da7e77255d8a6ff3bdfbeb2cc"
263
+ "sha256": "87f817965611e59cb84b1547dd59352f0f637d66084e3d4d7a84cea299ad82e2"
272
264
  },
273
265
  {
274
266
  "path": "payload/mac/install/install-runtime.sh",
275
- "sha256": "2575f5ae2aeb03d6bce5ae1194498ac34d14d09c993c4a1a4474e187cae10618"
267
+ "sha256": "2cba0b8bc3731c5725aae2229fe4b2069f71c4f269e1cc212c03197152561daf"
276
268
  },
277
269
  {
278
270
  "path": "payload/mac/install/psk_dependency_check.py",
@@ -280,11 +272,15 @@
280
272
  },
281
273
  {
282
274
  "path": "payload/mac/install/render-launchd.py",
283
- "sha256": "29db1aa46d62cd23ba27ab283bb990d168bfc08fb82cfc681046dc7b887d85fe"
275
+ "sha256": "454b8ed22c801fce9c557cfcd09928cd01caf9c37a517ece0ec424a5532b95c4"
284
276
  },
285
277
  {
286
278
  "path": "payload/mac/install/uninstall-runtime.sh",
287
- "sha256": "0edeb5336a71c235d8796a8e59072c6d8983d196de5aae0cfcb4b0c3560fa33f"
279
+ "sha256": "10cd5eb9ea5424a7a71b6c92a0eba97d2d524807d49e7e0035c51ad4f1fce546"
280
+ },
281
+ {
282
+ "path": "payload/mac/install/verify-payload-manifest.py",
283
+ "sha256": "131788b553d88077ba7f0592579b3c702fb91a328b7cd81d596358051df1ba48"
288
284
  },
289
285
  {
290
286
  "path": "payload/mac/mcp/phone_tools.py",
@@ -296,8 +292,8 @@
296
292
  }
297
293
  ],
298
294
  "package": "pairling",
299
- "package_version": "0.2.11",
295
+ "package_version": "0.2.12",
300
296
  "schema_version": 1,
301
297
  "source_dirty": false,
302
- "source_revision": "83c69e1"
298
+ "source_revision": "71ea638dd7f9fe82a505448f437113380eec83aa"
303
299
  }