Beispiel #1
0
        private Credentials PromptForWindowsCredentials(string authority, string workspaceName)
        {
            var credui = new NativeMethods.CREDUI_INFO {
                cbSize         = Marshal.SizeOf(typeof(NativeMethods.CREDUI_INFO)),
                hwndParent     = _services.GetService <IPlatformServices>().ApplicationWindowHandle,
                pszCaptionText = Resources.Info_ConnectingTo.FormatInvariant(workspaceName)
            };

            uint authPkg     = 0;
            var  credStorage = IntPtr.Zero;
            var  save        = true;
            var  flags       = NativeMethods.CredUIWinFlags.CREDUIWIN_CHECKBOX;
            // For password, use native memory so it can be securely freed.
            var passwordStorage = CreatePasswordBuffer();
            var inCredSize      = 1024;
            var inCredBuffer    = Marshal.AllocCoTaskMem(inCredSize);

            try {
                if (!NativeMethods.CredPackAuthenticationBuffer(0, WindowsIdentity.GetCurrent().Name, "", inCredBuffer, ref inCredSize))
                {
                    var error = Marshal.GetLastWin32Error();
                    throw new Win32Exception(error);
                }

                var err = NativeMethods.CredUIPromptForWindowsCredentials(ref credui, 0, ref authPkg, inCredBuffer, (uint)inCredSize, out credStorage, out var credSize, ref save, flags);
                if (err != 0)
                {
                    throw new OperationCanceledException();
                }

                var userNameBuilder = new StringBuilder(NativeMethods.CRED_MAX_USERNAME_LENGTH);
                var userNameLen     = NativeMethods.CRED_MAX_USERNAME_LENGTH;
                var domainBuilder   = new StringBuilder(NativeMethods.CRED_MAX_USERNAME_LENGTH);
                var domainLen       = NativeMethods.CRED_MAX_USERNAME_LENGTH;
                var passLen         = NativeMethods.CREDUI_MAX_PASSWORD_LENGTH;
                if (!NativeMethods.CredUnPackAuthenticationBuffer(NativeMethods.CRED_PACK_PROTECTED_CREDENTIALS, credStorage, credSize, userNameBuilder, ref userNameLen, domainBuilder, ref domainLen, passwordStorage, ref passLen))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                var userName = userNameBuilder.ToString();
                var password = SecurityUtilities.SecureStringFromNativeBuffer(passwordStorage);
                return(Save(userName, password, authority, save));
            } finally {
                if (inCredBuffer != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(inCredBuffer);
                }

                if (credStorage != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(credStorage);
                }

                if (passwordStorage != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordStorage);
                }
            }
        }
        private void GetUserNamePasswordWindows(SvnUserNamePasswordEventArgs e, string description)
        {
            NativeMethods.CREDUI_INFO info = new NativeMethods.CREDUI_INFO();
            info.pszCaptionText = Strings.ConnectToSubversion;
            info.pszMessageText = description;
            info.hwndParent     = (_window != null) ? _window.Handle : IntPtr.Zero;
            info.cbSize         = Marshal.SizeOf(typeof(NativeMethods.CREDUI_INFO));

            StringBuilder sbUserName = new StringBuilder(e.InitialUserName ?? "", 1024);
            StringBuilder sbPassword = new StringBuilder("", 1024);

            bool dlgSave = false;

            int flags = (int)NativeMethods.CREDUI_FLAGS.GENERIC_CREDENTIALS | (int)NativeMethods.CREDUI_FLAGS.ALWAYS_SHOW_UI | (int)NativeMethods.CREDUI_FLAGS.DO_NOT_PERSIST;

            if (e.MaySave)
            {
                flags |= (int)NativeMethods.CREDUI_FLAGS.SHOW_SAVE_CHECK_BOX;
            }

            switch (NativeMethods.CredUIPromptForCredentials(ref info, e.Realm, IntPtr.Zero, 0, sbUserName, 1024, sbPassword, 1024, ref dlgSave,
                                                             (NativeMethods.CREDUI_FLAGS)flags))
            {
            case NativeMethods.CredUIReturnCodes.NO_ERROR:
                e.UserName = sbUserName.ToString();
                e.Password = sbPassword.ToString();
                e.Save     = e.MaySave && dlgSave;
                break;

            case NativeMethods.CredUIReturnCodes.ERROR_CANCELLED:
                e.Break = true;
                break;
            }
        }
Beispiel #3
0
        private static NativeMethods.CredUIReturnCodes CredUIPromptForCredentials(NativeMethods.CREDUI_INFO credUiInfo, ref bool pfSave, out string userName, out SecureString password)
        {
            StringBuilder stringBuilder  = new StringBuilder(CredentialHelper.MaxUserNameLength);
            StringBuilder stringBuilder2 = new StringBuilder(CredentialHelper.MaxPasswordLength);

            NativeMethods.CredUIReturnCodes credUIReturnCodes = NativeMethods.CredUIPromptForCredentials(ref credUiInfo, null, IntPtr.Zero, 0U, stringBuilder, stringBuilder.Capacity, stringBuilder2, stringBuilder2.Capacity, ref pfSave, 262338);
            userName = ((credUIReturnCodes == null) ? stringBuilder.ToString() : null);
            password = ((credUIReturnCodes == null) ? stringBuilder2.ToString().ConvertToSecureString() : null);
            return(credUIReturnCodes);
        }
Beispiel #4
0
        private NativeMethods.CREDUI_INFO CreateCredUIInfo(IntPtr owner, bool downlevelText)
        {
            NativeMethods.CREDUI_INFO info = new NativeMethods.CREDUI_INFO();
            info.cbSize     = System.Runtime.InteropServices.Marshal.SizeOf(info);
            info.hwndParent = owner;
            if (downlevelText)
            {
                info.pszCaptionText = WindowTitle;
                switch (DownlevelTextMode)
                {
                case DownlevelTextMode.MainInstructionAndContent:
                    if (MainInstruction.Length == 0)
                    {
                        info.pszMessageText = Content;
                    }
                    else if (Content.Length == 0)
                    {
                        info.pszMessageText = MainInstruction;
                    }
                    else
                    {
                        info.pszMessageText = MainInstruction + Environment.NewLine + Environment.NewLine + Content;
                    }
                    break;

                case DownlevelTextMode.MainInstructionOnly:
                    info.pszMessageText = MainInstruction;
                    break;

                case DownlevelTextMode.ContentOnly:
                    info.pszMessageText = Content;
                    break;
                }
            }
            else
            {
                // Vista and later don't use the window title.
                info.pszMessageText = Content;
                info.pszCaptionText = MainInstruction;
            }
            return(info);
        }
Beispiel #5
0
        private bool PromptForCredentialsCredUI(IntPtr owner, bool storedCredentials)
        {
            NativeMethods.CREDUI_INFO  info  = CreateCredUIInfo(owner, true);
            NativeMethods.CREDUI_FLAGS flags = NativeMethods.CREDUI_FLAGS.GENERIC_CREDENTIALS | NativeMethods.CREDUI_FLAGS.DO_NOT_PERSIST | NativeMethods.CREDUI_FLAGS.ALWAYS_SHOW_UI;
            if (ShowSaveCheckBox)
            {
                flags |= NativeMethods.CREDUI_FLAGS.SHOW_SAVE_CHECK_BOX;
            }

            StringBuilder user = new StringBuilder(NativeMethods.CREDUI_MAX_USERNAME_LENGTH);

            user.Append(UserName);
            StringBuilder pw = new StringBuilder(NativeMethods.CREDUI_MAX_PASSWORD_LENGTH);

            pw.Append(Password);

            NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIPromptForCredentials(ref info, Target, IntPtr.Zero, 0, user, NativeMethods.CREDUI_MAX_USERNAME_LENGTH, pw, NativeMethods.CREDUI_MAX_PASSWORD_LENGTH, ref _isSaveChecked, flags);
            switch (result)
            {
            case NativeMethods.CredUIReturnCodes.NO_ERROR:
                UserName = user.ToString();
                Password = pw.ToString();
                if (ShowSaveCheckBox)
                {
                    _confirmTarget = Target;
                    // If the credential was stored previously but the user has now cleared the save checkbox,
                    // we want to delete the credential.
                    if (storedCredentials && !IsSaveChecked)
                    {
                        DeleteCredential(Target);
                    }
                }
                return(true);

            case NativeMethods.CredUIReturnCodes.ERROR_CANCELLED:
                return(false);

            default:
                throw new CredentialException((int)result);
            }
        }
