Hi Guys,
I had a problem with SSHD 0.6 on an environment which is only accessible
through a socks server (socks v5 with authentication). It happens when the
client sends a command, like:
ssh user@ip hostname
I'm using the *ScpCommandFactory *to handle ssh commands. In this case, the
shell often finishes before the streams get flushed and none output is sent
to the client. To fix the problem I added the red lines below to the file *
InvertedShellWrapper.java*, pumpStreams method:
protected void pumpStreams() {
try {
// Use a single thread to correctly sequence the output and
error streams.
// If any bytes are available from the output stream, send them
first, then
// check the error stream, or wait until more data is available.
byte[] buffer = new byte[512];
for (;;) {
if (!shell.isAlive()) {
// Make sure all streams were flushed
pumpStream(in, shellIn, buffer);
pumpStream(shellOut, out, buffer);
pumpStream(shellErr, err, buffer);
callback.onExit(shell.exitValue());
return;
}
if (pumpStream(in, shellIn, buffer)) {
continue;
}
if (pumpStream(shellOut, out, buffer)) {
continue;
}
if (pumpStream(shellErr, err, buffer)) {
continue;
}
// Sleep a bit. This is not very good, as it consumes CPU,
but the
// input streams are not selectable for nio, and any other
blocking
// method would consume at least two threads
Thread.sleep(1);
}
} catch (Exception e) {
shell.destroy();
callback.onExit(shell.exitValue());
}
}
These lines have fixed the problem for me.
I have also fixed another problem and I think it could be helpful for some
of us, spite of the problem is related with the ssh client and the
environment as well.
It happens when the Perl SSH client try to connect, also through a socks
server, after the first connection. The server key is sent to the client in
the same package of server's Identification. As it happens only when using
a socks server, its possible that the socks server is adding both content
from the server in a single package before send it back to the client. And
the perl SSH client (and maybe another immature client) is not checking for
both content in a single package. So, I fix the problem adding a bit delay
in the sendIdentification method from AbstractSession class.
protected void sendIdentification(String ident) {
IoBuffer buffer = IoBuffer.allocate(32);
buffer.setAutoExpand(true);
buffer.put((ident + "\r\n").getBytes());
buffer.flip();
ioSession.write(buffer);
// Gives a bit time to the socks server send the identification to
the client
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
//
}
}
At the first time, the problem doesn't happen because java takes a time to
open the resources and load the classes to the memory and it gives the
socks server the time it needs to send it back in a single package.
Regards,
Edison