mirror of
https://github.com/masterking32/MasterHttpRelayVPN.git
synced 2026-05-17 21:24:37 +03:00
feat: enhance certificate management with uninstall functionality
This commit is contained in:
@@ -232,7 +232,7 @@ Firefox uses its own certificate store, so even after OS-level install you need
|
||||
|
||||
> **Auto-install on startup:** When running in `apps_script` mode the proxy will automatically detect if the CA is not yet trusted and attempt to install it for you. If it succeeds you'll see a confirmation in the log; if it fails (e.g. needs administrator rights) it will print instructions. You can also run `python main.py --install-cert` at any time to (re-)install the certificate.
|
||||
|
||||
> **Uninstalling:** To remove the certificate from your system's trust stores, run `python main.py --uninstall-cert` or use `python start.bat --uninstall-cert` on Windows. This removes the certificate from all system trust stores and Firefox profiles.
|
||||
> **Uninstalling:** To remove the certificate from your system's trust stores, run `python main.py --uninstall-cert` or use `start.bat --uninstall-cert` on Windows. This removes the certificate from all system trust stores and Firefox profiles.
|
||||
|
||||
> ⚠️ **Security note:** This certificate only works locally on your machine. Don't share the `ca/` folder with anyone. If you want to start fresh, delete the `ca/` folder and the tool will generate a new one.
|
||||
|
||||
|
||||
+1
-1
@@ -291,7 +291,7 @@ python3 main.py --disable-socks5
|
||||
python3 main.py --log-level DEBUG
|
||||
python3 main.py -c /path/to/config.json
|
||||
python3 main.py --install-cert # نصب گواهی CA و خروج
|
||||
python3 main.py --uninstall-cert # حذف گراهی CA و خروج
|
||||
python3 main.py --uninstall-cert # حذف گواهی CA و خروج
|
||||
python3 main.py --no-cert-check # رد شدن از بررسی خودکار گواهی
|
||||
python3 main.py --scan # اسکن IP های Google و یافتن سریعترین
|
||||
```
|
||||
|
||||
@@ -108,6 +108,28 @@ def parse_args():
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
# Handle cert-only commands before loading config so they can run standalone.
|
||||
if args.install_cert or args.uninstall_cert:
|
||||
setup_logging("INFO")
|
||||
_log = logging.getLogger("Main")
|
||||
|
||||
if args.install_cert:
|
||||
_log.info("Installing CA certificate…")
|
||||
if not os.path.exists(CA_CERT_FILE):
|
||||
from mitm import MITMCertManager
|
||||
MITMCertManager() # side-effect: creates ca/ca.crt + ca/ca.key
|
||||
ok = install_ca(CA_CERT_FILE)
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
_log.info("Removing CA certificate…")
|
||||
ok = uninstall_ca(CA_CERT_FILE)
|
||||
if ok:
|
||||
_log.info("CA certificate removed successfully.")
|
||||
else:
|
||||
_log.warning("CA certificate removal may have failed. Check logs above.")
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
config_path = args.config
|
||||
|
||||
try:
|
||||
@@ -195,24 +217,6 @@ def main():
|
||||
print("Deploy the Apps Script from Code.gs and paste the Deployment ID.")
|
||||
sys.exit(1)
|
||||
|
||||
# ── Certificate installation ──────────────────────────────────────────
|
||||
if args.install_cert:
|
||||
setup_logging("INFO")
|
||||
_log = logging.getLogger("Main")
|
||||
_log.info("Installing CA certificate…")
|
||||
ok = install_ca(CA_CERT_FILE)
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
# ── Certificate uninstallation ───────────────────────────────────────────
|
||||
if args.uninstall_cert:
|
||||
setup_logging("INFO")
|
||||
_log = logging.getLogger("Main")
|
||||
_log.info("Removing CA certificate…")
|
||||
ok = uninstall_ca(CA_CERT_FILE)
|
||||
if ok:
|
||||
_log.info("CA certificate removed successfully.")
|
||||
else:
|
||||
_log.warning("CA certificate removal may have failed. Check logs above.")
|
||||
# ── Google IP Scanner ──────────────────────────────────────────────────
|
||||
if args.scan:
|
||||
setup_logging("INFO")
|
||||
|
||||
+26
-10
@@ -383,8 +383,11 @@ def _uninstall_firefox(cert_name: str):
|
||||
for profile in profile_dirs:
|
||||
db = f"sql:{profile}" if os.path.exists(os.path.join(profile, "cert9.db")) else f"dbm:{profile}"
|
||||
try:
|
||||
_run(["certutil", "-D", "-n", cert_name, "-d", db], check=False)
|
||||
result = _run(["certutil", "-D", "-n", cert_name, "-d", db], check=False)
|
||||
if result.returncode == 0:
|
||||
log.info("Removed from Firefox profile: %s", os.path.basename(profile))
|
||||
else:
|
||||
log.debug("Firefox profile %s: certificate not present", os.path.basename(profile))
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as exc:
|
||||
log.debug("Firefox profile %s: %s", os.path.basename(profile), exc)
|
||||
|
||||
@@ -393,11 +396,14 @@ def _uninstall_firefox(cert_name: str):
|
||||
# Uninstall functions
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
def _uninstall_windows(cert_name: str) -> bool:
|
||||
def _uninstall_windows(cert_path: str, cert_name: str) -> bool:
|
||||
"""Remove certificate from the Windows Trusted Root store."""
|
||||
thumbprint = _cert_thumbprint(cert_path)
|
||||
|
||||
# Try per-user store first (no admin required)
|
||||
try:
|
||||
_run(["certutil", "-delstore", "-user", "Root", cert_name])
|
||||
target = thumbprint if thumbprint else cert_name
|
||||
_run(["certutil", "-delstore", "-user", "Root", target])
|
||||
log.info("Certificate removed from Windows user Trusted Root store.")
|
||||
return True
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as exc:
|
||||
@@ -405,7 +411,8 @@ def _uninstall_windows(cert_name: str) -> bool:
|
||||
|
||||
# Try system store (requires admin)
|
||||
try:
|
||||
_run(["certutil", "-delstore", "Root", cert_name])
|
||||
target = thumbprint if thumbprint else cert_name
|
||||
_run(["certutil", "-delstore", "Root", target])
|
||||
log.info("Certificate removed from Windows system Trusted Root store.")
|
||||
return True
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as exc:
|
||||
@@ -413,11 +420,20 @@ def _uninstall_windows(cert_name: str) -> bool:
|
||||
|
||||
# Fallback: use PowerShell
|
||||
try:
|
||||
if thumbprint:
|
||||
ps_cmd = (
|
||||
f"Remove-Item -Path Cert:\\CurrentUser\\Root\\{cert_name} -Force -ErrorAction SilentlyContinue"
|
||||
"Get-ChildItem Cert:\\CurrentUser\\Root | "
|
||||
f"Where-Object {{ $_.Thumbprint -eq '{thumbprint}' }} | "
|
||||
"Remove-Item -Force -ErrorAction SilentlyContinue"
|
||||
)
|
||||
_run(["powershell", "-NoProfile", "-Command", ps_cmd], check=False)
|
||||
log.info("Attempted certificate removal via PowerShell.")
|
||||
else:
|
||||
ps_cmd = (
|
||||
"Get-ChildItem Cert:\\CurrentUser\\Root | "
|
||||
f"Where-Object {{ $_.Subject -like '*CN={cert_name}*' -or $_.FriendlyName -eq '{cert_name}' }} | "
|
||||
"Remove-Item -Force -ErrorAction SilentlyContinue"
|
||||
)
|
||||
_run(["powershell", "-NoProfile", "-Command", ps_cmd])
|
||||
log.info("Certificate removal via PowerShell completed.")
|
||||
return True
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as exc:
|
||||
log.error("PowerShell removal failed: %s", exc)
|
||||
@@ -436,7 +452,7 @@ def _uninstall_macos(cert_name: str) -> bool:
|
||||
"security", "delete-certificate",
|
||||
"-c", cert_name,
|
||||
login_keychain,
|
||||
], check=False)
|
||||
])
|
||||
log.info("Certificate removed from macOS login keychain.")
|
||||
return True
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as exc:
|
||||
@@ -448,7 +464,7 @@ def _uninstall_macos(cert_name: str) -> bool:
|
||||
"sudo", "security", "delete-certificate",
|
||||
"-c", cert_name,
|
||||
"/Library/Keychains/System.keychain",
|
||||
], check=False)
|
||||
])
|
||||
log.info("Certificate removed from macOS system keychain.")
|
||||
return True
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as exc:
|
||||
@@ -582,7 +598,7 @@ def uninstall_ca(cert_path: str, cert_name: str = CERT_NAME) -> bool:
|
||||
log.info("Removing CA certificate from %s…", system)
|
||||
|
||||
if system == "Windows":
|
||||
ok = _uninstall_windows(cert_name)
|
||||
ok = _uninstall_windows(cert_path, cert_name)
|
||||
elif system == "Darwin":
|
||||
ok = _uninstall_macos(cert_name)
|
||||
elif system == "Linux":
|
||||
|
||||
@@ -65,7 +65,8 @@ if not exist "config.json" (
|
||||
)
|
||||
|
||||
REM -------- Check for uninstall flag --------
|
||||
if "%~1"=="--uninstall-cert" (
|
||||
echo %* | findstr /C:"--uninstall-cert" >nul
|
||||
if not errorlevel 1 (
|
||||
echo [*] Uninstalling CA certificate ...
|
||||
"%VPY%" main.py --uninstall-cert
|
||||
exit /b %errorlevel%
|
||||
|
||||
Reference in New Issue
Block a user