Permalink
Browse files

Send using normal SMS instead of data SMS to avoid network problems

  • Loading branch information...
1 parent 836c035 commit e40ba79a26fc1dc3c0bbf798989d4e301f78f9f3 @erikwt committed May 31, 2010
View
@@ -1,3 +1,4 @@
.directory
.project
dist
+envsetup.sh
View
@@ -197,7 +197,7 @@
</receiver>
<!-- Require sender permissions to prevent SMS spoofing -->
- <receiver android:name=".transaction.PrivilegedSmsReceiver"
+ <receiver android:name=".transaction.EncryptedMessageReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
@@ -270,17 +270,6 @@
<activity android:name=".ui.PublicKeyReceived">
</activity>
-
- <receiver android:name=".transaction.PublicKeyReceiver"
- android:permission="android.permission.BROADCAST_SMS">
-
- <intent-filter>
- <action android:name="android.intent.action.DATA_SMS_RECEIVED" />
- <data android:scheme="sms" />
- <data android:host="localhost" />
- <data android:port="31337" />
- </intent-filter>
- </receiver>
<activity android:name=".ui.AuthenticateActivity">
</activity>
@@ -301,17 +290,6 @@
<activity android:name=".ui.EncryptedMessageNotificationActivity">
</activity>
- <receiver android:name=".transaction.EncryptedMessageReceiver"
- android:permission="android.permission.BROADCAST_SMS">
-
- <intent-filter>
- <action android:name="android.intent.action.DATA_SMS_RECEIVED" />
- <data android:scheme="sms" />
- <data android:host="localhost" />
- <data android:port="31338" />
- </intent-filter>
- </receiver>
-
<meta-data android:name="android.app.default_searchable"
android:value=".ui.SearchActivity" />
@@ -767,6 +767,8 @@
<string name="add_recipient">Add recipient</string>
<string name="received_public_key">Received Parandroid public key</string>
<string name="received_encrypted_message">Received Parandroid encrypted message</string>
+ <string name="protocol_too_high">Please update Parandroid Messaging, protocol in received message is higher than yours.</string>
+ <string name="corrupted_message">Parandroid message corrupted!</string>
<string name="public_keys_saved">Public keys</string>
<string name="public_keys_pending">Pending</string>
<string name="no_public_keys">No public keys</string>
@@ -776,7 +778,7 @@
<string name="accept_public_key">Accept this public key</string>
<string name="decline_public_key">Decline this public key</string>
<string name="decline_public_key_dialog">Are you sure you want to decline this public key?</string>
-
+
<string name="failed_changing_password">Failed changing password</string>
<string name="successfully_changed_password">Successfully changed password</string>
<string name="password_not_changed">Password not changed</string>
@@ -493,4 +493,37 @@ public static SQLiteDatabase openKeyring(Context context){
return keyRing;
}
+
+ public static String stripHeader(String message){
+ if(!message.startsWith(MultipartDataMessage.MESSAGE_HEADER) && !message.startsWith(MultipartDataMessage.PUBLIC_KEY_HEADER))
+ return message;
+
+ String header = message.startsWith(MultipartDataMessage.MESSAGE_HEADER) ? MultipartDataMessage.MESSAGE_HEADER : MultipartDataMessage.PUBLIC_KEY_HEADER;
+ int lastSeparator = message.indexOf(MultipartDataMessage.HEADER_SEPERATOR, header.length());
+
+ if(lastSeparator == -1 || message.length() <= lastSeparator)
+ return message.substring(header.length());
+
+ return message.substring(lastSeparator + 1);
+ }
+
+ public static int getProcolVersion(String message){
+ if(!message.startsWith(MultipartDataMessage.MESSAGE_HEADER) && !message.startsWith(MultipartDataMessage.PUBLIC_KEY_HEADER))
+ return -1;
+
+ String header = message.startsWith(MultipartDataMessage.MESSAGE_HEADER) ? MultipartDataMessage.MESSAGE_HEADER : MultipartDataMessage.PUBLIC_KEY_HEADER;
+
+ int metadataStart = header.length();
+ int metadataEnd = message.indexOf(MultipartDataMessage.HEADER_SEPERATOR, metadataStart);
+ if(metadataEnd == -1)
+ return -1;
+
+ try{
+ int protocolVersion = Integer.parseInt(message.substring(metadataStart, metadataEnd)) >> 8;
+ return protocolVersion;
+ }catch(Exception e){
+ Log.e(TAG, "Corrupted message, no protocol version: " + message);
+ return -1;
+ }
+ }
}
@@ -19,6 +19,7 @@
import org.parandroid.sms.R;
import org.parandroid.sms.LogTag;
import org.parandroid.sms.transaction.MessagingNotification;
+import org.parandroid.sms.transaction.MultipartDataMessage;
import org.parandroid.sms.ui.MessageUtils;
import org.parandroid.sms.util.DraftCache;
@@ -509,15 +510,10 @@ private static void fillFromCursor(Context context, Conversation conv,
String snippet = MessageUtils.extractEncStrFromCursor(c, SNIPPET, SNIPPET_CS);
if (TextUtils.isEmpty(snippet)) {
snippet = context.getString(R.string.no_subject_view);
- }else if(snippet.indexOf(" ") == -1){
- // No space, might be encrypted
- try{
- Base64.decode(snippet);
- // Encrypted message detected, show parandroid snippet
- snippet = context.getString(R.string.parandroid_snippet);
- }catch(Exception e){
- // Not base64, so not encrypted.
- }
+ }else if(snippet.startsWith(MultipartDataMessage.MESSAGE_HEADER)){
+ snippet = context.getString(R.string.parandroid_snippet);
+ }else if(snippet.startsWith(MultipartDataMessage.PUBLIC_KEY_HEADER)){
+ snippet = context.getString(R.string.received_public_key);
}
conv.mSnippet = snippet;
@@ -6,6 +6,7 @@
import org.parandroid.encryption.MessageEncryptionFactory;
import org.parandroid.sms.R;
import org.parandroid.sms.ui.EncryptedMessageNotificationActivity;
+import org.parandroid.sms.ui.ManagePublicKeysActivity;
import org.parandroid.sms.ui.MessageItem;
import org.parandroid.sms.ui.MessageUtils;
import org.parandroid.sms.ui.MessagingPreferenceActivity;
@@ -19,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.provider.Telephony.Sms;
@@ -39,90 +41,55 @@
@Override
public void onReceive(Context context, Intent intent) {
- String uricontent = intent.getDataString();
- String port = uricontent.substring(uricontent.lastIndexOf(":") + 1);
- Log.v(TAG, "Reveiced package on port " + port);
- if(Integer.parseInt(port) != MessageEncryptionFactory.ENCRYPTED_MESSAGE_PORT) return;
-
- SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
+ SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
SmsMessage message = messages[0];
- String sender = message.getOriginatingAddress();
-
- byte[] data = message.getUserData();
- if(data.length < 3){
- Log.e(TAG, "Encrypted message too short: '" + data + "'");
+ if(message.getMessageBody().startsWith(MultipartDataMessage.MESSAGE_HEADER)){
+ handleMessage(context, messages);
+ }else if(message.getMessageBody().startsWith(MultipartDataMessage.PUBLIC_KEY_HEADER)){
+ handlePublicKey(context, messages);
+ }else{
+ Log.i(TAG, "Got message, but not with a Parandroid header. Skipping.");
return;
}
-
- int protocolVersion = data[0];
- int currentMessage = data[1] >> 4;
- int totalMessages = data[1] & 15;
- int messageId = data[2];
-
- Log.i(TAG, "Message header:\nProtocol version: " + protocolVersion + " (" + (Integer.toBinaryString(protocolVersion)) + ")");
- Log.i(TAG, "Message count: " + currentMessage + " (" + (Integer.toBinaryString(currentMessage)) + ")");
- Log.i(TAG, "Total messages: " + totalMessages + " (" + (Integer.toBinaryString(totalMessages)) + ")");
- Log.i(TAG, "Message ID: " + messageId + " (" + (Integer.toBinaryString(messageId)) + ")");
-
- HashMap<Integer, HashMap<Integer, byte[]>> messageStore;
- if(messageMap.containsKey(sender)) messageStore = messageMap.get(sender);
- else{
- messageStore = new HashMap<Integer, HashMap<Integer, byte[]>>();
- messageMap.put(sender, messageStore);
- }
+ }
+
+
+ public void handleMessage(Context context, SmsMessage[] messages){
+ SmsMessage message = messages[0];
+ String sender = message.getOriginatingAddress();
+
+ String body = message.getMessageBody();
+ for(int i = 1; i < messages.length; i++)
+ body += messages[i].getMessageBody();
- if(!messageStore.containsKey(messageId)){
- HashMap<Integer, byte[]> messageParts = new HashMap<Integer, byte[]>();
- messageStore.put(messageId, messageParts);
- }
+ int protocolVersion = MessageEncryptionFactory.getProcolVersion(body);
- HashMap<Integer, byte[]> messageParts = messageStore.get(messageId);
+ Log.i(TAG, "Received message with protocol version: " + protocolVersion);
- byte[] part = new byte[data.length - 3];
- System.arraycopy(data, 3, part, 0, part.length);
+ String notificationString = null;
+ String notificationTitle = context.getString(R.string.received_encrypted_message);
+ if(protocolVersion == -1){
+ notificationString = context.getString(R.string.corrupted_message);
+ }else if(protocolVersion > MultipartDataMessage.PROTOCOL_VERSION){
+ // Protocol version too high, user might need to update
+ notificationString = context.getString(R.string.protocol_too_high);
+ }else{
+ notificationString = notificationTitle;
+ }
- messageParts.put(currentMessage, part);
- if(messageParts.size() == totalMessages){
- Log.v(TAG, "Received all parts of message: " + messageId);
- handleMultipartDataMessage(context, sender, messages, messageId);
- messageStore.remove(messageId);
- }
- }
-
-
- private void handleMultipartDataMessage(Context context, String sender, SmsMessage[] messages, int messageId){
- HashMap<Integer, byte[]> messageParts = messageMap.get(sender).get(messageId);
-
- int len = 0, offset = 0;
- ArrayList<byte[]> dataParts = new ArrayList<byte[]>();
-
- for(int i = messageParts.size() - 1; i >= 0; i--){
- byte[] part = messageParts.get(i);
- len += part.length;
- dataParts.add(part);
- }
-
- byte[] body = new byte[len];
- for(byte[] part : dataParts){
- System.arraycopy(part, 0, body, offset, part.length);
- offset += part.length;
- }
-
- Log.v(TAG, "Received encrypted message");
+ Log.v(TAG, "Received encrypted message");
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- String notificationString = context.getString(R.string.received_encrypted_message);
long threadId = Threads.getOrCreateThreadId(context, sender);
- insertEncryptedMessage(context, messages, body, threadId);
int notificationId = MessageUtils.getNotificationId(sender);
Intent targetIntent = new Intent(context, EncryptedMessageNotificationActivity.class);
targetIntent.putExtra("notificationId", notificationId);
targetIntent.putExtra("threadId", threadId);
- Notification n = new Notification(context, R.drawable.stat_notify_encrypted_msg, notificationString, System.currentTimeMillis(), notificationString, notificationString, targetIntent);
+ Notification n = new Notification(context, R.drawable.stat_notify_encrypted_msg, notificationString, System.currentTimeMillis(), notificationTitle, notificationString, targetIntent);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
if (sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_ENABLED, true)) {
@@ -141,46 +108,65 @@ private void handleMultipartDataMessage(Context context, String sender, SmsMessa
mNotificationManager.notify(notificationId, n);
}
-
- /**
- * Insert the encrypted message into the database. Uses base64 encoding for the data.
- *
- * @param messages
- * @param threadId
- */
- private void insertEncryptedMessage(Context context, SmsMessage[] messages, byte[] body, long threadId){
- SmsMessage msg = messages[0];
- ContentValues values = extractContentValues(msg);
+ public void handlePublicKey(Context context, SmsMessage[] messages){
+ SmsMessage message = messages[0];
+ String sender = message.getOriginatingAddress();
+
+ String body = message.getMessageBody();
+ for(int i = 1; i < messages.length; i++)
+ body += messages[i].getMessageBody();
+
+ int protocolVersion = MessageEncryptionFactory.getProcolVersion(body);
- values.put(Inbox.BODY, new String(body));
- values.put(Sms.THREAD_ID, threadId);
- values.put(Inbox.TYPE, MessageItem.MESSAGE_TYPE_PARANDROID_INBOX);
+ Log.i(TAG, "Received message with protocol version: " + protocolVersion);
- ContentResolver resolver = context.getContentResolver();
- SqliteWrapper.insert(context, resolver, Inbox.CONTENT_URI, values);
-
- threadId = values.getAsLong(Sms.THREAD_ID);
- Recycler.getSmsRecycler().deleteOldMessagesByThreadId(context, threadId);
- }
-
-
- /**
- * Extract all the content values except the body from an SMS
- * message.
- *
- * @see SmsReceiverService.extractContentValues (copy)
- */
- private ContentValues extractContentValues(SmsMessage sms) {
- ContentValues values = new ContentValues();
- values.put(Inbox.ADDRESS, sms.getDisplayOriginatingAddress());
- values.put(Inbox.DATE, new Long(System.currentTimeMillis()));
- values.put(Inbox.PROTOCOL, sms.getProtocolIdentifier());
- values.put(Inbox.READ, Integer.valueOf(0));
- if (sms.getPseudoSubject().length() > 0) {
- values.put(Inbox.SUBJECT, sms.getPseudoSubject());
+ String notificationString = null;
+ String notificationTitle = context.getString(R.string.received_public_key);
+ if(protocolVersion == -1){
+ notificationString = context.getString(R.string.corrupted_message);
+ }else if(protocolVersion > MultipartDataMessage.PROTOCOL_VERSION){
+ // Protocol version too high, user might need to update
+ notificationString = context.getString(R.string.protocol_too_high);
+ }else{
+ notificationString = notificationTitle;
}
- values.put(Inbox.REPLY_PATH_PRESENT, sms.isReplyPathPresent() ? 1 : 0);
- values.put(Inbox.SERVICE_CENTER, sms.getServiceCenterAddress());
- return values;
- }
+
+ String publicKey = MessageEncryptionFactory.stripHeader(body);
+ Log.i(TAG, "Inserting public key (length: " + publicKey.length() + "): " + publicKey);
+
+ SQLiteDatabase keyRing = MessageEncryptionFactory.openKeyring(context);
+
+ ContentValues cv = new ContentValues();
+ cv.put("number", sender);
+ cv.put("publickey", publicKey);
+ cv.put("accepted", false);
+
+ long id = keyRing.insert(MessageEncryptionFactory.PUBLIC_KEY_TABLE, "", cv);
+ keyRing.close();
+
+ Log.i(TAG, "Inserted public key at id: " + id);
+
+ Intent targetIntent = new Intent(context, ManagePublicKeysActivity.class);
+ targetIntent.putExtra("id", id);
+
+ NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ Notification n = new Notification(context, R.drawable.stat_notify_public_key_recieved, notificationString, System.currentTimeMillis(), notificationTitle, notificationString, targetIntent);
+
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
+ if (sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_ENABLED, true)) {
+ if(sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, true))
+ n.defaults |= Notification.DEFAULT_VIBRATE;
+
+ String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, null);
+ n.sound = TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr);
+
+ n.flags |= Notification.FLAG_SHOW_LIGHTS;
+ n.ledARGB = 0xff00ff00;
+ n.ledOnMS = 500;
+ n.ledOffMS = 2000;
+ }
+
+ mNotificationManager.notify((int) id, n);
+ }
}
Oops, something went wrong.

0 comments on commit e40ba79

Please sign in to comment.