Support for an 'end session' protocol message.

1) On the push side, this message is a flag in PushMessageContent.
   Any secure message with that flag will terminate the current
   sessin.

2) On the SMS side, there is an "end session" wire type and
   the convention that a message with this wire type must be
   secure and contain the string "TERMINATE."
This commit is contained in:
Moxie Marlinspike
2014-02-19 13:46:49 -08:00
parent 0688dd0c2c
commit 19dddd7adf
32 changed files with 400 additions and 84 deletions

View File

@@ -0,0 +1,22 @@
package org.thoughtcrime.securesms.sms;
public class IncomingEndSessionMessage extends IncomingTextMessage {
public IncomingEndSessionMessage(IncomingTextMessage base) {
this(base, base.getMessageBody());
}
public IncomingEndSessionMessage(IncomingTextMessage base, String newBody) {
super(base, newBody);
}
@Override
public IncomingEndSessionMessage withMessageBody(String messageBody) {
return new IncomingEndSessionMessage(this, messageBody);
}
@Override
public boolean isEndSession() {
return true;
}
}

View File

@@ -216,6 +216,10 @@ public class IncomingTextMessage implements Parcelable {
return false;
}
public boolean isEndSession() {
return false;
}
public boolean isIdentityUpdate() {
return false;
}

View File

@@ -71,6 +71,8 @@ public class MultipartSmsMessageHandler {
return new IncomingKeyExchangeMessage(message.getBaseMessage(), strippedMessage);
} else if (message.getWireType() == MultipartSmsTransportMessage.WIRETYPE_PREKEY) {
return new IncomingPreKeyBundleMessage(message.getBaseMessage(), strippedMessage);
} else if (message.getWireType() == MultipartSmsTransportMessage.WIRETYPE_END_SESSION) {
return new IncomingEndSessionMessage(message.getBaseMessage(), strippedMessage);
} else {
return new IncomingEncryptedMessage(message.getBaseMessage(), strippedMessage);
}

View File

@@ -2,12 +2,14 @@ package org.thoughtcrime.securesms.sms;
import android.util.Log;
import org.thoughtcrime.securesms.protocol.EndSessionWirePrefix;
import org.thoughtcrime.securesms.protocol.KeyExchangeWirePrefix;
import org.thoughtcrime.securesms.protocol.PrekeyBundleWirePrefix;
import org.thoughtcrime.securesms.protocol.SecureMessageWirePrefix;
import org.thoughtcrime.securesms.protocol.WirePrefix;
import org.whispersystems.textsecure.util.Base64;
import org.whispersystems.textsecure.util.Conversions;
import org.whispersystems.textsecure.util.Hex;
import java.io.IOException;
import java.util.ArrayList;
@@ -21,9 +23,10 @@ public class MultipartSmsTransportMessage {
public static final int MULTI_MESSAGE_MULTIPART_OVERHEAD = 3;
public static final int FIRST_MULTI_MESSAGE_MULTIPART_OVERHEAD = 2;
public static final int WIRETYPE_SECURE = 1;
public static final int WIRETYPE_KEY = 2;
public static final int WIRETYPE_PREKEY = 3;
public static final int WIRETYPE_SECURE = 1;
public static final int WIRETYPE_KEY = 2;
public static final int WIRETYPE_PREKEY = 3;
public static final int WIRETYPE_END_SESSION = 4;
private static final int VERSION_OFFSET = 0;
private static final int MULTIPART_OFFSET = 1;
@@ -39,6 +42,7 @@ public class MultipartSmsTransportMessage {
if (WirePrefix.isEncryptedMessage(message.getMessageBody())) wireType = WIRETYPE_SECURE;
else if (WirePrefix.isPreKeyBundle(message.getMessageBody())) wireType = WIRETYPE_PREKEY;
else if (WirePrefix.isEndSession(message.getMessageBody())) wireType = WIRETYPE_END_SESSION;
else wireType = WIRETYPE_KEY;
Log.w(TAG, "Decoded message with version: " + getCurrentVersion());
@@ -158,6 +162,7 @@ public class MultipartSmsTransportMessage {
if (message.isKeyExchange()) prefix = new KeyExchangeWirePrefix();
else if (message.isPreKeyBundle()) prefix = new PrekeyBundleWirePrefix();
else if (message.isEndSession()) prefix = new EndSessionWirePrefix();
else prefix = new SecureMessageWirePrefix();
if (count == 1) return getSingleEncoded(decoded, prefix);

View File

@@ -0,0 +1,22 @@
package org.thoughtcrime.securesms.sms;
public class OutgoingEndSessionMessage extends OutgoingTextMessage {
public OutgoingEndSessionMessage(OutgoingTextMessage base) {
this(base, base.getMessageBody());
}
public OutgoingEndSessionMessage(OutgoingTextMessage message, String body) {
super(message, body);
}
@Override
public boolean isEndSession() {
return true;
}
@Override
public OutgoingTextMessage withBody(String body) {
return new OutgoingEndSessionMessage(this, body);
}
}

View File

@@ -52,6 +52,10 @@ public class OutgoingTextMessage {
return false;
}
public boolean isEndSession() {
return false;
}
public boolean isPreKeyBundle() {
return false;
}
@@ -61,6 +65,8 @@ public class OutgoingTextMessage {
return new OutgoingEncryptedMessage(record.getIndividualRecipient(), record.getBody().getBody());
} else if (record.isKeyExchange()) {
return new OutgoingKeyExchangeMessage(record.getIndividualRecipient(), record.getBody().getBody());
} else if (record.isEndSession()) {
return new OutgoingEndSessionMessage(new OutgoingTextMessage(record.getIndividualRecipient(), record.getBody().getBody()));
} else {
return new OutgoingTextMessage(record.getIndividualRecipient(), record.getBody().getBody());
}