From f7f806afa5083617f4aba02fc3b285b06a7d73d4 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 7 Mar 2017 14:01:17 +0900 Subject: agent: Fix get_client_pid for portability. * configure.ac: Simply check getpeerucred and ucred.h, and structure members. * agent/command-ssh.c: Include ucred.h. (get_client_pid) [HAVE_STRUCT_SOCKPEERCRED_PID]: Use sockpeercred structure for OpenBSD. [LOCAL_PEERPID]: Use LOCAL_PEERPID for macOS. [LOCAL_PEEREID]: Use LOCAL_PEEREID for NetBSD. [HAVE_GETPEERUCRED]: Use getpeerucred for OpenSolaris. -- This change also addresses following bug. GnuPG-bug-id: 2981. Signed-off-by: NIIBE Yutaka --- agent/command-ssh.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'agent/command-ssh.c') diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 3ab41cfdb..c7afe3bc9 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -40,6 +40,9 @@ #include #include #include +#ifdef HAVE_UCRED_H +#include +#endif #include "agent.h" @@ -3556,31 +3559,39 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) } -/* Return the peer's pid. Stripped down code from libassuan. */ +/* Return the peer's pid. */ static unsigned long get_client_pid (int fd) { pid_t client_pid = (pid_t)(-1); -#ifdef HAVE_SO_PEERCRED +#ifdef SO_PEERCRED { +#ifdef HAVE_STRUCT_SOCKPEERCRED_PID + struct sockpeercred cr; +#else struct ucred cr; +#endif socklen_t cl = sizeof cr; if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl)) - client_pid = cr.pid; + { +#if defined (HAVE_STRUCT_SOCKPEERCRED_PID) || defined (HAVE_STRUCT_UCRED_PID) + client_pid = cr.pid; +#elif defined (HAVE_STRUCT_UCRED_CR_PID) + client_pid = cr.cr_pid; +#else +#error "Unknown SO_PEERCRED struct" +#endif + } } -#elif defined (HAVE_GETPEERUCRED) +#elif defined (LOCAL_PEERPID) { - ucred_t *ucred = NULL; + socklen_t len = sizeof (pid_t); - if (getpeerucred (fd, &ucred) != -1) - { - client_pid= ucred_getpid (ucred); - ucred_free (ucred); - } + getsockopt(fd, SOL_LOCAL, LOCAL_PEERPID, &client_pid, &len); } -#elif defined (HAVE_LOCAL_PEEREID) +#elif defined (LOCAL_PEEREID) { struct unpcbid unp; socklen_t unpl = sizeof unp; @@ -3588,6 +3599,16 @@ get_client_pid (int fd) if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1) client_pid = unp.unp_pid; } +#elif defined (HAVE_GETPEERUCRED) + { + ucred_t *ucred = NULL; + + if (getpeerucred (fd, &ucred) != -1) + { + client_pid= ucred_getpid (ucred); + ucred_free (ucred); + } + } #endif return client_pid == (pid_t)(-1)? 0 : (unsigned long)client_pid; -- cgit v1.2.3