0

I am trying to create a ssh connection with our WLC controller. When using putty manually i can connect perfectly so the credentials are fine. I tried using renci.ShhNet for this.

I can create the shhclient and use the connect function. But when i try to use the client.runcommand or the client.createcommand and then execute this command the application just 'hangs'.

My first attempt was this:

PasswordConnectionInfo conn = new PasswordConnectionInfo("10.49.144.3", WLCUser, WLCPassword);

            using (var client = new SshClient(conn))
            {
                client.Connect();
                var result = client.RunCommand($"config wlan disable {wlanId}");
                Thread.Sleep(5000);
                result = client.RunCommand($"config wlan security wpa akm psk set-key ascii {newPassword} {wlanId}");
                Thread.Sleep(5000);
                result = client.RunCommand($"config wlan enable {wlanId}");

But this hangs on the first RunCommand and i can't quite see why this hangs.

As a second resort i tried using the CreateShellStream and sending commands that way. When investigating the response i get from this stream i can see our WLC asking for username and password again. And i seem to be sending my commands to the username and password prompt. I tried sending username as password as first commands again, but this also does not work.

my second attempt:

void mainFunction()
{
PasswordConnectionInfo conn = new PasswordConnectionInfo("10.49.144.3", WLCUser, WLCPassword);

            using (var client = new SshClient(conn))
            {
                client.Connect();
                StringBuilder output = new StringBuilder();
                ShellStream stream = client.CreateShellStream("Customcommand", 80,24,800,600,1024);
                output.Append(sendCommand(WLCUser, stream));
                output.Append(sendCommand(WLCPassword, stream));
                output.Append(sendCommand("blablabla", stream));
                Console.WriteLine(output.ToString());
                client.Disconnect();
            }
}

public StringBuilder sendCommand(string customCMD, ShellStream stream)
        {
            StringBuilder answer;

            var reader = new StreamReader(stream);
            var writer = new StreamWriter(stream);
            writer.AutoFlush = true;
            WriteStream(customCMD, writer, stream);
            answer = ReadStream(reader);
            return answer;
        }

        private void WriteStream(string cmd, StreamWriter writer, ShellStream stream)
        {
            writer.WriteLine(cmd);
            while (stream.Length == 0)
            {
                Thread.Sleep(500);
            }
        }

        private StringBuilder ReadStream(StreamReader reader)
        {
            StringBuilder result = new StringBuilder();

            string line;
            while ((line = reader.ReadLine()) != null)
            {
                result.AppendLine(line);
            }
            return result;
        }

This produces the folowwing output for me:


---------------------------------------------------------------------

|                        Connected to TIG                           |

|                                                                   |

|                            WARNING !!!                            |

|                                                                   |

|       YOU HAVE CONNECTED TO A PRIVATE COMPUTING FACILITY          |

|   IF YOU ARE NOT AN AUTHORISED USER, DISCONNECT IMMEDIATELY       |

---------------------------------------------------------------------
(Cisco Controller) 
User: UserSecret
Password:
User:
PasswordSecret
Password:
User:
blablabla
Password:
User:

As you can see, i think he is expecting a username and password again, but i do not seem able to send it?

any ideas as to what is going wrong?

  • You need to add a carriage return at the end of each sendCommand. – jdweng Mar 09 '20 at 16:42
  • You could also leverage the expects feature of Ssh.Net with `ShellStream`. Essentially you are telling it to expect a certain output and what to input when that output is read. Example usage can be seen in [this](https://stackoverflow.com/a/27971356/10479955) answer. – Tyler Hundley Mar 09 '20 at 17:09
  • Nope, sending a carriage return at the end makes it even weirder – Thierry Verhaegen Mar 10 '20 at 08:30

1 Answers1

0

okay, i haven't figured out why, but apparently the piece of code i borrowed (the sendcommand bit) did not play well with the shellstream. When i wrote directly to the shell stream, instead of to the streamwriter, it seemed to work.

I now have this, and this seems to work:

using (var client = new SshClient(conn))
            {
                client.Connect();
                if (client.IsConnected)
                {
                    StringBuilder output = new StringBuilder();
                    ShellStream stream = client.CreateShellStream("Customcommand", 0, 0, 0, 0, 1024);
                    var reader = new StreamReader(stream);
                    stream.WriteLine(WLCUser);
                    stream.Flush();
                    stream.WriteLine(WLCPassword);
                    stream.Flush();
                    stream.WriteLine($"config wlan disable {wlanId}");
                    stream.Flush();
                    Thread.Sleep(5000);
                    stream.WriteLine($"config wlan security wpa akm psk set-key ascii {newPassword} {wlanId}");
                    stream.Flush();
                    Thread.Sleep(5000);
                    stream.WriteLine($"config wlan enable {wlanId}");
                    stream.Flush();
                    Thread.Sleep(1000);

                    Console.WriteLine(reader.ReadToEnd());
                    client.Disconnect();
                }
            }