From 6c7296a37bae345af5e947c69ad48e3fdc451cd6 Mon Sep 17 00:00:00 2001 From: Lars Noschinski Date: Sun, 23 Feb 2014 21:08:35 +0100 Subject: [PATCH] Add and use IQReplyFilter (SMACK-533) In the absence of checks on the from address, it is possible for other clients to fake an answer to an IQ request. This commit adds an IQReplyFilter, which drops all packets which are not a valid reply to an IQ request. In particular, it checks for packet id, from address and packet type. Most(?) places waiting for a reply to an IQ request are converted to use the IQReplyFilter. For a discussion of the issues, see the thread "Spoofing of iq ids and misbehaving servers" from 2014-01 on the jdev@jabber.org mailing list and following discussion in February and March. --- .../jivesoftware/smack/AccountManager.java | 18 +- .../org/jivesoftware/smack/Connection.java | 17 +- .../java/org/jivesoftware/smack/Roster.java | 22 +- .../org/jivesoftware/smack/RosterGroup.java | 17 +- .../smack/filter/FromMatchesFilter.java | 70 +++- .../smack/filter/IQReplyFilter.java | 114 ++++++ .../smack/filters/FromMatchesFilterTest.java | 352 +++++++++++++++--- .../smackx/carbons/CarbonManager.java | 4 +- .../filetransfer/FileTransferNegotiator.java | 5 +- .../jivesoftware/util/ConnectionUtils.java | 3 +- .../smackx/jingle/nat/RTPBridge.java | 18 +- .../jivesoftware/smackx/jingle/nat/STUN.java | 8 +- .../smackx/workgroup/agent/AgentSession.java | 6 +- 13 files changed, 520 insertions(+), 134 deletions(-) create mode 100644 core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java diff --git a/core/src/main/java/org/jivesoftware/smack/AccountManager.java b/core/src/main/java/org/jivesoftware/smack/AccountManager.java index 4509a7203..a54c5c98f 100644 --- a/core/src/main/java/org/jivesoftware/smack/AccountManager.java +++ b/core/src/main/java/org/jivesoftware/smack/AccountManager.java @@ -17,14 +17,6 @@ package org.jivesoftware.smack; -import org.jivesoftware.smack.filter.AndFilter; -import org.jivesoftware.smack.filter.PacketFilter; -import org.jivesoftware.smack.filter.PacketIDFilter; -import org.jivesoftware.smack.filter.PacketTypeFilter; -import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.packet.Registration; -import org.jivesoftware.smack.util.StringUtils; - import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -32,6 +24,10 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.Registration; +import org.jivesoftware.smack.util.StringUtils; + /** * Allows creation and management of accounts on an XMPP server. * @@ -246,11 +242,7 @@ public class AccountManager { map.put("username",StringUtils.parseName(connection.getUser())); map.put("password",newPassword); reg.setAttributes(map); - PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), - new PacketTypeFilter(IQ.class)); - PacketCollector collector = connection.createPacketCollector(filter); - connection.sendPacket(reg); - collector.nextResultOrThrow(); + connection.createPacketCollectorAndSend(reg).nextResultOrThrow(); } /** diff --git a/core/src/main/java/org/jivesoftware/smack/Connection.java b/core/src/main/java/org/jivesoftware/smack/Connection.java index 944729984..b75489ec7 100644 --- a/core/src/main/java/org/jivesoftware/smack/Connection.java +++ b/core/src/main/java/org/jivesoftware/smack/Connection.java @@ -37,11 +37,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; -import org.jivesoftware.smack.compression.XMPPInputOutputStream; import org.jivesoftware.smack.compression.Java7ZlibInputOutputStream; +import org.jivesoftware.smack.compression.XMPPInputOutputStream; import org.jivesoftware.smack.debugger.SmackDebugger; +import org.jivesoftware.smack.filter.IQReplyFilter; import org.jivesoftware.smack.filter.PacketFilter; -import org.jivesoftware.smack.filter.PacketIDFilter; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Presence; @@ -577,15 +578,15 @@ public abstract class Connection { /** * Creates a new packet collector collecting packets that are replies to packet. - * Does also send packet. Note that the packet filter is at the moment created as - * ID filter of packet's ID. This may change in the future to also check the - * correct "from JID" value. - * + * Does also send packet. The packet filter for the collector is an + * {@link IQReplyFilter}, guaranteeing that packet id and JID in the 'from' address have + * expected values. + * * @param packet the packet to filter responses from * @return a new packet collector. */ - public PacketCollector createPacketCollectorAndSend(Packet packet) { - PacketFilter packetFilter = new PacketIDFilter(packet.getPacketID()); + public PacketCollector createPacketCollectorAndSend(IQ packet) { + PacketFilter packetFilter = new IQReplyFilter(packet, this); // Create the packet collector before sending the packet PacketCollector packetCollector = createPacketCollector(packetFilter); // Now we can send the packet as the collector has been created diff --git a/core/src/main/java/org/jivesoftware/smack/Roster.java b/core/src/main/java/org/jivesoftware/smack/Roster.java index 40e1f818d..8ea2582b9 100644 --- a/core/src/main/java/org/jivesoftware/smack/Roster.java +++ b/core/src/main/java/org/jivesoftware/smack/Roster.java @@ -17,8 +17,21 @@ package org.jivesoftware.smack; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.jivesoftware.smack.filter.IQReplyFilter; import org.jivesoftware.smack.filter.PacketFilter; -import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; @@ -27,11 +40,6 @@ import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.packet.RosterPacket.Item; import org.jivesoftware.smack.util.StringUtils; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - /** * Represents a user's roster, which is the collection of users a person receives * presence updates for. Roster items are categorized into groups for easier management.

@@ -192,7 +200,7 @@ public class Roster { RosterPacket packet = new RosterPacket(); if (rosterStore != null && connection.isRosterVersioningSupported()) { packet.setVersion(rosterStore.getRosterVersion()); - PacketFilter filter = new PacketIDFilter(packet.getPacketID()); + PacketFilter filter = new IQReplyFilter(packet, connection); connection.addPacketListener(new RosterResultListener(), filter); } connection.sendPacket(packet); diff --git a/core/src/main/java/org/jivesoftware/smack/RosterGroup.java b/core/src/main/java/org/jivesoftware/smack/RosterGroup.java index ee3b79049..916369b29 100644 --- a/core/src/main/java/org/jivesoftware/smack/RosterGroup.java +++ b/core/src/main/java/org/jivesoftware/smack/RosterGroup.java @@ -17,17 +17,16 @@ package org.jivesoftware.smack; -import org.jivesoftware.smack.filter.PacketIDFilter; -import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.packet.RosterPacket; -import org.jivesoftware.smack.util.StringUtils; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.RosterPacket; +import org.jivesoftware.smack.util.StringUtils; + /** * A group of roster entries. * @@ -172,9 +171,7 @@ public class RosterGroup { item.addGroupName(getName()); packet.addRosterItem(item); // Wait up to a certain number of seconds for a reply from the server. - collector = connection - .createPacketCollector(new PacketIDFilter(packet.getPacketID())); - connection.sendPacket(packet); + collector = connection.createPacketCollectorAndSend(packet); } } if (collector != null) { @@ -206,9 +203,7 @@ public class RosterGroup { item.removeGroupName(this.getName()); packet.addRosterItem(item); // Wait up to a certain number of seconds for a reply from the server. - collector = connection - .createPacketCollector(new PacketIDFilter(packet.getPacketID())); - connection.sendPacket(packet); + collector = connection.createPacketCollectorAndSend(packet); } } if (collector != null) { diff --git a/core/src/main/java/org/jivesoftware/smack/filter/FromMatchesFilter.java b/core/src/main/java/org/jivesoftware/smack/filter/FromMatchesFilter.java index 0a27ef26b..7d576735b 100644 --- a/core/src/main/java/org/jivesoftware/smack/filter/FromMatchesFilter.java +++ b/core/src/main/java/org/jivesoftware/smack/filter/FromMatchesFilter.java @@ -37,30 +37,72 @@ public class FromMatchesFilter implements PacketFilter { private boolean matchBareJID = false; /** - * Creates a "from" filter using the "from" field part. If the specified address is a bare JID - * then the filter will match any address whose bare JID matches the specified JID. But if the - * specified address is a full JID then the filter will only match if the sender of the packet - * matches the specified resource. - * - * @param address the from field value the packet must match. Could be a full or bare JID. + * @see FromMatchesFilter#create(String) */ + @Deprecated public FromMatchesFilter(String address) { - if (address == null) { - throw new IllegalArgumentException("Parameter cannot be null."); - } - this.address = address.toLowerCase(); - matchBareJID = "".equals(StringUtils.parseResource(address)); + this(address, "".equals(StringUtils.parseResource(address))); + } + + /** + * Creates a filter matching on the "from" field. The from address must be the same as the + * filter address. The second parameter specifies whether the full or the bare addresses are + * compared. + * + * @param address The address to filter for. If null is given, the packet must not + * have a from address. + * @param matchBare + */ + public FromMatchesFilter(String address, boolean matchBare) { + this.address = (address == null) ? null : address.toLowerCase(); + matchBareJID = matchBare; + } + + /** + * Creates a filter matching on the "from" field. If the filter address is bare, compares + * the filter address with the bare from address. Otherwise, compares the filter address + * with the full from address. + * + * @param address The address to filter for. If null is given, the packet must not + * have a from address. + */ + public static FromMatchesFilter create(String address) { + return new FromMatchesFilter(address, "".equals(StringUtils.parseResource(address))) ; + } + + /** + * Creates a filter matching on the "from" field. Compares the bare version of from and filter + * address. + * + * @param address The address to filter for. If null is given, the packet must not + * have a from address. + */ + public static FromMatchesFilter createBare(String address) { + address = (address == null) ? null : StringUtils.parseBareAddress(address); + return new FromMatchesFilter(address, true); + } + + + /** + * Creates a filter matching on the "from" field. Compares the full version of from and filter + * address. + * + * @param address The address to filter for. If null is given, the packet must not + * have a from address. + */ + public static FromMatchesFilter createFull(String address) { + return new FromMatchesFilter(address, false); } public boolean accept(Packet packet) { String from = packet.getFrom(); if (from == null) { - return false; + return address == null; } if (matchBareJID) { - from = StringUtils.parseBareAddress(from); + from = StringUtils.parseBareAddress(from).toLowerCase(); } - return address.equals(from.toLowerCase()); + return address.equals(from); } public String toString() { diff --git a/core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java b/core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java new file mode 100644 index 000000000..63cbff7f4 --- /dev/null +++ b/core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java @@ -0,0 +1,114 @@ +/** + * + * Copyright 2014 Lars Noschinski + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.filter; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.jivesoftware.smack.Connection; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.Packet; +import org.jivesoftware.smack.util.StringUtils; + +/** + * Filters for packets which are a valid reply to an IQ request. + *

+ * Such a packet must have the same packet id and must be an IQ packet of type + * RESULT or ERROR. Moreover, it is necessary to check + * the from address to ignore forged replies. + *

+ * We accept a from address if one of the following is true: + *

+ *

+ * For a discussion of the issues, see the thread "Spoofing of iq ids and + * misbehaving servers" from 2014-01 on the jdev@jabber.org mailing list + * and following discussion in February and March. + * + * @author Lars Noschinski + * + */ +public class IQReplyFilter implements PacketFilter { + private static final Logger LOGGER = Logger.getLogger(IQReplyFilter.class.getName()); + + private final PacketFilter filter; + private final String to; + private final String local; + private final String server; + private final String packetId; + + /** + * Filters for packets which are a valid reply to an IQ request. + *

+ * Such a packet must have the same packet id and must be an IQ packet of type + * RESULT or ERROR. Moreover, it is necessary to check + * the from address to ignore forged replies. + *

+ * We accept a from address if one of the following is true: + *

+ *

+ * For a discussion of the issues, see the thread "Spoofing of iq ids and + * misbehaving servers" from 2014-01 on the jdev@jabber.org mailing list + * and following discussion in February and March. + * + * @param iqPacket An IQ request. Filter for replies to this packet. + */ + public IQReplyFilter(IQ iqPacket, Connection conn) { + to = iqPacket.getTo(); + local = conn.getUser().toLowerCase(); + server = conn.getServiceName().toLowerCase(); + packetId = iqPacket.getPacketID(); + + PacketFilter iqFilter = new OrFilter(new IQTypeFilter(IQ.Type.ERROR), new IQTypeFilter(IQ.Type.RESULT)); + PacketFilter idFilter = new PacketIDFilter(iqPacket.getPacketID()); + OrFilter fromFilter = new OrFilter(); + fromFilter.addFilter(FromMatchesFilter.createFull(to)); + if (to == null) { + fromFilter.addFilter(FromMatchesFilter.createBare(local)); + fromFilter.addFilter(FromMatchesFilter.createFull(server)); + } + else if (to.toLowerCase().equals(StringUtils.parseBareAddress(local))) { + fromFilter.addFilter(FromMatchesFilter.createFull(null)); + } + filter = new AndFilter(fromFilter, iqFilter, idFilter); + } + + @Override + public boolean accept(Packet packet) { + if (filter.accept(packet)) { + return true; + } else { + String msg = String.format("Rejected potentially spoofed reply to IQ-packet. Filter settings: " + + "packetId=%s, to=%s, local=%s, server=%s. Received packet with from=%d", + packetId, to, local, server, packet.getFrom()); + LOGGER.log(Level.INFO, msg , packet); + return false; + } + } + +} diff --git a/core/src/test/java/org/jivesoftware/smack/filters/FromMatchesFilterTest.java b/core/src/test/java/org/jivesoftware/smack/filters/FromMatchesFilterTest.java index 7e423acf2..e6f530391 100644 --- a/core/src/test/java/org/jivesoftware/smack/filters/FromMatchesFilterTest.java +++ b/core/src/test/java/org/jivesoftware/smack/filters/FromMatchesFilterTest.java @@ -35,79 +35,333 @@ public class FromMatchesFilterTest { private static final String BASE_JID2 = "sss@muc.myserver.com"; private static final String FULL_JID2 = BASE_JID2 + "/resource"; + private static final String BASE_JID3 = "ss@muc.myserver.comm.net"; + private static final String SERVICE_JID1 = "muc.myserver.com"; private static final String SERVICE_JID2 = "pubsub.myserver.com"; @Test - public void compareMatchingFullJid() + public void oldCompareMatchingFullJid() { - FromMatchesFilter filter = new FromMatchesFilter(FULL_JID1_R1); - Packet packet = new Packet() { - @Override - public String toXML() { return null; } - }; + FromMatchesFilter filter = new FromMatchesFilter(FULL_JID1_R1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; - packet.setFrom(FULL_JID1_R1); - assertTrue(filter.accept(packet)); - - packet.setFrom(BASE_JID1); - assertFalse(filter.accept(packet)); - - packet.setFrom(FULL_JID1_R2); - assertFalse(filter.accept(packet)); - - packet.setFrom(BASE_JID2); - assertFalse(filter.accept(packet)); + packet.setFrom(FULL_JID1_R1); + assertTrue(filter.accept(packet)); - packet.setFrom(FULL_JID2); - assertFalse(filter.accept(packet)); + packet.setFrom(BASE_JID1); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); } @Test - public void compareMatchingBaseJid() + public void oldCompareMatchingBaseJid() { - FromMatchesFilter filter = new FromMatchesFilter(BASE_JID1); - Packet packet = new Packet() { - @Override - public String toXML() { return null; } - }; + FromMatchesFilter filter = new FromMatchesFilter(BASE_JID1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; - packet.setFrom(BASE_JID1); - assertTrue(filter.accept(packet)); + packet.setFrom(BASE_JID1); + assertTrue(filter.accept(packet)); - packet.setFrom(FULL_JID1_R1); - assertTrue(filter.accept(packet)); + packet.setFrom(FULL_JID1_R1); + assertTrue(filter.accept(packet)); - packet.setFrom(FULL_JID1_R2); - assertTrue(filter.accept(packet)); + packet.setFrom(FULL_JID1_R2); + assertTrue(filter.accept(packet)); - packet.setFrom(BASE_JID2); - assertFalse(filter.accept(packet)); + packet.setFrom(BASE_JID2); + assertFalse(filter.accept(packet)); - packet.setFrom(FULL_JID2); - assertFalse(filter.accept(packet)); + packet.setFrom(FULL_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); } @Test - public void compareMatchingServiceJid() + public void oldCompareMatchingServiceJid() { - FromMatchesFilter filter = new FromMatchesFilter(SERVICE_JID1); - Packet packet = new Packet() { - @Override - public String toXML() { return null; } - }; + FromMatchesFilter filter = new FromMatchesFilter(SERVICE_JID1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; - packet.setFrom(SERVICE_JID1); - assertTrue(filter.accept(packet)); + packet.setFrom(SERVICE_JID1); + assertTrue(filter.accept(packet)); - packet.setFrom(SERVICE_JID2); - assertFalse(filter.accept(packet)); + packet.setFrom(SERVICE_JID2); + assertFalse(filter.accept(packet)); - packet.setFrom(BASE_JID1); - assertFalse(filter.accept(packet)); + packet.setFrom(BASE_JID1); + assertFalse(filter.accept(packet)); - packet.setFrom(FULL_JID1_R1); - assertFalse(filter.accept(packet)); + packet.setFrom(FULL_JID1_R1); + assertFalse(filter.accept(packet)); + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); } + + @Test + public void autoCompareMatchingFullJid() + { + FromMatchesFilter filter = FromMatchesFilter.create(FULL_JID1_R1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; + + packet.setFrom(FULL_JID1_R1); + assertTrue(filter.accept(packet)); + + packet.setFrom(BASE_JID1); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); + } + + @Test + public void autoCompareMatchingBaseJid() + { + FromMatchesFilter filter = FromMatchesFilter.create(BASE_JID1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; + + packet.setFrom(BASE_JID1); + assertTrue(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R1); + assertTrue(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R2); + assertTrue(filter.accept(packet)); + + packet.setFrom(BASE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); +} + + @Test + public void autoCompareMatchingServiceJid() + { + FromMatchesFilter filter = FromMatchesFilter.create(SERVICE_JID1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; + + packet.setFrom(SERVICE_JID1); + assertTrue(filter.accept(packet)); + + packet.setFrom(SERVICE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID1); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R1); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); + } + + @Test + public void bareCompareMatchingFullJid() + { + FromMatchesFilter filter = FromMatchesFilter.createBare(FULL_JID1_R1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; + + packet.setFrom(BASE_JID1); + assertTrue(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R1); + assertTrue(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R2); + assertTrue(filter.accept(packet)); + + packet.setFrom(BASE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); + } + + @Test + public void bareCompareMatchingBaseJid() + { + FromMatchesFilter filter = FromMatchesFilter.createBare(BASE_JID1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; + + packet.setFrom(BASE_JID1); + assertTrue(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R1); + assertTrue(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R2); + assertTrue(filter.accept(packet)); + + packet.setFrom(BASE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); +} + + @Test + public void bareCompareMatchingServiceJid() + { + FromMatchesFilter filter = FromMatchesFilter.createBare(SERVICE_JID1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; + + packet.setFrom(SERVICE_JID1); + assertTrue(filter.accept(packet)); + + packet.setFrom(SERVICE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID1); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R1); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); + } + + @Test + public void fullCompareMatchingFullJid() + { + FromMatchesFilter filter = FromMatchesFilter.createFull(FULL_JID1_R1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; + + packet.setFrom(FULL_JID1_R1); + assertTrue(filter.accept(packet)); + + packet.setFrom(BASE_JID1); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); + } + + @Test + public void fullCompareMatchingBaseJid() + { + FromMatchesFilter filter = FromMatchesFilter.createFull(BASE_JID1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; + + packet.setFrom(BASE_JID1); + assertTrue(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R1); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); + } + + @Test + public void fullCompareMatchingServiceJid() + { + FromMatchesFilter filter = FromMatchesFilter.createFull(SERVICE_JID1); + Packet packet = new Packet() { + @Override + public String toXML() { return null; } + }; + + packet.setFrom(SERVICE_JID1); + assertTrue(filter.accept(packet)); + + packet.setFrom(SERVICE_JID2); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID1); + assertFalse(filter.accept(packet)); + + packet.setFrom(FULL_JID1_R1); + assertFalse(filter.accept(packet)); + + packet.setFrom(BASE_JID3); + assertFalse(filter.accept(packet)); + } + } diff --git a/experimental/src/main/java/org/jivesoftware/smackx/carbons/CarbonManager.java b/experimental/src/main/java/org/jivesoftware/smackx/carbons/CarbonManager.java index 541309c77..4152569dd 100644 --- a/experimental/src/main/java/org/jivesoftware/smackx/carbons/CarbonManager.java +++ b/experimental/src/main/java/org/jivesoftware/smackx/carbons/CarbonManager.java @@ -25,7 +25,7 @@ import org.jivesoftware.smack.Connection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.filter.PacketIDFilter; +import org.jivesoftware.smack.filter.IQReplyFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Packet; @@ -130,7 +130,7 @@ public class CarbonManager { } connection.removePacketListener(this); } - }, new PacketIDFilter(setIQ.getPacketID())); + }, new IQReplyFilter(setIQ, connection)); connection.sendPacket(setIQ); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java index 57066fb08..4cc6a8404 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java @@ -31,7 +31,6 @@ import org.jivesoftware.smack.Connection; import org.jivesoftware.smack.ConnectionListener; import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.XMPPError; @@ -409,9 +408,7 @@ public class FileTransferNegotiator { si.setTo(userID); si.setType(IQ.Type.SET); - PacketCollector collector = connection - .createPacketCollector(new PacketIDFilter(si.getPacketID())); - connection.sendPacket(si); + PacketCollector collector = connection.createPacketCollectorAndSend(si); Packet siResponse = collector.nextResult(responseTimeout); collector.cancel(); diff --git a/extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java b/extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java index 48fd46a9a..cbb65f1f1 100644 --- a/extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java +++ b/extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java @@ -23,6 +23,7 @@ import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.Connection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.PacketFilter; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; @@ -79,7 +80,7 @@ public class ConnectionUtils { } }; - when(connection.createPacketCollectorAndSend(isA(Packet.class))).thenAnswer(collectorAndSend); + when(connection.createPacketCollectorAndSend(isA(IQ.class))).thenAnswer(collectorAndSend); // mock send method Answer addIncoming = new Answer() { diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java index 7aa9274be..9296275f6 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java @@ -24,10 +24,9 @@ import java.util.Enumeration; import java.util.Iterator; import java.util.logging.Logger; -import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.Connection; +import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.ProviderManager; @@ -397,10 +396,7 @@ public class RTPBridge extends IQ { RTPBridge rtpPacket = new RTPBridge(sessionID); rtpPacket.setTo(RTPBridge.NAME + "." + connection.getServiceName()); - PacketCollector collector = connection - .createPacketCollector(new PacketIDFilter(rtpPacket.getPacketID())); - - connection.sendPacket(rtpPacket); + PacketCollector collector = connection.createPacketCollectorAndSend(rtpPacket); RTPBridge response = (RTPBridge) collector.nextResult(); @@ -476,10 +472,7 @@ public class RTPBridge extends IQ { // LOGGER.debug("Relayed to: " + candidate.getIp() + ":" + candidate.getPort()); - PacketCollector collector = connection - .createPacketCollector(new PacketIDFilter(rtpPacket.getPacketID())); - - connection.sendPacket(rtpPacket); + PacketCollector collector = connection.createPacketCollectorAndSend(rtpPacket); RTPBridge response = (RTPBridge) collector.nextResult(); @@ -507,10 +500,7 @@ public class RTPBridge extends IQ { // LOGGER.debug("Relayed to: " + candidate.getIp() + ":" + candidate.getPort()); - PacketCollector collector = xmppConnection - .createPacketCollector(new PacketIDFilter(rtpPacket.getPacketID())); - - xmppConnection.sendPacket(rtpPacket); + PacketCollector collector = xmppConnection.createPacketCollectorAndSend(rtpPacket); RTPBridge response = (RTPBridge) collector.nextResult(); diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java index 70f7b71dc..e50cc2bda 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java @@ -21,10 +21,9 @@ import java.util.Iterator; import java.util.List; import java.util.logging.Logger; -import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.Connection; +import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.ProviderManager; @@ -193,10 +192,7 @@ public class STUN extends IQ { STUN stunPacket = new STUN(); stunPacket.setTo(DOMAIN + "." + connection.getServiceName()); - PacketCollector collector = connection - .createPacketCollector(new PacketIDFilter(stunPacket.getPacketID())); - - connection.sendPacket(stunPacket); + PacketCollector collector = connection.createPacketCollectorAndSend(stunPacket); STUN response = (STUN) collector.nextResult(); diff --git a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java index 9ce90438a..5975cdee1 100644 --- a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java +++ b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java @@ -769,11 +769,7 @@ public class AgentSession { notes.setTo(workgroupJID); notes.setSessionID(sessionID); notes.setNotes(note); - PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(notes.getPacketID())); - // Send the request - connection.sendPacket(notes); - - collector.nextResultOrThrow(); + connection.createPacketCollectorAndSend(notes).nextResultOrThrow(); } /**