Amir Amir - 12 days ago 7
Android Question

sshxcute session is down

I'm trying to send some commands using java through SSH to a remote machine.

I've managed to get the following snippet of code working by tweaking the sshd config file on the remote machine:

ConnBean connection = new ConnBean("remote.machine", "user", "password");
SSHExec ssh = SSHExec.getInstance(connection);
ssh.connect();
ExecCommand cmd = new ExecCommand("echo 123");
ssh.exec(cmd);


This code works perfectly fine in a fresh Java project. However, when I use the exact same sshxcute jar with the exact same code in my android application (written in Java), I get a
JSchException
saying that the session is down. This is because the
ssh.connect()
step has failed.

So what is the difference between running this on a fresh java project and running it on a Java based android app?

I have tried using a JSch connection instead like so:

JSch jsch = new JSch();
Session session = jsch.getSession("user", "remote.machine", 22);
session.setPassword("password");
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
prop.put("Compression", "no");
session.setConfig(prop);

ChannelExec channel = (ChannelExec) session.openChannel("exec");
BufferedReader in=new BufferedReader(new InputStreamReader(channel.getInputStream()));
channel.setCommand("echo 123");
channel.connect();
session.connect();


Again, this works in a new Java project but not in the Android app where I get the same exception.

Here's the stacktrace:

W/System.err: com.jcraft.jsch.JSchException: session is down
W/System.err: at com.jcraft.jsch.Session.openChannel(Session.java:752)
W/System.err: at net.neoremind.sshxcute.core.SSHExec.exec(SSHExec.java:164)
W/System.err: at pi.picontroller.MainControl.launchFifa(MainControl.java:28)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
W/System.err: at android.view.View.performClick(View.java:5610)
W/System.err: at android.view.View$PerformClick.run(View.java:22260)
W/System.err: at android.os.Handler.handleCallback(Handler.java:751)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:154)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6077)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)


The method that I added to test connectivity:

private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
try {
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
}
return true;
} catch (IOException ex) {
return false;
}
}

Answer

I think that the problem must be in pi.picontroller.MainControl. Looking at the source code for JCsh and the net.neoremind.sshxcute stuff, it is clear that the MainControl.launchFifa must be attempting to use a Session that is in the "not connected" state. To have gotten into that state without any notification, the MainControl has most likely squashed an exception, or ignored a return code.

I suspect that the (suspected) difference in the networking environment are really just a trigger for the problem, not the problem itself.


Looking at your version of the code using SSHExec that you showed us:

ssh.connect();

This call returns a boolean to say whether the connection succeeded or not. You aren't checking it. You should.

Note that if the connection fails with an exception, SSHExec.connect() will log the exception and return false.

If this doesn't help, then try setting the logging level to DEBUG.