Change nexus values to properties
[appc.git] / appc-adapters / appc-ssh-adapter / appc-ssh-adapter-sshd / src / main / java / org / openecomp / appc / adapter / ssh / sshd / SshConnectionSshd.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : APP-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.appc.adapter.ssh.sshd;
23
24 import org.apache.sshd.ClientChannel;
25 import org.apache.sshd.ClientSession;
26 import org.apache.sshd.SshClient;
27 import org.apache.sshd.client.channel.ChannelExec;
28 import org.apache.sshd.client.future.AuthFuture;
29 import org.apache.sshd.client.future.OpenFuture;
30 import org.apache.sshd.common.KeyPairProvider;
31 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
32 import org.openecomp.appc.adapter.ssh.SshConnection;
33 import org.openecomp.appc.adapter.ssh.SshException;
34 import org.openecomp.appc.encryption.EncryptionTool;
35 import com.att.eelf.configuration.EELFLogger;
36 import com.att.eelf.configuration.EELFManager;
37
38 import java.io.OutputStream;
39 import java.security.KeyPair;
40
41 /**
42  * Implementation of SshConnection interface based on Apache MINA SSHD library.
43  */
44 class SshConnectionSshd implements SshConnection {
45
46         private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger();
47
48         private static final long AUTH_TIMEOUT = 60000;
49         private static final long EXEC_TIMEOUT = 120000;
50
51         private String host;
52         private int port;
53         private String username;
54         private String password;
55         private long timeout = EXEC_TIMEOUT;
56         private String keyFile;
57         private SshClient sshClient;
58         private ClientSession clientSession;
59
60         public SshConnectionSshd(String host, int port, String username, String password, String keyFile) {
61                 this.host = host;
62                 this.port = port;
63                 this.username = username;
64                 this.password = password;
65                 this.keyFile = keyFile;
66         }
67
68         public SshConnectionSshd(String host, int port, String username, String password) {
69                 this(host, port, username, password, null);
70         }
71
72         public SshConnectionSshd(String host, int port, String keyFile) {
73                 this(host, port, null, null, keyFile);
74         }
75
76         @Override
77         public void connect() {
78                 sshClient = SshClient.setUpDefaultClient();
79                 sshClient.start();
80                 try {
81                         clientSession = sshClient.connect(EncryptionTool.getInstance().decrypt(username), host, port).await().getSession();
82                         if(password != null) {
83                                 clientSession.addPasswordIdentity(EncryptionTool.getInstance().decrypt(password));
84                         }
85                         if(keyFile != null) {
86                                 KeyPairProvider keyPairProvider = new FileKeyPairProvider(new String[]{keyFile});
87                                 KeyPair keyPair = keyPairProvider.loadKeys().iterator().next();
88                                 clientSession.addPublicKeyIdentity(keyPair);
89                         }
90                         AuthFuture authFuture = clientSession.auth();
91                         authFuture.await(AUTH_TIMEOUT);
92                         if(!authFuture.isSuccess()) {
93                                 throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "]. Authentication failed.");
94                         }
95                 } catch(RuntimeException e) {
96                         throw e;
97                 } catch(Exception e) {
98                         throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "].", e);
99                 }
100                 if(logger.isDebugEnabled()) {
101                         logger.debug("SSH: connected to [" + toString() + "]");
102                 }
103         }
104
105         @Override
106         public void disconnect() {
107                 try {
108                         if(logger.isDebugEnabled()) {
109                                 logger.debug("SSH: disconnecting from [" + toString() + "]");
110                         }
111                         clientSession.close(false);
112                 } finally {
113                         if(sshClient != null) {
114                                 sshClient.stop();
115                         }
116                 }
117         }
118
119         @Override
120         public void setExecTimeout(long timeout) {
121                 this.timeout = timeout;
122         }
123
124         @Override
125         public int execCommand(String cmd, OutputStream out, OutputStream err) {
126                 return execCommand(cmd, out, err, false);
127         }
128
129         @Override
130         public int execCommandWithPty(String cmd, OutputStream out) {
131                 return execCommand(cmd, out, out, true);
132         }
133
134         private int execCommand(String cmd, OutputStream out, OutputStream err, boolean usePty) {
135                 try {
136                         if(logger.isDebugEnabled()) {
137                                 logger.debug("SSH: executing command");
138                         }
139                         ChannelExec client = clientSession.createExecChannel(cmd);
140             client.setUsePty(usePty); // use pseudo-tty?
141                         client.setOut(out);
142                         client.setErr(err);
143                         OpenFuture openFuture = client.open();
144                         int exitStatus = 0;
145                         try {
146                                 client.waitFor(ClientChannel.CLOSED, timeout);
147                                 openFuture.verify();
148                                 Integer exitStatusI = client.getExitStatus();
149                                 if(exitStatusI == null) {
150                                         throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]. Operation timed out.");
151                                 }
152                                 exitStatus = exitStatusI;
153                         } finally {
154                                 client.close(false);
155                         }
156                         return exitStatus;
157                 } catch(RuntimeException e) {
158                         throw e;
159                 } catch(Exception t) {
160                         throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]", t);
161                 }
162         }
163
164         @Override
165         public String toString() {
166                 String address = host;
167                 if(username != null) {
168                         address = username + '@' +address;
169                 }
170                 return address;
171         }
172 }