0

I have a task: to do telnet commands through ssh session.

I have read similar problems:

  1. Running telnet command on remote SSH session using JSch
  2. telnet through SSH
  3. Execution hangs after Running telnet command on remote SSH session using JSch

And I wrote the code (with lib https://mvnrepository.com/artifact/com.jcraft/jsch):

  1. Class Ssh:

    public class Ssh { private final String USER; private final String PASSWORD; private final String HOST;

     public Ssh(String user, String password, String host) {
         this.USER = user;
         this.PASSWORD = password;
         this.HOST = host;
     }
    
     public Session runSsh() {
         try {
             Session session = new JSch().getSession(USER, HOST, 22);
             session.setPassword(PASSWORD);
             // It must not be recommended, but if you want to skip host-key check,
             session.setConfig("StrictHostKeyChecking", "no");
             session.connect(3000);
             return session;
         } catch (JSchException e) {
             System.out.println(e);
         }
         return null;
     }
    

    }

  2. Class Telnet

    public class Telnet {

     public String runCommand(Session session, String command) throws Exception {
         Channel channel = session.openChannel("shell");
         channel.connect(3000);
    
         DataOutputStream outputStream = new DataOutputStream(channel.getOutputStream());
    
         outputStream.writeBytes("telnet localhost 5000\r\n");
         outputStream.writeBytes(command + "\r\n");
         outputStream.writeBytes("exit\r\n");
         outputStream.flush();
    
         DataInputStream inputStream = new DataInputStream(channel.getInputStream());
         BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    
         channel.setInputStream(inputStream, true);
    
         String line = reader.readLine();
         String result = line +"\n";
         while (!(line= reader.readLine()).equals("exit")){
             result += line +"\n";
         }
         result += "Connection closed by foreign host";
    
         outputStream.close();
         inputStream.close();
         channel.disconnect();
         session.disconnect();
    
         return result;
     }
    

    }

  3. Class Main

    public class Main {

     public static void main(String[] arg) {
         Ssh ssh = new Ssh("user","password","ip-server");
         Telnet telnet = new Telnet();
         try {
             Session sessionSsh = ssh.runSsh();
             String result = telnet.runCommand(sessionSsh, "H");
             System.out.println(result);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
    

    }

I get the result:

telnet localhost 5000


Entering character mode

Escape character is '^]'.




 Command Shell 1 on intelpc-1 (Port: 5000)

 b01_1_1 (5000) >
H

Connection closed by foreign host

Process finished with exit code 0

I don't see the result of executing the command telnet...

I made different commands via telnet:

- H
or
- u s3

But I can't see their result :(

Tell me please. How do I get the results of the telnet command execution?

2 Answers2

0

I debugged your example and in my case, I needed to wait for the program, which you connect via telnet, until it is ready to receive a command.

In the second step, you can send your command and the exit command to stop the telnet, so you are reading from the stream until it has stopped by saying "Connection closed...". Be aware, that exiting from telnet can have different commands, some use quit, some other use exit or only wait for a termination signal.

 class Telnet {

        public String runCommand(Session session, String command) throws Exception {
            Channel channel = session.openChannel("shell");
            channel.connect(3000);

            DataOutputStream outputStream = new DataOutputStream(channel.getOutputStream());

            outputStream.writeBytes("telnet localhost 16379\r\n");
            outputStream.flush();

            DataInputStream inputStream = new DataInputStream(channel.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            channel.setInputStream(inputStream, true);

            // Read until we are ready to write
            String line;
            while (!(line= reader.readLine()).equals("Escape character is '^]'.")){
                System.out.println(line);
            }

            // write command and exit telnet
            outputStream.writeBytes(command + "\r\n");
            outputStream.writeBytes("quit\r\n");
            outputStream.flush();

            // read until telnet has closed
            String result = "";
            while (!(line= reader.readLine()).equals("Connection closed by foreign host.")){
                result += line +"\n";
            }

            outputStream.close();
            inputStream.close();
            channel.disconnect();
            session.disconnect();

            return result;
        }
    }

In the end, there are alternative ways to communicate without telnet, i.e. local port forwarding.

Matthias Wiedemann
  • 1,313
  • 12
  • 22
  • Thanks for your reply. I used your code, but I didn't get a result ( You also wrote: In the end, there are alternative ways to communicate without telnet, i.e. local port forwarding. Thank you very much. I started using ssh tunneling: ssh Session.setPortForwardingL(9999, ssh Session.getHost(), 5000); If you first create ssh tunneling, then after that telnet commands give the result. I will write my result in detail later. – Alexey Zhukov Sep 30 '21 at 08:19
0

Thanks to Matthias Wiedemann.

I used the SSH tunneling https://www.ssh.com/academy/ssh/tunneling/example as Matthias Wiedemann advised.

Total:

1 step. Connecting via SSH and create session SSH

SSH ssh = new SSH(user, password, host, port);
Session session = SSHUtil.createSession(ssh);

2 step. Creating a tunnel using SSH

SSHUtil.createChannel(session, outputConsole);
SSHUtil.createSshTunnel(session, port);

3 step. Connection via Telnet and executing Telnet commands using the tunnel port (instead of 5000, the port became 9999).

clientForTelnet = new ClientForTelnet(new Telnet(host, port));
outputConsole.print(TelnetUtil.connect(clientForTelnet));

outputConsole is PrintStream.

I got the following:

1.

public class SSHUtil{

    private final static Logger LOGGER = LogManager.getLogger(SSHUtil.class);

    public static Session createSession(SSH ssh) {
        Session session = null;
        try {
            session = new JSch().getSession(ssh.getUSER(), ssh.getHOST().getIp(), ssh.getPORT().getPort());
            session.setPassword(ssh.getPASSWORD());
            session.setConfig("StrictHostKeyChecking", "no"); // It must not be recommended, but if you want to skip host-key check
            session.connect(10000);
            LOGGER.info("SSH session created");
        } catch (JSchException e) {
            LOGGER.error("SSH session not created " + e);
        }
        return session;
    }

    public static Channel createChannel(Session session, PrintStream output) {
        Channel channel = null;
        try {
            channel = session.openChannel("shell");
            channel.setInputStream(System.in);
            channel.setOutputStream(output);
            //  streamOut = channel.getOutputStream();

            channel.connect(10000);
            LOGGER.info("SSH channel created");
        } catch (JSchException e) {
            LOGGER.error("SSH channel not created " + e);
        }
        return channel;
    }

    public static void createSshTunnel(Session session, Port port) {
        // TODO сделать пул портов, чтобы исключить вероятность, что порт 9999 занят
        try {
            session.setPortForwardingL(9999, session.getHost(), port.getPort());
            LOGGER.info("Tunnel created localhost:" + 9999 + " -> " + session.getHost() + ":" + port.getPort());
        } catch (JSchException e) {
            LOGGER.error("SSH tunnel not created " + e);
        }
    }

    public static void disconnect(Session session) {
        if (session != null && session.isConnected()) {
            session.disconnect();
        }
    }

}
  1. public class TelnetUtil {
    private final static Logger LOGGER = LogManager.getLogger(TelnetUtil.class);

    public static String connect(ClientForTelnet clientForTelnet) {
        try {
            // Connect to the server
            clientForTelnet.getTc().connect(clientForTelnet.getTelnet().getHOST().getIp(), clientForTelnet.getTelnet().getPORT().getPort());

            // Get input and output stream references
            clientForTelnet.setIn(clientForTelnet.getTc().getInputStream());
            clientForTelnet.setOut(new PrintStream(clientForTelnet.getTc().getOutputStream()));
        } catch (IOException e) {
            LOGGER.error(e);
        }

        return readUntil(clientForTelnet.getPrompt(), clientForTelnet.getIn());
    }

    public static String readUntil(String pattern, InputStream in) {
        StringBuilder sb = new StringBuilder();
        try {
            char lastChar = pattern.charAt(pattern.length() - 1);
            boolean found = false;
            char ch = (char) in.read();
            while (true) {
           //     System.out.print(ch);
                sb.append(ch);
                if (ch == lastChar) {
                    if (sb.toString().endsWith(pattern)) {
                        return sb.toString();
                    }
                }
                ch = (char) in.read();
            }
        } catch (IOException e) {
            LOGGER.error(e);
        }
        return sb.toString();
    }

    public static void write(String value, PrintStream out) {
        out.println(value);
        out.flush();
    }

    public static String sendCommand(ClientForTelnet clientForTelnet, String command) {
        write(command, clientForTelnet.getOut());
        return readUntil(clientForTelnet.getPrompt(), clientForTelnet.getIn());
    }

    public static void disconnect(TelnetClient tc) {
        try {
            tc.disconnect();
        } catch (IOException e) {
            LOGGER.error(e);
        }
    }

}
  1. public class SSH { private final String USER; private final String PASSWORD; private final Host HOST; private final Port PORT;

      private final Port DEFAULT_PORT = new Port(22);
    
      public SSH(String user, String password, Host host, Port port) {
          this.USER = user;
          this.PASSWORD = password;
          this.HOST = host;
          this.PORT = port;
      }
    
      public SSH(String user, String password, Host host) {
          this.USER = user;
          this.PASSWORD = password;
          this.HOST = host;
          this.PORT = DEFAULT_PORT;
      }
    
      public String getUSER() {
          return USER;
      }
    
      public String getPASSWORD() {
          return PASSWORD;
      }
    
      public Host getHOST() {
          return HOST;
      }
    
      public Port getPORT() {
          return PORT;
      }
    

    }

  2. public class Telnet {

      private final Host HOST;
      private final Port PORT;
    
      private final Port DEFAULT_PORT = new Port(5000);
    
      public Telnet(Host host, Port port) {
          this.HOST = host;
          this.PORT = port;
      }
    
      public Telnet(Host host) {
          this.HOST = host;
          this.PORT = DEFAULT_PORT;
      }
    
      public Host getHOST() {
          return HOST;
      }
    
      public Port getPORT() {
          return PORT;
      }
    

    }

  3. public class ClientForTelnet {

      private final TelnetClient TC = new TelnetClient();
      private final String PROMT = ">";
      private final Telnet TELNET;
    
      private InputStream in;
      private PrintStream out;
    
      public ClientForTelnet(Telnet telnet) {
          this.TELNET = telnet;
      }
    
      public InputStream getIn() {
          return in;
      }
    
      public PrintStream getOut() {
          return out;
      }
    
      public Telnet getTelnet() {
          return TELNET;
      }
    
      public String getPrompt() {
          return PROMT;
      }
    
      public TelnetClient getTc() {
          return TC;
      }
    
      public void setIn(InputStream in) {
          this.in = in;
      }
    
      public void setOut(PrintStream out) {
          this.out = out;
      }
    

    }

public class Host {

    private final static Logger LOGGER = LogManager.getLogger(Host.class);

    private String ip;

    public Host(String ip) {
        this.ip = ip;
    }

    public String getIp() {
        return ip;
    }

}
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 11 '21 at 05:43