1

I'm starting up a process and making use of plink to create a reverse tunnel to an ssh that's in my local network.

I can connect fine to the server, but its not displaying the full content on the console window, my goal is to wait for everything to display and then proceed by inputting the password using process.standardInput.

I should receive this on the console window:

Using username "dayan".
Passphrase for key "rsa-key-20130516":

But i receive just the first line:

Using username "dayan".

If i press enter, it does provide me with the "Incorrect password error" but i never see "Passphrase for key rsa-key...."

Also please note that I did put in the correct password and the console remained blank, but on the Linux shell that holds the SSH server, I ran a who command and noticed I was connected successfully.

What could be the issue here?

ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.FileName = Path.Combine(BinPath, "plink.exe");

processInfo.Arguments = 
String.Format(@" {0} {1}:127.0.0.1:{2} -i {3} -l {4} {5}", 
remoteOption, LocalPort, TargetPort, KeyPath, username, TargetIp);

processInfo.UseShellExecute = false;
processInfo.CreateNoWindow = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardInput = true;
processInfo.RedirectStandardError = true;

Process process = Process.Start(processInfo);
StreamReader output = process.StandardOutput;

while (!output.EndOfStream) {
    string s = output.ReadLine();
    if (s != "")
        Console.WriteLine(s);
}

process.WaitForExit();
process.Close();
4

1 回答 1

1

The user name will be already submitted here:

processInfo.Arguments = 
String.Format(@" {0} {1}:127.0.0.1:{2} -i {3} -l {4} {5}", 
remoteOption, LocalPort, TargetPort, KeyPath, username, TargetIp);

So when you start the process, plink will still handle the user name as input and return a line to process.StandardOutput.

Now it waits for the password but don't ends the line, so string s = output.ReadLine(); dismatchs the real output the program submits.

Try instead reading each byte of the output:

  var buffer = new char[1];
  while (output.Read(buffer, 0, 1) > 0)
  {
       Console.Write(new string(buffer));
  };

This will catch also the CR+LFs, so you don't have to mention, if the output have to add a new line. If you want to handle CR+LFs manually (espec. parsing a specific line) you can add the buffer to a string, and only send it, if you find a "\r" or a ":" or so like:

  var buffer = new char[1];
  string line = "";
  while (process.StandardError.Read(buffer, 0, 1) > 0)
  {
      line += new string(buffer);

      if (line.Contains("\r\n") || (line.Contains("Passphrase for key") && line.Contains(":")))
      {
         Console.WriteLine(line.Replace("\r\n",""));
         line = "";
      }
  };
于 2013-05-17T06:18:19.420 回答