Replace Ed25519 with hashed API tokens and an in-Firefox client manager.

This commit is contained in:
alexveley
2026-09-22 07:24:35 -04:00
parent 55f7e863dc
commit 9242c01015
16 changed files with 487 additions and 339 deletions
+19 -4
View File
@@ -15,7 +15,7 @@ from urllib.parse import parse_qs, urlparse
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from fab_auth import CLIENTS_PATH, ReplayCache, verify_request # noqa: E402
from fab_auth import CLIENTS_PATH, handle_admin, verify_bearer # noqa: E402
if sys.platform == "win32":
import msvcrt
@@ -31,7 +31,6 @@ STATE_DIR = Path(os.environ.get("LOCALAPPDATA", str(Path.home()))) / "firefox-ag
STDIN_LOCK = threading.Lock()
PENDING: dict[str, tuple[threading.Event, dict[str, Any]]] = {}
PENDING_LOCK = threading.Lock()
REPLAY = ReplayCache()
def log(msg: str) -> None:
@@ -112,7 +111,7 @@ class Handler(BaseHTTPRequestHandler):
if not self._gate_ok():
return False
try:
verify_request({k: v for k, v in self.headers.items()}, http_method, path, raw_body, REPLAY)
verify_bearer({k: v for k, v in self.headers.items()})
except PermissionError as exc:
self._send(401, {"ok": False, "error": str(exc)})
return False
@@ -209,6 +208,22 @@ def stdin_loop() -> None:
break
if message is None:
break
if message.get("type") == "admin":
try:
result = handle_admin(str(message.get("method") or ""), message.get("args") or [])
send_to_extension(
{"type": "admin-result", "id": message.get("id"), "ok": True, "result": result}
)
except Exception as exc:
send_to_extension(
{
"type": "admin-result",
"id": message.get("id"),
"ok": False,
"error": str(exc),
}
)
continue
req_id = str(message.get("id") or "")
with PENDING_LOCK:
pending = PENDING.pop(req_id, None)
@@ -223,7 +238,7 @@ def stdin_loop() -> None:
def main() -> int:
STATE_DIR.mkdir(parents=True, exist_ok=True)
if not CLIENTS_PATH.exists():
log(f"no registered clients at {CLIENTS_PATH}; run tools/register_client.py add")
log(f"no registered clients at {CLIENTS_PATH}; use the add-on Manage clients page")
threading.Thread(target=stdin_loop, name="fab-stdin", daemon=True).start()
server = ThreadingHTTPServer((HOST, PORT), Handler)
log(f"listening on http://{HOST}:{PORT}")