From bb0d3d8af1526e82ce87363b71cbb7e08ea841e9 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 24 Nov 2025 16:10:04 +0000 Subject: [PATCH] Enhance SSL check functionality with improved logging and UI feedback --- nice.py | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/nice.py b/nice.py index 382ec8c..4a1fd4e 100644 --- a/nice.py +++ b/nice.py @@ -409,30 +409,45 @@ def ssl_check_cmd(url: str) -> str: host = url port = 443 + logger.debug(f"ssl_check_cmd: host={host} port={port}") openssl_path = shutil.which("openssl") if openssl_path: cmd = [openssl_path, "s_client", "-showcerts", "-connect", f"{host}:{port}", "-servername", host] + logger.debug(f"Running openssl: {' '.join(cmd)}") try: - proc = subprocess.run(cmd, capture_output=True, text=True, timeout=30) + # Provide a small stdin so s_client can complete instead of + # waiting for interactive input. Capture both stdout and stderr. + proc = subprocess.run(cmd, input='\n', capture_output=True, text=True, timeout=60) out = proc.stdout + "\n" + proc.stderr + logger.debug(f"OpenSSL finished, {len(out)} bytes returned, rc={proc.returncode}") return out + except subprocess.TimeoutExpired: + logger.debug("OpenSSL timed out") + return ( + "OpenSSL check timed out after 60s\n" + "This can happen if the connection is blocked by a proxy or firewall. " + "Try running the openssl command manually or check your network/proxy settings.\n" + ) except Exception as e: + logger.exception("OpenSSL check failed") return f"OpenSSL check failed: {e}\n" else: # Fallback: use Python ssl to fetch the peer certificate (leaf only) import ssl + logger.debug("OpenSSL not found; using Python ssl fallback") try: ctx = ssl.create_default_context() - with ctx.wrap_socket( - socket.socket(socket.AF_INET), server_hostname=host - ) as s: - s.settimeout(10) - s.connect((host, port)) - der = s.getpeercert(True) + s = socket.socket(socket.AF_INET) + with ctx.wrap_socket(s, server_hostname=host) as ss: + ss.settimeout(15) + ss.connect((host, port)) + der = ss.getpeercert(True) pem = ssl.DER_cert_to_PEM_cert(der) + logger.debug("Python ssl fallback succeeded") return pem except Exception as e: + logger.exception("Python SSL fallback failed") return f"Python SSL fallback failed: {e}\n" @@ -725,13 +740,29 @@ def main_page(): "Delete all files in ANON_PATH" ) async def ssl_check_ui() -> None: - # Run the openssl/Python SSL check in a thread and show output in a dialog - output = await run.cpu_bound(ssl_check_cmd, BASE_SITE_URL) + # Show a running dialog immediately so user sees progress + with ui.dialog() as running_dlg: + with ui.card().classes("p-4"): + ui.label("SSL check running...").classes("text-h6") + running_dlg.open() + + try: + logger.debug("Starting SSL check via UI") + output = await run.cpu_bound(ssl_check_cmd, BASE_SITE_URL) + except Exception as e: + logger.exception("SSL check failed") + running_dlg.close() + ui.notify(f"SSL check failed: {e}", color="negative") + return + + # close the running dialog and show the results in a new dialog + running_dlg.close() with ui.dialog() as d: with ui.card().classes("p-4"): ui.label("SSL Check output").classes("text-h6") ui.code(output).props("white-space: pre-wrap") ui.button("Close", on_click=d.close) + d.open() ui.button("SSL check", on_click=ssl_check_ui).tooltip("Run openssl s_client -showcerts against the configured site and show output")