Enable specifying sshd subsystem to use via -Subsystem (#6603)

The current implementation of PSRP over SSH only enables remoting to one version of PowerShell Core 6.
sshd_config allows specifying multiple subsystems that can start different versions of PowerShell Core 6 (or same versions with different parameters).
Enable use of a new -Subsystem parameter to specify the subsystem to use with ssh.
This commit is contained in:
Steve Lee
2018-04-24 12:51:56 -07:00
committed by Travis Plunk
parent 313a8596bb
commit c80cecf35f
4 changed files with 45 additions and 10 deletions
@@ -275,6 +275,7 @@ namespace Microsoft.PowerShell.Commands
public string UserName;
public string KeyFilePath;
public int Port;
public string Subsystem;
}
/// <summary>
@@ -763,6 +764,13 @@ namespace Microsoft.PowerShell.Commands
set;
}
/// <summary>
/// This parameter specifies the SSH subsystem to use for the remote connection.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true,
ParameterSetName = InvokeCommandCommand.SSHHostParameterSet)]
public String Subsystem { get; set; }
#endregion
#endregion Properties
@@ -822,6 +830,7 @@ namespace Microsoft.PowerShell.Commands
private const string KeyFilePathParameter = "KeyFilePath";
private const string IdentityFilePathAlias = "IdentityFilePath";
private const string PortParameter = "Port";
private const string SubsystemParameter = "Subsystem";
#endregion
@@ -915,6 +924,10 @@ namespace Microsoft.PowerShell.Commands
{
connectionInfo.Port = GetSSHConnectionIntParameter(item[paramName]);
}
else if (paramName.Equals(SubsystemParameter, StringComparison.OrdinalIgnoreCase))
{
connectionInfo.Subsystem = GetSSHConnectionStringParameter(item[paramName]);
}
else
{
throw new PSArgumentException(
@@ -1385,7 +1398,7 @@ namespace Microsoft.PowerShell.Commands
{
ParseSshHostName(computerName, out string host, out string userName, out int port);
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port);
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port, this.Subsystem);
var typeTable = TypeTable.LoadDefaultTypeFiles();
var remoteRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo, this.Host, typeTable) as RemoteRunspace;
var pipeline = CreatePipeline(remoteRunspace);
@@ -1407,7 +1420,8 @@ namespace Microsoft.PowerShell.Commands
sshConnection.UserName,
sshConnection.ComputerName,
sshConnection.KeyFilePath,
sshConnection.Port);
sshConnection.Port,
sshConnection.Subsystem);
var typeTable = TypeTable.LoadDefaultTypeFiles();
var remoteRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo, this.Host, typeTable) as RemoteRunspace;
var pipeline = CreatePipeline(remoteRunspace);
@@ -1282,7 +1282,7 @@ namespace Microsoft.PowerShell.Commands
private RemoteRunspace GetRunspaceForSSHSession()
{
ParseSshHostName(HostName, out string host, out string userName, out int port);
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port);
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port, this.Subsystem);
var typeTable = TypeTable.LoadDefaultTypeFiles();
// Use the class _tempRunspace field while the runspace is being opened so that StopProcessing can be handled at that time.
@@ -1080,7 +1080,8 @@ namespace Microsoft.PowerShell.Commands
userName,
host,
this.KeyFilePath,
port);
port,
Subsystem);
var typeTable = TypeTable.LoadDefaultTypeFiles();
string rsName = GetRunspaceName(index, out int rsIdUnused);
index++;
@@ -1105,7 +1106,8 @@ namespace Microsoft.PowerShell.Commands
sshConnection.UserName,
sshConnection.ComputerName,
sshConnection.KeyFilePath,
sshConnection.Port);
sshConnection.Port,
sshConnection.Subsystem);
var typeTable = TypeTable.LoadDefaultTypeFiles();
string rsName = GetRunspaceName(index, out int rsIdUnused);
index++;
@@ -1867,6 +1867,15 @@ namespace System.Management.Automation.Runspaces
set;
}
/// <summary>
/// Subsystem to use
/// </summary>
private string Subsystem
{
get;
set;
}
#endregion
#region Constructors
@@ -1894,6 +1903,7 @@ namespace System.Management.Automation.Runspaces
this.ComputerName = computerName;
this.KeyFilePath = keyFilePath;
this.Port = DefaultPort;
this.Subsystem = DefaultSubsystem;
}
/// <summary>
@@ -1903,15 +1913,18 @@ namespace System.Management.Automation.Runspaces
/// <param name="computerName">Computer Name</param>
/// <param name="keyFilePath">Key File Path</param>
/// <param name="port">Port number for connection (default 22)</param>
/// <param name="subsystem">Subsystem to use (default 'powershell')</param>
public SSHConnectionInfo(
string userName,
string computerName,
string keyFilePath,
int port) : this(userName, computerName, keyFilePath)
int port,
string subsystem) : this(userName, computerName, keyFilePath)
{
ValidatePortInRange(port);
this.Port = (port != 0) ? port : DefaultPort;
this.Subsystem = (String.IsNullOrEmpty(subsystem)) ? DefaultSubsystem : subsystem;
}
#endregion
@@ -1965,6 +1978,7 @@ namespace System.Management.Automation.Runspaces
newCopy.UserName = this.UserName;
newCopy.KeyFilePath = this.KeyFilePath;
newCopy.Port = this.Port;
newCopy.Subsystem = this.Subsystem;
return newCopy;
}
@@ -2040,14 +2054,14 @@ namespace System.Management.Automation.Runspaces
}
arguments = (string.IsNullOrEmpty(domainName)) ?
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" {1}@{2} -p {3} -s powershell", this.KeyFilePath, userName, this.ComputerName, this.Port) :
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" -l {1}@{2} {3} -p {4} -s powershell", this.KeyFilePath, userName, domainName, this.ComputerName, this.Port);
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" {1}@{2} -p {3} -s {4}", this.KeyFilePath, userName, this.ComputerName, this.Port, this.Subsystem) :
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" -l {1}@{2} {3} -p {4} -s {5}", this.KeyFilePath, userName, domainName, this.ComputerName, this.Port, this.Subsystem);
}
else
{
arguments = (string.IsNullOrEmpty(domainName)) ?
string.Format(CultureInfo.InvariantCulture, @"{0}@{1} -p {2} -s powershell", userName, this.ComputerName, this.Port) :
string.Format(CultureInfo.InvariantCulture, @"-l {0}@{1} {2} -p {3} -s powershell", userName, domainName, this.ComputerName, this.Port);
string.Format(CultureInfo.InvariantCulture, @"{0}@{1} -p {2} -s {3}", userName, this.ComputerName, this.Port, this.Subsystem) :
string.Format(CultureInfo.InvariantCulture, @"-l {0}@{1} {2} -p {3} -s {4}", userName, domainName, this.ComputerName, this.Port, this.Subsystem);
}
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(
@@ -2082,6 +2096,11 @@ namespace System.Management.Automation.Runspaces
/// </summary>
private const int DefaultPort = 22;
/// <summary>
/// Default value for subsystem
/// </summary>
private const string DefaultSubsystem = "powershell";
#endregion
#region SSH Process Creation