Annotate

plugins/mod_s2s_auth_dane_in.lua @ 13357:f424c9f1460b

mod_mam: Use for loop in metadata query Some storage drivers will perform cleanup after the last iteration, but if only one step is taken this might be delayed until the garbage collector gets to it.
author Kim Alvefur <zash@zash.se>
date Sun, 26 Nov 2023 22:58:11 +0100
parent 13322:28211ed70b4c
child 13416:d8e885db9851
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13297
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 module:set_global();
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 local dns = require "prosody.net.adns";
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4 local async = require "prosody.util.async";
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
5 local encodings = require "prosody.util.encodings";
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
6 local hashes = require "prosody.util.hashes";
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
7 local promise = require "prosody.util.promise";
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
8 local x509 = require "prosody.util.x509";
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
10 local idna_to_ascii = encodings.idna.to_ascii;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11 local sha256 = hashes.sha256;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 local sha512 = hashes.sha512;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
14 local use_dane = module:get_option_boolean("use_dane", nil);
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
15 if use_dane == nil then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
16 module:log("warn", "DANE support incomplete, add use_dane = true in the global section to support outgoing s2s connections");
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 elseif use_dane == false then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18 module:log("debug", "DANE support disabled with use_dane = false, disabling.")
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
19 return
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 local function ensure_secure(r)
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 assert(r.secure, "insecure");
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24 return r;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 local lazy_tlsa_mt = {
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 __index = function(t, i)
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 if i == 1 then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 local h = sha256(t[0]);
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 t[1] = h;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32 return h;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33 elseif i == 2 then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34 local h = sha512(t[0]);
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
35 t[1] = h;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36 return h;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
37 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
38 end;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
39 }
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
40 local function lazy_hash(t)
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
41 return setmetatable(t, lazy_tlsa_mt);
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
42 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
43
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44 module:hook("s2s-check-certificate", function(event)
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
45 local session, host, cert = event.session, event.host, event.cert;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
46 local log = session.log or module._log;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
47
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
48 if not host or not cert or session.direction ~= "incoming" then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 return
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
51
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
52 local by_select_match = {
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
53 [0] = lazy_hash {
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
54 -- cert
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
55 [0] = x509.pem2der(cert:pem());
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
57 };
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58 }
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
59 if cert.pubkey then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60 by_select_match[1] = lazy_hash {
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 -- spki
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
62 [0] = x509.pem2der(cert:pubkey());
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
63 };
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
64 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
66 local resolver = dns.resolver();
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
67
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
68 local dns_domain = idna_to_ascii(host);
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
70 local function fetch_tlsa(res)
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
71 local tlsas = {};
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
72 for _, rr in ipairs(res) do
13322
28211ed70b4c mod_s2s_auth_dane_in: Bail out on explicit service denial
Kim Alvefur <zash@zash.se>
parents: 13297
diff changeset
73 if rr.srv.target == "." then return {}; end
13297
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74 table.insert(tlsas, resolver:lookup_promise(("_%d._tcp.%s"):format(rr.srv.port, rr.srv.target), "TLSA"):next(ensure_secure));
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
76 return promise.all(tlsas);
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
77 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
78
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79 local ret = async.wait_for(promise.all({
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80 resolver:lookup_promise("_xmpps-server._tcp." .. dns_domain, "SRV"):next(ensure_secure):next(fetch_tlsa);
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 resolver:lookup_promise("_xmpp-server._tcp." .. dns_domain, "SRV"):next(ensure_secure):next(fetch_tlsa);
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82 }));
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 if not ret then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85 return
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
87
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
88 local found_supported = false;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
89 for _, by_proto in ipairs(ret) do
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
90 for _, by_srv in ipairs(by_proto) do
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
91 for _, by_target in ipairs(by_srv) do
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
92 for _, rr in ipairs(by_target) do
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
93 if rr.tlsa.use == 3 and by_select_match[rr.tlsa.select] and rr.tlsa.match <= 2 then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
94 found_supported = true;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
95 if rr.tlsa.data == by_select_match[rr.tlsa.select][rr.tlsa.match] then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
96 module:log("debug", "%s matches", rr)
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
97 session.cert_chain_status = "valid";
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
98 session.cert_identity_status = "valid";
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
99 return true;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
100 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
101 else
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
102 log("debug", "Unsupported DANE TLSA record: %s", rr);
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
103 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
104 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
105 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
106 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
107 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
108
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
109 if found_supported then
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
110 session.cert_chain_status = "invalid";
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
111 session.cert_identity_status = nil;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
112 return true;
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
113 end
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
114
7264c4d16072 mod_s2s_auth_dane_in: DANE support for s2sin
Kim Alvefur <zash@zash.se>
parents:
diff changeset
115 end, 800);