|
@@ -24,13 +24,28 @@
|
|
|
|
|
|
package net.douglasthrift.bigscreenbot;
|
|
|
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileNotFoundException;
|
|
|
+import java.io.FileOutputStream;
|
|
|
import java.io.IOException;
|
|
|
|
|
|
import java.net.InetAddress;
|
|
|
+import java.net.MalformedURLException;
|
|
|
import java.net.UnknownHostException;
|
|
|
+import java.net.URL;
|
|
|
|
|
|
+import java.security.GeneralSecurityException;
|
|
|
import java.security.KeyManagementException;
|
|
|
+import java.security.KeyPair;
|
|
|
+import java.security.KeyPairGenerator;
|
|
|
+import java.security.KeyStore;
|
|
|
+import java.security.KeyStoreException;
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
+import java.security.UnrecoverableKeyException;
|
|
|
+
|
|
|
+import java.security.cert.Certificate;
|
|
|
+import java.security.cert.CertificateException;
|
|
|
+import java.security.cert.X509Certificate;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
@@ -38,6 +53,7 @@ import java.util.List;
|
|
|
import javax.jmdns.JmDNS;
|
|
|
import javax.jmdns.ServiceInfo;
|
|
|
|
|
|
+import javax.net.ssl.SSLSocket;
|
|
|
import javax.net.ssl.SSLSocketFactory;
|
|
|
import javax.net.ssl.KeyManager;
|
|
|
import javax.net.ssl.KeyManagerFactory;
|
|
@@ -48,15 +64,27 @@ import com.google.anymote.common.ErrorListener;
|
|
|
import com.google.anymote.device.DeviceAdapter;
|
|
|
import com.google.anymote.device.MessageReceiver;
|
|
|
|
|
|
+import com.google.polo.exception.PoloException;
|
|
|
+
|
|
|
+import com.google.polo.pairing.PairingContext;
|
|
|
+
|
|
|
import com.google.polo.ssl.DummySSLSocketFactory;
|
|
|
+import com.google.polo.ssl.SslUtil;
|
|
|
|
|
|
public class Remote
|
|
|
{
|
|
|
+ private static final String STORE = "bigscreenbot.keystore";
|
|
|
+ private static final char[] PASSWORD = "b1GsSC33Nb0T".toCharArray();
|
|
|
+ private static final char[] NULL = new char[]{};
|
|
|
private static final String TYPE = "_anymote._tcp.local.";
|
|
|
+ private static final String LOCAL_ALIAS = "anymote-remote";
|
|
|
+ private static final String REMOTE_ALIAS = "anymote-server-%1$X";
|
|
|
private Settings settings;
|
|
|
private JmDNS mdns;
|
|
|
+ private KeyStore store;
|
|
|
+ SSLSocketFactory factory;
|
|
|
|
|
|
- public Remote(Settings settings) throws UnknownHostException, IOException
|
|
|
+ public Remote(Settings settings) throws UnknownHostException, IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException, GeneralSecurityException
|
|
|
{
|
|
|
this.settings = settings;
|
|
|
|
|
@@ -66,6 +94,43 @@ public class Remote
|
|
|
mdns = JmDNS.create(InetAddress.getByName(interfaze));
|
|
|
else
|
|
|
mdns = JmDNS.create();
|
|
|
+
|
|
|
+ store = KeyStore.getInstance(KeyStore.getDefaultType());
|
|
|
+
|
|
|
+ FileInputStream stream = null;
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ stream = new FileInputStream(STORE);
|
|
|
+
|
|
|
+ store.load(stream, PASSWORD);
|
|
|
+ }
|
|
|
+ catch (FileNotFoundException exception)
|
|
|
+ {
|
|
|
+ store.load(null, PASSWORD);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ if (stream != null)
|
|
|
+ stream.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!store.containsAlias(LOCAL_ALIAS))
|
|
|
+ {
|
|
|
+ KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
|
|
|
+ KeyPair pair = generator.generateKeyPair();
|
|
|
+ X509Certificate certificate = SslUtil.generateX509V3Certificate(pair, "CN=anymote-remote/bigscreenbot/" + System.getProperty("os.name") + "/" + System.getProperty("os.arch") + "/" + System.getProperty("user.name") + "@" + InetAddress.getLocalHost().getHostName());
|
|
|
+
|
|
|
+ store.setKeyEntry(LOCAL_ALIAS, pair.getPrivate(), NULL, new Certificate[]{ certificate });
|
|
|
+
|
|
|
+ store();
|
|
|
+ }
|
|
|
+
|
|
|
+ KeyManagerFactory factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
|
|
+
|
|
|
+ factory.init(store, NULL);
|
|
|
+
|
|
|
+ this.factory = DummySSLSocketFactory.fromKeyManagers(factory.getKeyManagers());
|
|
|
}
|
|
|
|
|
|
public List<String> listDevices()
|
|
@@ -78,13 +143,30 @@ public class Remote
|
|
|
return devices;
|
|
|
}
|
|
|
|
|
|
- public void startPairDevice(String device) throws NoSuchAlgorithmException, KeyManagementException
|
|
|
+ public void startPairDevice(String device) throws MalformedURLException, UnknownHostException, IOException, PoloException
|
|
|
{
|
|
|
ServiceInfo info = mdns.getServiceInfo(TYPE, device);
|
|
|
- InetAddress address = info.getInetAddresses()[0];
|
|
|
- int port = info.getPort();
|
|
|
+ InetAddress address;
|
|
|
+ int port;
|
|
|
+
|
|
|
+ if (info != null)
|
|
|
+ {
|
|
|
+ address = info.getInetAddresses()[0];
|
|
|
+ port = info.getPort();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ URL url = new URL("http://" + device);
|
|
|
|
|
|
- SSLSocketFactory factory = DummySSLSocketFactory.fromKeyManagers(getKeyManagers());
|
|
|
+ address = InetAddress.getByName(url.getHost());
|
|
|
+ port = url.getPort();
|
|
|
+
|
|
|
+ if (port == -1)
|
|
|
+ port = 9551;
|
|
|
+ }
|
|
|
+
|
|
|
+ SSLSocket socket = (SSLSocket)factory.createSocket(address, port);
|
|
|
+ PairingContext context = PairingContext.fromSslSocket(socket, false);
|
|
|
}
|
|
|
|
|
|
public void finishPairDevice(String device, String code)
|
|
@@ -105,13 +187,21 @@ public class Remote
|
|
|
mdns.close();
|
|
|
}
|
|
|
|
|
|
- private KeyManager[] getKeyManagers() throws NoSuchAlgorithmException
|
|
|
+ private void store() throws FileNotFoundException, IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException
|
|
|
{
|
|
|
- KeyManagerFactory factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
|
|
-
|
|
|
- //factory.init(store, "".toCharArray());
|
|
|
-
|
|
|
- return factory.getKeyManagers();
|
|
|
+ FileOutputStream stream = null;
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ stream = new FileOutputStream(STORE);
|
|
|
+
|
|
|
+ store.store(stream, PASSWORD);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ if (stream != null)
|
|
|
+ stream.close();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|