From da87eac48e814c245d4a3d2ba8e7a59c0c7147c4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 12 Jul 2017 22:16:31 +0200 Subject: [PATCH] provide upgrade path for accounts with publish-options --- .../crypto/axolotl/AxolotlService.java | 15 +++++++++++++-- .../eu/siacs/conversations/entities/Account.java | 1 + .../persistance/DatabaseBackend.java | 10 +++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 564e8cc2..412214b3 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -82,6 +82,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { private boolean pepBroken = false; private AtomicBoolean ownPushPending = new AtomicBoolean(false); + private AtomicBoolean changeAccessMode = new AtomicBoolean(false); @Override public void onAdvancedStreamFeaturesAvailable(Account account) { @@ -411,6 +412,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { if (Config.OMEMO_AUTO_EXPIRY != 0) { needsPublishing |= deviceIds.removeAll(getExpiredDevices()); } + needsPublishing |= this.changeAccessMode.get(); for (Integer deviceId : deviceIds) { SignalProtocolAddress ownDeviceAddress = new SignalProtocolAddress(jid.toBareJid().toPreppedString(), deviceId); if (sessions.get(ownDeviceAddress) == null) { @@ -533,6 +535,11 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } }); } else { + if (AxolotlService.this.changeAccessMode.compareAndSet(true,false)) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": done changing access mode"); + account.setOption(Account.OPTION_REQURIES_ACCESS_MODE_CHANGE,false); + mXmppConnectionService.databaseBackend.updateAccount(account); + } ownPushPending.set(false); if (packet.getType() == IqPacket.TYPE.ERROR) { pepBroken = true; @@ -586,6 +593,10 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { Log.d(Config.LOGTAG, getLogprefix(account) + "publishBundlesIfNeeded called, but PEP is broken. Ignoring... "); return; } + this.changeAccessMode.set(account.isOptionSet(Account.OPTION_REQURIES_ACCESS_MODE_CHANGE) && account.getXmppConnection().getFeatures().pepPublishOptions()); + if (this.changeAccessMode.get()) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server gained publish-options capabilities. changing access model"); + } IqPacket packet = mXmppConnectionService.getIqGenerator().retrieveBundlesForDevice(account.getJid().toBareJid(), getOwnDeviceId()); mXmppConnectionService.sendIqPacket(account, packet, new OnIqPacketReceived() { @Override @@ -670,7 +681,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } - if (changed) { + if (changed || changeAccessMode.get()) { if (account.getPrivateKeyAlias() != null && Config.X509_VERIFICATION) { mXmppConnectionService.publishDisplayName(account); publishDeviceVerificationAndBundle(signedPreKeyRecord, preKeyRecords, announce, wipe); @@ -728,7 +739,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { publishDeviceBundle(signedPreKeyRecord,preKeyRecords, announceAfter, wipe, false); } }); - } if (packet.getType() == IqPacket.TYPE.RESULT) { + } else if (packet.getType() == IqPacket.TYPE.RESULT) { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Successfully published bundle. "); if (wipe) { wipeOtherPepDevices(); diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 8feffae2..c5c7762a 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -57,6 +57,7 @@ public class Account extends AbstractEntity { public static final int OPTION_REGISTER = 2; public static final int OPTION_USECOMPRESSION = 3; public static final int OPTION_MAGIC_CREATE = 4; + public static final int OPTION_REQURIES_ACCESS_MODE_CHANGE = 5; public final HashSet> inProgressDiscoFetches = new HashSet<>(); public boolean httpUploadAvailable(long filesize) { diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index a42166e3..483d6291 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -61,7 +61,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 35; + private static final int DATABASE_VERSION = 36; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -446,6 +446,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (oldVersion < 35 && newVersion >= 35) { db.execSQL(CREATE_MESSAGE_CONVERSATION_INDEX); } + if (oldVersion < 36 && newVersion >= 36) { + List accounts = getAccounts(db); + for (Account account : accounts) { + account.setOption(Account.OPTION_REQURIES_ACCESS_MODE_CHANGE,true); + db.update(Account.TABLENAME, account.getContentValues(), Account.UUID + + "=?", new String[]{account.getUuid()}); + } + } } private static ContentValues createFingerprintStatusContentValues(FingerprintStatus.Trust trust, boolean active) {