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.
This commit is contained in:
Daiki Ueno 2019-06-20 06:55:56 +02:00 committed by Daiki Ueno
parent 2ae6ec89f4
commit a5db34dcd5
3 changed files with 50 additions and 18 deletions

View File

@ -333,6 +333,7 @@ secret_value_get_text
secret_value_get_content_type secret_value_get_content_type
secret_value_ref secret_value_ref
secret_value_unref secret_value_unref
secret_value_unref_to_password
<SUBSECTION Standard> <SUBSECTION Standard>
SECRET_TYPE_VALUE SECRET_TYPE_VALUE
secret_value_get_type secret_value_get_type

View File

@ -256,36 +256,64 @@ is_password_value (SecretValue *value)
return FALSE; 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 * gchar *
_secret_value_unref_to_password (SecretValue *value) secret_value_unref_to_password (SecretValue *value,
gsize *length)
{ {
SecretValue *val = value; SecretValue *val = value;
gchar *result; gchar *result;
g_return_val_if_fail (value != NULL, NULL); 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)) { if (!is_password_value (value)) {
secret_value_unref (value); secret_value_unref (value);
return NULL; return NULL;
} }
if (g_atomic_int_dec_and_test (&val->refs)) { return secret_value_unref_to_password (value, NULL);
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;
} }
gchar * gchar *

View File

@ -51,6 +51,9 @@ SecretValue * secret_value_ref (SecretValue *value);
void secret_value_unref (gpointer 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_DEFINE_AUTOPTR_CLEANUP_FUNC (SecretValue, secret_value_unref)
G_END_DECLS G_END_DECLS