Intercept the WSL OpenBao browser launch.
OpenBao opens the login with cmd.exe /c start, so the xdg-open launcher never ran. The attended PATH now supplies cmd.exe for that one allowlisted URL and opens it in the empty Playwright Chromium profile. Assistant: grok Assistant-Session: 01a198fa-fd27-7e41-a0a2-57355c3e4efd
This commit is contained in:
parent
2aab7f6f2b
commit
8d4d285643
4 changed files with 69 additions and 13 deletions
31
scripts/operator-browser/cmd.exe
Executable file
31
scripts/operator-browser/cmd.exe
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Intercept OpenBao's WSL browser launch.
|
||||
|
||||
hashicorp/cap opens a WSL login with `cmd.exe /c start <url>`. That reaches
|
||||
the Windows default browser. This command sits ahead of the real cmd.exe on
|
||||
the attended-login PATH and opens the allowlisted URL in Playwright Chromium.
|
||||
"""
|
||||
import os
|
||||
import runpy
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
REAL_CMD = "/mnt/c/Windows/System32/cmd.exe"
|
||||
launcher = runpy.run_path(str(Path(__file__).resolve().with_name("xdg-open")))
|
||||
|
||||
|
||||
def main():
|
||||
kind, url = launcher["classify_cmd"](sys.argv[1:])
|
||||
if kind == "open":
|
||||
launcher["stamp"]("called")
|
||||
return launcher["open_url"](url)
|
||||
if kind == "reject":
|
||||
launcher["stamp"]("called")
|
||||
launcher["stamp"]("rejected")
|
||||
return 1
|
||||
os.execv(REAL_CMD, [REAL_CMD, *sys.argv[1:]])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
|
@ -78,6 +78,20 @@ def launch_argv(browser, profile_dir, url):
|
|||
]
|
||||
|
||||
|
||||
def classify_cmd(argv):
|
||||
"""Classify OpenBao's WSL launch, `cmd.exe /c start <url>`.
|
||||
|
||||
hashicorp/cap replaces each & with ^& before calling the Windows
|
||||
default browser. Other cmd.exe uses are left for the real binary.
|
||||
"""
|
||||
if list(argv[:2]) != ["/c", "start"] or len(argv) != 3:
|
||||
return "delegate", ""
|
||||
url = str(argv[2]).replace("^&", "&")
|
||||
if allowed(url):
|
||||
return "open", url
|
||||
return "reject", ""
|
||||
|
||||
|
||||
def stamp(result):
|
||||
path = Path("/home/worsch/.local/state/railiance/receipts/operator-browser-last.txt")
|
||||
try:
|
||||
|
|
@ -88,11 +102,7 @@ def stamp(result):
|
|||
return
|
||||
|
||||
|
||||
def main():
|
||||
stamp("called")
|
||||
if len(sys.argv) != 2 or not allowed(sys.argv[1]):
|
||||
stamp("rejected")
|
||||
return 1
|
||||
def open_url(url):
|
||||
if not os.environ.get("DISPLAY") and not os.environ.get("WAYLAND_DISPLAY"):
|
||||
stamp("no-display")
|
||||
return 1
|
||||
|
|
@ -102,7 +112,7 @@ def main():
|
|||
return 1
|
||||
profile = Path(tempfile.mkdtemp(prefix="operator-browser-"))
|
||||
os.chmod(profile, 0o700)
|
||||
command = launch_argv(browser, str(profile), sys.argv[1])
|
||||
command = launch_argv(browser, str(profile), url)
|
||||
try:
|
||||
subprocess.Popen(
|
||||
command,
|
||||
|
|
@ -118,5 +128,13 @@ def main():
|
|||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
stamp("called")
|
||||
if len(sys.argv) != 2 or not allowed(sys.argv[1]):
|
||||
stamp("rejected")
|
||||
return 1
|
||||
return open_url(sys.argv[1])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue