/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2015 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * 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 org.pentaho.di.job.entries.sftp; import java.io.IOException; import java.util.Collections; import java.util.Properties; import java.util.Random; import java.util.UUID; import org.apache.sshd.SshServer; import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory; import org.apache.sshd.server.Command; import org.apache.sshd.server.PasswordAuthenticator; import org.apache.sshd.server.command.ScpCommandFactory; import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; import org.apache.sshd.server.session.ServerSession; import org.apache.sshd.sftp.subsystem.SftpSubsystem; import org.junit.rules.TemporaryFolder; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; /** * @author Andrey Khayrutdinov */ public class SftpServer implements PasswordAuthenticator { /** * Creates a server's instance for <tt>localhost</tt> using random values for username, password, and port. * * @param folder temporary folder * @return server's instance * @throws IOException */ public static SftpServer createDefaultServer( TemporaryFolder folder ) throws IOException { return new SftpServer( "fakeuser", UUID.randomUUID().toString(), new Random().nextInt( 20000 ) + 1024, folder.getRoot().getAbsolutePath(), folder.newFile( "server.key" ).getAbsolutePath() ); } private final String username; private final String password; private final SshServer server; /** * Creates a server's instance for <tt>localhost</tt>, using supplied values for username, password, and port. * * @param username * The username that will be allowed for authentication * @param password * The password that will be allowed for authentication * @param port * The port number that the SSH Server should listen on * @param homeDir * The local directory that should be the SSH Server's root directory * @param hostKeyPath * The file that should be used to store the SSH Host Key * @return * An SftpServer instance * @throws IOException */ public SftpServer( String username, String password, int port, String homeDir, String hostKeyPath ) { this.username = username; this.password = password; this.server = createSshServer( port, homeDir, hostKeyPath ); } private SshServer createSshServer( int port, String homeDir, String hostKeyPath ) { SshServer server = SshServer.setUpDefaultServer(); server.setHost( "localhost" ); server.setPort( port ); server.setFileSystemFactory( new VirtualFileSystemFactory( homeDir ) ); server.setSubsystemFactories( Collections.<NamedFactory<Command>>singletonList( new SftpSubsystem.Factory() ) ); server.setCommandFactory( new ScpCommandFactory() ); server.setKeyPairProvider( new SimpleGeneratorHostKeyProvider( hostKeyPath ) ); server.setPasswordAuthenticator( this ); return server; } public String getUsername() { return username; } public String getPassword() { return password; } public int getPort() { return server.getPort(); } public void start() throws IOException { server.start(); } public void stop() throws InterruptedException { server.stop(); } public Session createJschSession() throws JSchException { JSch jsch = new JSch(); com.jcraft.jsch.Session session = jsch.getSession( username, server.getHost(), server.getPort() ); session.setPassword( password ); Properties config = new java.util.Properties(); config.put( "StrictHostKeyChecking", "no" ); session.setConfig( config ); return session; } @Override public boolean authenticate( String username, String password, ServerSession session ) { return this.username.equals( username ) && this.password.equals( password ); } }