How to echo a string to SSH using JAVA - java

I am trying to execute a remote query over SSH using pubic key/private key based authentication. Following command works fine and gives me the required output as a string on a bash shell after sharing the public keys between local host and the remote server.
echo 123456 12#13:14 ABCD abc1234 | ssh -T user#abc.xyz.com
How do I achieve the same with JAVA using JSCH or SSHJ or any other similar library
This is what I have tried so far using SSHJ but it did not work for me (Connection was successful but no results)
public static void main(String... args)throws IOException {
final SSHClient ssh = new SSHClient();
ssh.loadKnownHosts();
ssh.connect("abc.xyz.com");
try {
ssh.authPublickey("user");
final Session session = ssh.startSession();
try {
final Command cmd = session.exec("123456 12#13:14 ABCD abc1234");
System.out.println(IOUtils.readFully(cmd.getInputStream()).toString());
cmd.join(5, TimeUnit.SECONDS);
System.out.println("\n** exit status: " + cmd.getExitStatus());
} finally {
session.close();
}
} finally {
ssh.disconnect();
ssh.close();
}
}

Below code uses JSCH Library and is working on my end :-
JSch jsch = new JSch();
String path = "PATH TO PRIVATE KEY";
jsch.addIdentity(path);
jsch.setConfig("StrictHostKeyChecking", "no");
Session session = jsch.getSession(userName, ipToConnect, portToConnect);
session.connect();
Channel channel = session.openChannel("exec");
((ChannelExec)channel).setCommand("COMMAND TO FIRE");
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
//Read Response Here
channel.disconnect();
session.disconnect();
Note : You can use password based authentication also instead of key bases with JSCH

Related

Run program in remote computer over ssh via Java (JSch)

I am writing a block of Java code that allows me to connect to a remote computer and execute a program on it. So far I am able to connect to the program and run it. I can see the program's output on my console. However, the program stops executing and my java code exists with exit code = 0. Here is my connect method. I call it in my main with the correct arguments.
public void listFolderStructure(String username,
String host, int port, String command) throws Exception {
Session session = null;
ChannelExec channel = null;
try {
JSch jsch = new JSch();
session = jsch.getSession(username, host, port);
session.setConfig("PreferredAuthentications", "publickey");
jsch.addIdentity("~/.ssh/id_rsa");
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
channel = (ChannelExec) session.openChannel("exec");
channel.setXForwarding(true);
channel.setCommand(command);
ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
channel.setOutputStream(responseStream);
channel.connect();
while (channel.isConnected()) {
Thread.sleep(100);
}
String responseString = new String(responseStream.toByteArray());
System.out.println(responseString);
} finally {
if (session != null) {
session.disconnect();
}
if (channel != null) {
channel.disconnect();
}
}
}
And this is part the output of the program on my console. Note: Connecting to the remote via ssh and running the program from a terminal gives the same output but the program's gui window displays on my computer and it runs as per usual
2021-04-03 20:36:42 [INFO]: Loaded plugin:
"/home/usr/adtf3.7/bin/adtf_kernel.adtfplugin" [runtime.cpp(1887)]
2021-04-03 20:36:42 [INFO]: Registered class "kernel.service.adtf.cid". ( 14 )
[runtime.cpp(2213)]
2021-04-03 20:36:42 [INFO]: Try to load
"/home/usr/adtf3.7/bin/adtf_playback.adtfplugin" [runtime.cpp(1784)]
2021-04-03 20:36:42 [INFO]: Loaded plugin:
"/home/usr/adtf3.7/bin/adtf_playback.adtfplugin" [runtime.cpp(1887)]
2021-04-03 20:36:42 [INFO]: Registered class "playback.service.adtf.cid". ( 15 ) [
Process finished with exit code 0
Is there a way to connect to the remote via Jsch and have the program's ui display as it normally would without it exiting? (code 0)
Any help would be greatly appreciated
EDIT: Thank you #Martin Prikryl; one of his suggestions helped out and I can now run the program on the remote. The only issue I'm facing now is getting the UI to display on my machine instead of the remote machine
Method that can run programs on the remote:
public void run_command(String command) throws JSchException {
String username = this.user;
String host = this.host;
int port = this.port;
JSch jsch = new JSch();
jsch.addIdentity("~/.ssh/id_rsa");
this.sshSession = jsch.getSession(username, host, port);
this.sshSession.setConfig("PreferredAuthentications", "publickey");
this.sshSession.setConfig("StrictHostKeyChecking", "no");
this.sshSession.connect();
this.sshChannel = this.sshSession.openChannel("shell");
this.sshChannel.setXForwarding(true);
ByteArrayInputStream reader = new ByteArrayInputStream(("export DISPLAY=:0; "+command + " \n").getBytes());
this.sshChannel.setInputStream(reader);
this.sshChannel.setOutputStream(System.out);
this.sshChannel.connect();
try {
Thread.sleep(1000); // give GUI time to come up
} catch (InterruptedException ex) {
// print message
}
this.sshChannel.disconnect();
}
alternatively this can be used to connect to a remote without Jsch. Extending to command however; i.e: ..this.host;gedit makes the terminal instantly dissapear.
public void open_remote_terminal() {
try {
String command ="gnome-terminal -x ssh -x "+this.user+"#"+this.host;
Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}
}

Getting exception "session is down" when calling the ftp server through jsch

When I am trying to get connected with the ftp server for file uploading, I am getting exception com.jcraft.jsch.JSchException: session is down
Code is in groovy:
String SFTPHOST = "########"
int SFTPPORT = 22
String SFTPUSER = "########"
String SFTPPASS = "########"
String SFTPWORKINGDIR = "/QA/"
ChannelSftp sftp = null
Session session = null
try {
JSch jsch = new JSch()
session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT)
session.setPassword(SFTPPASS)
session.setConfig("StrictHostKeyChecking", "no")
session.setConfig("PreferredAuthentications",
"publickey,keyboard-interactive,password")
session.connect()
Channel channel = session.openChannel "sftp"
channel.connect()
sftp = channel as ChannelSftp
sftp.cd SFTPWORKINGDIR
File f = new File("Demo.csv")
sftp.put(new FileInputStream(f), f.getName())
//def fileList = sftp.ls("*")
println fileList.size()
} catch (Exception ex) {
ex.printStackTrace()
}
I got the issue...Actually JSch is not an FTP client it's an SSH client (with an included SFTP implementation). And the ftp server which i am connecting with is not a ssh server. That's why jsch is unable to connect with that ftp server. I have used apache commons ftp client and its working fine

