Add possiblity to add new device, as master

This commit is contained in:
AsamK 2016-04-08 23:32:26 +02:00
parent 33956bde62
commit 947818d317
2 changed files with 78 additions and 0 deletions

View file

@ -40,6 +40,8 @@ import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.Security; import java.security.Security;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -177,6 +179,28 @@ public class Main {
System.exit(3); System.exit(3);
} }
break; 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": case "send":
if (dBusConn == null && !m.isRegistered()) { if (dBusConn == null && !m.isRegistered()) {
System.err.println("User is not registered."); System.err.println("User is not registered.");
@ -462,6 +486,11 @@ public class Main {
parserLink.addArgument("-n", "--name") parserLink.addArgument("-n", "--name")
.help("Specify a name to describe this new device."); .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"); Subparser parserRegister = subparsers.addParser("register");
parserRegister.addArgument("-v", "--voice") parserRegister.addArgument("-v", "--voice")
.help("The verification should be done over voice, not sms.") .help("The verification should be done over voice, not sms.")

View file

@ -23,10 +23,12 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.http.util.TextUtils;
import org.asamk.Signal; import org.asamk.Signal;
import org.whispersystems.libsignal.*; import org.whispersystems.libsignal.*;
import org.whispersystems.libsignal.ecc.Curve; import org.whispersystems.libsignal.ecc.Curve;
import org.whispersystems.libsignal.ecc.ECKeyPair; import org.whispersystems.libsignal.ecc.ECKeyPair;
import org.whispersystems.libsignal.ecc.ECPublicKey;
import org.whispersystems.libsignal.state.PreKeyRecord; import org.whispersystems.libsignal.state.PreKeyRecord;
import org.whispersystems.libsignal.state.SignalProtocolStore; import org.whispersystems.libsignal.state.SignalProtocolStore;
import org.whispersystems.libsignal.state.SignedPreKeyRecord; 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.*;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.*; 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.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.TrustStore; 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.push.exceptions.EncapsulatedExceptions;
import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.InvalidNumberException;
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import java.io.*; import java.io.*;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -245,6 +250,50 @@ class Manager implements Signal {
registered = true; registered = true;
refreshPreKeys(); 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() { private List<PreKeyRecord> generatePreKeys() {