Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
Credential.cs405 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#pragma warning disable 1634, 16915 6using System.Diagnostics.CodeAnalysis;7using System.Net;8using System.Security;9using System.Runtime.Serialization;10using System.Security.Cryptography;11using Microsoft.PowerShell;12 13namespace System.Management.Automation14{15    /// <summary>16    /// Defines the valid types of PSCredentials.  Used by PromptForCredential calls.17    /// </summary>18    [Flags]19    public enum PSCredentialTypes20    {21        /// <summary>22        /// Generic credentials.23        /// </summary>24        Generic = 1,25 26        /// <summary>27        /// Credentials valid for a domain.28        /// </summary>29        Domain = 2,30 31        /// <summary>32        /// Default credentials.33        /// </summary>34        Default = Generic | Domain35    }36 37    /// <summary>38    /// Defines the options available when prompting for credentials.  Used39    /// by PromptForCredential calls.40    /// </summary>41    [Flags]42    public enum PSCredentialUIOptions43    {44        /// <summary>45        /// Validates the username, but not its existence46        /// or correctness.47        /// </summary>48        Default = ValidateUserNameSyntax,49 50        /// <summary>51        /// Performs no validation.52        /// </summary>53        None = 0,54 55        /// <summary>56        /// Validates the username, but not its existence.57        /// or correctness.58        /// </summary>59        ValidateUserNameSyntax,60 61        /// <summary>62        /// Always prompt, even if a persisted credential was available.63        /// </summary>64        AlwaysPrompt,65 66        /// <summary>67        /// Username is read-only, and the user may not modify it.68        /// </summary>69        ReadOnlyUserName70    }71 72    /// <summary>73    /// Declare a delegate which returns the encryption key and initialization vector for symmetric encryption algorithm.74    /// </summary>75    /// <param name="context">The streaming context, which contains the serialization context.</param>76    /// <param name="key">Symmetric encryption key.</param>77    /// <param name="iv">Symmetric encryption initialization vector.</param>78    /// <returns></returns>79    public delegate bool GetSymmetricEncryptionKey(StreamingContext context, out byte[] key, out byte[] iv);80 81    /// <summary>82    /// Offers a centralized way to manage usernames, passwords, and83    /// credentials.84    /// </summary>85    [Serializable]86    public sealed class PSCredential : ISerializable87    {88        /// <summary>89        /// Gets or sets a delegate which returns the encryption key and initialization vector for symmetric encryption algorithm.90        /// </summary>91        public static GetSymmetricEncryptionKey GetSymmetricEncryptionKeyDelegate92        {93            get94            {95                return s_delegate;96            }97 98            set99            {100                s_delegate = value;101            }102        }103 104        private static GetSymmetricEncryptionKey s_delegate = null;105 106        /// <summary>107        /// GetObjectData.108        /// </summary>109        /// <param name="info"></param>110        /// <param name="context"></param>111        public void GetObjectData(SerializationInfo info, StreamingContext context)112        {113            if (info == null)114                return;115 116            // serialize the secure string117            string safePassword = string.Empty;118 119            if (_password != null && _password.Length > 0)120            {121                byte[] key;122                byte[] iv;123                if (s_delegate != null && s_delegate(context, out key, out iv))124                {125                    safePassword = SecureStringHelper.Encrypt(_password, key, iv).EncryptedData;126                }127                else128                {129                    try130                    {131                        safePassword = SecureStringHelper.Protect(_password);132                    }133                    catch (CryptographicException cryptographicException)134                    {135                        throw PSTraceSource.NewInvalidOperationException(cryptographicException, Credential.CredentialDisallowed);136                    }137                }138            }139 140            info.AddValue("UserName", _userName);141            info.AddValue("Password", safePassword);142        }143 144        /// <summary>145        /// PSCredential.146        /// </summary>147        /// <param name="info"></param>148        /// <param name="context"></param>149        private PSCredential(SerializationInfo info, StreamingContext context)150        {151            if (info == null)152                return;153 154            _userName = (string)info.GetValue("UserName", typeof(string));155 156            // deserialize to secure string157            string safePassword = (string)info.GetValue("Password", typeof(string));158            if (safePassword == string.Empty)159            {160                _password = new SecureString();161            }162            else163            {164                byte[] key;165                byte[] iv;166                if (s_delegate != null && s_delegate(context, out key, out iv))167                {168                    _password = SecureStringHelper.Decrypt(safePassword, key, iv);169                }170                else171                {172                    _password = SecureStringHelper.Unprotect(safePassword);173                }174            }175        }176 177        private readonly string _userName;178        private readonly SecureString _password;179 180        /// <summary>181        /// User's name.182        /// </summary>183        public string UserName184        {185            get { return _userName; }186        }187 188        /// <summary>189        /// User's password.190        /// </summary>191        public SecureString Password192        {193            get { return _password; }194        }195 196        /// <summary>197        /// Initializes a new instance of the PSCredential class with a198        /// username and password.199        /// </summary>200        /// <param name="userName">User's name.</param>201        /// <param name="password">User's password.</param>202        public PSCredential(string userName, SecureString password)203        {204            Utils.CheckArgForNullOrEmpty(userName, "userName");205            Utils.CheckArgForNull(password, "password");206 207            _userName = userName;208            _password = password;209        }210 211        /// <summary>212        /// Initializes a new instance of the PSCredential class with a213        /// username and password from PSObject.214        /// </summary>215        /// <param name="pso"></param>216        public PSCredential(PSObject pso)217        {218            if (pso == null)219                throw PSTraceSource.NewArgumentNullException(nameof(pso));220 221            if (pso.Properties["UserName"] != null)222            {223                _userName = (string)pso.Properties["UserName"].Value;224 225                if (pso.Properties["Password"] != null)226                    _password = (SecureString)pso.Properties["Password"].Value;227            }228        }229 230        /// <summary>231        /// Initializes a new instance of the PSCredential class.232        /// </summary>233        private PSCredential()234        {235        }236 237        private NetworkCredential _netCred;238 239        /// <summary>240        /// Returns an equivalent NetworkCredential object for this241        /// PSCredential.242        ///243        /// A null is returned if244        /// -- current object has not been initialized245        /// -- current creds are not compatible with NetworkCredential246        ///    (such as smart card creds or cert creds)247        /// </summary>248        /// <returns>249        ///     null if the current object has not been initialized.250        ///     null if the current credentials are incompatible with251        ///       a NetworkCredential -- such as smart card credentials.252        ///     the appropriate network credential for this PSCredential otherwise.253        /// </returns>254        public NetworkCredential GetNetworkCredential()255        {256            if (_netCred == null)257            {258                string user = null;259                string domain = null;260 261                if (IsValidUserName(_userName, out user, out domain))262                {263                    _netCred = new NetworkCredential(user, _password, domain);264                }265            }266 267            return _netCred;268        }269 270        /// <summary>271        /// Provides an explicit cast to get a NetworkCredential272        /// from this PSCredential.273        /// </summary>274        /// <param name="credential">PSCredential to convert.</param>275        /// <returns>276        ///     null if the current object has not been initialized.277        ///     null if the current credentials are incompatible with278        ///       a NetworkCredential -- such as smart card credentials.279        ///     the appropriate network credential for this PSCredential otherwise.280        /// </returns>281        public static explicit operator NetworkCredential(PSCredential credential)282        {283#pragma warning disable 56506284 285            if (credential == null)286            {287                throw PSTraceSource.NewArgumentNullException("credential");288            }289 290            return credential.GetNetworkCredential();291 292#pragma warning restore 56506293        }294 295        /// <summary>296        /// Gets an empty PSCredential.  This is an PSCredential with both UserName297        /// and Password initialized to null.298        /// </summary>299        public static PSCredential Empty300        {301            get302            {303                return s_empty;304            }305        }306 307        private static readonly PSCredential s_empty = new PSCredential();308 309        /// <summary>310        /// Parse a string that represents a fully qualified username311        /// to verify that it is syntactically valid. We only support312        /// two formats:313        /// -- domain\user314        /// -- user@domain315        ///316        /// for any other format, we simply treat the entire string317        /// as user name and set domain name to "".318        /// </summary>319        private static bool IsValidUserName(string input,320                                            out string user,321                                            out string domain)322        {323            if (string.IsNullOrEmpty(input))324            {325                user = domain = null;326                return false;327            }328 329            SplitUserDomain(input, out user, out domain);330 331            if ((user == null) ||332                (domain == null) ||333                (user.Length == 0))334            {335                // UserName is the public property of Credential object. Use this as336                // parameter name in error337                // See bug NTRAID#Windows OS Bugs-1106386-2005/03/25-hiteshr338                throw PSTraceSource.NewArgumentException("UserName", Credential.InvalidUserNameFormat);339            }340 341            return true;342        }343 344        /// <summary>345        /// Split a given string into its user and domain346        /// components. Supported formats are:347        /// -- domain\user348        /// -- user@domain349        ///350        /// With any other format, the entire input is treated as user351        /// name and domain is set to "".352        ///353        /// In any case, the function does not check if the split string354        /// are really valid as user or domain names.355        /// </summary>356        private static void SplitUserDomain(string input,357                                            out string user,358                                            out string domain)359        {360            int i = 0;361            user = null;362            domain = null;363 364            if ((i = input.IndexOf('\\')) >= 0)365            {366                user = input.Substring(i + 1);367                domain = input.Substring(0, i);368                return;369            }370 371            // In V1 and V2, we had a bug where email addresses (i.e. foo@bar.com)372            // were being split into Username=Foo, Domain=bar.com.373            //374            // This was breaking apps (i.e.: Exchange), so we need to make375            // Username = foo@bar.com if the domain has a dot in it (since376            // domains can't have dots).377            //378            // HOWEVER, there was a workaround for this bug in v1 and v2, where the379            // cred could be entered as "foo@bar.com@bar.com" - making:380            // Username = foo@bar.com, Domain = bar.com381            //382            // We need to keep the behaviour in this case.383 384            i = input.LastIndexOf('@');385 386            if (387                (i >= 0) &&388                (389                    (input.LastIndexOf('.') < i) ||390                    (input.IndexOf('@') != i)391                )392            )393            {394                domain = input.Substring(i + 1);395                user = input.Substring(0, i);396            }397            else398            {399                user = input;400                domain = string.Empty;401            }402        }403    }404}405