Software / code / prosody
Annotate
util/session.lua @ 13801:a5d5fefb8b68 13.0
mod_tls: Enable Prosody's certificate checking for incoming s2s connections (fixes #1916) (thanks Damian, Zash)
Various options in Prosody allow control over the behaviour of the certificate
verification process For example, some deployments choose to allow falling
back to traditional "dialback" authentication (XEP-0220), while others verify
via DANE, hard-coded fingerprints, or other custom plugins.
Implementing this flexibility requires us to override OpenSSL's default
certificate verification, to allow Prosody to verify the certificate itself,
apply custom policies and make decisions based on the outcome.
To enable our custom logic, we have to suppress OpenSSL's default behaviour of
aborting the connection with a TLS alert message. With LuaSec, this can be
achieved by using the verifyext "lsec_continue" flag.
We also need to use the lsec_ignore_purpose flag, because XMPP s2s uses server
certificates as "client" certificates (for mutual TLS verification in outgoing
s2s connections).
Commit 99d2100d2918 moved these settings out of the defaults and into mod_s2s,
because we only really need these changes for s2s, and they should be opt-in,
rather than automatically applied to all TLS services we offer.
That commit was incomplete, because it only added the flags for incoming
direct TLS connections. StartTLS connections are handled by mod_tls, which was
not applying the lsec_* flags. It previously worked because they were already
in the defaults.
This resulted in incoming s2s connections with "invalid" certificates being
aborted early by OpenSSL, even if settings such as `s2s_secure_auth = false`
or DANE were present in the config.
Outgoing s2s connections inherit verify "none" from the defaults, which means
OpenSSL will receive the cert but will not terminate the connection when it is
deemed invalid. This means we don't need lsec_continue there, and we also
don't need lsec_ignore_purpose (because the remote peer is a "server").
Wondering why we can't just use verify "none" for incoming s2s? It's because
in that mode, OpenSSL won't request a certificate from the peer for incoming
connections. Setting verify "peer" is how you ask OpenSSL to request a
certificate from the client, but also what triggers its built-in verification.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 01 Apr 2025 17:26:56 +0100 |
| parent | 13165:9c13c11b199d |
| rev | line source |
|---|---|
|
12975
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12640
diff
changeset
|
1 local initialize_filters = require "prosody.util.filters".initialize; |
|
13165
9c13c11b199d
renamening: Fix newly added imports to use the new namespace
Kim Alvefur <zash@zash.se>
parents:
13007
diff
changeset
|
2 local time = require "prosody.util.time"; |
|
12975
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12640
diff
changeset
|
3 local logger = require "prosody.util.logger"; |
| 6937 | 4 |
| 5 local function new_session(typ) | |
| 6 local session = { | |
| 7 type = typ .. "_unauthed"; | |
|
9947
8ebca1240203
util.session: Fix session id not include unauthed forever
Kim Alvefur <zash@zash.se>
parents:
7181
diff
changeset
|
8 base_type = typ; |
|
13007
534c055ec378
util.session: Add 'since' property with timestamp of session creation
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
9 since = time.now(); |
| 6937 | 10 }; |
| 11 return session; | |
| 12 end | |
| 13 | |
|
6938
9df70e9e006b
util.session: What is the identity of a session?
Kim Alvefur <zash@zash.se>
parents:
6937
diff
changeset
|
14 local function set_id(session) |
|
9947
8ebca1240203
util.session: Fix session id not include unauthed forever
Kim Alvefur <zash@zash.se>
parents:
7181
diff
changeset
|
15 local id = session.base_type .. tostring(session):match("%x+$"):lower(); |
|
6938
9df70e9e006b
util.session: What is the identity of a session?
Kim Alvefur <zash@zash.se>
parents:
6937
diff
changeset
|
16 session.id = id; |
|
9df70e9e006b
util.session: What is the identity of a session?
Kim Alvefur <zash@zash.se>
parents:
6937
diff
changeset
|
17 return session; |
|
9df70e9e006b
util.session: What is the identity of a session?
Kim Alvefur <zash@zash.se>
parents:
6937
diff
changeset
|
18 end |
|
9df70e9e006b
util.session: What is the identity of a session?
Kim Alvefur <zash@zash.se>
parents:
6937
diff
changeset
|
19 |
|
6939
a9ae0c6ac4f4
util.session: What does the session say?
Kim Alvefur <zash@zash.se>
parents:
6938
diff
changeset
|
20 local function set_logger(session) |
|
7181
8af558965da3
util.session: Fix luacheck warnings
Kim Alvefur <zash@zash.se>
parents:
6941
diff
changeset
|
21 local log = logger.init(session.id); |
|
6939
a9ae0c6ac4f4
util.session: What does the session say?
Kim Alvefur <zash@zash.se>
parents:
6938
diff
changeset
|
22 session.log = log; |
|
a9ae0c6ac4f4
util.session: What does the session say?
Kim Alvefur <zash@zash.se>
parents:
6938
diff
changeset
|
23 return session; |
|
a9ae0c6ac4f4
util.session: What does the session say?
Kim Alvefur <zash@zash.se>
parents:
6938
diff
changeset
|
24 end |
|
a9ae0c6ac4f4
util.session: What does the session say?
Kim Alvefur <zash@zash.se>
parents:
6938
diff
changeset
|
25 |
|
6940
2be5e19485aa
util.session: How does a session relate do a connection?
Kim Alvefur <zash@zash.se>
parents:
6939
diff
changeset
|
26 local function set_conn(session, conn) |
|
2be5e19485aa
util.session: How does a session relate do a connection?
Kim Alvefur <zash@zash.se>
parents:
6939
diff
changeset
|
27 session.conn = conn; |
|
2be5e19485aa
util.session: How does a session relate do a connection?
Kim Alvefur <zash@zash.se>
parents:
6939
diff
changeset
|
28 session.ip = conn:ip(); |
|
2be5e19485aa
util.session: How does a session relate do a connection?
Kim Alvefur <zash@zash.se>
parents:
6939
diff
changeset
|
29 return session; |
|
2be5e19485aa
util.session: How does a session relate do a connection?
Kim Alvefur <zash@zash.se>
parents:
6939
diff
changeset
|
30 end |
|
2be5e19485aa
util.session: How does a session relate do a connection?
Kim Alvefur <zash@zash.se>
parents:
6939
diff
changeset
|
31 |
|
6941
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
32 local function set_send(session) |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
33 local conn = session.conn; |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
34 if not conn then |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
35 function session.send(data) |
|
10110
3fa3872588a8
util.session: Remove tostring call from logging
Kim Alvefur <zash@zash.se>
parents:
9947
diff
changeset
|
36 session.log("debug", "Discarding data sent to unconnected session: %s", data); |
|
6941
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
37 return false; |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
38 end |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
39 return session; |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
40 end |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
41 local filter = initialize_filters(session); |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
42 local w = conn.write; |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
43 session.send = function (t) |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
44 if t.name then |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
45 t = filter("stanzas/out", t); |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
46 end |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
47 if t then |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
48 t = filter("bytes/out", tostring(t)); |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
49 if t then |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
50 local ret, err = w(conn, t); |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
51 if not ret then |
|
10110
3fa3872588a8
util.session: Remove tostring call from logging
Kim Alvefur <zash@zash.se>
parents:
9947
diff
changeset
|
52 session.log("debug", "Error writing to connection: %s", err); |
|
6941
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
53 return false, err; |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
54 end |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
55 end |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
56 end |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
57 return true; |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
58 end |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
59 return session; |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
60 end |
|
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
61 |
|
12640
999b1c59af6f
util.session: Add role management methods
Matthew Wild <mwild1@gmail.com>
parents:
10110
diff
changeset
|
62 local function set_role(session, role) |
|
999b1c59af6f
util.session: Add role management methods
Matthew Wild <mwild1@gmail.com>
parents:
10110
diff
changeset
|
63 session.role = role; |
|
999b1c59af6f
util.session: Add role management methods
Matthew Wild <mwild1@gmail.com>
parents:
10110
diff
changeset
|
64 end |
|
999b1c59af6f
util.session: Add role management methods
Matthew Wild <mwild1@gmail.com>
parents:
10110
diff
changeset
|
65 |
| 6937 | 66 return { |
| 67 new = new_session; | |
|
12640
999b1c59af6f
util.session: Add role management methods
Matthew Wild <mwild1@gmail.com>
parents:
10110
diff
changeset
|
68 |
|
6938
9df70e9e006b
util.session: What is the identity of a session?
Kim Alvefur <zash@zash.se>
parents:
6937
diff
changeset
|
69 set_id = set_id; |
|
6939
a9ae0c6ac4f4
util.session: What does the session say?
Kim Alvefur <zash@zash.se>
parents:
6938
diff
changeset
|
70 set_logger = set_logger; |
|
6940
2be5e19485aa
util.session: How does a session relate do a connection?
Kim Alvefur <zash@zash.se>
parents:
6939
diff
changeset
|
71 set_conn = set_conn; |
|
6941
33fbc835697d
util.session: How would you even send anything to a session?
Kim Alvefur <zash@zash.se>
parents:
6940
diff
changeset
|
72 set_send = set_send; |
|
12640
999b1c59af6f
util.session: Add role management methods
Matthew Wild <mwild1@gmail.com>
parents:
10110
diff
changeset
|
73 set_role = set_role; |
| 6937 | 74 } |