private static extern uint CredUIPromptForWindowsCredentials(ref CredUIInfo info,
                                                              int error,
                                                              ref uint authPackage,
                                                              IntPtr inAuthBuffer,
                                                              uint inAuthBufferSize,
                                                              out IntPtr outAuthBuffer,
                                                              out uint outAuthBufferSize,
                                                              ref bool save,
                                                              CredentialsUI flags);
 private static CredUIInfo CreateCredUIInfo(IntPtr owner, string title, string message)
 {
     var credUI = new CredUIInfo();
     credUI.cbSize = Marshal.SizeOf(credUI);
     credUI.hwndParent = owner;
     credUI.pszCaptionText = title;
     credUI.pszMessageText = message;
     return credUI;
 }
示例#3
0
        private static CredUIInfo CreateCredUIInfo(IntPtr owner, string title, string message)
        {
            var credUI = new CredUIInfo();

            credUI.cbSize         = Marshal.SizeOf(credUI);
            credUI.hwndParent     = owner;
            credUI.pszCaptionText = title;
            credUI.pszMessageText = message;
            return(credUI);
        }
示例#4
0
 private static extern uint CredUIPromptForWindowsCredentials(
     ref CredUIInfo credInfo,
     int authError,
     ref uint authPackage,
     IntPtr InAuthBuffer,
     uint InAuthBufferSize,
     out IntPtr refOutAuthBuffer,
     out uint refOutAuthBufferSize,
     ref bool fSave,
     PromptForWindowsCredentialsFlags flags);
 internal extern static CredUIReturnCodes CredUIPromptForCredentials(
     ref CredUIInfo creditUR,
     string targetName,
     IntPtr reserved1,
     int iError,
     StringBuilder userName,
     int maxUserName,
     StringBuilder password,
     int maxPassword,
     ref bool iSave,
     UserCredentialsDialogFlags flags);
            public static NetworkCredential ShowCredentialsPrompt(string caption, string message, ref bool save)
            {
                CredUIInfo credUI = new CredUIInfo
                {
                    Size        = Marshal.SizeOf(typeof(CredUIInfo)),
                    CaptionText = caption,
                    MessageText = message
                };

                uint   authPackage = 0;
                IntPtr outCredBuffer;
                uint   outCredSize;
                var    flags = CredentialsUI.Generic;

                if (save)
                {
                    flags |= CredentialsUI.ShowSaveBox;
                }

                uint result = CredUIPromptForWindowsCredentials(ref credUI, NoError, ref authPackage, IntPtr.Zero, 0,
                                                                out outCredBuffer, out outCredSize, ref save, flags);

                var usernameBuffer = Marshal.AllocCoTaskMem(UserNameMaxLength);
                var passwordBuffer = Marshal.AllocCoTaskMem(PasswordMaxLength);
                var domainBuffer   = Marshal.AllocCoTaskMem(DomainNameMaxLength);

                int userNameLength = UserNameMaxLength;
                int domainLength   = PasswordMaxLength;
                int passwordLength = DomainNameMaxLength;

                if (result == 0)
                {
                    if (CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize,
                                                       usernameBuffer, ref userNameLength,
                                                       domainBuffer, ref domainLength,
                                                       passwordBuffer, ref passwordLength))
                    {
                        // Clear & free the memory
                        RtlZeroMemory(outCredBuffer, outCredSize);
                        CoTaskMemFree(outCredBuffer);

                        // -1 to remove the last \0 if the string is not empty
                        string userName = Marshal.PtrToStringUni(usernameBuffer, Math.Max(0, userNameLength - 1));
                        string password = Marshal.PtrToStringUni(passwordBuffer, Math.Max(0, passwordLength - 1));
                        string domain   = Marshal.PtrToStringUni(domainBuffer, Math.Max(0, domainLength - 1));

                        return(new NetworkCredential(userName, password, domain));
                    }
                }

                return(null);
            }
 static extern CredUIReturnCodes CredUIPromptForCredentials( ref CredUIInfo uiInfo, string targetName, IntPtr reserved, int error, StringBuilder userName, int maxUserName, StringBuilder password, int maxPassword, ref int save, CredUIFlags flags );
        public DialogResult ShowDialog( IWin32Window owner, bool retry )
        {
            if ( !CanCallCredUI )
                return ShowPseudoDialog ( owner, retry );
            else {
                LocalCbtHook hook = new LocalCbtHook ( );
                try {
                    hook.WindowActivated += new LocalCbtHook.CbtEventHandler ( hook_WindowActivated );
                    hook.WindowCreated += new LocalCbtHook.CbtEventHandler ( hook_WindowCreated );
                    hook.WindowDestroyed += new LocalCbtHook.CbtEventHandler ( hook_WindowDestroyed );
                    hook.Install ( );

                    CredUIInfo uiInfo = new CredUIInfo ( owner, text, caption );
                    StringBuilder sbUsername = new StringBuilder ( username, MaxUsername );
                    StringBuilder sbPassword = new StringBuilder ( password, MaxPassword );
                    int nSave = Convert.ToInt32 ( save );
                    CredUIFlags flags = CredUIFlags.GenericCredentials;
                    if ( expectConfirmation )
                        flags |= CredUIFlags.ExpectConfirmation;
                    if ( forceUI )
                        flags |= CredUIFlags.AlwaysShowUI;
                    if ( retry )
                        flags |= CredUIFlags.IncorrectPassword;
                    programmaticCloseResult = DialogResult.None;
                    CredUIReturnCodes retVal = CredUIPromptForCredentials ( ref uiInfo, targetName, IntPtr.Zero, 0, sbUsername, MaxUsername, sbPassword, MaxPassword, ref nSave, flags );
                    save = Convert.ToBoolean ( nSave );

                    if ( programmaticCloseResult != DialogResult.None )
                        return programmaticCloseResult;
                    switch ( retVal ) {
                        case CredUIReturnCodes.NoError:
                            username = sbUsername.ToString ( );
                            password = sbPassword.ToString ( );
                            save = Convert.ToBoolean ( nSave );
                            return DialogResult.OK;
                        case CredUIReturnCodes.Cancelled:
                            return DialogResult.Cancel;
                        default:
                            return DialogResult.Abort;
                    }
                } finally {
                    hook.WindowActivated -= new LocalCbtHook.CbtEventHandler ( hook_WindowActivated );
                    hook.WindowCreated -= new LocalCbtHook.CbtEventHandler ( hook_WindowCreated );
                    hook.WindowDestroyed -= new LocalCbtHook.CbtEventHandler ( hook_WindowDestroyed );
                    hook.Uninstall ( );
                }
            }
        }
 internal static extern CredUIReturnCodes CredUIPromptForCredentials(
     ref CredUIInfo creditUR,
     string targetName,
     IntPtr reserved1,
     int iError,
     StringBuilder userName,
     int maxUserName,
     StringBuilder password,
     int maxPassword,
     ref bool iSave,
     UserCredentialsDialogFlags flags);
 public static extern int CredUIPromptForCredentials(ref CredUIInfo uiInfo, string targetName, IntPtr reserved1, int iError, StringBuilder userName, int maxUserName, StringBuilder password, int maxPassword, [MarshalAs(UnmanagedType.Bool)] ref bool pfSave, WindowsCredentialsFlags flags);
