aboutsummaryrefslogtreecommitdiffstats
path: root/src/assuan-socket-server.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2018-02-20 01:48:52 +0000
committerNIIBE Yutaka <[email protected]>2018-02-20 01:58:41 +0000
commit0ad3aafe2c02cdff21e10a59de56b8a2f9532be3 (patch)
tree1d0702c230671eb76b5690a4f19d1088efb30d03 /src/assuan-socket-server.c
parentPost release updates (diff)
downloadlibassuan-0ad3aafe2c02cdff21e10a59de56b8a2f9532be3.tar.gz
libassuan-0ad3aafe2c02cdff21e10a59de56b8a2f9532be3.zip
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 <[email protected]>
Diffstat (limited to 'src/assuan-socket-server.c')
-rw-r--r--src/assuan-socket-server.c96
1 files changed, 63 insertions, 33 deletions
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;