Mercurial > prosody-modules
annotate mod_auth_ccert/mod_auth_ccert.lua @ 5593:6d0574bfbf5d
mod_client_management: Include software version in table (when known)
Showing software versions could be useful for statistical reasons, e.g.
determining how quickly (or not) users upgrade, but most importantly for
revoking vulnerable clients versions in case of a security issue.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 13 Jul 2023 23:26:02 +0200 |
parents | 86acfa44dc24 |
children |
rev | line source |
---|---|
1062
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
1 -- Copyright (C) 2013 Kim Alvefur |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
2 -- |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
3 -- This file is MIT/X11 licensed. |
3041
86acfa44dc24
mod_auth_ccert: Silence warning about unused global [luacheck]
Kim Alvefur <zash@zash.se>
parents:
1325
diff
changeset
|
4 -- |
86acfa44dc24
mod_auth_ccert: Silence warning about unused global [luacheck]
Kim Alvefur <zash@zash.se>
parents:
1325
diff
changeset
|
5 -- luacheck: ignore 131/get_sasl_handler |
1062
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
6 |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
7 local jid_compare = require "util.jid".compare; |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
8 local jid_split = require "util.jid".prepped_split; |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 local new_sasl = require "util.sasl".new; |
1069
d7719bf1aed6
mod_auth_ccert: Add missing OID for email
Kim Alvefur <zash@zash.se>
parents:
1068
diff
changeset
|
10 local now = os.time; |
1062
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
11 local log = module._log; |
1069
d7719bf1aed6
mod_auth_ccert: Add missing OID for email
Kim Alvefur <zash@zash.se>
parents:
1068
diff
changeset
|
12 |
1062
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
13 local subject_alternative_name = "2.5.29.17"; |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
14 local id_on_xmppAddr = "1.3.6.1.5.5.7.8.5"; |
1069
d7719bf1aed6
mod_auth_ccert: Add missing OID for email
Kim Alvefur <zash@zash.se>
parents:
1068
diff
changeset
|
15 local oid_emailAddress = "1.2.840.113549.1.9.1"; |
1062
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
16 |
1065
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
17 local cert_match = module:get_option("certificate_match", "xmppaddr"); |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
18 |
1068
8ad0d234608c
mod_auth_ccert: Pass the session username-outfigurer function too
Kim Alvefur <zash@zash.se>
parents:
1067
diff
changeset
|
19 local username_extractor = {}; |
1065
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
20 |
1068
8ad0d234608c
mod_auth_ccert: Pass the session username-outfigurer function too
Kim Alvefur <zash@zash.se>
parents:
1067
diff
changeset
|
21 function username_extractor.xmppaddr(cert, authz, session) |
1065
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
22 local extensions = cert:extensions(); |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
23 local SANs = extensions[subject_alternative_name]; |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
24 local xmppAddrs = SANs and SANs[id_on_xmppAddr]; |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
25 |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
26 if not xmppAddrs then |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
27 (session.log or log)("warn", "Client certificate contains no xmppAddrs"); |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
28 return nil, false; |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
29 end |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
30 |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
31 for i=1,#xmppAddrs do |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
32 if authz == "" or jid_compare(authz, xmppAddrs[i]) then |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
33 (session.log or log)("debug", "xmppAddrs[%d] %q matches authz %q", i, xmppAddrs[i], authz) |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
34 local username, host = jid_split(xmppAddrs[i]); |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
35 if host == module.host then |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
36 return username, true |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
37 end |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
38 end |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
39 end |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
40 end |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
41 |
1066
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
42 function username_extractor.email(cert) |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
43 local subject = cert:subject(); |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
44 for i=1,#subject do |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
45 local ava = subject[i]; |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
46 if ava.oid == oid_emailAddress then |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
47 local username, host = jid_split(ava.value); |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
48 if host == module.host then |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
49 return username, true |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
50 end |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
51 end |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
52 end |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
53 end |
83175a6af8c5
mod_auth_ccert: Add optional method for certificates which contain an email address
Kim Alvefur <zash@zash.se>
parents:
1065
diff
changeset
|
54 |
1065
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
55 local find_username = username_extractor[cert_match]; |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
56 if not find_username then |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
57 module:log("error", "certificate_match = %q is not supported"); |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
58 return |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
59 end |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
60 |
3d04d9377a67
mod_auth_ccert: Prepare for supporting more ways to figure out the username
Kim Alvefur <zash@zash.se>
parents:
1063
diff
changeset
|
61 |
1062
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
62 function get_sasl_handler(session) |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
63 return new_sasl(module.host, { |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
64 external = session.secure and function(authz) |
1325
b21236b6b8d8
Backed out changeset 853a382c9bd6
Kim Alvefur <zash@zash.se>
parents:
1324
diff
changeset
|
65 if not session.secure then |
1062
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
66 -- getpeercertificate() on a TCP connection would be bad, abort! |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
67 (session.log or log)("error", "How did you manage to select EXTERNAL without TLS?"); |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
68 return nil, false; |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
69 end |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
70 local sock = session.conn:socket(); |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
71 local cert = sock:getpeercertificate(); |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
72 if not cert then |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
73 (session.log or log)("warn", "No certificate provided"); |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
74 return nil, false; |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
75 end |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
76 |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
77 if not cert:validat(now()) then |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
78 (session.log or log)("warn", "Client certificate expired") |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
79 return nil, "expired"; |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
80 end |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
81 |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
82 local chain_valid, chain_errors = sock:getpeerverification(); |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
83 if not chain_valid then |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
84 (session.log or log)("warn", "Invalid client certificate chain"); |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
85 for i, error in ipairs(chain_errors) do |
1092
f46307e8e2f8
mod_auth_ccert: Use value from ipairs
Kim Alvefur <zash@zash.se>
parents:
1070
diff
changeset
|
86 (session.log or log)("warn", "%d: %s", i, table.concat(error, ", ")); |
1062
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
87 end |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
88 return nil, false; |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
89 end |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
90 |
1068
8ad0d234608c
mod_auth_ccert: Pass the session username-outfigurer function too
Kim Alvefur <zash@zash.se>
parents:
1067
diff
changeset
|
91 return find_username(cert, authz, session); |
1062
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
92 end |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
93 }); |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
94 end |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
95 |
f853a1a3aa15
mod_auth_ccert: Initial commit of authentication module for using CA-issued client certificates
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
96 module:provides "auth"; |