mod_s2s_auth_dane/mod_s2s_auth_dane.lua
author Matthew Wild <mwild1@gmail.com>
Tue, 18 Jan 2022 17:01:18 +0000
changeset 4880 0f5f2d4475b9
parent 4495 35381608d323
permissions -rw-r--r--
mod_http_xep227: Add support for import via APIs rather than direct store manipulation In particular this transitions PEP nodes and data to be imported via mod_pep's APIs, fixing issues with importing at runtime while PEP data may already be live in RAM. Next obvious candidate for this approach is rosters, so clients get immediate roster pushes and other special handling (such as emitting subscribes to reach the desired subscription state).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- mod_s2s_auth_dane
1332
08a0241f5d2c mod_s2s_auth_dane: Add some comments
Kim Alvefur <zash@zash.se>
parents: 1330
diff changeset
     2
-- Copyright (C) 2013-2014 Kim Alvefur
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
--
1332
08a0241f5d2c mod_s2s_auth_dane: Add some comments
Kim Alvefur <zash@zash.se>
parents: 1330
diff changeset
     4
-- This file is MIT/X11 licensed.
08a0241f5d2c mod_s2s_auth_dane: Add some comments
Kim Alvefur <zash@zash.se>
parents: 1330
diff changeset
     5
--
1370
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
     6
-- Implements DANE and Secure Delegation using DNS SRV as described in
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
     7
-- http://tools.ietf.org/html/draft-miller-xmpp-dnssec-prooftype
1349
350e903b14ff mod_s2s_auth_dane: Comments and TODOs
Kim Alvefur <zash@zash.se>
parents: 1348
diff changeset
     8
--
350e903b14ff mod_s2s_auth_dane: Comments and TODOs
Kim Alvefur <zash@zash.se>
parents: 1348
diff changeset
     9
-- Known issues:
1332
08a0241f5d2c mod_s2s_auth_dane: Add some comments
Kim Alvefur <zash@zash.se>
parents: 1330
diff changeset
    10
-- Could be done much cleaner if mod_s2s was using util.async
1349
350e903b14ff mod_s2s_auth_dane: Comments and TODOs
Kim Alvefur <zash@zash.se>
parents: 1348
diff changeset
    11
--
350e903b14ff mod_s2s_auth_dane: Comments and TODOs
Kim Alvefur <zash@zash.se>
parents: 1348
diff changeset
    12
-- TODO Things to test/handle:
350e903b14ff mod_s2s_auth_dane: Comments and TODOs
Kim Alvefur <zash@zash.se>
parents: 1348
diff changeset
    13
-- Negative or bogus answers
350e903b14ff mod_s2s_auth_dane: Comments and TODOs
Kim Alvefur <zash@zash.se>
parents: 1348
diff changeset
    14
-- No encryption offered
350e903b14ff mod_s2s_auth_dane: Comments and TODOs
Kim Alvefur <zash@zash.se>
parents: 1348
diff changeset
    15
-- Different hostname before and after STARTTLS - mod_s2s should complain
350e903b14ff mod_s2s_auth_dane: Comments and TODOs
Kim Alvefur <zash@zash.se>
parents: 1348
diff changeset
    16
-- Interaction with Dialback
1762
7ba877e2d660 mod_s2s_auth_dane: Ignore mutating of the 'module' global, that is ok in prosody plugins [luacheck]
Kim Alvefur <zash@zash.se>
parents: 1761
diff changeset
    17
--
7ba877e2d660 mod_s2s_auth_dane: Ignore mutating of the 'module' global, that is ok in prosody plugins [luacheck]
Kim Alvefur <zash@zash.se>
parents: 1761
diff changeset
    18
-- luacheck: ignore module
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
module:set_global();
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
2201
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
    22
local have_async, async = pcall(require, "util.async");
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    23
local noop = function () end
4495
35381608d323 mod_s2s_auth_dane: Fix traceback in DANE-TA check because unpack() moved
Kim Alvefur <zash@zash.se>
parents: 4494
diff changeset
    24
local unpack = table.unpack or _G.unpack;
1348
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
    25
local type = type;
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
    26
local t_insert = table.insert;
1348
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
    27
local set = require"util.set";
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
local dns_lookup = require"net.adns".lookup;
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
local hashes = require"util.hashes";
1412
d85695be0441 Backout 33f132c3f4b7 until 0.10
Kim Alvefur <zash@zash.se>
parents: 1411
diff changeset
    30
local base64 = require"util.encodings".base64;
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
    31
local idna_to_ascii = require "util.encodings".idna.to_ascii;
1370
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
    32
local idna_to_unicode = require"util.encodings".idna.to_unicode;
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
    33
local nameprep = require"util.encodings".stringprep.nameprep;
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
    34
local cert_verify_identity = require "util.x509".verify_identity;
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
1410
f4e497a53c6e mod_s2s_auth_dane: Change how TLSA support is detected
Kim Alvefur <zash@zash.se>
parents: 1409
diff changeset
    36
do
f4e497a53c6e mod_s2s_auth_dane: Change how TLSA support is detected
Kim Alvefur <zash@zash.se>
parents: 1409
diff changeset
    37
	local net_dns = require"net.dns";
f4e497a53c6e mod_s2s_auth_dane: Change how TLSA support is detected
Kim Alvefur <zash@zash.se>
parents: 1409
diff changeset
    38
	if not net_dns.types or not net_dns.types[52] then
f4e497a53c6e mod_s2s_auth_dane: Change how TLSA support is detected
Kim Alvefur <zash@zash.se>
parents: 1409
diff changeset
    39
		module:log("error", "No TLSA support available, DANE will not be supported");
