Search in sources :

Example 1 with ClientChannel

use of org.apache.sshd.ClientChannel in project fabric8 by jboss-fuse.

the class ContainerConnectAction method executSshCommand.

/**
 * Executes the ssh command.
 */
private void executSshCommand(CommandSession session, String username, String password, String hostname, String port, String cmd) throws Exception {
    if (cmd == null || cmd.length() == 0) {
        // ENTESB-6826: we're connecting in "shell" mode, which isn't wise when running from bin/client or ssh
        if (session.getKeyboard().getClass().getName().equals("org.apache.sshd.common.channel.ChannelPipedInputStream")) {
            System.err.println("When connecting to remote container using \"fabric:container-connect\" using ssh or bin/client, please establish SSH session (run bin/client) first and then run \"fabric:container-connect\"");
            return;
        }
    }
    // Create the client from prototype
    SshClient client = createClient();
    String agentSocket;
    if (this.session.get(SshAgent.SSH_AUTHSOCKET_ENV_NAME) != null) {
        agentSocket = this.session.get(SshAgent.SSH_AUTHSOCKET_ENV_NAME).toString();
        client.getProperties().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, agentSocket);
    }
    try {
        ConnectFuture future = client.connect(hostname, Integer.parseInt(port));
        future.await();
        sshSession = future.getSession();
        Object oldIgnoreInterrupts = this.session.get(Console.IGNORE_INTERRUPTS);
        this.session.put(Console.IGNORE_INTERRUPTS, Boolean.TRUE);
        try {
            System.out.println("Connected");
            boolean authed = false;
            if (!authed) {
                if (username == null) {
                    throw new FabricAuthenticationException("No username specified.");
                }
                log.debug("Prompting user for password");
                String pwd = password != null ? password : ShellUtils.readLine(session, "Password: ", true);
                sshSession.authPassword(username, pwd);
                int ret = sshSession.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0);
                if ((ret & ClientSession.AUTHED) == 0) {
                    System.err.println("Password authentication failed");
                } else {
                    authed = true;
                }
            }
            if (!authed) {
                throw new FabricAuthenticationException("Failed to authenticate.");
            }
            // If user is authenticated credentials to session for future use.
            ShellUtils.storeFabricCredentials(session, username, password);
            ClientChannel channel;
            if (cmd != null && cmd.length() > 0) {
                channel = sshSession.createChannel("exec", cmd);
                channel.setIn(new ByteArrayInputStream(new byte[0]));
            } else {
                channel = sshSession.createChannel("shell");
                channel.setIn(new NoCloseInputStream(System.in));
                ((ChannelShell) channel).setPtyColumns(ShellUtils.getTermWidth(session));
                ((ChannelShell) channel).setupSensibleDefaultPty();
                ((ChannelShell) channel).setAgentForwarding(true);
            }
            channel.setOut(new NoCloseOutputStream(System.out));
            channel.setErr(new NoCloseOutputStream(System.err));
            channel.open();
            channel.waitFor(ClientChannel.CLOSED, 0);
        } finally {
            session.put(Console.IGNORE_INTERRUPTS, oldIgnoreInterrupts);
            sshSession.close(false);
        }
    } finally {
        client.stop();
    }
}
Also used : NoCloseInputStream(org.apache.sshd.common.util.NoCloseInputStream) SshClient(org.apache.sshd.SshClient) FabricAuthenticationException(io.fabric8.api.FabricAuthenticationException) ByteArrayInputStream(java.io.ByteArrayInputStream) ConnectFuture(org.apache.sshd.client.future.ConnectFuture) ChannelShell(org.apache.sshd.client.channel.ChannelShell) NoCloseOutputStream(org.apache.sshd.common.util.NoCloseOutputStream) ClientChannel(org.apache.sshd.ClientChannel)

Example 2 with ClientChannel

use of org.apache.sshd.ClientChannel in project ovirt-engine by oVirt.

the class SSHClient method executeCommand.

/**
 * Execute generic command.
 *
 * @param command
 *            command to execute.
 * @param in
 *            stdin.
 * @param out
 *            stdout.
 * @param err
 *            stderr.
 */
