Merge branch '4.2'

This commit is contained in:
Florian Schmaus 2017-11-22 08:37:47 +01:00
commit 81002c4fbd
63 changed files with 391 additions and 266 deletions

View File

@ -79,6 +79,14 @@ allprojects {
':smack-android', ':smack-android',
':smack-android-extensions', ':smack-android-extensions',
].collect{ project(it) } ].collect{ project(it) }
androidOptionalProjects = [
':smack-tcp',
':smack-extensions',
':smack-experimental',
':smack-bosh',
':smack-omemo',
':smack-omemo-signal',
].collect{ project(it) }
gplLicensedProjects = [ gplLicensedProjects = [
':smack-omemo-signal', ':smack-omemo-signal',
':smack-omemo-signal-integration-test', ':smack-omemo-signal-integration-test',

View File

@ -60,6 +60,10 @@
<property name="format" value="^\s*[\S&amp;&amp;[^\*/]]+\s+$"/> <property name="format" value="^\s*[\S&amp;&amp;[^\*/]]+\s+$"/>
<property name="message" value="Line containing trailing whitespace character(s)"/> <property name="message" value="Line containing trailing whitespace character(s)"/>
</module> </module>
<module name="RegexpSingleline">
<property name="format" value="^\s*//[^\s]"/>
<property name="message" value="Comment start ('//') followed by non-space character. You would not continue after a punctuation without a space, would you?"/>
</module>
<module name="JavadocPackage"/> <module name="JavadocPackage"/>
<module name="TreeWalker"> <module name="TreeWalker">
<module name="FinalClass"/> <module name="FinalClass"/>

View File

@ -6,24 +6,24 @@ Smack: Getting Started
This document will introduce you to the Smack API and provide an overview of This document will introduce you to the Smack API and provide an overview of
important classes and concepts. important classes and concepts.
JAR Files and Requirements Smack Modules and Requirements
-------------------------- -------------------------------
Smack is meant to be easily embedded into any existing Java application. The Smack is meant to be easily embedded into any existing Java application. The
library ships as several JAR files to provide more flexibility over which library ships as several modulesto provide more flexibility over which
features applications require: features applications require:
* `smack-core.jar` -- provides core XMPP functionality. All XMPP features that are part of the XMPP RFCs are included. * `smack-core` -- provides core XMPP functionality. All XMPP features that are part of the XMPP RFCs are included.
* `smack-im.jar` -- provides functinoality defined in RFC 6121 (XMPP-IM), like the Roster. * `smack-im` -- provides functinoality defined in RFC 6121 (XMPP-IM), like the Roster.
* `smack-tcp.jar` -- support for XMPP over TCP. Includes XMPPTCPConnection class, which you usually want to use * `smack-tcp` -- support for XMPP over TCP. Includes XMPPTCPConnection class, which you usually want to use
* `smack-extensions.jar` -- support for many of the extensions (XEPs) defined by the XMPP Standards Foundation, including multi-user chat, file transfer, user search, etc. The extensions are documented in the [extensions manual](extensions/index.md). * `smack-extensions` -- support for many of the extensions (XEPs) defined by the XMPP Standards Foundation, including multi-user chat, file transfer, user search, etc. The extensions are documented in the [extensions manual](extensions/index.md).
* `smack-experimental.jar` -- support for experimental extensions (XEPs) defined by the XMPP Standards Foundation. The API and functionality of those extensions should be considered as unstable. * `smack-experimental` -- support for experimental extensions (XEPs) defined by the XMPP Standards Foundation. The API and functionality of those extensions should be considered as unstable.
* `smack-legacy.jar` -- support for legacy extensions (XEPs) defined by the XMPP Standards Foundation. * `smack-legacy` -- support for legacy extensions (XEPs) defined by the XMPP Standards Foundation.
* `smack-bosh.jar` -- support for BOSH (XEP-0124). This code should be considered as beta. * `smack-bosh` -- support for BOSH (XEP-0124). This code should be considered as beta.
* `smack-jingle.jar` -- support for Jingle. This code is old and currenlty unmaintained. * `smack-resolver-minidns` -- support for resolving DNS SRV records with the help of MiniDNS. Ideal for platforms that do not support the javax.naming API. Also supports [DNSSEC](dnssec.md).
* `smack-resolver-dnsjava.jar` -- support for resolving DNS SRV records with the help of dnsjava. Ideal for platforms that do not support the javax.naming API. * `smack-resolver-dnsjava` -- support for resolving DNS SRV records with the help of dnsjava.
* `smack-resolver-javax.jar` -- support for resolving DNS SRV records with the javax namespace API. * `smack-resolver-javax` -- support for resolving DNS SRV records with the javax namespace API.
* `smack-debug.jar` -- an enhanced GUI debugger for protocol traffic. It will automatically be used when found in the classpath and when [debugging](debugging.md) is enabled. * `smack-debug` -- an enhanced GUI debugger for protocol traffic. It will automatically be used when found in the classpath and when [debugging](debugging.md) is enabled.
Configuration Configuration
------------- -------------
@ -46,10 +46,14 @@ The `XMPPTCPConnection` class is used to create a connection to an XMPP
server. Below are code examples for making a connection: server. Below are code examples for making a connection:
``` ```
// Create a connection to the jabber.org server. // Create a connection and login to the example.org XMPP service.
AbstractXMPPConnection conn1 = **new** XMPPTCPConnection("username", "password", "jabber.org"); AbstractXMPPConnection connection = new XMPPTCPConnection("username", "password" "example.org");
conn1.connect(); conn1.connect().login();
```
Further connection parameters can be configured by using a configuration builder:
```
// Create a connection to the jabber.org server on a specific port. // Create a connection to the jabber.org server on a specific port.
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder() XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.setUsernameAndPassword("username", "password") .setUsernameAndPassword("username", "password")
@ -59,7 +63,7 @@ XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.build(); .build();
AbstractXMPPConnection conn2 = **new** XMPPTCPConnection(config); AbstractXMPPConnection conn2 = **new** XMPPTCPConnection(config);
conn2.connect(); conn2.connect().login();
``` ```
Note that maximum security will be used when connecting to the server by Note that maximum security will be used when connecting to the server by

View File

@ -9,9 +9,8 @@ smack-extensions and smack-experimental."""
dependencies { dependencies {
// androidProjects lists all projects that are checked to compile against android.jar // androidProjects lists all projects that are checked to compile against android.jar
// Filter out the optional Smack dependencies from androidProjects // Filter out the optional Smack dependencies from androidProjects
androidProjects.findAll { (androidProjects - androidOptionalProjects)
![':smack-tcp', ':smack-extensions', ':smack-experimental', ':smack-bosh'].contains(it.getPath()) .each { project ->
}.each { project ->
compile project compile project
} }

View File

@ -524,7 +524,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
} }
break; break;
case "error": case "error":
//Some bosh error isn't stream error. // Some BOSH error isn't stream error.
if ("urn:ietf:params:xml:ns:xmpp-streams".equals(parser.getNamespace(null))) { if ("urn:ietf:params:xml:ns:xmpp-streams".equals(parser.getNamespace(null))) {
throw new StreamErrorException(PacketParserUtils.parseStreamError(parser)); throw new StreamErrorException(PacketParserUtils.parseStreamError(parser));
} else { } else {

View File

@ -46,6 +46,7 @@ import org.jivesoftware.smack.SmackException.AlreadyConnectedException;
import org.jivesoftware.smack.SmackException.AlreadyLoggedInException; import org.jivesoftware.smack.SmackException.AlreadyLoggedInException;
import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.SmackException.ResourceBindingNotOfferedException; import org.jivesoftware.smack.SmackException.ResourceBindingNotOfferedException;
import org.jivesoftware.smack.SmackException.SecurityRequiredByClientException; import org.jivesoftware.smack.SmackException.SecurityRequiredByClientException;
import org.jivesoftware.smack.SmackException.SecurityRequiredException; import org.jivesoftware.smack.SmackException.SecurityRequiredException;
@ -1541,7 +1542,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
final StanzaListener packetListener = new StanzaListener() { final StanzaListener packetListener = new StanzaListener() {
@Override @Override
public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException { public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException, NotLoggedInException {
boolean removed = removeAsyncStanzaListener(this); boolean removed = removeAsyncStanzaListener(this);
if (!removed) { if (!removed) {
// We lost a race against the "no response" handling runnable. Avoid calling the callback, as the // We lost a race against the "no response" handling runnable. Avoid calling the callback, as the
@ -1609,7 +1610,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
public void addOneTimeSyncCallback(final StanzaListener callback, final StanzaFilter packetFilter) { public void addOneTimeSyncCallback(final StanzaListener callback, final StanzaFilter packetFilter) {
final StanzaListener packetListener = new StanzaListener() { final StanzaListener packetListener = new StanzaListener() {
@Override @Override
public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException { public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException, NotLoggedInException {
try { try {
callback.processStanza(packet); callback.processStanza(packet);
} finally { } finally {

View File

@ -18,6 +18,7 @@
package org.jivesoftware.smack; package org.jivesoftware.smack;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
/** /**
@ -49,7 +50,8 @@ public interface StanzaListener {
* @param packet the stanza(/packet) to process. * @param packet the stanza(/packet) to process.
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
* @throws NotLoggedInException
*/ */
public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException; public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException, NotLoggedInException;
} }

View File

@ -66,7 +66,15 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
private Type type = Type.available; private Type type = Type.available;
private String status = null; private String status = null;
/**
* The priority of the presence. The magic value {@link Integer#MIN_VALUE} is used to indicate that the original
* presence stanza did not had an explicit priority set. In which case the priority defaults to 0.
*
* @see <a href="https://tools.ietf.org/html/rfc6121#section-4.7.2.3">RFC 6121 § 4.7.2.3.</a>
*/
private int priority = Integer.MIN_VALUE; private int priority = Integer.MIN_VALUE;
private Mode mode = null; private Mode mode = null;
/** /**
@ -201,6 +209,9 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
* @see <a href="https://tools.ietf.org/html/rfc6121#section-4.7.2.3">RFC 6121 § 4.7.2.3. Priority Element</a> * @see <a href="https://tools.ietf.org/html/rfc6121#section-4.7.2.3">RFC 6121 § 4.7.2.3. Priority Element</a>
*/ */
public int getPriority() { public int getPriority() {
if (priority == Integer.MIN_VALUE) {
return 0;
}
return priority; return priority;
} }

View File

@ -226,9 +226,13 @@ public class XMPPError extends AbstractError {
} }
public static XMPPError.Builder from(Condition condition, String descriptiveText) { public static XMPPError.Builder from(Condition condition, String descriptiveText) {
Map<String, String> descriptiveTexts = new HashMap<String, String>(); XMPPError.Builder builder = getBuilder().setCondition(condition);
descriptiveTexts.put("en", descriptiveText); if (descriptiveText != null) {
return getBuilder().setCondition(condition).setDescriptiveTexts(descriptiveTexts); Map<String, String> descriptiveTexts = new HashMap<>();
descriptiveTexts.put("en", descriptiveText);
builder.setDescriptiveTexts(descriptiveTexts);
}
return builder;
} }
public static Builder getBuilder() { public static Builder getBuilder() {

View File

@ -97,7 +97,6 @@ public class Socks5ProxySocketConnection implements ProxySocketConnection {
| 1 | 1 | | 1 | 1 |
+----+--------+ +----+--------+
*/ */
//in.read(buf, 0, 2);
fill(in, buf, 2); fill(in, buf, 2);
boolean check = false; boolean check = false;
@ -160,7 +159,6 @@ public class Socks5ProxySocketConnection implements ProxySocketConnection {
`failure' (STATUS value other than X'00') status, it MUST close the `failure' (STATUS value other than X'00') status, it MUST close the
connection. connection.
*/ */
//in.read(buf, 0, 2);
fill(in, buf, 2); fill(in, buf, 2);
if (buf[1] == 0) if (buf[1] == 0)
{ {
@ -260,7 +258,6 @@ public class Socks5ProxySocketConnection implements ProxySocketConnection {
o BND.PORT server bound port in network octet order o BND.PORT server bound port in network octet order
*/ */
//in.read(buf, 0, 4);
fill(in, buf, 4); fill(in, buf, 4);
if (buf[1] != 0) if (buf[1] != 0)
@ -279,17 +276,13 @@ public class Socks5ProxySocketConnection implements ProxySocketConnection {
switch (buf[3] & 0xff) switch (buf[3] & 0xff)
{ {
case 1: case 1:
//in.read(buf, 0, 6);
fill(in, buf, 6); fill(in, buf, 6);
break; break;
case 3: case 3:
//in.read(buf, 0, 1);
fill(in, buf, 1); fill(in, buf, 1);
//in.read(buf, 0, buf[0]+2);
fill(in, buf, (buf[0] & 0xff) + 2); fill(in, buf, (buf[0] & 0xff) + 2);
break; break;
case 4: case 4:
//in.read(buf, 0, 18);
fill(in, buf, 18); fill(in, buf, 18);
break; break;
default: default:

View File

@ -272,7 +272,7 @@ public class StringUtils {
* array index. * array index.
*/ */
private static final char[] numbersAndLetters = ("0123456789abcdefghijklmnopqrstuvwxyz" + private static final char[] numbersAndLetters = ("0123456789abcdefghijklmnopqrstuvwxyz" +
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray(); "ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();
/** /**
* Returns a random String of numbers and letters (lower and upper case) * Returns a random String of numbers and letters (lower and upper case)
@ -288,17 +288,7 @@ public class StringUtils {
* @return a random String of numbers and letters of the specified length. * @return a random String of numbers and letters of the specified length.
*/ */
public static String insecureRandomString(int length) { public static String insecureRandomString(int length) {
if (length < 1) { return randomString(length, randGen.get());
return null;
}
final Random random = randGen.get();
// Create a char buffer to put random letters and numbers in.
char[] randBuffer = new char[length];
for (int i = 0; i < randBuffer.length; i++) {
randBuffer[i] = numbersAndLetters[random.nextInt(numbersAndLetters.length)];
}
return new String(randBuffer);
} }
private static final ThreadLocal<SecureRandom> SECURE_RANDOM = new ThreadLocal<SecureRandom>() { private static final ThreadLocal<SecureRandom> SECURE_RANDOM = new ThreadLocal<SecureRandom>() {
@ -309,12 +299,16 @@ public class StringUtils {
}; };
public static String randomString(final int length) { public static String randomString(final int length) {
return randomString(length, SECURE_RANDOM.get());
}
private static String randomString(final int length, Random random) {
if (length < 1) { if (length < 1) {
return null; return null;
} }
byte[] randomBytes = new byte[length]; byte[] randomBytes = new byte[length];
SECURE_RANDOM.get().nextBytes(randomBytes); random.nextBytes(randomBytes);
char[] randomChars = new char[length]; char[] randomChars = new char[length];
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
randomChars[i] = getPrintableChar(randomBytes[i]); randomChars[i] = getPrintableChar(randomBytes[i]);

View File

@ -172,7 +172,7 @@ public class StanzaCollectorTest
catch (InterruptedException e) catch (InterruptedException e)
{ {
} }
//We cannot guarantee that this is going to pass due to the possible issue of timing between consumer 1 // We cannot guarantee that this is going to pass due to the possible issue of timing between consumer 1
// and main, but the probability is extremely remote. // and main, but the probability is extremely remote.
assertNull(collector.pollResult()); assertNull(collector.pollResult());
} }

View File

@ -17,6 +17,7 @@
package org.jivesoftware.smackx.bytestreams.ibb; package org.jivesoftware.smackx.bytestreams.ibb;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler; import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
@ -65,7 +66,7 @@ class DataListener extends AbstractIqRequestHandler {
ibbSession.processIQPacket(data); ibbSession.processIQPacket(data);
} }
} }
catch (NotConnectedException | InterruptedException e) { catch (NotConnectedException | InterruptedException | NotLoggedInException e) {
return null; return null;
} }
return null; return null;

View File

@ -25,6 +25,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.StanzaListener; import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.AndFilter;
@ -847,8 +848,9 @@ public class InBandBytestreamSession implements BytestreamSession {
* @param data * @param data
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
* @throws NotLoggedInException
*/ */
public void processIQPacket(Data data) throws NotConnectedException, InterruptedException { public void processIQPacket(Data data) throws NotConnectedException, InterruptedException, NotLoggedInException {
inputStream.dataPacketListener.processStanza(data); inputStream.dataPacketListener.processStanza(data);
} }

View File

@ -27,7 +27,6 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.ConnectionCreationListener;
@ -766,6 +765,25 @@ public final class ServiceDiscoveryManager extends Manager {
*/ */
public List<DiscoverInfo> findServicesDiscoverInfo(String feature, boolean stopOnFirst, boolean useCache) public List<DiscoverInfo> findServicesDiscoverInfo(String feature, boolean stopOnFirst, boolean useCache)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return findServicesDiscoverInfo(feature, stopOnFirst, useCache, null);
}
/**
* Find all services under the users service that provide a given feature.
*
* @param feature the feature to search for
* @param stopOnFirst if true, stop searching after the first service was found
* @param useCache if true, query a cache first to avoid network I/O
* @param encounteredExceptions an optional map which will be filled with the exceptions encountered
* @return a possible empty list of services providing the given feature
* @throws NoResponseException
* @throws XMPPErrorException
* @throws NotConnectedException
* @throws InterruptedException
* @since 4.2.2
*/
public List<DiscoverInfo> findServicesDiscoverInfo(String feature, boolean stopOnFirst, boolean useCache, Map<? super Jid, Exception> encounteredExceptions)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
List<DiscoverInfo> serviceDiscoInfo = null; List<DiscoverInfo> serviceDiscoInfo = null;
DomainBareJid serviceName = connection().getXMPPServiceDomain(); DomainBareJid serviceName = connection().getXMPPServiceDomain();
if (useCache) { if (useCache) {
@ -780,8 +798,9 @@ public final class ServiceDiscoveryManager extends Manager {
try { try {
info = discoverInfo(serviceName); info = discoverInfo(serviceName);
} catch (XMPPErrorException e) { } catch (XMPPErrorException e) {
// Be extra robust here: Return the empty linked list and log this situation if (encounteredExceptions != null) {
LOGGER.log(Level.WARNING, "Could not discover information about service", e); encounteredExceptions.put(serviceName, e);
}
return serviceDiscoInfo; return serviceDiscoInfo;
} }
// Check if the server supports the feature // Check if the server supports the feature
@ -800,25 +819,27 @@ public final class ServiceDiscoveryManager extends Manager {
// Get the disco items and send the disco packet to each server item // Get the disco items and send the disco packet to each server item
items = discoverItems(serviceName); items = discoverItems(serviceName);
} catch (XMPPErrorException e) { } catch (XMPPErrorException e) {
LOGGER.log(Level.WARNING, "Could not discover items about service", e); if (encounteredExceptions != null) {
encounteredExceptions.put(serviceName, e);
}
return serviceDiscoInfo; return serviceDiscoInfo;
} }
for (DiscoverItems.Item item : items.getItems()) { for (DiscoverItems.Item item : items.getItems()) {
Jid address = item.getEntityID();
try { try {
// TODO is it OK here in all cases to query without the node attribute? // TODO is it OK here in all cases to query without the node attribute?
// MultipleRecipientManager queried initially also with the node attribute, but this // MultipleRecipientManager queried initially also with the node attribute, but this
// could be simply a fault instead of intentional. // could be simply a fault instead of intentional.
info = discoverInfo(item.getEntityID()); info = discoverInfo(address);
} }
catch (XMPPErrorException | NoResponseException e) { catch (XMPPErrorException | NoResponseException e) {
// Don't throw this exceptions if one of the server's items fail if (encounteredExceptions != null) {
LOGGER.log(Level.WARNING, "Exception while discovering info for feature " + feature encounteredExceptions.put(address, e);
+ " of " + item.getEntityID() + " node: " + item.getNode(), e); }
continue; continue;
} }
if (info.containsFeature(feature)) { if (info.containsFeature(feature)) {
serviceDiscoInfo.add(info); serviceDiscoInfo.add(info);
//serviceAddresses.add(item.getEntityID().asDomainBareJid());
if (stopOnFirst) { if (stopOnFirst) {
break; break;
} }

View File

@ -303,7 +303,7 @@ public class OutgoingFileTransfer extends FileTransfer {
transferThread = new Thread(new Runnable() { transferThread = new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
//Create packet filter // Create packet filter.
try { try {
outputStream = negotiateStream(fileName, fileSize, description); outputStream = negotiateStream(fileName, fileSize, description);
} catch (XMPPErrorException e) { } catch (XMPPErrorException e) {

View File

@ -84,7 +84,7 @@ public final class JingleManager extends Manager {
JingleSessionHandler sessionHandler = jingleSessionHandlers.get(fullJidAndSessionId); JingleSessionHandler sessionHandler = jingleSessionHandlers.get(fullJidAndSessionId);
if (sessionHandler != null) { if (sessionHandler != null) {
//Handle existing session // Handle existing session
return sessionHandler.handleJingleSessionRequest(jingle); return sessionHandler.handleJingleSessionRequest(jingle);
} }
@ -96,19 +96,19 @@ public final class JingleManager extends Manager {
description.getNamespace()); description.getNamespace());
if (jingleDescriptionHandler == null) { if (jingleDescriptionHandler == null) {
//Unsupported Application // Unsupported Application
LOGGER.log(Level.WARNING, "Unsupported Jingle application."); LOGGER.log(Level.WARNING, "Unsupported Jingle application.");
return jutil.createSessionTerminateUnsupportedApplications(fullFrom, sid); return jutil.createSessionTerminateUnsupportedApplications(fullFrom, sid);
} }
return jingleDescriptionHandler.handleJingleRequest(jingle); return jingleDescriptionHandler.handleJingleRequest(jingle);
} }
//Unknown session // Unknown session
LOGGER.log(Level.WARNING, "Unknown session."); LOGGER.log(Level.WARNING, "Unknown session.");
return jutil.createErrorUnknownSession(jingle); return jutil.createErrorUnknownSession(jingle);
} }
}); });
//Register transports. // Register transports.
JingleTransportMethodManager transportMethodManager = JingleTransportMethodManager.getInstanceFor(connection); JingleTransportMethodManager transportMethodManager = JingleTransportMethodManager.getInstanceFor(connection);
transportMethodManager.registerTransportManager(JingleIBBTransportManager.getInstanceFor(connection)); transportMethodManager.registerTransportManager(JingleIBBTransportManager.getInstanceFor(connection));
transportMethodManager.registerTransportManager(JingleS5BTransportManager.getInstanceFor(connection)); transportMethodManager.registerTransportManager(JingleS5BTransportManager.getInstanceFor(connection));

View File

@ -59,6 +59,6 @@ public final class JingleIBBTransportManager extends JingleTransportManager<Jing
@Override @Override
public void authenticated(XMPPConnection connection, boolean resumed) { public void authenticated(XMPPConnection connection, boolean resumed) {
//Nothing to do. // Nothing to do.
} }
} }

View File

@ -105,7 +105,7 @@ public class JingleIBBTransportSession extends JingleTransportSession<JingleIBBT
@Override @Override
public IQ handleTransportInfo(Jingle transportInfo) { public IQ handleTransportInfo(Jingle transportInfo) {
return IQ.createResultIQ(transportInfo); return IQ.createResultIQ(transportInfo);
//TODO // TODO
} }
@Override @Override

View File

@ -77,7 +77,7 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
.setStreamId(sid).setMode(mode).setDestinationAddress( .setStreamId(sid).setMode(mode).setDestinationAddress(
Socks5Utils.createDigest(sid, jingleSession.getLocal(), jingleSession.getRemote())); Socks5Utils.createDigest(sid, jingleSession.getLocal(), jingleSession.getRemote()));
//Local host // Local host
if (JingleS5BTransportManager.isUseLocalCandidates()) { if (JingleS5BTransportManager.isUseLocalCandidates()) {
for (Bytestream.StreamHost host : transportManager().getLocalStreamHosts()) { for (Bytestream.StreamHost host : transportManager().getLocalStreamHosts()) {
jb.addTransportCandidate(new JingleS5BTransportCandidate(host, 100, JingleS5BTransportCandidate.Type.direct)); jb.addTransportCandidate(new JingleS5BTransportCandidate(host, 100, JingleS5BTransportCandidate.Type.direct));
@ -204,7 +204,7 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
case JingleS5BTransportInfo.ProxyError.ELEMENT: case JingleS5BTransportInfo.ProxyError.ELEMENT:
return handleProxyError(transportInfo); return handleProxyError(transportInfo);
} }
//We should never go here, but lets be gracious... // We should never go here, but lets be gracious...
return IQ.createResultIQ(transportInfo); return IQ.createResultIQ(transportInfo);
} }
@ -239,7 +239,7 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
} }
public IQ handleProxyError(Jingle jingle) { public IQ handleProxyError(Jingle jingle) {
//TODO // TODO
return IQ.createResultIQ(jingle); return IQ.createResultIQ(jingle);
} }
@ -265,7 +265,7 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
LOGGER.log(Level.INFO, "Ready."); LOGGER.log(Level.INFO, "Ready.");
//Determine nominated candidate. // Determine nominated candidate.
UsedCandidate nominated; UsedCandidate nominated;
if (ourChoice != CANDIDATE_FAILURE && theirChoice != CANDIDATE_FAILURE) { if (ourChoice != CANDIDATE_FAILURE && theirChoice != CANDIDATE_FAILURE) {
if (ourChoice.candidate.getPriority() > theirChoice.candidate.getPriority()) { if (ourChoice.candidate.getPriority() > theirChoice.candidate.getPriority()) {
@ -288,7 +288,7 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
nominated = connectToOurCandidate(nominated.candidate); nominated = connectToOurCandidate(nominated.candidate);
} catch (InterruptedException | IOException | XMPPException | SmackException | TimeoutException e) { } catch (InterruptedException | IOException | XMPPException | SmackException | TimeoutException e) {
LOGGER.log(Level.INFO, "Could not connect to our candidate.", e); LOGGER.log(Level.INFO, "Could not connect to our candidate.", e);
//TODO: Proxy-Error // TODO: Proxy-Error
return; return;
} }
@ -326,7 +326,7 @@ public class JingleS5BTransportSession extends JingleTransportSession<JingleS5BT
callback.onSessionInitiated(bs); callback.onSessionInitiated(bs);
} }
//Our choice // Our choice
else { else {
LOGGER.log(Level.INFO, "Our choice, so their candidate was used."); LOGGER.log(Level.INFO, "Our choice, so their candidate was used.");
boolean isProxy = nominated.candidate.getType() == JingleS5BTransportCandidate.Type.proxy; boolean isProxy = nominated.candidate.getType() == JingleS5BTransportCandidate.Type.proxy;

View File

@ -333,7 +333,7 @@ public class MultiUserChat {
new NotFilter(MessageWithThreadFilter.INSTANCE)) new NotFilter(MessageWithThreadFilter.INSTANCE))
); );
// @formatter:on // @formatter:on
connection.addSyncStanzaListener(declinesListener, DECLINE_FILTER); connection.addSyncStanzaListener(declinesListener, new AndFilter(fromRoomFilter, DECLINE_FILTER));
connection.addPacketInterceptor(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room), connection.addPacketInterceptor(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room),
StanzaTypeFilter.PRESENCE)); StanzaTypeFilter.PRESENCE));
messageCollector = connection.createStanzaCollector(fromRoomGroupchatFilter); messageCollector = connection.createStanzaCollector(fromRoomGroupchatFilter);
@ -727,20 +727,19 @@ public class MultiUserChat {
* @throws InterruptedException * @throws InterruptedException
*/ */
public synchronized void leave() throws NotConnectedException, InterruptedException { public synchronized void leave() throws NotConnectedException, InterruptedException {
// If not joined already, do nothing. // Note that this method is intentionally not guarded by
if (!joined) { // "if (!joined) return" because it should be always be possible to leave the room in case the instance's
return; // state does not reflect the actual state.
}
// Reset occupant information first so that we are assume that we left the room even if sendStanza() would
// throw.
userHasLeft();
// We leave a room by sending a presence packet where the "to" // We leave a room by sending a presence packet where the "to"
// field is in the form "roomName@service/nickname" // field is in the form "roomName@service/nickname"
Presence leavePresence = new Presence(Presence.Type.unavailable); Presence leavePresence = new Presence(Presence.Type.unavailable);
leavePresence.setTo(JidCreate.fullFrom(room, nickname)); leavePresence.setTo(JidCreate.fullFrom(room, nickname));
connection.sendStanza(leavePresence); connection.sendStanza(leavePresence);
// Reset occupant information.
occupantsMap.clear();
nickname = null;
joined = false;
userHasLeft();
} }
/** /**
@ -878,12 +877,21 @@ public class MultiUserChat {
Destroy destroy = new Destroy(alternateJID, reason); Destroy destroy = new Destroy(alternateJID, reason);
iq.setDestroy(destroy); iq.setDestroy(destroy);
connection.createStanzaCollectorAndSend(iq).nextResultOrThrow(); try {
connection.createStanzaCollectorAndSend(iq).nextResultOrThrow();
}
catch (XMPPErrorException e) {
// Note that we do not call userHasLeft() here because an XMPPErrorException would usually indicate that the
// room was not destroyed and we therefore we also did not leave the room.
throw e;
}
catch (NoResponseException | NotConnectedException | InterruptedException e) {
// Reset occupant information.
userHasLeft();
throw e;
}
// Reset occupant information. // Reset occupant information.
occupantsMap.clear();
nickname = null;
joined = false;
userHasLeft(); userHasLeft();
} }
@ -2011,6 +2019,7 @@ public class MultiUserChat {
private void removeConnectionCallbacks() { private void removeConnectionCallbacks() {
connection.removeSyncStanzaListener(messageListener); connection.removeSyncStanzaListener(messageListener);
connection.removeSyncStanzaListener(presenceListener); connection.removeSyncStanzaListener(presenceListener);
connection.removeSyncStanzaListener(subjectListener);
connection.removeSyncStanzaListener(declinesListener); connection.removeSyncStanzaListener(declinesListener);
connection.removePacketInterceptor(presenceInterceptor); connection.removePacketInterceptor(presenceInterceptor);
if (messageCollector != null) { if (messageCollector != null) {
@ -2023,6 +2032,11 @@ public class MultiUserChat {
* Remove all callbacks and resources necessary when the user has left the room for some reason. * Remove all callbacks and resources necessary when the user has left the room for some reason.
*/ */
private synchronized void userHasLeft() { private synchronized void userHasLeft() {
// We do not reset nickname here, in case this method has been called erroneously, it should still be possible
// to call leave() in order to resync the state. And leave() requires the nickname to send the unsubscribe
// presence.
occupantsMap.clear();
joined = false;
// Update the list of joined rooms // Update the list of joined rooms
multiUserChatManager.removeJoinedRoom(room); multiUserChatManager.removeJoinedRoom(room);
removeConnectionCallbacks(); removeConnectionCallbacks();
@ -2340,15 +2354,12 @@ public class MultiUserChat {
if (statusCodes.contains(Status.KICKED_307)) { if (statusCodes.contains(Status.KICKED_307)) {
// Check if this occupant was kicked // Check if this occupant was kicked
if (isUserModification) { if (isUserModification) {
joined = false; // Reset occupant information.
userHasLeft();
for (UserStatusListener listener : userStatusListeners) { for (UserStatusListener listener : userStatusListeners) {
listener.kicked(mucUser.getItem().getActor(), mucUser.getItem().getReason()); listener.kicked(mucUser.getItem().getActor(), mucUser.getItem().getReason());
} }
// Reset occupant information.
occupantsMap.clear();
nickname = null;
userHasLeft();
} }
else { else {
for (ParticipantStatusListener listener : participantStatusListeners) { for (ParticipantStatusListener listener : participantStatusListeners) {
@ -2397,7 +2408,7 @@ public class MultiUserChat {
listener.nicknameChanged(from, mucUser.getItem().getNick()); listener.nicknameChanged(from, mucUser.getItem().getNick());
} }
} }
//The room has been destroyed // The room has been destroyed.
if (mucUser.getDestroy() != null) { if (mucUser.getDestroy() != null) {
MultiUserChat alternateMUC = multiUserChatManager.getMultiUserChat(mucUser.getDestroy().getJid()); MultiUserChat alternateMUC = multiUserChatManager.getMultiUserChat(mucUser.getDestroy().getJid());
for (UserStatusListener listener : userStatusListeners) { for (UserStatusListener listener : userStatusListeners) {

View File

@ -19,6 +19,8 @@ package org.jivesoftware.smackx.offline;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
@ -58,6 +60,8 @@ import org.jivesoftware.smackx.xdata.Form;
*/ */
public class OfflineMessageManager { public class OfflineMessageManager {
private static final Logger LOGGER = Logger.getLogger(OfflineMessageManager.class.getName());
private final static String namespace = "http://jabber.org/protocol/offline"; private final static String namespace = "http://jabber.org/protocol/offline";
private final XMPPConnection connection; private final XMPPConnection connection;
@ -144,7 +148,7 @@ public class OfflineMessageManager {
* @throws InterruptedException * @throws InterruptedException
*/ */
public List<Message> getMessages(final List<String> nodes) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public List<Message> getMessages(final List<String> nodes) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
List<Message> messages = new ArrayList<Message>(); List<Message> messages = new ArrayList<Message>(nodes.size());
OfflineMessageRequest request = new OfflineMessageRequest(); OfflineMessageRequest request = new OfflineMessageRequest();
for (String node : nodes) { for (String node : nodes) {
OfflineMessageRequest.Item item = new OfflineMessageRequest.Item(node); OfflineMessageRequest.Item item = new OfflineMessageRequest.Item(node);
@ -165,12 +169,17 @@ public class OfflineMessageManager {
try { try {
connection.createStanzaCollectorAndSend(request).nextResultOrThrow(); connection.createStanzaCollectorAndSend(request).nextResultOrThrow();
// Collect the received offline messages // Collect the received offline messages
Message message = messageCollector.nextResult(); Message message;
while (message != null && pendingNodes > 0) { do {
pendingNodes--;
messages.add(message);
message = messageCollector.nextResult(); message = messageCollector.nextResult();
} if (message != null) {
messages.add(message);
pendingNodes--;
} else if (message == null && pendingNodes > 0) {
LOGGER.log(Level.WARNING,
"Did not receive all expected offline messages. " + pendingNodes + " are missing.");
}
} while (message != null && pendingNodes > 0);
} }
finally { finally {
// Stop queuing offline messages // Stop queuing offline messages

View File

@ -704,7 +704,7 @@ public class VCard extends IQ {
} }
private boolean hasContent() { private boolean hasContent() {
//noinspection OverlyComplexBooleanExpression // noinspection OverlyComplexBooleanExpression
return hasNameField() return hasNameField()
|| hasOrganizationFields() || hasOrganizationFields()
|| emailHome != null || emailHome != null

View File

@ -55,8 +55,8 @@ public class VersionTest extends InitExtensions {
assertTrue(replyPacket instanceof Version); assertTrue(replyPacket instanceof Version);
Version reply = (Version) replyPacket; Version reply = (Version) replyPacket;
//getFrom check is pending for SMACK-547 // getFrom check is pending for SMACK-547
//assertEquals("juliet@capulet.lit/balcony", reply.getFrom()); // assertEquals("juliet@capulet.lit/balcony", reply.getFrom());
assertThat("capulet.lit", equalsCharSequence(reply.getTo())); assertThat("capulet.lit", equalsCharSequence(reply.getTo()));
assertEquals("s2c1", reply.getStanzaId()); assertEquals("s2c1", reply.getStanzaId());
assertEquals(IQ.Type.result, reply.getType()); assertEquals(IQ.Type.result, reply.getType());

View File

@ -124,7 +124,7 @@ public class PingTest extends InitExtensions {
@Test @Test
public void checkFailedPingToEntityError() throws Exception { public void checkFailedPingToEntityError() throws Exception {
ThreadedDummyConnection threadedCon = getAuthentiactedDummyConnection(); ThreadedDummyConnection threadedCon = getAuthentiactedDummyConnection();
//@formatter:off // @formatter:off
String reply = String reply =
"<iq type='error' id='qrzSp-16' to='test@myserver.com'>" + "<iq type='error' id='qrzSp-16' to='test@myserver.com'>" +
"<ping xmlns='urn:xmpp:ping'/>" + "<ping xmlns='urn:xmpp:ping'/>" +
@ -132,7 +132,7 @@ public class PingTest extends InitExtensions {
"<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" + "<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" +
"</error>" + "</error>" +
"</iq>"; "</iq>";
//@formatter:on // @formatter:on
IQ serviceUnavailable = (IQ) PacketParserUtils.parseStanza(reply); IQ serviceUnavailable = (IQ) PacketParserUtils.parseStanza(reply);
threadedCon.addIQReply(serviceUnavailable); threadedCon.addIQReply(serviceUnavailable);
@ -160,7 +160,7 @@ public class PingTest extends InitExtensions {
@Test @Test
public void checkPingToServerError() throws Exception { public void checkPingToServerError() throws Exception {
ThreadedDummyConnection con = getAuthentiactedDummyConnection(); ThreadedDummyConnection con = getAuthentiactedDummyConnection();
//@formatter:off // @formatter:off
String reply = String reply =
"<iq type='error' id='qrzSp-16' to='test@myserver.com' from='" + con.getXMPPServiceDomain() + "'>" + "<iq type='error' id='qrzSp-16' to='test@myserver.com' from='" + con.getXMPPServiceDomain() + "'>" +
"<ping xmlns='urn:xmpp:ping'/>" + "<ping xmlns='urn:xmpp:ping'/>" +
@ -168,7 +168,7 @@ public class PingTest extends InitExtensions {
"<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" + "<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" +
"</error>" + "</error>" +
"</iq>"; "</iq>";
//@formatter:on // @formatter:on
IQ serviceUnavailable = (IQ) PacketParserUtils.parseStanza(reply); IQ serviceUnavailable = (IQ) PacketParserUtils.parseStanza(reply);
con.addIQReply(serviceUnavailable); con.addIQReply(serviceUnavailable);
@ -194,13 +194,13 @@ public class PingTest extends InitExtensions {
DiscoverInfo info = new DiscoverInfo(); DiscoverInfo info = new DiscoverInfo();
info.addFeature(Ping.NAMESPACE); info.addFeature(Ping.NAMESPACE);
//@formatter:off // @formatter:off
String reply = String reply =
"<iq type='result' id='qrzSp-16' to='test@myserver.com'>" + "<iq type='result' id='qrzSp-16' to='test@myserver.com'>" +
"<query xmlns='http://jabber.org/protocol/disco#info'><identity category='client' type='pc' name='Pidgin'/>" + "<query xmlns='http://jabber.org/protocol/disco#info'><identity category='client' type='pc' name='Pidgin'/>" +
"<feature var='urn:xmpp:ping'/>" + "<feature var='urn:xmpp:ping'/>" +
"</query></iq>"; "</query></iq>";
//@formatter:on // @formatter:on
IQ discoReply = (IQ) PacketParserUtils.parseStanza(reply); IQ discoReply = (IQ) PacketParserUtils.parseStanza(reply);
con.addIQReply(discoReply); con.addIQReply(discoReply);
@ -216,13 +216,13 @@ public class PingTest extends InitExtensions {
DiscoverInfo info = new DiscoverInfo(); DiscoverInfo info = new DiscoverInfo();
info.addFeature(Ping.NAMESPACE); info.addFeature(Ping.NAMESPACE);
//@formatter:off // @formatter:off
String reply = String reply =
"<iq type='result' id='qrzSp-16' to='test@myserver.com'>" + "<iq type='result' id='qrzSp-16' to='test@myserver.com'>" +
"<query xmlns='http://jabber.org/protocol/disco#info'><identity category='client' type='pc' name='Pidgin'/>" + "<query xmlns='http://jabber.org/protocol/disco#info'><identity category='client' type='pc' name='Pidgin'/>" +
"<feature var='urn:xmpp:noping'/>" + "<feature var='urn:xmpp:noping'/>" +
"</query></iq>"; "</query></iq>";
//@formatter:on // @formatter:on
IQ discoReply = (IQ) PacketParserUtils.parseStanza(reply); IQ discoReply = (IQ) PacketParserUtils.parseStanza(reply);
con.addIQReply(discoReply); con.addIQReply(discoReply);

View File

@ -50,7 +50,7 @@ public class DataFormTest {
@Test @Test
public void test() throws Exception { public void test() throws Exception {
//Build a Form // Build a Form.
DataForm df = new DataForm(DataForm.Type.submit); DataForm df = new DataForm(DataForm.Type.submit);
String instruction = "InstructionTest1"; String instruction = "InstructionTest1";
df.addInstruction(instruction); df.addInstruction(instruction);
@ -77,7 +77,7 @@ public class DataFormTest {
@Test @Test
public void testLayout() throws Exception { public void testLayout() throws Exception {
//Build a Form // Build a Form.
DataForm df = new DataForm(DataForm.Type.submit); DataForm df = new DataForm(DataForm.Type.submit);
String instruction = "InstructionTest1"; String instruction = "InstructionTest1";
df.addInstruction(instruction); df.addInstruction(instruction);
@ -119,7 +119,7 @@ public class DataFormTest {
@Test @Test
public void testValidation() throws Exception { public void testValidation() throws Exception {
//Build a Form // Build a Form.
DataForm df = new DataForm(DataForm.Type.submit); DataForm df = new DataForm(DataForm.Type.submit);
String instruction = "InstructionTest1"; String instruction = "InstructionTest1";
df.addInstruction(instruction); df.addInstruction(instruction);

View File

@ -251,9 +251,10 @@ public final class Roster extends Manager {
connection.addSyncStanzaListener(presencePacketListener, PRESENCE_PACKET_FILTER); connection.addSyncStanzaListener(presencePacketListener, PRESENCE_PACKET_FILTER);
connection.addAsyncStanzaListener(new StanzaListener() { connection.addAsyncStanzaListener(new StanzaListener() {
@SuppressWarnings("fallthrough")
@Override @Override
public void processStanza(Stanza stanza) throws NotConnectedException, public void processStanza(Stanza stanza) throws NotConnectedException,
InterruptedException { InterruptedException, NotLoggedInException {
Presence presence = (Presence) stanza; Presence presence = (Presence) stanza;
Jid from = presence.getFrom(); Jid from = presence.getFrom();
SubscribeAnswer subscribeAnswer = null; SubscribeAnswer subscribeAnswer = null;
@ -279,13 +280,26 @@ public final class Roster extends Manager {
break; break;
} }
if (subscribeAnswer == null) {
return;
}
Presence response; Presence response;
if (subscribeAnswer == SubscribeAnswer.Approve) { switch (subscribeAnswer) {
case ApproveAndAlsoRequestIfRequired:
BareJid bareFrom = from.asBareJid();
RosterUtil.askForSubscriptionIfRequired(Roster.this, bareFrom);
// The fall through is intended.
case Approve:
response = new Presence(Presence.Type.subscribed); response = new Presence(Presence.Type.subscribed);
} break;
else { case Deny:
response = new Presence(Presence.Type.unsubscribed); response = new Presence(Presence.Type.unsubscribed);
break;
default:
throw new AssertionError();
} }
response.setTo(presence.getFrom()); response.setTo(presence.getFrom());
connection.sendStanza(response); connection.sendStanza(response);
} }

View File

@ -23,6 +23,7 @@ import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import org.jivesoftware.smack.SmackException.FeatureNotSupportedException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException; import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
@ -86,6 +87,33 @@ public class RosterUtil {
} }
} }
/**
* Pre-approve the subscription if it is required and possible.
*
* @param roster The roster which should be used for the pre-approval.
* @param jid The XMPP address which should be pre-approved.
* @throws NotLoggedInException
* @throws NotConnectedException
* @throws InterruptedException
* @since 4.2.2
*/
public static void preApproveSubscriptionIfRequiredAndPossible(Roster roster, BareJid jid)
throws NotLoggedInException, NotConnectedException, InterruptedException {
if (!roster.isSubscriptionPreApprovalSupported()) {
return;
}
RosterEntry entry = roster.getEntry(jid);
if (entry == null || (!entry.canSeeMyPresence() && !entry.isApproved())) {
try {
roster.preApprove(jid);
} catch (FeatureNotSupportedException e) {
// Should never happen since we checked for the feature above.
throw new AssertionError(e);
}
}
}
public static void askForSubscriptionIfRequired(Roster roster, BareJid jid) public static void askForSubscriptionIfRequired(Roster roster, BareJid jid)
throws NotLoggedInException, NotConnectedException, InterruptedException { throws NotLoggedInException, NotConnectedException, InterruptedException {
RosterEntry entry = roster.getEntry(jid); RosterEntry entry = roster.getEntry(jid);

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2015 Florian Schmaus * Copyright 2015-2017 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,13 +23,29 @@ import org.jxmpp.jid.Jid;
/** /**
* Handle incoming requests to subscribe to our presence. * Handle incoming requests to subscribe to our presence. The
* {@link #processSubscribe(Jid, Presence)} method may return a subscribe
* answer. If no subscribe answer is returned, the next listener will be
* notified and asked. If no listener returns an answer, then nothing happens.
* *
*/ */
public interface SubscribeListener { public interface SubscribeListener {
public enum SubscribeAnswer { public enum SubscribeAnswer {
/**
* Approve the subscription request.
*/
Approve, Approve,
/**
* Approve the subscription request and also request subscription from the other party if not already subscribed.
* @since 4.2.2
*/
ApproveAndAlsoRequestIfRequired,
/**
* Deny the subscription request.
*/
Deny, Deny,
} }

View File

@ -58,7 +58,7 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest {
EntityBareJid userOne = conOne.getUser().asEntityBareJid(); EntityBareJid userOne = conOne.getUser().asEntityBareJid();
EntityBareJid userTwo = conTwo.getUser().asEntityBareJid(); EntityBareJid userTwo = conTwo.getUser().asEntityBareJid();
//Make sure MAM is archiving messages // Make sure MAM is archiving messages.
mamManagerConTwo.updateArchivingPreferences(null, null, MamPrefsIQ.DefaultBehavior.always); mamManagerConTwo.updateArchivingPreferences(null, null, MamPrefsIQ.DefaultBehavior.always);
Message message = new Message(userTwo); Message message = new Message(userTwo);

View File

@ -55,7 +55,7 @@ public abstract class AbstractOmemoIntegrationTest extends AbstractSmackIntegrat
throw new TestNotPossibleException("Server does not support OMEMO (PubSub)"); throw new TestNotPossibleException("Server does not support OMEMO (PubSub)");
} }
//Check for OmemoService // Check for OmemoService
if (!OmemoService.isServiceRegistered()) { if (!OmemoService.isServiceRegistered()) {
throw new TestNotPossibleException("No OmemoService registered."); throw new TestNotPossibleException("No OmemoService registered.");
} }

View File

@ -57,14 +57,14 @@ public class OmemoInitializationTest extends AbstractOmemoIntegrationTest {
*/ */
@SmackIntegrationTest @SmackIntegrationTest
public void initializationTest() throws XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, SmackException.NotLoggedInException, CorruptedOmemoKeyException, NotAPubSubNodeException { public void initializationTest() throws XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, SmackException.NotLoggedInException, CorruptedOmemoKeyException, NotAPubSubNodeException {
//test keys. // test keys.
setUpOmemoManager(alice); setUpOmemoManager(alice);
assertNotNull("IdentityKey must not be null after initialization.", store.loadOmemoIdentityKeyPair(alice)); assertNotNull("IdentityKey must not be null after initialization.", store.loadOmemoIdentityKeyPair(alice));
assertTrue("We must have " + OmemoConstants.TARGET_PRE_KEY_COUNT + " preKeys.", assertTrue("We must have " + OmemoConstants.TARGET_PRE_KEY_COUNT + " preKeys.",
store.loadOmemoPreKeys(alice).size() == OmemoConstants.TARGET_PRE_KEY_COUNT); store.loadOmemoPreKeys(alice).size() == OmemoConstants.TARGET_PRE_KEY_COUNT);
assertNotNull("Our signedPreKey must not be null.", store.loadCurrentSignedPreKeyId(alice)); assertNotNull("Our signedPreKey must not be null.", store.loadCurrentSignedPreKeyId(alice));
//Is deviceId published? // Is deviceId published?
assertTrue("Published deviceList must contain our deviceId.", assertTrue("Published deviceList must contain our deviceId.",
OmemoService.fetchDeviceList(alice, alice.getOwnJid()) OmemoService.fetchDeviceList(alice, alice.getOwnJid())
.getDeviceIds().contains(alice.getDeviceId())); .getDeviceIds().contains(alice.getDeviceId()));

View File

@ -63,7 +63,7 @@ final class OmemoIntegrationTestHelper {
try { try {
omemoManager.requestDeviceListUpdateFor(omemoManager.getOwnJid()); omemoManager.requestDeviceListUpdateFor(omemoManager.getOwnJid());
} catch (SmackException.NotConnectedException | InterruptedException | SmackException.NoResponseException e) { } catch (SmackException.NotConnectedException | InterruptedException | SmackException.NoResponseException e) {
//ignore // ignore
} }
CachedDeviceList deviceList = OmemoService.getInstance().getOmemoStoreBackend().loadCachedDeviceList(omemoManager, omemoManager.getOwnJid()); CachedDeviceList deviceList = OmemoService.getInstance().getOmemoStoreBackend().loadCachedDeviceList(omemoManager, omemoManager.getOwnJid());
@ -71,26 +71,26 @@ final class OmemoIntegrationTestHelper {
try { try {
pm.getLeafNode(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(id)).deleteAllItems(); pm.getLeafNode(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(id)).deleteAllItems();
} catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | NotAPubSubNodeException e) { } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | NotAPubSubNodeException e) {
//Silent // Silent
} }
try { try {
pm.deleteNode(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(id)); pm.deleteNode(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(id));
} catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
//Silent // Silent
} }
} }
try { try {
pm.getLeafNode(OmemoConstants.PEP_NODE_DEVICE_LIST).deleteAllItems(); pm.getLeafNode(OmemoConstants.PEP_NODE_DEVICE_LIST).deleteAllItems();
} catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | NotAPubSubNodeException e) { } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | NotAPubSubNodeException e) {
//Silent // Silent
} }
try { try {
pm.deleteNode(OmemoConstants.PEP_NODE_DEVICE_LIST); pm.deleteNode(OmemoConstants.PEP_NODE_DEVICE_LIST);
} catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
//Silent // Silent
} }
} }
@ -100,7 +100,7 @@ final class OmemoIntegrationTestHelper {
try { try {
roster.removeEntry(r); roster.removeEntry(r);
} catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | SmackException.NotLoggedInException e) { } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | SmackException.NotLoggedInException e) {
//Silent // Silent
} }
} }
} }
@ -128,7 +128,7 @@ final class OmemoIntegrationTestHelper {
static void unidirectionalTrust(OmemoManager alice, OmemoManager bob) throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, CannotEstablishOmemoSessionException { static void unidirectionalTrust(OmemoManager alice, OmemoManager bob) throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, CannotEstablishOmemoSessionException {
//Fetch deviceList // Fetch deviceList
alice.requestDeviceListUpdateFor(bob.getOwnJid()); alice.requestDeviceListUpdateFor(bob.getOwnJid());
LOGGER.log(Level.INFO, "Current deviceList state: " + alice.getOwnDevice() + " knows " + bob.getOwnDevice() + ": " LOGGER.log(Level.INFO, "Current deviceList state: " + alice.getOwnDevice() + " knows " + bob.getOwnDevice() + ": "
+ OmemoService.getInstance().getOmemoStoreBackend().loadCachedDeviceList(alice, bob.getOwnJid())); + OmemoService.getInstance().getOmemoStoreBackend().loadCachedDeviceList(alice, bob.getOwnJid()));
@ -136,12 +136,12 @@ final class OmemoIntegrationTestHelper {
alice.getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(alice, bob.getOwnJid()) alice.getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(alice, bob.getOwnJid())
.getActiveDevices().contains(bob.getDeviceId())); .getActiveDevices().contains(bob.getDeviceId()));
//Create sessions // Create sessions
alice.buildSessionsWith(bob.getOwnJid()); alice.buildSessionsWith(bob.getOwnJid());
assertTrue("Trusting party must have a session with the other end at this point.", assertTrue("Trusting party must have a session with the other end at this point.",
!alice.getOmemoService().getOmemoStoreBackend().loadAllRawSessionsOf(alice, bob.getOwnJid()).isEmpty()); !alice.getOmemoService().getOmemoStoreBackend().loadAllRawSessionsOf(alice, bob.getOwnJid()).isEmpty());
//Trust the other party // Trust the other party
alice.getOmemoService().getOmemoStoreBackend().trustOmemoIdentity(alice, bob.getOwnDevice(), alice.getOmemoService().getOmemoStoreBackend().trustOmemoIdentity(alice, bob.getOwnDevice(),
alice.getOmemoService().getOmemoStoreBackend().getFingerprint(alice, bob.getOwnDevice())); alice.getOmemoService().getOmemoStoreBackend().getFingerprint(alice, bob.getOwnDevice()));

View File

@ -79,7 +79,7 @@ public class OmemoKeyTransportTest extends AbstractOmemoIntegrationTest {
bob.addOmemoMessageListener(new OmemoMessageListener() { bob.addOmemoMessageListener(new OmemoMessageListener() {
@Override @Override
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) { public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
//Don't care // Don't care
} }
@Override @Override

View File

@ -101,23 +101,23 @@ public class OmemoMessageSendingTest extends AbstractOmemoIntegrationTest {
final SimpleResultSyncPoint messageOneSyncPoint = new SimpleResultSyncPoint(); final SimpleResultSyncPoint messageOneSyncPoint = new SimpleResultSyncPoint();
final SimpleResultSyncPoint messageTwoSyncPoint = new SimpleResultSyncPoint(); final SimpleResultSyncPoint messageTwoSyncPoint = new SimpleResultSyncPoint();
//Subscribe to one another // Subscribe to one another
subscribe(alice, bob, "Bob"); subscribe(alice, bob, "Bob");
subscribe(bob, alice,"Alice"); subscribe(bob, alice,"Alice");
//initialize OmemoManagers // initialize OmemoManagers
setUpOmemoManager(alice); setUpOmemoManager(alice);
setUpOmemoManager(bob); setUpOmemoManager(bob);
//Save initial bundles // Save initial bundles
OmemoBundleElement aliceBundle = store.packOmemoBundle(alice); OmemoBundleElement aliceBundle = store.packOmemoBundle(alice);
OmemoBundleElement bobsBundle = store.packOmemoBundle(bob); OmemoBundleElement bobsBundle = store.packOmemoBundle(bob);
//Trust // Trust
unidirectionalTrust(alice, bob); unidirectionalTrust(alice, bob);
unidirectionalTrust(bob, alice); unidirectionalTrust(bob, alice);
//Register messageListeners // Register messageListeners
bob.addOmemoMessageListener(new OmemoMessageListener() { bob.addOmemoMessageListener(new OmemoMessageListener() {
@Override @Override
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) { public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
@ -151,7 +151,7 @@ public class OmemoMessageSendingTest extends AbstractOmemoIntegrationTest {
} }
}); });
//Prepare Alice message for Bob // Prepare Alice message for Bob
Message encryptedA = alice.encrypt(bob.getOwnJid(), alicesSecret); Message encryptedA = alice.encrypt(bob.getOwnJid(), alicesSecret);
ChatManager.getInstanceFor(alice.getConnection()).chatWith(bob.getOwnJid().asEntityBareJidIfPossible()) ChatManager.getInstanceFor(alice.getConnection()).chatWith(bob.getOwnJid().asEntityBareJidIfPossible())
.send(encryptedA); .send(encryptedA);
@ -163,11 +163,11 @@ public class OmemoMessageSendingTest extends AbstractOmemoIntegrationTest {
TestCase.fail("Bob must have received Alice message."); TestCase.fail("Bob must have received Alice message.");
} }
//Check if Bob published a new Bundle // Check if Bob published a new Bundle
assertNotSame("Bob must have published another bundle at this point, since we used a PreKeyMessage.", assertNotSame("Bob must have published another bundle at this point, since we used a PreKeyMessage.",
bobsBundle, OmemoService.fetchBundle(alice, bob.getOwnDevice())); bobsBundle, OmemoService.fetchBundle(alice, bob.getOwnDevice()));
//Prepare Bobs response // Prepare Bobs response
Message encryptedB = bob.encrypt(alice.getOwnJid(), bobsSecret); Message encryptedB = bob.encrypt(alice.getOwnJid(), bobsSecret);
ChatManager.getInstanceFor(bob.getConnection()).chatWith(alice.getOwnJid().asEntityBareJidIfPossible()) ChatManager.getInstanceFor(bob.getConnection()).chatWith(alice.getOwnJid().asEntityBareJidIfPossible())
.send(encryptedB); .send(encryptedB);

View File

@ -56,7 +56,7 @@ public class OmemoStoreTest extends AbstractOmemoIntegrationTest {
@SmackIntegrationTest @SmackIntegrationTest
public void storeTest() throws Exception { public void storeTest() throws Exception {
//########### PRE-INITIALIZATION ############ // ########### PRE-INITIALIZATION ############
assertEquals("Creating an OmemoManager without MUST have set the default deviceId.", alice.getDeviceId(), OmemoService.getInstance().getOmemoStoreBackend().getDefaultDeviceId(alice.getOwnJid())); assertEquals("Creating an OmemoManager without MUST have set the default deviceId.", alice.getDeviceId(), OmemoService.getInstance().getOmemoStoreBackend().getDefaultDeviceId(alice.getOwnJid()));
assertEquals("OmemoManager must be equal, since both got created without giving a deviceId.", alice, bob); assertEquals("OmemoManager must be equal, since both got created without giving a deviceId.", alice, bob);
@ -69,11 +69,11 @@ public class OmemoStoreTest extends AbstractOmemoIntegrationTest {
OmemoStore<?,?,?,?,?,?,?,?,?> store = OmemoService.getInstance().getOmemoStoreBackend(); OmemoStore<?,?,?,?,?,?,?,?,?> store = OmemoService.getInstance().getOmemoStoreBackend();
OmemoFingerprint finger = new OmemoFingerprint("FINGER"); OmemoFingerprint finger = new OmemoFingerprint("FINGER");
//DefaultDeviceId // DefaultDeviceId
store.setDefaultDeviceId(alice.getOwnJid(), 777); store.setDefaultDeviceId(alice.getOwnJid(), 777);
assertEquals("defaultDeviceId setting/getting must equal.", 777, store.getDefaultDeviceId(alice.getOwnJid())); assertEquals("defaultDeviceId setting/getting must equal.", 777, store.getDefaultDeviceId(alice.getOwnJid()));
//Trust/Distrust/Decide // Trust/Distrust/Decide
bob.shutdown(); bob.shutdown();
bob = OmemoManager.getInstanceFor(conTwo, 998); bob = OmemoManager.getInstanceFor(conTwo, 998);
assertFalse("Bobs device MUST be undecided at this point", assertFalse("Bobs device MUST be undecided at this point",
@ -89,7 +89,7 @@ public class OmemoStoreTest extends AbstractOmemoIntegrationTest {
assertFalse("Bobs device MUST be untrusted at this point.", assertFalse("Bobs device MUST be untrusted at this point.",
store.isTrustedOmemoIdentity(alice, bob.getOwnDevice(), finger)); store.isTrustedOmemoIdentity(alice, bob.getOwnDevice(), finger));
//Dates // Dates
assertNull("Date of last received message must be null when no message was received ever.", assertNull("Date of last received message must be null when no message was received ever.",
store.getDateOfLastReceivedMessage(alice, bob.getOwnDevice())); store.getDateOfLastReceivedMessage(alice, bob.getOwnDevice()));
Date now = new Date(); Date now = new Date();
@ -102,7 +102,7 @@ public class OmemoStoreTest extends AbstractOmemoIntegrationTest {
assertEquals("Date of last signed prekey renewal must match our date.", assertEquals("Date of last signed prekey renewal must match our date.",
now, store.getDateOfLastSignedPreKeyRenewal(alice)); now, store.getDateOfLastSignedPreKeyRenewal(alice));
//Keys // Keys
assertNull("IdentityKeyPair must be null at this point.", assertNull("IdentityKeyPair must be null at this point.",
store.loadOmemoIdentityKeyPair(alice)); store.loadOmemoIdentityKeyPair(alice));
assertNull("IdentityKey of contact must be null at this point.", assertNull("IdentityKey of contact must be null at this point.",
@ -118,7 +118,7 @@ public class OmemoStoreTest extends AbstractOmemoIntegrationTest {
100, store.generateOmemoPreKeys(1, 100).size()); 100, store.generateOmemoPreKeys(1, 100).size());
//LastPreKeyId // LastPreKeyId
assertEquals("LastPreKeyId must be 0 at this point.", assertEquals("LastPreKeyId must be 0 at this point.",
0, store.loadLastPreKeyId(alice)); 0, store.loadLastPreKeyId(alice));
store.storeLastPreKeyId(alice, 1234); store.storeLastPreKeyId(alice, 1234);
@ -126,7 +126,7 @@ public class OmemoStoreTest extends AbstractOmemoIntegrationTest {
assertEquals("LastPreKeyId set/get must equal.", 1234, store.loadLastPreKeyId(alice)); assertEquals("LastPreKeyId set/get must equal.", 1234, store.loadLastPreKeyId(alice));
store.storeLastPreKeyId(alice, 0); store.storeLastPreKeyId(alice, 0);
//CurrentSignedPreKeyId // CurrentSignedPreKeyId
assertEquals("CurrentSignedPreKeyId must be 0 at this point.", assertEquals("CurrentSignedPreKeyId must be 0 at this point.",
0, store.loadCurrentSignedPreKeyId(alice)); 0, store.loadCurrentSignedPreKeyId(alice));
store.storeCurrentSignedPreKeyId(alice, 554); store.storeCurrentSignedPreKeyId(alice, 554);
@ -137,10 +137,10 @@ public class OmemoStoreTest extends AbstractOmemoIntegrationTest {
deletePath(alice); deletePath(alice);
//################# POST-INITIALIZATION ################# // ################# POST-INITIALIZATION #################
setUpOmemoManager(alice); setUpOmemoManager(alice);
//Keys // Keys
assertNotNull("IdentityKeyPair must not be null after initialization", assertNotNull("IdentityKeyPair must not be null after initialization",
store.loadOmemoIdentityKeyPair(alice)); store.loadOmemoIdentityKeyPair(alice));
assertNotSame("LastPreKeyId must not be 0 after initialization.", assertNotSame("LastPreKeyId must not be 0 after initialization.",

View File

@ -45,7 +45,7 @@ public abstract class JingleNegotiator {
private static final Logger LOGGER = Logger.getLogger(JingleNegotiator.class.getName()); private static final Logger LOGGER = Logger.getLogger(JingleNegotiator.class.getName());
//private XMPPConnection connection; // The connection associated // private XMPPConnection connection; // The connection associated
protected JingleSession session; protected JingleSession session;

View File

@ -148,7 +148,7 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList
public JingleSession(XMPPConnection conn, JingleSessionRequest request, Jid initiator, Jid responder, public JingleSession(XMPPConnection conn, JingleSessionRequest request, Jid initiator, Jid responder,
List<JingleMediaManager> jingleMediaManagers) { List<JingleMediaManager> jingleMediaManagers) {
this(conn, initiator, responder, generateSessionId(), jingleMediaManagers); this(conn, initiator, responder, generateSessionId(), jingleMediaManagers);
//sessionRequest = request; // unused // sessionRequest = request; // unused
} }
/** /**
@ -317,7 +317,7 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList
// Acknowledge the IQ reception // Acknowledge the IQ reception
// Not anymore. The state machine generates an appropriate response IQ that // Not anymore. The state machine generates an appropriate response IQ that
// gets sent back at the end of this routine. // gets sent back at the end of this routine.
//sendAck(iq); // sendAck(iq);
} catch (JingleException e) { } catch (JingleException e) {
// Send an error message, if present // Send an error message, if present
@ -829,7 +829,7 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList
addExpectedId(jout.getStanzaId()); addExpectedId(jout.getStanzaId());
sendStanza(jout); sendStanza(jout);
//triggerSessionEstablished(); // triggerSessionEstablished();
} }
} }
@ -1143,7 +1143,7 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList
*/ */
public void startIncoming() { public void startIncoming() {
//updatePacketListener(); // updatePacketListener();
} }
@Override @Override

View File

@ -118,7 +118,7 @@ public class JingleSessionRequest {
session = manager.createIncomingJingleSession(this); session = manager.createIncomingJingleSession(this);
// Acknowledge the IQ reception // Acknowledge the IQ reception
session.setSid(this.getSessionID()); session.setSid(this.getSessionID());
//session.sendAck(this.getJingle()); // session.sendAck(this.getJingle());
session.updatePacketListener(); session.updatePacketListener();
session.receivePacketAndRespond(this.getJingle()); session.receivePacketAndRespond(this.getJingle());
} }
@ -135,7 +135,7 @@ public class JingleSessionRequest {
session = manager.createIncomingJingleSession(this); session = manager.createIncomingJingleSession(this);
// Acknowledge the IQ reception // Acknowledge the IQ reception
session.setSid(this.getSessionID()); session.setSid(this.getSessionID());
//session.sendAck(this.getJingle()); // session.sendAck(this.getJingle());
session.updatePacketListener(); session.updatePacketListener();
session.terminate("Declined"); session.terminate("Declined");
} catch (Exception e) { } catch (Exception e) {

View File

@ -93,7 +93,7 @@ public class JingleSessionStatePending extends JingleSessionState {
default: default:
// Anything other action is an error. // Anything other action is an error.
//response = createJingleError(inJingle, JingleError.OUT_OF_ORDER); // response = createJingleError(inJingle, JingleError.OUT_OF_ORDER);
break; break;
} }
@ -106,8 +106,8 @@ public class JingleSessionStatePending extends JingleSessionState {
private IQ receiveContentAcceptAction(Jingle inJingle) { private IQ receiveContentAcceptAction(Jingle inJingle) {
// According to XEP-167 the only thing we can do is ack. // According to XEP-167 the only thing we can do is ack.
//setSessionState(JingleSessionStateEnum.ACTIVE); // setSessionState(JingleSessionStateEnum.ACTIVE);
//return createAck(inJingle); // return createAck(inJingle);
// This is now handled by the media negotiator for the matching <content> segment. // This is now handled by the media negotiator for the matching <content> segment.
return null; return null;

View File

@ -49,7 +49,7 @@ public class MediaNegotiator extends JingleNegotiator {
private static final Logger LOGGER = Logger.getLogger(MediaNegotiator.class.getName()); private static final Logger LOGGER = Logger.getLogger(MediaNegotiator.class.getName());
//private JingleSession session; // The session this negotiation // private JingleSession session; // The session this negotiation
private final JingleMediaManager mediaManager; private final JingleMediaManager mediaManager;
@ -252,7 +252,7 @@ public class MediaNegotiator extends JingleNegotiator {
// If there are suitable/matching payload types then accept this content. // If there are suitable/matching payload types then accept this content.
if (bestCommonAudioPt != null) { if (bestCommonAudioPt != null) {
// Let thre transport negotiators sort-out connectivity and content-accept instead. // Let thre transport negotiators sort-out connectivity and content-accept instead.
//response = createAudioPayloadTypesOffer(); // response = createAudioPayloadTypesOffer();
setNegotiatorState(JingleNegotiatorState.PENDING); setNegotiatorState(JingleNegotiatorState.PENDING);
} else { } else {
// Don't really know what to send here. XEP-166 is not clear. // Don't really know what to send here. XEP-166 is not clear.
@ -291,7 +291,7 @@ public class MediaNegotiator extends JingleNegotiator {
// and send an accept if we have an agreement... // and send an accept if we have an agreement...
ptChange = !bestCommonAudioPt.equals(oldBestCommonAudioPt); ptChange = !bestCommonAudioPt.equals(oldBestCommonAudioPt);
if (oldBestCommonAudioPt == null || ptChange) { if (oldBestCommonAudioPt == null || ptChange) {
//response = createAcceptMessage(); // response = createAcceptMessage();
} }
} else { } else {
throw new JingleException(JingleError.NO_COMMON_PAYLOAD); throw new JingleException(JingleError.NO_COMMON_PAYLOAD);
@ -319,7 +319,7 @@ public class MediaNegotiator extends JingleNegotiator {
if (bestCommonAudioPt == null) { if (bestCommonAudioPt == null) {
// Update the best common audio PT // Update the best common audio PT
bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts); bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts);
//response = createAcceptMessage(); // response = createAcceptMessage();
} }
offeredPayloads = description.getAudioPayloadTypesList(); offeredPayloads = description.getAudioPayloadTypesList();

View File

@ -117,7 +117,7 @@ public class JMFInit extends Frame implements Runnable {
throw td; throw td;
} }
catch (Throwable t) { catch (Throwable t) {
//Do nothing // Do nothing.
} }
Class<?> jsauto; Class<?> jsauto;
@ -226,7 +226,7 @@ public class JMFInit extends Frame implements Runnable {
} }
} }
catch (Throwable tt) { catch (Throwable tt) {
//Do nothing // Do nothing.
} }
} }
@ -270,7 +270,7 @@ public class JMFInit extends Frame implements Runnable {
} }
} }
catch (Throwable tt) { catch (Throwable tt) {
//Do nothing // Do nothing.
} }
} }

View File

@ -152,9 +152,9 @@ public class JmfMediaManager extends JingleMediaManager {
// should be and put it there. // should be and put it there.
runLinuxPreInstall(); runLinuxPreInstall();
//if (jmfProperties.length() == 0) { // if (jmfProperties.length() == 0) {
new JMFInit(null, false); new JMFInit(null, false);
//} // }
} }

View File

@ -146,7 +146,7 @@ public class ImageReceiver extends Canvas {
public void drawTile(int x, int y, BufferedImage bufferedImage) { public void drawTile(int x, int y, BufferedImage bufferedImage) {
tiles[x][y] = bufferedImage; tiles[x][y] = bufferedImage;
//repaint(x * tileWidth, y * tileWidth, tileWidth, tileWidth); // repaint(x * tileWidth, y * tileWidth, tileWidth, tileWidth);
this.getGraphics().drawImage(bufferedImage, tileWidth * x, tileWidth * y, this); this.getGraphics().drawImage(bufferedImage, tileWidth * x, tileWidth * y, this);
} }

View File

@ -221,8 +221,8 @@ public class ICECandidate extends TransportCandidate implements Comparable<ICECa
*/ */
@Override @Override
public void check(final List<TransportCandidate> localCandidates) { public void check(final List<TransportCandidate> localCandidates) {
//TODO candidate is being checked trigger // TODO candidate is being checked trigger
//candidatesChecking.add(cand); // candidatesChecking.add(cand);
final ICECandidate checkingCandidate = this; final ICECandidate checkingCandidate = this;
@ -287,8 +287,8 @@ public class ICECandidate extends TransportCandidate implements Comparable<ICECa
triggerCandidateChecked(result.isReachable()); triggerCandidateChecked(result.isReachable());
//TODO candidate is being checked trigger // TODO candidate is being checked trigger
//candidatesChecking.remove(cand); // candidatesChecking.remove(cand);
} }
}, "Transport candidate check"); }, "Transport candidate check");

View File

@ -54,7 +54,7 @@ public class ICEResolver extends TransportResolver {
String server; String server;
int port; int port;
static Map<String, ICENegociator> negociatorsMap = new HashMap<String, ICENegociator>(); static Map<String, ICENegociator> negociatorsMap = new HashMap<String, ICENegociator>();
//ICENegociator iceNegociator = null; // ICENegociator iceNegociator = null;
public ICEResolver(XMPPConnection connection, String server, int port) { public ICEResolver(XMPPConnection connection, String server, int port) {
super(); super();

View File

@ -110,7 +110,7 @@ public class TcpUdpBridgeClient {
byte[] b = new byte[500]; byte[] b = new byte[500];
int s = in.read(b); int s = in.read(b);
//if (s == -1) continue; // if (s == -1) continue;
LOGGER.fine("TCP Client:" + new String(b, 0, s, "UTF-8")); LOGGER.fine("TCP Client:" + new String(b, 0, s, "UTF-8"));

View File

@ -112,7 +112,7 @@ public class TcpUdpBridgeServer {
byte[] b = new byte[500]; byte[] b = new byte[500];
int s = in.read(b); int s = in.read(b);
//if (s == -1) continue; // if (s == -1) continue;
LOGGER.fine("TCP Server:" + new String(b, 0, s, "UTF-8")); LOGGER.fine("TCP Server:" + new String(b, 0, s, "UTF-8"));

View File

@ -352,8 +352,8 @@ public abstract class TransportCandidate {
* Subclasses should provide better methods if they can... * Subclasses should provide better methods if they can...
*/ */
public void check(final List<TransportCandidate> localCandidates) { public void check(final List<TransportCandidate> localCandidates) {
//TODO candidate is being checked trigger // TODO candidate is being checked trigger
//candidatesChecking.add(cand); // candidatesChecking.add(cand);
Thread checkThread = new Thread(new Runnable() { Thread checkThread = new Thread(new Runnable() {
@Override @Override
@ -372,8 +372,8 @@ public abstract class TransportCandidate {
} }
triggerCandidateChecked(isUsable); triggerCandidateChecked(isUsable);
//TODO candidate is being checked trigger // TODO candidate is being checked trigger
//candidatesChecking.remove(cand); // candidatesChecking.remove(cand);
} }
}, "Transport candidate check"); }, "Transport candidate check");
@ -680,7 +680,7 @@ public abstract class TransportCandidate {
socket.receive(packet); socket.receive(packet);
//LOGGER.fine("ECHO Packet Received in: " + socket.getLocalAddress().getHostAddress() + ":" + socket.getLocalPort() + " From: " + packet.getAddress().getHostAddress() + ":" + packet.getPort()); // LOGGER.fine("ECHO Packet Received in: " + socket.getLocalAddress().getHostAddress() + ":" + socket.getLocalPort() + " From: " + packet.getAddress().getHostAddress() + ":" + packet.getPort());
boolean accept = false; boolean accept = false;

View File

@ -61,7 +61,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
public final static int CANDIDATES_ACCEPT_PERIOD = 4000; public final static int CANDIDATES_ACCEPT_PERIOD = 4000;
// The session this nenotiator belongs to // The session this nenotiator belongs to
//private final JingleSession session; // private final JingleSession session;
// The transport manager // The transport manager
private final TransportResolver resolver; private final TransportResolver resolver;
@ -137,7 +137,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
*/ */
private void setAcceptedLocalCandidate(TransportCandidate bestLocalCandidate) { private void setAcceptedLocalCandidate(TransportCandidate bestLocalCandidate) {
for (int i = 0; i < resolver.getCandidateCount(); i++) { for (int i = 0; i < resolver.getCandidateCount(); i++) {
//TODO FIX The EQUAL Sentence // TODO FIX The EQUAL Sentence
if (resolver.getCandidate(i).getIp().equals(bestLocalCandidate.getIp()) if (resolver.getCandidate(i).getIp().equals(bestLocalCandidate.getIp())
&& resolver.getCandidate(i).getPort() == bestLocalCandidate.getPort()) { && resolver.getCandidate(i).getPort() == bestLocalCandidate.getPort()) {
acceptedLocalCandidate = resolver.getCandidate(i); acceptedLocalCandidate = resolver.getCandidate(i);
@ -145,7 +145,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
} }
} }
LOGGER.fine("BEST: ip=" + bestLocalCandidate.getIp() + " port=" + bestLocalCandidate.getPort() + " has not been offered."); LOGGER.fine("BEST: ip=" + bestLocalCandidate.getIp() + " port=" + bestLocalCandidate.getPort() + " has not been offered.");
//throw new XMPPException("Local transport candidate has not be offered."); // throw new XMPPException("Local transport candidate has not be offered.");
} }
/** /**
@ -316,7 +316,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
// Once we are in pending state, look for any valid remote // Once we are in pending state, look for any valid remote
// candidate, and send an "accept" if we have one... // candidate, and send an "accept" if we have one...
TransportCandidate bestRemote = getBestRemoteCandidate(); TransportCandidate bestRemote = getBestRemoteCandidate();
//State state = getState(); // State state = getState();
if ((bestRemote != null) if ((bestRemote != null)
&& ((getNegotiatorState() == JingleNegotiatorState.PENDING))) { && ((getNegotiatorState() == JingleNegotiatorState.PENDING))) {
@ -359,7 +359,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
if (candidate instanceof ICECandidate) { if (candidate instanceof ICECandidate) {
ICECandidate iceCandidate = (ICECandidate) candidate; ICECandidate iceCandidate = (ICECandidate) candidate;
if (iceCandidate.getType().equals(Type.relay)) { if (iceCandidate.getType().equals(Type.relay)) {
//TODO Check if the relay is reacheable // TODO Check if the relay is reacheable.
addValidRemoteCandidate(iceCandidate); addValidRemoteCandidate(iceCandidate);
foundRemoteRelay = true; foundRemoteRelay = true;
} }
@ -409,7 +409,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
} }
bestRemote = getBestRemoteCandidate(); bestRemote = getBestRemoteCandidate();
//State state = getState(); // State state = getState();
if ((bestRemote != null) if ((bestRemote != null)
&& ((getNegotiatorState() == JingleNegotiatorState.PENDING))) { && ((getNegotiatorState() == JingleNegotiatorState.PENDING))) {
if (!acceptedRemoteCandidates.contains(bestRemote)) { if (!acceptedRemoteCandidates.contains(bestRemote)) {
@ -699,7 +699,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
IQ response = null; IQ response = null;
// Parse the Jingle and get any proposed transport candidates // Parse the Jingle and get any proposed transport candidates
//addRemoteCandidates(obtainCandidatesList(jin)); // addRemoteCandidates(obtainCandidatesList(jin));
// Start offering candidates // Start offering candidates
sendTransportCandidatesOffer(); sendTransportCandidatesOffer();
@ -723,7 +723,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
IQ response = null; IQ response = null;
// Parse the Jingle and get any proposed transport candidates // Parse the Jingle and get any proposed transport candidates
//addRemoteCandidates(obtainCandidatesList(jin)); // addRemoteCandidates(obtainCandidatesList(jin));
// // Start offering candidates // // Start offering candidates
// sendTransportCandidatesOffer(); // sendTransportCandidatesOffer();
@ -771,7 +771,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
if (isEstablished()) { if (isEstablished()) {
LOGGER.fine(cand.getIp() + " is set active"); LOGGER.fine(cand.getIp() + " is set active");
//setNegotiatorState(JingleNegotiatorState.SUCCEEDED); // setNegotiatorState(JingleNegotiatorState.SUCCEEDED);
} }
} }
return response; return response;
@ -785,9 +785,9 @@ public abstract class TransportNegotiator extends JingleNegotiator {
IQ response = null; IQ response = null;
LOGGER.fine("Transport stabilished"); LOGGER.fine("Transport stabilished");
//triggerTransportEstablished(getAcceptedLocalCandidate(), getBestRemoteCandidate()); // triggerTransportEstablished(getAcceptedLocalCandidate(), getBestRemoteCandidate());
//setNegotiatorState(JingleNegotiatorState.SUCCEEDED); // setNegotiatorState(JingleNegotiatorState.SUCCEEDED);
return response; return response;
} }

View File

@ -232,7 +232,7 @@ public abstract class JingleTransportProvider extends ExtensionElementProvider<J
String name = parser.getAttributeValue("", "name"); String name = parser.getAttributeValue("", "name");
String port = parser.getAttributeValue("", "port"); String port = parser.getAttributeValue("", "port");
//LOGGER.debug(); // LOGGER.debug();
if (generation != null) { if (generation != null) {
try { try {

View File

@ -210,7 +210,7 @@ public class SignalOmemoKeyUtil extends OmemoKeyUtil<IdentityKeyPair, IdentityKe
@Override @Override
public OmemoFingerprint getFingerprint(IdentityKey identityKey) { public OmemoFingerprint getFingerprint(IdentityKey identityKey) {
String fp = identityKey.getFingerprint(); String fp = identityKey.getFingerprint();
//Cut "(byte)0x" prefixes, remove spaces and commas, cut first two digits. // Cut "(byte)0x" prefixes, remove spaces and commas, cut first two digits.
fp = fp.replace("(byte)0x", "").replace(",", "").replace(" ", "").substring(2); fp = fp.replace("(byte)0x", "").replace(",", "").replace(" ", "").substring(2);
return new OmemoFingerprint(fp); return new OmemoFingerprint(fp);
} }

View File

@ -96,8 +96,8 @@ public class SignalOmemoStoreConnector
@Override @Override
public boolean isTrustedIdentity(SignalProtocolAddress signalProtocolAddress, IdentityKey identityKey) { public boolean isTrustedIdentity(SignalProtocolAddress signalProtocolAddress, IdentityKey identityKey) {
//Disable internal trust management. Instead we use OmemoStore.isTrustedOmemoIdentity() before encrypting for a // Disable internal trust management. Instead we use OmemoStore.isTrustedOmemoIdentity() before encrypting for a
//recipient. // recipient.
return true; return true;
} }

View File

@ -317,7 +317,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
preKeys.put(Integer.parseInt(f.getName()), p); preKeys.put(Integer.parseInt(f.getName()), p);
} catch (IOException e) { } catch (IOException e) {
//Do nothing // Do nothing.
} }
} }
return preKeys; return preKeys;
@ -355,7 +355,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
signedPreKeys.put(Integer.parseInt(f.getName()), p); signedPreKeys.put(Integer.parseInt(f.getName()), p);
} catch (IOException e) { } catch (IOException e) {
//Do nothing // Do nothing.
} }
} }
return signedPreKeys; return signedPreKeys;
@ -414,7 +414,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
sessions.put(id, s); sessions.put(id, s);
} catch (IOException e) { } catch (IOException e) {
//Do nothing // Do nothing.
} }
} }
return sessions; return sessions;
@ -469,7 +469,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
return null; return null;
} }
//active // active
File activeDevicesPath = hierarchy.getContactsActiveDevicesPath(omemoManager, contact); File activeDevicesPath = hierarchy.getContactsActiveDevicesPath(omemoManager, contact);
try { try {
cachedDeviceList.getActiveDevices().addAll(readIntegers(activeDevicesPath)); cachedDeviceList.getActiveDevices().addAll(readIntegers(activeDevicesPath));
@ -477,12 +477,12 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
// Don't worry... // Don't worry...
} }
//inactive // inactive
File inactiveDevicesPath = hierarchy.getContactsInactiveDevicesPath(omemoManager, contact); File inactiveDevicesPath = hierarchy.getContactsInactiveDevicesPath(omemoManager, contact);
try { try {
cachedDeviceList.getInactiveDevices().addAll(readIntegers(inactiveDevicesPath)); cachedDeviceList.getInactiveDevices().addAll(readIntegers(inactiveDevicesPath));
} catch (IOException e) { } catch (IOException e) {
//It's ok :) // It's ok :)
} }
return cachedDeviceList; return cachedDeviceList;
@ -631,7 +631,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
throw new IOException("Could not write bytes to null-path."); throw new IOException("Could not write bytes to null-path.");
} }
//Create file // Create file
FileHierarchy.createFile(target); FileHierarchy.createFile(target);
IOException io = null; IOException io = null;
@ -730,7 +730,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
integers.add(in.readInt()); integers.add(in.readInt());
} }
} catch (EOFException e) { } catch (EOFException e) {
//Reached end of the list. // Reached end of the list.
} }
} catch (IOException e) { } catch (IOException e) {

View File

@ -178,7 +178,7 @@ public final class OmemoManager extends Manager {
if (connection.getUser() != null) { if (connection.getUser() != null) {
user = connection.getUser().asBareJid(); user = connection.getUser().asBareJid();
} else { } else {
//This might be dangerous // This might be dangerous
try { try {
user = JidCreate.bareFrom(((AbstractXMPPConnection) connection).getConfiguration().getUsername()); user = JidCreate.bareFrom(((AbstractXMPPConnection) connection).getConfiguration().getUsername());
} catch (XmppStringprepException e) { } catch (XmppStringprepException e) {
@ -406,7 +406,7 @@ public final class OmemoManager extends Manager {
* @throws CorruptedOmemoKeyException * @throws CorruptedOmemoKeyException
*/ */
public void regenerate() throws SmackException, InterruptedException, XMPPException.XMPPErrorException, CorruptedOmemoKeyException { public void regenerate() throws SmackException, InterruptedException, XMPPException.XMPPErrorException, CorruptedOmemoKeyException {
//create a new identity and publish new keys to the server // create a new identity and publish new keys to the server
getOmemoService().regenerate(this, null); getOmemoService().regenerate(this, null);
getOmemoService().publishDeviceIdIfNeeded(this,false); getOmemoService().publishDeviceIdIfNeeded(this,false);
getOmemoService().publishBundle(this); getOmemoService().publishBundle(this);
@ -622,9 +622,9 @@ public final class OmemoManager extends Manager {
* @throws PubSubException.NotALeafNodeException if the bundle node on the server is a CollectionNode * @throws PubSubException.NotALeafNodeException if the bundle node on the server is a CollectionNode
*/ */
public void rotateSignedPreKey() throws CorruptedOmemoKeyException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, PubSubException.NotALeafNodeException { public void rotateSignedPreKey() throws CorruptedOmemoKeyException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, PubSubException.NotALeafNodeException {
//generate key // generate key
getOmemoService().getOmemoStoreBackend().changeSignedPreKey(this); getOmemoService().getOmemoStoreBackend().changeSignedPreKey(this);
//publish // publish
getOmemoService().publishDeviceIdIfNeeded(this, false); getOmemoService().publishDeviceIdIfNeeded(this, false);
getOmemoService().publishBundle(this); getOmemoService().publishBundle(this);
} }
@ -788,31 +788,31 @@ public final class OmemoManager extends Manager {
continue; continue;
} }
//Device List <list> // Device List <list>
OmemoDeviceListVAxolotlElement omemoDeviceListElement = (OmemoDeviceListVAxolotlElement) payloadItem.getPayload(); OmemoDeviceListVAxolotlElement omemoDeviceListElement = (OmemoDeviceListVAxolotlElement) payloadItem.getPayload();
int ourDeviceId = getDeviceId(); int ourDeviceId = getDeviceId();
getOmemoService().getOmemoStoreBackend().mergeCachedDeviceList(OmemoManager.this, from, omemoDeviceListElement); getOmemoService().getOmemoStoreBackend().mergeCachedDeviceList(OmemoManager.this, from, omemoDeviceListElement);
if (from == null) { if (from == null) {
//Unknown sender, no more work to do. // Unknown sender, no more work to do.
//TODO: This DOES happen for some reason. Figure out when... // TODO: This DOES happen for some reason. Figure out when...
continue; continue;
} }
if (!from.equals(getOwnJid())) { if (!from.equals(getOwnJid())) {
//Not our deviceList, so nothing more to do // Not our deviceList, so nothing more to do
continue; continue;
} }
if (omemoDeviceListElement.getDeviceIds().contains(ourDeviceId)) { if (omemoDeviceListElement.getDeviceIds().contains(ourDeviceId)) {
//We are on the list. Nothing more to do // We are on the list. Nothing more to do
continue; continue;
} }
//Our deviceList and we are not on it! We don't want to miss all the action!!! // Our deviceList and we are not on it! We don't want to miss all the action!!!
LOGGER.log(Level.INFO, "Our deviceId was not on the list!"); LOGGER.log(Level.INFO, "Our deviceId was not on the list!");
Set<Integer> deviceListIds = omemoDeviceListElement.copyDeviceIds(); Set<Integer> deviceListIds = omemoDeviceListElement.copyDeviceIds();
//enroll at the deviceList // enroll at the deviceList
deviceListIds.add(ourDeviceId); deviceListIds.add(ourDeviceId);
final OmemoDeviceListVAxolotlElement newOmemoDeviceListElement = new OmemoDeviceListVAxolotlElement(deviceListIds); final OmemoDeviceListVAxolotlElement newOmemoDeviceListElement = new OmemoDeviceListVAxolotlElement(deviceListIds);

View File

@ -190,7 +190,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
throws NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException, throws NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException,
BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException { BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
//Check availability of algorithms and encodings needed for crypto // Check availability of algorithms and encodings needed for crypto
checkAvailableAlgorithms(); checkAvailableAlgorithms();
} }
@ -214,12 +214,12 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
boolean mustPublishId = false; boolean mustPublishId = false;
if (getOmemoStoreBackend().isFreshInstallation(omemoManager)) { if (getOmemoStoreBackend().isFreshInstallation(omemoManager)) {
LOGGER.log(Level.INFO, "No key material found. Looks like we have a fresh installation."); LOGGER.log(Level.INFO, "No key material found. Looks like we have a fresh installation.");
//Create new key material and publish it to the server // Create new key material and publish it to the server
regenerate(omemoManager, omemoManager.getDeviceId()); regenerate(omemoManager, omemoManager.getDeviceId());
mustPublishId = true; mustPublishId = true;
} }
//Get fresh device list from server // Get fresh device list from server
mustPublishId |= refreshOwnDeviceList(omemoManager); mustPublishId |= refreshOwnDeviceList(omemoManager);
publishDeviceIdIfNeeded(omemoManager, false, mustPublishId); publishDeviceIdIfNeeded(omemoManager, false, mustPublishId);
@ -244,7 +244,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
protected static void checkAvailableAlgorithms() throws NoSuchPaddingException, UnsupportedEncodingException, protected static void checkAvailableAlgorithms() throws NoSuchPaddingException, UnsupportedEncodingException,
InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException,
NoSuchProviderException, InvalidKeyException { NoSuchProviderException, InvalidKeyException {
//Test crypto functions // Test crypto functions
new OmemoMessageBuilder<>(null, null, ""); new OmemoMessageBuilder<>(null, null, "");
} }
@ -257,7 +257,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
* (should never ever happen *crosses fingers*) * (should never ever happen *crosses fingers*)
*/ */
void regenerate(OmemoManager omemoManager, Integer nDeviceId) throws CorruptedOmemoKeyException { void regenerate(OmemoManager omemoManager, Integer nDeviceId) throws CorruptedOmemoKeyException {
//Generate unique ID that is not already taken // Generate unique ID that is not already taken
while (nDeviceId == null || !getOmemoStoreBackend().isAvailableDeviceId(omemoManager, nDeviceId)) { while (nDeviceId == null || !getOmemoStoreBackend().isAvailableDeviceId(omemoManager, nDeviceId)) {
nDeviceId = OmemoManager.randomDeviceId(); nDeviceId = OmemoManager.randomDeviceId();
} }
@ -292,7 +292,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
getOmemoStoreBackend().setDateOfLastSignedPreKeyRenewal(omemoManager); getOmemoStoreBackend().setDateOfLastSignedPreKeyRenewal(omemoManager);
} }
//publish // publish
PubSubManager.getInstance(omemoManager.getConnection(), omemoManager.getOwnJid()) PubSubManager.getInstance(omemoManager.getConnection(), omemoManager.getOwnJid())
.tryToPublishAndPossibleAutoCreate(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(omemoManager.getDeviceId()), .tryToPublishAndPossibleAutoCreate(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(omemoManager.getDeviceId()),
new PayloadItem<>(getOmemoStoreBackend().packOmemoBundle(omemoManager))); new PayloadItem<>(getOmemoStoreBackend().packOmemoBundle(omemoManager)));
@ -369,12 +369,12 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
boolean removeStaleDevicesIfNeeded(OmemoManager omemoManager, Set<Integer> deviceListIds) { boolean removeStaleDevicesIfNeeded(OmemoManager omemoManager, Set<Integer> deviceListIds) {
boolean publish = false; boolean publish = false;
int ownDeviceId = omemoManager.getDeviceId(); int ownDeviceId = omemoManager.getDeviceId();
//Clear devices that we didn't receive a message from for a while // Clear devices that we didn't receive a message from for a while
Iterator<Integer> it = deviceListIds.iterator(); Iterator<Integer> it = deviceListIds.iterator();
while (OmemoConfiguration.getDeleteStaleDevices() && it.hasNext()) { while (OmemoConfiguration.getDeleteStaleDevices() && it.hasNext()) {
int id = it.next(); int id = it.next();
if (id == ownDeviceId) { if (id == ownDeviceId) {
//Skip own id // Skip own id
continue; continue;
} }
@ -601,11 +601,11 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
for (int id : devices.getActiveDevices()) { for (int id : devices.getActiveDevices()) {
OmemoDevice device = new OmemoDevice(jid, id); OmemoDevice device = new OmemoDevice(jid, id);
if (getOmemoStoreBackend().containsRawSession(omemoManager, device)) { if (getOmemoStoreBackend().containsRawSession(omemoManager, device)) {
//We have a session already. // We have a session already.
continue; continue;
} }
//Build missing session // Build missing session
try { try {
buildSessionFromOmemoBundle(omemoManager, device, false); buildSessionFromOmemoBundle(omemoManager, device, false);
} catch (CannotEstablishOmemoSessionException e) { } catch (CannotEstablishOmemoSessionException e) {
@ -648,7 +648,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
return; return;
} }
//Do not build sessions with devices we already know... // Do not build sessions with devices we already know...
if (!fresh && getOmemoStoreBackend().containsRawSession(omemoManager, device)) { if (!fresh && getOmemoStoreBackend().containsRawSession(omemoManager, device)) {
getOmemoStoreBackend().getOmemoSessionOf(omemoManager, device); //Make sure its loaded though getOmemoStoreBackend().getOmemoSessionOf(omemoManager, device); //Make sure its loaded though
return; return;
@ -663,10 +663,10 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
HashMap<Integer, T_Bundle> bundles = getOmemoStoreBackend().keyUtil().BUNDLE.bundles(bundle, device); HashMap<Integer, T_Bundle> bundles = getOmemoStoreBackend().keyUtil().BUNDLE.bundles(bundle, device);
//Select random Bundle // Select random Bundle
int randomIndex = new Random().nextInt(bundles.size()); int randomIndex = new Random().nextInt(bundles.size());
T_Bundle randomPreKeyBundle = new ArrayList<>(bundles.values()).get(randomIndex); T_Bundle randomPreKeyBundle = new ArrayList<>(bundles.values()).get(randomIndex);
//Build raw session // Build raw session
processBundle(omemoManager, randomPreKeyBundle, device); processBundle(omemoManager, randomPreKeyBundle, device);
} }
@ -701,9 +701,9 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
CryptoFailedException, XMPPException.XMPPErrorException, CorruptedOmemoKeyException { CryptoFailedException, XMPPException.XMPPErrorException, CorruptedOmemoKeyException {
ArrayList<OmemoVAxolotlElement.OmemoHeader.Key> messageRecipientKeys = message.getHeader().getKeys(); ArrayList<OmemoVAxolotlElement.OmemoHeader.Key> messageRecipientKeys = message.getHeader().getKeys();
//Do we have a key with our ID in the message? // Do we have a key with our ID in the message?
for (OmemoVAxolotlElement.OmemoHeader.Key k : messageRecipientKeys) { for (OmemoVAxolotlElement.OmemoHeader.Key k : messageRecipientKeys) {
//Only decrypt with our deviceID // Only decrypt with our deviceID
if (k.getId() != omemoManager.getDeviceId()) { if (k.getId() != omemoManager.getDeviceId()) {
continue; continue;
} }
@ -785,7 +785,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
throws CryptoFailedException, UndecidedOmemoIdentityException, NoSuchAlgorithmException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, CannotEstablishOmemoSessionException { throws CryptoFailedException, UndecidedOmemoIdentityException, NoSuchAlgorithmException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, CannotEstablishOmemoSessionException {
CannotEstablishOmemoSessionException sessionException = null; CannotEstablishOmemoSessionException sessionException = null;
//Them - The contact wants to read the message on all their devices. // Them - The contact wants to read the message on all their devices.
HashMap<BareJid, ArrayList<OmemoDevice>> receivers = new HashMap<>(); HashMap<BareJid, ArrayList<OmemoDevice>> receivers = new HashMap<>();
for (BareJid recipient : recipients) { for (BareJid recipient : recipients) {
try { try {
@ -820,7 +820,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
} }
} }
//Us - We want to read the message on all of our devices // Us - We want to read the message on all of our devices
CachedDeviceList ourDevices = getOmemoStoreBackend().loadCachedDeviceList(omemoManager, omemoManager.getOwnJid()); CachedDeviceList ourDevices = getOmemoStoreBackend().loadCachedDeviceList(omemoManager, omemoManager.getOwnJid());
if (ourDevices == null) { if (ourDevices == null) {
ourDevices = new CachedDeviceList(); ourDevices = new CachedDeviceList();
@ -830,7 +830,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
for (int id : ourDevices.getActiveDevices()) { for (int id : ourDevices.getActiveDevices()) {
OmemoDevice ourDevice = new OmemoDevice(omemoManager.getOwnJid(), id); OmemoDevice ourDevice = new OmemoDevice(omemoManager.getOwnJid(), id);
if (id == omemoManager.getDeviceId()) { if (id == omemoManager.getDeviceId()) {
//Don't build session with our exact device. // Don't build session with our exact device.
continue; continue;
} }
@ -957,11 +957,11 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
try { try {
builder.addRecipient(c); builder.addRecipient(c);
} catch (CorruptedOmemoKeyException e) { } catch (CorruptedOmemoKeyException e) {
//TODO: How to react? // TODO: How to react?
LOGGER.log(Level.SEVERE, "encryptOmemoMessage failed to establish a session with device " LOGGER.log(Level.SEVERE, "encryptOmemoMessage failed to establish a session with device "
+ c + ": " + e.getMessage()); + c + ": " + e.getMessage());
} catch (UndecidedOmemoIdentityException e) { } catch (UndecidedOmemoIdentityException e) {
//Collect all undecided devices // Collect all undecided devices
if (undecided == null) { if (undecided == null) {
undecided = e; undecided = e;
} else { } else {
@ -1132,7 +1132,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
List<ClearTextMessage> result = new ArrayList<>(); List<ClearTextMessage> result = new ArrayList<>();
for (Forwarded f : mamQueryResult.forwardedMessages) { for (Forwarded f : mamQueryResult.forwardedMessages) {
if (OmemoManager.stanzaContainsOmemoElement(f.getForwardedStanza())) { if (OmemoManager.stanzaContainsOmemoElement(f.getForwardedStanza())) {
//Decrypt OMEMO messages // Decrypt OMEMO messages
try { try {
result.add(processLocalMessage(omemoManager, f.getForwardedStanza().getFrom().asBareJid(), (Message) f.getForwardedStanza())); result.add(processLocalMessage(omemoManager, f.getForwardedStanza().getFrom().asBareJid(), (Message) f.getForwardedStanza()));
} catch (NoRawSessionException | CorruptedOmemoKeyException | CryptoFailedException e) { } catch (NoRawSessionException | CorruptedOmemoKeyException | CryptoFailedException e) {
@ -1140,7 +1140,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
+ f.getForwardedStanza().getFrom() + " due to corrupted session/key: " + e.getMessage()); + f.getForwardedStanza().getFrom() + " due to corrupted session/key: " + e.getMessage());
} }
} else { } else {
//Wrap cleartext messages // Wrap cleartext messages
Message m = (Message) f.getForwardedStanza(); Message m = (Message) f.getForwardedStanza();
result.add(new ClearTextMessage(m.getBody(), m, result.add(new ClearTextMessage(m.getBody(), m,
new OmemoMessageInformation(null, null, OmemoMessageInformation.CARBON.NONE, false))); new OmemoMessageInformation(null, null, OmemoMessageInformation.CARBON.NONE, false)));
@ -1210,7 +1210,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
MultiUserChatManager mucm = MultiUserChatManager.getInstanceFor(omemoManager.getConnection()); MultiUserChatManager mucm = MultiUserChatManager.getInstanceFor(omemoManager.getConnection());
OmemoDevice senderDevice = getSender(omemoManager, stanza); OmemoDevice senderDevice = getSender(omemoManager, stanza);
try { try {
//Is it a MUC message... // Is it a MUC message...
if (isMucMessage(omemoManager, stanza)) { if (isMucMessage(omemoManager, stanza)) {
MultiUserChat muc = mucm.getMultiUserChat(stanza.getFrom().asEntityBareJidIfPossible()); MultiUserChat muc = mucm.getMultiUserChat(stanza.getFrom().asEntityBareJidIfPossible());
@ -1231,7 +1231,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
} }
} }
} }
//... or a normal chat message... // ... or a normal chat message...
else { else {
if (omemoMessage.isMessageElement()) { if (omemoMessage.isMessageElement()) {
@ -1304,7 +1304,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
} }
try { try {
//Is it a MUC message... // Is it a MUC message...
if (isMucMessage(omemoManager, carbonCopy)) { if (isMucMessage(omemoManager, carbonCopy)) {
MultiUserChat muc = mucm.getMultiUserChat(carbonCopy.getFrom().asEntityBareJidIfPossible()); MultiUserChat muc = mucm.getMultiUserChat(carbonCopy.getFrom().asEntityBareJidIfPossible());
@ -1325,7 +1325,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
} }
} }
} }
//... or a normal chat message... // ... or a normal chat message...
else { else {
if (omemoMessage.isMessageElement()) { if (omemoMessage.isMessageElement()) {

View File

@ -84,14 +84,14 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
boolean isAvailableDeviceId(OmemoManager omemoManager, int id) { boolean isAvailableDeviceId(OmemoManager omemoManager, int id) {
LOGGER.log(Level.INFO, "Check if id " + id + " is available..."); LOGGER.log(Level.INFO, "Check if id " + id + " is available...");
//Lookup local cached device list // Lookup local cached device list
BareJid ownJid = omemoManager.getOwnJid(); BareJid ownJid = omemoManager.getOwnJid();
CachedDeviceList cachedDeviceList = loadCachedDeviceList(omemoManager, ownJid); CachedDeviceList cachedDeviceList = loadCachedDeviceList(omemoManager, ownJid);
if (cachedDeviceList == null) { if (cachedDeviceList == null) {
cachedDeviceList = new CachedDeviceList(); cachedDeviceList = new CachedDeviceList();
} }
//Does the list already contain that id? // Does the list already contain that id?
return !cachedDeviceList.contains(id); return !cachedDeviceList.contains(id);
} }
@ -220,7 +220,7 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
*/ */
void initializeOmemoSessions(OmemoManager omemoManager) { void initializeOmemoSessions(OmemoManager omemoManager) {
//Get HashMap of our omemoSessions // Get HashMap of our omemoSessions
HashMap<OmemoDevice, OmemoSession<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Sess, T_Addr, T_ECPub, T_Bundle, T_Ciph>> HashMap<OmemoDevice, OmemoSession<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Sess, T_Addr, T_ECPub, T_Bundle, T_Ciph>>
sessions = omemoSessions.get(omemoManager); sessions = omemoSessions.get(omemoManager);
if (sessions == null) { if (sessions == null) {
@ -228,12 +228,12 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
omemoSessions.put(omemoManager, sessions); omemoSessions.put(omemoManager, sessions);
} }
//Sessions with our own devices // Sessions with our own devices
HashMap<Integer, T_Sess> ourRawSessions = loadAllRawSessionsOf(omemoManager, omemoManager.getOwnJid()); HashMap<Integer, T_Sess> ourRawSessions = loadAllRawSessionsOf(omemoManager, omemoManager.getOwnJid());
ourRawSessions.remove(omemoManager.getDeviceId()); //Just to make sure we have no session with ourselves... ourRawSessions.remove(omemoManager.getDeviceId()); //Just to make sure we have no session with ourselves...
sessions.putAll(createOmemoSessionsFromRawSessions(omemoManager, omemoManager.getOwnJid(), ourRawSessions)); sessions.putAll(createOmemoSessionsFromRawSessions(omemoManager, omemoManager.getOwnJid(), ourRawSessions));
//Sessions with contacts // Sessions with contacts
for (RosterEntry rosterEntry : Roster.getInstanceFor(omemoManager.getConnection()).getEntries()) { for (RosterEntry rosterEntry : Roster.getInstanceFor(omemoManager.getConnection()).getEntries()) {
HashMap<Integer, T_Sess> contactDevices = loadAllRawSessionsOf(omemoManager, rosterEntry.getJid().asBareJid()); HashMap<Integer, T_Sess> contactDevices = loadAllRawSessionsOf(omemoManager, rosterEntry.getJid().asBareJid());
sessions.putAll(createOmemoSessionsFromRawSessions(omemoManager, rosterEntry.getJid().asBareJid(), contactDevices)); sessions.putAll(createOmemoSessionsFromRawSessions(omemoManager, rosterEntry.getJid().asBareJid(), contactDevices));
@ -284,7 +284,7 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
OmemoSession<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Sess, T_Addr, T_ECPub, T_Bundle, T_Ciph> OmemoSession<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Sess, T_Addr, T_ECPub, T_Bundle, T_Ciph>
session = sessions.get(device); session = sessions.get(device);
//No OmemoSession found // No OmemoSession found
if (session == null) { if (session == null) {
T_IdKey identityKey = null; T_IdKey identityKey = null;
try { try {

View File

@ -129,9 +129,9 @@ public abstract class OmemoSession<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
if (unpackedKey.length == 32) { if (unpackedKey.length == 32) {
authTag = new byte[16]; authTag = new byte[16];
//copy key part into messageKey // copy key part into messageKey
System.arraycopy(unpackedKey, 0, messageKey, 0, 16); System.arraycopy(unpackedKey, 0, messageKey, 0, 16);
//copy tag part into authTag // copy tag part into authTag
System.arraycopy(unpackedKey, 16, authTag, 0,16); System.arraycopy(unpackedKey, 16, authTag, 0,16);
} else if (element.isKeyTransportElement() && unpackedKey.length == 16) { } else if (element.isKeyTransportElement() && unpackedKey.length == 16) {
messageKey = unpackedKey; messageKey = unpackedKey;

View File

@ -22,14 +22,14 @@ package org.jivesoftware.smackx.omemo.util;
*/ */
public final class OmemoConstants { public final class OmemoConstants {
//Constants // Constants
/** /**
* Omemo related namespace. * Omemo related namespace.
*/ */
public static final String OMEMO_NAMESPACE_V_AXOLOTL = "eu.siacs.conversations.axolotl"; public static final String OMEMO_NAMESPACE_V_AXOLOTL = "eu.siacs.conversations.axolotl";
public static final String OMEMO = "OMEMO"; public static final String OMEMO = "OMEMO";
//PubSub Node names // PubSub Node names
public static final String PEP_NODE_DEVICE_LIST = OMEMO_NAMESPACE_V_AXOLOTL + ".devicelist"; public static final String PEP_NODE_DEVICE_LIST = OMEMO_NAMESPACE_V_AXOLOTL + ".devicelist";
public static final String PEP_NODE_DEVICE_LIST_NOTIFY = PEP_NODE_DEVICE_LIST + "+notify"; public static final String PEP_NODE_DEVICE_LIST_NOTIFY = PEP_NODE_DEVICE_LIST + "+notify";
public static final String PEP_NODE_BUNDLES = OMEMO_NAMESPACE_V_AXOLOTL + ".bundles"; public static final String PEP_NODE_BUNDLES = OMEMO_NAMESPACE_V_AXOLOTL + ".bundles";

View File

@ -144,7 +144,7 @@ public class OmemoMessageBuilder<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
return; return;
} }
//Encrypt message body // Encrypt message body
SecretKey secretKey = new SecretKeySpec(messageKey, KEYTYPE); SecretKey secretKey = new SecretKeySpec(messageKey, KEYTYPE);
IvParameterSpec ivSpec = new IvParameterSpec(initializationVector); IvParameterSpec ivSpec = new IvParameterSpec(initializationVector);
Cipher cipher = Cipher.getInstance(CIPHERMODE, PROVIDER); Cipher cipher = Cipher.getInstance(CIPHERMODE, PROVIDER);
@ -194,12 +194,12 @@ public class OmemoMessageBuilder<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
if (session != null) { if (session != null) {
if (!ignoreTrust && !omemoStore.isDecidedOmemoIdentity(omemoManager, device, session.getIdentityKey())) { if (!ignoreTrust && !omemoStore.isDecidedOmemoIdentity(omemoManager, device, session.getIdentityKey())) {
//Warn user of undecided device // Warn user of undecided device
throw new UndecidedOmemoIdentityException(device); throw new UndecidedOmemoIdentityException(device);
} }
if (!ignoreTrust && omemoStore.isTrustedOmemoIdentity(omemoManager, device, session.getIdentityKey())) { if (!ignoreTrust && omemoStore.isTrustedOmemoIdentity(omemoManager, device, session.getIdentityKey())) {
//Encrypt key and save to header // Encrypt key and save to header
CiphertextTuple encryptedKey = session.encryptMessageKey(messageKey); CiphertextTuple encryptedKey = session.encryptMessageKey(messageKey);
keys.add(new OmemoVAxolotlElement.OmemoHeader.Key(encryptedKey.getCiphertext(), device.getDeviceId(), encryptedKey.isPreKeyMessage())); keys.add(new OmemoVAxolotlElement.OmemoHeader.Key(encryptedKey.getCiphertext(), device.getDeviceId(), encryptedKey.isPreKeyMessage()));
} }

View File

@ -107,7 +107,7 @@ public class OmemoConfigurationTest {
OmemoConfiguration.setMaxNumberOfStoredSignedPreKeys(0); OmemoConfiguration.setMaxNumberOfStoredSignedPreKeys(0);
TestCase.fail("OmemoConfiguration.setMaxNumberOfStoredSignedPreKeys should not accept values <= 0"); TestCase.fail("OmemoConfiguration.setMaxNumberOfStoredSignedPreKeys should not accept values <= 0");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
//Expected // Expected
} }
} }
} }

View File

@ -81,6 +81,7 @@ import org.jivesoftware.smack.SmackException.AlreadyLoggedInException;
import org.jivesoftware.smack.SmackException.ConnectionException; import org.jivesoftware.smack.SmackException.ConnectionException;
import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.SmackException.SecurityRequiredByServerException; import org.jivesoftware.smack.SmackException.SecurityRequiredByServerException;
import org.jivesoftware.smack.StanzaListener; import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.SynchronizationPoint; import org.jivesoftware.smack.SynchronizationPoint;
@ -309,7 +310,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
addConnectionListener(new AbstractConnectionListener() { addConnectionListener(new AbstractConnectionListener() {
@Override @Override
public void connectionClosedOnError(Exception e) { public void connectionClosedOnError(Exception e) {
if (e instanceof XMPPException.StreamErrorException) { if (e instanceof XMPPException.StreamErrorException || e instanceof StreamManagementException) {
dropSmState(); dropSmState();
} }
} }
@ -716,8 +717,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
else if ("Apple".equals(keyStoreType)) { else if ("Apple".equals(keyStoreType)) {
ks = KeyStore.getInstance("KeychainStore","Apple"); ks = KeyStore.getInstance("KeychainStore","Apple");
ks.load(null,null); ks.load(null,null);
//pcb = new PasswordCallback("Apple Keychain",false); // pcb = new PasswordCallback("Apple Keychain",false);
//pcb.setPassword(null); // pcb.setPassword(null);
} }
else if (keyStoreType != null) { else if (keyStoreType != null) {
ks = KeyStore.getInstance(keyStoreType); ks = KeyStore.getInstance(keyStoreType);
@ -1146,8 +1147,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
if (!smSessionId.equals(resumed.getPrevId())) { if (!smSessionId.equals(resumed.getPrevId())) {
throw new StreamIdDoesNotMatchException(smSessionId, resumed.getPrevId()); throw new StreamIdDoesNotMatchException(smSessionId, resumed.getPrevId());
} }
// Mark SM as enabled and resumption as successful. // Mark SM as enabled
smResumedSyncPoint.reportSuccess();
smEnabledSyncPoint.reportSuccess(); smEnabledSyncPoint.reportSuccess();
// First, drop the stanzas already handled by the server // First, drop the stanzas already handled by the server
processHandledCount(resumed.getHandledCount()); processHandledCount(resumed.getHandledCount());
@ -1163,6 +1163,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
if (!stanzasToResend.isEmpty()) { if (!stanzasToResend.isEmpty()) {
requestSmAcknowledgementInternal(); requestSmAcknowledgementInternal();
} }
// Mark SM resumption as successful
smResumedSyncPoint.reportSuccess();
LOGGER.fine("Stream Management (XEP-198): Stream resumed"); LOGGER.fine("Stream Management (XEP-198): Stream resumed");
break; break;
case AckAnswer.ELEMENT: case AckAnswer.ELEMENT:
@ -1183,7 +1185,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
} }
break; break;
case XmlPullParser.END_TAG: case XmlPullParser.END_TAG:
if (parser.getName().equals("stream")) { final String endTagName = parser.getName();
if ("stream".equals(endTagName)) {
if (!parser.getNamespace().equals("http://etherx.jabber.org/streams")) { if (!parser.getNamespace().equals("http://etherx.jabber.org/streams")) {
LOGGER.warning(XMPPTCPConnection.this + " </stream> but different namespace " + parser.getNamespace()); LOGGER.warning(XMPPTCPConnection.this + " </stream> but different namespace " + parser.getNamespace());
break; break;
@ -1879,7 +1882,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
try { try {
listener.processStanza(ackedStanza); listener.processStanza(ackedStanza);
} }
catch (InterruptedException | NotConnectedException e) { catch (InterruptedException | NotConnectedException | NotLoggedInException e) {
LOGGER.log(Level.FINER, "Received exception", e); LOGGER.log(Level.FINER, "Received exception", e);
} }
} }
@ -1892,7 +1895,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
try { try {
listener.processStanza(ackedStanza); listener.processStanza(ackedStanza);
} }
catch (InterruptedException | NotConnectedException e) { catch (InterruptedException | NotConnectedException | NotLoggedInException e) {
LOGGER.log(Level.FINER, "Received exception", e); LOGGER.log(Level.FINER, "Received exception", e);
} }
} }

View File

@ -2,7 +2,7 @@ allprojects {
ext { ext {
shortVersion = '4.3.0-alpha1' shortVersion = '4.3.0-alpha1'
isSnapshot = true isSnapshot = true
jxmppVersion = '0.5.0' jxmppVersion = '0.6.0'
smackMinAndroidSdk = 8 smackMinAndroidSdk = 8
} }
} }