aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/s2smanager.lua40
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;