f4e497a53c6e mod_s2s_auth_dane: Change how TLSA support is detected
Kim Alvefur <zash@zash.se>
parents: 1409
diff changeset
    40
		return
f4e497a53c6e mod_s2s_auth_dane: Change how TLSA support is detected
Kim Alvefur <zash@zash.se>
parents: 1409
diff changeset
    41
	end
1358
497e1df4b7ee mod_s2s_auth_dane: Abort module loading if luaunbound is unavailable
Kim Alvefur <zash@zash.se>
parents: 1356
diff changeset
    42
end
497e1df4b7ee mod_s2s_auth_dane: Abort module loading if luaunbound is unavailable
Kim Alvefur <zash@zash.se>
parents: 1356
diff changeset
    43
1412
d85695be0441 Backout 33f132c3f4b7 until 0.10
Kim Alvefur <zash@zash.se>
parents: 1411
diff changeset
    44
local pat = "%-%-%-%-%-BEGIN ([A-Z ]+)%-%-%-%-%-\r?\n"..
d85695be0441 Backout 33f132c3f4b7 until 0.10
Kim Alvefur <zash@zash.se>
parents: 1411
diff changeset
    45
"([0-9A-Za-z=+/\r\n]*)\r?\n%-%-%-%-%-END %1%-%-%-%-%-";
d85695be0441 Backout 33f132c3f4b7 until 0.10
Kim Alvefur <zash@zash.se>
parents: 1411
diff changeset
    46
local function pem2der(pem)
d85695be0441 Backout 33f132c3f4b7 until 0.10
Kim Alvefur <zash@zash.se>
parents: 1411
diff changeset
    47
	local typ, data = pem:match(pat);
d85695be0441 Backout 33f132c3f4b7 until 0.10
Kim Alvefur <zash@zash.se>
parents: 1411
diff changeset
    48
	if typ and data then
d85695be0441 Backout 33f132c3f4b7 until 0.10
Kim Alvefur <zash@zash.se>
parents: 1411
diff changeset
    49
		return base64.decode(data), typ;
d85695be0441 Backout 33f132c3f4b7 until 0.10
Kim Alvefur <zash@zash.se>
parents: 1411
diff changeset
    50
	end
d85695be0441 Backout 33f132c3f4b7 until 0.10
Kim Alvefur <zash@zash.se>
parents: 1411
diff changeset
    51
end
1348
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
    52
local use_map = { ["DANE-EE"] = 3; ["DANE-TA"] = 2; ["PKIX-EE"] = 1; ["PKIX-CA"] = 0 }
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
    53
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
    54
local implemented_uses = set.new { "DANE-EE", "PKIX-EE" };
1502
72ef98818b90 mod_s2s_auth_dane: Fix traceback caused by LuaSec not being loaded
Kim Alvefur <zash@zash.se>
parents: 1437
diff changeset
    55
do
72ef98818b90 mod_s2s_auth_dane: Fix traceback caused by LuaSec not being loaded
Kim Alvefur <zash@zash.se>
parents: 1437
diff changeset
    56
	local cert_mt = debug.getregistry()["SSL:Certificate"];
72ef98818b90 mod_s2s_auth_dane: Fix traceback caused by LuaSec not being loaded
Kim Alvefur <zash@zash.se>
parents: 1437
diff changeset
    57
	if cert_mt and cert_mt.__index.issued then
72ef98818b90 mod_s2s_auth_dane: Fix traceback caused by LuaSec not being loaded
Kim Alvefur <zash@zash.se>
parents: 1437
diff changeset
    58
		-- Need cert:issued() for these
72ef98818b90 mod_s2s_auth_dane: Fix traceback caused by LuaSec not being loaded
Kim Alvefur <zash@zash.se>
parents: 1437
diff changeset
    59
		implemented_uses:add("DANE-TA");
72ef98818b90 mod_s2s_auth_dane: Fix traceback caused by LuaSec not being loaded
Kim Alvefur <zash@zash.se>
parents: 1437
diff changeset
    60
		implemented_uses:add("PKIX-CA");
72ef98818b90 mod_s2s_auth_dane: Fix traceback caused by LuaSec not being loaded
Kim Alvefur <zash@zash.se>
parents: 1437
diff changeset
    61
	else
2007
8ccf347c7753 mod_s2s_auth_dane: Warn only if there enabled uses that can't be supported
Kim Alvefur <zash@zash.se>
parents: 1976
diff changeset
    62
		module:log("debug", "The cert:issued() method is unavailable, DANE-TA and PKIX-CA can't be enabled");
1502
72ef98818b90 mod_s2s_auth_dane: Fix traceback caused by LuaSec not being loaded
Kim Alvefur <zash@zash.se>
parents: 1437
diff changeset
    63
	end
2036
6645838c6475 mod_s2s_auth_dane: Check if cert:pubkey() is available
Kim Alvefur <zash@zash.se>
parents: 2007
diff changeset
    64
	if not cert_mt.__index.pubkey then
2039
39774b078dde mod_s2s_auth_dane: Correct message about not being able to support SPKI
Kim Alvefur <zash@zash.se>
parents: 2036
diff changeset
    65
		module:log("debug", "The cert:pubkey() method is unavailable, the SPKI usage can't be supported");
2036
6645838c6475 mod_s2s_auth_dane: Check if cert:pubkey() is available
Kim Alvefur <zash@zash.se>
parents: 2007
diff changeset
    66
	end
1396
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
    67
