aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2016-11-20 17:42:16 +0100
committerChristian Schneppe <christian@pix-art.de>2016-11-20 17:42:16 +0100
commit1cf0241aed94015f5c5fc523b756cbbd5a797de7 (patch)
treeea70a1e4bc142fb97c52925fbdf6e310a33749e6 /src
parentc284f598a7acd002a92d69b646f4f643878fa0f7 (diff)
remove omemo devices from annoucement after 7 days of inactivity
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/pixart/messenger/Config.java7
-rw-r--r--src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java74
-rw-r--r--src/main/java/de/pixart/messenger/crypto/axolotl/FingerprintStatus.java4
-rw-r--r--src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java14
4 files changed, 72 insertions, 27 deletions
diff --git a/src/main/java/de/pixart/messenger/Config.java b/src/main/java/de/pixart/messenger/Config.java
index f44ab661b..13b3055bb 100644
--- a/src/main/java/de/pixart/messenger/Config.java
+++ b/src/main/java/de/pixart/messenger/Config.java
@@ -6,6 +6,8 @@ import de.pixart.messenger.xmpp.chatstate.ChatState;
public final class Config {
+ public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
+
private static final int UNENCRYPTED = 1;
private static final int OPENPGP = 2;
private static final int OTR = 4;
@@ -79,8 +81,6 @@ public final class Config {
public static final int VIDEO_BITRATE = 500000;
public static final int VIDEO_MAX_SIZE = 10485760; //10 MiB
- public static final int FILE_MAX_SIZE = 1048576; //1 MiB
-
public static final int DEFAULT_ZOOM = 15; //for locations
public static final int MESSAGE_MERGE_WINDOW = 20;
@@ -90,6 +90,8 @@ public final class Config {
public static final int REFRESH_UI_INTERVAL = 1000;
+ public static final long OMEMO_AUTO_EXPIRY = 7 * MILLISECONDS_IN_DAY; // delete old OMEMO devices after 7 days od inactivity
+
public static final int MAX_DISPLAY_MESSAGE_CHARS = 4096;
public static final boolean ExportLogs = true; // automatically export logs
@@ -115,7 +117,6 @@ public final class Config {
public static final boolean PARSE_REAL_JID_FROM_MUC_MAM = false; //dangerous if server doesn’t filter
- public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2;
public static final int MAM_MAX_MESSAGES = 500;
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 8c9b5a7bb..8a38ce20d 100644
--- a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
+++ b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java
@@ -35,6 +35,7 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
import de.pixart.messenger.Config;
import de.pixart.messenger.entities.Account;
@@ -75,6 +76,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
private final SerialSingleThreadExecutor executor;
private int numPublishTriesOnEmptyPep = 0;
private boolean pepBroken = false;
+ private AtomicBoolean ownPushPending = new AtomicBoolean(false);
@Override
public void onAdvancedStreamFeaturesAvailable(Account account) {
@@ -302,15 +304,15 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
public Collection<XmppAxolotlSession> findOwnSessions() {
AxolotlAddress ownAddress = getAddressForJid(account.getJid().toBareJid());
ArrayList<XmppAxolotlSession> s = new ArrayList<>(this.sessions.getAll(ownAddress).values());
- Collections.sort(s);
- return s;
+ Collections.sort(s);
+ return s;
}
public Collection<XmppAxolotlSession> findSessionsForContact(Contact contact) {
AxolotlAddress contactAddress = getAddressForJid(contact.getJid());
ArrayList<XmppAxolotlSession> s = new ArrayList<>(this.sessions.getAll(contactAddress).values());
- Collections.sort(s);
- return s;
+ Collections.sort(s);
+ return s;
}
private Set<XmppAxolotlSession> findSessionsForConversation(Conversation conversation) {
@@ -354,23 +356,14 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
}
public void registerDevices(final Jid jid, @NonNull final Set<Integer> deviceIds) {
- if (jid.toBareJid().equals(account.getJid().toBareJid())) {
- if (!deviceIds.isEmpty()) {
- Log.d(Config.LOGTAG, getLogprefix(account) + "Received non-empty own device list. Resetting publish attempts and pepBroken status.");
- pepBroken = false;
- numPublishTriesOnEmptyPep = 0;
- }
- if (deviceIds.contains(getOwnDeviceId())) {
- deviceIds.remove(getOwnDeviceId());
- } else {
- publishOwnDeviceId(deviceIds);
- }
- for (Integer deviceId : deviceIds) {
- AxolotlAddress ownDeviceAddress = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId);
- if (sessions.get(ownDeviceAddress) == null) {
- buildSessionFromPEP(ownDeviceAddress);
- }
- }
+ boolean me = jid.toBareJid().equals(account.getJid().toBareJid());
+ if (me && ownPushPending.getAndSet(false)) {
+ Log.d(Config.LOGTAG,account.getJid().toBareJid()+": ignoring own device update because of pending push");
+ return;
+ }
+ boolean needsPublishing = me && !deviceIds.contains(getOwnDeviceId());
+ if (me) {
+ deviceIds.remove(getOwnDeviceId());
}
Set<Integer> expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toPreppedString()));
expiredDevices.removeAll(deviceIds);
@@ -389,10 +382,25 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
XmppAxolotlSession session = sessions.get(address);
if (session != null && session.getFingerprint() != null) {
if (!session.getTrust().isActive()) {
+ Log.d(Config.LOGTAG,"reactivating device with fingprint "+session.getFingerprint());
session.setTrust(session.getTrust().toActive());
}
}
}
+ if (me) {
+ if (Config.OMEMO_AUTO_EXPIRY != 0) {
+ needsPublishing |= deviceIds.removeAll(getExpiredDevices());
+ }
+ for (Integer deviceId : deviceIds) {
+ AxolotlAddress ownDeviceAddress = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId);
+ if (sessions.get(ownDeviceAddress) == null) {
+ buildSessionFromPEP(ownDeviceAddress);
+ }
+ }
+ if (needsPublishing) {
+ publishOwnDeviceId(deviceIds);
+ }
+ }
this.deviceIds.put(jid, deviceIds);
mXmppConnectionService.keyStatusUpdated(null);
}
@@ -427,14 +435,30 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
} else {
Element item = mXmppConnectionService.getIqParser().getItem(packet);
Set<Integer> deviceIds = mXmppConnectionService.getIqParser().deviceIds(item);
- if (!deviceIds.contains(getOwnDeviceId())) {
- publishOwnDeviceId(deviceIds);
- }
+ registerDevices(account.getJid().toBareJid(),deviceIds);
}
}
});
}
+ private Set<Integer> getExpiredDevices() {
+ Set<Integer> devices = new HashSet<>();
+ for(XmppAxolotlSession session : findOwnSessions()) {
+ if (session.getTrust().isActive()) {
+ long diff = System.currentTimeMillis() - session.getTrust().getLastActivation();
+ if (diff > Config.OMEMO_AUTO_EXPIRY) {
+ long lastMessageDiff = System.currentTimeMillis() - mXmppConnectionService.databaseBackend.getLastTimeFingerprintUsed(account,session.getFingerprint());
+ if (lastMessageDiff > Config.OMEMO_AUTO_EXPIRY) {
+ devices.add(session.getRemoteAddress().getDeviceId());
+ session.setTrust(session.getTrust().toInactive());
+ Log.d(Config.LOGTAG, "added own device " + session.getFingerprint() + " to list of expired devices. Last message received "+(lastMessageDiff/1000)+"s ago");
+ }
+ }
+ }
+ }
+ return devices;
+ }
+
public void publishOwnDeviceId(Set<Integer> deviceIds) {
Set<Integer> deviceIdsCopy = new HashSet<>(deviceIds);
if (!deviceIdsCopy.contains(getOwnDeviceId())) {
@@ -453,9 +477,11 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
}
deviceIdsCopy.add(getOwnDeviceId());
IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(deviceIdsCopy);
+ 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"));
diff --git a/src/main/java/de/pixart/messenger/crypto/axolotl/FingerprintStatus.java b/src/main/java/de/pixart/messenger/crypto/axolotl/FingerprintStatus.java
index bffb94e1f..0614b759f 100644
--- a/src/main/java/de/pixart/messenger/crypto/axolotl/FingerprintStatus.java
+++ b/src/main/java/de/pixart/messenger/crypto/axolotl/FingerprintStatus.java
@@ -156,6 +156,10 @@ public class FingerprintStatus implements Comparable<FingerprintStatus> {
}
}
+ public long getLastActivation() {
+ return lastActivation;
+ }
+
public enum Trust {
COMPROMISED,
UNDECIDED,
diff --git a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
index 03b71c226..25fb2aeef 100644
--- a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
+++ b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
@@ -786,6 +786,20 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
}
+ public long getLastTimeFingerprintUsed(Account account, String fingerprint) {
+ String SQL = "select messages.timeSent from accounts join conversations on accounts.uuid=conversations.accountUuid join messages on conversations.uuid=messages.conversationUuid where accounts.uuid=? and messages.axolotl_fingerprint=? order by messages.timesent desc limit 1";
+ String[] args = {account.getUuid(), fingerprint};
+ Cursor cursor = getReadableDatabase().rawQuery(SQL,args);
+ long time;
+ if (cursor.moveToFirst()) {
+ time = cursor.getLong(0);
+ } else {
+ time = 0;
+ }
+ cursor.close();
+ return time;
+ }
+
public Pair<Long, String> getLastClearDate(Account account) {
SQLiteDatabase db = this.getReadableDatabase();
String[] columns = {Conversation.ATTRIBUTES};