Really really delay SMS processing until sqlcipher migration completes

Blocking the SMS job on the screen lock isn't enough, since then
the job races against the migration.

Fixes 
This commit is contained in:
Moxie Marlinspike 2018-02-26 14:02:12 -08:00
parent a0a9e412b4
commit 18aa202695
6 changed files with 87 additions and 4 deletions

@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.GcmRefreshJob;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirementProvider;
import org.thoughtcrime.securesms.jobs.requirements.ServiceRequirementProvider;
import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirementProvider;
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
@ -121,7 +122,8 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
.withJobSerializer(new JavaJobSerializer())
.withRequirementProviders(new MasterSecretRequirementProvider(this),
new ServiceRequirementProvider(this),
new NetworkRequirementProvider(this))
new NetworkRequirementProvider(this),
new SqlCipherMigrationRequirementProvider())
.withConsumerThreads(5)
.build();
}

@ -696,6 +696,10 @@ public class SmsDatabase extends MessagingDatabase {
return threadDeleted;
}
public void ensureMigration() {
databaseHelper.getWritableDatabase();
}
private boolean isDuplicate(IncomingTextMessage message, long threadId) {
SQLiteDatabase database = databaseHelper.getReadableDatabase();
Cursor cursor = database.query(TABLE_NAME, null, DATE_SENT + " = ? AND " + ADDRESS + " = ? AND " + THREAD_ID + " = ?",

@ -10,9 +10,11 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirement;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.libsignal.util.guava.Optional;
@ -33,6 +35,7 @@ public class SmsReceiveJob extends ContextJob {
.withPersistence()
.withWakeLock(true)
.withRequirement(new MasterSecretRequirement(context))
.withRequirement(new SqlCipherMigrationRequirement(context))
.create());
this.pdus = pdus;
@ -43,7 +46,7 @@ public class SmsReceiveJob extends ContextJob {
public void onAdded() {}
@Override
public void onRun() {
public void onRun() throws MigrationPendingException {
Log.w(TAG, "onRun()");
Optional<IncomingTextMessage> message = assembleMessageFragments(pdus, subscriptionId);
@ -68,7 +71,7 @@ public class SmsReceiveJob extends ContextJob {
@Override
public boolean onShouldRetry(Exception exception) {
return false;
return exception instanceof MigrationPendingException;
}
private boolean isBlocked(IncomingTextMessage message) {
@ -80,8 +83,13 @@ public class SmsReceiveJob extends ContextJob {
return false;
}
private Optional<InsertResult> storeMessage(IncomingTextMessage message) {
private Optional<InsertResult> storeMessage(IncomingTextMessage message) throws MigrationPendingException {
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
database.ensureMigration();
if (TextSecurePreferences.getNeedsSqlCipherMigration(context)) {
throw new MigrationPendingException();
}
if (message.isSecureMessage()) {
IncomingTextMessage placeholder = new IncomingTextMessage(message, "");
@ -111,4 +119,8 @@ public class SmsReceiveJob extends ContextJob {
return Optional.of(new IncomingTextMessage(messages));
}
private class MigrationPendingException extends Exception {
}
}

@ -0,0 +1,31 @@
package org.thoughtcrime.securesms.jobs.requirements;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.jobqueue.dependencies.ContextDependent;
import org.whispersystems.jobqueue.requirements.Requirement;
public class SqlCipherMigrationRequirement implements Requirement, ContextDependent {
@SuppressWarnings("unused")
private static final String TAG = SqlCipherMigrationRequirement.class.getSimpleName();
private transient Context context;
public SqlCipherMigrationRequirement(@NonNull Context context) {
this.context = context;
}
@Override
public void setContext(Context context) {
this.context = context;
}
@Override
public boolean isPresent() {
return !TextSecurePreferences.getNeedsSqlCipherMigration(context);
}
}

@ -0,0 +1,31 @@
package org.thoughtcrime.securesms.jobs.requirements;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.whispersystems.jobqueue.requirements.RequirementListener;
import org.whispersystems.jobqueue.requirements.RequirementProvider;
public class SqlCipherMigrationRequirementProvider implements RequirementProvider {
private RequirementListener listener;
public SqlCipherMigrationRequirementProvider() {
EventBus.getDefault().register(this);
}
@Override
public void setListener(RequirementListener listener) {
this.listener = listener;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(SqlCipherNeedsMigrationEvent event) {
if (listener != null) listener.onRequirementStatusChanged();
}
public static class SqlCipherNeedsMigrationEvent {
}
}

@ -14,7 +14,9 @@ import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.util.Pair;
import org.greenrobot.eventbus.EventBus;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirementProvider;
import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference;
import java.io.IOException;
@ -127,6 +129,7 @@ public class TextSecurePreferences {
public static void setNeedsSqlCipherMigration(@NonNull Context context, boolean value) {
setBooleanPreference(context, NEEDS_SQLCIPHER_MIGRATION, value);
EventBus.getDefault().post(new SqlCipherMigrationRequirementProvider.SqlCipherNeedsMigrationEvent());
}
public static boolean getNeedsSqlCipherMigration(@NonNull Context context) {