"""Shared fake `bw` binary source used by the offline test suites. The fake records, per invocation: argv, the *names* of secret-channel env vars it received (never values), and its own /proc/self/cmdline. State lives under BITWARDENCLI_APPDATA_DIR: state.json + items.json. """ FAKE_BW = r'''#!/usr/bin/env python3 import json, os, sys D = os.environ.get("BITWARDENCLI_APPDATA_DIR") if not D: print("missing BITWARDENCLI_APPDATA_DIR", file=sys.stderr); sys.exit(9) os.makedirs(D, exist_ok=True) with open(os.path.join(D, "calls.jsonl"), "a") as fh: try: cmdline = open("/proc/self/cmdline", "rb").read().decode("utf-8", "replace") except OSError: cmdline = "" fh.write(json.dumps({ "argv": sys.argv, "env_names": sorted(k for k in os.environ if k.startswith(("BW_", "VAULT_", "BROKER_", "AGENT_BROKER_"))), "cmdline": cmdline, }) + "\n") args = [a for a in sys.argv[1:] if a != "--nointeraction"] state_file = os.path.join(D, "state.json") def load(): try: return json.load(open(state_file)) except Exception: return {} def save(st): json.dump(st, open(state_file, "w")) def die(msg, rc=1): print(msg, file=sys.stderr); sys.exit(rc) st = load() if args[:2] == ["config", "server"]: st["server"] = args[2]; save(st) print("Saved setting `config`."); sys.exit(0) if args and args[0] == "status": status = ("unauthenticated" if not st.get("logged_in") else "unlocked" if st.get("session") else "locked") print(json.dumps({"serverUrl": st.get("server"), "status": status})) sys.exit(0) if args and args[0] == "login" and "--apikey" in args: if os.environ.get("BW_CLIENTID") == "user.fixture-id" and \ os.environ.get("BW_CLIENTSECRET") == "fixture-client-secret": st["logged_in"] = True; save(st) print("You are logged in!"); sys.exit(0) die("Invalid client_id") if args and args[0] == "unlock": if "--check" in args: die("Vault is locked.", 1) if not st.get("session") else \ (print("Vault is unlocked."), sys.exit(0)) pw = None if "--passwordenv" in args: pw = os.environ.get(args[args.index("--passwordenv") + 1]) if "--passwordfile" in args: pw = open(args[args.index("--passwordfile") + 1]).readline().rstrip("\n") if pw == "fixture-master-password-DO-NOT-USE": st["session"] = "fixture-session-key-" + os.urandom(4).hex(); save(st) print(st["session"] if "--raw" in args else "Your vault is now unlocked!") sys.exit(0) die("Cryptography error, The decryption operation failed") def need_session(): if not st.get("session") or os.environ.get("BW_SESSION") != st["session"]: die("Vault is locked.") if args and args[0] == "sync": need_session(); print("Syncing complete."); sys.exit(0) if args[:2] == ["list", "items"]: need_session() print(open(os.path.join(D, "items.json")).read()); sys.exit(0) if args[:2] == ["get", "item"]: need_session() for it in json.load(open(os.path.join(D, "items.json"))): if it["id"] == args[2]: print(json.dumps(it)); sys.exit(0) die("Not found.") if args and args[0] == "lock": st.pop("session", None); save(st) print("Your vault is now locked."); sys.exit(0) if args and args[0] == "logout": st.clear(); save(st) print("You have logged out."); sys.exit(0) die("unknown cmd " + " ".join(args)) '''