Beispiel #6
0
        private static NativeMethods.CredUIReturnCodes SspiPromptForCredentials(NativeMethods.CREDUI_INFO credUiInfo, Uri targetUri, ref bool pfSave, out string userName, out SecureString password)
        {
            IntPtr zero = IntPtr.Zero;

            NativeMethods.CredUIReturnCodes credUIReturnCodes = NativeMethods.SspiPromptForCredentials(targetUri.Host, ref credUiInfo, 0U, "Negotiate", IntPtr.Zero, ref zero, ref pfSave, 1);
            if (credUIReturnCodes == null)
            {
                try
                {
                    CredentialHelper.AuthIdentityToCredential(zero, out userName, out password);
                    return(credUIReturnCodes);
                }
                finally
                {
                    NativeMethods.SspiFreeAuthIdentity(zero);
                }
            }
            userName = null;
            password = null;
            return(credUIReturnCodes);
        }
Beispiel #7
0
        public static bool ShowDialog(
            IntPtr ParentWindowHandle,
            string title,
            string message,
            string target,
            ref string username,
            ref string password)
        {
            //get any exceptions out of the way
            RuntimeHelpers.PrepareConstrainedRegions();

            //allocate memory for returns
            StringBuilder sbUsername = new StringBuilder(NativeMethods.CRED_MAX_USERNAME_LENGTH);

            if (username != null)
            {
                sbUsername.Append(username);
            }
            //bad, bad, bad... cleartext passwords (WCF doesn't support securestring)
            StringBuilder sbPassword = new StringBuilder(NativeMethods.CREDUI_MAX_PASSWORD_LENGTH);

            if (password != null)
            {
                sbPassword.Append(password);
            }

            //setup args
            var credInfo = new NativeMethods.CREDUI_INFO()
            {
                hwndParent     = ParentWindowHandle,
                hbmBanner      = IntPtr.Zero,
                pszCaptionText = title,
                pszMessageText = message
            };

            credInfo.cbSize = Marshal.SizeOf(credInfo);
            bool save = false;

            var ret = NativeMethods.CredUIPromptForCredentials(
                ref credInfo, target, IntPtr.Zero, 0,
                sbUsername, NativeMethods.CRED_MAX_USERNAME_LENGTH,
                sbPassword, NativeMethods.CREDUI_MAX_PASSWORD_LENGTH,
                ref save, NativeMethods.CREDUI_FLAGS.GENERIC_CREDENTIALS
                | NativeMethods.CREDUI_FLAGS.ALWAYS_SHOW_UI
                | NativeMethods.CREDUI_FLAGS.DO_NOT_PERSIST
                | NativeMethods.CREDUI_FLAGS.EXCLUDE_CERTIFICATES);

            username = sbUsername.ToString();
            password = sbPassword.ToString();

            if (ret == NativeMethods.CredUIReturnCodes.NO_ERROR)
            {
                return(true);
            }
            else if (ret == NativeMethods.CredUIReturnCodes.ERROR_CANCELLED)
            {
                return(false);
            }
            else
            {
                throw new Exception(ret.ToString());
            }
        }
