public void AddOrUpdate(string key, ICredential credential)
        {
            byte[] passwordBytes = Encoding.Unicode.GetBytes(credential.Password);

            var w32Credential = new Win32Credential
            {
                Type               = CredentialType.Generic,
                TargetName         = key,
                CredentialBlob     = Marshal.AllocCoTaskMem(passwordBytes.Length),
                CredentialBlobSize = passwordBytes.Length,
                Persist            = CredentialPersist.LocalMachine,
                AttributeCount     = 0,
                UserName           = credential.UserName,
            };

            try
            {
                Marshal.Copy(passwordBytes, 0, w32Credential.CredentialBlob, passwordBytes.Length);

                ThrowOnError(
                    CredWrite(ref w32Credential, 0),
                    "Failed to write item to store."
                    );
            }
            finally
            {
                if (w32Credential.CredentialBlob != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(w32Credential.CredentialBlob);
                }
            }
        }
示例#2
0
        private WindowsCredential CreateCredentialFromStructure(Win32Credential credential)
        {
            string password = null;

            if (credential.CredentialBlobSize != 0 && credential.CredentialBlob != IntPtr.Zero)
            {
                byte[] passwordBytes = InteropUtils.ToByteArray(
                    credential.CredentialBlob,
                    credential.CredentialBlobSize);
                password = Encoding.Unicode.GetString(passwordBytes);
            }

            // Recover the target name we gave from the internal (raw) target name
            string targetName = credential.TargetName.TrimUntilIndexOf(TargetNameLegacyGenericPrefix);

            // Recover the service name from the target name
            string serviceName = targetName;

            if (!string.IsNullOrWhiteSpace(_namespace))
            {
                serviceName = serviceName.TrimUntilIndexOf($"{_namespace}:");
            }

            // Strip any userinfo component from the service name
            serviceName = RemoveUriUserInfo(serviceName);

            return(new WindowsCredential(serviceName, credential.UserName, password, targetName));
        }
        public ICredential Get(string key)
        {
            IntPtr credPtr = IntPtr.Zero;

            try
            {
                ThrowOnError(
                    CredRead(key, CredentialType.Generic, 0, out credPtr),
                    "Failed to read item from store."
                    );

                Win32Credential credential = Marshal.PtrToStructure <Win32Credential>(credPtr);

                var userName = credential.UserName;

                byte[] passwordBytes = NativeMethods.ToByteArray(credential.CredentialBlob, credential.CredentialBlobSize);
                var    password      = Encoding.Unicode.GetString(passwordBytes);

                return(new Credential(userName, password));
            }
            catch (KeyNotFoundException)
            {
                return(null);
            }
            finally
            {
                if (credPtr != IntPtr.Zero)
                {
                    CredFree(credPtr);
                }
            }
        }
 public void Credential_Save()
 {
     TestUtils.RunIfWindows(() =>
     {
         Win32Credential saved = new Win32Credential("username", "password", "target", CredentialType.Generic);
         saved.PersistanceType = PersistanceType.LocalComputer;
         Assert.True(saved.Save());
     });
 }
 public void Credential_Delete_NullTerminator()
 {
     TestUtils.RunIfWindows(() =>
     {
         Win32Credential credential = new Win32Credential((string)null, (string)null, "\0", CredentialType.None);
         credential.Description     = (string)null;
         Assert.False(credential.Delete());
     });
 }
 public void Credential_ShouldThrowObjectDisposedException()
 {
     TestUtils.RunIfWindows(() =>
     {
         Win32Credential disposed = new Win32Credential {
             Password = "******"
         };
         disposed.Dispose();
         Assert.Throws <ObjectDisposedException>(() => disposed.Username = "******");
     });
 }
