/// <summary> /// Extract the stored credential from WIndows Credential store /// </summary> /// <param name="Target">Name of the application/Url where the credential is used for</param> /// <returns>empty credentials if target not found, else stored credentials</returns> public static NetworkCredential GetCredentials(string Target) { IntPtr nCredPtr; var username = String.Empty; var passwd = String.Empty; try { // Make the API call using the P/Invoke signature bool ret = NativeCode.CredRead(Target, NativeCode.CredentialType.Generic, 0, out nCredPtr); // If the API was successful then... if (ret) { using (CriticalCredentialHandle critCred = new CriticalCredentialHandle(nCredPtr)) { Credential cred = critCred.GetCredential(); passwd = cred.CredentialBlob; username = cred.UserName; } } } catch (Exception e) { log.error($"Could not get credentials for {Target}", e); } return new NetworkCredential(username, passwd, string.Empty); }
/// <summary> /// Extract the stored credential from WIndows Credential store /// </summary> /// <param name="Target">Name of the application/Url where the credential is used for</param> /// <returns>empty credentials if target not found, else stored credentials</returns> public static NetworkCredential GetCredentials(string Target) { IntPtr nCredPtr; var username = String.Empty; var passwd = String.Empty; var domain = String.Empty; // Make the API call using the P/Invoke signature bool ret = NativeCode.CredRead(Target, NativeCode.CredentialType.Generic, 0, out nCredPtr); // If the API was successful then... if (ret) { using (CriticalCredentialHandle critCred = new CriticalCredentialHandle(nCredPtr)) { Credential cred = critCred.GetCredential(); passwd = cred.CredentialBlob; var user = cred.UserName; StringBuilder userBuilder = new StringBuilder(); StringBuilder domainBuilder = new StringBuilder(); var code = NativeCode.CredUIParseUserName(user, userBuilder, int.MaxValue, domainBuilder, int.MaxValue); //assuming invalid account name to be not meeting condition for CredUIParseUserName //"The name must be in UPN or down-level format, or a certificate" if (code == NativeCode.CredentialUIReturnCodes.InvalidAccountName) { userBuilder.Append(user); } username = userBuilder.ToString(); domain = domainBuilder.ToString(); } } return(new NetworkCredential(username, passwd, domain)); }
/// <summary> /// Saves teh given Network Credential into Windows Credential store /// </summary> /// <param name="Target">Name of the application/Url where the credential is used for</param> /// <param name="credential">Credential to store</param> /// <returns>True:Success, False:Failure</returns> public static bool SaveCredentials(string Target, NetworkCredential credential) { // Go ahead with what we have are stuff it into the CredMan structures. Credential cred = new Credential(credential); cred.TargetName = Target; cred.Persist = NativeCode.Persistance.Entrprise; NativeCode.NativeCredential ncred = cred.GetNativeCredential(); // Write the info into the CredMan storage. return(NativeCode.CredWrite(ref ncred, 0)); }
/// <summary> /// Remove stored credentials from windows credential store /// </summary> /// <param name="Target">Name of the application/Url where the credential is used for</param> /// <returns>True: Success, False: Failure</returns> public static bool RemoveCredentials(string Target) { try { // Make the API call using the P/Invoke signature return NativeCode.CredDelete(Target, NativeCode.CredentialType.Generic, 0); } catch (Exception e) { log.error($"Could not remove credentials {Target}", e); return false; } }
// Perform any specific actions to release the handle in the ReleaseHandle method. // Often, you need to use Pinvoke to make a call into the Win32 API to release the // handle. In this case, however, we can use the Marshal class to release the unmanaged memory. override protected bool ReleaseHandle() { // If the handle was set, free it. Return success. if (!IsInvalid) { // NOTE: We should also ZERO out the memory allocated to the handle, before free'ing it // so there are no traces of the sensitive data left in memory. NativeCode.CredFree(handle); // Mark the handle as invalid for future users. SetHandleAsInvalid(); return(true); } // Return false. return(false); }
/// <summary> /// Accepts credentials in a console window /// </summary> /// <param name="Target">A descriptive text for where teh credentials being asked are used for</param> /// <returns>NetworkCredential object containing the user name, </returns> public static NetworkCredential PromptForCredentialsConsole(string target) { var user = String.Empty; var password = String.Empty; var domain = String.Empty; // Setup the flags and variables StringBuilder userPassword = new StringBuilder(), userID = new StringBuilder(); bool save = true; NativeCode.CredentialUIFlags flags = NativeCode.CredentialUIFlags.CompleteUsername | NativeCode.CredentialUIFlags.ExcludeCertificates; // Prompt the user NativeCode.CredentialUIReturnCodes returnCode = NativeCode.CredUICmdLinePromptForCredentials(target, IntPtr.Zero, 0, userID, 100, userPassword, 100, ref save, flags); password = userPassword.ToString(); StringBuilder userBuilder = new StringBuilder(); StringBuilder domainBuilder = new StringBuilder(); returnCode = NativeCode.CredUIParseUserName(userID.ToString(), userBuilder, int.MaxValue, domainBuilder, int.MaxValue); switch (returnCode) { case NativeCode.CredentialUIReturnCodes.Success: // The username is valid. user = userBuilder.ToString(); domain = domainBuilder.ToString(); break; case NativeCode.CredentialUIReturnCodes.InvalidAccountName: // The username is not valid. user = userID.ToString(); domain = null; break; case NativeCode.CredentialUIReturnCodes.InsufficientBuffer: // One of the buffers is too small. throw new OutOfMemoryException(); case NativeCode.CredentialUIReturnCodes.InvalidParameter : // ulUserMaxChars or ulDomainMaxChars is zero OR userName, user, or domain is NULL. throw new ArgumentNullException("userName"); } return(new NetworkCredential(user, password, domain)); }
/// <summary> /// Saves teh given Network Credential into Windows Credential store /// </summary> /// <param name="Target">Name of the application/Url where the credential is used for</param> /// <param name="credential">Credential to store</param> /// <returns>True:Success, False:Failure</returns> public static bool SaveCredentials(string Target, NetworkCredential credential) { // Go ahead with what we have are stuff it into the CredMan structures. Credential cred = new Credential(credential); cred.TargetName = Target; cred.Persist = NativeCode.Persistance.Entrprise; NativeCode.NativeCredential ncred = cred.GetNativeCredential(); // Write the info into the CredMan storage. try { return NativeCode.CredWrite(ref ncred, 0); } catch (Exception e) { log.error($"Failed saving credentials for {Target}", e); return false; } }
private static bool ParseUserName(string usernameBuf, int maxUserName, int maxDomain, out string user, out string domain) { StringBuilder userBuilder = new StringBuilder(); StringBuilder domainBuilder = new StringBuilder(); user = String.Empty; domain = String.Empty; var returnCode = NativeCode.CredUIParseUserName(usernameBuf, userBuilder, maxUserName, domainBuilder, maxDomain); Debug.WriteLine(returnCode); switch (returnCode) { case NativeCode.CredentialUIReturnCodes.Success: // The username is valid. user = userBuilder.ToString(); domain = domainBuilder.ToString(); return(true); } return(false); }
private static bool PromptForCredentials(string target, NativeCode.CredentialUIInfo credUI, ref bool save, out string user, out string password, out string domain) { user = String.Empty; password = String.Empty; domain = String.Empty; // Setup the flags and variables credUI.cbSize = Marshal.SizeOf(credUI); int errorcode = 0; uint dialogReturn; uint authPackage = 0; IntPtr outCredBuffer = new IntPtr(); uint outCredSize; var flags = NativeCode.PromptForWindowsCredentialsFlags.GenericCredentials | NativeCode.PromptForWindowsCredentialsFlags.EnumerateCurrentUser; flags = save ? flags | NativeCode.PromptForWindowsCredentialsFlags.ShowCheckbox : flags; // Setup the flags and variables int result = NativeCode.CredUIPromptForWindowsCredentials(ref credUI, errorcode, ref authPackage, IntPtr.Zero, 0, out outCredBuffer, out outCredSize, ref save, flags); var usernameBuf = new StringBuilder(100); var passwordBuf = new StringBuilder(100); var domainBuf = new StringBuilder(100); int maxUserName = 100; int maxDomain = 100; int maxPassword = 100; if (result == 0) { if (NativeCode.CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize, usernameBuf, ref maxUserName, domainBuf, ref maxDomain, passwordBuf, ref maxPassword)) { user = usernameBuf.ToString(); password = passwordBuf.ToString(); domain = domainBuf.ToString(); if (String.IsNullOrWhiteSpace(domain)) { Debug.WriteLine("Domain null"); if (!ParseUserName(usernameBuf.ToString(), maxUserName, maxDomain, out user, out domain)) { user = usernameBuf.ToString(); } password = passwordBuf.ToString(); } } //mimic SecureZeroMem function to make sure buffer is zeroed out. SecureZeroMem is not an exported function, neither is RtlSecureZeroMemory var zeroBytes = new byte[outCredSize]; Marshal.Copy(zeroBytes, 0, outCredBuffer, (int)outCredSize); //clear the memory allocated by CredUIPromptForWindowsCredentials NativeCode.CoTaskMemFree(outCredBuffer); return(true); } user = null; domain = null; return(false); }
/// <summary> /// Remove stored credentials from windows credential store /// </summary> /// <param name="Target">Name of the application/Url where the credential is used for</param> /// <returns>True: Success, False: Failure</returns> public static bool RemoveCredentials(string Target) { // Make the API call using the P/Invoke signature return(NativeCode.CredDelete(Target, NativeCode.CredentialType.Generic, 0)); }