- netconf SSH bridge bundle
[controller.git] / opendaylight / netconf / netconf-ssh / src / main / java / org / opendaylight / controller / netconf / ssh / threads / SocketThread.java
diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java
new file mode 100644 (file)
index 0000000..95fdd48
--- /dev/null
@@ -0,0 +1,176 @@
+package org.opendaylight.controller.netconf.ssh.threads;
+
+
+import ch.ethz.ssh2.AuthenticationResult;
+import ch.ethz.ssh2.PtySettings;
+import ch.ethz.ssh2.ServerAuthenticationCallback;
+import ch.ethz.ssh2.ServerConnection;
+import ch.ethz.ssh2.ServerConnectionCallback;
+import ch.ethz.ssh2.ServerSession;
+import ch.ethz.ssh2.ServerSessionCallback;
+import ch.ethz.ssh2.SimpleServerSessionCallback;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import javax.annotation.concurrent.ThreadSafe;
+import org.opendaylight.controller.netconf.ssh.authentication.RSAKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@ThreadSafe
+public class SocketThread implements Runnable, ServerAuthenticationCallback, ServerConnectionCallback
+{
+
+    private Socket socket;
+    private static final String USER = "netconf";
+    private static final String PASSWORD = "netconf";
+    private InetSocketAddress clientAddress;
+    private static final Logger logger =  LoggerFactory.getLogger(SocketThread.class);
+    private ServerConnection conn = null;
+    private long sessionId;
+
+
+    public static void start(Socket socket, InetSocketAddress clientAddress, long sessionId) throws IOException{
+        Thread netconf_ssh_socket_thread = new Thread(new SocketThread(socket,clientAddress,sessionId));
+        netconf_ssh_socket_thread.setDaemon(true);
+        netconf_ssh_socket_thread.start();
+    }
+    private SocketThread(Socket socket, InetSocketAddress clientAddress, long sessionId) throws IOException {
+
+        this.socket = socket;
+        this.clientAddress = clientAddress;
+        this.sessionId = sessionId;
+
+    }
+
+    @Override
+    public void run() {
+        conn = new ServerConnection(socket);
+        RSAKey keyStore = new RSAKey();
+        conn.setRsaHostKey(keyStore.getPrivateKey());
+        conn.setAuthenticationCallback(this);
+        conn.setServerConnectionCallback(this);
+        try {
+            conn.connect();
+        } catch (IOException e) {
+            logger.error("SocketThread error ",e);
+        }
+    }
+    public ServerSessionCallback acceptSession(final ServerSession session)
+    {
+        SimpleServerSessionCallback cb = new SimpleServerSessionCallback()
+        {
+            @Override
+            public Runnable requestSubsystem(final ServerSession ss, final String subsystem) throws IOException
+            {
+                return new Runnable(){
+                    public void run()
+                    {
+                        if (subsystem.equals("netconf")){
+                            IOThread netconf_ssh_input = null;
+                            IOThread  netconf_ssh_output = null;
+                            try {
+                                String hostName = clientAddress.getHostName();
+                                int portNumber = clientAddress.getPort();
+                                final Socket echoSocket = new Socket(hostName, portNumber);
+                                logger.trace("echo socket created");
+
+                                logger.trace("starting netconf_ssh_input thread");
+                                netconf_ssh_input =  new IOThread(echoSocket.getInputStream(),ss.getStdin(),"input_thread_"+sessionId,ss,conn);
+                                netconf_ssh_input.setDaemon(false);
+                                netconf_ssh_input.start();
+
+                                logger.trace("starting netconf_ssh_output thread");
+                                netconf_ssh_output = new IOThread(ss.getStdout(),echoSocket.getOutputStream(),"output_thread_"+sessionId,ss,conn);
+                                netconf_ssh_output.setDaemon(false);
+                                netconf_ssh_output.start();
+
+                            } catch (Throwable t){
+                                logger.error(t.getMessage(),t);
+
+                                try {
+                                    if (netconf_ssh_input!=null){
+                                        netconf_ssh_input.join();
+                                    }
+                                } catch (InterruptedException e) {
+                                   logger.error("netconf_ssh_input join error ",e);
+                                }
+
+                                try {
+                                    if (netconf_ssh_output!=null){
+                                        netconf_ssh_output.join();
+                                    }
+                                } catch (InterruptedException e) {
+                                    logger.error("netconf_ssh_output join error ",e);
+                                }
+
+                            }
+                        } else {
+                            try {
+                                ss.getStdin().write("wrong subsystem requested - closing connection".getBytes());
+                                ss.close();
+                            } catch (IOException e) {
+                                logger.debug("excpetion while sending bad subsystem response",e);
+                            }
+                        }
+                    }
+                };
+            }
+            @Override
+            public Runnable requestPtyReq(final ServerSession ss, final PtySettings pty) throws IOException
+            {
+                return new Runnable()
+                {
+                    public void run()
+                    {
+                        //noop
+                    }
+                };
+            }
+
+            @Override
+            public Runnable requestShell(final ServerSession ss) throws IOException
+            {
+                return new Runnable()
+                {
+                    public void run()
+                    {
+                        //noop
+                    }
+                };
+            }
+        };
+
+        return cb;
+    }
+
+    public String initAuthentication(ServerConnection sc)
+    {
+        return "";
+    }
+
+    public String[] getRemainingAuthMethods(ServerConnection sc)
+    {
+        return new String[] { ServerAuthenticationCallback.METHOD_PASSWORD };
+    }
+
+    public AuthenticationResult authenticateWithNone(ServerConnection sc, String username)
+    {
+        return AuthenticationResult.FAILURE;
+    }
+
+    public AuthenticationResult authenticateWithPassword(ServerConnection sc, String username, String password)
+    {
+        if (USER.equals(username) && PASSWORD.equals(password))
+            return AuthenticationResult.SUCCESS;
+
+        return AuthenticationResult.FAILURE;
+    }
+
+    public AuthenticationResult authenticateWithPublicKey(ServerConnection sc, String username, String algorithm,
+            byte[] publickey, byte[] signature)
+    {
+        return AuthenticationResult.FAILURE;
+    }
+
+}