Software / code / prosody
Comparison
plugins/mod_register_limits.lua @ 8485:0e02c6de5c02
mod_register_ibr: Split out throttling and IP limitations into mod_register_limits (#723)
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 09 Dec 2017 19:35:08 +0100 |
| parent | 8484:plugins/mod_register_ibr.lua@f591855f060d |
| child | 8584:e3d953481f7d |
comparison
equal
deleted
inserted
replaced
| 8484:f591855f060d | 8485:0e02c6de5c02 |
|---|---|
| 1 -- Prosody IM | |
| 2 -- Copyright (C) 2008-2010 Matthew Wild | |
| 3 -- Copyright (C) 2008-2010 Waqas Hussain | |
| 4 -- | |
| 5 -- This project is MIT/X11 licensed. Please see the | |
| 6 -- COPYING file in the source package for more information. | |
| 7 -- | |
| 8 | |
| 9 | |
| 10 local create_throttle = require "util.throttle".create; | |
| 11 local new_cache = require "util.cache".new; | |
| 12 local ip_util = require "util.ip"; | |
| 13 local new_ip = ip_util.new_ip; | |
| 14 local match_ip = ip_util.match; | |
| 15 local parse_cidr = ip_util.parse_cidr; | |
| 16 | |
| 17 local min_seconds_between_registrations = module:get_option_number("min_seconds_between_registrations"); | |
| 18 local whitelist_only = module:get_option_boolean("whitelist_registration_only"); | |
| 19 local whitelisted_ips = module:get_option_set("registration_whitelist", { "127.0.0.1", "::1" })._items; | |
| 20 local blacklisted_ips = module:get_option_set("registration_blacklist", {})._items; | |
| 21 | |
| 22 local throttle_max = module:get_option_number("registration_throttle_max", min_seconds_between_registrations and 1); | |
| 23 local throttle_period = module:get_option_number("registration_throttle_period", min_seconds_between_registrations); | |
| 24 local throttle_cache_size = module:get_option_number("registration_throttle_cache_size", 100); | |
| 25 local blacklist_overflow = module:get_option_boolean("blacklist_on_registration_throttle_overload", false); | |
| 26 | |
| 27 local throttle_cache = new_cache(throttle_cache_size, blacklist_overflow and function (ip, throttle) | |
| 28 if not throttle:peek() then | |
| 29 module:log("info", "Adding ip %s to registration blacklist", ip); | |
| 30 blacklisted_ips[ip] = true; | |
| 31 end | |
| 32 end or nil); | |
| 33 | |
| 34 local function check_throttle(ip) | |
| 35 if not throttle_max then return true end | |
| 36 local throttle = throttle_cache:get(ip); | |
| 37 if not throttle then | |
| 38 throttle = create_throttle(throttle_max, throttle_period); | |
| 39 end | |
| 40 throttle_cache:set(ip, throttle); | |
| 41 return throttle:poll(1); | |
| 42 end | |
| 43 | |
| 44 local function ip_in_set(set, ip) | |
| 45 if set[ip] then | |
| 46 return true; | |
| 47 end | |
| 48 ip = new_ip(ip); | |
| 49 for in_set in pairs(set) do | |
| 50 if match_ip(ip, parse_cidr(in_set)) then | |
| 51 return true; | |
| 52 end | |
| 53 end | |
| 54 return false; | |
| 55 end | |
| 56 | |
| 57 module:hook("user-registering", function (event) | |
| 58 local session = event.session; | |
| 59 local ip = event.ip or session and session.ip; | |
| 60 local log = session and session.log or module._log; | |
| 61 if not ip then | |
| 62 log("debug", "User's IP not known; can't apply blacklist/whitelist"); | |
| 63 elseif ip_in_set(blacklisted_ips, event.ip) or (whitelist_only and not ip_in_set(whitelisted_ips, ip)) then | |
| 64 event.allowed = false; | |
| 65 elseif throttle_max and not ip_in_set(whitelisted_ips, ip) then | |
| 66 if not check_throttle(event.ip) then | |
| 67 log("debug", "Registrations over limit for ip %s", ip or "?"); | |
| 68 event.allowed = false; | |
| 69 end | |
| 70 end | |
| 71 end); |