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.
This commit is contained in:
Lars Noschinski 2014-02-23 21:08:35 +01:00 committed by Florian Schmaus
parent 980047c4e1
commit 6c7296a37b
13 changed files with 520 additions and 134 deletions

View File

@ -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();
}
/**

View File

@ -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 <code>packet</code>.
* Does also send <code>packet</code>. Note that the packet filter is at the moment created as
* ID filter of <code>packet</code>'s ID. This may change in the future to also check the
* correct "from JID" value.
*
* Does also send <code>packet</code>. 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

View File

@ -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.<p>
@ -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);

View File

@ -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) {

View File

@ -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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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() {

View File

@ -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.
* <p>
* Such a packet must have the same packet id and must be an IQ packet of type
* <code>RESULT</code> or <code>ERROR</code>. Moreover, it is necessary to check
* the <code>from</code> address to ignore forged replies.
* <p>
* We accept a <code>from</code> address if one of the following is true:
* <ul>
* <li>It matches the <code>to</code> address of the request.
* <li>The <code>to</code> address of the request was empty and the
* <code>from</code> address matches either the bare jid of the server or the
* (bare or full jid) of the client.
* <li>To <code>to</code> was our bare address and the <code>from</code> is empty.
* </ul>
* <p>
* 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.
* <p>
* Such a packet must have the same packet id and must be an IQ packet of type
* <code>RESULT</code> or <code>ERROR</code>. Moreover, it is necessary to check
* the <code>from</code> address to ignore forged replies.
* <p>
* We accept a <code>from</code> address if one of the following is true:
* <ul>
* <li>It matches the <code>to</code> address of the request.
* <li>The <code>to</code> address of the request was empty and the
* <code>from</code> address matches either the bare jid of the server or the
* (bare or full jid) of the client.
* <li>To <code>to</code> was our bare address and the <code>from</code> is empty.
* </ul>
* <p>
* 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;
}
}
}

View File

@ -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));
}
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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<Object> addIncoming = new Answer<Object>() {

View File

@ -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();

View File

@ -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();

View File

@ -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();
}
/**