diff --git a/src/org/thoughtcrime/securesms/service/SmsReceiver.java b/src/org/thoughtcrime/securesms/service/SmsReceiver.java
index c00b637210..6c830fa539 100644
--- a/src/org/thoughtcrime/securesms/service/SmsReceiver.java
+++ b/src/org/thoughtcrime/securesms/service/SmsReceiver.java
@@ -1,6 +1,6 @@
-/**
+/**
* Copyright (C) 2011 Whisper Systems
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
@@ -10,12 +10,20 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.thoughtcrime.securesms.service;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.telephony.SmsMessage;
+import android.util.Log;
+
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
import org.thoughtcrime.securesms.crypto.DecryptingQueue;
import org.thoughtcrime.securesms.crypto.InvalidKeyException;
@@ -30,106 +38,98 @@ import org.thoughtcrime.securesms.protocol.WirePrefix;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.sms.MultipartMessageHandler;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.telephony.SmsMessage;
-import android.util.Log;
-
public class SmsReceiver {
private MultipartMessageHandler multipartMessageHandler = new MultipartMessageHandler();
-
+
private final Context context;
-
+
public SmsReceiver(Context context) {
this.context = context;
}
-
+
private String assembleSecureMessageFragments(String sender, String messageBody) {
String localPrefix;
-
+
if (WirePrefix.isEncryptedMessage(messageBody)) {
localPrefix = Prefix.ASYMMETRIC_ENCRYPT;
} else {
localPrefix = Prefix.KEY_EXCHANGE;
}
-
+
Log.w("SMSReceiverService", "Calculated local prefix for message: " + messageBody + " - Local Prefix: " + localPrefix);
messageBody = messageBody.substring(WirePrefix.PREFIX_SIZE);
-
+
Log.w("SMSReceiverService", "Parsed off wire prefix: " + messageBody);
-
+
if (!multipartMessageHandler.isManualTransport(messageBody))
return localPrefix + messageBody;
else
return multipartMessageHandler.processPotentialMultipartMessage(localPrefix, sender, messageBody);
-
+
}
-
+
private String assembleMessageFragments(SmsMessage[] messages) {
StringBuilder body = new StringBuilder();
-
+
for (SmsMessage message : messages) {
body.append(message.getDisplayMessageBody());
}
-
+
String messageBody = body.toString();
-
+
if (WirePrefix.isEncryptedMessage(messageBody) || WirePrefix.isKeyExchange(messageBody)) {
return assembleSecureMessageFragments(messages[0].getDisplayOriginatingAddress(), messageBody);
} else {
return messageBody;
}
}
-
+
private void storeSecureMessage(MasterSecret masterSecret, SmsMessage message, String messageBody) {
long messageId = DatabaseFactory.getSmsDatabase(context).insertSecureMessageReceived(message, messageBody);
Log.w("SmsReceiver", "Inserted secure message received: " + messageId);
- if (masterSecret != null)
- DecryptingQueue.scheduleDecryption(context, masterSecret, messageId, message.getDisplayOriginatingAddress(), messageBody);
+ if (masterSecret != null)
+ DecryptingQueue.scheduleDecryption(context, masterSecret, messageId, message.getDisplayOriginatingAddress(), messageBody);
}
-
+
private long storeStandardMessage(MasterSecret masterSecret, SmsMessage message, String messageBody) {
if (masterSecret != null) return DatabaseFactory.getEncryptingSmsDatabase(context).insertMessageReceived(masterSecret, message, messageBody);
else if (MasterSecretUtil.hasAsymmericMasterSecret(context)) return DatabaseFactory.getEncryptingSmsDatabase(context).insertMessageReceived(MasterSecretUtil.getAsymmetricMasterSecret(context, null), message, messageBody);
- else return DatabaseFactory.getSmsDatabase(context).insertMessageReceived(message, messageBody);
+ else return DatabaseFactory.getSmsDatabase(context).insertMessageReceived(message, messageBody);
}
private void storeKeyExchangeMessage(MasterSecret masterSecret, SmsMessage message, String messageBody) {
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(ApplicationPreferencesActivity.AUTO_KEY_EXCHANGE_PREF, true)) {
try {
- Recipient recipient = new Recipient(null, message.getDisplayOriginatingAddress(), null);
- KeyExchangeMessage keyExchangeMessage = new KeyExchangeMessage(messageBody);
- KeyExchangeProcessor processor = new KeyExchangeProcessor(context, masterSecret, recipient);
-
- Log.w("SmsReceiver", "Received key with fingerprint: " + keyExchangeMessage.getPublicKey().getFingerprint());
-
- if (processor.isStale(keyExchangeMessage)) {
- messageBody = messageBody.substring(Prefix.KEY_EXCHANGE.length());
- messageBody = Prefix.STALE_KEY_EXCHANGE + messageBody;
- } else if (!processor.hasCompletedSession() || processor.hasSameSessionIdentity(keyExchangeMessage)) {
- messageBody = messageBody.substring(Prefix.KEY_EXCHANGE.length());
- messageBody = Prefix.PROCESSED_KEY_EXCHANGE + messageBody;
- long messageId = storeStandardMessage(masterSecret, message, messageBody);
- long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId);
-
- processor.processKeyExchangeMessage(keyExchangeMessage, threadId);
- return;
- }
+ Recipient recipient = new Recipient(null, message.getDisplayOriginatingAddress(), null);
+ KeyExchangeMessage keyExchangeMessage = new KeyExchangeMessage(messageBody);
+ KeyExchangeProcessor processor = new KeyExchangeProcessor(context, masterSecret, recipient);
+
+ Log.w("SmsReceiver", "Received key with fingerprint: " + keyExchangeMessage.getPublicKey().getFingerprint());
+
+ if (processor.isStale(keyExchangeMessage)) {
+ messageBody = messageBody.substring(Prefix.KEY_EXCHANGE.length());
+ messageBody = Prefix.STALE_KEY_EXCHANGE + messageBody;
+ } else if (!processor.hasCompletedSession() || processor.hasSameSessionIdentity(keyExchangeMessage)) {
+ messageBody = messageBody.substring(Prefix.KEY_EXCHANGE.length());
+ messageBody = Prefix.PROCESSED_KEY_EXCHANGE + messageBody;
+ long messageId = storeStandardMessage(masterSecret, message, messageBody);
+ long threadId = DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageId);
+
+ processor.processKeyExchangeMessage(keyExchangeMessage, threadId);
+ return;
+ }
} catch (InvalidVersionException e) {
- Log.w("SmsReceiver", e);
+ Log.w("SmsReceiver", e);
} catch (InvalidKeyException e) {
- Log.w("SmsReceiver", e);
+ Log.w("SmsReceiver", e);
}
}
storeStandardMessage(masterSecret, message, messageBody);
}
-
+
private boolean storeMessage(MasterSecret masterSecret, SmsMessage message, String messageBody) {
if (messageBody.startsWith(Prefix.ASYMMETRIC_ENCRYPT)) {
storeSecureMessage(masterSecret, message, messageBody);
@@ -138,48 +138,48 @@ public class SmsReceiver {
} else {
storeStandardMessage(masterSecret, message, messageBody);
}
-
+
return true;
}
private SmsMessage[] parseMessages(Bundle bundle) {
Object[] pdus = (Object[])bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdus.length];
-
+
for (int i=0;i.
*/
package org.thoughtcrime.securesms.service;
-import java.util.ArrayList;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.telephony.SmsManager;
+import android.util.Log;
import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.crypto.MasterSecret;
@@ -32,24 +38,18 @@ import org.thoughtcrime.securesms.sms.MultipartMessageHandler;
import org.thoughtcrime.securesms.sms.SmsTransportDetails;
import org.thoughtcrime.securesms.util.InvalidMessageException;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.telephony.SmsManager;
-import android.util.Log;
+import java.util.ArrayList;
public class SmsSender {
private final MultipartMessageHandler multipartMessageHandler = new MultipartMessageHandler();
-
+
private final Context context;
-
+
public SmsSender(Context context) {
this.context = context;
}
-
+
public void process(MasterSecret masterSecret, Intent intent) {
MasterCipher masterCipher = new MasterCipher(masterSecret);
long messageId = intent.getLongExtra("message_id", -1);
@@ -60,44 +60,44 @@ public class SmsSender {
try {
if (messageId == -1) c = DatabaseFactory.getSmsDatabase(context).getOutgoingMessages();
else c = DatabaseFactory.getSmsDatabase(context).getMessage(messageId);
-
- if (c != null && c.moveToFirst()) {
- do {
- messageId = c.getLong(c.getColumnIndexOrThrow(SmsDatabase.ID));
- String body = c.getString(c.getColumnIndexOrThrow(SmsDatabase.BODY));
- String address = c.getString(c.getColumnIndexOrThrow(SmsDatabase.ADDRESS));
- String messageText = getClearTextBody(masterCipher, body);
- long type = c.getLong(c.getColumnIndexOrThrow(SmsDatabase.TYPE));
-
- if (!SmsDatabase.Types.isPendingMessageType(type))
- continue;
-
- if (isSecureMessage(type))
- messageText = getAsymmetricEncrypt(masterSecret, messageText, address);
-
- Log.w("SMSSenderService", "Actually delivering: " + messageId);
- deliverTextMessage(address, messageText, messageId, type);
- } while (c.moveToNext());
- }
+ if (c != null && c.moveToFirst()) {
+ do {
+ messageId = c.getLong(c.getColumnIndexOrThrow(SmsDatabase.ID));
+ String body = c.getString(c.getColumnIndexOrThrow(SmsDatabase.BODY));
+ String address = c.getString(c.getColumnIndexOrThrow(SmsDatabase.ADDRESS));
+ String messageText = getClearTextBody(masterCipher, body);
+ long type = c.getLong(c.getColumnIndexOrThrow(SmsDatabase.TYPE));
+
+ if (!SmsDatabase.Types.isPendingMessageType(type))
+ continue;
+
+ if (isSecureMessage(type))
+ messageText = getAsymmetricEncrypt(masterSecret, messageText, address);
+
+ Log.w("SMSSenderService", "Actually delivering: " + messageId);
+
+ deliverTextMessage(address, messageText, messageId, type);
+ } while (c.moveToNext());
+ }
} finally {
if (c != null)
- c.close();
+ c.close();
}
}
-
+
private String getClearTextBody(MasterCipher masterCipher, String body) {
if (body.startsWith(Prefix.SYMMETRIC_ENCRYPT)) {
try {
- return masterCipher.decryptBody(body.substring(Prefix.SYMMETRIC_ENCRYPT.length()));
+ return masterCipher.decryptBody(body.substring(Prefix.SYMMETRIC_ENCRYPT.length()));
} catch (InvalidMessageException e) {
- return "Error decrypting message.";
+ return "Error decrypting message.";
}
} else {
return body;
}
}
-
+
private ArrayList constructSentIntents(long messageId, long type, ArrayList messages) {
ArrayList sentIntents = new ArrayList(messages.size());
@@ -107,10 +107,10 @@ public class SmsSender {
pending.putExtra("message_id", messageId);
sentIntents.add(PendingIntent.getBroadcast(context, 0, pending, 0));
}
-
+
return sentIntents;
}
-
+
private void deliverGSMTransportTextMessage(String recipient, String text, long messageId, long type) {
ArrayList messages = SmsManager.getDefault().divideMessage(text);
ArrayList sentIntents = constructSentIntents(messageId, type, messages);
@@ -128,7 +128,7 @@ public class SmsSender {
private void deliverSecureTransportTextMessage(String recipient, String text, long messageId, long type) {
WirePrefix prefix;
-
+
if (isSecureMessage(type)) {
prefix = new SecureMessageWirePrefix();
text = text.substring(Prefix.ASYMMETRIC_ENCRYPT.length());
@@ -136,12 +136,12 @@ public class SmsSender {
prefix = new KeyExchangeWirePrefix();
text = text.substring(Prefix.KEY_EXCHANGE.length());
}
-
+
if (!multipartMessageHandler.isManualTransport(text)) {
deliverGSMTransportTextMessage(recipient, prefix.calculatePrefix(text) + text, messageId, type);
return;
}
-
+
ArrayList messages = multipartMessageHandler.divideMessage(recipient, text, prefix);
ArrayList sentIntents = constructSentIntents(messageId, type, messages);
for (int i=0;i