Browse Source

This would be great if it worked.

Douglas William Thrift 13 years ago
parent
commit
56c91fc17a

+ 1 - 0
.gitignore

@@ -1,2 +1,3 @@
+*.keystore
 *.properties
 bin

+ 1 - 1
build.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<project name="Big Screen Bot" default="jar" basedir=".">
+<project name="Big Screen Bot" default="compile" basedir=".">
     <property name="bin" location="bin"/>
     <property name="lib" location="lib"/>
     <property name="src" location="src"/>

+ 33 - 6
src/net/douglasthrift/bigscreenbot/BigScreenBot.java

@@ -27,6 +27,7 @@ package net.douglasthrift.bigscreenbot;
 import java.io.IOException;
 
 import java.net.MalformedURLException;
+import java.net.UnknownHostException;
 import java.net.URL;
 
 import java.security.GeneralSecurityException;
@@ -42,6 +43,8 @@ import java.util.regex.Pattern;
 
 import javax.net.ssl.SSLSocketFactory;
 
+import com.google.polo.exception.PoloException;
+
 import com.google.polo.ssl.DummySSLSocketFactory;
 
 import org.apache.commons.cli.CommandLine;
@@ -135,6 +138,10 @@ public class BigScreenBot extends Bot
         {
             error(exception, 1);
         }
+        catch (GeneralSecurityException exception)
+        {
+            error(exception, 1);
+        }
 
         setAutoNickChange(true);
         setFinger("Big Screen Bot");
@@ -373,16 +380,36 @@ public class BigScreenBot extends Bot
                         @Override
                         public void run()
                         {
-                            synchronized (remote)
+                            try
                             {
-                                try
+                                synchronized (remote)
                                 {
                                     remote.startPairDevice(arguments[0]);
                                 }
-                                catch (GeneralSecurityException exception)
-                                {
-                                    error(channel, sender, exception);
-                                }
+                            }
+                            catch (MalformedURLException exception)
+                            {
+                                sendMessage(channel, sender, String.format("invalid device name (\"%1$s\")", arguments[0]));
+
+                                return;
+                            }
+                            catch (UnknownHostException exception)
+                            {
+                                sendMessage(channel, sender, String.format("could not find device (\"%1$s\")", arguments[0]));
+
+                                return;
+                            }
+                            catch (IOException exception)
+                            {
+                                error(channel, sender, exception);
+
+                                return;
+                            }
+                            catch (PoloException exception)
+                            {
+                                error(channel, sender, exception);
+
+                                return;
                             }
 
                             sendMessage(channel, sender, String.format("enter the code from the device (\"%1$s\") to finish pairing", arguments[0]));

+ 101 - 11
src/net/douglasthrift/bigscreenbot/Remote.java

@@ -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();
+        }
     }
 }