/// <summary> /// This will the allocated memory from method <see cref="SecureStringToGlobalAllocUni"/>. /// </summary> /// <remarks> /// This method is located in the <see cref="Marshal"/> class in .NET Framework v2.0 /// </remarks> public static void ZeroFreeGlobalAllocUni(IntPtr s) { // Demand Permission new CryptographicPermission(CryptographicPermissionFlags.Decrypt).Demand(); Win32Native.ZeroMemory(s, (uint)Win32Native.lstrlenW(s) * 2); Marshal.FreeHGlobal(s); }
/// <summary> /// This method creates and displays a configurable dialog box that accepts credentials information from a user. /// </summary> /// <param name="targetName">Contains the name of the target for the credentials, /// typically a server name. For distributed file system (DFS) connections, /// this string is of the form "servername\sharename". /// This parameter is used to identify Target Information when storing and retrieving credentials. /// </param> /// <param name="caption">String containing the title for the dialog box.</param> /// <param name="message">String containing a brief message to display in the dialog box.</param> /// <param name="owner">Specifies the handle to the parent window of the dialog box. /// If this member is NULL, the desktop will be the parent window of the dialog box. /// </param> /// <returns><see cref="SecureCredential"/> object with the supplied credentials.</returns> /// <permission cref="UIPermission">Demand for <see cref="UIPermissionWindow.SafeTopLevelWindows"/> permission.</permission> public static SecureCredential PromptForSecureCredentials(string targetName, string caption, string message, IntPtr owner) { // Parameter validation if (targetName == null) { throw new ArgumentNullException("targetName"); } if (caption == null) { caption = String.Empty; } if (message == null) { message = String.Empty; } new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand(); // Uncommment this lines to use custom bitmap // Bitmap credBMP = new Bitmap(@"..\credui.bmp"); // replace IntPtr.Zero by credBMP.GetHbitmap() Win32Native.CREDUI_INFO creditUI = new Win32Native.CREDUI_INFO(owner, caption, message, IntPtr.Zero); int saveCredentials = 0; StringBuilder user = new StringBuilder(Win32Native.MAX_USER_NAME); byte[] pwd = new byte[Win32Native.MAX_PASSWORD]; GCHandle pwdHandle = GCHandle.Alloc(pwd, GCHandleType.Pinned); try { Win32Native.CredUiFlags flags = Win32Native.CredUiFlags.GENERIC_CREDENTIALS | Win32Native.CredUiFlags.SHOW_SAVE_CHECK_BOX | Win32Native.CredUiFlags.ALWAYS_SHOW_UI | Win32Native.CredUiFlags.EXPECT_CONFIRMATION | Win32Native.CredUiFlags.INCORRECT_PASSWORD; //For more info see: //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/creduipromptforcredentials.asp //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/dpapiusercredentials.asp?frame=true Win32Native.CredUIReturnCodes result = Win32Native.CredUIPromptForCredentialsW( ref creditUI, targetName, IntPtr.Zero, 0, user, Win32Native.MAX_USER_NAME, pwdHandle.AddrOfPinnedObject(), pwd.Length, ref saveCredentials, flags); switch (result) { case Win32Native.CredUIReturnCodes.NO_ERROR: StringBuilder usr = new StringBuilder(Win32Native.MAX_USER_NAME); StringBuilder domain = new StringBuilder(Win32Native.MAX_DOMAIN); result = Win32Native.CredUIParseUserNameW(user.ToString(), usr, Win32Native.MAX_USER_NAME, domain, Win32Native.MAX_DOMAIN); if (result == Win32Native.CredUIReturnCodes.NO_ERROR) { if (saveCredentials == 1) { ConfirmCredentials(targetName, true); } unsafe { return(new SecureCredential(usr.ToString(), (char *)pwdHandle.AddrOfPinnedObject().ToPointer(), Win32Native.lstrlenW(pwdHandle.AddrOfPinnedObject()), domain.ToString())); } } else { throw new SecurityException(TranslateReturnCode(result)); } case Win32Native.CredUIReturnCodes.ERROR_CANCELLED: return(null); default: throw new SecurityException(TranslateReturnCode(result)); } } finally { // Clear pwd data. Array.Clear(pwd, 0, pwd.Length); // Zero out the memory buffer Win32Native.ZeroMemory(pwdHandle.AddrOfPinnedObject(), (uint)pwd.Length); // Free the allocated handle if (pwdHandle.IsAllocated) { pwdHandle.Free(); } } }