agent: Fix get_client_pid for portability.
authorNIIBE Yutaka <gniibe@fsij.org>
Tue, 7 Mar 2017 05:01:17 +0000 (14:01 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Tue, 7 Mar 2017 05:06:35 +0000 (14:06 +0900)
* 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 <gniibe@fsij.org>
agent/command-ssh.c
configure.ac

index 3ab41cf..c7afe3b 100644 (file)
@@ -40,6 +40,9 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <assert.h>
+#ifdef HAVE_UCRED_H
+#include <ucred.h>
+#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;
index 5fc2b85..6d35450 100644 (file)
@@ -1274,7 +1274,8 @@ AC_MSG_NOTICE([checking for header files])
 AC_HEADER_STDC
 AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h \
                   pty.h utmp.h pwd.h inttypes.h signal.h sys/select.h     \
-                  stdint.h signal.h util.h libutil.h termios.h])
+                  stdint.h signal.h util.h libutil.h termios.h \
+                  ucred.h])
 
 AC_HEADER_TIME
 
@@ -1394,49 +1395,13 @@ fi
 
 
 #
-# Check for the getsockopt SO_PEERCRED
-# (This has been copied from libassuan)
+# Check for the getsockopt SO_PEERCRED, etc.
 #
-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)
+AC_CHECK_MEMBERS([struct ucred.pid, struct ucred.cr_pid, struct sockpeercred.pid], [], [], [#include <sys/types.h>
+#include <sys/socket.h> ])
 
-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
+# (Open)Solaris
+AC_CHECK_FUNCS([getpeerucred])
 
 
 #