end
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
    68
local configured_uses = module:get_option_set("dane_uses", { "DANE-EE", "DANE-TA" });
1348
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
    69
local enabled_uses = set.intersection(implemented_uses, configured_uses) / function(use) return use_map[use] end;
2007
8ccf347c7753 mod_s2s_auth_dane: Warn only if there enabled uses that can't be supported
Kim Alvefur <zash@zash.se>
parents: 1976
diff changeset
    70
local unsupported = configured_uses - implemented_uses;
8ccf347c7753 mod_s2s_auth_dane: Warn only if there enabled uses that can't be supported
Kim Alvefur <zash@zash.se>
parents: 1976
diff changeset
    71
if not unsupported:empty() then
8ccf347c7753 mod_s2s_auth_dane: Warn only if there enabled uses that can't be supported
Kim Alvefur <zash@zash.se>
parents: 1976
diff changeset
    72
	module:log("warn", "Unable to support DANE uses %s", tostring(unsupported));
8ccf347c7753 mod_s2s_auth_dane: Warn only if there enabled uses that can't be supported
Kim Alvefur <zash@zash.se>
parents: 1976
diff changeset
    73
end
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    75
-- Find applicable TLSA records
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    76
-- Takes a s2sin/out and a callback
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    77
local function dane_lookup(host_session, cb)
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    78
	cb = cb or noop;
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
    79
	local log = host_session.log or module._log;
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    80
	if host_session.dane ~= nil then return end -- Has already done a lookup
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    81
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
    82
	if host_session.direction == "incoming" then
1678
7f4c64cfed09 mod_s2s_auth_dane: Abort earlier for sessions from hosts that don't say who they are
Kim Alvefur <zash@zash.se>
parents: 1677
diff changeset
    83
		if not host_session.from_host then
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
    84
			log("debug", "Session doesn't have a 'from' host set");
1678
7f4c64cfed09 mod_s2s_auth_dane: Abort earlier for sessions from hosts that don't say who they are
Kim Alvefur <zash@zash.se>
parents: 1677
diff changeset
    85
			return;
7f4c64cfed09 mod_s2s_auth_dane: Abort earlier for sessions from hosts that don't say who they are
Kim Alvefur <zash@zash.se>
parents: 1677
diff changeset
    86
		end
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    87
		-- We don't know what hostname or port to use for Incoming connections
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    88
		-- so we do a SRV lookup and then request TLSA records for each SRV
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    89
		-- Most servers will probably use the same certificate on outgoing
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    90
		-- and incoming connections, so this should work well
1362
920ac9a8480b mod_s2s_auth_dane: Fix tb when no hostname sent by remote
Kim Alvefur <zash@zash.se>
parents: 1359
diff changeset
    91
		local name = host_session.from_host and idna_to_ascii(host_session.from_host);
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    92
		if not name then
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
    93
			log("warn", "Could not convert '%s' to ASCII for DNS lookup", tostring(host_session.from_host));
1677
aac5e56615ce mod_s2s_auth_dane: Demote log message about failure to ASCII-ify hostname from error to warning
Kim Alvefur <zash@zash.se>
parents: 1656
diff changeset
    94
			return;
aac5e56615ce mod_s2s_auth_dane: Demote log message about failure to ASCII-ify hostname from error to warning
Kim Alvefur <zash@zash.se>
parents: 1656
diff changeset
    95
		end
