diff options
Diffstat (limited to 'core/s2smanager.lua')
-rw-r--r-- | core/s2smanager.lua | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/core/s2smanager.lua b/core/s2smanager.lua index c4a94682..be5c04fc 100644 --- a/core/s2smanager.lua +++ b/core/s2smanager.lua @@ -27,6 +27,7 @@ local modulemanager = require "core.modulemanager"; local st = require "stanza"; local stanza = st.stanza; local nameprep = require "util.encodings".stringprep.nameprep; +local cert_verify_identity = require "util.certverification".verify_identity; local fire_event = prosody.events.fire_event; local uuid_gen = require "util.uuid".generate; @@ -373,16 +374,44 @@ function session_open_stream(session, from, to) from=from, to=to, version='1.0', ["xml:lang"]='en'}):top_tag()); end +local function check_cert_status(session) + local conn = session.conn:socket() + local cert = conn:getpeercertificate() + + if cert then + local chain_valid, err = conn:getpeerchainvalid() + if not chain_valid then + session.cert_chain_status = "invalid"; + (session.log or log)("debug", "certificate chain validation result: %s", err); + else + session.cert_chain_status = "valid"; + + local host = session.direction == "incoming" and session.from_host or session.to_host + + -- 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 + end + end + end +end + function streamopened(session, attr) local send = session.sends2s; -- TODO: #29: SASL/TLS on s2s streams session.version = tonumber(attr.version) or 0; + -- TODO: Rename session.secure to session.encrypted if session.secure == false then session.secure = true; end - + if session.direction == "incoming" then -- Send a reply stream header session.to_host = attr.to and nameprep(attr.to); @@ -407,6 +436,9 @@ function streamopened(session, attr) return; end end + + if session.secure and not session.cert_chain_status then check_cert_status(session); end + send("<?xml version='1.0'?>"); send(stanza("stream:stream", { xmlns='jabber:server', ["xmlns:db"]='jabber:server:dialback', ["xmlns:stream"]='http://etherx.jabber.org/streams', id=session.streamid, from=session.to_host, to=session.from_host, version=(session.version > 0 and "1.0" or nil) }):top_tag()); @@ -426,7 +458,9 @@ function streamopened(session, attr) -- If we are just using the connection for verifying dialback keys, we won't try and auth it if not attr.id then error("stream response did not give us a streamid!!!"); end session.streamid = attr.id; - + + if session.secure and not session.cert_chain_status then check_cert_status(session); end + -- Send unauthed buffer -- (stanzas which are fine to send before dialback) -- Note that this is *not* the stanza queue (which @@ -490,9 +524,11 @@ function make_authenticated(session, host) elseif session.type == "s2sin_unauthed" then session.type = "s2sin"; if host then + if not session.hosts[host] then session.hosts[host] = {}; end session.hosts[host].authed = true; end elseif session.type == "s2sin" and host then + if not session.hosts[host] then session.hosts[host] = {}; end session.hosts[host].authed = true; else return false; |