diff options
author | Stef Walter <stefw@gnome.org> | 2015-06-07 09:47:38 +0200 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2015-06-07 09:49:09 +0200 |
commit | a8862f74aaed5ac7ea7b3d72984ddd9c40febd34 (patch) | |
tree | c07b02d846547db6f46bbb1accb1622845248f2d | |
parent | ab2182a1efedaae28a58d2a239cdf224da6249ce (diff) | |
download | gnome-keyring-a8862f74aaed5ac7ea7b3d72984ddd9c40febd34.tar.gz |
daemon: Remove the GnuPG agent
The GnuPG agent is incomplete and incompatible with many uses of
GnuPG 2.x.
There is a new pinentry that replaces this. It prompts via system
modal dialogs, and allows optional caching of passphrases.
https://bugzilla.gnome.org/show_bug.cgi?id=750514
-rw-r--r-- | HACKING | 3 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 18 | ||||
-rw-r--r-- | daemon/.gitignore | 2 | ||||
-rw-r--r-- | daemon/Makefile.am | 3 | ||||
-rw-r--r-- | daemon/gkd-glue.c | 41 | ||||
-rw-r--r-- | daemon/gkd-glue.h | 2 | ||||
-rw-r--r-- | daemon/gkd-main.c | 18 | ||||
-rw-r--r-- | daemon/gkd-pkcs11.c | 5 | ||||
-rw-r--r-- | daemon/gnome-keyring-gpg.desktop.in.in | 13 | ||||
-rw-r--r-- | daemon/gpg-agent/.gitignore | 1 | ||||
-rw-r--r-- | daemon/gpg-agent/Makefile.am | 15 | ||||
-rw-r--r-- | daemon/gpg-agent/gkd-gpg-agent-ops.c | 665 | ||||
-rw-r--r-- | daemon/gpg-agent/gkd-gpg-agent-private.h | 118 | ||||
-rw-r--r-- | daemon/gpg-agent/gkd-gpg-agent-standalone.c | 123 | ||||
-rw-r--r-- | daemon/gpg-agent/gkd-gpg-agent.c | 506 | ||||
-rw-r--r-- | daemon/gpg-agent/gkd-gpg-agent.h | 39 | ||||
-rw-r--r-- | daemon/login/gkd-login.c | 8 | ||||
-rw-r--r-- | docs/gnome-keyring-daemon.xml | 4 | ||||
-rw-r--r-- | po/POTFILES.in | 2 | ||||
-rw-r--r-- | po/POTFILES.skip | 3 | ||||
-rw-r--r-- | schema/org.gnome.crypto.cache.gschema.xml | 5 |
22 files changed, 10 insertions, 1586 deletions
@@ -40,9 +40,6 @@ daemon/control daemon/dbus Various DBus bits of the daemon including the Secret Service API. -daemon/gpg-agent - A GPG agent implementation that uses a PKCS#11 module for it's password storage. - daemon/login Used to lock and unlock the daemon. diff --git a/Makefile.am b/Makefile.am index 6b006179..99069201 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,7 +10,6 @@ DISTCHECK_CONFIGURE_FLAGS = \ --enable-doc \ --enable-pam \ --enable-ssh-agent \ - --enable-gpg-agent \ --disable-strict \ --disable-coverage \ --disable-silent-rules \ @@ -198,7 +197,6 @@ include egg/Makefile.am include daemon/Makefile.am include daemon/control/Makefile.am include daemon/dbus/Makefile.am -include daemon/gpg-agent/Makefile.am include daemon/login/Makefile.am include daemon/ssh-agent/Makefile.am include pkcs11/Makefile.am diff --git a/configure.ac b/configure.ac index 65d47c16..3f0f6669 100644 --- a/configure.ac +++ b/configure.ac @@ -350,23 +350,6 @@ fi AM_CONDITIONAL(WITH_SSH, test "$enable_ssh_agent" != "no") # -------------------------------------------------------------------- -# GPG Agent support -# - -AC_ARG_ENABLE([gpg-agent], - AC_HELP_STRING([--disable-gpg-agent], - [Don't include GPG agent in gnome-keyring])) - -if test "$enable_gpg_agent" != "no"; then - AC_DEFINE(WITH_GPG, 1, [Whether to build GPG agent or not]) - gpg_status="yes" -else - gpg_status="no" -fi - -AM_CONDITIONAL(WITH_GPG, test "$enable_gpg_agent" != "no") - -# -------------------------------------------------------------------- # libgcrypt # @@ -664,7 +647,6 @@ echo " SELinux: $selinux_status" echo echo "CONFIGURATION" echo " SSH Agent: $ssh_status" -echo " GPG Agent: $gpg_status" echo echo "BUILD" echo " Debug Build: $debug_status" diff --git a/daemon/.gitignore b/daemon/.gitignore index 031e7ee6..a6d75155 100644 --- a/daemon/.gitignore +++ b/daemon/.gitignore @@ -1,8 +1,6 @@ /gnome-keyring-daemon /org.gnome.keyring.service /org.freedesktop.secrets.service -/gnome-keyring-gpg.desktop -/gnome-keyring-gpg.desktop.in /gnome-keyring-pkcs11.desktop /gnome-keyring-pkcs11.desktop.in /gnome-keyring-secrets.desktop diff --git a/daemon/Makefile.am b/daemon/Makefile.am index e9c4a189..79bd85a3 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -19,7 +19,6 @@ gnome_keyring_daemon_LDADD = \ libgkd-login.la \ libgkd-control.la \ libgkd-ssh-agent.la \ - libgkd-gpg-agent.la \ libgkm-wrap-layer.la \ libgkm-rpc-layer.la \ libgkm-secret-store.la \ @@ -41,7 +40,7 @@ desktop_in_in_files = \ daemon/gnome-keyring-pkcs11.desktop.in.in \ daemon/gnome-keyring-secrets.desktop.in.in \ daemon/gnome-keyring-ssh.desktop.in.in \ - daemon/gnome-keyring-gpg.desktop.in.in + $(NULL) desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in) desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) diff --git a/daemon/gkd-glue.c b/daemon/gkd-glue.c index 6974432f..329a37ed 100644 --- a/daemon/gkd-glue.c +++ b/daemon/gkd-glue.c @@ -23,7 +23,6 @@ #include "gkd-glue.h" #include "gkd-util.h" -#include "gpg-agent/gkd-gpg-agent.h" #include "ssh-agent/gkd-ssh-agent.h" #include "egg/egg-cleanup.h" @@ -67,43 +66,3 @@ gkd_daemon_startup_ssh (void) return TRUE; } - -static void -pkcs11_gpg_cleanup (gpointer unused) -{ - gkd_gpg_agent_shutdown (); -} - -static gboolean -accept_gpg_client (GIOChannel *channel, GIOCondition cond, gpointer unused) -{ - if (cond == G_IO_IN) - gkd_gpg_agent_accept (); - return TRUE; -} - -gboolean -gkd_daemon_startup_gpg (void) -{ - GIOChannel *channel; - const gchar *base_dir; - int sock; - - base_dir = gkd_util_get_master_directory (); - g_return_val_if_fail (base_dir, FALSE); - - sock = gkd_gpg_agent_startup (base_dir); - if (sock == -1) - return FALSE; - - channel = g_io_channel_unix_new (sock); - g_io_add_watch (channel, G_IO_IN | G_IO_HUP, accept_gpg_client, NULL); - g_io_channel_unref (channel); - - /* gpg-agent sets the environment variable */ - gkd_util_push_environment ("GPG_AGENT_INFO", g_getenv ("GPG_AGENT_INFO")); - - egg_cleanup_register (pkcs11_gpg_cleanup, NULL); - - return TRUE; -} diff --git a/daemon/gkd-glue.h b/daemon/gkd-glue.h index db0b26b6..5cca8e4f 100644 --- a/daemon/gkd-glue.h +++ b/daemon/gkd-glue.h @@ -26,6 +26,4 @@ gboolean gkd_daemon_startup_ssh (void); -gboolean gkd_daemon_startup_gpg (void); - #endif /* GKD_GLUE_H_ */ diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c index 2bcfc045..f5676337 100644 --- a/daemon/gkd-main.c +++ b/daemon/gkd-main.c @@ -78,7 +78,6 @@ typedef int socklen_t; #define GKD_COMP_PKCS11 "pkcs11" #define GKD_COMP_SECRETS "secrets" #define GKD_COMP_SSH "ssh" -#define GKD_COMP_GPG "gpg" EGG_SECURE_DECLARE (daemon_main); @@ -112,7 +111,6 @@ static gchar* run_components = DEFAULT_COMPONENTS; static gboolean pkcs11_started = FALSE; static gboolean secrets_started = FALSE; static gboolean ssh_started = FALSE; -static gboolean gpg_started = FALSE; static gboolean dbus_started = FALSE; static gboolean run_foreground = FALSE; @@ -533,7 +531,7 @@ replace_daemon_at (const gchar *directory) /* * The first control_directory is the environment one, always - * prefer that since it's the one that ssh and gpg will connect to + * prefer that since it's the one that ssh will connect to */ if (control_directory == NULL) control_directory = g_strdup (directory); @@ -709,20 +707,6 @@ gkr_daemon_startup_steps (const gchar *components) } #endif -#ifdef WITH_GPG - if (strstr (components, GKD_COMP_GPG)) { - if (gpg_started) { - g_message ("The GPG agent was already initialized"); - } else { - gpg_started = TRUE; - if (!gkd_daemon_startup_gpg ()) { - gpg_started = FALSE; - return FALSE; - } - } - } -#endif - return TRUE; } diff --git a/daemon/gkd-pkcs11.c b/daemon/gkd-pkcs11.c index b2e94c34..71fdfe21 100644 --- a/daemon/gkd-pkcs11.c +++ b/daemon/gkd-pkcs11.c @@ -32,7 +32,6 @@ #include "pkcs11/gnome2-store/gkm-gnome2-store.h" #include "pkcs11/xdg-store/gkm-xdg-store.h" -#include "gpg-agent/gkd-gpg-agent.h" #include "ssh-agent/gkd-ssh-agent.h" #include <string.h> @@ -52,7 +51,6 @@ pkcs11_daemon_cleanup (gpointer unused) gkd_ssh_agent_uninitialize (); gkm_rpc_layer_uninitialize (); - gkd_gpg_agent_uninitialize (); rv = (pkcs11_roof->C_Finalize) (NULL); if (rv != CKR_OK) @@ -115,8 +113,7 @@ gkd_pkcs11_initialize (void) egg_cleanup_register (pkcs11_daemon_cleanup, NULL); - ret = gkd_gpg_agent_initialize (pkcs11_roof) && - gkd_ssh_agent_initialize (pkcs11_roof) && + ret = gkd_ssh_agent_initialize (pkcs11_roof) && gkm_rpc_layer_initialize (pkcs11_roof); return ret; diff --git a/daemon/gnome-keyring-gpg.desktop.in.in b/daemon/gnome-keyring-gpg.desktop.in.in deleted file mode 100644 index b82ecde2..00000000 --- a/daemon/gnome-keyring-gpg.desktop.in.in +++ /dev/null @@ -1,13 +0,0 @@ -[Desktop Entry] -Type=Application -_Name=GPG Password Agent -_Comment=GNOME Keyring: GPG Agent -Exec=@bindir@/gnome-keyring-daemon --start --components=gpg -OnlyShowIn=GNOME;Unity;MATE; -X-GNOME-Autostart-Phase=Initialization -X-GNOME-AutoRestart=false -X-GNOME-Autostart-Notify=true -X-GNOME-Bugzilla-Bugzilla=GNOME -X-GNOME-Bugzilla-Product=gnome-keyring -X-GNOME-Bugzilla-Component=general -X-GNOME-Bugzilla-Version=@VERSION@ diff --git a/daemon/gpg-agent/.gitignore b/daemon/gpg-agent/.gitignore deleted file mode 100644 index 924e19e5..00000000 --- a/daemon/gpg-agent/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/gkd-gpg-agent-standalone diff --git a/daemon/gpg-agent/Makefile.am b/daemon/gpg-agent/Makefile.am deleted file mode 100644 index 70b565dd..00000000 --- a/daemon/gpg-agent/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ - -# ------------------------------------------------------------------------------ -# The ssh-agent component code - -noinst_LTLIBRARIES += \ - libgkd-gpg-agent.la - -libgkd_gpg_agent_la_SOURCES = \ - daemon/gpg-agent/gkd-gpg-agent.c \ - daemon/gpg-agent/gkd-gpg-agent.h \ - daemon/gpg-agent/gkd-gpg-agent-private.h \ - daemon/gpg-agent/gkd-gpg-agent-ops.c -libgkd_gpg_agent_la_CFLAGS = \ - $(GCK_CFLAGS) \ - $(GCR_CFLAGS) diff --git a/daemon/gpg-agent/gkd-gpg-agent-ops.c b/daemon/gpg-agent/gkd-gpg-agent-ops.c deleted file mode 100644 index 2eae16c4..00000000 --- a/daemon/gpg-agent/gkd-gpg-agent-ops.c +++ /dev/null @@ -1,665 +0,0 @@ -/* - * gnome-keyring - * - * Copyright (C) 2010 Stefan Walter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * <http://www.gnu.org/licenses/>. - */ - -#include "config.h" - -#include "gkd-gpg-agent.h" -#include "gkd-gpg-agent-private.h" - -#include "daemon/login/gkd-login.h" - -#include "egg/egg-error.h" -#include "egg/egg-secure-memory.h" - -#include "pkcs11/pkcs11i.h" - -#include <gcr/gcr-base.h> -#include <gcr/gcr-unlock-options.h> - -#include <glib/gi18n.h> - -#include <ctype.h> -#include <string.h> - -#define GKD_GPG_AGENT_PASS_AS_DATA 0x00000001 -#define GKD_GPG_AGENT_REPEAT 0x00000002 - -#define COLLECTION "session" -#define N_COLLECTION 7 - -EGG_SECURE_DECLARE (gpg_agent_ops); - -/* ---------------------------------------------------------------------------------- - * PASSWORD STUFF - */ - -static gchar* -calculate_label_for_key (const gchar *keyid, const gchar *description) -{ - gchar *label = NULL; - gchar **lines, **l; - const gchar *line; - gsize len; - - /* Use the line that starts and ends with quotes */ - if (description) { - lines = g_strsplit (description, "\n", -1); - for (l = lines, line = *l; !label && line; l++, line = *l) { - len = strlen (line); - if (len > 2 && line[0] == '\"' && line[len - 1] == '\"') - label = g_strndup (line + 1, len - 2); - } - g_strfreev (lines); - } - - /* Use last eight characters of keyid */ - if (!label && keyid) { - len = strlen (keyid); - if (len > 8) - label = g_strdup (keyid + (len - 8)); - else - label = g_strdup (keyid); - } - - if (!label) - label = g_strdup (_("Unknown")); - - return label; -} - -static void -do_clear_password (GckSession *session, const gchar *keyid) -{ - gkd_login_clear_password (session, "keyid", keyid, - "source", "gnome-keyring:gpg-agent", NULL); -} - -static void -load_unlock_options (GcrPrompt *prompt) -{ - GSettings *settings; - gchar *method; - gboolean chosen; - - settings = gkd_gpg_agent_settings (); - - method = g_settings_get_string (settings, "gpg-cache-method"); - if (!method) { - method = g_strdup (GCR_UNLOCK_OPTION_SESSION); - - /* COMPAT: with old seahorse-agent settings that were migrated */ - } else if (g_str_equal (method, "gnome")) { - g_free (method); - method = g_strdup (GCR_UNLOCK_OPTION_ALWAYS); - } else if (g_str_equal (method, "internal")) { - g_free (method); - method = g_strdup (GCR_UNLOCK_OPTION_SESSION); - } - - chosen = g_str_equal (GCR_UNLOCK_OPTION_ALWAYS, method); - gcr_prompt_set_choice_chosen (prompt, chosen); - - g_free (method); -} - -static GcrPrompt * -open_password_prompt (GckSession *session, - const gchar *keyid, - const gchar *errmsg, - const gchar *prompt_text, - const gchar *description, - gboolean confirm) -{ - GcrPrompt *prompt; - GError *error = NULL; - gboolean auto_unlock; - const gchar *choice; - - g_assert (GCK_IS_SESSION (session)); - - prompt = GCR_PROMPT (gcr_system_prompt_open (-1, NULL, &error)); - if (prompt == NULL) { - g_warning ("couldn't create prompt for gnupg passphrase: %s", egg_error_message (error)); - g_error_free (error); - return NULL; - } - - gcr_prompt_set_title (prompt, _("Enter Passphrase")); - gcr_prompt_set_message (prompt, prompt_text ? prompt_text : _("Enter Passphrase")); - gcr_prompt_set_description (prompt, description); - - gcr_prompt_set_password_new (prompt, confirm); - gcr_prompt_set_continue_label (prompt, _("Unlock")); - - if (errmsg) - gcr_prompt_set_warning (prompt, errmsg); - - if (keyid == NULL) { - gcr_prompt_set_choice_label (prompt, NULL); - - } else { - auto_unlock = gkd_login_available (session); - - choice = NULL; - if (auto_unlock) - choice = _("Automatically unlock this key, whenever I'm logged in"); - gcr_prompt_set_choice_label (prompt, choice); - - load_unlock_options (prompt); - } - - return prompt; -} - -static gchar* -do_get_password (GckSession *session, const gchar *keyid, const gchar *errmsg, - const gchar *prompt_text, const gchar *description, gboolean confirm) -{ - GSettings *settings; - gchar *password = NULL; - GcrPrompt *prompt; - gboolean chosen; - GError *error = NULL; - gint lifetime; - gchar *method; - gchar *label; - gchar *text; - - g_assert (GCK_IS_SESSION (session)); - - /* Do we have the keyid? */ - password = gkd_login_lookup_password (session, "keyid", keyid, - "source", "gnome-keyring:gpg-agent", NULL); - if (password != NULL) - return password; - - prompt = open_password_prompt (session, keyid, errmsg, prompt_text, - description, confirm); - if (prompt != NULL) { - password = egg_secure_strdup (gcr_prompt_password (prompt, NULL, &error)); - if (password == NULL) { - if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("couldn't prompt for password: %s", egg_error_message (error)); - g_clear_error (&error); - } - } - - if (password != NULL && keyid != NULL) { - settings = gkd_gpg_agent_settings (); - - /* Load up the save options */ - chosen = gcr_prompt_get_choice_chosen (prompt); - - if (chosen) { - method = g_strdup (GCR_UNLOCK_OPTION_ALWAYS); - lifetime = -1; - - } else { - method = g_settings_get_string (settings, "gpg-cache-method"); - lifetime = g_settings_get_int (settings, "gpg-cache-ttl"); - if (g_str_equal (method, GCR_UNLOCK_OPTION_ALWAYS)) { - g_free (method); - method = NULL; - } - } - - /* Now actually save the password */ - text = calculate_label_for_key (keyid, description); - label = g_strdup_printf (_("PGP Key: %s"), text); - gkd_login_store_password (session, password, label, method, lifetime, - "keyid", keyid, "source", "gnome-keyring:gpg-agent", NULL); - g_free (label); - g_free (method); - g_free (text); - } - - g_clear_object (&prompt); - return password; -} - -/* ---------------------------------------------------------------------------------- - * PARSING and UTIL - */ - -/* Is the argument a assuan null parameter? */ -static gboolean -is_null_argument (gchar *arg) -{ - return (strcmp (arg, "X") == 0); -} - -static const gchar HEX_CHARS[] = "0123456789ABCDEF"; - -/* Decode an assuan parameter */ -static void -decode_assuan_arg (gchar *arg) -{ - gchar *t; - gint len; - - for (len = strlen (arg); len > 0; arg++, len--) { - switch (*arg) { - /* + becomes a space */ - case '+': - *arg = ' '; - break; - - /* hex encoded as in URIs */ - case '%': - *arg = '?'; - t = strchr (HEX_CHARS, arg[1]); - if (t != NULL) { - *arg = ((t - HEX_CHARS) & 0xf) << 4; - t = strchr (HEX_CHARS, arg[2]); - if (t != NULL) - *arg |= (t - HEX_CHARS) & 0xf; - } - len -= 2; - if (len < 1) /* last char, null terminate */ - arg[1] = 0; - else /* collapse rest */ - memmove (arg + 1, arg + 3, len); - break; - }; - } -} - -/* Parse an assuan argument that we recognize */ -static guint32 -parse_assuan_flag (gchar *flag) -{ - g_assert (flag); - if (g_str_equal (flag, GPG_AGENT_FLAG_DATA)) - return GKD_GPG_AGENT_PASS_AS_DATA; - else if (g_str_has_prefix (flag, GPG_AGENT_FLAG_REPEAT)) { - gint count = 1; - - flag += strlen(GPG_AGENT_FLAG_REPEAT); - if (*flag == '=') { - count = atoi (++flag); - if (!(count == 0 || count == 1)) - g_warning ("--repeat=%d treated as --repeat=1", count); - } - - if (count) - return GKD_GPG_AGENT_REPEAT; - } - return 0; -} - -/* Split a line into each of it's arguments. This modifies line */ -static void -split_arguments (gchar *line, guint32 *flags, ...) -{ - gchar **cur; - gchar *flag; - va_list ap; - - va_start (ap, flags); - - /* Initial white space */ - while (*line && isspace (*line)) - line++; - - /* The flags */ - if (flags) { - *flags = 0; - - while (*line) { - /* Options start with a double dash */ - if(!(line[0] == '-' && line[1] == '-')) - break; - line +=2; - flag = line; - - /* All non-whitespace */ - while (*line && !isspace (*line)) - line++; - - /* Skip and null any whitespace */ - while (*line && isspace (*line)) { - *line = 0; - line++; - } - - *flags |= parse_assuan_flag (flag); - } - } - - /* The arguments */ - while ((cur = va_arg (ap, gchar **)) != NULL) { - if (*line) { - *cur = line; - - /* All non-whitespace */ - while (*line && !isspace (*line)) - line++; - - /* Skip and null any whitespace */ - while (*line && isspace (*line)) { - *line = 0; - line++; - } - - decode_assuan_arg (*cur); - } else { - *cur = NULL; - } - } - - va_end (ap); -} - -static guint -x11_display_dot_offset (const gchar *d) -{ - const gchar *p; - guint l = strlen (d); - - for (p = d + l; *p != '.'; --p) { - if (p <= d) - break; - if (*p == ':') - break; - } - if (*p == '.') - l = p - d; - - return l; -} - -/* - * Displays are of the form: hostname:displaynumber.screennumber, where - * hostname can be empty (to indicate a local connection). - * Two displays are equivalent if their hostnames and displaynumbers match. - */ -static gboolean -x11_displays_eq (const gchar *d1, const gchar *d2) -{ - guint l1, l2; - l1 = x11_display_dot_offset (d1); - l2 = x11_display_dot_offset (d2); - return (g_ascii_strncasecmp (d1, d2, l1 > l2 ? l1 : l2) == 0); -} - -/* Does command have option? */ -static gboolean -command_has_option (gchar *command, gchar *option) -{ - gboolean has_option = FALSE; - - if (!strcmp (command, GPG_AGENT_GETPASS)) { - has_option = (!strcmp (option, GPG_AGENT_FLAG_DATA) || - !strcmp (option, GPG_AGENT_FLAG_REPEAT)); - } - /* else if (other commands) */ - - return has_option; -} - -static const char HEXC[] = "0123456789abcdef"; - -/* Encode a password in hex */ -static gchar* -hex_encode_password (const gchar *pass) -{ - int j, c; - gchar *enc, *k; - - /* Encode the password */ - c = sizeof (gchar *) * ((strlen (pass) * 2) + 1); - k = enc = egg_secure_alloc (c); - - /* Simple hex encoding */ - while (*pass) { - j = *(pass) >> 4 & 0xf; - *(k++) = HEXC[j]; - - j = *(pass++) & 0xf; - *(k++) = HEXC[j]; - } - - return enc; -} - -static gchar* -uri_encode_password (const gchar *value) -{ - gchar *p; - gchar *result; - - /* Just allocate for worst case */ - result = egg_secure_alloc ((strlen (value) * 3) + 1); - - /* Now loop through looking for escapes */ - p = result; - while (*value) { - - /* These characters we let through verbatim */ - if (*value && (g_ascii_isalnum (*value) || strchr ("_-.", *value) != NULL)) { - *(p++) = *(value++); - - /* All others get encoded */ - } else { - *(p++) = '%'; - *(p++) = HEXC[((unsigned char)*value) >> 4]; - *(p++) = HEXC[((unsigned char)*value) & 0x0F]; - ++value; - } - } - - *p = 0; - return result; -} - -/* ---------------------------------------------------------------------------------- - * OPERATIONS - */ - -gboolean -gkd_gpg_agent_ops_options (GkdGpgAgentCall *call, gchar *args) -{ - gchar *option; - gsize len; - - split_arguments (args, NULL, &option, NULL); - if (!option) { - g_message ("received invalid option argument"); - return gkd_gpg_agent_send_reply (call, FALSE, "105 parameter error"); - } - - /* - * If the option is a display option we make sure it's - * the same as our display. Otherwise we don't answer. - */ - len = strlen (GPG_AGENT_OPT_DISPLAY); - if (g_ascii_strncasecmp (option, GPG_AGENT_OPT_DISPLAY, len) == 0) { - option += len; - - if (x11_displays_eq (option, g_getenv ("DISPLAY"))) { - call->terminal_ok = TRUE; - } else { - g_message ("received request different display: %s", option); - return gkd_gpg_agent_send_reply (call, FALSE, "105 parameter conflict"); - } - } - - /* We don't do anything with the other options right now */ - return gkd_gpg_agent_send_reply (call, TRUE, NULL); -} - -gboolean -gkd_gpg_agent_ops_getpass (GkdGpgAgentCall *call, gchar *args) -{ - gchar *id; - gchar *errmsg; - gchar *prompt; - gchar *description; - GckSession *session; - gchar *password; - gchar *encoded; - guint32 flags; - - /* We don't answer this unless it's from the right terminal */ - if (!call->terminal_ok) { - g_message ("received passphrase request from wrong terminal"); - return gkd_gpg_agent_send_reply (call, FALSE, "113 Server Resource Problem"); - } - - split_arguments (args, &flags, &id, &errmsg, &prompt, &description, NULL); - - if (!id || !errmsg || !prompt || !description) { - g_message ("received invalid passphrase request"); - return gkd_gpg_agent_send_reply (call, FALSE, "105 parameter error"); - } - - if (is_null_argument (id)) - id = NULL; - if (is_null_argument (errmsg)) - errmsg = NULL; - if (is_null_argument (prompt)) - prompt = NULL; - if (is_null_argument (description)) - description = NULL; - - session = gkd_gpg_agent_checkout_main_session (); - g_return_val_if_fail (session, FALSE); - - password = do_get_password (session, id, errmsg, prompt, description, - flags & GKD_GPG_AGENT_REPEAT); - - gkd_gpg_agent_checkin_main_session (session); - - if (password == NULL) { - gkd_gpg_agent_send_reply (call, FALSE, "111 cancelled"); - } else if (flags & GKD_GPG_AGENT_PASS_AS_DATA) { - encoded = uri_encode_password (password); - gkd_gpg_agent_send_data (call, encoded); - gkd_gpg_agent_send_reply (call, TRUE, NULL); - egg_secure_strfree (encoded); - } else { - encoded = hex_encode_password (password); - gkd_gpg_agent_send_reply (call, TRUE, encoded); - egg_secure_strfree (encoded); - } - - egg_secure_strfree (password); - return TRUE; -} - -gboolean -gkd_gpg_agent_ops_clrpass (GkdGpgAgentCall *call, gchar *args) -{ - GckSession *session; - gchar *id; - - /* We don't answer this unless it's from the right terminal */ - if (!call->terminal_ok) { - g_message ("received passphrase request from wrong terminal"); - return gkd_gpg_agent_send_reply (call, FALSE, "113 Server Resource Problem"); - } - - split_arguments (args, NULL, &id, NULL); - - if (!id) { - gkd_gpg_agent_send_reply (call, FALSE, "105 parameter error"); - g_warning ("received invalid clear pass request: %s", args); - } - - session = gkd_gpg_agent_checkout_main_session (); - g_return_val_if_fail (session, FALSE); - - /* Ignore the result, always return success */ - do_clear_password (session, id); - - gkd_gpg_agent_checkin_main_session (session); - - gkd_gpg_agent_send_reply (call, TRUE, NULL); - return TRUE; -} - -gboolean -gkd_gpg_agent_ops_getinfo (GkdGpgAgentCall *call, gchar *request) -{ - gchar *args; - gboolean implemented = FALSE; - - args = strchr (request, ' '); - if (args) { - *args = 0; - args++; - while (isspace (*args)) - args++; - } - - if (!strcmp (request, "cmd_has_option")) { - gchar *command = args; - gchar *option; - - if (!command || !*command) - return gkd_gpg_agent_send_reply (call, FALSE, "105 parameter error"); - - option = strchr(args, ' '); - - if (option) { - *option = 0; - option++; - while (isspace (*option)) - option++; - } else { - return gkd_gpg_agent_send_reply (call, FALSE, "105 parameter error"); - } - - implemented = command_has_option (command, option); - } - - /* else if (other info request) */ - - if (implemented) - return gkd_gpg_agent_send_reply (call, TRUE, NULL); - else - return gkd_gpg_agent_send_reply (call, FALSE, "280 not implemented"); -} - -gboolean -gkd_gpg_agent_ops_nop (GkdGpgAgentCall *call, gchar *args) -{ - return gkd_gpg_agent_send_reply (call, TRUE, NULL); -} - -gboolean -gkd_gpg_agent_ops_bye (GkdGpgAgentCall *call, gchar *args) -{ - gkd_gpg_agent_send_reply (call, TRUE, "closing connection"); - return FALSE; -} - -gboolean -gkd_gpg_agent_ops_reset (GkdGpgAgentCall *call, gchar *args) -{ - /* We keep no state :) */ - return gkd_gpg_agent_send_reply (call, TRUE, NULL); -} - -gboolean -gkd_gpg_agent_ops_id (GkdGpgAgentCall *call, gchar *args) -{ - return gkd_gpg_agent_send_reply (call, TRUE, "gnome-keyring-daemon"); -} diff --git a/daemon/gpg-agent/gkd-gpg-agent-private.h b/daemon/gpg-agent/gkd-gpg-agent-private.h deleted file mode 100644 index e205c4f0..00000000 --- a/daemon/gpg-agent/gkd-gpg-agent-private.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * gnome-keyring - * - * Copyright (C) 2010 Stefan Walter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * <http://www.gnu.org/licenses/>. - */ - -#ifndef GKDGPGPRIVATE_H_ -#define GKDGPGPRIVATE_H_ - -#include "egg/egg-buffer.h" - -#include "pkcs11/pkcs11.h" - -#include <gck/gck.h> - -#include <glib.h> - -typedef struct _GkdGpgAgentCall { - int sock; - GckModule *module; - GIOChannel *channel; - gboolean terminal_ok; -} GkdGpgAgentCall; - -/* ----------------------------------------------------------------------------- - * GPG CONSTANTS - */ - - -/* Commands */ -#define GPG_AGENT_ID "AGENT_ID" -#define GPG_AGENT_NOP "NOP" -#define GPG_AGENT_BYE "BYE" -#define GPG_AGENT_RESET "RESET" -#define GPG_AGENT_OPTION "OPTION" -#define GPG_AGENT_GETPASS "GET_PASSPHRASE" -#define GPG_AGENT_CLRPASS "CLEAR_PASSPHRASE" -#define GPG_AGENT_GETINFO "GETINFO" - -#define GPG_AGENT_OPT_DISPLAY "display=" - -/* Options */ -#define GPG_AGENT_FLAG_DATA "data" -#define GPG_AGENT_FLAG_CHECK "check" -#define GPG_AGENT_FLAG_REPEAT "repeat" - -/* Responses */ -#define GPG_AGENT_OK "OK " -#define GPG_AGENT_ERR "ERR " -#define GPG_AGENT_DATA "D " - -/* ----------------------------------------------------------------------------- - * gkd-gpg-agent-ops.c - */ - -/* ----------------------------------------------------------------------------- - * gkd-gpg-agent.c - */ - -gboolean gkd_gpg_agent_initialize_with_module (GckModule *module); - -GckSession* gkd_gpg_agent_checkout_main_session (void); - -void gkd_gpg_agent_checkin_main_session (GckSession* session); - -gboolean gkd_gpg_agent_send_reply (GkdGpgAgentCall *call, - gboolean ok, - const gchar *response); - -gboolean gkd_gpg_agent_send_data (GkdGpgAgentCall *call, - const gchar *data); - -GSettings* gkd_gpg_agent_settings (void); - -/* ----------------------------------------------------------------------------- - * gkd-gpg-agent-ops - */ - - -gboolean gkd_gpg_agent_ops_options (GkdGpgAgentCall *call, - gchar *args); - -gboolean gkd_gpg_agent_ops_getpass (GkdGpgAgentCall *call, - gchar *args); - -gboolean gkd_gpg_agent_ops_clrpass (GkdGpgAgentCall *call, - gchar *args); - -gboolean gkd_gpg_agent_ops_getinfo (GkdGpgAgentCall *call, - gchar *args); - -gboolean gkd_gpg_agent_ops_nop (GkdGpgAgentCall *call, - gchar *args); - -gboolean gkd_gpg_agent_ops_bye (GkdGpgAgentCall *call, - gchar *args); - -gboolean gkd_gpg_agent_ops_reset (GkdGpgAgentCall *call, - gchar *args); - -gboolean gkd_gpg_agent_ops_id (GkdGpgAgentCall *call, - gchar *args); - -#endif /*GKDGPGPRIVATE_H_*/ diff --git a/daemon/gpg-agent/gkd-gpg-agent-standalone.c b/daemon/gpg-agent/gkd-gpg-agent-standalone.c deleted file mode 100644 index db9776e1..00000000 --- a/daemon/gpg-agent/gkd-gpg-agent-standalone.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * gnome-keyring - * - * Copyright (C) 2010 Stefan Walter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * <http://www.gnu.org/licenses/>. - */ - -#include "config.h" - -#include "gkd-gpg-agent.h" -#include "gkd-gpg-agent-private.h" - -#include "egg/egg-error.h" -#include "egg/egg-secure-memory.h" - -#include <gck/gck.h> - -#include <glib.h> -#include <glib-object.h> - -#include <pwd.h> -#include <string.h> -#include <unistd.h> - -EGG_SECURE_DEFINE_GLIB_GLOBALS (); - -static gboolean -accept_client (GIOChannel *channel, GIOCondition cond, gpointer unused) -{ - gkd_gpg_agent_accept (); - return TRUE; -} - -static gboolean -authenticate_slot (GckModule *module, GckSlot *slot, gchar *label, gchar **password, gpointer unused) -{ - gchar *prompt = g_strdup_printf ("Enter token password (%s): ", label); - char *result = getpass (prompt); - g_free (prompt); - *password = g_strdup (result); - memset (result, 0, strlen (result)); - return TRUE; -} - -static gboolean -authenticate_object (GckModule *module, GckObject *object, gchar *label, gchar **password) -{ - gchar *prompt = g_strdup_printf ("Enter object password (%s): ", label); - char *result = getpass (prompt); - g_free (prompt); - *password = g_strdup (result); - memset (result, 0, strlen (result)); - return TRUE; -} - -int -main(int argc, char *argv[]) -{ - GckModule *module; - GError *error = NULL; - GIOChannel *channel; - GMainLoop *loop; - gboolean ret; - int sock; - -#if !GLIB_CHECK_VERSION(2,35,0) - g_type_init (); -#endif - - if (argc <= 1) { - g_message ("specify pkcs11 module on the command line"); - return 1; - } - - module = gck_module_initialize (argv[1], NULL, &error); - if (!module) { - g_message ("couldn't load pkcs11 module: %s", egg_error_message (error)); - g_clear_error (&error); - return 1; - } - - g_signal_connect (module, "authenticate-slot", G_CALLBACK (authenticate_slot), NULL); - g_signal_connect (module, "authenticate-object", G_CALLBACK (authenticate_object), NULL); - - ret = gkd_gpg_agent_initialize_with_module (module); - g_object_unref (module); - - if (ret == FALSE) - return 1; - - sock = gkd_gpg_agent_startup ("/tmp"); - if (sock == -1) - return 1; - - channel = g_io_channel_unix_new (sock); - g_io_add_watch (channel, G_IO_IN | G_IO_HUP, accept_client, NULL); - g_io_channel_unref (channel); - - g_print ("GPG_AGENT_INFO=%s\n", g_getenv ("GPG_AGENT_INFO")); - - /* Run a main loop */ - loop = g_main_loop_new (NULL, FALSE); - g_main_loop_run (loop); - g_main_loop_unref (loop); - - gkd_gpg_agent_shutdown (); - gkd_gpg_agent_uninitialize (); - - return 0; -} diff --git a/daemon/gpg-agent/gkd-gpg-agent.c b/daemon/gpg-agent/gkd-gpg-agent.c deleted file mode 100644 index 0d94adc2..00000000 --- a/daemon/gpg-agent/gkd-gpg-agent.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * gnome-keyring - * - * Copyright (C) 2010 Stefan Walter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * <http://www.gnu.org/licenses/>. - */ - -#include "config.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "gkd-gpg-agent.h" -#include "gkd-gpg-agent-private.h" - -#include "egg/egg-error.h" -#include "egg/egg-secure-memory.h" - -#ifndef HAVE_SOCKLEN_T -typedef int socklen_t; -#endif - -/* The loaded PKCS#11 module */ -static GckModule *pkcs11_module = NULL; - -#ifndef KL -#define KL(s) ((sizeof(s) - 1) / sizeof(s[0])) -#endif - -static gboolean -write_all (int fd, const gchar *buf, int len) -{ - int all = len; - int res; - - if (len == -1) - all = len = strlen (buf); - - while (len > 0) { - - res = write (fd, buf, len); - - if (res <= 0) { - if (errno == EAGAIN && errno == EINTR) - continue; - if (errno != EPIPE) - g_warning ("couldn't write %u bytes to client: %s", all, - res < 0 ? g_strerror (errno) : ""); - return FALSE; - } else { - len -= res; - buf += res; - } - } - - return TRUE; -} - -/* Called when seahorse-actions has a response to send back */ -gboolean -gkd_gpg_agent_send_reply (GkdGpgAgentCall *call, gboolean ok, const gchar *response) -{ - int fd = g_io_channel_unix_get_fd (call->channel); - if (!write_all (fd, ok ? GPG_AGENT_OK : GPG_AGENT_ERR, ok ? KL (GPG_AGENT_OK) : KL (GPG_AGENT_ERR)) || - (response && !write_all (fd, response, -1)) || - !write_all (fd, "\n", 1)) - return FALSE; - - return TRUE; -} - -gboolean -gkd_gpg_agent_send_data (GkdGpgAgentCall *call, const gchar *data) -{ - int fd = g_io_channel_unix_get_fd (call->channel); - if (!write_all (fd, GPG_AGENT_DATA, KL (GPG_AGENT_DATA)) || - !write_all (fd, data, -1) || - !write_all (fd, "\n", 1)) - return FALSE; - - return TRUE; -} - -/* Process a request line from client */ -static gboolean -process_line (GkdGpgAgentCall *call, gchar *line) -{ - gchar *args; - - g_assert (call); - g_assert (line); - - g_strstrip (line); - - if (!*line) - return TRUE; - - /* Split the command off from the args */ - args = strchr (line, ' '); - if (args) { - *args = 0; - args++; - } else { - /* Pointer to the end, empty string */ - args = line + strlen (line); - } - - if (g_ascii_strcasecmp (line, GPG_AGENT_OPTION) == 0) - return gkd_gpg_agent_ops_options (call, args); - - else if (g_ascii_strcasecmp (line, GPG_AGENT_GETPASS) == 0) - return gkd_gpg_agent_ops_getpass (call, args); - - else if (g_ascii_strcasecmp (line, GPG_AGENT_CLRPASS) == 0) - return gkd_gpg_agent_ops_clrpass (call, args); - - else if (g_ascii_strcasecmp (line, GPG_AGENT_GETINFO) == 0) - return gkd_gpg_agent_ops_getinfo (call, args); - - else if (g_ascii_strcasecmp (line, GPG_AGENT_NOP) == 0) - return gkd_gpg_agent_ops_nop (call, args); - - else if (g_ascii_strcasecmp (line, GPG_AGENT_BYE) == 0) - return gkd_gpg_agent_ops_bye (call, args); - - else if (g_ascii_strcasecmp (line, GPG_AGENT_RESET) == 0) - return gkd_gpg_agent_ops_reset (call, args); - - else if (g_ascii_strcasecmp (line, GPG_AGENT_ID) == 0) - return gkd_gpg_agent_ops_id (call, args); - - else { - g_message ("unrecognized command: %s", line); - return gkd_gpg_agent_send_reply (call, FALSE, "103 unknown command"); - } -} - -static gpointer -run_client_thread (gpointer data) -{ - gint *socket = data; - GError *error = NULL; - GkdGpgAgentCall call; - GIOStatus status; - gboolean cont = TRUE; - gchar *line; - gsize n_line; - - g_assert (GCK_IS_MODULE (pkcs11_module)); - - call.sock = g_atomic_int_get (socket); - call.channel = g_io_channel_unix_new (call.sock); - g_io_channel_set_encoding (call.channel, NULL, NULL); - g_io_channel_set_close_on_unref (call.channel, FALSE); - call.module = g_object_ref (pkcs11_module); - - /* Initial response on the connection */ - gkd_gpg_agent_send_reply (&call, TRUE, "your orders please"); - - while (cont) { - line = NULL; - n_line = 0; - - /* Read in a line */ - status = g_io_channel_read_line (call.channel, &line, &n_line, NULL, &error); - switch (status) { - case G_IO_STATUS_ERROR: - g_critical ("gpg agent couldn't read from socket: %s", - egg_error_message (error)); - g_clear_error (&error); - cont = FALSE; - break; - case G_IO_STATUS_NORMAL: - cont = process_line (&call, line); - g_free (line); - break; - case G_IO_STATUS_EOF: - cont = FALSE; - break; - case G_IO_STATUS_AGAIN: - break; - default: - g_return_val_if_reached (NULL); - break; - }; - } - - g_io_channel_shutdown (call.channel, FALSE, NULL); - g_io_channel_unref (call.channel); - g_object_unref (call.module); - - close (call.sock); - g_atomic_int_set (socket, -1); - - return NULL; -} - -/* -------------------------------------------------------------------------------------- - * SESSION MANAGEMENT - */ - -/* The main PKCS#11 session that owns objects, and the mutex/cond for waiting on it */ -static GckSession *pkcs11_main_session = NULL; -static gboolean pkcs11_main_checked = FALSE; -static GMutex *pkcs11_main_mutex = NULL; -static GCond *pkcs11_main_cond = NULL; - -GckSession* -gkd_gpg_agent_checkout_main_session (void) -{ - GckSession *result; - - g_mutex_lock (pkcs11_main_mutex); - - g_assert (GCK_IS_SESSION (pkcs11_main_session)); - while (pkcs11_main_checked) - g_cond_wait (pkcs11_main_cond, pkcs11_main_mutex); - pkcs11_main_checked = TRUE; - result = g_object_ref (pkcs11_main_session); - - g_mutex_unlock (pkcs11_main_mutex); - - return result; -} - -void -gkd_gpg_agent_checkin_main_session (GckSession *session) -{ - g_assert (GCK_IS_SESSION (session)); - - g_mutex_lock (pkcs11_main_mutex); - - g_assert (session == pkcs11_main_session); - g_assert (pkcs11_main_checked); - - g_object_unref (session); - pkcs11_main_checked = FALSE; - g_cond_signal (pkcs11_main_cond); - - g_mutex_unlock (pkcs11_main_mutex); -} - -/* -------------------------------------------------------------------------------------- - * SETTINGS - */ - -/* The cache settings */ -static GSettings *cache_settings = NULL; - -GSettings* -gkd_gpg_agent_settings (void) -{ - g_return_val_if_fail (cache_settings, NULL); - return cache_settings; -} - -/* -------------------------------------------------------------------------------------- - * MAIN THREAD - */ - -typedef struct _Client { - GThread *thread; - gint sock; - gchar *buffer; - gsize n_buffer; -} Client; - -/* Each client thread in this list */ -static GList *socket_clients = NULL; - -/* The main socket we listen on */ -static int socket_fd = -1; - -/* The path of the socket listening on */ -static char socket_path[1024] = { 0, }; - -void -gkd_gpg_agent_accept (void) -{ - Client *client; - struct sockaddr_un addr; - socklen_t addrlen; - GError *error = NULL; - GList *l; - int new_fd; - - g_return_if_fail (socket_fd != -1); - - /* Cleanup any completed dispatch threads */ - for (l = socket_clients; l; l = g_list_next (l)) { - client = l->data; - if (g_atomic_int_get (&client->sock) == -1) { - g_thread_join (client->thread); - g_slice_free (Client, client); - l->data = NULL; - } - } - socket_clients = g_list_remove_all (socket_clients, NULL); - - addrlen = sizeof (addr); - new_fd = accept (socket_fd, (struct sockaddr*) &addr, &addrlen); - if (new_fd < 0) { - g_warning ("cannot accept GPG agent connection: %s", strerror (errno)); - return; - } - - client = g_slice_new0 (Client); - client->sock = new_fd; - - /* And create a new thread/process */ - client->thread = g_thread_new ("gpg-agent", run_client_thread, &client->sock); - if (!client->thread) { - g_warning ("couldn't create thread GPG agent connection: %s", - error && error->message ? error->message : ""); - g_slice_free (Client, client); - return; - } - - socket_clients = g_list_append (socket_clients, client); -} - -void -gkd_gpg_agent_shutdown (void) -{ - Client *client; - GList *l; - - if (socket_fd != -1) - close (socket_fd); - - if (*socket_path) - unlink (socket_path); - - /* Stop all of the dispatch threads */ - for (l = socket_clients; l; l = g_list_next (l)) { - client = l->data; - - /* Forcibly shutdown the connection */ - if (client->sock != -1) - shutdown (client->sock, SHUT_RDWR); - g_thread_join (client->thread); - - /* This is always closed by client thread */ - g_assert (client->sock == -1); - g_slice_free (Client, client); - } - - g_list_free (socket_clients); - socket_clients = NULL; -} - -void -gkd_gpg_agent_uninitialize (void) -{ - gboolean ret; - - g_assert (pkcs11_main_mutex); - ret = g_mutex_trylock (pkcs11_main_mutex); - g_assert (ret); - - g_assert (GCK_IS_SESSION (pkcs11_main_session)); - g_assert (!pkcs11_main_checked); - g_object_unref (pkcs11_main_session); - pkcs11_main_session = NULL; - - g_mutex_unlock (pkcs11_main_mutex); - g_mutex_clear (pkcs11_main_mutex); - g_free (pkcs11_main_mutex); - g_cond_clear (pkcs11_main_cond); - g_free (pkcs11_main_cond); - - g_assert (pkcs11_module); - g_object_unref (pkcs11_module); - pkcs11_module = NULL; - - g_assert (cache_settings); - g_object_unref (cache_settings); - cache_settings = NULL; -} - -int -gkd_gpg_agent_initialize (CK_FUNCTION_LIST_PTR funcs) -{ - GckModule *module; - gboolean ret; - - g_return_val_if_fail (funcs, -1); - - module = gck_module_new (funcs); - ret = gkd_gpg_agent_initialize_with_module (module); - g_object_unref (module); - return ret; -} - -gboolean -gkd_gpg_agent_initialize_with_module (GckModule *module) -{ - GckSession *session = NULL; - GckSlot *slot; - GError *error = NULL; - GList *modules; - - g_assert (GCK_IS_MODULE (module)); - - /* - * Find the right slot. - */ - modules = g_list_append (NULL, module); - slot = gck_modules_token_for_uri (modules, "pkcs11:token=Secret%20Store", &error); - g_list_free (modules); - - if (!slot) { - g_warning ("couldn't find secret store module: %s", egg_error_message (error)); - g_clear_error (&error); - return FALSE; - } - - /* Try and open a session */ - session = gck_slot_open_session (slot, GCK_SESSION_READ_WRITE | GCK_SESSION_AUTHENTICATE, NULL, &error); - g_object_unref (slot); - - if (!session) { - g_warning ("couldn't select a usable pkcs#11 slot for the gpg agent to use"); - g_clear_error (&error); - return FALSE; - } - - pkcs11_module = g_object_ref (module); - - pkcs11_main_mutex = g_new0 (GMutex, 1); - g_mutex_init (pkcs11_main_mutex); - pkcs11_main_cond = g_new0 (GCond, 1); - g_cond_init (pkcs11_main_cond); - pkcs11_main_checked = FALSE; - pkcs11_main_session = session; - - cache_settings = g_settings_new ("org.gnome.crypto.cache"); - - return TRUE; -} - -int -gkd_gpg_agent_startup (const gchar *prefix) -{ - struct sockaddr_un addr; - gchar *agent_info; - int sock; - - g_return_val_if_fail (prefix, -1); - - snprintf (socket_path, sizeof (socket_path), "%s/gpg", prefix); - unlink (socket_path); - - sock = socket (AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - g_warning ("couldn't create socket: %s", g_strerror (errno)); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path)); - if (bind (sock, (struct sockaddr *) & addr, sizeof (addr)) < 0) { - g_warning ("couldn't bind to socket: %s: %s", socket_path, g_strerror (errno)); - close (sock); - return -1; - } - - if (listen (sock, 128) < 0) { - g_warning ("couldn't listen on socket: %s", g_strerror (errno)); - close (sock); - return -1; - } - - /* - * TODO: This should be <socket>:<pid>:<protocol_version> - * Need to figure out a way to get the PID in there. - */ - agent_info = g_strdup_printf ("%s:0:1", socket_path); - g_setenv ("GPG_AGENT_INFO", agent_info, TRUE); - g_free (agent_info); - - socket_fd = sock; - return sock; -} diff --git a/daemon/gpg-agent/gkd-gpg-agent.h b/daemon/gpg-agent/gkd-gpg-agent.h deleted file mode 100644 index 320d6492..00000000 --- a/daemon/gpg-agent/gkd-gpg-agent.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * gnome-keyring - * - * Copyright (C) 2010 Stefan Walter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * <http://www.gnu.org/licenses/>. - */ - - -#ifndef GKDGPGAGENT_H_ -#define GKDGPGAGENT_H_ - -#include <glib.h> - -#include "pkcs11/pkcs11.h" - -int gkd_gpg_agent_startup (const gchar *prefix); - -void gkd_gpg_agent_accept (void); - -void gkd_gpg_agent_shutdown (void); - -gboolean gkd_gpg_agent_initialize (CK_FUNCTION_LIST_PTR funcs); - -void gkd_gpg_agent_uninitialize (void); - -#endif /* GKDGPGAGENT_H_ */ diff --git a/daemon/login/gkd-login.c b/daemon/login/gkd-login.c index a3d6dcfb..549fbe37 100644 --- a/daemon/login/gkd-login.c +++ b/daemon/login/gkd-login.c @@ -482,7 +482,7 @@ find_saved_items (GckSession *session, search = gck_session_create_object (session, gck_builder_end (&builder), NULL, &error); if (search == NULL) { - g_warning ("couldn't perform search for gpg agent stored passphrases: %s", + g_warning ("couldn't perform search for stored passphrases: %s", egg_error_message (error)); g_clear_error (&error); return NULL; @@ -493,7 +493,7 @@ find_saved_items (GckSession *session, g_object_unref (search); if (data == NULL) { - g_warning ("couldn't retrieve list of gpg agent stored passphrases: %s", + g_warning ("couldn't retrieve list of stored passphrases: %s", egg_error_message (error)); g_clear_error (&error); return NULL; @@ -574,7 +574,7 @@ gkd_login_lookup_password (GckSession *session, data = gck_object_get_data_full (l->data, CKA_VALUE, egg_secure_realloc, NULL, &length, &error); if (error) { if (!g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN)) - g_warning ("couldn't lookup gpg agent password: %s", egg_error_message (error)); + g_warning ("couldn't lookup password: %s", egg_error_message (error)); g_clear_error (&error); data = NULL; } else { @@ -704,7 +704,7 @@ gkd_login_store_password (GckSession *session, item = gck_session_create_object (session, gck_builder_end (&builder), NULL, &error); if (item == NULL) { - g_warning ("couldn't store gpg agent password: %s", egg_error_message (error)); + g_warning ("couldn't store password: %s", egg_error_message (error)); g_clear_error (&error); ret = FALSE; } else { diff --git a/docs/gnome-keyring-daemon.xml b/docs/gnome-keyring-daemon.xml index 93533915..b8781596 100644 --- a/docs/gnome-keyring-daemon.xml +++ b/docs/gnome-keyring-daemon.xml @@ -59,10 +59,10 @@ <variablelist> <varlistentry> - <term><option>-c</option>, <option>--components=<parameter>ssh,secrets,gpg,pkcs11</parameter></option></term> + <term><option>-c</option>, <option>--components=<parameter>ssh,secrets,pkcs11</parameter></option></term> <listitem> <para>Ask the daemon to only initialize certain components. Valid - components are <literal>ssh</literal>, <literal>gpg</literal>, + components are <literal>ssh</literal>, <literal>secrets</literal>, <literal>pkcs11</literal>.</para> <para>By default all components are initialized.</para> </listitem> diff --git a/po/POTFILES.in b/po/POTFILES.in index 1f92a0d3..6d1a337e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -3,11 +3,9 @@ daemon/dbus/gkd-secret-change.c daemon/dbus/gkd-secret-create.c daemon/dbus/gkd-secret-unlock.c -daemon/gnome-keyring-gpg.desktop.in.in daemon/gnome-keyring-pkcs11.desktop.in.in daemon/gnome-keyring-secrets.desktop.in.in daemon/gnome-keyring-ssh.desktop.in.in -daemon/gpg-agent/gkd-gpg-agent-ops.c daemon/login/gkd-login.c daemon/org.gnome.keyring.service.in egg/dotlock.c diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 9de11d3a..e652b97a 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -1,10 +1,9 @@ daemon/gnome-keyring-secrets.desktop.in daemon/gnome-keyring-ssh.desktop.in -daemon/gnome-keyring-gpg.desktop.in daemon/gnome-keyring-pkcs11.desktop.in daemon/org.freedesktop.secrets.service.in daemon/org.gnome.keyring.service.in # POTFILES.skip insists on finding files $builddir :S x86_64/ -_build/
\ No newline at end of file +_build/ diff --git a/schema/org.gnome.crypto.cache.gschema.xml b/schema/org.gnome.crypto.cache.gschema.xml index 45473993..377a6a9e 100644 --- a/schema/org.gnome.crypto.cache.gschema.xml +++ b/schema/org.gnome.crypto.cache.gschema.xml @@ -13,10 +13,5 @@ <summary>Cache Time To Live</summary> <description>The amount of time in seconds to cache passphrases when the 'idle' or 'timeout' gpg-cache-method are in use.</description> </key> - <key name="gpg-cache-authorize" type="b"> - <default>false</default> - <summary>Authorize Cache Access</summary> - <description>Not yet implemented.</description> - </key> </schema> </schemalist> |