mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-26 05:52:06 +01:00
Compare commits
No commits in common. "4249c1a845320e8d92f415b59d7fa06e3bcfe194" and "3e74d11b45fc796984dcc2e8142c3bafad2919fe" have entirely different histories.
4249c1a845
...
3e74d11b45
51 changed files with 616 additions and 911 deletions
|
@ -99,7 +99,6 @@ allprojects {
|
|||
gplLicensedProjects = [
|
||||
':smack-omemo-signal',
|
||||
':smack-omemo-signal-integration-test',
|
||||
':smack-repl'
|
||||
].collect{ project(it) }
|
||||
// When this list is empty, then move the according javadoc
|
||||
// tool Werror option into the global configure section.
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 20XX John Doe
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
|
@ -81,7 +81,7 @@ completed with default values:
|
|||
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
|
||||
|
||||
// Create a MultiUserChat using an XMPPConnection for a room
|
||||
MultiUserChat muc = manager.getMultiUserChat(mucJid);
|
||||
MultiUserChat muc = = manager.getMultiUserChat(mucJid);
|
||||
|
||||
// Prepare a list of owners of the new room
|
||||
Set<Jid> owners = JidUtil.jidSetFrom(new String[] { "me@example.org", "juliet@example.org" });
|
||||
|
|
|
@ -62,7 +62,7 @@ XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
|
|||
.setPort(8222)
|
||||
.build();
|
||||
|
||||
AbstractXMPPConnection conn2 = new XMPPTCPConnection(config);
|
||||
AbstractXMPPConnection conn2 = **new** XMPPTCPConnection(config);
|
||||
conn2.connect().login();
|
||||
```
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@ and a stanza listener:
|
|||
```
|
||||
// Create a stanza filter to listen for new messages from a particular
|
||||
// user. We use an AndFilter to combine two other filters._
|
||||
StanzaFilter filter = new AndFilter(StanzaTypeFilter.MESSAGE,
|
||||
FromMatchesFilter.create(JidCreate.entityBareFrom("mary@jivesoftware.com")));
|
||||
StanzaFilter filter = new AndFilter(StanzaTypeFilter.MESSAGE, FromMatchesFilter.create("mary@jivesoftware.com"));
|
||||
// Assume we've created an XMPPConnection named "connection".
|
||||
|
||||
// First, register a stanza collector using the filter we created.
|
||||
|
@ -30,7 +29,7 @@ StanzaCollector myCollector = connection.createStanzaCollector(filter);
|
|||
|
||||
// Next, create a stanza listener. We use an anonymous inner class for brevity.
|
||||
StanzaListener myListener = new StanzaListener() {
|
||||
public void processStanza(Stanza stanza) {
|
||||
**public** **void** processStanza(Stanza stanza) {
|
||||
// Do something with the incoming stanza here._
|
||||
}
|
||||
};
|
||||
|
|
|
@ -46,9 +46,9 @@ ProviderManager.addExtensionProvider("element", "namespace", new MyExtProvider()
|
|||
|
||||
* Add a loader - You can add a ProviderLoader which will inject a means of loading multiple providers (both types) into the manager. This is the mechanism used by Smack to load from the Smack specific file format (via ProviderFileLoader). Implementers can provide the means to load providers from any source they wish, or simply reuse the ProviderFileLoader to load from their own provider files.
|
||||
|
||||
```
|
||||
|
||||
ProviderManager.addLoader(new ProviderFileLoader(FileUtils.getStreamForUrl("classpath:com/myco/provider/myco_custom.providers", null)));
|
||||
```
|
||||
|
||||
|
||||
* VM Argument - You can add a provider file via the VM argument _smack.provider.file_. This will load the file at the specified URL during startup when Smack initializes. This also assumes the default configuration, since it requires that the **VmArgInitializer** was part of the startup configuration.
|
||||
|
||||
|
|
|
@ -141,32 +141,6 @@ hr {
|
|||
|
||||
<div id="pageBody">
|
||||
|
||||
<h2>4.3.4 -- <span style="font-weight: normal;">2019-05-27</span></h2>
|
||||
|
||||
<h2> Bug
|
||||
</h2>
|
||||
<ul>
|
||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-861'>SMACK-861</a>] - Potential NPE in Roster.getPresencesInternal(BareJid)
|
||||
</li>
|
||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-863'>SMACK-863</a>] - ServiceDiscoveryManger does not use the main identity, causing setIdentity() to have no effect
|
||||
</li>
|
||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-864'>SMACK-864</a>] - Potential Denial of Service (DOS) by remote entities caused by unlimited threads for asynchronous operations
|
||||
</li>
|
||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-865'>SMACK-865</a>] - Some Manager.getInsanceFor() methods are missing the 'synchronized' keyword
|
||||
</li>
|
||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-868'>SMACK-868</a>] - XHTMLText.appendOpenBodyTag() produces invalid XML
|
||||
</li>
|
||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-870'>SMACK-870</a>] - TLS X.509 certificate verification should be performed with the ACE representation of the XMPP service domain when possible
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2> Improvement
|
||||
</h2>
|
||||
<ul>
|
||||
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-869'>SMACK-869</a>] - Exceptions in async tasks should not go uncaught to the call stack to avoid program termination
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>4.3.3 -- <span style="font-weight: normal;">2019-03-14</span></h2>
|
||||
|
||||
<h2> Bug
|
||||
|
|
|
@ -1192,12 +1192,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
|
||||
@Override
|
||||
public void setReplyTimeout(long timeout) {
|
||||
if (Long.MAX_VALUE - System.currentTimeMillis() < timeout) {
|
||||
throw new IllegalArgumentException("Extremely long reply timeout");
|
||||
}
|
||||
else {
|
||||
replyTimeout = timeout;
|
||||
}
|
||||
replyTimeout = timeout;
|
||||
}
|
||||
|
||||
private SmackConfiguration.UnknownIqRequestReplyMode unknownIqRequestReplyMode = SmackConfiguration.getUnknownIqRequestReplyMode();
|
||||
|
@ -1256,7 +1251,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
try {
|
||||
stanza = PacketParserUtils.parseStanza(parser, incomingStreamXmlEnvironment);
|
||||
}
|
||||
catch (XmlPullParserException | SmackParsingException | IOException | IllegalArgumentException e) {
|
||||
catch (XmlPullParserException | SmackParsingException | IOException e) {
|
||||
CharSequence content = PacketParserUtils.parseContentDepth(parser,
|
||||
parserDepth);
|
||||
UnparseableStanza message = new UnparseableStanza(content, e);
|
||||
|
|
|
@ -750,7 +750,7 @@ public abstract class ConnectionConfiguration {
|
|||
|
||||
/**
|
||||
* Set the Internet address of the host providing the XMPP service. If set, then this will overwrite anything
|
||||
* set via {@link #setHost(CharSequence)}.
|
||||
* set via {@link #setHost(String)}.
|
||||
*
|
||||
* @param address the Internet address of the host providing the XMPP service.
|
||||
* @return a reference to this builder.
|
||||
|
@ -762,29 +762,16 @@ public abstract class ConnectionConfiguration {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the name of the host providing the XMPP service. This method takes DNS names and
|
||||
* IP addresses.
|
||||
* Set the name of the host providing the XMPP service. Note that this method does only allow DNS names and not
|
||||
* IP addresses. Use {@link #setHostAddress(InetAddress)} if you want to explicitly set the Internet address of
|
||||
* the host providing the XMPP service.
|
||||
*
|
||||
* @param host the DNS name of the host providing the XMPP service.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setHost(CharSequence host) {
|
||||
String fqdnOrIpString = host.toString();
|
||||
if (InetAddressUtil.isIpAddress(fqdnOrIpString)) {
|
||||
InetAddress hostInetAddress;
|
||||
try {
|
||||
hostInetAddress = InetAddress.getByName(fqdnOrIpString);
|
||||
}
|
||||
catch (UnknownHostException e) {
|
||||
// Should never happen.
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
setHostAddress(hostInetAddress);
|
||||
} else {
|
||||
DnsName dnsName = DnsName.from(fqdnOrIpString);
|
||||
setHost(dnsName);
|
||||
}
|
||||
return getThis();
|
||||
public B setHost(String host) {
|
||||
DnsName hostDnsName = DnsName.from(host);
|
||||
return setHost(hostDnsName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -808,12 +795,23 @@ public abstract class ConnectionConfiguration {
|
|||
* @see #setHost(DnsName)
|
||||
* @see #setHostAddress(InetAddress)
|
||||
* @since 4.3.2
|
||||
* @deprecated use {@link #setHost(CharSequence)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public B setHostAddressByNameOrIp(CharSequence fqdnOrIp) {
|
||||
return setHost(fqdnOrIp);
|
||||
String fqdnOrIpString = fqdnOrIp.toString();
|
||||
if (InetAddressUtil.isIpAddress(fqdnOrIp)) {
|
||||
InetAddress hostInetAddress;
|
||||
try {
|
||||
hostInetAddress = InetAddress.getByName(fqdnOrIpString);
|
||||
}
|
||||
catch (UnknownHostException e) {
|
||||
// Should never happen.
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
setHostAddress(hostInetAddress);
|
||||
} else {
|
||||
setHost(fqdnOrIpString);
|
||||
}
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public B setPort(int port) {
|
||||
|
|
|
@ -257,8 +257,9 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
|
|||
|
||||
@Override
|
||||
public final int compareTo(SASLMechanism other) {
|
||||
// Switch to Integer.compare(int, int) once Smack is on Android 19 or higher.
|
||||
Integer ourPriority = getPriority();
|
||||
return Integer.compare(ourPriority, other.getPriority());
|
||||
return ourPriority.compareTo(other.getPriority());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A collection of utility methods for String objects.
|
||||
|
@ -542,16 +541,4 @@ public class StringUtils {
|
|||
}
|
||||
return cs.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by XML 1.0 § 2.3 as:
|
||||
* S ::= (#x20 | #x9 | #xD | #xA)+
|
||||
*
|
||||
* @see <a href="https://www.w3.org/TR/xml/#sec-white-space">XML 1.0 § 2.3</a>
|
||||
*/
|
||||
private static final Pattern XML_WHITESPACE = Pattern.compile("[\t\n\r ]");
|
||||
|
||||
public static String deleteXmlWhitespace(String string) {
|
||||
return XML_WHITESPACE.matcher(string).replaceAll("");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.jivesoftware.smack.util.stringencoder;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.jivesoftware.smack.util.Objects;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
public class Base64 {
|
||||
|
||||
|
@ -58,9 +57,6 @@ public class Base64 {
|
|||
// TODO: We really should not mask the IllegalArgumentException. But some unit test depend on this behavior, like
|
||||
// ibb.packet.DataPacketExtension.shouldReturnNullIfDataIsInvalid().
|
||||
public static final byte[] decode(String string) {
|
||||
// xs:base64Binary may include XML whitespace which we need to delete before feeding the string into the Base64
|
||||
// decoder. See also XML Schema Part 2: Datatypes Second Edition § 3.2.16.
|
||||
string = StringUtils.deleteXmlWhitespace(string);
|
||||
try {
|
||||
return base64encoder.decode(string);
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018-2019 Florian Schmaus.
|
||||
* Copyright 2018 Florian Schmaus.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -28,7 +28,7 @@ public class ConnectionConfigurationTest {
|
|||
DummyConnectionConfiguration.Builder builder = newUnitTestBuilder();
|
||||
|
||||
final String ip = "192.168.0.1";
|
||||
builder.setHost(ip);
|
||||
builder.setHostAddressByNameOrIp(ip);
|
||||
|
||||
DummyConnectionConfiguration connectionConfiguration = builder.build();
|
||||
assertEquals('/' + ip, connectionConfiguration.getHostAddress().toString());
|
||||
|
@ -39,7 +39,7 @@ public class ConnectionConfigurationTest {
|
|||
DummyConnectionConfiguration.Builder builder = newUnitTestBuilder();
|
||||
|
||||
final String fqdn = "foo.example.org";
|
||||
builder.setHost(fqdn);
|
||||
builder.setHostAddressByNameOrIp(fqdn);
|
||||
|
||||
DummyConnectionConfiguration connectionConfiguration = builder.build();
|
||||
assertEquals(fqdn, connectionConfiguration.getHost().toString());
|
||||
|
|
|
@ -109,16 +109,4 @@ public class StringUtilsTest {
|
|||
String result = StringUtils.randomString(0);
|
||||
assertEquals("", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testeDeleteXmlWhitespace() {
|
||||
String noWhitespace = StringUtils.deleteXmlWhitespace(" foo\nbar ");
|
||||
assertEquals("foobar", noWhitespace);
|
||||
|
||||
noWhitespace = StringUtils.deleteXmlWhitespace(" \tbaz\rbarz\t ");
|
||||
assertEquals("bazbarz", noWhitespace);
|
||||
|
||||
noWhitespace = StringUtils.deleteXmlWhitespace("SNAFU");
|
||||
assertEquals("SNAFU", noWhitespace);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -387,6 +387,11 @@ public final class HttpFileUploadManager extends Manager {
|
|||
|
||||
private void uploadFile(final File file, final Slot slot, UploadProgressListener listener) throws IOException {
|
||||
final long fileSize = file.length();
|
||||
// TODO Remove once Smack's minimum Android API level is 19 or higher. See also comment below.
|
||||
if (fileSize >= Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("File size " + fileSize + " must be less than " + Integer.MAX_VALUE);
|
||||
}
|
||||
final int fileSizeInt = (int) fileSize;
|
||||
|
||||
// Construct the FileInputStream first to make sure we can actually read the file.
|
||||
final FileInputStream fis = new FileInputStream(file);
|
||||
|
@ -398,7 +403,8 @@ public final class HttpFileUploadManager extends Manager {
|
|||
urlConnection.setRequestMethod("PUT");
|
||||
urlConnection.setUseCaches(false);
|
||||
urlConnection.setDoOutput(true);
|
||||
urlConnection.setFixedLengthStreamingMode(fileSize);
|
||||
// TODO Change to using fileSize once Smack's minimum Android API level is 19 or higher.
|
||||
urlConnection.setFixedLengthStreamingMode(fileSizeInt);
|
||||
urlConnection.setRequestProperty("Content-Type", "application/octet-stream;");
|
||||
for (Entry<String, String> header : slot.getHeaders().entrySet()) {
|
||||
urlConnection.setRequestProperty(header.getKey(), header.getValue());
|
||||
|
|
|
@ -47,7 +47,8 @@ public abstract class DiscoInfoLookupShortcutMechanism implements Comparable<Dis
|
|||
|
||||
@Override
|
||||
public final int compareTo(DiscoInfoLookupShortcutMechanism other) {
|
||||
// Switch to Integer.compare(int, int) once Smack is on Android 19 or higher.
|
||||
Integer ourPriority = getPriority();
|
||||
return Integer.compare(ourPriority, other.getPriority());
|
||||
return ourPriority.compareTo(other.getPriority());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@ import org.jivesoftware.smackx.disco.packet.DiscoverItems;
|
|||
/**
|
||||
* The NodeInformationProvider is responsible for providing supported identities, features
|
||||
* and hosted items (i.e. DiscoverItems.Item) about a given node. This information will be
|
||||
* requested each time this XMPP client receives a disco info or items requests on the
|
||||
* requested each time this XMPPP client receives a disco info or items requests on the
|
||||
* given node. each time this XMPPP client receives a disco info or items requests on the
|
||||
* given node.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
|
|
|
@ -294,9 +294,6 @@ public final class MultiUserChatManager extends Manager {
|
|||
* Returns a Set of the rooms where the user has joined. The Iterator will contain Strings where each String
|
||||
* represents a room (e.g. room@muc.jabber.org).
|
||||
*
|
||||
* Note: In order to get a list of bookmarked (but not necessarily joined) conferences, use
|
||||
* {@link org.jivesoftware.smackx.bookmarks.BookmarkManager#getBookmarkedConferences()}.
|
||||
*
|
||||
* @return a List of the rooms where the user has joined using a given connection.
|
||||
*/
|
||||
public Set<EntityBareJid> getJoinedRooms() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software, 2015-2019 Florian Schmaus
|
||||
* Copyright 2003-2007 Jive Software, 2015-2018 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -41,6 +41,7 @@ import org.jivesoftware.smackx.pubsub.EventElement;
|
|||
import org.jivesoftware.smackx.pubsub.Item;
|
||||
import org.jivesoftware.smackx.pubsub.LeafNode;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubException.NotALeafNodeException;
|
||||
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;
|
||||
|
@ -150,19 +151,19 @@ public final class PepManager extends Manager {
|
|||
/**
|
||||
* Publish an event.
|
||||
*
|
||||
* @param nodeId the ID of the node to publish on.
|
||||
* @param item the item to publish.
|
||||
* @return the leaf node the item was published on.
|
||||
* @param node the node to publish on.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotAPubSubNodeException
|
||||
* @throws NotALeafNodeException
|
||||
*/
|
||||
public LeafNode publish(String nodeId, Item item) throws NotConnectedException, InterruptedException,
|
||||
NoResponseException, XMPPErrorException, NotALeafNodeException {
|
||||
// PEP nodes are auto created if not existent. Hence Use PubSubManager.tryToPublishAndPossibleAutoCreate() here.
|
||||
return pepPubSubManager.tryToPublishAndPossibleAutoCreate(nodeId, item);
|
||||
public void publish(Item item, String node) throws NotConnectedException, InterruptedException,
|
||||
NoResponseException, XMPPErrorException, NotAPubSubNodeException, NotALeafNodeException {
|
||||
LeafNode pubSubNode = pepPubSubManager.getLeafNode(node);
|
||||
pubSubNode.publish(item);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -186,17 +186,6 @@ public final class PubSubManager extends Manager {
|
|||
pubSubService = toAddress;
|
||||
}
|
||||
|
||||
private void checkIfXmppErrorBecauseOfNotLeafNode(String nodeId, XMPPErrorException xmppErrorException)
|
||||
throws XMPPErrorException, NotALeafNodeException {
|
||||
Condition condition = xmppErrorException.getStanzaError().getCondition();
|
||||
if (condition == Condition.feature_not_implemented) {
|
||||
// XEP-0060 § 6.5.9.5: Item retrieval not supported, e.g. because node is a collection node
|
||||
throw new PubSubException.NotALeafNodeException(nodeId, pubSubService);
|
||||
}
|
||||
|
||||
throw xmppErrorException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instant node, if supported.
|
||||
*
|
||||
|
@ -398,7 +387,13 @@ public final class PubSubManager extends Manager {
|
|||
// Try to ensure that this is not a collection node by asking for one item form the node.
|
||||
leafNode.getItems(1);
|
||||
} catch (XMPPErrorException e) {
|
||||
checkIfXmppErrorBecauseOfNotLeafNode(id, e);
|
||||
Condition condition = e.getStanzaError().getCondition();
|
||||
if (condition == Condition.feature_not_implemented) {
|
||||
// XEP-0060 § 6.5.9.5: Item retrieval not supported, e.g. because node is a collection node
|
||||
throw new PubSubException.NotALeafNodeException(id, pubSubService);
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
nodeMap.put(id, leafNode);
|
||||
|
@ -435,19 +430,12 @@ public final class PubSubManager extends Manager {
|
|||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotALeafNodeException
|
||||
* @since 4.2.1
|
||||
*/
|
||||
public <I extends Item> LeafNode tryToPublishAndPossibleAutoCreate(String id, I item)
|
||||
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException,
|
||||
NotALeafNodeException {
|
||||
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
LeafNode leafNode = new LeafNode(this, id);
|
||||
|
||||
try {
|
||||
leafNode.publish(item);
|
||||
} catch (XMPPErrorException e) {
|
||||
checkIfXmppErrorBecauseOfNotLeafNode(id, e);
|
||||
}
|
||||
leafNode.publish(item);
|
||||
|
||||
// If LeafNode.publish() did not throw then we have successfully published an item and possible auto-created
|
||||
// (XEP-0163 § 3., XEP-0060 § 7.1.4) the node. So we can put the node into the nodeMap.
|
||||
|
|
|
@ -1680,7 +1680,7 @@ public final class Roster extends Manager {
|
|||
@Override
|
||||
public void onSuccess(IQ packet) {
|
||||
final XMPPConnection connection = connection();
|
||||
LOGGER.log(Level.FINE, "RosterResultListener received {0}", packet);
|
||||
LOGGER.log(Level.FINE, "RosterResultListener received {}", packet);
|
||||
Collection<Jid> addedEntries = new ArrayList<>();
|
||||
Collection<Jid> updatedEntries = new ArrayList<>();
|
||||
Collection<Jid> deletedEntries = new ArrayList<>();
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.jivesoftware.smackx.omemo;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
|
@ -65,7 +64,7 @@ public abstract class AbstractTwoUsersOmemoIntegrationTest extends AbstractOmemo
|
|||
}
|
||||
|
||||
@AfterClass
|
||||
public void cleanUp() throws IOException {
|
||||
public void cleanUp() {
|
||||
alice.stopStanzaAndPEPListeners();
|
||||
bob.stopStanzaAndPEPListeners();
|
||||
OmemoManagerSetupHelper.cleanUpPubSub(alice);
|
||||
|
|
|
@ -55,7 +55,6 @@ public class MessageEncryptionIntegrationTest extends AbstractTwoUsersOmemoInteg
|
|||
* Bob still has B2
|
||||
* @throws Exception
|
||||
*/
|
||||
@SuppressWarnings("SynchronizeOnNonFinalField")
|
||||
@SmackIntegrationTest
|
||||
public void messageTest() throws Exception {
|
||||
OmemoBundleElement a1 = alice.getOmemoService().getOmemoStoreBackend().packOmemoBundle(alice.getOwnDevice());
|
||||
|
@ -75,7 +74,7 @@ public class MessageEncryptionIntegrationTest extends AbstractTwoUsersOmemoInteg
|
|||
OmemoBundleElement a1_ = alice.getOmemoService().getOmemoStoreBackend().packOmemoBundle(alice.getOwnDevice());
|
||||
OmemoBundleElement b2;
|
||||
|
||||
synchronized (bob) { // Circumvent race condition where bundle gets replenished after getting stored in b2
|
||||
synchronized (bob.LOCK) { // Circumvent race condition where bundle gets replenished after getting stored in b2
|
||||
b2 = bob.getOmemoService().getOmemoStoreBackend().packOmemoBundle(bob.getOwnDevice());
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.jivesoftware.smackx.omemo;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
|
@ -51,7 +50,7 @@ public class OmemoMamDecryptionTest extends AbstractTwoUsersOmemoIntegrationTest
|
|||
@SmackIntegrationTest
|
||||
public void mamDecryptionTest() throws XMPPException.XMPPErrorException, SmackException.NotLoggedInException,
|
||||
SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException,
|
||||
CryptoFailedException, UndecidedOmemoIdentityException, IOException {
|
||||
CryptoFailedException, UndecidedOmemoIdentityException {
|
||||
// Make sure, Bobs server stores messages in the archive
|
||||
MamManager bobsMamManager = MamManager.getInstanceFor(bob.getConnection());
|
||||
bobsMamManager.enableMamForAllMessages();
|
||||
|
|
|
@ -20,7 +20,6 @@ import static org.junit.Assert.assertEquals;
|
|||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
|
@ -47,7 +46,7 @@ public class OmemoManagerSetupHelper {
|
|||
public static void trustAllIdentities(OmemoManager alice, OmemoManager bob)
|
||||
throws InterruptedException, SmackException.NotConnectedException, SmackException.NotLoggedInException,
|
||||
SmackException.NoResponseException, CannotEstablishOmemoSessionException, CorruptedOmemoKeyException,
|
||||
XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, IOException {
|
||||
XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException {
|
||||
Roster roster = Roster.getInstanceFor(alice.getConnection());
|
||||
|
||||
if (alice.getOwnJid() != bob.getOwnJid() &&
|
||||
|
@ -67,7 +66,7 @@ public class OmemoManagerSetupHelper {
|
|||
public static void trustAllIdentitiesWithTests(OmemoManager alice, OmemoManager bob)
|
||||
throws InterruptedException, SmackException.NotConnectedException, SmackException.NotLoggedInException,
|
||||
SmackException.NoResponseException, CannotEstablishOmemoSessionException, CorruptedOmemoKeyException,
|
||||
XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, IOException {
|
||||
XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException {
|
||||
alice.requestDeviceListUpdateFor(bob.getOwnJid());
|
||||
HashMap<OmemoDevice, OmemoFingerprint> fps1 = alice.getActiveFingerprints(bob.getOwnJid());
|
||||
|
||||
|
@ -125,7 +124,7 @@ public class OmemoManagerSetupHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public static void cleanUpPubSub(OmemoManager omemoManager) throws IOException {
|
||||
public static void cleanUpPubSub(OmemoManager omemoManager) {
|
||||
PubSubManager pm = PubSubManager.getInstanceFor(omemoManager.getConnection(), omemoManager.getOwnJid());
|
||||
try {
|
||||
omemoManager.requestDeviceListUpdateFor(omemoManager.getOwnJid());
|
||||
|
|
|
@ -20,8 +20,6 @@ import static junit.framework.TestCase.assertEquals;
|
|||
import static junit.framework.TestCase.assertFalse;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException;
|
||||
|
@ -39,9 +37,7 @@ public class ReadOnlyDeviceIntegrationTest extends AbstractTwoUsersOmemoIntegrat
|
|||
}
|
||||
|
||||
@SmackIntegrationTest
|
||||
public void test() throws InterruptedException, SmackException.NoResponseException,
|
||||
SmackException.NotLoggedInException, SmackException.NotConnectedException, CryptoFailedException,
|
||||
UndecidedOmemoIdentityException, IOException {
|
||||
public void test() throws InterruptedException, SmackException.NoResponseException, SmackException.NotLoggedInException, SmackException.NotConnectedException, CryptoFailedException, UndecidedOmemoIdentityException {
|
||||
boolean prevIgnoreReadOnlyConf = OmemoConfiguration.getIgnoreReadOnlyDevices();
|
||||
int prevMaxMessageCounter = OmemoConfiguration.getMaxReadOnlyMessageCount();
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ public class SessionRenegotiationIntegrationTest extends AbstractTwoUsersOmemoIn
|
|||
super(environment);
|
||||
}
|
||||
|
||||
@SuppressWarnings("SynchronizeOnNonFinalField")
|
||||
@SmackIntegrationTest
|
||||
public void sessionRenegotiationTest() throws Exception {
|
||||
|
||||
|
@ -51,7 +50,7 @@ public class SessionRenegotiationIntegrationTest extends AbstractTwoUsersOmemoIn
|
|||
bob.removeOmemoMessageListener(listener1);
|
||||
|
||||
// Remove the session on Bobs side.
|
||||
synchronized (bob) {
|
||||
synchronized (bob.LOCK) {
|
||||
bob.getOmemoService().getOmemoStoreBackend().removeRawSession(bob.getOwnDevice(), alice.getOwnDevice());
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.omemo.signal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -74,7 +73,7 @@ public class SignalOmemoRatchet
|
|||
@Override
|
||||
public byte[] doubleRatchetDecrypt(OmemoDevice sender, byte[] encryptedKey)
|
||||
throws CorruptedOmemoKeyException, NoRawSessionException, CryptoFailedException,
|
||||
UntrustedOmemoIdentityException, IOException {
|
||||
UntrustedOmemoIdentityException {
|
||||
|
||||
SessionCipher cipher = getCipher(sender);
|
||||
byte[] decryptedKey;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.omemo.signal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
|
@ -80,7 +79,7 @@ public class SignalOmemoStoreConnector
|
|||
public IdentityKeyPair getIdentityKeyPair() {
|
||||
try {
|
||||
return omemoStore.loadOmemoIdentityKeyPair(getOurDevice());
|
||||
} catch (CorruptedOmemoKeyException | IOException e) {
|
||||
} catch (CorruptedOmemoKeyException e) {
|
||||
LOGGER.log(Level.SEVERE, "IdentityKeyPair seems to be invalid.", e);
|
||||
return null;
|
||||
}
|
||||
|
@ -104,11 +103,7 @@ public class SignalOmemoStoreConnector
|
|||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
try {
|
||||
omemoStore.storeOmemoIdentityKey(getOurDevice(), device, identityKey);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
omemoStore.storeOmemoIdentityKey(getOurDevice(), device, identityKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -123,12 +118,7 @@ public class SignalOmemoStoreConnector
|
|||
|
||||
@Override
|
||||
public PreKeyRecord loadPreKey(int i) throws InvalidKeyIdException {
|
||||
PreKeyRecord preKey;
|
||||
try {
|
||||
preKey = omemoStore.loadOmemoPreKey(getOurDevice(), i);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
PreKeyRecord preKey = omemoStore.loadOmemoPreKey(getOurDevice(), i);
|
||||
|
||||
if (preKey == null) {
|
||||
throw new InvalidKeyIdException("No PreKey with Id " + i + " found.");
|
||||
|
@ -139,11 +129,7 @@ public class SignalOmemoStoreConnector
|
|||
|
||||
@Override
|
||||
public void storePreKey(int i, PreKeyRecord preKeyRecord) {
|
||||
try {
|
||||
omemoStore.storeOmemoPreKey(getOurDevice(), i, preKeyRecord);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
omemoStore.storeOmemoPreKey(getOurDevice(), i, preKeyRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -169,12 +155,7 @@ public class SignalOmemoStoreConnector
|
|||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
SessionRecord record;
|
||||
try {
|
||||
record = omemoStore.loadRawSession(getOurDevice(), device);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
SessionRecord record = omemoStore.loadRawSession(getOurDevice(), device);
|
||||
|
||||
if (record != null) {
|
||||
return record;
|
||||
|
@ -192,11 +173,7 @@ public class SignalOmemoStoreConnector
|
|||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
try {
|
||||
return new ArrayList<>(omemoStore.loadAllRawSessionsOf(getOurDevice(), jid).keySet());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return new ArrayList<>(omemoStore.loadAllRawSessionsOf(getOurDevice(), jid).keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -208,11 +185,7 @@ public class SignalOmemoStoreConnector
|
|||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
try {
|
||||
omemoStore.storeRawSession(getOurDevice(), device, sessionRecord);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
omemoStore.storeRawSession(getOurDevice(), device, sessionRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -253,12 +226,7 @@ public class SignalOmemoStoreConnector
|
|||
|
||||
@Override
|
||||
public SignedPreKeyRecord loadSignedPreKey(int i) throws InvalidKeyIdException {
|
||||
SignedPreKeyRecord signedPreKeyRecord;
|
||||
try {
|
||||
signedPreKeyRecord = omemoStore.loadOmemoSignedPreKey(getOurDevice(), i);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
SignedPreKeyRecord signedPreKeyRecord = omemoStore.loadOmemoSignedPreKey(getOurDevice(), i);
|
||||
if (signedPreKeyRecord == null) {
|
||||
throw new InvalidKeyIdException("No signed preKey with id " + i + " found.");
|
||||
}
|
||||
|
@ -268,22 +236,14 @@ public class SignalOmemoStoreConnector
|
|||
@Override
|
||||
public List<SignedPreKeyRecord> loadSignedPreKeys() {
|
||||
|
||||
TreeMap<Integer, SignedPreKeyRecord> signedPreKeyRecordHashMap;
|
||||
try {
|
||||
signedPreKeyRecordHashMap = omemoStore.loadOmemoSignedPreKeys(getOurDevice());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
TreeMap<Integer, SignedPreKeyRecord> signedPreKeyRecordHashMap =
|
||||
omemoStore.loadOmemoSignedPreKeys(getOurDevice());
|
||||
return new ArrayList<>(signedPreKeyRecordHashMap.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSignedPreKey(int i, SignedPreKeyRecord signedPreKeyRecord) {
|
||||
try {
|
||||
omemoStore.storeOmemoSignedPreKey(getOurDevice(), i, signedPreKeyRecord);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
omemoStore.storeOmemoSignedPreKey(getOurDevice(), i, signedPreKeyRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.omemo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.SortedSet;
|
||||
|
@ -81,7 +80,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
|
||||
@Override
|
||||
public T_IdKeyPair loadOmemoIdentityKeyPair(OmemoDevice userDevice)
|
||||
throws CorruptedOmemoKeyException, IOException {
|
||||
throws CorruptedOmemoKeyException {
|
||||
T_IdKeyPair pair = getCache(userDevice).identityKeyPair;
|
||||
|
||||
if (pair == null && persistent != null) {
|
||||
|
@ -95,7 +94,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public void storeOmemoIdentityKeyPair(OmemoDevice userDevice, T_IdKeyPair identityKeyPair) throws IOException {
|
||||
public void storeOmemoIdentityKeyPair(OmemoDevice userDevice, T_IdKeyPair identityKeyPair) {
|
||||
getCache(userDevice).identityKeyPair = identityKeyPair;
|
||||
if (persistent != null) {
|
||||
persistent.storeOmemoIdentityKeyPair(userDevice, identityKeyPair);
|
||||
|
@ -112,7 +111,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
|
||||
@Override
|
||||
public T_IdKey loadOmemoIdentityKey(OmemoDevice userDevice, OmemoDevice contactsDevice)
|
||||
throws CorruptedOmemoKeyException, IOException {
|
||||
throws CorruptedOmemoKeyException {
|
||||
T_IdKey idKey = getCache(userDevice).identityKeys.get(contactsDevice);
|
||||
|
||||
if (idKey == null && persistent != null) {
|
||||
|
@ -126,7 +125,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public void storeOmemoIdentityKey(OmemoDevice userDevice, OmemoDevice device, T_IdKey t_idKey) throws IOException {
|
||||
public void storeOmemoIdentityKey(OmemoDevice userDevice, OmemoDevice device, T_IdKey t_idKey) {
|
||||
getCache(userDevice).identityKeys.put(device, t_idKey);
|
||||
if (persistent != null) {
|
||||
persistent.storeOmemoIdentityKey(userDevice, device, t_idKey);
|
||||
|
@ -142,7 +141,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public void storeOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice, int counter) throws IOException {
|
||||
public void storeOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice, int counter) {
|
||||
getCache(userDevice).messageCounters.put(contactsDevice, counter);
|
||||
if (persistent != null) {
|
||||
persistent.storeOmemoMessageCounter(userDevice, contactsDevice, counter);
|
||||
|
@ -150,7 +149,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public int loadOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException {
|
||||
public int loadOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice) {
|
||||
Integer counter = getCache(userDevice).messageCounters.get(contactsDevice);
|
||||
if (counter == null && persistent != null) {
|
||||
counter = persistent.loadOmemoMessageCounter(userDevice, contactsDevice);
|
||||
|
@ -166,7 +165,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice from, Date date) throws IOException {
|
||||
public void setDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice from, Date date) {
|
||||
getCache(userDevice).lastMessagesDates.put(from, date);
|
||||
if (persistent != null) {
|
||||
persistent.setDateOfLastReceivedMessage(userDevice, from, date);
|
||||
|
@ -174,7 +173,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public Date getDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice from) throws IOException {
|
||||
public Date getDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice from) {
|
||||
Date last = getCache(userDevice).lastMessagesDates.get(from);
|
||||
|
||||
if (last == null && persistent != null) {
|
||||
|
@ -188,7 +187,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date) throws IOException {
|
||||
public void setDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date) {
|
||||
getCache(userDevice).lastDeviceIdPublicationDates.put(contactsDevice, date);
|
||||
if (persistent != null) {
|
||||
persistent.setDateOfLastReceivedMessage(userDevice, contactsDevice, date);
|
||||
|
@ -196,7 +195,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public Date getDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException {
|
||||
public Date getDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice) {
|
||||
Date last = getCache(userDevice).lastDeviceIdPublicationDates.get(contactsDevice);
|
||||
|
||||
if (last == null && persistent != null) {
|
||||
|
@ -210,7 +209,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice, Date date) throws IOException {
|
||||
public void setDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice, Date date) {
|
||||
getCache(userDevice).lastRenewalDate = date;
|
||||
if (persistent != null) {
|
||||
persistent.setDateOfLastSignedPreKeyRenewal(userDevice, date);
|
||||
|
@ -218,7 +217,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public Date getDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice) throws IOException {
|
||||
public Date getDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice) {
|
||||
Date lastRenewal = getCache(userDevice).lastRenewalDate;
|
||||
|
||||
if (lastRenewal == null && persistent != null) {
|
||||
|
@ -232,7 +231,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public T_PreKey loadOmemoPreKey(OmemoDevice userDevice, int preKeyId) throws IOException {
|
||||
public T_PreKey loadOmemoPreKey(OmemoDevice userDevice, int preKeyId) {
|
||||
T_PreKey preKey = getCache(userDevice).preKeys.get(preKeyId);
|
||||
|
||||
if (preKey == null && persistent != null) {
|
||||
|
@ -246,7 +245,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public void storeOmemoPreKey(OmemoDevice userDevice, int preKeyId, T_PreKey t_preKey) throws IOException {
|
||||
public void storeOmemoPreKey(OmemoDevice userDevice, int preKeyId, T_PreKey t_preKey) {
|
||||
getCache(userDevice).preKeys.put(preKeyId, t_preKey);
|
||||
if (persistent != null) {
|
||||
persistent.storeOmemoPreKey(userDevice, preKeyId, t_preKey);
|
||||
|
@ -262,7 +261,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public TreeMap<Integer, T_PreKey> loadOmemoPreKeys(OmemoDevice userDevice) throws IOException {
|
||||
public TreeMap<Integer, T_PreKey> loadOmemoPreKeys(OmemoDevice userDevice) {
|
||||
TreeMap<Integer, T_PreKey> preKeys = getCache(userDevice).preKeys;
|
||||
|
||||
if (preKeys.isEmpty() && persistent != null) {
|
||||
|
@ -273,7 +272,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public T_SigPreKey loadOmemoSignedPreKey(OmemoDevice userDevice, int signedPreKeyId) throws IOException {
|
||||
public T_SigPreKey loadOmemoSignedPreKey(OmemoDevice userDevice, int signedPreKeyId) {
|
||||
T_SigPreKey sigPreKey = getCache(userDevice).signedPreKeys.get(signedPreKeyId);
|
||||
|
||||
if (sigPreKey == null && persistent != null) {
|
||||
|
@ -287,7 +286,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public TreeMap<Integer, T_SigPreKey> loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException {
|
||||
public TreeMap<Integer, T_SigPreKey> loadOmemoSignedPreKeys(OmemoDevice userDevice) {
|
||||
TreeMap<Integer, T_SigPreKey> sigPreKeys = getCache(userDevice).signedPreKeys;
|
||||
|
||||
if (sigPreKeys.isEmpty() && persistent != null) {
|
||||
|
@ -300,7 +299,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
@Override
|
||||
public void storeOmemoSignedPreKey(OmemoDevice userDevice,
|
||||
int signedPreKeyId,
|
||||
T_SigPreKey signedPreKey) throws IOException {
|
||||
T_SigPreKey signedPreKey) {
|
||||
getCache(userDevice).signedPreKeys.put(signedPreKeyId, signedPreKey);
|
||||
if (persistent != null) {
|
||||
persistent.storeOmemoSignedPreKey(userDevice, signedPreKeyId, signedPreKey);
|
||||
|
@ -316,7 +315,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public T_Sess loadRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException {
|
||||
public T_Sess loadRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice) {
|
||||
HashMap<Integer, T_Sess> contactSessions = getCache(userDevice).sessions.get(contactsDevice.getJid());
|
||||
if (contactSessions == null) {
|
||||
contactSessions = new HashMap<>();
|
||||
|
@ -335,7 +334,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Integer, T_Sess> loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException {
|
||||
public HashMap<Integer, T_Sess> loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) {
|
||||
HashMap<Integer, T_Sess> sessions = getCache(userDevice).sessions.get(contact);
|
||||
if (sessions == null) {
|
||||
sessions = new HashMap<>();
|
||||
|
@ -350,7 +349,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public void storeRawSession(OmemoDevice userDevice, OmemoDevice contactsDevicece, T_Sess session) throws IOException {
|
||||
public void storeRawSession(OmemoDevice userDevice, OmemoDevice contactsDevicece, T_Sess session) {
|
||||
HashMap<Integer, T_Sess> sessions = getCache(userDevice).sessions.get(contactsDevicece.getJid());
|
||||
if (sessions == null) {
|
||||
sessions = new HashMap<>();
|
||||
|
@ -392,7 +391,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public OmemoCachedDeviceList loadCachedDeviceList(OmemoDevice userDevice, BareJid contact) throws IOException {
|
||||
public OmemoCachedDeviceList loadCachedDeviceList(OmemoDevice userDevice, BareJid contact) {
|
||||
OmemoCachedDeviceList list = getCache(userDevice).deviceLists.get(contact);
|
||||
|
||||
if (list == null && persistent != null) {
|
||||
|
@ -408,7 +407,7 @@ public class CachingOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_Se
|
|||
@Override
|
||||
public void storeCachedDeviceList(OmemoDevice userDevice,
|
||||
BareJid contact,
|
||||
OmemoCachedDeviceList deviceList) throws IOException {
|
||||
OmemoCachedDeviceList deviceList) {
|
||||
getCache(userDevice).deviceLists.put(contact, new OmemoCachedDeviceList(deviceList));
|
||||
|
||||
if (persistent != null) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Paul Schaub, 2019 Florian Schmaus.
|
||||
* Copyright 2017 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -21,6 +21,7 @@ import java.io.DataOutputStream;
|
|||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
@ -35,6 +36,7 @@ import java.util.TreeSet;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.util.CloseableUtil;
|
||||
import org.jivesoftware.smack.util.stringencoder.BareJidEncoder;
|
||||
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException;
|
||||
|
@ -65,13 +67,13 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
|
||||
@Override
|
||||
public T_IdKeyPair loadOmemoIdentityKeyPair(OmemoDevice userDevice)
|
||||
throws CorruptedOmemoKeyException, IOException {
|
||||
throws CorruptedOmemoKeyException {
|
||||
File identityKeyPairPath = hierarchy.getIdentityKeyPairPath(userDevice);
|
||||
return keyUtil().identityKeyPairFromBytes(readBytes(identityKeyPairPath));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeOmemoIdentityKeyPair(OmemoDevice userDevice, T_IdKeyPair identityKeyPair) throws IOException {
|
||||
public void storeOmemoIdentityKeyPair(OmemoDevice userDevice, T_IdKeyPair identityKeyPair) {
|
||||
File identityKeyPairPath = hierarchy.getIdentityKeyPairPath(userDevice);
|
||||
writeBytes(identityKeyPairPath, keyUtil().identityKeyPairToBytes(identityKeyPair));
|
||||
}
|
||||
|
@ -86,14 +88,14 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
|
||||
@Override
|
||||
public T_IdKey loadOmemoIdentityKey(OmemoDevice userDevice, OmemoDevice contactsDevice)
|
||||
throws CorruptedOmemoKeyException, IOException {
|
||||
throws CorruptedOmemoKeyException {
|
||||
File identityKeyPath = hierarchy.getContactsIdentityKeyPath(userDevice, contactsDevice);
|
||||
byte[] bytes = readBytes(identityKeyPath);
|
||||
return bytes != null ? keyUtil().identityKeyFromBytes(bytes) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeOmemoIdentityKey(OmemoDevice userDevice, OmemoDevice contactsDevice, T_IdKey t_idKey) throws IOException {
|
||||
public void storeOmemoIdentityKey(OmemoDevice userDevice, OmemoDevice contactsDevice, T_IdKey t_idKey) {
|
||||
File identityKeyPath = hierarchy.getContactsIdentityKeyPath(userDevice, contactsDevice);
|
||||
writeBytes(identityKeyPath, keyUtil().identityKeyToBytes(t_idKey));
|
||||
}
|
||||
|
@ -124,46 +126,46 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date) throws IOException {
|
||||
public void setDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date) {
|
||||
File lastMessageReceived = hierarchy.getLastMessageReceivedDatePath(userDevice, contactsDevice);
|
||||
writeLong(lastMessageReceived, date.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException {
|
||||
public Date getDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice contactsDevice) {
|
||||
File lastMessageReceived = hierarchy.getLastMessageReceivedDatePath(userDevice, contactsDevice);
|
||||
Long date = readLong(lastMessageReceived);
|
||||
return date != null ? new Date(date) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date) throws IOException {
|
||||
public void setDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date) {
|
||||
File lastDeviceIdPublished = hierarchy.getLastDeviceIdPublicationDatePath(userDevice, contactsDevice);
|
||||
writeLong(lastDeviceIdPublished, date.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException {
|
||||
public Date getDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice) {
|
||||
File lastDeviceIdPublished = hierarchy.getLastDeviceIdPublicationDatePath(userDevice, contactsDevice);
|
||||
Long date = readLong(lastDeviceIdPublished);
|
||||
return date != null ? new Date(date) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice, Date date) throws IOException {
|
||||
public void setDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice, Date date) {
|
||||
File lastSignedPreKeyRenewal = hierarchy.getLastSignedPreKeyRenewal(userDevice);
|
||||
writeLong(lastSignedPreKeyRenewal, date.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice) throws IOException {
|
||||
public Date getDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice) {
|
||||
File lastSignedPreKeyRenewal = hierarchy.getLastSignedPreKeyRenewal(userDevice);
|
||||
Long date = readLong(lastSignedPreKeyRenewal);
|
||||
return date != null ? new Date(date) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T_PreKey loadOmemoPreKey(OmemoDevice userDevice, int preKeyId) throws IOException {
|
||||
public T_PreKey loadOmemoPreKey(OmemoDevice userDevice, int preKeyId) {
|
||||
File preKeyPath = hierarchy.getPreKeyPath(userDevice, preKeyId);
|
||||
byte[] bytes = readBytes(preKeyPath);
|
||||
|
||||
|
@ -179,7 +181,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public void storeOmemoPreKey(OmemoDevice userDevice, int preKeyId, T_PreKey t_preKey) throws IOException {
|
||||
public void storeOmemoPreKey(OmemoDevice userDevice, int preKeyId, T_PreKey t_preKey) {
|
||||
File preKeyPath = hierarchy.getPreKeyPath(userDevice, preKeyId);
|
||||
writeBytes(preKeyPath, keyUtil().preKeyToBytes(t_preKey));
|
||||
}
|
||||
|
@ -193,7 +195,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public TreeMap<Integer, T_PreKey> loadOmemoPreKeys(OmemoDevice userDevice) throws IOException {
|
||||
public TreeMap<Integer, T_PreKey> loadOmemoPreKeys(OmemoDevice userDevice) {
|
||||
File preKeyDirectory = hierarchy.getPreKeysDirectory(userDevice);
|
||||
TreeMap<Integer, T_PreKey> preKeys = new TreeMap<>();
|
||||
|
||||
|
@ -219,7 +221,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public T_SigPreKey loadOmemoSignedPreKey(OmemoDevice userDevice, int signedPreKeyId) throws IOException {
|
||||
public T_SigPreKey loadOmemoSignedPreKey(OmemoDevice userDevice, int signedPreKeyId) {
|
||||
File signedPreKeyPath = new File(hierarchy.getSignedPreKeysDirectory(userDevice), Integer.toString(signedPreKeyId));
|
||||
byte[] bytes = readBytes(signedPreKeyPath);
|
||||
if (bytes != null) {
|
||||
|
@ -233,7 +235,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public TreeMap<Integer, T_SigPreKey> loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException {
|
||||
public TreeMap<Integer, T_SigPreKey> loadOmemoSignedPreKeys(OmemoDevice userDevice) {
|
||||
File signedPreKeysDirectory = hierarchy.getSignedPreKeysDirectory(userDevice);
|
||||
TreeMap<Integer, T_SigPreKey> signedPreKeys = new TreeMap<>();
|
||||
|
||||
|
@ -261,7 +263,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
@Override
|
||||
public void storeOmemoSignedPreKey(OmemoDevice userDevice,
|
||||
int signedPreKeyId,
|
||||
T_SigPreKey signedPreKey) throws IOException {
|
||||
T_SigPreKey signedPreKey) {
|
||||
File signedPreKeyPath = new File(hierarchy.getSignedPreKeysDirectory(userDevice), Integer.toString(signedPreKeyId));
|
||||
writeBytes(signedPreKeyPath, keyUtil().signedPreKeyToBytes(signedPreKey));
|
||||
}
|
||||
|
@ -275,7 +277,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public T_Sess loadRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException {
|
||||
public T_Sess loadRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice) {
|
||||
File sessionPath = hierarchy.getContactsSessionPath(userDevice, contactsDevice);
|
||||
byte[] bytes = readBytes(sessionPath);
|
||||
if (bytes != null) {
|
||||
|
@ -289,7 +291,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Integer, T_Sess> loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException {
|
||||
public HashMap<Integer, T_Sess> loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) {
|
||||
File contactsDirectory = hierarchy.getContactsDir(userDevice, contact);
|
||||
HashMap<Integer, T_Sess> sessions = new HashMap<>();
|
||||
String[] devices = contactsDirectory.list();
|
||||
|
@ -320,7 +322,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public void storeRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice, T_Sess session) throws IOException {
|
||||
public void storeRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice, T_Sess session) {
|
||||
File sessionPath = hierarchy.getContactsSessionPath(userDevice, contactsDevice);
|
||||
writeBytes(sessionPath, keyUtil().rawSessionToBytes(session));
|
||||
}
|
||||
|
@ -355,13 +357,13 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public void storeOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice, int counter) throws IOException {
|
||||
public void storeOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice, int counter) {
|
||||
File messageCounterFile = hierarchy.getDevicesMessageCounterPath(userDevice, contactsDevice);
|
||||
writeIntegers(messageCounterFile, Collections.singleton(counter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int loadOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException {
|
||||
public int loadOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice) {
|
||||
File messageCounterFile = hierarchy.getDevicesMessageCounterPath(userDevice, contactsDevice);
|
||||
Set<Integer> integers = readIntegers(messageCounterFile);
|
||||
|
||||
|
@ -373,7 +375,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
|
||||
@Override
|
||||
public OmemoCachedDeviceList loadCachedDeviceList(OmemoDevice userDevice, BareJid contact) throws IOException {
|
||||
public OmemoCachedDeviceList loadCachedDeviceList(OmemoDevice userDevice, BareJid contact) {
|
||||
OmemoCachedDeviceList cachedDeviceList = new OmemoCachedDeviceList();
|
||||
|
||||
if (contact == null) {
|
||||
|
@ -400,7 +402,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
@Override
|
||||
public void storeCachedDeviceList(OmemoDevice userDevice,
|
||||
BareJid contact,
|
||||
OmemoCachedDeviceList contactsDeviceList) throws IOException {
|
||||
OmemoCachedDeviceList contactsDeviceList) {
|
||||
if (contact == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -418,7 +420,166 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
deleteDirectory(deviceDirectory);
|
||||
}
|
||||
|
||||
private static void writeLong(File target, long i) throws IOException {
|
||||
private static void writeLong(File target, long i) {
|
||||
if (target == null) {
|
||||
LOGGER.log(Level.WARNING, "Could not write long to null-path.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
FileHierarchy.createFile(target);
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not create file.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
DataOutputStream out = null;
|
||||
try {
|
||||
out = new DataOutputStream(new FileOutputStream(target));
|
||||
out.writeLong(i);
|
||||
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not write longs to file.", e);
|
||||
} finally {
|
||||
CloseableUtil.maybeClose(out, LOGGER);
|
||||
}
|
||||
}
|
||||
|
||||
private static Long readLong(File target) {
|
||||
if (target == null) {
|
||||
LOGGER.log(Level.WARNING, "Could not read long from null-path.");
|
||||
return null;
|
||||
}
|
||||
|
||||
Long l;
|
||||
DataInputStream in = null;
|
||||
|
||||
try {
|
||||
in = new DataInputStream(new FileInputStream(target));
|
||||
l = in.readLong();
|
||||
} catch (FileNotFoundException e) {
|
||||
l = null;
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not read long from file.", e);
|
||||
return null;
|
||||
} finally {
|
||||
CloseableUtil.maybeClose(in, LOGGER);
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
private static void writeBytes(File target, byte[] bytes) {
|
||||
if (target == null) {
|
||||
LOGGER.log(Level.WARNING, "Could not write bytes to null-path.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create file
|
||||
try {
|
||||
FileHierarchy.createFile(target);
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not create file.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
DataOutputStream out = null;
|
||||
|
||||
try {
|
||||
out = new DataOutputStream(new FileOutputStream(target));
|
||||
out.write(bytes);
|
||||
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not write bytes to file.", e);
|
||||
} finally {
|
||||
CloseableUtil.maybeClose(out, LOGGER);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] readBytes(File target) {
|
||||
if (target == null) {
|
||||
LOGGER.log(Level.WARNING, "Could not read bytes from null-path.");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] b = null;
|
||||
DataInputStream in = null;
|
||||
|
||||
try {
|
||||
in = new DataInputStream(new FileInputStream(target));
|
||||
b = new byte[(int) target.length()];
|
||||
in.read(b);
|
||||
} catch (FileNotFoundException e) {
|
||||
b = null;
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not read bytes from file.", e);
|
||||
} finally {
|
||||
CloseableUtil.maybeClose(in, LOGGER);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
private static void writeIntegers(File target, Set<Integer> integers) {
|
||||
if (target == null) {
|
||||
LOGGER.log(Level.WARNING, "Could not write integers to null-path.");
|
||||
return;
|
||||
}
|
||||
|
||||
DataOutputStream out = null;
|
||||
|
||||
try {
|
||||
out = new DataOutputStream(new FileOutputStream(target));
|
||||
for (int i : integers) {
|
||||
out.writeInt(i);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not write integers to file.", e);
|
||||
} finally {
|
||||
CloseableUtil.maybeClose(out, LOGGER);
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<Integer> readIntegers(File target) {
|
||||
if (target == null) {
|
||||
LOGGER.log(Level.WARNING, "Could not read integers from null-path.");
|
||||
return null;
|
||||
}
|
||||
|
||||
HashSet<Integer> integers = new HashSet<>();
|
||||
DataInputStream in = null;
|
||||
|
||||
try {
|
||||
in = new DataInputStream(new FileInputStream(target));
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
integers.add(in.readInt());
|
||||
}
|
||||
} catch (EOFException e) {
|
||||
// Reached end of the list.
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
integers = null;
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not read integers.", e);
|
||||
} finally {
|
||||
CloseableUtil.maybeClose(in, LOGGER);
|
||||
}
|
||||
|
||||
return integers;
|
||||
}
|
||||
|
||||
/**
|
||||
* One day... *sheds a tear*
|
||||
* TODO Use methods below once Smack's minimum Android API level is 19 or higher
|
||||
*/
|
||||
/*
|
||||
private static void writeLong(File target, long i)
|
||||
throws IOException
|
||||
{
|
||||
if (target == null) {
|
||||
throw new IOException("Could not write long to null-path.");
|
||||
}
|
||||
|
@ -430,7 +591,9 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
}
|
||||
|
||||
private static Long readLong(File target) throws IOException {
|
||||
private static Long readLong(File target)
|
||||
throws IOException
|
||||
{
|
||||
if (target == null) {
|
||||
throw new IOException("Could not read long from null-path.");
|
||||
}
|
||||
|
@ -444,7 +607,9 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
}
|
||||
|
||||
private static void writeBytes(File target, byte[] bytes) throws IOException {
|
||||
private static void writeBytes(File target, byte[] bytes)
|
||||
throws IOException
|
||||
{
|
||||
if (target == null) {
|
||||
throw new IOException("Could not write bytes to null-path.");
|
||||
}
|
||||
|
@ -457,7 +622,9 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
}
|
||||
|
||||
private static byte[] readBytes(File target) throws IOException {
|
||||
private static byte[] readBytes(File target)
|
||||
throws IOException
|
||||
{
|
||||
if (target == null) {
|
||||
throw new IOException("Could not read bytes from null-path.");
|
||||
}
|
||||
|
@ -474,7 +641,9 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
return b;
|
||||
}
|
||||
|
||||
private static void writeIntegers(File target, Set<Integer> integers) throws IOException {
|
||||
private static void writeIntegers(File target, Set<Integer> integers)
|
||||
throws IOException
|
||||
{
|
||||
if (target == null) {
|
||||
throw new IOException("Could not write integers to null-path.");
|
||||
}
|
||||
|
@ -488,7 +657,9 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
}
|
||||
}
|
||||
|
||||
private static Set<Integer> readIntegers(File target) throws IOException {
|
||||
private static Set<Integer> readIntegers(File target)
|
||||
throws IOException
|
||||
{
|
||||
if (target == null) {
|
||||
throw new IOException("Could not write integers to null-path.");
|
||||
}
|
||||
|
@ -511,6 +682,7 @@ public abstract class FileBasedOmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigP
|
|||
|
||||
return integers;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Delete a directory with all subdirectories.
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.jivesoftware.smackx.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.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -97,6 +96,7 @@ public final class OmemoManager extends Manager {
|
|||
private static final Logger LOGGER = Logger.getLogger(OmemoManager.class.getName());
|
||||
|
||||
private static final Integer UNKNOWN_DEVICE_ID = -1;
|
||||
final Object LOCK = new Object();
|
||||
|
||||
private static final WeakHashMap<XMPPConnection, TreeMap<Integer, OmemoManager>> INSTANCES = new WeakHashMap<>();
|
||||
private final OmemoService<?, ?, ?, ?, ?, ?, ?, ?, ?> service;
|
||||
|
@ -234,22 +234,23 @@ public final class OmemoManager extends Manager {
|
|||
* @throws XMPPException.XMPPErrorException
|
||||
* @throws SmackException.NotLoggedInException
|
||||
* @throws PubSubException.NotALeafNodeException
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized void initialize()
|
||||
public void initialize()
|
||||
throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, InterruptedException,
|
||||
SmackException.NoResponseException, SmackException.NotConnectedException, XMPPException.XMPPErrorException,
|
||||
PubSubException.NotALeafNodeException, IOException {
|
||||
if (!connection().isAuthenticated()) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
}
|
||||
PubSubException.NotALeafNodeException {
|
||||
synchronized (LOCK) {
|
||||
if (!connection().isAuthenticated()) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
}
|
||||
|
||||
if (getTrustCallback() == null) {
|
||||
throw new IllegalStateException("No TrustCallback set.");
|
||||
}
|
||||
if (getTrustCallback() == null) {
|
||||
throw new IllegalStateException("No TrustCallback set.");
|
||||
}
|
||||
|
||||
getOmemoService().init(new LoggedInOmemoManager(this));
|
||||
ServiceDiscoveryManager.getInstanceFor(connection()).addFeature(PEP_NODE_DEVICE_LIST_NOTIFY);
|
||||
getOmemoService().init(new LoggedInOmemoManager(this));
|
||||
ServiceDiscoveryManager.getInstanceFor(connection()).addFeature(PEP_NODE_DEVICE_LIST_NOTIFY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,9 +279,8 @@ public final class OmemoManager extends Manager {
|
|||
* @see #requestDeviceListUpdateFor(BareJid)
|
||||
* @param contact contact we want to get a set of device of.
|
||||
* @return set of known devices of that contact.
|
||||
* @throws IOException
|
||||
*/
|
||||
public Set<OmemoDevice> getDevicesOf(BareJid contact) throws IOException {
|
||||
public Set<OmemoDevice> getDevicesOf(BareJid contact) {
|
||||
OmemoCachedDeviceList list = getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(getOwnDevice(), contact);
|
||||
HashSet<OmemoDevice> devices = new HashSet<>();
|
||||
|
||||
|
@ -304,15 +304,16 @@ public final class OmemoManager extends Manager {
|
|||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws SmackException.NotLoggedInException
|
||||
* @throws IOException
|
||||
*/
|
||||
public OmemoMessage.Sent encrypt(BareJid recipient, String message)
|
||||
throws CryptoFailedException, UndecidedOmemoIdentityException,
|
||||
InterruptedException, SmackException.NotConnectedException,
|
||||
SmackException.NoResponseException, SmackException.NotLoggedInException, IOException {
|
||||
SmackException.NoResponseException, SmackException.NotLoggedInException {
|
||||
synchronized (LOCK) {
|
||||
Set<BareJid> recipients = new HashSet<>();
|
||||
recipients.add(recipient);
|
||||
return encrypt(recipients, message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,18 +328,19 @@ public final class OmemoManager extends Manager {
|
|||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws SmackException.NotLoggedInException
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized OmemoMessage.Sent encrypt(Set<BareJid> recipients, String message)
|
||||
public OmemoMessage.Sent encrypt(Set<BareJid> recipients, String message)
|
||||
throws CryptoFailedException, UndecidedOmemoIdentityException,
|
||||
InterruptedException, SmackException.NotConnectedException,
|
||||
SmackException.NoResponseException, SmackException.NotLoggedInException, IOException {
|
||||
LoggedInOmemoManager guard = new LoggedInOmemoManager(this);
|
||||
Set<OmemoDevice> devices = getDevicesOf(getOwnJid());
|
||||
for (BareJid recipient : recipients) {
|
||||
devices.addAll(getDevicesOf(recipient));
|
||||
SmackException.NoResponseException, SmackException.NotLoggedInException {
|
||||
synchronized (LOCK) {
|
||||
LoggedInOmemoManager guard = new LoggedInOmemoManager(this);
|
||||
Set<OmemoDevice> devices = getDevicesOf(getOwnJid());
|
||||
for (BareJid recipient : recipients) {
|
||||
devices.addAll(getDevicesOf(recipient));
|
||||
}
|
||||
return service.createOmemoMessage(guard, devices, message);
|
||||
}
|
||||
return service.createOmemoMessage(guard, devices, message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -355,23 +357,24 @@ public final class OmemoManager extends Manager {
|
|||
* @throws SmackException.NoResponseException
|
||||
* @throws NoOmemoSupportException When the muc doesn't support OMEMO.
|
||||
* @throws SmackException.NotLoggedInException
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized OmemoMessage.Sent encrypt(MultiUserChat muc, String message)
|
||||
public OmemoMessage.Sent encrypt(MultiUserChat muc, String message)
|
||||
throws UndecidedOmemoIdentityException, CryptoFailedException,
|
||||
XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException,
|
||||
SmackException.NoResponseException, NoOmemoSupportException,
|
||||
SmackException.NotLoggedInException, IOException {
|
||||
if (!multiUserChatSupportsOmemo(muc)) {
|
||||
throw new NoOmemoSupportException();
|
||||
}
|
||||
SmackException.NotLoggedInException {
|
||||
synchronized (LOCK) {
|
||||
if (!multiUserChatSupportsOmemo(muc)) {
|
||||
throw new NoOmemoSupportException();
|
||||
}
|
||||
|
||||
Set<BareJid> recipients = new HashSet<>();
|
||||
Set<BareJid> recipients = new HashSet<>();
|
||||
|
||||
for (EntityFullJid e : muc.getOccupants()) {
|
||||
recipients.add(muc.getOccupant(e).getJid().asBareJid());
|
||||
for (EntityFullJid e : muc.getOccupants()) {
|
||||
recipients.add(muc.getOccupant(e).getJid().asBareJid());
|
||||
}
|
||||
return encrypt(recipients, message);
|
||||
}
|
||||
return encrypt(recipients, message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,11 +390,10 @@ public final class OmemoManager extends Manager {
|
|||
* @throws CorruptedOmemoKeyException if our or their key is corrupted
|
||||
* @throws NoRawSessionException if the message was not a preKeyMessage, but we had no session with the contact
|
||||
* @throws CryptoFailedException if decryption fails
|
||||
* @throws IOException
|
||||
*/
|
||||
public OmemoMessage.Received decrypt(BareJid sender, OmemoElement omemoElement)
|
||||
throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, NoRawSessionException,
|
||||
CryptoFailedException, IOException {
|
||||
CryptoFailedException {
|
||||
LoggedInOmemoManager managerGuard = new LoggedInOmemoManager(this);
|
||||
return getOmemoService().decryptMessage(managerGuard, sender, omemoElement);
|
||||
}
|
||||
|
@ -402,10 +404,9 @@ public final class OmemoManager extends Manager {
|
|||
* @param mamQuery The MAM query
|
||||
* @return list of decrypted OmemoMessages
|
||||
* @throws SmackException.NotLoggedInException if the Manager is not authenticated.
|
||||
* @throws IOException
|
||||
*/
|
||||
public List<MessageOrOmemoMessage> decryptMamQueryResult(MamManager.MamQuery mamQuery)
|
||||
throws SmackException.NotLoggedInException, IOException {
|
||||
throws SmackException.NotLoggedInException {
|
||||
return new ArrayList<>(getOmemoService().decryptMamQueryResult(new LoggedInOmemoManager(this), mamQuery));
|
||||
}
|
||||
|
||||
|
@ -485,22 +486,24 @@ public final class OmemoManager extends Manager {
|
|||
* @throws SmackException.NoResponseException
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized void sendRatchetUpdateMessage(OmemoDevice recipient)
|
||||
public void sendRatchetUpdateMessage(OmemoDevice recipient)
|
||||
throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, InterruptedException,
|
||||
SmackException.NoResponseException, NoSuchAlgorithmException, SmackException.NotConnectedException,
|
||||
CryptoFailedException, CannotEstablishOmemoSessionException, IOException {
|
||||
Message message = new Message();
|
||||
message.setFrom(getOwnJid());
|
||||
message.setTo(recipient.getJid());
|
||||
CryptoFailedException, CannotEstablishOmemoSessionException {
|
||||
synchronized (LOCK) {
|
||||
Message message = new Message();
|
||||
message.setFrom(getOwnJid());
|
||||
message.setTo(recipient.getJid());
|
||||
|
||||
OmemoElement element = getOmemoService().createRatchetUpdateElement(new LoggedInOmemoManager(this), recipient);
|
||||
message.addExtension(element);
|
||||
OmemoElement element = getOmemoService()
|
||||
.createRatchetUpdateElement(new LoggedInOmemoManager(this), recipient);
|
||||
message.addExtension(element);
|
||||
|
||||
// Set MAM Storage hint
|
||||
StoreHint.set(message);
|
||||
connection().sendStanza(message);
|
||||
// Set MAM Storage hint
|
||||
StoreHint.set(message);
|
||||
connection().sendStanza(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -513,13 +516,14 @@ public final class OmemoManager extends Manager {
|
|||
* @throws SmackException.NoResponseException
|
||||
* @throws PubSubException.NotALeafNodeException
|
||||
* @throws XMPPException.XMPPErrorException
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized boolean contactSupportsOmemo(BareJid contact)
|
||||
public boolean contactSupportsOmemo(BareJid contact)
|
||||
throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException,
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException, IOException {
|
||||
OmemoCachedDeviceList deviceList = getOmemoService().refreshDeviceList(connection(), getOwnDevice(), contact);
|
||||
return !deviceList.getActiveDevices().isEmpty();
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||
synchronized (LOCK) {
|
||||
OmemoCachedDeviceList deviceList = getOmemoService().refreshDeviceList(connection(), getOwnDevice(), contact);
|
||||
return !deviceList.getActiveDevices().isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -565,15 +569,16 @@ public final class OmemoManager extends Manager {
|
|||
* @return fingerprint
|
||||
* @throws SmackException.NotLoggedInException if we don't know our bareJid yet.
|
||||
* @throws CorruptedOmemoKeyException if our identityKey is corrupted.
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized OmemoFingerprint getOwnFingerprint()
|
||||
throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, IOException {
|
||||
if (getOwnJid() == null) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
}
|
||||
public OmemoFingerprint getOwnFingerprint()
|
||||
throws SmackException.NotLoggedInException, CorruptedOmemoKeyException {
|
||||
synchronized (LOCK) {
|
||||
if (getOwnJid() == null) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
}
|
||||
|
||||
return getOmemoService().getOmemoStoreBackend().getFingerprint(getOwnDevice());
|
||||
return getOmemoService().getOmemoStoreBackend().getFingerprint(getOwnDevice());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -586,22 +591,22 @@ public final class OmemoManager extends Manager {
|
|||
* @throws SmackException.NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized OmemoFingerprint getFingerprint(OmemoDevice device)
|
||||
public OmemoFingerprint getFingerprint(OmemoDevice device)
|
||||
throws CannotEstablishOmemoSessionException, SmackException.NotLoggedInException,
|
||||
CorruptedOmemoKeyException, SmackException.NotConnectedException, InterruptedException,
|
||||
SmackException.NoResponseException, IOException {
|
||||
if (getOwnJid() == null) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
}
|
||||
SmackException.NoResponseException {
|
||||
synchronized (LOCK) {
|
||||
if (getOwnJid() == null) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
}
|
||||
|
||||
if (device.equals(getOwnDevice())) {
|
||||
return getOwnFingerprint();
|
||||
}
|
||||
if (device.equals(getOwnDevice())) {
|
||||
return getOwnFingerprint();
|
||||
}
|
||||
|
||||
return getOmemoService().getOmemoStoreBackend()
|
||||
.getFingerprintAndMaybeBuildSession(new LoggedInOmemoManager(this), device);
|
||||
return getOmemoService().getOmemoStoreBackend().getFingerprintAndMaybeBuildSession(new LoggedInOmemoManager(this), device);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -616,30 +621,31 @@ public final class OmemoManager extends Manager {
|
|||
* @throws SmackException.NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized HashMap<OmemoDevice, OmemoFingerprint> getActiveFingerprints(BareJid contact)
|
||||
public HashMap<OmemoDevice, OmemoFingerprint> getActiveFingerprints(BareJid contact)
|
||||
throws SmackException.NotLoggedInException, CorruptedOmemoKeyException,
|
||||
CannotEstablishOmemoSessionException, SmackException.NotConnectedException, InterruptedException,
|
||||
SmackException.NoResponseException, IOException {
|
||||
if (getOwnJid() == null) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
}
|
||||
|
||||
HashMap<OmemoDevice, OmemoFingerprint> fingerprints = new HashMap<>();
|
||||
OmemoCachedDeviceList deviceList = getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(getOwnDevice(),
|
||||
contact);
|
||||
|
||||
for (int id : deviceList.getActiveDevices()) {
|
||||
OmemoDevice device = new OmemoDevice(contact, id);
|
||||
OmemoFingerprint fingerprint = getFingerprint(device);
|
||||
|
||||
if (fingerprint != null) {
|
||||
fingerprints.put(device, fingerprint);
|
||||
SmackException.NoResponseException {
|
||||
synchronized (LOCK) {
|
||||
if (getOwnJid() == null) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
}
|
||||
}
|
||||
|
||||
return fingerprints;
|
||||
HashMap<OmemoDevice, OmemoFingerprint> fingerprints = new HashMap<>();
|
||||
OmemoCachedDeviceList deviceList = getOmemoService().getOmemoStoreBackend()
|
||||
.loadCachedDeviceList(getOwnDevice(), contact);
|
||||
|
||||
for (int id : deviceList.getActiveDevices()) {
|
||||
OmemoDevice device = new OmemoDevice(contact, id);
|
||||
OmemoFingerprint fingerprint = getFingerprint(device);
|
||||
|
||||
if (fingerprint != null) {
|
||||
fingerprints.put(device, fingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
return fingerprints;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -686,12 +692,13 @@ public final class OmemoManager extends Manager {
|
|||
* @throws XMPPException.XMPPErrorException
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized void requestDeviceListUpdateFor(BareJid contact)
|
||||
public void requestDeviceListUpdateFor(BareJid contact)
|
||||
throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException,
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException, IOException {
|
||||
getOmemoService().refreshDeviceList(connection(), getOwnDevice(), contact);
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||
synchronized (LOCK) {
|
||||
getOmemoService().refreshDeviceList(connection(), getOwnDevice(), contact);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -702,13 +709,13 @@ public final class OmemoManager extends Manager {
|
|||
* @throws XMPPException.XMPPErrorException
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
* @throws PubSubException.NotALeafNodeException
|
||||
*/
|
||||
public void purgeDeviceList()
|
||||
throws SmackException.NotLoggedInException, InterruptedException, XMPPException.XMPPErrorException,
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException, IOException, PubSubException.NotALeafNodeException {
|
||||
getOmemoService().purgeDeviceList(new LoggedInOmemoManager(this));
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||
synchronized (LOCK) {
|
||||
getOmemoService().purgeDeviceList(new LoggedInOmemoManager(this));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -722,23 +729,22 @@ public final class OmemoManager extends Manager {
|
|||
* @throws SmackException.NotConnectedException XMPP error
|
||||
* @throws SmackException.NoResponseException XMPP error
|
||||
* @throws SmackException.NotLoggedInException
|
||||
* @throws IOException
|
||||
* @throws PubSubException.NotALeafNodeException
|
||||
*/
|
||||
public synchronized void rotateSignedPreKey()
|
||||
public void rotateSignedPreKey()
|
||||
throws CorruptedOmemoKeyException, SmackException.NotLoggedInException, XMPPException.XMPPErrorException,
|
||||
SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException,
|
||||
IOException, PubSubException.NotALeafNodeException {
|
||||
if (!connection().isAuthenticated()) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||
synchronized (LOCK) {
|
||||
if (!connection().isAuthenticated()) {
|
||||
throw new SmackException.NotLoggedInException();
|
||||
}
|
||||
|
||||
// generate key
|
||||
getOmemoService().getOmemoStoreBackend().changeSignedPreKey(getOwnDevice());
|
||||
|
||||
// publish
|
||||
OmemoBundleElement bundle = getOmemoService().getOmemoStoreBackend().packOmemoBundle(getOwnDevice());
|
||||
OmemoService.publishBundle(connection(), getOwnDevice(), bundle);
|
||||
}
|
||||
|
||||
// generate key
|
||||
getOmemoService().getOmemoStoreBackend().changeSignedPreKey(getOwnDevice());
|
||||
|
||||
// publish
|
||||
OmemoBundleElement bundle = getOmemoService().getOmemoStoreBackend().packOmemoBundle(getOwnDevice());
|
||||
OmemoService.publishBundle(connection(), getOwnDevice(), bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -785,8 +791,10 @@ public final class OmemoManager extends Manager {
|
|||
*
|
||||
* @return deviceId
|
||||
*/
|
||||
public synchronized Integer getDeviceId() {
|
||||
return deviceId;
|
||||
public Integer getDeviceId() {
|
||||
synchronized (LOCK) {
|
||||
return deviceId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -794,24 +802,28 @@ public final class OmemoManager extends Manager {
|
|||
*
|
||||
* @return omemoDevice
|
||||
*/
|
||||
public synchronized OmemoDevice getOwnDevice() {
|
||||
BareJid jid = getOwnJid();
|
||||
if (jid == null) {
|
||||
return null;
|
||||
public OmemoDevice getOwnDevice() {
|
||||
synchronized (LOCK) {
|
||||
BareJid jid = getOwnJid();
|
||||
if (jid == null) {
|
||||
return null;
|
||||
}
|
||||
return new OmemoDevice(jid, getDeviceId());
|
||||
}
|
||||
return new OmemoDevice(jid, getDeviceId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the deviceId of the manager to nDeviceId.
|
||||
* @param nDeviceId new deviceId
|
||||
*/
|
||||
synchronized void setDeviceId(int nDeviceId) {
|
||||
// Move this instance inside the HashMaps
|
||||
INSTANCES.get(connection()).remove(getDeviceId());
|
||||
INSTANCES.get(connection()).put(nDeviceId, this);
|
||||
void setDeviceId(int nDeviceId) {
|
||||
synchronized (LOCK) {
|
||||
// Move this instance inside the HashMaps
|
||||
INSTANCES.get(connection()).remove(getDeviceId());
|
||||
INSTANCES.get(connection()).put(nDeviceId, this);
|
||||
|
||||
this.deviceId = nDeviceId;
|
||||
this.deviceId = nDeviceId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -944,8 +956,8 @@ public final class OmemoManager extends Manager {
|
|||
try {
|
||||
getOmemoService().onOmemoMessageStanzaReceived(packet,
|
||||
new LoggedInOmemoManager(OmemoManager.this));
|
||||
} catch (SmackException.NotLoggedInException | IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Exception while processing OMEMO stanza", e);
|
||||
} catch (SmackException.NotLoggedInException e) {
|
||||
LOGGER.warning("Received OMEMO stanza while being offline: " + e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -967,8 +979,8 @@ public final class OmemoManager extends Manager {
|
|||
try {
|
||||
getOmemoService().onOmemoCarbonCopyReceived(direction, carbonCopy, wrappingMessage,
|
||||
new LoggedInOmemoManager(OmemoManager.this));
|
||||
} catch (SmackException.NotLoggedInException | IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Exception while processing OMEMO stanza", e);
|
||||
} catch (SmackException.NotLoggedInException e) {
|
||||
LOGGER.warning("Received OMEMO carbon copy while being offline: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1006,23 +1018,14 @@ public final class OmemoManager extends Manager {
|
|||
}
|
||||
|
||||
// Device List <list>
|
||||
OmemoCachedDeviceList deviceList;
|
||||
OmemoDeviceListElement receivedDeviceList = (OmemoDeviceListElement) payloadItem.getPayload();
|
||||
try {
|
||||
getOmemoService().getOmemoStoreBackend().mergeCachedDeviceList(getOwnDevice(), from,
|
||||
receivedDeviceList);
|
||||
getOmemoService().getOmemoStoreBackend().mergeCachedDeviceList(getOwnDevice(), from, receivedDeviceList);
|
||||
|
||||
if (!from.asBareJid().equals(getOwnJid())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
deviceList = getOmemoService().cleanUpDeviceList(getOwnDevice());
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE,
|
||||
"IOException while processing OMEMO PEP device updates. Message: " + message,
|
||||
e);
|
||||
if (!from.asBareJid().equals(getOwnJid())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OmemoCachedDeviceList deviceList = getOmemoService().cleanUpDeviceList(getOwnDevice());
|
||||
final OmemoDeviceListElement_VAxolotl newDeviceList = new OmemoDeviceListElement_VAxolotl(deviceList);
|
||||
|
||||
if (!newDeviceList.copyDeviceIds().equals(receivedDeviceList.copyDeviceIds())) {
|
||||
|
@ -1035,7 +1038,7 @@ public final class OmemoManager extends Manager {
|
|||
try {
|
||||
OmemoService.publishDeviceList(connection(), newDeviceList);
|
||||
} catch (InterruptedException | XMPPException.XMPPErrorException |
|
||||
SmackException.NotConnectedException | SmackException.NoResponseException | PubSubException.NotALeafNodeException e) {
|
||||
SmackException.NotConnectedException | SmackException.NoResponseException e) {
|
||||
LOGGER.log(Level.WARNING, "Could not publish our deviceList upon an received update.", e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.omemo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -66,11 +65,10 @@ public abstract class OmemoRatchet<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws NoRawSessionException when no double ratchet session was found.
|
||||
* @throws CryptoFailedException
|
||||
* @throws UntrustedOmemoIdentityException
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract byte[] doubleRatchetDecrypt(OmemoDevice sender, byte[] encryptedKey)
|
||||
throws CorruptedOmemoKeyException, NoRawSessionException, CryptoFailedException,
|
||||
UntrustedOmemoIdentityException, IOException;
|
||||
UntrustedOmemoIdentityException;
|
||||
|
||||
/**
|
||||
* Encrypt a messageKey with the double ratchet session of the recipient.
|
||||
|
@ -88,10 +86,9 @@ public abstract class OmemoRatchet<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @return tuple of cipher generated from the unpacked message key and the auth-tag
|
||||
* @throws CryptoFailedException if decryption using the double ratchet fails
|
||||
* @throws NoRawSessionException if we have no session, but the element was NOT a PreKeyMessage
|
||||
* @throws IOException
|
||||
*/
|
||||
CipherAndAuthTag retrieveMessageKeyAndAuthTag(OmemoDevice sender, OmemoElement element) throws CryptoFailedException,
|
||||
NoRawSessionException, IOException {
|
||||
NoRawSessionException {
|
||||
int keyId = omemoManager.getDeviceId();
|
||||
byte[] unpackedKey = null;
|
||||
List<CryptoFailedException> decryptExceptions = new ArrayList<>();
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.jivesoftware.smackx.omemo;
|
|||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.Crypto.KEYLENGTH;
|
||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.Crypto.KEYTYPE;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
@ -74,11 +73,9 @@ import org.jivesoftware.smackx.omemo.trust.TrustState;
|
|||
import org.jivesoftware.smackx.omemo.util.MessageOrOmemoMessage;
|
||||
import org.jivesoftware.smackx.omemo.util.OmemoConstants;
|
||||
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.PubSubException;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubException.NotALeafNodeException;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubManager;
|
||||
|
||||
import org.jxmpp.jid.BareJid;
|
||||
|
@ -237,12 +234,11 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws PubSubException.NotALeafNodeException
|
||||
* @throws IOException
|
||||
*/
|
||||
void init(OmemoManager.LoggedInOmemoManager managerGuard)
|
||||
throws InterruptedException, CorruptedOmemoKeyException, XMPPException.XMPPErrorException,
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException,
|
||||
PubSubException.NotALeafNodeException, IOException {
|
||||
PubSubException.NotALeafNodeException {
|
||||
|
||||
OmemoManager manager = managerGuard.get();
|
||||
OmemoDevice userDevice = manager.getOwnDevice();
|
||||
|
@ -277,13 +273,12 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws CorruptedOmemoKeyException if our IdentityKeyPair is corrupted.
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws CannotEstablishOmemoSessionException if session negotiation fails.
|
||||
* @throws IOException
|
||||
*/
|
||||
OmemoElement createRatchetUpdateElement(OmemoManager.LoggedInOmemoManager managerGuard,
|
||||
OmemoDevice contactsDevice)
|
||||
throws InterruptedException, SmackException.NoResponseException, CorruptedOmemoKeyException,
|
||||
SmackException.NotConnectedException, CannotEstablishOmemoSessionException, NoSuchAlgorithmException,
|
||||
CryptoFailedException, IOException {
|
||||
CryptoFailedException {
|
||||
|
||||
OmemoManager manager = managerGuard.get();
|
||||
OmemoDevice userDevice = manager.getOwnDevice();
|
||||
|
@ -339,7 +334,6 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws SmackException.NoResponseException
|
||||
* @throws UndecidedOmemoIdentityException if the list of recipient devices contains undecided devices
|
||||
* @throws CryptoFailedException if we are lacking some crypto primitives
|
||||
* @throws IOException
|
||||
*/
|
||||
private OmemoMessage.Sent encrypt(OmemoManager.LoggedInOmemoManager managerGuard,
|
||||
Set<OmemoDevice> contactsDevices,
|
||||
|
@ -347,7 +341,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
byte[] iv,
|
||||
String message)
|
||||
throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException,
|
||||
UndecidedOmemoIdentityException, CryptoFailedException, IOException {
|
||||
UndecidedOmemoIdentityException, CryptoFailedException {
|
||||
|
||||
OmemoManager manager = managerGuard.get();
|
||||
OmemoDevice userDevice = manager.getOwnDevice();
|
||||
|
@ -441,12 +435,11 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws CorruptedOmemoKeyException if the identityKey of the sender is damaged.
|
||||
* @throws CryptoFailedException if decryption fails.
|
||||
* @throws NoRawSessionException if we have no session with the device and it sent a normal (non-preKey) message.
|
||||
* @throws IOException
|
||||
*/
|
||||
OmemoMessage.Received decryptMessage(OmemoManager.LoggedInOmemoManager managerGuard,
|
||||
BareJid senderJid,
|
||||
OmemoElement omemoElement)
|
||||
throws CorruptedOmemoKeyException, CryptoFailedException, NoRawSessionException, IOException {
|
||||
throws CorruptedOmemoKeyException, CryptoFailedException, NoRawSessionException {
|
||||
|
||||
OmemoManager manager = managerGuard.get();
|
||||
int senderId = omemoElement.getHeader().getSid();
|
||||
|
@ -495,14 +488,13 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws CryptoFailedException if we are lacking some cryptographic algorithms
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
*/
|
||||
OmemoMessage.Sent createKeyTransportElement(OmemoManager.LoggedInOmemoManager managerGuard,
|
||||
Set<OmemoDevice> contactsDevices,
|
||||
byte[] key,
|
||||
byte[] iv)
|
||||
throws InterruptedException, UndecidedOmemoIdentityException, CryptoFailedException,
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException, IOException {
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||
return encrypt(managerGuard, contactsDevices, key, iv, null);
|
||||
}
|
||||
|
||||
|
@ -519,13 +511,12 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws CryptoFailedException if we are lacking some cryptographic algorithms
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
*/
|
||||
OmemoMessage.Sent createOmemoMessage(OmemoManager.LoggedInOmemoManager managerGuard,
|
||||
Set<OmemoDevice> contactsDevices,
|
||||
String message)
|
||||
throws InterruptedException, UndecidedOmemoIdentityException, CryptoFailedException,
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException, IOException {
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||
|
||||
byte[] key, iv;
|
||||
iv = OmemoMessageBuilder.generateIv();
|
||||
|
@ -583,13 +574,12 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws SmackException.NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws NotALeafNodeException
|
||||
*/
|
||||
static void publishBundle(XMPPConnection connection, OmemoDevice userDevice, OmemoBundleElement bundle)
|
||||
throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException,
|
||||
SmackException.NoResponseException, NotALeafNodeException {
|
||||
PepManager pm = PepManager.getInstanceFor(connection);
|
||||
pm.publish(userDevice.getBundleNodeName(), new PayloadItem<>(bundle));
|
||||
SmackException.NoResponseException {
|
||||
PubSubManager pm = PubSubManager.getInstanceFor(connection, connection.getUser().asBareJid());
|
||||
pm.tryToPublishAndPossibleAutoCreate(userDevice.getBundleNodeName(), new PayloadItem<>(bundle));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -638,9 +628,10 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
*/
|
||||
static void publishDeviceList(XMPPConnection connection, OmemoDeviceListElement deviceList)
|
||||
throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException,
|
||||
SmackException.NoResponseException, NotALeafNodeException {
|
||||
PepManager pm = PepManager.getInstanceFor(connection);
|
||||
pm.publish(OmemoConstants.PEP_NODE_DEVICE_LIST, new PayloadItem<>(deviceList));
|
||||
SmackException.NoResponseException {
|
||||
|
||||
PubSubManager.getInstanceFor(connection, connection.getUser().asBareJid())
|
||||
.tryToPublishAndPossibleAutoCreate(OmemoConstants.PEP_NODE_DEVICE_LIST, new PayloadItem<>(deviceList));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -652,11 +643,10 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws XMPPException.XMPPErrorException
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
*/
|
||||
private void refreshAndRepublishDeviceList(XMPPConnection connection, OmemoDevice userDevice)
|
||||
throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException,
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException, IOException {
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||
|
||||
// refreshOmemoDeviceList;
|
||||
OmemoDeviceListElement publishedList;
|
||||
|
@ -695,9 +685,8 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
*
|
||||
* @param userDevice
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
OmemoCachedDeviceList cleanUpDeviceList(OmemoDevice userDevice) throws IOException {
|
||||
OmemoCachedDeviceList cleanUpDeviceList(OmemoDevice userDevice) {
|
||||
OmemoCachedDeviceList cachedDeviceList;
|
||||
|
||||
// Delete stale devices if allowed and necessary
|
||||
|
@ -730,11 +719,10 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws XMPPException.XMPPErrorException
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
*/
|
||||
OmemoCachedDeviceList refreshDeviceList(XMPPConnection connection, OmemoDevice userDevice, BareJid contact)
|
||||
throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException,
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException, IOException {
|
||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||
// refreshOmemoDeviceList;
|
||||
OmemoDeviceListElement publishedList;
|
||||
try {
|
||||
|
@ -802,12 +790,11 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws SmackException.NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
*/
|
||||
private Set<OmemoDevice> buildMissingSessionsWithDevices(XMPPConnection connection,
|
||||
OmemoDevice userDevice,
|
||||
Set<OmemoDevice> devices)
|
||||
throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, IOException {
|
||||
throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||
|
||||
Set<OmemoDevice> devicesWithSession = new HashSet<>();
|
||||
for (OmemoDevice device : devices) {
|
||||
|
@ -841,9 +828,8 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @param callback OmemoTrustCallback to query the trust decisions from
|
||||
* @param devices set of OmemoDevices
|
||||
* @return set of OmemoDevices which contains all devices from the set devices, which are undecided
|
||||
* @throws IOException
|
||||
*/
|
||||
private Set<OmemoDevice> getUndecidedDevices(OmemoDevice userDevice, OmemoTrustCallback callback, Set<OmemoDevice> devices) throws IOException {
|
||||
private Set<OmemoDevice> getUndecidedDevices(OmemoDevice userDevice, OmemoTrustCallback callback, Set<OmemoDevice> devices) {
|
||||
Set<OmemoDevice> undecidedDevices = new HashSet<>();
|
||||
|
||||
for (OmemoDevice device : devices) {
|
||||
|
@ -872,9 +858,8 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param contactsDevice OmemoDevice of the contact.
|
||||
* @return true if userDevice has session with contactsDevice.
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean hasSession(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException {
|
||||
private boolean hasSession(OmemoDevice userDevice, OmemoDevice contactsDevice) {
|
||||
return getOmemoStoreBackend().loadRawSession(userDevice, contactsDevice) != null;
|
||||
}
|
||||
|
||||
|
@ -896,9 +881,8 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
*
|
||||
* @param userDevice our OmemoDevice
|
||||
* @return true if rotation is necessary
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean shouldRotateSignedPreKey(OmemoDevice userDevice) throws IOException {
|
||||
private boolean shouldRotateSignedPreKey(OmemoDevice userDevice) {
|
||||
if (!OmemoConfiguration.getRenewOldSignedPreKeys()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -925,9 +909,8 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
*
|
||||
* @param userDevice our OmemoDevice
|
||||
* @return our altered deviceList with stale devices marked as inactive.
|
||||
* @throws IOException
|
||||
*/
|
||||
private OmemoCachedDeviceList deleteStaleDevices(OmemoDevice userDevice) throws IOException {
|
||||
private OmemoCachedDeviceList deleteStaleDevices(OmemoDevice userDevice) {
|
||||
OmemoCachedDeviceList deviceList = getOmemoStoreBackend().loadCachedDeviceList(userDevice);
|
||||
int maxAgeHours = OmemoConfiguration.getDeleteStaleDevicesAfterHours();
|
||||
return removeStaleDevicesFromDeviceList(userDevice, userDevice.getJid(), deviceList, maxAgeHours);
|
||||
|
@ -945,12 +928,11 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @param contact subjects BareJid.
|
||||
* @param contactsDeviceList subjects deviceList.
|
||||
* @return copy of subjects deviceList with stale devices marked as inactive.
|
||||
* @throws IOException
|
||||
*/
|
||||
private OmemoCachedDeviceList removeStaleDevicesFromDeviceList(OmemoDevice userDevice,
|
||||
BareJid contact,
|
||||
OmemoCachedDeviceList contactsDeviceList,
|
||||
int maxAgeHours) throws IOException {
|
||||
int maxAgeHours) {
|
||||
OmemoCachedDeviceList deviceList = new OmemoCachedDeviceList(contactsDeviceList); // Don't work on original list.
|
||||
|
||||
// Iterate through original list, but modify copy instead
|
||||
|
@ -1042,10 +1024,9 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @param managerGuard authenticated OmemoManager.
|
||||
* @param mamQuery Mam archive query
|
||||
* @return list of {@link MessageOrOmemoMessage}s.
|
||||
* @throws IOException
|
||||
*/
|
||||
List<MessageOrOmemoMessage> decryptMamQueryResult(OmemoManager.LoggedInOmemoManager managerGuard,
|
||||
MamManager.MamQuery mamQuery) throws IOException {
|
||||
MamManager.MamQuery mamQuery) {
|
||||
List<MessageOrOmemoMessage> result = new ArrayList<>();
|
||||
for (Message message : mamQuery.getMessages()) {
|
||||
if (OmemoManager.stanzaContainsOmemoElement(message)) {
|
||||
|
@ -1074,10 +1055,10 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
public void onOmemoCarbonCopyReceived(CarbonExtension.Direction direction,
|
||||
Message carbonCopy,
|
||||
Message wrappingMessage,
|
||||
OmemoManager.LoggedInOmemoManager managerGuard) throws IOException {
|
||||
OmemoManager.LoggedInOmemoManager managerGuard) {
|
||||
OmemoManager manager = managerGuard.get();
|
||||
// Avoid the ratchet being manipulated and the bundle being published multiple times simultaneously
|
||||
synchronized (manager) {
|
||||
synchronized (manager.LOCK) {
|
||||
OmemoDevice userDevice = manager.getOwnDevice();
|
||||
OmemoElement element = carbonCopy.getExtension(OmemoElement.NAME_ENCRYPTED, OmemoElement_VAxolotl.NAMESPACE);
|
||||
if (element == null) {
|
||||
|
@ -1121,9 +1102,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
getOmemoStoreBackend().replenishKeys(userDevice);
|
||||
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
|
||||
publishBundle(manager.getConnection(), userDevice, bundleElement);
|
||||
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException
|
||||
| SmackException.NotConnectedException | XMPPException.XMPPErrorException
|
||||
| NotALeafNodeException e) {
|
||||
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
|
||||
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
|
||||
}
|
||||
}
|
||||
|
@ -1131,10 +1110,10 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoMessageStanzaReceived(Stanza stanza, OmemoManager.LoggedInOmemoManager managerGuard) throws IOException {
|
||||
public void onOmemoMessageStanzaReceived(Stanza stanza, OmemoManager.LoggedInOmemoManager managerGuard) {
|
||||
OmemoManager manager = managerGuard.get();
|
||||
// Avoid the ratchet being manipulated and the bundle being published multiple times simultaneously
|
||||
synchronized (manager) {
|
||||
synchronized (manager.LOCK) {
|
||||
OmemoDevice userDevice = manager.getOwnDevice();
|
||||
OmemoElement element = stanza.getExtension(OmemoElement.NAME_ENCRYPTED, OmemoElement_VAxolotl.NAMESPACE);
|
||||
if (element == null) {
|
||||
|
@ -1204,9 +1183,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
getOmemoStoreBackend().replenishKeys(userDevice);
|
||||
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
|
||||
publishBundle(manager.getConnection(), userDevice, bundleElement);
|
||||
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException
|
||||
| SmackException.NotConnectedException | XMPPException.XMPPErrorException
|
||||
| NotALeafNodeException e) {
|
||||
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
|
||||
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
|
||||
}
|
||||
}
|
||||
|
@ -1220,12 +1197,11 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @param stanza stanza
|
||||
* @param managerGuard authenticated OmemoManager
|
||||
* @return decrypted OmemoMessage or null
|
||||
* @throws IOException
|
||||
*/
|
||||
OmemoMessage.Received decryptStanza(Stanza stanza, OmemoManager.LoggedInOmemoManager managerGuard) throws IOException {
|
||||
OmemoMessage.Received decryptStanza(Stanza stanza, OmemoManager.LoggedInOmemoManager managerGuard) {
|
||||
OmemoManager manager = managerGuard.get();
|
||||
// Avoid the ratchet being manipulated and the bundle being published multiple times simultaneously
|
||||
synchronized (manager) {
|
||||
synchronized (manager.LOCK) {
|
||||
OmemoDevice userDevice = manager.getOwnDevice();
|
||||
OmemoElement element = stanza.getExtension(OmemoElement.NAME_ENCRYPTED, OmemoElement_VAxolotl.NAMESPACE);
|
||||
if (element == null) {
|
||||
|
@ -1286,9 +1262,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
getOmemoStoreBackend().replenishKeys(userDevice);
|
||||
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
|
||||
publishBundle(manager.getConnection(), userDevice, bundleElement);
|
||||
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException
|
||||
| SmackException.NotConnectedException | XMPPException.XMPPErrorException
|
||||
| NotALeafNodeException e) {
|
||||
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
|
||||
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
|
||||
}
|
||||
}
|
||||
|
@ -1301,10 +1275,9 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
*
|
||||
* @param managerGuard authenticated OmemoManager.
|
||||
* @param brokenDevice device which session broke.
|
||||
* @throws IOException
|
||||
*/
|
||||
private void repairBrokenSessionWithPreKeyMessage(OmemoManager.LoggedInOmemoManager managerGuard,
|
||||
OmemoDevice brokenDevice) throws IOException {
|
||||
OmemoDevice brokenDevice) {
|
||||
|
||||
LOGGER.log(Level.WARNING, "Attempt to repair the session by sending a fresh preKey message to "
|
||||
+ brokenDevice);
|
||||
|
@ -1334,12 +1307,11 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws SmackException.NotConnectedException
|
||||
* @throws CryptoFailedException if encryption fails (should not happen though, but who knows...)
|
||||
* @throws CannotEstablishOmemoSessionException if we cannot establish a session with contactsDevice.
|
||||
* @throws IOException
|
||||
*/
|
||||
private void sendRatchetUpdate(OmemoManager.LoggedInOmemoManager managerGuard, OmemoDevice contactsDevice)
|
||||
throws CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException,
|
||||
NoSuchAlgorithmException, SmackException.NotConnectedException, CryptoFailedException,
|
||||
CannotEstablishOmemoSessionException, IOException {
|
||||
CannotEstablishOmemoSessionException {
|
||||
|
||||
OmemoManager manager = managerGuard.get();
|
||||
OmemoElement ratchetUpdate = createRatchetUpdateElement(managerGuard, contactsDevice);
|
||||
|
@ -1378,12 +1350,10 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
|||
* @throws XMPPException.XMPPErrorException
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
* @throws NotALeafNodeException
|
||||
*/
|
||||
public void purgeDeviceList(OmemoManager.LoggedInOmemoManager managerGuard)
|
||||
throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException,
|
||||
SmackException.NoResponseException, IOException, NotALeafNodeException {
|
||||
SmackException.NoResponseException {
|
||||
|
||||
OmemoManager omemoManager = managerGuard.get();
|
||||
OmemoDevice userDevice = omemoManager.getOwnDevice();
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.jivesoftware.smackx.omemo;
|
|||
|
||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.PRE_KEY_COUNT_PER_BUNDLE;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -79,9 +78,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our current device.
|
||||
* @param id deviceId to check for.
|
||||
* @return true if list did not contain our id, else false
|
||||
* @throws IOException
|
||||
*/
|
||||
boolean isAvailableDeviceId(OmemoDevice userDevice, int id) throws IOException {
|
||||
boolean isAvailableDeviceId(OmemoDevice userDevice, int id) {
|
||||
LOGGER.log(Level.INFO, "Check if id " + id + " is available...");
|
||||
|
||||
// Lookup local cached device list
|
||||
|
@ -103,9 +101,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param contact Contact we received the list from.
|
||||
* @param list List we received.
|
||||
* @throws IOException
|
||||
*/
|
||||
OmemoCachedDeviceList mergeCachedDeviceList(OmemoDevice userDevice, BareJid contact, OmemoDeviceListElement list) throws IOException {
|
||||
OmemoCachedDeviceList mergeCachedDeviceList(OmemoDevice userDevice, BareJid contact, OmemoDeviceListElement list) {
|
||||
OmemoCachedDeviceList cached = loadCachedDeviceList(userDevice, contact);
|
||||
|
||||
if (cached == null) {
|
||||
|
@ -134,11 +131,10 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
*
|
||||
* @param userDevice our OmemoDevice.
|
||||
* @throws CorruptedOmemoKeyException when our identityKey is invalid.
|
||||
* @throws IOException
|
||||
* @throws IllegalStateException when our IdentityKeyPair is null.
|
||||
*/
|
||||
void changeSignedPreKey(OmemoDevice userDevice)
|
||||
throws CorruptedOmemoKeyException, IOException {
|
||||
throws CorruptedOmemoKeyException {
|
||||
|
||||
T_IdKeyPair idKeyPair = loadOmemoIdentityKeyPair(userDevice);
|
||||
if (idKeyPair == null) {
|
||||
|
@ -163,9 +159,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* Remove the oldest signedPreKey until there are only MAX_NUMBER_OF_STORED_SIGNED_PREKEYS left.
|
||||
*
|
||||
* @param userDevice our OmemoDevice.
|
||||
* @throws IOException
|
||||
*/
|
||||
private void removeOldSignedPreKeys(OmemoDevice userDevice) throws IOException {
|
||||
private void removeOldSignedPreKeys(OmemoDevice userDevice) {
|
||||
if (OmemoConfiguration.getMaxNumberOfStoredSignedPreKeys() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -186,10 +181,9 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @return OmemoBundleElement
|
||||
* @throws CorruptedOmemoKeyException when a key could not be loaded
|
||||
* @throws IOException
|
||||
*/
|
||||
OmemoBundleElement_VAxolotl packOmemoBundle(OmemoDevice userDevice)
|
||||
throws CorruptedOmemoKeyException, IOException {
|
||||
throws CorruptedOmemoKeyException {
|
||||
|
||||
int currentSignedPreKeyId = loadCurrentOmemoSignedPreKeyId(userDevice);
|
||||
T_SigPreKey currentSignedPreKey = loadOmemoSignedPreKeys(userDevice).get(currentSignedPreKeyId);
|
||||
|
@ -207,10 +201,9 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* Replenish our supply of keys. If we are missing any type of keys, generate them fresh.
|
||||
* @param userDevice
|
||||
* @throws CorruptedOmemoKeyException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void replenishKeys(OmemoDevice userDevice)
|
||||
throws CorruptedOmemoKeyException, IOException {
|
||||
throws CorruptedOmemoKeyException {
|
||||
|
||||
T_IdKeyPair identityKeyPair = loadOmemoIdentityKeyPair(userDevice);
|
||||
if (identityKeyPair == null) {
|
||||
|
@ -251,10 +244,9 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @return identityKeyPair
|
||||
* @throws CorruptedOmemoKeyException Thrown, if the stored key is damaged (*hands up* not my fault!)
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract T_IdKeyPair loadOmemoIdentityKeyPair(OmemoDevice userDevice)
|
||||
throws CorruptedOmemoKeyException, IOException;
|
||||
throws CorruptedOmemoKeyException;
|
||||
|
||||
/**
|
||||
* Store our identityKeyPair in storage. It would be a cool feature, if the key could be stored in a encrypted
|
||||
|
@ -262,9 +254,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
*
|
||||
* @param userDevice our OmemoDevice.
|
||||
* @param identityKeyPair identityKeyPair
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void storeOmemoIdentityKeyPair(OmemoDevice userDevice, T_IdKeyPair identityKeyPair) throws IOException;
|
||||
public abstract void storeOmemoIdentityKeyPair(OmemoDevice userDevice, T_IdKeyPair identityKeyPair);
|
||||
|
||||
/**
|
||||
* Remove the identityKeyPair of a user.
|
||||
|
@ -279,10 +270,9 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param contactsDevice the device of which we want to load the identityKey.
|
||||
* @return identityKey
|
||||
* @throws CorruptedOmemoKeyException when the key in question is corrupted and cant be deserialized.
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract T_IdKey loadOmemoIdentityKey(OmemoDevice userDevice, OmemoDevice contactsDevice)
|
||||
throws CorruptedOmemoKeyException, IOException;
|
||||
throws CorruptedOmemoKeyException;
|
||||
|
||||
/**
|
||||
* Store the public identityKey of the device.
|
||||
|
@ -290,9 +280,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param contactsDevice device.
|
||||
* @param contactsKey identityKey belonging to the contactsDevice.
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void storeOmemoIdentityKey(OmemoDevice userDevice, OmemoDevice contactsDevice, T_IdKey contactsKey) throws IOException;
|
||||
public abstract void storeOmemoIdentityKey(OmemoDevice userDevice, OmemoDevice contactsDevice, T_IdKey contactsKey);
|
||||
|
||||
/**
|
||||
* Removes the identityKey of a device.
|
||||
|
@ -309,9 +298,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our omemoDevice.
|
||||
* @param contactsDevice device of which we want to set the message counter.
|
||||
* @param counter counter value.
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void storeOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice, int counter) throws IOException;
|
||||
public abstract void storeOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice, int counter);
|
||||
|
||||
/**
|
||||
* Return the current value of the message counter.
|
||||
|
@ -321,9 +309,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our omemoDevice
|
||||
* @param contactsDevice device of which we want to get the message counter.
|
||||
* @return counter value.
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract int loadOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException;
|
||||
public abstract int loadOmemoMessageCounter(OmemoDevice userDevice, OmemoDevice contactsDevice);
|
||||
|
||||
/**
|
||||
* Set the date of the last message that was received from a device.
|
||||
|
@ -331,9 +318,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice omemoManager of our device.
|
||||
* @param contactsDevice device in question
|
||||
* @param date date of the last received message
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void setDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date) throws IOException;
|
||||
public abstract void setDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date);
|
||||
|
||||
/**
|
||||
* Return the date of the last message that was received from device 'from'.
|
||||
|
@ -341,9 +327,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param contactsDevice device in question
|
||||
* @return date if existent, null
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract Date getDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException;
|
||||
public abstract Date getDateOfLastReceivedMessage(OmemoDevice userDevice, OmemoDevice contactsDevice);
|
||||
|
||||
/**
|
||||
* Set the date of the last time the deviceId was published. This method only gets called, when the deviceId
|
||||
|
@ -352,9 +337,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice
|
||||
* @param contactsDevice OmemoDevice in question
|
||||
* @param date date of the last publication after not being published
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void setDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date) throws IOException;
|
||||
public abstract void setDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice, Date date);
|
||||
|
||||
/**
|
||||
* Return the date of the last time the deviceId was published after previously being not published.
|
||||
|
@ -363,27 +347,24 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice
|
||||
* @param contactsDevice OmemoDevice in question
|
||||
* @return date of the last publication after not being published
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract Date getDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException;
|
||||
public abstract Date getDateOfLastDeviceIdPublication(OmemoDevice userDevice, OmemoDevice contactsDevice);
|
||||
|
||||
/**
|
||||
* Set the date of the last time the signed preKey was renewed.
|
||||
*
|
||||
* @param userDevice our OmemoDevice.
|
||||
* @param date date
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void setDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice, Date date) throws IOException;
|
||||
public abstract void setDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice, Date date);
|
||||
|
||||
/**
|
||||
* Get the date of the last time the signed preKey was renewed.
|
||||
*
|
||||
* @param userDevice our OmemoDevice.
|
||||
* @return date if existent, otherwise null
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract Date getDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice) throws IOException;
|
||||
public abstract Date getDateOfLastSignedPreKeyRenewal(OmemoDevice userDevice);
|
||||
|
||||
/**
|
||||
* Generate 'count' new PreKeys beginning with id 'startId'.
|
||||
|
@ -403,9 +384,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param preKeyId id of the key to be loaded
|
||||
* @return loaded preKey
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract T_PreKey loadOmemoPreKey(OmemoDevice userDevice, int preKeyId) throws IOException;
|
||||
public abstract T_PreKey loadOmemoPreKey(OmemoDevice userDevice, int preKeyId);
|
||||
|
||||
/**
|
||||
* Store a PreKey in storage.
|
||||
|
@ -413,18 +393,16 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param preKeyId id of the key
|
||||
* @param preKey key
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void storeOmemoPreKey(OmemoDevice userDevice, int preKeyId, T_PreKey preKey) throws IOException;
|
||||
public abstract void storeOmemoPreKey(OmemoDevice userDevice, int preKeyId, T_PreKey preKey);
|
||||
|
||||
/**
|
||||
* Store a whole bunch of preKeys.
|
||||
*
|
||||
* @param userDevice our OmemoDevice.
|
||||
* @param preKeyHashMap HashMap of preKeys
|
||||
* @throws IOException
|
||||
*/
|
||||
public void storeOmemoPreKeys(OmemoDevice userDevice, TreeMap<Integer, T_PreKey> preKeyHashMap) throws IOException {
|
||||
public void storeOmemoPreKeys(OmemoDevice userDevice, TreeMap<Integer, T_PreKey> preKeyHashMap) {
|
||||
for (Map.Entry<Integer, T_PreKey> entry : preKeyHashMap.entrySet()) {
|
||||
storeOmemoPreKey(userDevice, entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
@ -444,9 +422,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
*
|
||||
* @param userDevice our OmemoDevice.
|
||||
* @return Map containing our preKeys
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract TreeMap<Integer, T_PreKey> loadOmemoPreKeys(OmemoDevice userDevice) throws IOException;
|
||||
public abstract TreeMap<Integer, T_PreKey> loadOmemoPreKeys(OmemoDevice userDevice);
|
||||
|
||||
/**
|
||||
* Return the signedPreKey with the id 'singedPreKeyId'.
|
||||
|
@ -454,11 +431,10 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param signedPreKeyId id of the key
|
||||
* @return key
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract T_SigPreKey loadOmemoSignedPreKey(OmemoDevice userDevice, int signedPreKeyId) throws IOException;
|
||||
public abstract T_SigPreKey loadOmemoSignedPreKey(OmemoDevice userDevice, int signedPreKeyId);
|
||||
|
||||
public int loadCurrentOmemoSignedPreKeyId(OmemoDevice userDevice) throws IOException {
|
||||
public int loadCurrentOmemoSignedPreKeyId(OmemoDevice userDevice) {
|
||||
return loadOmemoSignedPreKeys(userDevice).lastKey();
|
||||
}
|
||||
|
||||
|
@ -467,9 +443,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
*
|
||||
* @param userDevice our OmemoDevice.
|
||||
* @return HashMap of our singedPreKeys
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract TreeMap<Integer, T_SigPreKey> loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException;
|
||||
public abstract TreeMap<Integer, T_SigPreKey> loadOmemoSignedPreKeys(OmemoDevice userDevice);
|
||||
|
||||
/**
|
||||
* Generate a new signed preKey.
|
||||
|
@ -490,9 +465,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param signedPreKeyId id of the signedPreKey
|
||||
* @param signedPreKey the key itself
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void storeOmemoSignedPreKey(OmemoDevice userDevice, int signedPreKeyId, T_SigPreKey signedPreKey) throws IOException;
|
||||
public abstract void storeOmemoSignedPreKey(OmemoDevice userDevice, int signedPreKeyId, T_SigPreKey signedPreKey);
|
||||
|
||||
/**
|
||||
* Remove a signedPreKey from storage.
|
||||
|
@ -508,9 +482,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param contactsDevice device whose session we want to load
|
||||
* @return crypto related session
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract T_Sess loadRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice) throws IOException;
|
||||
public abstract T_Sess loadRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice);
|
||||
|
||||
/**
|
||||
* Load all crypto-lib specific session objects of contact 'contact'.
|
||||
|
@ -518,9 +491,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param contact BareJid of the contact we want to get all sessions from
|
||||
* @return TreeMap of deviceId and sessions of the contact
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract HashMap<Integer, T_Sess> loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException;
|
||||
public abstract HashMap<Integer, T_Sess> loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact);
|
||||
|
||||
/**
|
||||
* Store a crypto-lib specific session to storage.
|
||||
|
@ -528,9 +500,8 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param contactsDevice OmemoDevice whose session we want to store
|
||||
* @param session session
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void storeRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice, T_Sess session) throws IOException;
|
||||
public abstract void storeRawSession(OmemoDevice userDevice, OmemoDevice contactsDevice, T_Sess session);
|
||||
|
||||
/**
|
||||
* Remove a crypto-lib specific session from storage.
|
||||
|
@ -564,17 +535,15 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param contact contact we want to get the deviceList of
|
||||
* @return CachedDeviceList of the contact
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract OmemoCachedDeviceList loadCachedDeviceList(OmemoDevice userDevice, BareJid contact) throws IOException;
|
||||
public abstract OmemoCachedDeviceList loadCachedDeviceList(OmemoDevice userDevice, BareJid contact);
|
||||
|
||||
/**
|
||||
* Load a list of deviceIds from our own devices.
|
||||
* @param userDevice
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public OmemoCachedDeviceList loadCachedDeviceList(OmemoDevice userDevice) throws IOException {
|
||||
public OmemoCachedDeviceList loadCachedDeviceList(OmemoDevice userDevice) {
|
||||
return loadCachedDeviceList(userDevice, userDevice.getJid());
|
||||
}
|
||||
|
||||
|
@ -585,11 +554,10 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @param userDevice our OmemoDevice.
|
||||
* @param contact Contact
|
||||
* @param contactsDeviceList list of the contacts devices' ids.
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void storeCachedDeviceList(OmemoDevice userDevice,
|
||||
BareJid contact,
|
||||
OmemoCachedDeviceList contactsDeviceList) throws IOException;
|
||||
OmemoCachedDeviceList contactsDeviceList);
|
||||
|
||||
/**
|
||||
* Delete this device's IdentityKey, PreKeys, SignedPreKeys and Sessions.
|
||||
|
@ -612,10 +580,9 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @return fingerprint of our identityKeyPair
|
||||
*
|
||||
* @throws CorruptedOmemoKeyException if the identityKey of userDevice is corrupted.
|
||||
* @throws IOException
|
||||
*/
|
||||
public OmemoFingerprint getFingerprint(OmemoDevice userDevice)
|
||||
throws CorruptedOmemoKeyException, IOException {
|
||||
throws CorruptedOmemoKeyException {
|
||||
|
||||
T_IdKeyPair keyPair = loadOmemoIdentityKeyPair(userDevice);
|
||||
if (keyPair == null) {
|
||||
|
@ -633,10 +600,9 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @return fingerprint of the userDevices IdentityKey.
|
||||
* @throws CorruptedOmemoKeyException if the IdentityKey is corrupted.
|
||||
* @throws NoIdentityKeyException if no IdentityKey for contactsDevice has been found locally.
|
||||
* @throws IOException
|
||||
*/
|
||||
public OmemoFingerprint getFingerprint(OmemoDevice userDevice, OmemoDevice contactsDevice)
|
||||
throws CorruptedOmemoKeyException, NoIdentityKeyException, IOException {
|
||||
throws CorruptedOmemoKeyException, NoIdentityKeyException {
|
||||
|
||||
T_IdKey identityKey = loadOmemoIdentityKey(userDevice, contactsDevice);
|
||||
if (identityKey == null) {
|
||||
|
@ -659,11 +625,10 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @throws SmackException.NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws IOException
|
||||
*/
|
||||
public OmemoFingerprint getFingerprintAndMaybeBuildSession(OmemoManager.LoggedInOmemoManager managerGuard, OmemoDevice contactsDevice)
|
||||
throws CannotEstablishOmemoSessionException, CorruptedOmemoKeyException,
|
||||
SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, IOException {
|
||||
SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||
OmemoManager omemoManager = managerGuard.get();
|
||||
|
||||
// Load identityKey
|
||||
|
|
|
@ -60,8 +60,8 @@ public abstract class OmemoBundleElement implements ExtensionElement {
|
|||
* @param preKeysB64 HashMap of base64 encoded preKeys
|
||||
*/
|
||||
public OmemoBundleElement(int signedPreKeyId, String signedPreKeyB64, String signedPreKeySigB64, String identityKeyB64, HashMap<Integer, String> preKeysB64) {
|
||||
if (signedPreKeyId < 0) {
|
||||
throw new IllegalArgumentException("signedPreKeyId MUST be greater than or equal to 0.");
|
||||
if (signedPreKeyId <= 0) {
|
||||
throw new IllegalArgumentException("signedPreKeyId MUST be greater than 0.");
|
||||
}
|
||||
this.signedPreKeyId = signedPreKeyId;
|
||||
this.signedPreKeyB64 = StringUtils.requireNotNullNorEmpty(signedPreKeyB64, "signedPreKeyB64 MUST NOT be null nor empty.");
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.omemo.internal.listener;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
|
||||
import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
|
||||
|
@ -28,6 +26,5 @@ import org.jivesoftware.smackx.omemo.OmemoManager;
|
|||
*/
|
||||
public interface OmemoCarbonCopyStanzaReceivedListener {
|
||||
|
||||
void onOmemoCarbonCopyReceived(CarbonExtension.Direction direction, Message carbonCopy, Message wrappingMessage,
|
||||
OmemoManager.LoggedInOmemoManager omemoManager) throws IOException;
|
||||
void onOmemoCarbonCopyReceived(CarbonExtension.Direction direction, Message carbonCopy, Message wrappingMessage, OmemoManager.LoggedInOmemoManager omemoManager);
|
||||
}
|
||||
|
|
|
@ -16,13 +16,11 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.omemo.internal.listener;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
|
||||
import org.jivesoftware.smackx.omemo.OmemoManager;
|
||||
|
||||
public interface OmemoMessageStanzaReceivedListener {
|
||||
|
||||
void onOmemoMessageStanzaReceived(Stanza stanza, OmemoManager.LoggedInOmemoManager omemoManager) throws IOException;
|
||||
void onOmemoMessageStanzaReceived(Stanza stanza, OmemoManager.LoggedInOmemoManager omemoManager);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import static org.jivesoftware.smackx.omemo.util.OmemoConstants.Crypto.CIPHERMOD
|
|||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.Crypto.KEYLENGTH;
|
||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.Crypto.KEYTYPE;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
|
@ -220,11 +219,10 @@ public class OmemoMessageBuilder<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
* @throws CorruptedOmemoKeyException if the identityKey of that device is corrupted.
|
||||
* @throws UndecidedOmemoIdentityException if the user hasn't yet decided whether to trust that device or not.
|
||||
* @throws UntrustedOmemoIdentityException if the user has decided not to trust that device.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void addRecipient(OmemoDevice contactsDevice)
|
||||
throws NoIdentityKeyException, CorruptedOmemoKeyException, UndecidedOmemoIdentityException,
|
||||
UntrustedOmemoIdentityException, IOException {
|
||||
UntrustedOmemoIdentityException {
|
||||
|
||||
OmemoFingerprint fingerprint;
|
||||
fingerprint = OmemoService.getInstance().getOmemoStoreBackend().getFingerprint(userDevice, contactsDevice);
|
||||
|
|
|
@ -302,20 +302,20 @@ public abstract class OmemoStoreTest<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey
|
|||
}
|
||||
|
||||
@Test
|
||||
public void loadAllRawSessionsReturnsEmptyMapTest() throws IOException {
|
||||
public void loadAllRawSessionsReturnsEmptyMapTest() {
|
||||
HashMap<Integer, T_Sess> sessions = store.loadAllRawSessionsOf(alice, bob.getJid());
|
||||
assertNotNull(sessions);
|
||||
assertEquals(0, sessions.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadNonExistentRawSessionReturnsNullTest() throws IOException {
|
||||
public void loadNonExistentRawSessionReturnsNullTest() {
|
||||
T_Sess session = store.loadRawSession(alice, bob);
|
||||
assertNull(session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadStoreMessageCounterTest() throws IOException {
|
||||
public void loadStoreMessageCounterTest() {
|
||||
assertEquals(0, store.loadOmemoMessageCounter(alice, bob));
|
||||
store.storeOmemoMessageCounter(alice, bob, 20);
|
||||
assertEquals(20, store.loadOmemoMessageCounter(alice, bob));
|
||||
|
|
|
@ -19,7 +19,6 @@ dependencies {
|
|||
compile project(':smack-experimental')
|
||||
compile project(':smack-legacy')
|
||||
compile project(':smack-integration-test')
|
||||
compile project(':smack-omemo-signal')
|
||||
compile "org.scala-lang:scala-library:$scalaVersion"
|
||||
compile "com.lihaoyi:ammonite_$scalaVersion:1.3.2"
|
||||
testCompile project(path: ":smack-core", configuration: "testRuntime")
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
*
|
||||
* Copyright 2019 Florian Schmaus
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
* 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
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* 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.igniterealtime.smack.smackrepl;
|
||||
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
*
|
||||
* Copyright 2016 Florian Schmaus
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
* 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
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* 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.igniterealtime.smack.smackrepl;
|
||||
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
*
|
||||
* Copyright 2018 Florian Schmaus
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
* 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
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* 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.igniterealtime.smack.smackrepl;
|
||||
|
||||
|
|
|
@ -1,218 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2019 Paul Schaub
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.igniterealtime.smack.smackrepl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.SmackException.NotLoggedInException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||
|
||||
import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||
import org.jivesoftware.smackx.omemo.OmemoManager;
|
||||
import org.jivesoftware.smackx.omemo.OmemoMessage;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CannotEstablishOmemoSessionException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.UndecidedOmemoIdentityException;
|
||||
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
|
||||
import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener;
|
||||
import org.jivesoftware.smackx.omemo.listener.OmemoMucMessageListener;
|
||||
import org.jivesoftware.smackx.omemo.signal.SignalCachingOmemoStore;
|
||||
import org.jivesoftware.smackx.omemo.signal.SignalFileBasedOmemoStore;
|
||||
import org.jivesoftware.smackx.omemo.signal.SignalOmemoService;
|
||||
import org.jivesoftware.smackx.omemo.trust.OmemoFingerprint;
|
||||
import org.jivesoftware.smackx.omemo.trust.OmemoTrustCallback;
|
||||
import org.jivesoftware.smackx.omemo.trust.TrustState;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubException;
|
||||
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
|
||||
public class OmemoClient {
|
||||
|
||||
public static final Logger LOGGER = Logger.getLogger(OmemoClient.class.getName());
|
||||
|
||||
private static final Scanner scanner = new Scanner(System.in, "UTF-8");
|
||||
private final XMPPTCPConnection connection;
|
||||
private final OmemoManager omemoManager;
|
||||
|
||||
public static void main(String[] args)
|
||||
throws XMPPException, SmackException, IOException, InterruptedException, CorruptedOmemoKeyException {
|
||||
SmackConfiguration.DEBUG = true;
|
||||
if (args.length != 2) {
|
||||
print("Missing arguments: <jid> <password>");
|
||||
return;
|
||||
}
|
||||
SignalOmemoService.acknowledgeLicense();
|
||||
SignalOmemoService.setup();
|
||||
SignalOmemoService omemoService = (SignalOmemoService) SignalOmemoService.getInstance();
|
||||
Path omemoStoreDirectory = Files.createTempDirectory("omemo-store");
|
||||
omemoService.setOmemoStoreBackend(new SignalCachingOmemoStore(new SignalFileBasedOmemoStore(omemoStoreDirectory.toFile())));
|
||||
|
||||
EntityBareJid jid = JidCreate.entityBareFromOrThrowUnchecked(args[0]);
|
||||
String password = args[1];
|
||||
OmemoClient client = new OmemoClient(jid, password);
|
||||
try {
|
||||
client.start();
|
||||
|
||||
while (true) {
|
||||
String input = scanner.nextLine();
|
||||
if (input.startsWith("/quit")) {
|
||||
break;
|
||||
}
|
||||
if (input.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
client.handleInput(input);
|
||||
}
|
||||
} finally {
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public OmemoClient(EntityBareJid jid, String password) {
|
||||
connection = new XMPPTCPConnection(XMPPTCPConnectionConfiguration.builder()
|
||||
.setXmppAddressAndPassword(jid, password).build());
|
||||
connection.setReplyTimeout(10 * 1000);
|
||||
omemoManager = OmemoManager.getInstanceFor(connection);
|
||||
omemoManager.setTrustCallback(new OmemoTrustCallback() {
|
||||
// In a real app you'd want to persist these decisions
|
||||
private final Map<OmemoFingerprint, TrustState> trustStateMap = new HashMap<>();
|
||||
@Override
|
||||
public TrustState getTrust(OmemoDevice device, OmemoFingerprint fingerprint) {
|
||||
return trustStateMap.get(fingerprint) != null ? trustStateMap.get(fingerprint) : TrustState.undecided;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrust(OmemoDevice device, OmemoFingerprint fingerprint, TrustState state) {
|
||||
trustStateMap.put(fingerprint, state);
|
||||
}
|
||||
});
|
||||
omemoManager.addOmemoMessageListener(new OmemoMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMessageReceived(Stanza s, OmemoMessage.Received m) {
|
||||
print(m.getSenderDevice() + ": " + (m.getBody() != null ? m.getBody() : "<keyTransportMessage>"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoCarbonCopyReceived(CarbonExtension.Direction d, Message cc, Message wm, OmemoMessage.Received m) {
|
||||
onOmemoMessageReceived(cc, m);
|
||||
}
|
||||
});
|
||||
omemoManager.addOmemoMucMessageListener(new OmemoMucMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMucMessageReceived(MultiUserChat muc, Stanza s, OmemoMessage.Received m) {
|
||||
print(s.getFrom() + ":" + m.getSenderDevice().getDeviceId() + ": " + (m.getBody() != null ? m.getBody() : "<keyTransportMessage>"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void start()
|
||||
throws XMPPException, SmackException, IOException, InterruptedException, CorruptedOmemoKeyException {
|
||||
connection.connect().login();
|
||||
omemoManager.initialize();
|
||||
print("Logged in!");
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
public void handleInput(String input)
|
||||
throws NotConnectedException, NotLoggedInException, InterruptedException, IOException {
|
||||
String[] com = input.split(" ", 3);
|
||||
switch (com[0]) {
|
||||
case "/omemo":
|
||||
if (com.length < 3) {
|
||||
print("Usage: /omemo <contact-jid> <message>");
|
||||
return;
|
||||
}
|
||||
|
||||
BareJid recipient = JidCreate.bareFrom(com[1]);
|
||||
String body = com[2];
|
||||
|
||||
try {
|
||||
Message omemoMessage = omemoManager.encrypt(recipient, body).asMessage(recipient);
|
||||
connection.sendStanza(omemoMessage);
|
||||
} catch (UndecidedOmemoIdentityException e) {
|
||||
print("Undecided Identities!\n" + Arrays.toString(e.getUndecidedDevices().toArray()));
|
||||
} catch (CryptoFailedException | SmackException.NoResponseException e) {
|
||||
LOGGER.log(Level.SEVERE, "Unexpected Exception", e);
|
||||
}
|
||||
break;
|
||||
case "/trust":
|
||||
print("Trust");
|
||||
if (com.length != 2) {
|
||||
print("Usage: /trust <contact-jid>");
|
||||
}
|
||||
|
||||
BareJid contact = JidCreate.bareFrom(com[1]);
|
||||
|
||||
HashMap<OmemoDevice, OmemoFingerprint> devices;
|
||||
try {
|
||||
devices = omemoManager.getActiveFingerprints(contact);
|
||||
} catch (CorruptedOmemoKeyException | CannotEstablishOmemoSessionException | SmackException.NoResponseException e) {
|
||||
LOGGER.log(Level.SEVERE, "Unexpected Exception", e);
|
||||
return;
|
||||
}
|
||||
for (OmemoDevice d : devices.keySet()) {
|
||||
print("Trust (1) or distrust (2)?\n" + devices.get(d).blocksOf8Chars());
|
||||
if (Integer.parseInt(scanner.nextLine()) == 1) {
|
||||
omemoManager.trustOmemoIdentity(d, devices.get(d));
|
||||
} else {
|
||||
omemoManager.distrustOmemoIdentity(d, devices.get(d));
|
||||
}
|
||||
}
|
||||
print("Done.");
|
||||
break;
|
||||
case "/purge":
|
||||
try {
|
||||
omemoManager.purgeDeviceList();
|
||||
print("Purged.");
|
||||
} catch (XMPPException.XMPPErrorException | SmackException.NoResponseException | PubSubException.NotALeafNodeException e) {
|
||||
LOGGER.log(Level.SEVERE, "Unexpected Exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void print(String msg) {
|
||||
// CHECKSTYLE:OFF
|
||||
System.out.println(msg);
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
}
|
|
@ -2,21 +2,17 @@
|
|||
*
|
||||
* Copyright 2016 Florian Schmaus
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
* 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
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* 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.igniterealtime.smack.smackrepl;
|
||||
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
*
|
||||
* Copyright 2018 Florian Schmaus
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
* 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
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* 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.igniterealtime.smack.smackrepl;
|
||||
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
*
|
||||
* Copyright 2016 Florian Schmaus
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
* 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
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* 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.igniterealtime.smack.smackrepl;
|
||||
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
*
|
||||
* Copyright 2016 Florian Schmaus
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
* 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
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* 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.igniterealtime.smack.smackrepl;
|
||||
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
*
|
||||
* Copyright 2016 Florian Schmaus
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
* 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
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,21 +2,17 @@
|
|||
*
|
||||
* Copyright 2016 Florian Schmaus
|
||||
*
|
||||
* This file is part of smack-repl.
|
||||
* 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
|
||||
*
|
||||
* smack-repl is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* 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.igniterealtime.smack.smackrepl;
|
||||
|
||||
|
|
Loading…
Reference in a new issue