From 0bba35623358d072883333afb8d28f7aa9c39f20 Mon Sep 17 00:00:00 2001 From: PaulHigin Date: Thu, 20 Apr 2017 09:50:39 -0700 Subject: [PATCH 1/4] Fix to support multi-line error messages from SSH client --- .../fanin/OutOfProcTransportManager.cs | 84 +++++++++++++------ .../resources/RemotingErrorIdStrings.resx | 7 +- 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs index d8625acc5f9..8f4d239b6d1 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs @@ -1453,11 +1453,6 @@ internal override void CreateAsync() out _stdOutReader, out _stdErrReader); - _sshProcess.Exited += (sender, args) => - { - CloseConnection(); - }; - // Start error reader thread. StartErrorThread(_stdErrReader); @@ -1515,38 +1510,77 @@ private void ProcessErrorThread(object state) 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)) + { + sb.Append("\r\n"); + sb.Append(task.Result); + } + else + { + running = false; + } + } + catch (Exception) + { + running = false; + } } + + return sb.ToString(); } private void StartReaderThread( diff --git a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx index 9668c4b18b6..4cc2dd71def 100644 --- a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx +++ b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx @@ -59,8 +59,8 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + @@ -1615,9 +1615,6 @@ All WinRM sessions connected to Windows PowerShell session configurations, such The SSH client session has ended with error message: {0} - - The SSH client session has ended with no error message. - The provided SSHConnection hashtable is missing the required ComputerName or HostName parameter. From 722b5f6aec55524e2d83986538d456e95f8de69a Mon Sep 17 00:00:00 2001 From: PaulHigin Date: Thu, 20 Apr 2017 09:54:12 -0700 Subject: [PATCH 2/4] Fixed resx file --- .../resources/RemotingErrorIdStrings.resx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx index 4cc2dd71def..fcc7d505d92 100644 --- a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx +++ b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx @@ -59,8 +59,8 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + From d5da165bee791d6b99f88c2181240455579593ee Mon Sep 17 00:00:00 2001 From: PaulHigin Date: Thu, 20 Apr 2017 15:53:05 -0700 Subject: [PATCH 3/4] Added null check --- .../engine/remoting/fanin/OutOfProcTransportManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs index 8f4d239b6d1..a4d54065990 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs @@ -1564,7 +1564,7 @@ private static string ReadError(StreamReader reader) try { var task = reader.ReadLineAsync(); - if (task.Wait(1000)) + if (task.Wait(1000) && (task.Result != null)) { sb.Append("\r\n"); sb.Append(task.Result); From c8b4ba11e0113dad73d8e53f5ee68b955b9b3b3c Mon Sep 17 00:00:00 2001 From: PaulHigin Date: Fri, 21 Apr 2017 10:09:38 -0700 Subject: [PATCH 4/4] Added Environment.NewLine --- .../engine/remoting/fanin/OutOfProcTransportManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs index a4d54065990..3e0c864756b 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs @@ -1566,7 +1566,7 @@ private static string ReadError(StreamReader reader) var task = reader.ReadLineAsync(); if (task.Wait(1000) && (task.Result != null)) { - sb.Append("\r\n"); + sb.Append(Environment.NewLine); sb.Append(task.Result); } else