How to send password in command using ssh command

I am using Jsch library to connect with my server. After connecting i am passing command which require password to proceed further hence i am passing my password in command only but nothing happens.
Code:
JSch jsch = new JSch();
jsch.removeAllIdentity();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
.setConfig("StrictHostKeyChecking", "no");
session.setConfig("PubkeyAuthentication", "no");
System.out.println("Establishing Connection...");
session.setConfig("PreferredAuthentications",
"publickey,keyboard-interactive,password");
session.connect();
System.out.println("Connection established.");
System.out.println("Crating SFTP Channel.");`
Channel shellChannel = session.openChannel("shell");
shellChannel.connect();
((ChannelShell) shellChannel).setPty(true);
shellChannel.setInputStream(System.in);
shellChannel.setOutputStream(System.out);
PrintStream shellStream = new PrintStream(
shellChannel.getOutputStream());
shellChannel.connect();
shellStream
.println("cd /usr/local/apache2/; ls; cd ../www; ls; git fetch origin; <mypasssword>");
shellStream.flush();
System.out.println("SFTP Channel created.");`
When i run this code git ask password to proceed further.
Note: i cannot disable password for git fetch origin.
I tried your code to access my linux box - it does log in successfully, but then fails to send any commands. I'm not sure if that's the problem you are having - but I will add my solution here, just in case.
Moved the shellStream.println(); command to its own function:
public static void sendCommand(String c) {
shellStream.print(c + "\n");
shellStream.flush();
}
Had to make shellChannel and shellStream global variables in the process.
Changed shellStream.println(); to shellStream.print("\n");, as the aforementioned refused to work.
After this line of your code:
shellStream = new PrintStream(shellChannel.getOutputStream());
Added my command sequence:
Thread.sleep(1000); // wait for it to connect
sendCommand("sudo su"); // the command I tried
Thread.sleep(1000); // not sure how long you need to wait
sendCommand("mypassword");
Thread.sleep(1000);
// etc.
By the way, you are calling shellChannel.connect(); twice in your code - I removed the last one.
Here's the final working version of your code:
import java.io.IOException;
import java.io.PrintStream;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class MyShell {
static String user = "daniel";
static String host = "localhost";
static int port = 22;
static String password = "mypass";
static Session session;
static Channel shellChannel;
static PrintStream shellStream;
public static void main(String[] args) throws JSchException, IOException,
InterruptedException {
JSch jsch = new JSch();
jsch.removeAllIdentity();
session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.setConfig("PubkeyAuthentication", "no");
System.out.println("Establishing Connection...");
session.setConfig("PreferredAuthentications",
"publickey,keyboard-interactive,password");
session.connect();
System.out.println("Connection established.");
System.out.println("Crating SFTP Channel.");
shellChannel = session.openChannel("shell");
shellChannel.connect();
((ChannelShell) shellChannel).setPty(true);
shellChannel.setInputStream(System.in);
shellChannel.setOutputStream(System.out);
shellStream = new PrintStream(shellChannel.getOutputStream());
Thread.sleep(1000);
sendCommand("sudo su");
Thread.sleep(1000);
sendCommand("mypass");
Thread.sleep(1000);
sendCommand("ls");
}
public static void sendCommand(String c) {
shellStream.print(c + "\n");
shellStream.flush();
}
}
session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
Keyboard-interactive here mean the password must be tipped with a keyboard. SSH is quite peaky about that, even if there's ways to pass a password through the command line.
The best way would be to use a pubkey auth, but if that's not a option, try to login using only password
session.setConfig("PreferredAuthentications", "password");
Also you may just send the password using
session.setPassword("password");