Beispiel #8
0
        private bool PromptForCredentialsCredUIWin(IntPtr owner, bool storedCredentials)
        {
            NativeMethods.CREDUI_INFO    info  = CreateCredUIInfo(owner, false);
            NativeMethods.CredUIWinFlags flags = NativeMethods.CredUIWinFlags.Generic;
            if (ShowSaveCheckBox)
            {
                flags |= NativeMethods.CredUIWinFlags.Checkbox;
            }

            IntPtr inBuffer  = IntPtr.Zero;
            IntPtr outBuffer = IntPtr.Zero;

            try
            {
                uint inBufferSize = 0;
                if (UserName.Length > 0)
                {
                    NativeMethods.CredPackAuthenticationBuffer(0, UserName, Password, IntPtr.Zero, ref inBufferSize);
                    if (inBufferSize > 0)
                    {
                        inBuffer = Marshal.AllocCoTaskMem((int)inBufferSize);
                        if (!NativeMethods.CredPackAuthenticationBuffer(0, UserName, Password, inBuffer, ref inBufferSize))
                        {
                            throw new CredentialException(Marshal.GetLastWin32Error());
                        }
                    }
                }

                uint outBufferSize;
                uint package = 0;
                NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIPromptForWindowsCredentials(ref info, 0, ref package, inBuffer, inBufferSize, out outBuffer, out outBufferSize, ref _isSaveChecked, flags);
                switch (result)
                {
                case NativeMethods.CredUIReturnCodes.NO_ERROR:
                    StringBuilder userName     = new StringBuilder(NativeMethods.CREDUI_MAX_USERNAME_LENGTH);
                    StringBuilder password     = new StringBuilder(NativeMethods.CREDUI_MAX_PASSWORD_LENGTH);
                    uint          userNameSize = (uint)userName.Capacity;
                    uint          passwordSize = (uint)password.Capacity;
                    uint          domainSize   = 0;
                    if (!NativeMethods.CredUnPackAuthenticationBuffer(0, outBuffer, outBufferSize, userName, ref userNameSize, null, ref domainSize, password, ref passwordSize))
                    {
                        throw new CredentialException(Marshal.GetLastWin32Error());
                    }
                    UserName = userName.ToString();
                    Password = password.ToString();
                    if (ShowSaveCheckBox)
                    {
                        _confirmTarget = Target;
                        // If the credential was stored previously but the user has now cleared the save checkbox,
                        // we want to delete the credential.
                        if (storedCredentials && !IsSaveChecked)
                        {
                            DeleteCredential(Target);
                        }
                    }
                    return(true);

                case NativeMethods.CredUIReturnCodes.ERROR_CANCELLED:
                    return(false);

                default:
                    throw new CredentialException((int)result);
                }
            }
            finally
            {
                if (inBuffer != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(inBuffer);
                }
                if (outBuffer != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(outBuffer);
                }
            }
        }
        /// <summary>
        /// Overridden. Displays the modal dialog.
        /// </summary>
        /// <param name="hwndOwner">The handle of the window that owns the dialog box.</param>
        /// <returns><b>true</b> if the user completed the entry successfully, otherwise <b>false</b>.</returns>
        protected override bool RunDialog(IntPtr hwndOwner)
        {
            if (this.TargetName == null)
            {
                ThrowHelper.ThrowInvalidOperationException(Resources.Exception_TargetNameCannotBeNullReference);
            }

            bool retval = false;

            int size = Marshal.SizeOf(typeof(NativeMethods.CREDUI_INFO));

            IntPtr pUiCred = IntPtr.Zero;
            try
            {
                NativeMethods.CREDUI_INFO dlg = new NativeMethods.CREDUI_INFO();
                dlg.size = size;

                dlg.caption = this.Caption;
                dlg.message = this.Message;
                dlg.hwndOwner = hwndOwner;

                pUiCred = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(dlg, pUiCred, true);

                bool saveChecked = this.SaveChecked;

                // Use the default maximum lengths if the caller did not provide a different value.
                int userNameLength = this.MaxUserNameLength == 0 ? NativeMethods.CREDUI_MAX_USERNAME_LENGTH : this.MaxUserNameLength;
                int passwordLength = this.MaxPasswordLength == 0 ? NativeMethods.CREDUI_MAX_PASSWORD_LENGTH : this.MaxPasswordLength;

                StringBuilder userNameBuffer = new StringBuilder(userNameLength);
                StringBuilder passwordBuffer = new StringBuilder(passwordLength);

                if (!string.IsNullOrEmpty(this.UserName))
                {
                    userNameBuffer.Append(this.UserName);
                }

                if (!string.IsNullOrEmpty(this.Password))
                {
                    passwordBuffer.Append(this.Password);
                }

                NativeMethods.CREDUI_FLAGS flags = this.BuildDialogOptions();

                int ret = SafeNativeMethods.Instance.PromptForCredentials(pUiCred, this.TargetName, IntPtr.Zero, NativeMethods.SUCCESS, userNameBuffer, userNameLength, passwordBuffer, passwordLength, ref saveChecked, flags);
                if (ret == NativeMethods.ERROR_CANCELLED)
                {
                    retval = false;
                }
                else if (ret == NativeMethods.SUCCESS)
                {
                    // Update the output values on the component with the new values returned from the dialog box.
                    this.SaveChecked = saveChecked;

                    this.UserName = userNameBuffer.ToString();
                    this.Password = passwordBuffer.ToString();

                    retval = true;
                }
                else
                {
                    ThrowHelper.ThrowWin32Exception(ret);
                }
            }
            finally
            {
                if (pUiCred != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pUiCred);
                }
            }

            return retval;
        }
