From 021861f4c1cba9e14b034fb729fad0afd4d21c85 Mon Sep 17 00:00:00 2001 From: goapunk <goapunk@riseup.net> Date: Sat, 22 Sep 2018 13:30:04 +0200 Subject: [PATCH] temp --- .../TransportPropertyManagerImpl.java | 1 + ...ilboxIntroductionRequestReceivedEvent.java | 24 ++ ...lboxIntroductionResponseReceivedEvent.java | 29 ++ .../introduction/IntroductionManagerImpl.java | 1 + .../briar/mailbox/AbortMessage.java | 5 +- .../AbstractMailboxIntroductionMessage.java | 5 +- .../briar/mailbox/AbstractProtocolEngine.java | 69 +++-- .../briar/mailbox/ContactAcceptMessage.java | 5 +- .../briar/mailbox/ContactRequestMessage.java | 2 +- .../briar/mailbox/DeclineMessage.java | 4 +- .../briar/mailbox/IntroductionConstants.java | 2 +- .../briar/mailbox/MailboxAcceptMessage.java | 16 +- .../briar/mailbox/MailboxAuthMessage.java | 5 +- .../MailboxIntroductionManagerImpl.java | 248 ++++++++++++++++-- .../mailbox/MailboxIntroductionModule.java | 20 +- .../mailbox/MailboxIntroductionValidator.java | 33 +-- ...ncoder.java => MailboxMessageEncoder.java} | 19 +- ...pl.java => MailboxMessageEncoderImpl.java} | 67 ++--- ...eParser.java => MailboxMessageParser.java} | 9 +- ...mpl.java => MailboxMessageParserImpl.java} | 56 ++-- .../briar/mailbox/MailboxProtocolEngine.java | 182 +++++++++++++ .../briar/mailbox/MailboxSession.java | 44 ++-- ...ncoder.java => MailboxSessionEncoder.java} | 2 +- ...pl.java => MailboxSessionEncoderImpl.java} | 6 +- ...nParser.java => MailboxSessionParser.java} | 4 +- ...mpl.java => MailboxSessionParserImpl.java} | 37 +-- .../briar/mailbox/MessageMetadata.java | 55 ++++ .../briar/mailbox/OwnerProtocolEngine.java | 65 +++-- .../briar/mailbox/OwnerSession.java | 3 +- .../briar/mailbox/RequestMessage.java | 13 +- .../briarproject/briar/mailbox/Session.java | 14 +- .../briar/messaging/MessagingManagerImpl.java | 1 + .../GroupInvitationManagerImpl.java | 2 + .../briar/sharing/SharingManagerImpl.java | 2 + .../IntroductionIntegrationTest.java | 4 + .../MailboxIntroductionIntegrationTest.java | 105 ++++---- ...xIntroductionIntegrationTestComponent.java | 6 +- .../briar/test/BriarIntegrationTest.java | 2 +- 38 files changed, 815 insertions(+), 352 deletions(-) create mode 100644 briar-api/src/main/java/org/briarproject/briar/api/mailbox/event/MailboxIntroductionRequestReceivedEvent.java create mode 100644 briar-api/src/main/java/org/briarproject/briar/api/mailbox/event/MailboxIntroductionResponseReceivedEvent.java rename briar-core/src/main/java/org/briarproject/briar/mailbox/{MessageEncoder.java => MailboxMessageEncoder.java} (71%) rename briar-core/src/main/java/org/briarproject/briar/mailbox/{MessageEncoderImpl.java => MailboxMessageEncoderImpl.java} (72%) rename briar-core/src/main/java/org/briarproject/briar/mailbox/{MessageParser.java => MailboxMessageParser.java} (85%) rename briar-core/src/main/java/org/briarproject/briar/mailbox/{MessageParserImpl.java => MailboxMessageParserImpl.java} (74%) create mode 100644 briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxProtocolEngine.java rename briar-core/src/main/java/org/briarproject/briar/mailbox/{SessionEncoder.java => MailboxSessionEncoder.java} (93%) rename briar-core/src/main/java/org/briarproject/briar/mailbox/{SessionEncoderImpl.java => MailboxSessionEncoderImpl.java} (98%) rename briar-core/src/main/java/org/briarproject/briar/mailbox/{SessionParser.java => MailboxSessionParser.java} (87%) rename briar-core/src/main/java/org/briarproject/briar/mailbox/{SessionParserImpl.java => MailboxSessionParserImpl.java} (89%) create mode 100644 briar-core/src/main/java/org/briarproject/briar/mailbox/MessageMetadata.java diff --git a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java index 98822d8b0..4b058a6da 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java @@ -108,6 +108,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, @Override public void onClientVisibilityChanging(Transaction txn, Contact c, Visibility v) throws DbException { + if(!getApplicableContactTypes().contains(c.getType())) return; // Apply the client's visibility to the contact group Group g = getContactGroup(c); db.setGroupVisibility(txn, c.getId(), g.getId(), v); diff --git a/briar-api/src/main/java/org/briarproject/briar/api/mailbox/event/MailboxIntroductionRequestReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/mailbox/event/MailboxIntroductionRequestReceivedEvent.java new file mode 100644 index 000000000..40eb88813 --- /dev/null +++ b/briar-api/src/main/java/org/briarproject/briar/api/mailbox/event/MailboxIntroductionRequestReceivedEvent.java @@ -0,0 +1,24 @@ +package org.briarproject.briar.api.mailbox.event; + +import org.briarproject.bramble.api.event.Event; +import org.briarproject.bramble.api.identity.AuthorId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import javax.annotation.concurrent.Immutable; + +@Immutable +@NotNullByDefault +public class MailboxIntroductionRequestReceivedEvent extends Event { + + private final AuthorId contactId; + + public MailboxIntroductionRequestReceivedEvent(AuthorId contactId) { + this.contactId = contactId; + + } + + public AuthorId getAuthorId() { + return contactId; + } + +} diff --git a/briar-api/src/main/java/org/briarproject/briar/api/mailbox/event/MailboxIntroductionResponseReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/mailbox/event/MailboxIntroductionResponseReceivedEvent.java new file mode 100644 index 000000000..c4bba8eb1 --- /dev/null +++ b/briar-api/src/main/java/org/briarproject/briar/api/mailbox/event/MailboxIntroductionResponseReceivedEvent.java @@ -0,0 +1,29 @@ +package org.briarproject.briar.api.mailbox.event; + +import org.briarproject.bramble.api.event.Event; +import org.briarproject.bramble.api.identity.Author; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import javax.annotation.concurrent.Immutable; + +@Immutable +@NotNullByDefault +public class MailboxIntroductionResponseReceivedEvent extends Event { + + private final Author from; + private final Author to; + + public MailboxIntroductionResponseReceivedEvent(Author from, Author to) { + this.from = from; + this.to = to; + } + + + public Author getFrom() { + return from; + } + + public Author getTo() { + return to; + } +} diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java index 19021d113..d387af92c 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java @@ -155,6 +155,7 @@ class IntroductionManagerImpl extends ConversationClientImpl @Override public void onClientVisibilityChanging(Transaction txn, Contact c, Visibility v) throws DbException { + if(!getApplicableContactTypes().contains(c.getType())) return; // Apply the client's visibility to the contact group Group g = getContactGroup(c); db.setGroupVisibility(txn, c.getId(), g.getId(), v); diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/AbortMessage.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/AbortMessage.java index 413705a17..eb326edb4 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/AbortMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/AbortMessage.java @@ -15,9 +15,8 @@ class AbortMessage extends AbstractMailboxIntroductionMessage { private final SessionId sessionId; protected AbortMessage(MessageId messageId, GroupId groupId, long timestamp, - @Nullable MessageId previousMessageId, SessionId sessionId, - long messageCounter) { - super(messageId, groupId, timestamp, previousMessageId, messageCounter); + @Nullable MessageId previousMessageId, SessionId sessionId) { + super(messageId, groupId, timestamp, previousMessageId); this.sessionId = sessionId; } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/AbstractMailboxIntroductionMessage.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/AbstractMailboxIntroductionMessage.java index fd8419d72..376480baf 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/AbstractMailboxIntroductionMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/AbstractMailboxIntroductionMessage.java @@ -16,16 +16,13 @@ abstract class AbstractMailboxIntroductionMessage { private final long timestamp; @Nullable private final MessageId previousMessageId; - private final long messageCounter; AbstractMailboxIntroductionMessage(MessageId messageId, GroupId groupId, - long timestamp, @Nullable MessageId previousMessageId, - long messageCounter) { + long timestamp, @Nullable MessageId previousMessageId) { this.messageId = messageId; this.groupId = groupId; this.timestamp = timestamp; this.previousMessageId = previousMessageId; - this.messageCounter = messageCounter; } MessageId getMessageId() { diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/AbstractProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/AbstractProtocolEngine.java index ad3cd17b2..25bc73371 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/AbstractProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/AbstractProtocolEngine.java @@ -11,16 +11,12 @@ import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.TransportId; -import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.system.Clock; import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.SessionId; -import java.util.Map; - import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -41,20 +37,18 @@ abstract class AbstractProtocolEngine<S extends Session> protected final ContactGroupFactory contactGroupFactory; protected final MessageTracker messageTracker; protected final IdentityManager identityManager; - protected final MessageParser messageParser; - protected final MessageEncoder messageEncoder; + protected final MailboxMessageParser messageParser; + protected final MailboxMessageEncoder messageEncoder; protected final Clock clock; + protected final MailboxIntroductionCrypto crypto; - AbstractProtocolEngine( - DatabaseComponent db, - ClientHelper clientHelper, + AbstractProtocolEngine(DatabaseComponent db, ClientHelper clientHelper, ContactManager contactManager, ContactGroupFactory contactGroupFactory, - MessageTracker messageTracker, - IdentityManager identityManager, - MessageParser messageParser, - MessageEncoder messageEncoder, - Clock clock) { + MessageTracker messageTracker, IdentityManager identityManager, + MailboxMessageParser messageParser, + MailboxMessageEncoder messageEncoder, Clock clock, + MailboxIntroductionCrypto crypto) { this.db = db; this.clientHelper = clientHelper; this.contactManager = contactManager; @@ -64,38 +58,39 @@ abstract class AbstractProtocolEngine<S extends Session> this.messageParser = messageParser; this.messageEncoder = messageEncoder; this.clock = clock; + this.crypto = crypto; } Message sendMailboxRequestMessage(Transaction txn, PeerSession s, - long timestamp) throws DbException { + long timestamp, Author introduceeAuthor, long messageCounter) + throws DbException { Message m = messageEncoder .encodeRequestMessage(s.getContactGroupId(), timestamp, - s.getLastLocalMessageId()); - sendMessage(txn, MAILBOX_REQUEST, s.getSessionId(), m); + s.getLastLocalMessageId(), introduceeAuthor, + messageCounter); + sendMessage(txn, MAILBOX_REQUEST, s.getSessionId(), m, messageCounter); return m; } Message sendMailboxAcceptMessage(Transaction txn, PeerSession s, - long timestamp, - byte[] ephemeralPublicKey, long acceptTimestamp, - Map<TransportId, TransportProperties> transportProperties, - boolean visible) throws DbException { + long timestamp, byte[] ephemeralPublicKey, long acceptTimestamp, + long messageCounter) throws DbException { Message m = messageEncoder .encodeMailboxAcceptMessage(s.getContactGroupId(), timestamp, s.getLastLocalMessageId(), s.getSessionId(), - ephemeralPublicKey, acceptTimestamp, - transportProperties); - sendMessage(txn, MAILBOX_ACCEPT, s.getSessionId(), m); + ephemeralPublicKey, acceptTimestamp, messageCounter); + sendMessage(txn, MAILBOX_ACCEPT, s.getSessionId(), m, messageCounter); return m; } Message sendContactRequestMessage(Transaction txn, PeerSession s, - long timestamp, Author author, @Nullable String message) - throws DbException { + long timestamp, Author author, Author introduceeAuthor, + long messageCounter) throws DbException { Message m = messageEncoder .encodeRequestMessage(s.getContactGroupId(), timestamp, - s.getLastLocalMessageId()); - sendMessage(txn, CONTACT_REQUEST, s.getSessionId(), m); + s.getLastLocalMessageId(), introduceeAuthor, + messageCounter); + sendMessage(txn, CONTACT_REQUEST, s.getSessionId(), m, 0); return m; } @@ -136,7 +131,7 @@ abstract class AbstractProtocolEngine<S extends Session> Message m = messageEncoder .encodeDeclineMessage(s.getContactGroupId(), timestamp, s.getLastLocalMessageId(), s.getSessionId()); - sendMessage(txn, DECLINE, s.getSessionId(), m); + sendMessage(txn, DECLINE, s.getSessionId(), m, 0); return m; } @@ -145,15 +140,16 @@ abstract class AbstractProtocolEngine<S extends Session> Message m = messageEncoder .encodeAbortMessage(s.getContactGroupId(), timestamp, s.getLastLocalMessageId(), s.getSessionId()); - sendMessage(txn, ABORT, s.getSessionId(), m); + sendMessage(txn, ABORT, s.getSessionId(), m, 0); return m; } private void sendMessage(Transaction txn, MessageType type, - SessionId sessionId, Message m) + SessionId sessionId, Message m, long messageCounter) throws DbException { BdfDictionary meta = messageEncoder - .encodeMetadata(type, sessionId, m.getTimestamp(), true); + .encodeMetadata(type, sessionId, m.getTimestamp(), true, + messageCounter); try { clientHelper.addLocalMessage(txn, m, meta, true); } catch (FormatException e) { @@ -169,13 +165,8 @@ abstract class AbstractProtocolEngine<S extends Session> } long getLocalTimestamp(long localTimestamp, long requestTimestamp) { - return Math.max( - clock.currentTimeMillis(), - Math.max( - localTimestamp, - requestTimestamp - ) + 1 - ); + return Math.max(clock.currentTimeMillis(), + Math.max(localTimestamp, requestTimestamp) + 1); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/ContactAcceptMessage.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/ContactAcceptMessage.java index 82781be3d..8797283b4 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/ContactAcceptMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/ContactAcceptMessage.java @@ -21,9 +21,8 @@ class ContactAcceptMessage extends AbstractMailboxIntroductionMessage { protected ContactAcceptMessage(MessageId messageId, GroupId groupId, long timestamp, @Nullable MessageId previousMessageId, SessionId sessionId, byte[] ephemeralPublicKey, - long acceptTimestamp, byte[] mac, byte[] signature, - long messageCounter) { - super(messageId, groupId, timestamp, previousMessageId, messageCounter); + long acceptTimestamp, byte[] mac, byte[] signature) { + super(messageId, groupId, timestamp, previousMessageId); this.sessionId = sessionId; this.ephemeralPublicKey = ephemeralPublicKey; this.acceptTimestamp = acceptTimestamp; diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/ContactRequestMessage.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/ContactRequestMessage.java index ecfa53859..676ee4500 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/ContactRequestMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/ContactRequestMessage.java @@ -21,7 +21,7 @@ class ContactRequestMessage extends AbstractMailboxIntroductionMessage { SessionId sessionId, byte[] ephemeralPublicKey, long acceptTimestamp, long messageCounter) { - super(messageId, groupId, timestamp, previousMessageId, messageCounter); + super(messageId, groupId, timestamp, previousMessageId); this.sessionId = sessionId; this.ephemeralPublicKey = ephemeralPublicKey; this.acceptTimestamp = acceptTimestamp; diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/DeclineMessage.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/DeclineMessage.java index df841bdcd..b7da465ea 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/DeclineMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/DeclineMessage.java @@ -16,8 +16,8 @@ class DeclineMessage extends AbstractMailboxIntroductionMessage { protected DeclineMessage(MessageId messageId, GroupId groupId, long timestamp, @Nullable MessageId previousMessageId, - SessionId sessionId, long messageCounter) { - super(messageId, groupId, timestamp, previousMessageId, messageCounter); + SessionId sessionId) { + super(messageId, groupId, timestamp, previousMessageId); this.sessionId = sessionId; } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/IntroductionConstants.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/IntroductionConstants.java index fa6bc0624..3e2d61274 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/IntroductionConstants.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/IntroductionConstants.java @@ -10,7 +10,7 @@ interface IntroductionConstants { String MSG_KEY_SESSION_ID = "sessionId"; String MSG_KEY_TIMESTAMP = "timestamp"; String MSG_KEY_LOCAL = "local"; - String MSG_KEY_VISIBLE_IN_UI = "visibleInUi"; + String MSG_KEY_COUNTER = "counter"; String MSG_KEY_AVAILABLE_TO_ANSWER = "availableToAnswer"; // Session Keys diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxAcceptMessage.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxAcceptMessage.java index 7284e0273..6b740de82 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxAcceptMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxAcceptMessage.java @@ -1,14 +1,10 @@ package org.briarproject.briar.mailbox; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.TransportId; -import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.SessionId; -import java.util.Map; - import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -19,19 +15,15 @@ class MailboxAcceptMessage extends AbstractMailboxIntroductionMessage { private final SessionId sessionId; private final byte[] ephemeralPublicKey; private final long acceptTimestamp; - private final Map<TransportId, TransportProperties> transportProperties; protected MailboxAcceptMessage(MessageId messageId, GroupId groupId, long timestamp, @Nullable MessageId previousMessageId, SessionId sessionId, byte[] ephemeralPublicKey, - long acceptTimestamp, - Map<TransportId, TransportProperties> transportProperties, - long messageCounter) { - super(messageId, groupId, timestamp, previousMessageId, messageCounter); + long acceptTimestamp) { + super(messageId, groupId, timestamp, previousMessageId); this.sessionId = sessionId; this.ephemeralPublicKey = ephemeralPublicKey; this.acceptTimestamp = acceptTimestamp; - this.transportProperties = transportProperties; } public SessionId getSessionId() { @@ -46,8 +38,4 @@ class MailboxAcceptMessage extends AbstractMailboxIntroductionMessage { return acceptTimestamp; } - public Map<TransportId, TransportProperties> getTransportProperties() { - return transportProperties; - } - } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxAuthMessage.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxAuthMessage.java index 917a841ad..da930637d 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxAuthMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxAuthMessage.java @@ -28,9 +28,8 @@ class MailboxAuthMessage extends AbstractMailboxIntroductionMessage { SessionId sessionId, byte[] ephemeralPublicKey, long acceptTimestamp, Map<TransportId, TransportProperties> transportProperties, - byte[] mac, byte[] signature, - long messageCounter) { - super(messageId, groupId, timestamp, previousMessageId, messageCounter); + byte[] mac, byte[] signature) { + super(messageId, groupId, timestamp, previousMessageId); this.sessionId = sessionId; this.ephemeralPublicKey = ephemeralPublicKey; this.acceptTimestamp = acceptTimestamp; diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionManagerImpl.java index 69258f5ad..82a802fee 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionManagerImpl.java @@ -4,7 +4,9 @@ import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ContactGroupFactory; import org.briarproject.bramble.api.contact.Contact; +import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactManager; +import org.briarproject.bramble.api.contact.ContactType; import org.briarproject.bramble.api.contact.PrivateMailbox; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfList; @@ -23,8 +25,11 @@ import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.mailbox.MailboxIntroductionManager; +import org.briarproject.briar.api.mailbox.Role; import org.briarproject.briar.client.BdfIncomingMessageHook; +import java.util.Arrays; +import java.util.Collection; import java.util.Map; import java.util.logging.Logger; @@ -32,9 +37,13 @@ import javax.annotation.Nullable; import javax.inject.Inject; import static org.briarproject.bramble.api.contact.ContactManager.ContactHook; +import static org.briarproject.bramble.api.contact.ContactType.MAILBOX_OWNER; +import static org.briarproject.bramble.api.contact.ContactType.values; import static org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook; import static org.briarproject.briar.api.mailbox.Role.MAILBOX; import static org.briarproject.briar.api.mailbox.Role.OWNER; +import static org.briarproject.briar.mailbox.IntroductionConstants.GROUP_KEY_CONTACT_ID; +import static org.briarproject.briar.mailbox.MessageType.MAILBOX_REQUEST; class MailboxIntroductionManagerImpl extends BdfIncomingMessageHook implements MailboxIntroductionManager, Client, ClientVersioningHook, @@ -45,31 +54,29 @@ class MailboxIntroductionManagerImpl extends BdfIncomingMessageHook private final ClientVersioningManager clientVersioningManager; private final ContactGroupFactory contactGroupFactory; private final ContactManager contactManager; - private final MessageParser messageParser; + private final MailboxMessageParser messageParser; // private final SessionEncoder sessionEncoder; - private final SessionParser sessionParser; + private final MailboxSessionParser sessionParser; private final OwnerProtocolEngine ownerProtocolEngine; - private final SessionEncoder sessionEncoder; + private final MailboxSessionEncoder sessionEncoder; private final MailboxIntroductionCrypto crypto; - //private final MailboxProtocolEngine mailboxProtocolEngine; + private final MailboxProtocolEngine mailboxProtocolEngine; private final IdentityManager identityManager; private final Group localGroup; @Inject - MailboxIntroductionManagerImpl( - DatabaseComponent db, + MailboxIntroductionManagerImpl(DatabaseComponent db, ClientHelper clientHelper, ClientVersioningManager clientVersioningManager, MetadataParser metadataParser, ContactGroupFactory contactGroupFactory, - ContactManager contactManager, - MessageParser messageParser, - SessionParser sessionParser, + ContactManager contactManager, MailboxMessageParser messageParser, + MailboxSessionParser sessionParser, OwnerProtocolEngine ownerProtocolEngine, - SessionEncoder sessionEncoder, + MailboxSessionEncoder sessionEncoder, MailboxIntroductionCrypto crypto, - // MailboxProtocolEngine mailboxProtocolEngine, + MailboxProtocolEngine mailboxProtocolEngine, IdentityManager identityManager) { super(db, clientHelper, metadataParser); this.clientVersioningManager = clientVersioningManager; @@ -80,24 +87,194 @@ class MailboxIntroductionManagerImpl extends BdfIncomingMessageHook this.ownerProtocolEngine = ownerProtocolEngine; this.sessionEncoder = sessionEncoder; this.crypto = crypto; -// this.mailboxProtocolEngine = mailboxProtocolEngine; + this.mailboxProtocolEngine = mailboxProtocolEngine; this.identityManager = identityManager; this.localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID, MAJOR_VERSION); } + @Override + public void createLocalState(Transaction txn) throws DbException { + // Create a local group to store protocol sessions + if (db.containsGroup(txn, localGroup.getId())) return; + db.addGroup(txn, localGroup); + // Set up groups for communication with any pre-existing contacts + for (Contact c : db.getAllContacts(txn)) addingContact(txn, c); + } + @Override protected boolean incomingMessage(Transaction txn, Message m, BdfList body, - BdfDictionary meta) throws DbException, FormatException { + BdfDictionary bdfMeta) throws DbException, FormatException { + // For testing + ContactId introduceeId = getContactId(txn, m.getGroupId()); + ContactType type = db.getContactType(txn, introduceeId); + if (type == MAILBOX_OWNER) { + return incomingMessageMailbox(txn, m, body, bdfMeta); + } else return incomingMessageContact(txn, m, body, bdfMeta); + } + + private boolean incomingMessageMailbox(Transaction txn, Message m, + BdfList body, BdfDictionary bdfMeta) + throws DbException, FormatException { + // Parse the metadata + MessageMetadata meta = messageParser.parseMetadata(bdfMeta); + // Look up the session, if there is one + SessionId sessionId = meta.getSessionId(); + MailboxSession newMailboxSession = null; + if (sessionId == null) { + if (meta.getMessageType() != MAILBOX_REQUEST) + throw new AssertionError(); + newMailboxSession = createNewMailboxSession(txn, m, body); + sessionId = newMailboxSession.getSessionId(); + } + StoredSession ss = getSession(txn, sessionId); + // Handle the message + Session session; + MessageId storageId; + if (ss == null) { + if (meta.getMessageType() != MAILBOX_REQUEST) + throw new FormatException(); + if (newMailboxSession == null) throw new AssertionError(); + storageId = createStorageId(txn); + session = handleMessage(txn, m, body, meta.getMessageType(), + newMailboxSession, mailboxProtocolEngine); + } else { + storageId = ss.storageId; + long messageCounter = + sessionParser.getMessageCounter(ss.bdfSession); + if (meta.getCounter() < messageCounter) { + // TODO: ignore or abort? + throw new FormatException(); + } + Role role = sessionParser.getRole(ss.bdfSession); + if (role == OWNER) { + session = handleMessage(txn, m, body, meta.getMessageType(), + sessionParser.parseOwnerSession(ss.bdfSession), + ownerProtocolEngine); + } else if (role == MAILBOX) { + session = handleMessage(txn, m, body, meta.getMessageType(), + sessionParser.parseMailboxSession(m.getGroupId(), + ss.bdfSession), mailboxProtocolEngine); + } else throw new AssertionError(); + } + // Store the updated session + storeSession(txn, storageId, session); return false; } + private boolean incomingMessageContact(Transaction txn, Message m, + BdfList body, BdfDictionary bdfMeta) + throws DbException, FormatException { + // Parse the metadata + MessageMetadata meta = messageParser.parseMetadata(bdfMeta); + // Look up the session, if there is one + SessionId sessionId = meta.getSessionId(); + MailboxSession newMailboxSession = null; + if (sessionId == null) { + if (meta.getMessageType() != MAILBOX_REQUEST) + throw new AssertionError(); + newMailboxSession = createNewMailboxSession(txn, m, body); + sessionId = newMailboxSession.getSessionId(); + } + StoredSession ss = getSession(txn, sessionId); + // Handle the message + Session session; + MessageId storageId; + if (ss == null) { + if (meta.getMessageType() != MAILBOX_REQUEST) + throw new FormatException(); + if (newMailboxSession == null) throw new AssertionError(); + storageId = createStorageId(txn); + session = handleMessage(txn, m, body, meta.getMessageType(), + newMailboxSession, mailboxProtocolEngine); + } else { + storageId = ss.storageId; + long messageCounter = + sessionParser.getMessageCounter(ss.bdfSession); + if (meta.getCounter() < messageCounter) { + // TODO: ignore or abort? + throw new FormatException(); + } + Role role = sessionParser.getRole(ss.bdfSession); + if (role == OWNER) { + session = handleMessage(txn, m, body, meta.getMessageType(), + sessionParser.parseOwnerSession(ss.bdfSession), + ownerProtocolEngine); + } else if (role == MAILBOX) { + session = handleMessage(txn, m, body, meta.getMessageType(), + sessionParser.parseMailboxSession(m.getGroupId(), + ss.bdfSession), mailboxProtocolEngine); + } else throw new AssertionError(); + } + // Store the updated session + storeSession(txn, storageId, session); + return false; + } + + private MailboxSession createNewMailboxSession(Transaction txn, Message m, + BdfList body) throws DbException, FormatException { + ContactId ownerId = getContactId(txn, m.getGroupId()); + Author owner = db.getContact(txn, ownerId).getAuthor(); + Author local = identityManager.getLocalAuthor(txn); + Author remote = messageParser.parseRequestMessage(m, body).getAuthor(); + if (local.equals(remote)) throw new FormatException(); + SessionId sessionId = crypto.getSessionId(owner, local, remote); + boolean alice = crypto.isAlice(local.getId(), remote.getId()); + return MailboxSession + .getInitial(m.getGroupId(), sessionId, owner, alice, remote); + } + + /* + private IntroduceeSession createNewIntroduceeSession(Transaction txn, + Message m, BdfList body) throws DbException, FormatException { + ContactId ownerId = getContactId(txn, m.getGroupId()); + Author owner = db.getContact(txn, ownerId).getAuthor(); + Author local = identityManager.getLocalAuthor(txn); + Author remote = messageParser.parseRequestMessage(m, body).getAuthor(); + if (local.equals(remote)) throw new FormatException(); + SessionId sessionId = crypto.getSessionId(owner, local, remote); + boolean alice = crypto.isAlice(local.getId(), remote.getId()); + return IntroduceeSession + .getInitial(m.getGroupId(), sessionId, owner, alice, + remote); + } +*/ + + private <S extends Session> S handleMessage(Transaction txn, Message m, + BdfList body, MessageType type, S session, ProtocolEngine<S> engine) + throws DbException, FormatException { + switch (type) { + + case MAILBOX_REQUEST: { + RequestMessage request = + messageParser.parseRequestMessage(m, body); + return engine.onRequestMessage(txn, session, request); + } + case MAILBOX_ACCEPT: { + MailboxAcceptMessage acceptMessage = + messageParser.parseMailboxAcceptMessage(m, body); + return engine + .onMailboxAcceptMessage(txn, session, acceptMessage); + } + case ABORT: { + AbortMessage abort = messageParser.parseAbortMessage(m, body); + return engine.onAbortMessage(txn, session, abort); + } + default: + throw new AssertionError(); + } + } + + @Override + public Collection<ContactType> getApplicableContactTypes() { + return Arrays.asList(values()); + } + @Override public void addingContact(Transaction txn, Contact c) throws DbException { switch (c.getType()) { case PRIVATE_MAILBOX: - privateMailboxAdded(txn, (PrivateMailbox) c); - break; + case MAILBOX_OWNER: case CONTACT: contactAdded(txn, c); break; @@ -108,15 +285,28 @@ class MailboxIntroductionManagerImpl extends BdfIncomingMessageHook } @Override - public void contactAdded(Transaction txn, Contact contact) - throws DbException { + public void contactAdded(Transaction txn, Contact c) throws DbException { + // Create a group to share with the contact + Group g = getContactGroup(c); + db.addGroup(txn, g); + // Apply the client's visibility to the contact group + Group.Visibility client = clientVersioningManager + .getClientVisibility(txn, c.getId(), CLIENT_ID, MAJOR_VERSION); + db.setGroupVisibility(txn, c.getId(), g.getId(), client); + // Attach the contact ID to the group + BdfDictionary meta = new BdfDictionary(); + meta.put(GROUP_KEY_CONTACT_ID, c.getId().getInt()); + try { + clientHelper.mergeGroupMetadata(txn, g.getId(), meta); + } catch (FormatException e) { + throw new AssertionError(e); + } LOG.info("Contact added"); } @Override public void privateMailboxAdded(Transaction txn, - PrivateMailbox privateMailbox) - throws DbException { + PrivateMailbox privateMailbox) throws DbException { LOG.info("Private mailbox added"); } @@ -179,8 +369,7 @@ class MailboxIntroductionManagerImpl extends BdfIncomingMessageHook Session session) throws DbException { BdfDictionary d; if (session.getRole() == OWNER) { - d = sessionEncoder - .encodeIntroducerSession((OwnerSession) session); + d = sessionEncoder.encodeIntroducerSession((OwnerSession) session); } else if (session.getRole() == MAILBOX) { d = sessionEncoder .encodeIntroduceeSession((IntroduceeSession) session); @@ -194,6 +383,13 @@ class MailboxIntroductionManagerImpl extends BdfIncomingMessageHook } } + private ContactId getContactId(Transaction txn, GroupId contactGroupId) + throws DbException, FormatException { + BdfDictionary meta = + clientHelper.getGroupMetadataAsDictionary(txn, contactGroupId); + return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue()); + } + @Override public Group getContactGroup(Contact c) { return contactGroupFactory @@ -212,15 +408,13 @@ class MailboxIntroductionManagerImpl extends BdfIncomingMessageHook LOG.info("contact removed"); } - @Override - public void createLocalState(Transaction txn) throws DbException { - - } - @Override public void onClientVisibilityChanging(Transaction txn, Contact c, Group.Visibility v) throws DbException { - + if (!getApplicableContactTypes().contains(c.getType())) return; + // Apply the client's visibility to the contact group + Group g = getContactGroup(c); + db.setGroupVisibility(txn, c.getId(), g.getId(), v); } private static class StoredSession { diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionModule.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionModule.java index 14420f789..5bf216054 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionModule.java @@ -30,17 +30,19 @@ public class MailboxIntroductionModule { MailboxIntroductionManager mailboxIntroductionManager; } + @Provides @Singleton - MailboxIntroductionValidator provideValidator( + MailboxIntroductionValidator provideMailboxValidator( ValidationManager validationManager, - MessageEncoder messageEncoder, MetadataEncoder metadataEncoder, + MailboxMessageEncoder messageEncoder, + MetadataEncoder metadataEncoder, ClientHelper clientHelper, Clock clock) { MailboxIntroductionValidator mailboxIntroductionValidator = new MailboxIntroductionValidator(messageEncoder, clientHelper, metadataEncoder, clock); validationManager - .registerMessageValidator(IntroductionManager.CLIENT_ID, + .registerMessageValidator(CLIENT_ID, IntroductionManager.MAJOR_VERSION, mailboxIntroductionValidator); return mailboxIntroductionValidator; @@ -63,22 +65,26 @@ public class MailboxIntroductionModule { } @Provides - MessageParser provideMessageParser(MessageParserImpl messageParser) { + MailboxMessageParser provideMailboxMessageParser( + MailboxMessageParserImpl messageParser) { return messageParser; } @Provides - MessageEncoder provideMessageEncoder(MessageEncoderImpl messageEncoder) { + MailboxMessageEncoder provideMailboxMessageEncoder( + MailboxMessageEncoderImpl messageEncoder) { return messageEncoder; } @Provides - SessionParser provideSessionParser(SessionParserImpl sessionParser) { + MailboxSessionParser provideMailboxSessionParser( + MailboxSessionParserImpl sessionParser) { return sessionParser; } @Provides - SessionEncoder provideSessionEncoder(SessionEncoderImpl sessionEncoder) { + MailboxSessionEncoder provideMailboxSessionEncoder( + MailboxSessionEncoderImpl sessionEncoder) { return sessionEncoder; } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionValidator.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionValidator.java index 46cf6776f..144fd6d88 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxIntroductionValidator.java @@ -24,7 +24,6 @@ import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.bramble.util.ValidationUtils.checkLength; import static org.briarproject.bramble.util.ValidationUtils.checkSize; -import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_REQUEST_MESSAGE_LENGTH; import static org.briarproject.briar.mailbox.MessageType.MAILBOX_ACCEPT; import static org.briarproject.briar.mailbox.MessageType.MAILBOX_AUTH; @@ -33,10 +32,9 @@ import static org.briarproject.briar.mailbox.MessageType.MAILBOX_AUTH; @NotNullByDefault class MailboxIntroductionValidator extends BdfMessageValidator { - private final MessageEncoder messageEncoder; + private final MailboxMessageEncoder messageEncoder; - MailboxIntroductionValidator( - MessageEncoder messageEncoder, + MailboxIntroductionValidator(MailboxMessageEncoder messageEncoder, ClientHelper clientHelper, MetadataEncoder metadataEncoder, Clock clock) { super(clientHelper, metadataEncoder, clock); @@ -66,18 +64,13 @@ class MailboxIntroductionValidator extends BdfMessageValidator { private BdfMessageContext validateRequestMessage(Message m, BdfList body) throws FormatException { checkSize(body, 4); - byte[] previousMessageId = body.getOptionalRaw(1); checkLength(previousMessageId, UniqueId.LENGTH); - BdfList authorList = body.getList(2); clientHelper.parseAndValidateAuthor(authorList); - - String msg = body.getOptionalString(3); - checkLength(msg, 1, MAX_REQUEST_MESSAGE_LENGTH); - - BdfDictionary meta = - messageEncoder.encodeRequestMetadata(m.getTimestamp()); + long messageCounter = body.getLong(3); + BdfDictionary meta = messageEncoder + .encodeRequestMetadata(m.getTimestamp(), messageCounter); if (previousMessageId == null) { return new BdfMessageContext(meta); } else { @@ -103,15 +96,12 @@ class MailboxIntroductionValidator extends BdfMessageValidator { long timestamp = body.getLong(4); if (timestamp < 0) throw new FormatException(); - BdfDictionary transportProperties = body.getDictionary(5); - if (transportProperties.size() < 1) throw new FormatException(); - clientHelper - .parseAndValidateTransportPropertiesMap(transportProperties); + long messageCounter = body.getLong(5); SessionId sessionId = new SessionId(sessionIdBytes); BdfDictionary meta = messageEncoder .encodeMetadata(MAILBOX_ACCEPT, sessionId, m.getTimestamp(), - false); + false, messageCounter); if (previousMessageId == null) { return new BdfMessageContext(meta); } else { @@ -140,15 +130,14 @@ class MailboxIntroductionValidator extends BdfMessageValidator { SessionId sessionId = new SessionId(sessionIdBytes); BdfDictionary meta = messageEncoder .encodeMetadata(MAILBOX_AUTH, sessionId, m.getTimestamp(), - false); + false, 0); MessageId dependency = new MessageId(previousMessageId); return new BdfMessageContext(meta, Collections.singletonList(dependency)); } - private BdfMessageContext validateOtherMessage( - MessageType type, - Message m, BdfList body) throws FormatException { + private BdfMessageContext validateOtherMessage(MessageType type, Message m, + BdfList body) throws FormatException { checkSize(body, 3); byte[] sessionIdBytes = body.getRaw(1); @@ -159,7 +148,7 @@ class MailboxIntroductionValidator extends BdfMessageValidator { SessionId sessionId = new SessionId(sessionIdBytes); BdfDictionary meta = messageEncoder - .encodeMetadata(type, sessionId, m.getTimestamp(), false); + .encodeMetadata(type, sessionId, m.getTimestamp(), false, 0); if (previousMessageId == null) { return new BdfMessageContext(meta); } else { diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageEncoder.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageEncoder.java similarity index 71% rename from briar-core/src/main/java/org/briarproject/briar/mailbox/MessageEncoder.java rename to briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageEncoder.java index cc44d68c2..dc9b032e1 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageEncoder.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageEncoder.java @@ -1,39 +1,36 @@ package org.briarproject.briar.mailbox; import org.briarproject.bramble.api.data.BdfDictionary; +import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.TransportId; -import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.SessionId; -import java.util.Map; - import javax.annotation.Nullable; @NotNullByDefault -interface MessageEncoder { +interface MailboxMessageEncoder { - BdfDictionary encodeRequestMetadata(long timestamp); + BdfDictionary encodeRequestMetadata(long timestamp, long messageCounter); BdfDictionary encodeMetadata(MessageType type, - @Nullable SessionId sessionId, long timestamp, boolean local); + @Nullable SessionId sessionId, long timestamp, boolean local, + long messsageCounter); void addSessionId(BdfDictionary meta, SessionId sessionId); - void setVisibleInUi(BdfDictionary meta, boolean visible); - void setAvailableToAnswer(BdfDictionary meta, boolean available); Message encodeRequestMessage(GroupId contactGroupId, long timestamp, - @Nullable MessageId previousMessageId); + @Nullable MessageId previousMessageId, Author introduceeAuthor, + long messageCounter); Message encodeMailboxAcceptMessage(GroupId contactGroupId, long timestamp, @Nullable MessageId previousMessageId, SessionId sessionId, byte[] ephemeralPublicKey, long acceptTimestamp, - Map<TransportId, TransportProperties> transportProperties); + long messageCounter); Message encodeDeclineMessage(GroupId contactGroupId, long timestamp, @Nullable MessageId previousMessageId, SessionId sessionId); diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageEncoderImpl.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageEncoderImpl.java similarity index 72% rename from briar-core/src/main/java/org/briarproject/briar/mailbox/MessageEncoderImpl.java rename to briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageEncoderImpl.java index dfb5dfd3c..fc2ddcff7 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageEncoderImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageEncoderImpl.java @@ -4,64 +4,62 @@ import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfList; +import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.TransportId; -import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.MessageFactory; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.SessionId; -import java.util.Map; - import javax.annotation.Nullable; import javax.inject.Inject; import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_AVAILABLE_TO_ANSWER; +import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_COUNTER; import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_LOCAL; import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_MESSAGE_TYPE; import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_SESSION_ID; import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_TIMESTAMP; -import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_VISIBLE_IN_UI; import static org.briarproject.briar.mailbox.MessageType.ABORT; import static org.briarproject.briar.mailbox.MessageType.DECLINE; import static org.briarproject.briar.mailbox.MessageType.MAILBOX_ACCEPT; import static org.briarproject.briar.mailbox.MessageType.MAILBOX_REQUEST; @NotNullByDefault -class MessageEncoderImpl implements - MessageEncoder { +class MailboxMessageEncoderImpl implements MailboxMessageEncoder { private final ClientHelper clientHelper; private final MessageFactory messageFactory; @Inject - MessageEncoderImpl(ClientHelper clientHelper, + MailboxMessageEncoderImpl(ClientHelper clientHelper, MessageFactory messageFactory) { this.clientHelper = clientHelper; this.messageFactory = messageFactory; } @Override - public BdfDictionary encodeRequestMetadata(long timestamp) { + public BdfDictionary encodeRequestMetadata(long timestamp, + long messageCounter) { BdfDictionary meta = - encodeMetadata(MAILBOX_REQUEST, null, timestamp, false); + encodeMetadata(MAILBOX_REQUEST, null, timestamp, false, + messageCounter); meta.put(MSG_KEY_AVAILABLE_TO_ANSWER, false); return meta; } @Override public BdfDictionary encodeMetadata(MessageType type, - @Nullable SessionId sessionId, long timestamp, boolean local) { + @Nullable SessionId sessionId, long timestamp, boolean local, + long messageCounter) { BdfDictionary meta = new BdfDictionary(); meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue()); - if (sessionId != null) - meta.put(MSG_KEY_SESSION_ID, sessionId); - else if (type != MAILBOX_REQUEST) - throw new IllegalArgumentException(); + if (sessionId != null) meta.put(MSG_KEY_SESSION_ID, sessionId); + else if (type != MAILBOX_REQUEST) throw new IllegalArgumentException(); meta.put(MSG_KEY_TIMESTAMP, timestamp); meta.put(MSG_KEY_LOCAL, local); + meta.put(MSG_KEY_COUNTER, messageCounter); return meta; } @@ -70,11 +68,6 @@ class MessageEncoderImpl implements meta.put(MSG_KEY_SESSION_ID, sessionId); } - @Override - public void setVisibleInUi(BdfDictionary meta, boolean visible) { - meta.put(MSG_KEY_VISIBLE_IN_UI, visible); - } - @Override public void setAvailableToAnswer(BdfDictionary meta, boolean available) { meta.put(MSG_KEY_AVAILABLE_TO_ANSWER, available); @@ -82,28 +75,21 @@ class MessageEncoderImpl implements @Override public Message encodeRequestMessage(GroupId contactGroupId, long timestamp, - @Nullable MessageId previousMessageId) { - BdfList body = BdfList.of( - MAILBOX_REQUEST.getValue(), - previousMessageId - ); + @Nullable MessageId previousMessageId, Author introduceeAuthor, + long messageCounter) { + BdfList body = BdfList.of(MAILBOX_REQUEST.getValue(), previousMessageId, + clientHelper.toList(introduceeAuthor), messageCounter); return createMessage(contactGroupId, timestamp, body); } @Override public Message encodeMailboxAcceptMessage(GroupId contactGroupId, - long timestamp, - @Nullable MessageId previousMessageId, SessionId sessionId, - byte[] ephemeralPublicKey, long acceptTimestamp, - Map<TransportId, TransportProperties> transportProperties) { - BdfList body = BdfList.of( - MAILBOX_ACCEPT.getValue(), - sessionId, - previousMessageId, - ephemeralPublicKey, - acceptTimestamp, - clientHelper.toDictionary(transportProperties) - ); + long timestamp, @Nullable MessageId previousMessageId, + SessionId sessionId, byte[] ephemeralPublicKey, + long acceptTimestamp, long messageCounter) { + BdfList body = BdfList.of(MAILBOX_ACCEPT.getValue(), sessionId, + previousMessageId, ephemeralPublicKey, acceptTimestamp, + messageCounter); return createMessage(contactGroupId, timestamp, body); } @@ -124,11 +110,8 @@ class MessageEncoderImpl implements private Message encodeMessage(MessageType type, GroupId contactGroupId, SessionId sessionId, long timestamp, @Nullable MessageId previousMessageId) { - BdfList body = BdfList.of( - type.getValue(), - sessionId, - previousMessageId - ); + BdfList body = + BdfList.of(type.getValue(), sessionId, previousMessageId); return createMessage(contactGroupId, timestamp, body); } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageParser.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageParser.java similarity index 85% rename from briar-core/src/main/java/org/briarproject/briar/mailbox/MessageParser.java rename to briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageParser.java index 640178c99..7370e7bd2 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageParser.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageParser.java @@ -8,12 +8,12 @@ import org.briarproject.bramble.api.sync.Message; import org.briarproject.briar.api.client.SessionId; @NotNullByDefault -interface MessageParser { - - BdfDictionary getMessagesVisibleInUiQuery(); +interface MailboxMessageParser { BdfDictionary getRequestsAvailableToAnswerQuery(SessionId sessionId); + MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException; + //MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException; RequestMessage parseRequestMessage(Message m, BdfList body) @@ -28,8 +28,7 @@ interface MessageParser { MailboxAuthMessage parseMailboxAuthMessage(Message m, BdfList body) throws FormatException; - AbortMessage parseAbortMessage( - Message m, BdfList body) + AbortMessage parseAbortMessage(Message m, BdfList body) throws FormatException; } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageParserImpl.java similarity index 74% rename from briar-core/src/main/java/org/briarproject/briar/mailbox/MessageParserImpl.java rename to briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageParserImpl.java index ec0e13baa..93e72e916 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxMessageParserImpl.java @@ -5,50 +5,40 @@ import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfList; +import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.TransportId; -import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.SessionId; -import java.util.Map; - import javax.inject.Inject; import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_AVAILABLE_TO_ANSWER; +import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_COUNTER; +import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_LOCAL; import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_MESSAGE_TYPE; import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_SESSION_ID; -import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_VISIBLE_IN_UI; +import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_TIMESTAMP; import static org.briarproject.briar.mailbox.MessageType.MAILBOX_REQUEST; @NotNullByDefault -class MessageParserImpl implements - MessageParser { +class MailboxMessageParserImpl implements MailboxMessageParser { private final ClientHelper clientHelper; @Inject - MessageParserImpl(ClientHelper clientHelper) { + MailboxMessageParserImpl(ClientHelper clientHelper) { this.clientHelper = clientHelper; } - @Override - public BdfDictionary getMessagesVisibleInUiQuery() { - return BdfDictionary.of(new BdfEntry(MSG_KEY_VISIBLE_IN_UI, true)); - } - @Override public BdfDictionary getRequestsAvailableToAnswerQuery( SessionId sessionId) { - return BdfDictionary.of( - new BdfEntry(MSG_KEY_AVAILABLE_TO_ANSWER, true), + return BdfDictionary.of(new BdfEntry(MSG_KEY_AVAILABLE_TO_ANSWER, true), new BdfEntry(MSG_KEY_MESSAGE_TYPE, MAILBOX_REQUEST.getValue()), - new BdfEntry(MSG_KEY_SESSION_ID, sessionId) - ); + new BdfEntry(MSG_KEY_SESSION_ID, sessionId)); } - /* @Override public MessageMetadata parseMetadata(BdfDictionary d) throws FormatException { @@ -59,13 +49,11 @@ class MessageParserImpl implements sessionIdBytes == null ? null : new SessionId(sessionIdBytes); long timestamp = d.getLong(MSG_KEY_TIMESTAMP); boolean local = d.getBoolean(MSG_KEY_LOCAL); - boolean read = d.getBoolean(MSG_KEY_READ); - boolean visible = d.getBoolean(MSG_KEY_VISIBLE_IN_UI); + long counter = d.getLong(MSG_KEY_COUNTER); boolean available = d.getBoolean(MSG_KEY_AVAILABLE_TO_ANSWER, false); - return new MessageMetadata(type, sessionId, timestamp, local, read, - visible, available); + return new MessageMetadata(type, sessionId, timestamp, local, counter, + available); } - */ @Override public RequestMessage parseRequestMessage(Message m, BdfList body) @@ -73,26 +61,23 @@ class MessageParserImpl implements byte[] previousMsgBytes = body.getOptionalRaw(1); MessageId previousMessageId = (previousMsgBytes == null ? null : new MessageId(previousMsgBytes)); - return new RequestMessage(m.getId(), m.getGroupId(), - m.getTimestamp(), previousMessageId, body.getLong(2)); + Author author = clientHelper.parseAndValidateAuthor(body.getList(2)); + return new RequestMessage(m.getId(), m.getGroupId(), m.getTimestamp(), + previousMessageId, author); } @Override public MailboxAcceptMessage parseMailboxAcceptMessage(Message m, - BdfList body) - throws FormatException { + BdfList body) throws FormatException { SessionId sessionId = new SessionId(body.getRaw(1)); byte[] previousMsgBytes = body.getOptionalRaw(2); MessageId previousMessageId = (previousMsgBytes == null ? null : new MessageId(previousMsgBytes)); byte[] ephemeralPublicKey = body.getRaw(3); long acceptTimestamp = body.getLong(4); - Map<TransportId, TransportProperties> transportProperties = clientHelper - .parseAndValidateTransportPropertiesMap(body.getDictionary(5)); return new MailboxAcceptMessage(m.getId(), m.getGroupId(), - m.getTimestamp(), - previousMessageId, sessionId, ephemeralPublicKey, - acceptTimestamp, transportProperties, body.getLong(5)); + m.getTimestamp(), previousMessageId, sessionId, + ephemeralPublicKey, acceptTimestamp); } @Override @@ -103,7 +88,7 @@ class MessageParserImpl implements MessageId previousMessageId = (previousMsgBytes == null ? null : new MessageId(previousMsgBytes)); return new DeclineMessage(m.getId(), m.getGroupId(), m.getTimestamp(), - previousMessageId, sessionId, body.getLong(3)); + previousMessageId, sessionId); } @Override @@ -122,15 +107,14 @@ class MessageParserImpl implements } @Override - public AbortMessage parseAbortMessage( - Message m, BdfList body) + public AbortMessage parseAbortMessage(Message m, BdfList body) throws FormatException { SessionId sessionId = new SessionId(body.getRaw(1)); byte[] previousMsgBytes = body.getOptionalRaw(2); MessageId previousMessageId = (previousMsgBytes == null ? null : new MessageId(previousMsgBytes)); return new AbortMessage(m.getId(), m.getGroupId(), m.getTimestamp(), - previousMessageId, sessionId, body.getLong(3)); + previousMessageId, sessionId); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxProtocolEngine.java new file mode 100644 index 000000000..901c6efca --- /dev/null +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxProtocolEngine.java @@ -0,0 +1,182 @@ +package org.briarproject.briar.mailbox; + +import org.briarproject.bramble.api.FormatException; +import org.briarproject.bramble.api.client.ClientHelper; +import org.briarproject.bramble.api.client.ContactGroupFactory; +import org.briarproject.bramble.api.contact.ContactManager; +import org.briarproject.bramble.api.crypto.KeyPair; +import org.briarproject.bramble.api.data.BdfDictionary; +import org.briarproject.bramble.api.db.DatabaseComponent; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.identity.IdentityManager; +import org.briarproject.bramble.api.identity.LocalAuthor; +import org.briarproject.bramble.api.sync.Message; +import org.briarproject.bramble.api.sync.MessageId; +import org.briarproject.bramble.api.system.Clock; +import org.briarproject.briar.api.client.MessageTracker; +import org.briarproject.briar.api.client.SessionId; +import org.briarproject.briar.api.mailbox.event.MailboxIntroductionRequestReceivedEvent; + +import javax.annotation.Nullable; +import javax.inject.Inject; + +import static org.briarproject.briar.mailbox.IntroduceeState.AWAIT_REMOTE_RESPONSE; + +class MailboxProtocolEngine extends AbstractProtocolEngine<MailboxSession> { + + @Inject + MailboxProtocolEngine(DatabaseComponent db, ClientHelper clientHelper, + ContactManager contactManager, + ContactGroupFactory contactGroupFactory, + MessageTracker messageTracker, IdentityManager identityManager, + MailboxMessageParser messageParser, + MailboxMessageEncoder messageEncoder, Clock clock, + MailboxIntroductionCrypto crypto) { + super(db, clientHelper, contactManager, contactGroupFactory, + messageTracker, identityManager, messageParser, messageEncoder, + clock, crypto); + } + + @Override + public MailboxSession onRequestAction(Transaction txn, + MailboxSession session, long timestamp) throws DbException { + return null; + } + + @Override + public MailboxSession onAcceptAction(Transaction txn, + MailboxSession session, long timestamp) throws DbException { + return null; + } + + @Override + public MailboxSession onDeclineAction(Transaction txn, + MailboxSession session, long timestamp) throws DbException { + return null; + } + + @Override + public MailboxSession onRequestMessage(Transaction txn, + MailboxSession session, RequestMessage m) + throws DbException, FormatException { + switch (session.getState()) { + case START: + return onRemoteRequest(txn, session, m); + case AWAIT_LOCAL_RESPONSE: + case LOCAL_DECLINED: + case LOCAL_ACCEPTED: + case AWAIT_REMOTE_RESPONSE: + case MAILBOX_ADDED: + return abort(txn, session); + default: + throw new AssertionError(); + } + } + + private MailboxSession onRemoteRequest(Transaction txn, MailboxSession s, + RequestMessage m) throws DbException { + // The dependency, if any, must be the last remote message + if (isInvalidDependency(s, m.getPreviousMessageId())) + return abort(txn, s); + + // Add SessionId to message metadata + addSessionId(txn, m.getMessageId(), s.getSessionId()); + + // Broadcast IntroductionRequestReceivedEvent + LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); + txn.attach(new MailboxIntroductionRequestReceivedEvent( + localAuthor.getId())); + + // Create ephemeral key pair and get local transport properties + KeyPair keyPair = crypto.generateKeyPair(); + byte[] publicKey = keyPair.getPublic().getEncoded(); + byte[] privateKey = keyPair.getPrivate().getEncoded(); + long localTimestamp = clock.currentTimeMillis(); + // Send ephemeral public key and timestamp back + Message reply = + sendMailboxAcceptMessage(txn, s, localTimestamp, publicKey, + localTimestamp, s.getMessageCounter()); + + //TODO: Check for reasons to decline and if any, move to LOCAL_DECLINE + // Move to the AWAIT_REMOTE_RESPONSE state + return MailboxSession + .addLocalAccept(s, AWAIT_REMOTE_RESPONSE, reply, publicKey, + privateKey, localTimestamp); + } + + private MailboxSession abort(Transaction txn, MailboxSession s) + throws DbException { + /* + // Mark the request message unavailable to answer + markRequestsUnavailableToAnswer(txn, s); + + // Send an ABORT message + Message sent = sendAbortMessage(txn, s, getLocalTimestamp(s)); + + // Broadcast abort event for testing + txn.attach(new IntroductionAbortedEvent(s.getSessionId())); + + // Reset the session back to initial state + return IntroduceeSession.clear(s, START, sent.getId(), + sent.getTimestamp(), s.getLastRemoteMessageId()); + */ + return null; + } + + @Override + public MailboxSession onMailboxAcceptMessage(Transaction txn, + MailboxSession session, MailboxAcceptMessage m) + throws DbException, FormatException { + return null; + } + + @Override + public MailboxSession onContactAcceptMessage(Transaction txn, + MailboxSession session, MailboxAcceptMessage m) + throws DbException, FormatException { + return null; + } + + @Override + public MailboxSession onDeclineMessage(Transaction txn, + MailboxSession session, DeclineMessage m) + throws DbException, FormatException { + return null; + } + + @Override + public MailboxSession onAuthMessage(Transaction txn, MailboxSession session, + MailboxAuthMessage m) throws DbException, FormatException { + return null; + } + + @Override + public MailboxSession onAbortMessage(Transaction txn, + MailboxSession session, AbortMessage m) + throws DbException, FormatException { + return null; + } + + + private boolean isInvalidDependency(IntroduceeSession s, + @Nullable MessageId dependency) { + return isInvalidDependency(s.getLastRemoteMessageId(), dependency); + } + + private long getLocalTimestamp(IntroduceeSession s) { + return getLocalTimestamp(s.getLocalTimestamp(), + s.getRequestTimestamp()); + } + + private void addSessionId(Transaction txn, MessageId m, SessionId sessionId) + throws DbException { + BdfDictionary meta = new BdfDictionary(); + messageEncoder.addSessionId(meta, sessionId); + try { + clientHelper.mergeMessageMetadata(txn, m, meta); + } catch (FormatException e) { + throw new AssertionError(e); + } + } +} diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSession.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSession.java index edf1f0957..54f46c749 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSession.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSession.java @@ -36,8 +36,7 @@ class MailboxSession extends IntroduceeSession { static MailboxSession getInitial(GroupId contactGroupId, SessionId sessionId, Author introducer, boolean localIsAlice, Author remoteAuthor) { - Local local = - new Local(localIsAlice, null, -1, null, null, -1, null); + Local local = new Local(localIsAlice, null, -1, null, null, -1, null); Remote remote = new Remote(!localIsAlice, remoteAuthor, null, null, null, -1, null); @@ -45,28 +44,19 @@ class MailboxSession extends IntroduceeSession { introducer, local, remote, null, null, 0); } - static MailboxSession addRemoteRequest( - MailboxSession s, - IntroduceeState state, - ContactRequestMessage m, byte[] ephemeralPublicKey, - byte[] ephemeralPrivateKey, - long acceptTimestamp, boolean alice) { - Local local = new Local(alice, m.getMessageId(), - m.getTimestamp(), ephemeralPublicKey, ephemeralPrivateKey, - acceptTimestamp, null); - Remote remote = - new Remote(!alice, s.remote.author, m.getMessageId(), - m.getEphemeralPublicKey(), null, m.getAcceptTimestamp(), - null); + static MailboxSession addLocalAccept(MailboxSession s, + IntroduceeState state, Message m, byte[] ephemeralPublicKey, + byte[] ephemeralPrivateKey, long acceptTimestamp) { + Local local = new Local(s.local.alice, m.getId(), m.getTimestamp(), + ephemeralPublicKey, ephemeralPrivateKey, acceptTimestamp, null); return new MailboxSession(s.getSessionId(), state, m.getTimestamp(), - s.contactGroupId, s.introducer, local, remote, s.masterKey, - s.transportKeys, s.getSessionCounter()); + s.contactGroupId, s.introducer, local, s.remote, s.masterKey, + s.transportKeys, s.getMessageCounter() + 1); } - static MailboxSession addLocalAuth( - MailboxSession s, - IntroduceeState state, Message m, SecretKey masterKey, - SecretKey aliceMacKey, SecretKey bobMacKey) { + static MailboxSession addLocalAuth(MailboxSession s, IntroduceeState state, + Message m, SecretKey masterKey, SecretKey aliceMacKey, + SecretKey bobMacKey) { // add mac key and sent message Local local = new Local(s.local.alice, m.getId(), m.getTimestamp(), s.local.ephemeralPublicKey, s.local.ephemeralPrivateKey, @@ -81,21 +71,19 @@ class MailboxSession extends IntroduceeSession { return new MailboxSession(s.getSessionId(), state, s.getRequestTimestamp(), s.contactGroupId, s.introducer, local, remote, masterKey.getBytes(), s.transportKeys, - s.getSessionCounter()); + s.getMessageCounter()); } - static MailboxSession awaitAuth( - MailboxSession s, MailboxAuthMessage m, + static MailboxSession awaitAuth(MailboxSession s, MailboxAuthMessage m, Message sent, @Nullable Map<TransportId, KeySetId> transportKeys) { Local local = new Local(s.local, sent.getId(), sent.getTimestamp()); Remote remote = new Remote(s.remote, m.getMessageId()); return new MailboxSession(s.getSessionId(), AWAIT_REMOTE_RESPONSE, s.getRequestTimestamp(), s.contactGroupId, s.introducer, local, - remote, null, transportKeys, s.getSessionCounter()); + remote, null, transportKeys, s.getMessageCounter()); } - static MailboxSession clear( - MailboxSession s, IntroduceeState state, + static MailboxSession clear(MailboxSession s, IntroduceeState state, @Nullable MessageId lastLocalMessageId, long localTimestamp, @Nullable MessageId lastRemoteMessageId) { Local local = @@ -106,7 +94,7 @@ class MailboxSession extends IntroduceeSession { null, null, -1, null); return new MailboxSession(s.getSessionId(), state, s.getRequestTimestamp(), s.contactGroupId, s.introducer, local, - remote, null, null, s.getSessionCounter()); + remote, null, null, s.getMessageCounter()); } @Override diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/SessionEncoder.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionEncoder.java similarity index 93% rename from briar-core/src/main/java/org/briarproject/briar/mailbox/SessionEncoder.java rename to briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionEncoder.java index c781f014a..6ac94a2a3 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/SessionEncoder.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionEncoder.java @@ -5,7 +5,7 @@ import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; @NotNullByDefault -interface SessionEncoder { +interface MailboxSessionEncoder { BdfDictionary getIntroduceeSessionsByIntroducerQuery(Author introducer); diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/SessionEncoderImpl.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionEncoderImpl.java similarity index 98% rename from briar-core/src/main/java/org/briarproject/briar/mailbox/SessionEncoderImpl.java rename to briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionEncoderImpl.java index 413048223..d8ef32f1c 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/SessionEncoderImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionEncoderImpl.java @@ -45,13 +45,13 @@ import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_T @Immutable @NotNullByDefault -class SessionEncoderImpl implements - SessionEncoder { +class MailboxSessionEncoderImpl implements + MailboxSessionEncoder { private final ClientHelper clientHelper; @Inject - SessionEncoderImpl(ClientHelper clientHelper) { + MailboxSessionEncoderImpl(ClientHelper clientHelper) { this.clientHelper = clientHelper; } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/SessionParser.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionParser.java similarity index 87% rename from briar-core/src/main/java/org/briarproject/briar/mailbox/SessionParser.java rename to briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionParser.java index a66a24f70..0d42aefd7 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/SessionParser.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionParser.java @@ -8,12 +8,14 @@ import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.mailbox.Role; @NotNullByDefault -interface SessionParser { +interface MailboxSessionParser { BdfDictionary getSessionQuery(SessionId s); Role getRole(BdfDictionary d) throws FormatException; + long getMessageCounter(BdfDictionary d) throws FormatException; + OwnerSession parseOwnerSession(BdfDictionary d) throws FormatException; diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/SessionParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionParserImpl.java similarity index 89% rename from briar-core/src/main/java/org/briarproject/briar/mailbox/SessionParserImpl.java rename to briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionParserImpl.java index ebc687e95..d3f995611 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/SessionParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MailboxSessionParserImpl.java @@ -24,6 +24,9 @@ import javax.inject.Inject; import static org.briarproject.briar.api.mailbox.Role.INTRODUCEE; import static org.briarproject.briar.api.mailbox.Role.OWNER; import static org.briarproject.briar.api.mailbox.Role.fromValue; +import static org.briarproject.briar.mailbox.IntroduceeSession.Local; +import static org.briarproject.briar.mailbox.IntroduceeSession.Remote; +import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_COUNTER; import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_ACCEPT_TIMESTAMP; import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_ALICE; import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_AUTHOR; @@ -48,17 +51,15 @@ import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_S import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_STATE; import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_TRANSPORT_KEYS; import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_TRANSPORT_PROPERTIES; -import static org.briarproject.briar.mailbox.MailboxSession.Local; -import static org.briarproject.briar.mailbox.MailboxSession.Remote; @Immutable @NotNullByDefault -class SessionParserImpl implements SessionParser { +class MailboxSessionParserImpl implements MailboxSessionParser { private final ClientHelper clientHelper; @Inject - SessionParserImpl(ClientHelper clientHelper) { + MailboxSessionParserImpl(ClientHelper clientHelper) { this.clientHelper = clientHelper; } @@ -72,6 +73,11 @@ class SessionParserImpl implements SessionParser { return fromValue(d.getLong(SESSION_KEY_ROLE).intValue()); } + @Override + public long getMessageCounter(BdfDictionary d) throws FormatException { + return d.getLong(MSG_KEY_COUNTER); + } + @Override public OwnerSession parseOwnerSession(BdfDictionary d) throws FormatException { @@ -84,12 +90,11 @@ class SessionParserImpl implements SessionParser { d.getDictionary(SESSION_KEY_INTRODUCEE_A)); Introducee introduceeB = parseIntroducee(sessionId, d.getDictionary(SESSION_KEY_INTRODUCEE_B)); - return new OwnerSession(sessionId, state, requestTimestamp, - introduceeA, introduceeB, sessionCounter); + return new OwnerSession(sessionId, state, requestTimestamp, introduceeA, + introduceeB, sessionCounter); } - private Introducee parseIntroducee(SessionId sessionId, - BdfDictionary d) + private Introducee parseIntroducee(SessionId sessionId, BdfDictionary d) throws FormatException { MessageId lastLocalMessageId = getMessageId(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID); @@ -98,14 +103,12 @@ class SessionParserImpl implements SessionParser { long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP); GroupId groupId = getGroupId(d, SESSION_KEY_GROUP_ID); Author author = getAuthor(d, SESSION_KEY_AUTHOR); - return new Introducee(sessionId, groupId, author, - localTimestamp, + return new Introducee(sessionId, groupId, author, localTimestamp, lastLocalMessageId, lastRemoteMessageId); } @Override - public MailboxSession parseMailboxSession( - GroupId introducerGroupId, + public MailboxSession parseMailboxSession(GroupId introducerGroupId, BdfDictionary d) throws FormatException { if (getRole(d) != INTRODUCEE) throw new IllegalArgumentException(); SessionId sessionId = getSessionId(d); @@ -119,8 +122,8 @@ class SessionParserImpl implements SessionParser { Map<TransportId, KeySetId> transportKeys = parseTransportKeys( d.getOptionalDictionary(SESSION_KEY_TRANSPORT_KEYS)); return new MailboxSession(sessionId, state, requestTimestamp, - introducerGroupId, introducer, local, remote, - masterKey, transportKeys, sessionCounter); + introducerGroupId, introducer, local, remote, masterKey, + transportKeys, sessionCounter); } private Local parseLocal(BdfDictionary d) throws FormatException { @@ -158,8 +161,7 @@ class SessionParserImpl implements SessionParser { .parseAndValidateTransportPropertiesMap(tpDict); long acceptTimestamp = d.getLong(SESSION_KEY_ACCEPT_TIMESTAMP); byte[] macKey = d.getOptionalRaw(SESSION_KEY_MAC_KEY); - return new Remote(alice, remoteAuthor, - lastRemoteMessageId, + return new Remote(alice, remoteAuthor, lastRemoteMessageId, ephemeralPublicKey, transportProperties, acceptTimestamp, macKey); } @@ -201,8 +203,7 @@ class SessionParserImpl implements SessionParser { Map<TransportId, KeySetId> map = new HashMap<>(d.size()); for (String key : d.keySet()) { map.put(new TransportId(key), - new KeySetId(d.getLong(key).intValue()) - ); + new KeySetId(d.getLong(key).intValue())); } return map; } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageMetadata.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageMetadata.java new file mode 100644 index 000000000..9c0c50617 --- /dev/null +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/MessageMetadata.java @@ -0,0 +1,55 @@ +package org.briarproject.briar.mailbox; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.briar.api.client.SessionId; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +@Immutable +@NotNullByDefault +class MessageMetadata { + + private final MessageType type; + @Nullable + private final SessionId sessionId; + private final long timestamp, counter; + private final boolean local; + private final boolean available; + + MessageMetadata(MessageType type, @Nullable SessionId sessionId, + long timestamp, boolean local, long counter, boolean available) { + this.type = type; + this.sessionId = sessionId; + this.timestamp = timestamp; + this.local = local; + this.counter = counter; + this.available = available; + } + + MessageType getMessageType() { + return type; + } + + @Nullable + public SessionId getSessionId() { + return sessionId; + } + + long getTimestamp() { + return timestamp; + } + + boolean isLocal() { + return local; + } + + long getCounter() { + return counter; + } + + boolean isAvailableToAnswer() { + return available; + } + +} diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/OwnerProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/OwnerProtocolEngine.java index 3aa608b08..adb82656b 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/OwnerProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/OwnerProtocolEngine.java @@ -7,38 +7,37 @@ import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.system.Clock; import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.ProtocolStateException; +import org.briarproject.briar.api.mailbox.event.MailboxIntroductionResponseReceivedEvent; import javax.inject.Inject; +import static org.briarproject.briar.mailbox.OwnerState.AWAIT_RESPONSE_B; import static org.briarproject.briar.mailbox.OwnerState.AWAIT_RESPONSE_M; class OwnerProtocolEngine extends AbstractProtocolEngine<OwnerSession> { @Inject - OwnerProtocolEngine( - DatabaseComponent db, - ClientHelper clientHelper, + OwnerProtocolEngine(DatabaseComponent db, ClientHelper clientHelper, ContactManager contactManager, ContactGroupFactory contactGroupFactory, - MessageTracker messageTracker, - IdentityManager identityManager, - MessageParser messageParser, - MessageEncoder messageEncoder, - Clock clock) { + MessageTracker messageTracker, IdentityManager identityManager, + MailboxMessageParser messageParser, + MailboxMessageEncoder messageEncoder, Clock clock, + MailboxIntroductionCrypto crypto) { super(db, clientHelper, contactManager, contactGroupFactory, messageTracker, identityManager, messageParser, messageEncoder, - clock); + clock, crypto); } @Override public OwnerSession onRequestAction(Transaction txn, OwnerSession s, - long timestamp) - throws DbException { + long timestamp) throws DbException { switch (s.getState()) { case START: return onLocalRequest(txn, s, timestamp); @@ -69,7 +68,7 @@ class OwnerProtocolEngine extends AbstractProtocolEngine<OwnerSession> { @Override public OwnerSession onRequestMessage(Transaction txn, OwnerSession session, RequestMessage m) throws DbException, FormatException { -// return abort(txn, session); + // return abort(txn, session); throw new UnsupportedOperationException(); } @@ -98,9 +97,21 @@ class OwnerProtocolEngine extends AbstractProtocolEngine<OwnerSession> { throw new UnsupportedOperationException(); } - private void onMailboxAccept(Transaction txn, OwnerSession s, - MailboxAcceptMessage m) { - + private OwnerSession onMailboxAccept(Transaction txn, OwnerSession s, + MailboxAcceptMessage m) throws DbException { + // The dependency, if any, must be the last remote message + if (isInvalidDependency(s.getMailbox().lastRemoteMessageId, + m.getPreviousMessageId())) return abort(txn, s); + Message forward = sendMailboxAcceptMessage(txn, s.getIntroducee(), + clock.currentTimeMillis(), m.getEphemeralPublicKey(), + m.getAcceptTimestamp(), s.getMessageCounter()); + broadcastMailboxIntroductionResponseReceived(txn, s.getMailbox().author, + s.getIntroducee().author); + return new OwnerSession(s.getSessionId(), AWAIT_RESPONSE_B, + s.getRequestTimestamp(), + new Introducee(s.getMailbox(), m.getMessageId()), + new Introducee(s.getIntroducee(), forward), + s.getMessageCounter() + 1); } @Override @@ -122,29 +133,37 @@ class OwnerProtocolEngine extends AbstractProtocolEngine<OwnerSession> { } private OwnerSession onLocalRequest(Transaction txn, OwnerSession s, - long timestamp) - throws DbException { + long timestamp) throws DbException { // Send REQUEST messages long maxIntroduceeTimestamp = Math.max(getLocalTimestamp(s, s.getMailbox()), getLocalTimestamp(s, s.getIntroducee())); long localTimestamp = Math.max(timestamp, maxIntroduceeTimestamp); Message sentMailbox = - sendMailboxRequestMessage(txn, s.getMailbox(), localTimestamp); - /* - // Track the message - messageTracker.trackOutgoingMessage(txn, sentMailbox); - */ + sendMailboxRequestMessage(txn, s.getMailbox(), localTimestamp, + s.getIntroducee().author, s.getMessageCounter()); // Move to the AWAIT_RESPONSES state Introducee mailbox = new Introducee(s.getMailbox(), sentMailbox); Introducee b = new Introducee(s.getIntroducee().sessionId, s.getIntroducee().groupId, s.getIntroducee().author); return new OwnerSession(s.getSessionId(), AWAIT_RESPONSE_M, - localTimestamp, mailbox, b, s.getSessionCounter()); + localTimestamp, mailbox, b, s.getMessageCounter()); } private long getLocalTimestamp(OwnerSession s, PeerSession p) { return getLocalTimestamp(p.getLocalTimestamp(), s.getRequestTimestamp()); } + + private OwnerSession abort(Transaction txn, Session s) { + return null; + } + + void broadcastMailboxIntroductionResponseReceived(Transaction txn, + Author from, Author to) { + MailboxIntroductionResponseReceivedEvent e = + new MailboxIntroductionResponseReceivedEvent(to, from); + txn.attach(e); + } + } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/OwnerSession.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/OwnerSession.java index d63caea3d..ec7c9c448 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/OwnerSession.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/OwnerSession.java @@ -9,6 +9,7 @@ import org.briarproject.briar.api.mailbox.Role; import javax.annotation.concurrent.Immutable; import static org.briarproject.briar.api.mailbox.Role.MAILBOX; +import static org.briarproject.briar.api.mailbox.Role.OWNER; @Immutable @NotNullByDefault @@ -33,7 +34,7 @@ class OwnerSession extends Session<OwnerState> { @Override Role getRole() { - return MAILBOX; + return OWNER; } Introducee getMailbox() { diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/RequestMessage.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/RequestMessage.java index 5c060c9e3..2e25c9094 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/RequestMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/RequestMessage.java @@ -1,5 +1,6 @@ package org.briarproject.briar.mailbox; +import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; @@ -11,9 +12,17 @@ import javax.annotation.concurrent.Immutable; @NotNullByDefault class RequestMessage extends AbstractMailboxIntroductionMessage { + + private final Author author; + protected RequestMessage(MessageId messageId, GroupId groupId, long timestamp, @Nullable MessageId previousMessageId, - long messageCounter) { - super(messageId, groupId, timestamp, previousMessageId, messageCounter); + Author author) { + super(messageId, groupId, timestamp, previousMessageId); + this.author = author; + } + + public Author getAuthor() { + return author; } } diff --git a/briar-core/src/main/java/org/briarproject/briar/mailbox/Session.java b/briar-core/src/main/java/org/briarproject/briar/mailbox/Session.java index 5f1305600..5e7a75bac 100644 --- a/briar-core/src/main/java/org/briarproject/briar/mailbox/Session.java +++ b/briar-core/src/main/java/org/briarproject/briar/mailbox/Session.java @@ -13,14 +13,14 @@ abstract class Session<S extends State> { private final SessionId sessionId; private final S state; private final long requestTimestamp; - private final long sessionCounter; + private long messageCounter; Session(SessionId sessionId, S state, long requestTimestamp, - long sessionCounter) { + long messageCounter) { this.sessionId = sessionId; this.state = state; this.requestTimestamp = requestTimestamp; - this.sessionCounter = sessionCounter; + this.messageCounter = messageCounter; } abstract Role getRole(); @@ -37,8 +37,12 @@ abstract class Session<S extends State> { return requestTimestamp; } - long getSessionCounter() { - return sessionCounter; + synchronized long getMessageCounter() { + return messageCounter; + } + + synchronized void increaseMessageCounter() { + messageCounter++; } } diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java index af46561a3..f70c239ed 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java @@ -107,6 +107,7 @@ class MessagingManagerImpl extends ConversationClientImpl @Override public void onClientVisibilityChanging(Transaction txn, Contact c, Visibility v) throws DbException { + if(!getApplicableContactTypes().contains(c.getType())) return; // Apply the client's visibility to the contact group Group g = getContactGroup(c); db.setGroupVisibility(txn, c.getId(), g.getId(), v); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java index b5a771970..5083da073 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java @@ -588,6 +588,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl @Override public void onClientVisibilityChanging(Transaction txn, Contact c, Visibility v) throws DbException { + if(!getApplicableContactTypes().contains(c.getType())) return; // Apply the client's visibility to the contact group Group g = getContactGroup(c); db.setGroupVisibility(txn, c.getId(), g.getId(), v); @@ -600,6 +601,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl private void onPrivateGroupClientVisibilityChanging(Transaction txn, Contact c, Visibility client) throws DbException { try { + if(!getApplicableContactTypes().contains(c.getType())) return; Collection<Group> shareables = db.getGroups(txn, PrivateGroupManager.CLIENT_ID, PrivateGroupManager.MAJOR_VERSION); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java index 7b9c81867..f80a38a97 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java @@ -510,6 +510,7 @@ abstract class SharingManagerImpl<S extends Shareable> @Override public void onClientVisibilityChanging(Transaction txn, Contact c, Visibility v) throws DbException { + if(!getApplicableContactTypes().contains(c.getType())) return; // Apply the client's visibility to the contact group Group g = getContactGroup(c); db.setGroupVisibility(txn, c.getId(), g.getId(), v); @@ -523,6 +524,7 @@ abstract class SharingManagerImpl<S extends Shareable> private void onShareableClientVisibilityChanging(Transaction txn, Contact c, Visibility client) throws DbException { try { + if(!getApplicableContactTypes().contains(c.getType())) return; Collection<Group> shareables = db.getGroups(txn, getShareableClientId(), getShareableMajorVersion()); Map<GroupId, Visibility> m = getPreferredVisibilities(txn, c); diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java index b3161af64..341936e3c 100644 --- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java @@ -119,6 +119,10 @@ public class IntroductionIntegrationTest c2 = DaggerIntroductionIntegrationTestComponent.builder() .testDatabaseModule(new TestDatabaseModule(t2Dir)).build(); injectEagerSingletons(c2); + + cMailbox = DaggerIntroductionIntegrationTestComponent.builder() + .testDatabaseModule(new TestDatabaseModule(t3Dir)).build(); + injectEagerSingletons(cMailbox); } @Test diff --git a/briar-core/src/test/java/org/briarproject/briar/mailbox/MailboxIntroductionIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/mailbox/MailboxIntroductionIntegrationTest.java index c8e83d3cd..3d794f9eb 100644 --- a/briar-core/src/test/java/org/briarproject/briar/mailbox/MailboxIntroductionIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/mailbox/MailboxIntroductionIntegrationTest.java @@ -5,7 +5,6 @@ import net.jodah.concurrentunit.Waiter; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.contact.Contact; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.PrivateMailbox; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfEntry; @@ -14,6 +13,7 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.identity.Author; +import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; @@ -24,14 +24,14 @@ import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.test.TestDatabaseModule; import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.introduction.IntroductionMessage; -import org.briarproject.briar.api.introduction.IntroductionRequest; -import org.briarproject.briar.api.introduction.IntroductionResponse; import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent; -import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent; import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent; import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent; import org.briarproject.briar.api.mailbox.MailboxIntroductionManager; +import org.briarproject.briar.api.mailbox.event.MailboxIntroductionRequestReceivedEvent; +import org.briarproject.briar.api.mailbox.event.MailboxIntroductionResponseReceivedEvent; import org.briarproject.briar.test.BriarIntegrationTest; +import org.briarproject.briar.test.BriarIntegrationTestComponent; import org.junit.Before; import org.junit.Test; @@ -42,8 +42,8 @@ import java.util.concurrent.TimeoutException; import static org.briarproject.bramble.test.TestPluginConfigModule.TRANSPORT_ID; import static org.briarproject.bramble.test.TestUtils.getTransportProperties; -import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_ID; import static org.briarproject.briar.api.introduction.IntroductionManager.MAJOR_VERSION; +import static org.briarproject.briar.api.mailbox.MailboxIntroductionManager.CLIENT_ID; import static org.briarproject.briar.mailbox.IntroductionConstants.MSG_KEY_MESSAGE_TYPE; import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_AUTHOR; import static org.briarproject.briar.mailbox.IntroductionConstants.SESSION_KEY_INTRODUCEE_A; @@ -54,8 +54,7 @@ import static org.briarproject.briar.mailbox.MessageType.MAILBOX_ACCEPT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -public class MailboxIntroductionIntegrationTest - extends +public class MailboxIntroductionIntegrationTest extends BriarIntegrationTest<MailboxIntroductionIntegrationTestComponent> { // objects accessed from background threads need to be volatile @@ -68,6 +67,7 @@ public class MailboxIntroductionIntegrationTest private OwnerListener listener0; private IntroduceeListener listener1; private IntroduceeListener listener2; + private IntroduceeListener listenerMailbox; /* interface StateVisitor { @@ -114,23 +114,34 @@ public class MailboxIntroductionIntegrationTest injectEagerSingletons(cMailbox); } + @Override + protected void injectEagerSingletons( + BriarIntegrationTestComponent component) { + super.injectEagerSingletons(component); + component.inject(new MailboxIntroductionModule.EagerSingletons()); + } + @Test public void testIntroductionSession() throws Exception { - addListeners(true, true); + addListeners(true, true, true); // make introduction long time = clock.currentTimeMillis(); Contact introducee = contact1From0; PrivateMailbox mailbox = privateMailboxFrom0; - introductionManager0 - .makeIntroduction(mailbox, introducee, time); + introductionManager0.makeIntroduction(mailbox, introducee, time); // sync first REQUEST message sync0ToMailbox(1, true); eventWaiter.await(TIMEOUT, 1); - assertTrue(listener1.requestReceived); - assertEquals(mailbox.getAuthor().getName(), - listener1.getRequest().getName()); + assertTrue(listenerMailbox.requestReceived); + assertEquals(authorMailbox.getId(), listenerMailbox.getRequest()); + // sync first REQUEST message + syncMailboxTo0(1, true); + eventWaiter.await(TIMEOUT, 1); + assertTrue(listener0.response1Received); + assertEquals(authorMailbox.getId(), listener0.getAuthors()[0]); + assertEquals(author1.getId(), listener0.getAuthors()[1]); } @@ -139,16 +150,23 @@ public class MailboxIntroductionIntegrationTest TransportPropertyManager tpm0 = c0.getTransportPropertyManager(); TransportPropertyManager tpm1 = c1.getTransportPropertyManager(); TransportPropertyManager tpm2 = c2.getTransportPropertyManager(); + TransportPropertyManager tpmMailbox = + cMailbox.getTransportPropertyManager(); tpm0.mergeLocalProperties(TRANSPORT_ID, getTransportProperties(2)); sync0To1(1, true); sync0To2(1, true); + sync0ToMailbox(1, true); tpm1.mergeLocalProperties(TRANSPORT_ID, getTransportProperties(2)); sync1To0(1, true); tpm2.mergeLocalProperties(TRANSPORT_ID, getTransportProperties(2)); sync2To0(1, true); + + tpmMailbox + .mergeLocalProperties(TRANSPORT_ID, getTransportProperties(2)); + syncMailboxTo0(1, true); } private void assertMessagesAreAcked( @@ -158,7 +176,8 @@ public class MailboxIntroductionIntegrationTest } } - private void addListeners(boolean accept1, boolean accept2) { + private void addListeners(boolean accept1, boolean accept2, + boolean accept3) { // listen to events listener0 = new OwnerListener(); c0.getEventBus().addListener(listener0); @@ -166,6 +185,8 @@ public class MailboxIntroductionIntegrationTest c1.getEventBus().addListener(listener1); listener2 = new IntroduceeListener(2, accept2); c2.getEventBus().addListener(listener2); + listenerMailbox = new IntroduceeListener(3, accept3); + cMailbox.getEventBus().addListener(listenerMailbox); } @MethodsNotNullByDefault @@ -176,11 +197,15 @@ public class MailboxIntroductionIntegrationTest protected volatile Event latestEvent; @SuppressWarnings("WeakerAccess") - IntroductionResponse getResponse() { + AuthorId[] getAuthors() { assertTrue( - latestEvent instanceof IntroductionResponseReceivedEvent); - return ((IntroductionResponseReceivedEvent) latestEvent) - .getIntroductionResponse(); + latestEvent instanceof MailboxIntroductionResponseReceivedEvent); + AuthorId[] authors = + {((MailboxIntroductionResponseReceivedEvent) latestEvent) + .getFrom().getId(), + ((MailboxIntroductionResponseReceivedEvent) latestEvent) + .getTo().getId()}; + return authors; } } @@ -203,14 +228,11 @@ public class MailboxIntroductionIntegrationTest @Override public void eventOccurred(Event e) { - if (e instanceof IntroductionRequestReceivedEvent) { + if (e instanceof MailboxIntroductionRequestReceivedEvent) { latestEvent = e; - IntroductionRequestReceivedEvent introEvent = - ((IntroductionRequestReceivedEvent) e); + MailboxIntroductionRequestReceivedEvent introEvent = + (MailboxIntroductionRequestReceivedEvent) e; requestReceived = true; - IntroductionRequest ir = introEvent.getIntroductionRequest(); - ContactId contactId = introEvent.getContactId(); - sessionId = ir.getSessionId(); long time = clock.currentTimeMillis(); try { if (introducee == 1 && answerRequests) { @@ -245,11 +267,11 @@ public class MailboxIntroductionIntegrationTest } } - private IntroductionRequest getRequest() { + private AuthorId getRequest() { assertTrue( - latestEvent instanceof IntroductionRequestReceivedEvent); - return ((IntroductionRequestReceivedEvent) latestEvent) - .getIntroductionRequest(); + latestEvent instanceof MailboxIntroductionRequestReceivedEvent); + return ((MailboxIntroductionRequestReceivedEvent) latestEvent) + .getAuthorId(); } } @@ -261,28 +283,21 @@ public class MailboxIntroductionIntegrationTest @Override public void eventOccurred(Event e) { - if (e instanceof IntroductionResponseReceivedEvent) { + if (e instanceof MailboxIntroductionResponseReceivedEvent) { latestEvent = e; - ContactId c = - ((IntroductionResponseReceivedEvent) e) - .getContactId(); - if (c.equals(contactId1From0)) { + AuthorId from = ((MailboxIntroductionResponseReceivedEvent) e) + .getFrom().getId(); + if (from.equals(authorMailbox.getId())) { response1Received = true; - } else if (c.equals(contactId2From0)) { - response2Received = true; } eventWaiter.resume(); - } else if (e instanceof IntroductionAbortedEvent) { - latestEvent = e; - aborted = true; - eventWaiter.resume(); } } } - private void replacePreviousLocalMessageId(Author author, - BdfDictionary d, MessageId id) throws FormatException { + private void replacePreviousLocalMessageId(Author author, BdfDictionary d, + MessageId id) throws FormatException { BdfDictionary i1 = d.getDictionary(SESSION_KEY_INTRODUCEE_A); BdfDictionary i2 = d.getDictionary(SESSION_KEY_INTRODUCEE_B); Author a1 = clientHelper @@ -305,9 +320,8 @@ public class MailboxIntroductionIntegrationTest Contact contact, MessageType type) throws FormatException, DbException { Group g = introductionManager0.getContactGroup(contact); - BdfDictionary query = BdfDictionary.of( - new BdfEntry(MSG_KEY_MESSAGE_TYPE, type.getValue()) - ); + BdfDictionary query = BdfDictionary + .of(new BdfEntry(MSG_KEY_MESSAGE_TYPE, type.getValue())); Map<MessageId, BdfDictionary> map = ch.getMessageMetadataAsDictionary(g.getId(), query); assertEquals(1, map.size()); @@ -323,8 +337,7 @@ public class MailboxIntroductionIntegrationTest } else throw new AssertionError("Not implemented"); } - private OwnerSession getOwnerSession() - throws DbException, FormatException { + private OwnerSession getOwnerSession() throws DbException, FormatException { Map<MessageId, BdfDictionary> dicts = c0.getClientHelper() .getMessageMetadataAsDictionary(getLocalGroup().getId()); assertEquals(1, dicts.size()); diff --git a/briar-core/src/test/java/org/briarproject/briar/mailbox/MailboxIntroductionIntegrationTestComponent.java b/briar-core/src/test/java/org/briarproject/briar/mailbox/MailboxIntroductionIntegrationTestComponent.java index 80abea604..946855a73 100644 --- a/briar-core/src/test/java/org/briarproject/briar/mailbox/MailboxIntroductionIntegrationTestComponent.java +++ b/briar-core/src/test/java/org/briarproject/briar/mailbox/MailboxIntroductionIntegrationTestComponent.java @@ -67,11 +67,11 @@ interface MailboxIntroductionIntegrationTestComponent void inject(MailboxIntroductionIntegrationTest init); - MessageEncoder getMessageEncoder(); + MailboxMessageEncoder getMessageEncoder(); - MessageParser getMessageParser(); + MailboxMessageParser getMessageParser(); - SessionParser getSessionParser(); + MailboxSessionParser getSessionParser(); MailboxIntroductionCrypto getMailboxIntroductionCrypto(); diff --git a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java index 7c43ea31a..394d19204 100644 --- a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java @@ -187,7 +187,7 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone component.inject(new GroupInvitationModule.EagerSingletons()); component.inject(new IdentityModule.EagerSingletons()); component.inject(new IntroductionModule.EagerSingletons()); - component.inject(new MailboxIntroductionModule.EagerSingletons()); + // component.inject(new MailboxIntroductionModule.EagerSingletons()); component.inject(new LifecycleModule.EagerSingletons()); component.inject(new MessagingModule.EagerSingletons()); component.inject(new PrivateGroupModule.EagerSingletons()); -- GitLab