From a5db34dcd5991796eb5c370ada5b70b386df9d80 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Thu, 20 Jun 2019 06:55:56 +0200 Subject: [PATCH] secret-value: Add secret_value_unref_to_password This adds the secret_value_unref_to_password function that unreferences and returns the stored secret in non-pageable memory. This is supposed to be used with secret_password_lookup_binary* functions. --- .../libsecret/libsecret-sections.txt | 1 + libsecret/secret-value.c | 64 +++++++++++++------ libsecret/secret-value.h | 3 + 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/docs/reference/libsecret/libsecret-sections.txt b/docs/reference/libsecret/libsecret-sections.txt index d8f9509..f811b9d 100644 --- a/docs/reference/libsecret/libsecret-sections.txt +++ b/docs/reference/libsecret/libsecret-sections.txt @@ -333,6 +333,7 @@ secret_value_get_text secret_value_get_content_type secret_value_ref secret_value_unref +secret_value_unref_to_password SECRET_TYPE_VALUE secret_value_get_type diff --git a/libsecret/secret-value.c b/libsecret/secret-value.c index ca891cb..63464cd 100644 --- a/libsecret/secret-value.c +++ b/libsecret/secret-value.c @@ -256,36 +256,64 @@ is_password_value (SecretValue *value) return FALSE; } +/** + * secret_value_unref_to_password: + * @value: the value + * @length: the length of the secret + * + * Unreference a #SecretValue and steal the secret data in + * #SecretValue as nonpageable memory. + * + * Returns: (transfer full): a new password string stored in nonpageable memory + * which must be freed with secret_password_free() when done + * + * Since: 0.19.0 + */ gchar * -_secret_value_unref_to_password (SecretValue *value) +secret_value_unref_to_password (SecretValue *value, + gsize *length) { SecretValue *val = value; gchar *result; g_return_val_if_fail (value != NULL, NULL); + if (g_atomic_int_dec_and_test (&val->refs)) { + if (val->destroy == egg_secure_free) { + result = val->secret; + if (length) + *length = val->length; + + } else { + result = egg_secure_strndup (val->secret, val->length); + if (val->destroy) + (val->destroy) (val->secret); + if (length) + *length = val->length; + } + g_free (val->content_type); + g_slice_free (SecretValue, val); + + } else { + result = egg_secure_strndup (val->secret, val->length); + if (length) + *length = val->length; + } + + return result; +} + +gchar * +_secret_value_unref_to_password (SecretValue *value) +{ + g_return_val_if_fail (value != NULL, NULL); + if (!is_password_value (value)) { secret_value_unref (value); return NULL; } - if (g_atomic_int_dec_and_test (&val->refs)) { - if (val->destroy == egg_secure_free) { - result = val->secret; - - } else { - result = egg_secure_strndup (val->secret, val->length); - if (val->destroy) - (val->destroy) (val->secret); - } - g_free (val->content_type); - g_slice_free (SecretValue, val); - - } else { - result = egg_secure_strndup (val->secret, val->length); - } - - return result; + return secret_value_unref_to_password (value, NULL); } gchar * diff --git a/libsecret/secret-value.h b/libsecret/secret-value.h index 43b0e09..7699c08 100644 --- a/libsecret/secret-value.h +++ b/libsecret/secret-value.h @@ -51,6 +51,9 @@ SecretValue * secret_value_ref (SecretValue *value); void secret_value_unref (gpointer value); +gchar * secret_value_unref_to_password (SecretValue *value, + gsize *length); + G_DEFINE_AUTOPTR_CLEANUP_FUNC (SecretValue, secret_value_unref) G_END_DECLS