示例#7
0
        private bool IsMatch(string service, string account, Win32Credential credential)
        {
            // Match against the username first
            if (!string.IsNullOrWhiteSpace(account) &&
                !StringComparer.Ordinal.Equals(account, credential.UserName))
            {
                return(false);
            }

            // Trim the "LegacyGeneric" prefix Windows adds and any namespace we have been filtered with
            string targetName = credential.TargetName.TrimUntilIndexOf(TargetNameLegacyGenericPrefix);

            if (!string.IsNullOrWhiteSpace(_namespace))
            {
                targetName = targetName.TrimUntilIndexOf($"{_namespace}:");
            }

            // If the target name matches the service name exactly then return 'match'
            if (StringComparer.Ordinal.Equals(service, targetName))
            {
                return(true);
            }

            // Try matching the target and service as URIs
            if (Uri.TryCreate(service, UriKind.Absolute, out Uri serviceUri) &&
                Uri.TryCreate(targetName, UriKind.Absolute, out Uri targetUri))
            {
                // Match host name
                if (!StringComparer.OrdinalIgnoreCase.Equals(serviceUri.Host, targetUri.Host))
                {
                    return(false);
                }

                // Match port number
                if (!serviceUri.IsDefaultPort && serviceUri.Port == targetUri.Port)
                {
                    return(false);
                }

                // Match path
                if (!string.IsNullOrWhiteSpace(serviceUri.AbsolutePath) &&
                    !StringComparer.OrdinalIgnoreCase.Equals(serviceUri.AbsolutePath, targetUri.AbsolutePath))
                {
                    return(false);
                }

                // URLs match
                return(true);
            }

            // Unable to match
            return(false);
        }
示例#8
0
        private IEnumerable <WindowsCredential> Enumerate(string service, string account)
        {
            IntPtr credList = IntPtr.Zero;

            try
            {
                int result = Win32Error.GetLastError(
                    Advapi32.CredEnumerate(
                        null,
                        CredentialEnumerateFlags.AllCredentials,
                        out int count,
                        out credList)
                    );

                switch (result)
                {
                case Win32Error.Success:
                    int ptrSize = Marshal.SizeOf <IntPtr>();
                    for (int i = 0; i < count; i++)
                    {
                        IntPtr          credPtr    = Marshal.ReadIntPtr(credList, i * ptrSize);
                        Win32Credential credential = Marshal.PtrToStructure <Win32Credential>(credPtr);

                        if (!IsMatch(service, account, credential))
                        {
                            continue;
                        }

                        yield return(CreateCredentialFromStructure(credential));
                    }
                    break;

                case Win32Error.NotFound:
                    yield break;

                default:
                    Win32Error.ThrowIfError(result, "Failed to enumerate credentials.");
                    yield break;
                }
            }
            finally
            {
                if (credList != IntPtr.Zero)
                {
                    Advapi32.CredFree(credList);
                }
            }
        }
        public void Credential_Exists_Target_ShouldNotBeNull()
        {
            TestUtils.RunIfWindows(() =>
            {
                new Win32Credential {
                    Username = "******", Password = "******", Target = "target"
                }.Save();

                Win32Credential existingCred = new Win32Credential {
                    Target = "target"
                };
                Assert.True(existingCred.Exists());

                existingCred.Delete();
            });
        }
示例#10
0
        public void CredentialSetLoadWithTargetFilter()
        {
            RunIfWrapper.RunIfWindows(() =>
            {
                Win32Credential credential = new Win32Credential
                {
                    Username = "******",
                    Password = Guid.NewGuid().ToString(),
                    Target   = "filtertarget"
                };
                credential.Save();

                CredentialSet set = new CredentialSet("filtertarget");
                Assert.Equal(1, set.Load().Count);
                set.Dispose();
            });
        }
        public void CredentialSetLoadWithTargetFilter()
        {
            TestUtils.RunIfWindows(() =>
            {
                Win32Credential credential = new Win32Credential
                {
                    Username = "******",
                    Password = "******",
                    Target   = "filtertarget"
                };
                credential.Save();

                CredentialSet set = new CredentialSet("filtertarget");
                Assert.Equal(1, set.Load().Count);
                set.Dispose();
            });
        }
        public void Credential_Load()
        {
            TestUtils.RunIfWindows(() =>
            {
                Win32Credential setup = new Win32Credential("username", "password", "target", CredentialType.Generic);
                setup.Save();

                Win32Credential credential = new Win32Credential {
                    Target = "target", Type = CredentialType.Generic
                };
                Assert.True(credential.Load());

                Assert.NotEmpty(credential.Username);
                Assert.NotNull(credential.Password);
                Assert.Equal("username", credential.Username);
                Assert.Equal("password", credential.Password);
                Assert.Equal("target", credential.Target);
            });
        }
