/// <summary> /// Enumerate the specified stored credentials in the Windows Credential store /// </summary> /// <param name="target">Name of the application or URL for which the credential is used</param> /// <returns>Return a <see cref="List{ICredential}"/> if success, null if target not found, throw if failed to read stored credentials</returns> public static List <ICredential> EnumerateICredentials(string target = null) { IntPtr pCredentials = IntPtr.Zero; uint count = 0; var success = NativeCode.CredEnumerate(target, 0, out count, out pCredentials); if (!success) { var lastError = Marshal.GetLastWin32Error(); if (lastError == (int)NativeCode.CredentialUIReturnCodes.NotFound) { return(null); } throw new CredentialAPIException($"Unable to Enumerate Credential store", "CredEnumerate", lastError); } List <NetworkCredential> networkCredentials = new List <NetworkCredential>(); Credential[] credentials; try { using var criticalSection = new CriticalCredentialHandle(pCredentials); credentials = criticalSection.EnumerateCredentials(count); } catch (Exception) { return(null); } return(credentials.Select(c => c as ICredential).ToList()); }
/// <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> /// <param name="type">Credential type</param> /// <returns>return the ICredential if success, null if target not found, throw if failed to read stored credentials</returns> public static ICredential GetICredential(string target, CredentialType type = CredentialType.Generic) { IntPtr nCredPtr; // Make the API call using the P/Invoke signature bool isSuccess = NativeCode.CredRead(target, (UInt32)type, 0, out nCredPtr); if (!isSuccess) { var lastError = Marshal.GetLastWin32Error(); if (lastError == (int)NativeCode.CredentialUIReturnCodes.NotFound) { return(null); } throw new CredentialAPIException($"Unable to Read Credential", "CredRead", lastError); } try { using var critCred = new CriticalCredentialHandle(nCredPtr); Credential cred = critCred.GetCredential(); return(cred); } catch (Exception) { return(null); } }
public NetworkCredential ToNetworkCredential() { if (!string.IsNullOrEmpty(UserName)) { var userBuilder = new StringBuilder(UserName.Length + 2); var domainBuilder = new StringBuilder(UserName.Length + 2); var returnCode = NativeCode.CredUIParseUserName(UserName, userBuilder, userBuilder.Capacity, domainBuilder, domainBuilder.Capacity); var lastError = Marshal.GetLastWin32Error(); //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 (returnCode == NativeCode.CredentialUIReturnCodes.InvalidAccountName) { userBuilder.Append(UserName); } else if (returnCode != 0) { throw new CredentialAPIException($"Unable to Parse UserName", "CredUIParseUserName", lastError); } return(new NetworkCredential(userBuilder.ToString(), this.CredentialBlob, domainBuilder.ToString())); } else { return(new NetworkCredential(UserName, this.CredentialBlob)); } }
private static void GetCredentialsFromOutputBuffer(ref string user, ref string password, ref string domain, IntPtr outCredBuffer, uint outCredSize) { int maxUserName = 100; int maxDomain = 100; int maxPassword = 100; var usernameBuf = new StringBuilder(maxUserName); var passwordBuf = new StringBuilder(maxDomain); var domainBuf = new StringBuilder(maxPassword); 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(), usernameBuf.Capacity, domainBuf.Capacity, 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); }
/// <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> /// <param name="type">Credential type</param> /// <returns>return the credentials if success, null if target not found, throw if failed to read stored credentials</returns> public static NetworkCredential GetCredentials(string target, CredentialType type = CredentialType.Generic) { IntPtr nCredPtr; var username = String.Empty; var passwd = String.Empty; var domain = String.Empty; // Make the API call using the P/Invoke signature bool isSuccess = NativeCode.CredRead(target, (NativeCode.CredentialType)type, 0, out nCredPtr); if (!isSuccess) { var lastError = Marshal.GetLastWin32Error(); if (lastError == (int)NativeCode.CredentialUIReturnCodes.NotFound) { return(null); } throw new Win32Exception(lastError, String.Format("'CredRead' call throw an error (Error code: {0})", lastError)); } try { using (var critCred = new CriticalCredentialHandle(nCredPtr)) { Credential cred = critCred.GetCredential(); return(cred.ToNetworkCredential()); } } catch (Exception) { return(null); } }
/// <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> /// <param name="type">Credential type</param> /// <returns>return the credentials if success, null if target not found, throw if failed to read stored credentials</returns> public static NetworkCredential GetCredentials(string target, CredentialType type = CredentialType.Generic) { IntPtr nCredPtr; var username = String.Empty; var passwd = String.Empty; var domain = String.Empty; // Make the API call using the P/Invoke signature bool isSuccess = NativeCode.CredRead(target, (NativeCode.CredentialType)type, 0, out nCredPtr); if (!isSuccess) { var lastError = Marshal.GetLastWin32Error(); if (lastError == (int)NativeCode.CredentialUIReturnCodes.NotFound) { return(null); } throw new Win32Exception(lastError, String.Format("'CredRead' call throw an error (Error code: {0})", lastError)); } try { using (var critCred = new CriticalCredentialHandle(nCredPtr)) { Credential cred = critCred.GetCredential(); passwd = cred.CredentialBlob; if (!String.IsNullOrEmpty(cred.UserName)) { var user = cred.UserName; StringBuilder userBuilder = new StringBuilder(cred.UserName.Length + 2); StringBuilder domainBuilder = new StringBuilder(cred.UserName.Length + 2); var returnCode = NativeCode.CredUIParseUserName(user, userBuilder, userBuilder.Capacity, domainBuilder, domainBuilder.Capacity); var lastError = Marshal.GetLastWin32Error(); //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 (returnCode == NativeCode.CredentialUIReturnCodes.InvalidAccountName) { userBuilder.Append(user); } else if (returnCode != 0) { throw new Win32Exception(lastError, String.Format("CredUIParseUserName throw an error (Error code: {0})", lastError)); } username = userBuilder.ToString(); domain = domainBuilder.ToString(); } return(new NetworkCredential(username, passwd, domain)); } } catch (Exception) { return(null); } }
/// <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>null if target not found, else stored credentials</returns> public static NetworkCredential GetCredentials(string Target, CredentialType type = CredentialType.Generic) { 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)type, 0, out nCredPtr); int lastError = Marshal.GetLastWin32Error(); if (!ret) { throw new Win32Exception(lastError, "CredDelete throw an error"); } // If the API was successful then... if (ret) { try { using (CriticalCredentialHandle critCred = new CriticalCredentialHandle(nCredPtr)) { Credential cred = critCred.GetCredential(); passwd = cred.CredentialBlob; if (!String.IsNullOrEmpty(cred.UserName)) { var user = cred.UserName; StringBuilder userBuilder = new StringBuilder(cred.UserName.Length + 2); StringBuilder domainBuilder = new StringBuilder(cred.UserName.Length + 2); var ret1 = NativeCode.CredUIParseUserName(user, userBuilder, userBuilder.Capacity, domainBuilder, domainBuilder.Capacity); lastError = Marshal.GetLastWin32Error(); //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 (ret1 == NativeCode.CredentialUIReturnCodes.InvalidAccountName) { userBuilder.Append(user); } else if ((uint)ret1 > 0) { throw new Win32Exception(lastError, "CredUIParseUserName throw an error"); } username = userBuilder.ToString(); domain = domainBuilder.ToString(); } return(new NetworkCredential(username, passwd, domain)); } } catch (Exception e) { return(null); } } return(null); }
/// <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 var ret = NativeCode.CredDelete(Target, NativeCode.CredentialType.Generic, 0); int lastError = Marshal.GetLastWin32Error(); if (!ret) { throw new Win32Exception(lastError, "CredDelete throw an error"); } return(ret); }
public bool RemoveCredential() { // Make the API call using the P/Invoke signature var isSuccess = NativeCode.CredDelete(TargetName, (uint)Type, 0); if (isSuccess) { return(true); } int lastError = Marshal.GetLastWin32Error(); throw new CredentialAPIException($"Unable to Delete Credential", "CredDelete", lastError); }
/// <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, throw if failed</returns> public static bool RemoveCredentials(string target) { // Make the API call using the P/Invoke signature var isSuccess = NativeCode.CredDelete(target, NativeCode.CredentialType.Generic, 0); if (isSuccess) { return(true); } int lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(lastError, String.Format("'CredDelete' call throw an error (Error code: {0})", lastError)); }
/// <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, throw if failed</returns> public static bool RemoveCredentials(string target, CredentialType type = CredentialType.Generic) { // Make the API call using the P/Invoke signature var isSuccess = NativeCode.CredDelete(target, (UInt32)type, 0); if (isSuccess) { return(true); } int lastError = Marshal.GetLastWin32Error(); throw new CredentialAPIException($"Unable to Delete Credential", "CredDelete", lastError); }
private static bool PromptForCredentials(string target, NativeCode.CredentialUIInfo credUI, ref bool save, ref string user, out string password, out string domain) { password = string.Empty; domain = string.Empty; // Setup the flags and variables credUI.cbSize = Marshal.SizeOf(credUI); int errorcode = 0; uint authPackage = 0; var outCredBuffer = new IntPtr(); uint outCredSize; var flags = NativeCode.PromptForWindowsCredentialsFlags.GenericCredentials | NativeCode.PromptForWindowsCredentialsFlags.EnumerateCurrentUser; flags = save ? flags | NativeCode.PromptForWindowsCredentialsFlags.ShowCheckbox : flags; // Prefill username IntPtr inCredBuffer; int inCredSize; GetInputBuffer(user, out inCredBuffer, out inCredSize); // Setup the flags and variables int result = NativeCode.CredUIPromptForWindowsCredentials(ref credUI, errorcode, ref authPackage, inCredBuffer, inCredSize, out outCredBuffer, out outCredSize, ref save, flags); if (inCredBuffer != IntPtr.Zero) { NativeCode.CoTaskMemFree(inCredBuffer); } if (result == 0) { GetCredentialsFromOutputBuffer(ref user, ref password, ref domain, outCredBuffer, outCredSize); return(true); } user = null; domain = null; 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); }
internal static bool ParseUserName(string usernameBuf, int maxUserName, int maxDomain, out string user, out string domain) { var userBuilder = new StringBuilder(maxUserName); var domainBuilder = new StringBuilder(maxDomain); 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); }
/// <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 | NativeCode.CredentialUIFlags.GenericCredentials; // 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 the 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, throw if failed</returns> public static bool SaveCredentials(string target, NetworkCredential credential) { // Go ahead with what we have are stuff it into the CredMan structures. var cred = new Credential(credential) { TargetName = target, Persist = NativeCode.Persistance.Entrprise }; NativeCode.NativeCredential ncred = cred.GetNativeCredential(); // Write the info into the CredMan storage. if (NativeCode.CredWrite(ref ncred, 0)) { return(true); } int lastError = Marshal.GetLastWin32Error(); string message = String.Format("'CredWrite' call throw an error (Error code: {0})", lastError); throw new Win32Exception(lastError, message); }
/// <summary> /// Saves the 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. bool written = NativeCode.CredWrite(ref ncred, 0); int lastError = Marshal.GetLastWin32Error(); if (written) { return(true); } else { string message = string.Format("CredWrite failed with the error code {0}.", lastError); throw new Exception(message); } }
private static void GetInputBuffer(string user, out IntPtr inCredBuffer, out int inCredSize) { if (!string.IsNullOrEmpty(user)) { var usernameBuf = new StringBuilder(user); var passwordBuf = new StringBuilder(); inCredSize = 1024; inCredBuffer = Marshal.AllocCoTaskMem(inCredSize); if (NativeCode.CredPackAuthenticationBuffer(0x00, usernameBuf, passwordBuf, inCredBuffer, ref inCredSize)) { return; } if (inCredBuffer != IntPtr.Zero) { NativeCode.CoTaskMemFree(inCredBuffer); } } inCredBuffer = IntPtr.Zero; inCredSize = 0; }
internal static NetworkCredential ToNetworkCredential(this Credential cred) { if (cred == null) { return(null); } string username = string.Empty; string domain = string.Empty; var passwd = cred.CredentialBlob; if (!string.IsNullOrEmpty(cred.UserName)) { var user = cred.UserName; var userBuilder = new StringBuilder(cred.UserName.Length + 2); var domainBuilder = new StringBuilder(cred.UserName.Length + 2); var returnCode = NativeCode.CredUIParseUserName(user, userBuilder, userBuilder.Capacity, domainBuilder, domainBuilder.Capacity); var lastError = Marshal.GetLastWin32Error(); //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 (returnCode == NativeCode.CredentialUIReturnCodes.InvalidAccountName) { userBuilder.Append(user); } else if (returnCode != 0) { throw new Win32Exception(lastError, String.Format("CredUIParseUserName throw an error (Error code: {0})", lastError)); } username = userBuilder.ToString(); domain = domainBuilder.ToString(); } return(new NetworkCredential(username, passwd, domain)); }
/// <summary> /// Enumerate the specified stored credentials in the Windows Credential store /// </summary> /// <param name="target">Name of the application or URL for which the credential is used</param> /// <returns>Return a <see cref="List{NetworkCredential}"/> if success, null if target not found, throw if failed to read stored credentials</returns> public static List <NetworkCredential> EnumerateCredentials(string target = null) { IntPtr pCredentials = IntPtr.Zero; uint count = 0; var success = NativeCode.CredEnumerate(target, 0, out count, out pCredentials); if (!success) { var lastError = Marshal.GetLastWin32Error(); if (lastError == (int)NativeCode.CredentialUIReturnCodes.NotFound) { return(null); } throw new Win32Exception(lastError, string.Format("'CredEnumerate' call throw an error (Error code: {0})", lastError)); } List <NetworkCredential> networkCredentials = new List <NetworkCredential>(); Credential[] credentials; try { using (var criticalSection = new CriticalCredentialHandle(pCredentials)) { credentials = criticalSection.EnumerateCredentials(count); } } catch (Exception) { return(null); } return(credentials.Select(c => c.ToNetworkCredential()).ToList()); }
public bool SaveCredential(bool AllowBlankPassword = false) { IntPtr buffer = default(IntPtr); GCHandle pinned = default(GCHandle); if (!String.IsNullOrEmpty(this.Comment) && Encoding.Unicode.GetBytes(this.Comment).Length > 256) { throw new ArgumentException("Comment can't be more than 256 bytes long", "Comment"); } if (String.IsNullOrEmpty(this.TargetName)) { throw new ArgumentNullException("TargetName", "TargetName can't be Null or Empty"); } else if (this.TargetName.Length > 32767) { throw new ArgumentNullException("TargetName can't be more than 32kB", "TargetName"); } if (!AllowBlankPassword && String.IsNullOrEmpty(this.CredentialBlob)) { throw new ArgumentNullException("CredentialBlob", "CredentialBlob can't be Null or Empty"); } NativeCode.NativeCredential ncred = new NativeCode.NativeCredential { Comment = this.Comment, TargetAlias = null, Type = (UInt32)this.Type, Persist = (UInt32)this.Persistance, UserName = this.UserName, TargetName = this.TargetName, CredentialBlobSize = (UInt32)Encoding.Unicode.GetBytes(this.CredentialBlob).Length }; if (ncred.CredentialBlobSize > MaxCredentialBlobSize) { throw new ArgumentException($"Credential can't be more than {MaxCredentialBlobSize} bytes long", "CredentialBlob"); } ncred.CredentialBlob = Marshal.StringToCoTaskMemUni(this.CredentialBlob); if (this.LastWritten != DateTime.MinValue) { var fileTime = this.LastWritten.ToFileTimeUtc(); ncred.LastWritten.dwLowDateTime = (int)(fileTime & 0xFFFFFFFFL); ncred.LastWritten.dwHighDateTime = (int)((fileTime >> 32) & 0xFFFFFFFFL); } NativeCode.NativeCredentialAttribute[] nativeAttribs = null; try { if (Attributes == null || Attributes.Count == 0) { ncred.AttributeCount = 0; ncred.Attributes = IntPtr.Zero; } else { if (Attributes.Count > 64) { throw new ArgumentException("Credentials can't have more than 64 Attributes!!"); } ncred.AttributeCount = (UInt32)Attributes.Count; nativeAttribs = new NativeCode.NativeCredentialAttribute[Attributes.Count]; var attribSize = Marshal.SizeOf(typeof(NativeCode.NativeCredentialAttribute)); byte[] rawData = new byte[Attributes.Count * attribSize]; buffer = Marshal.AllocHGlobal(attribSize); var formatter = new BinaryFormatter(); var i = 0; foreach (var a in Attributes) { if (a.Key.Length > 256) { throw new ArgumentException($"Attribute names can't be more than 256 bytes long. Error with key:{a.Key}", a.Key); } if (a.Value == null) { throw new ArgumentNullException(a.Key, $"Attribute value cant'be null. Error with key:{a.Key}"); } if (!a.Value.GetType().IsSerializable) { throw new ArgumentException($"Attribute value must be Serializable. Error with key:{a.Key}", a.Key); } using var stream = new MemoryStream(); formatter.Serialize(stream, a.Value); var value = stream.ToArray(); if (value.Length > 256) { throw new ArgumentException($"Attribute values can't be more than 256 bytes long after serialization. Error with Value for key:{a.Key}", a.Key); } var attrib = new NativeCode.NativeCredentialAttribute { Keyword = a.Key, ValueSize = (UInt32)value.Length }; attrib.Value = Marshal.AllocHGlobal(value.Length); Marshal.Copy(value, 0, attrib.Value, value.Length); nativeAttribs[i] = attrib; Marshal.StructureToPtr(attrib, buffer, false); Marshal.Copy(buffer, rawData, i * attribSize, attribSize); i++; } pinned = GCHandle.Alloc(rawData, GCHandleType.Pinned); ncred.Attributes = pinned.AddrOfPinnedObject(); } // Write the info into the CredMan storage. if (NativeCode.CredWrite(ref ncred, 0)) { return(true); } else { int lastError = Marshal.GetLastWin32Error(); throw new CredentialAPIException($"Unable to Save Credential", "CredWrite", lastError); } } finally { if (ncred.CredentialBlob != default(IntPtr)) { Marshal.FreeCoTaskMem(ncred.CredentialBlob); } if (nativeAttribs != null) { foreach (var a in nativeAttribs) { if (a.Value != default(IntPtr)) { Marshal.FreeHGlobal(a.Value); } } if (pinned.IsAllocated) { pinned.Free(); } if (buffer != default(IntPtr)) { Marshal.FreeHGlobal(buffer); } } } }
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 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(), usernameBuf.Capacity, domainBuf.Capacity, 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); }