Merge "Added multipart table response as notification in yang model."
[controller.git] / opendaylight / netconf / netconf-ssh / src / main / java / org / opendaylight / controller / netconf / ssh / threads / SocketThread.java
1 package org.opendaylight.controller.netconf.ssh.threads;
2
3
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.RSAKey;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 @ThreadSafe
21 public class SocketThread implements Runnable, ServerAuthenticationCallback, ServerConnectionCallback
22 {
23
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
34
35     public static void start(Socket socket, InetSocketAddress clientAddress, long sessionId) throws IOException{
36         Thread netconf_ssh_socket_thread = new Thread(new SocketThread(socket,clientAddress,sessionId));
37         netconf_ssh_socket_thread.setDaemon(true);
38         netconf_ssh_socket_thread.start();
39     }
40     private SocketThread(Socket socket, InetSocketAddress clientAddress, long sessionId) throws IOException {
41
42         this.socket = socket;
43         this.clientAddress = clientAddress;
44         this.sessionId = sessionId;
45         this.remoteAddressWithPort = socket.getRemoteSocketAddress().toString().replaceFirst("/","");
46
47     }
48
49     @Override
50     public void run() {
51         conn = new ServerConnection(socket);
52         RSAKey keyStore = new RSAKey();
53         conn.setRsaHostKey(keyStore.getPrivateKey());
54         conn.setAuthenticationCallback(this);
55         conn.setServerConnectionCallback(this);
56         try {
57             conn.connect();
58         } catch (IOException e) {
59             logger.error("SocketThread error ",e);
60         }
61     }
62     public ServerSessionCallback acceptSession(final ServerSession session)
63     {
64         SimpleServerSessionCallback cb = new SimpleServerSessionCallback()
65         {
66             @Override
67             public Runnable requestSubsystem(final ServerSession ss, final String subsystem) throws IOException
68             {
69                 return new Runnable(){
70                     public void run()
71                     {
72                         if (subsystem.equals("netconf")){
73                             IOThread netconf_ssh_input = null;
74                             IOThread  netconf_ssh_output = null;
75                             try {
76                                 String hostName = clientAddress.getHostName();
77                                 int portNumber = clientAddress.getPort();
78                                 final Socket echoSocket = new Socket(hostName, portNumber);
79                                 logger.trace("echo socket created");
80
81                                 logger.trace("starting netconf_ssh_input thread");
82                                 netconf_ssh_input =  new IOThread(echoSocket.getInputStream(),ss.getStdin(),"input_thread_"+sessionId,ss,conn);
83                                 netconf_ssh_input.setDaemon(false);
84                                 netconf_ssh_input.start();
85
86                                 logger.trace("starting netconf_ssh_output thread");
87                                 final String customHeader = "["+currentUser+";"+remoteAddressWithPort+";ssh;;;;;;]\n";
88                                 netconf_ssh_output = new IOThread(ss.getStdout(),echoSocket.getOutputStream(),"output_thread_"+sessionId,ss,conn,customHeader);
89                                 netconf_ssh_output.setDaemon(false);
90                                 netconf_ssh_output.start();
91
92                             } catch (Throwable t){
93                                 logger.error(t.getMessage(),t);
94
95                                 try {
96                                     if (netconf_ssh_input!=null){
97                                         netconf_ssh_input.join();
98                                     }
99                                 } catch (InterruptedException e) {
100                                    logger.error("netconf_ssh_input join error ",e);
101                                 }
102
103                                 try {
104                                     if (netconf_ssh_output!=null){
105                                         netconf_ssh_output.join();
106                                     }
107                                 } catch (InterruptedException e) {
108                                     logger.error("netconf_ssh_output join error ",e);
109                                 }
110
111                             }
112                         } else {
113                             try {
114                                 ss.getStdin().write("wrong subsystem requested - closing connection".getBytes());
115                                 ss.close();
116                             } catch (IOException e) {
117                                 logger.debug("excpetion while sending bad subsystem response",e);
118                             }
119                         }
120                     }
121                 };
122             }
123             @Override
124             public Runnable requestPtyReq(final ServerSession ss, final PtySettings pty) throws IOException
125             {
126                 return new Runnable()
127                 {
128                     public void run()
129                     {
130                         //noop
131                     }
132                 };
133             }
134
135             @Override
136             public Runnable requestShell(final ServerSession ss) throws IOException
137             {
138                 return new Runnable()
139                 {
140                     public void run()
141                     {
142                         //noop
143                     }
144                 };
145             }
146         };
147
148         return cb;
149     }
150
151     public String initAuthentication(ServerConnection sc)
152     {
153         logger.trace("Established connection with host {}",remoteAddressWithPort);
154         return "Established connection with host "+remoteAddressWithPort+"\r\n";
155     }
156
157     public String[] getRemainingAuthMethods(ServerConnection sc)
158     {
159         return new String[] { ServerAuthenticationCallback.METHOD_PASSWORD };
160     }
161
162     public AuthenticationResult authenticateWithNone(ServerConnection sc, String username)
163     {
164         return AuthenticationResult.FAILURE;
165     }
166
167     public AuthenticationResult authenticateWithPassword(ServerConnection sc, String username, String password)
168     {
169         if (USER.equals(username) && PASSWORD.equals(password)){
170             currentUser = username;
171             logger.trace("user {}@{} authenticated",currentUser,remoteAddressWithPort);
172             return AuthenticationResult.SUCCESS;
173         }
174
175
176         return AuthenticationResult.FAILURE;
177     }
178
179     public AuthenticationResult authenticateWithPublicKey(ServerConnection sc, String username, String algorithm,
180             byte[] publickey, byte[] signature)
181     {
182         return AuthenticationResult.FAILURE;
183     }
184
185 }