Install into all detected Firefox profile NSS databases.
(cert_path: str, cert_name: str)
| 320 | # ───────────────────────────────────────────────────────────────────────────── |
| 321 | |
| 322 | def _install_firefox(cert_path: str, cert_name: str): |
| 323 | """Install into all detected Firefox profile NSS databases.""" |
| 324 | if not _has_cmd("certutil"): |
| 325 | log.debug("NSS certutil not found — skipping Firefox install.") |
| 326 | return |
| 327 | |
| 328 | profile_dirs: list[str] = [] |
| 329 | system = platform.system() |
| 330 | |
| 331 | if system == "Windows": |
| 332 | appdata = os.environ.get("APPDATA", "") |
| 333 | profile_dirs += glob.glob(os.path.join(appdata, r"Mozilla\Firefox\Profiles\*")) |
| 334 | elif system == "Darwin": |
| 335 | profile_dirs += glob.glob(os.path.expanduser("~/Library/Application Support/Firefox/Profiles/*")) |
| 336 | else: |
| 337 | profile_dirs += glob.glob(os.path.expanduser("~/.mozilla/firefox/*.default*")) |
| 338 | profile_dirs += glob.glob(os.path.expanduser("~/.mozilla/firefox/*.release*")) |
| 339 | |
| 340 | if not profile_dirs: |
| 341 | log.debug("No Firefox profiles found.") |
| 342 | return |
| 343 | |
| 344 | for profile in profile_dirs: |
| 345 | db = f"sql:{profile}" if os.path.exists(os.path.join(profile, "cert9.db")) else f"dbm:{profile}" |
| 346 | try: |
| 347 | # Remove old entry first (ignore errors) |
| 348 | _run(["certutil", "-D", "-n", cert_name, "-d", db], check=False) |
| 349 | _run([ |
| 350 | "certutil", "-A", |
| 351 | "-n", cert_name, |
| 352 | "-t", "CT,,", |
| 353 | "-i", cert_path, |
| 354 | "-d", db, |
| 355 | ]) |
| 356 | log.info("Installed in Firefox profile: %s", os.path.basename(profile)) |
| 357 | except (subprocess.CalledProcessError, FileNotFoundError) as exc: |
| 358 | log.warning("Firefox profile %s: %s", os.path.basename(profile), exc) |
| 359 | |
| 360 | |
| 361 | def _uninstall_firefox(cert_name: str): |
no test coverage detected