remove omemo devices from annoucement after 7 days of inactivity

This commit is contained in:
Daniel Gultsch 2016-11-19 21:39:16 +01:00
parent 2614706d39
commit b71aa6d3a4
4 changed files with 69 additions and 22 deletions

View File

@ -78,6 +78,10 @@ public final class Config {
public static final int MAX_DISPLAY_MESSAGE_CHARS = 4096; public static final int MAX_DISPLAY_MESSAGE_CHARS = 4096;
public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
public static final long OMEMO_AUTO_EXPIRY = 7 * MILLISECONDS_IN_DAY;
public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb
public static final boolean DISABLE_HTTP_UPLOAD = false; public static final boolean DISABLE_HTTP_UPLOAD = false;
public static final boolean DISABLE_STRING_PREP = false; // setting to true might increase startup performance public static final boolean DISABLE_STRING_PREP = false; // setting to true might increase startup performance
@ -97,7 +101,6 @@ public final class Config {
public static final boolean PARSE_REAL_JID_FROM_MUC_MAM = false; //dangerous if server doesnt filter public static final boolean PARSE_REAL_JID_FROM_MUC_MAM = false; //dangerous if server doesnt 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 long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2;
public static final int MAM_MAX_MESSAGES = 500; public static final int MAM_MAX_MESSAGES = 500;

View File

@ -29,13 +29,13 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
@ -77,6 +77,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
private int numPublishTriesOnEmptyPep = 0; private int numPublishTriesOnEmptyPep = 0;
private boolean pepBroken = false; private boolean pepBroken = false;
private AtomicBoolean ownPushPending = new AtomicBoolean(false);
@Override @Override
public void onAdvancedStreamFeaturesAvailable(Account account) { public void onAdvancedStreamFeaturesAvailable(Account account) {
if (Config.supportOmemo() if (Config.supportOmemo()
@ -357,23 +359,14 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
} }
public void registerDevices(final Jid jid, @NonNull final Set<Integer> deviceIds) { public void registerDevices(final Jid jid, @NonNull final Set<Integer> deviceIds) {
if (jid.toBareJid().equals(account.getJid().toBareJid())) { boolean me = jid.toBareJid().equals(account.getJid().toBareJid());
if (!deviceIds.isEmpty()) { if (me && ownPushPending.getAndSet(false)) {
Log.d(Config.LOGTAG, getLogprefix(account) + "Received non-empty own device list. Resetting publish attempts and pepBroken status."); Log.d(Config.LOGTAG,account.getJid().toBareJid()+": ignoring own device update because of pending push");
pepBroken = false; return;
numPublishTriesOnEmptyPep = 0;
} }
if (deviceIds.contains(getOwnDeviceId())) { boolean needsPublishing = me && !deviceIds.contains(getOwnDeviceId());
if (me) {
deviceIds.remove(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);
}
}
} }
Set<Integer> expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toPreppedString())); Set<Integer> expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toPreppedString()));
expiredDevices.removeAll(deviceIds); expiredDevices.removeAll(deviceIds);
@ -392,10 +385,25 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
XmppAxolotlSession session = sessions.get(address); XmppAxolotlSession session = sessions.get(address);
if (session != null && session.getFingerprint() != null) { if (session != null && session.getFingerprint() != null) {
if (!session.getTrust().isActive()) { if (!session.getTrust().isActive()) {
Log.d(Config.LOGTAG,"reactivating device with fingprint "+session.getFingerprint());
session.setTrust(session.getTrust().toActive()); 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); this.deviceIds.put(jid, deviceIds);
mXmppConnectionService.keyStatusUpdated(null); mXmppConnectionService.keyStatusUpdated(null);
} }
@ -430,14 +438,30 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
} else { } else {
Element item = mXmppConnectionService.getIqParser().getItem(packet); Element item = mXmppConnectionService.getIqParser().getItem(packet);
Set<Integer> deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); Set<Integer> deviceIds = mXmppConnectionService.getIqParser().deviceIds(item);
if (!deviceIds.contains(getOwnDeviceId())) { registerDevices(account.getJid().toBareJid(),deviceIds);
publishOwnDeviceId(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) { public void publishOwnDeviceId(Set<Integer> deviceIds) {
Set<Integer> deviceIdsCopy = new HashSet<>(deviceIds); Set<Integer> deviceIdsCopy = new HashSet<>(deviceIds);
if (!deviceIdsCopy.contains(getOwnDeviceId())) { if (!deviceIdsCopy.contains(getOwnDeviceId())) {
@ -456,9 +480,11 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
} }
deviceIdsCopy.add(getOwnDeviceId()); deviceIdsCopy.add(getOwnDeviceId());
IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(deviceIdsCopy); IqPacket publish = mXmppConnectionService.getIqGenerator().publishDeviceIds(deviceIdsCopy);
ownPushPending.set(true);
mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() { mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() {
@Override @Override
public void onIqPacketReceived(Account account, IqPacket packet) { public void onIqPacketReceived(Account account, IqPacket packet) {
ownPushPending.set(false);
if (packet.getType() == IqPacket.TYPE.ERROR) { if (packet.getType() == IqPacket.TYPE.ERROR) {
pepBroken = true; pepBroken = true;
Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing own device id" + packet.findChild("error")); Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing own device id" + packet.findChild("error"));

View File

@ -156,6 +156,10 @@ public class FingerprintStatus implements Comparable<FingerprintStatus> {
} }
} }
public long getLastActivation() {
return lastActivation;
}
public enum Trust { public enum Trust {
COMPROMISED, COMPROMISED,
UNDECIDED, UNDECIDED,

View File

@ -787,6 +787,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) { public Pair<Long,String> getLastClearDate(Account account) {
SQLiteDatabase db = this.getReadableDatabase(); SQLiteDatabase db = this.getReadableDatabase();
String[] columns = {Conversation.ATTRIBUTES}; String[] columns = {Conversation.ATTRIBUTES};