public void executeCommand(String command, InputStream in, OutputStream out, OutputStream err) throws Exception {
    log.debug("Executing: '{}'", command);
    if (in == null) {
        in = new ByteArrayInputStream(new byte[0]);
    }
    if (out == null) {
        out = new ConstraintByteArrayOutputStream(CONSTRAINT_BUFFER_SIZE);
    }
    if (err == null) {
        err = new ConstraintByteArrayOutputStream(CONSTRAINT_BUFFER_SIZE);
    }
    /*
         * Redirect streams into indexed streams.
         */
    ClientChannel channel = null;
    try (final ProgressInputStream iin = new ProgressInputStream(in);
        final ProgressOutputStream iout = new ProgressOutputStream(out);
        final ProgressOutputStream ierr = new ProgressOutputStream(err)) {
        channel = session.createExecChannel(command);
        channel.setIn(iin);
        channel.setOut(iout);
        channel.setErr(ierr);
        channel.open();
        long hardEnd = 0;
        if (hardTimeout != 0) {
            hardEnd = System.currentTimeMillis() + hardTimeout;
        }
        boolean hardTimeout = false;
        int stat;
        boolean activity;
        do {
            stat = channel.waitFor(ClientChannel.CLOSED | ClientChannel.EOF | ClientChannel.TIMEOUT, softTimeout);
            hardTimeout = hardEnd != 0 && System.currentTimeMillis() >= hardEnd;
            /*
                 * Notice that we should visit all so do not cascade statement.
                 */
            activity = iin.wasProgress();
            activity = iout.wasProgress() || activity;
            activity = ierr.wasProgress() || activity;
        } while (!hardTimeout && (stat & ClientChannel.TIMEOUT) != 0 && activity);
        if (hardTimeout) {
            throw new TimeLimitExceededException(String.format("SSH session hard timeout host '%1$s'", this.getDisplayHost()));
        }
        if ((stat & ClientChannel.TIMEOUT) != 0) {
            throw new TimeLimitExceededException(String.format("SSH session timeout host '%1$s'", this.getDisplayHost()));
        }
        stat = channel.waitFor(ClientChannel.CLOSED | ClientChannel.EXIT_STATUS | ClientChannel.EXIT_SIGNAL | ClientChannel.TIMEOUT, softTimeout);
        if ((stat & ClientChannel.EXIT_SIGNAL) != 0) {
            throw new IOException(String.format("Signal received during SSH session host '%1$s'", this.getDisplayHost()));
        }
        if ((stat & ClientChannel.EXIT_STATUS) != 0 && channel.getExitStatus() != 0) {
            throw new IOException(String.format("Command returned failure code %2$d during SSH session '%1$s'", this.getDisplayHost(), channel.getExitStatus()));
        }
        if ((stat & ClientChannel.TIMEOUT) != 0) {
            throw new TimeLimitExceededException(String.format("SSH session timeout waiting for status host '%1$s'", this.getDisplayHost()));
        }
        // the PipedOutputStream does not
        // flush streams at close
        // this leads other side of pipe
        // to miss last bytes
        // not sure why it is required as
        // FilteredOutputStream does flush
        // on close.
        out.flush();
        err.flush();
    } catch (RuntimeException e) {
        log.error("Execute failed", ExceptionUtils.getRootCauseMessage(e));
        log.debug("Exception", e);
        throw e;
    } finally {
        if (channel != null) {
            int stat = channel.waitFor(ClientChannel.CLOSED | ClientChannel.TIMEOUT, 1);
            if ((stat & ClientChannel.CLOSED) != 0) {
                channel.close(true);
            }
        }
    }
    log.debug("Executed: '{}'", command);
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) TimeLimitExceededException(javax.naming.TimeLimitExceededException) IOException(java.io.IOException) ClientChannel(org.apache.sshd.ClientChannel)

Example 3 with ClientChannel

use of org.apache.sshd.ClientChannel in project camel by apache.

the class SshHelper method sendExecCommand.

