import java.io.Console;
import java.io.IOException;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.Scanner;
+import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.sshd.client.SshClient;
+import org.apache.sshd.client.channel.ClientChannel;
+import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.future.ConnectFuture;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.client.subsystem.sftp.fs.SftpFileSystemProvider;
+import org.apache.sshd.common.util.io.NoCloseInputStream;
+import org.apache.sshd.common.util.io.NoCloseOutputStream;
+@SuppressWarnings("restriction")
abstract class AbstractSsh {
private final static Log log = LogFactory.getLog(AbstractSsh.class);
return sftpFileSystemProvider;
}
- @SuppressWarnings("restriction")
void authenticate() {
try {
if (sshKeyPair != null) {
openSession(uri.getUserInfo(), uri.getHost(), uri.getPort() > 0 ? uri.getPort() : null);
}
- @SuppressWarnings("restriction")
void openSession(String login, String host, Integer port) {
if (session != null)
throw new IllegalStateException("Session is already open");
}
}
- @SuppressWarnings("restriction")
void closeSession() {
if (session == null)
throw new IllegalStateException("No session is open");
return session;
}
+ public void setSshKeyPair(SshKeyPair sshKeyPair) {
+ this.sshKeyPair = sshKeyPair;
+ }
+
+ public static void openShell(ClientSession session) {
+ try (ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL)) {
+ channel.setIn(new NoCloseInputStream(System.in));
+ channel.setOut(new NoCloseOutputStream(System.out));
+ channel.setErr(new NoCloseOutputStream(System.err));
+ channel.open();
+
+ Set<ClientChannelEvent> events = new HashSet<>();
+ events.add(ClientChannelEvent.CLOSED);
+ channel.waitFor(events, 0);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+ session.close(false);
+ }
+ }
+
+ static URI toUri(String username, String host, int port) {
+ try {
+ if (username == null)
+ username = "root";
+ return new URI("ssh://" + username + "@" + host + ":" + port);
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException("Cannot generate SSH URI to " + host + ":" + port + " for " + username,
+ e);
+ }
+ }
+
}
--- /dev/null
+package org.argeo.ssh;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
+import org.apache.sshd.server.scp.ScpCommandFactory;
+import org.apache.sshd.server.shell.ProcessShellFactory;
+import org.argeo.util.os.OS;
+
+/** A simple SSH server with some defaults. Supports SCP. */
+@SuppressWarnings("restriction")
+public class BasicSshServer {
+ private Integer port;
+ private Path hostKeyPath;
+
+ private SshServer sshd = null;
+
+ public BasicSshServer(Integer port, Path hostKeyPath) {
+ this.port = port;
+ this.hostKeyPath = hostKeyPath;
+ }
+
+ public void init() {
+ try {
+ sshd = SshServer.setUpDefaultServer();
+ sshd.setPort(port);
+ if (hostKeyPath == null)
+ throw new IllegalStateException("An SSH server key must be set");
+ sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(hostKeyPath));
+ // sshd.setShellFactory(new ProcessShellFactory(new String[] { "/bin/sh", "-i",
+ // "-l" }));
+ String[] shellCommand = OS.LOCAL.getDefaultShellCommand();
+ sshd.setShellFactory(new ProcessShellFactory(shellCommand));
+ sshd.setCommandFactory(new ScpCommandFactory());
+ sshd.start();
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot start SSH server on port " + port, e);
+ }
+ }
+
+ public void destroy() {
+ try {
+ sshd.stop();
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot stop SSH server on port " + port, e);
+ }
+ }
+
+ public Integer getPort() {
+ return port;
+ }
+
+ public void setPort(Integer port) {
+ this.port = port;
+ }
+
+ public Path getHostKeyPath() {
+ return hostKeyPath;
+ }
+
+ public void setHostKeyPath(Path hostKeyPath) {
+ this.hostKeyPath = hostKeyPath;
+ }
+
+ public static void main(String[] args) {
+ int port = 2222;
+ Path hostKeyPath = Paths.get("hostkey.ser");
+ try {
+ if (args.length > 0)
+ port = Integer.parseInt(args[0]);
+ if (args.length > 1)
+ hostKeyPath = Paths.get(args[1]);
+ } catch (Exception e1) {
+ printUsage();
+ }
+
+ BasicSshServer sshServer = new BasicSshServer(port, hostKeyPath);
+ sshServer.init();
+ Runtime.getRuntime().addShutdownHook(new Thread("Shutdown SSH server") {
+
+ @Override
+ public void run() {
+ sshServer.destroy();
+ }
+ });
+ try {
+ synchronized (sshServer) {
+ sshServer.wait();
+ }
+ } catch (InterruptedException e) {
+ sshServer.destroy();
+ }
+
+ }
+
+ public static void printUsage() {
+ System.out.println("java " + BasicSshServer.class.getName() + " [port] [server key path]");
+ }
+
+}
import org.apache.sshd.client.subsystem.sftp.fs.SftpFileSystem;
+/** Create an SFTP {@link FileSystem}. */
public class Sftp extends AbstractSsh {
private URI uri;
private SftpFileSystem fileSystem;
+ public Sftp(String username, String host, int port) {
+ this(AbstractSsh.toUri(username, host, port));
+ }
+
public Sftp(URI uri) {
this.uri = uri;
openSession(uri);
+++ /dev/null
-package org.argeo.ssh;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import org.apache.sshd.server.SshServer;
-import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
-import org.apache.sshd.server.scp.ScpCommandFactory;
-import org.apache.sshd.server.shell.ProcessShellFactory;
-import org.argeo.util.os.OS;
-
-/** A simple SSH server with some defaults. Supports SCP. */
-@SuppressWarnings("restriction")
-public class SimpleSshServer {
- private Integer port;
- private Path hostKeyPath;
-
- private SshServer sshd = null;
-
- public SimpleSshServer(Integer port, Path hostKeyPath) {
- this.port = port;
- this.hostKeyPath = hostKeyPath;
- }
-
- public void init() {
- try {
- sshd = SshServer.setUpDefaultServer();
- sshd.setPort(port);
- if (hostKeyPath == null)
- throw new IllegalStateException("An SSH server key must be set");
- sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(hostKeyPath));
- // sshd.setShellFactory(new ProcessShellFactory(new String[] { "/bin/sh", "-i",
- // "-l" }));
- String[] shellCommand = OS.LOCAL.getDefaultShellCommand();
- sshd.setShellFactory(new ProcessShellFactory(shellCommand));
- sshd.setCommandFactory(new ScpCommandFactory());
- sshd.start();
- } catch (Exception e) {
- throw new RuntimeException("Cannot start SSH server on port " + port, e);
- }
- }
-
- public void destroy() {
- try {
- sshd.stop();
- } catch (IOException e) {
- throw new RuntimeException("Cannot stop SSH server on port " + port, e);
- }
- }
-
- public Integer getPort() {
- return port;
- }
-
- public void setPort(Integer port) {
- this.port = port;
- }
-
- public Path getHostKeyPath() {
- return hostKeyPath;
- }
-
- public void setHostKeyPath(Path hostKeyPath) {
- this.hostKeyPath = hostKeyPath;
- }
-
- public static void main(String[] args) {
- int port = 2222;
- Path hostKeyPath = Paths.get("hostkey.ser");
- try {
- if (args.length > 0)
- port = Integer.parseInt(args[0]);
- if (args.length > 1)
- hostKeyPath = Paths.get(args[1]);
- } catch (Exception e1) {
- printUsage();
- }
-
- SimpleSshServer sshServer = new SimpleSshServer(port, hostKeyPath);
- sshServer.init();
- Runtime.getRuntime().addShutdownHook(new Thread("Shutdown SSH server") {
-
- @Override
- public void run() {
- sshServer.destroy();
- }
- });
- try {
- synchronized (sshServer) {
- sshServer.wait();
- }
- } catch (InterruptedException e) {
- sshServer.destroy();
- }
-
- }
-
- public static void printUsage() {
- System.out.println("java " + SimpleSshServer.class.getName() + " [port] [server key path]");
- }
-
-}
package org.argeo.ssh;
-import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
-import org.apache.sshd.client.channel.ClientChannel;
-import org.apache.sshd.client.channel.ClientChannelEvent;
-import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.common.util.io.NoCloseInputStream;
-import org.apache.sshd.common.util.io.NoCloseOutputStream;
-@SuppressWarnings("restriction")
+/** Create an SSH shell. */
public class Ssh extends AbstractSsh {
private final URI uri;
+ public Ssh(String username, String host, int port) {
+ this(AbstractSsh.toUri(username, host, port));
+ }
+
public Ssh(URI uri) {
this.uri = uri;
openSession(uri);
}
- static void openShell(ClientSession session) {
- try (ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL)) {
- channel.setIn(new NoCloseInputStream(System.in));
- channel.setOut(new NoCloseOutputStream(System.out));
- channel.setErr(new NoCloseOutputStream(System.err));
- channel.open();
-
- Set<ClientChannelEvent> events = new HashSet<>();
- events.add(ClientChannelEvent.CLOSED);
- channel.waitFor(events, 0);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } finally {
- session.close(false);
- }
- }
-
public static void main(String[] args) {
Options options = getOptions();
CommandLineParser parser = new DefaultParser();
ssh.authenticate();
if (command.size() == 0) {// shell
- openShell(ssh.getSession());
+ AbstractSsh.openShell(ssh.getSession());
} else {// execute command
}