aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2017-08-01 13:19:11 +0200
committerChristian Schneppe <christian@pix-art.de>2017-08-01 13:19:11 +0200
commitd7bc205420bc07578aee49087b3988429e22372b (patch)
tree990bd1205488b516c9c7862f7c617866d541daae /src/main/java/de/pixart/messenger
parent7e0d6f846030ce6632e0071bfa0a9301a2ff778d (diff)
use publish-options instead of always pushing node configuration
Diffstat (limited to 'src/main/java/de/pixart/messenger')
-rw-r--r--src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java86
-rw-r--r--src/main/java/de/pixart/messenger/generator/IqGenerator.java18
-rw-r--r--src/main/java/de/pixart/messenger/utils/Namespace.java2
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/XmppConnection.java7
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/forms/Data.java16
5 files changed, 93 insertions, 36 deletions
diff --git a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
index 340f050c5..5dc37e4c9 100644
--- a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
+++ b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
@@ -46,6 +46,7 @@ import de.pixart.messenger.entities.Message;
import de.pixart.messenger.parser.IqParser;
import de.pixart.messenger.services.XmppConnectionService;
import de.pixart.messenger.utils.CryptoHelper;
+import de.pixart.messenger.utils.Namespace;
import de.pixart.messenger.utils.SerialSingleThreadExecutor;
import de.pixart.messenger.xml.Element;
import de.pixart.messenger.xmpp.OnAdvancedStreamFeaturesLoaded;
@@ -213,7 +214,6 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
putDevicesForJid(account.getJid().toBareJid().toPreppedString(), deviceIds, store);
for (String address : store.getKnownAddresses()) {
deviceIds = store.getSubDeviceSessions(address);
- Log.d(Config.LOGTAG, account.getJid().toBareJid() + " adding device ids for " + address + " " + deviceIds);
putDevicesForJid(address, deviceIds, store);
}
@@ -434,16 +434,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
}
Set<Integer> deviceIds = new HashSet<>();
deviceIds.add(getOwnDeviceId());
- IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(deviceIds);
- Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Wiping all other devices from Pep:" + publish);
- mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- if (packet.getType() == IqPacket.TYPE.RESULT) {
- mXmppConnectionService.pushNodeConfiguration(account, AxolotlService.PEP_DEVICE_LIST, PublishOptions.openAccess(), null);
- }
- }
- });
+ publishDeviceIdsAndRefineAccessModel(deviceIds);
}
public void distrustFingerprint(final String fingerprint) {
@@ -510,17 +501,40 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
numPublishTriesOnEmptyPep = 0;
}
deviceIdsCopy.add(getOwnDeviceId());
- IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(deviceIdsCopy);
+ publishDeviceIdsAndRefineAccessModel(deviceIdsCopy);
+ }
+
+ private void publishDeviceIdsAndRefineAccessModel(Set<Integer> ids) {
+ publishDeviceIdsAndRefineAccessModel(ids, true);
+ }
+
+ private void publishDeviceIdsAndRefineAccessModel(final Set<Integer> ids, final boolean firstAttempt) {
+ final Bundle publishOptions = account.getXmppConnection().getFeatures().pepPublishOptions() ? PublishOptions.openAccess() : null;
+ IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(ids, publishOptions);
ownPushPending.set(true);
mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
- ownPushPending.set(false);
- if (packet.getType() == IqPacket.TYPE.ERROR) {
- pepBroken = true;
- Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing own device id" + packet.findChild("error"));
- } else if (packet.getType() != IqPacket.TYPE.TIMEOUT) {
- mXmppConnectionService.pushNodeConfiguration(account, AxolotlService.PEP_DEVICE_LIST, PublishOptions.openAccess(), null);
+ Element error = packet.getType() == IqPacket.TYPE.ERROR ? packet.findChild("error") : null;
+ if (firstAttempt && error != null && error.hasChild("precondition-not-met", Namespace.PUBSUB_ERROR)) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": precondition wasn't met for device list. pushing node configuration");
+ mXmppConnectionService.pushNodeConfiguration(account, AxolotlService.PEP_DEVICE_LIST, publishOptions, new XmppConnectionService.OnConfigurationPushed() {
+ @Override
+ public void onPushSucceeded() {
+ publishDeviceIdsAndRefineAccessModel(ids, false);
+ }
+
+ @Override
+ public void onPushFailed() {
+ publishDeviceIdsAndRefineAccessModel(ids, false);
+ }
+ });
+ } else {
+ ownPushPending.set(false);
+ if (packet.getType() == IqPacket.TYPE.ERROR) {
+ pepBroken = true;
+ Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing own device id" + packet.findChild("error"));
+ }
}
}
});
@@ -680,32 +694,46 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
Set<PreKeyRecord> preKeyRecords,
final boolean announceAfter,
final boolean wipe) {
+ publishDeviceBundle(signedPreKeyRecord, preKeyRecords, announceAfter, wipe, true);
+ }
+
+ private void publishDeviceBundle(final SignedPreKeyRecord signedPreKeyRecord,
+ final Set<PreKeyRecord> preKeyRecords,
+ final boolean announceAfter,
+ final boolean wipe,
+ final boolean firstAttempt) {
+ final Bundle publishOptions = account.getXmppConnection().getFeatures().pepPublishOptions() ? PublishOptions.openAccess() : null;
IqPacket publish = mXmppConnectionService.getIqGenerator().publishBundles(
signedPreKeyRecord, axolotlStore.getIdentityKeyPair().getPublicKey(),
- preKeyRecords, getOwnDeviceId());
+ preKeyRecords, getOwnDeviceId(), publishOptions);
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": Bundle " + getOwnDeviceId() + " in PEP not current. Publishing...");
mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(final Account account, IqPacket packet) {
- if (packet.getType() == IqPacket.TYPE.RESULT) {
+ Element error = packet.getType() == IqPacket.TYPE.ERROR ? packet.findChild("error") : null;
+ if (firstAttempt && error != null && error.hasChild("precondition-not-met", Namespace.PUBSUB_ERROR)) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": precondition wasn't met for bundle. pushing node configuration");
final String node = AxolotlService.PEP_BUNDLES + ":" + getOwnDeviceId();
- mXmppConnectionService.pushNodeConfiguration(account, node, PublishOptions.openAccess(), new XmppConnectionService.OnConfigurationPushed() {
+ mXmppConnectionService.pushNodeConfiguration(account, node, publishOptions, new XmppConnectionService.OnConfigurationPushed() {
@Override
public void onPushSucceeded() {
- Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Successfully published bundle. ");
- if (wipe) {
- wipeOtherPepDevices();
- } else if (announceAfter) {
- Log.d(Config.LOGTAG, getLogprefix(account) + "Announcing device " + getOwnDeviceId());
- publishOwnDeviceIdIfNeeded();
- }
+ publishDeviceBundle(signedPreKeyRecord, preKeyRecords, announceAfter, wipe, false);
}
@Override
public void onPushFailed() {
- Log.d(Config.LOGTAG, "unable to change access model for pubsub node");
+ publishDeviceBundle(signedPreKeyRecord, preKeyRecords, announceAfter, wipe, false);
}
});
+ }
+ if (packet.getType() == IqPacket.TYPE.RESULT) {
+ Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Successfully published bundle. ");
+ if (wipe) {
+ wipeOtherPepDevices();
+ } else if (announceAfter) {
+ Log.d(Config.LOGTAG, getLogprefix(account) + "Announcing device " + getOwnDeviceId());
+ publishOwnDeviceIdIfNeeded();
+ }
} else if (packet.getType() == IqPacket.TYPE.ERROR) {
pepBroken = true;
Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing bundle: " + packet.findChild("error"));
diff --git a/src/main/java/de/pixart/messenger/generator/IqGenerator.java b/src/main/java/de/pixart/messenger/generator/IqGenerator.java
index 2e6d53402..f1c59e1c4 100644
--- a/src/main/java/de/pixart/messenger/generator/IqGenerator.java
+++ b/src/main/java/de/pixart/messenger/generator/IqGenerator.java
@@ -91,16 +91,24 @@ public class IqGenerator extends AbstractGenerator {
return packet;
}
- protected IqPacket publish(final String node, final Element item) {
+ protected IqPacket publish(final String node, final Element item, final Bundle options) {
final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
final Element pubsub = packet.addChild("pubsub",
"http://jabber.org/protocol/pubsub");
final Element publish = pubsub.addChild("publish");
publish.setAttribute("node", node);
publish.addChild(item);
+ if (options != null) {
+ final Element publishOptions = pubsub.addChild("publish-options");
+ publishOptions.addChild(Data.create(Namespace.PUBSUB_PUBLISH_OPTIONS, options));
+ }
return packet;
}
+ protected IqPacket publish(final String node, final Element item) {
+ return publish(node, item, null);
+ }
+
protected IqPacket retrieve(String node, Element item) {
final IqPacket packet = new IqPacket(IqPacket.TYPE.GET);
final Element pubsub = packet.addChild("pubsub",
@@ -184,7 +192,7 @@ public class IqGenerator extends AbstractGenerator {
return packet;
}
- public IqPacket publishDeviceIds(final Set<Integer> ids) {
+ public IqPacket publishDeviceIds(final Set<Integer> ids, final Bundle publishOptions) {
final Element item = new Element("item");
final Element list = item.addChild("list", AxolotlService.PEP_PREFIX);
for (Integer id : ids) {
@@ -192,11 +200,11 @@ public class IqGenerator extends AbstractGenerator {
device.setAttribute("id", id);
list.addChild(device);
}
- return publish(AxolotlService.PEP_DEVICE_LIST, item);
+ return publish(AxolotlService.PEP_DEVICE_LIST, item, publishOptions);
}
public IqPacket publishBundles(final SignedPreKeyRecord signedPreKeyRecord, final IdentityKey identityKey,
- final Set<PreKeyRecord> preKeyRecords, final int deviceId) {
+ final Set<PreKeyRecord> preKeyRecords, final int deviceId, Bundle publishOptions) {
final Element item = new Element("item");
final Element bundle = item.addChild("bundle", AxolotlService.PEP_PREFIX);
final Element signedPreKeyPublic = bundle.addChild("signedPreKeyPublic");
@@ -215,7 +223,7 @@ public class IqGenerator extends AbstractGenerator {
prekey.setContent(Base64.encodeToString(preKeyRecord.getKeyPair().getPublicKey().serialize(), Base64.DEFAULT));
}
- return publish(AxolotlService.PEP_BUNDLES + ":" + deviceId, item);
+ return publish(AxolotlService.PEP_BUNDLES + ":" + deviceId, item, publishOptions);
}
public IqPacket publishVerification(byte[] signature, X509Certificate[] certificates, final int deviceId) {
diff --git a/src/main/java/de/pixart/messenger/utils/Namespace.java b/src/main/java/de/pixart/messenger/utils/Namespace.java
index 25470d66b..1cf4d5c74 100644
--- a/src/main/java/de/pixart/messenger/utils/Namespace.java
+++ b/src/main/java/de/pixart/messenger/utils/Namespace.java
@@ -13,4 +13,6 @@ public final class Namespace {
public static final String OOB = "jabber:x:oob";
public static final String SASL = "urn:ietf:params:xml:ns:xmpp-sasl";
public static final String TLS = "urn:ietf:params:xml:ns:xmpp-tls";
+ public static final String PUBSUB_PUBLISH_OPTIONS = "http://jabber.org/protocol/pubsub#publish-options";
+ public static final String PUBSUB_ERROR = "http://jabber.org/protocol/pubsub#errors";
}
diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
index 67cb15658..1976bdc4a 100644
--- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
+++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
@@ -1701,6 +1701,13 @@ public class XmppConnection implements Runnable {
}
}
+ public boolean pepPublishOptions() {
+ synchronized (XmppConnection.this.disco) {
+ ServiceDiscoveryResult info = disco.get(account.getJid().toBareJid());
+ return info != null && info.getFeatures().contains(Namespace.PUBSUB_PUBLISH_OPTIONS);
+ }
+ }
+
public boolean mam() {
return hasDiscoFeature(account.getJid().toBareJid(), Namespace.MAM)
|| hasDiscoFeature(account.getJid().toBareJid(), Namespace.MAM_LEGACY);
diff --git a/src/main/java/de/pixart/messenger/xmpp/forms/Data.java b/src/main/java/de/pixart/messenger/xmpp/forms/Data.java
index c2653a5e9..ed426f397 100644
--- a/src/main/java/de/pixart/messenger/xmpp/forms/Data.java
+++ b/src/main/java/de/pixart/messenger/xmpp/forms/Data.java
@@ -39,13 +39,14 @@ public class Data extends Element {
return null;
}
- public void put(String name, String value) {
+ public Field put(String name, String value) {
Field field = getFieldByName(name);
if (field == null) {
field = new Field(name);
this.addChild(field);
}
field.setValue(value);
+ return field;
}
public void put(String name, Collection<String> values) {
@@ -91,7 +92,8 @@ public class Data extends Element {
}
public void setFormType(String formType) {
- this.put(FORM_TYPE, formType);
+ Field field = this.put(FORM_TYPE, formType);
+ field.setAttribute("type", "hidden");
}
public String getFormType() {
@@ -107,4 +109,14 @@ public class Data extends Element {
public String getTitle() {
return findChildContent("title");
}
+
+ public static Data create(String type, Bundle bundle) {
+ Data data = new Data();
+ data.setFormType(type);
+ data.setAttribute("type", "submit");
+ for (String key : bundle.keySet()) {
+ data.put(key, bundle.getString(key));
+ }
+ return data;
+ }
}