Mercurial > prosody-modules
comparison mod_s2s_auth_dane/mod_s2s_auth_dane.lua @ 1332:08a0241f5d2c
mod_s2s_auth_dane: Add some comments
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Fri, 07 Mar 2014 23:30:34 +0100 |
| parents | bb6f3312ab46 |
| children | 15912b077370 |
comparison
equal
deleted
inserted
replaced
| 1331:dbaa67babeb4 | 1332:08a0241f5d2c |
|---|---|
| 1 -- mod_s2s_auth_dane | 1 -- mod_s2s_auth_dane |
| 2 -- Copyright (C) 2013-2014 Kim Alvefur | |
| 2 -- | 3 -- |
| 3 -- Between the DNS lookup and the certificate validation, there is a race condition. | 4 -- This file is MIT/X11 licensed. |
| 4 -- Solving that probably requires changes to mod_s2s, like using util.async | 5 -- |
| 6 -- Could be done much cleaner if mod_s2s was using util.async | |
| 5 | 7 |
| 6 | 8 |
| 7 module:set_global(); | 9 module:set_global(); |
| 8 | 10 |
| 9 local dns_lookup = require"net.adns".lookup; | 11 local dns_lookup = require"net.adns".lookup; |
| 10 local hashes = require"util.hashes"; | 12 local hashes = require"util.hashes"; |
| 11 local base64 = require"util.encodings".base64; | 13 local base64 = require"util.encodings".base64; |
| 12 | 14 |
| 13 local s2sout = module:depends"s2s".route_to_new_session.s2sout; | 15 local s2sout = module:depends"s2s".route_to_new_session.s2sout; |
| 14 local _try_connect = s2sout.try_connect; | |
| 15 | 16 |
| 16 local pat = "%-%-%-%-%-BEGIN ([A-Z ]+)%-%-%-%-%-\r?\n".. | 17 local pat = "%-%-%-%-%-BEGIN ([A-Z ]+)%-%-%-%-%-\r?\n".. |
| 17 "([0-9A-Za-z=+/\r\n]*)\r?\n%-%-%-%-%-END %1%-%-%-%-%-"; | 18 "([0-9A-Za-z=+/\r\n]*)\r?\n%-%-%-%-%-END %1%-%-%-%-%-"; |
| 18 local function pem2der(pem) | 19 local function pem2der(pem) |
| 19 local typ, data = pem:match(pat); | 20 local typ, data = pem:match(pat); |
| 25 -- TODO Things to test/handle: | 26 -- TODO Things to test/handle: |
| 26 -- Negative or bogus answers | 27 -- Negative or bogus answers |
| 27 -- No SRV records | 28 -- No SRV records |
| 28 -- No encryption offered | 29 -- No encryption offered |
| 29 | 30 |
| 31 -- This function is called when a new SRV target has been picked | |
| 32 -- the original function does A/AAAA resolution before continuing | |
| 33 local _try_connect = s2sout.try_connect; | |
| 30 function s2sout.try_connect(host_session, connect_host, connect_port, err) | 34 function s2sout.try_connect(host_session, connect_host, connect_port, err) |
| 31 local srv_hosts = host_session.srv_hosts; | 35 local srv_hosts = host_session.srv_hosts; |
| 32 local srv_choice = host_session.srv_choice; | 36 local srv_choice = host_session.srv_choice; |
| 33 if srv_hosts and srv_hosts.answer.secure and not srv_hosts[srv_choice].dane then | 37 if srv_hosts and srv_hosts.answer.secure and not srv_hosts[srv_choice].dane then |
| 34 srv_hosts[srv_choice].dane = dns_lookup(function(answer) | 38 srv_hosts[srv_choice].dane = dns_lookup(function(answer) |
| 95 module:log("warn", "DANE %s is unsupported", tlsa:getUsage() or ("usage "..tostring(use))); | 99 module:log("warn", "DANE %s is unsupported", tlsa:getUsage() or ("usage "..tostring(use))); |
| 96 -- TODO CA checks needs to loop over the chain and stuff | 100 -- TODO CA checks needs to loop over the chain and stuff |
| 97 end | 101 end |
| 98 end | 102 end |
| 99 if not match_found then | 103 if not match_found then |
| 104 -- No TLSA matched or response was bogus | |
| 100 (session.log or module._log)("warn", "DANE validation failed"); | 105 (session.log or module._log)("warn", "DANE validation failed"); |
| 101 session.cert_identity_status = "invalid"; | 106 session.cert_identity_status = "invalid"; |
| 102 session.cert_chain_status = "invalid"; | 107 session.cert_chain_status = "invalid"; |
| 103 end | 108 end |
| 104 end | 109 end |
| 109 local session = event.session; | 114 local session = event.session; |
| 110 local srv_hosts = session.srv_hosts; | 115 local srv_hosts = session.srv_hosts; |
| 111 local srv_choice = session.srv_choice; | 116 local srv_choice = session.srv_choice; |
| 112 if srv_hosts[srv_choice].dane and not session.secure then | 117 if srv_hosts[srv_choice].dane and not session.secure then |
| 113 -- TLSA record but no TLS, not ok. | 118 -- TLSA record but no TLS, not ok. |
| 119 -- TODO Optional? | |
| 114 session:close({ | 120 session:close({ |
| 115 condition = "policy-violation", | 121 condition = "policy-violation", |
| 116 text = "Encrypted server-to-server communication is required but was not " | 122 text = "Encrypted server-to-server communication is required but was not " |
| 117 ..((session.direction == "outgoing" and "offered") or "used") | 123 ..((session.direction == "outgoing" and "offered") or "used") |
| 118 }); | 124 }); |
| 120 end | 126 end |
| 121 end); | 127 end); |
| 122 end | 128 end |
| 123 | 129 |
| 124 function module.unload() | 130 function module.unload() |
| 131 -- Restore the original try_connect function | |
| 125 s2sout.try_connect = _try_connect; | 132 s2sout.try_connect = _try_connect; |
| 126 end | 133 end |
| 127 | 134 |
