From 0e55cbbda6764c152aa42874824ee2748eacb863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BC=D1=8F=D0=BD=20=D0=9C=D0=B8=D0=BD=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Mon, 6 Nov 2023 15:31:59 -0600 Subject: [PATCH] Clean up prosody modules with some extra checks (#14020) * fix: Adds check for jitsi_meet_room not being string. Oct 20 12:22:50 mod_bosh error Traceback[bosh]: /usr/share/jitsi-meet/prosody-plugins/token/util.lib.lua:336: bad argument #1 to 'lower' (string expected, got userdata) stack traceback: [C]: in function 'lower' /usr/share/jitsi-meet/prosody-plugins/token/util.lib.lua:336: in function 'verify_room' ...re/jitsi-meet/prosody-plugins/mod_token_verification.lua:78: in function 'verify_user' * fix: Adds check for missing speaker stats for occupant. error Traceback[c2s]: ...itsi-meet/prosody-plugins/mod_speakerstats_component.lua:124: attempt to index field '?' (a nil value) stack traceback: ...itsi-meet/prosody-plugins/mod_speakerstats_component.lua:124: in function '?' * fix: Nil check for breakout_rooms. c2saaaad95a16c0 error Traceback[c2s]: ...re/jitsi-meet/prosody-plugins/mod_muc_breakout_rooms.lua:345: attempt to index local 'main_room' (a nil value) stack traceback: ...re/jitsi-meet/prosody-plugins/mod_muc_breakout_rooms.lua:345: in function '?' /usr/share/lua/5.2/prosody/util/events.lua:81: in function (...tail calls...) /usr/lib/prosody/modules/muc/muc.lib.lua:496: in function * fix: Adds nil check in allowners. c2saaaae3024810 error Traceback[c2s]: /usr/share/jitsi-meet/prosody-plugins/mod_muc_allowners.lua:171: attempt to index local 'room' (a nil value) stack traceback: /usr/share/jitsi-meet/prosody-plugins/mod_muc_allowners.lua:171: in function '?' /usr/share/lua/5.2/prosody/util/events.lua:81: in function * fix: Adds nil check in lobby. mod_bosh error Traceback[bosh]: ...share/jitsi-meet/prosody-plugins/mod_muc_lobby_rooms.lua:168: attempt to index local 'lobby_room' (a nil value) stack traceback: ...share/jitsi-meet/prosody-plugins/mod_muc_lobby_rooms.lua:168: in function '?' /usr/share/lua/5.2/prosody/util/filters.lua:25: in function 'filter' /usr/lib/prosody/modules/mod_bosh.lua:361: in function 'send' /usr/lib/prosody/modules/muc/mod_muc.lua:495: in function '?' * fix: Fixes nil error in fmuc. s2sinaaaaf2817260 error Traceback[s2s]: /usr/share/jitsi-meet/prosody-plugins/mod_fmuc.lua:295: attempt to index local 'occupant' (a nil value) stack traceback: /usr/share/jitsi-meet/prosody-plugins/mod_fmuc.lua:295: in function '?' /usr/share/lua/5.2/prosody/util/events.lua:81: in function (...tail calls...) /usr/lib/prosody/modules/muc/muc.lib.lua:1201: in function * fix: Fixes nil occupant. c2s55f4d5411dd0 error Traceback[c2s]: /usr/share/jitsi-meet/prosody-plugins/mod_muc_flip.lua:120: attempt to index local 'kicked_occupant' (a nil value) stack traceback: /usr/share/jitsi-meet/prosody-plugins/mod_muc_flip.lua:120: in function '?' /usr/share/lua/5.2/prosody/util/events.lua:81: in function (...tail calls...) /usr/lib/prosody/modules/muc/muc.lib.lua:791: in function * fix: Fixes caching main room. Objects should not be set in room._data as this field is being serialized and we see errors like. error Traceback[c2s]: /usr/share/lua/5.2/prosody/util/serialization.lua:34: Can't serialize userdata stack traceback: [C]: in function 'error' /usr/share/lua/5.2/prosody/util/serialization.lua:34: in function (...tail calls...) /usr/share/lua/5.2/prosody/util/serialization.lua:199: in function 'serialize_table' /usr/share/lua/5.2/prosody/util/serialization.lua:197: in function 'serialize_table' /usr/share/lua/5.2/prosody/util/serialization.lua:197: in function 'serialize_table' /usr/share/lua/5.2/prosody/util/serialization.lua:219: in function (...tail calls...) /usr/lib/prosody/modules/mod_storage_memory.lua:42: in function (...tail calls...) ...re/jitsi-meet/prosody-plugins/mod_muc_breakout_rooms.lua:207: in function 'create_breakout_room' * fix: Fixes calling save_occupant after changing its role. * squash: Fixed passed value to type. --- resources/prosody-plugins/mod_fmuc.lua | 4 +++- resources/prosody-plugins/mod_muc_allowners.lua | 2 +- .../prosody-plugins/mod_muc_breakout_rooms.lua | 5 ++--- resources/prosody-plugins/mod_muc_flip.lua | 13 ++++++++++--- resources/prosody-plugins/mod_muc_lobby_rooms.lua | 8 +++++++- .../prosody-plugins/mod_speakerstats_component.lua | 9 +++++---- resources/prosody-plugins/token/util.lib.lua | 7 ++++++- 7 files changed, 34 insertions(+), 14 deletions(-) diff --git a/resources/prosody-plugins/mod_fmuc.lua b/resources/prosody-plugins/mod_fmuc.lua index 4e210bef46dd..1aceb58480ca 100644 --- a/resources/prosody-plugins/mod_fmuc.lua +++ b/resources/prosody-plugins/mod_fmuc.lua @@ -292,10 +292,12 @@ end); module:hook('muc-occupant-groupchat', function(event) local occupant, room, stanza = event.occupant, event.room, event.stanza; local from = stanza.attr.from; - local occupant_host = jid.host(occupant.bare_jid); + local occupant_host; -- if there is no occupant this is a message from main, probably coming from other vnode if occupant then + occupant_host = jid.host(occupant.bare_jid); + -- we manage nick only for visitors if occupant_host ~= main_domain then -- add to message stanza display name for the visitor diff --git a/resources/prosody-plugins/mod_muc_allowners.lua b/resources/prosody-plugins/mod_muc_allowners.lua index cde35d0452ff..b8df9ff832d4 100644 --- a/resources/prosody-plugins/mod_muc_allowners.lua +++ b/resources/prosody-plugins/mod_muc_allowners.lua @@ -136,7 +136,7 @@ function filter_admin_set_query(event) local _aff = item.attr.affiliation; -- if it is a moderated room we skip it - if is_moderated(room.jid) then + if room and is_moderated(room.jid) then return nil; end diff --git a/resources/prosody-plugins/mod_muc_breakout_rooms.lua b/resources/prosody-plugins/mod_muc_breakout_rooms.lua index a407b3b94d16..b3557c66d618 100644 --- a/resources/prosody-plugins/mod_muc_breakout_rooms.lua +++ b/resources/prosody-plugins/mod_muc_breakout_rooms.lua @@ -342,12 +342,11 @@ end function on_breakout_room_pre_create(event) local breakout_room = event.room; local main_room, main_room_jid = get_main_room(breakout_room.jid); - local name = main_room._data.breakout_rooms[breakout_room.jid]; -- Only allow existent breakout rooms to be started. -- Authorisation of breakout rooms is done by their random uuid name - if main_room and main_room._data.breakout_rooms and name then - breakout_room:set_subject(breakout_room.jid, name); + if main_room and main_room._data.breakout_rooms and main_room._data.breakout_rooms[breakout_room.jid] then + breakout_room:set_subject(breakout_room.jid, main_room._data.breakout_rooms[breakout_room.jid]); else module:log('debug', 'Invalid breakout room %s will not be created.', breakout_room.jid); breakout_room:destroy(main_room_jid, 'Breakout room is invalid.'); diff --git a/resources/prosody-plugins/mod_muc_flip.lua b/resources/prosody-plugins/mod_muc_flip.lua index 34ab2fa9780e..85b726b1cd0b 100644 --- a/resources/prosody-plugins/mod_muc_flip.lua +++ b/resources/prosody-plugins/mod_muc_flip.lua @@ -62,7 +62,7 @@ module:hook("muc-occupant-pre-join", function(event) module:log("debug", "Bypass lobby invitee %s", occupant_jid) occupant.role = "participant"; room:set_affiliation(true, jid_bare(occupant_jid), "member") - room:save(); + room:save_occupant(occupant); end -- bypass password on the flip device local join = stanza:get_child("x", MUC_NS); @@ -111,12 +111,19 @@ end) module:hook("muc-occupant-joined", function(event) local room, occupant = event.room, event.occupant; if is_healthcheck_room(room.jid) or is_admin(occupant.bare_jid) then - return ; + return; end if room._data.flip_participant_nick and occupant.nick == room._data.flip_participant_nick then -- make joining participant from flip device have the same role and affiliation as for the previous device local kicked_occupant = room:get_occupant_by_nick(room._data.kicked_participant_nick); + + if not kicked_occupant then + module:log("info", "Kick participant not found, nick %s from main room jid %s", + room._data.kicked_participant_nick, room.jid) + return; + end + local initial_affiliation = room:get_affiliation(kicked_occupant.jid) or "member"; module:log("debug", "Transfer affiliation %s to occupant jid %s", initial_affiliation, occupant.jid) room:set_affiliation(true, occupant.bare_jid, initial_affiliation) @@ -129,7 +136,7 @@ module:hook("muc-occupant-joined", function(event) local kicked_participant_node_jid = jid.split(kicked_occupant.jid); module:log("info", "Kick participant jid %s nick %s from main room jid %s", kicked_occupant.jid, room._data.kicked_participant_nick, room.jid) room:set_role(true, room._data.kicked_participant_nick, 'none') - room:save() + room:save_occupant(occupant); -- Kick participant from the first device from the lobby room if room._data.lobbyroom then local lobby_room_jid = room._data.lobbyroom; diff --git a/resources/prosody-plugins/mod_muc_lobby_rooms.lua b/resources/prosody-plugins/mod_muc_lobby_rooms.lua index dc7e2dd3c905..d064410ee7d8 100644 --- a/resources/prosody-plugins/mod_muc_lobby_rooms.lua +++ b/resources/prosody-plugins/mod_muc_lobby_rooms.lua @@ -165,6 +165,12 @@ function filter_stanza(stanza) -- allow messages to or from moderator local lobby_room_jid = jid_bare(stanza.attr.from); local lobby_room = lobby_muc_service.get_room_from_jid(lobby_room_jid); + + if not lobby_room then + module:log('warn', 'No lobby room found %s', stanza.attr.from); + return nil; + end + local is_to_moderator = lobby_room:get_affiliation(stanza.attr.to) == 'owner'; local from_occupant = lobby_room:get_occupant_by_nick(stanza.attr.from); @@ -396,7 +402,7 @@ process_host_module(main_muc_component_config, function(host_module, host) if not affiliation or affiliation == 'none' or affiliation == 'member' then occupant.role = 'participant'; room:set_affiliation(true, invitee_bare_jid, 'member'); - room:save(); + room:save_occupant(occupant); return; end diff --git a/resources/prosody-plugins/mod_speakerstats_component.lua b/resources/prosody-plugins/mod_speakerstats_component.lua index 04598b82acfb..54029147f35a 100644 --- a/resources/prosody-plugins/mod_speakerstats_component.lua +++ b/resources/prosody-plugins/mod_speakerstats_component.lua @@ -35,15 +35,16 @@ end -- Searches all rooms in the main muc component that holds a breakout room -- caches it if found so we don't search it again +-- we should not cache objects in _data as this is being serialized when calling room:save() local function get_main_room(breakout_room) - if breakout_room._data and breakout_room._data.main_room then - return breakout_room._data.main_room; + if breakout_room.main_room then + return breakout_room.main_room; end -- let's search all rooms to find the main room for room in main_muc_service.each_room() do if room._data and room._data.breakout_rooms_active and room._data.breakout_rooms[breakout_room.jid] then - breakout_room._data.main_room = room; + breakout_room.main_room = room; return room; end end @@ -117,7 +118,7 @@ function on_message(event) local from = event.stanza.attr.from; local occupant = room:get_occupant_by_real_jid(from); - if not occupant then + if not occupant or not room.speakerStats[occupant.jid] then module:log("warn", "No occupant %s found for %s", from, roomAddress); return false; end diff --git a/resources/prosody-plugins/token/util.lib.lua b/resources/prosody-plugins/token/util.lib.lua index ab413c85cf8e..78b2d2e7c9ae 100644 --- a/resources/prosody-plugins/token/util.lib.lua +++ b/resources/prosody-plugins/token/util.lib.lua @@ -17,6 +17,7 @@ local starts_with = main_util.starts_with; local cjson_safe = require 'cjson.safe' local timer = require "util.timer"; local async = require "util.async"; +local inspect = require 'inspect'; local nr_retries = 3; local ssl = require "ssl"; @@ -344,7 +345,11 @@ function Util:verify_room(session, room_address) local auth_room = session.jitsi_meet_room; if auth_room then - auth_room = string.lower(auth_room); + if type(auth_room) == 'string' then + auth_room = string.lower(auth_room); + else + module:log('warn', 'session.jitsi_meet_room not string: %s', inspect(auth_room)); + end end if not self.enableDomainVerification then -- if auth_room is missing, this means user is anonymous (no token for