diff options
author | zavok <an2qzavok@gmail.com> | 2015-11-23 17:08:20 +0300 |
---|---|---|
committer | zavok <an2qzavok@gmail.com> | 2015-11-23 17:08:20 +0300 |
commit | 51da5915b03d9b06936ac32f47287beb73d96973 (patch) | |
tree | ad7a5eca744666befa37adb779e4fb2daccc3627 /pinentry/password-cache.c |
This is a "barely works" version of spine, I hope it works, at least barely.
Diffstat (limited to 'pinentry/password-cache.c')
-rw-r--r-- | pinentry/password-cache.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/pinentry/password-cache.c b/pinentry/password-cache.c new file mode 100644 index 0000000..70b33f4 --- /dev/null +++ b/pinentry/password-cache.c @@ -0,0 +1,163 @@ +/* password-cache.c - Password cache support. + Copyright (C) 2015 g10 Code GmbH + + This file is part of PINENTRY. + + PINENTRY is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + PINENTRY is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#ifdef HAVE_LIBSECRET +# include <libsecret/secret.h> +#endif + +#include "password-cache.h" +#include "memory.h" + +#ifdef HAVE_LIBSECRET +static const SecretSchema * +gpg_schema (void) +{ + static const SecretSchema the_schema = { + "org.gnupg.Passphrase", SECRET_SCHEMA_NONE, + { + { "stored-by", SECRET_SCHEMA_ATTRIBUTE_STRING }, + { "keygrip", SECRET_SCHEMA_ATTRIBUTE_STRING }, + { "NULL", 0 }, + } + }; + return &the_schema; +} + +static char * +keygrip_to_label (const char *keygrip) +{ + char const prefix[] = "GnuPG: "; + char *label; + + label = malloc (sizeof (prefix) + strlen (keygrip)); + if (label) + { + memcpy (label, prefix, sizeof (prefix) - 1); + strcpy (&label[sizeof (prefix) - 1], keygrip); + } + return label; +} +#endif + +void +password_cache_save (const char *keygrip, const char *password) +{ +#ifdef HAVE_LIBSECRET + char *label; + GError *error = NULL; + + if (! *keygrip) + return; + + label = keygrip_to_label (keygrip); + if (! label) + return; + + if (! secret_password_store_sync (gpg_schema (), + SECRET_COLLECTION_DEFAULT, + label, password, NULL, &error, + "stored-by", "GnuPG Pinentry", + "keygrip", keygrip, NULL)) + { + printf("Failed to cache password for key %s with secret service: %s\n", + keygrip, error->message); + + g_error_free (error); + } + + free (label); +#else + return; +#endif +} + +char * +password_cache_lookup (const char *keygrip) +{ +#ifdef HAVE_LIBSECRET + GError *error = NULL; + char *password; + char *password2; + + if (! *keygrip) + return NULL; + + password = secret_password_lookup_nonpageable_sync + (gpg_schema (), NULL, &error, + "keygrip", keygrip, NULL); + + if (error != NULL) + { + printf("Failed to lookup password for key %s with secret service: %s\n", + keygrip, error->message); + g_error_free (error); + return NULL; + } + if (! password) + /* The password for this key is not cached. Just return NULL. */ + return NULL; + + /* The password needs to be returned in secmem allocated memory. */ + password2 = secmem_malloc (strlen (password) + 1); + if (password2) + strcpy(password2, password); + else + printf("secmem_malloc failed: can't copy password!\n"); + + secret_password_free (password); + + return password2; +#else + return NULL; +#endif +} + +/* Try and remove the cached password for key grip. Returns -1 on + error, 0 if the key is not found and 1 if the password was + removed. */ +int +password_cache_clear (const char *keygrip) +{ +#ifdef HAVE_LIBSECRET + GError *error = NULL; + int removed = secret_password_clear_sync (gpg_schema (), NULL, &error, + "keygrip", keygrip, NULL); + if (error != NULL) + { + printf("Failed to clear password for key %s with secret service: %s\n", + keygrip, error->message); + g_debug("%s", error->message); + g_error_free (error); + return -1; + } + if (removed) + return 1; + return 0; +#else + return -1; +#endif +} |