public bool Save(byte[] passwordBytes) { CheckNotDisposed(); _unmanagedCodePermission.Demand(); ValidatePasswordLength(passwordBytes); var blob = Marshal.AllocCoTaskMem(passwordBytes.Length); Marshal.Copy(passwordBytes, 0, blob, passwordBytes.Length); var credential = new NativeMethods.CREDENTIAL { TargetName = Target, UserName = Username, CredentialBlob = blob, CredentialBlobSize = passwordBytes.Length, Comment = Description, Type = (int)Type, Persist = (int)PersistenceType }; bool result = NativeMethods.CredWrite(ref credential, 0); Marshal.FreeCoTaskMem(blob); if (!result) { return(false); } LastWriteTimeUtc = DateTime.UtcNow; return(true); }
public bool Save() { CheckNotDisposed(); _unmanagedCodePermission.Demand(); byte[] passwordBytes = Encoding.Unicode.GetBytes(Password); ValidatePasswordLength(passwordBytes); var credential = new NativeMethods.CREDENTIAL { TargetName = Target, UserName = Username, CredentialBlob = Marshal.StringToCoTaskMemUni(Password), CredentialBlobSize = passwordBytes.Length, Comment = Description, Type = (int)Type, Persist = (int)PersistenceType }; bool result = NativeMethods.CredWrite(ref credential, 0); if (!result) { return(false); } LastWriteTimeUtc = DateTime.UtcNow; return(true); }
private readonly bool isLoaded; // is the credential blob loaded #region -- Ctor/Dtor ---------------------------------------------------------- /// <summary></summary> /// <param name="target"></param> /// <param name="realm"></param> /// <param name="showErrorMessage">The user will be informed of the type of error.</param> public PpsClientLogin(string target, string realm, bool showErrorMessage) { this.target = target; this.realm = realm; this.showErrorMessage = showErrorMessage; if (NativeMethods.CredRead(target, NativeMethods.CredentialType.Generic, 0, out var pCred)) { credential = Marshal.PtrToStructure <NativeMethods.CREDENTIAL>(pCred); if (credential.CredentialBlob != IntPtr.Zero) // copy the password in our one memory area { password = Marshal.AllocCoTaskMem(credential.CredentialBlobSize); passwordLength = (credential.CredentialBlobSize >> 1) - 1; UnsafeNativeMethods.CopyMemory(password, credential.CredentialBlob, credential.CredentialBlobSize); } NativeMethods.CredFree(pCred); isLoaded = true; saveOptions = passwordLength > 0 ? PpsClientLoginSaveOptions.Password : PpsClientLoginSaveOptions.UserName; } else { isLoaded = false; saveOptions = PpsClientLoginSaveOptions.None; } } // ctor
internal void LoadInternal(NativeMethods.CREDENTIAL credential) { Username = credential.UserName; if (credential.CredentialBlobSize > 0) { Password = Marshal.PtrToStringUni(credential.CredentialBlob, credential.CredentialBlobSize / 2); } Target = credential.TargetName; Type = (CredentialType)credential.Type; PersistenceType = (PersistenceType)credential.Persist; Description = credential.Comment; LastWriteTimeUtc = DateTime.FromFileTimeUtc(credential.LastWritten); }
/// <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); } }
internal static extern bool CredWrite([In] ref NativeMethods.CREDENTIAL userCredential, [In] UInt32 flags);