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.Diagnostics.CodeAnalysis;8using System.Globalization;9using System.IO;10using System.Management.Automation;11using System.Management.Automation.Provider;12using System.Reflection;13using System.Resources;14using System.Runtime.InteropServices;15using System.Text;16using System.Text.RegularExpressions;17using System.Threading;18using System.Xml;19 20using Microsoft.Win32;21 22namespace Microsoft.WSMan.Management23{24 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#")]25 internal sealed class WSManHelper26 {27 // regular expressions28 private const string PTRN_URI_LAST = @"([a-z_][-a-z0-9._]*)$";29 private const string PTRN_OPT = @"^-([a-z]+):(.*)";30 private const string PTRN_HASH_TOK = @"\s*([\w:]+)\s*=\s*(\$null|""([^""]*)"")\s*";31 32 // schemas33 private const string URI_IPMI = @"http://schemas.dmtf.org/wbem/wscim/1/cim-schema";34 private const string URI_WMI = @"http://schemas.microsoft.com/wbem/wsman/1/wmi";35 private const string NS_IPMI = @"http://schemas.dmtf.org/wbem/wscim/1/cim-schema";36 private const string NS_CIMBASE = @"http://schemas.dmtf.org/wbem/wsman/1/base";37 private const string NS_WSMANL = @"http://schemas.microsoft.com";38 private const string NS_XSI = @"xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""";39 private const string ATTR_NIL = @"xsi:nil=""true""";40 private const string ATTR_NIL_NAME = @"xsi:nil";41 private const string NS_XSI_URI = @"http://www.w3.org/2001/XMLSchema-instance";42 private const string ALIAS_XPATH = @"xpath";43 private const string URI_XPATH_DIALECT = @"http://www.w3.org/TR/1999/REC-xpath-19991116";44 45 // credSSP strings46 internal string CredSSP_RUri = "winrm/config/client/auth";47 internal string CredSSP_XMLNmsp = "http://schemas.microsoft.com/wbem/wsman/1/config/client/auth";48 internal string CredSSP_SNode = "/cfg:Auth/cfg:CredSSP";49 internal string Client_uri = "winrm/config/client";50 internal string urlprefix_node = "/cfg:Client/cfg:URLPrefix";51 internal string Client_XMLNmsp = "http://schemas.microsoft.com/wbem/wsman/1/config/client";52 53 internal string Service_Uri = "winrm/config/service";54 internal string Service_UrlPrefix_Node = "/cfg:Service/cfg:URLPrefix";55 internal string Service_XMLNmsp = "http://schemas.microsoft.com/wbem/wsman/1/config/service";56 internal string Service_CredSSP_Uri = "winrm/config/service/auth";57 internal string Service_CredSSP_XMLNmsp = "http://schemas.microsoft.com/wbem/wsman/1/config/service/auth";58 59 // gpo registry path and keys60 internal string Registry_Path_Credentials_Delegation = @"SOFTWARE\Policies\Microsoft\Windows";61 internal string Key_Allow_Fresh_Credentials = "AllowFreshCredentials";62 internal string Key_Concatenate_Defaults_AllowFresh = "ConcatenateDefaults_AllowFresh";63 internal string Delegate = "delegate";64 internal string keyAllowcredssp = "AllowCredSSP";65 66 // 'Constants for MS-XML67 private const string NODE_ATTRIBUTE = "2";68 private const int NODE_TEXT = 3;69 70 // strings for dialects71 internal string ALIAS_WQL = @"wql";72 internal string ALIAS_ASSOCIATION = @"association";73 internal string ALIAS_SELECTOR = @"selector";74 internal string URI_WQL_DIALECT = @"http://schemas.microsoft.com/wbem/wsman/1/WQL";75 internal string URI_SELECTOR_DIALECT = @"http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter";76 internal string URI_ASSOCIATION_DIALECT = @" http://schemas.dmtf.org/wbem/wsman/1/cimbinding/associationFilter";77 78 // string for operation79 internal string WSManOp = null;80 81 private readonly PSCmdlet cmdletname;82 private readonly NavigationCmdletProvider _provider;83 84 private FileStream _fs;85 private StreamReader _sr;86 87 private static readonly ResourceManager _resourceMgr = new ResourceManager("Microsoft.WSMan.Management.resources.WsManResources", typeof(WSManHelper).GetTypeInfo().Assembly);88 89 //90 //91 // Below class is just a static container which would release sessions in case this DLL is unloaded.92 internal sealed class Sessions93 {94 /// <summary>95 /// Dictionary object to store the connection.96 /// </summary>97 internal static readonly Dictionary<string, object> SessionObjCache = new Dictionary<string, object>();98 99 ~Sessions()100 {101 ReleaseSessions();102 }103 }104 105 internal static readonly Sessions AutoSession = new Sessions();106 //107 //108 //109 110 internal static void ReleaseSessions()111 {112 lock (Sessions.SessionObjCache)113 {114 object sessionobj;115 foreach (string key in Sessions.SessionObjCache.Keys)116 {117 Sessions.SessionObjCache.TryGetValue(key, out sessionobj);118 try119 {120 Marshal.ReleaseComObject(sessionobj);121 }122 catch (ArgumentException)123 {124 // Somehow the object was a null reference. Ignore the error125 }126 127 sessionobj = null;128 }129 130 Sessions.SessionObjCache.Clear();131 }132 }133 134 internal WSManHelper()135 {136 }137 138 internal WSManHelper(PSCmdlet cmdlet)139 {140 cmdletname = cmdlet;141 }142 143 internal WSManHelper(NavigationCmdletProvider provider)144 {145 _provider = provider;146 }147 148 internal static void ThrowIfNotAdministrator()149 {150 System.Security.Principal.WindowsIdentity currentIdentity = System.Security.Principal.WindowsIdentity.GetCurrent();151 System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(currentIdentity);152 if (!principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))153 {154 string message = _resourceMgr.GetString("ErrorElevationNeeded");155 throw new InvalidOperationException(message);156 }157 }158 159 internal string GetResourceMsgFromResourcetext(string rscname)160 {161 return _resourceMgr.GetString(rscname);162 }163 164 internal static string FormatResourceMsgFromResourcetextS(string rscname,165 params object[] args)166 {167 return FormatResourceMsgFromResourcetextS(_resourceMgr, rscname, args);168 }169 170 internal string FormatResourceMsgFromResourcetext(string resourceName,171 params object[] args)172 {173 return FormatResourceMsgFromResourcetextS(_resourceMgr, resourceName, args);174 }175 176 private static string FormatResourceMsgFromResourcetextS(177 ResourceManager resourceManager,178 string resourceName,179 object[] args)180 {181 ArgumentNullException.ThrowIfNull(resourceManager);182 ArgumentException.ThrowIfNullOrEmpty(resourceName);183 184 string template = resourceManager.GetString(resourceName);185 186 string result = null;187 if (template != null)188 {189 result = string.Format(CultureInfo.CurrentCulture,190 template, args);191 }192 193 return result;194 }195 196 /// <summary>197 /// Add a session to dictionary.198 /// </summary>199 /// <param name="key">Connection string.</param>200 /// <param name="value">Session object.</param>201 internal void AddtoDictionary(string key, object value)202 {203 key = key.ToLowerInvariant();204 lock (Sessions.SessionObjCache)205 {206 if (!Sessions.SessionObjCache.ContainsKey(key))207 {208 Sessions.SessionObjCache.Add(key, value);209 }210 else211 {212 object objsession = null;213 Sessions.SessionObjCache.TryGetValue(key, out objsession);214 try215 {216 Marshal.ReleaseComObject(objsession);217 }218 catch (ArgumentException)219 {220 // Somehow the object was a null reference. Ignore the error221 }222 223 Sessions.SessionObjCache.Remove(key);224 Sessions.SessionObjCache.Add(key, value);225 }226 }227 }228 229 internal object RemoveFromDictionary(string computer)230 {231 object objsession = null;232 computer = computer.ToLowerInvariant();233 lock (Sessions.SessionObjCache)234 {235 if (Sessions.SessionObjCache.ContainsKey(computer))236 {237 Sessions.SessionObjCache.TryGetValue(computer, out objsession);238 try239 {240 Marshal.ReleaseComObject(objsession);241 }242 catch (ArgumentException)243 {244 // Somehow the object was a null reference. Ignore the error245 }246 247 Sessions.SessionObjCache.Remove(computer);248 }249 }250 251 return objsession;252 }253 254 internal static Dictionary<string, object> GetSessionObjCache()255 {256 try257 {258 lock (Sessions.SessionObjCache)259 {260 if (!Sessions.SessionObjCache.ContainsKey("localhost"))261 {262 IWSManEx wsmanObject = (IWSManEx)new WSManClass();263 IWSManSession SessionObj = (IWSManSession)wsmanObject.CreateSession(null, 0, null);264 Sessions.SessionObjCache.Add("localhost", SessionObj);265 }266 }267 }268 catch (IOException)269 {270 }271 catch (System.Security.SecurityException)272 {273 }274 catch (System.UnauthorizedAccessException)275 {276 }277 catch (COMException)278 {279 }280 281 return Sessions.SessionObjCache;282 }283 284 internal string GetRootNodeName(string operation, string resourceUri, string actionStr)285 {286 string resultStr = null, sfx = null;287 if (resourceUri != null)288 {289 resultStr = resourceUri;290 resultStr = StripParams(resultStr);291 292 Regex regexpr = new Regex(PTRN_URI_LAST, RegexOptions.IgnoreCase);293 MatchCollection matches = regexpr.Matches(resultStr);294 if (matches.Count > 0)295 {296 if (operation.Equals("invoke", StringComparison.OrdinalIgnoreCase))297 {298 sfx = "_INPUT";299 resultStr = string.Concat(actionStr, sfx);300 }301 else302 {303 resultStr = matches[0].ToString();304 }305 }306 else307 {308 // error309 }310 }311 312 return resultStr;313 }314 315 internal string StripParams(string uri)316 {317 int pos = uri.IndexOf('?');318 if (pos > 0)319 return uri.Substring(pos, uri.Length - pos);320 else321 return uri;322 }323 324 internal string ReadFile(string path)325 {326 if (!File.Exists(path))327 {328 throw new ArgumentException(GetResourceMsgFromResourcetext("InvalidFileName"));329 }330 331 string strOut = null;332 try333 {334 _fs = new FileStream(path, FileMode.Open, FileAccess.Read);335 // create stream Reader336 _sr = new StreamReader(_fs);337 strOut = _sr.ReadToEnd();338 }339 catch (ArgumentNullException e)340 {341 ErrorRecord er = new ErrorRecord(e, "ArgumentNullException", ErrorCategory.InvalidArgument, null);342 cmdletname.ThrowTerminatingError(er);343 }344 catch (UnauthorizedAccessException e)345 {346 ErrorRecord er = new ErrorRecord(e, "UnauthorizedAccessException", ErrorCategory.PermissionDenied, null);347 cmdletname.ThrowTerminatingError(er);348 }349 catch (FileNotFoundException e)350 {351 ErrorRecord er = new ErrorRecord(e, "FileNotFoundException", ErrorCategory.ObjectNotFound, null);352 cmdletname.ThrowTerminatingError(er);353 }354 catch (DirectoryNotFoundException e)355 {356 ErrorRecord er = new ErrorRecord(e, "DirectoryNotFoundException", ErrorCategory.ObjectNotFound, null);357 cmdletname.ThrowTerminatingError(er);358 }359 catch (System.Security.SecurityException e)360 {361 ErrorRecord er = new ErrorRecord(e, "SecurityException", ErrorCategory.SecurityError, null);362 cmdletname.ThrowTerminatingError(er);363 }364 finally365 {366 _sr?.Dispose();367 _fs?.Dispose();368 }369 370 return strOut;371 }372 373 internal string ProcessInput(IWSManEx wsman, string filepath, string operation, string root, Hashtable valueset, IWSManResourceLocator resourceUri, IWSManSession sessionObj)374 {375 string resultString = null;376 377 // if file path is given378 if (!string.IsNullOrEmpty(filepath) && valueset == null)379 {380 if (!File.Exists(filepath))381 {382 throw new FileNotFoundException(_resourceMgr.GetString("InvalidFileName"));383 }384 385 resultString = ReadFile(filepath);386 return resultString;387 }388 389 switch (operation)390 {391 case "new":392 case "invoke":393 394 string parameters = null, nilns = null;395 string xmlns = GetXmlNs(resourceUri.ResourceUri);396 397 // if valueset is given, i.e hashtable398 if (valueset != null)399 {400 foreach (DictionaryEntry entry in valueset)401 {402 parameters = parameters + "<p:" + entry.Key.ToString();403 if (entry.Value.ToString() == null)404 {405 parameters = parameters + " " + ATTR_NIL;406 nilns = " " + NS_XSI;407 }408 409 parameters = parameters + ">" + entry.Value.ToString() + "</p:" + entry.Key.ToString() + ">";410 }411 }412 413 resultString = "<p:" + root + " " + xmlns + nilns + ">" + parameters + "</p:" + root + ">";414 415 break;416 case "set":417 418 string getResult = sessionObj.Get(resourceUri, 0);419 XmlDocument xmlfile = new XmlDocument();420 xmlfile.LoadXml(getResult);421 422 string xpathString = null;423 if (valueset != null)424 {425 foreach (DictionaryEntry entry in valueset)426 {427 xpathString = @"/*/*[local-name()=""" + entry.Key + @"""]";428 if (entry.Key.ToString().Equals("location", StringComparison.OrdinalIgnoreCase))429 {430 // 'Ignore cim:Location431 xpathString = @"/*/*[local-name()=""" + entry.Key + @""" and namespace-uri() != """ + NS_CIMBASE + @"""]";432 }433 434 XmlNodeList nodes = xmlfile.SelectNodes(xpathString);435 if (nodes.Count == 0)436 {437 throw new ArgumentException(_resourceMgr.GetString("NoResourceMatch"));438 }439 else if (nodes.Count > 1)440 {441 throw new ArgumentException(_resourceMgr.GetString("MultipleResourceMatch"));442 }443 else444 {445 XmlNode node = nodes[0];446 if (node.HasChildNodes)447 {448 if (node.ChildNodes.Count > 1)449 {450 throw new ArgumentException(_resourceMgr.GetString("NOAttributeMatch"));451 }452 else453 {454 XmlNode tmpNode = node.ChildNodes[0]; //.Item[0];455 if (!tmpNode.NodeType.ToString().Equals("text", StringComparison.OrdinalIgnoreCase))456 {457 throw new ArgumentException(_resourceMgr.GetString("NOAttributeMatch"));458 }459 }460 }461 462 if (string.IsNullOrEmpty(entry.Key.ToString()))463 {464 // XmlNode newnode = xmlfile.CreateNode(XmlNodeType.Attribute, ATTR_NIL_NAME, NS_XSI_URI);465 XmlAttribute newnode = xmlfile.CreateAttribute(nameof(XmlNodeType.Attribute), ATTR_NIL_NAME, NS_XSI_URI);466 newnode.Value = "true";467 node.Attributes.Append(newnode);468 // (newnode.Attributes.Item(0).FirstChild );469 node.Value = string.Empty;470 }471 else472 {473 node.Attributes.RemoveNamedItem(ATTR_NIL_NAME);474 node.InnerText = entry.Value.ToString();475 }476 }477 }478 }479 480 resultString = xmlfile.OuterXml;481 break;482 }483 484 return resultString;485 }486 487 internal string GetXmlNs(string resUri)488 {489 return (@"xmlns:p=""" + StripParams(resUri) + @"""");490 }491 492 internal XmlNode GetXmlNode(string xmlString, string xpathpattern, string xmlnamespace)493 {494 XmlNode node = null;495 XmlDocument xDoc = new XmlDocument();496 xDoc.LoadXml(xmlString);497 XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable);498 if (!string.IsNullOrEmpty(xmlnamespace))499 {500 nsmgr.AddNamespace("cfg", xmlnamespace);501 }502 503 node = xDoc.SelectSingleNode(xpathpattern, nsmgr);504 return node;505 }506 507 internal string CreateConnectionString(Uri ConnUri, int port, string computername, string applicationname)508 {509 string ConnectionString = null;510 if (ConnUri != null)511 {512 ConnectionString = ConnUri.OriginalString;513 }514 else515 {516 if (computername == null && (port != 0 || applicationname != null))517 {518 // the user didn't give us a computer name but he gave a port and/or application name;519 // in this case we need to have a computer name, to form the connection string;520 // assume localhost521 computername = "localhost";522 }523 524 ConnectionString = computername;525 if (port != 0)526 {527 ConnectionString = ConnectionString + ":" + port;528 }529 530 if (applicationname != null)531 {532 ConnectionString = ConnectionString + "/" + applicationname;533 }534 }535 536 return ConnectionString;537 }538 539 internal IWSManResourceLocator InitializeResourceLocator(Hashtable optionset, Hashtable selectorset, string fragment, Uri dialect, IWSManEx wsmanObj, Uri resourceuri)540 {541 string resource = null;542 if (resourceuri != null)543 {544 resource = resourceuri.ToString();545 }546 547 if (selectorset != null)548 {549 resource += "?";550 int i = 0;551 foreach (DictionaryEntry entry in selectorset)552 {553 i++;554 resource = resource + entry.Key.ToString() + "=" + entry.Value.ToString();555 if (i < selectorset.Count)556 resource += "+";557 }558 }559 560 IWSManResourceLocator m_resource = null;561 try562 {563 m_resource = (IWSManResourceLocator)wsmanObj.CreateResourceLocator(resource);564 565 if (optionset != null)566 {567 foreach (DictionaryEntry entry in optionset)568 {569 if (entry.Value.ToString() == null)570 {571 m_resource.AddOption(entry.Key.ToString(), null, 1);572 }573 else574 {575 m_resource.AddOption(entry.Key.ToString(), entry.Value, 1);576 }577 }578 }579 580 if (!string.IsNullOrEmpty(fragment))581 {582 m_resource.FragmentPath = fragment;583 }584 585 if (dialect != null)586 {587 m_resource.FragmentDialect = dialect.ToString();588 }589 }590 catch (COMException ex)591 {592 AssertError(ex.Message, false, null);593 }594 595 return m_resource;596 }597 598 /// <summary>599 /// Used to resolve authentication from the parameters chosen by the user.600 /// User has the following options:601 /// 1. AuthMechanism + Credential602 /// 2. CertificateThumbPrint603 ///604 /// All the above are mutually exclusive.605 /// </summary>606 /// <exception cref="InvalidOperationException">607 /// If there is ambiguity as specified above.608 /// </exception>609 internal static void ValidateSpecifiedAuthentication(AuthenticationMechanism authentication, PSCredential credential, string certificateThumbprint)610 {611 if ((credential != null) && (certificateThumbprint != null))612 {613 string message = FormatResourceMsgFromResourcetextS(614 "AmbiguousAuthentication",615 "CertificateThumbPrint", "credential");616 617 throw new InvalidOperationException(message);618 }619 620 if ((authentication != AuthenticationMechanism.Default) &&621 (authentication != AuthenticationMechanism.ClientCertificate) &&622 (certificateThumbprint != null))623 {624 string message = FormatResourceMsgFromResourcetextS(625 "AmbiguousAuthentication",626 "CertificateThumbPrint", authentication.ToString());627 628 throw new InvalidOperationException(message);629 }630 }631 632 internal IWSManSession CreateSessionObject(IWSManEx wsmanObject, AuthenticationMechanism authentication, SessionOption sessionoption, PSCredential credential, string connectionString, string certificateThumbprint, bool usessl)633 {634 ValidateSpecifiedAuthentication(authentication, credential, certificateThumbprint);635 636 ////if authentication is given637 int sessionFlags = 0;638 639 if (authentication.ToString() != null)640 {641 if (authentication.Equals(AuthenticationMechanism.None))642 {643 sessionFlags |= (int)WSManSessionFlags.WSManFlagUseNoAuthentication;644 }645 646 if (authentication.Equals(AuthenticationMechanism.Basic))647 {648 sessionFlags = sessionFlags | (int)WSManSessionFlags.WSManFlagUseBasic | (int)WSManSessionFlags.WSManFlagCredUserNamePassword;649 }650 651 if (authentication.Equals(AuthenticationMechanism.Negotiate))652 {653 sessionFlags |= (int)WSManSessionFlags.WSManFlagUseNegotiate;654 }655 656 if (authentication.Equals(AuthenticationMechanism.Kerberos))657 {658 sessionFlags |= (int)WSManSessionFlags.WSManFlagUseKerberos;659 }660 661 if (authentication.Equals(AuthenticationMechanism.Digest))662 {663 sessionFlags = sessionFlags | (int)WSManSessionFlags.WSManFlagUseDigest | (int)WSManSessionFlags.WSManFlagCredUserNamePassword;664 }665 666 if (authentication.Equals(AuthenticationMechanism.Credssp))667 {668 sessionFlags = sessionFlags | (int)WSManSessionFlags.WSManFlagUseCredSsp | (int)WSManSessionFlags.WSManFlagCredUserNamePassword;669 }670 671 if (authentication.Equals(AuthenticationMechanism.ClientCertificate))672 {673 sessionFlags |= (int)WSManSessionFlags.WSManFlagUseClientCertificate;674 }675 }676 677 IWSManConnectionOptionsEx2 connObject = (IWSManConnectionOptionsEx2)wsmanObject.CreateConnectionOptions();678 if (credential != null)679 {680 // connObject = (IWSManConnectionOptionsEx2)wsmanObject.CreateConnectionOptions();681 System.Net.NetworkCredential nwCredential = new System.Net.NetworkCredential();682 if (credential.UserName != null)683 {684 nwCredential = credential.GetNetworkCredential();685 if (string.IsNullOrEmpty(nwCredential.Domain))686 {687 if (authentication.Equals(AuthenticationMechanism.Digest) || authentication.Equals(AuthenticationMechanism.Basic))688 {689 connObject.UserName = nwCredential.UserName;690 }691 else692 {693 // just wanted to not use null domain, empty is actually fine694 connObject.UserName = "\\" + nwCredential.UserName;695 }696 }697 else698 {699 connObject.UserName = nwCredential.Domain + "\\" + nwCredential.UserName;700 }701 702 connObject.Password = nwCredential.Password;703 if (!authentication.Equals(AuthenticationMechanism.Credssp) || !authentication.Equals(AuthenticationMechanism.Digest) || authentication.Equals(AuthenticationMechanism.Basic))704 {705 sessionFlags |= (int)WSManSessionFlags.WSManFlagCredUserNamePassword;706 }707 }708 }709 710 if (certificateThumbprint != null)711 {712 connObject.CertificateThumbprint = certificateThumbprint;713 sessionFlags |= (int)WSManSessionFlags.WSManFlagUseClientCertificate;714 }715 716 if (sessionoption != null)717 {718 if (sessionoption.ProxyAuthentication != 0)719 {720 int ProxyAccessflags = 0;721 int ProxyAuthenticationFlags = 0;722 if (sessionoption.ProxyAccessType.Equals(ProxyAccessType.ProxyIEConfig))723 {724 ProxyAccessflags = connObject.ProxyIEConfig();725 }726 else if (sessionoption.ProxyAccessType.Equals(ProxyAccessType.ProxyAutoDetect))727 {728 ProxyAccessflags = connObject.ProxyAutoDetect();729 }730 else if (sessionoption.ProxyAccessType.Equals(ProxyAccessType.ProxyNoProxyServer))731 {732 ProxyAccessflags = connObject.ProxyNoProxyServer();733 }734 else if (sessionoption.ProxyAccessType.Equals(ProxyAccessType.ProxyWinHttpConfig))735 {736 ProxyAccessflags = connObject.ProxyWinHttpConfig();737 }738 739 if (sessionoption.ProxyAuthentication.Equals(ProxyAuthentication.Basic))740 {741 ProxyAuthenticationFlags = connObject.ProxyAuthenticationUseBasic();742 }743 else if (sessionoption.ProxyAuthentication.Equals(ProxyAuthentication.Negotiate))744 {745 ProxyAuthenticationFlags = connObject.ProxyAuthenticationUseNegotiate();746 }747 else if (sessionoption.ProxyAuthentication.Equals(ProxyAuthentication.Digest))748 {749 ProxyAuthenticationFlags = connObject.ProxyAuthenticationUseDigest();750 }751 752 if (sessionoption.ProxyCredential != null)753 {754 try755 {756 connObject.SetProxy(ProxyAccessflags, ProxyAuthenticationFlags, sessionoption.ProxyCredential.UserName, sessionoption.ProxyCredential.Password);757 }758 catch (Exception ex)759 {760 AssertError(ex.Message, false, null);761 }762 }763 else764 {765 connObject.SetProxy((int)sessionoption.ProxyAccessType, (int)sessionoption.ProxyAuthentication, null, null);766 }767 }768 769 if (sessionoption.SkipCACheck)770 {771 sessionFlags |= (int)WSManSessionFlags.WSManFlagSkipCACheck;772 }773 774 if (sessionoption.SkipCNCheck)775 {776 sessionFlags |= (int)WSManSessionFlags.WSManFlagSkipCNCheck;777 }778 779 if (sessionoption.SPNPort > 0)780 {781 sessionFlags |= (int)WSManSessionFlags.WSManFlagEnableSpnServerPort;782 }783 784 if (sessionoption.UseUtf16)785 {786 sessionFlags |= (int)WSManSessionFlags.WSManFlagUtf16;787 }788 else789 {790 // If UseUtf16 is false, then default Encoding is Utf8791 sessionFlags |= (int)WSManSessionFlags.WSManFlagUtf8;792 }793 794 if (!sessionoption.UseEncryption)795 {796 sessionFlags |= (int)WSManSessionFlags.WSManFlagNoEncryption;797 }798 799 if (sessionoption.SkipRevocationCheck)800 {801 sessionFlags |= (int)WSManSessionFlags.WSManFlagSkipRevocationCheck;802 }803 }804 else805 {806 // If SessionOption is null then, default Encoding is Utf8807 sessionFlags |= (int)WSManSessionFlags.WSManFlagUtf8;808 }809 810 if (usessl)811 {812 sessionFlags |= (int)WSManSessionFlags.WSManFlagUseSsl;813 }814 815 IWSManSession m_SessionObj = null;816 try817 {818 m_SessionObj = (IWSManSession)wsmanObject.CreateSession(connectionString, sessionFlags, connObject);819 if (sessionoption != null)820 {821 if (sessionoption.OperationTimeout > 0)822 {823 m_SessionObj.Timeout = sessionoption.OperationTimeout;824 }825 }826 }827 catch (COMException ex)828 {829 AssertError(ex.Message, false, null);830 }831 832 return m_SessionObj;833 }834 835 internal void CleanUp()836 {837 if (_sr != null)838 {839 _sr.Dispose();840 _sr = null;841 }842 843 if (_fs != null)844 {845 _fs.Dispose();846 _fs = null;847 }848 }849 850 internal string GetFilterString(Hashtable seletorset)851 {852 StringBuilder filter = new StringBuilder();853 foreach (DictionaryEntry entry in seletorset)854 {855 if (entry.Key != null && entry.Value != null)856 {857 filter.Append(entry.Key.ToString());858 filter.Append('=');859 filter.Append(entry.Value.ToString());860 filter.Append('+');861 }862 }863 864 filter.Remove(filter.ToString().Length - 1, 1);865 return filter.ToString();866 }867 868 internal void AssertError(string ErrorMessage, bool IsWSManError, object targetobject)869 {870 if (IsWSManError)871 {872 XmlDocument ErrorDoc = new XmlDocument();873 ErrorDoc.LoadXml(ErrorMessage);874 InvalidOperationException ex = new InvalidOperationException(ErrorDoc.OuterXml);875 ErrorRecord er = new ErrorRecord(ex, "WsManError", ErrorCategory.InvalidOperation, targetobject);876 if (cmdletname != null)877 {878 cmdletname.ThrowTerminatingError(er);879 }880 else881 {882 _provider.ThrowTerminatingError(er);883 }884 }885 else886 {887 InvalidOperationException ex = new InvalidOperationException(ErrorMessage);888 ErrorRecord er = new ErrorRecord(ex, "WsManError", ErrorCategory.InvalidOperation, targetobject);889 if (cmdletname != null)890 {891 cmdletname.ThrowTerminatingError(er);892 }893 else894 {895 _provider.ThrowTerminatingError(er);896 }897 }898 }899 900 internal string GetURIWithFilter(string uri, string filter, Hashtable selectorset, string operation)901 {902 StringBuilder sburi = new StringBuilder();903 sburi.Append(uri);904 sburi.Append('?');905 906 if (operation.Equals("remove", StringComparison.OrdinalIgnoreCase))907 {908 sburi.Append(GetFilterString(selectorset));909 if (sburi.ToString().EndsWith('?'))910 {911 sburi.Remove(sburi.Length - 1, 1);912 }913 }914 915 return sburi.ToString();916 }917 918 /// <summary>919 /// This method is used by Connect-WsMan Cmdlet and New-Item of WsMan Provider to create connection to WsMan.920 /// </summary>921 /// <param name="ParameterSetName"></param>922 /// <param name="connectionuri"></param>923 /// <param name="port"></param>924 /// <param name="computername"></param>925 /// <param name="applicationname"></param>926 /// <param name="usessl"></param>927 /// <param name="authentication"></param>928 /// <param name="sessionoption"></param>929 /// <param name="credential"></param>930 /// <param name="certificateThumbprint"></param>931 internal void CreateWsManConnection(string ParameterSetName, Uri connectionuri, int port, string computername, string applicationname, bool usessl, AuthenticationMechanism authentication, SessionOption sessionoption, PSCredential credential, string certificateThumbprint)932 {933 IWSManEx m_wsmanObject = (IWSManEx)new WSManClass();934 try935 {936 string connectionStr = CreateConnectionString(connectionuri, port, computername, applicationname);937 if (connectionuri != null)938 {939 // in the format http(s)://server[:port/applicationname]940 string[] constrsplit = connectionStr.Split(":" + port + "/" + applicationname, StringSplitOptions.None);941 string[] constrsplit1 = constrsplit[0].Split("//", StringSplitOptions.None);942 computername = constrsplit1[1].Trim();943 }944 945 IWSManSession m_session = CreateSessionObject(m_wsmanObject, authentication, sessionoption, credential, connectionStr, certificateThumbprint, usessl);946 m_session.Identify(0);947 string key = computername ?? "localhost";948 949 AddtoDictionary(key, m_session);950 }951 catch (IndexOutOfRangeException)952 {953 AssertError(_resourceMgr.GetString("NotProperURI"), false, connectionuri);954 }955 catch (Exception ex)956 {957 AssertError(ex.Message, false, computername);958 }959 finally960 {961 if (!string.IsNullOrEmpty(m_wsmanObject.Error))962 {963 AssertError(m_wsmanObject.Error, true, computername);964 }965 }966 }967 968 /// <summary>969 /// Verifies all the registry keys are set as expected. In case of failure .. try ecery second for 60 seconds before returning false.970 /// </summary>971 /// <param name="AllowFreshCredentialsValueShouldBePresent">True if trying to Enable CredSSP.</param>972 /// <param name="DelegateComputer">Names of the delegate computer.</param>973 /// <param name="applicationname">Name of the application.</param>974 /// <returns>True if valid.</returns>975 internal bool ValidateCreadSSPRegistryRetry(bool AllowFreshCredentialsValueShouldBePresent, string[] DelegateComputer, string applicationname)976 {977 for (int i = 0; i < 60; i++)978 {979 if (!ValidateCredSSPRegistry(AllowFreshCredentialsValueShouldBePresent, DelegateComputer, applicationname))980 {981 Thread.Sleep(1000);982 }983 else984 {985 return true;986 }987 }988 989 return false;990 }991 992 internal bool ValidateCredSSPRegistry(bool AllowFreshCredentialsValueShouldBePresent, string[] DelegateComputer, string applicationname)993 {994 System.IntPtr NakedGPOCriticalSection = GpoNativeApi.EnterCriticalPolicySection(true);995 996 try997 {998 RegistryKey rGPOLocalMachineKey = Registry.LocalMachine.OpenSubKey(999 Registry_Path_Credentials_Delegation + @"\CredentialsDelegation",1000 RegistryKeyPermissionCheck.ReadWriteSubTree,1001 System.Security.AccessControl.RegistryRights.FullControl);1002 1003 if (rGPOLocalMachineKey != null)1004 {1005 rGPOLocalMachineKey = rGPOLocalMachineKey.OpenSubKey(1006 Key_Allow_Fresh_Credentials,1007 RegistryKeyPermissionCheck.ReadWriteSubTree,1008 System.Security.AccessControl.RegistryRights.FullControl);1009 if (rGPOLocalMachineKey == null)1010 {1011 return !AllowFreshCredentialsValueShouldBePresent;1012 }1013 1014 string[] valuenames = rGPOLocalMachineKey.GetValueNames();1015 if (valuenames.Length == 0)1016 {1017 return !AllowFreshCredentialsValueShouldBePresent;1018 }1019 1020 List<string> RegValues = new List<string>();1021 foreach (string value in valuenames)1022 {1023 object keyvalue = rGPOLocalMachineKey.GetValue(value);1024 1025 if (keyvalue != null && keyvalue.ToString().StartsWith(applicationname, StringComparison.OrdinalIgnoreCase))1026 {1027 if (!AllowFreshCredentialsValueShouldBePresent)1028 {1029 // If calling Disable-CredSSP .. no value should start with "applicationName" regardless of the computer.1030 return false;1031 }1032 1033 RegValues.Add(keyvalue.ToString());1034 }1035 }1036 1037 if (AllowFreshCredentialsValueShouldBePresent)1038 {1039 // For all the keys that starts with "applicationName" make sure the delegated computer is listed.1040 foreach (string comp in DelegateComputer)1041 {1042 if (!RegValues.Contains(applicationname + "/" + comp))1043 {1044 return false;1045 }1046 }1047 }1048 }1049 }1050 finally1051 {1052 bool GPOReleaseCriticalSection = GpoNativeApi.LeaveCriticalPolicySection(NakedGPOCriticalSection);1053 }1054 1055 return true;1056 }1057 }1058 1059 internal static class WSManResourceLoader1060 {1061 internal static void LoadResourceData()1062 {1063 try1064 {1065 string winDir = System.Environment.ExpandEnvironmentVariables("%Windir%");1066 uint lcid = checked((uint)CultureInfo.CurrentUICulture.LCID);1067 string filepath = string.Create(CultureInfo.CurrentCulture, $@"{winDir}\System32\Winrm\0{lcid:x2}\winrm.ini");1068 1069 if (File.Exists(filepath))1070 {1071 FileStream _fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);1072 StreamReader _sr = new StreamReader(_fs);1073 while (!_sr.EndOfStream)1074 {1075 string Line = _sr.ReadLine();1076 if (Line.Contains('='))1077 {1078 string[] arr = Line.Split('=', count: 2);1079 if (!ResourceValueCache.ContainsKey(arr[0].Trim()))1080 {1081 string value = arr[1].Trim('"');1082 ResourceValueCache.Add(arr[0].Trim(), value.Trim());1083 }1084 }1085 }1086 }1087 }1088 catch (IOException)1089 {1090 throw;1091 }1092 }1093 1094 /// <summary>1095 /// Get the resource value from WinRm.ini1096 /// from %windir%\system32\winrm\[Hexadecimal Language Folder]\winrm.ini.1097 /// </summary>1098 /// <param name="Key"></param>1099 /// <returns></returns>1100 internal static string GetResourceString(string Key)1101 {1102 // Checks whether resource values already loaded and loads.1103 if (ResourceValueCache.Count == 0)1104 {1105 LoadResourceData();1106 }1107 1108 string value = string.Empty;1109 if (ResourceValueCache.ContainsKey(Key.Trim()))1110 {1111 ResourceValueCache.TryGetValue(Key.Trim(), out value);1112 }1113 1114 return value.Trim();1115 }1116 1117 /// <summary>1118 /// </summary>1119 private static readonly Dictionary<string, string> ResourceValueCache = new Dictionary<string, string>();1120 }1121}1122 