Miron Aseev created SSHD-744:
--------------------------------
Summary: An SSH client receives an echo as a response from the
server
Key: SSHD-744
URL: https://issues.apache.org/jira/browse/SSHD-744
Project: MINA SSHD
Issue Type: Question
Affects Versions: 1.4.0
Reporter: Miron Aseev
Priority: Minor
I'm trying to integrate my Java application with a device which provides a
custom protocol over SSH.
The whole point of this protocol is about exchanging XML documents back and
forth. It can be described with the following steps:
# a client connects to the server
# the client sends an XML document which contains the request data
# the client waits for the XML document which contains a response data from a
server
# the server receives the XML document that was sent by the client and sends
the response XML document back to the client
# the client receives the XML response from the server and closes the connection
The recommended way to send requests to this device is to use `cat` and `ssh`
tools. Here's a simple example:
{code}
cat example.xml | ssh <user_id>@<device_ip>
{code}
where `example.xml` is a file that contains an XML document with the request
data.
Calling directly 'cat' and 'ssh' via Runtime.exec would be very problematic
because this approach has a lot of drawbacks. So, I decided to implement this
protocol using MINA SSHD library.
The problem I've run into is I receive my own request as a response from the
server. So there's some kind of echoing stuff going on, I think.
For example, when I send this XML document as a request to the server:
{code}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xg-request>
<action-request>
<action-name>test</action-name>
</action-request>
</xg-request>
{code}
I receive the following data as a response:
{code}
Last login: Wed May 3 07:33:43 2017 from ip
Header
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xg-request>
<action-request>
<action-name>test</action-name>
</action-request>
</xg-request>
{code}
The funny this is when I send the same request via cat and ssh (the example I
mentioned above), I receive the correct response from the device.
Here's an excerpt from my application:
{code}
public class Test {
private static final long AWAIT_TIMEOUT = TimeUnit.SECONDS.toMillis(5);
private static final String XML_PAYLOAD_HEADER = "<?xml";
public void init() throws IOException, JAXBException {
try (SshClient client = initSshClient();
ClientSession session =
initClientSession(client, "test", "localhost", 22, "pass")) {
sendRequest(session);
}
}
private static SshClient initSshClient() {
SshClient client = SshClient.setUpDefaultClient();
client.start();
return client;
}
private ClientSession initClientSession(SshClient client, String user,
String host, int port,
String password) throws IOException {
ClientSession session =
client.connect(user, host, port).verify(AWAIT_TIMEOUT).getSession();
session.addPasswordIdentity(password);
session.auth().verify(AWAIT_TIMEOUT);
return session;
}
private void sendRequest(ClientSession session) throws IOException {
try (PipedOutputStream out = new PipedOutputStream();
PipedInputStream channelIn = new PipedInputStream(out);
PipedOutputStream channelOut = new PipedOutputStream();
PipedInputStream in = new PipedInputStream(channelOut);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
BufferedWriter writer = new BufferedWriter(new
OutputStreamWriter(out));
ClientChannel channel = initClientChannel(session, channelIn,
channelOut)) {
String xmlRequest = ""; // Here goes a real XML document;
writer.write(xmlRequest);
writer.newLine();
writer.flush();
String response = readFully(reader);
}
}
private static ClientChannel initClientChannel(ClientSession session,
InputStream input,
OutputStream output) throws
IOException {
ClientChannel channel = session.createChannel(Channel.CHANNEL_SHELL);
channel.setIn(input);
channel.setOut(output);
channel.setErr(new ByteArrayOutputStream());
channel.open().verify(AWAIT_TIMEOUT);
return channel;
}
private static String readFully(BufferedReader reader) throws IOException {
StringBuilder builder = new StringBuilder();
String line;
boolean foundXmlPayload = false;
while ((line = reader.readLine()) != null) {
if (foundXmlPayload && line.isEmpty()) {
break;
}
builder.append(line);
if (!foundXmlPayload && builder.indexOf(XML_PAYLOAD_HEADER) != -1) {
foundXmlPayload = true;
}
}
return builder.toString();
}
}
{code}
Any suggestions would be greatly appreciated.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)