From 5af7532504e4aaaba58fef181a546d847b85ce3a Mon Sep 17 00:00:00 2001 From: Jing Sun Date: Thu, 21 Jan 2021 16:58:05 +0100 Subject: [PATCH] mod_muc/mod_muc_room: add option limits for password and captcha_whitelist (#2255) --- src/mod_muc.erl | 18 ++++++++++++++++++ src/mod_muc_opt.erl | 14 ++++++++++++++ src/mod_muc_room.erl | 19 ++++++++++++++----- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 28a0f505d..aeb85b95d 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -1164,6 +1164,10 @@ mod_opt_type(regexp_room_id) -> econf:re([unicode]); mod_opt_type(max_room_name) -> econf:pos_int(infinity); +mod_opt_type(max_password) -> + econf:pos_int(infinity); +mod_opt_type(max_captcha_whitelist) -> + econf:pos_int(infinity); mod_opt_type(max_user_conferences) -> econf:pos_int(); mod_opt_type(max_users) -> @@ -1244,6 +1248,8 @@ mod_options(Host) -> {max_room_desc, infinity}, {max_room_id, infinity}, {max_room_name, infinity}, + {max_password, infinity}, + {max_captcha_whitelist, infinity}, {max_rooms_discoitems, 100}, {max_user_conferences, 100}, {max_users, 200}, @@ -1405,6 +1411,18 @@ mod_doc() -> ?T("This option defines the maximum number of characters " "that Room Name can have when configuring the room. " "The default value is 'infinity'.")}}, + {max_password, + #{value => ?T("Number"), + desc => + ?T("This option defines the maximum number of characters " + "that Password can have when configuring the room. " + "The default value is 'infinity'.")}}, + {max_captcha_whitelist, + #{value => ?T("Number"), + desc => + ?T("This option defines the maximum number of characters " + "that Captcha Whitelist can have when configuring the room. " + "The default value is 'infinity'.")}}, {max_rooms_discoitems, #{value => ?T("Number"), desc => diff --git a/src/mod_muc_opt.erl b/src/mod_muc_opt.erl index 25bd4dc5f..e0988137e 100644 --- a/src/mod_muc_opt.erl +++ b/src/mod_muc_opt.erl @@ -18,6 +18,8 @@ -export([max_room_desc/1]). -export([max_room_id/1]). -export([max_room_name/1]). +-export([max_password/1]). +-export([max_captcha_whitelist/1]). -export([max_rooms_discoitems/1]). -export([max_user_conferences/1]). -export([max_users/1]). @@ -125,6 +127,18 @@ max_room_name(Opts) when is_map(Opts) -> max_room_name(Host) -> gen_mod:get_module_opt(Host, mod_muc, max_room_name). +-spec max_password(gen_mod:opts() | global | binary()) -> 'infinity' | pos_integer(). +max_password(Opts) when is_map(Opts) -> + gen_mod:get_opt(max_password, Opts); +max_password(Host) -> + gen_mod:get_module_opt(Host, mod_muc, max_password). + +-spec max_captcha_whitelist(gen_mod:opts() | global | binary()) -> 'infinity' | pos_integer(). +max_captcha_whitelist(Opts) when is_map(Opts) -> + gen_mod:get_opt(max_captcha_whitelist, Opts); +max_captcha_whitelist(Host) -> + gen_mod:get_module_opt(Host, mod_muc, max_captcha_whitelist). + -spec max_rooms_discoitems(gen_mod:opts() | global | binary()) -> non_neg_integer(). max_rooms_discoitems(Opts) when is_map(Opts) -> gen_mod:get_opt(max_rooms_discoitems, Opts); diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 036a0ce1e..fb06ef9fc 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -3369,7 +3369,7 @@ process_iq_owner(From, #iq{type = set, lang = Lang, case is_allowed_log_change(Options, StateData, From) andalso is_allowed_persistent_change(Options, StateData, From) andalso is_allowed_mam_change(Options, StateData, From) andalso - is_allowed_room_name_desc_limits(Options, StateData) andalso + is_allowed_string_limits(Options, StateData) andalso is_password_settings_correct(Options, StateData) of true -> set_config(Options, StateData, Lang); @@ -3453,16 +3453,25 @@ is_allowed_mam_change(Options, StateData, From) -> AccessMam, From) end. -%% Check if the Room Name and Room Description defined in the Data Form +%% Check if the string fields defined in the Data Form %% are conformant to the configured limits --spec is_allowed_room_name_desc_limits(muc_roomconfig:result(), state()) -> boolean(). -is_allowed_room_name_desc_limits(Options, StateData) -> +-spec is_allowed_string_limits(muc_roomconfig:result(), state()) -> boolean(). +is_allowed_string_limits(Options, StateData) -> RoomName = proplists:get_value(roomname, Options, <<"">>), RoomDesc = proplists:get_value(roomdesc, Options, <<"">>), + Password = proplists:get_value(roomsecret, Options, <<"">>), + CaptchaWhitelist = proplists:get_value(captcha_whitelist, Options, []), + CaptchaWhitelistSize = lists:foldl( + fun(Jid, Sum) -> byte_size(jid:encode(Jid)) + Sum end, + 0, CaptchaWhitelist), MaxRoomName = mod_muc_opt:max_room_name(StateData#state.server_host), MaxRoomDesc = mod_muc_opt:max_room_desc(StateData#state.server_host), + MaxPassword = mod_muc_opt:max_password(StateData#state.server_host), + MaxCaptchaWhitelist = mod_muc_opt:max_captcha_whitelist(StateData#state.server_host), (byte_size(RoomName) =< MaxRoomName) - andalso (byte_size(RoomDesc) =< MaxRoomDesc). + andalso (byte_size(RoomDesc) =< MaxRoomDesc) + andalso (byte_size(Password) =< MaxPassword) + andalso (CaptchaWhitelistSize =< MaxCaptchaWhitelist). %% Return false if: %% "the password for a password-protected room is blank"