コード例 #1
0
        private static unsafe ICredential CreateCredentialFromItem(SecretItem *item)
        {
            GHashTable *secretAttrs   = null;
            IntPtr      serviceKeyPtr = IntPtr.Zero;
            IntPtr      accountKeyPtr = IntPtr.Zero;
            IntPtr      passwordPtr   = IntPtr.Zero;
            GError *    error         = null;

            try
            {
                secretAttrs = secret_item_get_attributes(item);

                // Extract the service attribute
                serviceKeyPtr = Marshal.StringToHGlobalAnsi(ServiceAttributeName);
                IntPtr serviceValuePtr = g_hash_table_lookup(secretAttrs, serviceKeyPtr);
                string service         = Marshal.PtrToStringAuto(serviceValuePtr);

                // Extract the account attribute
                accountKeyPtr = Marshal.StringToHGlobalAnsi(AccountAttributeName);
                IntPtr accountValuePtr = g_hash_table_lookup(secretAttrs, accountKeyPtr);
                string account         = Marshal.PtrToStringAuto(accountValuePtr);

                // Load the secret value
                secret_item_load_secret_sync(item, IntPtr.Zero, out error);
                SecretValue *value = secret_item_get_secret(item);
                if (value == null)
                {
                    throw new InteropException("Failed to load secret", -1);
                }

                // Extract the secret/password
                passwordPtr = secret_value_unref_to_password(value, out int passwordLength);
                string password = Marshal.PtrToStringAuto(passwordPtr, passwordLength);

                return(new SecretServiceCredential(service, account, password));
            }
            finally
            {
                if (secretAttrs != null)
                {
                    g_hash_table_unref(secretAttrs);
                }
                if (accountKeyPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(accountKeyPtr);
                }
                if (serviceKeyPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(serviceKeyPtr);
                }
                if (passwordPtr != IntPtr.Zero)
                {
                    secret_password_free(passwordPtr);
                }
                if (error != null)
                {
                    g_error_free(error);
                }
            }
        }
コード例 #2
0
 public static extern unsafe bool secret_service_store_sync(
     SecretService *service,
     ref SecretSchema schema,
     Glib.GHashTable *attributes,
     string collection,
     string label,
     SecretValue *value,
     IntPtr cancellable,
     out Glib.GError *error);
コード例 #3
0
 public static extern unsafe IntPtr secret_value_unref_to_password(SecretValue *value, out int length);
コード例 #4
0
 public static extern unsafe void secret_value_unref(SecretValue *value);
コード例 #5
0
 public static extern unsafe IntPtr secret_value_get(SecretValue *value, out int length);
コード例 #6
0
        public unsafe void AddOrUpdate(string service, string account, string secret)
        {
            GHashTable * attributes  = null;
            SecretValue *secretValue = null;
            GError *     error       = null;

            try
            {
                SecretService *secService = GetSecretService();

                // Create attributes for the key and user
                attributes = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                   Marshal.FreeHGlobal, Marshal.FreeHGlobal);

                string fullServiceName = CreateServiceName(service);
                IntPtr serviceKeyPtr   = Marshal.StringToHGlobalAnsi(ServiceAttributeName);
                IntPtr serviceValuePtr = Marshal.StringToHGlobalAnsi(fullServiceName);
                g_hash_table_insert(attributes, serviceKeyPtr, serviceValuePtr);

                if (!string.IsNullOrWhiteSpace(account))
                {
                    IntPtr accountKeyPtr   = Marshal.StringToHGlobalAnsi(AccountAttributeName);
                    IntPtr accountValuePtr = Marshal.StringToHGlobalAnsi(account);
                    g_hash_table_insert(attributes, accountKeyPtr, accountValuePtr);
                }

                // Create the secret value object from the secret string
                byte[] secretBytes = Encoding.UTF8.GetBytes(secret);
                secretValue = secret_value_new(secretBytes, secretBytes.Length, PlainTextContentType);

                SecretSchema schema = GetSchema();

                // Store the secret with the associated attributes
                bool result = secret_service_store_sync(
                    secService,
                    ref schema,
                    attributes,
                    null,
                    fullServiceName, // Use full service name as label
                    secretValue,
                    IntPtr.Zero,
                    out error);

                if (error != null)
                {
                    int    code    = error->code;
                    string message = Marshal.PtrToStringAuto(error->message) !;
                    throw new InteropException("Failed to store credentials", code, new Exception(message));
                }

                if (!result)
                {
                    throw new InteropException("Failed to store credentials", -1);
                }
            }
            finally
            {
                if (attributes != null)
                {
                    g_hash_table_destroy(attributes);
                }
                if (secretValue != null)
                {
                    secret_value_unref(secretValue);
                }
                if (error != null)
                {
                    g_error_free(error);
                }
            }
        }
