2 -- Copyright (C) 2008-2009 Matthew Wild
3 -- Copyright (C) 2008-2009 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_verify_dialback = require "core.s2smanager".verify_dialback;
14 local s2s_destroy_session = require "core.s2smanager".destroy_session;
16 local log = module._log;
18 local st = require "util.stanza";
20 local xmlns_dialback = "jabber:server:dialback";
22 local dialback_requests = setmetatable({}, { __mode = 'v' });
24 module:add_handler({"s2sin_unauthed", "s2sin"}, "verify", xmlns_dialback,
25 function (origin, stanza)
26 -- We are being asked to verify the key, to ensure it was generated by us
27 origin.log("debug", "verifying that dialback key is ours...");
28 local attr = stanza.attr;
29 -- COMPAT: Grr, ejabberd breaks this one too?? it is black and white in XEP-220 example 34
30 --if attr.from ~= origin.to_host then error("invalid-from"); end
32 if s2s_verify_dialback(attr.id, attr.from, attr.to, stanza[1]) then
36 origin.log("warn", "Asked to verify a dialback key that was incorrect. An imposter is claiming to be %s?", attr.to);
38 origin.log("debug", "verified dialback key... it is %s", type);
39 origin.sends2s(st.stanza("db:verify", { from = attr.to, to = attr.from, id = attr.id, type = type }):text(stanza[1]));
42 module:add_handler({ "s2sin_unauthed", "s2sin" }, "result", xmlns_dialback,
43 function (origin, stanza)
44 -- he wants to be identified through dialback
45 -- We need to check the key with the Authoritative server
46 local attr = stanza.attr;
47 origin.hosts[attr.from] = { dialback_key = stanza[1] };
49 if not hosts[attr.to] then
50 -- Not a host that we serve
51 origin.log("info", "%s tried to connect to %s, which we don't serve", attr.from, attr.to);
52 origin:close("host-unknown");
56 dialback_requests[attr.from] = origin;
58 if not origin.from_host then
59 -- Just used for friendlier logging
60 origin.from_host = attr.from;
62 if not origin.to_host then
63 -- Just used for friendlier logging
64 origin.to_host = attr.to;
67 origin.log("debug", "asking %s if key %s belongs to them", attr.from, stanza[1]);
68 send_s2s(attr.to, attr.from,
69 st.stanza("db:verify", { from = attr.to, to = attr.from, id = origin.streamid }):text(stanza[1]));
72 module:add_handler({ "s2sout_unauthed", "s2sout" }, "verify", xmlns_dialback,
73 function (origin, stanza)
74 local attr = stanza.attr;
75 local dialback_verifying = dialback_requests[attr.from];
76 if dialback_verifying then
78 if attr.type == "valid" then
79 s2s_make_authenticated(dialback_verifying, attr.from);
82 -- Warn the original connection that is was not verified successfully
83 log("warn", "authoritative server for "..(attr.from or "(unknown)").." denied the key");
86 if not dialback_verifying.sends2s then
87 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+$"));
89 dialback_verifying.sends2s(
90 st.stanza("db:result", { from = attr.to, to = attr.from, id = attr.id, type = valid })
91 :text(dialback_verifying.hosts[attr.from].dialback_key));
93 dialback_requests[attr.from] = nil;
97 module:add_handler({ "s2sout_unauthed", "s2sout" }, "result", xmlns_dialback,
98 function (origin, stanza)
99 -- Remote server is telling us whether we passed dialback
101 local attr = stanza.attr;
102 if not hosts[attr.to] then
103 origin:close("host-unknown");
105 elseif hosts[attr.to].s2sout[attr.from] ~= origin then
107 origin:close("invalid-id");
110 if stanza.attr.type == "valid" then
111 s2s_make_authenticated(origin, attr.from);
113 s2s_destroy_session(origin)