aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_register_limits.lua
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2017-12-09 19:35:08 +0100
committerKim Alvefur <zash@zash.se>2017-12-09 19:35:08 +0100
commit818d4e73233d91011d1e35bc588206d85512517a (patch)
treec78e235c68681b7eeda2e003f7b3df33aab1cb0b /plugins/mod_register_limits.lua
parentd00ffdb2495a6ae9f61c9deacb6ad1bba3d9c7f5 (diff)
downloadprosody-818d4e73233d91011d1e35bc588206d85512517a.tar.gz
prosody-818d4e73233d91011d1e35bc588206d85512517a.zip
mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
Diffstat (limited to 'plugins/mod_register_limits.lua')
-rw-r--r--plugins/mod_register_limits.lua71
1 files changed, 71 insertions, 0 deletions
diff --git a/plugins/mod_register_limits.lua b/plugins/mod_register_limits.lua
new file mode 100644
index 00000000..1fb3c05e
--- /dev/null
+++ b/plugins/mod_register_limits.lua
@@ -0,0 +1,71 @@
+-- Prosody IM
+-- Copyright (C) 2008-2010 Matthew Wild
+-- Copyright (C) 2008-2010 Waqas Hussain
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+
+local create_throttle = require "util.throttle".create;
+local new_cache = require "util.cache".new;
+local ip_util = require "util.ip";
+local new_ip = ip_util.new_ip;
+local match_ip = ip_util.match;
+local parse_cidr = ip_util.parse_cidr;
+
+local min_seconds_between_registrations = module:get_option_number("min_seconds_between_registrations");
+local whitelist_only = module:get_option_boolean("whitelist_registration_only");
+local whitelisted_ips = module:get_option_set("registration_whitelist", { "127.0.0.1", "::1" })._items;
+local blacklisted_ips = module:get_option_set("registration_blacklist", {})._items;
+
+local throttle_max = module:get_option_number("registration_throttle_max", min_seconds_between_registrations and 1);
+local throttle_period = module:get_option_number("registration_throttle_period", min_seconds_between_registrations);
+local throttle_cache_size = module:get_option_number("registration_throttle_cache_size", 100);
+local blacklist_overflow = module:get_option_boolean("blacklist_on_registration_throttle_overload", false);
+
+local throttle_cache = new_cache(throttle_cache_size, blacklist_overflow and function (ip, throttle)
+ if not throttle:peek() then
+ module:log("info", "Adding ip %s to registration blacklist", ip);
+ blacklisted_ips[ip] = true;
+ end
+end or nil);
+
+local function check_throttle(ip)
+ if not throttle_max then return true end
+ local throttle = throttle_cache:get(ip);
+ if not throttle then
+ throttle = create_throttle(throttle_max, throttle_period);
+ end
+ throttle_cache:set(ip, throttle);
+ return throttle:poll(1);
+end
+
+local function ip_in_set(set, ip)
+ if set[ip] then
+ return true;
+ end
+ ip = new_ip(ip);
+ for in_set in pairs(set) do
+ if match_ip(ip, parse_cidr(in_set)) then
+ return true;
+ end
+ end
+ return false;
+end
+
+module:hook("user-registering", function (event)
+ local session = event.session;
+ local ip = event.ip or session and session.ip;
+ local log = session and session.log or module._log;
+ if not ip then
+ log("debug", "User's IP not known; can't apply blacklist/whitelist");
+ elseif ip_in_set(blacklisted_ips, event.ip) or (whitelist_only and not ip_in_set(whitelisted_ips, ip)) then
+ event.allowed = false;
+ elseif throttle_max and not ip_in_set(whitelisted_ips, ip) then
+ if not check_throttle(event.ip) then
+ log("debug", "Registrations over limit for ip %s", ip or "?");
+ event.allowed = false;
+ end
+ end
+end);