public static SshResult sendExecCommand(String command, SshEndpoint endpoint, SshClient client) throws Exception {
    SshResult result = null;
    SshConfiguration configuration = endpoint.getConfiguration();
    if (configuration == null) {
        throw new IllegalStateException("Configuration must be set");
    }
    ConnectFuture connectFuture = client.connect(null, configuration.getHost(), configuration.getPort());
    // Wait getTimeout milliseconds for connect operation to complete
    connectFuture.await(configuration.getTimeout());
    if (!connectFuture.isDone() || !connectFuture.isConnected()) {
        final String msg = "Failed to connect to " + configuration.getHost() + ":" + configuration.getPort() + " within timeout " + configuration.getTimeout() + "ms";
        LOG.debug(msg);
        throw new RuntimeCamelException(msg);
    }
    LOG.debug("Connected to {}:{}", configuration.getHost(), configuration.getPort());
    ClientChannel channel = null;
    ClientSession session = null;
    try {
        AuthFuture authResult;
        session = connectFuture.getSession();
        KeyPairProvider keyPairProvider;
        final String certResource = configuration.getCertResource();
        if (certResource != null) {
            LOG.debug("Attempting to authenticate using ResourceKey '{}'...", certResource);
            keyPairProvider = new ResourceHelperKeyPairProvider(new String[] { certResource }, endpoint.getCamelContext().getClassResolver());
        } else {
            keyPairProvider = configuration.getKeyPairProvider();
        }
        if (keyPairProvider != null) {
            LOG.debug("Attempting to authenticate username '{}' using Key...", configuration.getUsername());
            KeyPair pair = keyPairProvider.loadKey(configuration.getKeyType());
            authResult = session.authPublicKey(configuration.getUsername(), pair);
        } else {
            LOG.debug("Attempting to authenticate username '{}' using Password...", configuration.getUsername());
            authResult = session.authPassword(configuration.getUsername(), configuration.getPassword());
        }
        authResult.await(configuration.getTimeout());
        if (!authResult.isDone() || authResult.isFailure()) {
            LOG.debug("Failed to authenticate");
            throw new RuntimeCamelException("Failed to authenticate username " + configuration.getUsername());
        }
        channel = session.createChannel(ClientChannel.CHANNEL_EXEC, command);
        ByteArrayInputStream in = new ByteArrayInputStream(new byte[] { 0 });
        channel.setIn(in);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        channel.setOut(out);
        ByteArrayOutputStream err = new ByteArrayOutputStream();
        channel.setErr(err);
        OpenFuture openFuture = channel.open();
        openFuture.await(configuration.getTimeout());
        if (openFuture.isOpened()) {
            channel.waitFor(ClientChannel.CLOSED, 0);
            result = new SshResult(command, channel.getExitStatus(), new ByteArrayInputStream(out.toByteArray()), new ByteArrayInputStream(err.toByteArray()));
        }
        return result;
    } finally {
        if (channel != null) {
            channel.close(true);
        }
        // need to make sure the session is closed 
        if (session != null) {
            session.close(false);
        }
    }
}
Also used : KeyPair(java.security.KeyPair) ConnectFuture(org.apache.sshd.client.future.ConnectFuture) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ClientChannel(org.apache.sshd.ClientChannel) KeyPairProvider(org.apache.sshd.common.KeyPairProvider) OpenFuture(org.apache.sshd.client.future.OpenFuture) ByteArrayInputStream(java.io.ByteArrayInputStream) ClientSession(org.apache.sshd.ClientSession) RuntimeCamelException(org.apache.camel.RuntimeCamelException) AuthFuture(org.apache.sshd.client.future.AuthFuture)

Aggregations

ByteArrayInputStream (java.io.ByteArrayInputStream)3 ClientChannel (org.apache.sshd.ClientChannel)3 ConnectFuture (org.apache.sshd.client.future.ConnectFuture)2 FabricAuthenticationException (io.fabric8.api.FabricAuthenticationException)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 KeyPair (java.security.KeyPair)1 TimeLimitExceededException (javax.naming.TimeLimitExceededException)1 RuntimeCamelException (org.apache.camel.RuntimeCamelException)1 ClientSession (org.apache.sshd.ClientSession)1 SshClient (org.apache.sshd.SshClient)1 ChannelShell (org.apache.sshd.client.channel.ChannelShell)1 AuthFuture (org.apache.sshd.client.future.AuthFuture)1 OpenFuture (org.apache.sshd.client.future.OpenFuture)1 KeyPairProvider (org.apache.sshd.common.KeyPairProvider)1 NoCloseInputStream (org.apache.sshd.common.util.NoCloseInputStream)1 NoCloseOutputStream (org.apache.sshd.common.util.NoCloseOutputStream)1