feat(cert): add --remove-cert flag and Remove CA button for clean-slate revocation#121
Conversation
|
Reviewed the diff and ran locally on macOS host — That said, I can't auto-merge this one for two concrete reasons: 1. macOS + Linux E2E paths are self-declared as untested. You called this out in the PR body, which I appreciate. But 2. You're a new contributor to this repo (first PR). Combined with 1377 additions in a security-adjacent module, the conservative thing is to leave this open for explicit maintainer sign-off rather than auto-merging on my "cargo tests pass" alone. That's a rule rather than a reflection on the code quality. What would unblock merge: Ideally three smoke tests from three separate reviewers (one macOS, one Debian/Ubuntu-family Linux, one Fedora/RHEL-family Linux) walking through your I'll flag this in the repo for maintainer attention. If nobody steps up within a few days, I can run the macOS path myself on a disposable VM rather than my host machine — but that's slower than someone who can do it on their actual device. Two small review notes on the diff itself (not blockers):
Thanks again for the depth — this is the kind of PR I'd love to see more of. [reply via Anthropic Claude | reviewed by @therealaleph] |
|
Thanks for the careful review, the detailed context on the merge policy is appreciated, and the code-quality compliment means a lot. Quick note on the first-contributor point: this is actually not my first PR to this repo. I also contributed the On why this feature matters: the MITM CA this app installs has its private key on the user's disk, and the OS trusts it for every HTTPS site. That's a non-trivial capability to leave lying around, if the key is ever exposed (lost laptop, leaked backup, a machine sold or handed down, etc.), anyone holding it can mint certificates the browser silently accepts as legitimate for any domain. And on the OS side, a stale trusted root is effectively a standing MITM authorization until someone notices it in the cert store. Without a clean-slate uninstall path, users who try mhrv-rs and move on, or switch to Full Tunnel Mode and no longer need a local MITM, end up with that capability sitting on disk and in their trust store indefinitely. So I think having a one-command clean removal is worth some review rigor, which I fully agree with. On the two small notes, I've pushed a follow-up commit addressing both:
Test count: 109/109 passing. On the platform-coverage bar completely reasonable, and no pressure on the VM offer. Take it when it's convenient. If any macOS or Linux reviewer sees this thread and wants to walk the Thanks again. |
|
Heads-up: we just rewrote git history on This PR's branch is based on the pre-rewrite SHAs, so you'll need to rebase before it can merge cleanly. Easiest path: git fetch origin
git checkout feature/delete_certificate
git rebase origin/main
# resolve any conflicts (your changes don't touch any rewritten files,
# so this should be conflict-free — just SHA pointers updating)
git push --force-with-leaseIf Functionally nothing about your PR has changed and the review is still where we left it — still awaiting macOS + Linux smoke tests from reviewers. Sorry for the disruption. [reply via Anthropic Claude | reviewed by @therealaleph] |
|
Hey @dazzling-no-more — thanks for the cert-removal work. The feature itself looks solid (the The diff is showing +16,403 / -1,210 across 95 files because the fork point predates a lot of work that's already in
So GitHub is showing this as adding all of that again, not because you wrote it twice but because git thinks your branch lacks those commits. Could you do a clean rebase onto current If the rebase gets ugly because the cert-installer conflicts are nontrivial, the cleanest path is probably: Once the diff is just the The Windows smoke test is enough to start — I'll do macOS, and we can ask for a Linux pair from someone with a Debian + RHEL box once the diff is reviewable. [reply via Anthropic Claude | reviewed by @therealaleph] |
33a0302 to
f7dbfac
Compare
|
@therealaleph rebase is done and it can be merged if you managed to test it on macos. |
mhrv-rs --remove-cert (CLI) and Remove CA button (UI) for verified clean-slate revocation. Clears OS trust store, NSS browser stores (Linux Firefox/Chrome), and the on-disk ca/ directory. config.json and the Apps Script deployment are untouched. By-name trust verification runs before browser-state mutation; OS removal failures return RemovalIncomplete with browser state intact so retries are idempotent. Sudo-aware on Unix (re-roots HOME to the real user). 29 new unit tests on the pure logic (Firefox user.js marker handling, getent passwd parsing, NSS stderr classification, NssReport state rules). Tested end-to-end on Windows by the contributor; macOS verified at merge time on real hardware (login keychain delete + NSS-missing fallback). Linux paths await user testing. Closes #121. Thanks @dazzling-no-more. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Merged in v1.7.1 — thanks for the rebase and the careful work here. Code review notes that landed me on "merge":
macOS verified at merge. I ran
So that's macOS off the "still to test" list. Linux paths still rely on the unit-test coverage and your structural similarity to the install path; if any user reports a problem we'll have logs to triage from. The mutex-on-flags exit-2 behavior also verified on macOS. Two minor follow-ups I'd take in a future PR (no urgency):
Closing #121 as released. The umbrella was the cleanest way to track this; thanks for the structured PR description making the merge call straightforward. [reply via Anthropic Claude | reviewed by @therealaleph] |
Summary
mhrv-rs --remove-cert(CLI) and a Remove CA button in the desktop UI for a verified clean-slate CA revocation: clears the OS trust store (macOS login+system keychains, Linux anchor dirs, Windows user+machine Trusted Root), best-effort NSS cleanup (Firefox profiles + Chrome/Chromium on Linux), and deletes the on-diskca/directory.config.jsonand the Apps Script deployment are never touched, so users don't have to redeployCode.gs.is_ca_trusted_by_name()verification runs before file deletion and before NSS mutation. A failed OS removal returnsRemovalIncomplete, preservesca/, and leaves browser state alone — retries are idempotent.RemovalOutcome::{Clean, NssIncomplete}lets the UI/CLI print accurate "OS CA removed, browser cleanup partial" status instead of silent false success.reconcile_sudo_environment()detectsgeteuid() == 0 + SUDO_USERat each binary'smain()entry and re-rootsHOMEto the invoking user — so data dir / Firefox profiles / macOS login keychain target the real user rather than root.Only Windows has been smoke-tested end-to-end (Install → Check → Remove → Check round-trip via both CLI and UI, plus the mutex-on-flags exit-2 behavior). The macOS and Linux paths are built from the existing install-side patterns and covered by unit tests for all the pure logic, but the platform-specific
security delete-certificate/update-ca-certificates/trust extract-compatcode paths have not been executed on real hardware in this branch. A reviewer on macOS and a reviewer on at least one Linux distro (ideally one Debian-family and one RHEL-family) walking through the test plan below before merge would be valuable.What changed
remove_ca+ per-platform helpers,RemovalOutcome,NssReport,reconcile_sudo_environment, marker-gated Firefoxenterprise_rootspref (user-authored lines preserved), idempotent NSS delete that distinguishes "cert not found" from DB-locked/corrupt errors (regression guard forSEC_ERROR_LOCKED_DATABASE)--remove-certflag, mutually exclusive with--install-cert, callsreconcile_sudo_environment()at startupCmd::RemoveCahandler, sharedcert_op_in_progressgate covering both Install and Remove, active-proxy guard for Remove (the CA keypair is live in memory while the proxy runs)MasterHttpRelayVPN) for manual cleanup paths, upgrade note about the pre-markerenterprise_rootscosmetic orphanTests
29 new unit tests covering the pure logic:
user.jsmarker-block install/strip roundtrips and idempotency (bare lines respected as user-owned)getent passwdhome-dir parsing (Debian format + malformed inputs + macOS fallback semantics)NssReport::is_clean()state rulesSide-effecting paths (
security,certutil,update-ca-certificates) are covered by manual E2E per platform since the codebase doesn't yet have a command-runner abstraction.Test plan
Windows — ✅ smoke-tested locally
cargo test --lib— 101/101 passes locallyfile=missing trust_store=not trustedafter Removemhrv-rs --install-certthenmhrv-rs --remove-cert; verify%APPDATA%\mhrv-rs\ca\gonemhrv-rs --install-cert --remove-certreturns exit 2 with--install-cert and --remove-cert cannot be combinedStill to test
Detected sudo invocation (SUDO_USER=…): re-rooting HOME to …and that the cert is removed from the real user's Firefox user.js /~/.pki/nssdb, not root'supdate-ca-certificates(e.g. move it aside) and confirmca/survives +RemovalIncompleteis reportedmhrv-rs --remove-certas normal user, confirm no sudo prompt (system-keychain probe avoids escalation when the cert isn't there)cert_op_in_progressgate prevents the raceCompatibility with
Mode::Full(#94)Full mode doesn't use the MITM CA, so Remove CA is harmless there:
ca/deleted if present → no-op in practice.