]> nmode's Git Repositories - signal-cli/commitdiff
Add possiblity to add new device, as master
authorAsamK <asamk@gmx.de>
Fri, 8 Apr 2016 21:32:26 +0000 (23:32 +0200)
committerAsamK <asamk@gmx.de>
Sat, 16 Apr 2016 11:32:21 +0000 (13:32 +0200)
src/main/java/org/asamk/signal/Main.java
src/main/java/org/asamk/signal/Manager.java

index 0d2e6f062fc2213a138ef8884cf3b4ab0e9ac9ba..f2c83dfc56d92fb250b0fe9023e59f9f106c2b47 100644 (file)
@@ -40,6 +40,8 @@ import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.security.Security;
 import java.util.ArrayList;
 import java.util.List;
@@ -177,6 +179,28 @@ public class Main {
                         System.exit(3);
                     }
                     break;
+                case "addDevice":
+                    if (dBusConn != null) {
+                        System.err.println("link is not yet implemented via dbus");
+                        System.exit(1);
+                    }
+                    if (!m.isRegistered()) {
+                        System.err.println("User is not registered.");
+                        System.exit(1);
+                    }
+                    try {
+                        m.addDeviceLink(new URI(ns.getString("uri")));
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                        System.exit(3);
+                    } catch (InvalidKeyException e) {
+                        e.printStackTrace();
+                        System.exit(2);
+                    } catch (URISyntaxException e) {
+                        e.printStackTrace();
+                        System.exit(2);
+                    }
+                    break;
                 case "send":
                     if (dBusConn == null && !m.isRegistered()) {
                         System.err.println("User is not registered.");
@@ -462,6 +486,11 @@ public class Main {
         parserLink.addArgument("-n", "--name")
                 .help("Specify a name to describe this new device.");
 
+        Subparser parserAddDevice = subparsers.addParser("addDevice");
+        parserAddDevice.addArgument("--uri")
+                .required(true)
+                .help("Specify the uri contained in the QR code shown by the new device.");
+
         Subparser parserRegister = subparsers.addParser("register");
         parserRegister.addArgument("-v", "--voice")
                 .help("The verification should be done over voice, not sms.")
index d442224a854a60680e6f868aab0df0d2da1d225c..eb883bb84286aba77b7e7590d08884d3c097d281 100644 (file)
@@ -23,10 +23,12 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.http.util.TextUtils;
 import org.asamk.Signal;
 import org.whispersystems.libsignal.*;
 import org.whispersystems.libsignal.ecc.Curve;
 import org.whispersystems.libsignal.ecc.ECKeyPair;
+import org.whispersystems.libsignal.ecc.ECPublicKey;
 import org.whispersystems.libsignal.state.PreKeyRecord;
 import org.whispersystems.libsignal.state.SignalProtocolStore;
 import org.whispersystems.libsignal.state.SignedPreKeyRecord;
@@ -40,6 +42,7 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender;
 import org.whispersystems.signalservice.api.crypto.*;
 import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
 import org.whispersystems.signalservice.api.messages.*;
+import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage;
 import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.push.TrustStore;
@@ -47,10 +50,12 @@ import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedE
 import org.whispersystems.signalservice.api.push.exceptions.EncapsulatedExceptions;
 import org.whispersystems.signalservice.api.util.InvalidNumberException;
 import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
+import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
 
 import java.io.*;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.nio.file.Files;
 import java.nio.file.Paths;
@@ -245,6 +250,50 @@ class Manager implements Signal {
 
         registered = true;
         refreshPreKeys();
+        save();
+    }
+
+
+    public static Map<String, String> getQueryMap(String query) {
+        String[] params = query.split("&");
+        Map<String, String> map = new HashMap<>();
+        for (String param : params) {
+            String name = null;
+            try {
+                name = URLDecoder.decode(param.split("=")[0], "utf-8");
+            } catch (UnsupportedEncodingException e) {
+                // Impossible
+            }
+            String value = null;
+            try {
+                value = URLDecoder.decode(param.split("=")[1], "utf-8");
+            } catch (UnsupportedEncodingException e) {
+                // Impossible
+            }
+            map.put(name, value);
+        }
+        return map;
+    }
+
+    public void addDeviceLink(URI linkUri) throws IOException, InvalidKeyException {
+        Map<String, String> query = getQueryMap(linkUri.getQuery());
+        String deviceIdentifier = query.get("uuid");
+        String publicKeyEncoded = query.get("pub_key");
+
+        if (TextUtils.isEmpty(deviceIdentifier) || TextUtils.isEmpty(publicKeyEncoded)) {
+            throw new RuntimeException("Invalid device link uri");
+        }
+
+        ECPublicKey deviceKey = Curve.decodePoint(Base64.decode(publicKeyEncoded), 0);
+
+        addDeviceLink(deviceIdentifier, deviceKey);
+    }
+
+    private void addDeviceLink(String deviceIdentifier, ECPublicKey deviceKey) throws IOException, InvalidKeyException {
+        IdentityKeyPair identityKeyPair = signalProtocolStore.getIdentityKeyPair();
+        String verificationCode = accountManager.getNewDeviceVerificationCode();
+
+        accountManager.addDevice(deviceIdentifier, deviceKey, identityKeyPair, verificationCode);
     }
 
     private List<PreKeyRecord> generatePreKeys() {