SSH Remoting should handle multi-line error messages from SSH client (#3612)

* Fix to support multi-line error messages from SSH client

* Fixed resx file

* Added null check

* Added Environment.NewLine
This commit is contained in:
Paul Higinbotham 2017-04-21 18:01:11 -07:00 committed by Mike Richmond
parent e8ec40069b
commit a16b71bad4
2 changed files with 59 additions and 28 deletions

View file

@ -1453,11 +1453,6 @@ namespace System.Management.Automation.Remoting.Client
out _stdOutReader,
out _stdErrReader);
_sshProcess.Exited += (sender, args) =>
{
CloseConnection();
};
// Start error reader thread.
StartErrorThread(_stdErrReader);
@ -1515,40 +1510,79 @@ namespace System.Management.Automation.Remoting.Client
while (true)
{
string error = reader.ReadLine();
string error = ReadError(reader);
if (string.IsNullOrEmpty(error))
{
// Ignore blank error messages.
continue;
}
if (error.IndexOf("WARNING:", StringComparison.OrdinalIgnoreCase) > -1)
{
// Handle as interactive warning message.
Console.WriteLine(error);
}
else
{
// Any SSH client error results in a broken session.
PSRemotingTransportException psrte = new PSRemotingTransportException(
PSRemotingErrorId.IPCServerProcessReportedError,
RemotingErrorIdStrings.IPCServerProcessReportedError,
string.IsNullOrEmpty(error) ?
RemotingErrorIdStrings.SSHClientEndNoErrorMessage
: StringUtil.Format(RemotingErrorIdStrings.SSHClientEndWithErrorMessage, error));
RaiseErrorHandler(new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.CloseShellOperationEx));
CloseConnection();
}
// Any SSH client error results in a broken session.
PSRemotingTransportException psrte = new PSRemotingTransportException(
PSRemotingErrorId.IPCServerProcessReportedError,
RemotingErrorIdStrings.IPCServerProcessReportedError,
StringUtil.Format(RemotingErrorIdStrings.SSHClientEndWithErrorMessage, error));
HandleSSHError(psrte);
}
}
catch (ObjectDisposedException) { }
catch (Exception e)
{
string errorMsg = (e.Message != null) ? e.Message : string.Empty;
_tracer.WriteMessage("SSHClientSessionTransportManager", "ProcessErrorThread", Guid.Empty,
"Transport manager error thread ended with error: {0}", errorMsg);
PSRemotingTransportException psrte = new PSRemotingTransportException(
StringUtil.Format(RemotingErrorIdStrings.SSHClientEndWithErrorMessage, errorMsg),
e);
HandleSSHError(psrte);
}
}
private void HandleSSHError(PSRemotingTransportException psrte)
{
RaiseErrorHandler(new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.CloseShellOperationEx));
CloseConnection();
}
private static string ReadError(StreamReader reader)
{
// Blocking read from StdError stream
string error = reader.ReadLine();
if (string.IsNullOrEmpty(error) ||
error.IndexOf("WARNING:", StringComparison.OrdinalIgnoreCase) > -1)
{
// Handle as interactive warning message
Console.WriteLine(error);
return string.Empty;
}
// SSH may return a multi-line error message
System.Text.StringBuilder sb = new Text.StringBuilder(error);
var running = true;
while (running)
{
try
{
var task = reader.ReadLineAsync();
if (task.Wait(1000) && (task.Result != null))
{
sb.Append(Environment.NewLine);
sb.Append(task.Result);
}
else
{
running = false;
}
}
catch (Exception)
{
running = false;
}
}
return sb.ToString();
}
private void StartReaderThread(
StreamReader reader)
{

View file

@ -1615,9 +1615,6 @@ All WinRM sessions connected to Windows PowerShell session configurations, such
<data name="SSHClientEndWithErrorMessage" xml:space="preserve">
<value>The SSH client session has ended with error message: {0}</value>
</data>
<data name="SSHClientEndNoErrorMessage" xml:space="preserve">
<value>The SSH client session has ended with no error message.</value>
</data>
<data name="MissingRequiredSSHParameter" xml:space="preserve">
<value>The provided SSHConnection hashtable is missing the required ComputerName or HostName parameter.</value>
</data>