OMEMO: remove omemo device from own list if bundle is broken
This commit is contained in:
parent
9706c7e953
commit
c8a0bf7090
|
@ -83,6 +83,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
private int numPublishTriesOnEmptyPep = 0;
|
private int numPublishTriesOnEmptyPep = 0;
|
||||||
private boolean pepBroken = false;
|
private boolean pepBroken = false;
|
||||||
private int lastDeviceListNotificationHash = 0;
|
private int lastDeviceListNotificationHash = 0;
|
||||||
|
private final HashSet<Integer> cleanedOwnDeviceIds = new HashSet<>();
|
||||||
private Set<XmppAxolotlSession> postponedSessions = new HashSet<>(); //sessions stored here will receive after mam catchup treatment
|
private Set<XmppAxolotlSession> postponedSessions = new HashSet<>(); //sessions stored here will receive after mam catchup treatment
|
||||||
|
|
||||||
private AtomicBoolean changeAccessMode = new AtomicBoolean(false);
|
private AtomicBoolean changeAccessMode = new AtomicBoolean(false);
|
||||||
|
@ -503,7 +504,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
axolotlStore.setFingerprintStatus(fp, fingerprintStatus.toUntrusted());
|
axolotlStore.setFingerprintStatus(fp, fingerprintStatus.toUntrusted());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publishOwnDeviceIdIfNeeded() {
|
private void publishOwnDeviceIdIfNeeded() {
|
||||||
if (pepBroken) {
|
if (pepBroken) {
|
||||||
Log.d(Config.LOGTAG, getLogprefix(account) + "publishOwnDeviceIdIfNeeded called, but PEP is broken. Ignoring... ");
|
Log.d(Config.LOGTAG, getLogprefix(account) + "publishOwnDeviceIdIfNeeded called, but PEP is broken. Ignoring... ");
|
||||||
return;
|
return;
|
||||||
|
@ -545,7 +546,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publishOwnDeviceId(Set<Integer> deviceIds) {
|
private void publishOwnDeviceId(Set<Integer> deviceIds) {
|
||||||
Set<Integer> deviceIdsCopy = new HashSet<>(deviceIds);
|
Set<Integer> deviceIdsCopy = new HashSet<>(deviceIds);
|
||||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "publishing own device ids");
|
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "publishing own device ids");
|
||||||
if (deviceIdsCopy.isEmpty()) {
|
if (deviceIdsCopy.isEmpty()) {
|
||||||
|
@ -1062,76 +1063,84 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
throw new AssertionError("We should NEVER build a session with ourselves. What happened here?!");
|
throw new AssertionError("We should NEVER build a session with ourselves. What happened here?!");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
final Jid jid = Jid.of(address.getName());
|
||||||
IqPacket bundlesPacket = mXmppConnectionService.getIqGenerator().retrieveBundlesForDevice(
|
final boolean oneOfOurs = jid.asBareJid().equals(account.getJid().asBareJid());
|
||||||
Jid.of(address.getName()), address.getDeviceId());
|
IqPacket bundlesPacket = mXmppConnectionService.getIqGenerator().retrieveBundlesForDevice(jid, address.getDeviceId());
|
||||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Retrieving bundle: " + bundlesPacket);
|
mXmppConnectionService.sendIqPacket(account, bundlesPacket, (account, packet) -> {
|
||||||
mXmppConnectionService.sendIqPacket(account, bundlesPacket, new OnIqPacketReceived() {
|
if (packet.getType() == IqPacket.TYPE.TIMEOUT) {
|
||||||
|
fetchStatusMap.put(address, FetchStatus.TIMEOUT);
|
||||||
|
} else if (packet.getType() == IqPacket.TYPE.RESULT) {
|
||||||
|
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Received preKey IQ packet, processing...");
|
||||||
|
final IqParser parser = mXmppConnectionService.getIqParser();
|
||||||
|
final List<PreKeyBundle> preKeyBundleList = parser.preKeys(packet);
|
||||||
|
final PreKeyBundle bundle = parser.bundle(packet);
|
||||||
|
if (preKeyBundleList.isEmpty() || bundle == null) {
|
||||||
|
Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "preKey IQ packet invalid: " + packet);
|
||||||
|
fetchStatusMap.put(address, FetchStatus.ERROR);
|
||||||
|
finishBuildingSessionsFromPEP(address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Random random = new Random();
|
||||||
|
final PreKeyBundle preKey = preKeyBundleList.get(random.nextInt(preKeyBundleList.size()));
|
||||||
|
if (preKey == null) {
|
||||||
|
//should never happen
|
||||||
|
fetchStatusMap.put(address, FetchStatus.ERROR);
|
||||||
|
finishBuildingSessionsFromPEP(address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
final PreKeyBundle preKeyBundle = new PreKeyBundle(0, address.getDeviceId(),
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
preKey.getPreKeyId(), preKey.getPreKey(),
|
||||||
if (packet.getType() == IqPacket.TYPE.TIMEOUT) {
|
bundle.getSignedPreKeyId(), bundle.getSignedPreKey(),
|
||||||
fetchStatusMap.put(address, FetchStatus.TIMEOUT);
|
bundle.getSignedPreKeySignature(), bundle.getIdentityKey());
|
||||||
} else if (packet.getType() == IqPacket.TYPE.RESULT) {
|
|
||||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Received preKey IQ packet, processing...");
|
|
||||||
final IqParser parser = mXmppConnectionService.getIqParser();
|
|
||||||
final List<PreKeyBundle> preKeyBundleList = parser.preKeys(packet);
|
|
||||||
final PreKeyBundle bundle = parser.bundle(packet);
|
|
||||||
if (preKeyBundleList.isEmpty() || bundle == null) {
|
|
||||||
Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "preKey IQ packet invalid: " + packet);
|
|
||||||
fetchStatusMap.put(address, FetchStatus.ERROR);
|
|
||||||
finishBuildingSessionsFromPEP(address);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Random random = new Random();
|
|
||||||
final PreKeyBundle preKey = preKeyBundleList.get(random.nextInt(preKeyBundleList.size()));
|
|
||||||
if (preKey == null) {
|
|
||||||
//should never happen
|
|
||||||
fetchStatusMap.put(address, FetchStatus.ERROR);
|
|
||||||
finishBuildingSessionsFromPEP(address);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final PreKeyBundle preKeyBundle = new PreKeyBundle(0, address.getDeviceId(),
|
try {
|
||||||
preKey.getPreKeyId(), preKey.getPreKey(),
|
SessionBuilder builder = new SessionBuilder(axolotlStore, address);
|
||||||
bundle.getSignedPreKeyId(), bundle.getSignedPreKey(),
|
builder.process(preKeyBundle);
|
||||||
bundle.getSignedPreKeySignature(), bundle.getIdentityKey());
|
XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, bundle.getIdentityKey());
|
||||||
|
sessions.put(address, session);
|
||||||
try {
|
if (Config.X509_VERIFICATION) {
|
||||||
SessionBuilder builder = new SessionBuilder(axolotlStore, address);
|
verifySessionWithPEP(session);
|
||||||
builder.process(preKeyBundle);
|
|
||||||
XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, bundle.getIdentityKey());
|
|
||||||
sessions.put(address, session);
|
|
||||||
if (Config.X509_VERIFICATION) {
|
|
||||||
verifySessionWithPEP(session);
|
|
||||||
} else {
|
|
||||||
FingerprintStatus status = getFingerprintTrust(CryptoHelper.bytesToHex(bundle.getIdentityKey().getPublicKey().serialize()));
|
|
||||||
FetchStatus fetchStatus;
|
|
||||||
if (status != null && status.isVerified()) {
|
|
||||||
fetchStatus = FetchStatus.SUCCESS_VERIFIED;
|
|
||||||
} else if (status != null && status.isTrusted()) {
|
|
||||||
fetchStatus = FetchStatus.SUCCESS_TRUSTED;
|
|
||||||
} else {
|
|
||||||
fetchStatus = FetchStatus.SUCCESS;
|
|
||||||
}
|
|
||||||
fetchStatusMap.put(address, fetchStatus);
|
|
||||||
finishBuildingSessionsFromPEP(address);
|
|
||||||
}
|
|
||||||
} catch (UntrustedIdentityException | InvalidKeyException e) {
|
|
||||||
Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Error building session for " + address + ": "
|
|
||||||
+ e.getClass().getName() + ", " + e.getMessage());
|
|
||||||
fetchStatusMap.put(address, FetchStatus.ERROR);
|
|
||||||
finishBuildingSessionsFromPEP(address);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fetchStatusMap.put(address, FetchStatus.ERROR);
|
FingerprintStatus status = getFingerprintTrust(CryptoHelper.bytesToHex(bundle.getIdentityKey().getPublicKey().serialize()));
|
||||||
Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while building session:" + packet.findChild("error"));
|
FetchStatus fetchStatus;
|
||||||
|
if (status != null && status.isVerified()) {
|
||||||
|
fetchStatus = FetchStatus.SUCCESS_VERIFIED;
|
||||||
|
} else if (status != null && status.isTrusted()) {
|
||||||
|
fetchStatus = FetchStatus.SUCCESS_TRUSTED;
|
||||||
|
} else {
|
||||||
|
fetchStatus = FetchStatus.SUCCESS;
|
||||||
|
}
|
||||||
|
fetchStatusMap.put(address, fetchStatus);
|
||||||
finishBuildingSessionsFromPEP(address);
|
finishBuildingSessionsFromPEP(address);
|
||||||
}
|
}
|
||||||
|
} catch (UntrustedIdentityException | InvalidKeyException e) {
|
||||||
|
Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Error building session for " + address + ": "
|
||||||
|
+ e.getClass().getName() + ", " + e.getMessage());
|
||||||
|
fetchStatusMap.put(address, FetchStatus.ERROR);
|
||||||
|
finishBuildingSessionsFromPEP(address);
|
||||||
|
if (oneOfOurs && cleanedOwnDeviceIds.add(address.getDeviceId())) {
|
||||||
|
removeFromDeviceAnnouncement(address.getDeviceId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
} catch (IllegalArgumentException e) {
|
fetchStatusMap.put(address, FetchStatus.ERROR);
|
||||||
Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Got address with invalid jid: " + address.getName());
|
Element error = packet.findChild("error");
|
||||||
|
boolean itemNotFound = error != null && error.hasChild("item-not-found");
|
||||||
|
Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while building session:" + packet.findChild("error"));
|
||||||
|
finishBuildingSessionsFromPEP(address);
|
||||||
|
if (oneOfOurs && itemNotFound && cleanedOwnDeviceIds.add(address.getDeviceId())) {
|
||||||
|
removeFromDeviceAnnouncement(address.getDeviceId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFromDeviceAnnouncement(Integer id) {
|
||||||
|
HashSet<Integer> temp = new HashSet<>(getOwnDeviceIds());
|
||||||
|
if (temp.remove(id)) {
|
||||||
|
Log.d(Config.LOGTAG,account.getJid().asBareJid()+" remove own device id "+id+" from announcement. devices left:"+temp);
|
||||||
|
publishOwnDeviceId(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue