This one is driving me nuts... I want to write a simple C# application (with GUI) that logs into our Cisco Wireless Lan Controller (short WLC) via SSH and creates guest users. This would be quite easy with SSH.NET if not Cisco for whatever reason decided to not allow non-interactive logon - meaning you can't pass on username and password but have to type it in at the console. Even worse: they put an additional (non-functional) user prompt in front of the actual user prompt. God...
Anyway I figured it out using plink.exe and it is working quite ok, however I want to inspect the terminal output so I can decide if some commands were executed correctly. I want to use the output for the login too as the prompt appears somewhat slow and I can't rely on constant timing.
I have found some articles about redirection of the output (eg Process.start: how to get the output?), but it's just not working. I was only able to collect the output when plink.exe has been closed, but I need to read the output live with plink still running.
Here's my code so far:
namespace WIFI
{
public class Program
{
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new myForm());
}
public static String ProcessInput(string user)
{
GlobalVar.hasError = false;
GlobalVar.status = "";
if (user.Length < 5 || user.Length > 10)
{
GlobalVar.status = "Username ungültig";
GlobalVar.hasError = true;
}
else
{
WLCconnection WLC = new WLCconnection();
WLC.ConnectWLC();
if (!GlobalVar.hasError) WLC.UserExists(user);
if (!GlobalVar.hasError) WLC.CreateUser(user);
WLC.CloseWLC();
}
return GlobalVar.status;
}
}
public static class GlobalVar
{
public static Boolean hasError;
public static String status;
}
public class WLCconnection
{
Process terminal = new Process();
StringBuilder terminalOutput = new StringBuilder();
Boolean telnet = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["telnet"]);
String WLChostname = System.Configuration.ConfigurationManager.AppSettings["WLChostname"];
String WLCusername = System.Configuration.ConfigurationManager.AppSettings["WLCusername"];
String WLCpassword = System.Configuration.ConfigurationManager.AppSettings["WLCpassword"];
public void ConnectWLC()
{
terminal.StartInfo.FileName = @System.Configuration.ConfigurationManager.AppSettings["plinkpath"];
terminal.StartInfo.UseShellExecute = false;
terminal.StartInfo.RedirectStandardInput = true;
terminal.StartInfo.RedirectStandardOutput = true;
terminal.StartInfo.RedirectStandardError = true;
terminal.StartInfo.CreateNoWindow = true;
if (telnet) terminal.StartInfo.Arguments = "-telnet " + WLChostname;
else terminal.StartInfo.Arguments = "-ssh " + WLChostname;
terminal.OutputDataReceived += (s, e) => terminalOutput.Append(e.Data);
//terminal.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
terminal.ErrorDataReceived += (s, e) => terminalOutput.Append(e.Data);
//terminal.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
terminal.Start();
terminal.BeginOutputReadLine();
terminal.BeginErrorReadLine();
int runs = 0;
if (!telnet)
{
while (!terminalOutput.ToString().Contains("login as:") && !GlobalVar.hasError)
{
Thread.Sleep(500);
if (runs < 20) runs++;
else GlobalVar.hasError = true;
}
terminal.StandardInput.Write("workaroundSSHproblem\n");
}
runs = 0;
while (!terminalOutput.ToString().Contains("User:") && !GlobalVar.hasError)
{
Thread.Sleep(500);
if (runs < 20) runs++;
else GlobalVar.hasError = true;
}
terminal.StandardInput.Write(WLCusername + "\n");
runs = 0;
while (!terminalOutput.ToString().Contains("Password:") && !GlobalVar.hasError)
{
Thread.Sleep(500);
if (runs < 20) runs++;
else GlobalVar.hasError = true;
}
terminal.StandardInput.Write(WLCpassword + "\n");
}
public void CloseWLC()
{
terminal.StandardInput.WriteLine("logout");
terminal.WaitForExit();
terminal.CancelOutputRead();
terminal.Close();
terminal.Dispose();
}
public Boolean UserExists(String user)
{
int runs = 0;
while (!terminalOutput.ToString().Contains("(Cisco Controller) >") && !GlobalVar.hasError)
{
Thread.Sleep(500);
if (runs < 20) runs++;
else GlobalVar.hasError = true;
}
terminal.StandardInput.Write("show netuser detail " + user);
if (!terminalOutput.ToString().Contains("blabla"))
{
GlobalVar.status = "User " + user + " bereits aktiviert";
GlobalVar.hasError = true;
}
return GlobalVar.hasError;
}
public void CreateUser(String user)
{
int runs = 0;
while (!terminalOutput.ToString().Contains("(Cisco Controller) >") && !GlobalVar.hasError)
{
Thread.Sleep(500);
if (runs < 20) runs++;
else GlobalVar.hasError = true;
}
terminal.StandardInput.Write("config netuser add " + user + " " + System.Configuration.ConfigurationManager.AppSettings["guestpassword"] + " wlan 3 userType guest lifetime 86400");
if (!GlobalVar.hasError)
{
if (UserExists(user))
{
GlobalVar.status = "";
GlobalVar.hasError = false;
}
else
{
GlobalVar.status = "User " + user + " konnte nicht aktiviert werden";
GlobalVar.hasError = true;
}
}
}
protected void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
terminalOutput.Append(outLine.Data);
}
}
}
I'd really appreciate your help!