From: AsamK Date: Sat, 31 Mar 2018 21:41:58 +0000 (+0200) Subject: Support registration lock PIN X-Git-Tag: v0.6.0~4 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/e057743232c0cae1401ba01a0ed1fdcd1c6ba5e0 Support registration lock PIN --- diff --git a/build.gradle b/build.gradle index 95717c68..39612ba8 100644 --- a/build.gradle +++ b/build.gradle @@ -19,8 +19,8 @@ repositories { } dependencies { - compile 'com.github.turasa:signal-service-java:2.7.1_unofficial_1' - compile 'org.bouncycastle:bcprov-jdk15on:1.55' + compile 'com.github.turasa:signal-service-java:2.7.3_unofficial_1' + compile 'org.bouncycastle:bcprov-jdk15on:1.59' compile 'net.sourceforge.argparse4j:argparse4j:0.8.1' compile 'org.freedesktop.dbus:dbus-java:2.7.0' } diff --git a/src/main/java/org/asamk/signal/Main.java b/src/main/java/org/asamk/signal/Main.java index 57a25345..59689049 100644 --- a/src/main/java/org/asamk/signal/Main.java +++ b/src/main/java/org/asamk/signal/Main.java @@ -37,6 +37,7 @@ import org.freedesktop.dbus.DBusSigHandler; import org.freedesktop.dbus.exceptions.DBusException; import org.freedesktop.dbus.exceptions.DBusExecutionException; import org.whispersystems.libsignal.InvalidKeyException; +import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.messages.*; import org.whispersystems.signalservice.api.messages.calls.*; @@ -46,6 +47,7 @@ import org.whispersystems.signalservice.api.push.exceptions.EncapsulatedExceptio import org.whispersystems.signalservice.api.push.exceptions.NetworkFailureException; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; +import org.whispersystems.signalservice.internal.push.LockedException; import org.whispersystems.signalservice.internal.util.Base64; import java.io.File; @@ -183,6 +185,39 @@ public class Main { return 3; } break; + case "setPin": + if (dBusConn != null) { + System.err.println("setPin is not yet implemented via dbus"); + return 1; + } + if (!m.isRegistered()) { + System.err.println("User is not registered."); + return 1; + } + try { + String registrationLockPin = ns.getString("registrationLockPin"); + m.setRegistrationLockPin(Optional.of(registrationLockPin)); + } catch (IOException e) { + System.err.println("Set pin error: " + e.getMessage()); + return 3; + } + break; + case "removePin": + if (dBusConn != null) { + System.err.println("removePin is not yet implemented via dbus"); + return 1; + } + if (!m.isRegistered()) { + System.err.println("User is not registered."); + return 1; + } + try { + m.setRegistrationLockPin(Optional.absent()); + } catch (IOException e) { + System.err.println("Remove pin error: " + e.getMessage()); + return 3; + } + break; case "verify": if (dBusConn != null) { System.err.println("verify is not yet implemented via dbus"); @@ -197,7 +232,13 @@ public class Main { return 1; } try { - m.verifyAccount(ns.getString("verificationCode")); + String verificationCode = ns.getString("verificationCode"); + String pin = ns.getString("pin"); + m.verifyAccount(verificationCode, pin); + } catch (LockedException e) { + System.err.println("Verification failed! This number is locked with a pin. Hours remaining until reset: " + (e.getTimeRemaining() / 1000 / 60 / 60)); + System.err.println("Use '--pin PIN_CODE' to specify the registration lock PIN"); + return 3; } catch (IOException e) { System.err.println("Verify error: " + e.getMessage()); return 3; @@ -777,9 +818,17 @@ public class Main { Subparser parserUpdateAccount = subparsers.addParser("updateAccount"); parserUpdateAccount.help("Update the account attributes on the signal server."); + Subparser parserSetPin = subparsers.addParser("setPin"); + parserSetPin.addArgument("registrationLockPin") + .help("The registration lock PIN, that will be required for new registrations (resets after 7 days of inactivity)"); + + Subparser parserRemovePin = subparsers.addParser("removePin"); + Subparser parserVerify = subparsers.addParser("verify"); parserVerify.addArgument("verificationCode") .help("The verification code you received via sms or voice call."); + parserVerify.addArgument("-p", "--pin") + .help("The registration lock PIN, that was set by the user (Optional)"); Subparser parserSend = subparsers.addParser("send"); parserSend.addArgument("-g", "--group") diff --git a/src/main/java/org/asamk/signal/Manager.java b/src/main/java/org/asamk/signal/Manager.java index 5d5b45d4..46c2e64c 100644 --- a/src/main/java/org/asamk/signal/Manager.java +++ b/src/main/java/org/asamk/signal/Manager.java @@ -116,6 +116,7 @@ class Manager implements Signal { private String username; private int deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID; private String password; + private String registrationLockPin; private String signalingKey; private int preKeyIdOffset; private int nextSignedPreKeyId; @@ -258,6 +259,8 @@ class Manager implements Signal { } username = getNotNullNode(rootNode, "username").asText(); password = getNotNullNode(rootNode, "password").asText(); + JsonNode pinNode = rootNode.get("registrationLockPin"); + registrationLockPin = pinNode == null ? null : pinNode.asText(); if (rootNode.has("signalingKey")) { signalingKey = getNotNullNode(rootNode, "signalingKey").asText(); } @@ -326,6 +329,7 @@ class Manager implements Signal { rootNode.put("username", username) .put("deviceId", deviceId) .put("password", password) + .put("registrationLockPin", registrationLockPin) .put("signalingKey", signalingKey) .put("preKeyIdOffset", preKeyIdOffset) .put("nextSignedPreKeyId", nextSignedPreKeyId) @@ -374,7 +378,7 @@ class Manager implements Signal { } public void updateAccountAttributes() throws IOException { - accountManager.setAccountAttributes(signalingKey, signalProtocolStore.getLocalRegistrationId(), true); + accountManager.setAccountAttributes(signalingKey, signalProtocolStore.getLocalRegistrationId(), true, registrationLockPin); } public void unregister() throws IOException { @@ -504,18 +508,28 @@ class Manager implements Signal { } } - public void verifyAccount(String verificationCode) throws IOException { + public void verifyAccount(String verificationCode, String pin) throws IOException { verificationCode = verificationCode.replace("-", ""); signalingKey = Util.getSecret(52); - accountManager.verifyAccountWithCode(verificationCode, signalingKey, signalProtocolStore.getLocalRegistrationId(), true); + accountManager.verifyAccountWithCode(verificationCode, signalingKey, signalProtocolStore.getLocalRegistrationId(), true, pin); //accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID))); registered = true; + registrationLockPin = pin; refreshPreKeys(); save(); } + public void setRegistrationLockPin(Optional pin) throws IOException { + accountManager.setPin(pin); + if (pin.isPresent()) { + registrationLockPin = pin.get(); + } else { + registrationLockPin = null; + } + } + private void refreshPreKeys() throws IOException { List oneTimePreKeys = generatePreKeys(); SignedPreKeyRecord signedPreKeyRecord = generateSignedPreKey(signalProtocolStore.getIdentityKeyPair());