Beispiel #10
0
        /// <summary>
        /// When overridden in a derived class, specifies a common dialog box.
        /// </summary>
        /// <param name="parentWindowHandle">A value that represents the window handle of the owner window for the common dialog box.</param>
        /// <returns>
        /// true if the dialog box was successfully run; otherwise, false.
        /// </returns>
        protected override bool RunDialog(IntPtr parentWindowHandle)
        {
            NativeMethods.CREDUI_INFO info = new NativeMethods.CREDUI_INFO(parentWindowHandle, this.Caption, this.Message, this.Banner);
            try
            {
                StringBuilder userName = new StringBuilder(this.UserName, maxStringLength);
                StringBuilder password = new StringBuilder(maxStringLength);
                bool          save     = this.SaveChecked;

                if (string.IsNullOrEmpty(this.Target))
                {
                    this.Target = this.DefaultTarget;
                }
                NativeMethods.CredUIReturnCodes ret = NativeMethods.CredUIPromptForCredentials(ref info, this.Target, IntPtr.Zero,
                                                                                               this.AuthenticationError, userName, maxStringLength, password, maxStringLength, ref save, this.Options);
                switch (ret)
                {
                case NativeMethods.CredUIReturnCodes.NO_ERROR:
                    if (this.ValidatePassword && !IsValidPassword(userName.ToString(), password.ToString()))
                    {
                        return(false);
                    }

                    /*if (save)
                     * {
                     *      CredUIReturnCodes cret = CredUIConfirmCredentials(this.Target, false);
                     *      if (cret != CredUIReturnCodes.NO_ERROR && cret != CredUIReturnCodes.ERROR_INVALID_PARAMETER)
                     *      {
                     *              this.Options |= CredentialsDialogOptions.IncorrectPassword;
                     *              return false;
                     *      }
                     * }*/
                    break;

                case NativeMethods.CredUIReturnCodes.ERROR_CANCELLED:
                    return(false);

                default:
                    throw new InvalidOperationException(string.Format("Unknown error in CredentialsDialog. Error: 0x{0:X}", ret));
                }

                if (this.EncryptPassword)
                {
                    // Convert the password to a SecureString
                    SecureString newPassword = StringBuilderToSecureString(password);

                    // Clear the old password and set the new one (read-only)
                    if (this.SecurePassword != null)
                    {
                        this.SecurePassword.Dispose();
                    }
                    newPassword.MakeReadOnly();
                    this.SecurePassword = newPassword;
                }
                else
                {
                    this.Password = password.ToString();
                }

                // Update other properties
                this.UserName    = userName.ToString();
                this.SaveChecked = save;
                return(true);
            }
            finally
            {
                info.Dispose();
            }
        }
        /// <summary>
        /// Overridden. Displays the modal dialog.
        /// </summary>
        /// <param name="hwndOwner">The handle of the window that owns the dialog box.</param>
        /// <returns><b>true</b> if the user completed the entry successfully, otherwise <b>false</b>.</returns>
        protected override bool RunDialog(IntPtr hwndOwner)
        {
            if (this.TargetName == null)
            {
                ThrowHelper.ThrowInvalidOperationException(Resources.Exception_TargetNameCannotBeNullReference);
            }

            bool retval = false;

            int size = Marshal.SizeOf(typeof(NativeMethods.CREDUI_INFO));

            IntPtr pUiCred = IntPtr.Zero;

            try
            {
                NativeMethods.CREDUI_INFO dlg = new NativeMethods.CREDUI_INFO();
                dlg.size = size;

                dlg.caption   = this.Caption;
                dlg.message   = this.Message;
                dlg.hwndOwner = hwndOwner;

                pUiCred = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(dlg, pUiCred, true);

                bool saveChecked = this.SaveChecked;

                // Use the default maximum lengths if the caller did not provide a different value.
                int userNameLength = this.MaxUserNameLength == 0 ? NativeMethods.CREDUI_MAX_USERNAME_LENGTH : this.MaxUserNameLength;
                int passwordLength = this.MaxPasswordLength == 0 ? NativeMethods.CREDUI_MAX_PASSWORD_LENGTH : this.MaxPasswordLength;

                StringBuilder userNameBuffer = new StringBuilder(userNameLength);
                StringBuilder passwordBuffer = new StringBuilder(passwordLength);

                if (!string.IsNullOrEmpty(this.UserName))
                {
                    userNameBuffer.Append(this.UserName);
                }

                if (!string.IsNullOrEmpty(this.Password))
                {
                    passwordBuffer.Append(this.Password);
                }

                NativeMethods.CREDUI_FLAGS flags = this.BuildDialogOptions();

                int ret = SafeNativeMethods.Instance.PromptForCredentials(pUiCred, this.TargetName, IntPtr.Zero, NativeMethods.SUCCESS, userNameBuffer, userNameLength, passwordBuffer, passwordLength, ref saveChecked, flags);
                if (ret == NativeMethods.ERROR_CANCELLED)
                {
                    retval = false;
                }
                else if (ret == NativeMethods.SUCCESS)
                {
                    // Update the output values on the component with the new values returned from the dialog box.
                    this.SaveChecked = saveChecked;

                    this.UserName = userNameBuffer.ToString();
                    this.Password = passwordBuffer.ToString();

                    retval = true;
                }
                else
                {
                    ThrowHelper.ThrowWin32Exception(ret);
                }
            }
            finally
            {
                if (pUiCred != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pUiCred);
                }
            }

            return(retval);
        }
