mirror of
https://gitverse.ru/kpa39l/xmpp-server-prosody.git
synced 2026-09-29 09:45:02 +00:00
48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
#!/usr/bin/env python3
|
|
"""STARTTLS probe for Prosody/XMPP servers (c2s 5222 default, --s2s uses jabber:server for 5269).
|
|
|
|
Usage: starttls_probe.py <host> <port> <domain> [--s2s]
|
|
|
|
Verifies: stream features -> starttls -> <proceed/> -> TLS handshake -> cert subject/issuer/SAN.
|
|
Reason to exist: `openssl s_client -starttls xmpp` reports "no peer certificate"/Cipher NONE
|
|
on Prosody 0.11 even when TLS works fine (false negative).
|
|
|
|
Exit 0 with "TLS OK" = c2s/s2s STARTTLS fully working with a trusted cert.
|
|
"""
|
|
import socket, ssl, sys, time
|
|
|
|
HOST = sys.argv[1] if len(sys.argv) > 1 else "127.0.0.1"
|
|
PORT = int(sys.argv[2]) if len(sys.argv) > 2 else 5222
|
|
DOMAIN = sys.argv[3] if len(sys.argv) > 3 else "nixg.ru"
|
|
S2S = "--s2s" in sys.argv
|
|
|
|
NS = "jabber:server" if S2S else "jabber:client"
|
|
s = socket.create_connection((HOST, PORT), timeout=10)
|
|
s.settimeout(8)
|
|
|
|
|
|
def recv():
|
|
data = s.recv(8192)
|
|
print(" <<", data.decode(errors="replace")[:300].replace("\n", " "))
|
|
return data
|
|
|
|
|
|
s.sendall(
|
|
("<stream:stream to='%s' xmlns='%s' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>" % (DOMAIN, NS)).encode()
|
|
)
|
|
time.sleep(1)
|
|
recv()
|
|
s.sendall(b"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>")
|
|
time.sleep(1)
|
|
recv()
|
|
ctx = ssl.create_default_context()
|
|
tls = ctx.wrap_socket(s, server_hostname=DOMAIN)
|
|
print("TLS OK:", tls.cipher()[0], tls.version())
|
|
try:
|
|
cert = tls.getpeercert()
|
|
print("SUBJECT:", cert["subject"])
|
|
print("ISSUER:", cert["issuer"])
|
|
print("SAN:", cert.get("subjectAltName"))
|
|
except Exception as e:
|
|
print("cert verification issue:", e)
|
|
tls.close() |