0

I need to find a way to automate ssh commands to my router. My goal is to make the router restart whenever I run the script from my Java program. I'm having some issues though.

First of all, this is the sequence of output I get from my router's ssh: First I do:

ssh [email protected]

which returns:

[email protected]'s password: 

I enter the password, "admin". It then goes to this prompt:

Welcome Visiting Huawei Home Gateway
Copyright by Huawei Technologies Co., Ltd.

Password is default value, please modify it!
WAP>

Now, I input "reset" and it restarts the router.

I've tried Tcl with Expect and while I can get it working on Windows, it doesn't work on Linux. Here's my code for the Tcl script:

#!/bin/sh
# \ exec tclsh "$0" ${1+"$@"}
package require Expect
spawn ssh [email protected]
send "admin\r"
send "reset\r"
after 3000
exit

Whenever I try to execute it, Tcl8.6 runs through it and terminates without actually doing anything. However, if I manually input all of these commands while running Tcl8.6, it works just fine

I've also tried the JSch Java library. With that, I can get the Java program to connect and output the shell of the router, but any command that I try to send does nothing. Here's the code from that:

    ...
JSch jsch = new JSch();

        Session session = jsch.getSession("root", "192.168.100.1", 22);

        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);

        // Skip prompting for the password info and go direct...
        session.setPassword("admin");
        session.connect();

        String command = "reset\r";

        Channel channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(command);

        ((ChannelExec) channel).setErrStream(System.err);

        InputStream in = channel.getInputStream();

        System.out.println("Connect to session...");
        channel.connect();


        byte[] tmp = new byte[1024];
        while (true) {
            while (in.available() > 0) {
                int i = in.read(tmp, 0, 1024);
                if (i < 0) {
                    break;
                }
                System.out.print(new String(tmp, 0, i));
            }
            if (channel.isClosed()) {
                System.out.println("exit-status: " + channel.getExitStatus());
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (Exception ee) {
            }
        }
        channel.disconnect();
        session.disconnect();
        System.out.println("disconnected");

This is the output that I get:

Connect to session...

Welcome Visiting Huawei Home Gateway
Copyright by Huawei Technologies Co., Ltd.

Password is default value, please modify it!
WAP>

It just stays here until I exit. The router doesn't restart. I've also tried:

String command = "reset";

but it does the same thing. Anybody know of any other ways I could do this?

1
  • 1
    I just noticed your command ends with \r. Try \n instead and see if it works for you. Commented Aug 13, 2016 at 10:53

1 Answer 1

4

Try interacting with the device using shell instead of exec.

Here is a quick-and-dirty code I used to do so, you can adjust it to suit your needs:

private static final String PROMPT = ">";

public static void main(String[] args) throws Exception {

    Session session = null;
    ChannelShell channel = null;

    try {

        JSch jsch = new JSch();
        session = jsch.getSession("root", "192.168.100.1", 22);
        session.setConfig("StrictHostKeyChecking", "no");
        session.setPassword("admin");
        session.connect();

        channel = (ChannelShell) session.openChannel("shell");

        PipedOutputStream reply = new PipedOutputStream();
        PipedInputStream input = new PipedInputStream(reply);
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        channel.setInputStream(input, true);
        channel.setOutputStream(output, true);

        channel.connect();

        getPrompt(channel, output);
        writeCommand(reply, "reset");
        getPrompt(channel, output);

    } finally {

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

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

private static void writeCommand(PipedOutputStream reply, String command) throws IOException {
    System.out.println("Command: " + command);
    reply.write(command.getBytes());
    reply.write("\n".getBytes());
}

private static void getPrompt(ChannelShell channel, ByteArrayOutputStream output)
        throws UnsupportedEncodingException, InterruptedException {

    while (!channel.isClosed()) {

        String response = new String(output.toByteArray(), "UTF-8");
        System.out.println(response);
        if (response.trim().endsWith(PROMPT)) {
            output.reset();
            return;
        }

        Thread.sleep(100);
    }
}

UPDATE: I have noticed that the command you send via SSH ends with \r. Try \n instead and see if it works for you.

Sign up to request clarification or add additional context in comments.

4 Comments

Unfortunately, it doesn't seem to be working with that code either. It just does the same thing. It outputs the shell of the router, but does nothing after. I've tried both "\n" and "\r".
It seems to be working now. Your code is fine, it's just that there was a small modification I made that was causing issues. Thanks!
Great! You may want to explain that modification in an update to your question, so that others know. Or write here and I'll update the answer.
Oh no, your code is fine the way it is. It's just that I tried to get rid of the methods for some reason which caused it to mess up. Using it the way you have it works fine though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.