From 996e06c451cf8f33983c9321d48b3f80f894e517 Mon Sep 17 00:00:00 2001 From: heavyrian2012 Date: Sat, 26 Nov 2022 22:21:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A6=81=E6=AD=A2=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF=E7=BE=A4=E6=93=8D=E4=BD=9C=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- broker/config/wildfirechat.conf | 4 +++ .../java/io/moquette/BrokerConstants.java | 1 + .../io/moquette/imhandler/AddGroupMember.java | 14 ++++++++ .../imhandler/CreateGroupHandler.java | 6 ++++ .../imhandler/DismissGroupHandler.java | 8 ++++- .../imhandler/KickoffGroupMember.java | 7 ++++ .../imhandler/ModifyGroupInfoHandler.java | 13 +++++++ .../moquette/imhandler/QuitGroupHandler.java | 7 ++++ .../imhandler/SetGroupManagerHandler.java | 7 ++++ .../imhandler/TransferGroupHandler.java | 7 ++++ .../persistence/MemoryMessagesStore.java | 35 +++++++++++++++++++ .../java/io/moquette/spi/IMessagesStore.java | 2 ++ .../cn/wildfirechat/proto/ProtoConstants.java | 28 +++++++++++++++ .../src/main/resources/wildfirechat.conf | 4 +++ 14 files changed, 142 insertions(+), 1 deletion(-) diff --git a/broker/config/wildfirechat.conf b/broker/config/wildfirechat.conf index 04407681..68472a79 100755 --- a/broker/config/wildfirechat.conf +++ b/broker/config/wildfirechat.conf @@ -170,6 +170,10 @@ group.allow_robot_custom_operation_notification true ## 0 不发送,1 退群时发送,2 踢人时发送,3 退群和踢人时都发送。 group.visible_quit_or_kickoff_notification 0 +## 禁止客户端群操作。第1位是禁止创建群组,第2位是禁止销毁群组,3位禁止加入群,4位禁止退出群,5位禁止邀请群成员,6位禁止移出群成员,7位禁止转移群,8位禁止设置群管理员,9位禁止白名单处理,10位禁止群禁言,11位禁止修改群组信息,12位禁止群成员禁言。 +## Server API不受此限制。 +#group.forbidden_client_operation 0xFFF + ## 隐藏用户信息属性类型,2是性别,3是电话号码,4是邮箱,5是地址,6是公司信息,7是社交账号,8是Extra信息。当需要隐藏多个时以英文逗号分开; ## 本配置是为了提高安全性,避免把对应信息同步到客户端,这样就能防止程序被破解从而拿到用户关键信息。仅对客户端有效,server api不受影响。 ## 注意,修改本配置不会对已经同步的信息产生影响。 diff --git a/broker/src/main/java/io/moquette/BrokerConstants.java b/broker/src/main/java/io/moquette/BrokerConstants.java index 0004146b..89773044 100755 --- a/broker/src/main/java/io/moquette/BrokerConstants.java +++ b/broker/src/main/java/io/moquette/BrokerConstants.java @@ -171,6 +171,7 @@ public final class BrokerConstants { public static final String GROUP_Allow_Robot_Custom_Operation_Notification = "group.allow_robot_custom_operation_notificatio"; public static final String GROUP_Visible_Quit_Kickoff_Notification = "group.visible_quit_or_kickoff_notification"; + public static final String GROUP_Forbidden_Client_Operation = "group.forbidden_client_operation"; public static final String USER_HIDE_PROPERTIES = "user.hide_properties"; public static final String USER_KEEP_DISPLAY_NAME_WHEN_DESTROY = "user.keep_display_name_when_destroy"; diff --git a/broker/src/main/java/io/moquette/imhandler/AddGroupMember.java b/broker/src/main/java/io/moquette/imhandler/AddGroupMember.java index a7144805..65042524 100644 --- a/broker/src/main/java/io/moquette/imhandler/AddGroupMember.java +++ b/broker/src/main/java/io/moquette/imhandler/AddGroupMember.java @@ -24,6 +24,20 @@ public class AddGroupMember extends GroupHandler 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } else { + if ((forbiddenClientOperation & ProtoConstants.ForbiddenClientGroupOperationMask.Forbidden_Invite_Group_Member) > 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } + } + ErrorCode errorCode = m_messagesStore.addGroupMembers(fromUser, isAdmin, request.getGroupId(), request.getAddedMemberList(), request.getExtra()); if (errorCode == ERROR_CODE_SUCCESS) { if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { diff --git a/broker/src/main/java/io/moquette/imhandler/CreateGroupHandler.java b/broker/src/main/java/io/moquette/imhandler/CreateGroupHandler.java index d9fa18f6..bd613759 100644 --- a/broker/src/main/java/io/moquette/imhandler/CreateGroupHandler.java +++ b/broker/src/main/java/io/moquette/imhandler/CreateGroupHandler.java @@ -44,6 +44,12 @@ public class CreateGroupHandler extends GroupHandler 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), request.getMemberExtra(), isAdmin); if (groupInfo != null) { if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { diff --git a/broker/src/main/java/io/moquette/imhandler/DismissGroupHandler.java b/broker/src/main/java/io/moquette/imhandler/DismissGroupHandler.java index a21cf8c8..63fa6b4d 100644 --- a/broker/src/main/java/io/moquette/imhandler/DismissGroupHandler.java +++ b/broker/src/main/java/io/moquette/imhandler/DismissGroupHandler.java @@ -26,7 +26,6 @@ public class DismissGroupHandler extends GroupHandler 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } + //send notify message first, then dismiss group if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent()); diff --git a/broker/src/main/java/io/moquette/imhandler/KickoffGroupMember.java b/broker/src/main/java/io/moquette/imhandler/KickoffGroupMember.java index 253f75c4..2e77f204 100644 --- a/broker/src/main/java/io/moquette/imhandler/KickoffGroupMember.java +++ b/broker/src/main/java/io/moquette/imhandler/KickoffGroupMember.java @@ -62,6 +62,13 @@ public class KickoffGroupMember extends GroupHandler 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } + //send notify message first, then kickoff the member if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent()); diff --git a/broker/src/main/java/io/moquette/imhandler/ModifyGroupInfoHandler.java b/broker/src/main/java/io/moquette/imhandler/ModifyGroupInfoHandler.java index 65f31dad..382dfb75 100644 --- a/broker/src/main/java/io/moquette/imhandler/ModifyGroupInfoHandler.java +++ b/broker/src/main/java/io/moquette/imhandler/ModifyGroupInfoHandler.java @@ -31,6 +31,19 @@ public class ModifyGroupInfoHandler extends GroupHandler 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } else { + if((forbiddenClientOperation & ProtoConstants.ForbiddenClientGroupOperationMask.Forbidden_Modify_Group_Info) > 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } + } + ErrorCode errorCode= m_messagesStore.modifyGroupInfo(fromUser, request.getGroupId(), request.getType(), request.getValue(), isAdmin); if (errorCode == ERROR_CODE_SUCCESS) { if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { diff --git a/broker/src/main/java/io/moquette/imhandler/QuitGroupHandler.java b/broker/src/main/java/io/moquette/imhandler/QuitGroupHandler.java index 9f99a1d4..ae7729eb 100644 --- a/broker/src/main/java/io/moquette/imhandler/QuitGroupHandler.java +++ b/broker/src/main/java/io/moquette/imhandler/QuitGroupHandler.java @@ -31,6 +31,13 @@ public class QuitGroupHandler extends GroupHandler return ErrorCode.ERROR_CODE_NOT_RIGHT; } + if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_User) { + int forbiddenClientOperation = m_messagesStore.getGroupForbiddenClientOperation(); + if((forbiddenClientOperation & ProtoConstants.ForbiddenClientGroupOperationMask.Forbidden_Quit_Group) > 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } + ErrorCode errorCode = m_messagesStore.quitGroup(fromUser, request.getGroupId(), isAdmin); if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) { if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { diff --git a/broker/src/main/java/io/moquette/imhandler/SetGroupManagerHandler.java b/broker/src/main/java/io/moquette/imhandler/SetGroupManagerHandler.java index bc655bc2..50013aba 100644 --- a/broker/src/main/java/io/moquette/imhandler/SetGroupManagerHandler.java +++ b/broker/src/main/java/io/moquette/imhandler/SetGroupManagerHandler.java @@ -30,6 +30,13 @@ public class SetGroupManagerHandler extends GroupHandler 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } + ErrorCode errorCode = m_messagesStore.setGroupManager(fromUser, request.getGroupId(), request.getType(), request.getUserIdList(), isAdmin); if (errorCode == ERROR_CODE_SUCCESS) { if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { diff --git a/broker/src/main/java/io/moquette/imhandler/TransferGroupHandler.java b/broker/src/main/java/io/moquette/imhandler/TransferGroupHandler.java index 73860c78..222150a9 100644 --- a/broker/src/main/java/io/moquette/imhandler/TransferGroupHandler.java +++ b/broker/src/main/java/io/moquette/imhandler/TransferGroupHandler.java @@ -30,6 +30,13 @@ public class TransferGroupHandler extends GroupHandler 0) { + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } + ErrorCode errorCode = m_messagesStore.transferGroup(fromUser, request.getGroupId(), request.getNewOwner(), isAdmin); if (errorCode == ERROR_CODE_SUCCESS) { if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { diff --git a/broker/src/main/java/io/moquette/persistence/MemoryMessagesStore.java b/broker/src/main/java/io/moquette/persistence/MemoryMessagesStore.java index 1922c4f7..8ca8f9b5 100755 --- a/broker/src/main/java/io/moquette/persistence/MemoryMessagesStore.java +++ b/broker/src/main/java/io/moquette/persistence/MemoryMessagesStore.java @@ -171,6 +171,7 @@ public class MemoryMessagesStore implements IMessagesStore { private boolean mGroupAllowClientCustomOperationNotification; private boolean mGroupAllowRobotCustomOperationNotification; private int mGroupVisibleQuitKickoffNotification; + private int mGroupForbiddenClientOperation; private int mSyncDataPartSize = 0; private boolean keepDisplayNameWhenDestroyUser = true; @@ -460,6 +461,35 @@ public class MemoryMessagesStore implements IMessagesStore { } + try { + String s = server.getConfig().getProperty(GROUP_Forbidden_Client_Operation, null); + if(!StringUtil.isNullOrEmptyAfterTrim(s)) { + s = s.toLowerCase(); + if(s.startsWith("0x")) { + s = s.substring(2); + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(s.length()-1-i); + mGroupForbiddenClientOperation <<= 4; + if(ch <= 9) { + mGroupForbiddenClientOperation += ch; + } else { + if(ch > 'f' || ch < 'a') { + mGroupForbiddenClientOperation = 0; + LOG.error("Invalid group.forbidden_client_operation {}", server.getConfig().getProperty(GROUP_Forbidden_Client_Operation, null)); + break; + } else { + mGroupForbiddenClientOperation += (ch - 'a' + 10); + } + } + } + } else { + mGroupForbiddenClientOperation = Integer.parseInt(s); + } + } + } catch (NumberFormatException e) { + LOG.error("Invalid group.forbidden_client_operation {}", server.getConfig().getProperty(GROUP_Forbidden_Client_Operation, null)); + } + try { mSyncDataPartSize = Integer.parseInt(server.getConfig().getProperty(SYNC_Data_Part_Size, "0")); } catch (Exception e) { @@ -4214,6 +4244,11 @@ public class MemoryMessagesStore implements IMessagesStore { return mGroupVisibleQuitKickoffNotification; } + @Override + public int getGroupForbiddenClientOperation() { + return mGroupForbiddenClientOperation; + } + @Override public boolean isForwardMessageWithClientInfo() { return mForwardMessageWithClientInfo; diff --git a/broker/src/main/java/io/moquette/spi/IMessagesStore.java b/broker/src/main/java/io/moquette/spi/IMessagesStore.java index 7b3b6f6f..cb07719e 100755 --- a/broker/src/main/java/io/moquette/spi/IMessagesStore.java +++ b/broker/src/main/java/io/moquette/spi/IMessagesStore.java @@ -233,6 +233,8 @@ public interface IMessagesStore { boolean isAllowRobotCustomGroupNotification(); int getVisibleQuitKickoffNotification(); + int getGroupForbiddenClientOperation(); + boolean isForwardMessageWithClientInfo(); boolean isRobotCallbackWithClientInfo(); boolean isChannelCallbackWithClientInfo(); diff --git a/common/src/main/java/cn/wildfirechat/proto/ProtoConstants.java b/common/src/main/java/cn/wildfirechat/proto/ProtoConstants.java index a3ad10c2..746eaaed 100644 --- a/common/src/main/java/cn/wildfirechat/proto/ProtoConstants.java +++ b/common/src/main/java/cn/wildfirechat/proto/ProtoConstants.java @@ -292,6 +292,34 @@ public class ProtoConstants { int ApplicationType_Admin = 2; } + //禁止客户端群操作。 + // 第1位是禁止创建群组, + // 第2位是禁止销毁群组, + // 3位禁止加入群, + // 4位禁止退出群, + // 5位禁止邀请群成员, + // 6位禁止移出群成员, + // 7位禁止转移群 + // 8位禁止设置群管理员 + // 9位禁止允许群成员(专业版支持), + // 10位禁止群禁言 + // 11位禁止修改群组信息, + // 12位禁止群成员禁言(专业版支持) + public interface ForbiddenClientGroupOperationMask { + int Forbidden_Create_Group = 0x01; + int Forbidden_Dismiss_Group = 0x02; + int Forbidden_Join_Group = 0x04; + int Forbidden_Quit_Group = 0x08; + int Forbidden_Invite_Group_Member = 0x10; + int Forbidden_Kickoff_Group_Member = 0x20; + int Forbidden_Transfer_Group = 0x40; + int Forbidden_Set_Group_Manage = 0x80; + int Forbidden_Allow_Group_Member = 0x100; + int Forbidden_Mute_Group = 0x200; + int Forbidden_Modify_Group_Info = 0x400; + int Forbidden_Mute_Group_Member = 0x800; + } + public static final int MESSAGE_CONTENT_TYPE_CREATE_GROUP = 104; public static final int MESSAGE_CONTENT_TYPE_ADD_GROUP_MEMBER = 105; public static final int MESSAGE_CONTENT_TYPE_KICKOF_GROUP_MEMBER = 106; diff --git a/distribution/src/main/resources/wildfirechat.conf b/distribution/src/main/resources/wildfirechat.conf index 7c017d2b..de278628 100755 --- a/distribution/src/main/resources/wildfirechat.conf +++ b/distribution/src/main/resources/wildfirechat.conf @@ -169,6 +169,10 @@ group.allow_robot_custom_operation_notification true ## 如果应用需要退群或者踢人不通知普通成员,请设置此参数为3,然后修改客户端踢人或退群消息的flag为not_presist。 group.visible_quit_or_kickoff_notification 0 +## 禁止客户端群操作。第1位是禁止创建群组,第2位是禁止销毁群组,3位禁止加入群,4位禁止退出群,5位禁止邀请群成员,6位禁止移出群成员,7位禁止转移群,8位禁止设置群管理员,9位禁止白名单处理,10位禁止群禁言,11位禁止修改群组信息,12位禁止群成员禁言。 +## 如果有客户端有被破解的风险,可以禁止客户端群操作,然后通过Server API操作。Server API不受限制。 +#group.forbidden_client_operation 0xFFF + ## 隐藏用户信息属性类型,2是性别,3是电话号码,4是邮箱,5是地址,6是公司信息,7是社交账号,8是Extra信息。当需要隐藏多个时以英文逗号分开; ## 本配置是为了提高安全性,避免把对应信息同步到客户端,这样就能防止程序被破解从而拿到用户关键信息。仅对客户端有效,server api不受影响。 ## 注意,修改本配置不会对已经同步的信息产生影响。