1 package org.opendaylight.controller.netconf.ssh.threads;
4 import ch.ethz.ssh2.AuthenticationResult;
5 import ch.ethz.ssh2.PtySettings;
6 import ch.ethz.ssh2.ServerAuthenticationCallback;
7 import ch.ethz.ssh2.ServerConnection;
8 import ch.ethz.ssh2.ServerConnectionCallback;
9 import ch.ethz.ssh2.ServerSession;
10 import ch.ethz.ssh2.ServerSessionCallback;
11 import ch.ethz.ssh2.SimpleServerSessionCallback;
12 import java.io.IOException;
13 import java.net.InetSocketAddress;
14 import java.net.Socket;
15 import javax.annotation.concurrent.ThreadSafe;
16 import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
21 public class SocketThread implements Runnable, ServerAuthenticationCallback, ServerConnectionCallback
24 private Socket socket;
25 private static final String USER = "netconf";
26 private static final String PASSWORD = "netconf";
27 private InetSocketAddress clientAddress;
28 private static final Logger logger = LoggerFactory.getLogger(SocketThread.class);
29 private ServerConnection conn = null;
30 private long sessionId;
31 private String currentUser;
32 private final String remoteAddressWithPort;
33 private final AuthProvider authProvider;
36 public static void start(Socket socket,
37 InetSocketAddress clientAddress,
39 AuthProvider authProvider) throws IOException{
40 Thread netconf_ssh_socket_thread = new Thread(new SocketThread(socket,clientAddress,sessionId,authProvider));
41 netconf_ssh_socket_thread.setDaemon(true);
42 netconf_ssh_socket_thread.start();
44 private SocketThread(Socket socket,
45 InetSocketAddress clientAddress,
47 AuthProvider authProvider) throws IOException {
50 this.clientAddress = clientAddress;
51 this.sessionId = sessionId;
52 this.remoteAddressWithPort = socket.getRemoteSocketAddress().toString().replaceFirst("/","");
53 this.authProvider = authProvider;
59 conn = new ServerConnection(socket);
61 conn.setPEMHostKey(authProvider.getPEMAsCharArray(),"netconf");
62 } catch (Exception e) {
63 logger.debug("Server authentication setup failed.");
65 conn.setAuthenticationCallback(this);
66 conn.setServerConnectionCallback(this);
69 } catch (IOException e) {
70 logger.error("SocketThread error ",e);
73 public ServerSessionCallback acceptSession(final ServerSession session)
75 SimpleServerSessionCallback cb = new SimpleServerSessionCallback()
78 public Runnable requestSubsystem(final ServerSession ss, final String subsystem) throws IOException
80 return new Runnable(){
83 if (subsystem.equals("netconf")){
84 IOThread netconf_ssh_input = null;
85 IOThread netconf_ssh_output = null;
87 String hostName = clientAddress.getHostName();
88 int portNumber = clientAddress.getPort();
89 final Socket echoSocket = new Socket(hostName, portNumber);
90 logger.trace("echo socket created");
92 logger.trace("starting netconf_ssh_input thread");
93 netconf_ssh_input = new IOThread(echoSocket.getInputStream(),ss.getStdin(),"input_thread_"+sessionId,ss,conn);
94 netconf_ssh_input.setDaemon(false);
95 netconf_ssh_input.start();
97 logger.trace("starting netconf_ssh_output thread");
98 final String customHeader = "["+currentUser+";"+remoteAddressWithPort+";ssh;;;;;;]\n";
99 netconf_ssh_output = new IOThread(ss.getStdout(),echoSocket.getOutputStream(),"output_thread_"+sessionId,ss,conn,customHeader);
100 netconf_ssh_output.setDaemon(false);
101 netconf_ssh_output.start();
103 } catch (Throwable t){
104 logger.error("SSH bridge couldn't create echo socket",t.getMessage(),t);
107 if (netconf_ssh_input!=null){
108 netconf_ssh_input.join();
110 } catch (InterruptedException e) {
111 Thread.currentThread().interrupt();
112 logger.error("netconf_ssh_input join error ",e);
116 if (netconf_ssh_output!=null){
117 netconf_ssh_output.join();
119 } catch (InterruptedException e) {
120 Thread.currentThread().interrupt();
121 logger.error("netconf_ssh_output join error ",e);
127 ss.getStdin().write("wrong subsystem requested - closing connection".getBytes());
129 } catch (IOException e) {
130 logger.debug("excpetion while sending bad subsystem response",e);
137 public Runnable requestPtyReq(final ServerSession ss, final PtySettings pty) throws IOException
139 return new Runnable()
149 public Runnable requestShell(final ServerSession ss) throws IOException
151 return new Runnable()
164 public String initAuthentication(ServerConnection sc)
166 logger.trace("Established connection with host {}",remoteAddressWithPort);
167 return "Established connection with host "+remoteAddressWithPort+"\r\n";
170 public String[] getRemainingAuthMethods(ServerConnection sc)
172 return new String[] { ServerAuthenticationCallback.METHOD_PASSWORD };
175 public AuthenticationResult authenticateWithNone(ServerConnection sc, String username)
177 return AuthenticationResult.FAILURE;
180 public AuthenticationResult authenticateWithPassword(ServerConnection sc, String username, String password)
184 if (authProvider.authenticated(username,password)){
185 currentUser = username;
186 logger.trace("user {}@{} authenticated",currentUser,remoteAddressWithPort);
187 return AuthenticationResult.SUCCESS;
189 } catch (Exception e){
190 logger.info("Authentication failed due to :" + e.getLocalizedMessage());
192 return AuthenticationResult.FAILURE;
195 public AuthenticationResult authenticateWithPublicKey(ServerConnection sc, String username, String algorithm,
196 byte[] publickey, byte[] signature)
198 return AuthenticationResult.FAILURE;