2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
10 local hosts = _G.hosts;
11 local send_s2s = require "core.s2smanager".send_to_host;
12 local s2s_make_authenticated = require "core.s2smanager".make_authenticated;
13 local s2s_initiate_dialback = require "core.s2smanager".initiate_dialback;
14 local s2s_verify_dialback = require "core.s2smanager".verify_dialback;
15 local s2s_destroy_session = require "core.s2smanager".destroy_session;
17 local log = module._log;
19 local st = require "util.stanza";
21 local xmlns_stream = "http://etherx.jabber.org/streams";
22 local xmlns_dialback = "jabber:server:dialback";
24 local dialback_requests = setmetatable({}, { __mode = 'v' });
26 module:add_handler({"s2sin_unauthed", "s2sin"}, "verify", xmlns_dialback,
27 function (origin, stanza)
28 -- We are being asked to verify the key, to ensure it was generated by us
29 origin.log("debug", "verifying that dialback key is ours...");
30 local attr = stanza.attr;
31 -- COMPAT: Grr, ejabberd breaks this one too?? it is black and white in XEP-220 example 34
32 --if attr.from ~= origin.to_host then error("invalid-from"); end
34 if s2s_verify_dialback(attr.id, attr.from, attr.to, stanza[1]) then
38 origin.log("warn", "Asked to verify a dialback key that was incorrect. An imposter is claiming to be %s?", attr.to);
40 origin.log("debug", "verified dialback key... it is %s", type);
41 origin.sends2s(st.stanza("db:verify", { from = attr.to, to = attr.from, id = attr.id, type = type }):text(stanza[1]));
44 module:add_handler({ "s2sin_unauthed", "s2sin" }, "result", xmlns_dialback,
45 function (origin, stanza)
46 -- he wants to be identified through dialback
47 -- We need to check the key with the Authoritative server
48 local attr = stanza.attr;
49 origin.hosts[attr.from] = { dialback_key = stanza[1] };
51 if not hosts[attr.to] then
52 -- Not a host that we serve
53 origin.log("info", "%s tried to connect to %s, which we don't serve", attr.from, attr.to);
54 origin:close("host-unknown");
58 dialback_requests[attr.from] = origin;
60 if not origin.from_host then
61 -- Just used for friendlier logging
62 origin.from_host = attr.from;
64 if not origin.to_host then
65 -- Just used for friendlier logging
66 origin.to_host = attr.to;
69 origin.log("debug", "asking %s if key %s belongs to them", attr.from, stanza[1]);
70 send_s2s(attr.to, attr.from,
71 st.stanza("db:verify", { from = attr.to, to = attr.from, id = origin.streamid }):text(stanza[1]));
74 module:add_handler({ "s2sout_unauthed", "s2sout" }, "verify", xmlns_dialback,
75 function (origin, stanza)
76 local attr = stanza.attr;
77 local dialback_verifying = dialback_requests[attr.from];
78 if dialback_verifying then
80 if attr.type == "valid" then
81 s2s_make_authenticated(dialback_verifying, attr.from);
84 -- Warn the original connection that is was not verified successfully
85 log("warn", "authoritative server for "..(attr.from or "(unknown)").." denied the key");
88 if not dialback_verifying.sends2s then
89 log("warn", "Incoming s2s session %s was closed in the meantime, so we can't notify it of the db result", tostring(dialback_verifying):match("%w+$"));
91 dialback_verifying.sends2s(
92 st.stanza("db:result", { from = attr.to, to = attr.from, id = attr.id, type = valid })
93 :text(dialback_verifying.hosts[attr.from].dialback_key));
95 dialback_requests[attr.from] = nil;
99 module:add_handler({ "s2sout_unauthed", "s2sout" }, "result", xmlns_dialback,
100 function (origin, stanza)
101 -- Remote server is telling us whether we passed dialback
103 local attr = stanza.attr;
104 if not hosts[attr.to] then
105 origin:close("host-unknown");
107 elseif hosts[attr.to].s2sout[attr.from] ~= origin then
109 origin:close("invalid-id");
112 if stanza.attr.type == "valid" then
113 s2s_make_authenticated(origin, attr.from);
115 s2s_destroy_session(origin)
119 module:hook_stanza(xmlns_stream, "features", function (origin, stanza)
120 s2s_initiate_dialback(origin);
124 -- Offer dialback to incoming hosts
125 module:hook("s2s-stream-features", function (data)
126 data.features:tag("dialback", { xmlns='urn:xmpp:features:dialback' }):tag("optional"):up():up();