Skip to content

Commit

Permalink
v2.1.1 (build 236)
Browse files Browse the repository at this point in the history
  • Loading branch information
finiasz committed May 2, 2024
1 parent fbc43e6 commit cb07c92
Show file tree
Hide file tree
Showing 14 changed files with 127 additions and 57 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Build 236 (2.1.1)
2024-05-01

- Hotfix: when sqlcipher migration fails, continue using the old un-encrypted database
- Fix some edge case where one-to-one status could be lost in multi-device

# Build 235 (2.1)
2024-04-25

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public static AuthEncKeyAndChannelInfo unwrapMessageKey(ChannelManagerSession ch
return null;
}
AuthEncKey messageKey = channelManagerSession.encryptionForIdentityDelegate.unwrap(channelManagerSession.session, header.getWrappedKey(), header.getOwnedIdentity());
if (messageKey == null) {
return null;
}
return new AuthEncKeyAndChannelInfo(messageKey, ReceptionChannelInfo.createAsymmetricChannelInfo());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public static Session getSession(String dbPath, String dbKey) throws SQLExceptio

sessionPoolLock.lock();
List<Session> sessionList = sessionPool.get(dbPath);
if ((sessionList == null) || (sessionList.size() == 0)) {
if ((sessionList == null) || (sessionList.isEmpty())) {
sessionPoolLock.unlock();
session = new Session(dbPath, dbKey, false);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ public Engine(File baseDirectory, ObvBackupAndSyncDelegate appBackupAndSyncDeleg

File dbFile = new File(baseDirectory, Constants.ENGINE_DB_FILENAME);
File tmpEncryptedDbFile = new File(baseDirectory, Constants.TMP_ENGINE_ENCRYPTED_DB_FILENAME);
if (tmpEncryptedDbFile.exists()) {
//noinspection ResultOfMethodCallIgnored
tmpEncryptedDbFile.delete();
}

try (Session session = Session.getUpgradeTablesSession(dbPath, null)) {
try (Statement statement = session.createStatement()) {
Expand All @@ -217,8 +221,9 @@ public Engine(File baseDirectory, ObvBackupAndSyncDelegate appBackupAndSyncDeleg
throw new RuntimeException("Engine database encryption error: unable to delete unencrypted database!");
}
} catch (Exception fatal) {
// database is encrypted but not with the provided dbKey!
throw new RuntimeException("Database seems encrypted but cannot be opened with provided dbKey", fatal);
// database is encrypted but not with the provided dbKey, or database encryption failed --> try disabling encryption to use a plain database
Logger.e("Engine database encryption failed, falling back to un-encrypted database");
dbKey = null;
}
}

Expand Down Expand Up @@ -260,7 +265,8 @@ public Engine(File baseDirectory, ObvBackupAndSyncDelegate appBackupAndSyncDeleg


MetaManager metaManager = new MetaManager();
this.createSessionDelegate = () -> Session.getSession(dbPath, dbKey);
String finalDbKey = dbKey;
this.createSessionDelegate = () -> Session.getSession(dbPath, finalDbKey);
metaManager.registerImplementedDelegates(this.createSessionDelegate);
metaManager.registerImplementedDelegates(this);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1653,11 +1653,20 @@ public boolean isIdentityAOneToOneContactOfOwnedIdentity(Session session, Identi
return (contactIdentityObject != null && contactIdentityObject.isOneToOne());
}

@Override
public boolean isIdentityANotOneToOneContactOfOwnedIdentity(Session session, Identity ownedIdentity, Identity contactIdentity) throws SQLException {
ContactIdentity contactIdentityObject = ContactIdentity.get(wrapSession(session), ownedIdentity, contactIdentity);
return (contactIdentityObject != null && contactIdentityObject.isNotOneToOne());
}


// this method always sets to ONE_TO_ONE_STATUS_TRUE or ONE_TO_ONE_STATUS_FALSE, but never leaves in ONE_TO_ONE_STATUS_UNKNOWN
@Override
public void setContactOneToOne(Session session, Identity ownedIdentity, Identity contactIdentity, boolean oneToOne) throws SQLException {
ContactIdentity contactIdentityObject = ContactIdentity.get(wrapSession(session), ownedIdentity, contactIdentity);
// only actually call the setter if the oneToOne is changed
if (contactIdentityObject != null && contactIdentityObject.isOneToOne() != oneToOne) {
// only actually call the setter if the oneToOne is changed (or if contact oneToOne was unknown)
if (contactIdentityObject != null
&& ((oneToOne && !contactIdentityObject.isOneToOne()) || (!oneToOne && !contactIdentityObject.isNotOneToOne()))) {
contactIdentityObject.setOneToOne(oneToOne);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,16 @@ public class ContactIdentity implements ObvDatabase {
static final String REVOKED_AS_COMPROMISED = "revoked_as_compromised";
public boolean forcefullyTrustedByUser;
static final String FORCEFULLY_TRUSTED_BY_USER = "forcefully_trusted_by_user";
private boolean oneToOne;
private int oneToOne;
static final String ONE_TO_ONE = "one_to_one";
private long lastNoDeviceContactDeviceDiscovery;
static final String LAST_NO_DEVICE_CONTACT_DEVICE_DISCOVERY = "last_no_device_contact_device_discovery";


public static final int ONE_TO_ONE_STATUS_FALSE = 0;
public static final int ONE_TO_ONE_STATUS_TRUE = 1;
public static final int ONE_TO_ONE_STATUS_UNKNOWN = 2;

public Identity getContactIdentity() {
return contactIdentity;
}
Expand Down Expand Up @@ -121,7 +126,10 @@ public boolean isActive() {
}

public boolean isOneToOne() {
return oneToOne;
return oneToOne == ONE_TO_ONE_STATUS_TRUE;
}
public boolean isNotOneToOne() {
return oneToOne == ONE_TO_ONE_STATUS_FALSE;
}

public long getLastNoDeviceContactDeviceDiscovery() {
Expand Down Expand Up @@ -338,18 +346,22 @@ public void setCertifiedByOwnKeycloak(boolean certifiedByOwnKeycloak, String las
}
}

// this method always sets to ONE_TO_ONE_STATUS_TRUE or ONE_TO_ONE_STATUS_FALSE, but never leaves in ONE_TO_ONE_STATUS_UNKNOWN
public void setOneToOne(boolean oneToOne) throws SQLException {
try (PreparedStatement statement = identityManagerSession.session.prepareStatement("UPDATE " + TABLE_NAME +
" SET " + ONE_TO_ONE + " = ? " +
" WHERE " + CONTACT_IDENTITY + " = ? " +
" AND " + OWNED_IDENTITY + " = ?;")) {
statement.setBoolean(1, oneToOne);
statement.setInt(1, oneToOne ? ONE_TO_ONE_STATUS_TRUE : ONE_TO_ONE_STATUS_FALSE);
statement.setBytes(2, contactIdentity.getBytes());
statement.setBytes(3, ownedIdentity.getBytes());
statement.executeUpdate();
this.oneToOne = oneToOne;
commitHookBits |= HOOK_BIT_ONE_TO_ONE_CHANGED;
identityManagerSession.session.addSessionCommitListener(this);
// do not notify when changing from unknown to false (normally this setter is not called in that case, but let's make sure!
if (isOneToOne() != oneToOne) {
commitHookBits |= HOOK_BIT_ONE_TO_ONE_CHANGED;
identityManagerSession.session.addSessionCommitListener(this);
}
this.oneToOne = oneToOne ? ONE_TO_ONE_STATUS_TRUE : ONE_TO_ONE_STATUS_FALSE;
}
}

Expand Down Expand Up @@ -577,8 +589,8 @@ public static ContactIdentity create(IdentityManagerSession identityManagerSessi
throw new SQLException();
}


ContactIdentity contactIdentityObject = new ContactIdentity(identityManagerSession, contactIdentity, ownedIdentity, contactIdentityDetails.getVersion(), new TrustLevel(0, 0), oneToOne);
// when creating a not one-to-one contact, set their one-to-one status as unknown
ContactIdentity contactIdentityObject = new ContactIdentity(identityManagerSession, contactIdentity, ownedIdentity, contactIdentityDetails.getVersion(), new TrustLevel(0, 0), oneToOne ? ONE_TO_ONE_STATUS_TRUE : ONE_TO_ONE_STATUS_UNKNOWN);
contactIdentityObject.revokedAsCompromised = revokedAsCompromised;
contactIdentityObject.insert();

Expand Down Expand Up @@ -609,7 +621,7 @@ public static ContactIdentity create(IdentityManagerSession identityManagerSessi
}
}

public ContactIdentity(IdentityManagerSession identityManagerSession, Identity contactIdentity, Identity ownedIdentity, int version, TrustLevel trustLevel, boolean oneToOne) {
public ContactIdentity(IdentityManagerSession identityManagerSession, Identity contactIdentity, Identity ownedIdentity, int version, TrustLevel trustLevel, int oneToOne) {
this.identityManagerSession = identityManagerSession;
this.contactIdentity = contactIdentity;
this.ownedIdentity = ownedIdentity;
Expand Down Expand Up @@ -637,7 +649,7 @@ private ContactIdentity(IdentityManagerSession identityManagerSession, ResultSet
this.certifiedByOwnKeycloak = res.getBoolean(CERTIFIED_BY_OWN_KEYCLOAK);
this.revokedAsCompromised = res.getBoolean(REVOKED_AS_COMPROMISED);
this.forcefullyTrustedByUser = res.getBoolean(FORCEFULLY_TRUSTED_BY_USER);
this.oneToOne = res.getBoolean(ONE_TO_ONE);
this.oneToOne = res.getInt(ONE_TO_ONE);
this.lastNoDeviceContactDeviceDiscovery = res.getLong(LAST_NO_DEVICE_CONTACT_DEVICE_DISCOVERY);
}

Expand Down Expand Up @@ -882,7 +894,7 @@ public void insert() throws SQLException {
statement.setBoolean(6, certifiedByOwnKeycloak);
statement.setBoolean(7, revokedAsCompromised);
statement.setBoolean(8, forcefullyTrustedByUser);
statement.setBoolean(9, oneToOne);
statement.setInt(9, oneToOne);
statement.setLong(10, lastNoDeviceContactDeviceDiscovery);
statement.executeUpdate();
commitHookBits |= HOOK_BIT_INSERTED;
Expand Down Expand Up @@ -1179,7 +1191,21 @@ Pojo_0 backup() throws SQLException {
pojo.trust_level = trustLevel.toString();
pojo.revoked = revokedAsCompromised;
pojo.forcefully_trusted = forcefullyTrustedByUser;
pojo.one_to_one = oneToOne;
switch (oneToOne) {
case ONE_TO_ONE_STATUS_TRUE: {
pojo.one_to_one = true;
break;
}
case ONE_TO_ONE_STATUS_FALSE: {
pojo.one_to_one = false;
break;
}
case ONE_TO_ONE_STATUS_UNKNOWN:
default: {
pojo.one_to_one = null;
break;
}
}
pojo.trust_origins = ContactTrustOrigin.backupAll(identityManagerSession, ownedIdentity, contactIdentity);
pojo.contact_groups = ContactGroup.backupAllForOwner(identityManagerSession, ownedIdentity, contactIdentity);

Expand All @@ -1205,7 +1231,7 @@ private static void restoreContact(IdentityManagerSession identityManagerSession
published_details = ContactIdentityDetails.restore(identityManagerSession, ownedIdentity, contactIdentity, pojo.published_details);
}

ContactIdentity contactIdentityObject = new ContactIdentity(identityManagerSession, contactIdentity, ownedIdentity, trusted_details.getVersion(), TrustLevel.of(pojo.trust_level), (pojo.one_to_one == null || pojo.one_to_one));
ContactIdentity contactIdentityObject = new ContactIdentity(identityManagerSession, contactIdentity, ownedIdentity, trusted_details.getVersion(), TrustLevel.of(pojo.trust_level), pojo.one_to_one == null ? ONE_TO_ONE_STATUS_UNKNOWN : (pojo.one_to_one ? ONE_TO_ONE_STATUS_TRUE : ONE_TO_ONE_STATUS_FALSE));
if (published_details != null) {
contactIdentityObject.publishedDetailsVersion = published_details.getVersion();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public static ContactSyncSnapshot of(IdentityManagerSession identityManagerSessi
contactSyncSnapshot.published_details = IdentityDetailsSyncSnapshot.of(identityManagerSession, publishedDetails);
}

contactSyncSnapshot.one_to_one = contact.isOneToOne() ? true : null;
contactSyncSnapshot.one_to_one = contact.isOneToOne() ? Boolean.TRUE : (contact.isNotOneToOne() ? Boolean.FALSE : null);

contactSyncSnapshot.revoked = contact.isRevokedAsCompromised() ? true : null;

Expand Down Expand Up @@ -109,7 +109,7 @@ public ContactIdentity restore(IdentityManagerSession identityManagerSession, Id
}

TrustLevel trustLevel = (domain.contains(TRUST_LEVEL) && trust_level != null) ? TrustLevel.of(trust_level) : new TrustLevel(0, 0);
boolean oneToOne = (domain.contains(ONE_TO_ONE) && one_to_one != null) ? one_to_one : !domain.contains(ONE_TO_ONE);
int oneToOne = (domain.contains(ONE_TO_ONE) && one_to_one != null) ? (one_to_one ? ContactIdentity.ONE_TO_ONE_STATUS_TRUE : ContactIdentity.ONE_TO_ONE_STATUS_FALSE) : ContactIdentity.ONE_TO_ONE_STATUS_UNKNOWN;

ContactIdentity contactIdentityObject = new ContactIdentity(identityManagerSession, contactIdentity, ownedIdentity, trustedDetails.getVersion(), trustLevel, oneToOne);
if (publishedDetails != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ public interface IdentityDelegate {
boolean isIdentityAnActiveContactOfOwnedIdentity(Session session, Identity ownedIdentity, Identity contactIdentity) throws SQLException;
boolean isIdentityAContactOfOwnedIdentity(Session session, Identity ownedIdentity, Identity contactIdentity) throws SQLException;
boolean isIdentityAOneToOneContactOfOwnedIdentity(Session session, Identity ownedIdentity, Identity contactIdentity) throws SQLException;
boolean isIdentityANotOneToOneContactOfOwnedIdentity(Session session, Identity ownedIdentity, Identity contactIdentity) throws SQLException;
void setContactOneToOne(Session session, Identity ownedIdentity, Identity contactIdentity, boolean oneToOne) throws SQLException;
// TrustLevel getContactIdentityTrustLevel(Session session, Identity ownedIdentity, Identity contactIdentity) throws SQLException;
EnumSet<ObvContactActiveOrInactiveReason> getContactActiveOrInactiveReasons(Session session, Identity ownedIdentity, Identity contactIdentity) throws SQLException;
Expand Down
Loading

0 comments on commit cb07c92

Please sign in to comment.