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); } } }
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 = "******"); }); }
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); }
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(); }); }
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); }); }
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); } } }
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(); }); }
public static extern bool CredWrite( ref Win32Credential credential, int flags);
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); } } }