1976
b10118d7c0df mod_s2s_auth_dane: More DNS related debug logging
Kim Alvefur <zash@zash.se>
parents: 1975
diff changeset
    96
		log("debug", "Querying SRV records from _xmpp-server._tcp.%s.", name);
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    97
		host_session.dane = dns_lookup(function (answer, err)
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    98
			host_session.dane = false; -- Mark that we already did the lookup
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
    99
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   100
			if not answer then
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   101
				log("debug", "Resolver error: %s", tostring(err));
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   102
				return cb(host_session);
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   103
			end
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   104
1975
54405541d0ba mod_s2s_auth_dane: Abort on bogus reply to SRV lookup
Kim Alvefur <zash@zash.se>
parents: 1974
diff changeset
   105
			if answer.bogus then
54405541d0ba mod_s2s_auth_dane: Abort on bogus reply to SRV lookup
Kim Alvefur <zash@zash.se>
parents: 1974
diff changeset
   106
				log("warn", "Results are bogus!");
54405541d0ba mod_s2s_auth_dane: Abort on bogus reply to SRV lookup
Kim Alvefur <zash@zash.se>
parents: 1974
diff changeset
   107
				-- Bad sign, probably not a good idea to do any fallback here
54405541d0ba mod_s2s_auth_dane: Abort on bogus reply to SRV lookup
Kim Alvefur <zash@zash.se>
parents: 1974
diff changeset
   108
				host_session.dane = answer;
54405541d0ba mod_s2s_auth_dane: Abort on bogus reply to SRV lookup
Kim Alvefur <zash@zash.se>
parents: 1974
diff changeset
   109
			elseif not answer.secure then
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   110
				log("debug", "Results are not secure");
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   111
				return cb(host_session);
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   112
			end
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   113
1704
ab3175685f94 mod_s2s_auth_dane: Don't count number of RRs in DNS reply if the DNS lib already did
Kim Alvefur <zash@zash.se>
parents: 1678
diff changeset
   114
			local n = answer.n or #answer;
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   115
			if n == 0 then
1947
7e04ca0aa757 mod_s2s_auth_dane: Support servers without SRV records by falling back to port 5269 and the bare hostname for TLSA lookups
Kim Alvefur <zash@zash.se>
parents: 1762
diff changeset
   116
				-- No SRV records, synthesize fallback host and port
7e04ca0aa757 mod_s2s_auth_dane: Support servers without SRV records by falling back to port 5269 and the bare hostname for TLSA lookups
Kim Alvefur <zash@zash.se>
parents: 1762
diff changeset
   117
				-- this may behave oddly for connections in the other direction if
7e04ca0aa757 mod_s2s_auth_dane: Support servers without SRV records by falling back to port 5269 and the bare hostname for TLSA lookups
Kim Alvefur <zash@zash.se>
parents: 1762
diff changeset
   118
				-- mod_s2s doesn't keep the answer around
7e04ca0aa757 mod_s2s_auth_dane: Support servers without SRV records by falling back to port 5269 and the bare hostname for TLSA lookups
Kim Alvefur <zash@zash.se>
parents: 1762
diff changeset
   119
				answer[1] = { srv = { target = name, port = 5269 } };
7e04ca0aa757 mod_s2s_auth_dane: Support servers without SRV records by falling back to port 5269 and the bare hostname for TLSA lookups
Kim Alvefur <zash@zash.se>
parents: 1762
diff changeset
   120
				n = 1;
7e04ca0aa757 mod_s2s_auth_dane: Support servers without SRV records by falling back to port 5269 and the bare hostname for TLSA lookups
Kim Alvefur <zash@zash.se>
parents: 1762
diff changeset
   121
			elseif n == 1 and answer[1].srv.target == '.' then
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   122
				return cb(host_session); -- No service ... This shouldn't happen?
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   123
			end
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   124
			local srv_hosts = { answer = answer };
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   125
			host_session.srv_hosts = srv_hosts;
1705
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   126
			local dane;
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   127
			for _, record in ipairs(answer) do
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   128
				t_insert(srv_hosts, record.srv);
1976
b10118d7c0df mod_s2s_auth_dane: More DNS related debug logging
Kim Alvefur <zash@zash.se>
parents: 1975
diff changeset
   129
				log("debug", "Querying TLSA record for %s:%d", record.srv.target, record.srv.port);
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   130
				dns_lookup(function(dane_answer)
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   131
					log("debug", "Got answer for %s:%d", record.srv.target, record.srv.port);
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   132
					n = n - 1;
1705
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   133
					-- There are three kinds of answers
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   134
					-- Insecure, Secure and Bogus
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   135
					--
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   136
					-- We collect Secure answers for later use
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   137
					--
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   138
					-- Insecure (legacy) answers are simply ignored
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   139
					--
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   140
					-- If we get a Bogus (dnssec error) reply, keep the
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   141
					-- status around.  If there were only bogus replies, the
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   142
					-- connection will be aborted.  If there were at least
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   143
					-- one non-Bogus reply, we proceed.  If none of the
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   144
					-- replies matched, we consider the connection insecure.
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   145
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   146
					if (dane_answer.bogus or dane_answer.secure) and not dane then
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   147
						-- The first answer we care about
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   148
						-- For services with only one SRV record, this will be the only one
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   149
						log("debug", "First secure (or bogus) TLSA")
1705
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   150
						dane = dane_answer;
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   151
					elseif dane_answer.bogus then
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   152
						log("debug", "Got additional bogus TLSA")
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   153
						dane.bogus = dane_answer.bogus;
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   154
					elseif dane_answer.secure then
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   155
						log("debug", "Got additional secure TLSA")
1656
9a3d2f1479a4 mod_s2s_auth_dane: Cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 1646
diff changeset
   156
						for _, dane_record in ipairs(dane_answer) do
9a3d2f1479a4 mod_s2s_auth_dane: Cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 1646
diff changeset
   157
							t_insert(dane, dane_record);
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   158
						end
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   159
					end
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   160
					if n == 0 then
1705
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   161
						if dane then
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   162
							host_session.dane = dane;
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   163
							if #dane > 0 and dane.bogus then
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   164
								-- Got at least one non-bogus reply,
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   165
								-- This should trigger a failure if one of them did not match
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   166
								log("warn", "Ignoring bogus replies");
1705
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   167
								dane.bogus = nil;
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   168
							end
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   169
							if #dane == 0 and dane.bogus == nil then
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   170
								-- Got no usable data
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   171
								host_session.dane = false;
9b429fc9e8a0 mod_s2s_auth_dane: Simplify cases where there are only one SRV record
Kim Alvefur <zash@zash.se>
parents: 1704
diff changeset
   172
							end
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   173
						end
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   174
						return cb(host_session);
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   175
					end
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   176
				end, ("_%d._tcp.%s."):format(record.srv.port, record.srv.target), "TLSA");
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   177
			end
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   178
		end, "_xmpp-server._tcp."..name..".", "SRV");
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   179
		return true;
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   180
	elseif host_session.direction == "outgoing" then
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   181
		-- Prosody has already done SRV lookups for outgoing session, so check if those are secure
1359
74769c0c79f8 mod_s2s_auth_dane: Verify that the SRV is secure
Kim Alvefur <zash@zash.se>
parents: 1358
diff changeset
   182
		local srv_hosts = host_session.srv_hosts;
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   183
		if not ( srv_hosts and srv_hosts.answer and srv_hosts.answer.secure ) then
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   184
			return; -- No secure SRV records, fall back to non-DANE mode