JSchException: Auth fail and fingerprint

I'm trying to connect to my SFTP server from a Java script.
I'm using JSch lib for my purpose. Username, password and hostname are correct but I obtain an: Auth fail error.
I've also tried to add the following lines before session.connect(), but the problem still remains.
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
What do I have to put inside knownhosts.txt? The fingerprint of my server key?
public static void upload(ArrayList<File> a) {
try{
JSch jsch = new JSch();
jsch.setKnownHosts("knownhosts.txt");
Session session = jsch.getSession("username", "hostname", 22);
session.setPassword("mypassword");
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp channelSftp = (ChannelSftp) channel;
channelSftp.cd("/var/www/");
for(File object: a){
channelSftp.put(new FileInputStream(object), object.getName(), channelSftp.OVERWRITE);
}
channelSftp.exit();
session.disconnect();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Do you have some advices? Thanks in advance!
Does your network/SMTP server support IP6? If your client has IP6 support, later versions of Java default to IP6, but many SMTP servers are configured on IP4. See this article here for Sending email using JSP for directions on configuring your JVM to force IP4. This needs to be set on the JVM as it is instantiated.

Can we use JSch for SSH key-based communication?

I am using JSch for sftp communication, now i want to use facilitate the key-based authentication, key is loaded on client and server machine once by my network team and all later communication would be only user based for which we have loaded the key.
sftp -oPort=10022 jmark#192.18.0.246
as tjill#192.18.0.135
like this command work fine and connect to the sftp, how i can achieve this functionality programmatically.
if it is not possible using JSch, please suggest some other library. I came across Apache SSHD.
It is possible. Have a look at JSch.addIdentity(...)
This allows you to use key either as byte array or to read it from file.
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class UserAuthPubKey {
public static void main(String[] arg) {
try {
JSch jsch = new JSch();
String user = "tjill";
String host = "192.18.0.246";
int port = 10022;
String privateKey = ".ssh/id_rsa";
jsch.addIdentity(privateKey);
System.out.println("identity added ");
Session session = jsch.getSession(user, host, port);
System.out.println("session created.");
// disabling StrictHostKeyChecking may help to make connection but makes it insecure
// see http://stackoverflow.com/questions/30178936/jsch-sftp-security-with-session-setconfigstricthostkeychecking-no
//
// java.util.Properties config = new java.util.Properties();
// config.put("StrictHostKeyChecking", "no");
// session.setConfig(config);
session.connect();
System.out.println("session connected.....");
Channel channel = session.openChannel("sftp");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect();
System.out.println("shell channel connected....");
ChannelSftp c = (ChannelSftp) channel;
String fileName = "test.txt";
c.put(fileName, "./in/");
c.exit();
System.out.println("done");
} catch (Exception e) {
System.err.println(e);
}
}
}

Categories