Beispiel #1
0
        private static Credentials Save(string userName, SecureString password, string authority, bool save)
        {
            var creds = default(NativeMethods.CredentialData);

            try {
                creds.TargetName = authority;
                // We have to save the credentials even if user selected NOT to save. Otherwise, user will be asked to enter
                // credentials for every REPL/intellisense/package/Connection test request. This can provide the best user experience.
                // We can limit how long the information is saved, in the case whee user selected not to save the credential persistence
                // is limited to the current log on session. The credentials will not be available if the use logs off and back on.
                creds.Persist            = save ? NativeMethods.CRED_PERSIST.CRED_PERSIST_ENTERPRISE : NativeMethods.CRED_PERSIST.CRED_PERSIST_SESSION;
                creds.Type               = NativeMethods.CRED_TYPE.GENERIC;
                creds.UserName           = userName;
                creds.CredentialBlob     = Marshal.SecureStringToCoTaskMemUnicode(password);
                creds.CredentialBlobSize = (uint)((password.Length + 1) * sizeof(char)); // unicode password + unicode null
                if (!NativeMethods.CredWrite(ref creds, 0))
                {
                    var error = Marshal.GetLastWin32Error();
                    throw new Win32Exception(error, Resources.Error_CredWriteFailed);
                }
            } finally {
                if (creds.CredentialBlob != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(creds.CredentialBlob);
                }
            }
            return(Credentials.Create(userName, password));
        }
Beispiel #2
0
 private Credentials ReadSavedCredentials(string authority)
 {
     using (var ch = CredentialHandle.ReadFromCredentialManager(authority)) {
         if (ch != null)
         {
             var credData = ch.GetCredentialData();
             return(Credentials.Create(credData.UserName, SecurityUtilities.SecureStringFromNativeBuffer(credData.CredentialBlob)));
         }
         return(null);
     }
 }
Beispiel #3
0
 public Credentials GetUserCredentials(string authority, string workspaceName)
 {
     _services.MainThread().CheckAccess();
     var(username, password) = ReadUserCredentials(authority);
     return(username != null?Credentials.Create(username, password) : PromptForWindowsCredentials(authority, workspaceName));
 }
Beispiel #4
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);
                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);
                }
            }
        }