Display error code from server when already registered elsewhere.

This commit is contained in:
Moxie Marlinspike 2014-02-25 16:59:56 -08:00
parent 5fa429b0d5
commit 20fd881613
5 changed files with 43 additions and 10 deletions

View File

@ -0,0 +1,6 @@
package org.whispersystems.textsecure.push;
import java.io.IOException;
public class ExpectationFailedException extends IOException {
}

View File

@ -207,7 +207,7 @@ public class PushServiceSocket {
public List<ContactTokenDetails> retrieveDirectory(Set<String> contactTokens) {
try {
ContactTokenList contactTokenList = new ContactTokenList(new LinkedList(contactTokens));
ContactTokenList contactTokenList = new ContactTokenList(new LinkedList<String>(contactTokens));
String response = makeRequest(DIRECTORY_TOKENS_PATH, "PUT", new Gson().toJson(contactTokenList));
ContactTokenDetailsList activeTokens = new Gson().fromJson(response, ContactTokenDetailsList.class);
@ -334,6 +334,10 @@ public class PushServiceSocket {
throw new StaleDevicesException(new Gson().fromJson(response, StaleDevices.class));
}
if (connection.getResponseCode() == 417) {
throw new ExpectationFailedException();
}
if (connection.getResponseCode() != 200 && connection.getResponseCode() != 204) {
throw new IOException("Bad response: " + connection.getResponseCode() + " " + connection.getResponseMessage());
}

View File

@ -268,6 +268,8 @@
<string name="RegistrationProgressActivity_too_many_requests">Too Many Requests!</string>
<string name="RegistrationProgressActivity_youve_already_requested_a_voice_call">You\'ve already recently requested a voice call. You can request another in 20 minutes.</string>
<string name="RegistrationProgressActivity_verifying_voice_code">Verifying voice code...</string>
<string name="RegistrationProgressActivity_registration_conflict">Registration conflict</string>
<string name="RegistrationProgressActivity_this_number_is_already_registered_on_a_different">This number is already registered on a different TextSecure server (CyanogenMod?). You must unregistering there before registering here.</string>
<!-- RegistrationService -->
<string name="RegistrationService_registration_complete">Registration Complete</string>
@ -771,7 +773,6 @@
<!-- verify_keys -->
<string name="verify_keys__menu_verified">Verified</string>
<!-- EOF -->
</resources>

View File

@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.service.RegistrationService;
import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.whispersystems.textsecure.push.ExpectationFailedException;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.push.RateLimitException;
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
@ -314,6 +315,12 @@ public class RegistrationProgressActivity extends SherlockActivity {
PhoneNumberFormatter.formatNumberInternational(state.number)));
}
private void handleMultiRegistrationError(RegistrationState state) {
handleVerificationTimeout(state);
Util.showAlertDialog(this, getString(R.string.RegistrationProgressActivity_registration_conflict),
getString(R.string.RegistrationProgressActivity_this_number_is_already_registered_on_a_different));
}
private void handleVerificationComplete() {
if (visible) {
Toast.makeText(this,
@ -403,6 +410,7 @@ public class RegistrationProgressActivity extends SherlockActivity {
case RegistrationState.STATE_COMPLETE: handleVerificationComplete(); break;
case RegistrationState.STATE_GCM_TIMEOUT: handleGcmTimeout(state); break;
case RegistrationState.STATE_NETWORK_ERROR: handleConnectivityError(state); break;
case RegistrationState.STATE_MULTI_REGISTERED: handleMultiRegistrationError(state); break;
case RegistrationState.STATE_VOICE_REQUESTED: handleVerificationRequestedVoice(state); break;
}
}
@ -429,10 +437,11 @@ public class RegistrationProgressActivity extends SherlockActivity {
private class VerifyClickListener implements View.OnClickListener {
private static final int SUCCESS = 0;
private static final int NETWORK_ERROR = 1;
private static final int RATE_LIMIT_ERROR = 2;
private static final int VERIFICATION_ERROR = 3;
private static final int SUCCESS = 0;
private static final int NETWORK_ERROR = 1;
private static final int RATE_LIMIT_ERROR = 2;
private static final int VERIFICATION_ERROR = 3;
private static final int MULTI_REGISTRATION_ERROR = 4;
private final String e164number;
private final String password;
@ -495,6 +504,10 @@ public class RegistrationProgressActivity extends SherlockActivity {
Util.showAlertDialog(context, getString(R.string.RegistrationProgressActivity_too_many_attempts),
getString(R.string.RegistrationProgressActivity_youve_submitted_an_incorrect_verification_code_too_many_times));
break;
case MULTI_REGISTRATION_ERROR:
Util.showAlertDialog(context, getString(R.string.RegistrationProgressActivity_registration_conflict),
getString(R.string.RegistrationProgressActivity_this_number_is_already_registered_on_a_different));
break;
}
}
@ -505,6 +518,9 @@ public class RegistrationProgressActivity extends SherlockActivity {
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
socket.verifyAccount(code, signalingKey, true, registrationId);
return SUCCESS;
} catch (ExpectationFailedException e) {
Log.w("RegistrationProgressActivity", e);
return MULTI_REGISTRATION_ERROR;
} catch (RateLimitException e) {
Log.w("RegistrationProgressActivity", e);
return RATE_LIMIT_ERROR;

View File

@ -23,13 +23,13 @@ import org.whispersystems.textsecure.crypto.IdentityKey;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.whispersystems.textsecure.crypto.PreKeyUtil;
import org.whispersystems.textsecure.crypto.ecc.Curve;
import org.whispersystems.textsecure.push.ExpectationFailedException;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.storage.PreKeyRecord;
import org.whispersystems.textsecure.util.Util;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -89,9 +89,9 @@ public class RegistrationService extends Service {
executor.execute(new Runnable() {
@Override
public void run() {
if (intent.getAction().equals(REGISTER_NUMBER_ACTION)) handleSmsRegistrationIntent(intent);
else if (intent.getAction().equals(VOICE_REQUESTED_ACTION)) handleVoiceRequestedIntent(intent);
else if (intent.getAction().equals(VOICE_REGISTER_ACTION)) handleVoiceRegistrationIntent(intent);
if (REGISTER_NUMBER_ACTION.equals(intent.getAction())) handleSmsRegistrationIntent(intent);
else if (VOICE_REQUESTED_ACTION.equals(intent.getAction())) handleVoiceRequestedIntent(intent);
else if (VOICE_REGISTER_ACTION.equals(intent.getAction())) handleVoiceRegistrationIntent(intent);
}
});
}
@ -256,6 +256,10 @@ public class RegistrationService extends Service {
setState(new RegistrationState(RegistrationState.STATE_COMPLETE, number));
broadcastComplete(true);
} catch (ExpectationFailedException efe) {
Log.w("RegistrationService", efe);
setState(new RegistrationState(RegistrationState.STATE_MULTI_REGISTERED, number));
broadcastComplete(false);
} catch (UnsupportedOperationException uoe) {
Log.w("RegistrationService", uoe);
setState(new RegistrationState(RegistrationState.STATE_GCM_UNSUPPORTED, number));
@ -434,6 +438,8 @@ public class RegistrationService extends Service {
public static final int STATE_VOICE_REQUESTED = 12;
public static final int STATE_GENERATING_KEYS = 13;
public static final int STATE_MULTI_REGISTERED = 14;
public final int state;
public final String number;
public final String password;