17 -- |
17 -- |
18 -- luacheck: ignore module |
18 -- luacheck: ignore module |
19 |
19 |
20 module:set_global(); |
20 module:set_global(); |
21 |
21 |
|
22 local have_async, async = pcall(require, "util.async"); |
22 local noop = function () end |
23 local noop = function () end |
23 local type = type; |
24 local type = type; |
24 local t_insert = table.insert; |
25 local t_insert = table.insert; |
25 local set = require"util.set"; |
26 local set = require"util.set"; |
26 local dns_lookup = require"net.adns".lookup; |
27 local dns_lookup = require"net.adns".lookup; |
206 local function resume(host_session) |
207 local function resume(host_session) |
207 host_session.log("debug", "DANE lookup completed, resuming connection"); |
208 host_session.log("debug", "DANE lookup completed, resuming connection"); |
208 host_session.conn:resume() |
209 host_session.conn:resume() |
209 end |
210 end |
210 |
211 |
|
212 if have_async then |
|
213 function pause(host_session) |
|
214 host_session.log("debug", "Pausing connection until DANE lookup is completed"); |
|
215 local wait, done = async.waiter(); |
|
216 host_session._done_waiting_for_dane = done; |
|
217 wait(); |
|
218 end |
|
219 local function _resume(_, host_session) |
|
220 if host_session._done_waiting_for_dane then |
|
221 host_session.log("debug", "DANE lookup completed, resuming connection"); |
|
222 host_session._done_waiting_for_dane(); |
|
223 host_session._done_waiting_for_dane = nil; |
|
224 end |
|
225 end |
|
226 function resume(host_session) |
|
227 -- Something about the way luaunbound calls callbacks is messed up |
|
228 if host_session._done_waiting_for_dane then |
|
229 module:add_timer(0, _resume, host_session); |
|
230 end |
|
231 end |
|
232 end |
|
233 |
211 function module.add_host(module) |
234 function module.add_host(module) |
212 local function on_new_s2s(event) |
235 local function on_new_s2s(event) |
213 local host_session = event.origin; |
236 local host_session = event.origin; |
214 if host_session.type == "s2sout" or host_session.type == "s2sin" then |
237 if host_session.type == "s2sout" or host_session.type == "s2sin" then |
215 return; -- Already authenticated |
238 return; -- Already authenticated |
216 end |
239 end |
217 if host_session.dane ~= nil then |
240 if host_session.dane ~= nil then |
218 return; -- Already done DANE lookup |
241 return; -- Already done DANE lookup |
219 end |
242 end |
220 if dane_lookup(host_session, resume) then |
243 dane_lookup(host_session, resume); |
221 pause(host_session); |
244 -- Let it run in parallell until we need to check the cert |
222 end |
|
223 end |
245 end |
224 |
246 |
225 -- New outgoing connections |
247 -- New outgoing connections |
226 module:hook("stanza/http://etherx.jabber.org/streams:features", on_new_s2s, 501); |
248 module:hook("stanza/http://etherx.jabber.org/streams:features", on_new_s2s, 501); |
227 module:hook("s2sout-authenticate-legacy", on_new_s2s, 200); |
249 module:hook("s2sout-authenticate-legacy", on_new_s2s, 200); |
279 module:hook("s2s-check-certificate", function(event) |
301 module:hook("s2s-check-certificate", function(event) |
280 local session, cert, host = event.session, event.cert, event.host; |
302 local session, cert, host = event.session, event.cert, event.host; |
281 if not cert then return end |
303 if not cert then return end |
282 local log = session.log or module._log; |
304 local log = session.log or module._log; |
283 local dane = session.dane; |
305 local dane = session.dane; |
|
306 if type(dane) ~= "table" then |
|
307 if dane == nil and dane_lookup(session, resume) then |
|
308 pause(session); |
|
309 dane = session.dane; |
|
310 end |
|
311 end |
284 if type(dane) == "table" then |
312 if type(dane) == "table" then |
285 local match_found, supported_found; |
313 local match_found, supported_found; |
286 for i = 1, #dane do |
314 for i = 1, #dane do |
287 local tlsa = dane[i].tlsa; |
315 local tlsa = dane[i].tlsa; |
288 log("debug", "TLSA #%d: %s", i, tostring(tlsa)) |
316 log("debug", "TLSA #%d: %s", i, tostring(tlsa)) |