コード例 #7
0
        public unsafe ICredential Get(string key)
        {
            GHashTable *queryAttrs  = null;
            GHashTable *secretAttrs = null;
            IntPtr      userKeyPtr  = IntPtr.Zero;
            IntPtr      passwordPtr = IntPtr.Zero;
            GList *     results     = null;
            GError *    error       = null;

            try
            {
                SecretService *service = GetSecretService();

                // Build search query
                queryAttrs = g_hash_table_new_full(
                    g_str_hash, g_str_equal,
                    Marshal.FreeHGlobal, Marshal.FreeHGlobal);
                IntPtr keyKeyPtr   = Marshal.StringToHGlobalAnsi(KeyAttributeName);
                IntPtr keyValuePtr = Marshal.StringToHGlobalAnsi(key);
                g_hash_table_insert(queryAttrs, keyKeyPtr, keyValuePtr);

                SecretSchema schema = GetSchema();

                // Execute search query and return one result
                results = secret_service_search_sync(
                    service,
                    ref schema,
                    queryAttrs,
                    SecretSearchFlags.SECRET_SEARCH_UNLOCK,
                    IntPtr.Zero,
                    out error);

                if (error != null)
                {
                    int    code    = error->code;
                    string message = Marshal.PtrToStringAuto(error->message) !;
                    throw new InteropException("Failed to search for credentials", code, new Exception(message));
                }

                if (results != null && results->data != null)
                {
                    SecretItem *item = (SecretItem *)results->data;

                    // Although we've unlocked the collection during the search call,
                    // an item can also be individually locked within a collection.
                    // If the item is locked we should try and unlock it.
                    if (secret_item_get_locked(item))
                    {
                        var toUnlockList = new GList
                        {
                            data = (IntPtr)item,
                            next = IntPtr.Zero,
                            prev = IntPtr.Zero
                        };

                        int numUnlocked = secret_service_unlock_sync(
                            service,
                            &toUnlockList,
                            IntPtr.Zero,
                            out _,
                            out error
                            );

                        if (numUnlocked != 1)
                        {
                            throw new InteropException("Failed to unlock item", numUnlocked);
                        }
                    }

                    // Extract the user attribute
                    secretAttrs = secret_item_get_attributes(item);
                    userKeyPtr  = Marshal.StringToHGlobalAnsi(UserAttributeName);
                    IntPtr userValuePtr = g_hash_table_lookup(secretAttrs, userKeyPtr);
                    string userName     = Marshal.PtrToStringAuto(userValuePtr);

                    // Load the secret value
                    secret_item_load_secret_sync(item, IntPtr.Zero, out error);
                    SecretValue *value = secret_item_get_secret(item);
                    if (value == null)
                    {
                        throw new InteropException("Failed to load secret", -1);
                    }

                    // Extract the secret/password
                    passwordPtr = secret_value_unref_to_password(value, out int passwordLength);
                    string password = Marshal.PtrToStringAuto(passwordPtr, passwordLength);

                    return(new GitCredential(userName, password));
                }

                return(null);
            }
            finally
            {
                if (queryAttrs != null)
                {
                    g_hash_table_destroy(queryAttrs);
                }
                if (secretAttrs != null)
                {
                    g_hash_table_unref(secretAttrs);
                }
                if (userKeyPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(userKeyPtr);
                }
                if (passwordPtr != IntPtr.Zero)
                {
                    secret_password_free(passwordPtr);
                }
                if (error != null)
                {
                    g_error_free(error);
                }
                if (results != null)
                {
                    g_list_free_full(results, g_object_unref);
                }
            }
        }
コード例 #8
0
        public unsafe void AddOrUpdate(string key, ICredential credential)
        {
            GHashTable * attributes  = null;
            SecretValue *secretValue = null;
            GError *     error       = null;

            try
            {
                SecretService *service = GetSecretService();

                // Create attributes for the key and user
                attributes = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                   Marshal.FreeHGlobal, Marshal.FreeHGlobal);

                IntPtr keyKeyPtr   = Marshal.StringToHGlobalAnsi(KeyAttributeName);
                IntPtr keyValuePtr = Marshal.StringToHGlobalAnsi(key);
                g_hash_table_insert(attributes, keyKeyPtr, keyValuePtr);

                IntPtr userKeyPtr   = Marshal.StringToHGlobalAnsi(UserAttributeName);
                IntPtr userValuePtr = Marshal.StringToHGlobalAnsi(credential.UserName);
                g_hash_table_insert(attributes, userKeyPtr, userValuePtr);

                // Create the secret value from the password
                byte[] passwordBytes = Encoding.UTF8.GetBytes(credential.Password);
                secretValue = secret_value_new(passwordBytes, passwordBytes.Length, PlainTextContentType);

                SecretSchema schema = GetSchema();

                // Store the secret with the associated attributes
                bool result = secret_service_store_sync(
                    service,
                    ref schema,
                    attributes,
                    null,
                    key, // Use the key also as the label
                    secretValue,
                    IntPtr.Zero,
                    out error);

                if (error != null)
                {
                    int    code    = error->code;
                    string message = Marshal.PtrToStringAuto(error->message) !;
                    throw new InteropException("Failed to store credentials", code, new Exception(message));
                }

                if (!result)
                {
                    throw new InteropException("Failed to store credentials", -1);
                }
            }
            finally
            {
                if (attributes != null)
                {
                    g_hash_table_destroy(attributes);
                }
                if (secretValue != null)
                {
                    secret_value_unref(secretValue);
                }
                if (error != null)
                {
                    g_error_free(error);
                }
            }
        }