예제 #1
0
        public (string username, SecureString password) ReadUserCredentials(string authority)
        {
            using (var ch = CredentialHandle.ReadFromCredentialManager(authority)) {
                if (ch == null)
                {
                    return(null, null);
                }

                var credData = ch.GetCredentialData();
                return(credData.UserName, SecurityUtilities.SecureStringFromNativeBuffer(credData.CredentialBlob));
            }
        }
예제 #2
0
        private async Task <Credentials> PromptForWindowsCredentialsAsync(string authority, string workspaceName, CancellationToken cancellationToken)
        {
            await _services.MainThread().SwitchToAsync(cancellationToken);

            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);
                SaveUserCredentials(authority, userName, password, save);
                return(Credentials.Create(userName, password));
            } finally {
                if (inCredBuffer != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(inCredBuffer);
                }

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

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