Software /
code /
prosody-modules
Annotate
mod_isolate_host/mod_isolate_host.lua @ 5296:0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
The hook for setting the no_host_isolation is only called for c2s
sessions. This does not work for stanzas generated by the server,
such as PEP notifications or presence probe answers.
To handle that, we do per-stanza checks for the case that the origin
is local.
author | Jonas Schäfer <jonas@wielicki.name> |
---|---|
date | Sat, 01 Apr 2023 12:03:08 +0200 |
parent | 5096:16db0a6e868c |
child | 5297:4bba2d27ffaf |
rev | line source |
---|---|
1011
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 local jid = require "util.jid"; |
5004
bc75fc9400ae
mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents:
1792
diff
changeset
|
2 local jid_bare, jid_host = jid.bare, jid.host; |
1011
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 local set = require "util.set"; |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 local st = require "util.stanza"; |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 local stanza_types = set.new{"message", "presence", "iq"}; |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 local jid_types = set.new{"bare", "full", "host"}; |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 local except_domains = module:get_option_inherited_set("isolate_except_domains", {}); |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 local except_users = module:get_option_inherited_set("isolate_except_users", {}); |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 |
5004
bc75fc9400ae
mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents:
1792
diff
changeset
|
12 if not module.may then |
bc75fc9400ae
mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents:
1792
diff
changeset
|
13 module:depends("compat_roles"); |
bc75fc9400ae
mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents:
1792
diff
changeset
|
14 end |
bc75fc9400ae
mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents:
1792
diff
changeset
|
15 |
1011
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 function check_stanza(event) |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 local origin, stanza = event.origin, event.stanza; |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 if origin.no_host_isolation then return; end |
5004
bc75fc9400ae
mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents:
1792
diff
changeset
|
19 local to_host = jid_host(event.stanza.attr.to); |
1011
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 if to_host and to_host ~= origin.host and not except_domains:contains(to_host) then |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 if to_host:match("^[^.]+%.(.+)$") == origin.host then -- Permit subdomains |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 except_domains:add(to_host); |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 return; |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 end |
5296
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
25 if origin.type == "local" then |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
26 -- this is code-generated, which means that set_session_isolation_flag has never triggered. |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
27 -- we need to check explicitly. |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
28 if not is_jid_isolated(jid_bare(event.stanza.attr.from)) then |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
29 module:log("debug", "server-generated stanza from %s is allowed, as the jid is not isolated", event.stanza.attr.from); |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
30 return; |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
31 end |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
32 end |
1011
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 module:log("warn", "Forbidding stanza from %s to %s", stanza.attr.from or origin.full_jid, stanza.attr.to); |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 origin.send(st.error_reply(stanza, "auth", "forbidden", "Communication with "..to_host.." is not available")); |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 return true; |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 end |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 end |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 for stanza_type in stanza_types do |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 for jid_type in jid_types do |
1792
8e19b943c2cd
mod_isolate_host: Bump event hook priorities to make sure they are above the core plugins
Kim Alvefur <zash@zash.se>
parents:
1011
diff
changeset
|
41 module:hook("pre-"..stanza_type.."/"..jid_type, check_stanza, 1); |
1011
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 end |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 end |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 |
5004
bc75fc9400ae
mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents:
1792
diff
changeset
|
45 module:default_permission("prosody:admin", "xmpp:federate"); |
bc75fc9400ae
mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents:
1792
diff
changeset
|
46 |
5296
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
47 function is_jid_isolated(bare_jid) |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
48 if module:may("xmpp:federate", bare_jid) or except_users:contains(bare_jid) then |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
49 return false; |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
50 else |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
51 return true; |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
52 end |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
53 end |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
54 |
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
55 function set_session_isolation_flag(event) |
1011
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 local session = event.session; |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 local bare_jid = jid_bare(session.full_jid); |
5296
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
58 if not is_jid_isolated(bare_jid) then |
1011
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 session.no_host_isolation = true; |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 end |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 module:log("debug", "%s is %sisolated", session.full_jid or "[?]", session.no_host_isolation and "" or "not "); |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 end |
9466efd10af9
mod_isolate_host: Prevent communication between hosts, even internal ones
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 |
5296
0f5657db1cfc
mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents:
5096
diff
changeset
|
64 module:hook("resource-bind", set_session_isolation_flag); |