fix(hopper): pass private X authority cookie through stdin

This commit is contained in:
morluto
2026-10-24 02:48:54 +08:00
parent 965aff805d
commit 324ca9453e
3 changed files with 53 additions and 4 deletions
+4 -4
View File
@@ -479,13 +479,13 @@ def authorize_display(
authorized = subprocess.run(
[
xauth_path,
"-q",
"-f",
str(authority),
"add",
display_name,
".",
secrets.token_hex(16),
"source",
"-",
],
input=("add %s . %s\n" % (display_name, secrets.token_hex(16))).encode("ascii"),
check=False,
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
@@ -340,3 +340,20 @@ describe("private display probe output settlement", () => {
},
);
});
it("passes the private X authority cookie through xauth stdin", () => {
const fixture = fileURLToPath(
new URL("../../../fixtures/hopperXauthority.py", import.meta.url),
);
const process = spawnSync("python3", ["-I", "-S", fixture, helperPath], {
encoding: "utf8",
timeout: 5_000,
});
expect(process.status, process.stderr).toBe(0);
expect(JSON.parse(process.stdout)).toMatchObject({
arguments: ["fixture-xauth", "-q", "-f", expect.any(String), "source", "-"],
stdin: `add :123 . ${"0123456789abcdef".repeat(2)}\n`,
cookie_in_argv: false,
mode: 0o600,
});
});
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env python3
"""Observe the production xauth invocation without launching an X server."""
import importlib.util
import json
from pathlib import Path
import sys
import tempfile
import types
spec = importlib.util.spec_from_file_location("hopper_demo_x11", sys.argv[1])
assert spec is not None and spec.loader is not None
helper = importlib.util.module_from_spec(spec)
spec.loader.exec_module(helper)
cookie = "0123456789abcdef" * 2
calls = []
def run(arguments, **options):
calls.append((arguments, options))
return types.SimpleNamespace(returncode=0)
helper.subprocess.run = run
helper.secrets.token_hex = lambda _bytes: cookie
with tempfile.TemporaryDirectory(prefix="rea-xauth-fixture-") as root:
authority = Path(root) / "authority"
authority.touch()
helper.authorize_display(authority, ":123", "fixture-xauth")
arguments, options = calls[0]
print(json.dumps({
"arguments": arguments,
"stdin": options["input"].decode("ascii"),
"cookie_in_argv": any(cookie in value for value in arguments),
"mode": authority.stat().st_mode & 0o777,
}))