mod_isolate_host/mod_isolate_host.lua
author Nicholas George <wirlaburla@worlio.com>
Tue, 21 May 2024 01:09:12 -0500
changeset 5915 e7584fd5b191
parent 5793 25e20fa3824c
permissions -rw-r--r--
mod_muc_restrict_pm: fix table in README
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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";
5008
bc75fc9400ae mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents: 1796
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
5008
bc75fc9400ae mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents: 1796
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: 1796
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: 1796
diff changeset
    14
end
bc75fc9400ae mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents: 1796
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
5008
bc75fc9400ae mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents: 1796
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
5300
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    25
		if origin.type == "local" then
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
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: 5100
diff changeset
    27
			-- we need to check explicitly.
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
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: 5100
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: 5100
diff changeset
    30
				return;
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    31
			end
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
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
1796
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
5008
bc75fc9400ae mod_isolate_host: Switch to module:may() (back compatible via compat_roles)
Matthew Wild <mwild1@gmail.com>
parents: 1796
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: 1796
diff changeset
    46
5300
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    47
function is_jid_isolated(bare_jid)
5301
4bba2d27ffaf mod_isolate_host: potentially pedantic optimization
Jonas Schäfer <jonas@wielicki.name>
parents: 5300
diff changeset
    48
	if except_users:contains(bare_jid) or module:may("xmpp:federate", bare_jid) then
5300
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    49
		return false;
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    50
	else
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    51
		return true;
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    52
	end
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    53
end
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    54
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
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);
5300
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
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
5793
25e20fa3824c mod_isolate_host: Fix inverted logic in log message
Matthew Wild <mwild1@gmail.com>
parents: 5301
diff changeset
    61
	module:log("debug", "%s is %sisolated", session.full_jid or "[?]", session.no_host_isolation and "not " or "");
1011
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
5300
0f5657db1cfc mod_isolate_host: handle server-generated stanzas
Jonas Schäfer <jonas@wielicki.name>
parents: 5100
diff changeset
    64
module:hook("resource-bind", set_session_isolation_flag);