From 7e1480d62e00d5260e39406fde27ae854e11ab74 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 22 Dec 2015 20:10:07 +0000 Subject: util.cache (and tests): Call on_evict after insertion of the new key, so inside on_evict we can be more certain about the current state of the cache (i.e. full, new item added, old item removed) --- tests/test_util_cache.lua | 55 +++++++++++++++++++++++++++++++++++++++++++++++ util/cache.lua | 11 +++++----- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/tests/test_util_cache.lua b/tests/test_util_cache.lua index a174eea7..72cb5a85 100644 --- a/tests/test_util_cache.lua +++ b/tests/test_util_cache.lua @@ -170,5 +170,60 @@ function new(new) end assert_equal(i, 4); + local evicted_key, evicted_value; + local c = new(3, function (_key, _value) + evicted_key, evicted_value = _key, _value; + end); + local function set(k, v, should_evict_key, should_evict_value) + evicted_key, evicted_value = nil, nil; + c:set(k, v); + assert_equal(evicted_key, should_evict_key); + assert_equal(evicted_value, should_evict_value); + end + set("a", 1) + set("a", 1) + set("a", 1) + set("a", 1) + set("a", 1) + + set("b", 2) + set("c", 3) + set("b", 2) + set("d", 4, "a", 1) + set("e", 5, "c", 3) + + + local evicted_key, evicted_value; + local c3 = new(1, function (_key, _value, c3) + evicted_key, evicted_value = _key, _value; + if _key == "a" then + -- Put it back in... + -- Check that the newest key/value was set before on_evict was called + assert_equal(c3:get("b"), 2); + -- Sanity check for what we're evicting + assert_equal(_key, "a"); + assert_equal(_value, 1); + -- Re-insert the evicted key (causes this evict function to run again with "b",2) + c3:set(_key, _value) + assert_equal(c3:get(_key), _value) + end + end); + local function set(k, v, should_evict_key, should_evict_value) + evicted_key, evicted_value = nil, nil; + c3:set(k, v); + assert_equal(evicted_key, should_evict_key); + assert_equal(evicted_value, should_evict_value); + end + set("a", 1) + set("a", 1) + set("a", 1) + set("a", 1) + set("a", 1) + -- The evict handler re-inserts "a"->1, so "b" gets evicted: + set("b", 2, "b", 2) + -- Check the final state is what we expect + assert_equal(c3:get("a"), 1); + assert_equal(c3:get("b"), nil); + assert_equal(c3:count(), 1); end diff --git a/util/cache.lua b/util/cache.lua index 72b74351..d3639b3f 100644 --- a/util/cache.lua +++ b/util/cache.lua @@ -51,19 +51,20 @@ function cache_methods:set(k, v) return true; end -- Check whether we need to remove oldest k/v + local on_evict, evicted_key, evicted_value; if self._count == self.size then local tail = self._tail; - local on_evict = self._on_evict; - if on_evict then - on_evict(tail.key, tail.value); - end + on_evict, evicted_key, evicted_value = self._on_evict, tail.key, tail.value; _remove(self, tail); - self._data[tail.key] = nil; + self._data[evicted_key] = nil; end m = { key = k, value = v, prev = nil, next = nil }; self._data[k] = m; _insert(self, m); + if on_evict and evicted_key then + on_evict(evicted_key, evicted_value, self); + end return true; end -- cgit v1.2.3 From 15db20642a2295502d3af0ea3bff404ba8a299c6 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 21 Dec 2015 14:41:38 +0100 Subject: mod_register: Use session log instance to ease indentification --- plugins/mod_register.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index e537e903..a1b4e581 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -84,6 +84,7 @@ end); local function handle_registration_stanza(event) local session, stanza = event.origin, event.stanza; + local log = session.log or module._log; local query = stanza.tags[1]; if stanza.attr.type == "get" then @@ -106,13 +107,13 @@ local function handle_registration_stanza(event) local ok, err = usermanager_delete_user(username, host); if not ok then - module:log("debug", "Removing user account %s@%s failed: %s", username, host, err); + log("debug", "Removing user account %s@%s failed: %s", username, host, err); session.close = old_session_close; session.send(st.error_reply(stanza, "cancel", "service-unavailable", err)); return true; end - module:log("info", "User removed their account: %s@%s", username, host); + log("info", "User removed their account: %s@%s", username, host); module:fire_event("user-deregistered", { username = username, host = host, source = "mod_register", session = session }); else local username = nodeprep(query:get_child_text("username")); @@ -177,6 +178,7 @@ local blacklisted_ips = module:get_option_set("registration_blacklist", {})._ite module:hook("stanza/iq/jabber:iq:register:query", function(event) local session, stanza = event.origin, event.stanza; + local log = session.log or module._log; if not(allow_registration) or session.type ~= "c2s_unauthed" then session.send(st.error_reply(stanza, "cancel", "service-unavailable")); @@ -196,7 +198,7 @@ module:hook("stanza/iq/jabber:iq:register:query", function(event) else -- Check that the user is not blacklisted or registering too often if not session.ip then - module:log("debug", "User's IP not known; can't apply blacklist/whitelist"); + log("debug", "User's IP not known; can't apply blacklist/whitelist"); elseif blacklisted_ips[session.ip] or (whitelist_only and not whitelisted_ips[session.ip]) then session.send(st.error_reply(stanza, "cancel", "not-acceptable", "You are not allowed to register an account.")); return true; @@ -238,7 +240,7 @@ module:hook("stanza/iq/jabber:iq:register:query", function(event) return true; end session.send(st.reply(stanza)); -- user created! - module:log("info", "User account created: %s@%s", username, host); + log("info", "User account created: %s@%s", username, host); module:fire_event("user-registered", { username = username, host = host, source = "mod_register", session = session }); -- cgit v1.2.3 From 6ecf2ab1de3f7c3ad5a96e5e68c7dfb30c6eb331 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 21 Dec 2015 14:48:33 +0100 Subject: mod_register: Add comment explaining the workaround for replying when the account is being deleted --- plugins/mod_register.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index a1b4e581..7e1cdc8f 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -98,6 +98,7 @@ local function handle_registration_stanza(event) if query.tags[1] and query.tags[1].name == "remove" then local username, host = session.username, session.host; + -- This one weird trick sends a reply to this stanza before the user is deleted local old_session_close = session.close; session.close = function(session, ...) session.send(st.reply(stanza)); -- cgit v1.2.3 From 18b6111e743b371d555d308249d58960751eccb7 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 22 Dec 2015 14:15:09 +0000 Subject: mod_admin_telnet: Backport 06696882d972 from 0.10 (this command greatly helps with debugging HTTP issues) --- plugins/mod_admin_telnet.lua | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 437ded01..86403606 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1081,6 +1081,33 @@ function def_env.dns:cache() return true, "Cache:\n"..tostring(dns.cache()) end +def_env.http = {}; + +function def_env.http:list() + local print = self.session.print; + + for host in pairs(prosody.hosts) do + local http_apps = modulemanager.get_items("http-provider", host); + if #http_apps > 0 then + local http_host = module:context(host):get_option("http_host"); + print("HTTP endpoints on "..host..(http_host and (" (using "..http_host.."):") or ":")); + for _, provider in ipairs(http_apps) do + local url = module:context(host):http_url(provider.name); + print("", url); + end + print(""); + end + end + + local default_host = module:get_option("http_default_host"); + if not default_host then + print("HTTP requests to unknown hosts will return 404 Not Found"); + else + print("HTTP requests to unknown hosts will be handled by "..default_host); + end + return true; +end + ------------- function printbanner(session) -- cgit v1.2.3 From 1951ac9ea1350ff7161c4fb6288688c71f4284fd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 08:32:13 +0100 Subject: util.array: Fix minory style issues --- util/array.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/util/array.lua b/util/array.lua index d4ab1771..fee2078f 100644 --- a/util/array.lua +++ b/util/array.lua @@ -37,7 +37,7 @@ setmetatable(array, { __call = new_array }); -- Read-only methods function array_methods:random() - return self[math_random(1,#self)]; + return self[math_random(1, #self)]; end -- These methods can be called two ways: @@ -45,7 +45,7 @@ end -- existing_array:method([params, ...]) -- Transform existing array into result -- function array_base.map(outa, ina, func) - for k,v in ipairs(ina) do + for k, v in ipairs(ina) do outa[k] = func(v); end return outa; @@ -54,7 +54,7 @@ end function array_base.filter(outa, ina, func) local inplace, start_length = ina == outa, #ina; local write = 1; - for read=1,start_length do + for read = 1, start_length do local v = ina[read]; if func(v) then outa[write] = v; @@ -63,7 +63,7 @@ function array_base.filter(outa, ina, func) end if inplace and write <= start_length then - for i=write,start_length do + for i = write, start_length do outa[i] = nil; end end @@ -80,7 +80,7 @@ function array_base.sort(outa, ina, ...) end function array_base.pluck(outa, ina, key) - for i=1,#ina do + for i = 1, #ina do outa[i] = ina[i][key]; end return outa; @@ -108,16 +108,16 @@ end --- These methods only mutate the array function array_methods:shuffle(outa, ina) local len = #self; - for i=1,#self do - local r = math_random(i,len); + for i = 1, #self do + local r = math_random(i, len); self[i], self[r] = self[r], self[i]; end return self; end function array_methods:append(array) - local len,len2 = #self, #array; - for i=1,len2 do + local len, len2 = #self, #array; + for i = 1, len2 do self[len+i] = array[i]; end return self; @@ -147,7 +147,7 @@ function array.collect(f, s, var) local t = {}; while true do var = f(s, var); - if var == nil then break; end + if var == nil then break; end t_insert(t, var); end return setmetatable(t, array_mt); -- cgit v1.2.3 From f4d50275c99e9d7788bb9904b6081dea004ddf1d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 08:39:22 +0100 Subject: util.array: Just use table.remove as array:pop() --- util/array.lua | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/util/array.lua b/util/array.lua index fee2078f..3ddc97f6 100644 --- a/util/array.lua +++ b/util/array.lua @@ -128,11 +128,7 @@ function array_methods:push(x) return self; end -function array_methods:pop(x) - local v = self[x]; - t_remove(self, x); - return v; -end +array_methods.pop = t_remove; function array_methods:concat(sep) return t_concat(array.map(self, tostring), sep); -- cgit v1.2.3 From 00a70c5562e0abb5b30f3a7fae1abada1d26001c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 08:42:02 +0100 Subject: util.openssl: Move quoting and tostring call into escape function --- util/openssl.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/openssl.lua b/util/openssl.lua index 39fe99d6..5043e368 100644 --- a/util/openssl.lua +++ b/util/openssl.lua @@ -144,7 +144,7 @@ end do -- Lua to shell calls. local function shell_escape(s) - return s:gsub("'",[['\'']]); + return "'" .. tostring(s):gsub("'",[['\'']]) .. "'"; end local function serialize(f,o) @@ -153,12 +153,12 @@ do -- Lua to shell calls. if type(k) == "string" then t_insert(r, ("-%s"):format(k)); if v ~= true then - t_insert(r, ("'%s'"):format(shell_escape(tostring(v)))); + t_insert(r, shell_escape(v)); end end end for _,v in ipairs(o) do - t_insert(r, ("'%s'"):format(shell_escape(tostring(v)))); + t_insert(r, shell_escape(v)); end return t_concat(r, " "); end -- cgit v1.2.3 From 9a10ad6f7f08d6966105e72b7fe27fd97a4ebda5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 08:46:54 +0100 Subject: util.openssl: Rename variables for readability --- util/openssl.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/util/openssl.lua b/util/openssl.lua index 5043e368..48922926 100644 --- a/util/openssl.lua +++ b/util/openssl.lua @@ -147,27 +147,27 @@ do -- Lua to shell calls. return "'" .. tostring(s):gsub("'",[['\'']]) .. "'"; end - local function serialize(f,o) - local r = {"openssl", f}; - for k,v in pairs(o) do + local function serialize(command, args) + local commandline = { "openssl", command }; + for k, v in pairs(args) do if type(k) == "string" then - t_insert(r, ("-%s"):format(k)); + t_insert(commandline, ("-%s"):format(k)); if v ~= true then - t_insert(r, shell_escape(v)); + t_insert(commandline, shell_escape(v)); end end end - for _,v in ipairs(o) do - t_insert(r, shell_escape(v)); + for _, v in ipairs(args) do + t_insert(commandline, shell_escape(v)); end - return t_concat(r, " "); + return t_concat(commandline, " "); end local os_execute = os.execute; setmetatable(_M, { __index=function(_,f) return function(opts) - return 0 == os_execute(serialize(f, type(opts) == "table" and opts or {})); + return 0 == os_execute(serialize(command, type(opts) == "table" and opts or {})); end; end; }); -- cgit v1.2.3 From 2487c3799d6532a7b7d82032830abf84b0d207df Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 08:47:57 +0100 Subject: util.openssl: Fix style / whitespace --- util/openssl.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/util/openssl.lua b/util/openssl.lua index 48922926..12e49eac 100644 --- a/util/openssl.lua +++ b/util/openssl.lua @@ -12,7 +12,7 @@ local config = {}; _M.config = config; local ssl_config = {}; -local ssl_config_mt = {__index=ssl_config}; +local ssl_config_mt = { __index = ssl_config }; function config.new() return setmetatable({ @@ -65,12 +65,12 @@ function ssl_config:serialize() s = s .. ("[%s]\n"):format(k); if k == "subject_alternative_name" then for san, n in pairs(t) do - for i = 1,#n do + for i = 1, #n do s = s .. s_format("%s.%d = %s\n", san, i -1, n[i]); end end elseif k == "distinguished_name" then - for i=1,#DN_order do + for i=1, #DN_order do local k = DN_order[i] local v = t[k]; if v then @@ -107,7 +107,7 @@ end function ssl_config:add_sRVName(host, service) t_insert(self.subject_alternative_name.otherName, - s_format("%s;%s", oid_dnssrv, ia5string("_" .. service .."." .. idna_to_ascii(host)))); + s_format("%s;%s", oid_dnssrv, ia5string("_" .. service .. "." .. idna_to_ascii(host)))); end function ssl_config:add_xmppAddr(host) @@ -118,10 +118,10 @@ end function ssl_config:from_prosody(hosts, config, certhosts) -- TODO Decide if this should go elsewhere local found_matching_hosts = false; - for i = 1,#certhosts do + for i = 1, #certhosts do local certhost = certhosts[i]; for name in pairs(hosts) do - if name == certhost or name:sub(-1-#certhost) == "."..certhost then + if name == certhost or name:sub(-1-#certhost) == "." .. certhost then found_matching_hosts = true; self:add_dNSName(name); --print(name .. "#component_module: " .. (config.get(name, "component_module") or "nil")); @@ -165,7 +165,7 @@ do -- Lua to shell calls. local os_execute = os.execute; setmetatable(_M, { - __index=function(_,f) + __index = function(_, command) return function(opts) return 0 == os_execute(serialize(command, type(opts) == "table" and opts or {})); end; -- cgit v1.2.3 From f13cbf54bb20960d5c9cc8a3a35d416831acd097 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 08:49:38 +0100 Subject: tests: Add small test for util.throttle --- tests/test.lua | 1 + tests/test_util_throttle.lua | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/test_util_throttle.lua diff --git a/tests/test.lua b/tests/test.lua index f7fdee91..1666fcf5 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -21,6 +21,7 @@ function run_all_tests() dotest "util.stanza" dotest "util.sasl.scram" dotest "util.cache" + dotest "util.throttle" dosingletest("test_sasl.lua", "latin1toutf8"); dosingletest("test_utf8.lua", "valid"); diff --git a/tests/test_util_throttle.lua b/tests/test_util_throttle.lua new file mode 100644 index 00000000..582f499d --- /dev/null +++ b/tests/test_util_throttle.lua @@ -0,0 +1,34 @@ + +local now = 0; -- wibbly-wobbly... timey-wimey... stuff +local function predictable_gettime() + return now; +end +local function later(n) + now = now + n; -- time passes at a different rate +end + +local function override_gettime(throttle) + local i = 0; + repeat + i = i + 1; + local name = debug.getupvalue(throttle.update, i); + if name then + debug.setupvalue(throttle.update, i, predictable_gettime); + return throttle; + end + until not name; +end + +function create(create) + local a = override_gettime( create(3, 10) ); + + assert_equal(a:poll(1), true); -- 3 -> 2 + assert_equal(a:poll(1), true); -- 2 -> 1 + assert_equal(a:poll(1), true); -- 1 -> 0 + assert_equal(a:poll(1), false); -- MEEP, out of credits! + later(1); -- ... what about + assert_equal(a:poll(1), false); -- now? - Still no! + later(9); -- Later that day + assert_equal(a:poll(1), true); -- Should be back at 3 credits ... 2 +end + -- cgit v1.2.3 From 5fdea68a39ba2d12af0ad79ba7c0f85d0c1ec698 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 08:57:12 +0100 Subject: mod_register: Switch to using util.throttle for limiting registrations per ip per time --- plugins/mod_register.lua | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index 7e1cdc8f..5e73dbf7 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -13,9 +13,9 @@ local usermanager_user_exists = require "core.usermanager".user_exists; local usermanager_create_user = require "core.usermanager".create_user; local usermanager_set_password = require "core.usermanager".set_password; local usermanager_delete_user = require "core.usermanager".delete_user; -local os_time = os.time; local nodeprep = require "util.encodings".stringprep.nodeprep; local jid_bare = require "util.jid".bare; +local create_throttle = require "util.throttle".create; local compat = module:get_option_boolean("registration_compat", true); local allow_registration = module:get_option_boolean("allow_registration", false); @@ -177,6 +177,19 @@ local whitelist_only = module:get_option_boolean("whitelist_registration_only"); local whitelisted_ips = module:get_option_set("registration_whitelist", { "127.0.0.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 function check_throttle(ip) + if not throttle_max then return true end + local throttle = recent_ips[ip]; + if not throttle then + throttle = create_throttle(throttle_max, throttle_period); + recent_ips[ip] = throttle; + end + return throttle:poll(1); +end + module:hook("stanza/iq/jabber:iq:register:query", function(event) local session, stanza = event.origin, event.stanza; local log = session.log or module._log; @@ -204,18 +217,9 @@ module:hook("stanza/iq/jabber:iq:register:query", function(event) session.send(st.error_reply(stanza, "cancel", "not-acceptable", "You are not allowed to register an account.")); return true; elseif min_seconds_between_registrations and not whitelisted_ips[session.ip] then - if not recent_ips[session.ip] then - recent_ips[session.ip] = { time = os_time(), count = 1 }; - else - local ip = recent_ips[session.ip]; - ip.count = ip.count + 1; - - if os_time() - ip.time < min_seconds_between_registrations then - ip.time = os_time(); - session.send(st.error_reply(stanza, "wait", "not-acceptable")); - return true; - end - ip.time = os_time(); + if check_throttle(session.ip) then + session.send(st.error_reply(stanza, "wait", "not-acceptable")); + return true; end end local username, password = nodeprep(data.username), data.password; -- cgit v1.2.3 From da2a7cf041fb3ffbedb413e7475434e207e88571 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 08:58:34 +0100 Subject: mod_register: Use util.cache to limit the number of per-ip throttles kept --- plugins/mod_register.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index 5e73dbf7..ee196722 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -16,6 +16,7 @@ local usermanager_delete_user = require "core.usermanager".delete_user; local nodeprep = require "util.encodings".stringprep.nodeprep; local jid_bare = require "util.jid".bare; local create_throttle = require "util.throttle".create; +local new_cache = require "util.cache".new; local compat = module:get_option_boolean("registration_compat", true); local allow_registration = module:get_option_boolean("allow_registration", false); @@ -171,7 +172,6 @@ local function parse_response(query) end end -local recent_ips = {}; 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" })._items; @@ -179,14 +179,17 @@ local blacklisted_ips = module:get_option_set("registration_blacklist", {})._ite 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 throttle_cache = new_cache(throttle_cache_size); local function check_throttle(ip) if not throttle_max then return true end - local throttle = recent_ips[ip]; + local throttle = throttle_cache:get(ip); if not throttle then throttle = create_throttle(throttle_max, throttle_period); - recent_ips[ip] = throttle; end + throttle_cache:set(ip, throttle); return throttle:poll(1); end -- cgit v1.2.3 From 3ceac426b5719284cc3ab15f2b3309a782c857f4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 09:00:03 +0100 Subject: mod_register: Support for blacklisting ips that are still over limit when they get pushed out of the cache --- plugins/mod_register.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index ee196722..1961b276 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -180,8 +180,14 @@ local blacklisted_ips = module:get_option_set("registration_blacklist", {})._ite 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); +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); local function check_throttle(ip) if not throttle_max then return true end -- cgit v1.2.3 From 22f1422f51beee193f64a6e2c6c3986431922f0b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 12:07:03 +0100 Subject: certs/Makefile: Run key generation with a stricter umask (fixes a race condition) --- certs/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/certs/Makefile b/certs/Makefile index f3854c5f..c709ff91 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -26,5 +26,5 @@ keysize=2048 sed 's,example\.com,$*,g' openssl.cnf > $@ %.key: - openssl genrsa $(keysize) > $@ - @chmod 400 $@ + umask 0077 && openssl genrsa -out $@ $(keysize) + @chmod 400 $@ -c -- cgit v1.2.3 From ce293a372a2f86fc796cc43568a7124689ce3862 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 12:10:26 +0100 Subject: certs/Makefile: Add targets for any combination of already existing config, key file --- certs/Makefile | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/certs/Makefile b/certs/Makefile index f3854c5f..6ffb6bd7 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -15,13 +15,46 @@ keysize=2048 # To request a cert %.csr: %.cnf %.key - openssl req -new -key $(lastword $^) -out $@ -utf8 -config $(firstword $^) + openssl req -new -key $(lastword $^) \ + -sha256 -utf8 -config $(firstword $^) -out $@ + +%.csr: %.cnf + umask 0077 && touch $*.key + openssl req -new -newkey rsa:$(keysize) -nodes -keyout $*.key \ + -sha256 -utf8 -config $^ -out $@ + @chmod 400 $*.key -c + +%.csr: %.key + openssl req -new -key $^ -utf8 -subj /CN=$* -out $@ + +%.csr: + umask 0077 && touch $*.key + openssl req -new -newkey rsa:$(keysize) -nodes -keyout $*.key \ + -utf8 -subj /CN=$* -out $@ + @chmod 400 $*.key -c # Self signed %.crt: %.cnf %.key - openssl req -new -x509 -nodes -key $(lastword $^) -days 365 \ - -sha1 -out $@ -utf8 -config $(firstword $^) + openssl req -new -x509 -key $(lastword $^) -days 365 -sha256 -utf8 \ + -config $(firstword $^) -out $@ + +%.crt: %.cnf + umask 0077 && touch $*.key + openssl req -new -x509 -newkey rsa:$(keysize) -nodes -keyout $*.key \ + -days 365 -sha256 -utf8 -config $(firstword $^) -out $@ + @chmod 400 $*.key -c + +%.crt: %.key + openssl req -new -x509 -nodes -key $^ -days 365 \ + -sha256 -out $@ -utf8 -config $(firstword $^) + +%.crt: + umask 0077 && touch $*.key + openssl req -new -x509 -newkey rsa:$(keysize) -nodes -keyout $*.key \ + -days 365 -sha256 -out $@ -utf8 -subj /CN=$* + @chmod 400 $*.key -c +# Generate a config from the example %.cnf: sed 's,example\.com,$*,g' openssl.cnf > $@ -- cgit v1.2.3 From e310e18a50db40e86930cf905561495637b3616c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 14:19:01 +0100 Subject: man prosodyctl: Accidentally markdown --- man/Makefile | 4 ++ man/prosodyctl.man | 171 +++++++++++++++++++++++++++++------------------- man/prosodyctl.markdown | 107 ++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+), 69 deletions(-) create mode 100644 man/Makefile create mode 100644 man/prosodyctl.markdown diff --git a/man/Makefile b/man/Makefile new file mode 100644 index 00000000..79bdd90a --- /dev/null +++ b/man/Makefile @@ -0,0 +1,4 @@ +all: prosodyctl.man + +%.man: %.markdown + pandoc -s -t man -o $@ $^ diff --git a/man/prosodyctl.man b/man/prosodyctl.man index 6dcb04cd..44e6022f 100644 --- a/man/prosodyctl.man +++ b/man/prosodyctl.man @@ -1,83 +1,116 @@ -.TH PROSODYCTL 1 "2009-07-02" - +.\" Automatically generated by Pandoc 1.15.2 +.\" +.hy +.TH "PROSODYCTL" "1" "2015\-12\-23" "" "" .SH NAME +.PP prosodyctl \- Manage a Prosody XMPP server - .SH SYNOPSIS -\fBprosodyctl\fP \fIcommand\fP [\fI--help\fP] - +.IP +.nf +\f[C] +prosodyctl\ command\ [\-\-help] +\f[] +.fi .SH DESCRIPTION -\fBprosodyctl\fP is the control tool for the Prosody XMPP server. It may be -used to control the server daemon and manage users. - -\fBprosodyctl\fP needs to be executed with sufficient privileges to perform -its commands. This typically means executing \fBprosodyctl\fP as the root user. -If a user named "prosody" is found then \fBprosodyctl\fP will change to that +.PP +prosodyctl is the control tool for the Prosody XMPP server. +It may be used to control the server daemon and manage users. +.PP +prosodyctl needs to be executed with sufficient privileges to perform +its commands. +This typically means executing prosodyctl as the root user. +If a user named "prosody" is found then prosodyctl will change to that user before executing its commands. - .SH COMMANDS .SS User Management -In the following commands users are identified by a Jabber ID, \fIjid\fP, of the -usual form: user@domain. - -.IP "\fBadduser\fP \fIjid\fP" -Adds a user with Jabber ID, \fIjid\fP, to the server. You will be -prompted to enter the user's password. - -.IP "\fBpasswd\fP \fIjid\fP" -Changes the password of an existing user with Jabber ID, \fIjid\fP. You will be -prompted to enter the user's new password. - -.IP "\fBdeluser\fP \fIjid\fP" -Deletes an existing user with Jabber ID, \fIjid\fP, from the server. - +.PP +In the following commands users are identified by a Jabber ID, jid, of +the usual form: user\@domain. +.TP +.B adduser jid +Adds a user with Jabber ID, jid, to the server. +You will be prompted to enter the user\[aq]s password. +.RS +.RE +.TP +.B passwd jid +Changes the password of an existing user with Jabber ID, jid. +You will be prompted to enter the user\[aq]s new password. +.RS +.RE +.TP +.B deluser jid +Deletes an existing user with Jabber ID, jid, from the server. +.RS +.RE .SS Daemon Management -Although \fBprosodyctl\fP has commands to manage the \fBprosody\fP daemon it is -recommended that you utilize your distributions daemon management features if -you attained Prosody through a package. - -To perform daemon control commands \fBprosodyctl\fP needs a \fIpidfile\fP value -specified in \fI/etc/prosody/prosody.cfg.lua\fP. Failure to do so will cause -\fBprosodyctl\fP to complain. - -.IP \fBstart\fP -Starts the \fBprosody\fP server daemon. If run as root \fBprosodyctl\fP will -attempt to change to a user named "prosody" before executing. This operation -will block for up to five seconds to wait for the server to execute. - -.IP \fBstop\fP -Stops the \fBprosody\fP server daemon. This operation will block for up to five -seconds to wait for the server to stop executing. - -.IP \fBrestart\fP -Restarts the \fBprosody\fP server daemon. Equivalent to running \fBprosodyctl -stop\fP followed by \fBprosodyctl start\fP. - -.IP \fBstatus\fP -Prints the current execution status of the \fBprosody\fP server daemon. - +.PP +Although prosodyctl has commands to manage the prosody daemon it is +recommended that you utilize your distributions daemon management +features if you attained Prosody through a package. +.PP +To perform daemon control commands prosodyctl needs a pidfile value +specified in \f[C]/etc/prosody/prosody.cfg.lua\f[]. +Failure to do so will cause prosodyctl to complain. +.TP +.B start +Starts the prosody server daemon. +If run as root prosodyctl will attempt to change to a user named +"prosody" before executing. +This operation will block for up to five seconds to wait for the server +to execute. +.RS +.RE +.TP +.B stop +Stops the prosody server daemon. +This operation will block for up to five seconds to wait for the server +to stop executing. +.RS +.RE +.TP +.B restart +Restarts the prosody server daemon. +Equivalent to running prosodyctl stop followed by prosodyctl start. +.RS +.RE +.TP +.B status +Prints the current execution status of the prosody server daemon. +.RS +.RE .SS Ejabberd Compatibility -\fBejabberd\fP is another XMPP server which provides a comparable control tool, -\fBejabberdctl\fP, to control its server's operations. \fBprosodyctl\fP -implements some commands which are compatible with \fBejabberdctl\fP. For -details of how these commands work you should see -.BR ejabberdctl (8). - -.IP "\fBregister\fP \fIuser server password\fP" -.IP "\fBunregister\fP \fIuser server\fP" - +.PP +ejabberd is another XMPP server which provides a comparable control +tool, ejabberdctl, to control its server\[aq]s operations. +prosodyctl implements some commands which are compatible with +ejabberdctl. +For details of how these commands work you should see ejabberdctl(8). +.IP +.nf +\f[C] +register\ user\ server\ password + +unregister\ user\ server +\f[] +.fi .SH OPTIONS -.IP \fI--help\fP +.TP +.B \f[C]\-\-help\f[] Display help text for the specified command. - +.RS +.RE .SH FILES -.IP \fI/etc/prosody/prosody.cfg.lua\fP -The main \fBprosody\fP configuration file. \fBprosodyctl\fP reads this to -determine the process ID file of the \fBprosody\fP server daemon and to -determine if a host has been configured. - +.TP +.B \f[C]/etc/prosody/prosody.cfg.lua\f[] +The main prosody configuration file. +prosodyctl reads this to determine the process ID file of the prosody +server daemon and to determine if a host has been configured. +.RS +.RE .SH ONLINE -More information may be found online at: \fIhttp://prosody.im/\fP - +.PP +More information may be found online at: .SH AUTHORS -Dwayne Bent +Dwayne Bent . diff --git a/man/prosodyctl.markdown b/man/prosodyctl.markdown new file mode 100644 index 00000000..e4cd8e91 --- /dev/null +++ b/man/prosodyctl.markdown @@ -0,0 +1,107 @@ +--- +author: +- 'Dwayne Bent ' +date: '2015-12-23' +section: 1 +title: PROSODYCTL +... + +NAME +==== + +prosodyctl - Manage a Prosody XMPP server + +SYNOPSIS +======== + + prosodyctl command [--help] + +DESCRIPTION +=========== + +prosodyctl is the control tool for the Prosody XMPP server. It may be +used to control the server daemon and manage users. + +prosodyctl needs to be executed with sufficient privileges to perform +its commands. This typically means executing prosodyctl as the root +user. If a user named "prosody" is found then prosodyctl will change to +that user before executing its commands. + +COMMANDS +======== + +User Management +--------------- + +In the following commands users are identified by a Jabber ID, jid, of +the usual form: user@domain. + +adduser jid +: Adds a user with Jabber ID, jid, to the server. You will be prompted + to enter the user's password. + +passwd jid +: Changes the password of an existing user with Jabber ID, jid. You + will be prompted to enter the user's new password. + +deluser jid +: Deletes an existing user with Jabber ID, jid, from the server. + +Daemon Management +----------------- + +Although prosodyctl has commands to manage the prosody daemon it is +recommended that you utilize your distributions daemon management +features if you attained Prosody through a package. + +To perform daemon control commands prosodyctl needs a pidfile value +specified in `/etc/prosody/prosody.cfg.lua`. Failure to do so will cause +prosodyctl to complain. + +start +: Starts the prosody server daemon. If run as root prosodyctl will + attempt to change to a user named "prosody" before executing. This + operation will block for up to five seconds to wait for the server + to execute. + +stop +: Stops the prosody server daemon. This operation will block for up to + five seconds to wait for the server to stop executing. + +restart +: Restarts the prosody server daemon. Equivalent to running prosodyctl + stop followed by prosodyctl start. + +status +: Prints the current execution status of the prosody server daemon. + +Ejabberd Compatibility +---------------------- + +ejabberd is another XMPP server which provides a comparable control +tool, ejabberdctl, to control its server's operations. prosodyctl +implements some commands which are compatible with ejabberdctl. For +details of how these commands work you should see ejabberdctl(8). + + register user server password + + unregister user server + +OPTIONS +======= + +`--help` +: Display help text for the specified command. + +FILES +===== + +`/etc/prosody/prosody.cfg.lua` +: The main prosody configuration file. prosodyctl reads this to + determine the process ID file of the prosody server daemon and to + determine if a host has been configured. + +ONLINE +====== + +More information may be found online at: -- cgit v1.2.3 From 449bfbc135e6592865fd68f29e2d75ec7667c4a7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 14:20:57 +0100 Subject: man prosodyctl: Add missing 'reload' command --- man/prosodyctl.man | 8 +++++++- man/prosodyctl.markdown | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/man/prosodyctl.man b/man/prosodyctl.man index 44e6022f..8dd9e1f8 100644 --- a/man/prosodyctl.man +++ b/man/prosodyctl.man @@ -76,6 +76,12 @@ Equivalent to running prosodyctl stop followed by prosodyctl start. .RS .RE .TP +.B reload +Signals the prosody server daemon to reload configuration and reopen log +files. +.RS +.RE +.TP .B status Prints the current execution status of the prosody server daemon. .RS @@ -113,4 +119,4 @@ server daemon and to determine if a host has been configured. .PP More information may be found online at: .SH AUTHORS -Dwayne Bent . +Dwayne Bent ; Kim Alvefur. diff --git a/man/prosodyctl.markdown b/man/prosodyctl.markdown index e4cd8e91..5360503b 100644 --- a/man/prosodyctl.markdown +++ b/man/prosodyctl.markdown @@ -1,6 +1,7 @@ --- author: - 'Dwayne Bent ' +- Kim Alvefur date: '2015-12-23' section: 1 title: PROSODYCTL @@ -72,6 +73,10 @@ restart : Restarts the prosody server daemon. Equivalent to running prosodyctl stop followed by prosodyctl start. +reload +: Signals the prosody server daemon to reload configuration and reopen + log files. + status : Prints the current execution status of the prosody server daemon. -- cgit v1.2.3 From 4e8f92f0aee1621af3bc1302af7c0982d9a53077 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 14:21:20 +0100 Subject: man prosodyctl: Add information about the 'about' and 'check' commands --- man/prosodyctl.man | 18 ++++++++++++++++++ man/prosodyctl.markdown | 15 +++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/man/prosodyctl.man b/man/prosodyctl.man index 8dd9e1f8..b91502a8 100644 --- a/man/prosodyctl.man +++ b/man/prosodyctl.man @@ -86,6 +86,24 @@ files. Prints the current execution status of the prosody server daemon. .RS .RE +.SS Debugging +.PP +prosodyctl can also show some information about the environment, +dependencies and such to aid in debugging. +.TP +.B about +Shows environment, various paths used by Prosody and installed +dependencies. +.RS +.RE +.TP +.B check [what] +Performs various sanity checks on the configuration, DNS setup and +configured TLS certificates. +\f[C]what\f[] can be one of \f[C]config\f[], \f[C]dns\f[] and +\f[C]certs\f[] to run only that check. +.RS +.RE .SS Ejabberd Compatibility .PP ejabberd is another XMPP server which provides a comparable control diff --git a/man/prosodyctl.markdown b/man/prosodyctl.markdown index 5360503b..217dfd3d 100644 --- a/man/prosodyctl.markdown +++ b/man/prosodyctl.markdown @@ -80,6 +80,21 @@ reload status : Prints the current execution status of the prosody server daemon. +Debugging +--------- + +prosodyctl can also show some information about the environment, +dependencies and such to aid in debugging. + +about +: Shows environment, various paths used by Prosody and + installed dependencies. + +check \[what\] +: Performs various sanity checks on the configuration, DNS setup and + configured TLS certificates. `what` can be one of `config`, `dns` + and `certs` to run only that check. + Ejabberd Compatibility ---------------------- -- cgit v1.2.3 From b50935a87c03246fac1541b275da4464a5b63b3b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 24 Dec 2015 10:39:13 +0100 Subject: certs/Makefile: Fix generating cert from only a key (no config then) --- certs/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/certs/Makefile b/certs/Makefile index 534aa0d4..96361748 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -45,8 +45,7 @@ keysize=2048 @chmod 400 $*.key -c %.crt: %.key - openssl req -new -x509 -nodes -key $^ -days 365 \ - -sha256 -out $@ -utf8 -config $(firstword $^) + openssl req -new -x509 -key $^ -days 365 -sha256 -utf8 -subj /CN=$* -out $@ %.crt: umask 0077 && touch $*.key -- cgit v1.2.3