+1 vote
by (180 points)

Hi,

I'm facing an error trying to invoke a very simple command via SSH to a Cisco WLC.
This command works great executing it via PuTTY (via SSH, and we also tested it via Telnet without any problem) in the same computer and with the same network conditions by the way.

Here is the log that I could get of REBEX library:

2016-02-17 17:30:31.925 Opening log file.
2016-02-17 17:30:31.925 Using FileLogWriter version 2.0.5885.0.
2016-02-17 17:30:32.299 INFO Ssh(1)[10] Info: Connecting to 172.16.48.10:22 using Ssh 1.0.5885.0 (trial version).
2016-02-17 17:30:37.360 DEBUG Ssh(1)[10] SSH: Server is 'SSH-2.0-CISCOWLC'.
2016-02-17 17:30:37.365 INFO Ssh(1)[10] SSH: Negotiation started.
2016-02-17 17:30:37.392 DEBUG Ssh(1)[10] SSH: Group exchange.
2016-02-17 17:30:37.396 DEBUG Ssh(1)[10] SSH: Negotiating key.
2016-02-17 17:30:37.471 DEBUG Ssh(1)[10] SSH: Received 2048-bit Diffie-Hellman prime (minimum allowed size is 1024 bits).
2016-02-17 17:30:37.613 DEBUG Ssh(1)[10] SSH: Validating signature.
2016-02-17 17:30:37.629 INFO Ssh(1)[10] SSH: Negotiation finished.
2016-02-17 17:30:37.629 INFO Ssh(1)[10] Info: Server: SSH-2.0-CISCO
WLC
2016-02-17 17:30:37.629 INFO Ssh(1)[10] Info: Fingerprint: 47:80:9b:bc:ce:12:03:31:6d:18:05:b5:b3:07:bb:b9
2016-02-17 17:30:37.630 INFO Ssh(1)[10] Info: Cipher info: SSH 2.0, DiffieHellmanGroupExchangeSHA1, DSS, aes192-ctr/aes192-ctr, hmac-sha1/hmac-sha1
2016-02-17 17:30:38.918 DEBUG Ssh(1)[10] SSH: Authentication successful.
2016-02-17 17:30:39.573 DEBUG Ssh(1)[10] SSH: Executing command 'config netuser add TestTlfCortesia291479946 testing wlan 6 userType guest lifetime 3600'.
2016-02-17 17:30:39.589 ERROR Ssh(1)[10] SSH: Rebex.Net.SshException: The request has failed.
en Rebex.Net.SshChannel.IR(UBI U)
2016-02-17 17:30:39.596 ERROR Ssh(1)[10] Info: Rebex.Net.SshException: The request has failed.
en Rebex.Net.SshChannel.IR(UBI U)
en Rebex.Net.SshChannel.RequestExec(String command)
en Rebex.Net.Ssh.YGW(String U)

Here is the method that invoke the command:

public string CreateUser(string guestUser, string guestPassword)
    {
        try
        {
            var cmd = string.Format("config netuser add {0} {1} wlan {2} userType guest lifetime {3}",
                guestUser, guestPassword, _ssidNumber.ToString(), _lifeTime.ToString());

            string response = string.Empty;
            using (var sshClient = new Ssh())
            {
                sshClient.LogWriter = new Rebex.FileLogWriter(
                    @"c:\logrebex.txt",
                    Rebex.LogLevel.Debug); 

                sshClient.Connect(_wdlcIp, _wdlcPort);


                sshClient.Login(_wlcUser, _wlcPass);

                response = sshClient.RunCommand(cmd);
            }

            return response;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

Any help will be very appreciated.
Thanks.

2 Answers

+1 vote
by (147k points)
selected by
 
Best answer

If Ssh.RunCommand doesn't work, you can try working around this by creating a shell session and scripting it:

...

using (var sshClient = new Ssh())
{
    sshClient.LogWriter = new Rebex.FileLogWriter(
        @"c:\temp\logrebex.txt",
        Rebex.LogLevel.Debug);

    sshClient.Connect(_wdlcIp, _wdlcPort);

    sshClient.Login(_wlcUser, _wlcPass);

    // start scripting shell session
    var scripting = sshClient.StartScripting();

    // detect prompt
    scripting.DetectPrompt();

    // send command and read response
    scripting.SendCommand(cmd);
    response = scripting.ReadUntilPrompt();
}

...

This is not identical to RunCommand because the scripting shell session has a virtual terminal allocated and this can make some commands behave differently (like in TerminalClientWinForm or PuTTY).

In your case, the server needs to perform the login once more through the session. Adding something like this should solve it as well:

...

using (var sshClient = new Ssh())
{
    sshClient.LogWriter = new Rebex.FileLogWriter(
        @"c:\temp\logrebex.txt",
        Rebex.LogLevel.Debug);

    sshClient.Connect(_wdlcIp, _wdlcPort);

    sshClient.Login(_wlcUser, _wlcPass);

    var scripting = sshClient.StartScripting();

    // wait for "user" prompt
    scripting.WaitFor(ScriptEvent.FromString("User:"));

    // send user name
    scripting.SendCommand(_wlcUser);

    // wait for "password" prompt
    scripting.WaitFor(ScriptEvent.FromString("Password:"));

    // send password
    scripting.SendCommand(_wlcPass);

    // detect prompt
    scripting.DetectPrompt();

    // send command and read response
    scripting.SendCommand(cmd);
    response = scripting.ReadUntilPrompt();
}

...
by (180 points)
Thanks again for your kind support Lukas.

I tried that code but the command did not execute. I resolved it this way:

                    var scripting = sshClient.StartScripting();
                    scripting.DetectPrompt();
                    scripting.SendCommand(_wlcUser);
                    scripting.SendCommand(_wlcPass);
                    scripting.DetectPrompt();
                    scripting.SendCommand(cmd);
                    response = scripting.ReadUntilPrompt();

I'm sending the user and password as a command, and then I send the real command. This works perfect!


Thanks!!
+1 vote
by (147k points)

It looks like the server is rejecting your "execute command" request. How are you connecting with PuTTY? If you use it to establish a shell session, it's not the same operation as executing commands. Are you able to connect to this Cisco WLC using our TerminalClientWinForm sample app?

by (180 points)
Hi Lukas,

I've just tested with REBEX TerminalClientWinForm and it works OK like if it was the PuTTY client.

What is very strange is that in the Connect windows I inserted the host, port, username and password. But the username and password was asked again at the beginning of the connection in the terminal:

(Cisco Controller)
User: telefe
Password:*********
(Cisco Controller) >

I think that maybe that is the problem. sshClient.Login(user, pass) is not working with cisco WLC. I'm a little confused here.

Thanks for your kind support.
by (147k points)
Yes, this seems to be related - if Cisco WLC actually needs to ask for credentials again when actually starting the session after successful authentication, then it makes sense for it to reject command execute requests (because it can't ask for credentials again in that case).

I'll add another answer with a workaround for this.
...