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

@@ -73,7 +73,7 @@ public class EncryptingSmsDatabase extends SmsDatabase {
{
long type = Types.BASE_INBOX_TYPE;
if (!message.isSecureMessage()) {
if (!message.isSecureMessage() && !message.isEndSession()) {
type |= Types.ENCRYPTION_SYMMETRIC_BIT;
message = message.withMessageBody(getEncryptedBody(masterSecret, message.getMessageBody()));
}

View File

@@ -39,6 +39,7 @@ public interface MmsSmsColumns {
// Secure Message Information
protected static final long SECURE_MESSAGE_BIT = 0x800000;
protected static final long END_SESSION_BIT = 0x400000;
// Encrypted Storage Information
protected static final long ENCRYPTION_MASK = 0xFF000000;
@@ -75,6 +76,10 @@ public interface MmsSmsColumns {
return (type & SECURE_MESSAGE_BIT) != 0;
}
public static boolean isEndSessionType(long type) {
return (type & END_SESSION_BIT) != 0;
}
public static boolean isKeyExchangeType(long type) {
return (type & KEY_EXCHANGE_BIT) != 0;
}

View File

@@ -256,6 +256,10 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
} else if (message.isSecureMessage()) {
type |= Types.SECURE_MESSAGE_BIT;
type |= Types.ENCRYPTION_REMOTE_BIT;
} else if (message.isEndSession()) {
type |= Types.END_SESSION_BIT;
type |= Types.SECURE_MESSAGE_BIT;
type |= Types.ENCRYPTION_REMOTE_BIT;
}
Recipients recipients;
@@ -328,6 +332,7 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
protected List<Long> insertMessageOutbox(long threadId, OutgoingTextMessage message, long type) {
if (message.isKeyExchange()) type |= Types.KEY_EXCHANGE_BIT;
else if (message.isSecureMessage()) type |= Types.SECURE_MESSAGE_BIT;
else if (message.isEndSession()) type |= Types.END_SESSION_BIT;
long date = System.currentTimeMillis();
List<Long> messageIds = new LinkedList<Long>();

View File

@@ -84,6 +84,10 @@ public abstract class DisplayRecord {
return SmsDatabase.Types.isKeyExchangeType(type);
}
public boolean isEndSession() {
return SmsDatabase.Types.isEndSessionType(type);
}
public int getGroupAction() {
return groupAction;
}

View File

@@ -79,6 +79,9 @@ public class SmsMessageRecord extends MessageRecord {
return emphasisAdded(context.getString(R.string.MessageDisplayHelper_message_encrypted_for_non_existing_session));
} else if (!getBody().isPlaintext()) {
return emphasisAdded(context.getString(R.string.MessageNotifier_encrypted_message));
} else if (SmsDatabase.Types.isEndSessionType(type)) {
// TODO jake is going to fix this up
return new SpannableString("Session closed!");
} else if (isOutgoing() && Tag.isTagged(getBody().getBody())) {
return new SpannableString(Tag.stripTag(getBody().getBody()));
} else {

View File

@@ -78,6 +78,9 @@ public class ThreadRecord extends DisplayRecord {
return emphasisAdded(context.getString(R.string.MessageDisplayHelper_message_encrypted_for_non_existing_session));
} else if (!getBody().isPlaintext()) {
return emphasisAdded(context.getString(R.string.MessageNotifier_encrypted_message));
} else if (SmsDatabase.Types.isEndSessionType(type)) {
// TODO jake is going to fix this up
return emphasisAdded("Session closed!");
} else {
if (Util.isEmpty(getBody().getBody())) {
return new SpannableString(context.getString(R.string.MessageNotifier_no_subject));