mod_client_certs/mod_client_certs.lua
author Thijs Alkemade <thijsalkemade@gmail.com>
Sat, 09 Jun 2012 23:15:44 +0200
changeset 709 151743149f07
parent 698 3a3293f37139
child 712 227d48f927ff
permissions -rw-r--r--
mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
     1
-- XEP-0257: Client Certificates Management implementation for Prosody
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
     2
-- Copyright (C) 2012 Thijs Alkemade
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
     3
--
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
     4
-- This file is MIT/X11 licensed.
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
     5
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
     6
local st = require "util.stanza";
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
     7
local jid_bare = require "util.jid".bare;
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
     8
local jid_split = require "util.jid".split;
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
     9
local xmlns_saslcert = "urn:xmpp:saslcert:0";
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    10
local xmlns_pubkey = "urn:xmpp:tmp:pubkey";
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    11
local dm_load = require "util.datamanager".load;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    12
local dm_store = require "util.datamanager".store;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    13
local dm_table = "client_certs";
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    14
local x509 = require "ssl.x509";
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    15
local id_on_xmppAddr = "1.3.6.1.5.5.7.8.5";
698
3a3293f37139 mod_client_certs: Fix the checking of valid id_on_xmppAddr fields.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 697
diff changeset
    16
local id_ce_subjectAltName = "2.5.29.17";
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    17
local digest_algo = "sha1";
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    18
local base64 = require "util.encodings".base64;
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    19
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    20
local function enable_cert(username, cert, info)
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    21
	local certs = dm_load(username, module.host, dm_table) or {};
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    22
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    23
	info.pem = cert:pem();
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    24
	local digest = cert:digest(digest_algo);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    25
	info.digest = digest;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    26
	certs[info.id] = info;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    27
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    28
	dm_store(username, module.host, dm_table, certs);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    29
	return true
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    30
end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    31
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    32
local function disable_cert(username, name)
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    33
	local certs = dm_load(username, module.host, dm_table) or {};
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    34
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    35
	local info = certs[name];
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    36
	local cert;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    37
	if info then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    38
		certs[name] = nil;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    39
		cert = x509.cert_from_pem(info.pem);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    40
	else
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    41
		return nil, "item-not-found"
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    42
	end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    43
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    44
	dm_store(username, module.host, dm_table, certs);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    45
	return cert; -- So we can compare it with stuff
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    46
end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    47
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    48
local function get_id_on_xmpp_addrs(cert)
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    49
	local id_on_xmppAddrs = {};
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    50
	for k,ext in pairs(cert:extensions()) do
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    51
		if k == id_ce_subjectAltName then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    52
			for e,extv in pairs(ext) do
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    53
				if e == id_on_xmppAddr then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    54
					for i,v in ipairs(extv) do
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    55
						id_on_xmppAddrs[#id_on_xmppAddrs+1] = v;
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    56
					end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    57
				end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    58
			end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    59
		end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    60
	end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    61
	module:log("debug", "Found JIDs: (%d) %s", #id_on_xmppAddrs, table.concat(id_on_xmppAddrs, ", "));
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    62
	return id_on_xmppAddrs;
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    63
end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    64
	
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
    65
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    66
module:hook("iq/self/"..xmlns_saslcert..":items", function(event)
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    67
	local origin, stanza = event.origin, event.stanza;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    68
	if stanza.attr.type == "get" then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    69
		module:log("debug", "%s requested items", origin.full_jid);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    70
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    71
		local reply = st.reply(stanza):tag("items", { xmlns = xmlns_saslcert });
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    72
		local certs = dm_load(origin.username, module.host, dm_table) or {};
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    73
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    74
		for digest,info in pairs(certs) do
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    75
			reply:tag("item", { id = info.id })
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    76
				:tag("name"):text(info.name):up()
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    77
				:tag("keyinfo", { xmlns = xmlns_pubkey }):tag("name"):text(info["key_name"]):up()
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    78
				:tag("x509cert"):text(info.x509cert)
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    79
			:up();
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    80
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    81
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    82
		origin.send(reply);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    83
		return true
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    84
	end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    85
end);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    86
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    87
module:hook("iq/self/"..xmlns_saslcert..":append", function(event)
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    88
	local origin, stanza = event.origin, event.stanza;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    89
	if stanza.attr.type == "set" then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    90
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    91
		local append = stanza:get_child("append", xmlns_saslcert);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    92
		local name = append:get_child_text("name", xmlns_saslcert);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    93
		local key_info = append:get_child("keyinfo", xmlns_pubkey);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    94
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    95
		if not key_info or not name then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    96
			origin.send(st.error_reply(stanza, "cancel", "bad-request", "Missing fields.")); -- cancel? not modify?
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    97
			return true
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    98
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
    99
		
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   100
		local id = key_info:get_child_text("name", xmlns_pubkey);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   101
		local x509cert = key_info:get_child_text("x509cert", xmlns_pubkey);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   102
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   103
		if not id or not x509cert then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   104
			origin.send(st.error_reply(stanza, "cancel", "bad-request", "No certificate found."));
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   105
			return true
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   106
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   107
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   108
		local can_manage = key_info:get_child("no-cert-management", xmlns_saslcert) ~= nil;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   109
		local x509cert = key_info:get_child_text("x509cert");
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   110
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   111
		local cert = x509.cert_from_pem(
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   112
		"-----BEGIN CERTIFICATE-----\n"
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   113
		.. x509cert ..
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   114
		"\n-----END CERTIFICATE-----\n");
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   115
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   116
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   117
		if not cert then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   118
			origin.send(st.error_reply(stanza, "modify", "not-acceptable", "Could not parse X.509 certificate"));
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   119
			return true;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   120
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   121
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   122
		-- Check the certificate. Is it not expired? Does it include id-on-xmppAddr?
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   123
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   124
		--[[ the method expired doesn't exist in luasec .. yet?
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   125
		if cert:expired() then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   126
			module:log("debug", "This certificate is already expired.");
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   127
			origin.send(st.error_reply(stanza, "cancel", "bad-request", "This certificate is expired."));
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   128
			return true
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   129
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   130
		--]]
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   131
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   132
		if not cert:valid_at(os.time()) then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   133
			module:log("debug", "This certificate is not valid at this moment.");
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   134
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   135
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   136
		local valid_id_on_xmppAddrs;
698
3a3293f37139 mod_client_certs: Fix the checking of valid id_on_xmppAddr fields.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 697
diff changeset
   137
		local require_id_on_xmppAddr = true;
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   138
		if require_id_on_xmppAddr then
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   139
			valid_id_on_xmppAddrs = get_id_on_xmpp_addrs(cert);
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   140
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   141
			local found = false;
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   142
			for i,k in pairs(valid_id_on_xmppAddrs) do
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   143
				if jid_bare(k) == jid_bare(origin.full_jid) then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   144
					found = true;
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   145
					break;
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   146
				end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   147
			end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   148
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   149
			if not found then
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   150
				origin.send(st.error_reply(stanza, "cancel", "bad-request", "This certificate is has no valid id-on-xmppAddr field."));
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   151
				return true -- REJECT?!
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   152
			end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   153
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   154
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   155
		enable_cert(origin.username, cert, {
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   156
			id = id,
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   157
			name = name,
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   158
			x509cert = x509cert,
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   159
			no_cert_management = can_manage,
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   160
		});
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   161
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   162
		module:log("debug", "%s added certificate named %s", origin.full_jid, name);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   163
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   164
		origin.send(st.reply(stanza));
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   165
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   166
		return true
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   167
	end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   168
end);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   169
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   170
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   171
local function handle_disable(event)
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   172
	local origin, stanza = event.origin, event.stanza;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   173
	if stanza.attr.type == "set" then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   174
		local disable = stanza.tags[1];
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   175
		module:log("debug", "%s disabled a certificate", origin.full_jid);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   176
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   177
		local item = disable:get_child("item");
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   178
		local name = item and item.attr.id;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   179
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   180
		if not name then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   181
			origin.send(st.error_reply(stanza, "cancel", "bad-request", "No key specified."));
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   182
			return true
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   183
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   184
698
3a3293f37139 mod_client_certs: Fix the checking of valid id_on_xmppAddr fields.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 697
diff changeset
   185
		local disabled_cert = disable_cert(origin.username, name);
697
c3337f62a538 mod_client_certs: Disconnect every session that was using that cert when revoking a client certificate.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 695
diff changeset
   186
698
3a3293f37139 mod_client_certs: Fix the checking of valid id_on_xmppAddr fields.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 697
diff changeset
   187
		if disabled_cert and disable.name == "revoke" then
697
c3337f62a538 mod_client_certs: Disconnect every session that was using that cert when revoking a client certificate.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 695
diff changeset
   188
			module:log("debug", "%s revoked a certificate! Disconnecting all clients that used it", origin.full_jid);
c3337f62a538 mod_client_certs: Disconnect every session that was using that cert when revoking a client certificate.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 695
diff changeset
   189
			local sessions = hosts[module.host].sessions[origin.username].sessions;
698
3a3293f37139 mod_client_certs: Fix the checking of valid id_on_xmppAddr fields.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 697
diff changeset
   190
			local disabled_cert_pem = disabled_cert:pem();
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   191
697
c3337f62a538 mod_client_certs: Disconnect every session that was using that cert when revoking a client certificate.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 695
diff changeset
   192
			for _, session in pairs(sessions) do
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   193
				if session and session.conn then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   194
					local cert = session.conn:socket():getpeercertificate();
697
c3337f62a538 mod_client_certs: Disconnect every session that was using that cert when revoking a client certificate.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 695
diff changeset
   195
				
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   196
					if cert and cert:pem() == disabled_cert_pem then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   197
						module:log("debug", "Found a session that should be closed: %s", tostring(session));
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   198
						session:close{ condition = "not-authorized", text = "This client side certificate has been revoked."};
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   199
					end
697
c3337f62a538 mod_client_certs: Disconnect every session that was using that cert when revoking a client certificate.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 695
diff changeset
   200
				end
c3337f62a538 mod_client_certs: Disconnect every session that was using that cert when revoking a client certificate.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 695
diff changeset
   201
			end
c3337f62a538 mod_client_certs: Disconnect every session that was using that cert when revoking a client certificate.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 695
diff changeset
   202
		end
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   203
		origin.send(st.reply(stanza));
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   204
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   205
		return true
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   206
	end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   207
end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   208
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   209
module:hook("iq/self/"..xmlns_saslcert..":disable", handle_disable);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   210
module:hook("iq/self/"..xmlns_saslcert..":revoke", handle_disable);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   211
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   212
-- Here comes the SASL EXTERNAL stuff
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   213
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   214
local now = os.time;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   215
module:hook("stream-features", function(event)
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   216
	local session, features = event.origin, event.features;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   217
	if session.secure and session.type == "c2s_unauthed" then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   218
		local cert = session.conn:socket():getpeercertificate();
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   219
		if not cert then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   220
			module:log("error", "No Client Certificate");
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   221
			return
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   222
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   223
		module:log("info", "Client Certificate: %s", cert:digest(digest_algo));
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   224
		if not cert:valid_at(now()) then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   225
			module:log("debug", "Client has an expired certificate", cert:digest(digest_algo));
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   226
			return
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   227
		end
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   228
		module:log("debug", "Stream features:\n%s", tostring(features));
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   229
		local mechs = features:get_child("mechanisms", "urn:ietf:params:xml:ns:xmpp-sasl");
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   230
		if mechs then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   231
			mechs:tag("mechanism"):text("EXTERNAL");
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   232
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   233
	end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   234
end, -1);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   235
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   236
local sm_make_authenticated = require "core.sessionmanager".make_authenticated;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   237
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   238
module:hook("stanza/urn:ietf:params:xml:ns:xmpp-sasl:auth", function(event)
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   239
	local session, stanza = event.origin, event.stanza;
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   240
	if session.type == "c2s_unauthed" and stanza.attr.mechanism == "EXTERNAL" then
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   241
		if session.secure then
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   242
			local cert = session.conn:socket():getpeercertificate();
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   243
			local username_data = stanza:get_text();
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   244
			local username = nil;
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   245
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   246
			if username_data == "=" then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   247
				-- Check for either an id_on_xmppAddr
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   248
				local jids = get_id_on_xmpp_addrs(cert);
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   249
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   250
				if not (#jids == 1) then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   251
					module:log("debug", "Client tried to authenticate as =, but certificate has multiple JIDs.");
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   252
					module:fire_event("authentication-failure", { session = session, condition = "not-authorized" });
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   253
					session.send(st.stanza("failure", { xmlns="urn:ietf:params:xml:ns:xmpp-sasl"}):tag"not-authorized");
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   254
					return true;
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   255
				end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   256
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   257
				username = jids[1];
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   258
			else
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   259
				-- Check the base64 encoded username
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   260
				username = base64.decode(username_data);
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   261
			end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   262
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   263
			local user, host, resource = jid_split(username);
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   264
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   265
			module:log("debug", "Inferred username: %s", user or "nil");
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   266
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   267
			if (not username) or (not host == module.host) then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   268
				module:log("debug", "No valid username found for %s", tostring(session));
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   269
				module:fire_event("authentication-failure", { session = session, condition = "not-authorized" });
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   270
				session.send(st.stanza("failure", { xmlns="urn:ietf:params:xml:ns:xmpp-sasl"}):tag"not-authorized");
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   271
				return true;
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   272
			end
709
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   273
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   274
			local certs = dm_load(user, module.host, dm_table) or {};
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   275
			local digest = cert:digest(digest_algo);
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   276
			local pem = cert:pem();
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   277
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   278
			for name,info in pairs(certs) do
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   279
				if info.digest == digest and info.pem == pem then
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   280
					sm_make_authenticated(session, user);
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   281
					module:fire_event("authentication-success", { session = session });
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   282
					session.send(st.stanza("success", { xmlns="urn:ietf:params:xml:ns:xmpp-sasl"}));
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   283
					session:reset_stream();
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   284
					return true;
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   285
				end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   286
			end
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   287
			module:fire_event("authentication-failure", { session = session, condition = "not-authorized" });
151743149f07 mod_client_certs: Follow the rules in XEP-0178 about the inclusion of the username when using EXTERNAL, instead of mapping one certificate to one user.
Thijs Alkemade <thijsalkemade@gmail.com>
parents: 698
diff changeset
   288
			session.send(st.stanza("failure", { xmlns="urn:ietf:params:xml:ns:xmpp-sasl"}):tag"not-authorized");
695
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   289
		else
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   290
			session.send(st.stanza("failure", { xmlns="urn:ietf:params:xml:ns:xmpp-sasl"}):tag"encryption-required");
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   291
		end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   292
		return true;
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   293
	end
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   294
end, 1);
f6be46f15b74 mod_client_certs: Checking in the latest version I have with Zash's changes.
Thijs Alkemade <thijsalkemade@gmail.com>
parents:
diff changeset
   295