Annotate

mod_s2s_auth_posh/mod_s2s_auth_posh.lua @ 3200:d070a751b6ed

mod_s2s_auth_posh: Cache tweak
author Kim Alvefur <zash@zash.se>
date Thu, 21 Dec 2017 03:04:51 +0100
parent 3199:cb7c24305ed2
child 3201:73be17be7d84
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 -- Copyright (C) 2013 - 2014 Tobias Markmann
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2 -- This file is MIT/X11 licensed.
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 --
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4 -- Implements authentication via POSH (PKIX over Secure HTTP)
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
5 -- http://tools.ietf.org/html/draft-miller-posh-03
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
6 --
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
7 module:set_global();
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
8 --local https = require 'ssl.https'
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9 --local http = require "socket.http";
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
10 local json = require 'util.json'
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 local base64 = require"util.encodings".base64;
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
13 local pem2der = require "util.x509".pem2der;
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
14 local hashes = require"util.hashes";
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
15 local build_url = require"socket.url".build;
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
16 local async = require "util.async";
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
17 local http = require"net.http";
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
18
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
19 local cache = require "util.cache".new(100);
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
20
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
21 local hash_order = { "sha-512", "sha-384", "sha-256", "sha-224", "sha-1" };
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
22 local hash_funcs = { hashes.sha512, hashes.sha384, hashes.sha256, hashes.sha224, hashes.sha1 };
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24 local function posh_lookup(host_session, resume)
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 -- do nothing if posh info already exists
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26 if host_session.posh ~= nil then return end
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 local target_host = false;
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 if host_session.direction == "incoming" then
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 target_host = host_session.from_host;
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 elseif host_session.direction == "outgoing" then
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32 target_host = host_session.to_host;
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33 end
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
35 local cached = cache:get(target_host);
3200
d070a751b6ed mod_s2s_auth_posh: Cache tweak
Kim Alvefur <zash@zash.se>
parents: 3199
diff changeset
36 if cached then
d070a751b6ed mod_s2s_auth_posh: Cache tweak
Kim Alvefur <zash@zash.se>
parents: 3199
diff changeset
37 if os.time() > cached.expires then
d070a751b6ed mod_s2s_auth_posh: Cache tweak
Kim Alvefur <zash@zash.se>
parents: 3199
diff changeset
38 cache:set(target_host, nil);
d070a751b6ed mod_s2s_auth_posh: Cache tweak
Kim Alvefur <zash@zash.se>
parents: 3199
diff changeset
39 else
d070a751b6ed mod_s2s_auth_posh: Cache tweak
Kim Alvefur <zash@zash.se>
parents: 3199
diff changeset
40 host_session.posh = { jwk = cached };
d070a751b6ed mod_s2s_auth_posh: Cache tweak
Kim Alvefur <zash@zash.se>
parents: 3199
diff changeset
41 return false;
d070a751b6ed mod_s2s_auth_posh: Cache tweak
Kim Alvefur <zash@zash.se>
parents: 3199
diff changeset
42 end
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
43 end
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
44 local log = host_session.log or module._log;
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
45
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
46 log("debug", "Session direction: %s", tostring(host_session.direction));
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
47
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
48 local url = build_url { scheme = "https", host = target_host, path = "/.well-known/posh/xmpp-server.json" };
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
50 log("debug", "Request POSH information for %s", tostring(target_host));
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
51 http.request(url, nil, function(response, code)
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
52 if code ~= 200 then
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
53 log("debug", "No or invalid POSH response received");
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
54 resume();
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
55 return;
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56 end
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
57 log("debug", "Received POSH response");
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
58 local jwk = json.decode(response);
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
59 if not jwk then
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
60 log("error", "POSH response is not valid JSON!\n%s", tostring(response));
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
61 resume();
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
62 return;
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
63 end
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
64 host_session.posh = { orig = response };
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
65 jwk.expires = os.time() + tonumber(jwk.expires) or 3600;
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
66 host_session.posh.jwk = jwk;
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
67 cache:set(target_host, jwk);
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
68 resume();
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
69 end)
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
70 return true;
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
71 end
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
72
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
73 -- Do POSH authentication
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74 module:hook("s2s-check-certificate", function(event)
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75 local session, cert = event.session, event.cert;
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
76 local log = session.log or module._log;
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
77 log("info", "Trying POSH authentication.");
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
78 -- if session.cert_identity_status ~= "valid" and session.posh then
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
79 local wait, done = async.waiter();
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
80 if posh_lookup(session, done) then
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
81 wait();
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
82 end
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
83 local posh = session.posh;
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
84 local jwk = posh and posh.jwk;
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
85 local fingerprints = jwk and jwk.fingerprints;
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
87 local cert_der = pem2der(cert:pem());
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
88 local cert_hashes = {};
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
89 for i = 1, #hash_order do
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
90 cert_hashes[i] = base64.encode(hash_funcs[i](cert_der));
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
91 end
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
92 for i = 1, #fingerprints do
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
93 local fp = fingerprints[i];
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
94 for j = 1, #hash_order do
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
95 local hash = fp[hash_order[j]];
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
96 if cert_hashes[j] == hash then
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
97 session.cert_chain_status = "valid";
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
98 session.cert_identity_status = "valid";
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
99 log("debug", "POSH authentication succeeded!");
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
100 return true;
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
101 elseif hash then
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
102 -- Don't try weaker hashes
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
103 break;
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
104 end
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
105 end
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
106 end
3199
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
107
cb7c24305ed2 mod_s2s_auth_posh: Changes done outside of version control during 2014-2017
Kim Alvefur <zash@zash.se>
parents: 3198
diff changeset
108 log("debug", "POSH authentication failed!");
3198
f3e452b43cfe mod_s2s_auth_posh: PKIX over Secure HTTP
Kim Alvefur <zash@zash.se>
parents:
diff changeset
109 end);