server: add a HELLO handshake
[fanfix.git] / src / be / nikiroo / utils / serial / server / ConnectActionClient.java
index 626b62f78494ab4fdb818220629a281bc3507f14..1b92b42235a91e471cb650b2e8dc48608a1d6dc3 100644 (file)
@@ -2,8 +2,9 @@ package be.nikiroo.utils.serial.server;
 
 import java.io.IOException;
 import java.net.Socket;
+import java.net.UnknownHostException;
 
-import be.nikiroo.utils.Version;
+import javax.net.ssl.SSLException;
 
 /**
  * Base class used for the client basic handling.
@@ -21,36 +22,6 @@ abstract class ConnectActionClient {
         */
        protected ConnectAction action;
 
-       /**
-        * Create a new {@link ConnectActionClient} with the current application
-        * version (see {@link Version#getCurrentVersion()}) as the client version.
-        * 
-        * @param s
-        *            the socket to bind to
-        */
-       public ConnectActionClient(Socket s) {
-               this(s, Version.getCurrentVersion());
-       }
-
-       /**
-        * Create a new {@link ConnectActionClient} with the current application
-        * version (see {@link Version#getCurrentVersion()}) as the client version.
-        * 
-        * @param host
-        *            the host to bind to
-        * @param port
-        *            the port to bind to
-        * @param ssl
-        *            TRUE for an SSL connection, FALSE for plain text
-        * 
-        * @throws IOException
-        *             in case of I/O error when creating the socket
-        */
-       public ConnectActionClient(String host, int port, boolean ssl)
-                       throws IOException {
-               this(Server.createSocket(host, port, ssl), Version.getCurrentVersion());
-       }
-
        /**
         * Create a new {@link ConnectActionClient}.
         * 
@@ -58,17 +29,21 @@ abstract class ConnectActionClient {
         *            the host to bind to
         * @param port
         *            the port to bind to
-        * @param ssl
-        *            TRUE for an SSL connection, FALSE for plain text
-        * @param version
-        *            the client version
+        * @param key
+        *            an optional key to encrypt all the communications (if NULL,
+        *            everything will be sent in clear text)
         * 
         * @throws IOException
-        *             in case of I/O error when creating the socket
+        *             in case of I/O error
+        * @throws UnknownHostException
+        *             if the host is not known
+        * @throws IllegalArgumentException
+        *             if the port parameter is outside the specified range of valid
+        *             port values, which is between 0 and 65535, inclusive
         */
-       public ConnectActionClient(String host, int port, boolean ssl,
-                       Version version) throws IOException {
-               this(Server.createSocket(host, port, ssl), version);
+       public ConnectActionClient(String host, int port, String key)
+                       throws IOException {
+               this(new Socket(host, port), key);
        }
 
        /**
@@ -76,30 +51,44 @@ abstract class ConnectActionClient {
         * 
         * @param s
         *            the socket to bind to
-        * @param version
-        *            the client version
+        * @param key
+        *            an optional key to encrypt all the communications (if NULL,
+        *            everything will be sent in clear text)
         */
-       public ConnectActionClient(Socket s, Version version) {
-               action = new ConnectAction(s, false, version) {
+       public ConnectActionClient(Socket s, String key) {
+               action = new ConnectAction(s, false, key) {
                        @Override
-                       protected void action(Version serverVersion) throws Exception {
-                               ConnectActionClient.this.action(serverVersion);
+                       protected void action() throws Exception {
+                               ConnectActionClient.this.clientHello();
+                               ConnectActionClient.this.action();
                        }
 
                        @Override
                        protected void onError(Exception e) {
                                ConnectActionClient.this.onError(e);
                        }
-
-                       @Override
-                       protected Version negotiateVersion(Version clientVersion) {
-                               new Exception("Should never be called on a client")
-                                               .printStackTrace();
-                               return null;
-                       }
                };
        }
 
+       /**
+        * Send the HELLO message (send a String "HELLO" to the server, to check I/O
+        * and encryption modes).
+        * <p>
+        * Will automatically handle the answer (the server must answer "HELLO" in
+        * kind).
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        * @throws SSLException
+        *             in case of encryption error
+        */
+       protected void clientHello() throws IOException {
+               String HELLO = action.sendString("HELLO");
+               if (!"HELLO".equals(HELLO)) {
+                       throw new SSLException("Server did not accept the encryption key");
+               }
+       }
+
        /**
         * Actually start the process and call the action (synchronous).
         */
@@ -122,14 +111,11 @@ abstract class ConnectActionClient {
        /**
         * Method that will be called when an action is performed on the client.
         * 
-        * @param serverVersion
-        *            the server version
-        * 
         * @throws Exception
         *             in case of I/O error
         */
        @SuppressWarnings("unused")
-       public void action(Version serverVersion) throws Exception {
+       public void action() throws Exception {
        }
 
        /**