Ejemplo n.º 1
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));
        }
Ejemplo n.º 2
0
        private static byte[] GetAccountNameAttributeData(IntPtr itemRef)
        {
            IntPtr tagArrayPtr    = IntPtr.Zero;
            IntPtr formatArrayPtr = IntPtr.Zero;
            IntPtr attrListPtr    = IntPtr.Zero; // SecKeychainAttributeList

            try
            {
                // Extract the user name by querying for the item's 'account' attribute
                tagArrayPtr = Marshal.AllocHGlobal(sizeof(SecKeychainAttrType));
                Marshal.WriteInt32(tagArrayPtr, (int)SecKeychainAttrType.AccountItem);

                formatArrayPtr = Marshal.AllocHGlobal(sizeof(CssmDbAttributeFormat));
                Marshal.WriteInt32(formatArrayPtr, (int)CssmDbAttributeFormat.String);

                var attributeInfo = new SecKeychainAttributeInfo
                {
                    Count  = 1,
                    Tag    = tagArrayPtr,
                    Format = formatArrayPtr,
                };

                ThrowIfError(
                    SecKeychainItemCopyAttributesAndData(
                        itemRef, ref attributeInfo,
                        IntPtr.Zero, out attrListPtr, out _, IntPtr.Zero)
                    );

                SecKeychainAttributeList attrList = Marshal.PtrToStructure <SecKeychainAttributeList>(attrListPtr);
                Debug.Assert(attrList.Count == 1, "Only expecting a list structure containing one attribute to be returned");

                SecKeychainAttribute attribute = Marshal.PtrToStructure <SecKeychainAttribute>(attrList.Attributes);

                return(InteropUtils.ToByteArray(attribute.Data, attribute.Length));
            }
            finally
            {
                if (tagArrayPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(tagArrayPtr);
                }

                if (formatArrayPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(formatArrayPtr);
                }

                if (attrListPtr != IntPtr.Zero)
                {
                    SecKeychainItemFreeAttributesAndData(attrListPtr, IntPtr.Zero);
                }
            }
        }
Ejemplo n.º 3
0
        public ICredential Get(string key)
        {
            IntPtr passwordData = IntPtr.Zero;
            IntPtr itemRef      = IntPtr.Zero;

            try
            {
                // Find the item (itemRef) and password (passwordData) in the keychain
                int findResult = SecKeychainFindGenericPassword(
                    IntPtr.Zero, (uint)key.Length, key, 0, null,
                    out uint passwordLength, out passwordData, out itemRef);

                switch (findResult)
                {
                case OK:
                    // Get and decode the user name from the 'account name' attribute
                    byte[] userNameBytes = GetAccountNameAttributeData(itemRef);
                    string userName      = Encoding.UTF8.GetString(userNameBytes);

                    // Decode the password from the raw data
                    byte[] passwordBytes = InteropUtils.ToByteArray(passwordData, passwordLength);
                    string password      = Encoding.UTF8.GetString(passwordBytes);

                    return(new GitCredential(userName, password));

                case ErrorSecItemNotFound:
                    return(null);

                default:
                    ThrowIfError(findResult);
                    return(null);
                }
            }
            finally
            {
                if (passwordData != IntPtr.Zero)
                {
                    SecKeychainItemFreeContent(IntPtr.Zero, passwordData);
                }

                if (itemRef != IntPtr.Zero)
                {
                    CoreFoundation.CFRelease(itemRef);
                }
            }
        }
Ejemplo n.º 4
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);
                }
            }
        }