MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections;6using System.Collections.Generic;7using System.Collections.ObjectModel;8using System.ComponentModel;9using System.Diagnostics.CodeAnalysis;10using System.Globalization;11using System.IO;12using System.Management.Automation;13using System.Management.Automation.Provider;14using System.Reflection;15using System.Runtime.CompilerServices;16using System.Runtime.InteropServices;17using System.Security;18using System.Threading;19using System.Xml;20 21using Microsoft.Win32;22 23using Dbg = System.Management.Automation;24 25namespace Microsoft.WSMan.Management26{27 #region WSManCredSSP cmdlet base28 29 /// <summary>30 /// Base class used *-WSManCredSSP cmdlets (Enable-WSManCredSSP, Disable-WSManCredSSP)31 /// </summary>32 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")]33 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SSP")]34 public class WSManCredSSPCommandBase : PSCmdlet35 {36 #region Protected / Internal Data37 38 internal const string Server = "Server";39 internal const string Client = "Client";40 41 #endregion42 43 #region Parameters44 45 /// <summary>46 /// Role can either "Client" or "Server".47 /// </summary>48 [Parameter(Mandatory = true, Position = 0)]49 [ValidateSet(Client, Server)]50 public string Role51 {52 get { return role; }53 54 set { role = value; }55 }56 57 private string role;58 #endregion59 60 #region Utilities61 62 /// <summary>63 /// </summary>64 /// <returns>65 /// Returns a session object upon successful creation..otherwise66 /// writes an error using WriteError and returns null.67 /// </returns>68 internal IWSManSession CreateWSManSession()69 {70 IWSManEx wsmanObject = (IWSManEx)new WSManClass();71 IWSManSession m_SessionObj = null;72 73 try74 {75 m_SessionObj = (IWSManSession)wsmanObject.CreateSession(null, 0, null);76 return m_SessionObj;77 }78 catch (COMException ex)79 {80 ErrorRecord er = new ErrorRecord(ex, "COMException", ErrorCategory.InvalidOperation, null);81 WriteError(er);82 }83 84 return null;85 }86 87 #endregion88 }89 90 #endregion91 92 #region DisableWsManCredSsp93 94 /// <summary>95 /// Disables CredSSP authentication on the client. CredSSP authentication96 /// enables an application to delegate the user's credentials from the client to97 /// the server, hence allowing the user to perform management operations that98 /// access a second hop.99 /// </summary>100 [Cmdlet(VerbsLifecycle.Disable, "WSManCredSSP", HelpUri = "https://go.microsoft.com/fwlink/?LinkId=2096628")]101 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")]102 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SSP")]103 public class DisableWSManCredSSPCommand : WSManCredSSPCommandBase, IDisposable104 {105 #region private106 107 // The application name MUST be "wsman" as wsman got approval from security108 // folks who suggested to register the SPN with name "wsman".109 private const string applicationname = "wsman";110 111 private void DisableClientSideSettings()112 {113 WSManHelper helper = new WSManHelper(this);114 IWSManSession m_SessionObj = CreateWSManSession();115 if (m_SessionObj == null)116 {117 return;118 }119 120 try121 {122 string result = m_SessionObj.Get(helper.CredSSP_RUri, 0);123 XmlDocument resultopxml = new XmlDocument();124 resultopxml.LoadXml(result);125 XmlNamespaceManager nsmgr = new XmlNamespaceManager(resultopxml.NameTable);126 nsmgr.AddNamespace("cfg", helper.CredSSP_XMLNmsp);127 XmlNode xNode = resultopxml.SelectSingleNode(helper.CredSSP_SNode, nsmgr);128 if (xNode is null)129 {130 InvalidOperationException ex = new InvalidOperationException();131 ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);132 WriteError(er);133 return;134 }135 136 string inputXml = @"<cfg:Auth xmlns:cfg=""http://schemas.microsoft.com/wbem/wsman/1/config/client/auth""><cfg:CredSSP>false</cfg:CredSSP></cfg:Auth>";137 138 m_SessionObj.Put(helper.CredSSP_RUri, inputXml, 0);139 140 if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)141 {142 this.DeleteUserDelegateSettings();143 }144 else145 {146 ThreadStart start = new ThreadStart(this.DeleteUserDelegateSettings);147 Thread thread = new Thread(start);148 thread.SetApartmentState(ApartmentState.STA);149 thread.Start();150 thread.Join();151 }152 153 if (!helper.ValidateCreadSSPRegistryRetry(false, null, applicationname))154 {155 helper.AssertError(helper.GetResourceMsgFromResourcetext("DisableCredSSPPolicyValidateError"), false, null);156 }157 }158 catch (System.Xml.XPath.XPathException ex)159 {160 ErrorRecord er = new ErrorRecord(ex, "XpathException", ErrorCategory.InvalidOperation, null);161 WriteError(er);162 }163 finally164 {165 if (!string.IsNullOrEmpty(m_SessionObj.Error))166 {167 helper.AssertError(m_SessionObj.Error, true, null);168 }169 170 if (m_SessionObj != null)171 Dispose(m_SessionObj);172 }173 }174 175 private void DisableServerSideSettings()176 {177 WSManHelper helper = new WSManHelper(this);178 IWSManSession m_SessionObj = CreateWSManSession();179 if (m_SessionObj == null)180 {181 return;182 }183 184 try185 {186 string result = m_SessionObj.Get(helper.Service_CredSSP_Uri, 0);187 XmlDocument resultopxml = new XmlDocument();188 resultopxml.LoadXml(result);189 190 XmlNamespaceManager nsmgr = new XmlNamespaceManager(resultopxml.NameTable);191 nsmgr.AddNamespace("cfg", helper.Service_CredSSP_XMLNmsp);192 XmlNode xNode = resultopxml.SelectSingleNode(helper.CredSSP_SNode, nsmgr);193 if (xNode is null)194 {195 InvalidOperationException ex = new InvalidOperationException();196 ErrorRecord er = new ErrorRecord(ex,197 helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"),198 ErrorCategory.InvalidOperation, null);199 WriteError(er);200 return;201 }202 203 string inputXml = string.Format(204 CultureInfo.InvariantCulture,205 @"<cfg:Auth xmlns:cfg=""{0}""><cfg:CredSSP>false</cfg:CredSSP></cfg:Auth>",206 helper.Service_CredSSP_XMLNmsp);207 208 m_SessionObj.Put(helper.Service_CredSSP_Uri, inputXml, 0);209 }210 finally211 {212 if (!string.IsNullOrEmpty(m_SessionObj.Error))213 {214 helper.AssertError(m_SessionObj.Error, true, null);215 }216 217 if (m_SessionObj != null)218 {219 Dispose(m_SessionObj);220 }221 }222 }223 224 private void DeleteUserDelegateSettings()225 {226 System.IntPtr KeyHandle = System.IntPtr.Zero;227 IGroupPolicyObject GPO = (IGroupPolicyObject)new GPClass();228 GPO.OpenLocalMachineGPO(1);229 KeyHandle = GPO.GetRegistryKey(2);230 RegistryKey rootKey = Registry.CurrentUser;231 const string GPOpath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy Objects";232 RegistryKey GPOKey = rootKey.OpenSubKey(GPOpath, true);233 foreach (string keyname in GPOKey.GetSubKeyNames())234 {235 if (keyname.EndsWith("Machine", StringComparison.OrdinalIgnoreCase))236 {237 string key = GPOpath + "\\" + keyname + "\\" + @"Software\Policies\Microsoft\Windows";238 DeleteDelegateSettings(applicationname, Registry.CurrentUser, key, GPO);239 }240 }241 242 KeyHandle = System.IntPtr.Zero;243 }244 245 private void DeleteDelegateSettings(string applicationname, RegistryKey rootKey, string Registry_Path, IGroupPolicyObject GPO)246 {247 WSManHelper helper = new WSManHelper(this);248 RegistryKey rKey;249 int i = 0;250 bool otherkeys = false;251 try252 {253 string Registry_Path_Credentials_Delegation = Registry_Path + @"\CredentialsDelegation";254 RegistryKey Allow_Fresh_Credential_Key = rootKey.OpenSubKey(Registry_Path_Credentials_Delegation + @"\" + helper.Key_Allow_Fresh_Credentials, true);255 if (Allow_Fresh_Credential_Key != null)256 {257 string[] valuenames = Allow_Fresh_Credential_Key.GetValueNames();258 if (valuenames.Length > 0)259 {260 Collection<string> KeyCollection = new Collection<string>();261 foreach (string value in valuenames)262 {263 object keyvalue = Allow_Fresh_Credential_Key.GetValue(value);264 if (keyvalue != null)265 {266 if (!keyvalue.ToString().StartsWith(applicationname, StringComparison.OrdinalIgnoreCase))267 {268 KeyCollection.Add(keyvalue.ToString());269 otherkeys = true;270 }271 }272 273 Allow_Fresh_Credential_Key.DeleteValue(value);274 }275 276 foreach (string keyvalue in KeyCollection)277 {278 Allow_Fresh_Credential_Key.SetValue(Convert.ToString(i + 1, CultureInfo.InvariantCulture), keyvalue, RegistryValueKind.String);279 i++;280 }281 }282 }283 284 if (!otherkeys)285 {286 rKey = rootKey.OpenSubKey(Registry_Path_Credentials_Delegation, true);287 if (rKey != null)288 {289 object regval1 = rKey.GetValue(helper.Key_Allow_Fresh_Credentials);290 if (regval1 != null)291 {292 rKey.DeleteValue(helper.Key_Allow_Fresh_Credentials, false);293 }294 295 object regval2 = rKey.GetValue(helper.Key_Concatenate_Defaults_AllowFresh);296 if (regval2 != null)297 {298 rKey.DeleteValue(helper.Key_Concatenate_Defaults_AllowFresh, false);299 }300 301 if (rKey.OpenSubKey(helper.Key_Allow_Fresh_Credentials) != null)302 {303 rKey.DeleteSubKeyTree(helper.Key_Allow_Fresh_Credentials);304 }305 }306 }307 308 GPO.Save(true, true, new Guid("35378EAC-683F-11D2-A89A-00C04FBBCFA2"), new Guid("6AD20875-336C-4e22-968F-C709ACB15814"));309 }310 catch (InvalidOperationException ex)311 {312 ErrorRecord er = new ErrorRecord(ex, "InvalidOperation", ErrorCategory.InvalidOperation, null);313 WriteError(er);314 }315 catch (ArgumentException ex)316 {317 ErrorRecord er = new ErrorRecord(ex, "InvalidArgument", ErrorCategory.InvalidArgument, null);318 WriteError(er);319 }320 catch (SecurityException ex)321 {322 ErrorRecord er = new ErrorRecord(ex, "SecurityException", ErrorCategory.SecurityError, null);323 WriteError(er);324 }325 catch (UnauthorizedAccessException ex)326 {327 ErrorRecord er = new ErrorRecord(ex, "UnauthorizedAccess", ErrorCategory.SecurityError, null);328 WriteError(er);329 }330 }331 #endregion private332 /// <summary>333 /// Begin processing method.334 /// </summary>335 protected override void BeginProcessing()336 {337 // If not running elevated, then throw an "elevation required" error message.338 WSManHelper.ThrowIfNotAdministrator();339 340 if (Role.Equals(Client, StringComparison.OrdinalIgnoreCase))341 {342 DisableClientSideSettings();343 }344 345 if (Role.Equals(Server, StringComparison.OrdinalIgnoreCase))346 {347 DisableServerSideSettings();348 }349 }350 351 #region IDisposable Members352 353 /// <summary>354 /// Public dispose method.355 /// </summary>356 public357 void358 Dispose()359 {360 // CleanUp();361 GC.SuppressFinalize(this);362 }363 /// <summary>364 /// Public dispose method.365 /// </summary>366 public367 void368 Dispose(IWSManSession sessionObject)369 {370 sessionObject = null;371 this.Dispose();372 }373 374 #endregion IDisposable Members375 }376 #endregion DisableWsManCredSSP377 378 #region EnableCredSSP379 /// <summary>380 /// Enables CredSSP authentication on the client. CredSSP authentication enables381 /// an application to delegate the user's credentials from the client to the382 /// server, hence allowing the user to perform management operations that access383 /// a second hop.384 /// This cmdlet performs the following:385 ///386 /// On the client:387 /// 1. Enables WSMan local configuration on client to enable CredSSP388 /// 2. Sets CredSSP policy AllowFreshCredentials to wsman/Delegate. This policy389 /// allows delegating explicit credentials to a server when server390 /// authentication is achieved via a trusted X509 certificate or Kerberos.391 /// </summary>392 [Cmdlet(VerbsLifecycle.Enable, "WSManCredSSP", HelpUri = "https://go.microsoft.com/fwlink/?LinkId=2096719")]393 [OutputType(typeof(XmlElement))]394 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")]395 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SSP")]396 public class EnableWSManCredSSPCommand : WSManCredSSPCommandBase, IDisposable/*, IDynamicParameters*/397 {398 /// <summary>399 /// Delegate parameter.400 /// </summary>401 [Parameter(Position = 1)]402 [ValidateNotNullOrEmpty]403 [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]404 public string[] DelegateComputer405 {406 get { return delegatecomputer; }407 408 set { delegatecomputer = value; }409 }410 411 private string[] delegatecomputer;412 413 /// <summary>414 /// Property that sets force parameter.415 /// </summary>416 [Parameter]417 public SwitchParameter Force418 {419 get { return force; }420 421 set { force = value; }422 }423 424 private bool force = false;425 426 // helper variable427 private WSManHelper helper;428 429 // The application name MUST be "wsman" as wsman got approval from security430 // folks who suggested to register the SPN with name "wsman".431 private const string applicationname = "wsman";432 433 #region Cmdlet Overloads434 435 /// <summary>436 /// BeginProcessing method.437 /// </summary>438 protected override void BeginProcessing()439 {440 // If not running elevated, then throw an "elevation required" error message.441 WSManHelper.ThrowIfNotAdministrator();442 helper = new WSManHelper(this);443 444 // DelegateComputer cannot be specified when Role is other than client445 if ((delegatecomputer != null) && !Role.Equals(Client, StringComparison.OrdinalIgnoreCase))446 {447 string message = helper.FormatResourceMsgFromResourcetext("CredSSPRoleAndDelegateCannotBeSpecified",448 "DelegateComputer",449 "Role",450 Role,451 Client);452 453 throw new InvalidOperationException(message);454 }455 456 // DelegateComputer must be specified when Role is client457 if (Role.Equals(Client, StringComparison.OrdinalIgnoreCase) && (delegatecomputer == null))458 {459 string message = helper.FormatResourceMsgFromResourcetext("CredSSPClientAndDelegateMustBeSpecified",460 "DelegateComputer",461 "Role",462 Client);463 464 throw new InvalidOperationException(message);465 }466 467 if (Role.Equals(Client, StringComparison.OrdinalIgnoreCase))468 {469 EnableClientSideSettings();470 }471 472 if (Role.Equals(Server, StringComparison.OrdinalIgnoreCase))473 {474 EnableServerSideSettings();475 }476 }477 478 #endregion479 480 /// <summary>481 /// </summary>482 /// <exception cref="InvalidOperationException">483 /// </exception>484 private void EnableClientSideSettings()485 {486 string query = helper.GetResourceMsgFromResourcetext("CredSSPContinueQuery");487 string caption = helper.GetResourceMsgFromResourcetext("CredSSPContinueCaption");488 if (!force && !ShouldContinue(query, caption))489 {490 return;491 }492 493 IWSManSession m_SessionObj = CreateWSManSession();494 if (m_SessionObj == null)495 {496 return;497 }498 499 try500 {501 // get the credssp node to check if wsman is configured on this machine502 string result = m_SessionObj.Get(helper.CredSSP_RUri, 0);503 XmlNode node = helper.GetXmlNode(result, helper.CredSSP_SNode, helper.CredSSP_XMLNmsp);504 505 if (node == null)506 {507 InvalidOperationException ex = new InvalidOperationException();508 ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);509 WriteError(er);510 return;511 }512 513 const string newxmlcontent = @"<cfg:Auth xmlns:cfg=""http://schemas.microsoft.com/wbem/wsman/1/config/client/auth""><cfg:CredSSP>true</cfg:CredSSP></cfg:Auth>";514 try515 {516 XmlDocument xmldoc = new XmlDocument();517 518 // push the xml string with credssp enabled519 xmldoc.LoadXml(m_SessionObj.Put(helper.CredSSP_RUri, newxmlcontent, 0));520 521 // set the Registry using GroupPolicyObject522 if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)523 {524 this.UpdateCurrentUserRegistrySettings();525 }526 else527 {528 ThreadStart start = new ThreadStart(this.UpdateCurrentUserRegistrySettings);529 Thread thread = new Thread(start);530 thread.SetApartmentState(ApartmentState.STA);531 thread.Start();532 thread.Join();533 }534 535 if (helper.ValidateCreadSSPRegistryRetry(true, delegatecomputer, applicationname))536 {537 WriteObject(xmldoc.FirstChild);538 }539 else540 {541 helper.AssertError(helper.GetResourceMsgFromResourcetext("EnableCredSSPPolicyValidateError"), false, delegatecomputer);542 }543 }544 catch (COMException)545 {546 helper.AssertError(m_SessionObj.Error, true, delegatecomputer);547 }548 }549 finally550 {551 if (!string.IsNullOrEmpty(m_SessionObj.Error))552 {553 helper.AssertError(m_SessionObj.Error, true, delegatecomputer);554 }555 556 if (m_SessionObj != null)557 {558 Dispose(m_SessionObj);559 }560 }561 }562 563 private void EnableServerSideSettings()564 {565 string query = helper.GetResourceMsgFromResourcetext("CredSSPServerContinueQuery");566 string caption = helper.GetResourceMsgFromResourcetext("CredSSPContinueCaption");567 if (!force && !ShouldContinue(query, caption))568 {569 return;570 }571 572 IWSManSession m_SessionObj = CreateWSManSession();573 if (m_SessionObj == null)574 {575 return;576 }577 578 try579 {580 // get the credssp node to check if wsman is configured on this machine581 string result = m_SessionObj.Get(helper.Service_CredSSP_Uri, 0);582 XmlNode node = helper.GetXmlNode(result,583 helper.CredSSP_SNode,584 helper.Service_CredSSP_XMLNmsp);585 586 if (node == null)587 {588 InvalidOperationException ex = new InvalidOperationException();589 ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);590 WriteError(er);591 return;592 }593 594 try595 {596 XmlDocument xmldoc = new XmlDocument();597 string newxmlcontent = string.Format(598 CultureInfo.InvariantCulture,599 @"<cfg:Auth xmlns:cfg=""{0}""><cfg:CredSSP>true</cfg:CredSSP></cfg:Auth>",600 helper.Service_CredSSP_XMLNmsp);601 602 // push the xml string with credssp enabled603 xmldoc.LoadXml(m_SessionObj.Put(helper.Service_CredSSP_Uri, newxmlcontent, 0));604 WriteObject(xmldoc.FirstChild);605 }606 catch (COMException)607 {608 helper.AssertError(m_SessionObj.Error, true, delegatecomputer);609 }610 }611 finally612 {613 if (!string.IsNullOrEmpty(m_SessionObj.Error))614 {615 helper.AssertError(m_SessionObj.Error, true, delegatecomputer);616 }617 618 if (m_SessionObj != null)619 {620 Dispose(m_SessionObj);621 }622 }623 }624 625 /// <summary>626 /// </summary>627 private void UpdateCurrentUserRegistrySettings()628 {629 System.IntPtr KeyHandle = System.IntPtr.Zero;630 IGroupPolicyObject GPO = (IGroupPolicyObject)new GPClass();631 GPO.OpenLocalMachineGPO(1);632 KeyHandle = GPO.GetRegistryKey(2);633 RegistryKey rootKey = Registry.CurrentUser;634 const string GPOpath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy Objects";635 RegistryKey GPOKey = rootKey.OpenSubKey(GPOpath, true);636 foreach (string keyname in GPOKey.GetSubKeyNames())637 {638 if (keyname.EndsWith("Machine", StringComparison.OrdinalIgnoreCase))639 {640 string key = GPOpath + "\\" + keyname + "\\" + @"Software\Policies\Microsoft\Windows";641 UpdateGPORegistrySettings(applicationname, this.delegatecomputer, Registry.CurrentUser, key);642 }643 }644 // saving gpo settings645 GPO.Save(true, true, new Guid("35378EAC-683F-11D2-A89A-00C04FBBCFA2"), new Guid("7A9206BD-33AF-47af-B832-D4128730E990"));646 }647 648 /// <summary>649 /// Updates the grouppolicy registry settings.650 /// </summary>651 /// <param name="applicationname"></param>652 /// <param name="delegatestring"></param>653 /// <param name="rootKey"></param>654 /// <param name="Registry_Path"></param>655 private void UpdateGPORegistrySettings(string applicationname, string[] delegatestring, RegistryKey rootKey, string Registry_Path)656 {657 // RegistryKey rootKey = Registry.LocalMachine;658 RegistryKey Credential_Delegation_Key;659 RegistryKey Allow_Fresh_Credential_Key;660 int i = 0;661 try662 {663 string Registry_Path_Credentials_Delegation = Registry_Path + @"\CredentialsDelegation";664 // open the registry key.If key is not present,create a new one665 Credential_Delegation_Key = rootKey.OpenSubKey(Registry_Path_Credentials_Delegation, true) ?? rootKey.CreateSubKey(Registry_Path_Credentials_Delegation, RegistryKeyPermissionCheck.ReadWriteSubTree);666 667 Credential_Delegation_Key.SetValue(helper.Key_Allow_Fresh_Credentials, 1, RegistryValueKind.DWord);668 Credential_Delegation_Key.SetValue(helper.Key_Concatenate_Defaults_AllowFresh, 1, RegistryValueKind.DWord);669 670 // add the delegate value671 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);672 673 if (Allow_Fresh_Credential_Key != null)674 {675 i = Allow_Fresh_Credential_Key.ValueCount;676 foreach (string del in delegatestring)677 {678 Allow_Fresh_Credential_Key.SetValue(Convert.ToString(i + 1, CultureInfo.InvariantCulture), applicationname + @"/" + del, RegistryValueKind.String);679 i++;680 }681 }682 }683 catch (UnauthorizedAccessException ex)684 {685 ErrorRecord er = new ErrorRecord(ex, "UnauthorizedAccessException", ErrorCategory.PermissionDenied, null);686 WriteError(er);687 }688 catch (SecurityException ex)689 {690 ErrorRecord er = new ErrorRecord(ex, "SecurityException", ErrorCategory.InvalidOperation, null);691 WriteError(er);692 }693 catch (ArgumentException ex)694 {695 ErrorRecord er = new ErrorRecord(ex, "ArgumentException", ErrorCategory.InvalidOperation, null);696 WriteError(er);697 }698 }699 700 #region IDisposable Members701 702 /// <summary>703 /// Public dispose method.704 /// </summary>705 public706 void707 Dispose()708 {709 GC.SuppressFinalize(this);710 }711 /// <summary>712 /// Public dispose method.713 /// </summary>714 public715 void716 Dispose(IWSManSession sessionObject)717 {718 sessionObject = null;719 this.Dispose();720 }721 722 #endregion IDisposable Members723 }724 #endregion EnableCredSSP725 726 #region Get-CredSSP727 728 /// <summary>729 /// Gets the CredSSP related configuration on the client. CredSSP authentication730 /// enables an application to delegate the user's credentials from the client to731 /// the server, hence allowing the user to perform management operations that732 /// access a second hop.733 /// This cmdlet performs the following:734 /// 1. Gets the configuration for WSMan policy on client to enable/disable735 /// CredSSP736 /// 2. Gets the configuration information for the CredSSP policy737 /// AllowFreshCredentials . This policy allows delegating explicit credentials738 /// to a server when server authentication is achieved via a trusted X509739 /// certificate or Kerberos.740 /// </summary>741 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")]742 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SSP")]743 [Cmdlet(VerbsCommon.Get, "WSManCredSSP", HelpUri = "https://go.microsoft.com/fwlink/?LinkId=2096838")]744 [OutputType(typeof(string))]745 public class GetWSManCredSSPCommand : PSCmdlet, IDisposable746 {747 #region private748 private WSManHelper helper = null;749 /// <summary>750 /// Method to get the values.751 /// </summary>752 private string GetDelegateSettings(string applicationname)753 {754 RegistryKey rootKey = Registry.LocalMachine;755 RegistryKey rKey;756 string result = string.Empty;757 string[] valuenames = null;758 try759 {760 string Reg_key = helper.Registry_Path_Credentials_Delegation + @"\CredentialsDelegation";761 rKey = rootKey.OpenSubKey(Reg_key);762 if (rKey != null)763 {764 rKey = rKey.OpenSubKey(helper.Key_Allow_Fresh_Credentials);765 if (rKey != null)766 {767 valuenames = rKey.GetValueNames();768 if (valuenames.Length > 0)769 {770 string listvalue = CultureInfo.CurrentCulture.TextInfo.ListSeparator;771 foreach (string value in valuenames)772 {773 object keyvalue = rKey.GetValue(value);774 if (keyvalue != null)775 {776 if (keyvalue.ToString().StartsWith(applicationname, StringComparison.OrdinalIgnoreCase))777 {778 result = keyvalue.ToString() + listvalue + result;779 }780 }781 }782 783 if (result.EndsWith(listvalue, StringComparison.OrdinalIgnoreCase))784 {785 result = result.Remove(result.Length - 1);786 }787 }788 }789 }790 }791 catch (ArgumentException ex)792 {793 ErrorRecord er = new ErrorRecord(ex, "ArgumentException", ErrorCategory.PermissionDenied, null);794 WriteError(er);795 }796 catch (SecurityException ex)797 {798 ErrorRecord er = new ErrorRecord(ex, "SecurityException", ErrorCategory.PermissionDenied, null);799 WriteError(er);800 }801 catch (ObjectDisposedException ex)802 {803 ErrorRecord er = new ErrorRecord(ex, "ObjectDisposedException", ErrorCategory.PermissionDenied, null);804 WriteError(er);805 }806 807 return result;808 }809 #endregion private810 811 #region overrides812 /// <summary>813 /// Method to begin processing.814 /// </summary>815 protected override void BeginProcessing()816 {817 // If not running elevated, then throw an "elevation required" error message.818 WSManHelper.ThrowIfNotAdministrator();819 helper = new WSManHelper(this);820 IWSManSession m_SessionObj = null;821 try822 {823 IWSManEx wsmanObject = (IWSManEx)new WSManClass();824 m_SessionObj = (IWSManSession)wsmanObject.CreateSession(null, 0, null);825 string result = m_SessionObj.Get(helper.CredSSP_RUri, 0);826 XmlNode node = helper.GetXmlNode(result, helper.CredSSP_SNode, helper.CredSSP_XMLNmsp);827 if (node == null)828 {829 InvalidOperationException ex = new InvalidOperationException();830 ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);831 WriteError(er);832 return;833 }834 // The application name MUST be "wsman" as wsman got approval from security835 // folks who suggested to register the SPN with name "wsman".836 const string applicationname = "wsman";837 string credsspResult = GetDelegateSettings(applicationname);838 if (string.IsNullOrEmpty(credsspResult))839 {840 WriteObject(helper.GetResourceMsgFromResourcetext("NoDelegateFreshCred"));841 }842 else843 {844 WriteObject(helper.GetResourceMsgFromResourcetext("DelegateFreshCred") + credsspResult);845 }846 847 // Get the server side settings848 result = m_SessionObj.Get(helper.Service_CredSSP_Uri, 0);849 node = helper.GetXmlNode(result, helper.CredSSP_SNode, helper.Service_CredSSP_XMLNmsp);850 if (node == null)851 {852 InvalidOperationException ex = new InvalidOperationException();853 ErrorRecord er = new ErrorRecord(ex, helper.GetResourceMsgFromResourcetext("WinrmNotConfigured"), ErrorCategory.InvalidOperation, null);854 WriteError(er);855 return;856 }857 858 if (node.InnerText.Equals("true", StringComparison.OrdinalIgnoreCase))859 {860 WriteObject(helper.GetResourceMsgFromResourcetext("CredSSPServiceConfigured"));861 }862 else863 {864 WriteObject(helper.GetResourceMsgFromResourcetext("CredSSPServiceNotConfigured"));865 }866 }867 catch (UnauthorizedAccessException ex)868 {869 ErrorRecord er = new ErrorRecord(ex, "UnauthorizedAccess", ErrorCategory.PermissionDenied, null);870 WriteError(er);871 }872 catch (SecurityException ex)873 {874 ErrorRecord er = new ErrorRecord(ex, "SecurityException", ErrorCategory.InvalidOperation, null);875 WriteError(er);876 }877 catch (ArgumentException ex)878 {879 ErrorRecord er = new ErrorRecord(ex, "InvalidArgument", ErrorCategory.InvalidOperation, null);880 WriteError(er);881 }882 catch (System.Xml.XPath.XPathException ex)883 {884 ErrorRecord er = new ErrorRecord(ex, "XPathException", ErrorCategory.InvalidOperation, null);885 WriteError(er);886 }887 finally888 {889 if (!string.IsNullOrEmpty(m_SessionObj.Error))890 {891 helper.AssertError(m_SessionObj.Error, true, null);892 }893 894 if (m_SessionObj != null)895 {896 Dispose(m_SessionObj);897 }898 }899 }900 #endregion overrides901 #region IDisposable Members902 903 /// <summary>904 /// Public dispose method.905 /// </summary>906 public907 void908 Dispose()909 {910 GC.SuppressFinalize(this);911 }912 /// <summary>913 /// Public dispose method.914 /// </summary>915 public916 void917 Dispose(IWSManSession sessionObject)918 {919 sessionObject = null;920 this.Dispose();921 }922 923 #endregion IDisposable Members924 }925 926 #endregion927}928 