/// <summary> /// Retrieves credentials for the specified target from the operating system's credential store for the current user. /// </summary> /// <param name="target">The target name for the credentials.</param> /// <returns>The credentials if they were found; otherwise, <see langword="null" />.</returns> /// <remarks> /// <para> /// If the requested credential was not originally stored using the <see cref="CredentialDialog"/> class (but e.g. by /// another application), the password may not be decoded correctly. /// </para> /// <para> /// This function does not check the application instance credential cache for the credentials; for that you can use /// the <see cref="RetrieveCredentialFromApplicationInstanceCache"/> function. /// </para> /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="target"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentException"><paramref name="target"/> is an empty string ("").</exception> /// <exception cref="CredentialException">An error occurred retrieving the credentials.</exception> public static NetworkCredential RetrieveCredential(string target) { if (target == null) { throw new ArgumentNullException("target"); } if (target.Length == 0) { throw new ArgumentException(Properties.Resources.CredentialEmptyTargetError, "target"); } NetworkCredential cred = RetrieveCredentialFromApplicationInstanceCache(target); if (cred != null) { return(cred); } IntPtr credential; bool result = NativeMethods.CredRead(target, NativeMethods.CredTypes.CRED_TYPE_GENERIC, 0, out credential); int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); if (result) { try { NativeMethods.CREDENTIAL c = (NativeMethods.CREDENTIAL)System.Runtime.InteropServices.Marshal.PtrToStructure(credential, typeof(NativeMethods.CREDENTIAL)); byte[] encryptedPassword = new byte[c.CredentialBlobSize]; System.Runtime.InteropServices.Marshal.Copy(c.CredentialBlob, encryptedPassword, 0, encryptedPassword.Length); cred = new NetworkCredential(c.UserName, DecryptPassword(encryptedPassword)); } finally { NativeMethods.CredFree(credential); } return(cred); } else { if (error == (int)NativeMethods.CredUIReturnCodes.ERROR_NOT_FOUND) { return(null); } else { throw new CredentialException(error); } } }
/// <summary> /// Stores the specified credentials in the operating system's credential store for the currently logged on user. /// </summary> /// <param name="target">The target name for the credentials.</param> /// <param name="credential">The credentials to store.</param> /// <exception cref="ArgumentNullException"> /// <para> /// <paramref name="target"/> is <see langword="null" />. /// </para> /// <para> /// -or- /// </para> /// <para> /// <paramref name="credential"/> is <see langword="null" />. /// </para> /// </exception> /// <exception cref="ArgumentException"><paramref name="target"/> is an empty string ("").</exception> /// <exception cref="CredentialException">An error occurred storing the credentials.</exception> /// <remarks> /// <note> /// The <see cref="NetworkCredential.Domain"/> property is ignored and will not be stored, even if it is /// not <see langword="null" />. /// </note> /// <para> /// If the credential manager already contains credentials for the specified <paramref name="target"/>, they /// will be overwritten; this can even overwrite credentials that were stored by another application. Therefore /// it is strongly recommended that you prefix the target name to ensure uniqueness, e.g. using the /// form "Company_ApplicationName_www.example.com". /// </para> /// </remarks> public static void StoreCredential(string target, NetworkCredential credential) { if (target == null) { throw new ArgumentNullException("target"); } if (target.Length == 0) { throw new ArgumentException(Properties.Resources.CredentialEmptyTargetError, "target"); } if (credential == null) { throw new ArgumentNullException("credential"); } NativeMethods.CREDENTIAL c = new NativeMethods.CREDENTIAL(); c.UserName = credential.UserName; c.TargetName = target; c.Persist = NativeMethods.CredPersist.Enterprise; byte[] encryptedPassword = EncryptPassword(credential.Password); c.CredentialBlob = System.Runtime.InteropServices.Marshal.AllocHGlobal(encryptedPassword.Length); try { System.Runtime.InteropServices.Marshal.Copy(encryptedPassword, 0, c.CredentialBlob, encryptedPassword.Length); c.CredentialBlobSize = (uint)encryptedPassword.Length; c.Type = NativeMethods.CredTypes.CRED_TYPE_GENERIC; if (!NativeMethods.CredWrite(ref c, 0)) { throw new CredentialException(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); } } finally { System.Runtime.InteropServices.Marshal.FreeCoTaskMem(c.CredentialBlob); } }
/// <summary> /// Stores the specified credentials in the operating system's credential store for the currently logged on user. /// </summary> /// <param name="target">The target name for the credentials.</param> /// <param name="credential">The credentials to store.</param> /// <exception cref="ArgumentNullException"> /// <para> /// <paramref name="target"/> is <see langword="null" />. /// </para> /// <para> /// -or- /// </para> /// <para> /// <paramref name="credential"/> is <see langword="null" />. /// </para> /// </exception> /// <exception cref="ArgumentException"><paramref name="target"/> is an empty string ("").</exception> /// <exception cref="CredentialException">An error occurred storing the credentials.</exception> /// <remarks> /// <note> /// The <see cref="NetworkCredential.Domain"/> property is ignored and will not be stored, even if it is /// not <see langword="null" />. /// </note> /// <para> /// If the credential manager already contains credentials for the specified <paramref name="target"/>, they /// will be overwritten; this can even overwrite credentials that were stored by another application. Therefore /// it is strongly recommended that you prefix the target name to ensure uniqueness, e.g. using the /// form "Company_ApplicationName_www.example.com". /// </para> /// </remarks> public static void StoreCredential(string target, NetworkCredential credential) { if( target == null ) throw new ArgumentNullException("target"); if( target.Length == 0 ) throw new ArgumentException(Properties.Resources.CredentialEmptyTargetError, "target"); if( credential == null ) throw new ArgumentNullException("credential"); NativeMethods.CREDENTIAL c = new NativeMethods.CREDENTIAL(); c.UserName = credential.UserName; c.TargetName = target; c.Persist = NativeMethods.CredPersist.Enterprise; byte[] encryptedPassword = EncryptPassword(credential.Password); c.CredentialBlob = System.Runtime.InteropServices.Marshal.AllocHGlobal(encryptedPassword.Length); try { System.Runtime.InteropServices.Marshal.Copy(encryptedPassword, 0, c.CredentialBlob, encryptedPassword.Length); c.CredentialBlobSize = (uint)encryptedPassword.Length; c.Type = NativeMethods.CredTypes.CRED_TYPE_GENERIC; if( !NativeMethods.CredWrite(ref c, 0) ) throw new CredentialException(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); } finally { System.Runtime.InteropServices.Marshal.FreeCoTaskMem(c.CredentialBlob); } }