Enhance SSL check functionality with improved logging and UI feedback
This commit is contained in:
@@ -409,30 +409,45 @@ def ssl_check_cmd(url: str) -> str:
|
|||||||
host = url
|
host = url
|
||||||
port = 443
|
port = 443
|
||||||
|
|
||||||
|
logger.debug(f"ssl_check_cmd: host={host} port={port}")
|
||||||
openssl_path = shutil.which("openssl")
|
openssl_path = shutil.which("openssl")
|
||||||
if openssl_path:
|
if openssl_path:
|
||||||
cmd = [openssl_path, "s_client", "-showcerts", "-connect", f"{host}:{port}", "-servername", host]
|
cmd = [openssl_path, "s_client", "-showcerts", "-connect", f"{host}:{port}", "-servername", host]
|
||||||
|
logger.debug(f"Running openssl: {' '.join(cmd)}")
|
||||||
try:
|
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
|
out = proc.stdout + "\n" + proc.stderr
|
||||||
|
logger.debug(f"OpenSSL finished, {len(out)} bytes returned, rc={proc.returncode}")
|
||||||
return out
|
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:
|
except Exception as e:
|
||||||
|
logger.exception("OpenSSL check failed")
|
||||||
return f"OpenSSL check failed: {e}\n"
|
return f"OpenSSL check failed: {e}\n"
|
||||||
else:
|
else:
|
||||||
# Fallback: use Python ssl to fetch the peer certificate (leaf only)
|
# Fallback: use Python ssl to fetch the peer certificate (leaf only)
|
||||||
import ssl
|
import ssl
|
||||||
|
|
||||||
|
logger.debug("OpenSSL not found; using Python ssl fallback")
|
||||||
try:
|
try:
|
||||||
ctx = ssl.create_default_context()
|
ctx = ssl.create_default_context()
|
||||||
with ctx.wrap_socket(
|
s = socket.socket(socket.AF_INET)
|
||||||
socket.socket(socket.AF_INET), server_hostname=host
|
with ctx.wrap_socket(s, server_hostname=host) as ss:
|
||||||
) as s:
|
ss.settimeout(15)
|
||||||
s.settimeout(10)
|
ss.connect((host, port))
|
||||||
s.connect((host, port))
|
der = ss.getpeercert(True)
|
||||||
der = s.getpeercert(True)
|
|
||||||
pem = ssl.DER_cert_to_PEM_cert(der)
|
pem = ssl.DER_cert_to_PEM_cert(der)
|
||||||
|
logger.debug("Python ssl fallback succeeded")
|
||||||
return pem
|
return pem
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logger.exception("Python SSL fallback failed")
|
||||||
return f"Python SSL fallback failed: {e}\n"
|
return f"Python SSL fallback failed: {e}\n"
|
||||||
|
|
||||||
|
|
||||||
@@ -725,13 +740,29 @@ def main_page():
|
|||||||
"Delete all files in ANON_PATH"
|
"Delete all files in ANON_PATH"
|
||||||
)
|
)
|
||||||
async def ssl_check_ui() -> None:
|
async def ssl_check_ui() -> None:
|
||||||
# Run the openssl/Python SSL check in a thread and show output in a dialog
|
# Show a running dialog immediately so user sees progress
|
||||||
output = await run.cpu_bound(ssl_check_cmd, BASE_SITE_URL)
|
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.dialog() as d:
|
||||||
with ui.card().classes("p-4"):
|
with ui.card().classes("p-4"):
|
||||||
ui.label("SSL Check output").classes("text-h6")
|
ui.label("SSL Check output").classes("text-h6")
|
||||||
ui.code(output).props("white-space: pre-wrap")
|
ui.code(output).props("white-space: pre-wrap")
|
||||||
ui.button("Close", on_click=d.close)
|
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")
|
ui.button("SSL check", on_click=ssl_check_ui).tooltip("Run openssl s_client -showcerts against the configured site and show output")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user