示例#13
0
        public ICredential Get(string key)
        {
            IntPtr credPtr = IntPtr.Zero;

            try
            {
                int result = Win32Error.GetLastError(
                    Advapi32.CredRead(key, CredentialType.Generic, 0, out credPtr)
                    );

                switch (result)
                {
                case Win32Error.Success:
                    Win32Credential credential = Marshal.PtrToStructure <Win32Credential>(credPtr);

                    var userName = credential.UserName;

                    byte[] passwordBytes = InteropUtils.ToByteArray(credential.CredentialBlob, credential.CredentialBlobSize);
                    var    password      = Encoding.Unicode.GetString(passwordBytes);

                    return(new GitCredential(userName, password));

                case Win32Error.NotFound:
                    return(null);

                default:
                    Win32Error.ThrowIfError(result, "Failed to read item from store.");
                    return(null);
                }
            }
            finally
            {
                if (credPtr != IntPtr.Zero)
                {
                    Advapi32.CredFree(credPtr);
                }
            }
        }
示例#14
0
        public void CredentialSetLoad()
        {
            RunIfWrapper.RunIfWindows(() =>
            {
                Win32Credential credential = new Win32Credential
                {
                    Username = "******",
                    Password = "******",
                    Target   = "target",
                    Type     = CredentialType.Generic
                };
                credential.Save();

                CredentialSet set = new CredentialSet();
                set.Load();
                Assert.NotNull(set);
                Assert.NotEmpty(set);

                credential.Delete();

                set.Dispose();
            });
        }
示例#15
0
 public static extern bool CredWrite(
     ref Win32Credential credential,
     int flags);
示例#16
0
        public void AddOrUpdate(string service, string account, string secret)
        {
            EnsureArgument.NotNullOrWhiteSpace(service, nameof(service));

            IntPtr existingCredPtr = IntPtr.Zero;
            IntPtr credBlob        = IntPtr.Zero;

            try
            {
                // Determine if we need to update an existing credential, which might have
                // a target name that does not include the account name.
                //
                // We first check for the presence of a credential with an account-less
                // target name.
                //
                //  - If such credential exists and *has the same account* then we will
                //    update that entry.
                //  - If such credential exists and does *not* have the same account then
                //    we must create a new entry with the account in the target name.
                //  - If no such credential exists then we create a new entry with the
                //    account-less target name.
                //
                string targetName = CreateTargetName(service, account: null);
                if (Advapi32.CredRead(targetName, CredentialType.Generic, 0, out existingCredPtr))
                {
                    var existingCred = Marshal.PtrToStructure <Win32Credential>(existingCredPtr);
                    if (!StringComparer.Ordinal.Equals(existingCred.UserName, account))
                    {
                        // Create new entry with the account in the target name
                        targetName = CreateTargetName(service, account);
                    }
                }

                byte[] secretBytes = Encoding.Unicode.GetBytes(secret);
                credBlob = Marshal.AllocHGlobal(secretBytes.Length);
                Marshal.Copy(secretBytes, 0, credBlob, secretBytes.Length);

                var newCred = new Win32Credential
                {
                    Type               = CredentialType.Generic,
                    TargetName         = targetName,
                    CredentialBlobSize = secretBytes.Length,
                    CredentialBlob     = credBlob,
                    Persist            = CredentialPersist.LocalMachine,
                    UserName           = account,
                };

                int result = Win32Error.GetLastError(
                    Advapi32.CredWrite(ref newCred, 0)
                    );

                Win32Error.ThrowIfError(result, "Failed to write item to store.");
            }
            finally
            {
                if (credBlob != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(credBlob);
                }

                if (existingCredPtr != IntPtr.Zero)
                {
                    Advapi32.CredFree(existingCredPtr);
                }
            }
        }