示例#11
0
 public static extern int CredUIPromptForCredentials(ref CredUIInfo uiInfo, string targetName, IntPtr reserved1, int iError, StringBuilder userName, int maxUserName, StringBuilder password, int maxPassword, [MarshalAs(UnmanagedType.Bool)] ref bool pfSave, WindowsCredentialsFlags flags);
示例#12
0
        public static async Task<int> GetAndSaveCredentialsFromUserAsync(ILogger logger = null) {
            await TaskUtilities.SwitchToBackgroundThread();

            lock (_getAndSaveCredentialsFromUserLock) {
                CredUIInfo credInfo = new CredUIInfo();
                credInfo.cbSize = Marshal.SizeOf(credInfo);
                credInfo.pszCaptionText = Resources.Text_RHostBrokerCredentials;
                credInfo.pszMessageText = Resources.Text_RHostBrokerCredentialsDetail;
                credInfo.hwndParent = Process.GetCurrentProcess().MainWindowHandle;

                int errorCode = 0;
                uint authenticationPackage = 0;
                IntPtr credentialBuffer = IntPtr.Zero;
                uint credentialSize;
                bool saveCreds = false;

                IntPtr token = IntPtr.Zero;

                int attempts = 0;
                try {
                    while (attempts++ < MaxCredUIAttempts) {
                        logger?.LogInformation(Resources.Info_CredAttempt, attempts);
                        uint ret = CredUIPromptForWindowsCredentials(ref credInfo, errorCode, ref authenticationPackage, IntPtr.Zero, 0, out credentialBuffer, out credentialSize, ref saveCreds, PromptForWindowsCredentialsFlags.CREDUIWIN_GENERIC);

                        // User clicked the cancel button.
                        if (ret == Win32ErrorCodes.ERROR_CANCELLED) {
                            logger?.LogInformation(Resources.Info_CredUIDismissed);
                            break;
                        } else if (ret == Win32ErrorCodes.ERROR_SUCCESS) {
                            // User entered credentials
                            logger?.LogInformation(Resources.Info_CredUICredsReceived);
                            StringBuilder username = new StringBuilder(CRED_MAX_USERNAME_LENGTH);
                            StringBuilder domain = new StringBuilder(CRED_MAX_USERNAME_LENGTH);
                            StringBuilder password = new StringBuilder(CRED_MAX_USERNAME_LENGTH);

                            int usernameLen = username.Capacity;
                            int domainLen = domain.Capacity;
                            int passwordLen = password.Capacity;

                            if (!CredUnPackAuthenticationBuffer(0, credentialBuffer, credentialSize, username, ref usernameLen, domain, ref domainLen, password, ref passwordLen)) {
                                // Do another attempt by showing user the CredUI with the errorCode set.
                                errorCode = Marshal.GetLastWin32Error();
                                logger?.LogError(Resources.Error_CredentialUnpackingFailed, errorCode);
                                if (credentialBuffer != IntPtr.Zero) {
                                    Marshal.ZeroFreeCoTaskMemUnicode(credentialBuffer);
                                }
                                continue;
                            } else {
                                logger?.LogInformation(Resources.Info_CredUnpacked);
                                // Credential buffer is no longer needed
                                if (credentialBuffer != IntPtr.Zero) {
                                    Marshal.ZeroFreeCoTaskMemUnicode(credentialBuffer);
                                }
                            }


                            var usernameBldr = new StringBuilder(CRED_MAX_USERNAME_LENGTH + 1);
                            var domainBldr = new StringBuilder(CRED_MAX_USERNAME_LENGTH + 1);

                            uint error = CredUIParseUserName(username.ToString(), usernameBldr, usernameBldr.Capacity, domainBldr, domainBldr.Capacity);
                            if (error != 0) {
                                // Couldn't parse the user name. Do another attempt by showing user the CredUI with the errorCode set.
                                errorCode = (int)error;
                                logger?.LogError(Resources.Error_UserNameParsing, errorCode);
                                continue;
                            }

                            if (LogonUser(usernameBldr.ToString(), domainBldr.ToString(), password.ToString(), (int)LogonType.LOGON32_LOGON_INTERACTIVE, (int)LogonProvider.LOGON32_PROVIDER_DEFAULT, ref token)) {
                                logger?.LogInformation(Resources.Info_LogOnAttemptSucceeded);

                                Credential creds = new Credential();
                                creds.targetName = BrokerUserCredName;
                                creds.type = (int)CredType.GENERIC;
                                creds.userName = username.ToString();
                                creds.attributeCount = 0;
                                creds.persist = (int)CredPersist.LOCAL_MACHINE;
                                byte[] bpassword = Encoding.Unicode.GetBytes(password.ToString());
                                creds.credentialBlobSize = bpassword.Length;
                                creds.credentialBlob = Marshal.StringToCoTaskMemUni(password.ToString());

                                if (!CredWrite(ref creds, 0)) {
                                    // Failed to save credentials. Do another attempt by showing user the CredUI with the errorCode set.
                                    errorCode = Marshal.GetLastWin32Error();
                                    logger?.LogInformation(Resources.Error_CredSaveFailed, errorCode);
                                    if (token != IntPtr.Zero) {
                                        CloseHandle(token);
                                    }
                                    continue;
                                }

                                logger?.LogInformation(Resources.Info_CredSaveSucceeded);
                            } else {
                                // Failed to login user. Do another attempt by showing user the CredUI with the errorCode set.
                                errorCode = Marshal.GetLastWin32Error();
                                logger?.LogError(Resources.Error_LogOnAttemptFailed, errorCode);
                                if (token != IntPtr.Zero) {
                                    CloseHandle(token);
                                }
                                continue;
                            }

                            // Credentials received successfully.
                            // Exit loop, another attempt is not needed.
                            break;
                        } else {
                            // CredUIPromptForWindowsCredentials failed to load some component
                            logger?.LogError(Resources.Error_CredUIFailedToLoad, Marshal.GetLastWin32Error());
                            throw new Win32Exception(string.Format(Resources.Error_CredUIFailedToLoad, ret));
                        }
                    }
                } finally {
                    if (token != IntPtr.Zero) {
                        CloseHandle(token);
                    }

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

                return attempts;
            }
        }
示例#13
0
        public DialogResult ShowDialog(IWin32Window owner, bool retry)
        {
            if (!CanCallCredUI)
            {
                return(ShowPseudoDialog(owner, retry));
            }
            else
            {
                LocalCbtHook hook = new LocalCbtHook( );
                try {
                    hook.WindowActivated += new LocalCbtHook.CbtEventHandler(hook_WindowActivated);
                    hook.WindowCreated   += new LocalCbtHook.CbtEventHandler(hook_WindowCreated);
                    hook.WindowDestroyed += new LocalCbtHook.CbtEventHandler(hook_WindowDestroyed);
                    hook.Install( );

                    CredUIInfo    uiInfo     = new CredUIInfo(owner, text, caption);
                    StringBuilder sbUsername = new StringBuilder(username, MaxUsername);
                    StringBuilder sbPassword = new StringBuilder(password, MaxPassword);
                    int           nSave      = Convert.ToInt32(save);
                    CredUIFlags   flags      = CredUIFlags.GenericCredentials;
                    if (expectConfirmation)
                    {
                        flags |= CredUIFlags.ExpectConfirmation;
                    }
                    if (forceUI)
                    {
                        flags |= CredUIFlags.AlwaysShowUI;
                    }
                    if (retry)
                    {
                        flags |= CredUIFlags.IncorrectPassword;
                    }
                    programmaticCloseResult = DialogResult.None;
                    CredUIReturnCodes retVal = CredUIPromptForCredentials(ref uiInfo, targetName, IntPtr.Zero, 0, sbUsername, MaxUsername, sbPassword, MaxPassword, ref nSave, flags);
                    save = Convert.ToBoolean(nSave);

                    if (programmaticCloseResult != DialogResult.None)
                    {
                        return(programmaticCloseResult);
                    }
                    switch (retVal)
                    {
                    case CredUIReturnCodes.NoError:
                        username = sbUsername.ToString( );
                        password = sbPassword.ToString( );
                        save     = Convert.ToBoolean(nSave);
                        return(DialogResult.OK);

                    case CredUIReturnCodes.Cancelled:
                        return(DialogResult.Cancel);

                    default:
                        return(DialogResult.Abort);
                    }
                } finally {
                    hook.WindowActivated -= new LocalCbtHook.CbtEventHandler(hook_WindowActivated);
                    hook.WindowCreated   -= new LocalCbtHook.CbtEventHandler(hook_WindowCreated);
                    hook.WindowDestroyed -= new LocalCbtHook.CbtEventHandler(hook_WindowDestroyed);
                    hook.Uninstall( );
                }
            }
        }
示例#14
0
 static extern CredUIReturnCodes CredUIPromptForCredentials(ref CredUIInfo uiInfo, string targetName, IntPtr reserved, int error, StringBuilder userName, int maxUserName, StringBuilder password, int maxPassword, ref int save, CredUIFlags flags);