Make experimental feature PSRemotingSSHTransportErrorHandling stable (#18046)

This commit is contained in:
Steve Lee
2022-09-07 17:34:30 -07:00
committed by GitHub
parent 3f5c5cd617
commit 3bf6423a10
4 changed files with 15 additions and 90 deletions
-1
View File
@@ -5,7 +5,6 @@
"PSLoadAssemblyFromNativeCode",
"PSNativeCommandArgumentPassing",
"PSNativeCommandErrorActionPreference",
"PSRemotingSSHTransportErrorHandling",
"PSStrictModeAssignment",
"PSSubsystemPluginModel"
]
-1
View File
@@ -5,7 +5,6 @@
"PSLoadAssemblyFromNativeCode",
"PSNativeCommandArgumentPassing",
"PSNativeCommandErrorActionPreference",
"PSRemotingSSHTransportErrorHandling",
"PSStrictModeAssignment",
"PSSubsystemPluginModel"
]
@@ -23,7 +23,6 @@ namespace System.Management.Automation
internal const string EngineSource = "PSEngine";
internal const string PSNativeCommandArgumentPassingFeatureName = "PSNativeCommandArgumentPassing";
internal const string PSNativeCommandErrorActionPreferenceFeatureName = "PSNativeCommandErrorActionPreference";
internal const string PSRemotingSSHTransportErrorHandling = "PSRemotingSSHTransportErrorHandling";
internal const string PSAMSIMethodInvocationLogging = "PSAMSIMethodInvocationLogging";
internal const string PSStrictModeAssignment = "PSStrictModeAssignment";
@@ -126,9 +125,6 @@ namespace System.Management.Automation
new ExperimentalFeature(
name: PSNativeCommandErrorActionPreferenceFeatureName,
description: "Native commands with non-zero exit codes issue errors according to $ErrorActionPreference when $PSNativeCommandUseErrorActionPreference is $true"),
new ExperimentalFeature(
name: PSRemotingSSHTransportErrorHandling,
description: "Removes the SSH remoting transport stdErr stream message handling as terminating errors, and instead just writes error messages to console."),
new ExperimentalFeature(
name: PSAMSIMethodInvocationLogging,
description: "Provides AMSI notification of .NET method invocations."),
@@ -1819,50 +1819,30 @@ namespace System.Management.Automation.Remoting.Client
{
string error;
if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSRemotingSSHTransportErrorHandling))
// Blocking read from StdError stream
error = reader.ReadLine();
if (error == null)
{
// Blocking read from StdError stream
error = reader.ReadLine();
if (error == null)
{
// Stream is closed unexpectedly.
throw new PSInvalidOperationException(RemotingErrorIdStrings.SSHAbruptlyTerminated);
}
if (error.Length == 0)
{
// Ignore
continue;
}
try
{
// Messages in error stream from ssh are unreliable, and may just be warnings or
// banner text.
// So just report the messages but don't act on them.
System.Console.WriteLine(error);
}
catch (IOException)
{ }
continue;
// Stream is closed unexpectedly.
throw new PSInvalidOperationException(RemotingErrorIdStrings.SSHAbruptlyTerminated);
}
error = ReadError(reader);
if (error.Length == 0)
{
// Ignore
continue;
}
// Any SSH client error results in a broken session.
PSRemotingTransportException psrte = new PSRemotingTransportException(
PSRemotingErrorId.IPCServerProcessReportedError,
RemotingErrorIdStrings.IPCServerProcessReportedError,
StringUtil.Format(RemotingErrorIdStrings.SSHClientEndWithErrorMessage, error));
HandleSSHError(psrte);
try
{
// Messages in error stream from ssh are unreliable, and may just be warnings or
// banner text.
// So just report the messages but don't act on them.
System.Console.WriteLine(error);
}
catch (IOException)
{ }
}
}
catch (ObjectDisposedException)
@@ -1888,55 +1868,6 @@ namespace System.Management.Automation.Remoting.Client
CloseConnection();
}
private static string ReadError(StreamReader reader)
{
// Blocking read from StdError stream
string error = reader.ReadLine();
if (error == null)
{
// Stream is closed unexpectedly.
throw new PSInvalidOperationException(RemotingErrorIdStrings.SSHAbruptlyTerminated);
}
if ((error.Length == 0) ||
error.Contains("WARNING:", StringComparison.OrdinalIgnoreCase))
{
// Handle as interactive warning message
Console.WriteLine(error);
return string.Empty;
}
// SSH may return a multi-line error message.
// The StdError pipe stream is open ended causing StreamReader read operations to block
// if there is no incoming data. Since we don't know how many error message lines there
// will be we use an asynchronous read with timeout to prevent blocking indefinitely.
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)
{