From 248e76ff469585ecd339ef79d95ad51eb6855da0 Mon Sep 17 00:00:00 2001 From: vanitasvitae Date: Fri, 30 Jun 2017 14:30:19 +0200 Subject: [PATCH 01/25] Fix receiving OMEMO MUC messages The method OmemoManager.getSender() was faulty and returned null for MUC occupants, which lead to NPEs when receiving MUC messages with OMEMO. --- .../java/org/jivesoftware/smackx/omemo/OmemoService.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java index 17332669b..d3b6957c1 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java @@ -39,7 +39,6 @@ import java.util.Random; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; - import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; @@ -51,7 +50,6 @@ import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.XMPPError; - import org.jivesoftware.smackx.carbons.CarbonCopyReceivedListener; import org.jivesoftware.smackx.carbons.CarbonManager; import org.jivesoftware.smackx.carbons.packet.CarbonExtension; @@ -88,6 +86,7 @@ import org.jivesoftware.smackx.pubsub.PubSubManager; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.jxmpp.jid.BareJid; +import org.jxmpp.jid.Jid; /** * This class contains OMEMO related logic and registers listeners etc. @@ -1177,7 +1176,7 @@ public abstract class OmemoService Date: Sun, 2 Jul 2017 18:09:15 +0200 Subject: [PATCH 02/25] Deal with cases wehre HostAddress.fqdn is null Fixes SMACK-772 --- .../smack/util/dns/HostAddress.java | 22 ++++++++++++++++--- .../smack/tcp/XMPPTCPConnection.java | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java index 9d7f263a1..66a6d018a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/dns/HostAddress.java @@ -75,6 +75,22 @@ public class HostAddress { setException(e); } + public String getHost() { + if (fqdn != null) { + return fqdn; + } + + // In this case, the HostAddress(int, InetAddress) constructor must been used. We have no FQDN. And + // inetAddresses.size() must be exactly one. + assert inetAddresses.size() == 1; + return inetAddresses.get(0).getHostAddress(); + } + + /** + * Return the fully qualified domain name. This may return null in case there host address is only numeric, i.e. an IP address. + * + * @return the fully qualified domain name or null + */ public String getFQDN() { return fqdn; } @@ -109,7 +125,7 @@ public class HostAddress { @Override public String toString() { - return fqdn + ":" + port; + return getHost() + ":" + port; } @Override @@ -123,7 +139,7 @@ public class HostAddress { final HostAddress address = (HostAddress) o; - if (!fqdn.equals(address.fqdn)) { + if (!getHost().equals(address.getHost())) { return false; } return port == address.port; @@ -132,7 +148,7 @@ public class HostAddress { @Override public int hashCode() { int result = 1; - result = 37 * result + fqdn.hashCode(); + result = 37 * result + getHost().hashCode(); return result * 37 + port; } diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index f38e8987b..67ea8f631 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -563,7 +563,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { } for (HostAddress hostAddress : hostAddresses) { Iterator inetAddresses = null; - String host = hostAddress.getFQDN(); + String host = hostAddress.getHost(); int port = hostAddress.getPort(); if (proxyInfo == null) { inetAddresses = hostAddress.getInetAddresses().iterator(); From 685edde308972524c86feea82f74c1a60e650e29 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 2 Jul 2017 18:30:53 +0200 Subject: [PATCH 03/25] Don't hardcode "SunX509" as key algorithm in XMPPTCPConnection. Instead use the default algorithm. Fixes SMACK-771. --- .../java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 67ea8f631..fcb0bac22 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -745,7 +745,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { } if (ks != null) { - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + String keyManagerFactoryAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyManagerFactoryAlgorithm); try { if (pcb == null) { kmf.init(ks, null); From 7723210afb2752d8e0d75653471ed2c627e9abd5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 2 Jul 2017 18:54:31 +0200 Subject: [PATCH 04/25] Smack 4.2.1-beta1 --- version.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.gradle b/version.gradle index df62557f8..75113edca 100644 --- a/version.gradle +++ b/version.gradle @@ -1,7 +1,7 @@ allprojects { ext { - shortVersion = '4.2.1' - isSnapshot = true + shortVersion = '4.2.1-beta1' + isSnapshot = false jxmppVersion = '0.5.0' smackMinAndroidSdk = 8 } From 3fbdcfee63ca9f5c3eb10ba519fbc2c2625febae Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 2 Jul 2017 19:26:03 +0200 Subject: [PATCH 05/25] Smack 4.2.1-beta2-SNAPSHOT --- version.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.gradle b/version.gradle index 75113edca..4febee097 100644 --- a/version.gradle +++ b/version.gradle @@ -1,7 +1,7 @@ allprojects { ext { - shortVersion = '4.2.1-beta1' - isSnapshot = false + shortVersion = '4.2.1-beta2' + isSnapshot = true jxmppVersion = '0.5.0' smackMinAndroidSdk = 8 } From 2d4312272ce51a4526300739157bd05cc8a3aac5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 2 Jul 2017 22:11:14 +0200 Subject: [PATCH 06/25] Allow roster pushes from our full JID SMACK-773 --- .../org/jivesoftware/smack/roster/Roster.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index 9bfae16bc..dfd35a636 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -1676,8 +1676,8 @@ public final class Roster extends Manager { final XMPPConnection connection = connection(); RosterPacket rosterPacket = (RosterPacket) iqRequest; - EntityFullJid localAddress = connection.getUser(); - if (localAddress == null) { + EntityFullJid ourFullJid = connection.getUser(); + if (ourFullJid == null) { LOGGER.warning("Ignoring roster push " + iqRequest + " while " + connection + " has no bound resource. This may be a server bug."); return null; @@ -1685,12 +1685,23 @@ public final class Roster extends Manager { // Roster push (RFC 6121, 2.1.6) // A roster push with a non-empty from not matching our address MUST be ignored - EntityBareJid jid = localAddress.asEntityBareJid(); + EntityBareJid ourBareJid = ourFullJid.asEntityBareJid(); Jid from = rosterPacket.getFrom(); - if (from != null && !from.equals(jid)) { - LOGGER.warning("Ignoring roster push with a non matching 'from' ourJid='" + jid + "' from='" + from - + "'"); - return IQ.createErrorResponse(iqRequest, Condition.service_unavailable); + if (from != null) { + if (from.equals(ourFullJid)) { + // Since RFC 6121 roster pushes are no longer allowed to + // origin from the full JID as it was the case with RFC + // 3921. Log a warning an continue processing the push. + // See also SMACK-773. + LOGGER.warning( + "Received roster push from full JID. This behavior is since RFC 6121 not longer standard compliant. " + + "Please ask your server vendor to fix this and comply to RFC 6121 § 2.1.6. IQ roster push stanza: " + + iqRequest); + } else if (!from.equals(ourBareJid)) { + LOGGER.warning("Ignoring roster push with a non matching 'from' ourJid='" + ourBareJid + "' from='" + + from + "'"); + return IQ.createErrorResponse(iqRequest, Condition.service_unavailable); + } } // A roster push must contain exactly one entry From 3a79566f1caf8b8a6448a3cf4fcb78f8bbd3805d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 24 Jun 2017 10:02:41 +0200 Subject: [PATCH 07/25] OmemoManager: Fix typo s/defaulDeviceId/defaultDeviceId/ --- .../org/jivesoftware/smackx/omemo/OmemoManager.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java index dbebf20ce..faff979b0 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java @@ -163,13 +163,13 @@ public final class OmemoManager extends Manager { } } - int defaulDeviceId = OmemoService.getInstance().getOmemoStoreBackend().getDefaultDeviceId(user); - if (defaulDeviceId < 1) { - defaulDeviceId = randomDeviceId(); - OmemoService.getInstance().getOmemoStoreBackend().setDefaultDeviceId(user, defaulDeviceId); + int defaultDeviceId = OmemoService.getInstance().getOmemoStoreBackend().getDefaultDeviceId(user); + if (defaultDeviceId < 1) { + defaultDeviceId = randomDeviceId(); + OmemoService.getInstance().getOmemoStoreBackend().setDefaultDeviceId(user, defaultDeviceId); } - return getInstanceFor(connection, defaulDeviceId); + return getInstanceFor(connection, defaultDeviceId); } /** From 80b6e3019679b0b99a0db9895209ce663a3a4ca2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 3 Jul 2017 10:29:57 +0200 Subject: [PATCH 08/25] build.gradle: Do not resolve runtime configuration to early as it would cause "Cannot change dependencies of configuration after it has been included in dependency resolution" errors with Gradle >= 3. Thanks to James Justinic for pointing this out. --- build.gradle | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 716728794..6d1cceb7f 100644 --- a/build.gradle +++ b/build.gradle @@ -245,11 +245,18 @@ task distributionZip(type: Zip, dependsOn: [javadocAll, prepareReleasedocs, mark task maybeCheckForSnapshotDependencies { // Don't check for Snapshot dependencies if this is a snapshot. - if (isSnapshot) return - allprojects { project -> - project.configurations.runtime.each { - if (it.toString().contains("-SNAPSHOT")) - throw new Exception("Release build contains snapshot dependencies: " + it) + onlyIf { isReleaseVersion } + // Run in the execution phase, not in configuration phase, as the + // 'each' forces the runtime configuration to be resovled, which + // causes "Cannot change dependencies of configuration after it + // has been included in dependency resolution." errors. + // See https://discuss.gradle.org/t/23153 + doLast { + allprojects { project -> + project.configurations.runtime.each { + if (it.toString().contains("-SNAPSHOT")) + throw new Exception("Release build contains snapshot dependencies: " + it) + } } } } From b0298619bacf1690b304807aa744b14bf6b13fb8 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 3 Jul 2017 10:32:20 +0200 Subject: [PATCH 09/25] build.gradle: Use "def console" as otherwhise there may be a GroovyCastException: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'java.io.Console@148b13e5' with class 'java.io.Console' to class 'org.gradle.api.tasks.Console' at build_5dq456k95ni7h1f54hn45uzb7$_run_closure2.doCall(/home/flo/data/code/smack/build.gradle:194) at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:40) at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25) at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42) at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:221) at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:145) at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58) at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:315) at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:225) at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:138) at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:35) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) at com.sun.proxy.$Proxy59.graphPopulated(Unknown Source) at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:111) at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37) at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23) at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43) at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30) at org.gradle.initialization.DefaultGradleLauncher$RunTasksAction.execute(DefaultGradleLauncher.java:230) at org.gradle.initialization.DefaultGradleLauncher$RunTasksAction.execute(DefaultGradleLauncher.java:227) at org.gradle.internal.Transformers$4.transform(Transformers.java:169) at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106) at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56) at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:161) at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:112) at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:95) at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:66) at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28) at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35) at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41) at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26) at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75) at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49) at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:49) at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:31) at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:51) at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:173) at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:281) at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:254) at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:33) at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24) at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33) at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22) at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:247) at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:182) at org.gradle.launcher.Main.doAction(Main.java:33) at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45) at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:60) at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:37) at org.gradle.launcher.GradleMain.main(GradleMain.java:23) with some Gradle versions. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6d1cceb7f..e37ec8ead 100644 --- a/build.gradle +++ b/build.gradle @@ -191,7 +191,7 @@ gradle.taskGraph.whenReady { taskGraph -> if (signingRequired && taskGraph.allTasks.any { it instanceof Sign }) { // Use Java 6's console to read from the console (no good for a CI environment) - Console console = System.console() + def console = System.console() console.printf '\n\nWe have to sign some things in this build.\n\nPlease enter your signing details.\n\n' def password = console.readPassword('GnuPG Private Key Password: ') From ddabe439b4745d43a8f5c7a8c4c9278e7fbfec93 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 3 Jul 2017 10:36:05 +0200 Subject: [PATCH 10/25] build.gradle: Add hint about obtaining system console with newer Gradle versions and the Gradle daemon. --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index e37ec8ead..c358d9a1c 100644 --- a/build.gradle +++ b/build.gradle @@ -192,6 +192,9 @@ gradle.taskGraph.whenReady { taskGraph -> && taskGraph.allTasks.any { it instanceof Sign }) { // Use Java 6's console to read from the console (no good for a CI environment) def console = System.console() + if (console == null) { + throw new Exception("Could not obtain system console (Console is 'null'). Did you build with gradle daemon? Try the same Gradle command with \"--no-daemon\".") + } console.printf '\n\nWe have to sign some things in this build.\n\nPlease enter your signing details.\n\n' def password = console.readPassword('GnuPG Private Key Password: ') From 858ba3f82a2068bc7c1dcfeceaba1838ed315d82 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 5 Jul 2017 18:27:47 +0200 Subject: [PATCH 11/25] Fix HTTP File Upload's SlotRequest Fixes SMACK-774. Thanks to Nathan Freitas for reporting this. --- .../httpfileupload/element/SlotRequest.java | 14 +++++++------- .../element/SlotRequest_V0_2.java | 9 +++++++++ .../httpfileupload/SlotRequestCreateTest.java | 18 +++++++++--------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest.java index 882e93054..961fc27e1 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest.java @@ -32,9 +32,9 @@ public class SlotRequest extends IQ { public static final String ELEMENT = "request"; public static final String NAMESPACE = HttpFileUploadManager.NAMESPACE; - private final String filename; - private final long size; - private final String contentType; + protected final String filename; + protected final long size; + protected final String contentType; public SlotRequest(DomainBareJid uploadServiceAddress, String filename, long size) { this(uploadServiceAddress, filename, size, null); @@ -82,10 +82,10 @@ public class SlotRequest extends IQ { @Override protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { - xml.rightAngleBracket(); - xml.element("filename", filename); - xml.element("size", String.valueOf(size)); - xml.optElement("content-type", contentType); + xml.attribute("filename", filename); + xml.attribute("size", String.valueOf(size)); + xml.optAttribute("content-type", contentType); + xml.setEmptyElement(); return xml; } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest_V0_2.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest_V0_2.java index 4a7b02244..719371f52 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest_V0_2.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/httpfileupload/element/SlotRequest_V0_2.java @@ -40,4 +40,13 @@ public class SlotRequest_V0_2 extends SlotRequest { public SlotRequest_V0_2(DomainBareJid uploadServiceAddress, String filename, long size, String contentType) { super(uploadServiceAddress, filename, size, contentType, NAMESPACE); } + + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + xml.rightAngleBracket(); + xml.element("filename", filename); + xml.element("size", String.valueOf(size)); + xml.optElement("content-type", contentType); + return xml; + } } diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/httpfileupload/SlotRequestCreateTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/httpfileupload/SlotRequestCreateTest.java index 153dec1cc..e72c9dcf4 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/httpfileupload/SlotRequestCreateTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/httpfileupload/SlotRequestCreateTest.java @@ -27,17 +27,17 @@ import org.jxmpp.stringprep.XmppStringprepException; public class SlotRequestCreateTest { String testRequest - = "" - + "my_juliet.png" - + "23456" - + "image/jpeg" - + ""; + = ""; String testRequestWithoutContentType - = "" - + "my_romeo.png" - + "52523" - + ""; + = ""; @Test public void checkSlotRequestCreation() throws XmppStringprepException { From 9d63baf55a454ceef3c4e0ce001e4191e8f2fd07 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 5 Jul 2017 19:09:30 +0200 Subject: [PATCH 12/25] Use assertXMLEqual() in SlotRequestCreateTest --- .../httpfileupload/SlotRequestCreateTest.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/httpfileupload/SlotRequestCreateTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/httpfileupload/SlotRequestCreateTest.java index e72c9dcf4..525322357 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/httpfileupload/SlotRequestCreateTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/httpfileupload/SlotRequestCreateTest.java @@ -16,13 +16,16 @@ */ package org.jivesoftware.smackx.httpfileupload; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; + +import java.io.IOException; + import org.jivesoftware.smackx.httpfileupload.element.SlotRequest; import org.junit.Assert; import org.junit.Test; import org.jxmpp.jid.JidTestUtil; -import org.jxmpp.stringprep.XmppStringprepException; - +import org.xml.sax.SAXException; public class SlotRequestCreateTest { @@ -40,25 +43,25 @@ public class SlotRequestCreateTest { + "/>"; @Test - public void checkSlotRequestCreation() throws XmppStringprepException { + public void checkSlotRequestCreation() throws SAXException, IOException { SlotRequest slotRequest = new SlotRequest(JidTestUtil.DOMAIN_BARE_JID_1, "my_juliet.png", 23456, "image/jpeg"); Assert.assertEquals("my_juliet.png", slotRequest.getFilename()); Assert.assertEquals(23456, slotRequest.getSize()); Assert.assertEquals("image/jpeg", slotRequest.getContentType()); - Assert.assertEquals(testRequest, slotRequest.getChildElementXML().toString()); + assertXMLEqual(testRequest, slotRequest.getChildElementXML().toString()); } @Test - public void checkSlotRequestCreationWithoutContentType() throws XmppStringprepException { + public void checkSlotRequestCreationWithoutContentType() throws SAXException, IOException { SlotRequest slotRequest = new SlotRequest(JidTestUtil.DOMAIN_BARE_JID_1, "my_romeo.png", 52523); Assert.assertEquals("my_romeo.png", slotRequest.getFilename()); Assert.assertEquals(52523, slotRequest.getSize()); Assert.assertEquals(null, slotRequest.getContentType()); - Assert.assertEquals(testRequestWithoutContentType, slotRequest.getChildElementXML().toString()); + assertXMLEqual(testRequestWithoutContentType, slotRequest.getChildElementXML().toString()); } @Test(expected = IllegalArgumentException.class) From 419f6a336e24ca4effbde09b24f6c74122cd9fb9 Mon Sep 17 00:00:00 2001 From: vanitasvitae Date: Fri, 14 Jul 2017 16:09:37 +0200 Subject: [PATCH 13/25] Correct method name to getUndecidedDevices --- .../UndecidedOmemoIdentityException.java | 10 +++++----- .../smack/omemo/OmemoExceptionsTest.java | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/UndecidedOmemoIdentityException.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/UndecidedOmemoIdentityException.java index f7511445f..b477f539a 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/UndecidedOmemoIdentityException.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/UndecidedOmemoIdentityException.java @@ -35,20 +35,20 @@ public class UndecidedOmemoIdentityException extends Exception { } /** - * Return the HashSet of untrusted devices. + * Return the HashSet of undecided devices. * - * @return untrusted devices + * @return undecided devices */ - public HashSet getUntrustedDevices() { + public HashSet getUndecidedDevices() { return this.devices; } /** - * Add all untrusted devices of another Exception to this Exceptions HashSet of untrusted devices. + * Add all undecided devices of another Exception to this Exceptions HashSet of undecided devices. * * @param other other Exception */ public void join(UndecidedOmemoIdentityException other) { - this.devices.addAll(other.getUntrustedDevices()); + this.devices.addAll(other.getUndecidedDevices()); } } diff --git a/smack-omemo/src/test/java/org/jivesoftware/smack/omemo/OmemoExceptionsTest.java b/smack-omemo/src/test/java/org/jivesoftware/smack/omemo/OmemoExceptionsTest.java index 2de3a1505..e78f31630 100644 --- a/smack-omemo/src/test/java/org/jivesoftware/smack/omemo/OmemoExceptionsTest.java +++ b/smack-omemo/src/test/java/org/jivesoftware/smack/omemo/OmemoExceptionsTest.java @@ -45,18 +45,18 @@ public class OmemoExceptionsTest { OmemoDevice mallory = new OmemoDevice(JidCreate.bareFrom("mallory@server.tld"), 9876); UndecidedOmemoIdentityException u = new UndecidedOmemoIdentityException(alice); - assertTrue(u.getUntrustedDevices().contains(alice)); - assertTrue(u.getUntrustedDevices().size() == 1); + assertTrue(u.getUndecidedDevices().contains(alice)); + assertTrue(u.getUndecidedDevices().size() == 1); UndecidedOmemoIdentityException v = new UndecidedOmemoIdentityException(bob); - v.getUntrustedDevices().add(mallory); - assertTrue(v.getUntrustedDevices().size() == 2); - assertTrue(v.getUntrustedDevices().contains(bob)); - assertTrue(v.getUntrustedDevices().contains(mallory)); + v.getUndecidedDevices().add(mallory); + assertTrue(v.getUndecidedDevices().size() == 2); + assertTrue(v.getUndecidedDevices().contains(bob)); + assertTrue(v.getUndecidedDevices().contains(mallory)); - u.getUntrustedDevices().add(bob); + u.getUndecidedDevices().add(bob); u.join(v); - assertTrue(u.getUntrustedDevices().size() == 3); + assertTrue(u.getUndecidedDevices().size() == 3); } @Test From 0b8788a9fc52b060ac302970a3261ca5ab734036 Mon Sep 17 00:00:00 2001 From: Ingo Bauersachs Date: Thu, 20 Jul 2017 22:50:34 +0200 Subject: [PATCH 14/25] Fix parameter ordering in BoBHash construction --- .../src/main/java/org/jivesoftware/smackx/bob/BoBManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bob/BoBManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bob/BoBManager.java index 0c853a864..f7c7d261f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bob/BoBManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bob/BoBManager.java @@ -159,7 +159,7 @@ public final class BoBManager extends Manager { public BoBInfo addBoB(BoBData bobData) { // We only support SHA-1 for now. - BoBHash bobHash = new BoBHash("sha1", SHA1.hex(bobData.getContent())); + BoBHash bobHash = new BoBHash(SHA1.hex(bobData.getContent()), "sha1"); Set bobHashes = Collections.singleton(bobHash); bobHashes = Collections.unmodifiableSet(bobHashes); From 57e19d1a4f0ab00fb158da33c4d4514540a7aba1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 19 Jul 2017 13:59:11 +0200 Subject: [PATCH 15/25] Use Async.go() in OmemoCarbonCopyListener to prevent a timeout exception since carbon copy listeners are executed synchronously. --- .../smackx/omemo/OmemoService.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java index d3b6957c1..9138ca15f 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java @@ -50,6 +50,8 @@ import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.XMPPError; +import org.jivesoftware.smack.util.Async; + import org.jivesoftware.smackx.carbons.CarbonCopyReceivedListener; import org.jivesoftware.smackx.carbons.CarbonManager; import org.jivesoftware.smackx.carbons.packet.CarbonExtension; @@ -1308,7 +1310,7 @@ public abstract class OmemoService Date: Wed, 19 Jul 2017 14:00:15 +0200 Subject: [PATCH 16/25] Use Async.go() in OmemoManager's connection listener to prevent a timeout exception since those are executed synchronously. --- .../smackx/omemo/OmemoManager.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java index faff979b0..6a706295b 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java @@ -41,6 +41,7 @@ import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.util.Async; import org.jivesoftware.smackx.carbons.CarbonManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; @@ -654,12 +655,18 @@ public final class OmemoManager extends Manager { if (resumed) { return; } - try { - initialize(); - } catch (InterruptedException | CorruptedOmemoKeyException | PubSubException.NotALeafNodeException | SmackException.NotLoggedInException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { - LOGGER.log(Level.SEVERE, "connectionListener.authenticated() failed to initialize OmemoManager: " - + e.getMessage()); - } + Async.go(new Runnable() { + @Override + public void run() { + try { + initialize(); + } catch (InterruptedException | CorruptedOmemoKeyException | PubSubException.NotALeafNodeException | SmackException.NotLoggedInException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { + LOGGER.log(Level.SEVERE, "connectionListener.authenticated() failed to initialize OmemoManager: " + + e.getMessage()); + } + } + }); + } @Override From 7b5eecb82119dfdccd1eb818cae81934f45c5c9c Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 19 Jul 2017 14:02:20 +0200 Subject: [PATCH 17/25] Use AbstractConnectionListener in OmemoManager and manually inline the setConnectionListener() method. --- .../smackx/omemo/OmemoManager.java | 79 ++++++------------- 1 file changed, 23 insertions(+), 56 deletions(-) diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java index 6a706295b..d4b09dd9f 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java @@ -32,8 +32,8 @@ import java.util.WeakHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import org.jivesoftware.smack.AbstractConnectionListener; import org.jivesoftware.smack.AbstractXMPPConnection; -import org.jivesoftware.smack.ConnectionListener; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; @@ -111,8 +111,29 @@ public final class OmemoManager extends Manager { */ private OmemoManager(XMPPConnection connection, int deviceId) { super(connection); - setConnectionListener(); + this.deviceId = deviceId; + + connection.addConnectionListener(new AbstractConnectionListener() { + @Override + public void authenticated(XMPPConnection connection, boolean resumed) { + if (resumed) { + return; + } + Async.go(new Runnable() { + @Override + public void run() { + try { + initialize(); + } catch (InterruptedException | CorruptedOmemoKeyException | PubSubException.NotALeafNodeException | SmackException.NotLoggedInException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { + LOGGER.log(Level.SEVERE, "connectionListener.authenticated() failed to initialize OmemoManager: " + + e.getMessage()); + } + } + }); + } + }); + service = OmemoService.getInstance(); } @@ -642,60 +663,6 @@ public final class OmemoManager extends Manager { } } - private void setConnectionListener() { - connection().addConnectionListener(new ConnectionListener() { - @Override - public void connected(XMPPConnection connection) { - LOGGER.log(Level.INFO, "connected"); - } - - @Override - public void authenticated(XMPPConnection connection, boolean resumed) { - LOGGER.log(Level.INFO, "authenticated. Resumed: " + resumed); - if (resumed) { - return; - } - Async.go(new Runnable() { - @Override - public void run() { - try { - initialize(); - } catch (InterruptedException | CorruptedOmemoKeyException | PubSubException.NotALeafNodeException | SmackException.NotLoggedInException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { - LOGGER.log(Level.SEVERE, "connectionListener.authenticated() failed to initialize OmemoManager: " - + e.getMessage()); - } - } - }); - - } - - @Override - public void connectionClosed() { - - } - - @Override - public void connectionClosedOnError(Exception e) { - connectionClosed(); - } - - @Override - public void reconnectionSuccessful() { - - } - - @Override - public void reconnectingIn(int seconds) { - - } - - @Override - public void reconnectionFailed(Exception e) { - - } - }); - } - public static int randomDeviceId() { int i = new Random().nextInt(Integer.MAX_VALUE); From 2050b2f8b9cd4254ba05ac690a92148dadd4f07e Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 19 Jul 2017 14:06:34 +0200 Subject: [PATCH 18/25] Remove OmemoManager.resourceSupportsOmemo() since there is currently no way to determine if a full JID supports OMEMO. --- .../smackx/omemo/OmemoManager.java | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java index d4b09dd9f..d17582172 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java @@ -19,7 +19,6 @@ package org.jivesoftware.smackx.omemo; import static org.jivesoftware.smackx.omemo.util.OmemoConstants.BODY_OMEMO_HINT; import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO; import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL; -import static org.jivesoftware.smackx.omemo.util.OmemoConstants.PEP_NODE_DEVICE_LIST_NOTIFY; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -79,7 +78,6 @@ import org.jxmpp.jid.BareJid; import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; -import org.jxmpp.jid.FullJid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.stringprep.XmppStringprepException; @@ -493,24 +491,6 @@ public final class OmemoManager extends Manager { .getActiveDevices().isEmpty(); } - /** - * Returns true, if the device resource has announced OMEMO support. - * Throws an IllegalArgumentException if the provided FullJid does not have a resource part. - * - * @param fullJid jid of a resource - * @return true if resource supports OMEMO - * @throws XMPPException.XMPPErrorException if - * @throws SmackException.NotConnectedException something - * @throws InterruptedException goes - * @throws SmackException.NoResponseException wrong - */ - public boolean resourceSupportsOmemo(FullJid fullJid) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { - if (fullJid.hasNoResource()) { - throw new IllegalArgumentException("Jid " + fullJid + " has no resource part."); - } - return ServiceDiscoveryManager.getInstanceFor(connection()).discoverInfo(fullJid).containsFeature(PEP_NODE_DEVICE_LIST_NOTIFY); - } - /** * Returns true, if the MUC with the EntityBareJid multiUserChat is non-anonymous and members only (prerequisite * for OMEMO encryption in MUC). From fc17cf4e2d76b319e1a3c96e46e2a7a63960f341 Mon Sep 17 00:00:00 2001 From: Ingo Bauersachs Date: Sat, 15 Jul 2017 13:40:40 +0200 Subject: [PATCH 19/25] Fix link to OMEMO extension --- documentation/extensions/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/extensions/index.md b/documentation/extensions/index.md index 2eaa34d78..ede8f1877 100644 --- a/documentation/extensions/index.md +++ b/documentation/extensions/index.md @@ -94,7 +94,7 @@ Experimental Smack Extensions and currently supported XEPs of smack-experimental | [Push Notifications](pushnotifications.md) | [XEP-0357](http://xmpp.org/extensions/xep-0357.html) | Defines a way to manage push notifications from an XMPP Server. | | HTTP File Upload | [XEP-0363](http://xmpp.org/extensions/xep-0363.html) | Protocol to request permissions to upload a file to an HTTP server and get a shareable URL. | | [Multi-User Chat Light](muclight.md) | [XEP-xxxx](http://mongooseim.readthedocs.io/en/latest/open-extensions/xeps/xep-muc-light.html) | Multi-User Chats for mobile XMPP applications and specific enviroment. | -| [OMEMO End Encryption (omemo.md) | [XEP-0384](http://xmpp.org/extensions/xep-0384.html) | Encrypt messages using OMEMO encryption (currently only with smack-omemo-signal -> GPLv3). | +| [OMEMO End Encryption](omemo.md) | [XEP-0384](http://xmpp.org/extensions/xep-0384.html) | Encrypt messages using OMEMO encryption (currently only with smack-omemo-signal -> GPLv3). | | Google GCM JSON payload | n/a | Semantically the same as XEP-0335: JSON Containers | From c9b9558cd428e8a899c4ef44c99b9782a43434ee Mon Sep 17 00:00:00 2001 From: Ingo Bauersachs Date: Tue, 1 Aug 2017 16:17:35 +0200 Subject: [PATCH 20/25] Make add/remove for presence interceptors consistent --- .../main/java/org/jivesoftware/smackx/muc/MultiUserChat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 11ff6ac83..5d95069ce 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -1011,7 +1011,7 @@ public class MultiUserChat { * * @param presenceInterceptor the stanza(/packet) interceptor to remove. */ - public void removePresenceInterceptor(StanzaListener presenceInterceptor) { + public void removePresenceInterceptor(PresenceListener presenceInterceptor) { presenceInterceptors.remove(presenceInterceptor); } From b497a236f95453048bf9c25949bd736a9b5de530 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 25 Jul 2017 08:34:36 +0200 Subject: [PATCH 21/25] Improve StanzaListner javadoc --- .../src/main/java/org/jivesoftware/smack/StanzaListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/StanzaListener.java b/smack-core/src/main/java/org/jivesoftware/smack/StanzaListener.java index 992639a95..fb9b1b283 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/StanzaListener.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/StanzaListener.java @@ -41,7 +41,7 @@ public interface StanzaListener { /** * Process the next stanza(/packet) sent to this stanza(/packet) listener. *

- * A single thread is responsible for invoking all listeners, so + * If this listener is synchronous, then a single thread is responsible for invoking all listeners, so * it's very important that implementations of this method not block * for any extended period of time. *

From 7404bf8fe71afefbcc6cb2f2d8690ab75ecd01b7 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 14 Aug 2017 15:12:13 +0200 Subject: [PATCH 22/25] Fix OMEMO entry in extensions/index.md --- documentation/extensions/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/extensions/index.md b/documentation/extensions/index.md index ede8f1877..abc5e2f1f 100644 --- a/documentation/extensions/index.md +++ b/documentation/extensions/index.md @@ -1,4 +1,4 @@ -smackSmack Extensions User Manual +Smack Extensions User Manual ============================ The XMPP protocol includes a base protocol and many optional extensions @@ -94,7 +94,7 @@ Experimental Smack Extensions and currently supported XEPs of smack-experimental | [Push Notifications](pushnotifications.md) | [XEP-0357](http://xmpp.org/extensions/xep-0357.html) | Defines a way to manage push notifications from an XMPP Server. | | HTTP File Upload | [XEP-0363](http://xmpp.org/extensions/xep-0363.html) | Protocol to request permissions to upload a file to an HTTP server and get a shareable URL. | | [Multi-User Chat Light](muclight.md) | [XEP-xxxx](http://mongooseim.readthedocs.io/en/latest/open-extensions/xeps/xep-muc-light.html) | Multi-User Chats for mobile XMPP applications and specific enviroment. | -| [OMEMO End Encryption](omemo.md) | [XEP-0384](http://xmpp.org/extensions/xep-0384.html) | Encrypt messages using OMEMO encryption (currently only with smack-omemo-signal -> GPLv3). | +| [OMEMO Multi End Message and Object Encryption](omemo.md) | [XEP-XXXX](https://conversations.im/omemo/xep-omemo.html) | Encrypt messages using OMEMO encryption (currently only with smack-omemo-signal -> GPLv3). | | Google GCM JSON payload | n/a | Semantically the same as XEP-0335: JSON Containers | From b9ed22c732d295a2d7017e26837bc2f047f527b4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 14 Aug 2017 19:04:58 +0200 Subject: [PATCH 23/25] Add MamManager.isSupported() Fixes SMACK-777. --- .../jivesoftware/smackx/mam/MamManager.java | 24 +++++++++++++++++++ .../smackx/mam/MamIntegrationTest.java | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java index fb9c2535c..9d800f73c 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java @@ -50,6 +50,7 @@ import org.jivesoftware.smackx.rsm.packet.RSMSet; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; +import org.jxmpp.jid.BareJid; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.Jid; @@ -103,9 +104,12 @@ public final class MamManager extends Manager { private final Jid archiveAddress; + private final ServiceDiscoveryManager serviceDiscoveryManager; + private MamManager(XMPPConnection connection, Jid archiveAddress) { super(connection); this.archiveAddress = archiveAddress; + serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); } /** @@ -586,6 +590,23 @@ public final class MamManager extends Manager { } } + /** + * Check if MAM is supported for the XMPP connection managed by this MamManager. + * + * @return true if MAM is supported for the XMPP connection, falseotherwhise. + * + * @throws NoResponseException + * @throws XMPPErrorException + * @throws NotConnectedException + * @throws InterruptedException + * @since 4.2.1 + * @see XEP-0313 § 7. Determining support + */ + public boolean isSupported() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + BareJid myBareJid = connection().getUser().asBareJid(); + return serviceDiscoveryManager.supportsFeature(myBareJid, MamElements.NAMESPACE); + } + /** * Returns true if Message Archive Management is supported by the server. * @@ -594,7 +615,10 @@ public final class MamManager extends Manager { * @throws XMPPErrorException * @throws NoResponseException * @throws InterruptedException + * @depreacted use {@link #isSupported()} instead. */ + @Deprecated + // TODO Remove in Smack 4.3 public boolean isSupportedByServer() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { return ServiceDiscoveryManager.getInstanceFor(connection()).serverSupportsFeature(MamElements.NAMESPACE); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java index 665194be9..587885229 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java @@ -46,7 +46,7 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest { mamManagerConTwo = MamManager.getInstanceFor(conTwo); - if (!mamManagerConTwo.isSupportedByServer()) { + if (!mamManagerConTwo.isSupported()) { throw new TestNotPossibleException("Message Archive Management (XEP-0313) is not supported by the server."); } From 772e45da92750134110f17a5c4806b0db4966154 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 14 Aug 2017 20:14:35 +0200 Subject: [PATCH 24/25] Introduce NotAPubSubNodeException Fixes SMACK-759. --- .../jivesoftware/smackx/pep/PEPManager.java | 4 +- .../smackx/pubsub/PubSubAssertionError.java | 45 ------------------- .../smackx/pubsub/PubSubException.java | 38 +++++++++++++--- .../smackx/pubsub/PubSubManager.java | 23 +++++++--- .../smackx/omemo/OmemoInitializationTest.java | 4 +- .../omemo/OmemoIntegrationTestHelper.java | 12 ++--- .../smackx/omemo/OmemoMessageSendingTest.java | 9 +++- .../smackx/omemo/OmemoService.java | 31 +++++++------ 8 files changed, 86 insertions(+), 80 deletions(-) delete mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubAssertionError.java diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java index ca5bb629d..ca0a582b2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java @@ -39,6 +39,7 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.pubsub.EventElement; import org.jivesoftware.smackx.pubsub.Item; import org.jivesoftware.smackx.pubsub.LeafNode; +import org.jivesoftware.smackx.pubsub.PubSubException.NotAPubSubNodeException; import org.jivesoftware.smackx.pubsub.PubSubFeature; import org.jivesoftware.smackx.pubsub.PubSubManager; import org.jivesoftware.smackx.pubsub.filter.EventExtensionFilter; @@ -137,9 +138,10 @@ public final class PEPManager extends Manager { * @throws InterruptedException * @throws XMPPErrorException * @throws NoResponseException + * @throws NotAPubSubNodeException */ public void publish(Item item, String node) throws NotConnectedException, InterruptedException, - NoResponseException, XMPPErrorException { + NoResponseException, XMPPErrorException, NotAPubSubNodeException { XMPPConnection connection = connection(); PubSubManager pubSubManager = PubSubManager.getInstance(connection, connection.getUser().asEntityBareJid()); LeafNode pubSubNode = pubSubManager.getNode(node); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubAssertionError.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubAssertionError.java deleted file mode 100644 index 50bb26383..000000000 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubAssertionError.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * - * Copyright 2017 Florian Schmaus - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jivesoftware.smackx.pubsub; - -import org.jxmpp.jid.BareJid; - -public abstract class PubSubAssertionError extends AssertionError { - - /** - * - */ - private static final long serialVersionUID = 1L; - - protected PubSubAssertionError(String message) { - super(message); - } - - public static class DiscoInfoNodeAssertionError extends PubSubAssertionError { - - /** - * - */ - private static final long serialVersionUID = 1L; - - DiscoInfoNodeAssertionError(BareJid pubSubService, String nodeId) { - super("PubSub service '" + pubSubService + "' returned disco info result for node '" + nodeId - + "', but it did not contain an Identity of type 'leaf' or 'collection' (and category 'pubsub'), which is not allowed according to XEP-60 5.3."); - } - - } -} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubException.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubException.java index cb65d8278..5deac4931 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubException.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubException.java @@ -18,6 +18,8 @@ package org.jivesoftware.smackx.pubsub; import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smackx.disco.packet.DiscoverInfo; + import org.jxmpp.jid.BareJid; public abstract class PubSubException extends SmackException { @@ -27,6 +29,16 @@ public abstract class PubSubException extends SmackException { */ private static final long serialVersionUID = 1L; + private final String nodeId; + + protected PubSubException(String nodeId) { + this.nodeId = nodeId; + } + + public String getNodeId() { + return nodeId; + } + public static class NotALeafNodeException extends PubSubException { /** @@ -34,21 +46,35 @@ public abstract class PubSubException extends SmackException { */ private static final long serialVersionUID = 1L; - private final String nodeId; private final BareJid pubSubService; NotALeafNodeException(String nodeId, BareJid pubSubService) { - this.nodeId = nodeId; + super(nodeId); this.pubSubService = pubSubService; } - public String getNodeId() { - return nodeId; - } - public BareJid getPubSubService() { return pubSubService; } } + + public static class NotAPubSubNodeException extends PubSubException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private final DiscoverInfo discoverInfo; + + NotAPubSubNodeException(String nodeId, DiscoverInfo discoverInfo) { + super(nodeId); + this.discoverInfo = discoverInfo; + } + + public DiscoverInfo getDiscoverInfo() { + return discoverInfo; + } + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index c16ce3073..4a364c5a7 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -42,6 +42,7 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.pubsub.PubSubException.NotALeafNodeException; +import org.jivesoftware.smackx.pubsub.PubSubException.NotAPubSubNodeException; import org.jivesoftware.smackx.pubsub.packet.PubSub; import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace; import org.jivesoftware.smackx.pubsub.util.NodeUtils; @@ -229,8 +230,9 @@ public final class PubSubManager extends Manager { * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException * @throws InterruptedException + * @throws NotAPubSubNodeException */ - public T getNode(String id) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException + public T getNode(String id) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, NotAPubSubNodeException { Node node = nodeMap.get(id); @@ -249,10 +251,7 @@ public final class PubSubManager extends Manager { node = new CollectionNode(this, id); } else { - // XEP-60 5.3 states that - // "The 'disco#info' result MUST include an identity with a category of 'pubsub' and a type of either 'leaf' or 'collection'." - // If this is not the case, then we are dealing with an PubSub implementation that doesn't follow the specification. - throw new PubSubAssertionError.DiscoInfoNodeAssertionError(pubSubService, id); + throw new PubSubException.NotAPubSubNodeException(id, infoReply); } nodeMap.put(id, node); } @@ -278,6 +277,9 @@ public final class PubSubManager extends Manager { try { return getNode(id); } + catch (NotAPubSubNodeException e) { + return createNode(id); + } catch (XMPPErrorException e1) { if (e1.getXMPPError().getCondition() == Condition.item_not_found) { try { @@ -286,7 +288,13 @@ public final class PubSubManager extends Manager { catch (XMPPErrorException e2) { if (e2.getXMPPError().getCondition() == Condition.conflict) { // The node was created in the meantime, re-try getNode(). Note that this case should be rare. - return getNode(id); + try { + return getNode(id); + } + catch (NotAPubSubNodeException e) { + // Should not happen + throw new IllegalStateException(e); + } } throw e2; } @@ -313,10 +321,11 @@ public final class PubSubManager extends Manager { * @throws NotConnectedException * @throws InterruptedException * @throws XMPPErrorException + * @throws NotAPubSubNodeException * @since 4.2.1 */ public LeafNode getLeafNode(String id) throws NotALeafNodeException, NoResponseException, NotConnectedException, - InterruptedException, XMPPErrorException { + InterruptedException, XMPPErrorException, NotAPubSubNodeException { Node node; try { node = getNode(id); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoInitializationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoInitializationTest.java index 155b9ca3a..e019dce82 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoInitializationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoInitializationTest.java @@ -30,6 +30,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException; import org.jivesoftware.smackx.omemo.util.OmemoConstants; import org.jivesoftware.smackx.pubsub.PubSubException; +import org.jivesoftware.smackx.pubsub.PubSubException.NotAPubSubNodeException; import org.igniterealtime.smack.inttest.SmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; @@ -52,9 +53,10 @@ public class OmemoInitializationTest extends AbstractOmemoIntegrationTest { /** * Tests, if the initialization is done properly. + * @throws NotAPubSubNodeException */ @SmackIntegrationTest - public void initializationTest() throws XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, SmackException.NotLoggedInException, CorruptedOmemoKeyException { + public void initializationTest() throws XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, SmackException.NotLoggedInException, CorruptedOmemoKeyException, NotAPubSubNodeException { //test keys. setUpOmemoManager(alice); assertNotNull("IdentityKey must not be null after initialization.", store.loadOmemoIdentityKeyPair(alice)); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoIntegrationTestHelper.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoIntegrationTestHelper.java index 08b9b356b..78895cf08 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoIntegrationTestHelper.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoIntegrationTestHelper.java @@ -34,8 +34,8 @@ import org.jivesoftware.smackx.omemo.exceptions.CannotEstablishOmemoSessionExcep import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException; import org.jivesoftware.smackx.omemo.internal.CachedDeviceList; import org.jivesoftware.smackx.omemo.util.OmemoConstants; -import org.jivesoftware.smackx.pubsub.PubSubAssertionError; import org.jivesoftware.smackx.pubsub.PubSubException; +import org.jivesoftware.smackx.pubsub.PubSubException.NotAPubSubNodeException; import org.jivesoftware.smackx.pubsub.PubSubManager; /** @@ -70,26 +70,26 @@ final class OmemoIntegrationTestHelper { for (int id : deviceList.getAllDevices()) { try { pm.getLeafNode(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(id)).deleteAllItems(); - } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | PubSubAssertionError.DiscoInfoNodeAssertionError e) { + } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | NotAPubSubNodeException e) { //Silent } try { pm.deleteNode(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(id)); - } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | PubSubAssertionError e) { + } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { //Silent } } try { pm.getLeafNode(OmemoConstants.PEP_NODE_DEVICE_LIST).deleteAllItems(); - } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | PubSubAssertionError.DiscoInfoNodeAssertionError e) { + } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | NotAPubSubNodeException e) { //Silent } try { pm.deleteNode(OmemoConstants.PEP_NODE_DEVICE_LIST); - } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | PubSubAssertionError e) { + } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { //Silent } } @@ -147,7 +147,7 @@ final class OmemoIntegrationTestHelper { } - static void setUpOmemoManager(OmemoManager omemoManager) throws CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException, SmackException.NotConnectedException, XMPPException.XMPPErrorException, SmackException.NotLoggedInException, PubSubException.NotALeafNodeException { + static void setUpOmemoManager(OmemoManager omemoManager) throws CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException, SmackException.NotConnectedException, XMPPException.XMPPErrorException, SmackException.NotLoggedInException, PubSubException.NotALeafNodeException, NotAPubSubNodeException { omemoManager.initialize(); OmemoBundleElement bundle = OmemoService.fetchBundle(omemoManager, omemoManager.getOwnDevice()); assertNotNull("Bundle must not be null.", bundle); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessageSendingTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessageSendingTest.java index 690c19b81..bcdc29ed3 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessageSendingTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessageSendingTest.java @@ -40,6 +40,7 @@ import org.jivesoftware.smackx.omemo.internal.CipherAndAuthTag; import org.jivesoftware.smackx.omemo.internal.OmemoMessageInformation; import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener; import org.jivesoftware.smackx.pubsub.PubSubException; +import org.jivesoftware.smackx.pubsub.PubSubException.NotAPubSubNodeException; import junit.framework.TestCase; import org.igniterealtime.smack.inttest.SmackIntegrationTest; @@ -85,9 +86,15 @@ public class OmemoMessageSendingTest extends AbstractOmemoIntegrationTest { * @throws UndecidedOmemoIdentityException * @throws NoSuchAlgorithmException * @throws CryptoFailedException + * @throws NotAPubSubNodeException */ @SmackIntegrationTest - public void messageSendingTest() throws CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException, SmackException.NotConnectedException, XMPPException.XMPPErrorException, SmackException.NotLoggedInException, PubSubException.NotALeafNodeException, CannotEstablishOmemoSessionException, UndecidedOmemoIdentityException, NoSuchAlgorithmException, CryptoFailedException { + public void messageSendingTest() + throws CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException, + SmackException.NotConnectedException, XMPPException.XMPPErrorException, + SmackException.NotLoggedInException, PubSubException.NotALeafNodeException, + CannotEstablishOmemoSessionException, UndecidedOmemoIdentityException, NoSuchAlgorithmException, + CryptoFailedException, PubSubException.NotAPubSubNodeException { final String alicesSecret = "Hey Bob! I love you!"; final String bobsSecret = "I love you too, Alice."; //aww <3 diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java index 9138ca15f..093767166 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java @@ -82,8 +82,8 @@ import org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder; import org.jivesoftware.smackx.pep.PEPManager; import org.jivesoftware.smackx.pubsub.LeafNode; import org.jivesoftware.smackx.pubsub.PayloadItem; -import org.jivesoftware.smackx.pubsub.PubSubAssertionError; import org.jivesoftware.smackx.pubsub.PubSubException; +import org.jivesoftware.smackx.pubsub.PubSubException.NotAPubSubNodeException; import org.jivesoftware.smackx.pubsub.PubSubManager; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -428,11 +428,11 @@ public abstract class OmemoService Date: Mon, 14 Aug 2017 14:32:26 +0200 Subject: [PATCH 25/25] Smack 4.2.1 --- build.gradle | 12 +++++++ resources/releasedocs/changelog.html | 51 ++++++++++++++++++++++++++++ version.gradle | 4 +-- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index c358d9a1c..a8b0bb1ec 100644 --- a/build.gradle +++ b/build.gradle @@ -412,6 +412,18 @@ configure(integrationTestProjects + project(':smack-repl')) { project(':smack-omemo').clirr.enabled = false project(':smack-omemo-signal').clirr.enabled = false +configure( + [ ':smack-omemo', + ':smack-omemo-signal', + ':smack-omemo-signal-integration-test', + ].collect{ project(it) }) { + uploadArchives { + // Only enable uploadArchives for the smack-omemo* projects + // for snapshots. Not yet for releases. + enabled = isSnapshot + } +} + subprojects*.jar { manifest { from sharedManifest diff --git a/resources/releasedocs/changelog.html b/resources/releasedocs/changelog.html index b8909c036..7d4dbc1d9 100644 --- a/resources/releasedocs/changelog.html +++ b/resources/releasedocs/changelog.html @@ -141,6 +141,57 @@ hr {
+

4.2.1 -- 2017-08-14

+ +

Bug +

+
    +
  • [SMACK-749] - SCRAM-SHA-1 and SCRAM-SHA-1-PLUS SASL mechanisms have the same priority, causing SASL authentication failures +
  • +
  • [SMACK-755] - DIGEST-MD5 sometimes causes malformed request server response +
  • +
  • [SMACK-756] - IoTIsFriendResponse has invalid name and produces invalid XML +
  • +
  • [SMACK-759] - PubSubManager.getLeafNode() throws PubSubAssertionError.DiscoInfoNodeAssertionError if node exists but its not a PubSub Node +
  • +
  • [SMACK-764] - NPE in hashCode() in Occupant when jid is null +
  • +
  • [SMACK-766] - Smack possibly includes 'ask' attribute in roster items when sending requests +
  • +
  • [SMACK-768] - Smack throws NoResponse timeout when waiting for IQ although there was a response +
  • +
  • [SMACK-771] - XMPPTCPConnection should use KeyManagerFactory.getDefaultAlgorithm() instead of KeyManagerFactory.getInstance("sunX509"); +
  • +
  • [SMACK-772] - HostAddress must deal with 'fqdn' being null. +
  • +
  • [SMACK-773] - Allow roster pushes from our full JID for backwards compatibility +
  • +
  • [SMACK-774] - HTTP File Upload's SlotRequest metadata should be attributes not child elements +
  • +
+ +

New Feature +

+
    +
  • [SMACK-746] - Add support for XEP-0380: Explicit Message Encryption +
  • +
  • [SMACK-758] - Add support for XEP-0334: Message Processing Hints +
  • +
  • [SMACK-760] - Smack does not allow custom extension elements in SM's <failed/> +
  • +
+ +

Improvement +

+
    +
  • [SMACK-752] - XEP-0357 Push Notification enable IQ uses wrong form type: Should be 'submit' instead of 'form' +
  • +
  • [SMACK-754] - Allow MUC room subject changes from the MUCs bare JID +
  • +
  • [SMACK-777] - MamManager should use the user's bare JID to check if MAM is supported +
  • +
+

4.2.0 -- 2017-03-10

Sub-task diff --git a/version.gradle b/version.gradle index 4febee097..1988ed131 100644 --- a/version.gradle +++ b/version.gradle @@ -1,7 +1,7 @@ allprojects { ext { - shortVersion = '4.2.1-beta2' - isSnapshot = true + shortVersion = '4.2.1' + isSnapshot = false jxmppVersion = '0.5.0' smackMinAndroidSdk = 8 }