Beispiel #12
0
        }         // proc Commit

        #endregion

        #region -- ShowWindowsLogin ---------------------------------------------------

        /// <summary>Show the default windows login dialog.</summary>
        /// <param name="hwndParent"></param>
        /// <returns></returns>
        public bool ShowWindowsLogin(IntPtr hwndParent)
        {
            int hr;
            var dwAuthPackage     = (uint)0;
            var inCredBuffer      = IntPtr.Zero;
            var inCredBufferSize  = 0;
            var outCredBuffer     = IntPtr.Zero;
            var outCredBufferSize = 0;

            var newPasswordLength = NativeMethods.CREDUI_MAX_PASSWORD_LENGTH;
            var newPassword       = Marshal.AllocCoTaskMem(newPasswordLength);

            try
            {
                // pack the arguments
                if (isLoaded)
                {
                    var emptyPasswordSet = false;
                    var emptyPassword    = IntPtr.Zero;
                    try
                    {
                        if (password == IntPtr.Zero)
                        {
                            emptyPassword = Marshal.AllocCoTaskMem(2);
                            UnsafeNativeMethods.ZeroMemory(emptyPassword, 2);

                            password         = emptyPassword;
                            emptyPasswordSet = true;
                        }

                        if (!NativeMethods.CredPackAuthenticationBuffer(4 /*CRED_PACK_GENERIC_CREDENTIALS*/, credential.UserName, password, inCredBuffer, ref inCredBufferSize))
                        {
                            hr = Marshal.GetLastWin32Error();
                            if (hr == 122)
                            {
                                inCredBuffer = Marshal.AllocCoTaskMem((int)inCredBufferSize);
                                if (!NativeMethods.CredPackAuthenticationBuffer(4, credential.UserName, password, inCredBuffer, ref inCredBufferSize))
                                {
                                    throw new Win32Exception();
                                }
                            }
                            else
                            {
                                throw new Win32Exception(hr);
                            }
                        }
                    }
                    finally
                    {
                        if (emptyPasswordSet)
                        {
                            password = IntPtr.Zero;
                            Marshal.FreeCoTaskMem(emptyPassword);
                        }
                    }
                }

                // properties of the dialog
                var authentifactionError = showErrorMessage ? 1326 /* LogonFailure */ : 0;
                var messageText          = target;
                if (messageText != null)
                {
                    var pos = messageText.IndexOf(':');
                    if (pos != -1)
                    {
                        messageText = messageText.Substring(pos + 1);
                    }
                }
                var info = new NativeMethods.CREDUI_INFO
                {
                    cbSize         = Marshal.SizeOf(typeof(NativeMethods.CREDUI_INFO)),
                    hwndParent     = hwndParent,
                    pszMessageText = String.Format("{0} ({1}).", messageText, realm),
                    pszCaptionText = "Anmeldung",
                    hbmBanner      = IntPtr.Zero
                };

                // show the dialog
                var flags  = NativeMethods.CredUIFlags.Generic | NativeMethods.CredUIFlags.CheckBox;
                var doSave = saveOptions != PpsClientLoginSaveOptions.None;
                hr = NativeMethods.CredUIPromptForWindowsCredentials(ref info, authentifactionError, ref dwAuthPackage, inCredBuffer, inCredBufferSize, out outCredBuffer, out outCredBufferSize, ref doSave, flags);
                if (hr != 0)
                {
                    if (hr == 1223)                     // ERROR_CANCELLED
                    {
                        return(false);
                    }
                    else
                    {
                        throw new Win32Exception(hr);
                    }
                }
                saveOptions = doSave ? PpsClientLoginSaveOptions.Password : PpsClientLoginSaveOptions.None;

                // unpack the result
                var userName         = new StringBuilder(NativeMethods.CREDUI_MAX_USERNAME_LENGTH);
                var domainName       = new StringBuilder(NativeMethods.CREDUI_MAX_USERNAME_LENGTH);
                var userNameLength   = userName.Capacity;
                var domainNameLength = domainName.Capacity;

                if (!NativeMethods.CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredBufferSize, userName, ref userNameLength, domainName, ref domainNameLength, newPassword, ref newPasswordLength))
                {
                    throw new Win32Exception();
                }

                // set the user name
                if (domainName.Length > 0)
                {
                    credential.UserName = domainName.ToString() + "\\" + userName.ToString();
                }
                else
                {
                    credential.UserName = userName.ToString();
                }

                // release the old password
                var oldPassword       = password;
                var oldPasswordLength = passwordLength;

                if (newPasswordLength <= 1)
                {
                    password       = IntPtr.Zero;
                    passwordLength = 0;
                }
                else
                {
                    password       = newPassword;
                    passwordLength = newPasswordLength - 1;
                }

                // set the new one
                newPassword       = oldPassword;
                newPasswordLength = oldPasswordLength;

                return(true);
            }
            finally
            {
                SecureFreeCoTaskMem(ref newPassword, newPasswordLength);
                SecureFreeCoTaskMem(ref inCredBuffer, inCredBufferSize);
                SecureFreeCoTaskMem(ref outCredBuffer, outCredBufferSize);
            }
        }         // func ShowWindowsLogin
