From 29c1460fd73c4ee7dc4bb9c7d30dcf5b525d0314 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Fri, 21 Jun 2019 06:54:51 +0200 Subject: [PATCH] secret-password: Add store_binary functions This adds a set of functions that takes a SecretValue instead of a text password when storing a secret. This is useful if the stored password is not null-terminated. --- .../libsecret/libsecret-sections.txt | 4 + libsecret/secret-password.c | 213 ++++++++++++++++++ libsecret/secret-password.h | 34 +++ 3 files changed, 251 insertions(+) diff --git a/docs/reference/libsecret/libsecret-sections.txt b/docs/reference/libsecret/libsecret-sections.txt index 03cb96f..d8f9509 100644 --- a/docs/reference/libsecret/libsecret-sections.txt +++ b/docs/reference/libsecret/libsecret-sections.txt @@ -120,6 +120,10 @@ secret_password_storev secret_password_store_finish secret_password_store_sync secret_password_storev_sync +secret_password_store_binary +secret_password_store_binary_sync +secret_password_storev_binary +secret_password_storev_binary_sync secret_password_lookup secret_password_lookupv secret_password_lookup_finish diff --git a/libsecret/secret-password.c b/libsecret/secret-password.c index 1ff0e86..a59d61e 100644 --- a/libsecret/secret-password.c +++ b/libsecret/secret-password.c @@ -156,6 +156,102 @@ secret_password_storev (const SecretSchema *schema, secret_value_unref (value); } +/** + * secret_password_store_binary: (skip) + * @schema: the schema for attributes + * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret + * @label: label for the secret + * @value: a #SecretValue + * @cancellable: optional cancellation object + * @callback: called when the operation completes + * @user_data: data to be passed to the callback + * @...: the attribute keys and values, terminated with %NULL + * + * Store a password in the secret service. + * + * This is similar to secret_password_store(), but takes a + * #SecretValue as the argument instead of a null-terminated password. + * + * This method will return immediately and complete asynchronously. + * + * Since: 0.19.0 + */ +void +secret_password_store_binary (const SecretSchema *schema, + const gchar *collection, + const gchar *label, + SecretValue *value, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + ...) +{ + GHashTable *attributes; + va_list va; + + g_return_if_fail (schema != NULL); + g_return_if_fail (label != NULL); + g_return_if_fail (value != NULL); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + va_start (va, user_data); + attributes = secret_attributes_buildv (schema, va); + va_end (va); + + /* Precondition failed, already warned */ + if (!attributes) + return; + + secret_password_storev_binary (schema, attributes, collection, label, value, + cancellable, callback, user_data); + + g_hash_table_unref (attributes); +} + +/** + * secret_password_storev_binary: (rename-to secret_password_store_binary) + * @schema: the schema for attributes + * @attributes: (element-type utf8 utf8): the attribute keys and values + * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret + * @label: label for the secret + * @value: a #SecretValue + * @cancellable: optional cancellation object + * @callback: called when the operation completes + * @user_data: data to be passed to the callback + * + * Store a password in the secret service. + * + * This is similar to secret_password_storev(), but takes a + * #SecretValue as the argument instead of a null-terminated password. + * + * This method will return immediately and complete asynchronously. + * + * Since: 0.19.0 + */ +void +secret_password_storev_binary (const SecretSchema *schema, + GHashTable *attributes, + const gchar *collection, + const gchar *label, + SecretValue *value, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (schema != NULL); + g_return_if_fail (label != NULL); + g_return_if_fail (value != NULL); + g_return_if_fail (attributes != NULL); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + /* Warnings raised already */ + if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, FALSE)) + return; + + secret_service_store (NULL, schema, attributes, collection, + label, value, cancellable, callback, user_data); +} + /** * secret_password_store_finish: * @result: the asynchronous result passed to the callback @@ -301,6 +397,123 @@ secret_password_storev_sync (const SecretSchema *schema, return ret; } +/** + * secret_password_store_binary_sync: + * @schema: the schema for attributes + * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret + * @label: label for the secret + * @value: a #SecretValue + * @cancellable: optional cancellation object + * @error: location to place an error on failure + * @...: the attribute keys and values, terminated with %NULL + * + * Store a password in the secret service. + * + * This is similar to secret_password_store_sync(), but takes a + * #SecretValue as the argument instead of a null terminated password. + * + * This method may block indefinitely and should not be used in user interface + * threads. + * + * Returns: whether the storage was successful or not + * + * Since: 0.19.0 + */ +gboolean +secret_password_store_binary_sync (const SecretSchema *schema, + const gchar *collection, + const gchar *label, + SecretValue *value, + GCancellable *cancellable, + GError **error, + ...) +{ + GHashTable *attributes; + va_list va; + gboolean ret; + + g_return_val_if_fail (schema != NULL, FALSE); + g_return_val_if_fail (label != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + va_start (va, error); + attributes = secret_attributes_buildv (schema, va); + va_end (va); + + /* Precondition failed, already warned */ + if (!attributes) + return FALSE; + + ret = secret_password_storev_binary_sync (schema, attributes, collection, + label, value, cancellable, error); + + g_hash_table_unref (attributes); + return ret; +} + +/** + * secret_password_storev_binary_sync: (rename-to secret_password_store_binary_sync) + * @schema: the schema for attributes + * @attributes: (element-type utf8 utf8): the attribute keys and values + * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret + * @label: label for the secret + * @value: a #SecretValue + * @cancellable: optional cancellation object + * @error: location to place an error on failure + * + * Store a password in the secret service. + * + * This is similar to secret_password_storev_sync(), but takes a + * #SecretValue as the argument instead of a null-terminated passwords. + * + * This method may block indefinitely and should not be used in user interface + * threads. + * + * Returns: whether the storage was successful or not + * + * Since: 0.19.0 + */ +gboolean +secret_password_storev_binary_sync (const SecretSchema *schema, + GHashTable *attributes, + const gchar *collection, + const gchar *label, + SecretValue *value, + GCancellable *cancellable, + GError **error) +{ + SecretSync *sync; + gboolean ret; + + g_return_val_if_fail (schema != NULL, FALSE); + g_return_val_if_fail (label != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (attributes != NULL, FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* Warnings raised already */ + if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, FALSE)) + return FALSE; + + sync = _secret_sync_new (); + g_main_context_push_thread_default (sync->context); + + secret_password_storev_binary (schema, attributes, collection, label, value, + cancellable, _secret_sync_on_result, sync); + + g_main_loop_run (sync->loop); + + ret = secret_password_store_finish (sync->result, error); + + g_main_context_pop_thread_default (sync->context); + _secret_sync_free (sync); + + return ret; +} + /** * secret_password_lookup: (skip) * @schema: the schema for the attributes diff --git a/libsecret/secret-password.h b/libsecret/secret-password.h index 36cc18d..0719317 100644 --- a/libsecret/secret-password.h +++ b/libsecret/secret-password.h @@ -45,6 +45,24 @@ void secret_password_storev (const SecretSchema *sche GAsyncReadyCallback callback, gpointer user_data); +void secret_password_store_binary (const SecretSchema *schema, + const gchar *collection, + const gchar *label, + SecretValue *value, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + ...); + +void secret_password_storev_binary (const SecretSchema *schema, + GHashTable *attributes, + const gchar *collection, + const gchar *label, + SecretValue *value, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean secret_password_store_finish (GAsyncResult *result, GError **error); @@ -64,6 +82,22 @@ gboolean secret_password_storev_sync (const SecretSchema *sche GCancellable *cancellable, GError **error); +gboolean secret_password_store_binary_sync (const SecretSchema *schema, + const gchar *collection, + const gchar *label, + SecretValue *value, + GCancellable *cancellable, + GError **error, + ...); + +gboolean secret_password_storev_binary_sync (const SecretSchema *schema, + GHashTable *attributes, + const gchar *collection, + const gchar *label, + SecretValue *value, + GCancellable *cancellable, + GError **error); + void secret_password_lookup (const SecretSchema *schema, GCancellable *cancellable, GAsyncReadyCallback callback,