# HG changeset patch # User Matthew Wild # Date 1329232636 0 # Node ID b5a8e8492570675a0a57a9acb75317f700261e2f # Parent 15763c1d085cc8c4ecf2223becc3cdac702fd91f# Parent b1d82ae063e1b7f13f0d7121f6393dc0c85befdf Merge diff -r b1d82ae063e1 -r b5a8e8492570 mod_c2s_conn_throttle/mod_c2s_conn_throttle.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_c2s_conn_throttle/mod_c2s_conn_throttle.lua Tue Feb 14 15:17:16 2012 +0000 @@ -0,0 +1,42 @@ +-- Clients Connection Throttler. +-- Usage: +-- Add the module into modules loaded into the virtual host section +-- +-- cthrottler_logins_count = 3 -> number of logins attempt allowed +-- cthrottler_time = 120 -> in x seconds + +local time = os.time +local in_count = {} +local logins_count = module:get_option_number("cthrottler_logins_count", 3) +local throttle_time = module:get_option_number("cthrottler_time", 60) + +local function handle_sessions(event) + local session = event.origin + + if not in_count[session.ip] and session.type == "c2s_unauthed" then + in_count[session.ip] = { t = time(), c = 1 } + elseif in_count[session.ip] and session.type == "c2s_unauthed" then + if in_count[session.ip].starttls_c then in_count[session.ip].c = in_count[session.ip].starttls_c else in_count[session.ip].c = in_count[session.ip].c + 1 end + + if in_count[session.ip].c > logins_count and time() - in_count[session.ip].t < throttle_time then + module:log("error", "Exceeded login count for %s, closing connection", session.ip) + session:close{ condition = "policy-violation", text = "You exceeded the number of connections/logins allowed in "..throttle_time.." seconds, good bye." } + return true + elseif time() - in_count[session.ip].t > throttle_time then + in_count[session.ip] = nil ; return + end + end +end + +local function check_starttls(event) + local session = event.origin + + if in_count[session.ip] and type(in_count[session.ip].starttls_c) ~= "number" and session.type == "c2s_unauthed" then + in_count[session.ip].starttls_c = 1 + elseif in_count[session.ip] and type(in_count[session.ip].starttls_c) == "number" and session.type == "c2s_unauthed" then + in_count[session.ip].starttls_c = in_count[session.ip].starttls_c + 1 + end +end + +module:hook("stream-features", handle_sessions, 100) +module:hook("stanza/urn:ietf:params:xml:ns:xmpp-tls:starttls", check_starttls, 100) diff -r b1d82ae063e1 -r b5a8e8492570 mod_carbons/mod_carbons.lua --- a/mod_carbons/mod_carbons.lua Tue Feb 14 15:16:38 2012 +0000 +++ b/mod_carbons/mod_carbons.lua Tue Feb 14 15:17:16 2012 +0000 @@ -44,7 +44,7 @@ local bare_jid, user_sessions; local no_carbon_to = {}; - module:log("debug", "origin (%s) type: %s", tostring(origin), origin.type) + module:log("debug", "Message from %s to %s", orig_from, orig_to); if c2s then -- Stanza sent by a local client bare_jid = (origin.username.."@"..origin.host) user_sessions = host_sessions[origin.username]; @@ -53,11 +53,13 @@ bare_jid = jid_bare(orig_to); user_sessions = host_sessions[username]; if resource then + module:log("debug", "Message was to resource %s, it will not get carbon", resource); no_carbon_to[resource] = true; elseif user_sessions then local top_resources = user_sessions.top_resources; if top_resources then for _, session in ipairs(top_resources) do + module:log("debug", "Not sending carbons to top resource %s", session.resource); no_carbon_to[session.resource] = true; end end @@ -65,6 +67,7 @@ end if not user_sessions then + module:log("debug", "Skip carbons for offline user"); return -- No use in sending carbons to an offline user end @@ -73,6 +76,7 @@ return tag.attr.xmlns == xmlns_carbons and tag.name == "private" and tag or nil; end); + module:log("debug", "Message tagged private, ignoring"); return end @@ -80,7 +84,13 @@ user_sessions = user_sessions and user_sessions.sessions; for resource, session in pairs(user_sessions) do local full_jid = bare_jid .. "/" .. resource; + module:log("debug", "%s wants carbons: %s", session.full_jid, tostring(session.want_carbons)); if session.want_carbons then + if c2s then + module:log("debug", "Session is origin: %s", tostring(session == origin)); + else + module:log("debug", "Session is in ignore list: %s", tostring(no_carbon_to[resource])); + end if (c2s and session ~= origin) or (not c2s and not no_carbon_to[resource]) then local msg = st.clone(stanza); msg.attr.xmlns = msg.attr.xmlns or "jabber:client"; @@ -92,7 +102,8 @@ :tag(c2s and "sent" or "received", { xmlns = xmlns_carbons }):up() :tag("forwarded", { xmlns = xmlns_forward }) :add_child(msg); - core_post_stanza(origin, fwd); + module:log("debug", "Sending carbon"); + session.send(fwd); end end end diff -r b1d82ae063e1 -r b5a8e8492570 mod_cleanup_http/mod_cleanup_http.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_cleanup_http/mod_cleanup_http.lua Tue Feb 14 15:17:16 2012 +0000 @@ -0,0 +1,40 @@ +-- Auto-cleanup for Global BOSH modules. +-- Should take care of spring cleaning without messing in either the console, or restarting + +module:set_global() + +local http_modules = module:get_option("cleanup_http_modules", {}) +if type(http_modules) ~= "table" then module:log("error", "cleanup_http_modules needs to be a module.") ; return false end + +local function cleanup(data) + if data.module == "cleanup_http" then -- it's us getting unloaded destroy handler. + prosody.events.remove_handler("module-unloaded", cleanup) + elseif http_modules[data.module] then + local ports = http_modules[data.module] + + module:log("debug", "Cleaning up http handlers and ports as module %s is being unloaded.", data.module) + for _, options in ipairs(ports) do + if options.port then + httpserver.new.http_servers[options.port].handlers[options.path or "register_account"] = nil + end + end + + -- if there are no handlers left clean and close the socket, doesn't work with server_event + local event = require "core.configmanager".get("*", "core", "use_libevent") + + if not event then + for _, options in ipairs(ports) do + if options.port and not next(httpserver.new.http_servers[options.port].handlers) then + httpserver.new.http_servers[options.port] = nil + if options.interface then + for _, value in ipairs(options.interface) do + if server.getserver(value, options.port) then server.removeserver(value, options.port) end + end + else if server.getserver("*", options.port) then server.removeserver("*", options.port) end end + end + end + end + end +end + +prosody.events.add_handler("module-unloaded", cleanup) diff -r b1d82ae063e1 -r b5a8e8492570 mod_conformance_restricted/mod_conformance_restricted.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_conformance_restricted/mod_conformance_restricted.lua Tue Feb 14 15:17:16 2012 +0000 @@ -0,0 +1,34 @@ +-- Prosody IM +-- Copyright (C) 2012 Florian Zeitz +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + +local st = require "util.stanza"; + +module:hook("message/host", function (event) + local origin, stanza = event.origin, event.stanza; + local node, host, resource = jid.split(stanza.attr.to); + local body = stanza:get_child_text("body"); + + if resource ~= "conformance" then + return; -- Not interop testing + end + + if body == "PI" then + origin.send(""); + elseif body == "comment" then + origin.send(""); + elseif body == "DTD" then + origin.send("\n]>"); + elseif body == "entity" then + origin.send("&test;"); + else + local reply = st.reply(stanza); + reply:body("Send me one of: PI, comment, DTD, or entity"); + origin.send(reply); + end + + return true; +end); diff -r b1d82ae063e1 -r b5a8e8492570 mod_register_json/mod_register_json.lua --- a/mod_register_json/mod_register_json.lua Tue Feb 14 15:16:38 2012 +0000 +++ b/mod_register_json/mod_register_json.lua Tue Feb 14 15:17:16 2012 +0000 @@ -75,17 +75,14 @@ if blacklist:contains(req_body["ip"]) then module:log("warn", "Attempt of reg. submission to the JSON servlet from blacklisted address: %s", req_body["ip"]) ; return http_response(403, "The specified address is blacklisted, sorry sorry.") end if throttle_time and not whitelist:contains(req_body["ip"]) then if not recent_ips[req_body["ip"]] then - recent_ips[req_body["ip"]] = { time = os_time(), count = 1 } + recent_ips[req_body["ip"]] = os_time() else - local ip = recent_ips[req_body["ip"]] - ip.count = ip.count + 1 - - if os_time() - ip.time < throttle_time then - ip.time = os_time() + if os_time() - recent_ips[req_body["ip"]] < throttle_time then + recent_ips[req_body["ip"]] = os_time() module:log("warn", "JSON Registration request from %s has been throttled.", req_body["ip"]) return http_response(503, "Woah... How many users you want to register..? Request throttled, wait a bit and try again.") end - ip.time = os_time() + recent_ips[req_body["ip"]] = os_time() end end @@ -116,32 +113,6 @@ end -- Set it up! -function cleanup() -- it could be better if module:hook("module-unloaded", ...) actually worked. - module:log("debug", "Cleaning up handlers and stuff as module is being unloaded.") - for _, options in ipairs(ports) do - if options.port then - httpserver.new.http_servers[options.port].handlers[options.path or "register_account"] = nil - end - end - - -- if there are no handlers left clean and close the socket, doesn't work with server_event - local event = module:get_option_boolen("use_libevent", false) - - if not event then - for _, options in ipairs(ports) do - if options.port and not next(httpserver.new.http_servers[options.port].handlers) then - httpserver.new.http_servers[options.port] = nil - if options.interface then - for _, value in ipairs(options.interface) do - if server.getserver(value, options.port) then server.removeserver(value, options.port) end - end - else if server.getserver("*", options.port) then server.removeserver("*", options.port) end end - end - end - end - - prosody.events.remove_handler("module-unloaded", cleanup) -end function setup() for id, options in ipairs(ports) do @@ -150,7 +121,6 @@ else ports[id].port = 9443 end elseif options.port == 9280 and options.ssl then ports[id].port = 9443 end end httpserver.new_from_config(ports, handle_req, { base = "register_account" }) - prosody.events.add_handler("module-unloaded", cleanup) end if prosody.start_time then -- already started diff -r b1d82ae063e1 -r b5a8e8492570 mod_server_status/mod_server_status.lua --- a/mod_server_status/mod_server_status.lua Tue Feb 14 15:16:38 2012 +0000 +++ b/mod_server_status/mod_server_status.lua Tue Feb 14 15:17:16 2012 +0000 @@ -130,36 +130,8 @@ -- initialization. -- init http interface -function cleanup() -- handy, recycled from mod_register_json - module:log("debug", "Cleaning up handlers and stuff as module is being unloaded.") - for _, options in ipairs(ports) do - if options.port then - httpserver.new.http_servers[options.port].handlers[options.path or "server-status"] = nil - end - end - - local event = module:get_option_boolen("use_libevent", false) - - -- if there're no handlers left clean the socket, not sure if it works with server_select - if not event then - for _, options in ipairs(ports) do - if options.port and not next(httpserver.new.http_servers[options.port].handlers) then - httpserver.new.http_servers[options.port] = nil - if options.interface then - for _, value in ipairs(options.interface) do - if server.getserver(value, options.port) then server.removeserver(value, options.port) end - end - else if server.getserver("*", options.port) then server.removeserver("*", options.port) end end - end - end - end - - prosody.events.remove_handler("module-unloaded", cleanup) -end - local function setup() httpserver.new_from_config(ports, request, { base = "server-status" }) - prosody.events.add_handler("module-unloaded", cleanup) end if prosody.start_time then diff -r b1d82ae063e1 -r b5a8e8492570 mod_stanza_counter/mod_stanza_counter_http.lua --- a/mod_stanza_counter/mod_stanza_counter_http.lua Tue Feb 14 15:16:38 2012 +0000 +++ b/mod_stanza_counter/mod_stanza_counter_http.lua Tue Feb 14 15:17:16 2012 +0000 @@ -44,36 +44,8 @@ -- initialization. -- init http and cleanup interface -function cleanup() -- recycled from mod_register_json, it's handy - module:log("debug", "Cleaning up handlers and stuff as module is being unloaded.") - for _, options in ipairs(ports) do - if options.port then - httpserver.new.http_servers[options.port].handlers[options.path or "stanza-counter"] = nil - end - end - - -- if there are no handlers left clean and close the socket, doesn't work with server_event - local event = module:get_option_boolen("use_libevent", false) - - if not event then - for _, options in ipairs(ports) do - if options.port and not next(httpserver.new.http_servers[options.port].handlers) then - httpserver.new.http_servers[options.port] = nil - if options.interface then - for _, value in ipairs(options.interface) do - if server.getserver(value, options.port) then server.removeserver(value, options.port) end - end - else if server.getserver("*", options.port) then server.removeserver("*", options.port) end end - end - end - end - - prosody.events.remove_handler("module-unloaded", cleanup) -end - local function setup() httpserver.new_from_config(ports, req, { base = "stanza-counter" }) - prosody.events.add_handler("module-unloaded", cleanup) end -- set it