0

I am trying to run a sequence of commands on a CSICO router using JSCH and SSH. But the problem I am having is after executing the first command, the second one just doesn't execute. The session seems to go down after running the first command. It throws this exception:

com.jcraft.jsch.JSchException: Packet corrupt
    at com.jcraft.jsch.Session.start_discard(Session.java:1067)
    at com.jcraft.jsch.Session.read(Session.java:937)
    at com.jcraft.jsch.Session.connect(Session.java:309)
    at com.jcraft.jsch.Session.connect(Session.java:183)
    at com.att.ncaas.device.connection.ssh.SSHConnectionJSch.connect(SSHConnectionJSch.java:120)

The code look likes this:

public void connect () {

    ChannelExec channelExec = null;
    JSch jSch = new JSch();
    Session session = null;

    try {

        session = jSch.getSession(userid, ipAddress, port);

        // Set the password.
        session.setPassword("XXXXXXXXX");

        Properties properties = new Properties();

        properties.put("StrictHostKeyChecking", "no");

        // Set the Ciphers.
        /*
         * properties.put("cipher.s2c", "aes128-cbc"); properties.put("cipher.c2s",
         * "aes128-cbc"); properties.put("CheckCiphers", "aes128-cbc");
         */

        session.setConfig(properties);

        // Finally make the connection.
        session.connect();

        channelExec = (ChannelExec) session.openChannel("exec");

        // Command 1
        channelExec.setCommand("show run");

        ByteArrayOutputStream responseStream = new ByteArrayOutputStream();

        channelExec.setOutputStream(responseStream);

        channelExec.connect();

        while (channelExec.isConnected()) {
            Thread.sleep(1000);
        }

        String responseString = new String(responseStream.toByteArray());

        System.out.println("Show Run Output:\n");
        System.out.println(responseString);

        if (session.isConnected()) {
            System.out.println("Wooooooooooooooooooohoooooooooooooooooooooooo!!!!");
        } else {
            session.connect();
        }

        // Command 2
        channelExec.setCommand("show version");

        channelExec.connect();

        while (channelExec.isConnected()) {
            Thread.sleep(1000);
        }

        responseString = new String(responseStream.toByteArray());

        System.out.println("Show Version Output:\n");
        System.out.println(responseString);

    } catch (JSchException e) {

        e.printStackTrace();

    } catch (InterruptedException e) {

        e.printStackTrace();

    } catch (Exception e) {

        e.printStackTrace();

    } finally {

        if (session != null) {
            session.disconnect();
        }

        if (channelExec != null) {
            channelExec.disconnect();
        }
    }
}

When it comes for the second session.connect() inside the if block, it throws the error. The only other thing I noticed is the when I put the ciphers in, this part:

// Set the Ciphers.
properties.put("cipher.s2c", "aes128-cbc");
properties.put("cipher.c2s", "aes128-cbc");
properties.put("CheckCiphers", "aes128-cbc");

I get a different error on the same line. I get:

com.jcraft.jsch.JSchException: Session.connect: java.io.IOException: End of IO Stream Read
    at com.jcraft.jsch.Session.connect(Session.java:565)
    at com.jcraft.jsch.Session.connect(Session.java:183)

Any pointers on how to keep the session alive between two ChannelExec execute would really helpful. Thanks.

hell_storm2004
  • 1,401
  • 2
  • 33
  • 66

1 Answers1

1

First, you cannot reuse the "exec" channel this way. You have to open a new channel for the new command.


And note that Cisco is known not to support multiple commands in one "exec" channel, even if specified together upfront:
Error passing multiple commands to Cisco CLI via plink
I would not be surprised if it did not support multiple "exec" channels in one connection either.

Did you test with an SSH client, if it is even possible, to do what you are trying to implement?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • By SSH Client, do you mean something like Putty? – hell_storm2004 Oct 13 '22 at 10:43
  • Yes, PuTTY, OpenSSH – whatever client that can open multiple channels over one connection. – Martin Prikryl Oct 13 '22 at 11:22
  • Yes I wasn't able to get that done. My only option now is to do it via channel shell, if I am to understand correctly. Am I correct there? – hell_storm2004 Oct 17 '22 at 12:27
  • What you were not able to get done? The PuTTY test? Or using multiple "exec" channels in one SSH connection using Paramiko? – Martin Prikryl Oct 17 '22 at 13:33
  • The Putty test. I haven't tried Paramiko. From the looks of things, that seems to be a python tool, which I am not looking for. My main objective is to open a connection to CISCO router, run a few commands, and capture their outputs. I am a bit stumped here. Opening a shell is an option, but waiting for prompts does seem to tricky with it! I looked at a lot of examples, most of them are with one command. I am also exploring other other packages, like J2SSH Maverick and all at the moment. – hell_storm2004 Oct 17 '22 at 13:39
  • But considering what you have given me till now. I guess I can select it as the answer. As it does clearly define what I can and cannot do with the `exec` channel. – hell_storm2004 Oct 17 '22 at 13:40
  • 1
    Sorry, I've mistaken the question for different one. Of course, I've meant if you have tried multiple "exec" channels in JSch. – Martin Prikryl Oct 17 '22 at 17:33