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)