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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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);