From 7d3ed5d61af8d7f207ac8e920dbeecedd5760cbf Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Sat, 16 Jan 2021 20:54:19 +0100 Subject: [PATCH 1/2] OF-2189: Do not store offline if on blocklist. Messages that arrive for offline users should not be stored in their offline message store, if the message would have been blocked if the intended recipient would have been online. --- .../org/jivesoftware/openfire/OfflineMessageStore.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/OfflineMessageStore.java b/xmppserver/src/main/java/org/jivesoftware/openfire/OfflineMessageStore.java index 6d676d0ab0..0166b03c7b 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/OfflineMessageStore.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/OfflineMessageStore.java @@ -25,6 +25,8 @@ import org.jivesoftware.openfire.container.BasicModule; import org.jivesoftware.openfire.event.UserEventDispatcher; import org.jivesoftware.openfire.event.UserEventListener; +import org.jivesoftware.openfire.privacy.PrivacyList; +import org.jivesoftware.openfire.privacy.PrivacyListManager; import org.jivesoftware.openfire.user.User; import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.util.*; @@ -173,6 +175,14 @@ public OfflineMessage addMessage(Message message) { return null; } + // If the sender of the message is on the user's default privacy list, don't store (OF-2189). Note that we're + // processing messages sent to an offline user, so an active privacy list does not apply. + final PrivacyList defaultPrivacyList = PrivacyListManager.getInstance().getDefaultPrivacyList(username); + if (defaultPrivacyList.shouldBlockPacket(message)) { + Log.trace( "Not storing message, as it is rejected by the default privacy list of the recipient ({}).", recipient ); + return false; + } + long messageID = SequenceManager.nextID(JiveConstants.OFFLINE); // Get the message in XML format. From 37d8e4a13c813d8424470986a10722486b5a8a54 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Sat, 16 Jan 2021 22:16:00 +0100 Subject: [PATCH 2/2] OF-2189: Apply privacy lists to CC'ed stanzas. This prevents stanzas to bypass a privacy list or blocklist, when they're included in a carbon copy. --- .../openfire/carbons/Received.java | 27 +++++++++++++++++-- .../openfire/session/LocalClientSession.java | 16 +++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/carbons/Received.java b/xmppserver/src/main/java/org/jivesoftware/openfire/carbons/Received.java index 0f2279ebe5..c42c0da153 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/carbons/Received.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/carbons/Received.java @@ -1,7 +1,10 @@ package org.jivesoftware.openfire.carbons; +import org.dom4j.Element; import org.jivesoftware.openfire.forward.Forwarded; -import org.xmpp.packet.PacketExtension; +import org.xmpp.packet.*; + +import javax.annotation.Nonnull; /** * The implementation of the {@code } extension. @@ -14,8 +17,28 @@ public final class Received extends PacketExtension { public static final String NAME = "received"; public static final String NAMESPACE = "urn:xmpp:carbons:2"; - public Received(Forwarded forwarded) { + public Received(@Nonnull final Forwarded forwarded) { super(NAME, NAMESPACE); element.add(forwarded.getElement()); } + + public Packet getForwardedStanza() { + if (element.element("forwarded") == null) { + return null; + } + if (element.element("forwarded").elements() == null) { + return null; + } + final Element originalStanza = element.element("forwarded").elements().get(0); + switch (originalStanza.getName()) { + case "message": + return new Message(originalStanza, true); + case "iq": + return new IQ(originalStanza, true); + case "presence": + return new Presence(originalStanza, true); + default: + throw new IllegalArgumentException("A 'forwarded' stanza must by of type 'message', 'iq' or 'presence', not: " + originalStanza.getName()); + } + } } diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/session/LocalClientSession.java b/xmppserver/src/main/java/org/jivesoftware/openfire/session/LocalClientSession.java index 8f80ede5f1..f7722198f3 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/session/LocalClientSession.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/session/LocalClientSession.java @@ -23,6 +23,7 @@ import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.auth.AuthToken; import org.jivesoftware.openfire.auth.UnauthorizedException; +import org.jivesoftware.openfire.carbons.Received; import org.jivesoftware.openfire.cluster.ClusterManager; import org.jivesoftware.openfire.entitycaps.EntityCapabilitiesManager; import org.jivesoftware.openfire.net.SASLAuthentication; @@ -873,6 +874,21 @@ public void setHasRequestedBlocklist(boolean hasRequestedBlocklist) { @Override public boolean canProcess(Packet packet) { + // If the packet is a forwarded stanza (eg: carbon copy), ensure that the forwarded message would have + // passed the privacy lists that are active for _this_ session. Note that the active list could differ + // for each session of a particular user! (OF-2189) + // Implementation note: it might be tempting to implement this in org.jivesoftware.openfire.spi.RoutingTableImpl.ccMessage + // There is, however, no way to check the active privacy list for sessions on remote cluster nodes there. + final Received received = (Received) packet.getExtension(Received.NAME, Received.NAMESPACE); + if (received != null) { + final Packet forwardedStanza = received.getForwardedStanza(); + if (forwardedStanza != null) { + if (!canProcess(forwardedStanza)) { + return false; + } + } + } + PrivacyList list = getActiveList(); if (list != null) { // If a privacy list is active then make sure that the packet is not blocked