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); } } }
public static extern unsafe bool secret_item_delete_sync(SecretItem *self, IntPtr cancellable, out Glib.GError *error);
public static extern unsafe SecretValue *secret_item_get_secret(SecretItem *item);
public static extern unsafe bool secret_item_get_locked(SecretItem *self);
public static extern unsafe void secret_item_load_secret_sync( SecretItem *self, IntPtr cancellable, out Glib.GError *error);
public static extern unsafe Glib.GHashTable *secret_item_get_attributes(SecretItem * item);
public unsafe ICredential Get(string service, string account) { GHashTable *queryAttrs = null; GList * results = null; GError * error = null; try { SecretService *secService = GetSecretService(); queryAttrs = CreateSearchQuery(service, account); SecretSchema schema = GetSchema(); // Execute search query and return the first result results = secret_service_search_sync( secService, 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( secService, &toUnlockList, IntPtr.Zero, out _, out error ); if (numUnlocked != 1) { throw new InteropException("Failed to unlock item", numUnlocked); } } return(CreateCredentialFromItem(item)); } return(null); } finally { if (queryAttrs != null) { g_hash_table_destroy(queryAttrs); } if (error != null) { g_error_free(error); } if (results != null) { g_list_free_full(results, g_object_unref); } } }
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); } } }