Merge 0.9->0.10
[prosody.git] / plugins / mod_s2s / mod_s2s.lua
index 5afb958c4462e0270c73041bbdafe5f794f75011..263f24c0b55c2b633810521f89abdcb1cc159507 100644 (file)
@@ -150,6 +150,13 @@ function module.add_host(module)
        module:hook("route/remote", route_to_new_session, -10);
        module:hook("s2s-authenticated", make_authenticated, -1);
        module:hook("s2s-read-timeout", keepalive, -1);
+       module:hook_stanza("http://etherx.jabber.org/streams", "features", function (session, stanza)
+               if session.type == "s2sout" then
+                       -- Stream is authenticated and we are seem to be done with feature negotiation,
+                       -- so the stream is ready for stanzas.  RFC 6120 Section 4.3
+                       mark_connected(session);
+               end
+       end, -1);
 end
 
 -- Stream is authorised, and ready for normal stanzas
@@ -219,7 +226,10 @@ function make_authenticated(event)
        end
        session.log("debug", "connection %s->%s is now authenticated for %s", session.from_host, session.to_host, host);
 
-       mark_connected(session);
+       if (session.type == "s2sout" and session.external_auth ~= "succeeded") or session.type == "s2sin" then
+               -- Stream either used dialback for authentication or is an incoming stream.
+               mark_connected(session);
+       end
 
        return true;
 end
@@ -366,7 +376,7 @@ function stream_callbacks.streamopened(session, attr)
                        if to then
                                hosts[to].events.fire_event("s2s-stream-features", { origin = session, features = features });
                        else
-                               (session.log or log)("warn", "No 'to' on stream header from %s means we can't offer any features", from or "unknown host");
+                               (session.log or log)("warn", "No 'to' on stream header from %s means we can't offer any features", from or session.ip or "unknown host");
                        end
 
                        log("debug", "Sending stream features: %s", tostring(features));
@@ -467,7 +477,7 @@ local function session_close(session, reason, remote_reason)
                end
                if reason then -- nil == no err, initiated by us, false == initiated by remote
                        if type(reason) == "string" then -- assume stream error
-                               log("debug", "Disconnecting %s[%s], <stream:error> is: %s", session.host or "(unknown host)", session.type, reason);
+                               log("debug", "Disconnecting %s[%s], <stream:error> is: %s", session.host or session.ip or "(unknown host)", session.type, reason);
                                session.sends2s(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' }));
                        elseif type(reason) == "table" then
                                if reason.condition then
@@ -478,7 +488,7 @@ local function session_close(session, reason, remote_reason)
                                        if reason.extra then
                                                stanza:add_child(reason.extra);
                                        end
-                                       log("debug", "Disconnecting %s[%s], <stream:error> is: %s", session.host or "(unknown host)", session.type, tostring(stanza));
+                                       log("debug", "Disconnecting %s[%s], <stream:error> is: %s", session.host or session.ip or "(unknown host)", session.type, tostring(stanza));
                                        session.sends2s(stanza);
                                elseif reason.name then -- a stanza
                                        log("debug", "Disconnecting %s->%s[%s], <stream:error> is: %s", session.from_host or "(unknown host)", session.to_host or "(unknown host)", session.type, tostring(reason));
@@ -510,22 +520,10 @@ local function session_close(session, reason, remote_reason)
        end
 end
 
-function session_open_stream(session, from, to)
-       local attr = {
-               ["xmlns:stream"] = 'http://etherx.jabber.org/streams',
-               xmlns = 'jabber:server',
-               version = session.version and (session.version > 0 and "1.0" or nil),
-               ["xml:lang"] = 'en',
-               id = session.streamid,
-               from = from, to = to,
-       }
+function session_stream_attrs(session, from, to, attr)
        if not from or (hosts[from] and hosts[from].modules.dialback) then
                attr["xmlns:db"] = 'jabber:server:dialback';
        end
-
-       session.sends2s("<?xml version='1.0'?>");
-       session.sends2s(st.stanza("stream:stream", attr):top_tag());
-       return true;
 end
 
 -- Session initialization logic shared by incoming and outgoing
@@ -540,7 +538,7 @@ local function initialize_session(session)
                session.stream:reset();
        end
 
-       session.open_stream = session_open_stream;
+       session.stream_attrs = session_stream_attrs;
 
        local filter = session.filter;
        function session.data(data)
@@ -660,7 +658,7 @@ function check_auth_policy(event)
        end
 
        if must_secure and (session.cert_chain_status ~= "valid" or session.cert_identity_status ~= "valid") then
-               module:log("warn", "Forbidding insecure connection to/from %s", host);
+               module:log("warn", "Forbidding insecure connection to/from %s", host or session.ip or "(unknown host)");
                if session.direction == "incoming" then
                        session:close({ condition = "not-authorized", text = "Your server's certificate is invalid, expired, or not trusted by "..session.to_host });
                else -- Close outgoing connections without warning