mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-22 16:07:30 +00:00
Fix "Group Threads" so that messages are encrypted when possible.
1) Change the MessageSender logic so that individual SMS messages are encrypted whenever there is a secure session, unless the UI explicitly specifies otherwise. 2) Change the MMS logic so that messages to a recipient with a secure session are all sent individually, instead of including those recipients into the batch plaintext message.
This commit is contained in:
parent
1bd260b981
commit
c13a3a8181
@ -106,7 +106,7 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
|
|
||||||
private Recipients recipients;
|
private Recipients recipients;
|
||||||
private long threadId;
|
private long threadId;
|
||||||
private boolean sendEncrypted;
|
private boolean isEncryptedConversation;
|
||||||
|
|
||||||
private CharacterCalculator characterCalculator = new CharacterCalculator();
|
private CharacterCalculator characterCalculator = new CharacterCalculator();
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
MenuInflater inflater = this.getSupportMenuInflater();
|
MenuInflater inflater = this.getSupportMenuInflater();
|
||||||
menu.clear();
|
menu.clear();
|
||||||
|
|
||||||
if (isSingleConversation() && sendEncrypted)
|
if (isSingleConversation() && isEncryptedConversation)
|
||||||
{
|
{
|
||||||
if (isAuthenticatedSession()) {
|
if (isAuthenticatedSession()) {
|
||||||
inflater.inflate(R.menu.conversation_secure_verified, menu);
|
inflater.inflate(R.menu.conversation_secure_verified, menu);
|
||||||
@ -230,7 +230,7 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
public void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||||
if (sendEncrypted) {
|
if (isEncryptedConversation) {
|
||||||
android.view.MenuInflater inflater = getMenuInflater();
|
android.view.MenuInflater inflater = getMenuInflater();
|
||||||
inflater.inflate(R.menu.conversation_button_context, menu);
|
inflater.inflate(R.menu.conversation_button_context, menu);
|
||||||
}
|
}
|
||||||
@ -239,7 +239,7 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
@Override
|
@Override
|
||||||
public boolean onContextItemSelected(android.view.MenuItem item) {
|
public boolean onContextItemSelected(android.view.MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.menu_context_send_unencrypted: sendMessage(false); return true;
|
case R.id.menu_context_send_unencrypted: sendMessage(true); return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -362,7 +362,7 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
|
|
||||||
if (isSingleConversation()) {
|
if (isSingleConversation()) {
|
||||||
|
|
||||||
if (sendEncrypted) {
|
if (isEncryptedConversation) {
|
||||||
title = AuthenticityCalculator.getAuthenticatedName(this,
|
title = AuthenticityCalculator.getAuthenticatedName(this,
|
||||||
getRecipients().getPrimaryRecipient(),
|
getRecipients().getPrimaryRecipient(),
|
||||||
masterSecret);
|
masterSecret);
|
||||||
@ -400,11 +400,11 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
{
|
{
|
||||||
sendButton.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_menu_lock_holo_light, 0);
|
sendButton.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_menu_lock_holo_light, 0);
|
||||||
sendButton.setCompoundDrawablePadding(15);
|
sendButton.setCompoundDrawablePadding(15);
|
||||||
this.sendEncrypted = true;
|
this.isEncryptedConversation = true;
|
||||||
this.characterCalculator = new EncryptedCharacterCalculator();
|
this.characterCalculator = new EncryptedCharacterCalculator();
|
||||||
} else {
|
} else {
|
||||||
sendButton.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
sendButton.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||||
this.sendEncrypted = false;
|
this.isEncryptedConversation = false;
|
||||||
this.characterCalculator = new CharacterCalculator();
|
this.characterCalculator = new CharacterCalculator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,7 +577,7 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
if (rawText.length() < 1 && !attachmentManager.isAttachmentPresent())
|
if (rawText.length() < 1 && !attachmentManager.isAttachmentPresent())
|
||||||
throw new InvalidMessageException(getString(R.string.ConversationActivity_message_is_empty_exclamation));
|
throw new InvalidMessageException(getString(R.string.ConversationActivity_message_is_empty_exclamation));
|
||||||
|
|
||||||
if (!sendEncrypted && Tag.isTaggable(this, rawText))
|
if (!isEncryptedConversation && Tag.isTaggable(this, rawText))
|
||||||
rawText = Tag.getTaggedMessage(rawText);
|
rawText = Tag.getTaggedMessage(rawText);
|
||||||
|
|
||||||
return rawText;
|
return rawText;
|
||||||
@ -604,7 +604,7 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendMessage(boolean sendEncrypted) {
|
private void sendMessage(boolean forcePlaintext) {
|
||||||
try {
|
try {
|
||||||
Recipients recipients = getRecipients();
|
Recipients recipients = getRecipients();
|
||||||
|
|
||||||
@ -617,13 +617,13 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
if (attachmentManager.isAttachmentPresent()) {
|
if (attachmentManager.isAttachmentPresent()) {
|
||||||
allocatedThreadId = MessageSender.sendMms(ConversationActivity.this, masterSecret, recipients,
|
allocatedThreadId = MessageSender.sendMms(ConversationActivity.this, masterSecret, recipients,
|
||||||
threadId, attachmentManager.getSlideDeck(), message,
|
threadId, attachmentManager.getSlideDeck(), message,
|
||||||
sendEncrypted);
|
forcePlaintext);
|
||||||
} else if (recipients.isEmailRecipient()) {
|
} else if (recipients.isEmailRecipient()) {
|
||||||
allocatedThreadId = MessageSender.sendMms(ConversationActivity.this, masterSecret, recipients,
|
allocatedThreadId = MessageSender.sendMms(ConversationActivity.this, masterSecret, recipients,
|
||||||
threadId, new SlideDeck(), message, sendEncrypted);
|
threadId, new SlideDeck(), message, forcePlaintext);
|
||||||
} else {
|
} else {
|
||||||
allocatedThreadId = MessageSender.send(ConversationActivity.this, masterSecret, recipients,
|
allocatedThreadId = MessageSender.send(ConversationActivity.this, masterSecret, recipients,
|
||||||
threadId, message, sendEncrypted);
|
threadId, message, forcePlaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendComplete(recipients, allocatedThreadId);
|
sendComplete(recipients, allocatedThreadId);
|
||||||
@ -679,7 +679,7 @@ public class ConversationActivity extends SherlockFragmentActivity
|
|||||||
|
|
||||||
private class SendButtonListener implements OnClickListener, TextView.OnEditorActionListener {
|
private class SendButtonListener implements OnClickListener, TextView.OnEditorActionListener {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
sendMessage(sendEncrypted);
|
sendMessage(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
@ -16,13 +16,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.thoughtcrime.securesms.recipients;
|
package org.thoughtcrime.securesms.recipients;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.crypto.KeyUtil;
|
||||||
import org.thoughtcrime.securesms.util.NumberUtil;
|
import org.thoughtcrime.securesms.util.NumberUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Recipients implements Parcelable {
|
public class Recipients implements Parcelable {
|
||||||
@ -44,6 +47,12 @@ public class Recipients implements Parcelable {
|
|||||||
this.recipients = recipients;
|
this.recipients = recipients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Recipients(final Recipient recipient) {
|
||||||
|
this.recipients = new LinkedList<Recipient>() {{
|
||||||
|
add(recipient);
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
public Recipients(Parcel in) {
|
public Recipients(Parcel in) {
|
||||||
this.recipients = new ArrayList<Recipient>();
|
this.recipients = new ArrayList<Recipient>();
|
||||||
in.readTypedList(recipients, Recipient.CREATOR);
|
in.readTypedList(recipients, Recipient.CREATOR);
|
||||||
@ -68,6 +77,30 @@ public class Recipients implements Parcelable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Recipients getSecureSessionRecipients(Context context) {
|
||||||
|
List<Recipient> secureRecipients = new LinkedList<Recipient>();
|
||||||
|
|
||||||
|
for (Recipient recipient : recipients) {
|
||||||
|
if (KeyUtil.isSessionFor(context, recipient)) {
|
||||||
|
secureRecipients.add(recipient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Recipients(secureRecipients);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Recipients getInsecureSessionRecipients(Context context) {
|
||||||
|
List<Recipient> insecureRecipients = new LinkedList<Recipient>();
|
||||||
|
|
||||||
|
for (Recipient recipient : recipients) {
|
||||||
|
if (!KeyUtil.isSessionFor(context, recipient)) {
|
||||||
|
insecureRecipients.add(recipient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Recipients(insecureRecipients);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return this.recipients.isEmpty();
|
return this.recipients.isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -16,32 +16,31 @@
|
|||||||
*/
|
*/
|
||||||
package org.thoughtcrime.securesms.sms;
|
package org.thoughtcrime.securesms.sms;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.telephony.PhoneNumberUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.crypto.KeyUtil;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||||
import org.thoughtcrime.securesms.mms.TextSlide;
|
import org.thoughtcrime.securesms.mms.TextSlide;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||||
import org.thoughtcrime.securesms.service.MmsSender;
|
|
||||||
import org.thoughtcrime.securesms.service.SendReceiveService;
|
import org.thoughtcrime.securesms.service.SendReceiveService;
|
||||||
import org.thoughtcrime.securesms.service.SmsSender;
|
|
||||||
|
|
||||||
import ws.com.google.android.mms.ContentType;
|
import ws.com.google.android.mms.ContentType;
|
||||||
import ws.com.google.android.mms.MmsException;
|
import ws.com.google.android.mms.MmsException;
|
||||||
import ws.com.google.android.mms.pdu.EncodedStringValue;
|
import ws.com.google.android.mms.pdu.EncodedStringValue;
|
||||||
import ws.com.google.android.mms.pdu.PduBody;
|
import ws.com.google.android.mms.pdu.PduBody;
|
||||||
import ws.com.google.android.mms.pdu.SendReq;
|
import ws.com.google.android.mms.pdu.SendReq;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.telephony.PhoneNumberUtils;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class MessageSender {
|
public class MessageSender {
|
||||||
|
|
||||||
public static long sendMms(Context context, MasterSecret masterSecret, Recipients recipients,
|
public static long sendMms(Context context, MasterSecret masterSecret, Recipients recipients,
|
||||||
long threadId, SlideDeck slideDeck, String message, boolean isSecure) throws MmsException
|
long threadId, SlideDeck slideDeck, String message, boolean forcePlaintext)
|
||||||
|
throws MmsException
|
||||||
{
|
{
|
||||||
if (threadId == -1)
|
if (threadId == -1)
|
||||||
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
||||||
@ -50,41 +49,54 @@ public class MessageSender {
|
|||||||
slideDeck.addSlide(new TextSlide(context, message));
|
slideDeck.addSlide(new TextSlide(context, message));
|
||||||
|
|
||||||
SendReq sendRequest = new SendReq();
|
SendReq sendRequest = new SendReq();
|
||||||
String[] recipientsArray = recipients.toNumberStringArray();
|
|
||||||
EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(recipientsArray);
|
|
||||||
PduBody body = slideDeck.toPduBody();
|
PduBody body = slideDeck.toPduBody();
|
||||||
|
|
||||||
sendRequest.setTo(encodedNumbers);
|
|
||||||
sendRequest.setDate(System.currentTimeMillis() / 1000L);
|
sendRequest.setDate(System.currentTimeMillis() / 1000L);
|
||||||
sendRequest.setBody(body);
|
sendRequest.setBody(body);
|
||||||
sendRequest.setContentType(ContentType.MULTIPART_MIXED.getBytes());
|
sendRequest.setContentType(ContentType.MULTIPART_MIXED.getBytes());
|
||||||
|
|
||||||
long messageId = DatabaseFactory.getEncryptingMmsDatabase(context, masterSecret).insertMessageSent(sendRequest, threadId, isSecure);
|
Recipients secureRecipients = recipients.getSecureSessionRecipients(context);
|
||||||
Intent intent = new Intent(SendReceiveService.SEND_MMS_ACTION, null, context, SendReceiveService.class);
|
Recipients insecureRecipients = recipients.getInsecureSessionRecipients(context);
|
||||||
intent.putExtra("message_id", messageId);
|
|
||||||
context.startService(intent);
|
for (Recipient secureRecipient : secureRecipients.getRecipientsList()) {
|
||||||
|
sendMms(context, new Recipients(secureRecipient), masterSecret,
|
||||||
|
sendRequest, threadId, !forcePlaintext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!insecureRecipients.isEmpty()) {
|
||||||
|
sendMms(context, insecureRecipients, masterSecret, sendRequest, threadId, false);
|
||||||
|
}
|
||||||
|
|
||||||
return threadId;
|
return threadId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long send(Context context, MasterSecret masterSecret, Recipients recipients,
|
public static long send(Context context, MasterSecret masterSecret, Recipients recipients,
|
||||||
long threadId, String message, boolean isSecure)
|
long threadId, String message, boolean forcePlaintext)
|
||||||
{
|
{
|
||||||
if (threadId == -1)
|
if (threadId == -1)
|
||||||
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
||||||
|
|
||||||
Iterator<Recipient> i = recipients.getRecipientsList().iterator();
|
for (Recipient recipient : recipients.getRecipientsList()) {
|
||||||
|
boolean isSecure = KeyUtil.isSessionFor(context, recipient) && !forcePlaintext;
|
||||||
while (i.hasNext()) {
|
|
||||||
Recipient recipient = i.next();
|
|
||||||
|
|
||||||
long messageId;
|
long messageId;
|
||||||
|
|
||||||
if (!isSecure) messageId = DatabaseFactory.getEncryptingSmsDatabase(context).insertMessageSent(masterSecret, PhoneNumberUtils.formatNumber(recipient.getNumber()), threadId, message, System.currentTimeMillis());
|
if (!isSecure) {
|
||||||
else messageId = DatabaseFactory.getEncryptingSmsDatabase(context).insertSecureMessageSent(masterSecret, PhoneNumberUtils.formatNumber(recipient.getNumber()), threadId, message, System.currentTimeMillis());
|
messageId = DatabaseFactory.getEncryptingSmsDatabase(context)
|
||||||
|
.insertMessageSent(masterSecret,
|
||||||
|
PhoneNumberUtils.formatNumber(recipient.getNumber()),
|
||||||
|
threadId, message, System.currentTimeMillis());
|
||||||
|
} else {
|
||||||
|
messageId = DatabaseFactory.getEncryptingSmsDatabase(context)
|
||||||
|
.insertSecureMessageSent(masterSecret,
|
||||||
|
PhoneNumberUtils.formatNumber(recipient.getNumber()),
|
||||||
|
threadId, message, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
Log.w("SMSSender", "Got message id for new message: " + messageId);
|
Log.w("SMSSender", "Got message id for new message: " + messageId);
|
||||||
Intent intent = new Intent(SendReceiveService.SEND_SMS_ACTION, null, context, SendReceiveService.class);
|
|
||||||
|
Intent intent = new Intent(SendReceiveService.SEND_SMS_ACTION, null,
|
||||||
|
context, SendReceiveService.class);
|
||||||
intent.putExtra("message_id", messageId);
|
intent.putExtra("message_id", messageId);
|
||||||
context.startService(intent);
|
context.startService(intent);
|
||||||
}
|
}
|
||||||
@ -92,4 +104,22 @@ public class MessageSender {
|
|||||||
return threadId;
|
return threadId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void sendMms(Context context, Recipients recipients, MasterSecret masterSecret,
|
||||||
|
SendReq sendRequest, long threadId, boolean secure)
|
||||||
|
throws MmsException
|
||||||
|
{
|
||||||
|
String[] recipientsArray = recipients.toNumberStringArray();
|
||||||
|
EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(recipientsArray);
|
||||||
|
|
||||||
|
sendRequest.setTo(encodedNumbers);
|
||||||
|
|
||||||
|
long messageId = DatabaseFactory.getEncryptingMmsDatabase(context, masterSecret)
|
||||||
|
.insertMessageSent(sendRequest, threadId, secure);
|
||||||
|
|
||||||
|
Intent intent = new Intent(SendReceiveService.SEND_MMS_ACTION, null,
|
||||||
|
context, SendReceiveService.class);
|
||||||
|
intent.putExtra("message_id", messageId);
|
||||||
|
|
||||||
|
context.startService(intent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user