From 396e4d0cc2c5d824c09fd21316fabe755265c6b0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 28 Mar 2019 12:52:55 +0100 Subject: net.server_epoll: Skip delayed continuation read on paused connections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should prevent #1333 in cases where LuaSockets buffer is "dirty", i.e. contains more data after a read, where it gets resumed with a short delay. --- net/server_epoll.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_epoll.lua b/net/server_epoll.lua index cffd3a84..c41266e1 100644 --- a/net/server_epoll.lua +++ b/net/server_epoll.lua @@ -373,7 +373,7 @@ function interface:onreadable() end end if not self.conn then return; end - if self.conn:dirty() then + if self._wantread and self.conn:dirty() then self:setreadtimeout(false); self:pausefor(cfg.read_retry_delay); else -- cgit v1.2.3 From 6b6dd549e8573d87e431d02237fe9272a09bf2a3 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 13 Apr 2019 18:16:28 +0200 Subject: net.dns: Close resolv.conf handle when done (fixes #1342) --- net/dns.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/net/dns.lua b/net/dns.lua index af5f1216..3902f95c 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -704,6 +704,7 @@ function resolver:adddefaultnameservers() -- - - - - adddefaultnameservers end end end + resolv_conf:close(); end if not self.server or #self.server == 0 then -- TODO log warning about no nameservers, adding localhost as the default nameserver -- cgit v1.2.3 From 6e9f3cf6f3a2a0852dbf919b8a77245a38611140 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 14 Apr 2019 02:06:20 +0200 Subject: util.ip: Add missing netmask for 192.168/16 range (fixes #1343) --- util/ip.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/ip.lua b/util/ip.lua index 0ec9e297..d1808225 100644 --- a/util/ip.lua +++ b/util/ip.lua @@ -203,7 +203,7 @@ local rfc6598 = new_ip("100.64.0.0"); function ip_methods:private() local private = self.scope ~= 0xE; if not private and self.proto == "IPv4" then - return match(self, rfc1918_8, 8) or match(self, rfc1918_12, 12) or match(self, rfc1918_16) or match(self, rfc6598, 10); + return match(self, rfc1918_8, 8) or match(self, rfc1918_12, 12) or match(self, rfc1918_16, 16) or match(self, rfc6598, 10); end return private; end -- cgit v1.2.3 From 3d14e00260469a7d2ba439ec5c3aad9cdb7238d1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 19 Apr 2019 13:12:00 +0200 Subject: util.hashes: Use HMAC function provided by OpenSSL (fixes #1345) --- util-src/hashes.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/util-src/hashes.c b/util-src/hashes.c index 82f5876e..903ecb6e 100644 --- a/util-src/hashes.c +++ b/util-src/hashes.c @@ -25,6 +25,7 @@ typedef unsigned __int32 uint32_t; #include "lauxlib.h" #include #include +#include #if (LUA_VERSION_NUM == 501) #define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R) @@ -112,35 +113,28 @@ static void hmac(struct hash_desc *desc, const char *key, size_t key_len, desc->Final(result, desc->ctxo); } -#define MAKE_HMAC_FUNCTION(myFunc, func, size, type) \ +#define MAKE_HMAC_FUNCTION(myFunc, evp, size, type) \ static int myFunc(lua_State *L) { \ - type ctx, ctxo; \ unsigned char hash[size], result[2*size]; \ size_t key_len, msg_len; \ + unsigned int out_len; \ const char *key = luaL_checklstring(L, 1, &key_len); \ const char *msg = luaL_checklstring(L, 2, &msg_len); \ const int hex_out = lua_toboolean(L, 3); \ - struct hash_desc desc; \ - desc.Init = (int (*)(void*))func##_Init; \ - desc.Update = (int (*)(void*, const void *, size_t))func##_Update; \ - desc.Final = (int (*)(unsigned char*, void*))func##_Final; \ - desc.digestLength = size; \ - desc.ctx = &ctx; \ - desc.ctxo = &ctxo; \ - hmac(&desc, key, key_len, msg, msg_len, hash); \ + HMAC(evp(), key, key_len, (const unsigned char*)msg, msg_len, (unsigned char*)hash, &out_len); \ if (hex_out) { \ - toHex(hash, size, result); \ - lua_pushlstring(L, (char*)result, size*2); \ + toHex(hash, out_len, result); \ + lua_pushlstring(L, (char*)result, out_len*2); \ } else { \ - lua_pushlstring(L, (char*)hash, size); \ + lua_pushlstring(L, (char*)hash, out_len); \ } \ return 1; \ } -MAKE_HMAC_FUNCTION(Lhmac_sha1, SHA1, SHA_DIGEST_LENGTH, SHA_CTX) -MAKE_HMAC_FUNCTION(Lhmac_sha256, SHA256, SHA256_DIGEST_LENGTH, SHA256_CTX) -MAKE_HMAC_FUNCTION(Lhmac_sha512, SHA512, SHA512_DIGEST_LENGTH, SHA512_CTX) -MAKE_HMAC_FUNCTION(Lhmac_md5, MD5, MD5_DIGEST_LENGTH, MD5_CTX) +MAKE_HMAC_FUNCTION(Lhmac_sha1, EVP_sha1, SHA_DIGEST_LENGTH, SHA_CTX) +MAKE_HMAC_FUNCTION(Lhmac_sha256, EVP_sha256, SHA256_DIGEST_LENGTH, SHA256_CTX) +MAKE_HMAC_FUNCTION(Lhmac_sha512, EVP_sha512, SHA512_DIGEST_LENGTH, SHA512_CTX) +MAKE_HMAC_FUNCTION(Lhmac_md5, EVP_md5, MD5_DIGEST_LENGTH, MD5_CTX) static int LscramHi(lua_State *L) { union xory { -- cgit v1.2.3 From eca1ddea1e620a6200c4999b82d1c793b354c481 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 23 Apr 2019 19:13:50 +0200 Subject: mod_tls: Log debug message for each kind of TLS context created Creating TLS contexts triggers a lot of messages from certmanager that don't really describe their purpose. This is meant to provide hints about that. --- plugins/mod_tls.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/mod_tls.lua b/plugins/mod_tls.lua index 029ddd1d..eb208e28 100644 --- a/plugins/mod_tls.lua +++ b/plugins/mod_tls.lua @@ -52,12 +52,15 @@ function module.load() local parent_s2s = rawgetopt(parent, "s2s_ssl") or NULL; local host_s2s = rawgetopt(modhost, "s2s_ssl") or parent_s2s; + module:log("debug", "Creating context for c2s"); 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 + module:log("debug", "Creating context for s2sout"); 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 + module:log("debug", "Creating context for s2sin"); 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 end -- cgit v1.2.3 From b623c6cb41f91964faf97e2b9bb6fab9993ab658 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 23 Apr 2019 19:21:06 +0200 Subject: core.portmanager: Log debug message for each kind of TLS context created --- core/portmanager.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/core/portmanager.lua b/core/portmanager.lua index 1ed37da0..bed5eca5 100644 --- a/core/portmanager.lua +++ b/core/portmanager.lua @@ -112,6 +112,7 @@ local function activate(service_name) if service_info.encryption == "ssl" then local global_ssl_config = config.get("*", "ssl") or {}; local prefix_ssl_config = config.get("*", config_prefix.."ssl") or global_ssl_config; + log("debug", "Creating context for direct TLS service %s on port %d", service_info.name, port); ssl, err = certmanager.create_context(service_info.name.." port "..port, "server", prefix_ssl_config[interface], prefix_ssl_config[port], -- cgit v1.2.3 From bd81be8593e4f529af26978b02abafba37d59bae Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 24 Apr 2019 16:16:19 +0200 Subject: util.encodings: Allow unassigned code points in ICU mode to match libidn behavior (fixes #1348) --- util-src/encodings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util-src/encodings.c b/util-src/encodings.c index f7e8131f..e55a3f44 100644 --- a/util-src/encodings.c +++ b/util-src/encodings.c @@ -299,7 +299,7 @@ static int icu_stringprep_prep(lua_State *L, const UStringPrepProfile *profile) return 1; } - prepped_len = usprep_prepare(profile, unprepped, unprepped_len, prepped, 1024, 0, NULL, &err); + prepped_len = usprep_prepare(profile, unprepped, unprepped_len, prepped, 1024, USPREP_ALLOW_UNASSIGNED, NULL, &err); if(U_FAILURE(err)) { lua_pushnil(L); -- cgit v1.2.3 From 2abb1bdc3c550e45f943cd37f1e834419bd63605 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 1 May 2019 22:34:15 +0200 Subject: prosodyctl: Include version of LuaDBI in 'about' --- prosodyctl | 1 + 1 file changed, 1 insertion(+) diff --git a/prosodyctl b/prosodyctl index b1c6fffd..e580446b 100755 --- a/prosodyctl +++ b/prosodyctl @@ -395,6 +395,7 @@ function commands.about(arg) local module_versions, longest_name = {}, 8; local luaevent =dependencies.softreq"luaevent"; dependencies.softreq"ssl"; + dependencies.softreq"DBI"; for name, module in pairs(package.loaded) do if type(module) == "table" and rawget(module, "_VERSION") and name ~= "_G" and not name:match("%.") then -- cgit v1.2.3 From df1246244109fdbbeb805d8c03ce20bbe4dadc94 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 4 May 2019 04:23:35 +0200 Subject: net.server_epoll: Restore wantread flag after pause (fixes #1354) If a chunk of data has been received that is larger than the amount read at a time, then the connection is paused for a short time after which it tries to read some more. If, after that, there is still more data to read, it should do the same thing. However, because the "want read" flag is removed and was restored after the delayed reading, it would not schedule another delayed read. --- net/server_epoll.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_epoll.lua b/net/server_epoll.lua index c41266e1..c279c579 100644 --- a/net/server_epoll.lua +++ b/net/server_epoll.lua @@ -600,10 +600,10 @@ function interface:pausefor(t) self:set(false); self._pausefor = addtimer(t, function () self._pausefor = nil; + self:set(true); if self.conn and self.conn:dirty() then self:onreadable(); end - self:set(true); end); end -- cgit v1.2.3 From 36ec6ce8ab02e62c83ca39dfd6616a1bfa753968 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 4 May 2019 22:48:59 +0200 Subject: configure: Handle lua being found in /bin (workaround for #1353) --- configure | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/configure b/configure index 4307997c..0fe186b5 100755 --- a/configure +++ b/configure @@ -419,6 +419,13 @@ else } fi +# See #1353 +if [ "$LUA_DIR_SET" != "yes" ] && [ "$LUA_DIR" = "/" ] +then + LUA_DIR="/usr" +fi + + if [ "$lua_interp_found" != "yes" ] && [ "$RUNWITH_SET" != "yes" ] then if [ "$LUA_VERSION_SET" ]; then -- cgit v1.2.3 From 6bf96583fa7a3b1919815408dc9e1fecfe90af77 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 13 May 2019 14:47:41 +0200 Subject: mod_storage_sql: Move code out of if-else chain --- plugins/mod_storage_sql.lua | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index 56cef569..dbf5e2da 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -390,6 +390,14 @@ function archive_store:delete(username, query) else args[#args+1] = query.truncate; local unlimited = "ALL"; + sql_query = [[ + DELETE FROM "prosodyarchive" + WHERE "sort_id" IN ( + SELECT "sort_id" FROM "prosodyarchive" + WHERE %s + ORDER BY "sort_id" %s + LIMIT %s OFFSET ? + );]]; if engine.params.driver == "SQLite3" then sql_query = [[ DELETE FROM "prosodyarchive" @@ -407,15 +415,6 @@ function archive_store:delete(username, query) LIMIT %s OFFSET ? ) AS limiter on result.sort_id = limiter.sort_id;]]; unlimited = "18446744073709551615"; - else - sql_query = [[ - DELETE FROM "prosodyarchive" - WHERE "sort_id" IN ( - SELECT "sort_id" FROM "prosodyarchive" - WHERE %s - ORDER BY "sort_id" %s - LIMIT %s OFFSET ? - );]]; end sql_query = string.format(sql_query, t_concat(where, " AND "), query.reverse and "ASC" or "DESC", unlimited); -- cgit v1.2.3 From 663a4c3933139a06e70e9c163fc848eceb9b4442 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 13 May 2019 14:39:38 +0200 Subject: mod_storage_sql: Handle SQLite DELETE with LIMIT being optional (fixes #1359) --- plugins/mod_storage_sql.lua | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index dbf5e2da..a449091e 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -399,12 +399,14 @@ function archive_store:delete(username, query) LIMIT %s OFFSET ? );]]; if engine.params.driver == "SQLite3" then - sql_query = [[ - DELETE FROM "prosodyarchive" - WHERE %s - ORDER BY "sort_id" %s - LIMIT %s OFFSET ?; - ]]; + if engine._have_delete_limit then + sql_query = [[ + DELETE FROM "prosodyarchive" + WHERE %s + ORDER BY "sort_id" %s + LIMIT %s OFFSET ?; + ]]; + end unlimited = "-1"; elseif engine.params.driver == "MySQL" then sql_query = [[ @@ -620,6 +622,13 @@ function module.load() module:log("error", "Old database format detected. Please run: prosodyctl mod_%s upgrade", module.name); return false, "database upgrade needed"; end + if engine.params.driver == "SQLite3" then + for row in engine:select("PRAGMA compile_options") do + if row[1] == "ENABLE_UPDATE_DELETE_LIMIT" then + engine._have_delete_limit = true; + end + end + end end end); engines[sql.db2uri(params)] = engine; -- cgit v1.2.3 From 32b4030f4327148e2edf83ac4354e4d62039b3c0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 18 May 2019 17:45:20 +0200 Subject: mod_c2s: Associate connection with session last (fixes #1313) This way, any fatal error in the callback will not leave a half-established session. --- plugins/mod_c2s.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 8e31a968..15d3a9be 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -239,7 +239,6 @@ end --- Port listener function listener.onconnect(conn) local session = sm_new_session(conn); - sessions[conn] = session; session.log("info", "Client connected"); @@ -300,6 +299,8 @@ function listener.onconnect(conn) end session.dispatch_stanza = stream_callbacks.handlestanza; + + sessions[conn] = session; end function listener.onincoming(conn, data) -- cgit v1.2.3 From 23da49fba0397a2c8f2701efb22634f0a3f68bd8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 18 May 2019 17:28:21 +0200 Subject: util.random: Handle unlikely read errors from /dev/urandom (see #1313) --- util/random.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/random.lua b/util/random.lua index d8a84514..8ae06b49 100644 --- a/util/random.lua +++ b/util/random.lua @@ -12,7 +12,11 @@ if ok then return crand; end local urandom, urandom_err = io.open("/dev/urandom", "r"); local function bytes(n) - return urandom:read(n); + local data, err = urandom:read(n); + if not data then + error("Unable to retrieve data from secure random number generator (/dev/urandom): "..err); + end + return data; end if not urandom then -- cgit v1.2.3 From f51f1f1375c3b1ff58aaa1f8b9082b69b1ef95d7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 18 May 2019 18:51:25 +0200 Subject: util.random: Coerce error to string (thanks waqas) In theory this could happen in an EOF condition, which should be impossible with a read from /dev/urandom. --- util/random.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/random.lua b/util/random.lua index 8ae06b49..51f2747d 100644 --- a/util/random.lua +++ b/util/random.lua @@ -14,7 +14,7 @@ local urandom, urandom_err = io.open("/dev/urandom", "r"); local function bytes(n) local data, err = urandom:read(n); if not data then - error("Unable to retrieve data from secure random number generator (/dev/urandom): "..err); + error("Unable to retrieve data from secure random number generator (/dev/urandom): "..tostring(err)); end return data; end -- cgit v1.2.3 From 8ceccabe00d91193fa3b940b3c9b9d65727b8a0d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 21 May 2019 08:52:21 +0200 Subject: util.random: Throw different error for EOL condition --- util/random.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/random.lua b/util/random.lua index 51f2747d..6782d7fa 100644 --- a/util/random.lua +++ b/util/random.lua @@ -14,7 +14,11 @@ local urandom, urandom_err = io.open("/dev/urandom", "r"); local function bytes(n) local data, err = urandom:read(n); if not data then - error("Unable to retrieve data from secure random number generator (/dev/urandom): "..tostring(err)); + if err then + error("Unable to retrieve data from secure random number generator (/dev/urandom): "..tostring(err)); + else + error("Secure random number generator (/dev/urandom) returned an end-of-file condition"); + end end return data; end -- cgit v1.2.3 From cdd8ba5308e3d987fdd66559da734ab4cb8a169f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 27 May 2019 12:05:35 +0200 Subject: mod_announce: Check for admin on current virtualhost instead of global (fixes #1365) (thanks yc) --- plugins/mod_announce.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_announce.lua b/plugins/mod_announce.lua index 14bb9f3d..970a273a 100644 --- a/plugins/mod_announce.lua +++ b/plugins/mod_announce.lua @@ -44,7 +44,7 @@ function handle_announcement(event) return; -- Not an announcement end - if not is_admin(stanza.attr.from) then + if not is_admin(stanza.attr.from, host) then -- Not an admin? Not allowed! module:log("warn", "Non-admin '%s' tried to send server announcement", stanza.attr.from); return; -- cgit v1.2.3 From fddbd6ed134ebde535c574da5e8a7a0d4e007767 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 27 May 2019 19:00:32 +0200 Subject: mod_mam: Cache last date that archive owner has messages to reduce writes (fixes #1368) --- plugins/mod_mam/mod_mam.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index a8c2689d..8900a2be 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -348,8 +348,14 @@ if cleanup_after ~= "never" then -- messages, we collect the union of sets of users from dates that fall -- outside the cleanup range. + local last_date = require "util.cache".new(module:get_option_number("archive_cleanup_date_cache_size", 1000)); function schedule_cleanup(username, date) - cleanup_map:set(date or datestamp(), username, true); + date = date or datestamp(); + if last_date:get(username) == date then return end + local ok = cleanup_map:set(date, username, true); + if ok then + last_date:set(username, date); + end end cleanup_runner = require "util.async".runner(function () -- cgit v1.2.3 From 41c625f6a9cc611342a7a964888952c08e9201c6 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 27 May 2019 19:00:34 +0200 Subject: mod_muc_mam: Cache last date that archive owner has messages to reduce writes (fixes #1368) --- plugins/mod_muc_mam.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/mod_muc_mam.lua b/plugins/mod_muc_mam.lua index 1fbc8b2a..a2e3f81b 100644 --- a/plugins/mod_muc_mam.lua +++ b/plugins/mod_muc_mam.lua @@ -422,8 +422,14 @@ if cleanup_after ~= "never" then -- messages, we collect the union of sets of rooms from dates that fall -- outside the cleanup range. + local last_date = require "util.cache".new(module:get_option_number("muc_log_cleanup_date_cache_size", 1000)); function schedule_cleanup(roomname, date) - cleanup_map:set(date or datestamp(), roomname, true); + date = date or datestamp(); + if last_date:get(roomname) == date then return end + local ok = cleanup_map:set(date, roomname, true); + if ok then + last_date:set(roomname, date); + end end cleanup_runner = require "util.async".runner(function () -- cgit v1.2.3 From 71bdfa72d8ce993ede0ac595c8e78404758e3546 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 May 2019 15:16:56 +0200 Subject: mod_pep: Handle presence based subscription outside of util.pubsub (fixes #1372) Subscriptions were updated for each incoming presence stanza from contacts. Each subscription change triggered a configuration save, which would filter out the presence based subscriptions and usually end up replacing the existing data with identical data. With many subscribed nodes this adds up to a fair bit of IO bound work that is avoided by keeping them separate. --- plugins/mod_pep.lua | 54 +++++++++++++++++------------------------------------ 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index 7a4aac2b..f60f84c9 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -90,21 +90,6 @@ local function nodestore(username) return data, err; end function store:set(node, data) - if data then - -- Save the data without subscriptions - local subscribers = {}; - for jid, sub in pairs(data.subscribers) do - if type(sub) ~= "table" or not sub.presence then - subscribers[jid] = sub; - end - end - data = { - name = data.name; - config = data.config; - affiliations = data.affiliations; - subscribers = subscribers; - }; - end return node_config:set(username, node, data); end function store:users() @@ -151,7 +136,23 @@ local function get_broadcaster(username) end message:add_child(item); end + + local broadcast_to = {}; for jid in pairs(jids) do + broadcast_to[jid] = true; + end + + local service_recipients = recipients[username]; + if service_recipients then + local service = services[username]; + for recipient, nodes in pairs(service_recipients) do + if nodes:contains(node) and service:may(node, recipient, "subscribe") then + broadcast_to[recipient] = true; + end + end + end + + for jid in pairs(broadcast_to) do module:log("debug", "Sending notification to %s from %s: %s", jid, user_bare, tostring(item)); message.attr.to = jid; module:send(message); @@ -160,20 +161,6 @@ local function get_broadcaster(username) return simple_broadcast; end -local function on_node_creation(event) - local service = event.service; - local node = event.node; - local username = service.config.pep_username; - - local service_recipients = recipients[username]; - if not service_recipients then return; end - - for recipient, nodes in pairs(service_recipients) do - if nodes:contains(node) then - service:add_subscription(node, recipient, recipient, { presence = true }); - end - end -end function get_pep_service(username) module:log("debug", "get_pep_service(%q)", username); @@ -233,10 +220,6 @@ function get_pep_service(username) return service; end -module:hook("item-added/pep-service", function (event) - local service = event.item.service; - module:hook_object_event(service.events, "node-created", on_node_creation); -end); function handle_pubsub_iq(event) local origin, stanza = event.origin, event.stanza; @@ -303,12 +286,9 @@ local function update_subscriptions(recipient, service_name, nodes) end local service = get_pep_service(service_name); - for node in current - nodes do - service:remove_subscription(node, recipient, recipient); - end for node in nodes - current do - if service:add_subscription(node, recipient, recipient, { presence = true }) then + if service:may(node, recipient, "subscribe") then resend_last_item(recipient, node, service); end end -- cgit v1.2.3 From d324c430553c7470211b44cb5f3e9cded7c53228 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 May 2019 23:50:28 +0200 Subject: util.sql: Ignore if tables and indices already exist on creation (fixes #1064) Tested with SQLite3 3.16.2 and 3.27.2 and Postgres 11. MySQL does not support IF NOT EXISTS for indices so not handled here. --- util/sql.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/util/sql.lua b/util/sql.lua index 47900102..00c7b57f 100644 --- a/util/sql.lua +++ b/util/sql.lua @@ -238,6 +238,9 @@ function engine:transaction(...) end function engine:_create_index(index) local sql = "CREATE INDEX \""..index.name.."\" ON \""..index.table.."\" ("; + if self.params.driver ~= "MySQL" then + sql = sql:gsub("^CREATE INDEX", "%1 IF NOT EXISTS"); + end for i=1,#index do sql = sql.."\""..index[i].."\""; if i ~= #index then sql = sql..", "; end @@ -256,6 +259,9 @@ function engine:_create_index(index) end function engine:_create_table(table) local sql = "CREATE TABLE \""..table.name.."\" ("; + do + sql = sql:gsub("^CREATE TABLE", "%1 IF NOT EXISTS"); + end for i,col in ipairs(table.c) do local col_type = col.type; if col_type == "MEDIUMTEXT" and self.params.driver ~= "MySQL" then -- cgit v1.2.3 From efcd7d69026afe4a90e27c94a697644d57c5f764 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 10 Jun 2019 12:58:00 +0200 Subject: mod_pep: Revert 045209b41b3a, caused a regression Adding in all presence based subscriptions in the broadcaster caused resend_last_item() to unintentionally send out more notifications than it should have. --- plugins/mod_pep.lua | 54 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index f60f84c9..7a4aac2b 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -90,6 +90,21 @@ local function nodestore(username) return data, err; end function store:set(node, data) + if data then + -- Save the data without subscriptions + local subscribers = {}; + for jid, sub in pairs(data.subscribers) do + if type(sub) ~= "table" or not sub.presence then + subscribers[jid] = sub; + end + end + data = { + name = data.name; + config = data.config; + affiliations = data.affiliations; + subscribers = subscribers; + }; + end return node_config:set(username, node, data); end function store:users() @@ -136,23 +151,7 @@ local function get_broadcaster(username) end message:add_child(item); end - - local broadcast_to = {}; for jid in pairs(jids) do - broadcast_to[jid] = true; - end - - local service_recipients = recipients[username]; - if service_recipients then - local service = services[username]; - for recipient, nodes in pairs(service_recipients) do - if nodes:contains(node) and service:may(node, recipient, "subscribe") then - broadcast_to[recipient] = true; - end - end - end - - for jid in pairs(broadcast_to) do module:log("debug", "Sending notification to %s from %s: %s", jid, user_bare, tostring(item)); message.attr.to = jid; module:send(message); @@ -161,6 +160,20 @@ local function get_broadcaster(username) return simple_broadcast; end +local function on_node_creation(event) + local service = event.service; + local node = event.node; + local username = service.config.pep_username; + + local service_recipients = recipients[username]; + if not service_recipients then return; end + + for recipient, nodes in pairs(service_recipients) do + if nodes:contains(node) then + service:add_subscription(node, recipient, recipient, { presence = true }); + end + end +end function get_pep_service(username) module:log("debug", "get_pep_service(%q)", username); @@ -220,6 +233,10 @@ function get_pep_service(username) return service; end +module:hook("item-added/pep-service", function (event) + local service = event.item.service; + module:hook_object_event(service.events, "node-created", on_node_creation); +end); function handle_pubsub_iq(event) local origin, stanza = event.origin, event.stanza; @@ -286,9 +303,12 @@ local function update_subscriptions(recipient, service_name, nodes) end local service = get_pep_service(service_name); + for node in current - nodes do + service:remove_subscription(node, recipient, recipient); + end for node in nodes - current do - if service:may(node, recipient, "subscribe") then + if service:add_subscription(node, recipient, recipient, { presence = true }) then resend_last_item(recipient, node, service); end end -- cgit v1.2.3 From 8e381dbb1e0041b30908e37e0db5acbe87c21de4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Jun 2019 21:08:12 +0200 Subject: mod_blocklist: Add test case capturing current behavior --- spec/scansion/blocking.scs | 162 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 spec/scansion/blocking.scs diff --git a/spec/scansion/blocking.scs b/spec/scansion/blocking.scs new file mode 100644 index 00000000..5f4c8cba --- /dev/null +++ b/spec/scansion/blocking.scs @@ -0,0 +1,162 @@ +# XEP-0191: Blocking Command + +[Client] Romeo + jid: blocker@localhost + password: password + +[Client] Juliet + jid: blockee@localhost + password: password + +----- + +# The parties connect +Romeo connects + +Romeo sends: + + +Romeo receives: + + + + +Juliet connects + +Juliet sends: + + +Juliet receives: + + + + +# They add each other +Romeo sends: + + +Romeo receives: + + +Juliet receives: + + +Juliet sends: + + +Romeo receives: + + + + + +Juliet sends: + + +Juliet receives: + + +Romeo receives: + + +Romeo sends: + + +Juliet receives: + + + + + +Romeo receives: + + + + + +# They can now talk +Juliet sends: + + ohai + + +Romeo receives: + + ohai + + +# And now to the blockining + +Romeo sends: + + + + + + +Romeo receives: + + +Juliet receives: + + +# Can"t talk anymore +Romeo sends: + + hello? + + +Romeo receives: + + + + You have blocked this JID + + + + +Juliet sends: + + +Juliet receives: + + + + + + +Romeo sends: + + + + + + +Romeo receives: + + +# Can talk again +Romeo sends: + + hello! + + +Juliet receives: + + hello! + + +# Bye +Juliet disconnects + +Juliet sends: + + +Romeo receives: + + +Romeo disconnects + +Romeo sends: + + -- cgit v1.2.3 From 4a997af768df029e1b5f350c41e13887f679701e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Jun 2019 21:18:46 +0200 Subject: mod_blocklist: Update test case with correct behavior (see #1380) Expect failure --- spec/scansion/blocking.scs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/scansion/blocking.scs b/spec/scansion/blocking.scs index 5f4c8cba..809bbcb5 100644 --- a/spec/scansion/blocking.scs +++ b/spec/scansion/blocking.scs @@ -132,6 +132,12 @@ Romeo sends: +Juliet receives: + + + + + Romeo receives: -- cgit v1.2.3 From f1c10dbc910f8d98ad7379e50a6f8a183e60019a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Jun 2019 21:20:00 +0200 Subject: mod_blocklist: Trigger resend of presence when unblocking a contact (fixes #1380) --- plugins/mod_blocklist.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/mod_blocklist.lua b/plugins/mod_blocklist.lua index 8aca7332..ee48ffad 100644 --- a/plugins/mod_blocklist.lua +++ b/plugins/mod_blocklist.lua @@ -128,6 +128,7 @@ local function edit_blocklist(event) -- > only if the contact is allowed to receive presence notifications [...] -- So contacts we need to do that for are added to the set below. local send_unavailable = is_blocking and {}; + local send_available = not is_blocking and {}; -- Because blocking someone currently also blocks the ability to reject -- subscription requests, we'll preemptively reject such @@ -147,6 +148,8 @@ local function edit_blocklist(event) elseif is_contact_pending_in(username, module.host, jid) then remove_pending[jid] = true; end + elseif is_contact_subscribed(username, module.host, jid) then + send_available[jid] = true; end end @@ -203,6 +206,11 @@ local function edit_blocklist(event) save_roster(username, module.host, roster); -- Not much we can do about save failing here end + else + local user_bare = username .. "@" .. module.host; + for jid in pairs(send_available) do + module:send(st.presence({ type = "probe", to = user_bare, from = jid })); + end end local blocklist_push = st.iq({ type = "set", id = "blocklist-push" }) -- cgit v1.2.3 From a4f539d600ec4a3e88f545f80abd0d1349e95024 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Jun 2019 22:10:19 +0200 Subject: mod_blocklist: Remove unrelated tags from test case --- spec/scansion/blocking.scs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/spec/scansion/blocking.scs b/spec/scansion/blocking.scs index 809bbcb5..7b46167f 100644 --- a/spec/scansion/blocking.scs +++ b/spec/scansion/blocking.scs @@ -17,9 +17,7 @@ Romeo sends: Romeo receives: - - - + Juliet connects @@ -27,9 +25,7 @@ Juliet sends: Juliet receives: - - - + # They add each other Romeo sends: @@ -47,7 +43,6 @@ Juliet sends: Romeo receives: - Juliet sends: @@ -65,13 +60,11 @@ Romeo sends: Juliet receives: - Romeo receives: - # They can now talk @@ -134,7 +127,6 @@ Romeo sends: Juliet receives: - -- cgit v1.2.3 From 794356d5130ed275db3132b8eb5205080c8b9c91 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Jun 2019 22:25:46 +0200 Subject: scansion/blocking: Remove the right irrelevant thing --- spec/scansion/blocking.scs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/scansion/blocking.scs b/spec/scansion/blocking.scs index 7b46167f..6a9f199e 100644 --- a/spec/scansion/blocking.scs +++ b/spec/scansion/blocking.scs @@ -127,7 +127,7 @@ Romeo sends: Juliet receives: - + Romeo receives: -- cgit v1.2.3 From 005aa17e7a8a7e16a41113def642d8aabb3507fd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 8 Jul 2019 01:17:34 +0200 Subject: net.server_epoll: Backport timer optimization 6c2370f17027 from trunk (see #1388) The previous timer handling did not scale well and led to high CPU usage with many connections (each with at least an read timeout). --- net/server_epoll.lua | 77 ++++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 48 deletions(-) diff --git a/net/server_epoll.lua b/net/server_epoll.lua index c279c579..0c03ae15 100644 --- a/net/server_epoll.lua +++ b/net/server_epoll.lua @@ -6,9 +6,7 @@ -- -local t_sort = table.sort; local t_insert = table.insert; -local t_remove = table.remove; local t_concat = table.concat; local setmetatable = setmetatable; local tostring = tostring; @@ -20,6 +18,7 @@ local log = require "util.logger".init("server_epoll"); local socket = require "socket"; local luasec = require "ssl"; local gettime = require "util.time".now; +local indexedbheap = require "util.indexedbheap"; local createtable = require "util.table".create; local inet = require "util.net"; local inet_pton = inet.pton; @@ -66,22 +65,24 @@ local fds = createtable(10, 0); -- FD -> conn -- Timer and scheduling -- -local timers = {}; +local timers = indexedbheap.create(); local function noop() end local function closetimer(t) t[1] = 0; t[2] = noop; + timers:remove(t.id); end --- Set to true when timers have changed -local resort_timers = false; +local function reschedule(t, time) + t[1] = time; + timers:reprioritize(t.id, time); +end -- Add absolute timer local function at(time, f) - local timer = { time, f, close = closetimer }; - t_insert(timers, timer); - resort_timers = true; + local timer = { time, f, close = closetimer, reschedule = reschedule, id = nil }; + timer.id = timers:insert(timer, time); return timer; end @@ -94,50 +95,32 @@ end -- Return time until next timeout local function runtimers(next_delay, min_wait) -- Any timers at all? - if not timers[1] then - return next_delay; + local now = gettime(); + local peek = timers:peek(); + while peek do + + if peek > now then + next_delay = peek - now; + break; end - if resort_timers then - -- Sort earliest timers to the end - t_sort(timers, function (a, b) return a[1] > b[1]; end); - resort_timers = false; + local _, timer, id = timers:pop(); + local ok, ret = pcall(timer[2], now); + if ok and type(ret) == "number" then + local next_time = now+ret; + timer[1] = next_time; + timers:insert(timer, next_time); end - -- Iterate from the end and remove completed timers - for i = #timers, 1, -1 do - local timer = timers[i]; - local t, f = timer[1], timer[2]; - -- Get time for every iteration to increase accuracy - local now = gettime(); - if t > now then - -- This timer should not fire yet - local diff = t - now; - if diff < next_delay then - next_delay = diff; + peek = timers:peek(); end - break; - end - local new_timeout = f(now); - if new_timeout then - -- Schedule for 'delay' from the time actually scheduled, - -- not from now, in order to prevent timer drift. - timer[1] = t + new_timeout; - resort_timers = true; - else - t_remove(timers, i); - end + if peek == nil then + return next_delay; end - if resort_timers or next_delay < min_wait then - -- Timers may be added from within a timer callback. - -- Those would not be considered for next_delay, - -- and we might sleep for too long, so instead - -- we return a shorter timeout so we can - -- properly sort all new timers. - next_delay = min_wait; + if next_delay < min_wait then + return min_wait; end - return next_delay; end @@ -243,8 +226,7 @@ function interface:setreadtimeout(t) end t = t or cfg.read_timeout; if self._readtimeout then - self._readtimeout[1] = gettime() + t; - resort_timers = true; + self._readtimeout:reschedule(gettime() + t); else self._readtimeout = addtimer(t, function () if self:on("readtimeout") then @@ -268,8 +250,7 @@ function interface:setwritetimeout(t) end t = t or cfg.send_timeout; if self._writetimeout then - self._writetimeout[1] = gettime() + t; - resort_timers = true; + self._writetimeout:reschedule(gettime() + t); else self._writetimeout = addtimer(t, function () self:on("disconnect", "write timeout"); -- cgit v1.2.3 From e22a26259927efe96a2808964e98f1dd42a573e5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 8 Jul 2019 02:46:27 +0200 Subject: util.serialization: Cache default serialization instance (fixes #1389) Most serialization uses still use the default serialize() and thus duplicate much of the setup, which negates some of the performance improvements of the rewrite. --- util/serialization.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/util/serialization.lua b/util/serialization.lua index dd6a2a2b..5121a9f9 100644 --- a/util/serialization.lua +++ b/util/serialization.lua @@ -272,10 +272,15 @@ local function deserialize(str) return ret; end +local default = new(); return { new = new; serialize = function (x, opt) - return new(opt)(x); + if opt == nil then + return default(x); + else + return new(opt)(x); + end end; deserialize = deserialize; }; -- cgit v1.2.3 From 0d6f101a496bf5aa5bb827432270030192c1e5c8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 20 Jul 2019 04:19:58 +0200 Subject: mod_websocket: Clone stanza before mutating (fixes #1398) Checking for `stanza.attr.xmlns == nil` to determine if the stanza object is an actual stanza (``, `` or `` in the `jabber:client` or `jabbber:server` namespace) or some other stream element. Since this mutation is not reverted, it may leak to other places and cause them to mistreat stanzas as stream elements. Especially in cases like MUC where a single stanza is broadcast to many recipients. --- plugins/mod_websocket.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index b4aba338..686a8981 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -285,6 +285,7 @@ function handle_request(event) end); add_filter(session, "stanzas/out", function(stanza) + stanza = st.clone(stanza); local attr = stanza.attr; attr.xmlns = attr.xmlns or xmlns_client; if stanza.name:find("^stream:") then -- cgit v1.2.3 From 1e99785e748e680b10849ab116e692d9a193ac17 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 30 Jul 2019 08:01:22 +0200 Subject: MUC: Advertise XEP-0410 support Unsure if the feature was in the XEP at the time of 7c1cdf5f9f83 --- plugins/muc/muc.lib.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 9648ea78..a942182d 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -358,6 +358,7 @@ end module:hook("muc-disco#info", function(event) event.reply:tag("feature", {var = "http://jabber.org/protocol/muc"}):up(); event.reply:tag("feature", {var = "http://jabber.org/protocol/muc#stable_id"}):up(); + event.reply:tag("feature", {var = "http://jabber.org/protocol/muc#self-ping-optimization"}):up(); end); module:hook("muc-disco#info", function(event) table.insert(event.form, { name = "muc#roominfo_occupants", label = "Number of occupants" }); -- cgit v1.2.3 From 2f87bc1e336ac432fee87a92a7f6ea17e68338fc Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 31 Aug 2019 16:08:45 +0200 Subject: MUC: Fix delay@from to be room JID (fixes #1416) --- plugins/muc/history.lib.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/muc/history.lib.lua b/plugins/muc/history.lib.lua index 445aacb9..0d69c97d 100644 --- a/plugins/muc/history.lib.lua +++ b/plugins/muc/history.lib.lua @@ -178,10 +178,10 @@ module:hook("muc-add-history", function(event) local ts = gettime(); local stamp = datetime.datetime(ts); stanza:tag("delay", { -- XEP-0203 - xmlns = "urn:xmpp:delay", from = module.host, stamp = stamp + xmlns = "urn:xmpp:delay", from = room.jid, stamp = stamp }):up(); stanza:tag("x", { -- XEP-0091 (deprecated) - xmlns = "jabber:x:delay", from = module.host, stamp = datetime.legacy() + xmlns = "jabber:x:delay", from = room.jid, stamp = datetime.legacy() }):up(); local entry = { stanza = stanza, timestamp = ts }; table.insert(history, entry); -- cgit v1.2.3 -- cgit v1.2.3 From c3d0a0a3289319bedcbc74d8c7eba75d381e2017 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 11 Sep 2019 15:03:54 +0100 Subject: prosodyctl: Fix traceback on incorrect proxy65_address type --- prosodyctl | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/prosodyctl b/prosodyctl index e580446b..405ef1f8 100755 --- a/prosodyctl +++ b/prosodyctl @@ -1103,17 +1103,21 @@ function commands.check(arg) if modules:contains("proxy65") then local proxy65_target = configmanager.get(host, "proxy65_address") or host; - local A, AAAA = dns.lookup(idna.to_ascii(proxy65_target), "A"), dns.lookup(idna.to_ascii(proxy65_target), "AAAA"); - local prob = {}; - if not A then - table.insert(prob, "A"); - end - if v6_supported and not AAAA then - table.insert(prob, "AAAA"); - end - if #prob > 0 then - print(" File transfer proxy "..proxy65_target.." has no "..table.concat(prob, "/") - .." record. Create one or set 'proxy65_address' to the correct host/IP."); + if type(proxy65_target) == "string" then + local A, AAAA = dns.lookup(idna.to_ascii(proxy65_target), "A"), dns.lookup(idna.to_ascii(proxy65_target), "AAAA"); + local prob = {}; + if not A then + table.insert(prob, "A"); + end + if v6_supported and not AAAA then + table.insert(prob, "AAAA"); + end + if #prob > 0 then + print(" File transfer proxy "..proxy65_target.." has no "..table.concat(prob, "/") + .." record. Create one or set 'proxy65_address' to the correct host/IP."); + end + else + print(" proxy65_address for "..host.." should be set to a string, unable to perform DNS check"); end end -- cgit v1.2.3 From 44f502499a55638aae559a238f4eb760431581e0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 21 Sep 2019 15:20:50 +0200 Subject: mod_vcard_legacy: Advertise lack of avatar correctly (fixes #1431) (thanks lovetox) --- plugins/mod_vcard_legacy.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/mod_vcard_legacy.lua b/plugins/mod_vcard_legacy.lua index ab2c4490..6229b931 100644 --- a/plugins/mod_vcard_legacy.lua +++ b/plugins/mod_vcard_legacy.lua @@ -301,10 +301,10 @@ local function inject_xep153(event) local pep_service = mod_pep.get_pep_service(username); stanza:remove_children("x", "vcard-temp:x:update"); - local x_update = st.stanza("x", { xmlns = "vcard-temp:x:update" }); + local x_update = st.stanza("x", { xmlns = "vcard-temp:x:update" }):tag("photo"); local ok, avatar_hash = pep_service:get_last_item("urn:xmpp:avatar:metadata", true); if ok and avatar_hash then - x_update:text_tag("photo", avatar_hash); + x_update:text(avatar_hash); end stanza:add_direct_child(x_update); end -- cgit v1.2.3 From 67b37537bb92eb5c2c2dcc7af3498dbe22cf8355 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 21 Sep 2019 16:29:16 +0200 Subject: mod_vcard_legacy: Don't owerwrite empty photo elements (fixes #1432) --- plugins/mod_vcard_legacy.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/mod_vcard_legacy.lua b/plugins/mod_vcard_legacy.lua index 6229b931..5e75947a 100644 --- a/plugins/mod_vcard_legacy.lua +++ b/plugins/mod_vcard_legacy.lua @@ -300,13 +300,19 @@ local function inject_xep153(event) if stanza.attr.type then return end local pep_service = mod_pep.get_pep_service(username); - stanza:remove_children("x", "vcard-temp:x:update"); - local x_update = st.stanza("x", { xmlns = "vcard-temp:x:update" }):tag("photo"); + local x_update = stanza:get_child("x", "vcard-temp:x:update"); + if not x_update then + x_update = st.stanza("x", { xmlns = "vcard-temp:x:update" }):tag("photo"); + stanza:add_direct_child(x_update); + elseif x_update:get_child("photo") then + return; -- XEP implies that these should be left alone + else + x_update:tag("photo"); + end local ok, avatar_hash = pep_service:get_last_item("urn:xmpp:avatar:metadata", true); if ok and avatar_hash then x_update:text(avatar_hash); end - stanza:add_direct_child(x_update); end module:hook("pre-presence/full", inject_xep153, 1); -- cgit v1.2.3 From 8426a1b88e2a12239affdc970c845adfbda7bfdb Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 29 Sep 2019 20:48:00 +0200 Subject: MUC: Strip tags with MUC-related namespaces from private messages (fixes #1427) Prevents duplication since it adds another <{muc#user}x> here --- plugins/muc/muc.lib.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index a942182d..cf9b46f7 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -779,6 +779,7 @@ function room_mt:handle_message_to_occupant(origin, stanza) return true; end log("debug", "%s sent private message stanza to %s (%s)", from, to, o_data.jid); + stanza = muc_util.filter_muc_x(st.clone(stanza)); stanza:tag("x", { xmlns = "http://jabber.org/protocol/muc#user" }):up(); stanza.attr.from = current_nick; self:route_to_occupant(o_data, stanza) -- cgit v1.2.3 From 4d9a571128c08173315407e243a2b1badb5d9f8c Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 3 Oct 2019 16:38:15 +0100 Subject: mod_mam: Add flag to session when it performs a MAM query --- plugins/mod_mam/mod_mam.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index 8900a2be..b500770f 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -90,6 +90,8 @@ module:hook("iq-set/self/"..xmlns_mam..":query", function(event) local query = stanza.tags[1]; local qid = query.attr.queryid; + origin.mam_requested = true; + get_prefs(origin.username, true); -- Search query parameters -- cgit v1.2.3 From cd2d1e87d66d6a014dec2a6e6da199fc2fd3398d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 20 Oct 2019 01:20:11 +0200 Subject: MUC: Don't advertise registration feature on host JID (fixes #1451) There is currently no mention in XEP-0045 of how or where to advertise support for registration. Advertising on the host JID may be confusable with service-wide registration, as implemented in ejabberd. A common and sensible pattern in XMPP is that a feature is advertised on the JID where the service is available. --- plugins/muc/register.lib.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/muc/register.lib.lua b/plugins/muc/register.lib.lua index 21cb3f2f..95ed1a84 100644 --- a/plugins/muc/register.lib.lua +++ b/plugins/muc/register.lib.lua @@ -48,8 +48,6 @@ module:hook("muc-set-affiliation", function (event) event.room._reserved_nicks = nil; end); -module:add_feature("jabber:iq:register"); - module:hook("muc-disco#info", function (event) event.reply:tag("feature", { var = "jabber:iq:register" }):up(); end); -- cgit v1.2.3 From 2a7b5fee5b95d8b1f4ce0f597dae658411ffb303 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 20 Oct 2019 20:52:14 +0200 Subject: util.interpolation: Support unescaped variables with more modifiers (fixes #1452) Tests will be added in trunk. --- util/interpolation.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/interpolation.lua b/util/interpolation.lua index 315cc203..e0ccf47b 100644 --- a/util/interpolation.lua +++ b/util/interpolation.lua @@ -32,7 +32,7 @@ local function new_render(pat, escape, funcs) -- assert(type(values) == "table", "bad argument #2 to 'render' (table expected)"); return (s_gsub(template, pat, function (block) block = s_sub(block, 2, -2); - local name, opt, e = s_match(block, "^([%a_][%w_.]*)(%p?)()"); + local name, raw, opt, e = s_match(block, "^([%a_][%w_.]*)(!?)(%p?)()"); if not name then return end local value = values[name]; if not value and name:find(".", 2, true) then @@ -45,7 +45,7 @@ local function new_render(pat, escape, funcs) if funcs then while value ~= nil and opt == '|' do local f; - f, opt, e = s_match(block, "^([%a_][%w_.]*)(%p?)()", e); + f, raw, opt, e = s_match(block, "^([%a_][%w_.]*)(!?)(%p?)()", e); f = funcs[f]; if f then value = f(value); end end @@ -70,7 +70,7 @@ local function new_render(pat, escape, funcs) if type(value) ~= "string" then value = tostring(value); end - if opt ~= '!' then + if raw ~= '!' then return escape(value); end return value; -- cgit v1.2.3 From ce96d43cab1c757fd68ee6cfc19ad71c90c9e298 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 2 Nov 2019 19:24:26 +0100 Subject: net.resolvers: Apply IDNA conversion to ascii for DNS lookups (fixes #1426) --- net/resolvers/basic.lua | 3 ++- net/resolvers/service.lua | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/net/resolvers/basic.lua b/net/resolvers/basic.lua index 9a3c9952..d8031a6b 100644 --- a/net/resolvers/basic.lua +++ b/net/resolvers/basic.lua @@ -1,5 +1,6 @@ local adns = require "net.adns"; local inet_pton = require "util.net".pton; +local idna_to_ascii = require "util.encodings".idna.to_ascii; local methods = {}; local resolver_mt = { __index = methods }; @@ -59,7 +60,7 @@ end local function new(hostname, port, conn_type, extra) return setmetatable({ - hostname = hostname; + hostname = idna_to_ascii(hostname); port = port; conn_type = conn_type or "tcp"; extra = extra; diff --git a/net/resolvers/service.lua b/net/resolvers/service.lua index b5a2d821..a76adb73 100644 --- a/net/resolvers/service.lua +++ b/net/resolvers/service.lua @@ -1,5 +1,6 @@ local adns = require "net.adns"; local basic = require "net.resolvers.basic"; +local idna_to_ascii = require "util.encodings".idna.to_ascii; local methods = {}; local resolver_mt = { __index = methods }; @@ -58,7 +59,7 @@ end local function new(hostname, service, conn_type, extra) return setmetatable({ - hostname = hostname; + hostname = idna_to_ascii(hostname); service = service; conn_type = conn_type or "tcp"; extra = extra; -- cgit v1.2.3 From 6834e9cd6078109b32a4606710979a5b502903ed Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 2 Nov 2019 19:36:19 +0100 Subject: net.resolvers: Abort on hostnames not passing IDNA validation Prevents error on trying to use nil. Needs better error reporting in the future. --- net/resolvers/basic.lua | 5 +++++ net/resolvers/service.lua | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/net/resolvers/basic.lua b/net/resolvers/basic.lua index d8031a6b..cafef58b 100644 --- a/net/resolvers/basic.lua +++ b/net/resolvers/basic.lua @@ -18,6 +18,11 @@ function methods:next(cb) return; end + if not self.hostname then + -- FIXME report IDNA error + cb(nil); + end + local targets = {}; local n = 2; local function ready() diff --git a/net/resolvers/service.lua b/net/resolvers/service.lua index a76adb73..bb255c33 100644 --- a/net/resolvers/service.lua +++ b/net/resolvers/service.lua @@ -25,6 +25,11 @@ function methods:next(cb) return; end + if not self.hostname then + -- FIXME report IDNA error + cb(nil); + end + local targets = {}; local function ready() self.targets = targets; -- cgit v1.2.3 From d3ec2e6fef757bdf9d40a4412945d9daae3142b4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 3 Nov 2019 22:19:09 +0100 Subject: util.startup: Update config path (fixes #1430) --- util/startup.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/startup.lua b/util/startup.lua index c101c290..82d0804d 100644 --- a/util/startup.lua +++ b/util/startup.lua @@ -33,7 +33,8 @@ function startup.read_config() if file then file:close(); prosody.config_file = filename; - CFG_CONFIGDIR = filename:match("^(.*)[\\/][^\\/]*$"); -- luacheck: ignore 111 + prosody.paths.config = filename:match("^(.*)[\\/][^\\/]*$"); + CFG_CONFIGDIR = prosody.paths.config; -- luacheck: ignore 111 break; end end -- cgit v1.2.3 From 9b5d4cf8750c90b6eb90d985d98807b63910c7d3 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 4 Nov 2019 00:29:49 +0100 Subject: util.startup: Ensure prosody.paths are absolute (see #1430) Normally these paths are injected into the installed 'prosody' executable as absolute paths, but it is possible to override at least the config path via environment variable or command line argument. This makes sure a path relative to pwd stays relative to that instead of the data directory. --- util/startup.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/util/startup.lua b/util/startup.lua index 82d0804d..e88ed709 100644 --- a/util/startup.lua +++ b/util/startup.lua @@ -231,8 +231,14 @@ end function startup.chdir() if prosody.installed then + local lfs = require "lfs"; + -- Ensure paths are absolute, not relative to the working directory which we're about to change + local cwd = lfs.currentdir(); + prosody.paths.source = config.resolve_relative_path(cwd, prosody.paths.source); + prosody.paths.config = config.resolve_relative_path(cwd, prosody.paths.config); + prosody.paths.data = config.resolve_relative_path(cwd, prosody.paths.data); -- Change working directory to data path. - require "lfs".chdir(prosody.paths.data); + lfs.chdir(prosody.paths.data); end end -- cgit v1.2.3 From f86ea56d52295dea0867707cf163d9f3d8f4acc5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 8 Nov 2019 00:54:56 +0100 Subject: net.resolvers: Fix traceback from hostname failing IDNA Related to #1426 --- net/resolvers/basic.lua | 1 + net/resolvers/service.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/net/resolvers/basic.lua b/net/resolvers/basic.lua index cafef58b..f37e74a2 100644 --- a/net/resolvers/basic.lua +++ b/net/resolvers/basic.lua @@ -21,6 +21,7 @@ function methods:next(cb) if not self.hostname then -- FIXME report IDNA error cb(nil); + return; end local targets = {}; diff --git a/net/resolvers/service.lua b/net/resolvers/service.lua index bb255c33..34f14cba 100644 --- a/net/resolvers/service.lua +++ b/net/resolvers/service.lua @@ -28,6 +28,7 @@ function methods:next(cb) if not self.hostname then -- FIXME report IDNA error cb(nil); + return; end local targets = {}; -- cgit v1.2.3 From c62c176abe6ca5e33c25cdebcb7d1457486ce7ca Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 16 Nov 2019 16:45:33 +0100 Subject: util.pposix: Avoid overflow of malloc info at 2GB (fixes #1445 until 4GB) --- util-src/pposix.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util-src/pposix.c b/util-src/pposix.c index 5c926603..004f61a6 100644 --- a/util-src/pposix.c +++ b/util-src/pposix.c @@ -721,20 +721,20 @@ int lc_meminfo(lua_State *L) { struct mallinfo info = mallinfo(); lua_createtable(L, 0, 5); /* This is the total size of memory allocated with sbrk by malloc, in bytes. */ - lua_pushinteger(L, info.arena); + lua_pushinteger(L, (unsigned)info.arena); lua_setfield(L, -2, "allocated"); /* This is the total size of memory allocated with mmap, in bytes. */ - lua_pushinteger(L, info.hblkhd); + lua_pushinteger(L, (unsigned)info.hblkhd); lua_setfield(L, -2, "allocated_mmap"); /* This is the total size of memory occupied by chunks handed out by malloc. */ - lua_pushinteger(L, info.uordblks); + lua_pushinteger(L, (unsigned)info.uordblks); lua_setfield(L, -2, "used"); /* This is the total size of memory occupied by free (not in use) chunks. */ - lua_pushinteger(L, info.fordblks); + lua_pushinteger(L, (unsigned)info.fordblks); lua_setfield(L, -2, "unused"); /* This is the size of the top-most releasable chunk that normally borders the end of the heap (i.e., the high end of the virtual address space's data segment). */ - lua_pushinteger(L, info.keepcost); + lua_pushinteger(L, (unsigned)info.keepcost); lua_setfield(L, -2, "returnable"); return 1; } -- cgit v1.2.3 From 94f8d57fe4b3428973f0ba7b990915aa3abe3f7a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 23 Nov 2019 01:05:28 +0100 Subject: MUC: Keep role across nickname change (fixes #1466) --- plugins/muc/muc.lib.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index cf9b46f7..639ecc38 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -524,6 +524,9 @@ function room_mt:handle_normal_presence(origin, stanza) log("debug", "no occupant found for %s; creating new occupant object for %s", dest_jid, real_jid); is_first_dest_session = true; dest_occupant = self:new_occupant(bare_jid, dest_jid); + if orig_occupant then + dest_occupant.role = orig_occupant.role; + end else is_first_dest_session = false; end -- cgit v1.2.3 From 5c649dff87ecc21140bf07ed511e10b5f93417d1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 23 Nov 2019 23:10:39 +0100 Subject: prosodyctl check: Warn about conflict between mod_vcard and mod_vcard_legacy (#1469) --- prosodyctl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prosodyctl b/prosodyctl index 405ef1f8..a732a73e 100755 --- a/prosodyctl +++ b/prosodyctl @@ -933,6 +933,10 @@ function commands.check(arg) print(" For more information see https://prosody.im/doc/storage"); end end + if all_modules:contains("vcard") and all_modules:contains("vcard_legacy") then + print(" Both mod_vcard_legacy and mod_vcard are enabled but they conflict"); + print(" with each other. Remove one."); + end for host, host_config in pairs(config) do --luacheck: ignore 213/host if type(rawget(host_config, "storage")) == "string" and rawget(host_config, "default_storage") then print(""); -- cgit v1.2.3 From 7115b16bc42606dc1e33cfe313fa0592edc40637 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 23 Nov 2019 23:11:03 +0100 Subject: core.modulemanager: Disable mod_vcard if mod_vcard_legacy is enabled to prevent conflict (#1469) --- core/modulemanager.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/modulemanager.lua b/core/modulemanager.lua index 17602459..a824d36a 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -63,6 +63,11 @@ local function get_modules_for_host(host) modules:add("admin_telnet"); end + if modules:contains("vcard") and modules:contains("vcard_legacy") then + log("error", "The mod_vcard_legacy plugin replaces mod_vcard but both are enabled. Please update your config."); + modules:remove("vcard"); + end + return modules, component; end -- cgit v1.2.3 From a286ed0a57ae9b2f0cceb0fc0756a8db95708cc4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Nov 2019 04:23:51 +0100 Subject: net.resolvers.basic: Move IP literal check to constructor This is to prepare for fixing #1459. An IPv6 literal in [ ] brackets does not pass IDNA and resolving it fails there. --- net/resolvers/basic.lua | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/net/resolvers/basic.lua b/net/resolvers/basic.lua index f37e74a2..e3a94382 100644 --- a/net/resolvers/basic.lua +++ b/net/resolvers/basic.lua @@ -33,16 +33,6 @@ function methods:next(cb) self:next(cb); end - local is_ip = inet_pton(self.hostname); - if is_ip then - if #is_ip == 16 then - cb(self.conn_type.."6", self.hostname, self.port, self.extra); - elseif #is_ip == 4 then - cb(self.conn_type.."4", self.hostname, self.port, self.extra); - end - return; - end - -- Resolve DNS to target list local dns_resolver = adns.resolver(); dns_resolver:lookup(function (answer) @@ -65,11 +55,24 @@ function methods:next(cb) end local function new(hostname, port, conn_type, extra) + local ascii_host = idna_to_ascii(hostname); + local targets = nil; + + local is_ip = inet_pton(hostname); + if is_ip then + if #is_ip == 16 then + targets = { { conn_type.."6", hostname, port, extra } }; + elseif #is_ip == 4 then + targets = { { conn_type.."4", hostname, port, extra } }; + end + end + return setmetatable({ - hostname = idna_to_ascii(hostname); + hostname = ascii_host; port = port; conn_type = conn_type or "tcp"; extra = extra; + targets = targets; }, resolver_mt); end -- cgit v1.2.3 From 50137dbaf592e69bf9d06ae5398c6c0ff14479fe Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Nov 2019 04:26:44 +0100 Subject: net.resolvers.basic: Fix resolution of IPv6 literals (in brackets) (fixes #1459) --- net/resolvers/basic.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/resolvers/basic.lua b/net/resolvers/basic.lua index e3a94382..93182fda 100644 --- a/net/resolvers/basic.lua +++ b/net/resolvers/basic.lua @@ -59,6 +59,9 @@ local function new(hostname, port, conn_type, extra) local targets = nil; local is_ip = inet_pton(hostname); + if not is_ip and hostname:sub(1,1) == '[' then + is_ip = inet_pton(hostname:sub(2,-2)); + end if is_ip then if #is_ip == 16 then targets = { { conn_type.."6", hostname, port, extra } }; -- cgit v1.2.3 From 1c60c932b45c6d2866249ba047df4c73aa4992af Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 24 Nov 2019 04:41:07 +0100 Subject: net.resolvers.basic: Normalise IP literals, ensures net.server is happy --- net/resolvers/basic.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/resolvers/basic.lua b/net/resolvers/basic.lua index 93182fda..08c71ef5 100644 --- a/net/resolvers/basic.lua +++ b/net/resolvers/basic.lua @@ -1,5 +1,6 @@ local adns = require "net.adns"; local inet_pton = require "util.net".pton; +local inet_ntop = require "util.net".ntop; local idna_to_ascii = require "util.encodings".idna.to_ascii; local methods = {}; @@ -63,6 +64,7 @@ local function new(hostname, port, conn_type, extra) is_ip = inet_pton(hostname:sub(2,-2)); end if is_ip then + hostname = inet_ntop(is_ip); if #is_ip == 16 then targets = { { conn_type.."6", hostname, port, extra } }; elseif #is_ip == 4 then -- cgit v1.2.3 From 333526a6858a4076568bb134269c9c09c7211fe1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 6 Jun 2019 17:37:15 +0200 Subject: util.pubsub: Factor out calling of broadcaster This will simplify doing things along with broadcasting. --- util/pubsub.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/util/pubsub.lua b/util/pubsub.lua index e5e0cb7c..24f1f41d 100644 --- a/util/pubsub.lua +++ b/util/pubsub.lua @@ -499,7 +499,7 @@ function service:delete(node, actor) --> ok, err end self.events.fire_event("node-deleted", { service = self, node = node, actor = actor }); - self.config.broadcaster("delete", node, node_obj.subscribers, nil, actor, node_obj, self); + self:broadcast("delete", node, node_obj.subscribers, nil, actor, node_obj); return true; end @@ -562,10 +562,14 @@ function service:publish(node, actor, id, item, requested_config) --> ok, err local event_data = { service = self, node = node, actor = actor, id = id, item = item }; self.events.fire_event("item-published/"..node, event_data); self.events.fire_event("item-published", event_data); - self.config.broadcaster("items", node, node_obj.subscribers, item, actor, node_obj, self); + self:broadcast("items", node, node_obj.subscribers, item, actor, node_obj); return true; end +function service:broadcast(event, node, subscribers, item, actor, node_obj) + return self.config.broadcaster(event, node, subscribers, item, actor, node_obj, self); +end + function service:retract(node, actor, id, retract) --> ok, err -- Access checking if not self:may(node, actor, "retract") then @@ -582,7 +586,7 @@ function service:retract(node, actor, id, retract) --> ok, err end self.events.fire_event("item-retracted", { service = self, node = node, actor = actor, id = id }); if retract then - self.config.broadcaster("retract", node, node_obj.subscribers, retract, actor, node_obj, self); + self:broadcast("retract", node, node_obj.subscribers, retract, actor, node_obj); end return true end @@ -604,7 +608,7 @@ function service:purge(node, actor, notify) --> ok, err end self.events.fire_event("node-purged", { service = self, node = node, actor = actor }); if notify then - self.config.broadcaster("purge", node, node_obj.subscribers, nil, actor, node_obj, self); + self:broadcast("purge", node, node_obj.subscribers, nil, actor, node_obj); end return true end -- cgit v1.2.3 From 1bb215571dedbbc3acebca304a8055b7d6514f41 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 6 Jun 2019 18:13:46 +0200 Subject: util.pubsub: Pass subscribers trough a filter callback --- util/pubsub.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/pubsub.lua b/util/pubsub.lua index 24f1f41d..1674b9a7 100644 --- a/util/pubsub.lua +++ b/util/pubsub.lua @@ -6,6 +6,7 @@ local service_mt = {}; local default_config = { itemstore = function (config, _) return cache.new(config["max_items"]) end; broadcaster = function () end; + subscriber_filter = function (subs) return subs end; itemcheck = function () return true; end; get_affiliation = function () end; normalize_jid = function (jid) return jid; end; @@ -567,6 +568,7 @@ function service:publish(node, actor, id, item, requested_config) --> ok, err end function service:broadcast(event, node, subscribers, item, actor, node_obj) + subscribers = self.config.subscriber_filter(subscribers, node, event); return self.config.broadcaster(event, node, subscribers, item, actor, node_obj, self); end -- cgit v1.2.3 From 4bdf3f20a96aa1734faafacb17328853956cacbd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 10 Jun 2019 13:57:09 +0200 Subject: mod_pep: Handle presence subscriptions in filter (fixes #1372) Take two on 045209b41b3a --- plugins/mod_pep.lua | 51 +++++++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index 7a4aac2b..12be41a2 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -90,21 +90,6 @@ local function nodestore(username) return data, err; end function store:set(node, data) - if data then - -- Save the data without subscriptions - local subscribers = {}; - for jid, sub in pairs(data.subscribers) do - if type(sub) ~= "table" or not sub.presence then - subscribers[jid] = sub; - end - end - data = { - name = data.name; - config = data.config; - affiliations = data.affiliations; - subscribers = subscribers; - }; - end return node_config:set(username, node, data); end function store:users() @@ -160,18 +145,23 @@ local function get_broadcaster(username) return simple_broadcast; end -local function on_node_creation(event) - local service = event.service; - local node = event.node; - local username = service.config.pep_username; - - local service_recipients = recipients[username]; - if not service_recipients then return; end +local function get_subscriber_filter(username) + return function (jids, node) + local broadcast_to = {}; + for jid, opts in pairs(jids) do + broadcast_to[jid] = opts; + end - for recipient, nodes in pairs(service_recipients) do - if nodes:contains(node) then - service:add_subscription(node, recipient, recipient, { presence = true }); + local service_recipients = recipients[username]; + if service_recipients then + local service = services[username]; + for recipient, nodes in pairs(service_recipients) do + if nodes:contains(node) and service:may(node, recipient, "subscribe") then + broadcast_to[recipient] = true; + end + end end + return broadcast_to; end end @@ -196,6 +186,7 @@ function get_pep_service(username) nodestore = nodestore(username); itemstore = simple_itemstore(username); broadcaster = get_broadcaster(username); + subscriber_filter = get_subscriber_filter(username); itemcheck = is_item_stanza; get_affiliation = function (jid) if jid_bare(jid) == user_bare then @@ -233,11 +224,6 @@ function get_pep_service(username) return service; end -module:hook("item-added/pep-service", function (event) - local service = event.item.service; - module:hook_object_event(service.events, "node-created", on_node_creation); -end); - function handle_pubsub_iq(event) local origin, stanza = event.origin, event.stanza; local service_name = origin.username; @@ -303,12 +289,9 @@ local function update_subscriptions(recipient, service_name, nodes) end local service = get_pep_service(service_name); - for node in current - nodes do - service:remove_subscription(node, recipient, recipient); - end for node in nodes - current do - if service:add_subscription(node, recipient, recipient, { presence = true }) then + if service:may(node, recipient, "subscribe") then resend_last_item(recipient, node, service); end end -- cgit v1.2.3 From 097d7ca6638721a97bae4a92d1cdb3a41a05acdd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Dec 2019 22:42:39 +0100 Subject: mod_auth_internal_hashed: Pass on errors from password hash function (fixes #1477) --- plugins/mod_auth_internal_hashed.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/mod_auth_internal_hashed.lua b/plugins/mod_auth_internal_hashed.lua index 35764afb..083f648b 100644 --- a/plugins/mod_auth_internal_hashed.lua +++ b/plugins/mod_auth_internal_hashed.lua @@ -68,6 +68,9 @@ function provider.set_password(username, password) account.salt = generate_uuid(); account.iteration_count = max(account.iteration_count or 0, default_iteration_count); local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, account.salt, account.iteration_count); + if not valid then + return valid, stored_key; + end local stored_key_hex = to_hex(stored_key); local server_key_hex = to_hex(server_key); @@ -99,6 +102,9 @@ function provider.create_user(username, password) end local salt = generate_uuid(); local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, salt, default_iteration_count); + if not valid then + return valid, stored_key; + end local stored_key_hex = to_hex(stored_key); local server_key_hex = to_hex(server_key); return accounts:set(username, { -- cgit v1.2.3 From fa6f88cf3e2a5dc5ce939fdff4e7d1b1d74cf763 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Dec 2019 23:18:39 +0100 Subject: mod_mam: Log error when unable to store stanza (fix #1478) Unclear what else to do here. Caught by luacheck --- plugins/mod_mam/mod_mam.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index b500770f..2443270f 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -305,6 +305,8 @@ local function message_handler(event, c2s) event.stanza = clone_for_other_handlers; schedule_cleanup(store_user); module:fire_event("archive-message-added", { origin = origin, stanza = clone_for_storage, for_user = store_user, id = id }); + else + log("error", "Could not archive stanza: %s", err); end else log("debug", "Not archiving stanza: %s (prefs)", stanza:top_tag()); -- cgit v1.2.3 From 04965a84f1315221395442e70f8692158ffe2327 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 24 Dec 2019 00:27:41 +0100 Subject: mod_mam: Log error when unable to delete old messages (fix #1479) [luacheck] --- plugins/mod_mam/mod_mam.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index 2443270f..df5d925a 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -387,6 +387,8 @@ if cleanup_after ~= "never" then if ok then num_users = num_users + 1; sum = sum + (tonumber(ok) or 0); + else + module:log("error", "Could not delete messages for user '%s': %s", user, err); end end module:log("info", "Deleted %d expired messages for %d users", sum, num_users); -- cgit v1.2.3 From 62d5620fdb5686e2fb2ae6a2adb4ec7ef3c2b49e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 24 Dec 2019 00:27:44 +0100 Subject: mod_mam: Schedule cleanup again if unable to delete messages --- plugins/mod_mam/mod_mam.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index df5d925a..fd319486 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -388,6 +388,7 @@ if cleanup_after ~= "never" then num_users = num_users + 1; sum = sum + (tonumber(ok) or 0); else + cleanup_map:set(cut_off, user, true); module:log("error", "Could not delete messages for user '%s': %s", user, err); end end -- cgit v1.2.3 From 4e230b95efa6414813830e1371da5bff3de5c169 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Dec 2019 23:32:49 +0100 Subject: mod_muc_mam: Log error when unable to store stanza (fix #1480) [luacheck] --- plugins/mod_muc_mam.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/mod_muc_mam.lua b/plugins/mod_muc_mam.lua index a2e3f81b..37e41157 100644 --- a/plugins/mod_muc_mam.lua +++ b/plugins/mod_muc_mam.lua @@ -357,6 +357,8 @@ local function save_to_history(self, stanza) if id then schedule_cleanup(room_node); stanza:add_direct_child(st.stanza("stanza-id", { xmlns = xmlns_st_id, by = self.jid, id = id })); + else + module:log("error", "Could not archive stanza: %s", err); end end -- cgit v1.2.3 From 20d4a9b614d36aa41a446784cf40d08e965498b2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 24 Dec 2019 00:26:37 +0100 Subject: mod_muc_mam: Log error when unable to delete old messages (fix #1481) [luacheck] --- plugins/mod_muc_mam.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/mod_muc_mam.lua b/plugins/mod_muc_mam.lua index 37e41157..c6104757 100644 --- a/plugins/mod_muc_mam.lua +++ b/plugins/mod_muc_mam.lua @@ -459,6 +459,8 @@ if cleanup_after ~= "never" then if ok then num_rooms = num_rooms + 1; sum = sum + (tonumber(ok) or 0); + else + module:log("error", "Could not delete messages for room '%s': %s", room, err); end end module:log("info", "Deleted %d expired messages for %d rooms", sum, num_rooms); -- cgit v1.2.3 From ef1a12de07bec2a01242dd53f6157ec75b3f9637 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 24 Dec 2019 00:26:40 +0100 Subject: mod_muc_mam: Schedule cleanup again on failure --- plugins/mod_muc_mam.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_muc_mam.lua b/plugins/mod_muc_mam.lua index c6104757..a9287224 100644 --- a/plugins/mod_muc_mam.lua +++ b/plugins/mod_muc_mam.lua @@ -460,6 +460,7 @@ if cleanup_after ~= "never" then num_rooms = num_rooms + 1; sum = sum + (tonumber(ok) or 0); else + cleanup_map:set(cut_off, room, true); module:log("error", "Could not delete messages for room '%s': %s", room, err); end end -- cgit v1.2.3 From 271036a6a84cc469c8aa37dddedad47e101c67bc Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 24 Dec 2019 01:00:35 +0100 Subject: mod_muc_mam: Fix rebase mistake [luacheck] The 'err' was there in trunk --- plugins/mod_muc_mam.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_muc_mam.lua b/plugins/mod_muc_mam.lua index a9287224..2ce5e1b5 100644 --- a/plugins/mod_muc_mam.lua +++ b/plugins/mod_muc_mam.lua @@ -352,7 +352,7 @@ local function save_to_history(self, stanza) end -- And stash it - local id = archive:append(room_node, nil, stored_stanza, time_now(), with); + local id, err = archive:append(room_node, nil, stored_stanza, time_now(), with); if id then schedule_cleanup(room_node); -- cgit v1.2.3 From 453e74c0602cff3007ec0837c02ca1245e94236b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 24 Dec 2019 01:01:05 +0100 Subject: mod_mam: Fix rebase mistake [luacheck] The 'err' was there in trunk --- plugins/mod_mam/mod_mam.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua index fd319486..295d90e1 100644 --- a/plugins/mod_mam/mod_mam.lua +++ b/plugins/mod_mam/mod_mam.lua @@ -297,7 +297,7 @@ 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 ok, err = archive:append(store_user, nil, clone_for_storage, time_now(), with); if ok then local clone_for_other_handlers = st.clone(stanza); local id = ok; -- cgit v1.2.3 From 9bb36ab1f100f4f43307eccb030fca839dc115f0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 16 Dec 2018 02:56:11 +0100 Subject: core.rostermanager: Cache rosters of offline users for faster access (fixes #1233) (grafted from 42a3e3a2824822cef7640ac56d182c59bdd4224e) --- core/rostermanager.lua | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/core/rostermanager.lua b/core/rostermanager.lua index 61b08002..7bfad0a0 100644 --- a/core/rostermanager.lua +++ b/core/rostermanager.lua @@ -12,6 +12,7 @@ local log = require "util.logger".init("rostermanager"); local new_id = require "util.id".short; +local new_cache = require "util.cache".new; local pairs = pairs; local tostring = tostring; @@ -111,6 +112,23 @@ local function load_roster(username, host) else -- Attempt to load roster for non-loaded user log("debug", "load_roster: loading for offline user: %s", jid); end + local roster_cache = hosts[host] and hosts[host].roster_cache; + if not roster_cache then + if hosts[host] then + roster_cache = new_cache(1024); + hosts[host].roster_cache = roster_cache; + end + else + roster = roster_cache:get(jid); + if roster then + log("debug", "load_roster: cache hit"); + roster_cache:set(jid, roster); + if user then user.roster = roster; end + return roster; + else + log("debug", "load_roster: cache miss, loading from storage"); + end + end local roster_store = storagemanager.open(host, "roster", "keyval"); local data, err = roster_store:get(username); roster = data or {}; @@ -134,6 +152,10 @@ local function load_roster(username, host) if not err then hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster }); end + if roster_cache and not user then + log("debug", "load_roster: caching loaded roster"); + roster_cache:set(jid, roster); + end return roster, err; end -- cgit v1.2.3 From 96e84d9954e165006533ab98f9183ddcbfd3937f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 31 Dec 2019 02:48:49 +0100 Subject: prosodyctl check: Warn about conflict between mod_pep and mod_pep_simple Related #1483 --- prosodyctl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/prosodyctl b/prosodyctl index a732a73e..3242218d 100755 --- a/prosodyctl +++ b/prosodyctl @@ -937,6 +937,11 @@ function commands.check(arg) print(" Both mod_vcard_legacy and mod_vcard are enabled but they conflict"); print(" with each other. Remove one."); end + if all_modules:contains("pep") and all_modules:contains("pep_simple") then + print(""); + print(" Both mod_pep_simple and mod_pep are enabled but they conflict"); + print(" with each other. Remove one."); + end for host, host_config in pairs(config) do --luacheck: ignore 213/host if type(rawget(host_config, "storage")) == "string" and rawget(host_config, "default_storage") then print(""); -- cgit v1.2.3 From 87f0c198e51e0ea76090681ceb8705055ed3942b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 31 Dec 2019 02:50:25 +0100 Subject: prosodyctl: Print a blank line to improve spacing and readability --- prosodyctl | 1 + 1 file changed, 1 insertion(+) diff --git a/prosodyctl b/prosodyctl index 3242218d..982b102e 100755 --- a/prosodyctl +++ b/prosodyctl @@ -934,6 +934,7 @@ function commands.check(arg) end end if all_modules:contains("vcard") and all_modules:contains("vcard_legacy") then + print(""); print(" Both mod_vcard_legacy and mod_vcard are enabled but they conflict"); print(" with each other. Remove one."); end -- cgit v1.2.3 From e84ead8c296f6f5b4d7f11be2c3e1e4eb61ff20d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 2 Jan 2020 10:49:37 +0100 Subject: mod_websocket: Clear mask bit when reflecting ping frames (fixes #1484) --- plugins/mod_websocket.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index 686a8981..6625c676 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -236,6 +236,7 @@ function handle_request(event) return; elseif opcode == 0x9 then -- Ping frame frame.opcode = 0xA; + frame.MASK = false; -- Clients send masked frames, servers don't, see #1484 conn:write(build_frame(frame)); return ""; elseif opcode == 0xA then -- Pong frame, MAY be sent unsolicited, eg as keepalive -- cgit v1.2.3 -- cgit v1.2.3