mod_muc_ban_ip/mod_muc_ban_ip.lua
author Matthew Wild <mwild1@gmail.com>
Fri, 23 Sep 2022 22:41:15 +0100
changeset 5058 62480053c87b
parent 5019 47d9f704d14b
permissions -rw-r--r--
mod_cloud_notify_encrypted: Additional debug logging when enabling/skipping
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
module:set_global();
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
5019
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
     3
local jid_bare, jid_host = require "util.jid".bare, require "util.jid".host;
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local st = require "util.stanza";
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
local xmlns_muc_user = "http://jabber.org/protocol/muc#user";
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
5019
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
     7
local trusted_services = module:get_option_inherited_set("muc_ban_ip_trusted_services", {});
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
     8
local trust_local_restricted_services = module:get_option_boolean("muc_ban_ip_trust_local_restricted_services", true);
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
     9
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
local ip_bans = module:shared("bans");
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
local full_sessions = prosody.full_sessions;
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
5019
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    13
local function is_local_restricted_service(host)
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    14
	local muc_service = prosody.hosts[host] and prosody.hosts[host].modules.muc;
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    15
	if muc_service and module:context(host):get_option("restrict_room_creation") ~= nil then -- COMPAT: May need updating post-0.12
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    16
		return true;
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    17
	end
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    18
	return false;
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    19
end
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    20
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
local function ban_ip(session, from)
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
	local ip = session.ip;
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
	if not ip then
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
		module:log("warn", "Failed to ban IP (IP unknown) for %s", session.full_jid);
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
		return;
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
	end
5019
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    27
	local from_host = jid_host(from);
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    28
	if trusted_services:contains(from_host) or (trust_local_restricted_services and is_local_restricted_service(from_host)) then
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    29
		from = from_host; -- Ban from entire host
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    30
	end
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
	local banned_from = ip_bans[ip];
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
	if not banned_from then
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
		banned_from = {};
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
		ip_bans[ip] = banned_from;
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
	end
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	banned_from[from] = true;
3407
823027110e29 mod_muc_ban_ip: Improve logging to use session, and log when a ban is enforced
Matthew Wild <mwild1@gmail.com>
parents: 1655
diff changeset
    37
	module:log("debug", "Added ban for IP address %s from %s", ip, from);
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
end
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
1655
933403ee07ec mod_muc_ban_ip: Cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 1651
diff changeset
    40
local function check_for_incoming_ban(event)
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
	local stanza = event.stanza;
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
	local to_session = full_sessions[stanza.attr.to];
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
	if to_session then
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
		local directed = to_session.directed;
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
		local from = stanza.attr.from;
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
		if directed and directed[from] and stanza.attr.type == "unavailable" then
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
			-- This is a stanza from somewhere we sent directed presence to (may be a MUC)
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
			local x = stanza:get_child("x", xmlns_muc_user);
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
			if x then
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
				for status in x:childtags("status") do
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
					if status.attr.code == '301' then
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
						ban_ip(to_session, jid_bare(from));
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
					end
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
				end
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
			end
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
		end
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
	end
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
end
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
1655
933403ee07ec mod_muc_ban_ip: Cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 1651
diff changeset
    60
local function check_for_ban(event)
3407
823027110e29 mod_muc_ban_ip: Improve logging to use session, and log when a ban is enforced
Matthew Wild <mwild1@gmail.com>
parents: 1655
diff changeset
    61
	local origin, stanza = event.origin, event.stanza;
823027110e29 mod_muc_ban_ip: Improve logging to use session, and log when a ban is enforced
Matthew Wild <mwild1@gmail.com>
parents: 1655
diff changeset
    62
	local ip = origin.ip;
5019
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    63
	local to, to_host = jid_bare(stanza.attr.to), jid_host(stanza.attr.to);
47d9f704d14b mod_muc_ban_ip: Support for service-wide IP bans from trusted services
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
    64
	if ip_bans[ip] and (ip_bans[ip][to] or ip_bans[ip][to_host]) then
3999
4c9805f29f2d mod_muc_ban_ip: log fallback to module
Georg Lukas <georg@op-co.de>
parents: 3407
diff changeset
    65
		(origin.log or module._log)("debug", "IP banned: %s is banned from %s", ip, to)
4327
a7a06c8cea37 mod_muc_ban_ip: Lua is not C, fix typo
Georg Lukas <georg@op-co.de>
parents: 4325
diff changeset
    66
		if stanza.attr.type ~= "error" then
4325
71498f484c22 mod_muc_ban_ip: do not error() on banned user sending error to MUC
Georg Lukas <georg@op-co.de>
parents: 3999
diff changeset
    67
			origin.send(st.error_reply(stanza, "auth", "forbidden")
71498f484c22 mod_muc_ban_ip: do not error() on banned user sending error to MUC
Georg Lukas <georg@op-co.de>
parents: 3999
diff changeset
    68
				:tag("x", { xmlns = xmlns_muc_user })
71498f484c22 mod_muc_ban_ip: do not error() on banned user sending error to MUC
Georg Lukas <georg@op-co.de>
parents: 3999
diff changeset
    69
					:tag("status", { code = '301' }));
71498f484c22 mod_muc_ban_ip: do not error() on banned user sending error to MUC
Georg Lukas <georg@op-co.de>
parents: 3999
diff changeset
    70
		end
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
		return true;
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
	end
3999
4c9805f29f2d mod_muc_ban_ip: log fallback to module
Georg Lukas <georg@op-co.de>
parents: 3407
diff changeset
    73
	(origin.log or module._log)("debug", "IP not banned: %s from %s", ip, to)
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
end
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
function module.add_host(module)
1651
8860405e2af6 mod_muc_ban_ip: Increase priority of hooks, fixes if eg mod_presence gets called first
Kim Alvefur <zash@zash.se>
parents: 1005
diff changeset
    77
	module:hook("presence/full", check_for_incoming_ban, 100);
8860405e2af6 mod_muc_ban_ip: Increase priority of hooks, fixes if eg mod_presence gets called first
Kim Alvefur <zash@zash.se>
parents: 1005
diff changeset
    78
	module:hook("pre-presence/full", check_for_ban, 100);
1005
591590de34ef mod_muc_ban_ip: When a user is banned from a MUC, ban their IP from the MUC also (works for remote rooms too)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
end