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. 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