From ce74fcaab5a4056416c41fb7e077bb3eb4dd8ae1 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 21 Jun 2021 16:22:51 +0100 Subject: [PATCH] Store ID of message that triggered abort. --- .../IntroduceeProtocolEngine.java | 45 +++++----- .../IntroducerProtocolEngine.java | 84 +++++++++++-------- 2 files changed, 72 insertions(+), 57 deletions(-) diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java index 7f55f1a2a..41a3d71af 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java @@ -154,7 +154,8 @@ class IntroduceeProtocolEngine case REMOTE_ACCEPTED: case AWAIT_AUTH: case AWAIT_ACTIVATE: - return abort(txn, session); // Invalid in these states + // Invalid in these states + return abort(txn, session, m.getMessageId()); default: throw new AssertionError(); } @@ -174,7 +175,8 @@ class IntroduceeProtocolEngine case REMOTE_ACCEPTED: case AWAIT_AUTH: case AWAIT_ACTIVATE: - return abort(txn, session); // Invalid in these states + // Invalid in these states + return abort(txn, session, m.getMessageId()); default: throw new AssertionError(); } @@ -194,7 +196,8 @@ class IntroduceeProtocolEngine case REMOTE_ACCEPTED: case AWAIT_AUTH: case AWAIT_ACTIVATE: - return abort(txn, session); // Invalid in these states + // Invalid in these states + return abort(txn, session, m.getMessageId()); default: throw new AssertionError(); } @@ -213,7 +216,8 @@ class IntroduceeProtocolEngine case LOCAL_ACCEPTED: case REMOTE_ACCEPTED: case AWAIT_ACTIVATE: - return abort(txn, session); // Invalid in these states + // Invalid in these states + return abort(txn, session, m.getMessageId()); default: throw new AssertionError(); } @@ -232,7 +236,8 @@ class IntroduceeProtocolEngine case LOCAL_ACCEPTED: case REMOTE_ACCEPTED: case AWAIT_AUTH: - return abort(txn, session); // Invalid in these states + // Invalid in these states + return abort(txn, session, m.getMessageId()); default: throw new AssertionError(); } @@ -248,7 +253,7 @@ class IntroduceeProtocolEngine IntroduceeSession s, RequestMessage m) throws DbException { // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m.getMessageId()); // Mark the request visible in the UI and available to answer markMessageVisibleInUi(txn, m.getMessageId()); @@ -343,10 +348,10 @@ class IntroduceeProtocolEngine IntroduceeSession s, AcceptMessage m) throws DbException { // The timestamp must be higher than the last request message if (m.getTimestamp() <= s.getRequestTimestamp()) - return abort(txn, s); + return abort(txn, s, m.getMessageId()); // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m.getMessageId()); // Determine next state IntroduceeState state = @@ -365,10 +370,10 @@ class IntroduceeProtocolEngine IntroduceeSession s, DeclineMessage m) throws DbException { // The timestamp must be higher than the last request message if (m.getTimestamp() <= s.getRequestTimestamp()) - return abort(txn, s); + return abort(txn, s, m.getMessageId()); // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m.getMessageId()); // Mark the response visible in the UI markMessageVisibleInUi(txn, m.getMessageId()); @@ -398,10 +403,10 @@ class IntroduceeProtocolEngine throws DbException { // The timestamp must be higher than the last request message if (m.getTimestamp() <= s.getRequestTimestamp()) - return abort(txn, s); + return abort(txn, s, m.getMessageId()); // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m.getMessageId()); // Move to START state return IntroduceeSession.clear(s, START, s.getLastLocalMessageId(), @@ -423,7 +428,7 @@ class IntroduceeProtocolEngine signature = crypto.sign(ourMacKey, localAuthor.getPrivateKey()); } catch (GeneralSecurityException e) { logException(LOG, WARNING, e); - return abort(txn, s); + return abort(txn, s, s.getLastRemoteMessageId()); } if (s.getState() != AWAIT_AUTH) throw new AssertionError(); long localTimestamp = getTimestampForInvisibleMessage(s); @@ -436,14 +441,14 @@ class IntroduceeProtocolEngine IntroduceeSession s, AuthMessage m) throws DbException { // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m.getMessageId()); LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); try { crypto.verifyAuthMac(m.getMac(), s, localAuthor.getId()); crypto.verifySignature(m.getSignature(), s); } catch (GeneralSecurityException e) { - return abort(txn, s); + return abort(txn, s, m.getMessageId()); } long timestamp = Math.min(s.getLocal().acceptTimestamp, s.getRemote().acceptTimestamp); @@ -487,13 +492,13 @@ class IntroduceeProtocolEngine IntroduceeSession s, ActivateMessage m) throws DbException { // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m.getMessageId()); // Validate MAC try { crypto.verifyActivateMac(m.getMac(), s); } catch (GeneralSecurityException e) { - return abort(txn, s); + return abort(txn, s, m.getMessageId()); } // We might not have added transport keys @@ -522,8 +527,8 @@ class IntroduceeProtocolEngine s.getLocalTimestamp(), m.getMessageId()); } - private IntroduceeSession abort(Transaction txn, IntroduceeSession s) - throws DbException { + private IntroduceeSession abort(Transaction txn, IntroduceeSession s, + @Nullable MessageId lastRemoteMessageId) throws DbException { // Mark the request message unavailable to answer markRequestsUnavailableToAnswer(txn, s); @@ -536,7 +541,7 @@ class IntroduceeProtocolEngine // Reset the session back to initial state return IntroduceeSession.clear(s, START, sent.getId(), - sent.getTimestamp(), s.getLastRemoteMessageId()); + sent.getTimestamp(), lastRemoteMessageId); } private boolean isInvalidDependency(IntroduceeSession s, diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerProtocolEngine.java index f300c2d04..e2f511675 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroducerProtocolEngine.java @@ -115,7 +115,7 @@ class IntroducerProtocolEngine @Override public IntroducerSession onRequestMessage(Transaction txn, IntroducerSession s, RequestMessage m) throws DbException { - return abort(txn, s); // Invalid in this role + return abort(txn, s, m); // Invalid in this role } @Override @@ -136,7 +136,7 @@ class IntroducerProtocolEngine case AWAIT_ACTIVATES: case AWAIT_ACTIVATE_A: case AWAIT_ACTIVATE_B: - return abort(txn, s); // Invalid in these states + return abort(txn, s, m); // Invalid in these states default: throw new AssertionError(); } @@ -160,7 +160,7 @@ class IntroducerProtocolEngine case AWAIT_ACTIVATES: case AWAIT_ACTIVATE_A: case AWAIT_ACTIVATE_B: - return abort(txn, s); // Invalid in these states + return abort(txn, s, m); // Invalid in these states default: throw new AssertionError(); } @@ -183,7 +183,7 @@ class IntroducerProtocolEngine case AWAIT_ACTIVATES: case AWAIT_ACTIVATE_A: case AWAIT_ACTIVATE_B: - return abort(txn, s); // Invalid in these states + return abort(txn, s, m); // Invalid in these states default: throw new AssertionError(); } @@ -206,7 +206,7 @@ class IntroducerProtocolEngine case AWAIT_AUTHS: case AWAIT_AUTH_A: case AWAIT_AUTH_B: - return abort(txn, s); // Invalid in these states + return abort(txn, s, m); // Invalid in these states default: throw new AssertionError(); } @@ -244,17 +244,17 @@ class IntroducerProtocolEngine IntroducerSession s, AcceptMessage m) throws DbException { // The timestamp must be higher than the last request message if (m.getTimestamp() <= s.getRequestTimestamp()) - return abort(txn, s); + return abort(txn, s, m); // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getGroupId(), m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m); // The message must be expected in the current state boolean senderIsAlice = senderIsAlice(s, m); if (s.getState() != AWAIT_RESPONSES) { if (senderIsAlice && s.getState() != AWAIT_RESPONSE_A) - return abort(txn, s); + return abort(txn, s, m); else if (!senderIsAlice && s.getState() != AWAIT_RESPONSE_B) - return abort(txn, s); + return abort(txn, s, m); } // Mark the response visible in the UI @@ -309,16 +309,16 @@ class IntroducerProtocolEngine IntroducerSession s, AcceptMessage m) throws DbException { // The timestamp must be higher than the last request message if (m.getTimestamp() <= s.getRequestTimestamp()) - return abort(txn, s); + return abort(txn, s, m); // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getGroupId(), m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m); // The message must be expected in the current state boolean senderIsAlice = senderIsAlice(s, m); if (senderIsAlice && s.getState() != B_DECLINED) - return abort(txn, s); + return abort(txn, s, m); else if (!senderIsAlice && s.getState() != A_DECLINED) - return abort(txn, s); + return abort(txn, s, m); // Mark the response visible in the UI markMessageVisibleInUi(txn, m.getMessageId()); @@ -362,17 +362,17 @@ class IntroducerProtocolEngine IntroducerSession s, DeclineMessage m) throws DbException { // The timestamp must be higher than the last request message if (m.getTimestamp() <= s.getRequestTimestamp()) - return abort(txn, s); + return abort(txn, s, m); // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getGroupId(), m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m); // The message must be expected in the current state boolean senderIsAlice = senderIsAlice(s, m); if (s.getState() != AWAIT_RESPONSES) { if (senderIsAlice && s.getState() != AWAIT_RESPONSE_A) - return abort(txn, s); + return abort(txn, s, m); else if (!senderIsAlice && s.getState() != AWAIT_RESPONSE_B) - return abort(txn, s); + return abort(txn, s, m); } // Mark the response visible in the UI @@ -419,16 +419,16 @@ class IntroducerProtocolEngine IntroducerSession s, DeclineMessage m) throws DbException { // The timestamp must be higher than the last request message if (m.getTimestamp() <= s.getRequestTimestamp()) - return abort(txn, s); + return abort(txn, s, m); // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getGroupId(), m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m); // The message must be expected in the current state boolean senderIsAlice = senderIsAlice(s, m); if (senderIsAlice && s.getState() != B_DECLINED) - return abort(txn, s); + return abort(txn, s, m); else if (!senderIsAlice && s.getState() != A_DECLINED) - return abort(txn, s); + return abort(txn, s, m); // Mark the response visible in the UI markMessageVisibleInUi(txn, m.getMessageId()); @@ -470,14 +470,14 @@ class IntroducerProtocolEngine IntroducerSession s, AuthMessage m) throws DbException { // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getGroupId(), m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m); // The message must be expected in the current state boolean senderIsAlice = senderIsAlice(s, m); if (s.getState() != AWAIT_AUTHS) { if (senderIsAlice && s.getState() != AWAIT_AUTH_A) - return abort(txn, s); + return abort(txn, s, m); else if (!senderIsAlice && s.getState() != AWAIT_AUTH_B) - return abort(txn, s); + return abort(txn, s, m); } // Forward AUTH message @@ -506,14 +506,14 @@ class IntroducerProtocolEngine IntroducerSession s, ActivateMessage m) throws DbException { // The dependency, if any, must be the last remote message if (isInvalidDependency(s, m.getGroupId(), m.getPreviousMessageId())) - return abort(txn, s); + return abort(txn, s, m); // The message must be expected in the current state boolean senderIsAlice = senderIsAlice(s, m); if (s.getState() != AWAIT_ACTIVATES) { if (senderIsAlice && s.getState() != AWAIT_ACTIVATE_A) - return abort(txn, s); + return abort(txn, s, m); else if (!senderIsAlice && s.getState() != AWAIT_ACTIVATE_B) - return abort(txn, s); + return abort(txn, s, m); } // Forward ACTIVATE message @@ -588,21 +588,31 @@ class IntroducerProtocolEngine s.getRequestTimestamp(), introduceeA, introduceeB); } - private IntroducerSession abort(Transaction txn, IntroducerSession s) - throws DbException { + private IntroducerSession abort(Transaction txn, IntroducerSession s, + AbstractIntroductionMessage lastRemoteMessage) throws DbException { // Broadcast abort event for testing txn.attach(new IntroductionAbortedEvent(s.getSessionId())); + // Record the message that triggered the abort + Introducee introduceeA = s.getIntroduceeA(); + Introducee introduceeB = s.getIntroduceeB(); + if (senderIsAlice(s, lastRemoteMessage)) { + introduceeA = new Introducee(introduceeA, + lastRemoteMessage.getMessageId()); + } else { + introduceeB = new Introducee(introduceeB, + lastRemoteMessage.getMessageId()); + } + // Send an ABORT message to both introducees - long timestampA = - getTimestampForInvisibleMessage(s, s.getIntroduceeA()); - Message sentA = sendAbortMessage(txn, s.getIntroduceeA(), timestampA); - long timestampB = - getTimestampForInvisibleMessage(s, s.getIntroduceeB()); - Message sentB = sendAbortMessage(txn, s.getIntroduceeB(), timestampB); + long timestampA = getTimestampForInvisibleMessage(s, introduceeA); + Message sentA = sendAbortMessage(txn, introduceeA, timestampA); + long timestampB = getTimestampForInvisibleMessage(s, introduceeB); + Message sentB = sendAbortMessage(txn, introduceeB, timestampB); + // Reset the session back to initial state - Introducee introduceeA = new Introducee(s.getIntroduceeA(), sentA); - Introducee introduceeB = new Introducee(s.getIntroduceeB(), sentB); + introduceeA = new Introducee(introduceeA, sentA); + introduceeB = new Introducee(introduceeB, sentB); return new IntroducerSession(s.getSessionId(), START, s.getRequestTimestamp(), introduceeA, introduceeB); }