diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2018-02-20 10:48:52 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2018-02-20 10:58:41 +0900 |
commit | 0ad3aafe2c02cdff21e10a59de56b8a2f9532be3 (patch) | |
tree | 1d0702c230671eb76b5690a4f19d1088efb30d03 | |
parent | 9d7ac1e7deb750cf70d78b9298db9a8a60b62a43 (diff) | |
download | libassuan-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.ac | 50 | ||||
-rw-r--r-- | src/assuan-socket-server.c | 96 |
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; |