1947
7e04ca0aa757 mod_s2s_auth_dane: Support servers without SRV records by falling back to port 5269 and the bare hostname for TLSA lookups
Kim Alvefur <zash@zash.se>
parents: 1762
diff changeset
   185
			-- Empty response were not kept by older mod_s2s/s2sout
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   186
		end
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   187
		-- Do TLSA lookup for currently selected SRV record
1947
7e04ca0aa757 mod_s2s_auth_dane: Support servers without SRV records by falling back to port 5269 and the bare hostname for TLSA lookups
Kim Alvefur <zash@zash.se>
parents: 1762
diff changeset
   188
		local srv_choice = srv_hosts[host_session.srv_choice or 0] or { target = idna_to_ascii(host_session.to_host), port = 5269 };
1976
b10118d7c0df mod_s2s_auth_dane: More DNS related debug logging
Kim Alvefur <zash@zash.se>
parents: 1975
diff changeset
   189
		log("debug", "Querying TLSA record for %s:%d", srv_choice.target, srv_choice.port);
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   190
		host_session.dane = dns_lookup(function(answer)
1409
151aa00559d1 mod_s2s_auth_dane: Fix logic precedence issue
Kim Alvefur <zash@zash.se>
parents: 1396
diff changeset
   191
			if answer and ((answer.secure and #answer > 0) or answer.bogus) then
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   192
				srv_choice.dane = answer;
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   193
			else
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   194
				srv_choice.dane = false;
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   195
			end
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   196
			host_session.dane = srv_choice.dane;
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   197
			return cb(host_session);
1351
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   198
		end, ("_%d._tcp.%s."):format(srv_choice.port, srv_choice.target), "TLSA");
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   199
		return true;
a052740bbf48 mod_s2s_auth_dane: Back to _port._tcp.srvtarget.example.net
Kim Alvefur <zash@zash.se>
parents: 1350
diff changeset
   200
	end
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   201
end
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   202
2189
2cbd7876ba14 mod_s2s_auth_dane: Move pausing code to a function
Kim Alvefur <zash@zash.se>
parents: 2188
diff changeset
   203
local function pause(host_session)
2cbd7876ba14 mod_s2s_auth_dane: Move pausing code to a function
Kim Alvefur <zash@zash.se>
parents: 2188
diff changeset
   204
	host_session.log("debug", "Pausing connection until DANE lookup is completed");
2cbd7876ba14 mod_s2s_auth_dane: Move pausing code to a function
Kim Alvefur <zash@zash.se>
parents: 2188
diff changeset
   205
	host_session.conn:pause()
2cbd7876ba14 mod_s2s_auth_dane: Move pausing code to a function
Kim Alvefur <zash@zash.se>
parents: 2188
diff changeset
   206
end
2cbd7876ba14 mod_s2s_auth_dane: Move pausing code to a function
Kim Alvefur <zash@zash.se>
parents: 2188
diff changeset
   207
2188
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   208
local function resume(host_session)
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   209
	host_session.log("debug", "DANE lookup completed, resuming connection");
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   210
	host_session.conn:resume()
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   211
end
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   212
2201
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   213
if have_async then
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   214
	function pause(host_session)
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   215
		host_session.log("debug", "Pausing connection until DANE lookup is completed");
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   216
		local wait, done = async.waiter();
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   217
		host_session._done_waiting_for_dane = done;
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   218
		wait();
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   219
	end
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   220
	local function _resume(_, host_session)
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   221
		if host_session._done_waiting_for_dane then
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   222
			host_session.log("debug", "DANE lookup completed, resuming connection");
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   223
			host_session._done_waiting_for_dane();
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   224
			host_session._done_waiting_for_dane = nil;
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   225
		end
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   226
	end
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   227
	function resume(host_session)
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   228
		-- Something about the way luaunbound calls callbacks is messed up
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   229
		if host_session._done_waiting_for_dane then
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   230
			module:add_timer(0, _resume, host_session);
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   231
		end
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   232
	end
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   233
end
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   234
4494
cf2bdb2aaa57 mod_s2s_auth_dane: Disable now redundant validation done in trunk
Kim Alvefur <zash@zash.se>
parents: 2873
diff changeset
   235
local new_dane = module:get_option_boolean("use_dane", false);
cf2bdb2aaa57 mod_s2s_auth_dane: Disable now redundant validation done in trunk
Kim Alvefur <zash@zash.se>
parents: 2873
diff changeset
   236
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   237
function module.add_host(module)
2188
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   238
	local function on_new_s2s(event)
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   239
		local host_session = event.origin;
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   240
		if host_session.type == "s2sout" or host_session.type == "s2sin" then
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   241
			return; -- Already authenticated
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   242
		end
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   243
		if host_session.dane ~= nil then
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   244
			return; -- Already done DANE lookup
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   245
		end
2201
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   246
		dane_lookup(host_session, resume);
2873
77498ea07795 mod_s2s_auth_dane: Fix typo in comment [codespell]
Kim Alvefur <zash@zash.se>
parents: 2201
diff changeset
   247
		-- Let it run in parallel until we need to check the cert
2188
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   248
	end
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   249
4494
cf2bdb2aaa57 mod_s2s_auth_dane: Disable now redundant validation done in trunk
Kim Alvefur <zash@zash.se>
parents: 2873
diff changeset
   250
	if not new_dane then
cf2bdb2aaa57 mod_s2s_auth_dane: Disable now redundant validation done in trunk
Kim Alvefur <zash@zash.se>
parents: 2873
diff changeset
   251
		-- New outgoing connections
cf2bdb2aaa57 mod_s2s_auth_dane: Disable now redundant validation done in trunk
Kim Alvefur <zash@zash.se>
parents: 2873
diff changeset
   252
		module:hook("stanza/http://etherx.jabber.org/streams:features", on_new_s2s, 501);
cf2bdb2aaa57 mod_s2s_auth_dane: Disable now redundant validation done in trunk
Kim Alvefur <zash@zash.se>
parents: 2873
diff changeset
   253
		module:hook("s2sout-authenticate-legacy", on_new_s2s, 200);
cf2bdb2aaa57 mod_s2s_auth_dane: Disable now redundant validation done in trunk
Kim Alvefur <zash@zash.se>
parents: 2873
diff changeset
   254
	end
2188
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   255
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   256
	-- New incoming connections
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   257
	module:hook("s2s-stream-features", on_new_s2s, 10);
7155ed1fb540 Backed out changeset f00cbfb812cd, it only half-worked and broke things
Kim Alvefur <zash@zash.se>
parents: 2186
diff changeset
   258
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   259
	module:hook("s2s-authenticated", function(event)
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   260
		local session = event.session;
2184
5e0102a07fdc mod_s2s_auth_dane: Make sure dane field has correct type
Kim Alvefur <zash@zash.se>
parents: 2039
diff changeset
   261
		if session.dane and type(session.dane) == "table" and next(session.dane) ~= nil and not session.secure then
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   262
			-- TLSA record but no TLS, not ok.
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   263
			-- TODO Optional?
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   264
			-- Bogus replies should trigger this path
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   265
			-- How does this interact with Dialback?
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   266
			session:close({
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   267
				condition = "policy-violation",
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   268
				text = "Encrypted server-to-server communication is required but was not "
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   269
					..((session.direction == "outgoing" and "offered") or "used")
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   270
			});
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   271
			return false;
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   272
		end
1392
d99c10fc4d19 mod_s2s_auth_dane: Clean up no longer needed DNS replies
Kim Alvefur <zash@zash.se>
parents: 1391
diff changeset
   273
		-- Cleanup
d99c10fc4d19 mod_s2s_auth_dane: Clean up no longer needed DNS replies
Kim Alvefur <zash@zash.se>
parents: 1391
diff changeset
   274
		session.srv_hosts = nil;
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   275
	end);
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   276
end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   277
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   278
-- Compare one TLSA record against a certificate
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   279
local function one_dane_check(tlsa, cert, log)
1389
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   280
	local select, match, certdata = tlsa.select, tlsa.match;
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   281
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   282
	if select == 0 then
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   283
		certdata = pem2der(cert:pem());
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   284
	elseif select == 1 and cert.pubkey then
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   285
		certdata = pem2der(cert:pubkey());
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   286
	else
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   287
		log("warn", "DANE selector %s is unsupported", tlsa:getSelector() or select);
1389
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   288
		return;
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   289
	end
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   290
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   291
	if match == 1 then
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   292
		certdata = hashes.sha256(certdata);
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   293
	elseif match == 2 then
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   294
		certdata = hashes.sha512(certdata);
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   295
	elseif match ~= 0 then
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   296
		log("warn", "DANE match rule %s is unsupported", tlsa:getMatchType() or match);
1389
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   297
		return;
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   298
	end
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   299
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   300
	if #certdata ~= #tlsa.data then
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   301
		log("warn", "Length mismatch: Cert: %d, TLSA: %d", #certdata, #tlsa.data);
1630
aed20f9e78c8 mod_s2s_auth_dane: Comments and cleanup
Kim Alvefur <zash@zash.se>
parents: 1507
diff changeset
   302
	end
1389
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   303
	return certdata == tlsa.data;
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   304
end
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   305
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   306
module:hook("s2s-check-certificate", function(event)
1437
161bbe0b9dd3 mod_s2s_auth_dane: Tweak log messages
Kim Alvefur <zash@zash.se>
parents: 1436
diff changeset
   307
	local session, cert, host = event.session, event.cert, event.host;
1434
1caf971a2f0f mod_s2s_auth_dane: Return if no certificate found
Kim Alvefur <zash@zash.se>
parents: 1431
diff changeset
   308
	if not cert then return end
1431
33a796b2cb91 mod_s2s_auth_dane: Cache logger to save some table lookups and improve readability
Kim Alvefur <zash@zash.se>
parents: 1415
diff changeset
   309
	local log = session.log or module._log;
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   310
	local dane = session.dane;
2201
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   311
	if type(dane) ~= "table" then
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   312
		if dane == nil and dane_lookup(session, resume) then
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   313
			pause(session);
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   314
			dane = session.dane;
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   315
		end
90a444ccaa8e mod_s2s_auth_dane: Use util.async if available (current prosody trunk)
Kim Alvefur <zash@zash.se>
parents: 2189
diff changeset
   316
	end
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   317
	if type(dane) == "table" then
1646
a4a6b4be973a mod_s2s_auth_dane: Update for recent changes in Zashs LuaSec branch
Kim Alvefur <zash@zash.se>
parents: 1630
diff changeset
   318
		local match_found, supported_found;
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   319
		for i = 1, #dane do
1646
a4a6b4be973a mod_s2s_auth_dane: Update for recent changes in Zashs LuaSec branch
Kim Alvefur <zash@zash.se>
parents: 1630
diff changeset
   320
			local tlsa = dane[i].tlsa;
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   321
			log("debug", "TLSA #%d: %s", i, tostring(tlsa))
1646
a4a6b4be973a mod_s2s_auth_dane: Update for recent changes in Zashs LuaSec branch
Kim Alvefur <zash@zash.se>
parents: 1630
diff changeset
   322
			local use = tlsa.use;
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   323
1348
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
   324
			if enabled_uses:contains(use) then
1948
1950fa6aa0c0 mod_s2s_auth_dane: Consider the current certificate chain status before checking PKIX-{EE,CA} TLSA records
Kim Alvefur <zash@zash.se>
parents: 1947
diff changeset
   325
				-- DANE-EE or PKIX-EE
1955
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   326
				if use == 3 or use == 1 then
1389
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   327
					-- Should we check if the cert subject matches?
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   328
					local is_match = one_dane_check(tlsa, cert, log);
1389
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   329
					if is_match ~= nil then
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   330
						supported_found = true;
1348
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
   331
					end
1955
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   332
					if is_match and use == 1 and session.cert_chain_status ~= "valid" then
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   333
						-- for usage 1, PKIX-EE, the chain has to be valid already
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   334
						log("debug", "PKIX-EE TLSA matches untrusted certificate");
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   335
						is_match = false;
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   336
					end
1389
6bd9681d54b7 mod_s2s_auth_dane: Break out DANE check into a function
Kim Alvefur <zash@zash.se>
parents: 1383
diff changeset
   337
					if is_match then
1437
161bbe0b9dd3 mod_s2s_auth_dane: Tweak log messages
Kim Alvefur <zash@zash.se>
parents: 1436
diff changeset
   338
						log("info", "DANE validated ok for %s using %s", host, tlsa:getUsage());
1348
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
   339
						session.cert_identity_status = "valid";
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
   340
						if use == 3 then -- DANE-EE, chain status equals DNSSEC chain status
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
   341
							session.cert_chain_status = "valid";
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
   342
						end
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
   343
						match_found = true;
1966
2f32196586bb mod_s2s_auth_dane: Keep DANE response around after the connection is established to aid in debugging
Kim Alvefur <zash@zash.se>
parents: 1965
diff changeset
   344
						dane.matching = tlsa;
1348
6191613959dc mod_s2s_auth_dane: Make supported DANE usages configurable, default to DANE-EE
Kim Alvefur <zash@zash.se>
parents: 1347
diff changeset
   345
						break;
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   346
					end
1948
1950fa6aa0c0 mod_s2s_auth_dane: Consider the current certificate chain status before checking PKIX-{EE,CA} TLSA records
Kim Alvefur <zash@zash.se>
parents: 1947
diff changeset
   347
				-- DANE-TA or PKIX-CA
1955
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   348
				elseif use == 2 or use == 0 then
1396
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   349
					supported_found = true;
1646
a4a6b4be973a mod_s2s_auth_dane: Update for recent changes in Zashs LuaSec branch
Kim Alvefur <zash@zash.se>
parents: 1630
diff changeset
   350
					local chain = session.conn:socket():getpeerchain();
1656
9a3d2f1479a4 mod_s2s_auth_dane: Cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 1646
diff changeset
   351
					for c = 1, #chain do
9a3d2f1479a4 mod_s2s_auth_dane: Cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 1646
diff changeset
   352
						local cacert = chain[c];
1974
5ea6f4e6fa8c mod_s2s_auth_dane: Log as much as possible through session logger instance
Kim Alvefur <zash@zash.se>
parents: 1967
diff changeset
   353
						local is_match = one_dane_check(tlsa, cacert, log);
1396
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   354
						if is_match ~= nil then
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   355
							supported_found = true;
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   356
						end
1955
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   357
						if is_match and not cacert:issued(cert, unpack(chain)) then
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   358
							is_match = false;
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   359
						end
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   360
						if is_match and use == 0 and session.cert_chain_status ~= "valid" then
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   361
							-- for usage 0, PKIX-CA, identity and chain has to be valid already
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   362
							is_match = false;
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   363
						end
7974a24d29b6 mod_s2s_auth_dane: Consider TLSA records with PKIX uses as supported (if enabled) even if the chain is invalid (if no match is found the session is considered insecure)
Kim Alvefur <zash@zash.se>
parents: 1948
diff changeset
   364
						if is_match then
1437
161bbe0b9dd3 mod_s2s_auth_dane: Tweak log messages
Kim Alvefur <zash@zash.se>
parents: 1436
diff changeset
   365
							log("info", "DANE validated ok for %s using %s", host, tlsa:getUsage());
1396
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   366
							if use == 2 then -- DANE-TA
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   367
								session.cert_identity_status = "valid";
1761
d011b87b7f58 mod_s2s_auth_dane: Validate names of DANE-TA certs
Kim Alvefur <zash@zash.se>
parents: 1705
diff changeset
   368
								if cert_verify_identity(host, "xmpp-server", cert) then
d011b87b7f58 mod_s2s_auth_dane: Validate names of DANE-TA certs
Kim Alvefur <zash@zash.se>
parents: 1705
diff changeset
   369
									session.cert_chain_status = "valid";
d011b87b7f58 mod_s2s_auth_dane: Validate names of DANE-TA certs
Kim Alvefur <zash@zash.se>
parents: 1705
diff changeset
   370
									-- else -- TODO Check against SRV target?
d011b87b7f58 mod_s2s_auth_dane: Validate names of DANE-TA certs
Kim Alvefur <zash@zash.se>
parents: 1705
diff changeset
   371
								end
1396
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   372
							end
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   373
							match_found = true;
1966
2f32196586bb mod_s2s_auth_dane: Keep DANE response around after the connection is established to aid in debugging
Kim Alvefur <zash@zash.se>
parents: 1965
diff changeset
   374
							dane.matching = tlsa;
1396
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   375
							break;
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   376
						end
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   377
					end
cf4e39334ef7 mod_s2s_auth_dane: Add support for DANE-TA and PKIX-CA (requires LuaSec changes)
Kim Alvefur <zash@zash.se>
parents: 1395
diff changeset
   378
					if match_found then break end
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   379
				end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   380
			end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   381
		end
1347
52b419885f0a mod_s2s_auth_dane: Simplify, but diverge from DANE-SRV draft. Will now look for _xmpp-server.example.com IN TLSA for both directions
Kim Alvefur <zash@zash.se>
parents: 1344
diff changeset
   382
		if supported_found and not match_found or dane.bogus then
1332
08a0241f5d2c mod_s2s_auth_dane: Add some comments
Kim Alvefur <zash@zash.se>
parents: 1330
diff changeset
   383
			-- No TLSA matched or response was bogus
1436
3944e364ba88 mod_s2s_auth_dane: Add some more info to log messages
Kim Alvefur <zash@zash.se>
parents: 1435
diff changeset
   384
			local why = "No TLSA matched certificate";
3944e364ba88 mod_s2s_auth_dane: Add some more info to log messages
Kim Alvefur <zash@zash.se>
parents: 1435
diff changeset
   385
			if dane.bogus then
3944e364ba88 mod_s2s_auth_dane: Add some more info to log messages
Kim Alvefur <zash@zash.se>
parents: 1435
diff changeset
   386
				why = "Bogus: "..tostring(dane.bogus);
3944e364ba88 mod_s2s_auth_dane: Add some more info to log messages
Kim Alvefur <zash@zash.se>
parents: 1435
diff changeset
   387
			end
1507
6ea13869753f mod_s2s_auth_dane: Include hostname when logging a failure
Kim Alvefur <zash@zash.se>
parents: 1506
diff changeset
   388
			log("warn", "DANE validation failed for %s: %s", host, why);
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
   389
			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
   390
			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
   391
		end
1370
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   392
	else
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   393
		if session.cert_chain_status == "valid" and session.cert_identity_status ~= "valid"
1411
8626abe100e2 mod_s2s_auth_dane: Fix traceback if session.srv_hosts is nil
Kim Alvefur <zash@zash.se>
parents: 1410
diff changeset
   394
		and session.srv_hosts and session.srv_hosts.answer and session.srv_hosts.answer.secure then
1370
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   395
			local srv_hosts, srv_choice, srv_target = session.srv_hosts, session.srv_choice;
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   396
			for i = srv_choice or 1, srv_choice or #srv_hosts do
1415
8791fa8a18c8 mod_s2s_auth_dane: Fix potential traceback in logging if SRV target fails nameprep
Kim Alvefur <zash@zash.se>
parents: 1414
diff changeset
   397
				srv_target = session.srv_hosts[i].target:gsub("%.?$","");
1431
33a796b2cb91 mod_s2s_auth_dane: Cache logger to save some table lookups and improve readability
Kim Alvefur <zash@zash.se>
parents: 1415
diff changeset
   398
				log("debug", "Comparing certificate with Secure SRV target %s", srv_target);
1506
a40f9b8661d8 mod_s2s_auth_dane: Fix stringprepping when doing "DANE Light"
Kim Alvefur <zash@zash.se>
parents: 1502
diff changeset
   399
				srv_target = nameprep(idna_to_unicode(srv_target));
1370
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   400
				if srv_target and cert_verify_identity(srv_target, "xmpp-server", cert) then
1437
161bbe0b9dd3 mod_s2s_auth_dane: Tweak log messages
Kim Alvefur <zash@zash.se>
parents: 1436
diff changeset
   401
					log("info", "Certificate for %s matches Secure SRV target %s", host, srv_target);
1370
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   402
					session.cert_identity_status = "valid";
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   403
					return;
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   404
				end
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   405
			end
e3fe6c749bc3 mod_s2s_auth_dane: Merge functionality from mod_s2s_auth_dnssec_srv
Kim Alvefur <zash@zash.se>
parents: 1368
diff changeset
   406
		end
1258
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   407
	end
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   408
end);
fc82d8eded7d mod_s2s_auth_dane: Experimental DANE implementation
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   409
1967
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   410
-- Telnet command
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   411
if module:get_option_set("modules_enabled", {}):contains("admin_telnet") then
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   412
	module:depends("admin_telnet"); -- Make sure the env is there
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   413
	local def_env = module:shared("admin_telnet/env");
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   414
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   415
	local function annotate(session, line)
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   416
		line = line or {};
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   417
		table.insert(line, "--");
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   418
		if session.dane == nil then
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   419
			table.insert(line, "No DANE attempted, probably insecure SRV response");
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   420
		elseif session.dane == false then
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   421
			table.insert(line, "DANE failed or response was insecure");
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   422
		elseif type(session.dane) ~= "table" then
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   423
			table.insert(line, "Waiting for DANE records...");
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   424
		elseif session.dane.matching then
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   425
			table.insert(line, "Matching DANE record:\n|       " .. tostring(session.dane.matching));
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   426
		else
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   427
			table.insert(line, "DANE records:\n|       " .. tostring(session.dane));
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   428
		end
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   429
		return table.concat(line, " ");
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   430
	end
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   431
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   432
	function def_env.s2s:show_dane(...)
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   433
		return self:show(..., annotate);
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   434
	end
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   435
end
98d757dc0771 mod_s2s_auth_dane: Add a telnet console command that exposes DANE information
Kim Alvefur <zash@zash.se>
parents: 1966
diff changeset
   436