From c6af32650d0bf738652612755c292e07e86e080a Mon Sep 17 00:00:00 2001 From: ameba23 Date: Mon, 30 Aug 2021 10:47:13 +0200 Subject: [PATCH] Add revoke remote wipe back end functionality --- .../briar/remotewipe/MessageEncoderImpl.java | 9 ++ .../remotewipe/RemoteWipeManagerImpl.java | 95 +++++++++++++++++-- 2 files changed, 97 insertions(+), 7 deletions(-) diff --git a/briar-core/src/main/java/org/briarproject/briar/remotewipe/MessageEncoderImpl.java b/briar-core/src/main/java/org/briarproject/briar/remotewipe/MessageEncoderImpl.java index 2463793f6..cdfab49f8 100644 --- a/briar-core/src/main/java/org/briarproject/briar/remotewipe/MessageEncoderImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/remotewipe/MessageEncoderImpl.java @@ -9,6 +9,7 @@ import javax.inject.Inject; import static org.briarproject.briar.api.remotewipe.MessageType.SETUP; import static org.briarproject.briar.api.remotewipe.MessageType.WIPE; +import static org.briarproject.briar.api.remotewipe.MessageType.REVOKE; public class MessageEncoderImpl implements MessageEncoder { @@ -27,6 +28,14 @@ public class MessageEncoderImpl implements MessageEncoder { return encodeBody(body); } + @Override + public byte[] encodeRevokeMessage() { + BdfList body = BdfList.of( + REVOKE.getValue() + ); + return encodeBody(body); + } + @Override public byte[] encodeWipeMessage() { BdfList body = BdfList.of( diff --git a/briar-core/src/main/java/org/briarproject/briar/remotewipe/RemoteWipeManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/remotewipe/RemoteWipeManagerImpl.java index 4de108980..d6b9727c0 100644 --- a/briar-core/src/main/java/org/briarproject/briar/remotewipe/RemoteWipeManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/remotewipe/RemoteWipeManagerImpl.java @@ -47,8 +47,10 @@ import javax.annotation.Nullable; import javax.inject.Inject; import static java.util.logging.Logger.getLogger; +import static org.briarproject.briar.api.remotewipe.MessageType.REVOKE; import static org.briarproject.briar.api.remotewipe.MessageType.SETUP; import static org.briarproject.briar.api.remotewipe.MessageType.WIPE; +import static org.briarproject.briar.api.remotewipe.RemoteWipeConstants.GROUP_KEY_AM_WIPER; import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ; import static org.briarproject.briar.api.remotewipe.RemoteWipeConstants.GROUP_KEY_CONTACT_ID; import static org.briarproject.briar.api.remotewipe.RemoteWipeConstants.GROUP_KEY_RECEIVED_WIPE; @@ -137,6 +139,14 @@ public class RemoteWipeManagerImpl extends ConversationClientImpl m.getId()); txn.attach(new RemoteWipeReceivedEvent( createMessageHeader(m, meta, status, type), contactId)); + + // Update our local record + BdfDictionary localRecord = new BdfDictionary(); + localRecord.put(GROUP_KEY_AM_WIPER, true); + + if (!db.containsGroup(txn, localGroup.getId())) + db.addGroup(txn, localGroup); + clientHelper.mergeGroupMetadata(txn, localGroup.getId(), localRecord); } else if (type == WIPE) { if (!remoteWipeIsSetup(txn)) return false; if (clock.currentTimeMillis() - m.getTimestamp() > MAX_MESSAGE_AGE) @@ -144,7 +154,7 @@ public class RemoteWipeManagerImpl extends ConversationClientImpl ContactId contactId = getContactId(txn, m.getGroupId()); // Check if contact is in list of wipers - if (findMessage(txn, m.getGroupId(), SETUP, true) != null) { + if (isWiper(txn, contactId)) { LOG.info("Got a valid wipe message from a wiper"); BdfDictionary existingMeta = @@ -199,7 +209,24 @@ public class RemoteWipeManagerImpl extends ConversationClientImpl newMeta); } } + } else if (type == REVOKE) { + messageTracker.trackIncomingMessage(txn, m); + ContactId contactId = getContactId(txn, m.getGroupId()); + + MessageStatus status = db.getMessageStatus(txn, contactId, + m.getId()); + txn.attach(new RemoteWipeReceivedEvent( + createMessageHeader(m, meta, status, type), contactId)); + + // Update our local record + BdfDictionary localRecord = new BdfDictionary(); + localRecord.put(GROUP_KEY_AM_WIPER, false); + + if (!db.containsGroup(txn, localGroup.getId())) + db.addGroup(txn, localGroup); + clientHelper.mergeGroupMetadata(txn, localGroup.getId(), localRecord); } + return false; } @@ -222,9 +249,6 @@ public class RemoteWipeManagerImpl extends ConversationClientImpl LOG.info("All remote wipe setup messages sent"); // Make a record of this locally - if (!db.containsGroup(txn, localGroup.getId())) - db.addGroup(txn, localGroup); - BdfDictionary meta = new BdfDictionary(); meta.put(GROUP_KEY_WIPERS, wipersMetadata); @@ -252,6 +276,24 @@ public class RemoteWipeManagerImpl extends ConversationClientImpl messageTracker.trackOutgoingMessage(txn, m); } + private void sendRevokeMessage(Transaction txn, Contact contact) + throws DbException, FormatException { + Group group = getContactGroup(contact); + GroupId g = group.getId(); + if (!db.containsGroup(txn, g)) db.addGroup(txn, group); + long timestamp = clock.currentTimeMillis(); + + byte[] body = messageEncoder.encodeRevokeMessage(); + + Message m = clientHelper.createMessage(g, timestamp, body); + BdfDictionary meta = BdfDictionary.of( + new BdfEntry(MSG_KEY_MESSAGE_TYPE, SETUP.getValue()), + new BdfEntry(MSG_KEY_LOCAL, true), + new BdfEntry(MSG_KEY_TIMESTAMP, timestamp) + ); + clientHelper.addLocalMessage(txn, m, meta, true, false); + messageTracker.trackOutgoingMessage(txn, m); + } public void wipe(Transaction txn, Contact contact) throws DbException, FormatException { @@ -276,11 +318,23 @@ public class RemoteWipeManagerImpl extends ConversationClientImpl messageTracker.trackOutgoingMessage(txn, m); } + private boolean isWiper(Transaction txn, ContactId contactId) + throws DbException { + Author author = contactManager.getContact(txn, contactId).getAuthor(); + List currentWipers = getWipers(txn); + for (Author a : currentWipers) { + if (a.getId().equals(author.getId())) { + return true; + } + } + return false; + } + public boolean amWiper(Transaction txn, ContactId contactId) { try { - GroupId groupId = - getContactGroup(db.getContact(txn, contactId)).getId(); - return findMessage(txn, groupId, SETUP, false) != null; + BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(txn, + localGroup.getId()); + return meta.getBoolean(GROUP_KEY_AM_WIPER, false); } catch (DbException e) { return false; } catch (FormatException e) { @@ -288,6 +342,33 @@ public class RemoteWipeManagerImpl extends ConversationClientImpl } } + public void revoke(Transaction txn, ContactId contactId) + throws DbException, FormatException { + // Revoke a contact's wiper status + Contact contactToRevoke = contactManager.getContact(txn, contactId); + Author authorToRevoke = contactToRevoke.getAuthor(); + + List currentWipers = getWipers(txn); + BdfList newWipers = new BdfList(); + + for (Author a : currentWipers) { + if (a.getId().equals(authorToRevoke.getId())) { + sendRevokeMessage(txn, contactToRevoke); + } else { + newWipers.add(clientHelper.toList(a)); + } + } + // If we revoked someone, update our list + if (newWipers.size() < currentWipers.size()) { + BdfDictionary meta = new BdfDictionary(); + meta.put(GROUP_KEY_WIPERS, newWipers); + + if (!db.containsGroup(txn, localGroup.getId())) + db.addGroup(txn, localGroup); + clientHelper.mergeGroupMetadata(txn, localGroup.getId(), meta); + } + } + @Override public Group getContactGroup(Contact c) { return contactGroupFactory.createContactGroup(CLIENT_ID,