2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
 
   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
 
  12  *      http://www.apache.org/licenses/LICENSE-2.0
 
  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=========================================================
 
  22 package org.openecomp.appc.adapter.ssh.sshd;
 
  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;
 
  38 import java.io.OutputStream;
 
  39 import java.security.KeyPair;
 
  42  * Implementation of SshConnection interface based on Apache MINA SSHD library.
 
  44 class SshConnectionSshd implements SshConnection {
 
  46         private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger();
 
  48         private static final long AUTH_TIMEOUT = 60000;
 
  49         private static final long EXEC_TIMEOUT = 120000;
 
  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;
 
  60         public SshConnectionSshd(String host, int port, String username, String password, String keyFile) {
 
  63                 this.username = username;
 
  64                 this.password = password;
 
  65                 this.keyFile = keyFile;
 
  68         public SshConnectionSshd(String host, int port, String username, String password) {
 
  69                 this(host, port, username, password, null);
 
  72         public SshConnectionSshd(String host, int port, String keyFile) {
 
  73                 this(host, port, null, null, keyFile);
 
  77         public void connect() {
 
  78                 sshClient = SshClient.setUpDefaultClient();
 
  81                         clientSession = sshClient.connect(EncryptionTool.getInstance().decrypt(username), host, port).await().getSession();
 
  82                         if(password != null) {
 
  83                                 clientSession.addPasswordIdentity(EncryptionTool.getInstance().decrypt(password));
 
  86                                 KeyPairProvider keyPairProvider = new FileKeyPairProvider(new String[]{keyFile});
 
  87                                 KeyPair keyPair = keyPairProvider.loadKeys().iterator().next();
 
  88                                 clientSession.addPublicKeyIdentity(keyPair);
 
  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.");
 
  95                 } catch(RuntimeException e) {
 
  97                 } catch(Exception e) {
 
  98                         throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "].", e);
 
 100                 if(logger.isDebugEnabled()) {
 
 101                         logger.debug("SSH: connected to [" + toString() + "]");
 
 106         public void disconnect() {
 
 108                         if(logger.isDebugEnabled()) {
 
 109                                 logger.debug("SSH: disconnecting from [" + toString() + "]");
 
 111                         clientSession.close(false);
 
 113                         if(sshClient != null) {
 
 120         public void setExecTimeout(long timeout) {
 
 121                 this.timeout = timeout;
 
 125         public int execCommand(String cmd, OutputStream out, OutputStream err) {
 
 126                 return execCommand(cmd, out, err, false);
 
 130         public int execCommandWithPty(String cmd, OutputStream out) {
 
 131                 return execCommand(cmd, out, out, true);
 
 134         private int execCommand(String cmd, OutputStream out, OutputStream err, boolean usePty) {
 
 136                         if(logger.isDebugEnabled()) {
 
 137                                 logger.debug("SSH: executing command");
 
 139                         ChannelExec client = clientSession.createExecChannel(cmd);
 
 140             client.setUsePty(usePty); // use pseudo-tty?
 
 143                         OpenFuture openFuture = client.open();
 
 146                                 client.waitFor(ClientChannel.CLOSED, timeout);
 
 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.");
 
 152                                 exitStatus = exitStatusI;
 
 157                 } catch(RuntimeException e) {
 
 159                 } catch(Exception t) {
 
 160                         throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]", t);
 
 165         public String toString() {
 
 166                 String address = host;
 
 167                 if(username != null) {
 
 168                         address = username + '@' +address;