예제 #1
0
파일: Storage.cs 프로젝트: numbnet/unix
        public IEnumerable <SecureData> EnumerateSecureData(string prefix)
        {
            string filter = prefix ?? string.Empty + "*";

            if (NativeMethods.CredEnumerate(filter, 0, out int count, out IntPtr credentialArrayPtr))
            {
                Trace.WriteLine($"{count} credentials enumerated from secret store.");

                try
                {
                    for (int i = 0; i < count; i += 1)
                    {
                        int    offset        = i * Marshal.SizeOf(typeof(IntPtr));
                        IntPtr credentialPtr = Marshal.ReadIntPtr(credentialArrayPtr, offset);

                        if (credentialPtr != IntPtr.Zero)
                        {
                            NativeMethods.Credential credStruct = Marshal.PtrToStructure <NativeMethods.Credential>(credentialPtr);
                            int passwordLength = credStruct.CredentialBlobSize;

                            byte[] data = new byte[credStruct.CredentialBlobSize];
                            Marshal.Copy(credStruct.CredentialBlob, data, 0, credStruct.CredentialBlobSize);

                            string name = credStruct.UserName ?? string.Empty;
                            string key  = credStruct.TargetName;

                            yield return(new SecureData(key, name, data));
                        }
                    }
                }
                finally
                {
                    NativeMethods.CredFree(credentialArrayPtr);
                }
            }
예제 #2
0
        protected void PurgeCredentials(string @namespace)
        {
            string filter = @namespace + "*";
            int    count;
            IntPtr credentialArrayPtr;

            if (NativeMethods.CredEnumerate(filter, 0, out count, out credentialArrayPtr))
            {
                for (int i = 0; i < count; i += 1)
                {
                    int    offset        = i * Marshal.SizeOf(typeof(IntPtr));
                    IntPtr credentialPtr = Marshal.ReadIntPtr(credentialArrayPtr, offset);

                    if (credentialPtr != IntPtr.Zero)
                    {
                        NativeMethods.Credential credential = Marshal.PtrToStructure <NativeMethods.Credential>(credentialPtr);

                        if (!NativeMethods.CredDelete(credential.TargetName, credential.Type, 0))
                        {
                            int error = Marshal.GetLastWin32Error();
                            Debug.Fail("Failed with error code " + error.ToString("X"));
                        }
                    }
                }

                NativeMethods.CredFree(credentialArrayPtr);
            }
            else
            {
                int error = Marshal.GetLastWin32Error();
                Debug.Fail("Failed with error code " + error.ToString("X"));
            }
        }
        protected void WriteCredential(string targetName, Credential credentials)
        {
            NativeMethods.Credential credential = new NativeMethods.Credential()
            {
                Type               = NativeMethods.CredentialType.Generic,
                TargetName         = targetName,
                CredentialBlob     = Marshal.StringToCoTaskMemUni(credentials.Password),
                CredentialBlobSize = (uint)Encoding.Unicode.GetByteCount(credentials.Password),
                Persist            = NativeMethods.CredentialPersist.LocalMachine,
                AttributeCount     = 0,
                UserName           = credentials.Username,
            };
            try
            {
                if (!NativeMethods.CredWrite(ref credential, 0))
                {
                    int errorCode = Marshal.GetLastWin32Error();
                    throw new Exception("Failed to write credentials", new Win32Exception(errorCode));
                }

                Git.Trace.WriteLine($"credentials for '{targetName}' written to store.");
            }
            finally
            {
                if (credential.CredentialBlob != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(credential.CredentialBlob);
                }
            }
        }
예제 #4
0
        protected Credential ReadCredentials(string targetName)
        {
            Credential credentials = null;
            IntPtr     credPtr     = IntPtr.Zero;

            try
            {
                if (NativeMethods.CredRead(targetName, NativeMethods.CredentialType.Generic, 0, out credPtr))
                {
                    NativeMethods.Credential credStruct = (NativeMethods.Credential)Marshal.PtrToStructure(credPtr, typeof(NativeMethods.Credential));
                    int passwordLength = (int)credStruct.CredentialBlobSize;

                    string password = passwordLength > 0
                                    ? Marshal.PtrToStringUni(credStruct.CredentialBlob, passwordLength / sizeof(char))
                                    : String.Empty;
                    string username = credStruct.UserName ?? String.Empty;

                    credentials = new Credential(username, password);

                    Git.Trace.WriteLine($"credentials for '{targetName}' read from store.");
                }
            }
            finally
            {
                if (credPtr != IntPtr.Zero)
                {
                    NativeMethods.CredFree(credPtr);
                }
            }

            return(credentials);
        }
        protected void WriteCredential(string targetName, Credential credentials)
        {
            Trace.WriteLine("BaseSecureStore::WriteCredential");

            NativeMethods.Credential credential = new NativeMethods.Credential()
            {
                Type           = NativeMethods.CredentialType.Generic,
                TargetName     = targetName,
                Persist        = NativeMethods.CredentialPersist.LocalMachine,
                AttributeCount = 0,
                UserName       = credentials.Username,
            };
            try
            {
                // https://msdn.microsoft.com/en-us/library/gg309393.aspx
                credential.CredentialBlob = Marshal.SecureStringToCoTaskMemUnicode(credentials.Password);
                // See calculation in http://referencesource.microsoft.com/#mscorlib/system/security/securestring.cs,eab10308ba549df3
                credential.CredentialBlobSize = (uint)(credentials.Password.Length + 1 /*null terminator*/) * 2 /*Unicode encoding*/;

                if (!NativeMethods.CredWrite(ref credential, 0))
                {
                    int errorCode = Marshal.GetLastWin32Error();
                    Trace.WriteLine("BaseSecureStore::WriteCredential Failed to write credentials, error code " + errorCode);
                }
            }
            finally
            {
                if (credential.CredentialBlob != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(credential.CredentialBlob);
                }
            }
        }
        protected bool WriteToken(string targetName, Token token)
        {
            if (ReferenceEquals(targetName, null))
            {
                throw new ArgumentNullException(nameof(targetName));
            }
            if (ReferenceEquals(token, null))
            {
                throw new ArgumentNullException(nameof(token));
            }

            byte[] bytes = null;
            if (Token.Serialize(token, out bytes))
            {
                string name;
                if (Token.GetFriendlyNameFromType(token.Type, out name))
                {
                    NativeMethods.Credential credential = new NativeMethods.Credential()
                    {
                        Type               = NativeMethods.CredentialType.Generic,
                        TargetName         = targetName,
                        CredentialBlobSize = (uint)bytes.Length,
                        Persist            = NativeMethods.CredentialPersist.LocalMachine,
                        AttributeCount     = 0,
                        UserName           = name,
                    };
                    try
                    {
                        credential.CredentialBlob = Marshal.AllocCoTaskMem(bytes.Length);
                        Marshal.Copy(bytes, 0, credential.CredentialBlob, bytes.Length);

                        if (!NativeMethods.CredWrite(ref credential, 0))
                        {
                            int error = Marshal.GetLastWin32Error();
                            throw new Win32Exception(error, "Failed to write credentials");
                        }

                        Git.Trace.WriteLine($"token for '{targetName}' written to store.");
                    }
                    catch (Exception exception)
                    {
                        Debug.WriteLine(exception);

                        Git.Trace.WriteLine($"failed to write credentials: {exception.GetType().Name}.");

                        return(false);
                    }
                    finally
                    {
                        if (credential.CredentialBlob != IntPtr.Zero)
                        {
                            Marshal.FreeCoTaskMem(credential.CredentialBlob);
                        }
                    }
                }
            }

            return(true);
        }
        protected bool WriteCredential(string targetName, Credential credentials)
        {
            if (ReferenceEquals(targetName, null))
            {
                throw new ArgumentNullException(nameof(targetName));
            }
            if (ReferenceEquals(credentials, null))
            {
                throw new ArgumentNullException(nameof(credentials));
            }

            NativeMethods.Credential credential = new NativeMethods.Credential()
            {
                Type               = NativeMethods.CredentialType.Generic,
                TargetName         = targetName,
                CredentialBlob     = Marshal.StringToCoTaskMemUni(credentials.Password),
                CredentialBlobSize = (uint)Encoding.Unicode.GetByteCount(credentials.Password),
                Persist            = NativeMethods.CredentialPersist.LocalMachine,
                AttributeCount     = 0,
                UserName           = credentials.Username,
            };
            try
            {
                if (!NativeMethods.CredWrite(ref credential, 0))
                {
                    int error = Marshal.GetLastWin32Error();
                    throw new Win32Exception(error, "Failed to write credentials");
                }

                Git.Trace.WriteLine($"credentials for '{targetName}' written to store.");
            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception);

                Git.Trace.WriteLine($"failed to write credentials: {exception.GetType().Name}.");

                return(false);
            }
            finally
            {
                if (credential.CredentialBlob != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(credential.CredentialBlob);
                }
            }

            return(true);
        }
        protected void WriteToken(string targetName, Token token)
        {
            Trace.WriteLine("BaseSecureStore::WriteToken");

            byte[] bytes = null;
            if (!Token.Serialize(token, out bytes))
            {
                return;
            }

            string name;

            if (!Token.GetFriendlyNameFromType(token.Type, out name))
            {
                return;
            }

            NativeMethods.Credential credential = new NativeMethods.Credential()
            {
                Type               = NativeMethods.CredentialType.Generic,
                TargetName         = targetName,
                CredentialBlobSize = (uint)bytes.Length,
                Persist            = NativeMethods.CredentialPersist.LocalMachine,
                AttributeCount     = 0,
                UserName           = name,
            };
            try
            {
                credential.CredentialBlob = Marshal.AllocCoTaskMem(bytes.Length);
                Marshal.Copy(bytes, 0, credential.CredentialBlob, bytes.Length);

                if (!NativeMethods.CredWrite(ref credential, 0))
                {
                    int errorCode = Marshal.GetLastWin32Error();
                    Trace.WriteLine("BaseSecureStore::WriteToken Failed to write credentials, error code " + errorCode);
                }
            }
            finally
            {
                if (credential.CredentialBlob != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(credential.CredentialBlob);
                }
            }
        }
        protected Token ReadToken(string targetName)
        {
            Token  token   = null;
            IntPtr credPtr = IntPtr.Zero;

            try
            {
                if (NativeMethods.CredRead(targetName, NativeMethods.CredentialType.Generic, 0, out credPtr))
                {
                    NativeMethods.Credential credStruct = (NativeMethods.Credential)Marshal.PtrToStructure(credPtr, typeof(NativeMethods.Credential));
                    if (credStruct.CredentialBlob != null && credStruct.CredentialBlobSize > 0)
                    {
                        int    size  = (int)credStruct.CredentialBlobSize;
                        byte[] bytes = new byte[size];
                        Marshal.Copy(credStruct.CredentialBlob, bytes, 0, size);

                        TokenType type;
                        if (Token.GetTypeFromFriendlyName(credStruct.UserName, out type))
                        {
                            Token.Deserialize(bytes, type, out token);
                        }

                        Git.Trace.WriteLine($"token for '{targetName}' read from store.");
                    }
                }
            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception);

                Git.Trace.WriteLine($"failed to read credentials: {exception.GetType().Name}.");

                return(null);
            }
            finally
            {
                if (credPtr != IntPtr.Zero)
                {
                    NativeMethods.CredFree(credPtr);
                }
            }

            return(token);
        }
        protected Credential ReadCredentials(string targetName)
        {
            Trace.WriteLine("BaseSecureStore::ReadCredentials");

            Credential credentials = null;
            IntPtr     credPtr     = IntPtr.Zero;

            try
            {
                if (!NativeMethods.CredRead(targetName, NativeMethods.CredentialType.Generic, 0, out credPtr))
                {
                    return(null);
                }

                NativeMethods.Credential credStruct = (NativeMethods.Credential)Marshal.PtrToStructure(credPtr, typeof(NativeMethods.Credential));

                // https://msdn.microsoft.com/en-us/library/gg309393.aspx
                int          size = (int)credStruct.CredentialBlobSize;
                SecureString pwd  = null;
                if (size != 0)
                {
                    byte[] bpassword = new byte[size];
                    Marshal.Copy(credStruct.CredentialBlob, bpassword, 0, size);
                    char[] chars = Encoding.Unicode.GetChars(bpassword);
                    pwd = ConvertToSecureString(chars);
                    Array.Clear(chars, 0, chars.Length);
                    Array.Clear(bpassword, 0, bpassword.Length);
                }

                credentials = new Credential(credStruct.UserName, pwd);
            }
            finally
            {
                if (credPtr != IntPtr.Zero)
                {
                    NativeMethods.CredFree(credPtr);
                }
            }

            return(credentials);
        }
        protected void WriteToken(string targetName, Token token)
        {
            byte[] bytes = null;
            if (Token.Serialize(token, out bytes))
            {
                string name;
                if (Token.GetFriendlyNameFromType(token.Type, out name))
                {
                    NativeMethods.Credential credential = new NativeMethods.Credential()
                    {
                        Type               = NativeMethods.CredentialType.Generic,
                        TargetName         = targetName,
                        CredentialBlobSize = (uint)bytes.Length,
                        Persist            = NativeMethods.CredentialPersist.LocalMachine,
                        AttributeCount     = 0,
                        UserName           = name,
                    };
                    try
                    {
                        credential.CredentialBlob = Marshal.AllocCoTaskMem(bytes.Length);
                        Marshal.Copy(bytes, 0, credential.CredentialBlob, bytes.Length);

                        if (!NativeMethods.CredWrite(ref credential, 0))
                        {
                            int errorCode = Marshal.GetLastWin32Error();
                            throw new Exception("Failed to write credentials", new Win32Exception(errorCode));
                        }

                        Git.Trace.WriteLine($"token for '{targetName}' written to store.");
                    }
                    finally
                    {
                        if (credential.CredentialBlob != IntPtr.Zero)
                        {
                            Marshal.FreeCoTaskMem(credential.CredentialBlob);
                        }
                    }
                }
            }
        }
        protected Token ReadToken(string targetName)
        {
            Trace.WriteLine("BaseSecureStore::ReadToken");

            Token  token   = null;
            IntPtr credPtr = IntPtr.Zero;

            try
            {
                if (!NativeMethods.CredRead(targetName, NativeMethods.CredentialType.Generic, 0, out credPtr))
                {
                    return(null);
                }

                NativeMethods.Credential credStruct = (NativeMethods.Credential)Marshal.PtrToStructure(credPtr, typeof(NativeMethods.Credential));
                if (credStruct.CredentialBlob == null || credStruct.CredentialBlobSize <= 0)
                {
                    return(null);
                }

                int    size  = (int)credStruct.CredentialBlobSize;
                byte[] bytes = new byte[size];
                Marshal.Copy(credStruct.CredentialBlob, bytes, 0, size);

                TokenType type;
                if (Token.GetTypeFromFriendlyName(credStruct.UserName, out type))
                {
                    Token.Deserialize(bytes, type, out token);
                }
            }
            finally
            {
                if (credPtr != IntPtr.Zero)
                {
                    NativeMethods.CredFree(credPtr);
                }
            }

            return(token);
        }
        protected IEnumerable <Secret> EnumerateCredentials(string @namespace)
        {
            string filter = @namespace ?? string.Empty + "*";

            if (NativeMethods.CredEnumerate(filter, 0, out int count, out IntPtr credentialArrayPtr))
            {
                Trace.WriteLine($"{count} credentials enumerated from secret store.");

                try
                {
                    for (int i = 0; i < count; i += 1)
                    {
                        int    offset        = i * Marshal.SizeOf(typeof(IntPtr));
                        IntPtr credentialPtr = Marshal.ReadIntPtr(credentialArrayPtr, offset);

                        if (credentialPtr != IntPtr.Zero)
                        {
                            NativeMethods.Credential credStruct = Marshal.PtrToStructure <NativeMethods.Credential>(credentialPtr);
                            int passwordLength = (int)credStruct.CredentialBlobSize;

                            string password = passwordLength > 0
                                            ? Marshal.PtrToStringUni(credStruct.CredentialBlob, passwordLength / sizeof(char))
                                            : string.Empty;
                            string username = credStruct.UserName ?? string.Empty;

                            var credentials = new Credential(username, password);

                            yield return(credentials);
                        }
                    }
                }
                finally
                {
                    NativeMethods.CredFree(credentialArrayPtr);
                }
            }
        protected void WriteToken(string targetName, Token token)
        {
            byte[] bytes = null;
            if (Token.Serialize(token, out bytes))
            {
                string name;
                if (Token.GetFriendlyNameFromType(token.Type, out name))
                {
                    NativeMethods.Credential credential = new NativeMethods.Credential()
                    {
                        Type = NativeMethods.CredentialType.Generic,
                        TargetName = targetName,
                        CredentialBlobSize = (uint)bytes.Length,
                        Persist = NativeMethods.CredentialPersist.LocalMachine,
                        AttributeCount = 0,
                        UserName = name,
                    };
                    try
                    {
                        credential.CredentialBlob = Marshal.AllocCoTaskMem(bytes.Length);
                        Marshal.Copy(bytes, 0, credential.CredentialBlob, bytes.Length);

                        if (!NativeMethods.CredWrite(ref credential, 0))
                        {
                            int errorCode = Marshal.GetLastWin32Error();
                            throw new Exception("Failed to write credentials", new Win32Exception(errorCode));
                        }

                        Git.Trace.WriteLine($"token for '{targetName}' written to store.");
                    }
                    finally
                    {
                        if (credential.CredentialBlob != IntPtr.Zero)
                        {
                            Marshal.FreeCoTaskMem(credential.CredentialBlob);
                        }
                    }
                }
            }
        }
        protected void WriteCredential(string targetName, Credential credentials)
        {
            NativeMethods.Credential credential = new NativeMethods.Credential()
            {
                Type = NativeMethods.CredentialType.Generic,
                TargetName = targetName,
                CredentialBlob = Marshal.StringToCoTaskMemUni(credentials.Password),
                CredentialBlobSize = (uint)Encoding.Unicode.GetByteCount(credentials.Password),
                Persist = NativeMethods.CredentialPersist.LocalMachine,
                AttributeCount = 0,
                UserName = credentials.Username,
            };
            try
            {
                if (!NativeMethods.CredWrite(ref credential, 0))
                {
                    int errorCode = Marshal.GetLastWin32Error();
                    throw new Exception("Failed to write credentials", new Win32Exception(errorCode));
                }

                Git.Trace.WriteLine($"credentials for '{targetName}' written to store.");
            }
            finally
            {
                if (credential.CredentialBlob != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(credential.CredentialBlob);
                }
            }
        }
        protected void WriteCredential(string targetName, Credential credentials)
        {
            Trace.WriteLine("BaseSecureStore::WriteCredential");

            NativeMethods.Credential credential = new NativeMethods.Credential()
            {
                Type = NativeMethods.CredentialType.Generic,
                TargetName = targetName,
                Persist = NativeMethods.CredentialPersist.LocalMachine,
                AttributeCount = 0,
                UserName = credentials.Username,
            };
            try
            {
                // https://msdn.microsoft.com/en-us/library/gg309393.aspx
                credential.CredentialBlob = Marshal.SecureStringToCoTaskMemUnicode(credentials.Password);
                // See calculation in http://referencesource.microsoft.com/#mscorlib/system/security/securestring.cs,eab10308ba549df3
                credential.CredentialBlobSize = (uint)(credentials.Password.Length + 1 /*null terminator*/) * 2 /*unicode encoding*/;

                if (!NativeMethods.CredWrite(ref credential, 0))
                {
                    int errorCode = Marshal.GetLastWin32Error();
                    Trace.WriteLine("BaseSecureStore::WriteCredential Failed to write credentials, error code " + errorCode);
                }
            }
            finally
            {
                if (credential.CredentialBlob != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(credential.CredentialBlob);
                }
            }
        }
        protected void WriteToken(string targetName, Token token)
        {
            Trace.WriteLine("BaseSecureStore::WriteToken");

            byte[] bytes = null;
            if (Token.Serialize(token, out bytes))
            {
                string name;
                if (Token.GetFriendlyNameFromType(token.Type, out name))
                {
                    NativeMethods.Credential credential = new NativeMethods.Credential()
                    {
                        Type = NativeMethods.CredentialType.Generic,
                        TargetName = targetName,
                        CredentialBlobSize = (uint)bytes.Length,
                        Persist = NativeMethods.CredentialPersist.LocalMachine,
                        AttributeCount = 0,
                        UserName = name,
                    };
                    try
                    {
                        credential.CredentialBlob = Marshal.AllocCoTaskMem(bytes.Length);
                        Marshal.Copy(bytes, 0, credential.CredentialBlob, bytes.Length);

                        if (!NativeMethods.CredWrite(ref credential, 0))
                        {
                            int errorCode = Marshal.GetLastWin32Error();
                            Trace.WriteLine("BaseSecureStore::WriteToken Failed to write credentials, error code " + errorCode);
                        }
                    }
                    finally
                    {
                        if (credential.CredentialBlob != IntPtr.Zero)
                        {
                            Marshal.ZeroFreeCoTaskMemUnicode(credential.CredentialBlob);
                        }
                    }
                }
            }
        }