Beispiel #13
0
        /// <summary>
        /// When overridden in a derived class, specifies a common dialog box.
        /// </summary>
        /// <param name="parentWindowHandle">A value that represents the window handle of the owner window for the common dialog box.</param>
        /// <returns>
        /// true if the dialog box was successfully run; otherwise, false.
        /// </returns>
        protected override bool RunDialog(IntPtr parentWindowHandle)
        {
            NativeMethods.CREDUI_INFO info = new NativeMethods.CREDUI_INFO(parentWindowHandle, Caption, Message, Banner);
            try
            {
                if (Environment.OSVersion.Version.Major <= 5 || ForcePreVistaStyle)
                {
                    StringBuilder userName = new StringBuilder(UserName, maxStringLength);
                    StringBuilder password = new StringBuilder(maxStringLength);
                    bool          save     = SaveChecked;

                    if (string.IsNullOrEmpty(Target))
                    {
                        Target = DefaultTarget;
                    }
                    NativeMethods.CredUIReturnCodes ret = NativeMethods.CredUIPromptForCredentials(ref info, Target, IntPtr.Zero,
                                                                                                   AuthenticationError, userName, maxStringLength, password, maxStringLength, ref save,
                                                                                                   NativeMethods.CredentialsDialogOptions.Default | (SaveChecked ? NativeMethods.CredentialsDialogOptions.ShowSaveCheckBox : 0));
                    switch (ret)
                    {
                    case NativeMethods.CredUIReturnCodes.Success:
                        if (ValidatePassword && !IsValidPassword(userName.ToString(), password.ToString()))
                        {
                            return(false);
                        }

                        /*if (save)
                         * {
                         *      CredUIReturnCodes cret = CredUIConfirmCredentials(this.Target, false);
                         *      if (cret != CredUIReturnCodes.NO_ERROR && cret != CredUIReturnCodes.ERROR_INVALID_PARAMETER)
                         *      {
                         *              this.Options |= CredentialsDialogOptions.IncorrectPassword;
                         *              return false;
                         *      }
                         * }*/
                        break;

                    case NativeMethods.CredUIReturnCodes.Cancelled:
                        return(false);

                    default:
                        throw new InvalidOperationException($"Unknown error in CredentialsDialog. Error: 0x{ret:X}");
                    }

                    if (EncryptPassword)
                    {
                        // Convert the password to a SecureString
                        SecureString newPassword = StringBuilderToSecureString(password);

                        // Clear the old password and set the new one (read-only)
                        if (SecurePassword != null)
                        {
                            SecurePassword.Dispose();
                        }
                        newPassword.MakeReadOnly();
                        SecurePassword = newPassword;
                    }
                    else
                    {
                        Password = password.ToString();
                    }

                    // Update other properties
                    UserName    = userName.ToString();
                    SaveChecked = save;
                    return(true);
                }
                else
                {
                    NativeMethods.WindowsCredentialsDialogOptions flag = NativeMethods.WindowsCredentialsDialogOptions.Generic;
                    if (SaveChecked)
                    {
                        flag |= NativeMethods.WindowsCredentialsDialogOptions.ShowSaveCheckBox;
                    }

                    NativeMethods.AuthenticationBuffer buf = null;
                    if (EncryptPassword && SecurePassword != null)
                    {
                        buf = new NativeMethods.AuthenticationBuffer(UserName.ToSecureString(), SecurePassword);
                    }
                    else
                    {
                        buf = new NativeMethods.AuthenticationBuffer(UserName, Password);
                    }

                    IntPtr outAuthBuffer = IntPtr.Zero;
                    uint   outAuthBufferSize = 0, authPackage = 0;
                    bool   save = SaveChecked;
                    var    retVal = NativeMethods.CredUIPromptForWindowsCredentials(ref info, 0, ref authPackage,
                                                                                    buf, (uint)buf.Size, out outAuthBuffer, out outAuthBufferSize, ref save, flag);
                    var outAuth = new NativeMethods.AuthenticationBuffer(outAuthBuffer, (int)outAuthBufferSize);

                    if (retVal == NativeMethods.CredUIReturnCodes.Cancelled)
                    {
                        return(false);
                    }
                    if (retVal != NativeMethods.CredUIReturnCodes.Success)
                    {
                        throw new Win32Exception((int)retVal);
                    }

                    SaveChecked = save;
                    if (EncryptPassword)
                    {
                        SecureString u, d, p;
                        outAuth.UnPack(true, out u, out d, out p);
                        Password       = null;
                        SecurePassword = p;
                        UserName       = $"{d.ToInsecureString()}\\{u.ToInsecureString()}".TrimStart('\\');
                    }
                    else
                    {
                        string u, d, p;
                        outAuth.UnPack(true, out u, out d, out p);
                        Password       = p;
                        SecurePassword = null;
                        UserName       = $"{d}\\{u}".TrimStart('\\');
                        if (ValidatePassword && !IsValidPassword(UserName, Password))
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
            }
            finally
            {
                info.Dispose();
            }
        }