From 48162c5fca869aa8adefc5dc7e8a58bf1ce40c20 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 1 Nov 2018 23:58:41 +0100 Subject: mod_pep: Remove incorrect features advertised on the bare host --- plugins/mod_pep.lua | 3 --- 1 file changed, 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index 1d8c55bf..cb775fb5 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -250,9 +250,6 @@ end module:hook("iq/bare/"..xmlns_pubsub..":pubsub", handle_pubsub_iq); module:hook("iq/bare/"..xmlns_pubsub_owner..":pubsub", handle_pubsub_iq); -module:add_identity("pubsub", "pep", module:get_option_string("name", "Prosody")); -module:add_feature("http://jabber.org/protocol/pubsub#publish"); - local function get_caps_hash_from_presence(stanza, current) local t = stanza.attr.type; if not t then -- cgit v1.2.3 From 1682a8437de2afe9e01d5e4daaa87f56d7af7f6b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 10 Nov 2018 15:50:32 +0100 Subject: MUC: Fix spelling in comments --- plugins/muc/muc.lib.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 4060535a..d9fa37f5 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -39,7 +39,7 @@ function room_mt:__tostring() end function room_mt.save() - -- overriden by mod_muc.lua + -- overridden by mod_muc.lua end function room_mt:get_occupant_jid(real_jid) @@ -279,7 +279,7 @@ function room_mt:publicise_occupant_status(occupant, x, nick, actor, reason) self_p = st.clone(base_presence):add_child(self_x); end - -- General populance + -- General populace for occupant_nick, n_occupant in self:each_occupant() do if occupant_nick ~= occupant.nick then local pr; @@ -609,7 +609,7 @@ function room_mt:handle_normal_presence(origin, stanza) x:tag("status", {code = "303";}):up(); x:tag("status", {code = "110";}):up(); self:route_stanza(generated_unavail:add_child(x)); - dest_nick = nil; -- set dest_nick to nil; so general populance doesn't see it for whole orig_occupant + dest_nick = nil; -- set dest_nick to nil; so general populace doesn't see it for whole orig_occupant end end @@ -966,7 +966,7 @@ function room_mt:handle_admin_query_get_command(origin, stanza) local _aff_rank = valid_affiliations[_aff or "none"]; local _rol = item.attr.role; if _aff and _aff_rank and not _rol then - -- You need to be at least an admin, and be requesting info about your affifiliation or lower + -- You need to be at least an admin, and be requesting info about your affiliation or lower -- e.g. an admin can't ask for a list of owners local affiliation_rank = valid_affiliations[affiliation or "none"]; if (affiliation_rank >= valid_affiliations.admin and affiliation_rank >= _aff_rank) @@ -1291,7 +1291,7 @@ function room_mt:set_affiliation(actor, jid, affiliation, reason, data) -- Outcast can be by host. is_host_only and affiliation == "outcast" and select(2, jid_split(occupant.bare_jid)) == host ) then - -- need to publcize in all cases; as affiliation in has changed. + -- need to publicize in all cases; as affiliation in has changed. occupants_updated[occupant] = occupant.role; if occupant.role ~= role and ( is_downgrade or -- cgit v1.2.3 From c309d32629c0b0f103f32dda5506528e2e1f468b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 27 Nov 2018 17:01:47 +0100 Subject: MUC: Move check for explicit room join earlier in room creation flow --- plugins/muc/mod_muc.lua | 2 +- plugins/muc/muc.lib.lua | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 954bae92..89e67744 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -453,7 +453,7 @@ for event_name, method in pairs { if room == nil then -- Watch presence to create rooms - if stanza.attr.type == nil and stanza.name == "presence" then + if stanza.attr.type == nil and stanza.name == "presence" and stanza:get_child("x", "http://jabber.org/protocol/muc") then room = muclib.new_room(room_jid); return room:handle_first_presence(origin, stanza); elseif stanza.attr.type ~= "error" then diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 96f58023..0009e9b2 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -428,13 +428,6 @@ module:hook("muc-occupant-pre-change", function(event) end, 1); function room_mt:handle_first_presence(origin, stanza) - if not stanza:get_child("x", "http://jabber.org/protocol/muc") then - module:log("debug", "Room creation without , possibly desynced"); - - origin.send(st.error_reply(stanza, "cancel", "item-not-found")); - return true; - end - local real_jid = stanza.attr.from; local dest_jid = stanza.attr.to; local bare_jid = jid_bare(real_jid); -- cgit v1.2.3 From 38b328ad1be357a028a818eaad7c6c3541ac6759 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 1 Dec 2018 22:13:24 +0000 Subject: rostermanager, mod_presence: Store stanza for incoming subscription requests (fixes #689) (thanks Zash, Ge0rG) --- plugins/mod_presence.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_presence.lua b/plugins/mod_presence.lua index 5056a3a3..51254c63 100644 --- a/plugins/mod_presence.lua +++ b/plugins/mod_presence.lua @@ -80,8 +80,10 @@ function handle_normal_presence(origin, stanza) res.presence.attr.to = nil; end end - for jid in pairs(roster[false].pending) do -- resend incoming subscription requests - origin.send(st.presence({type="subscribe", from=jid})); -- TODO add to attribute? Use original? + for jid, pending_request in pairs(roster[false].pending) do -- resend incoming subscription requests + local subscribe = st.clone(st.deserialize(pending_request)); + subscribe.attr.type, subscribe.attr.from = "subscribe", jid; + origin.send(subscribe); end local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host}); for jid, item in pairs(roster) do -- resend outgoing subscription requests @@ -225,7 +227,7 @@ function handle_inbound_presence_subscriptions_and_probes(origin, stanza, from_b else core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"}), true); -- acknowledging receipt if not rostermanager.is_contact_pending_in(node, host, from_bare) then - if rostermanager.set_contact_pending_in(node, host, from_bare) then + if rostermanager.set_contact_pending_in(node, host, from_bare, stanza) then sessionmanager.send_to_available_resources(node, host, stanza); end -- TODO else return error, unable to save end -- cgit v1.2.3 From e984432ca4a85a2e9abef99b667731d8541ed662 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 2 Dec 2018 17:20:44 +0100 Subject: mod_presence: Remove unnecessary stanza clone call --- plugins/mod_presence.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_presence.lua b/plugins/mod_presence.lua index 51254c63..1ea837e8 100644 --- a/plugins/mod_presence.lua +++ b/plugins/mod_presence.lua @@ -81,7 +81,7 @@ function handle_normal_presence(origin, stanza) end end for jid, pending_request in pairs(roster[false].pending) do -- resend incoming subscription requests - local subscribe = st.clone(st.deserialize(pending_request)); + local subscribe = st.deserialize(pending_request); subscribe.attr.type, subscribe.attr.from = "subscribe", jid; origin.send(subscribe); end -- cgit v1.2.3 From aa3cfe1ea0241eeb60d09ad11bd2727d28887a7d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 2 Dec 2018 17:22:26 +0100 Subject: mod_presence: Handle older boolean subscription request data (thanks Martin) --- plugins/mod_presence.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_presence.lua b/plugins/mod_presence.lua index 1ea837e8..5aed5854 100644 --- a/plugins/mod_presence.lua +++ b/plugins/mod_presence.lua @@ -81,9 +81,13 @@ function handle_normal_presence(origin, stanza) end end for jid, pending_request in pairs(roster[false].pending) do -- resend incoming subscription requests - local subscribe = st.deserialize(pending_request); - subscribe.attr.type, subscribe.attr.from = "subscribe", jid; - origin.send(subscribe); + if type(pending_request) == "table" then + local subscribe = st.deserialize(pending_request); + subscribe.attr.type, subscribe.attr.from = "subscribe", jid; + origin.send(subscribe); + else + origin.send(st.presence({type="subscribe", from=jid})); + end end local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host}); for jid, item in pairs(roster) do -- resend outgoing subscription requests -- cgit v1.2.3 From 27083633e2ef371a834b30c654fefb6fe665bc8a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 4 Dec 2018 19:49:31 +0100 Subject: MUC/subject: Don't consider messages with or (fixes #667) --- plugins/muc/subject.lib.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'plugins') diff --git a/plugins/muc/subject.lib.lua b/plugins/muc/subject.lib.lua index 938abf61..c8b99cc7 100644 --- a/plugins/muc/subject.lib.lua +++ b/plugins/muc/subject.lib.lua @@ -94,6 +94,12 @@ module:hook("muc-occupant-groupchat", function(event) local stanza = event.stanza; local subject = stanza:get_child("subject"); if subject then + if stanza:get_child("body") or stanza:get_child("thread") then + -- Note: A message with a and a or a and + -- a is a legitimate message, but it SHALL NOT be interpreted + -- as a subject change. + return; + end local room = event.room; local occupant = event.occupant; -- Role check for subject changes -- cgit v1.2.3 From 6dcf53f7b284f265ce3f2215e33c6f0c28be5ce9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 8 Dec 2018 17:09:55 +0100 Subject: various: Don't rely on _G.unpack existing --- plugins/mod_admin_telnet.lua | 1 + plugins/mod_pep_simple.lua | 1 + plugins/mod_storage_sql.lua | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 1cbe27a4..8a3508db 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -22,6 +22,7 @@ local prosody = _G.prosody; local console_listener = { default_port = 5582; default_mode = "*a"; interface = "127.0.0.1" }; +local unpack = table.unpack or unpack; -- luacheck: ignore 113 local iterators = require "util.iterators"; local keys, values = iterators.keys, iterators.values; local jid_bare, jid_split, jid_join = import("util.jid", "bare", "prepped_split", "join"); diff --git a/plugins/mod_pep_simple.lua b/plugins/mod_pep_simple.lua index f0b5d7ef..f91e5448 100644 --- a/plugins/mod_pep_simple.lua +++ b/plugins/mod_pep_simple.lua @@ -14,6 +14,7 @@ local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed local pairs = pairs; local next = next; local type = type; +local unpack = table.unpack or unpack; -- luacheck: ignore 113 local calculate_hash = require "util.caps".calculate_hash; local core_post_stanza = prosody.core_post_stanza; local bare_sessions = prosody.bare_sessions; diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 56cef569..5c0c0208 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -11,7 +11,7 @@ local is_stanza = require"util.stanza".is_stanza; local t_concat = table.concat; local noop = function() end -local unpack = table.unpack or unpack; +local unpack = table.unpack or unpack; -- luacheck: ignore 113 local function iterator(result) return function(result_) local row = result_(); -- cgit v1.2.3 From 91e23f83983af91b65287c209caa54f9027a6487 Mon Sep 17 00:00:00 2001 From: Maxime ?pep? Buquet Date: Tue, 18 Dec 2018 20:23:33 +0000 Subject: admin_telnet: show when bidi is used on s2s --- plugins/mod_admin_telnet.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 8a3508db..63136d63 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -521,6 +521,9 @@ local function session_flags(session, line) if session.remote then line[#line+1] = "(remote)"; end + if session.is_bidi then + line[#line+1] = "(bidi)"; + end return table.concat(line, " "); end -- cgit v1.2.3 From ed48077ce4b5ac8310270edb93c7d68a88cf0602 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 23 Dec 2018 02:50:22 +0100 Subject: mod_pubsub: Add semicolon (code style) --- plugins/mod_pubsub/mod_pubsub.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_pubsub/mod_pubsub.lua b/plugins/mod_pubsub/mod_pubsub.lua index 40adcafe..1edc721b 100644 --- a/plugins/mod_pubsub/mod_pubsub.lua +++ b/plugins/mod_pubsub/mod_pubsub.lua @@ -73,7 +73,7 @@ function simple_broadcast(kind, node, jids, item, actor, node_obj) local msg_type = node_obj and node_obj.config.message_type or "headline"; local message = st.message({ from = module.host, type = msg_type, id = id }) :tag("event", { xmlns = xmlns_pubsub_event }) - :tag(kind, { node = node }) + :tag(kind, { node = node }); if item then message:add_child(item); -- cgit v1.2.3 From 4cbf600434638bcb53c8defb767a076135ab8f24 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 23 Dec 2018 02:53:12 +0100 Subject: mod_pep: Move broadcaster code around to be more like in mod_pubsub This eases comparing and contrasting these two modules. --- plugins/mod_pep.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index cb775fb5..40385616 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -136,9 +136,6 @@ local function get_broadcaster(username) if kind == "retract" then kind = "items"; -- XEP-0060 signals retraction in an container end - local message = st.message({ from = user_bare, type = "headline" }) - :tag("event", { xmlns = xmlns_pubsub_event }) - :tag(kind, { node = node }); if item then item = st.clone(item); item.attr.xmlns = nil; -- Clear the pubsub namespace @@ -147,6 +144,12 @@ local function get_broadcaster(username) item:maptags(function () return nil; end); end end + end + + local message = st.message({ from = user_bare, type = "headline" }) + :tag("event", { xmlns = xmlns_pubsub_event }) + :tag(kind, { node = node }); + if item then message:add_child(item); end for jid in pairs(jids) do -- cgit v1.2.3 From 36d31b94bf54bac423fdeac12c4978d22ca1b6f8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 23 Dec 2018 02:54:39 +0100 Subject: mod_pep: Add some spacing between blocks in broadcaster to improve readability --- plugins/mod_pep.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index 40385616..6275d47c 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -136,6 +136,7 @@ local function get_broadcaster(username) if kind == "retract" then kind = "items"; -- XEP-0060 signals retraction in an container end + if item then item = st.clone(item); item.attr.xmlns = nil; -- Clear the pubsub namespace @@ -149,9 +150,11 @@ local function get_broadcaster(username) local message = st.message({ from = user_bare, type = "headline" }) :tag("event", { xmlns = xmlns_pubsub_event }) :tag(kind, { node = node }); + if item then message:add_child(item); end + for jid in pairs(jids) do module:log("debug", "Sending notification to %s from %s: %s", jid, user_bare, tostring(item)); message.attr.to = jid; -- cgit v1.2.3 From b4e3b4ea25135148113b1fce6207b28889a4eb7e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 23 Dec 2018 02:56:10 +0100 Subject: mod_pep: Set an 'id' on notifications mod_pubsub got this in f2d35eee69c9 --- plugins/mod_pep.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index 6275d47c..5e3f43f2 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -8,6 +8,7 @@ local calculate_hash = require "util.caps".calculate_hash; local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed; local cache = require "util.cache"; local set = require "util.set"; +local new_id = require "util.id".medium; local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; local xmlns_pubsub_event = "http://jabber.org/protocol/pubsub#event"; @@ -147,7 +148,8 @@ local function get_broadcaster(username) end end - local message = st.message({ from = user_bare, type = "headline" }) + local id = new_id(); + local message = st.message({ from = user_bare, type = "headline", id = id }) :tag("event", { xmlns = xmlns_pubsub_event }) :tag(kind, { node = node }); -- cgit v1.2.3 From 6c573bacf091c7fe4e15591833639003b2519a3b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 23 Dec 2018 03:05:58 +0100 Subject: mod_pubsub: Change order of luacheck directives to match arguments they apply to --- plugins/mod_pubsub/mod_pubsub.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_pubsub/mod_pubsub.lua b/plugins/mod_pubsub/mod_pubsub.lua index 1edc721b..abc4fee8 100644 --- a/plugins/mod_pubsub/mod_pubsub.lua +++ b/plugins/mod_pubsub/mod_pubsub.lua @@ -99,7 +99,7 @@ function simple_broadcast(kind, node, jids, item, actor, node_obj) end local max_max_items = module:get_option_number("pubsub_max_items", 256); -function check_node_config(node, actor, new_config) -- luacheck: ignore 212/actor 212/node +function check_node_config(node, actor, new_config) -- luacheck: ignore 212/node 212/actor if (new_config["max_items"] or 1) > max_max_items then return false; end -- cgit v1.2.3 From d39cf4f42e2ec7afff198437a7ccb82f8b7664ab Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 23 Dec 2018 03:06:35 +0100 Subject: mod_pubsub: Split line in config check to improve readability Also makes it easier to compare with mod_pep --- plugins/mod_pubsub/mod_pubsub.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_pubsub/mod_pubsub.lua b/plugins/mod_pubsub/mod_pubsub.lua index abc4fee8..0036b48f 100644 --- a/plugins/mod_pubsub/mod_pubsub.lua +++ b/plugins/mod_pubsub/mod_pubsub.lua @@ -103,7 +103,8 @@ function check_node_config(node, actor, new_config) -- luacheck: ignore 212/node if (new_config["max_items"] or 1) > max_max_items then return false; end - if new_config["access_model"] ~= "whitelist" and new_config["access_model"] ~= "open" then + if new_config["access_model"] ~= "whitelist" + and new_config["access_model"] ~= "open" then return false; end return true; -- cgit v1.2.3 From 07ab17120c03070c138137dd30d3fb601716a8bc Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 28 Dec 2018 20:56:01 +0100 Subject: mod_admin_telnet: Invert host existence check Simplifies and reduces indentation --- plugins/mod_admin_telnet.lua | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 63136d63..5ba88b84 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1067,13 +1067,12 @@ def_env.xmpp = {}; local st = require "util.stanza"; function def_env.xmpp:ping(localhost, remotehost) - if prosody.hosts[localhost] then - module:send(st.iq{ from=localhost, to=remotehost, type="get", id="ping" } - :tag("ping", {xmlns="urn:xmpp:ping"}), prosody.hosts[localhost]); - return true, "Sent ping"; - else + if not prosody.hosts[localhost] then return nil, "No such host"; end + module:send(st.iq{ from=localhost, to=remotehost, type="get", id="ping" } + :tag("ping", {xmlns="urn:xmpp:ping"}), prosody.hosts[localhost]); + return true, "Sent ping"; end def_env.dns = {}; -- cgit v1.2.3 From b1b7f0261f054bf83a955e073dbdeb9631518097 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 27 Dec 2018 02:53:34 +0100 Subject: mod_admin_telnet: Enable async processing using util.async --- plugins/mod_admin_telnet.lua | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 5ba88b84..bb97a09b 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -31,6 +31,7 @@ local cert_verify_identity = require "util.x509".verify_identity; local envload = require "util.envload".envload; local envloadfile = require "util.envload".envloadfile; local has_pposix, pposix = pcall(require, "util.pposix"); +local async = require "util.async"; local commands = module:shared("commands") local def_env = module:shared("env"); @@ -48,6 +49,21 @@ end console = {}; +local runner_callbacks = {}; + +function runner_callbacks:ready() + self.data.conn:resume(); +end + +function runner_callbacks:waiting() + self.data.conn:pause(); +end + +function runner_callbacks:error(err) + module:log("error", "Traceback[telnet]: %s", err); +end + + function console:new_session(conn) local w = function(s) conn:write(s:gsub("\n", "\r\n")); end; local session = { conn = conn; @@ -63,6 +79,11 @@ function console:new_session(conn) }; session.env = setmetatable({}, default_env_mt); + session.thread = async.runner(function (line) + console:process_line(session, line); + session.send(string.char(0)); + end, runner_callbacks, session); + -- Load up environment with helper objects for name, t in pairs(def_env) do if type(t) == "table" then @@ -151,8 +172,7 @@ function console_listener.onincoming(conn, data) for line in data:gmatch("[^\n]*[\n\004]") do if session.closed then return end - console:process_line(session, line); - session.send(string.char(0)); + session.thread:run(line); end session.partial_data = data:match("[^\n]+$"); end -- cgit v1.2.3 From 01878444937fe8b7ea149ef35cd76453517bf798 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 28 Dec 2018 20:59:10 +0100 Subject: mod_admin_telnet: Make xmpp:ping command wait and report the reply --- plugins/mod_admin_telnet.lua | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index bb97a09b..ee6a4176 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1086,13 +1086,28 @@ end def_env.xmpp = {}; local st = require "util.stanza"; -function def_env.xmpp:ping(localhost, remotehost) +local new_id = require "util.id".medium; +function def_env.xmpp:ping(localhost, remotehost, timeout) if not prosody.hosts[localhost] then return nil, "No such host"; end - module:send(st.iq{ from=localhost, to=remotehost, type="get", id="ping" } - :tag("ping", {xmlns="urn:xmpp:ping"}), prosody.hosts[localhost]); - return true, "Sent ping"; + local iq = st.iq{ from=localhost, to=remotehost, type="get", id=new_id()} + :tag("ping", {xmlns="urn:xmpp:ping"}); + local ret, err; + local wait, done = async.waiter(); + module:context(localhost):send_iq(iq, nil, timeout) + :next(function (ret_) ret = ret_; end, + function (err_) err = err_; end) + :finally(done); + wait(); + if ret then + return true, "pong from " .. ret.stanza.attr.from; + elseif type(err) == "table" and st.is_stanza(err.stanza) then + local t, cond, text = err.stanza:get_error(); + return false, text or cond or t; + else + return false, tostring(err); + end end def_env.dns = {}; -- cgit v1.2.3 From f8bc92174749c64b3804b8ad46f47dfceb107312 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 24 Nov 2018 02:24:48 +0100 Subject: mod_saslauth: Improve log message when no SASL mechanisms offered (thanks hexa) --- plugins/mod_saslauth.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index fba84ef8..ba30b9e6 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -275,7 +275,8 @@ module:hook("stream-features", function(event) if mechanisms[1] then features:add_child(mechanisms); elseif not next(sasl_mechanisms) then - log("warn", "No available SASL mechanisms, verify that the configured authentication module is working"); + local authmod = module:get_option_string("authentication", "internal_plain"); + log("error", "No available SASL mechanisms, verify that the configured authentication module '%s' is loaded and configured correctly", authmod); else log("warn", "All available authentication mechanisms are either disabled or not suitable for an insecure connection"); end -- cgit v1.2.3 From da5ec59b36188e325ed6dc9fa6ebf8187d492b33 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 28 Dec 2018 00:13:03 +0100 Subject: mod_c2s: Improve log message in case there are no stream features on offer (thanks hexa) --- plugins/mod_c2s.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 8e31a968..36e6a152 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -106,7 +106,13 @@ function stream_callbacks.streamopened(session, attr) if features.tags[1] or session.full_jid then send(features); else - (session.log or log)("warn", "No stream features to offer"); + if session.secure then + -- Normally STARTTLS would be offered + (session.log or log)("warn", "No stream features to offer on secure session. Check authentication settings."); + else + -- Here SASL should be offered + (session.log or log)("warn", "No stream features to offer on insecure session. Check encryption and security settings."); + end session:close{ condition = "undefined-condition", text = "No stream features to proceed with" }; end end -- cgit v1.2.3 From 3f9505a0d5ce144beb79748bc783e06862693129 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 28 Dec 2018 00:04:26 +0100 Subject: mod_tls: Keep TLS context errors and repeat them again for each session --- plugins/mod_tls.lua | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_tls.lua b/plugins/mod_tls.lua index 029ddd1d..4ead60dc 100644 --- a/plugins/mod_tls.lua +++ b/plugins/mod_tls.lua @@ -35,9 +35,10 @@ local host = hosts[module.host]; local ssl_ctx_c2s, ssl_ctx_s2sout, ssl_ctx_s2sin; local ssl_cfg_c2s, ssl_cfg_s2sout, ssl_cfg_s2sin; +local err_c2s, err_s2sin, err_s2sout; function module.load() - local NULL, err = {}; + local NULL = {}; local modhost = module.host; local parent = modhost:match("%.(.*)$"); @@ -52,14 +53,14 @@ function module.load() local parent_s2s = rawgetopt(parent, "s2s_ssl") or NULL; local host_s2s = rawgetopt(modhost, "s2s_ssl") or parent_s2s; - ssl_ctx_c2s, err, ssl_cfg_c2s = create_context(host.host, "server", host_c2s, host_ssl, global_c2s); -- for incoming client connections - if not ssl_ctx_c2s then module:log("error", "Error creating context for c2s: %s", err); end + ssl_ctx_c2s, err_c2s, ssl_cfg_c2s = create_context(host.host, "server", host_c2s, host_ssl, global_c2s); -- for incoming client connections + if not ssl_ctx_c2s then module:log("error", "Error creating context for c2s: %s", err_c2s); end - ssl_ctx_s2sout, err, ssl_cfg_s2sout = create_context(host.host, "client", host_s2s, host_ssl, global_s2s); -- for outgoing server connections - if not ssl_ctx_s2sout then module:log("error", "Error creating contexts for s2sout: %s", err); end + ssl_ctx_s2sout, err_s2sout, ssl_cfg_s2sout = create_context(host.host, "client", host_s2s, host_ssl, global_s2s); -- for outgoing server connections + if not ssl_ctx_s2sout then module:log("error", "Error creating contexts for s2sout: %s", err_s2sout); end - ssl_ctx_s2sin, err, ssl_cfg_s2sin = create_context(host.host, "server", host_s2s, host_ssl, global_s2s); -- for incoming server connections - if not ssl_ctx_s2sin then module:log("error", "Error creating contexts for s2sin: %s", err); end + ssl_ctx_s2sin, err_s2sin, ssl_cfg_s2sin = create_context(host.host, "server", host_s2s, host_ssl, global_s2s); -- for incoming server connections + if not ssl_ctx_s2sin then module:log("error", "Error creating contexts for s2sin: %s", err_s2sin); end end module:hook_global("config-reloaded", module.load); @@ -74,12 +75,21 @@ local function can_do_tls(session) return session.ssl_ctx; end if session.type == "c2s_unauthed" then + if not ssl_ctx_c2s and c2s_require_encryption then + session.log("error", "No TLS context available for c2s. Earlier error was: %s", err_c2s); + end session.ssl_ctx = ssl_ctx_c2s; session.ssl_cfg = ssl_cfg_c2s; elseif session.type == "s2sin_unauthed" and allow_s2s_tls then + if not ssl_ctx_s2sin and s2s_require_encryption then + session.log("error", "No TLS context available for s2sin. Earlier error was: %s", err_s2sin); + end session.ssl_ctx = ssl_ctx_s2sin; session.ssl_cfg = ssl_cfg_s2sin; elseif session.direction == "outgoing" and allow_s2s_tls then + if not ssl_ctx_s2sout and s2s_require_encryption then + session.log("error", "No TLS context available for s2sout. Earlier error was: %s", err_s2sout); + end session.ssl_ctx = ssl_ctx_s2sout; session.ssl_cfg = ssl_cfg_s2sout; else -- cgit v1.2.3 From 708dc874279d00235cb729b61f7438e753bd8008 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 29 Dec 2018 03:21:13 +0100 Subject: mod_admin_telnet: Validate hostnames in xmpp:ping command Attempt to ping some invalid hostnames cause weird behavior --- plugins/mod_admin_telnet.lua | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index ee6a4176..f3731c8a 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1088,8 +1088,17 @@ def_env.xmpp = {}; local st = require "util.stanza"; local new_id = require "util.id".medium; function def_env.xmpp:ping(localhost, remotehost, timeout) - if not prosody.hosts[localhost] then - return nil, "No such host"; + localhost = select(2, jid_split(localhost)); + remotehost = select(2, jid_split(remotehost)); + if not localhost then + return nil, "Invalid sender hostname"; + elseif not prosody.hosts[localhost] then + return nil, "No such local host"; + end + if not remotehost then + return nil, "Invalid destination hostname"; + elseif prosody.hosts[remotehost] then + return nil, "Both hosts are local"; end local iq = st.iq{ from=localhost, to=remotehost, type="get", id=new_id()} :tag("ping", {xmlns="urn:xmpp:ping"}); -- cgit v1.2.3 From ad3e5fd42bd1dddd478fffd412a842e98c735e9a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 30 Dec 2018 16:03:15 +0100 Subject: core.moduleapi: Use util.error for :send_iq errors --- plugins/mod_admin_telnet.lua | 3 --- 1 file changed, 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index f3731c8a..5bb9361e 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1111,9 +1111,6 @@ function def_env.xmpp:ping(localhost, remotehost, timeout) wait(); if ret then return true, "pong from " .. ret.stanza.attr.from; - elseif type(err) == "table" and st.is_stanza(err.stanza) then - local t, cond, text = err.stanza:get_error(); - return false, text or cond or t; else return false, tostring(err); end -- cgit v1.2.3 From e4087a66e42e86ea4aae8d6cba1bc7dbb66ecb87 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 3 Jan 2019 17:25:43 +0100 Subject: mod_mam: Perform message expiry based on building an index by date For each day, store a set of users that have new messages. To expire messages, we collect the union of sets of users from dates that fall outside the cleanup range. The previous algoritm did not work well with many users, especially with the default settings. --- plugins/mod_mam/mod_mam.lua | 70 +++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 31 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index 94bedbb1..18f84752 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -33,7 +33,7 @@ local is_stanza = st.is_stanza; local tostring = tostring; local time_now = os.time; local m_min = math.min; -local timestamp, timestamp_parse = require "util.datetime".datetime, require "util.datetime".parse; +local timestamp, timestamp_parse, datestamp = import( "util.datetime", "datetime", "parse", "date"); local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", 50); local strip_tags = module:get_option_set("dont_archive_namespaces", { "http://jabber.org/protocol/chatstates" }); @@ -46,13 +46,8 @@ if not archive.find then end local use_total = module:get_option_boolean("mam_include_total", true); -local cleanup; - -local function schedule_cleanup(username) - if cleanup and not cleanup[username] then - table.insert(cleanup, username); - cleanup[username] = true; - end +function schedule_cleanup() + -- replaced by non-noop later if cleanup is enabled end -- Handle prefs. @@ -96,7 +91,6 @@ module:hook("iq-set/self/"..xmlns_mam..":query", function(event) local qid = query.attr.queryid; get_prefs(origin.username, true); - schedule_cleanup(origin.username); -- Search query parameters local qwith, qstart, qend; @@ -212,6 +206,7 @@ end local function shall_store(user, who) -- TODO Cache this? if not um.user_exists(user, host) then + module:log("debug", "%s@%s does not exist", user, host) return false; end local prefs = get_prefs(user); @@ -329,6 +324,9 @@ module:hook("pre-message/full", strip_stanza_id_after_other_events, -1); local cleanup_after = module:get_option_string("archive_expires_after", "1w"); local cleanup_interval = module:get_option_number("archive_cleanup_interval", 4 * 60 * 60); if cleanup_after ~= "never" then + local cleanup_storage = module:open_store("archive_cleanup"); + local cleanup_map = module:open_store("archive_cleanup", "map"); + local day = 86400; local multipliers = { d = day, w = day * 7, m = 31 * day, y = 365.2425 * day }; local n, m = cleanup_after:lower():match("(%d+)%s*([dwmy]?)"); @@ -346,33 +344,43 @@ if cleanup_after ~= "never" then return false; end - -- Set of known users to do message expiry for - -- Populated either below or when new messages are added - cleanup = {}; + -- For each day, store a set of users that have new messages. To expire + -- messages, we collect the union of sets of users from dates that fall + -- outside the cleanup range. - -- Iterating over users is not supported by all authentication modules - -- Catch and ignore error if not supported - pcall(function () - -- If this works, then we schedule cleanup for all known users on startup - for user in um.users(module.host) do - schedule_cleanup(user); - end - end); + function schedule_cleanup(username, date) + cleanup_map:set(date or datestamp(), username, true); + end - -- At odd intervals, delete old messages for one user - module:add_timer(math.random(10, 60), function() - local user = table.remove(cleanup, 1); - if user then - module:log("debug", "Removing old messages for user %q", user); + cleanup_runner = require "util.async".runner(function () + local users = {}; + local cut_off = datestamp(os.time() - cleanup_after); + for date in cleanup_storage:users() do + if date < cut_off then + module:log("debug", "Messages from %q should be expired", date); + local messages_this_day = cleanup_storage:get(date); + if messages_this_day then + for user in pairs(messages_this_day) do + users[user] = true; + end + cleanup_storage:set(date, nil); + end + end + end + local sum, num_users = 0, 0; + for user in pairs(users) do local ok, err = archive:delete(user, { ["end"] = os.time() - cleanup_after; }) - if not ok then - module:log("warn", "Could not expire archives for user %s: %s", user, err); - elseif type(ok) == "number" then - module:log("debug", "Removed %d messages", ok); + if ok then + num_users = num_users + 1; + sum = sum + tonumber(ok) or 0; end - cleanup[user] = nil; end - return math.random(cleanup_interval, cleanup_interval * 2); + module:log("info", "Deleted expired %d messages for %d users", sum, num_users); + end); + + cleanup_task = module:add_timer(1, function () + cleanup_runner:run(true); + return cleanup_interval; end); else module:log("debug", "Archive expiry disabled"); -- cgit v1.2.3 From 76f85eb776b39feeb37c8dd276fcd9eaf6c722c7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 4 Jan 2019 10:14:55 +0100 Subject: mod_mam: Fix word order in log message --- plugins/mod_mam/mod_mam.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index 18f84752..35a4b9a0 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -375,7 +375,7 @@ if cleanup_after ~= "never" then sum = sum + tonumber(ok) or 0; end end - module:log("info", "Deleted expired %d messages for %d users", sum, num_users); + module:log("info", "Deleted %d expired messages for %d users", sum, num_users); end); cleanup_task = module:add_timer(1, function () -- cgit v1.2.3 From 1271c21c89d544ad3d34526f9317c952092c0658 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 4 Jan 2019 13:38:30 +0100 Subject: mod_admin_telnet: Remove the long gone 'section' argument in the undocumented config:get command --- plugins/mod_admin_telnet.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 5bb9361e..4c049b95 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -495,9 +495,9 @@ function def_env.config:load(filename, format) return true, "Config loaded"; end -function def_env.config:get(host, section, key) +function def_env.config:get(host, key) local config_get = require "core.configmanager".get - return true, tostring(config_get(host, section, key)); + return true, tostring(config_get(host, key)); end function def_env.config:reload() -- cgit v1.2.3 From ce8379079e7e0fae9b292a7a8ce6ddd91a4f6e46 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 4 Jan 2019 13:39:13 +0100 Subject: mod_admin_telnet: config:get: Assume the global section if only one argument is given --- plugins/mod_admin_telnet.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 4c049b95..c6b67b95 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -496,6 +496,9 @@ function def_env.config:load(filename, format) end function def_env.config:get(host, key) + if key == nil then + host, key = "*", host; + end local config_get = require "core.configmanager".get return true, tostring(config_get(host, key)); end -- cgit v1.2.3 From f902e414f63ae70f74c414a57c0c3cfe26ba693d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 4 Jan 2019 13:41:39 +0100 Subject: mod_admin_telnet: Serialize config values (table: 0x123abc isn't useful) --- plugins/mod_admin_telnet.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index c6b67b95..cd9f8078 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -32,6 +32,7 @@ local envload = require "util.envload".envload; local envloadfile = require "util.envload".envloadfile; local has_pposix, pposix = pcall(require, "util.pposix"); local async = require "util.async"; +local serialize = require "util.serialization".new({ fatal = false, unquoted = true}); local commands = module:shared("commands") local def_env = module:shared("env"); @@ -500,7 +501,7 @@ function def_env.config:get(host, key) host, key = "*", host; end local config_get = require "core.configmanager".get - return true, tostring(config_get(host, key)); + return true, serialize(config_get(host, key)); end function def_env.config:reload() -- cgit v1.2.3 From 9e01c3ff642670c8b10a20686f7a6e100ad08fe9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 4 Jan 2019 15:13:52 +0100 Subject: mod_admin_telnet: Sort stats by name --- plugins/mod_admin_telnet.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index cd9f8078..5ce504f8 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1543,7 +1543,7 @@ function def_env.stats:show(filter) local stats, changed, extra = require "core.statsmanager".get_stats(); local available, displayed = 0, 0; local displayed_stats = new_stats_context(self); - for name, value in pairs(stats) do + for name, value in iterators.sorted_pairs(stats) do available = available + 1; if not filter or name:match(filter) then displayed = displayed + 1; -- cgit v1.2.3 From fa09b8372d173408df3cb468d9e1b5098c783f31 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 6 Jan 2019 09:34:59 +0100 Subject: mod_mam: Measure how long it takes to run the message expiry job job --- plugins/mod_mam/mod_mam.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index 35a4b9a0..5ba04d68 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -351,8 +351,10 @@ if cleanup_after ~= "never" then function schedule_cleanup(username, date) cleanup_map:set(date or datestamp(), username, true); end + local cleanup_time = module:measure("cleanup", "times"); cleanup_runner = require "util.async".runner(function () + local cleanup_done = cleanup_time(); local users = {}; local cut_off = datestamp(os.time() - cleanup_after); for date in cleanup_storage:users() do @@ -376,6 +378,7 @@ if cleanup_after ~= "never" then end end module:log("info", "Deleted %d expired messages for %d users", sum, num_users); + cleanup_done(); end); cleanup_task = module:add_timer(1, function () -- cgit v1.2.3 From d9e14b0e994443bb64eaae05b080a44929b8d03d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 6 Jan 2019 09:44:55 +0100 Subject: mod_mam: Handle expiry of messages that expire in the middle of the cut-off day --- plugins/mod_mam/mod_mam.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index 5ba04d68..d2ca709b 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -358,14 +358,18 @@ if cleanup_after ~= "never" then local users = {}; local cut_off = datestamp(os.time() - cleanup_after); for date in cleanup_storage:users() do - if date < cut_off then + if date <= cut_off then module:log("debug", "Messages from %q should be expired", date); local messages_this_day = cleanup_storage:get(date); if messages_this_day then for user in pairs(messages_this_day) do users[user] = true; end - cleanup_storage:set(date, nil); + if date < cut_off then + -- Messages from the same day as the cut-off might not have expired yet, + -- but all earlier will have, so clear storage for those days. + cleanup_storage:set(date, nil); + end end end end -- cgit v1.2.3 From 17be1c595df0e62ff28d9e115b83ace74c800db0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 6 Jan 2019 10:42:45 +0100 Subject: mod_http_errors: Normalize CSS --- plugins/mod_http_errors.lua | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http_errors.lua b/plugins/mod_http_errors.lua index 13473219..2bb13298 100644 --- a/plugins/mod_http_errors.lua +++ b/plugins/mod_http_errors.lua @@ -26,21 +26,24 @@ local html = [[ {title} -- cgit v1.2.3 From f61b36e2d32c4e5ea7ed7eb3d800bcc7ef5afee2 Mon Sep 17 00:00:00 2001 From: Jonas Wielicki Date: Sun, 6 Jan 2019 11:28:54 +0100 Subject: MUC: add ID to message if no ID is present --- plugins/muc/muc.lib.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'plugins') diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index bb79cda6..a34e912b 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -23,6 +23,7 @@ local resourceprep = require "util.encodings".stringprep.resourceprep; local st = require "util.stanza"; local base64 = require "util.encodings".base64; local md5 = require "util.hashes".md5; +local id = require "util.id"; local log = module._log; @@ -1037,6 +1038,9 @@ end function room_mt:handle_groupchat_to_room(origin, stanza) local from = stanza.attr.from; local occupant = self:get_occupant_by_real_jid(from); + if not stanza.attr.id then + stanza.attr.id = id.medium() + end if module:fire_event("muc-occupant-groupchat", { room = self; origin = origin; stanza = stanza; from = from; occupant = occupant; }) then return true; end -- cgit v1.2.3 From 12cea7094d339f68a661d00f096e8db9a51417f5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 6 Jan 2019 12:20:57 +0100 Subject: MUC: Rename import to avoid name clash [luacheck] --- plugins/muc/muc.lib.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index a34e912b..7259dde2 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -23,7 +23,7 @@ local resourceprep = require "util.encodings".stringprep.resourceprep; local st = require "util.stanza"; local base64 = require "util.encodings".base64; local md5 = require "util.hashes".md5; -local id = require "util.id"; +local new_id = require "util.id".medium; local log = module._log; @@ -1039,7 +1039,7 @@ function room_mt:handle_groupchat_to_room(origin, stanza) local from = stanza.attr.from; local occupant = self:get_occupant_by_real_jid(from); if not stanza.attr.id then - stanza.attr.id = id.medium() + stanza.attr.id = new_id() end if module:fire_event("muc-occupant-groupchat", { room = self; origin = origin; stanza = stanza; from = from; occupant = occupant; -- cgit v1.2.3 From 4a1dec0392e8a0a076c91ce6ff47f938ee9b2641 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 14 Jan 2019 00:17:02 +0100 Subject: mod_storage_memory: Implement :user iteration API --- plugins/mod_storage_memory.lua | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_memory.lua b/plugins/mod_storage_memory.lua index ed04a5fb..3a9de1cc 100644 --- a/plugins/mod_storage_memory.lua +++ b/plugins/mod_storage_memory.lua @@ -22,6 +22,10 @@ local function _purge_store(self, username) return true; end +local function _users(self) + return next, self.store, nil; +end + local keyval_store = {}; keyval_store.__index = keyval_store; @@ -39,9 +43,13 @@ end keyval_store.purge = _purge_store; +keyval_store.users = _users; + local archive_store = {}; archive_store.__index = archive_store; +archive_store.users = _users; + function archive_store:append(username, key, value, when, with) if is_stanza(value) then value = st.preserialize(value); -- cgit v1.2.3 From fe9e33d8c22b774d5a1f4cbc0b1145f54201c096 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 15 Jan 2019 20:08:30 +0100 Subject: mod_c2s, mod_s2s, mod_component: Log invalid XML escaped (fixes #734) See 6ed0d6224d64 --- plugins/mod_c2s.lua | 2 +- plugins/mod_component.lua | 2 +- plugins/mod_s2s/mod_s2s.lua | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 36e6a152..8d7b92fe 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -290,7 +290,7 @@ function listener.onconnect(conn) if data then local ok, err = stream:feed(data); if not ok then - log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_")); + log("debug", "Received invalid XML (%s) %d bytes: %q", tostring(err), #data, data:sub(1, 300)); session:close("not-well-formed"); end end diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index b41204a2..b8c87dee 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -310,7 +310,7 @@ function listener.onconnect(conn) function session.data(_, data) local ok, err = stream:feed(data); if ok then return; end - module:log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_")); + log("debug", "Received invalid XML (%s) %d bytes: %q", tostring(err), #data, data:sub(1, 300)); session:close("not-well-formed"); end diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index aae37b7f..79308847 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -595,8 +595,7 @@ local function initialize_session(session) if data then local ok, err = stream:feed(data); if ok then return; end - log("warn", "Received invalid XML: %s", data); - log("warn", "Problem was: %s", err); + log("debug", "Received invalid XML (%s) %d bytes: %q", tostring(err), #data, data:sub(1, 300)); session:close("not-well-formed"); end end -- cgit v1.2.3 From 0c19a99587bd6f0f590498dd1639c52af662c9ee Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 16 Jan 2019 14:20:16 +0100 Subject: mod_admin_telnet: sttas:show: Use format option that allows float numbers string.format("%d", 0.5) causes an error on Lua 5.3 --- plugins/mod_admin_telnet.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 5ce504f8..7fae8983 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1255,7 +1255,7 @@ local function format_stat(type, value, ref_value) --do return tostring(value) end if type == "duration" then if ref_value < 0.001 then - return ("%d µs"):format(value*1000000); + return ("%g µs"):format(value*1000000); elseif ref_value < 0.9 then return ("%0.2f ms"):format(value*1000); end -- cgit v1.2.3 From 0cc513679d55d2f1b67cbf4b5c133f86eaeeaaca Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 4 Oct 2018 12:22:12 +0200 Subject: mod_http: Solve CORS problems once and for all This blindly allows any cross-site requests. Future work should add an API to allow each HTTP app some influence over this for each HTTP path --- plugins/mod_http.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index a1d409bd..07d1094b 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -22,6 +22,11 @@ server.set_default_host(module:get_option_string("http_default_host")); server.set_option("body_size_limit", module:get_option_number("http_max_content_size")); server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); +-- CORS settigs +local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "POST", "PUT", "OPTIONS" }); +local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); +local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); + local function get_http_event(host, app_path, key) local method, path = key:match("^(%S+)%s+(.+)$"); if not method then -- No path specified, default to "" (base path) @@ -83,6 +88,13 @@ function moduleapi.http_url(module, app_name, default_path) return "http://disabled.invalid/"; end +local function apply_cors_headers(response, methods, headers, max_age, origin) + response.headers.access_control_allow_methods = tostring(methods); + response.headers.access_control_allow_headers = tostring(headers); + response.headers.access_control_max_age = tostring(max_age) + response.headers.access_control_allow_origin = origin or "*"; +end + function module.add_host(module) local host = module.host; if host ~= "*" then @@ -101,6 +113,12 @@ function module.add_host(module) end apps[app_name] = apps[app_name] or {}; local app_handlers = apps[app_name]; + + local function cors_handler(event_data) + local request, response = event_data.request, event_data.response; + apply_cors_headers(response, opt_methods, opt_headers, opt_max_age, request.headers.origin); + end + for key, handler in pairs(event.item.route or {}) do local event_name = get_http_event(host, app_path, key); if event_name then @@ -121,6 +139,7 @@ function module.add_host(module) if not app_handlers[event_name] then app_handlers[event_name] = handler; module:hook_object_event(server, event_name, handler); + module:hook_object_event(server, event_name, cors_handler, 1); else module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); end -- cgit v1.2.3 From 2cbbc9fe2bb407230e89c1903f8470ba6ff7ecb0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 4 Oct 2018 12:23:06 +0200 Subject: mod_bosh: Drop CORS code in favor of than in mod_http This deprecates the cross_domain_bosh setting. As a compat measure, if it is set, mod_http_crossdomain is loaded. --- plugins/mod_bosh.lua | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index d4701148..82615161 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -44,10 +44,12 @@ local bosh_max_polling = module:get_option_number("bosh_max_polling", 5); local bosh_max_wait = module:get_option_number("bosh_max_wait", 120); local consider_bosh_secure = module:get_option_boolean("consider_bosh_secure"); -local cross_domain = module:get_option("cross_domain_bosh", false); +local cross_domain = module:get_option("cross_domain_bosh"); -if cross_domain == true then cross_domain = "*"; end -if type(cross_domain) == "table" then cross_domain = table.concat(cross_domain, ", "); end +if cross_domain ~= nil then + module:log("info", "The 'cross_domain_bosh' option has been deprecated"); + module:depends("http_crossdomain"); +end local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat; @@ -91,22 +93,6 @@ function check_inactive(now, session, context, reason) -- luacheck: ignore 212/n end end -local function set_cross_domain_headers(response) - local headers = response.headers; - headers.access_control_allow_methods = "GET, POST, OPTIONS"; - headers.access_control_allow_headers = "Content-Type"; - headers.access_control_max_age = "7200"; - headers.access_control_allow_origin = cross_domain; - return response; -end - -function handle_OPTIONS(event) - if cross_domain and event.request.headers.origin then - set_cross_domain_headers(event.response); - end - return ""; -end - function handle_POST(event) log("debug", "Handling new request %s: %s\n----------", tostring(event.request), tostring(event.request.body)); @@ -121,10 +107,6 @@ function handle_POST(event) local headers = response.headers; headers.content_type = "text/xml; charset=utf-8"; - if cross_domain and request.headers.origin then - set_cross_domain_headers(response); - end - -- stream:feed() calls the stream_callbacks, so all stanzas in -- the body are processed in this next line before it returns. -- In particular, the streamopened() stream callback is where @@ -511,8 +493,6 @@ module:provides("http", { route = { ["GET"] = GET_response; ["GET /"] = GET_response; - ["OPTIONS"] = handle_OPTIONS; - ["OPTIONS /"] = handle_OPTIONS; ["POST"] = handle_POST; ["POST /"] = handle_POST; }; -- cgit v1.2.3 From 26542811eafd9c708a130272d7b7de77b92712de Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 4 Oct 2018 12:24:08 +0200 Subject: mod_websocket: Drop CORS code in favor of that in mod_http Like for mod_bosh, deprecates consider_websocket_secure and depend on mod_http_crossdomain if it is set. --- plugins/mod_websocket.lua | 38 ++++---------------------------------- 1 file changed, 4 insertions(+), 34 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index a668b4fa..da0ce8a6 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -29,18 +29,11 @@ local t_concat = table.concat; local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5); local consider_websocket_secure = module:get_option_boolean("consider_websocket_secure"); -local cross_domain = module:get_option_set("cross_domain_websocket", {}); -if cross_domain:contains("*") or cross_domain:contains(true) then - cross_domain = true; +local cross_domain = module:get_option("cross_domain_websocket"); +if cross_domain ~= nil then + module:log("info", "The 'cross_domain_websocket' option has been deprecated"); + module:depends("http_crossdomain"); end - -local function check_origin(origin) - if cross_domain == true then - return true; - end - return cross_domain:contains(origin); -end - local xmlns_framing = "urn:ietf:params:xml:ns:xmpp-framing"; local xmlns_streams = "http://etherx.jabber.org/streams"; local xmlns_client = "jabber:client"; @@ -158,11 +151,6 @@ function handle_request(event) return 501; end - if not check_origin(request.headers.origin or "") then - module:log("debug", "Origin %s is not allowed by 'cross_domain_websocket'", request.headers.origin or "(missing header)"); - return 403; - end - local function websocket_close(code, message) conn:write(build_close(code, message)); conn:close(); @@ -329,22 +317,4 @@ module:provides("http", { function module.add_host(module) module:hook("c2s-read-timeout", keepalive, -0.9); - - if cross_domain ~= true then - local url = require "socket.url"; - local ws_url = module:http_url("websocket", "xmpp-websocket"); - local url_components = url.parse(ws_url); - -- The 'Origin' consists of the base URL without path - url_components.path = nil; - local this_origin = url.build(url_components); - local local_cross_domain = module:get_option_set("cross_domain_websocket", { this_origin }); - -- Don't add / remove something added by another host - -- This might be weird with random load order - local_cross_domain:exclude(cross_domain); - cross_domain:include(local_cross_domain); - module:log("debug", "cross_domain = %s", tostring(cross_domain)); - function module.unload() - cross_domain:exclude(local_cross_domain); - end - end end -- cgit v1.2.3 From 4d5f1da475da390dab6e8835f8159d868fe8c5b3 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 18 Jan 2019 02:03:40 +0100 Subject: mod_http: Set up to handle OPTIONS Lower priority to allow http modules to handle it themselves, should they wish to --- plugins/mod_http.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 07d1094b..01f20f76 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -119,9 +119,15 @@ function module.add_host(module) apply_cors_headers(response, opt_methods, opt_headers, opt_max_age, request.headers.origin); end + local function options_handler(event_data) + cors_handler(event_data); + return ""; + end + for key, handler in pairs(event.item.route or {}) do local event_name = get_http_event(host, app_path, key); if event_name then + local options_event_name = event_name:gsub("^%S+", "OPTIONS"); if type(handler) ~= "function" then local data = handler; handler = function () return data; end @@ -140,6 +146,7 @@ function module.add_host(module) app_handlers[event_name] = handler; module:hook_object_event(server, event_name, handler); module:hook_object_event(server, event_name, cors_handler, 1); + module:hook_object_event(server, options_event_name, options_handler, -1); else module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); end -- cgit v1.2.3 From 13ce41d3f969bc039e3e1fcedcc566da86ba9028 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 17 Jan 2019 20:42:38 +0100 Subject: mod_http: Determine CORS methods to whitelist from actual methods used --- plugins/mod_http.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 01f20f76..829c2d02 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -14,6 +14,7 @@ local moduleapi = require "core.moduleapi"; local url_parse = require "socket.url".parse; local url_build = require "socket.url".build; local normalize_path = require "util.http".normalize_path; +local set = require "util.set"; local server = require "net.http.server"; @@ -23,7 +24,7 @@ server.set_option("body_size_limit", module:get_option_number("http_max_content_ server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); -- CORS settigs -local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "POST", "PUT", "OPTIONS" }); +local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "OPTIONS" }); local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); @@ -114,9 +115,11 @@ function module.add_host(module) apps[app_name] = apps[app_name] or {}; local app_handlers = apps[app_name]; + local app_methods = opt_methods; + local function cors_handler(event_data) local request, response = event_data.request, event_data.response; - apply_cors_headers(response, opt_methods, opt_headers, opt_max_age, request.headers.origin); + apply_cors_headers(response, app_methods, opt_headers, opt_max_age, request.headers.origin); end local function options_handler(event_data) @@ -127,6 +130,10 @@ function module.add_host(module) for key, handler in pairs(event.item.route or {}) do local event_name = get_http_event(host, app_path, key); if event_name then + local method = event_name:match("^%S+"); + if not app_methods:contains(method) then + app_methods = app_methods + set.new{ method }; + end local options_event_name = event_name:gsub("^%S+", "OPTIONS"); if type(handler) ~= "function" then local data = handler; -- cgit v1.2.3 From 814eebb672ee88a87a7c3effe5c437efd34f5f3e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 19 Jan 2019 20:03:04 +0100 Subject: mod_bosh, mod_websocket: Remove accidentally included dependency on non-existant module --- plugins/mod_bosh.lua | 1 - plugins/mod_websocket.lua | 1 - 2 files changed, 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 82615161..082ed961 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -48,7 +48,6 @@ local cross_domain = module:get_option("cross_domain_bosh"); if cross_domain ~= nil then module:log("info", "The 'cross_domain_bosh' option has been deprecated"); - module:depends("http_crossdomain"); end local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat; diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index da0ce8a6..008f6823 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -32,7 +32,6 @@ local consider_websocket_secure = module:get_option_boolean("consider_websocket_ local cross_domain = module:get_option("cross_domain_websocket"); if cross_domain ~= nil then module:log("info", "The 'cross_domain_websocket' option has been deprecated"); - module:depends("http_crossdomain"); end local xmlns_framing = "urn:ietf:params:xml:ns:xmpp-framing"; local xmlns_streams = "http://etherx.jabber.org/streams"; -- cgit v1.2.3 From 88568a7af092d21061020932dd3ed7cfb0113c15 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 20 Jan 2019 20:24:17 +0100 Subject: mod_mam: Fix operator precedence (thanks mimi89999) --- plugins/mod_mam/mod_mam.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index d2ca709b..67bf177e 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -378,7 +378,7 @@ if cleanup_after ~= "never" then local ok, err = archive:delete(user, { ["end"] = os.time() - cleanup_after; }) if ok then num_users = num_users + 1; - sum = sum + tonumber(ok) or 0; + sum = sum + (tonumber(ok) or 0); end end module:log("info", "Deleted %d expired messages for %d users", sum, num_users); -- cgit v1.2.3 From 344b370b5e6367761a32da79587ad02a15604845 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Feb 2019 16:18:30 +0100 Subject: MUC: Factor out role change permission check into its own method I would like to invert this logic so that it checks if the role change is allowed instead of checking if it is not allowed as it does now, in order to make it easier to understand. --- plugins/muc/muc.lib.lua | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'plugins') diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 9b168e93..2b6a7d76 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -1368,6 +1368,30 @@ function room_mt:get_role(nick) return occupant and occupant.role or nil; end +function room_mt:may_set_role(actor, occupant, role) + -- Can't do anything to other owners or admins + local occupant_affiliation = self:get_affiliation(occupant.bare_jid); + if occupant_affiliation == "owner" or occupant_affiliation == "admin" then + return nil, "cancel", "not-allowed"; + end + + -- If you are trying to give or take moderator role you need to be an owner or admin + if occupant.role == "moderator" or role == "moderator" then + local actor_affiliation = self:get_affiliation(actor); + if actor_affiliation ~= "owner" and actor_affiliation ~= "admin" then + return nil, "cancel", "not-allowed"; + end + end + + -- Need to be in the room and a moderator + local actor_occupant = self:get_occupant_by_real_jid(actor); + if not actor_occupant or actor_occupant.role ~= "moderator" then + return nil, "cancel", "not-allowed"; + end + + return true; +end + function room_mt:set_role(actor, occupant_jid, role, reason) if not actor then return nil, "modify", "not-acceptable"; end @@ -1382,24 +1406,9 @@ function room_mt:set_role(actor, occupant_jid, role, reason) if actor == true then actor = nil -- So we can pass it safely to 'publicise_occupant_status' below else - -- Can't do anything to other owners or admins - local occupant_affiliation = self:get_affiliation(occupant.bare_jid); - if occupant_affiliation == "owner" or occupant_affiliation == "admin" then - return nil, "cancel", "not-allowed"; - end - - -- If you are trying to give or take moderator role you need to be an owner or admin - if occupant.role == "moderator" or role == "moderator" then - local actor_affiliation = self:get_affiliation(actor); - if actor_affiliation ~= "owner" and actor_affiliation ~= "admin" then - return nil, "cancel", "not-allowed"; - end - end - - -- Need to be in the room and a moderator - local actor_occupant = self:get_occupant_by_real_jid(actor); - if not actor_occupant or actor_occupant.role ~= "moderator" then - return nil, "cancel", "not-allowed"; + local allowed, err, condition = self:may_set_role(actor, occupant, role) + if not allowed then + return allowed, err, condition; end end -- cgit v1.2.3 From 4b80adc9641fca202ab7e2488722280932b44ad2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Feb 2019 16:30:11 +0100 Subject: MUC: Fire an event to allow affecting decision of whether to allow a role change --- plugins/muc/muc.lib.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'plugins') diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 2b6a7d76..a8d3d790 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -1369,6 +1369,18 @@ function room_mt:get_role(nick) end function room_mt:may_set_role(actor, occupant, role) + local event = { + room = self, + actor = actor, + occupant = occupant, + role = role, + }; + + module:fire_event("muc-pre-set-role", event); + if event.allowed ~= nil then + return event.allowed, event.error, event.condition; + end + -- Can't do anything to other owners or admins local occupant_affiliation = self:get_affiliation(occupant.bare_jid); if occupant_affiliation == "owner" or occupant_affiliation == "admin" then -- cgit v1.2.3 From 37ba8188057989a530aa5a5e138b181d1ad855a1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 4 Mar 2019 13:13:37 +0100 Subject: mod_muc_mam: Validate that the FORM_TYPE of a query is as expected --- plugins/mod_muc_mam.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_muc_mam.lua b/plugins/mod_muc_mam.lua index 166a5c71..963e5255 100644 --- a/plugins/mod_muc_mam.lua +++ b/plugins/mod_muc_mam.lua @@ -21,6 +21,7 @@ local jid_bare = require "util.jid".bare; local jid_split = require "util.jid".split; local jid_prep = require "util.jid".prep; local dataform = require "util.dataforms".new; +local get_form_type = require "util.dataforms".get_type; local mod_muc = module:depends"muc"; local get_room_from_jid = mod_muc.get_room_from_jid; @@ -131,7 +132,11 @@ module:hook("iq-set/bare/"..xmlns_mam..":query", function(event) local qstart, qend; local form = query:get_child("x", "jabber:x:data"); if form then - local err; + local form_type, err = get_form_type(form); + if form_type ~= xmlns_mam then + origin.send(st.error_reply(stanza, "modify", "bad-request", "Unexpected FORM_TYPE, expected '"..xmlns_mam.."'")); + return true; + end form, err = query_form:data(form); if err then origin.send(st.error_reply(stanza, "modify", "bad-request", select(2, next(err)))); -- cgit v1.2.3 From a08b6d8226ab4f2fe5358f664990e245db01b9a6 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 10 Mar 2019 19:58:28 +0100 Subject: core.certmanager: Do not ask for client certificates by default Since it's mostly only mod_s2s that needs to request client certificates it makes some sense to have mod_s2s ask for this, instead of having eg mod_http ask to disable it. --- plugins/mod_http.lua | 3 --- plugins/mod_s2s/mod_s2s.lua | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 829c2d02..17ea27e1 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -228,9 +228,6 @@ module:provides("net", { listener = server.listener; default_port = 5281; encryption = "ssl"; - ssl_config = { - verify = "none"; - }; multiplex = { pattern = "^[A-Z]"; }; diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 79308847..b0d551fe 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -738,6 +738,9 @@ module:provides("net", { listener = listener; default_port = 5269; encryption = "starttls"; + ssl_config = { + verify = { "peer", "client_once", }; + }; multiplex = { pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:server%1.*>"; }; -- cgit v1.2.3 From 4b022060a27216380565302aa0fc3ca805a532eb Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 11 Mar 2019 13:07:59 +0100 Subject: mod_tls: Restore querying for certificates on s2s The 'ssl_config' setting in the mod_s2s network service is not used. Only direct TLS ports use this currently. --- plugins/mod_s2s/mod_s2s.lua | 2 +- plugins/mod_tls.lua | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index b0d551fe..f0fdc5fb 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -738,7 +738,7 @@ module:provides("net", { listener = listener; default_port = 5269; encryption = "starttls"; - ssl_config = { + ssl_config = { -- FIXME This is not used atm, see mod_tls verify = { "peer", "client_once", }; }; multiplex = { diff --git a/plugins/mod_tls.lua b/plugins/mod_tls.lua index 4ead60dc..d8bf02c4 100644 --- a/plugins/mod_tls.lua +++ b/plugins/mod_tls.lua @@ -53,13 +53,17 @@ function module.load() local parent_s2s = rawgetopt(parent, "s2s_ssl") or NULL; local host_s2s = rawgetopt(modhost, "s2s_ssl") or parent_s2s; + local request_client_certs = { verify = { "peer", "client_once", }; }; + ssl_ctx_c2s, err_c2s, ssl_cfg_c2s = create_context(host.host, "server", host_c2s, host_ssl, global_c2s); -- for incoming client connections if not ssl_ctx_c2s then module:log("error", "Error creating context for c2s: %s", err_c2s); end - ssl_ctx_s2sout, err_s2sout, ssl_cfg_s2sout = create_context(host.host, "client", host_s2s, host_ssl, global_s2s); -- for outgoing server connections + -- for outgoing server connections + ssl_ctx_s2sout, err_s2sout, ssl_cfg_s2sout = create_context(host.host, "client", host_s2s, host_ssl, global_s2s, request_client_certs); if not ssl_ctx_s2sout then module:log("error", "Error creating contexts for s2sout: %s", err_s2sout); end - ssl_ctx_s2sin, err_s2sin, ssl_cfg_s2sin = create_context(host.host, "server", host_s2s, host_ssl, global_s2s); -- for incoming server connections + -- for incoming server connections + ssl_ctx_s2sin, err_s2sin, ssl_cfg_s2sin = create_context(host.host, "server", host_s2s, host_ssl, global_s2s, request_client_certs); if not ssl_ctx_s2sin then module:log("error", "Error creating contexts for s2sin: %s", err_s2sin); end end -- cgit v1.2.3 From b4f63e714100773e131d69792239875583595c15 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 18 Mar 2019 09:50:23 +0000 Subject: MUC: Update error message for consistency --- plugins/muc/muc.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index a8d3d790..c828d17d 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -498,7 +498,7 @@ function room_mt:handle_normal_presence(origin, stanza) if orig_occupant == nil and not muc_x and stanza.attr.type == nil then module:log("debug", "Attempted join without , possibly desynced"); origin.send(st.error_reply(stanza, "cancel", "item-not-found", - "You must join the room before sending presence updates")); + "You are not currently connected to this chat")); return true; end -- cgit v1.2.3 From d684b288de7ac00a0e12795cc3fb8f02bfed1217 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 19 Mar 2019 09:05:37 +0000 Subject: mod_admin_telnet: Show module status in module:list() --- plugins/mod_admin_telnet.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 7fae8983..34cc4dc6 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -480,7 +480,12 @@ function def_env.module:list(hosts) end else for _, name in ipairs(modules) do - print(" "..name); + local status, status_text = modulemanager.get_module(host, name).module:get_status(); + local status_summary = ""; + if status == "warn" or status == "error" then + status_summary = (" (%s: %s)"):format(status, status_text); + end + print((" %s%s"):format(name, status_summary)); end end end -- cgit v1.2.3 From 8189ab0bcdceea2c6ee2df4c1fb522242d8e1533 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 19 Mar 2019 09:08:06 +0000 Subject: mod_component: Set module status to indicate whether component is connected --- plugins/mod_component.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index b8c87dee..b1ffc81d 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -49,6 +49,7 @@ function module.add_host(module) local send; local function on_destroy(session, err) --luacheck: ignore 212/err + module:set_status("warn", err and ("Disconnected: "..err) or "Disconnected"); env.connected = false; env.session = false; send = nil; @@ -102,6 +103,7 @@ function module.add_host(module) module:log("info", "External component successfully authenticated"); session.send(st.stanza("handshake")); module:fire_event("component-authenticated", { session = session }); + module:set_status("info", "Connected"); return true; end -- cgit v1.2.3 From 9fb58cf11f3de8f167a940c221d9a7b7a0c2da56 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 19 Mar 2019 09:08:33 +0000 Subject: mod_s2s: Set warning status if not listening on any ports --- plugins/mod_s2s/s2sout.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index 5f765da8..34e322d2 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -318,7 +318,7 @@ module:hook_global("service-added", function (event) local s2s_sources = portmanager.get_active_services():get("s2s"); if not s2s_sources then - module:log("warn", "s2s not listening on any ports, outgoing connections may fail"); + module:log_status("warn", "s2s not listening on any ports, outgoing connections may fail"); return; end for source, _ in pairs(s2s_sources) do -- cgit v1.2.3 From 143c6bb57368837d9860a3f8a3678304689d5d46 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 19 Mar 2019 09:08:56 +0000 Subject: mod_muc_mam: Set error status if loaded on incorrect host type --- plugins/mod_muc_mam.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_muc_mam.lua b/plugins/mod_muc_mam.lua index d414a449..7d429482 100644 --- a/plugins/mod_muc_mam.lua +++ b/plugins/mod_muc_mam.lua @@ -4,7 +4,7 @@ -- This file is MIT/X11 licensed. if module:get_host_type() ~= "component" then - module:log("error", "mod_%s should be loaded only on a MUC component, not normal hosts", module.name); + module:log_status("error", "mod_%s should be loaded only on a MUC component, not normal hosts", module.name); return; end -- cgit v1.2.3 From 8aef0281ab608e1b1d421673f924ff91d439097d Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 20 Oct 2017 12:53:53 +0200 Subject: mod_storage_internal,_sql: Add limit to number of items in an archive store (fixes #733) --- plugins/mod_storage_internal.lua | 35 +++++++++++++++++++++++++++++++++++ plugins/mod_storage_sql.lua | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index 42b451bd..d812c0e9 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -1,3 +1,4 @@ +local cache = require "util.cache"; local datamanager = require "core.storagemanager".olddm; local array = require "util.array"; local datetime = require "util.datetime"; @@ -7,6 +8,9 @@ local id = require "util.id".medium; local host = module.host; +local archive_item_limit = module:get_option_number("storage_archive_item_limit", 1000); +local archive_item_count_cache = cache.new(module:get_option("storage_archive_item_limit_cache_size", 1000)); + local driver = {}; function driver:open(store, typ) @@ -54,28 +58,56 @@ function archive:append(username, key, value, when, with) value.attr.stamp = datetime.datetime(when); value.attr.stamp_legacy = datetime.legacy(when); + local item_count = archive_item_count_cache:get(username); + if key then local items, err = datamanager.list_load(username, host, self.store); if not items and err then return items, err; end + + -- Check the quota + item_count = items and #items or 0; + archive_item_count_cache:set(username, item_count); + if item_count >= archive_item_limit then + module:log("debug", "%s reached or over quota, not adding to store", username); + return nil, "quota-limit"; + end + if items then + -- Filter out any item with the same key as the one being added items = array(items); items:filter(function (item) return item.key ~= key; end); + value.key = key; items:push(value); local ok, err = datamanager.list_store(username, host, self.store, items); if not ok then return ok, err; end + archive_item_count_cache:set(username, #items); return key; end else + if not item_count then -- Item count not cached? + -- We need to load the list to get the number of items currently stored + local items, err = datamanager.list_load(username, host, self.store); + if not items and err then return items, err; end + item_count = items and #items or 0; + archive_item_count_cache:set(username, item_count); + end + if item_count >= archive_item_limit then + module:log("debug", "%s reached or over quota, not adding to store", username); + return nil, "quota-limit"; + end key = id(); end + module:log("debug", "%s has %d items out of %d limit", username, item_count, archive_item_limit); + value.key = key; local ok, err = datamanager.list_append(username, host, self.store, value); if not ok then return ok, err; end + archive_item_count_cache:set(username, item_count+1); return key; end @@ -158,6 +190,7 @@ end function archive:delete(username, query) if not query or next(query) == nil then + archive_item_count_cache:set(username, nil); return datamanager.list_store(username, host, self.store, nil); end local items, err = datamanager.list_load(username, host, self.store); @@ -165,6 +198,7 @@ function archive:delete(username, query) if err then return items, err; end + archive_item_count_cache:set(username, 0); -- Store is empty return 0; end @@ -214,6 +248,7 @@ function archive:delete(username, query) end local ok, err = datamanager.list_store(username, host, self.store, items); if not ok then return ok, err; end + archive_item_count_cache:set(username, #items); return count; end diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 5c0c0208..4fe2a262 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -1,6 +1,7 @@ -- luacheck: ignore 212/self +local cache = require "util.cache"; local json = require "util.json"; local sql = require "util.sql"; local xml_parse = require "util.xml".parse; @@ -148,6 +149,9 @@ end --- Archive store API +local archive_item_limit = module:get_option_number("storage_archive_item_limit", 1000); +local archive_item_count_cache = cache.new(module:get_option("storage_archive_item_limit_cache_size", 1000)); + -- luacheck: ignore 512 431/user 431/store local map_store = {}; map_store.__index = map_store; @@ -231,6 +235,32 @@ archive_store.caps = { }; archive_store.__index = archive_store function archive_store:append(username, key, value, when, with) + local item_count = archive_item_count_cache:get(username); + if not item_count then + local ok, ret = engine:transaction(function() + local count_sql = [[ + SELECT COUNT(*) FROM "prosodyarchive" + WHERE "host"=? AND "user"=? AND "store"=?; + ]]; + local result = engine:select(count_sql, host, user, store); + if result then + for row in result do + item_count = row[1]; + end + end + end); + if not ok or not item_count then + module:log("error", "Failed while checking quota for %s: %s", username, ret); + return nil, "Failure while checking quota"; + end + archive_item_count_cache:set(username, item_count); + end + + module:log("debug", "%s has %d items out of %d limit", username, item_count, archive_item_limit); + if item_count >= archive_item_limit then + return nil, "quota-limit"; + end + local user,store = username,self.store; when = when or os.time(); with = with or ""; @@ -245,12 +275,18 @@ function archive_store:append(username, key, value, when, with) VALUES (?,?,?,?,?,?,?,?); ]]; if key then - engine:delete(delete_sql, host, user or "", store, key); + local result, err = engine:delete(delete_sql, host, user or "", store, key); + if result then + item_count = item_count - result:affected(); + archive_item_count_cache:set(username, item_count); + end else + item_count = item_count + 1; key = uuid.generate(); end local t, encoded_value = assert(serialize(value)); engine:insert(insert_sql, host, user or "", store, when, with, key, t, encoded_value); + archive_item_count_cache:set(username, item_count+1); return key; end); if not ok then return ok, ret; end @@ -422,6 +458,7 @@ function archive_store:delete(username, query) end return engine:delete(sql_query, unpack(args)); end); + archive_item_count_cache:set(username, nil); return ok and stmt:affected(), stmt; end -- cgit v1.2.3 From 351783fd1d132fea8098aa37084258afe81afccf Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 18:01:24 +0100 Subject: mod_storage_internal,_sql: Expose archive capabilities feature set This was planned to be added long ago but was forgotten. --- plugins/mod_storage_internal.lua | 6 ++++++ plugins/mod_storage_sql.lua | 2 ++ 2 files changed, 8 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index d812c0e9..c21fe0dc 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -47,6 +47,12 @@ end local archive = {}; driver.archive = { __index = archive }; +archive.caps = { + total = true; + quota = archive_item_limit; + truncate = true; +}; + function archive:append(username, key, value, when, with) when = when or now(); if not st.is_stanza(value) then diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 4fe2a262..82c5c3fe 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -232,6 +232,8 @@ end local archive_store = {} archive_store.caps = { total = true; + quota = archive_item_limit; + truncate = true; }; archive_store.__index = archive_store function archive_store:append(username, key, value, when, with) -- cgit v1.2.3 From 8c6c1d0fd0fa2f907b0821954b7aa03a5fe2618d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 18:02:27 +0100 Subject: mod_storage_internal,_sql: Key item count cache on both username and store --- plugins/mod_storage_internal.lua | 19 +++++++++++-------- plugins/mod_storage_sql.lua | 13 ++++++++----- 2 files changed, 19 insertions(+), 13 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index c21fe0dc..52ca4da8 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -5,6 +5,7 @@ local datetime = require "util.datetime"; local st = require "util.stanza"; local now = require "util.time".now; local id = require "util.id".medium; +local jid_join = require "util.jid".join; local host = module.host; @@ -64,7 +65,8 @@ function archive:append(username, key, value, when, with) value.attr.stamp = datetime.datetime(when); value.attr.stamp_legacy = datetime.legacy(when); - local item_count = archive_item_count_cache:get(username); + local cache_key = jid_join(username, host, self.store); + local item_count = archive_item_count_cache:get(cache_key); if key then local items, err = datamanager.list_load(username, host, self.store); @@ -72,7 +74,7 @@ function archive:append(username, key, value, when, with) -- Check the quota item_count = items and #items or 0; - archive_item_count_cache:set(username, item_count); + archive_item_count_cache:set(cache_key, item_count); if item_count >= archive_item_limit then module:log("debug", "%s reached or over quota, not adding to store", username); return nil, "quota-limit"; @@ -89,7 +91,7 @@ function archive:append(username, key, value, when, with) items:push(value); local ok, err = datamanager.list_store(username, host, self.store, items); if not ok then return ok, err; end - archive_item_count_cache:set(username, #items); + archive_item_count_cache:set(cache_key, #items); return key; end else @@ -98,7 +100,7 @@ function archive:append(username, key, value, when, with) local items, err = datamanager.list_load(username, host, self.store); if not items and err then return items, err; end item_count = items and #items or 0; - archive_item_count_cache:set(username, item_count); + archive_item_count_cache:set(cache_key, item_count); end if item_count >= archive_item_limit then module:log("debug", "%s reached or over quota, not adding to store", username); @@ -113,7 +115,7 @@ function archive:append(username, key, value, when, with) local ok, err = datamanager.list_append(username, host, self.store, value); if not ok then return ok, err; end - archive_item_count_cache:set(username, item_count+1); + archive_item_count_cache:set(cache_key, item_count+1); return key; end @@ -195,8 +197,9 @@ function archive:dates(username) end function archive:delete(username, query) + local cache_key = jid_join(username, host, self.store); if not query or next(query) == nil then - archive_item_count_cache:set(username, nil); + archive_item_count_cache:set(cache_key, nil); return datamanager.list_store(username, host, self.store, nil); end local items, err = datamanager.list_load(username, host, self.store); @@ -204,7 +207,7 @@ function archive:delete(username, query) if err then return items, err; end - archive_item_count_cache:set(username, 0); + archive_item_count_cache:set(cache_key, 0); -- Store is empty return 0; end @@ -254,7 +257,7 @@ function archive:delete(username, query) end local ok, err = datamanager.list_store(username, host, self.store, items); if not ok then return ok, err; end - archive_item_count_cache:set(username, #items); + archive_item_count_cache:set(cache_key, #items); return count; end diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 82c5c3fe..3028bb72 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -7,6 +7,7 @@ local sql = require "util.sql"; local xml_parse = require "util.xml".parse; local uuid = require "util.uuid"; local resolve_relative_path = require "util.paths".resolve_relative_path; +local jid_join = require "util.jid".join; local is_stanza = require"util.stanza".is_stanza; local t_concat = table.concat; @@ -237,7 +238,8 @@ archive_store.caps = { }; archive_store.__index = archive_store function archive_store:append(username, key, value, when, with) - local item_count = archive_item_count_cache:get(username); + local cache_key = jid_join(username, host, self.store); + local item_count = archive_item_count_cache:get(cache_key); if not item_count then local ok, ret = engine:transaction(function() local count_sql = [[ @@ -255,7 +257,7 @@ function archive_store:append(username, key, value, when, with) module:log("error", "Failed while checking quota for %s: %s", username, ret); return nil, "Failure while checking quota"; end - archive_item_count_cache:set(username, item_count); + archive_item_count_cache:set(cache_key, item_count); end module:log("debug", "%s has %d items out of %d limit", username, item_count, archive_item_limit); @@ -280,7 +282,7 @@ function archive_store:append(username, key, value, when, with) local result, err = engine:delete(delete_sql, host, user or "", store, key); if result then item_count = item_count - result:affected(); - archive_item_count_cache:set(username, item_count); + archive_item_count_cache:set(cache_key, item_count); end else item_count = item_count + 1; @@ -288,7 +290,7 @@ function archive_store:append(username, key, value, when, with) end local t, encoded_value = assert(serialize(value)); engine:insert(insert_sql, host, user or "", store, when, with, key, t, encoded_value); - archive_item_count_cache:set(username, item_count+1); + archive_item_count_cache:set(cache_key, item_count+1); return key; end); if not ok then return ok, ret; end @@ -460,7 +462,8 @@ function archive_store:delete(username, query) end return engine:delete(sql_query, unpack(args)); end); - archive_item_count_cache:set(username, nil); + local cache_key = jid_join(username, host, self.store); + archive_item_count_cache:set(cache_key, nil); return ok and stmt:affected(), stmt; end -- cgit v1.2.3 From db917661a6946e25b53b38b79ba7c8f4f01e50db Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 7 Nov 2017 18:58:52 +0100 Subject: mod_mam: Trim archive when quota has been exceeded --- plugins/mod_mam/mod_mam.lua | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index 88cbaa08..5be4bc24 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -40,6 +40,10 @@ local strip_tags = module:get_option_set("dont_archive_namespaces", { "http://ja local archive_store = module:get_option_string("archive_store", "archive"); local archive = module:open_store(archive_store, "archive"); +local cleanup_after = module:get_option_string("archive_expires_after", "1w"); +local cleanup_interval = module:get_option_number("archive_cleanup_interval", 4 * 60 * 60); +local archive_item_limit = module:get_option_number("storage_archive_item_limit", archive.caps and archive.caps.quota or 1000); + if not archive.find then error("mod_"..(archive._provided_by or archive.name and "storage_"..archive.name).." does not support archiving\n" .."See https://prosody.im/doc/storage and https://prosody.im/doc/archiving for more information"); @@ -295,7 +299,20 @@ local function message_handler(event, c2s) log("debug", "Archiving stanza: %s", stanza:top_tag()); -- And stash it - local ok = archive:append(store_user, nil, clone_for_storage, time_now(), with); + local time = time_now(); + local ok, err = archive:append(store_user, nil, clone_for_storage, time, with); + if not ok and err == "quota-limit" then + if archive.caps and archive.caps.truncate then + module:log("debug", "User '%s' over quota, trimming archive", store_user); + local truncated = archive:delete(store_user, { + truncate = archive_item_limit - 1; + ["end"] = type(cleanup_after) == "number" and (os.time() - cleanup_after) or nil; + }); + if truncated then + ok, err = archive:append(store_user, nil, clone_for_storage, time, with); + end + end + end if ok then local clone_for_other_handlers = st.clone(stanza); local id = ok; @@ -321,8 +338,6 @@ end module:hook("pre-message/bare", strip_stanza_id_after_other_events, -1); module:hook("pre-message/full", strip_stanza_id_after_other_events, -1); -local cleanup_after = module:get_option_string("archive_expires_after", "1w"); -local cleanup_interval = module:get_option_number("archive_cleanup_interval", 4 * 60 * 60); if cleanup_after ~= "never" then local cleanup_storage = module:open_store("archive_cleanup"); local cleanup_map = module:open_store("archive_cleanup", "map"); -- cgit v1.2.3 From d1ad7d498828b48d2a2477319083227b91b5441d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 20 Mar 2019 12:14:45 +0100 Subject: mod_storage_memory: Add support for archive item limits --- plugins/mod_storage_memory.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_memory.lua b/plugins/mod_storage_memory.lua index 745e394b..8e1cf879 100644 --- a/plugins/mod_storage_memory.lua +++ b/plugins/mod_storage_memory.lua @@ -8,6 +8,8 @@ local new_id = require "util.id".medium; local auto_purge_enabled = module:get_option_boolean("storage_memory_temporary", false); local auto_purge_stores = module:get_option_set("storage_memory_temporary_stores", {}); +local archive_item_limit = module:get_option_number("storage_archive_item_limit", 1000); + local memory = setmetatable({}, { __index = function(t, k) local store = module:shared(k) @@ -51,6 +53,12 @@ archive_store.__index = archive_store; archive_store.users = _users; +archive_store.caps = { + total = true; + quota = archive_item_limit; + truncate = true; +}; + function archive_store:append(username, key, value, when, with) if is_stanza(value) then value = st.preserialize(value); @@ -70,6 +78,8 @@ function archive_store:append(username, key, value, when, with) end if a[key] then table.remove(a, a[key]); + elseif #a >= archive_item_limit then + return nil, "quota-limit"; end local i = #a+1; a[i] = v; -- cgit v1.2.3 From 92595546031e1f8a6222e9e164f8cca45e949bdf Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 02:04:34 +0100 Subject: mod_storage_internal: Increase default quota to 10 000 Performance doesn't seem great but 10k should be far enough from limits inherited by the Lua parser. 1000 messages seemed pretty close to what an active user might produce in one week. --- plugins/mod_storage_internal.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index 52ca4da8..cb88f10f 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -9,7 +9,7 @@ local jid_join = require "util.jid".join; local host = module.host; -local archive_item_limit = module:get_option_number("storage_archive_item_limit", 1000); +local archive_item_limit = module:get_option_number("storage_archive_item_limit", 10000); local archive_item_count_cache = cache.new(module:get_option("storage_archive_item_limit_cache_size", 1000)); local driver = {}; -- cgit v1.2.3 From 7e9722a7362c9e7ffd6cca6c756ee61acc52ff93 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 02:09:38 +0100 Subject: mod_storage_sql: Don't increment counter twice (fixes accounting error) --- plugins/mod_storage_sql.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 3028bb72..154daf06 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -285,7 +285,6 @@ function archive_store:append(username, key, value, when, with) archive_item_count_cache:set(cache_key, item_count); end else - item_count = item_count + 1; key = uuid.generate(); end local t, encoded_value = assert(serialize(value)); -- cgit v1.2.3 From 669da78e01c61d83912210877b2c5514360fe7e9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 02:10:46 +0100 Subject: mod_storage_sql: Fix to use currently queried store Was using the previously queried store due to this being cached in an upvalue. --- plugins/mod_storage_sql.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 154daf06..325fab94 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -238,7 +238,8 @@ archive_store.caps = { }; archive_store.__index = archive_store function archive_store:append(username, key, value, when, with) - local cache_key = jid_join(username, host, self.store); + local user,store = username,self.store; + local cache_key = jid_join(username, host, store); local item_count = archive_item_count_cache:get(cache_key); if not item_count then local ok, ret = engine:transaction(function() @@ -265,7 +266,6 @@ function archive_store:append(username, key, value, when, with) return nil, "quota-limit"; end - local user,store = username,self.store; when = when or os.time(); with = with or ""; local ok, ret = engine:transaction(function() -- cgit v1.2.3 From 79bebb21f83365e33208644f1c0060752f4fc532 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 02:12:02 +0100 Subject: mod_storage_sql: Skip cache write This would cause the cache to be wrong in case the the later INSERT fails and the transaction is aborted. --- plugins/mod_storage_sql.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 325fab94..35a16870 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -282,7 +282,6 @@ function archive_store:append(username, key, value, when, with) local result, err = engine:delete(delete_sql, host, user or "", store, key); if result then item_count = item_count - result:affected(); - archive_item_count_cache:set(cache_key, item_count); end else key = uuid.generate(); -- cgit v1.2.3 From e21f31c7c282aa5fba3c37e6d1e829edb3b78a6b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 02:13:27 +0100 Subject: mod_storage_sql: Cache total count if it's calculated as part of the current query --- plugins/mod_storage_sql.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 35a16870..b3bd5171 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -384,6 +384,9 @@ function archive_store:find(username, query) total = row[1]; end end + if query.start == nil and query.with == nil and query["end"] == nil and query.key == nil then + archive_item_count_cache:set(cache_key, total); + end if query.limit == 0 then -- Skip the real query return noop, total; end -- cgit v1.2.3 From 2a073294ae4a6eccc10ffcef2a2146bfb9abe1ae Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 02:18:54 +0100 Subject: mod_storage_sql: Return cached count if only this is queried for --- plugins/mod_storage_sql.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index b3bd5171..8c03da01 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -362,7 +362,11 @@ end function archive_store:find(username, query) query = query or {}; local user,store = username,self.store; - local total; + local cache_key = jid_join(username, host, self.store); + local total = archive_item_count_cache:get(cache_key); + if total ~= nil and query.limit == 0 and query.start == nil and query.with == nil and query["end"] == nil and query.key == nil then + return noop, total; + end local ok, result = engine:transaction(function() local sql_query = [[ SELECT "key", "type", "value", "when", "with" -- cgit v1.2.3 From 36900805270064f089c7e3ae9b2e3be6b7a63df0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 02:22:21 +0100 Subject: mod_mam: On quota hit, separately delete by time and by item count This is to work around a possible SQL issue where offsets and time stamps don't interact correctly. --- plugins/mod_mam/mod_mam.lua | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index 5be4bc24..632de9ea 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -302,11 +302,19 @@ local function message_handler(event, c2s) local time = time_now(); local ok, err = archive:append(store_user, nil, clone_for_storage, time, with); if not ok and err == "quota-limit" then - if archive.caps and archive.caps.truncate then - module:log("debug", "User '%s' over quota, trimming archive", store_user); + if type(cleanup_after) == "number" then + module:log("debug", "User '%s' over quota, cleaning archive", store_user); + local cleaned = archive:delete(store_user, { + ["end"] = (os.time() - cleanup_after); + }); + if cleaned then + ok, err = archive:append(store_user, nil, clone_for_storage, time, with); + end + end + if not ok and (archive.caps and archive.caps.truncate) then + module:log("debug", "User '%s' over quota, truncating archive", store_user); local truncated = archive:delete(store_user, { truncate = archive_item_limit - 1; - ["end"] = type(cleanup_after) == "number" and (os.time() - cleanup_after) or nil; }); if truncated then ok, err = archive:append(store_user, nil, clone_for_storage, time, with); -- cgit v1.2.3 From a763f1f8235b4cc9633847203d3a282871ebfca4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 02:24:48 +0100 Subject: mod_storage_internal: Include store name when reporting quota status --- plugins/mod_storage_internal.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index cb88f10f..c87d01be 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -109,7 +109,7 @@ function archive:append(username, key, value, when, with) key = id(); end - module:log("debug", "%s has %d items out of %d limit", username, item_count, archive_item_limit); + module:log("debug", "%s has %d items out of %d limit in store %s", username, item_count, archive_item_limit, self.store); value.key = key; -- cgit v1.2.3 From 1a68e66b842a4af6fe19e99f2e09044a540b404e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Mar 2019 16:30:53 +0100 Subject: mod_storage_sql: No archive item limit by default --- plugins/mod_storage_sql.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 8c03da01..6b26759f 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -150,7 +150,7 @@ end --- Archive store API -local archive_item_limit = module:get_option_number("storage_archive_item_limit", 1000); +local archive_item_limit = module:get_option_number("storage_archive_item_limit"); local archive_item_count_cache = cache.new(module:get_option("storage_archive_item_limit_cache_size", 1000)); -- luacheck: ignore 512 431/user 431/store @@ -261,9 +261,11 @@ function archive_store:append(username, key, value, when, with) archive_item_count_cache:set(cache_key, item_count); end - module:log("debug", "%s has %d items out of %d limit", username, item_count, archive_item_limit); - if item_count >= archive_item_limit then - return nil, "quota-limit"; + if archive_item_limit then + module:log("debug", "%s has %d items out of %d limit", username, item_count, archive_item_limit); + if item_count >= archive_item_limit then + return nil, "quota-limit"; + end end when = when or os.time(); -- cgit v1.2.3 From c1a1511e2662fdd1749c30cfc1cabc3d4b89f082 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 25 Feb 2019 15:48:28 +0100 Subject: mod_storage_internal: Implement a summary API returning message counts per contact --- plugins/mod_storage_internal.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index c87d01be..aa5c3c8a 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -196,6 +196,16 @@ function archive:dates(username) return array(items):pluck("when"):map(datetime.date):unique(); end +function archive:summary(username, query) + local iter, err = self:find(username, query) + if not iter then return iter, err; end + local summary = {}; + for _, _, _, with in iter do + summary[with] = (summary[with] or 0) + 1; + end + return summary; +end + function archive:delete(username, query) local cache_key = jid_join(username, host, self.store); if not query or next(query) == nil then -- cgit v1.2.3 From aea959880cf8ae4d81c41d4e6ef224cc978ef278 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 25 Feb 2019 15:51:55 +0100 Subject: mod_storage_sql: Implement archive summary API --- plugins/mod_storage_sql.lua | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 6b26759f..ffe48ab8 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -419,6 +419,41 @@ function archive_store:find(username, query) end, total; end +function archive_store:summary(username, query) + query = query or {}; + local user,store = username,self.store; + local ok, result = engine:transaction(function() + local sql_query = [[ + SELECT DISTINCT "with", COUNT(*) + FROM "prosodyarchive" + WHERE %s + GROUP BY "with" + ORDER BY "sort_id" %s%s; + ]]; + local args = { host, user or "", store, }; + local where = { "\"host\" = ?", "\"user\" = ?", "\"store\" = ?", }; + + archive_where(query, args, where); + + archive_where_id_range(query, args, where); + + if query.limit then + args[#args+1] = query.limit; + end + + sql_query = sql_query:format(t_concat(where, " AND "), query.reverse + and "DESC" or "ASC", query.limit and " LIMIT ?" or ""); + return engine:select(sql_query, unpack(args)); + end); + if not ok then return ok, result end + local summary = {}; + for row in result do + local with, count = row[1], row[2]; + summary[with] = count; + end + return summary; +end + function archive_store:delete(username, query) query = query or {}; local user,store = username,self.store; -- cgit v1.2.3 From 4a2f05236136f1a2e1a74e120bb6131c628a278a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 23 Mar 2019 22:05:08 +0100 Subject: mod_storage_memory: Implement archive summary API --- plugins/mod_storage_memory.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_memory.lua b/plugins/mod_storage_memory.lua index 8e1cf879..41180aba 100644 --- a/plugins/mod_storage_memory.lua +++ b/plugins/mod_storage_memory.lua @@ -147,6 +147,16 @@ function archive_store:find(username, query) end, count; end +function archive:summary(username, query) + local iter, err = self:find(username, query) + if not iter then return iter, err; end + local summary = {}; + for _, _, _, with in iter do + summary[with] = (summary[with] or 0) + 1; + end + return summary; +end + function archive_store:delete(username, query) if not query or next(query) == nil then -- cgit v1.2.3 From eda65b96f853b9210c8a7e650eef5578a1ce34bf Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 23 Mar 2019 22:05:42 +0100 Subject: mod_storage_memory: Fix copypaste mistake --- plugins/mod_storage_memory.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_storage_memory.lua b/plugins/mod_storage_memory.lua index 41180aba..dde2d571 100644 --- a/plugins/mod_storage_memory.lua +++ b/plugins/mod_storage_memory.lua @@ -147,7 +147,7 @@ function archive_store:find(username, query) end, count; end -function archive:summary(username, query) +function archive_store:summary(username, query) local iter, err = self:find(username, query) if not iter then return iter, err; end local summary = {}; -- cgit v1.2.3 From 7ef5adb448ad36074123a924dc80607e087ed200 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 24 Nov 2018 02:25:44 +0100 Subject: mod_csi_simple: Use write locks in net.server if available --- plugins/mod_csi_simple.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index da2dd953..abe65fce 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -86,7 +86,9 @@ end, -1); module:hook("csi-client-inactive", function (event) local session = event.origin; - if session.pump then + if session.conn and session.conn and session.conn.pause_writes then + session.conn:pause_writes(); + elseif session.pump then session.pump:pause(); else local bare_jid = jid.join(session.username, session.host); @@ -115,6 +117,8 @@ module:hook("csi-client-active", function (event) local session = event.origin; if session.pump then session.pump:resume(); + elseif session.conn and session.conn and session.conn.resume_writes then + session.conn:resume_writes(); end end); -- cgit v1.2.3 From ee4a464a26db437f1b187c4a6cd83a53492010fc Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 18:30:51 +0100 Subject: mod_c2s: Fire an event when outgoing buffers have been emptied --- plugins/mod_c2s.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 8d7b92fe..7c6d95f7 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -332,6 +332,13 @@ function listener.onreadtimeout(conn) end end +function listener.ondrain(conn) + local session = sessions[conn]; + if session then + return (hosts[session.host] or prosody).events.fire_event("c2s-ondrain", { session = session }); + end +end + local function keepalive(event) local session = event.session; if not session.notopen then -- cgit v1.2.3 From e31a4cdd89be95fd6b97617491ea8e4a9822af66 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 18:32:50 +0100 Subject: mod_csi_simple: Break out stanza timestamping into a function for future reuse --- plugins/mod_csi_simple.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index abe65fce..6bd6c0bf 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -84,6 +84,14 @@ module:hook("csi-is-stanza-important", function (event) return true; end, -1); +local function with_timestamp(stanza, from) + if st.is_stanza(stanza) and stanza.attr.xmlns == nil and stanza.name ~= "iq" then + stanza = st.clone(stanza); + stanza:add_direct_child(st.stanza("delay", {xmlns = "urn:xmpp:delay", from = from, stamp = dt.datetime()})); + end + return stanza; +end + module:hook("csi-client-inactive", function (event) local session = event.origin; if session.conn and session.conn and session.conn.pause_writes then @@ -102,11 +110,7 @@ module:hook("csi-client-inactive", function (event) pump:flush(); send(stanza); else - if st.is_stanza(stanza) and stanza.attr.xmlns == nil and stanza.name ~= "iq" then - stanza = st.clone(stanza); - stanza:add_direct_child(st.stanza("delay", {xmlns = "urn:xmpp:delay", from = bare_jid, stamp = dt.datetime()})); - end - pump:push(stanza); + pump:push(with_timestamp(stanza, bare_jid)); end return true; end -- cgit v1.2.3 From 00f3e4db9c96b7939c1cf87c514a40f58ae7fde0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 18:33:38 +0100 Subject: mod_csi_simple: Count buffered items and flush when it reaches configured limit In this mode, stanzas have been serialized to strings in the internal net.server buffer, so it is difficult to count them after the fact. --- plugins/mod_csi_simple.lua | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index 6bd6c0bf..5c829179 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -10,6 +10,7 @@ local jid = require "util.jid"; local st = require "util.stanza"; local dt = require "util.datetime"; local new_queue = require "util.queue".new; +local filters = require "util.filters"; local function new_pump(output, ...) -- luacheck: ignore 212/self @@ -92,10 +93,22 @@ local function with_timestamp(stanza, from) return stanza; end +local function manage_buffer(stanza, session) + local ctr = session.csi_counter or 0; + if ctr >= queue_size or module:fire_event("csi-is-stanza-important", { stanza = stanza, session = session }) then + session.conn:resume_writes(); + else + stanza = with_timestamp(stanza, jid.join(session.username, session.host)) + end + session.csi_counter = ctr + 1; + return stanza; +end + module:hook("csi-client-inactive", function (event) local session = event.origin; if session.conn and session.conn and session.conn.pause_writes then session.conn:pause_writes(); + filters.add_filter(session, "stanzas/out", manage_buffer); elseif session.pump then session.pump:pause(); else @@ -122,7 +135,16 @@ module:hook("csi-client-active", function (event) if session.pump then session.pump:resume(); elseif session.conn and session.conn and session.conn.resume_writes then + filters.remove_filter(session, "stanzas/out", manage_buffer); session.conn:resume_writes(); end end); + +module:hook("c2s-ondrain", function (event) + local session = event.session; + if session.state == "inactive" and session.conn and session.conn and session.conn.pause_writes then + session.csi_counter = 0; + session.conn:pause_writes(); + end +end); -- cgit v1.2.3 From 439a1e0ebb1045d72b0a3c106dc1d122783387e2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 18:58:53 +0100 Subject: mod_csi_simple: Trigger buffer flush on seeing incoming data I.e. the client sent us something, which means its network / radio is active. --- plugins/mod_csi_simple.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index 5c829179..07a8cfb3 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -104,11 +104,17 @@ local function manage_buffer(stanza, session) return stanza; end +local function flush_buffer(data, session) + session.conn:resume_writes(); + return data; +end + module:hook("csi-client-inactive", function (event) local session = event.origin; if session.conn and session.conn and session.conn.pause_writes then session.conn:pause_writes(); filters.add_filter(session, "stanzas/out", manage_buffer); + filters.add_filter(session, "bytes/in", flush_buffer); elseif session.pump then session.pump:pause(); else @@ -136,6 +142,7 @@ module:hook("csi-client-active", function (event) session.pump:resume(); elseif session.conn and session.conn and session.conn.resume_writes then filters.remove_filter(session, "stanzas/out", manage_buffer); + filters.remove_filter(session, "bytes/in", flush_buffer); session.conn:resume_writes(); end end); -- cgit v1.2.3 From 461c69ff4eca9672bac066cb7f14fdc98bdae32b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 19:02:40 +0100 Subject: mod_csi_simple: Also flush buffer in "pump" mode --- plugins/mod_csi_simple.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index 07a8cfb3..ee7e01c9 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -109,9 +109,15 @@ local function flush_buffer(data, session) return data; end +local function flush_pump(data, session) + session.pump:flush(); + return data; +end + module:hook("csi-client-inactive", function (event) local session = event.origin; if session.conn and session.conn and session.conn.pause_writes then + session.log("info", "Native net.server buffer management mode"); session.conn:pause_writes(); filters.add_filter(session, "stanzas/out", manage_buffer); filters.add_filter(session, "bytes/in", flush_buffer); @@ -124,6 +130,7 @@ module:hook("csi-client-inactive", function (event) local pump = new_pump(session.send, queue_size); pump:pause(); session.pump = pump; + filters.add_filter(session, "bytes/in", flush_pump); function session.send(stanza) if session.state == "active" or module:fire_event("csi-is-stanza-important", { stanza = stanza, session = session }) then pump:flush(); -- cgit v1.2.3 From eefe3deafa99c7d227a4e77c179dde796824cb23 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 20:22:01 +0100 Subject: mod_csi_simple: Remove old "pump" queue/buffer method, handled in net.server now --- plugins/mod_csi_simple.lua | 63 ++-------------------------------------------- 1 file changed, 2 insertions(+), 61 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index ee7e01c9..0fa0d083 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -9,42 +9,8 @@ module:depends"csi" local jid = require "util.jid"; local st = require "util.stanza"; local dt = require "util.datetime"; -local new_queue = require "util.queue".new; local filters = require "util.filters"; -local function new_pump(output, ...) - -- luacheck: ignore 212/self - local q = new_queue(...); - local flush = true; - function q:pause() - flush = false; - end - function q:resume() - flush = true; - return q:flush(); - end - local push = q.push; - function q:push(item) - local ok = push(self, item); - if not ok then - q:flush(); - output(item, self); - elseif flush then - return q:flush(); - end - return true; - end - function q:flush() - local item = self:pop(); - while item do - output(item, self); - item = self:pop(); - end - return true; - end - return q; -end - local queue_size = module:get_option_number("csi_queue_size", 256); module:hook("csi-is-stanza-important", function (event) @@ -109,45 +75,20 @@ local function flush_buffer(data, session) return data; end -local function flush_pump(data, session) - session.pump:flush(); - return data; -end - module:hook("csi-client-inactive", function (event) local session = event.origin; if session.conn and session.conn and session.conn.pause_writes then - session.log("info", "Native net.server buffer management mode"); session.conn:pause_writes(); filters.add_filter(session, "stanzas/out", manage_buffer); filters.add_filter(session, "bytes/in", flush_buffer); - elseif session.pump then - session.pump:pause(); else - local bare_jid = jid.join(session.username, session.host); - local send = session.send; - session._orig_send = send; - local pump = new_pump(session.send, queue_size); - pump:pause(); - session.pump = pump; - filters.add_filter(session, "bytes/in", flush_pump); - function session.send(stanza) - if session.state == "active" or module:fire_event("csi-is-stanza-important", { stanza = stanza, session = session }) then - pump:flush(); - send(stanza); - else - pump:push(with_timestamp(stanza, bare_jid)); - end - return true; - end + session.log("warn", "Session connection does not support write pausing"); end end); module:hook("csi-client-active", function (event) local session = event.origin; - if session.pump then - session.pump:resume(); - elseif session.conn and session.conn and session.conn.resume_writes then + if session.conn and session.conn and session.conn.resume_writes then filters.remove_filter(session, "stanzas/out", manage_buffer); filters.remove_filter(session, "bytes/in", flush_buffer); session.conn:resume_writes(); -- cgit v1.2.3 From 8ad3c66121ddc50c102061c9365411545d660625 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 20:41:25 +0100 Subject: mod_csi_simple: Separate out functions to enable/disable optimizations This allows reusing this logic outside the events. Letting the functions be module globals makes it easier to access from eg the telnet console. --- plugins/mod_csi_simple.lua | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index 0fa0d083..14abbc68 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -75,8 +75,7 @@ local function flush_buffer(data, session) return data; end -module:hook("csi-client-inactive", function (event) - local session = event.origin; +function enable_optimizations(session) if session.conn and session.conn and session.conn.pause_writes then session.conn:pause_writes(); filters.add_filter(session, "stanzas/out", manage_buffer); @@ -84,15 +83,24 @@ module:hook("csi-client-inactive", function (event) else session.log("warn", "Session connection does not support write pausing"); end -end); +end -module:hook("csi-client-active", function (event) - local session = event.origin; +function disble_optimizations(session) if session.conn and session.conn and session.conn.resume_writes then filters.remove_filter(session, "stanzas/out", manage_buffer); filters.remove_filter(session, "bytes/in", flush_buffer); session.conn:resume_writes(); end +end + +module:hook("csi-client-inactive", function (event) + local session = event.origin; + enable_optimizations(session); +end); + +module:hook("csi-client-active", function (event) + local session = event.origin; + disble_optimizations(session); end); -- cgit v1.2.3 From 0c520e8a39f380940ad216a228eb0624d85e02bd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 20:43:15 +0100 Subject: mod_csi_simple: Disable optimizations on unload and re-enable on load --- plugins/mod_csi_simple.lua | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index 14abbc68..d0de222e 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -111,3 +111,24 @@ module:hook("c2s-ondrain", function (event) session.conn:pause_writes(); end end); + +function module.load() + for _, user_session in pairs(prosody.hosts[module.host].sessions) do + for _, session in pairs(user_session.sessions) do + if session.state == "inactive" then + enable_optimizations(session); + end + end + end +end + +function module.unload() + for _, user_session in pairs(prosody.hosts[module.host].sessions) do + for _, session in pairs(user_session.sessions) do + if session.state == "inactive" then + disble_optimizations(session); + end + end + end +end + -- cgit v1.2.3 From dd0258ff779f4ccc4da11a19c344d054ba7f8430 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 20:53:49 +0100 Subject: mod_csi_simple: Add some debug logging --- plugins/mod_csi_simple.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index d0de222e..ff1fa86c 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -71,6 +71,7 @@ local function manage_buffer(stanza, session) end local function flush_buffer(data, session) + session.log("debug", "Client sent something, flushing buffer once"); session.conn:resume_writes(); return data; end @@ -109,6 +110,7 @@ module:hook("c2s-ondrain", function (event) if session.state == "inactive" and session.conn and session.conn and session.conn.pause_writes then session.csi_counter = 0; session.conn:pause_writes(); + session.log("debug", "Buffer flushed, resuming inactive mode"); end end); -- cgit v1.2.3 From ee003734474622524bcf3eea479e64a6c91f2802 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Mar 2019 22:01:36 +0100 Subject: mod_csi_simple: Improve debug logs by mentioing why the buffer gets flushed --- plugins/mod_csi_simple.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index ff1fa86c..2dda1c42 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -61,7 +61,11 @@ end local function manage_buffer(stanza, session) local ctr = session.csi_counter or 0; - if ctr >= queue_size or module:fire_event("csi-is-stanza-important", { stanza = stanza, session = session }) then + if ctr >= queue_size then + session.log("debug", "Queue size limit hit, flushing buffer"); + session.conn:resume_writes(); + elseif module:fire_event("csi-is-stanza-important", { stanza = stanza, session = session }) then + session.log("debug", "Important stanza, flushing buffer"); session.conn:resume_writes(); else stanza = with_timestamp(stanza, jid.join(session.username, session.host)) -- cgit v1.2.3 From 3179518b6ac887fef63d5ffa83b2020691809299 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 25 Mar 2019 10:32:39 +0000 Subject: mod_csi_simple: Fix type in function name --- plugins/mod_csi_simple.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index 2dda1c42..c79c56fc 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -90,7 +90,7 @@ function enable_optimizations(session) end end -function disble_optimizations(session) +function disable_optimizations(session) if session.conn and session.conn and session.conn.resume_writes then filters.remove_filter(session, "stanzas/out", manage_buffer); filters.remove_filter(session, "bytes/in", flush_buffer); @@ -105,7 +105,7 @@ end); module:hook("csi-client-active", function (event) local session = event.origin; - disble_optimizations(session); + disable_optimizations(session); end); @@ -132,9 +132,8 @@ function module.unload() for _, user_session in pairs(prosody.hosts[module.host].sessions) do for _, session in pairs(user_session.sessions) do if session.state == "inactive" then - disble_optimizations(session); + disable_optimizations(session); end end end end - -- cgit v1.2.3 From 65f01dec0dc42ee9e1997f2dcddeb6375cdc92c8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 25 Mar 2019 15:20:28 +0100 Subject: mod_csi_simple: Include queue size in debug messages --- plugins/mod_csi_simple.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index c79c56fc..a9148618 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -62,10 +62,10 @@ end local function manage_buffer(stanza, session) local ctr = session.csi_counter or 0; if ctr >= queue_size then - session.log("debug", "Queue size limit hit, flushing buffer"); + session.log("debug", "Queue size limit hit, flushing buffer (queue size is %d)", session.csi_counter); session.conn:resume_writes(); elseif module:fire_event("csi-is-stanza-important", { stanza = stanza, session = session }) then - session.log("debug", "Important stanza, flushing buffer"); + session.log("debug", "Important stanza, flushing buffer (queue size is %d)", session.csi_counter); session.conn:resume_writes(); else stanza = with_timestamp(stanza, jid.join(session.username, session.host)) @@ -75,7 +75,7 @@ local function manage_buffer(stanza, session) end local function flush_buffer(data, session) - session.log("debug", "Client sent something, flushing buffer once"); + session.log("debug", "Client sent something, flushing buffer once (queue size is %d)", session.csi_counter); session.conn:resume_writes(); return data; end @@ -112,9 +112,9 @@ end); module:hook("c2s-ondrain", function (event) local session = event.session; if session.state == "inactive" and session.conn and session.conn and session.conn.pause_writes then - session.csi_counter = 0; session.conn:pause_writes(); - session.log("debug", "Buffer flushed, resuming inactive mode"); + session.log("debug", "Buffer flushed, resuming inactive mode (queue size was %d)", session.csi_counter); + session.csi_counter = 0; end end); -- cgit v1.2.3 From 0c7ea2e51a59a69ab23abc505bbcd9b6ba3722bc Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 26 Mar 2019 14:48:21 +0000 Subject: loggingmanager, mod_posix: Move syslog to core, fixes #541 (in a way) --- plugins/mod_posix.lua | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_posix.lua b/plugins/mod_posix.lua index 23df4d23..8367ae9e 100644 --- a/plugins/mod_posix.lua +++ b/plugins/mod_posix.lua @@ -113,19 +113,6 @@ local function write_pidfile() end end -local syslog_opened; -function syslog_sink_maker(config) -- luacheck: ignore 212/config - if not syslog_opened then - pposix.syslog_open("prosody", module:get_option_string("syslog_facility")); - syslog_opened = true; - end - local syslog = pposix.syslog_log; - return function (name, level, message, ...) - syslog(level, name, format(message, ...)); - end; -end -require "core.loggingmanager".register_sink_type("syslog", syslog_sink_maker); - local daemonize = module:get_option("daemonize", prosody.installed); local function remove_log_sinks() -- cgit v1.2.3 From f7b4b8ed7a50a034299e0e24ac9003757c01d78d Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 26 Mar 2019 14:59:42 +0000 Subject: mod_posix: Remove unnecessary import of util.format (thanks luacheck and buildbot) --- plugins/mod_posix.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_posix.lua b/plugins/mod_posix.lua index 8367ae9e..a2a60dd0 100644 --- a/plugins/mod_posix.lua +++ b/plugins/mod_posix.lua @@ -20,7 +20,6 @@ if not have_signal then module:log("warn", "Couldn't load signal library, won't respond to SIGTERM"); end -local format = require "util.format".format; local lfs = require "lfs"; local stat = lfs.attributes; -- cgit v1.2.3 From ad925d5dad90ae6462302e74325b74c88ff1fceb Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 2 Apr 2019 21:17:28 +0200 Subject: mod_limits: Fix indentation Appears to have been messed up in 60e113f3682f --- plugins/mod_limits.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_limits.lua b/plugins/mod_limits.lua index 914d5c44..32bc75a9 100644 --- a/plugins/mod_limits.lua +++ b/plugins/mod_limits.lua @@ -51,18 +51,18 @@ end local default_filter_set = {}; function default_filter_set.bytes_in(bytes, session) - local sess_throttle = session.throttle; - if sess_throttle then - local ok, balance, outstanding = sess_throttle:poll(#bytes, true); + local sess_throttle = session.throttle; + if sess_throttle then + local ok, balance, outstanding = sess_throttle:poll(#bytes, true); if not ok then - session.log("debug", "Session over rate limit (%d) with %d (by %d), pausing", sess_throttle.max, #bytes, outstanding); + session.log("debug", "Session over rate limit (%d) with %d (by %d), pausing", sess_throttle.max, #bytes, outstanding); outstanding = ceil(outstanding); session.conn:pause(); -- Read no more data from the connection until there is no outstanding data local outstanding_data = bytes:sub(-outstanding); bytes = bytes:sub(1, #bytes-outstanding); timer.add_task(limits_resolution, function () if not session.conn then return; end - if sess_throttle:peek(#outstanding_data) then + if sess_throttle:peek(#outstanding_data) then session.log("debug", "Resuming paused session"); session.conn:resume(); end -- cgit v1.2.3 From 0f802ffe183a94cc9407cdf92bb9eaa9c213e602 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 2 Apr 2019 20:38:51 +0200 Subject: mod_limits: Allow configuring a list of unrestricted JIDs (fixes #1323) --- plugins/mod_limits.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_limits.lua b/plugins/mod_limits.lua index 32bc75a9..56e3faaf 100644 --- a/plugins/mod_limits.lua +++ b/plugins/mod_limits.lua @@ -96,3 +96,20 @@ end function module.unload() filters.remove_filter_hook(filter_hook); end + +function module.add_host(module) + local unlimited_jids = module:get_option_inherited_set("unlimited_jids", {}); + + if not unlimited_jids:empy() then + module:hook("authentication-success", function (event) + local session = event.session; + local session_type = session.type:match("^[^_]+"); + local jid = session.username .. "@" .. session.host; + if unlimited_jids:contains(jid) then + local filter_set = type_filters[session_type]; + filters.remove_filter(session, "bytes/in", filter_set.bytes_in); + session.throttle = nil; + end + end); + end +end -- cgit v1.2.3 From fc818b419ebf2ef4991020744e0a2cb15ccf201a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 2 Apr 2019 21:22:20 +0200 Subject: mod_limits: Fix typo --- plugins/mod_limits.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_limits.lua b/plugins/mod_limits.lua index 56e3faaf..7ae8bb34 100644 --- a/plugins/mod_limits.lua +++ b/plugins/mod_limits.lua @@ -100,7 +100,7 @@ end function module.add_host(module) local unlimited_jids = module:get_option_inherited_set("unlimited_jids", {}); - if not unlimited_jids:empy() then + if not unlimited_jids:empty() then module:hook("authentication-success", function (event) local session = event.session; local session_type = session.type:match("^[^_]+"); -- cgit v1.2.3 From 568fc99fea90769ea7ddac77cbf1028ca3c332d2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 5 Apr 2019 17:12:19 +0200 Subject: mod_http_files: Use net.http.files --- plugins/mod_http_files.lua | 169 +++++++++------------------------------------ 1 file changed, 33 insertions(+), 136 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 1dae0d6d..acb99501 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -7,14 +7,9 @@ -- module:depends("http"); -local server = require"net.http.server"; -local lfs = require "lfs"; -local os_date = os.date; local open = io.open; -local stat = lfs.attributes; -local build_path = require"socket.url".build_path; -local path_sep = package.config:sub(1,1); +local fileserver = require"net.http.files"; local base_path = module:get_option_path("http_files_dir", module:get_option_path("http_path")); local cache_size = module:get_option_number("http_files_cache_size", 128); @@ -51,148 +46,50 @@ if not mime_map then end end -local forbidden_chars_pattern = "[/%z]"; -if prosody.platform == "windows" then - forbidden_chars_pattern = "[/%z\001-\031\127\"*:<>?|]" -end - -local urldecode = require "util.http".urldecode; -function sanitize_path(path) - if not path then return end - local out = {}; - - local c = 0; - for component in path:gmatch("([^/]+)") do - component = urldecode(component); - if component:find(forbidden_chars_pattern) then - return nil; - elseif component == ".." then - if c <= 0 then - return nil; - end - out[c] = nil; - c = c - 1; - elseif component ~= "." then - c = c + 1; - out[c] = component; - end - end - if path:sub(-1,-1) == "/" then - out[c+1] = ""; - end - return "/"..table.concat(out, "/"); -end - -local cache = require "util.cache".new(cache_size); - +-- COMPAT -- TODO deprecate function serve(opts) if type(opts) ~= "table" then -- assume path string opts = { path = opts }; end - -- luacheck: ignore 431 - local base_path = opts.path; - local dir_indices = opts.index_files or dir_indices; - local directory_index = opts.directory_index; - local function serve_file(event, path) - local request, response = event.request, event.response; - local sanitized_path = sanitize_path(path); - if path and not sanitized_path then - return 400; - end - path = sanitized_path; - local orig_path = sanitize_path(request.path); - local full_path = base_path .. (path or ""):gsub("/", path_sep); - local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows - if not attr then - return 404; - end - - local request_headers, response_headers = request.headers, response.headers; - - local last_modified = os_date('!%a, %d %b %Y %H:%M:%S GMT', attr.modification); - response_headers.last_modified = last_modified; - - local etag = ('"%02x-%x-%x-%x"'):format(attr.dev or 0, attr.ino or 0, attr.size or 0, attr.modification or 0); - response_headers.etag = etag; - - local if_none_match = request_headers.if_none_match - local if_modified_since = request_headers.if_modified_since; - if etag == if_none_match - or (not if_none_match and last_modified == if_modified_since) then - return 304; - end - - local data = cache:get(orig_path); - if data and data.etag == etag then - response_headers.content_type = data.content_type; - data = data.data; - elseif attr.mode == "directory" and path then - if full_path:sub(-1) ~= "/" then - local dir_path = { is_absolute = true, is_directory = true }; - for dir in orig_path:gmatch("[^/]+") do dir_path[#dir_path+1]=dir; end - response_headers.location = build_path(dir_path); - return 301; - end - for i=1,#dir_indices do - if stat(full_path..dir_indices[i], "mode") == "file" then - return serve_file(event, path..dir_indices[i]); - end - end - - if directory_index then - data = server._events.fire_event("directory-index", { path = request.path, full_path = full_path }); - end - if not data then - return 403; - end - cache:set(orig_path, { data = data, content_type = mime_map.html; etag = etag; }); - response_headers.content_type = mime_map.html; - - else - local f, err = open(full_path, "rb"); - if not f then - module:log("debug", "Could not open %s. Error was %s", full_path, err); - return 403; - end - local ext = full_path:match("%.([^./]+)$"); - local content_type = ext and mime_map[ext]; - response_headers.content_type = content_type; - if attr.size > cache_max_file_size then - response_headers.content_length = attr.size; - module:log("debug", "%d > cache_max_file_size", attr.size); - return response:send_file(f); - else - data = f:read("*a"); - f:close(); - end - cache:set(orig_path, { data = data; content_type = content_type; etag = etag }); - end - - return response:send(data); + if opts.directory_index == nil then + opts.directory_index = directory_index; end - - return serve_file; + if opts.mime_map == nil then + opts.mime_map = mime_map; + end + if opts.cache_size == nil then + opts.cache_size = cache_size; + end + if opts.cache_max_file_size == nil then + opts.cache_max_file_size = cache_max_file_size; + end + if opts.index_files == nil then + opts.index_files = dir_indices; + end + -- TODO Crank up to warning + module:log("debug", "Use of mod_http_files.serve() should be updated to use net.http.files"); + return fileserver.serve(opts); end function wrap_route(routes) + module:log("debug", "Use of mod_http_files.wrap_route() should be updated to use net.http.files"); for route,handler in pairs(routes) do if type(handler) ~= "function" then - routes[route] = serve(handler); + routes[route] = fileserver.serve(handler); end end return routes; end -if base_path then - module:provides("http", { - route = { - ["GET /*"] = serve { - path = base_path; - directory_index = directory_index; - } - }; - }); -else - module:log("debug", "http_files_dir not set, assuming use by some other module"); -end - +module:provides("http", { + route = { + ["GET /*"] = fileserver.serve({ + path = base_path; + directory_index = directory_index; + mime_map = mime_map; + cache_size = cache_size; + cache_max_file_size = cache_max_file_size; + index_files = dir_indices; + }); + }; +}); -- cgit v1.2.3 From 9163493840c796d31feabdf3d3d379442e3a7020 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 5 Apr 2019 18:18:23 +0200 Subject: mod_http_files: Try to determine which module using serve() needs updating --- plugins/mod_http_files.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index acb99501..c357ddfc 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -46,6 +46,12 @@ if not mime_map then end end +local function get_calling_module() + local info = debug.getinfo(3, "S"); + if not info then return "An unknown module"; end + return info.source:match"mod_[^/\\.]+" or info.short_src; +end + -- COMPAT -- TODO deprecate function serve(opts) if type(opts) ~= "table" then -- assume path string @@ -67,12 +73,12 @@ function serve(opts) opts.index_files = dir_indices; end -- TODO Crank up to warning - module:log("debug", "Use of mod_http_files.serve() should be updated to use net.http.files"); + module:log("debug", "%s should be updated to use 'net.http.files' insead of mod_http_files", get_calling_module()); return fileserver.serve(opts); end function wrap_route(routes) - module:log("debug", "Use of mod_http_files.wrap_route() should be updated to use net.http.files"); + module:log("debug", "%s should be updated to use 'net.http.files' insead of mod_http_files", get_calling_module()); for route,handler in pairs(routes) do if type(handler) ~= "function" then routes[route] = fileserver.serve(handler); -- cgit v1.2.3 From cb8a085c3bcbec83ad6b65631f8189e406bca042 Mon Sep 17 00:00:00 2001 From: Jo?o Duarte Date: Wed, 17 Apr 2019 10:11:22 -0700 Subject: mod_admin_telnet: Adds c2s:closeall() (Fixes #1315) --- plugins/mod_admin_telnet.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 34cc4dc6..c66630ca 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -250,6 +250,7 @@ function commands.help(session, data) print [[c2s:show_secure() - Show all encrypted client connections]] print [[c2s:show_tls() - Show TLS cipher info for encrypted sessions]] print [[c2s:close(jid) - Close all sessions for the specified JID]] + print [[c2s:closeall() - Close all active c2s connections ]] elseif section == "s2s" then print [[s2s:show(domain) - Show all s2s connections for the given domain (or all if no domain given)]] print [[s2s:show_tls(domain) - Show TLS cipher info for encrypted sessions]] @@ -661,6 +662,16 @@ function def_env.c2s:close(match_jid) return true, "Total: "..count.." sessions closed"; end +function def_env.c2s:closeall() + local count = 0; + --luacheck: ignore 212/jid + show_c2s(function (jid, session) + count = count + 1; + session:close(); + end); + return true, "Total: "..count.." sessions closed"; +end + def_env.s2s = {}; function def_env.s2s:show(match_jid, annotate) -- cgit v1.2.3 From d8a52f2c8a9b1ca96d9f9c08024e5ac55476e89b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 6 Aug 2012 15:35:27 +0200 Subject: mod_mimicking: Prevents registration of confusable usernames (by Florob) (fixes #1347) --- plugins/mod_mimicking.lua | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 plugins/mod_mimicking.lua (limited to 'plugins') diff --git a/plugins/mod_mimicking.lua b/plugins/mod_mimicking.lua new file mode 100644 index 00000000..9004957a --- /dev/null +++ b/plugins/mod_mimicking.lua @@ -0,0 +1,49 @@ +-- 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 skeleton = require "util.confusable".skeleton; +local datamanager = require "util.datamanager"; +local usage = require "util.prosodyctl".show_usage; +local warn = require "util.prosodyctl".show_warning; +local users = require "usermanager".users; + +module:hook("user-registered", function(user) + datamanager.store(skeleton(user.username), user.host, "skeletons", {username = user.username}); +end); + +module:hook("user-deregistered", function(user) + datamanager.store(skeleton(user.username), user.host, "skeletons", nil); +end); + +module:hook("registration-attempt", function(user) + if datamanager.load(skeleton(user.username), user.host, "skeletons") then + user.allowed = false; + end +end); + +function module.command(arg) + if (arg[1] ~= "bootstrap" or not arg[2]) then + usage("mod_mimicking bootstrap ", "Initialize skeleton database"); + return; + end + + local host = arg[2]; + + local host_session = prosody.hosts[host]; + if not host_session then + return "No such host"; + end + local provider = host_session.users; + if not(provider) or provider.name == "null" then + usermanager.initialize_host(host); + end + storagemanager.initialize_host(host); + + for user in users(host) do + datamanager.store(skeleton(user), host, "skeletons", {username = user}); + end +end -- cgit v1.2.3 From 701fd99947b8d897a60c74b1c2f4ab39fc620876 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Apr 2019 02:40:39 +0200 Subject: mod_mimicking: Import skeleton() from current location --- plugins/mod_mimicking.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_mimicking.lua b/plugins/mod_mimicking.lua index 9004957a..da03967f 100644 --- a/plugins/mod_mimicking.lua +++ b/plugins/mod_mimicking.lua @@ -1,11 +1,15 @@ -- Prosody IM -- Copyright (C) 2012 Florian Zeitz +-- Copyright (C) 2019 Kim Alvefur -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- -local skeleton = require "util.confusable".skeleton; +local encodings = require "util.encodings"; +assert(encodings.confusable, "This module requires that Prosody be built with ICU"); +local skeleton = encodings.confusable.skeleton; + local datamanager = require "util.datamanager"; local usage = require "util.prosodyctl".show_usage; local warn = require "util.prosodyctl".show_warning; -- cgit v1.2.3 From 1054f2438b2f56790a7d5dcdcb3f841d460d27e7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Apr 2019 02:37:35 +0200 Subject: mod_mimicking: Hook the correct event names --- plugins/mod_mimicking.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_mimicking.lua b/plugins/mod_mimicking.lua index da03967f..8b8d6ee3 100644 --- a/plugins/mod_mimicking.lua +++ b/plugins/mod_mimicking.lua @@ -19,11 +19,11 @@ module:hook("user-registered", function(user) datamanager.store(skeleton(user.username), user.host, "skeletons", {username = user.username}); end); -module:hook("user-deregistered", function(user) +module:hook("user-deleted", function(user) datamanager.store(skeleton(user.username), user.host, "skeletons", nil); end); -module:hook("registration-attempt", function(user) +module:hook("user-registering", function(user) if datamanager.load(skeleton(user.username), user.host, "skeletons") then user.allowed = false; end -- cgit v1.2.3 From 00887cf07d565353152332f0adb854659e237fbf Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Apr 2019 02:38:55 +0200 Subject: mod_mimicking: Use new storage API --- plugins/mod_mimicking.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_mimicking.lua b/plugins/mod_mimicking.lua index 8b8d6ee3..0da68059 100644 --- a/plugins/mod_mimicking.lua +++ b/plugins/mod_mimicking.lua @@ -10,21 +10,22 @@ local encodings = require "util.encodings"; assert(encodings.confusable, "This module requires that Prosody be built with ICU"); local skeleton = encodings.confusable.skeleton; -local datamanager = require "util.datamanager"; local usage = require "util.prosodyctl".show_usage; local warn = require "util.prosodyctl".show_warning; local users = require "usermanager".users; +local skeletons = module:open_store("skeletons"); + module:hook("user-registered", function(user) - datamanager.store(skeleton(user.username), user.host, "skeletons", {username = user.username}); + skeletons:set(skeleton(user.username), { username = user.username }); end); module:hook("user-deleted", function(user) - datamanager.store(skeleton(user.username), user.host, "skeletons", nil); + skeletons:set(skeleton(user.username), nil); end); module:hook("user-registering", function(user) - if datamanager.load(skeleton(user.username), user.host, "skeletons") then + if skeletons:get(skeleton(user.username)) then user.allowed = false; end end); -- cgit v1.2.3 From 54d0329e4c0809920c954a45e448263d3a669a2b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Apr 2019 02:40:14 +0200 Subject: mod_mimicking: Update command to work with current code --- plugins/mod_mimicking.lua | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_mimicking.lua b/plugins/mod_mimicking.lua index 0da68059..a8d6803e 100644 --- a/plugins/mod_mimicking.lua +++ b/plugins/mod_mimicking.lua @@ -11,10 +11,15 @@ assert(encodings.confusable, "This module requires that Prosody be built with IC local skeleton = encodings.confusable.skeleton; local usage = require "util.prosodyctl".show_usage; -local warn = require "util.prosodyctl".show_warning; -local users = require "usermanager".users; +local usermanager = require "core.usermanager"; +local storagemanager = require "core.storagemanager"; -local skeletons = module:open_store("skeletons"); +local skeletons +function module.load() + if module.host ~= "*" then + skeletons = module:open_store("skeletons"); + end +end module:hook("user-registered", function(user) skeletons:set(skeleton(user.username), { username = user.username }); @@ -42,13 +47,13 @@ function module.command(arg) if not host_session then return "No such host"; end - local provider = host_session.users; - if not(provider) or provider.name == "null" then - usermanager.initialize_host(host); - end + storagemanager.initialize_host(host); + usermanager.initialize_host(host); + + skeletons = storagemanager.open(host, "skeletons"); - for user in users(host) do - datamanager.store(skeleton(user), host, "skeletons", {username = user}); + for user in usermanager.users(host) do + skeletons:set(skeleton(user), { username = user }); end end -- cgit v1.2.3 From 21d4a58469853ebffca787cfc76e9b7d8b40d9b4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Apr 2019 17:26:56 +0200 Subject: mod_mimicking: Use more intuitive term "mimicry index" for skeletons Fits better with the module name too. --- plugins/mod_mimicking.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_mimicking.lua b/plugins/mod_mimicking.lua index a8d6803e..43d165d2 100644 --- a/plugins/mod_mimicking.lua +++ b/plugins/mod_mimicking.lua @@ -37,7 +37,7 @@ end); function module.command(arg) if (arg[1] ~= "bootstrap" or not arg[2]) then - usage("mod_mimicking bootstrap ", "Initialize skeleton database"); + usage("mod_mimicking bootstrap ", "Initialize username mimicry index"); return; end -- cgit v1.2.3 From 41c9fe2b76ee5bd90eeb948c7bb75bf94906b102 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Apr 2019 17:27:08 +0200 Subject: mod_mimicking: Improve error handling --- plugins/mod_mimicking.lua | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_mimicking.lua b/plugins/mod_mimicking.lua index 43d165d2..b586a70c 100644 --- a/plugins/mod_mimicking.lua +++ b/plugins/mod_mimicking.lua @@ -22,22 +22,34 @@ function module.load() end module:hook("user-registered", function(user) - skeletons:set(skeleton(user.username), { username = user.username }); + local skel = skeleton(user.username); + local ok, err = skeletons:set(skel, { username = user.username }); + if not ok then + module:log("error", "Unable to store mimicry data (%q => %q): %s", user.username, skel, err); + end end); module:hook("user-deleted", function(user) - skeletons:set(skeleton(user.username), nil); + local skel = skeleton(user.username); + local ok, err = skeletons:set(skel, nil); + if not ok and err then + module:log("error", "Unable to clear mimicry data (%q): %s", skel, err); + end end); module:hook("user-registering", function(user) - if skeletons:get(skeleton(user.username)) then + local existing, err = skeletons:get(skeleton(user.username)); + if existing then + module:log("debug", "Attempt to register username '%s' which could be confused with '%s'", user.username, existing.username); user.allowed = false; + elseif err then + module:log("error", "Unable to check if new username '%s' can be confused with any existing user: %s", err); end end); function module.command(arg) if (arg[1] ~= "bootstrap" or not arg[2]) then - usage("mod_mimicking bootstrap ", "Initialize username mimicry index"); + usage("mod_mimicking bootstrap ", "Initialize username mimicry database"); return; end @@ -53,7 +65,21 @@ function module.command(arg) skeletons = storagemanager.open(host, "skeletons"); + local count = 0; for user in usermanager.users(host) do - skeletons:set(skeleton(user), { username = user }); + local skel = skeleton(user); + local existing, err = skeletons:get(skel); + if existing and existing.username ~= user then + module:log("warn", "Existing usernames '%s' and '%s' are confusable", existing.username, user); + elseif err then + module:log("error", "Error checking for existing mimicry data (%q = %q): %s", user, skel, err); + end + local ok, err = skeletons:set(skel, { username = user }); + if ok then + count = count + 1; + elseif err then + module:log("error", "Unable to store mimicry data (%q => %q): %s", user, skel, err); + end end + module:log("info", "%d usernames indexed", count); end -- cgit v1.2.3 From 30ef8e7ac46587732ab469e9775229e8d78e1845 Mon Sep 17 00:00:00 2001 From: Arc Riley Date: Thu, 2 May 2019 16:33:14 -0700 Subject: mod_admin_telnet: include BOSH connections in c2s session commands (#998) --- plugins/mod_admin_telnet.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index c66630ca..5ee25771 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -591,6 +591,7 @@ end local function show_c2s(callback) local c2s = array.collect(values(module:shared"/*/c2s/sessions")); + c2s:append(values(module:shared"/*/bosh/sessions")); c2s:sort(function(a, b) if a.host == b.host then if a.username == b.username then -- cgit v1.2.3 From cdbb6348f6536cb270544c933f3e45ccf66ef585 Mon Sep 17 00:00:00 2001 From: Arc Riley Date: Thu, 2 May 2019 17:28:49 -0700 Subject: mod_admin_telnet: added "(bosh)" and "(websocket)" connection flags (#998) --- plugins/mod_admin_telnet.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 5ee25771..248d6b07 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -554,6 +554,12 @@ local function session_flags(session, line) if session.is_bidi then line[#line+1] = "(bidi)"; end + if session.bosh_version then + line[#line+1] = "(bosh)"; + end + if session.websocket_request then + line[#line+1] = "(websocket)"; + end return table.concat(line, " "); end -- cgit v1.2.3 From da0d3e296ca8fef7882cbf571039b153525a1185 Mon Sep 17 00:00:00 2001 From: Arc Riley Date: Thu, 2 May 2019 17:44:21 -0700 Subject: mod_admin_telnet: include BOSH connections in c2s:count (#998) --- plugins/mod_admin_telnet.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 248d6b07..0fbd3ff9 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -612,7 +612,9 @@ local function show_c2s(callback) end function def_env.c2s:count() - return true, "Total: ".. iterators.count(values(module:shared"/*/c2s/sessions")) .." clients"; + local c2s_count = iterators.count(values(module:shared"/*/c2s/sessions")) + local bosh_count = iterators.count(values(module:shared"/*/bosh/sessions")) + return true, "Total: ".. c2s_count + bosh_count .." clients"; end function def_env.c2s:show(match_jid, annotate) -- cgit v1.2.3 From 5bf3c84d07ff55408262ab5644752f6f0e28415e Mon Sep 17 00:00:00 2001 From: Arc Riley Date: Fri, 3 May 2019 04:10:31 -0700 Subject: mod_bosh: Added metrics for active/inactive sessions, new BOSH sessions, BOSH errors, and timeouts (finishes #998) --- plugins/mod_bosh.lua | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 082ed961..d4e980f2 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -55,6 +55,27 @@ local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat; -- All sessions, and sessions that have no requests open local sessions = module:shared("sessions"); +local measure_active = module:measure("active_sessions", "amount"); +local measure_inactive = module:measure("inactive_sessions", "amount"); +local report_bad_host = module:measure("bad_host", "rate"); +local report_bad_sid = module:measure("bad_sid", "rate"); +local report_new_sid = module:measure("new_sid", "rate"); +local report_timeout = module:measure("timeout", "rate"); + +module:hook("stats-update", function () + local active = 0; + local inactive = 0; + for _, session in pairs(sessions) do + if #session.requests > 0 then + active = active + 1; + else + inactive = inactive + 1; + end + end + measure_active(active); + measure_inactive(inactive); +end); + -- Used to respond to idle sessions (those with waiting requests) function on_destroy_request(request) log("debug", "Request destroyed: %s", tostring(request)); @@ -74,7 +95,7 @@ function on_destroy_request(request) if session.inactive_timer then session.inactive_timer:stop(); end - session.inactive_timer = module:add_timer(max_inactive, check_inactive, session, request.context, + session.inactive_timer = module:add_timer(max_inactive, session_timeout, session, request.context, "BOSH client silent for over "..max_inactive.." seconds"); (session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive); end @@ -85,8 +106,9 @@ function on_destroy_request(request) end end -function check_inactive(now, session, context, reason) -- luacheck: ignore 212/now +function session_timeout(now, session, context, reason) -- luacheck: ignore 212/now if not session.destroyed then + report_timeout(); sessions[context.sid] = nil; sm_destroy_session(session, reason); end @@ -186,6 +208,7 @@ function handle_POST(event) return; end module:log("warn", "Unable to associate request with a session (incomplete request?)"); + report_bad_sid(); local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", ["xmlns:stream"] = xmlns_streams, condition = "item-not-found" }); return tostring(close_reply) .. "\n"; @@ -253,6 +276,7 @@ function stream_callbacks.streamopened(context, attr) local wait = tonumber(attr.wait); if not to_host then log("debug", "BOSH client tried to connect to invalid host: %s", tostring(attr.to)); + report_bad_host(); local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", ["xmlns:stream"] = xmlns_streams, condition = "improper-addressing" }); response:send(tostring(close_reply)); @@ -290,6 +314,7 @@ function stream_callbacks.streamopened(context, attr) session.log("debug", "BOSH session created for request from %s", session.ip); log("info", "New BOSH session, assigned it sid '%s'", sid); + report_new_sid(); module:fire_event("bosh-session", { session = session, request = request }); @@ -344,6 +369,7 @@ function stream_callbacks.streamopened(context, attr) if not session then -- Unknown sid log("info", "Client tried to use sid '%s' which we don't know about", sid); + report_bad_sid(); response:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" }))); context.notopen = nil; return; -- cgit v1.2.3 From 690c6a4eb240ede63cf7a31007c25df29fa123f2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 3 May 2019 20:54:24 +0200 Subject: Fix various spelling mistakes [codespell] --- plugins/mod_blocklist.lua | 2 +- plugins/mod_saslauth.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_blocklist.lua b/plugins/mod_blocklist.lua index 8aca7332..2193a093 100644 --- a/plugins/mod_blocklist.lua +++ b/plugins/mod_blocklist.lua @@ -159,7 +159,7 @@ local function edit_blocklist(event) local blocklist = cache[username] or get_blocklist(username); local new_blocklist = { - -- We set the [false] key to someting as a signal not to migrate privacy lists + -- We set the [false] key to something as a signal not to migrate privacy lists [false] = blocklist[false] or { created = now; }; }; if type(blocklist[false]) == "table" then diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index ba30b9e6..3145cf9b 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -248,7 +248,7 @@ module:hook("stream-features", function(event) local sasl_handler = usermanager_get_sasl_handler(module.host, origin) origin.sasl_handler = sasl_handler; if origin.encrypted then - -- check wether LuaSec has the nifty binding to the function needed for tls-unique + -- check whether LuaSec has the nifty binding to the function needed for tls-unique -- FIXME: would be nice to have this check only once and not for every socket if sasl_handler.add_cb_handler then local socket = origin.conn:socket(); -- cgit v1.2.3 From 200664ab8a16a7f5a4d4a2de878c9f94cbeb4a8f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 5 May 2019 08:12:16 +0200 Subject: mod_storage_internal,memory: Only return total count if requested --- plugins/mod_storage_internal.lua | 17 +++++++++++------ plugins/mod_storage_memory.lua | 17 ++++++++++++----- 2 files changed, 23 insertions(+), 11 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index aa5c3c8a..f921747e 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -124,11 +124,14 @@ function archive:find(username, query) if not items then if err then return items, err; - else - return function () end, 0; + elseif query then + if query.total then + return function () end, 0; + end end + return function () end; end - local count = #items; + local count = nil; local i = 0; if query then items = array(items); @@ -152,11 +155,13 @@ function archive:find(username, query) return item.when <= query["end"]; end); end - count = #items; + if query.total then + count = #items; + end if query.reverse then items:reverse(); if query.before then - for j = 1, count do + for j = 1, #items do if (items[j].key or tostring(j)) == query.before then i = j; break; @@ -164,7 +169,7 @@ function archive:find(username, query) end end elseif query.after then - for j = 1, count do + for j = 1, #items do if (items[j].key or tostring(j)) == query.after then i = j; break; diff --git a/plugins/mod_storage_memory.lua b/plugins/mod_storage_memory.lua index dde2d571..4655cb3a 100644 --- a/plugins/mod_storage_memory.lua +++ b/plugins/mod_storage_memory.lua @@ -90,9 +90,14 @@ end function archive_store:find(username, query) local items = self.store[username or NULL]; if not items then - return function () end, 0; + if query then + if query.total then + return function () end, 0; + end + end + return function () end; end - local count = #items; + local count = nil; local i = 0; if query then items = array():append(items); @@ -116,11 +121,13 @@ function archive_store:find(username, query) return item.when <= query["end"]; end); end - count = #items; + if query.total then + count = #items; + end if query.reverse then items:reverse(); if query.before then - for j = 1, count do + for j = 1, #items do if (items[j].key or tostring(j)) == query.before then i = j; break; @@ -128,7 +135,7 @@ function archive_store:find(username, query) end end elseif query.after then - for j = 1, count do + for j = 1, #items do if (items[j].key or tostring(j)) == query.after then i = j; break; -- cgit v1.2.3 From c39b08a25d18e6ca268a3c75f52992255d7b3e50 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 5 May 2019 14:52:34 +0200 Subject: mod_muc_mam: Handle archive quotas Same as in mod_mam --- plugins/mod_muc_mam.lua | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_muc_mam.lua b/plugins/mod_muc_mam.lua index 35eabd3b..fffe23e7 100644 --- a/plugins/mod_muc_mam.lua +++ b/plugins/mod_muc_mam.lua @@ -33,6 +33,9 @@ local m_min = math.min; local timestamp, timestamp_parse, datestamp = import( "util.datetime", "datetime", "parse", "date"); local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", 50); +local cleanup_after = module:get_option_string("muc_log_expires_after", "1w"); +local cleanup_interval = module:get_option_number("muc_log_cleanup_interval", 4 * 60 * 60); + local default_history_length = 20; local max_history_length = module:get_option_number("max_history_messages", math.huge); @@ -50,6 +53,8 @@ local log_by_default = module:get_option_boolean("muc_log_by_default", true); local archive_store = "muc_log"; local archive = module:open_store(archive_store, "archive"); +local archive_item_limit = module:get_option_number("storage_archive_item_limit", archive.caps and archive.caps.quota or 1000); + if archive.name == "null" or not archive.find then if not archive.find then module:log("error", "Attempt to open archive storage returned a driver without archive API support"); @@ -64,12 +69,15 @@ end local function archiving_enabled(room) if log_all_rooms then + module:log("debug", "Archiving all rooms"); return true; end local enabled = room._data.archiving; if enabled == nil then + module:log("debug", "Default is %s (for %s)", log_by_default, room.jid); return log_by_default; end + module:log("debug", "Logging in room %s is %s", room.jid, enabled); return enabled; end @@ -357,7 +365,29 @@ local function save_to_history(self, stanza) end -- And stash it - local id = archive:append(room_node, nil, stored_stanza, time_now(), with); + local time = time_now(); + local id, err = archive:append(room_node, nil, stored_stanza, time, with); + + if not id and err == "quota-limit" then + if type(cleanup_after) == "number" then + module:log("debug", "Room '%s' over quota, cleaning archive", room_node); + local cleaned = archive:delete(room_node, { + ["end"] = (os.time() - cleanup_after); + }); + if cleaned then + id, err = archive:append(room_node, nil, stored_stanza, time, with); + end + end + if not id and (archive.caps and archive.caps.truncate) then + module:log("debug", "User '%s' over quota, truncating archive", room_node); + local truncated = archive:delete(room_node, { + truncate = archive_item_limit - 1; + }); + if truncated then + id, err = archive:append(room_node, nil, stored_stanza, time, with); + end + end + end if id then schedule_cleanup(room_node); @@ -399,9 +429,6 @@ end); -- Cleanup -local cleanup_after = module:get_option_string("muc_log_expires_after", "1w"); -local cleanup_interval = module:get_option_number("muc_log_cleanup_interval", 4 * 60 * 60); - if cleanup_after ~= "never" then local cleanup_storage = module:open_store("muc_log_cleanup"); local cleanup_map = module:open_store("muc_log_cleanup", "map"); -- cgit v1.2.3 From 017e7f74389c0e20a1baaae682fd85b825975592 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 5 May 2019 16:07:16 +0200 Subject: mod_storage_internal: Add support for iterating over users in archive stores May help with writing a better migrator --- plugins/mod_storage_internal.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index f921747e..96780b33 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -211,6 +211,10 @@ function archive:summary(username, query) return summary; end +function archive:users() + return datamanager.users(host, self.store, "list"); +end + function archive:delete(username, query) local cache_key = jid_join(username, host, self.store); if not query or next(query) == nil then -- cgit v1.2.3 From 696da1f571e723216a1e6b74d793eed4fe98dbd8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 5 May 2019 16:26:01 +0200 Subject: mod_storage_sql: Add support for iterating over users in archive stores --- plugins/mod_storage_sql.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index ffe48ab8..596687ae 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -509,6 +509,19 @@ function archive_store:delete(username, query) return ok and stmt:affected(), stmt; end +function archive_store:users() + local ok, result = engine:transaction(function() + local select_sql = [[ + SELECT DISTINCT "user" + FROM "prosodyarchive" + WHERE "host"=? AND "store"=?; + ]]; + return engine:select(select_sql, host, self.store); + end); + if not ok then error(result); end + return iterator(result); +end + local stores = { keyval = keyval_store; map = map_store; -- cgit v1.2.3 From cf5c64cd690c92ae7705fe6e7acce2ed81610ec2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 5 Mar 2019 00:12:30 +0100 Subject: mod_storage_internal: Return error if 'before' or 'after' are not found (partial fix for #1325) --- plugins/mod_storage_internal.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index 96780b33..fdce3c98 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -161,20 +161,30 @@ function archive:find(username, query) if query.reverse then items:reverse(); if query.before then + local found = false; for j = 1, #items do if (items[j].key or tostring(j)) == query.before then + found = true; i = j; break; end end + if not found then + return nil, "item-not-found"; + end end elseif query.after then + local found = false; for j = 1, #items do if (items[j].key or tostring(j)) == query.after then + found = true; i = j; break; end end + if not found then + return nil, "item-not-found"; + end end if query.limit and #items - i > query.limit then items[i+query.limit+1] = nil; -- cgit v1.2.3 From 59b4972c34a6887caf3ecb8b96d088fef831d9e9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 5 Mar 2019 00:16:41 +0100 Subject: mod_storage_memory: Return error if 'before' or 'after' are not found (partial fix for #1325) --- plugins/mod_storage_memory.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_memory.lua b/plugins/mod_storage_memory.lua index 4655cb3a..2fae8828 100644 --- a/plugins/mod_storage_memory.lua +++ b/plugins/mod_storage_memory.lua @@ -127,20 +127,30 @@ function archive_store:find(username, query) if query.reverse then items:reverse(); if query.before then + local found = false; for j = 1, #items do if (items[j].key or tostring(j)) == query.before then + found = true; i = j; break; end end + if not found then + return nil, "item-not-found"; + end end elseif query.after then + local found = false; for j = 1, #items do if (items[j].key or tostring(j)) == query.after then + found = true; i = j; break; end end + if not found then + return nil, "item-not-found"; + end end if query.limit and #items - i > query.limit then items[i+query.limit+1] = nil; -- cgit v1.2.3 From 7e32666c2b78f5bebe46bcf336f66a3e7d2eff36 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 23 Mar 2019 00:51:10 +0100 Subject: mod_storage_sql: Look up archive IDs in separate queries (fixes #1325) This is probably not good for performance. --- plugins/mod_storage_sql.lua | 58 ++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index f0a8fee0..5da5e448 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -327,38 +327,36 @@ local function archive_where(query, args, where) end end local function archive_where_id_range(query, args, where) - local args_len = #args -- Before or after specific item, exclusive + local id_lookup_sql = [[ + SELECT "sort_id" + FROM "prosodyarchive" + WHERE "key" = ? AND "host" = ? AND "user" = ? AND "store" = ? + LIMIT 1; + ]]; if query.after then -- keys better be unique! - where[#where+1] = [[ - "sort_id" > COALESCE( - ( - SELECT "sort_id" - FROM "prosodyarchive" - WHERE "key" = ? AND "host" = ? AND "user" = ? AND "store" = ? - LIMIT 1 - ), 0) - ]]; - args[args_len+1], args[args_len+2], args[args_len+3], args[args_len+4] = query.after, args[1], args[2], args[3]; - args_len = args_len + 4 + local after_id = nil; + for row in engine:select(id_lookup_sql, query.after, host, user or "", store) do + after_id = row[1]; + end + if not after_id then + return nil, "item-not-found"; + end + where[#where+1] = '"sort_id" > ?'; + args[#args+1] = after_id; end if query.before then - where[#where+1] = [[ - "sort_id" < COALESCE( - ( - SELECT "sort_id" - FROM "prosodyarchive" - WHERE "key" = ? AND "host" = ? AND "user" = ? AND "store" = ? - LIMIT 1 - ), - ( - SELECT MAX("sort_id")+1 - FROM "prosodyarchive" - ) - ) - ]] - args[args_len+1], args[args_len+2], args[args_len+3], args[args_len+4] = query.before, args[1], args[2], args[3]; + local before_id = nil; + for row in engine:select(id_lookup_sql, query.after, host, user or "", store) do + before_id = row[1]; + end + if not before_id then + return nil, "item-not-found"; + end + where[#where+1] = '"sort_id" < ?'; + args[#args+1] = before_id; end + return true; end function archive_store:find(username, query) @@ -398,7 +396,8 @@ function archive_store:find(username, query) end end - archive_where_id_range(query, args, where); + local ok, err = archive_where_id_range(query, args, where); + if not ok then return ok, err; end if query.limit then args[#args+1] = query.limit; @@ -466,7 +465,8 @@ function archive_store:delete(username, query) table.remove(where, 2); end archive_where(query, args, where); - archive_where_id_range(query, args, where); + local ok, err = archive_where_id_range(query, args, where); + if not ok then return ok, err; end if query.truncate == nil then sql_query = sql_query:format(t_concat(where, " AND ")); else -- cgit v1.2.3 From ffd7ca3f8daaa3d0137012759f7cfe52a835ea89 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 5 May 2019 07:16:05 +0200 Subject: mod_mam: Propagate item-not-found to client (fixes #1325) --- plugins/mod_mam/mod_mam.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index 632de9ea..317ddac1 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -142,7 +142,11 @@ module:hook("iq-set/self/"..xmlns_mam..":query", function(event) }); if not data then - origin.send(st.error_reply(stanza, "cancel", "internal-server-error", err)); + if err == "item-not-found" then + origin.send(st.error_reply(stanza, "modify", "item-not-found")); + else + origin.send(st.error_reply(stanza, "cancel", "internal-server-error")); + end return true; end local total = tonumber(err); -- cgit v1.2.3 From 43f98c242d4a212a8de0d8965733c206109c4d23 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 5 May 2019 07:16:03 +0200 Subject: mod_muc_mam: Propagate item-not-found to client (fixes #1325) --- plugins/mod_muc_mam.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_muc_mam.lua b/plugins/mod_muc_mam.lua index fffe23e7..bba7f422 100644 --- a/plugins/mod_muc_mam.lua +++ b/plugins/mod_muc_mam.lua @@ -189,7 +189,11 @@ module:hook("iq-set/bare/"..xmlns_mam..":query", function(event) }); if not data then - origin.send(st.error_reply(stanza, "cancel", "internal-server-error")); + if err == "item-not-found" then + origin.send(st.error_reply(stanza, "modify", "item-not-found")); + else + origin.send(st.error_reply(stanza, "cancel", "internal-server-error")); + end return true; end local total = tonumber(err); -- cgit v1.2.3 From faf1282ee2dfacfba3a947edd9142b93ca1f4162 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 5 May 2019 07:22:18 +0200 Subject: mod_storage_memory: Return correct error even if no archive data available --- plugins/mod_storage_memory.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_memory.lua b/plugins/mod_storage_memory.lua index 2fae8828..376ae277 100644 --- a/plugins/mod_storage_memory.lua +++ b/plugins/mod_storage_memory.lua @@ -91,6 +91,9 @@ function archive_store:find(username, query) local items = self.store[username or NULL]; if not items then if query then + if query.before or query.after then + return nil, "item-not-found"; + end if query.total then return function () end, 0; end -- cgit v1.2.3 From fa0d394f9b0ab4f503558d9c944fe4052d5eb324 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 5 May 2019 07:24:12 +0200 Subject: mod_storage_internal: Return appropriate error even with empty archive --- plugins/mod_storage_internal.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index fdce3c98..2556224d 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -125,6 +125,9 @@ function archive:find(username, query) if err then return items, err; elseif query then + if query.before or query.after then + return nil, "item-not-found"; + end if query.total then return function () end, 0; end -- cgit v1.2.3 From 2dbd1528bb118e77463db85403d535d307ec050d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 26 May 2019 15:04:16 +0200 Subject: mod_csi_simple: Disable optimizations on disconnect (fixes #1358) The connection becomes invalid here, regardless of 3rd party modules that might keep the session alive. --- plugins/mod_csi_simple.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_csi_simple.lua b/plugins/mod_csi_simple.lua index a9148618..13002ea8 100644 --- a/plugins/mod_csi_simple.lua +++ b/plugins/mod_csi_simple.lua @@ -108,6 +108,10 @@ module:hook("csi-client-active", function (event) disable_optimizations(session); end); +module:hook("pre-resource-unbind", function (event) + local session = event.session; + disable_optimizations(session); +end); module:hook("c2s-ondrain", function (event) local session = event.session; -- cgit v1.2.3 From 8799bf12c702335a32d1d220269090f653230b0d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 28 May 2019 00:46:24 +0200 Subject: mod_storage_sql: Correctly return item-not-found error `return ok, err` comes out as `transaction_ok, ok, err` --- plugins/mod_storage_sql.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 5da5e448..cfc8450c 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -367,7 +367,7 @@ function archive_store:find(username, query) if total ~= nil and query.limit == 0 and query.start == nil and query.with == nil and query["end"] == nil and query.key == nil then return noop, total; end - local ok, result = engine:transaction(function() + local ok, result, err = engine:transaction(function() local sql_query = [[ SELECT "key", "type", "value", "when", "with" FROM "prosodyarchive" @@ -407,7 +407,8 @@ function archive_store:find(username, query) and "DESC" or "ASC", query.limit and " LIMIT ?" or ""); return engine:select(sql_query, unpack(args)); end); - if not ok then return ok, result end + if not ok then return ok, result; end + if not result then return nil, err; end return function() local row = result(); if row ~= nil then -- cgit v1.2.3 From a52c045f4a8b7e11eac9b6ba4cf72e0a920594e5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 28 May 2019 00:47:50 +0200 Subject: mod_storage_sql: Fix to use correct arguments to archive id lookup --- plugins/mod_storage_sql.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index cfc8450c..ad2de840 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -336,7 +336,7 @@ local function archive_where_id_range(query, args, where) ]]; if query.after then -- keys better be unique! local after_id = nil; - for row in engine:select(id_lookup_sql, query.after, host, user or "", store) do + for row in engine:select(id_lookup_sql, query.after, args[1], args[2], args[3]) do after_id = row[1]; end if not after_id then @@ -347,7 +347,7 @@ local function archive_where_id_range(query, args, where) end if query.before then local before_id = nil; - for row in engine:select(id_lookup_sql, query.after, host, user or "", store) do + for row in engine:select(id_lookup_sql, query.after, args[1], args[2], args[3]) do before_id = row[1]; end if not before_id then -- cgit v1.2.3 From 411d4c02a1315eb778e2ee5613723b74b6cfd00d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 28 May 2019 00:56:30 +0200 Subject: mod_storage_sql: Ignore shadowed error variable [luacheck] --- plugins/mod_storage_sql.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index ad2de840..518e2654 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -153,7 +153,7 @@ end local archive_item_limit = module:get_option_number("storage_archive_item_limit"); local archive_item_count_cache = cache.new(module:get_option("storage_archive_item_limit_cache_size", 1000)); --- luacheck: ignore 512 431/user 431/store +-- luacheck: ignore 512 431/user 431/store 431/err local map_store = {}; map_store.__index = map_store; map_store.remove = {}; -- cgit v1.2.3 From 9a5a3fd0f10693e6cba2779095398614eb94e68c Mon Sep 17 00:00:00 2001 From: Michel Le Bihan Date: Mon, 3 Jun 2019 20:51:15 +0200 Subject: mod_admin_telnet: Collect array from Bosh connections when appending to connection list Fixes #1356 --- plugins/mod_admin_telnet.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 0fbd3ff9..fa03840b 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -597,7 +597,7 @@ end local function show_c2s(callback) local c2s = array.collect(values(module:shared"/*/c2s/sessions")); - c2s:append(values(module:shared"/*/bosh/sessions")); + c2s:append(array.collect(values(module:shared"/*/bosh/sessions"))); c2s:sort(function(a, b) if a.host == b.host then if a.username == b.username then -- cgit v1.2.3 From 027554ebcca06ab7fcf923c03089f82658adf990 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 16 Jun 2019 22:02:53 +0200 Subject: mod_pep: Log node name instead of payload Having the node logged is more useful and less problematic for privacy --- plugins/mod_pep.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index f06f1753..54f0451d 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -159,7 +159,7 @@ local function get_broadcaster(username) end for jid in pairs(jids) do - module:log("debug", "Sending notification to %s from %s: %s", jid, user_bare, tostring(item)); + module:log("debug", "Sending notification to %s from %s for node %s", jid, user_bare, node); message.attr.to = jid; module:send(message); end -- cgit v1.2.3 From 6c5d0e50e7d5d890c30308aad97ecbd4e65c5fcb Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 19 Jun 2019 08:51:39 +0200 Subject: MUC: Reflow event tables to improve readability Also makes it easier to read diffs of added fields. --- plugins/muc/muc.lib.lua | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index c828d17d..34961558 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -391,7 +391,11 @@ function room_mt:handle_kickable(origin, stanza) -- luacheck: ignore 212 end self:publicise_occupant_status(new_occupant or occupant, x); if is_last_session then - module:fire_event("muc-occupant-left", {room = self; nick = occupant.nick; occupant = occupant;}); + module:fire_event("muc-occupant-left", { + room = self; + nick = occupant.nick; + occupant = occupant; + }); end return true; end @@ -868,7 +872,11 @@ function room_mt:clear(x) end for occupant in pairs(occupants_updated) do self:publicise_occupant_status(occupant, x); - module:fire_event("muc-occupant-left", { room = self; nick = occupant.nick; occupant = occupant;}); + module:fire_event("muc-occupant-left", { + room = self; + nick = occupant.nick; + occupant = occupant; + }); end end @@ -1316,7 +1324,11 @@ function room_mt:set_affiliation(actor, jid, affiliation, reason, data) for occupant, old_role in pairs(occupants_updated) do self:publicise_occupant_status(occupant, x, nil, actor, reason); if occupant.role == nil then - module:fire_event("muc-occupant-left", {room = self; nick = occupant.nick; occupant = occupant;}); + module:fire_event("muc-occupant-left", { + room = self; + nick = occupant.nick; + occupant = occupant; + }); elseif is_semi_anonymous and (old_role == "moderator" and occupant.role ~= "moderator") or (old_role ~= "moderator" and occupant.role == "moderator") then -- Has gained or lost moderator status @@ -1432,7 +1444,11 @@ function room_mt:set_role(actor, occupant_jid, role, reason) self:save_occupant(occupant); self:publicise_occupant_status(occupant, x, nil, actor, reason); if role == nil then - module:fire_event("muc-occupant-left", {room = self; nick = occupant.nick; occupant = occupant;}); + module:fire_event("muc-occupant-left", { + room = self; + nick = occupant.nick; + occupant = occupant; + }); end return true; end -- cgit v1.2.3 From 47b408b4bdf206a1c2967e1d8272f945e816fc9c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Jun 2019 21:44:43 +0200 Subject: mod_blocklist: Add comment to clarify some logic --- plugins/mod_blocklist.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/mod_blocklist.lua b/plugins/mod_blocklist.lua index 18d28be2..cf8aad80 100644 --- a/plugins/mod_blocklist.lua +++ b/plugins/mod_blocklist.lua @@ -189,6 +189,7 @@ local function edit_blocklist(event) if is_blocking then for jid in pairs(send_unavailable) do + -- Check that this JID isn't already blocked, i.e. this is not a change if not blocklist[jid] then for _, session in pairs(sessions[username].sessions) do if session.presence then -- cgit v1.2.3