Skip to content

Instantly share code, notes, and snippets.

@ToastShaman
Created November 13, 2013 18:40
Show Gist options
  • Save ToastShaman/7454077 to your computer and use it in GitHub Desktop.
Save ToastShaman/7454077 to your computer and use it in GitHub Desktop.
Using an embedded Apache MINA SSHD server in a unit test to verify that your code is able to upload a file through SFTP. This unit tests uses JSch as the client to speak to an embedded Apache MINA sftp server and verifies that the upload of a text file was successful.
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-sftp</artifactId>
<version>0.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.vngx</groupId>
<artifactId>vngx-jsch</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sshd.SshServer;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.Session;
import org.apache.sshd.common.file.FileSystemView;
import org.apache.sshd.common.file.nativefs.NativeFileSystemFactory;
import org.apache.sshd.common.file.nativefs.NativeFileSystemView;
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.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.vngx.jsch.ChannelSftp;
import org.vngx.jsch.ChannelType;
import org.vngx.jsch.JSch;
import org.vngx.jsch.config.SessionConfig;
public class SftpServiceTest {
@Rule
public TemporaryFolder testFolder = new TemporaryFolder();
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private SshServer sshd;
@Before
public void prepare() throws IOException {
setupSSHServer();
}
private void setupSSHServer() throws IOException {
sshd = SshServer.setUpDefaultServer();
sshd.setFileSystemFactory(new NativeFileSystemFactory() {
@Override
public FileSystemView createFileSystemView(final Session session) {
return new NativeFileSystemView(session.getUsername(), false) {
@Override
public String getVirtualUserDir() {
return testFolder.getRoot().getAbsolutePath();
}
};
};
});
sshd.setPort(8001);
sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
sshd.setCommandFactory(new ScpCommandFactory());
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(testFolder.newFile("hostkey.ser").getAbsolutePath()));
sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
@Override
public boolean authenticate(final String username, final String password, final ServerSession session) {
return StringUtils.equals(username, USERNAME) && StringUtils.equals(password, PASSWORD);
}
});
sshd.start();
}
@Test
public void testUploadingFiles() throws Exception {
sendFile("test.txt", "abc");
assertThat(new File(testFolder.getRoot(), "test.txt").exists(), equalTo(true));
}
@After
public void cleanup() throws InterruptedException {
try {
sshd.stop(true);
} catch (Exception e) {
// do nothing
}
}
private void sendFile(final String filename, final String contents) throws Exception {
SessionConfig config = new SessionConfig();
config.setProperty(SessionConfig.STRICT_HOST_KEY_CHECKING, "no");
org.vngx.jsch.Session session = JSch.getInstance().createSession(USERNAME, "localhost", 8001, config);
session.connect(PASSWORD.getBytes(StandardCharsets.UTF_8));
ChannelSftp sftpChannel = session.openChannel(ChannelType.SFTP);
sftpChannel.connect();
OutputStream out = sftpChannel.put(filename);
out.write(contents.getBytes(StandardCharsets.UTF_8));
IOUtils.closeQuietly(out);
sftpChannel.disconnect();
session.disconnect();
}
}
@sachinlala
Copy link

I was able to resolve this by generating the PK file using bouncycastle lib - sharing the code here:

  private void genKey() throws Exception {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(2048, new SecureRandom());
    PrivateKey privateKey = keyPairGenerator.genKeyPair().getPrivate();
    StringWriter writer = new StringWriter();
    try (PEMWriter pemWriter = new PEMWriter(writer)) {
      pemWriter.writeObject(privateKey);
    }
    FileUtils.writeByteArrayToFile(new File("<location for test PK file>"), writer.toString().getBytes());
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment