summaryrefslogtreecommitdiffstats
path: root/agent
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2008-02-14 20:50:10 +0100
committerWerner Koch <wk@gnupg.org>2008-02-14 20:50:10 +0100
commit30a97e770cce0d6529058052cd78990ff08b84ad (patch)
tree626d2942172a8387a1cc00a1a9bce1e5bba1ad52 /agent
parentAlways search missing certifcates using a running Dirmngr's cache. (diff)
downloadgnupg2-30a97e770cce0d6529058052cd78990ff08b84ad.tar.xz
gnupg2-30a97e770cce0d6529058052cd78990ff08b84ad.zip
Poems for AllowSetForegroundWindow (W32)
Diffstat (limited to 'agent')
-rw-r--r--agent/ChangeLog7
-rw-r--r--agent/call-pinentry.c44
-rw-r--r--agent/command.c24
3 files changed, 72 insertions, 3 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 7dfd7c618..6a0006817 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,10 @@
+2008-02-14 Werner Koch <wk@g10code.com>
+
+ * command.c (agent_inq_pinentry_launched): New.
+ (option_handler): Add option allow-pinentry-notify.
+ * call-pinentry.c (getinfo_pid_cb): New.
+ (start_pinentry): Ask for the PID and notify the client.
+
2008-01-15 Marcus Brinkmann <marcus@g10code.de>
* call-pinentry.c (start_pinentry): Start pinentry in detached
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 9c350a670..8b9f2afd4 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -1,5 +1,5 @@
/* call-pinentry.c - fork of the pinentry to query stuff from the user
- * Copyright (C) 2001, 2002, 2004, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2004, 2007, 2008 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -177,6 +177,23 @@ atfork_cb (void *opaque, int where)
}
}
+static int
+getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
+{
+ unsigned long *pid = opaque;
+ char pidbuf[50];
+
+ /* There is only the pid in the server's response. */
+ if (length >= sizeof pidbuf)
+ length = sizeof pidbuf -1;
+ if (length)
+ {
+ strncpy (pidbuf, buffer, length);
+ pidbuf[length] = 0;
+ *pid = strtoul (pidbuf, NULL, 10);
+ }
+ return 0;
+}
/* Fork off the pin entry if this has not already been done. Note,
that this function must always be used to aquire the lock for the
@@ -193,6 +210,7 @@ start_pinentry (ctrl_t ctrl)
int i;
pth_event_t evt;
const char *tmpstr;
+ unsigned long pinentry_pid;
evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0));
if (!pth_mutex_acquire (&entry_lock, 0, evt))
@@ -357,9 +375,33 @@ start_pinentry (ctrl_t ctrl)
}
}
+
+ /* Now ask the Pinentry for its PID. If the Pinentry is new enough
+ it will send the pid back and we will use an inquire to notify
+ our client. The client may answer the inquiry either with END or
+ with CAN to cancel the pinentry. */
+ rc = assuan_transact (entry_ctx, "GETINFO pid",
+ getinfo_pid_cb, &pinentry_pid,
+ NULL, NULL, NULL, NULL);
+ if (rc)
+ {
+ log_info ("You may want to update to a newer pinentry\n");
+ rc = 0;
+ }
+ else if (!rc && (pid_t)pinentry_pid == (pid_t)(-1))
+ log_error ("pinentry did not return a PID\n");
+ else
+ {
+ rc = agent_inq_pinentry_launched (ctrl, pinentry_pid);
+ if (gpg_err_code (rc) == GPG_ERR_CANCELED)
+ return unlock_pinentry (gpg_error (GPG_ERR_CANCELED));
+ rc = 0;
+ }
+
return 0;
}
+
/* Returns True is the pinentry is currently active. If WAITSECONDS is
greater than zero the function will wait for this many seconds
before returning. */
diff --git a/agent/command.c b/agent/command.c
index 91279fa0f..9c2b8b7f9 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -1,6 +1,6 @@
/* command.c - gpg-agent command handler
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
- * 2006 Free Software Foundation, Inc.
+ * 2006, 2008 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -60,6 +60,8 @@ struct server_local_s
int stopme; /* If set to true the agent will be terminated after
the end of this session. */
#endif
+ int allow_pinentry_notify; /* Set if pinentry notifications should
+ be done. */
};
@@ -318,6 +320,22 @@ agent_write_status (ctrl_t ctrl, const char *keyword, ...)
}
+/* Helper to notify the client about a lauchned Pinentry. Because
+ that might disturb some older clients, this is only done when
+ enabled via an option. Returns an gpg error code. */
+gpg_error_t
+agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
+{
+ char line[100];
+
+ if (!ctrl || !ctrl->server_local
+ || !ctrl->server_local->allow_pinentry_notify)
+ return 0;
+ snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid);
+ return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
+}
+
+
/* GETEVENTCOUNTER
@@ -697,7 +715,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
part. Here is an example transaction:
C: GENKEY
- S: INQUIRE KEYPARM
+ S: INQUIRE KEYPARAM
C: D (genkey (rsa (nbits 1024)))
C: END
S: D (public-key
@@ -1465,6 +1483,8 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
}
else if (!strcmp (key, "use-cache-for-signing"))
ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
+ else if (!strcmp (key, "allow-pinentry-notify"))
+ ctrl->server_local->allow_pinentry_notify = 1;
else
return gpg_error (GPG_ERR_UNKNOWN_OPTION);