All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.consol.citrus.ssh.server.SshServer Maven / Gradle / Ivy

There is a newer version: 3.4.1
Show newest version
/*
 * Copyright 2006-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.consol.citrus.ssh.server;

import com.consol.citrus.exceptions.CitrusRuntimeException;
import com.consol.citrus.server.AbstractServer;
import com.consol.citrus.ssh.SshCommand;
import com.consol.citrus.ssh.client.SshEndpointConfiguration;
import com.consol.citrus.ssh.message.SshMessageConverter;
import org.apache.sshd.common.keyprovider.AbstractClassLoadableResourceKeyPairProvider;
import org.apache.sshd.common.keyprovider.AbstractFileKeyPairProvider;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.CommandFactory;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

/**
 * SSH Server implemented with Apache SSHD (http://mina.apache.org/sshd/).
 *
 * It uses the same semantic as the Jetty Servers for HTTP and WS mocks and translates
 * an incoming request into a message, for which a reply message gets translates to
 * the SSH return value.
 *
 * The incoming message generated has the following format:
 *
 * 
 *   cat -
 *   This is the standard input sent
 * 
 *
 * The reply message to be generated by a handler should have the following format
 *
 * 
 *   0
 *   This is the standard input sent
 *   warning: no tty
 * 
 *
 * @author Roland Huss
 * @since 04.09.12
 */
public class SshServer extends AbstractServer {

    /** Port to listen to **/
    private int port = 22;

    /** User allowed to connect **/
    private String user;

    /** User's password or ... **/
    private String password;

    /** ... path to its public key **/
    /** Use this to convert to PEM: ssh-keygen -f key.pub -e -m pem **/
    private String allowedKeyPath;

    /** Path to our own host keys. If not provided, a default is used. The format of this **/
    /** file should be PEM, a serialized {@link java.security.KeyPair}. **/
    private String hostKeyPath;

    /** Ssh message converter */
    private SshMessageConverter messageConverter = new SshMessageConverter();

    /** SSH server used **/
    private org.apache.sshd.server.SshServer sshd;

    @Override
    protected void startup() {
        if (!StringUtils.hasText(user)) {
            throw new CitrusRuntimeException("No 'user' provided (mandatory for authentication)");
        }
        sshd = org.apache.sshd.server.SshServer.setUpDefaultServer();
        sshd.setPort(port);

        if (hostKeyPath != null) {
            AbstractFileKeyPairProvider fileKeyPairProvider = SecurityUtils.createFileKeyPairProvider();
            fileKeyPairProvider.setPaths(Arrays.asList(new File(hostKeyPath).toPath()));
            sshd.setKeyPairProvider(fileKeyPairProvider);
        } else {
            AbstractClassLoadableResourceKeyPairProvider resourceKeyPairProvider = SecurityUtils.createClassLoadableResourceKeyPairProvider();
            resourceKeyPairProvider.setResources(Arrays.asList("com/consol/citrus/ssh/citrus.pem"));
            sshd.setKeyPairProvider(resourceKeyPairProvider);
        }

        // Authentication
        boolean authFound = false;
        if (password != null) {
            sshd.setPasswordAuthenticator(new SimplePasswordAuthenticator(user, password));
            authFound = true;
        }

        if (allowedKeyPath != null) {
            sshd.setPublickeyAuthenticator(new SinglePublicKeyAuthenticator(user, allowedKeyPath));
            authFound = true;
        }

        if (!authFound) {
            throw new CitrusRuntimeException("Neither 'password' nor 'allowed-key-path' is set. Please provide at least one");
        }

        // Setup endpoint adapter
        sshd.setCommandFactory(new CommandFactory() {
            public Command createCommand(String command) {
                return new SshCommand(command, getEndpointAdapter(), getEndpointConfiguration());
            }
        });

        try {
            sshd.start();
        } catch (IOException e) {
            throw new CitrusRuntimeException("Cannot start SSHD: " + e,e);
        }
    }

    @Override
    protected void shutdown() {
        try {
            sshd.stop();
        } catch (IOException e) {
            throw new CitrusRuntimeException("Cannot stop SSHD: " + e,e);
        }
    }

    @Override
    public SshEndpointConfiguration getEndpointConfiguration() {
        SshEndpointConfiguration endpointConfiguration = new SshEndpointConfiguration();
        endpointConfiguration.setMessageConverter(messageConverter);
        endpointConfiguration.setPort(port);
        endpointConfiguration.setUser(user);
        endpointConfiguration.setPassword(password);
        return endpointConfiguration;
    }

    /**
     * Gets the server port.
     * @return
     */
    public int getPort() {
        return port;
    }

    /**
     * Sets the port.
     * @param port the port to set
     */
    public void setPort(int port) {
        this.port = port;
    }

    /**
     * Gets the username.
     * @return
     */
    public String getUser() {
        return user;
    }

    /**
     * Sets the user.
     * @param user the user to set
     */
    public void setUser(String user) {
        this.user = user;
    }

    /**
     * Gets the user password.
     * @return
     */
    public String getPassword() {
        return password;
    }

    /**
     * Sets the password.
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * Gets the allowed key path.
     * @return
     */
    public String getAllowedKeyPath() {
        return allowedKeyPath;
    }

    /**
     * Sets the allowedKeyPath.
     * @param allowedKeyPath the allowedKeyPath to set
     */
    public void setAllowedKeyPath(String allowedKeyPath) {
        this.allowedKeyPath = allowedKeyPath;
    }

    /**
     * Gets the host key path.
     * @return
     */
    public String getHostKeyPath() {
        return hostKeyPath;
    }

    /**
     * Sets the hostKeyPath.
     * @param hostKeyPath the hostKeyPath to set
     */
    public void setHostKeyPath(String hostKeyPath) {
        this.hostKeyPath = hostKeyPath;
    }

    /**
     * Gets the message converter.
     * @return
     */
    public SshMessageConverter getMessageConverter() {
        return messageConverter;
    }

    /**
     * Sets the message converter.
     * @param messageConverter
     */
    public void setMessageConverter(SshMessageConverter messageConverter) {
        this.messageConverter = messageConverter;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy