summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2018-02-20 10:48:52 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2018-02-20 10:58:41 +0900
commit0ad3aafe2c02cdff21e10a59de56b8a2f9532be3 (patch)
tree1d0702c230671eb76b5690a4f19d1088efb30d03
parent9d7ac1e7deb750cf70d78b9298db9a8a60b62a43 (diff)
downloadlibassuan-0ad3aafe2c02cdff21e10a59de56b8a2f9532be3.tar.gz
Better credential support for other OSes.
* configure.ac (HAVE_UCRED_H, HAVE_SYS_UCRED_H): Check these headers unconditionally. (HAVE_SO_PEERCRED, HAVE_LOCAL_PEEREID): Remove. (HAVE_STRUCT_SOCKPEERCRED_PID): New. (HAVE_GETPEEREID): New. * src/assuan-socket-server.c (accept_connection_bottom): Add support for OpenBSD, macOS, and FreeBSD. -- Code in gpg-agent/command-ssh.c are integrated. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--configure.ac50
-rw-r--r--src/assuan-socket-server.c96
2 files changed, 72 insertions, 74 deletions
diff --git a/configure.ac b/configure.ac
index e824b39..d37f07f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -319,7 +319,7 @@ AC_SUBST(LIBASSUAN_CONFIG_EXTRA_LIBS)
AC_HEADER_STDC
AC_CHECK_HEADERS([string.h locale.h sys/uio.h stdint.h inttypes.h \
sys/types.h sys/stat.h unistd.h sys/time.h fcntl.h \
- sys/select.h ])
+ sys/select.h ucred.h sys/ucred.h])
AC_TYPE_UINTPTR_T
AC_TYPE_UINT16_T
@@ -421,48 +421,16 @@ AC_REPLACE_FUNCS(setenv)
#
-# Check for the getsockopt SO_PEERCRED
+# Check for the getsockopt SO_PEERCRED, etc.
#
-AC_MSG_CHECKING(for SO_PEERCRED)
-AC_CACHE_VAL(assuan_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);],
- assuan_cv_sys_so_peercred=yes,
- assuan_cv_sys_so_peercred=no)
- ])
-AC_MSG_RESULT($assuan_cv_sys_so_peercred)
+AC_CHECK_MEMBER(struct sockpeercred.pid, [], [], [#include <sys/types.h>
+#include <sys/socket.h> ])
-if test $assuan_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(assuan_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);],
- assuan_cv_sys_so_local_peereid=yes,
- assuan_cv_sys_so_local_peereid=no)
- ])
- AC_MSG_RESULT($assuan_cv_sys_so_local_peereid)
-
- if test $assuan_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])
+
+# FreeBSD
+AC_CHECK_FUNCS([getpeereid])
#
diff --git a/src/assuan-socket-server.c b/src/assuan-socket-server.c
index a5b7fd7..4e255c2 100644
--- a/src/assuan-socket-server.c
+++ b/src/assuan-socket-server.c
@@ -31,9 +31,6 @@
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-#ifdef HAVE_UCRED_H
-#include <ucred.h>
-#endif
#ifdef HAVE_W32_SYSTEM
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
@@ -48,6 +45,12 @@
# include <sys/socket.h>
# include <sys/un.h>
#endif
+#ifdef HAVE_SYS_UCRED_H
+#include <sys/ucred.h>
+#endif
+#ifdef HAVE_UCRED_H
+#include <ucred.h>
+#endif
#include "debug.h"
#include "assuan-defs.h"
@@ -60,60 +63,87 @@ accept_connection_bottom (assuan_context_t ctx)
TRACE (ctx, ASSUAN_LOG_SYSIO, "accept_connection_bottom", ctx);
ctx->peercred_valid = 0;
-#ifdef HAVE_SO_PEERCRED
+#ifdef SO_PEERCRED
{
- struct ucred cr;
+#ifdef HAVE_STRUCT_SOCKPEERCRED_PID
+ struct sockpeercred cr; /* OpenBSD */
+#else
+ struct ucred cr; /* GNU/Linux */
+#endif
socklen_t cl = sizeof cr;
- if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl))
+ if (!getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl))
{
- ctx->peercred.pid = cr.pid;
- ctx->peercred.uid = cr.uid;
- ctx->peercred.gid = cr.gid;
- ctx->peercred_valid = 1;
-
- /* This overrides any already set PID if the function returns
- a valid one. */
- if (cr.pid != ASSUAN_INVALID_PID && cr.pid)
- ctx->pid = cr.pid;
+ ctx->peercred_valid = 1;
+ ctx->peercred.pid = cr.pid;
+ ctx->peercred.uid = cr.uid;
+ ctx->peercred.gid = cr.gid;
}
}
-#elif defined (HAVE_GETPEERUCRED)
- {
- ucred_t *ucred = NULL;
+#elif defined (LOCAL_PEERPID)
+ { /* macOS */
+ socklen_t len = sizeof (pid_t);
- if (getpeerucred (fd, &ucred) != -1)
+ if (!getsockopt (fd, SOL_LOCAL, LOCAL_PEERPID, &ctx->peercred.pid, &len))
{
- ctx->peercred.uid = ucred_geteuid (ucred);
- ctx->peercred.gid = ucred_getegid (ucred);
- ctx->peercred.pid = ucred_getpid (ucred);
- ctx->peercred_valid = 1;
- ucred_free (ucred);
+ ctx->peercred_valid = 1;
+
+#if defined (LOCAL_PEERCRED)
+ {
+ struct xucred cr;
+ len = sizeof (struct xucred);
+
+ if (!getsockopt (fd, SOL_LOCAL, LOCAL_PEERCRED, &cr, &len))
+ {
+ ctx->peercred.uid = cr.cr_uid;
+ ctx->peercred.gid = cr.cr_gid;
+ }
+ }
+#endif
}
}
-#elif defined (HAVE_LOCAL_PEEREID)
- {
+#elif defined (LOCAL_PEEREID)
+ { /* NetBSD */
struct unpcbid unp;
socklen_t unpl = sizeof unp;
if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1)
+ {
+ ctx->peercred_valid = 1;
+ ctx->peercred.pid = unp.unp_pid;
+ ctx->peercred.uid = unp.unp_euid;
+ ctx->peercred.gid = unp.unp_egid;
+ }
+ }
+#elif defined (HAVE_GETPEERUCRED)
+ { /* Solaris */
+ ucred_t *ucred = NULL;
+
+ if (getpeerucred (fd, &ucred) != -1)
{
- ctx->peercred.pid = unp.unp_pid;
- ctx->peercred.uid = unp.unp_euid;
- ctx->peercred.gid = unp.unp_egid;
- ctx->peercred_valid = 1;
+ ctx->peercred_valid = 1;
+ ctx->peercred.pid = ucred_getpid (ucred);
+ ctx->peercred.uid = ucred_geteuid (ucred);
+ ctx->peercred.gid = ucred_getegid (ucred);
+
+ ucred_free (ucred);
}
}
#elif defined(HAVE_GETPEEREID)
- {
+ { /* FreeBSD */
if (getpeereid (fd, &ctx->peercred.uid, &ctx->peercred.gid) != -1)
{
- ctx->peercred.pid = ASSUAN_INVALID_PID;
- ctx->peercred_valid = 1;
+ ctx->peercred_valid = 1;
+ ctx->peercred.pid = ASSUAN_INVALID_PID;
}
}
#endif
+ /* This overrides any already set PID if the function returns
+ a valid one. */
+ if (ctx->peercred_valid && ctx->peercred.pid != ASSUAN_INVALID_PID)
+ ctx->pid = ctx->peercred.pid;
+
ctx->inbound.fd = fd;
ctx->inbound.eof = 0;
ctx->inbound.linelen = 0;