Comparison

mod_limit_auth/mod_limit_auth.lua @ 1583:c1bb2a64aabb

mod_limit_auth: Throttle authentication (failed) attempts with optional (0.10+) tarpit
author Kim Alvefur <zash@zash.se>
date Sat, 06 Dec 2014 17:42:51 +0100
child 1854:450ada5bb1b5
comparison
equal deleted inserted replaced
1582:8e282eb0c70c 1583:c1bb2a64aabb
1 -- mod_limit_auth
2
3 local st = require"util.stanza";
4 local new_throttle = require "util.throttle".create;
5
6 local period = math.max(module:get_option_number(module.name.."_period", 30), 0);
7 local max = math.max(module:get_option_number(module.name.."_max", 5), 1);
8
9 local tarpit_delay = module:get_option_number(module.name.."_tarpit_delay", nil);
10 if tarpit_delay then
11 local waiter = require "util.async".waiter;
12 local delay = tarpit_delay;
13 function tarpit_delay()
14 local wait, done = waiter();
15 module:add_timer(delay, done);
16 wait();
17 end
18 else
19 function tarpit_delay() end
20 end
21
22 local throttles = module:shared"throttles";
23
24 local reply = st.stanza("failure", { xmlns = "urn:ietf:params:xml:ns:xmpp-sasl" }):tag("temporary-auth-failure");
25
26 local function get_throttle(ip)
27 local throttle = throttles[ip];
28 if not throttle then
29 throttle = new_throttle(max, period);
30 throttles[ip] = throttle;
31 end
32 return throttle;
33 end
34
35 module:hook("stanza/urn:ietf:params:xml:ns:xmpp-sasl:auth", function (event)
36 local origin = event.origin;
37 if not get_throttle(origin.ip):peek(1) then
38 origin.log("warn", "Too many authentication attepmts for ip %s", origin.ip);
39 tarpit_delay();
40 origin.send(reply);
41 return true;
42 end
43 end, 10);
44
45 module:hook("authentication-failure", function (event)
46 get_throttle(event.session.ip):poll(1);
47 end);
48
49 -- TODO remove old throttles after some time