From: AsamK Date: Sun, 22 Aug 2021 08:17:47 +0000 (+0200) Subject: Discard messages from non-admins in announcement groups X-Git-Tag: v0.9.0~59 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/73e137137d272811b01ed053f57e0161e476d90a?ds=sidebyside Discard messages from non-admins in announcement groups --- diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index e4342f9a..9d0c355b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -1874,7 +1874,6 @@ public class Manager implements Closeable { // address/uuid in envelope is sent by server resolveRecipientTrusted(envelope.getSourceAddress()); } - final var notAGroupMember = isNotAGroupMember(envelope, content); if (!envelope.isReceipt()) { try { content = decryptMessage(envelope); @@ -1910,10 +1909,13 @@ public class Manager implements Closeable { queuedActions.addAll(actions); } } + final var notAllowedToSendToGroup = isNotAllowedToSendToGroup(envelope, content); if (isMessageBlocked(envelope, content)) { logger.info("Ignoring a message from blocked user/group: {}", envelope.getTimestamp()); - } else if (notAGroupMember) { - logger.info("Ignoring a message from a non group member: {}", envelope.getTimestamp()); + } else if (notAllowedToSendToGroup) { + logger.info("Ignoring a group message from an unauthorized sender (no member or admin): {} {}", + (envelope.hasSource() ? envelope.getSourceAddress() : content.getSender()).getIdentifier(), + envelope.getTimestamp()); } else { handler.handleMessage(envelope, content, exception); } @@ -1976,7 +1978,7 @@ public class Manager implements Closeable { return sourceContact != null && sourceContact.isBlocked(); } - private boolean isNotAGroupMember( + private boolean isNotAllowedToSendToGroup( SignalServiceEnvelope envelope, SignalServiceContent content ) { SignalServiceAddress source; @@ -1988,23 +1990,32 @@ public class Manager implements Closeable { return false; } - if (content != null && content.getDataMessage().isPresent()) { - var message = content.getDataMessage().get(); - if (message.getGroupContext().isPresent()) { - if (message.getGroupContext().get().getGroupV1().isPresent()) { - var groupInfo = message.getGroupContext().get().getGroupV1().get(); - if (groupInfo.getType() == SignalServiceGroup.Type.QUIT) { - return false; - } - } - var groupId = GroupUtils.getGroupId(message.getGroupContext().get()); - var group = getGroup(groupId); - if (group != null && !group.isMember(resolveRecipient(source))) { - return true; - } + if (content == null || !content.getDataMessage().isPresent()) { + return false; + } + + var message = content.getDataMessage().get(); + if (!message.getGroupContext().isPresent()) { + return false; + } + + if (message.getGroupContext().get().getGroupV1().isPresent()) { + var groupInfo = message.getGroupContext().get().getGroupV1().get(); + if (groupInfo.getType() == SignalServiceGroup.Type.QUIT) { + return false; } } - return false; + + var groupId = GroupUtils.getGroupId(message.getGroupContext().get()); + var group = getGroup(groupId); + if (group == null) { + return false; + } + + final var recipientId = resolveRecipient(source); + return !group.isMember(recipientId) || ( + group.isAnnouncementGroup() && !group.isAdmin(recipientId) + ); } private List handleMessage( diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java index 211e0f96..60efc84b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java @@ -40,6 +40,8 @@ public abstract class GroupInfo { public abstract int getMessageExpirationTime(); + public abstract boolean isAnnouncementGroup(); + public Set getMembersWithout(RecipientId recipientId) { return getMembers().stream().filter(member -> !member.equals(recipientId)).collect(Collectors.toSet()); } @@ -54,6 +56,10 @@ public abstract class GroupInfo { return getMembers().contains(recipientId); } + public boolean isAdmin(RecipientId recipientId) { + return getAdminMembers().contains(recipientId); + } + public boolean isPendingMember(RecipientId recipientId) { return getPendingMembers().contains(recipientId); } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV1.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV1.java index 8cf6cb94..49c9a504 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV1.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV1.java @@ -89,6 +89,11 @@ public class GroupInfoV1 extends GroupInfo { return messageExpirationTime; } + @Override + public boolean isAnnouncementGroup() { + return false; + } + public void addMembers(Collection members) { this.members.addAll(members); } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java index fe82862e..59cfedb5 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java @@ -7,6 +7,7 @@ import org.asamk.signal.manager.storage.recipients.RecipientResolver; import org.signal.storageservice.protos.groups.AccessControl; import org.signal.storageservice.protos.groups.Member; import org.signal.storageservice.protos.groups.local.DecryptedGroup; +import org.signal.storageservice.protos.groups.local.EnabledState; import org.signal.zkgroup.groups.GroupMasterKey; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; @@ -146,4 +147,9 @@ public class GroupInfoV2 extends GroupInfo { ? this.group.getDisappearingMessagesTimer().getDuration() : 0; } + + @Override + public boolean isAnnouncementGroup() { + return this.group != null && this.group.getIsAnnouncementGroup() == EnabledState.ENABLED; + } }