PowerShell/src/Microsoft.WSMan.Management/CredSSP.cs

928 lines
36 KiB
C#

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Management.Automation;
using System.Management.Automation.Provider;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using System.Xml;
using Microsoft.Win32;
using Dbg = System.Management.Automation;
namespace Microsoft.WSMan.Management
{
#region WSManCredSSP cmdlet base
/// <summary>
/// Base class used *-WSManCredSSP cmdlets (Enable-WSManCredSSP, Disable-WSManCredSSP)
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SSP")]
public class WSManCredSSPCommandBase : PSCmdlet
{
#region Protected / Internal Data
internal const string Server = "Server";
internal const string Client = "Client";
#endregion
#region Parameters
/// <summary>
/// Role can either "Client" or "Server".
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
[ValidateSet(Client, Server)]
public string Role
{
get { return role; }
set { role = value; }
}
private string role;
#endregion
#region Utilities
/// <summary>
/// </summary>
/// <returns>
/// Returns a session object upon successful creation..otherwise
/// writes an error using WriteError and returns null.
/// </returns>
internal IWSManSession CreateWSManSession()
{
IWSManEx wsmanObject = (IWSManEx)new WSManClass();
IWSManSession m_SessionObj = null;
try
{
m_SessionObj = (IWSManSession)wsmanObject.CreateSession(null, 0, null);
return m_SessionObj;
}
catch (COMException ex)
{
ErrorRecord er = new ErrorRecord(ex, "COMException", ErrorCategory.InvalidOperation, null);
WriteError(er);
}
return null;
}
#endregion
}
#endregion
#region DisableWsManCredSsp
/// <summary>
/// Disables CredSSP authentication on the client. CredSSP authentication
/// enables an application to delegate the user's credentials from the client to
/// the server, hence allowing the user to perform management operations that
/// access a second hop.
/// </summary>
[Cmdlet(VerbsLifecycle.Disable, "WSManCredSSP", HelpUri = "https://go.microsoft.com/fwlink/?LinkId=2096628")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SSP")]
public class DisableWSManCredSSPCommand : WSManCredSSPCommandBase, IDisposable
{
#region private
// The application name MUST be "wsman" as wsman got approval from security
// folks who suggested to register the SPN with name "wsman".
private const string applicationname = "wsman";
private void DisableClientSideSettings()
{
WSManHelper helper = new WSManHelper(this);
IWSManSession m_SessionObj = CreateWSManSession();
if (m_SessionObj == null)
{
return;
}
try
{
string result = m_SessionObj.Get(helper.CredSSP_RUri, 0);
XmlDocument resultopxml = new XmlDocument();
string inputXml = null;
resultopxml.LoadXml(result);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(resultopxml.NameTable);
nsmgr.AddNamespace("cfg", helper.CredSSP_XMLNmsp);
XmlNode xNode = resultopxml.SelectSingleNode(helper.CredSSP_SNode, nsmgr);
if (!(xNode == null))
{
inputXml = @"<cfg:Auth xmlns:cfg=""http://schemas.microsoft.com/wbem/wsman/1/config/client/auth""><cfg:CredSSP>false</cfg:CredSSP></cfg:Auth>";
}
else
{
InvalidOperationException ex = new InvalidOperationException();
ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);
WriteError(er);
return;
}
m_SessionObj.Put(helper.CredSSP_RUri, inputXml, 0);
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
{
this.DeleteUserDelegateSettings();
}
else
{
ThreadStart start = new ThreadStart(this.DeleteUserDelegateSettings);
Thread thread = new Thread(start);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
if (!helper.ValidateCreadSSPRegistryRetry(false, null, applicationname))
{
helper.AssertError(helper.GetResourceMsgFromResourcetext("DisableCredSSPPolicyValidateError"), false, null);
}
}
catch (System.Xml.XPath.XPathException ex)
{
ErrorRecord er = new ErrorRecord(ex, "XpathException", ErrorCategory.InvalidOperation, null);
WriteError(er);
}
finally
{
if (!string.IsNullOrEmpty(m_SessionObj.Error))
{
helper.AssertError(m_SessionObj.Error, true, null);
}
if (m_SessionObj != null)
Dispose(m_SessionObj);
}
}
private void DisableServerSideSettings()
{
WSManHelper helper = new WSManHelper(this);
IWSManSession m_SessionObj = CreateWSManSession();
if (m_SessionObj == null)
{
return;
}
try
{
string result = m_SessionObj.Get(helper.Service_CredSSP_Uri, 0);
XmlDocument resultopxml = new XmlDocument();
string inputXml = null;
resultopxml.LoadXml(result);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(resultopxml.NameTable);
nsmgr.AddNamespace("cfg", helper.Service_CredSSP_XMLNmsp);
XmlNode xNode = resultopxml.SelectSingleNode(helper.CredSSP_SNode, nsmgr);
if (!(xNode == null))
{
inputXml = string.Format(CultureInfo.InvariantCulture,
@"<cfg:Auth xmlns:cfg=""{0}""><cfg:CredSSP>false</cfg:CredSSP></cfg:Auth>",
helper.Service_CredSSP_XMLNmsp);
}
else
{
InvalidOperationException ex = new InvalidOperationException();
ErrorRecord er = new ErrorRecord(ex,
helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"),
ErrorCategory.InvalidOperation, null);
WriteError(er);
return;
}
m_SessionObj.Put(helper.Service_CredSSP_Uri, inputXml, 0);
}
finally
{
if (!string.IsNullOrEmpty(m_SessionObj.Error))
{
helper.AssertError(m_SessionObj.Error, true, null);
}
if (m_SessionObj != null)
{
Dispose(m_SessionObj);
}
}
}
private void DeleteUserDelegateSettings()
{
System.IntPtr KeyHandle = System.IntPtr.Zero;
IGroupPolicyObject GPO = (IGroupPolicyObject)new GPClass();
GPO.OpenLocalMachineGPO(1);
KeyHandle = GPO.GetRegistryKey(2);
RegistryKey rootKey = Registry.CurrentUser;
string GPOpath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy Objects";
RegistryKey GPOKey = rootKey.OpenSubKey(GPOpath, true);
foreach (string keyname in GPOKey.GetSubKeyNames())
{
if (keyname.EndsWith("Machine", StringComparison.OrdinalIgnoreCase))
{
string key = GPOpath + "\\" + keyname + "\\" + @"Software\Policies\Microsoft\Windows";
DeleteDelegateSettings(applicationname, Registry.CurrentUser, key, GPO);
}
}
KeyHandle = System.IntPtr.Zero;
}
private void DeleteDelegateSettings(string applicationname, RegistryKey rootKey, string Registry_Path, IGroupPolicyObject GPO)
{
WSManHelper helper = new WSManHelper(this);
RegistryKey rKey;
int i = 0;
bool otherkeys = false;
try
{
string Registry_Path_Credentials_Delegation = Registry_Path + @"\CredentialsDelegation";
RegistryKey Allow_Fresh_Credential_Key = rootKey.OpenSubKey(Registry_Path_Credentials_Delegation + @"\" + helper.Key_Allow_Fresh_Credentials, true);
if (Allow_Fresh_Credential_Key != null)
{
string[] valuenames = Allow_Fresh_Credential_Key.GetValueNames();
if (valuenames.Length > 0)
{
Collection<string> KeyCollection = new Collection<string>();
foreach (string value in valuenames)
{
object keyvalue = Allow_Fresh_Credential_Key.GetValue(value);
if (keyvalue != null)
{
if (!keyvalue.ToString().StartsWith(applicationname, StringComparison.OrdinalIgnoreCase))
{
KeyCollection.Add(keyvalue.ToString());
otherkeys = true;
}
}
Allow_Fresh_Credential_Key.DeleteValue(value);
}
foreach (string keyvalue in KeyCollection)
{
Allow_Fresh_Credential_Key.SetValue(Convert.ToString(i + 1, CultureInfo.InvariantCulture), keyvalue, RegistryValueKind.String);
i++;
}
}
}
if (!otherkeys)
{
rKey = rootKey.OpenSubKey(Registry_Path_Credentials_Delegation, true);
if (rKey != null)
{
object regval1 = rKey.GetValue(helper.Key_Allow_Fresh_Credentials);
if (regval1 != null)
{
rKey.DeleteValue(helper.Key_Allow_Fresh_Credentials, false);
}
object regval2 = rKey.GetValue(helper.Key_Concatenate_Defaults_AllowFresh);
if (regval2 != null)
{
rKey.DeleteValue(helper.Key_Concatenate_Defaults_AllowFresh, false);
}
if (rKey.OpenSubKey(helper.Key_Allow_Fresh_Credentials) != null)
{
rKey.DeleteSubKeyTree(helper.Key_Allow_Fresh_Credentials);
}
}
}
GPO.Save(true, true, new Guid("35378EAC-683F-11D2-A89A-00C04FBBCFA2"), new Guid("6AD20875-336C-4e22-968F-C709ACB15814"));
}
catch (InvalidOperationException ex)
{
ErrorRecord er = new ErrorRecord(ex, "InvalidOperation", ErrorCategory.InvalidOperation, null);
WriteError(er);
}
catch (ArgumentException ex)
{
ErrorRecord er = new ErrorRecord(ex, "InvalidArgument", ErrorCategory.InvalidArgument, null);
WriteError(er);
}
catch (SecurityException ex)
{
ErrorRecord er = new ErrorRecord(ex, "SecurityException", ErrorCategory.SecurityError, null);
WriteError(er);
}
catch (UnauthorizedAccessException ex)
{
ErrorRecord er = new ErrorRecord(ex, "UnauthorizedAccess", ErrorCategory.SecurityError, null);
WriteError(er);
}
}
#endregion private
/// <summary>
/// Begin processing method.
/// </summary>
protected override void BeginProcessing()
{
// If not running elevated, then throw an "elevation required" error message.
WSManHelper.ThrowIfNotAdministrator();
if (Role.Equals(Client, StringComparison.OrdinalIgnoreCase))
{
DisableClientSideSettings();
}
if (Role.Equals(Server, StringComparison.OrdinalIgnoreCase))
{
DisableServerSideSettings();
}
}
#region IDisposable Members
/// <summary>
/// Public dispose method.
/// </summary>
public
void
Dispose()
{
// CleanUp();
GC.SuppressFinalize(this);
}
/// <summary>
/// Public dispose method.
/// </summary>
public
void
Dispose(IWSManSession sessionObject)
{
sessionObject = null;
this.Dispose();
}
#endregion IDisposable Members
}
#endregion DisableWsManCredSSP
#region EnableCredSSP
/// <summary>
/// Enables CredSSP authentication on the client. CredSSP authentication enables
/// an application to delegate the user's credentials from the client to the
/// server, hence allowing the user to perform management operations that access
/// a second hop.
/// This cmdlet performs the following:
///
/// On the client:
/// 1. Enables WSMan local configuration on client to enable CredSSP
/// 2. Sets CredSSP policy AllowFreshCredentials to wsman/Delegate. This policy
/// allows delegating explicit credentials to a server when server
/// authentication is achieved via a trusted X509 certificate or Kerberos.
/// </summary>
[Cmdlet(VerbsLifecycle.Enable, "WSManCredSSP", HelpUri = "https://go.microsoft.com/fwlink/?LinkId=2096719")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SSP")]
public class EnableWSManCredSSPCommand : WSManCredSSPCommandBase, IDisposable/*, IDynamicParameters*/
{
/// <summary>
/// Delegate parameter.
/// </summary>
[Parameter(Position = 1)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] DelegateComputer
{
get { return delegatecomputer; }
set { delegatecomputer = value; }
}
private string[] delegatecomputer;
/// <summary>
/// Property that sets force parameter.
/// </summary>
[Parameter()]
public SwitchParameter Force
{
get { return force; }
set { force = value; }
}
private bool force = false;
// helper variable
private WSManHelper helper;
// The application name MUST be "wsman" as wsman got approval from security
// folks who suggested to register the SPN with name "wsman".
private const string applicationname = "wsman";
#region Cmdlet Overloads
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
// If not running elevated, then throw an "elevation required" error message.
WSManHelper.ThrowIfNotAdministrator();
helper = new WSManHelper(this);
// DelegateComputer cannot be specified when Role is other than client
if ((delegatecomputer != null) && !Role.Equals(Client, StringComparison.OrdinalIgnoreCase))
{
string message = helper.FormatResourceMsgFromResourcetext("CredSSPRoleAndDelegateCannotBeSpecified",
"DelegateComputer",
"Role",
Role,
Client);
throw new InvalidOperationException(message);
}
// DelegateComputer must be specified when Role is client
if (Role.Equals(Client, StringComparison.OrdinalIgnoreCase) && (delegatecomputer == null))
{
string message = helper.FormatResourceMsgFromResourcetext("CredSSPClientAndDelegateMustBeSpecified",
"DelegateComputer",
"Role",
Client);
throw new InvalidOperationException(message);
}
if (Role.Equals(Client, StringComparison.OrdinalIgnoreCase))
{
EnableClientSideSettings();
}
if (Role.Equals(Server, StringComparison.OrdinalIgnoreCase))
{
EnableServerSideSettings();
}
}
#endregion
/// <summary>
/// </summary>
/// <exception cref="InvalidOperationException">
/// </exception>
private void EnableClientSideSettings()
{
string query = helper.GetResourceMsgFromResourcetext("CredSSPContinueQuery");
string caption = helper.GetResourceMsgFromResourcetext("CredSSPContinueCaption");
if (!force && !ShouldContinue(query, caption))
{
return;
}
IWSManSession m_SessionObj = CreateWSManSession();
if (m_SessionObj == null)
{
return;
}
try
{
// get the credssp node to check if wsman is configured on this machine
string result = m_SessionObj.Get(helper.CredSSP_RUri, 0);
XmlNode node = helper.GetXmlNode(result, helper.CredSSP_SNode, helper.CredSSP_XMLNmsp);
if (node == null)
{
InvalidOperationException ex = new InvalidOperationException();
ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);
WriteError(er);
return;
}
string newxmlcontent = @"<cfg:Auth xmlns:cfg=""http://schemas.microsoft.com/wbem/wsman/1/config/client/auth""><cfg:CredSSP>true</cfg:CredSSP></cfg:Auth>";
try
{
XmlDocument xmldoc = new XmlDocument();
// push the xml string with credssp enabled
xmldoc.LoadXml(m_SessionObj.Put(helper.CredSSP_RUri, newxmlcontent, 0));
// set the Registry using GroupPolicyObject
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
{
this.UpdateCurrentUserRegistrySettings();
}
else
{
ThreadStart start = new ThreadStart(this.UpdateCurrentUserRegistrySettings);
Thread thread = new Thread(start);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
if (helper.ValidateCreadSSPRegistryRetry(true, delegatecomputer, applicationname))
{
WriteObject(xmldoc.FirstChild);
}
else
{
helper.AssertError(helper.GetResourceMsgFromResourcetext("EnableCredSSPPolicyValidateError"), false, delegatecomputer);
}
}
catch (COMException)
{
helper.AssertError(m_SessionObj.Error, true, delegatecomputer);
}
}
finally
{
if (!string.IsNullOrEmpty(m_SessionObj.Error))
{
helper.AssertError(m_SessionObj.Error, true, delegatecomputer);
}
if (m_SessionObj != null)
{
Dispose(m_SessionObj);
}
}
}
private void EnableServerSideSettings()
{
string query = helper.GetResourceMsgFromResourcetext("CredSSPServerContinueQuery");
string caption = helper.GetResourceMsgFromResourcetext("CredSSPContinueCaption");
if (!force && !ShouldContinue(query, caption))
{
return;
}
IWSManSession m_SessionObj = CreateWSManSession();
if (m_SessionObj == null)
{
return;
}
try
{
// get the credssp node to check if wsman is configured on this machine
string result = m_SessionObj.Get(helper.Service_CredSSP_Uri, 0);
XmlNode node = helper.GetXmlNode(result,
helper.CredSSP_SNode,
helper.Service_CredSSP_XMLNmsp);
if (node == null)
{
InvalidOperationException ex = new InvalidOperationException();
ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);
WriteError(er);
return;
}
try
{
XmlDocument xmldoc = new XmlDocument();
string newxmlcontent = string.Format(CultureInfo.InvariantCulture,
@"<cfg:Auth xmlns:cfg=""{0}""><cfg:CredSSP>true</cfg:CredSSP></cfg:Auth>",
helper.Service_CredSSP_XMLNmsp);
// push the xml string with credssp enabled
xmldoc.LoadXml(m_SessionObj.Put(helper.Service_CredSSP_Uri, newxmlcontent, 0));
WriteObject(xmldoc.FirstChild);
}
catch (COMException)
{
helper.AssertError(m_SessionObj.Error, true, delegatecomputer);
}
}
finally
{
if (!string.IsNullOrEmpty(m_SessionObj.Error))
{
helper.AssertError(m_SessionObj.Error, true, delegatecomputer);
}
if (m_SessionObj != null)
{
Dispose(m_SessionObj);
}
}
}
/// <summary>
/// </summary>
private void UpdateCurrentUserRegistrySettings()
{
System.IntPtr KeyHandle = System.IntPtr.Zero;
IGroupPolicyObject GPO = (IGroupPolicyObject)new GPClass();
GPO.OpenLocalMachineGPO(1);
KeyHandle = GPO.GetRegistryKey(2);
RegistryKey rootKey = Registry.CurrentUser;
string GPOpath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy Objects";
RegistryKey GPOKey = rootKey.OpenSubKey(GPOpath, true);
foreach (string keyname in GPOKey.GetSubKeyNames())
{
if (keyname.EndsWith("Machine", StringComparison.OrdinalIgnoreCase))
{
string key = GPOpath + "\\" + keyname + "\\" + @"Software\Policies\Microsoft\Windows";
UpdateGPORegistrySettings(applicationname, this.delegatecomputer, Registry.CurrentUser, key);
}
}
// saving gpo settings
GPO.Save(true, true, new Guid("35378EAC-683F-11D2-A89A-00C04FBBCFA2"), new Guid("7A9206BD-33AF-47af-B832-D4128730E990"));
}
/// <summary>
/// Updates the grouppolicy registry settings.
/// </summary>
/// <param name="applicationname"></param>
/// <param name="delegatestring"></param>
/// <param name="rootKey"></param>
/// <param name="Registry_Path"></param>
private void UpdateGPORegistrySettings(string applicationname, string[] delegatestring, RegistryKey rootKey, string Registry_Path)
{
// RegistryKey rootKey = Registry.LocalMachine;
RegistryKey Credential_Delegation_Key;
RegistryKey Allow_Fresh_Credential_Key;
int i = 0;
try
{
string Registry_Path_Credentials_Delegation = Registry_Path + @"\CredentialsDelegation";
// open the registry key.If key is not present,create a new one
Credential_Delegation_Key = rootKey.OpenSubKey(Registry_Path_Credentials_Delegation, true) ?? rootKey.CreateSubKey(Registry_Path_Credentials_Delegation, RegistryKeyPermissionCheck.ReadWriteSubTree);
Credential_Delegation_Key.SetValue(helper.Key_Allow_Fresh_Credentials, 1, RegistryValueKind.DWord);
Credential_Delegation_Key.SetValue(helper.Key_Concatenate_Defaults_AllowFresh, 1, RegistryValueKind.DWord);
// add the delegate value
Allow_Fresh_Credential_Key = rootKey.OpenSubKey(Registry_Path_Credentials_Delegation + @"\" + helper.Key_Allow_Fresh_Credentials, true) ?? rootKey.CreateSubKey(Registry_Path_Credentials_Delegation + @"\" + helper.Key_Allow_Fresh_Credentials, RegistryKeyPermissionCheck.ReadWriteSubTree);
if (Allow_Fresh_Credential_Key != null)
{
i = Allow_Fresh_Credential_Key.ValueCount;
foreach (string del in delegatestring)
{
Allow_Fresh_Credential_Key.SetValue(Convert.ToString(i + 1, CultureInfo.InvariantCulture), applicationname + @"/" + del, RegistryValueKind.String);
i++;
}
}
}
catch (UnauthorizedAccessException ex)
{
ErrorRecord er = new ErrorRecord(ex, "UnauthorizedAccessException", ErrorCategory.PermissionDenied, null);
WriteError(er);
}
catch (SecurityException ex)
{
ErrorRecord er = new ErrorRecord(ex, "SecurityException", ErrorCategory.InvalidOperation, null);
WriteError(er);
}
catch (ArgumentException ex)
{
ErrorRecord er = new ErrorRecord(ex, "ArgumentException", ErrorCategory.InvalidOperation, null);
WriteError(er);
}
}
#region IDisposable Members
/// <summary>
/// Public dispose method.
/// </summary>
public
void
Dispose()
{
GC.SuppressFinalize(this);
}
/// <summary>
/// Public dispose method.
/// </summary>
public
void
Dispose(IWSManSession sessionObject)
{
sessionObject = null;
this.Dispose();
}
#endregion IDisposable Members
}
#endregion EnableCredSSP
#region Get-CredSSP
/// <summary>
/// Gets the CredSSP related configuration on the client. CredSSP authentication
/// enables an application to delegate the user's credentials from the client to
/// the server, hence allowing the user to perform management operations that
/// access a second hop.
/// This cmdlet performs the following:
/// 1. Gets the configuration for WSMan policy on client to enable/disable
/// CredSSP
/// 2. Gets the configuration information for the CredSSP policy
/// AllowFreshCredentials . This policy allows delegating explicit credentials
/// to a server when server authentication is achieved via a trusted X509
/// certificate or Kerberos.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SSP")]
[Cmdlet(VerbsCommon.Get, "WSManCredSSP", HelpUri = "https://go.microsoft.com/fwlink/?LinkId=2096838")]
public class GetWSManCredSSPCommand : PSCmdlet, IDisposable
{
#region private
private WSManHelper helper = null;
/// <summary>
/// Method to get the values.
/// </summary>
private string GetDelegateSettings(string applicationname)
{
RegistryKey rootKey = Registry.LocalMachine;
RegistryKey rKey;
string result = string.Empty;
string[] valuenames = null;
try
{
string Reg_key = helper.Registry_Path_Credentials_Delegation + @"\CredentialsDelegation";
rKey = rootKey.OpenSubKey(Reg_key);
if (rKey != null)
{
rKey = rKey.OpenSubKey(helper.Key_Allow_Fresh_Credentials);
if (rKey != null)
{
valuenames = rKey.GetValueNames();
if (valuenames.Length > 0)
{
string listvalue = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
foreach (string value in valuenames)
{
object keyvalue = rKey.GetValue(value);
if (keyvalue != null)
{
if (keyvalue.ToString().StartsWith(applicationname, StringComparison.OrdinalIgnoreCase))
{
result = keyvalue.ToString() + listvalue + result;
}
}
}
if (result.EndsWith(listvalue, StringComparison.OrdinalIgnoreCase))
{
result = result.Remove(result.Length - 1);
}
}
}
}
}
catch (ArgumentException ex)
{
ErrorRecord er = new ErrorRecord(ex, "ArgumentException", ErrorCategory.PermissionDenied, null);
WriteError(er);
}
catch (SecurityException ex)
{
ErrorRecord er = new ErrorRecord(ex, "SecurityException", ErrorCategory.PermissionDenied, null);
WriteError(er);
}
catch (ObjectDisposedException ex)
{
ErrorRecord er = new ErrorRecord(ex, "ObjectDisposedException", ErrorCategory.PermissionDenied, null);
WriteError(er);
}
return result;
}
#endregion private
#region overrides
/// <summary>
/// Method to begin processing.
/// </summary>
protected override void BeginProcessing()
{
// If not running elevated, then throw an "elevation required" error message.
WSManHelper.ThrowIfNotAdministrator();
helper = new WSManHelper(this);
IWSManSession m_SessionObj = null;
try
{
IWSManEx wsmanObject = (IWSManEx)new WSManClass();
m_SessionObj = (IWSManSession)wsmanObject.CreateSession(null, 0, null);
string result = m_SessionObj.Get(helper.CredSSP_RUri, 0);
XmlNode node = helper.GetXmlNode(result, helper.CredSSP_SNode, helper.CredSSP_XMLNmsp);
if (node == null)
{
InvalidOperationException ex = new InvalidOperationException();
ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);
WriteError(er);
return;
}
// The application name MUST be "wsman" as wsman got approval from security
// folks who suggested to register the SPN with name "wsman".
string applicationname = "wsman";
string credsspResult = GetDelegateSettings(applicationname);
if (string.IsNullOrEmpty(credsspResult))
{
WriteObject(helper.GetResourceMsgFromResourcetext("NoDelegateFreshCred"));
}
else
{
WriteObject(helper.GetResourceMsgFromResourcetext("DelegateFreshCred") + credsspResult);
}
// Get the server side settings
result = m_SessionObj.Get(helper.Service_CredSSP_Uri, 0);
node = helper.GetXmlNode(result, helper.CredSSP_SNode, helper.Service_CredSSP_XMLNmsp);
if (node == null)
{
InvalidOperationException ex = new InvalidOperationException();
ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);
WriteError(er);
return;
}
if (node.InnerText.Equals("true", StringComparison.OrdinalIgnoreCase))
{
WriteObject(helper.GetResourceMsgFromResourcetext("CredSSPServiceConfigured"));
}
else
{
WriteObject(helper.GetResourceMsgFromResourcetext("CredSSPServiceNotConfigured"));
}
}
catch (UnauthorizedAccessException ex)
{
ErrorRecord er = new ErrorRecord(ex, "UnauthorizedAccess", ErrorCategory.PermissionDenied, null);
WriteError(er);
}
catch (SecurityException ex)
{
ErrorRecord er = new ErrorRecord(ex, "SecurityException", ErrorCategory.InvalidOperation, null);
WriteError(er);
}
catch (ArgumentException ex)
{
ErrorRecord er = new ErrorRecord(ex, "InvalidArgument", ErrorCategory.InvalidOperation, null);
WriteError(er);
}
catch (System.Xml.XPath.XPathException ex)
{
ErrorRecord er = new ErrorRecord(ex, "XPathException", ErrorCategory.InvalidOperation, null);
WriteError(er);
}
finally
{
if (!string.IsNullOrEmpty(m_SessionObj.Error))
{
helper.AssertError(m_SessionObj.Error, true, null);
}
if (m_SessionObj != null)
{
Dispose(m_SessionObj);
}
}
}
#endregion overrides
#region IDisposable Members
/// <summary>
/// Public dispose method.
/// </summary>
public
void
Dispose()
{
GC.SuppressFinalize(this);
}
/// <summary>
/// Public dispose method.
/// </summary>
public
void
Dispose(IWSManSession sessionObject)
{
sessionObject = null;
this.Dispose();
}
#endregion IDisposable Members
}
#endregion
}