Comparison

plugins/mod_register_ibr.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:f591855f060d
child 8488:95706e0f19fc
comparison
equal deleted inserted replaced
8484:f591855f060d 8485:0e02c6de5c02
11 local dataform_new = require "util.dataforms".new; 11 local dataform_new = require "util.dataforms".new;
12 local usermanager_user_exists = require "core.usermanager".user_exists; 12 local usermanager_user_exists = require "core.usermanager".user_exists;
13 local usermanager_create_user = require "core.usermanager".create_user; 13 local usermanager_create_user = require "core.usermanager".create_user;
14 local usermanager_delete_user = require "core.usermanager".delete_user; 14 local usermanager_delete_user = require "core.usermanager".delete_user;
15 local nodeprep = require "util.encodings".stringprep.nodeprep; 15 local nodeprep = require "util.encodings".stringprep.nodeprep;
16 local create_throttle = require "util.throttle".create;
17 local new_cache = require "util.cache".new;
18 local ip_util = require "util.ip";
19 local new_ip = ip_util.new_ip;
20 local match_ip = ip_util.match;
21 local parse_cidr = ip_util.parse_cidr;
22 16
23 local additional_fields = module:get_option("additional_registration_fields", {}); 17 local additional_fields = module:get_option("additional_registration_fields", {});
24 local require_encryption = module:get_option_boolean("c2s_require_encryption", 18 local require_encryption = module:get_option_boolean("c2s_require_encryption",
25 module:get_option_boolean("require_encryption", false)); 19 module:get_option_boolean("require_encryption", false));
26 20
111 end 105 end
112 return data; 106 return data;
113 end 107 end
114 end 108 end
115 109
116 local min_seconds_between_registrations = module:get_option_number("min_seconds_between_registrations");
117 local whitelist_only = module:get_option_boolean("whitelist_registration_only");
118 local whitelisted_ips = module:get_option_set("registration_whitelist", { "127.0.0.1", "::1" })._items;
119 local blacklisted_ips = module:get_option_set("registration_blacklist", {})._items;
120
121 local throttle_max = module:get_option_number("registration_throttle_max", min_seconds_between_registrations and 1);
122 local throttle_period = module:get_option_number("registration_throttle_period", min_seconds_between_registrations);
123 local throttle_cache_size = module:get_option_number("registration_throttle_cache_size", 100);
124 local blacklist_overflow = module:get_option_boolean("blacklist_on_registration_throttle_overload", false);
125
126 local throttle_cache = new_cache(throttle_cache_size, blacklist_overflow and function (ip, throttle)
127 if not throttle:peek() then
128 module:log("info", "Adding ip %s to registration blacklist", ip);
129 blacklisted_ips[ip] = true;
130 end
131 end or nil);
132
133 local function check_throttle(ip)
134 if not throttle_max then return true end
135 local throttle = throttle_cache:get(ip);
136 if not throttle then
137 throttle = create_throttle(throttle_max, throttle_period);
138 end
139 throttle_cache:set(ip, throttle);
140 return throttle:poll(1);
141 end
142
143 local function ip_in_set(set, ip)
144 if set[ip] then
145 return true;
146 end
147 ip = new_ip(ip);
148 for in_set in pairs(set) do
149 if match_ip(ip, parse_cidr(in_set)) then
150 return true;
151 end
152 end
153 return false;
154 end
155
156 -- In-band registration 110 -- In-band registration
157 module:hook("stanza/iq/jabber:iq:register:query", function(event) 111 module:hook("stanza/iq/jabber:iq:register:query", function(event)
158 local session, stanza = event.origin, event.stanza; 112 local session, stanza = event.origin, event.stanza;
159 local log = session.log or module._log; 113 local log = session.log or module._log;
160 114
179 for field, err in pairs(errors) do 133 for field, err in pairs(errors) do
180 log("debug", "Field %q: %s", field, err); 134 log("debug", "Field %q: %s", field, err);
181 end 135 end
182 session.send(st.error_reply(stanza, "modify", "not-acceptable")); 136 session.send(st.error_reply(stanza, "modify", "not-acceptable"));
183 else 137 else
184 -- Check that the user is not blacklisted or registering too often
185 if not session.ip then
186 log("debug", "User's IP not known; can't apply blacklist/whitelist");
187 elseif ip_in_set(blacklisted_ips, session.ip) or (whitelist_only and not ip_in_set(whitelisted_ips, session.ip)) then
188 session.send(st.error_reply(stanza, "cancel", "not-acceptable", "You are not allowed to register an account."));
189 return true;
190 elseif throttle_max and not ip_in_set(whitelisted_ips, session.ip) then
191 if not check_throttle(session.ip) then
192 log("debug", "Registrations over limit for ip %s", session.ip or "?");
193 session.send(st.error_reply(stanza, "wait", "not-acceptable"));
194 return true;
195 end
196 end
197 local username, password = nodeprep(data.username), data.password; 138 local username, password = nodeprep(data.username), data.password;
198 data.username, data.password = nil, nil; 139 data.username, data.password = nil, nil;
199 local host = module.host; 140 local host = module.host;
200 if not username or username == "" then 141 if not username or username == "" then
201 log("debug", "The requested username is invalid."); 142 log("debug", "The requested username is invalid.");