aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2017-02-03 16:13:08 +0000
committerWerner Koch <[email protected]>2017-02-03 16:13:08 +0000
commit309f464a5952c7d7504b875bf4853914b1242346 (patch)
tree7c81ec6fbd9c8f02bfcbef9dbcdd3f9323654b92
parentgpg: More diagnostics for a launched pinentry. (diff)
downloadgnupg-309f464a5952c7d7504b875bf4853914b1242346.tar.gz
gnupg-309f464a5952c7d7504b875bf4853914b1242346.zip
agent: Tell the Pinentry the client's pid.
* configure.ac: Check for SO_PEERCRED et al. * agent/agent.h (server_control_s): Add field 'client_pid'. * agent/command.c (start_command_handler): Set CLIENT_PID. * agent/command-ssh.c (get_client_pid): New. (start_command_handler_ssh): Set CLIENT_PID. * agent/call-pinentry.c (start_pinentry): Tell Pinentry the client-pid. Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to '')
-rw-r--r--agent/agent.h1
-rw-r--r--agent/call-pinentry.c14
-rw-r--r--agent/command-ssh.c40
-rw-r--r--agent/command.c9
-rw-r--r--configure.ac47
5 files changed, 110 insertions, 1 deletions
diff --git a/agent/agent.h b/agent/agent.h
index 2db5a5c74..217838472 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -218,6 +218,7 @@ struct server_control_s
session_env_t session_env;
char *lc_ctype;
char *lc_messages;
+ unsigned long client_pid;
/* The current pinentry mode. */
pinentry_mode_t pinentry_mode;
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 2bebee205..384b23a64 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -540,6 +540,20 @@ start_pinentry (ctrl_t ctrl)
}
}
+ /* Tell Pinentry about our client. */
+ if (ctrl->client_pid)
+ {
+ char *optstr;
+ if ((optstr = xtryasprintf ("OPTION owner=%lu", ctrl->client_pid)))
+ {
+ assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ /* We ignore errors because this is just a fancy thing and
+ older pinentries do not support this feature. */
+ xfree (optstr);
+ }
+ }
+
/* Ask the pinentry for its version and flavor and store that as a
* string in MB. This information is useful for helping users to
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index f57bac397..1d4453c84 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -3491,6 +3491,44 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
}
+/* Return the peer's pid. Stripped down code from libassuan. */
+static unsigned long
+get_client_pid (int fd)
+{
+ pid_t client_pid = (pid_t)(-1);
+
+#ifdef HAVE_SO_PEERCRED
+ {
+ struct ucred cr;
+ socklen_t cl = sizeof cr;
+
+ if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl))
+ client_pid = cr.pid;
+ }
+#elif defined (HAVE_GETPEERUCRED)
+ {
+ ucred_t *ucred = NULL;
+
+ if (getpeerucred (fd, &ucred) != -1)
+ {
+ client_pid= ucred_getpid (ucred);
+ ucred_free (ucred);
+ }
+ }
+#elif defined (HAVE_LOCAL_PEEREID)
+ {
+ struct unpcbid unp;
+ socklen_t unpl = sizeof unp;
+
+ if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1)
+ client_pid = unp.unp_pid;
+ }
+#endif
+
+ return client_pid == (pid_t)(-1)? 0 : (unsigned long)client_pid;
+}
+
+
/* Start serving client on SOCK_CLIENT. */
void
start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
@@ -3503,6 +3541,8 @@ start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
if (err)
goto out;
+ ctrl->client_pid = get_client_pid (FD2INT(sock_client));
+
/* Create stream from socket. */
stream_sock = es_fdopen (FD2INT(sock_client), "r+");
if (!stream_sock)
diff --git a/agent/command.c b/agent/command.c
index a2d493167..c8b34e988 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -3288,6 +3288,8 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
for (;;)
{
+ pid_t client_pid;
+
rc = assuan_accept (ctx);
if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
{
@@ -3299,7 +3301,12 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
break;
}
- ctrl->server_local->connect_from_self = (assuan_get_pid (ctx)==getpid ());
+ client_pid = assuan_get_pid (ctx);
+ ctrl->server_local->connect_from_self = (client_pid == getpid ());
+ if (client_pid != ASSUAN_INVALID_PID)
+ ctrl->client_pid = (unsigned long)client_pid;
+ else
+ ctrl->client_pid = 0;
rc = assuan_process (ctx);
if (rc)
diff --git a/configure.ac b/configure.ac
index 75bed06c4..ce02d037a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1375,6 +1375,53 @@ if test $ac_cv_func_mmap != yes -a $mmap_needed = yes; then
AC_MSG_ERROR([[Sorry, the current implemenation requires mmap.]])
fi
+
+#
+# Check for the getsockopt SO_PEERCRED
+# (This has been copied from libassuan)
+#
+AC_MSG_CHECKING(for SO_PEERCRED)
+AC_CACHE_VAL(gnupg_cv_sys_so_peercred,
+ [AC_TRY_COMPILE([#include <sys/socket.h>],
+ [struct ucred cr;
+ int cl = sizeof cr;
+ getsockopt (1, SOL_SOCKET, SO_PEERCRED, &cr, &cl);],
+ gnupg_cv_sys_so_peercred=yes,
+ gnupg_cv_sys_so_peercred=no)
+ ])
+AC_MSG_RESULT($gnupg_cv_sys_so_peercred)
+
+if test $gnupg_cv_sys_so_peercred = yes; then
+ AC_DEFINE(HAVE_SO_PEERCRED, 1,
+ [Defined if SO_PEERCRED is supported (Linux specific)])
+else
+ # Check for the getsockopt LOCAL_PEEREID (NetBSD)
+ AC_MSG_CHECKING(for LOCAL_PEEREID)
+ AC_CACHE_VAL(gnupg_cv_sys_so_local_peereid,
+ [AC_TRY_COMPILE([#include <sys/socket.>
+ #include <sys/un.h>],
+ [struct unpcbid unp;
+ int unpl = sizeof unp;
+ getsockopt (1, SOL_SOCKET, LOCAL_PEEREID, &unp, &unpl);],
+ gnupg_cv_sys_so_local_peereid=yes,
+ gnupg_cv_sys_so_local_peereid=no)
+ ])
+ AC_MSG_RESULT($gnupg_cv_sys_so_local_peereid)
+
+ if test $gnupg_cv_sys_so_local_peereid = yes; then
+ AC_DEFINE(HAVE_LOCAL_PEEREID, 1,
+ [Defined if LOCAL_PEEREID is supported (NetBSD specific)])
+ else
+ # (Open)Solaris
+ AC_CHECK_FUNCS([getpeerucred], AC_CHECK_HEADERS([ucred.h]))
+ if test $ac_cv_func_getpeerucred != yes; then
+ # FreeBSD
+ AC_CHECK_FUNCS([getpeereid])
+ fi
+ fi
+fi
+
+
#
# W32 specific test
#