I am trying to execute remote commands on an SSHServer running on my local windows machine.
I am able to run simple command like “whoami” but failing to run something like “java -version” or “dir”
Here is my code so far, can you tell where I am going wrong?
SSHServer.java
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory; import org.apache.sshd.common.session.SessionContext; import org.apache.sshd.server.SshServer; import org.apache.sshd.server.auth.password.PasswordAuthenticator; import org.apache.sshd.server.channel.ChannelSession; import org.apache.sshd.server.command.Command; import org.apache.sshd.server.command.CommandFactory; import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; import org.apache.sshd.server.scp.ScpCommandFactory; import org.apache.sshd.server.shell.InteractiveProcessShellFactory; import org.apache.sshd.server.shell.ProcessShellCommandFactory; import org.apache.sshd.server.shell.ProcessShellFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; public class SSHServer { private SshServer sshServer; private static final Logger logger = LoggerFactory.getLogger(SSHServer.class); public SSHServer(int port) { sshServer = SshServer.setUpDefaultServer(); initializeServer(port); } private void initializeServer(int port) { sshServer.setPort(port); sshServer.setKeyPairProvider(new SimpleGeneratorHostKeyProvider()); sshServer.setFileSystemFactory(getFileSystemFactory()); sshServer.setCommandFactory(getScpCommandFactory()); sshServer.setPasswordAuthenticator(getPasswordAuthenticator()); sshServer.setShellFactory(getProcessShellFactory()); //sshServer.setSessionHeartbeat(SessionHeartbeatController.HeartbeatType.IGNORE, TimeUnit.SECONDS, 5); } public int getPort() { return sshServer.getPort(); } public String getHost() { return sshServer.getHost(); } public void startServer() throws IOException { sshServer.start(); logger.debug("SSHServer started on Port: {}", sshServer.getPort()); } public void stopServer() throws IOException { sshServer.stop(); logger.debug("SSHServer stopped..."); } private ScpCommandFactory getScpCommandFactory() { CommandFactory myCommandFactory = new CommandFactory() { @Override public Command createCommand(ChannelSession channelSession, String s) { logger.info("Command on SSHServer: {}", s); return null; } }; return new ScpCommandFactory.Builder().withDelegate(new ProcessShellCommandFactory()).build(); } private VirtualFileSystemFactory getFileSystemFactory() { return new VirtualFileSystemFactory() { @Override public Path getUserHomeDir(SessionContext session) { String userHomeDir = System.getProperty("user.home"); return Paths.get(userHomeDir); } }; } private PasswordAuthenticator getPasswordAuthenticator() { return (username, password, serverSession) -> { logger.info("authenticating user: {}", username); return true; }; } private ProcessShellFactory getProcessShellFactory() { return new InteractiveProcessShellFactory(); } }
SSHClient.java
import org.apache.sshd.client.SshClient; import org.apache.sshd.client.future.ConnectFuture; import org.apache.sshd.client.session.ClientSession; import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory; import org.apache.sshd.common.session.SessionContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; public class SSHClient { private SshClient sshClient; private String username; private String host; private String password; private int port; private static final Logger logger = LoggerFactory.getLogger(SSHClient.class); private SSHClient(){} public SSHClient(String username, String password, String host, int port) { logger.info("Creating SSHClient for username: {} for {}:{}", username, host, port); sshClient = SshClient.setUpDefaultClient(); sshClient.setFileSystemFactory(new VirtualFileSystemFactory() { @Override public Path getUserHomeDir(SessionContext session) { return Paths.get(System.getProperty("user.home")); } }); this.username = username; this.password = password; this.host = host; this.port = port; } public ClientSession connect() throws IOException { ConnectFuture connectFuture = sshClient.connect(username, host, port).verify(); logger.info("SSHClient is connected: {}", connectFuture.isConnected()); return connectFuture.getSession(); } public void startClient() { sshClient.start(); logger.info("SSHClient is started..."); } public void stopClient() { sshClient.stop(); logger.info("SSHClient is stopped..."); } }
TestSSH.java
import org.apache.sshd.client.channel.ClientChannel; import org.apache.sshd.client.channel.ClientChannelEvent; import org.apache.sshd.client.session.ClientSession; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.EnumSet; import java.util.concurrent.TimeUnit; public class TestSSH { public static void main(String[] args) throws IOException { SSHServer sshServer = new SSHServer(null, 45018); sshServer.startServer(); SSHClient sshClient = new SSHClient("", "", "localhost", 45018); sshClient.startClient(); ClientSession clientSession = sshClient.connect(); clientSession.addPasswordIdentity("randompassword"); System.out.println(clientSession.auth().verify().isSuccess()); ClientChannel execChannel = clientSession.createChannel(ClientChannel.CHANNEL_EXEC, "whoami"); ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream err = new ByteArrayOutputStream(); execChannel.setOut(out); execChannel.setErr(err); execChannel.open().await(1, TimeUnit.SECONDS); Collection<ClientChannelEvent> waitMask = execChannel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), 10000); waitMask.forEach(event -> System.out.println(event.name())); System.out.println(execChannel.getExitStatus()); byte[] errBytes = err.toByteArray(); byte[] outBytes = out.toByteArray(); System.out.println(new String(outBytes, StandardCharsets.UTF_8)); System.out.println(new String(errBytes, StandardCharsets.UTF_8)); /* Scanner scanner = new Scanner(System.in); scanner.nextInt();*/ sshServer.stopServer(); System.out.println("Exiting"); System.exit(0); } }
here is the output for “whoami”:
2020-07-24 19:22:44,267 DEBUG c.w.v.g.s.SSHServer [main] SSHServer started on Port: 45018 2020-07-24 19:22:44,278 INFO c.w.v.g.s.SSHClient [main] Creating SSHClient for username: for localhost:45018 2020-07-24 19:22:44,369 INFO c.w.v.g.s.SSHClient [main] SSHClient is started... 2020-07-24 19:22:44,713 INFO c.w.v.g.s.SSHClient [main] SSHClient is connected: true 2020-07-24 19:22:45,835 INFO c.w.v.g.s.SSHServer [sshd-SshServer[41d477ed](port=45018)-nio2-thread-3] authenticating user: true CLOSED EOF EXIT_STATUS OPENED 0 properOutputhere 2020-07-24 19:22:46,969 DEBUG c.w.v.g.s.SSHServer [main] SSHServer stopped... Exiting Process finished with exit code 0
here is the output when I try to execute “dir” using:
ClientChannel execChannel = clientSession.createChannel(ClientChannel.CHANNEL_EXEC, "dir");
output:
2020-07-24 19:25:20,128 DEBUG c.w.v.g.s.SSHServer [main] SSHServer started on Port: 45018 2020-07-24 19:25:20,140 INFO c.w.v.g.s.SSHClient [main] Creating SSHClient for username: for localhost:45018 2020-07-24 19:25:20,237 INFO c.w.v.g.s.SSHClient [main] SSHClient is started... 2020-07-24 19:25:20,566 INFO c.w.v.g.s.SSHClient [main] SSHClient is connected: true 2020-07-24 19:25:21,453 INFO c.w.v.g.s.SSHServer [sshd-SshServer[33d512c1](port=45018)-nio2-thread-3] authenticating user: true TIMEOUT OPENED null 2020-07-24 19:25:31,539 DEBUG c.w.v.g.s.SSHServer [main] SSHServer stopped... Exiting Process finished with exit code 0
Advertisement
Answer
package com.example.demo; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.security.KeyPair; import java.util.EnumSet; import java.util.concurrent.TimeUnit; 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.session.ClientSession; import org.apache.sshd.common.channel.Channel; // https://stackoverflow.com/questions/63075107/how-to-execute-remote-commands-using-//apache-mina-sshd public class SshClientDemo { public String getFileList(String host, String username, String password, int port, long defaultTimeout) throws Exception { // uses the default id_rsa and id_rsa.pub files to connect to ssh server SshClient client = SshClient.setUpDefaultClient(); client.start(); try (ClientSession session = client.connect(username, host, port).verify(defaultTimeout, TimeUnit.SECONDS).getSession()) { //session.addPasswordIdentity(password); session.auth().verify(defaultTimeout, TimeUnit.SECONDS); try (ByteArrayOutputStream responseStream = new ByteArrayOutputStream(); ByteArrayOutputStream errorStream = new ByteArrayOutputStream(); ClientChannel channel = session.createChannel(Channel.CHANNEL_EXEC, "dir")) // to execute remote commands { channel.setOut(responseStream); channel.setErr(errorStream); try { channel.open().verify(defaultTimeout, TimeUnit.SECONDS); try (OutputStream pipedIn = channel.getInvertedIn()) { pipedIn.write("dir".getBytes()); pipedIn.flush(); } channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), TimeUnit.SECONDS.toMillis(defaultTimeout)); String error = new String(errorStream.toByteArray()); if (!error.isEmpty()) { throw new Exception(error); } return responseStream.toString(); } finally { channel.close(false); } } } finally { client.stop(); } } } // use this where you need to maybe main method SshClientDemo demo = new SshClientDemo(); try { String data = demo.getFileList("<your host name>", "<your user name>", null, 22, 10); System.out.println(" listing....."); System.out.println(data); } catch (Exception e) { e.printStackTrace(); } # output listing..... Volume in drive C is win-ent Volume Serial Number is 2C26-6048 Directory of c:usersatlantis 06/04/2021 04:03 PM <DIR> . 06/04/2021 04:03 PM <DIR> .. 06/18/2020 07:34 PM <DIR> .android 06/20/2020 10:24 PM 57 .angular-config.json 06/01/2020 11:26 AM <DIR> .ApacheDirectoryStudio 02/16/2020 12:11 AM <DIR> .aws 04/20/2021 03:01 PM 30,199 .bash_history 08/14/2020 08:06 PM 995 .bash_history2 04/22/2020 02:16 PM 20,438 .boto 04/01/2021 04:21 PM <DIR> .cache 07/23/2020 07:26 PM <DIR> .cassandra 08/14/2020 12:07 AM <DIR> .codemix 08/14/2020 12:13 AM <DIR> .codemix-store 08/13/2020 05:54 PM 104 .codemix.properties 09/01/2020 07:03 PM <DIR> .codewind 06/16/2020 12:06 PM <DIR> .config 07/26/2020 07:22 PM 15 .dbshell 03/13/2021 07:18 PM <DIR> .docker 11/23/2020 12:28 PM <DIR> .eclipse 04/17/2020 07:56 PM 60 .gitconfig 04/17/2021 03:06 PM <DIR> .gnupg 04/11/2021 10:46 PM <DIR> .gradle 03/31/2020 11:33 PM <DIR> .groovy 03/26/2021 09:51 PM <DIR> .hawtjni 06/19/2020 02:11 PM <DIR> .IntelliJIdea2019.2 04/26/2021 04:18 PM <DIR> .ipython 04/07/2021 07:24 PM <DIR> .jenkins 12/07/2020 09:26 PM <DIR> .jmc 04/26/2021 04:17 PM <DIR> .jupyter 03/13/2021 07:51 PM <DIR> .kube 09/15/2020 12:20 PM <DIR> .lemminx 04/14/2020 06:14 PM <DIR> .m2 04/23/2020 11:01 AM 37 .minttyrc 07/21/2020 12:18 PM 0 .mongorc.js 06/18/2020 08:58 PM <DIR> .nbi 06/18/2020 01:29 PM 4 .node_repl_history 06/07/2021 07:34 PM <DIR> .p2 05/07/2021 02:19 PM <DIR> .remain 06/04/2021 04:03 PM <DIR> .scalaide 08/10/2020 04:52 PM 11 .scala_history 06/14/2021 01:26 AM <DIR> .ssh 08/02/2020 06:06 PM <DIR> .sts4 08/22/2020 07:21 PM <DIR> .swt 04/16/2021 06:46 PM <DIR> .tmp 02/14/2020 10:58 PM <DIR> .tooling 04/16/2021 02:20 PM <DIR> .VirtualBox 04/12/2020 10:25 PM <DIR> .vscode 06/26/2020 11:00 AM 32 .vuerc 03/13/2021 03:30 PM <DIR> .webclipse 06/20/2020 11:17 AM <DIR> .WebStorm2019.3 06/07/2021 04:22 PM 0 .xdm-global-lock 06/06/2020 11:46 AM <DIR> .xdman 03/11/2021 10:02 PM <DIR> 3D Objects 04/11/2021 10:14 PM <DIR> caches 03/11/2021 10:02 PM <DIR> Contacts 04/11/2021 10:14 PM <DIR> daemon 05/12/2021 08:41 PM <DIR> Desktop 06/13/2021 10:35 PM <DIR> Documents 06/12/2021 04:18 PM <DIR> Downloads 03/11/2021 10:02 PM <DIR> Favorites 04/01/2021 11:58 PM <DIR> go 08/02/2020 05:20 PM <DIR> hsperfdata_atlantis 08/06/2020 08:30 PM <DIR> IBM 02/14/2020 05:14 PM <DIR> Intel 07/16/2020 07:23 PM 52,192 java_error_in_idea_6696.log 06/24/2020 11:01 AM 68,569 java_error_in_webstorm_17796.log 04/11/2021 10:17 PM <DIR> jdks 03/11/2021 10:02 PM <DIR> Links 07/23/2020 01:35 PM 1,180 mongo.sql 03/11/2021 10:02 PM <DIR> Music 04/11/2021 10:13 PM <DIR> native 09/04/2020 05:57 PM <DIR> OneDrive 06/30/2020 12:05 PM <DIR> opera autoupdate 06/08/2021 04:32 PM <DIR> Pictures 02/14/2020 05:27 PM <DIR> Roaming 03/11/2021 10:02 PM <DIR> Saved Games 07/13/2020 11:28 AM <DIR> sdk 03/11/2021 10:02 PM <DIR> Searches 03/11/2021 10:02 PM <DIR> Videos 06/15/2020 07:20 PM 144 webstorm.txt 17 File(s) 174,037 bytes 63 Dir(s) 36,056,952,832 bytes free