annotate mod_s2s_auth_dane/mod_s2s_auth_dane.lua @ 1268:854a3933cfcd

mod_muc_log_http: URL-encode room names. This allows special characters in room names to work. Ideally this escaping shouldn’t be done in the user visible content, but the module’s template system doesn’t currently allow that.
author Waqas Hussain <waqas20@gmail.com>
date Sat, 04 Jan 2014 16:50:57 -0500
parents 51e7a4bbd70b
children 69d42d2427f7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 -- mod_s2s_auth_dane
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2 --
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 -- Between the DNS lookup and the chertificate validation, there is a race condition.
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4 -- Solving that probably requires changes to mod_s2s, like using util.async
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
5
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
6
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
7 module:set_global();
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
8
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9 local dns_lookup = require"net.adns".lookup;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
10 local hashes = require"util.hashes";
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11 local base64 = require"util.encodings".base64;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13 local s2sout = module:depends"s2s".route_to_new_session.s2sout;
1266
51e7a4bbd70b mod_s2s_auth_dane: Style fixes
Kim Alvefur <zash@zash.se>
parents: 1265
diff changeset
14 local _try_connect = s2sout.try_connect;
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
15
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
16 local pat = "%-%-%-%-%-BEGIN ([A-Z ]+)%-%-%-%-%-\r?\n"..
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 "([0-9A-Za-z=+/\r\n]*)\r?\n%-%-%-%-%-END %1%-%-%-%-%-";
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18 local function pem2der(pem)
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
19 local typ, data = pem:match(pat);
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 if typ and data then
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21 return base64.decode(data), typ;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 -- TODO Things to test/handle:
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26 -- Negative or bogus answers
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 -- No SRV records
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 function s2sout.try_connect(host_session, connect_host, connect_port, err)
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 local srv_hosts = host_session.srv_hosts;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 local srv_choice = host_session.srv_choice;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32 if srv_hosts and srv_hosts.answer.secure and not srv_hosts[srv_choice].dane then
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33 dns_lookup(function(answer)
1262
1e84eebf3f46 mod_s2s_auth_dane: Invalidate trust if there are TLSA records but no matches, or bogus results
Kim Alvefur <zash@zash.se>
parents: 1261
diff changeset
34 if answer and ( #answer > 0 or answer.bogus ) then
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
35 srv_hosts[srv_choice].dane = answer;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36 for i, tlsa in ipairs(answer) do
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
37 module:log("debug", "TLSA %s", tostring(tlsa));
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
38 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
39 end
1266
51e7a4bbd70b mod_s2s_auth_dane: Style fixes
Kim Alvefur <zash@zash.se>
parents: 1265
diff changeset
40 end, ("_%d._tcp.%s"):format(connect_port, connect_host), "TLSA");
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
41 end
1266
51e7a4bbd70b mod_s2s_auth_dane: Style fixes
Kim Alvefur <zash@zash.se>
parents: 1265
diff changeset
42 return _try_connect(host_session, connect_host, connect_port, err);
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
43 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
45 module:hook("s2s-check-certificate", function(event)
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
46 local session, cert = event.session, event.cert;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
47 local srv_hosts = session.srv_hosts;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
48 local srv_choice = session.srv_choice;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 local choosen = srv_hosts and srv_hosts[srv_choice];
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50 if choosen and choosen.dane then
1266
51e7a4bbd70b mod_s2s_auth_dane: Style fixes
Kim Alvefur <zash@zash.se>
parents: 1265
diff changeset
51 local use, select, match, tlsa, certdata, match_found;
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
52 for i, rr in ipairs(choosen.dane) do
1266
51e7a4bbd70b mod_s2s_auth_dane: Style fixes
Kim Alvefur <zash@zash.se>
parents: 1265
diff changeset
53 tlsa = rr.tlsa;
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
54 module:log("debug", "TLSA %s", tostring(tlsa));
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
55 use, select, match, certdata = tlsa.use, tlsa.select, tlsa.match;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
57 if use == 1 or use == 3 then
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
59 if select == 0 then
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60 certdata = pem2der(cert:pem());
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 elseif select == 1 then
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
62 certdata = pem2der(cert:pubkey());
1261
6a37bd22c8df mod_s2s_auth_dane: Warn about unsupported DANE params
Kim Alvefur <zash@zash.se>
parents: 1258
diff changeset
63 else
6a37bd22c8df mod_s2s_auth_dane: Warn about unsupported DANE params
Kim Alvefur <zash@zash.se>
parents: 1258
diff changeset
64 module:log("warn", "DANE selector %d is unsupported", select);
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
66 if match == 1 then
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
67 certdata = hashes.sha256(certdata);
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
68 elseif match == 2 then
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69 certdata = hashes.sha512(certdata);
1261
6a37bd22c8df mod_s2s_auth_dane: Warn about unsupported DANE params
Kim Alvefur <zash@zash.se>
parents: 1258
diff changeset
70 elseif match ~= 0 then
6a37bd22c8df mod_s2s_auth_dane: Warn about unsupported DANE params
Kim Alvefur <zash@zash.se>
parents: 1258
diff changeset
71 module:log("warn", "DANE match rule %d is unsupported", match);
1266
51e7a4bbd70b mod_s2s_auth_dane: Style fixes
Kim Alvefur <zash@zash.se>
parents: 1265
diff changeset
72 certdata = nil;
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
73 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75 -- Should we check if the cert subject matches?
1261
6a37bd22c8df mod_s2s_auth_dane: Warn about unsupported DANE params
Kim Alvefur <zash@zash.se>
parents: 1258
diff changeset
76 if certdata and certdata == tlsa.data then
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
77 (session.log or module._log)("info", "DANE validation successful");
1266
51e7a4bbd70b mod_s2s_auth_dane: Style fixes
Kim Alvefur <zash@zash.se>
parents: 1265
diff changeset
78 session.cert_identity_status = "valid";
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79 if use == 3 then
1266
51e7a4bbd70b mod_s2s_auth_dane: Style fixes
Kim Alvefur <zash@zash.se>
parents: 1265
diff changeset
80 session.cert_chain_status = "valid";
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 -- for usage 1 the chain has to be valid already
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82 end
1266
51e7a4bbd70b mod_s2s_auth_dane: Style fixes
Kim Alvefur <zash@zash.se>
parents: 1265
diff changeset
83 match_found = true;
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 break;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 else
1261
6a37bd22c8df mod_s2s_auth_dane: Warn about unsupported DANE params
Kim Alvefur <zash@zash.se>
parents: 1258
diff changeset
87 module:log("warn", "DANE %s is unsupported", tlsa:getUsage() or ("usage "..tostring(use)));
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
88 -- TODO Ca checks needs to loop over the chain and stuff
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
89 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
90 end
1262
1e84eebf3f46 mod_s2s_auth_dane: Invalidate trust if there are TLSA records but no matches, or bogus results
Kim Alvefur <zash@zash.se>
parents: 1261
diff changeset
91 if not match_found then
1265
020165014e56 mod_s2s_auth_dane: Fix wording on validation failure
Kim Alvefur <zash@zash.se>
parents: 1262
diff changeset
92 (session.log or module._log)("warn", "DANE validation failed");
1262
1e84eebf3f46 mod_s2s_auth_dane: Invalidate trust if there are TLSA records but no matches, or bogus results
Kim Alvefur <zash@zash.se>
parents: 1261
diff changeset
93 session.cert_identity_status = "invalid";
1e84eebf3f46 mod_s2s_auth_dane: Invalidate trust if there are TLSA records but no matches, or bogus results
Kim Alvefur <zash@zash.se>
parents: 1261
diff changeset
94 session.cert_chain_status = "invalid";
1e84eebf3f46 mod_s2s_auth_dane: Invalidate trust if there are TLSA records but no matches, or bogus results
Kim Alvefur <zash@zash.se>
parents: 1261
diff changeset
95 end
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
96 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
97 end);
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
98
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
99 function module.unload()
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
100 s2sout.try_connect = _try_connect;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
101 end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
102