mirror of
https://github.com/bjc/prosody.git
synced 2025-04-01 20:27:39 +03:00
conn:ssl_peerverification() can now return a single error in case the connection has been closed for whatever reason
59 lines
2 KiB
Lua
59 lines
2 KiB
Lua
module:set_global();
|
|
|
|
local cert_verify_identity = require "prosody.util.x509".verify_identity;
|
|
local log = module._log;
|
|
|
|
local measure_cert_statuses = module:metric("counter", "checked", "", "Certificate validation results",
|
|
{ "chain"; "identity" })
|
|
|
|
module:hook("s2s-check-certificate", function(event)
|
|
local session, host, cert = event.session, event.host, event.cert;
|
|
local conn = session.conn;
|
|
local log = session.log or log;
|
|
|
|
local secure_hostname = conn.extra and conn.extra.secure_hostname;
|
|
|
|
if not cert then
|
|
log("warn", "No certificate provided by %s", host or "unknown host");
|
|
return;
|
|
end
|
|
|
|
local chain_valid, errors = conn:ssl_peerverification();
|
|
-- Is there any interest in printing out all/the number of errors here?
|
|
if not chain_valid then
|
|
log("debug", "certificate chain validation result: invalid");
|
|
if type(errors) == "table" then
|
|
for depth, t in pairs(errors) do
|
|
log("debug", "certificate error(s) at depth %d: %s", depth-1, table.concat(t, ", "));
|
|
end
|
|
else
|
|
log("debug", "certificate error: %s", errors);
|
|
end
|
|
session.cert_chain_status = "invalid";
|
|
session.cert_chain_errors = errors;
|
|
else
|
|
log("debug", "certificate chain validation result: valid");
|
|
session.cert_chain_status = "valid";
|
|
|
|
-- We'll go ahead and verify the asserted identity if the
|
|
-- connecting server specified one.
|
|
if host then
|
|
if cert_verify_identity(host, "xmpp-server", cert) then
|
|
session.cert_identity_status = "valid"
|
|
else
|
|
session.cert_identity_status = "invalid"
|
|
end
|
|
log("debug", "certificate identity validation result: %s", session.cert_identity_status);
|
|
end
|
|
|
|
-- Check for DNSSEC-signed SRV hostname
|
|
if secure_hostname and session.cert_identity_status ~= "valid" then
|
|
if cert_verify_identity(secure_hostname, "xmpp-server", cert) then
|
|
module:log("info", "Secure SRV name delegation %q -> %q", secure_hostname, host);
|
|
session.cert_identity_status = "valid"
|
|
end
|
|
end
|
|
end
|
|
measure_cert_statuses:with_labels(session.cert_chain_status or "unknown", session.cert_identity_status or "unknown"):add(1);
|
|
end, 509);
|
|
|