mirror of
https://github.com/moparisthebest/Conversations
synced 2024-11-28 11:42:15 -05:00
Add INACTIVE state for removed keys
We introduce a new trust state: INACTIVE. This state is intended for old keys that have been removed. When a TRUSTED device is removed from the PEP devicelist, it's status will be set to INACTIVE. INACTIVE keys are shown in the UI as greyed out, non-interactible key rows. Messages are not encrypted for INACTIVE devices. When an INACTIVE device reappears in PEP, or a message is received from an INACTIVE device, it is set back to trusted.
This commit is contained in:
parent
3c5c0c7d3b
commit
92b5081b5e
@ -102,7 +102,8 @@ public class AxolotlService {
|
||||
UNDECIDED(0),
|
||||
TRUSTED(1),
|
||||
UNTRUSTED(2),
|
||||
COMPROMISED(3);
|
||||
COMPROMISED(3),
|
||||
INACTIVE(4);
|
||||
|
||||
private static final Map<Integer, Trust> trustsByValue = new HashMap<>();
|
||||
|
||||
@ -125,12 +126,16 @@ public class AxolotlService {
|
||||
public String toString() {
|
||||
switch(this){
|
||||
case UNDECIDED:
|
||||
return "Trust undecided";
|
||||
return "Trust undecided "+getCode();
|
||||
case TRUSTED:
|
||||
return "Trusted";
|
||||
return "Trusted "+getCode();
|
||||
case COMPROMISED:
|
||||
return "Compromised "+getCode();
|
||||
case INACTIVE:
|
||||
return "Inactive "+getCode();
|
||||
case UNTRUSTED:
|
||||
default:
|
||||
return "Untrusted";
|
||||
return "Untrusted "+getCode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -538,14 +543,20 @@ public class AxolotlService {
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
private SQLiteAxolotlStore.Trust getTrust() {
|
||||
protected void setTrust(SQLiteAxolotlStore.Trust trust) {
|
||||
sqLiteAxolotlStore.setFingerprintTrust(fingerprint, trust);
|
||||
}
|
||||
|
||||
protected SQLiteAxolotlStore.Trust getTrust() {
|
||||
return sqLiteAxolotlStore.getFingerprintTrust(fingerprint);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] processReceiving(XmppAxolotlMessage.XmppAxolotlMessageHeader incomingHeader) {
|
||||
byte[] plaintext = null;
|
||||
switch (getTrust()) {
|
||||
SQLiteAxolotlStore.Trust trust = getTrust();
|
||||
switch (trust) {
|
||||
case INACTIVE:
|
||||
case UNDECIDED:
|
||||
case UNTRUSTED:
|
||||
case TRUSTED:
|
||||
@ -574,6 +585,10 @@ public class AxolotlService {
|
||||
Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Error decrypting axolotl header, "+e.getClass().getName()+": " + e.getMessage());
|
||||
}
|
||||
|
||||
if (plaintext != null && trust == SQLiteAxolotlStore.Trust.INACTIVE) {
|
||||
setTrust(SQLiteAxolotlStore.Trust.TRUSTED);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COMPROMISED:
|
||||
@ -774,15 +789,32 @@ public class AxolotlService {
|
||||
return this.deviceIds.get(account.getJid().toBareJid());
|
||||
}
|
||||
|
||||
private void setTrustOnSessions(final Jid jid, @NonNull final Set<Integer> deviceIds,
|
||||
final SQLiteAxolotlStore.Trust from,
|
||||
final SQLiteAxolotlStore.Trust to) {
|
||||
for(Integer deviceId:deviceIds) {
|
||||
AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toString(), deviceId);
|
||||
XmppAxolotlSession session = sessions.get(address);
|
||||
if (session != null && session.getFingerprint() != null
|
||||
&& session.getTrust() == from) {
|
||||
session.setTrust(to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerDevices(final Jid jid, @NonNull final Set<Integer> deviceIds) {
|
||||
if(deviceIds.contains(getOwnDeviceId())) {
|
||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Skipping own Device ID:"+ jid + ":"+getOwnDeviceId());
|
||||
deviceIds.remove(getOwnDeviceId());
|
||||
}
|
||||
for(Integer i:deviceIds) {
|
||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Adding Device ID:"+ jid + ":"+i);
|
||||
}
|
||||
Set<Integer> expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toString()));
|
||||
expiredDevices.removeAll(deviceIds);
|
||||
setTrustOnSessions(jid, expiredDevices, SQLiteAxolotlStore.Trust.TRUSTED,
|
||||
SQLiteAxolotlStore.Trust.INACTIVE);
|
||||
Set<Integer> newDevices = new HashSet<>(deviceIds);
|
||||
setTrustOnSessions(jid, newDevices, SQLiteAxolotlStore.Trust.INACTIVE,
|
||||
SQLiteAxolotlStore.Trust.TRUSTED);
|
||||
this.deviceIds.put(jid, deviceIds);
|
||||
mXmppConnectionService.keyStatusUpdated();
|
||||
publishOwnDeviceIdIfNeeded();
|
||||
}
|
||||
|
||||
@ -957,7 +989,7 @@ public class AxolotlService {
|
||||
}
|
||||
});
|
||||
}
|
||||
mXmppConnectionService.newKeysAvailable();
|
||||
mXmppConnectionService.keyStatusUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ import eu.siacs.conversations.xmpp.OnContactStatusChanged;
|
||||
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
|
||||
import eu.siacs.conversations.xmpp.OnMessageAcknowledged;
|
||||
import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
|
||||
import eu.siacs.conversations.xmpp.OnNewKeysAvailable;
|
||||
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
|
||||
import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
|
||||
import eu.siacs.conversations.xmpp.OnStatusChanged;
|
||||
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||
@ -309,8 +309,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
private int rosterChangedListenerCount = 0;
|
||||
private OnMucRosterUpdate mOnMucRosterUpdate = null;
|
||||
private int mucRosterChangedListenerCount = 0;
|
||||
private OnNewKeysAvailable mOnNewKeysAvailable = null;
|
||||
private int newKeysAvailableListenerCount = 0;
|
||||
private OnKeyStatusUpdated mOnKeyStatusUpdated = null;
|
||||
private int keyStatusUpdatedListenerCount = 0;
|
||||
private SecureRandom mRandom;
|
||||
private OpenPgpServiceConnection pgpServiceConnection;
|
||||
private PgpEngine mPgpEngine = null;
|
||||
@ -1372,30 +1372,31 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnNewKeysAvailableListener(final OnNewKeysAvailable listener) {
|
||||
public void setOnKeyStatusUpdatedListener(final OnKeyStatusUpdated listener) {
|
||||
synchronized (this) {
|
||||
if (checkListeners()) {
|
||||
switchToForeground();
|
||||
}
|
||||
this.mOnNewKeysAvailable = listener;
|
||||
if (this.newKeysAvailableListenerCount < 2) {
|
||||
this.newKeysAvailableListenerCount++;
|
||||
this.mOnKeyStatusUpdated = listener;
|
||||
if (this.keyStatusUpdatedListenerCount < 2) {
|
||||
this.keyStatusUpdatedListenerCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeOnNewKeysAvailableListener() {
|
||||
synchronized (this) {
|
||||
this.newKeysAvailableListenerCount--;
|
||||
if (this.newKeysAvailableListenerCount <= 0) {
|
||||
this.newKeysAvailableListenerCount = 0;
|
||||
this.mOnNewKeysAvailable = null;
|
||||
this.keyStatusUpdatedListenerCount--;
|
||||
if (this.keyStatusUpdatedListenerCount <= 0) {
|
||||
this.keyStatusUpdatedListenerCount = 0;
|
||||
this.mOnKeyStatusUpdated = null;
|
||||
if (checkListeners()) {
|
||||
switchToBackground();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) {
|
||||
synchronized (this) {
|
||||
if (checkListeners()) {
|
||||
@ -1427,7 +1428,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
&& this.mOnRosterUpdate == null
|
||||
&& this.mOnUpdateBlocklist == null
|
||||
&& this.mOnShowErrorToast == null
|
||||
&& this.mOnNewKeysAvailable == null);
|
||||
&& this.mOnKeyStatusUpdated == null);
|
||||
}
|
||||
|
||||
private void switchToForeground() {
|
||||
@ -2316,9 +2317,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||
}
|
||||
}
|
||||
|
||||
public void newKeysAvailable() {
|
||||
if(mOnNewKeysAvailable != null) {
|
||||
mOnNewKeysAvailable.onNewKeysAvailable();
|
||||
public void keyStatusUpdated() {
|
||||
if(mOnKeyStatusUpdated != null) {
|
||||
mOnKeyStatusUpdated.onKeyStatusUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,12 +42,13 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
|
||||
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
|
||||
import eu.siacs.conversations.utils.CryptoHelper;
|
||||
import eu.siacs.conversations.utils.UIHelper;
|
||||
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
|
||||
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||
import eu.siacs.conversations.xmpp.XmppConnection;
|
||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||
|
||||
public class ContactDetailsActivity extends XmppActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist {
|
||||
public class ContactDetailsActivity extends XmppActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist, OnKeyStatusUpdated {
|
||||
public static final String ACTION_VIEW_CONTACT = "view_contact";
|
||||
|
||||
private Contact contact;
|
||||
@ -468,4 +469,9 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||
populateView();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyStatusUpdated() {
|
||||
refreshUi();
|
||||
}
|
||||
}
|
||||
|
@ -35,12 +35,13 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
|
||||
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
|
||||
import eu.siacs.conversations.utils.CryptoHelper;
|
||||
import eu.siacs.conversations.utils.UIHelper;
|
||||
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
|
||||
import eu.siacs.conversations.xmpp.XmppConnection.Features;
|
||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||
import eu.siacs.conversations.xmpp.pep.Avatar;
|
||||
|
||||
public class EditAccountActivity extends XmppActivity implements OnAccountUpdate{
|
||||
public class EditAccountActivity extends XmppActivity implements OnAccountUpdate, OnKeyStatusUpdated {
|
||||
|
||||
private AutoCompleteTextView mAccountJid;
|
||||
private EditText mPassword;
|
||||
@ -618,4 +619,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||
});
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyStatusUpdated() {
|
||||
refreshUi();
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,11 @@ import eu.siacs.conversations.crypto.axolotl.AxolotlService.SQLiteAxolotlStore.T
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Contact;
|
||||
import eu.siacs.conversations.entities.Conversation;
|
||||
import eu.siacs.conversations.xmpp.OnNewKeysAvailable;
|
||||
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
|
||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||
|
||||
public class TrustKeysActivity extends XmppActivity implements OnNewKeysAvailable {
|
||||
public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdated {
|
||||
private Jid accountJid;
|
||||
private Jid contactJid;
|
||||
private boolean hasOtherTrustedKeys = false;
|
||||
@ -215,7 +215,7 @@ public class TrustKeysActivity extends XmppActivity implements OnNewKeysAvailabl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewKeysAvailable() {
|
||||
public void onKeyStatusUpdated() {
|
||||
final Account account = xmppConnectionService.findAccountByJid(accountJid);
|
||||
hasPendingFetches = false;
|
||||
getFingerprints(account);
|
||||
|
@ -83,7 +83,7 @@ import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinde
|
||||
import eu.siacs.conversations.ui.widget.Switch;
|
||||
import eu.siacs.conversations.utils.CryptoHelper;
|
||||
import eu.siacs.conversations.utils.ExceptionHelper;
|
||||
import eu.siacs.conversations.xmpp.OnNewKeysAvailable;
|
||||
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
|
||||
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||
@ -99,6 +99,7 @@ public abstract class XmppActivity extends Activity {
|
||||
|
||||
protected int mPrimaryTextColor;
|
||||
protected int mSecondaryTextColor;
|
||||
protected int mTertiaryTextColor;
|
||||
protected int mPrimaryBackgroundColor;
|
||||
protected int mSecondaryBackgroundColor;
|
||||
protected int mColorRed;
|
||||
@ -294,8 +295,8 @@ public abstract class XmppActivity extends Activity {
|
||||
if (this instanceof XmppConnectionService.OnShowErrorToast) {
|
||||
this.xmppConnectionService.setOnShowErrorToastListener((XmppConnectionService.OnShowErrorToast) this);
|
||||
}
|
||||
if (this instanceof OnNewKeysAvailable) {
|
||||
this.xmppConnectionService.setOnNewKeysAvailableListener((OnNewKeysAvailable) this);
|
||||
if (this instanceof OnKeyStatusUpdated) {
|
||||
this.xmppConnectionService.setOnKeyStatusUpdatedListener((OnKeyStatusUpdated) this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,7 +319,7 @@ public abstract class XmppActivity extends Activity {
|
||||
if (this instanceof XmppConnectionService.OnShowErrorToast) {
|
||||
this.xmppConnectionService.removeOnShowErrorToastListener();
|
||||
}
|
||||
if (this instanceof OnNewKeysAvailable) {
|
||||
if (this instanceof OnKeyStatusUpdated) {
|
||||
this.xmppConnectionService.removeOnNewKeysAvailableListener();
|
||||
}
|
||||
}
|
||||
@ -349,6 +350,7 @@ public abstract class XmppActivity extends Activity {
|
||||
ExceptionHelper.init(getApplicationContext());
|
||||
mPrimaryTextColor = getResources().getColor(R.color.black87);
|
||||
mSecondaryTextColor = getResources().getColor(R.color.black54);
|
||||
mTertiaryTextColor = getResources().getColor(R.color.black12);
|
||||
mColorRed = getResources().getColor(R.color.red500);
|
||||
mColorOrange = getResources().getColor(R.color.orange500);
|
||||
mColorGreen = getResources().getColor(R.color.green500);
|
||||
@ -668,10 +670,20 @@ public abstract class XmppActivity extends Activity {
|
||||
case TRUSTED:
|
||||
trustToggle.setChecked(trust == AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED, false);
|
||||
trustToggle.setEnabled(true);
|
||||
key.setTextColor(getPrimaryTextColor());
|
||||
keyType.setTextColor(getSecondaryTextColor());
|
||||
break;
|
||||
case UNDECIDED:
|
||||
trustToggle.setChecked(false, false);
|
||||
trustToggle.setEnabled(false);
|
||||
key.setTextColor(getPrimaryTextColor());
|
||||
keyType.setTextColor(getSecondaryTextColor());
|
||||
break;
|
||||
case INACTIVE:
|
||||
trustToggle.setChecked(true, false);
|
||||
trustToggle.setEnabled(false);
|
||||
key.setTextColor(getTertiaryTextColor());
|
||||
keyType.setTextColor(getTertiaryTextColor());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -824,6 +836,10 @@ public abstract class XmppActivity extends Activity {
|
||||
}
|
||||
};
|
||||
|
||||
public int getTertiaryTextColor() {
|
||||
return this.mTertiaryTextColor;
|
||||
}
|
||||
|
||||
public int getSecondaryTextColor() {
|
||||
return this.mSecondaryTextColor;
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
package eu.siacs.conversations.xmpp;
|
||||
|
||||
public interface OnKeyStatusUpdated {
|
||||
public void onKeyStatusUpdated();
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package eu.siacs.conversations.xmpp;
|
||||
|
||||
public interface OnNewKeysAvailable {
|
||||
public void onNewKeysAvailable();
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
<color name="accent">#ff0091ea</color>
|
||||
<color name="black87">#de000000</color>
|
||||
<color name="black54">#8a000000</color>
|
||||
<color name="black26">#42000000</color>
|
||||
<color name="black12">#1f000000</color>
|
||||
<color name="white">#ffffffff</color>
|
||||
<color name="white70">#b2ffffff</color>
|
||||
|
Loading…
Reference in New Issue
Block a user