summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-05-03 14:28:44 -0700
committerGarrett D'Amore <garrett@damore.org>2018-05-03 15:14:45 -0700
commitafd555af4fba0acbf16c174dd9dece24181a1a38 (patch)
tree9d49fec85c58ecad9a034a98e092627968494bc0
parentfa986e725f08e30eab68e16765b2cf71613b871c (diff)
downloadnng-afd555af4fba0acbf16c174dd9dece24181a1a38.tar.gz
nng-afd555af4fba0acbf16c174dd9dece24181a1a38.tar.bz2
nng-afd555af4fba0acbf16c174dd9dece24181a1a38.zip
fixes #383 Would like peerid for IPC
We offer uid, gid, process id, and even zone id where we have them. Docs and tests are provided.
-rw-r--r--CMakeLists.txt4
-rw-r--r--docs/man/nng_ipc.7.adoc47
-rw-r--r--src/core/platform.h15
-rw-r--r--src/platform/posix/posix_aio.h2
-rw-r--r--src/platform/posix/posix_ipc.c64
-rw-r--r--src/platform/posix/posix_pipedesc.c68
-rw-r--r--src/platform/windows/win_ipc.c60
-rw-r--r--src/transport/ipc/ipc.c68
-rw-r--r--src/transport/ipc/ipc.h19
-rw-r--r--tests/ipc.c67
10 files changed, 406 insertions, 8 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6cb8f95b..f1bde337 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -390,6 +390,10 @@ else ()
nng_check_struct_member(msghdr msg_control sys/socket.h NNG_HAVE_MSG_CONTROL)
nng_check_sym (kqueue sys/event.h NNG_HAVE_KQUEUE)
nng_check_sym (epoll_wait sys/epoll.h NNG_HAVE_EPOLL)
+ nng_check_sym (getpeereid unistd.h NNG_HAVE_GETPEEREID)
+ nng_check_sym (SO_PEERCRED sys/socket.h NNG_HAVE_SOPEERCRED)
+ nng_check_sym (LOCAL_PEERCRED sys/un.h NNG_HAVE_LOCALPEERCRED)
+ nng_check_sym (getpeerucred ucred.h NNG_HAVE_GETPEERUCRED)
endif ()
nng_check_sym (strlcat string.h NNG_HAVE_STRLCAT)
diff --git a/docs/man/nng_ipc.7.adoc b/docs/man/nng_ipc.7.adoc
index 5e711dc2..6bfa338b 100644
--- a/docs/man/nng_ipc.7.adoc
+++ b/docs/man/nng_ipc.7.adoc
@@ -68,8 +68,9 @@ the actual structure is of type `<<nng_sockaddr_ipc.5#,nng_sockaddr_ipc>>`.
((`NNG_OPT_IPC_PERMISSIONS`))::
-This write-only option may be used to configure the permissions that
-are used on the UNIX domain socket created by a listener.
+(`int`)
+This write-only option may be applied to a listener to configure the
+permissions that are used on the UNIX domain socket created by that listener.
This property is only supported on POSIX systems.
The value is of type `int`, representing the normal permission bits
on a file, such as `0600` (typically meaning read-write to the owner, and
@@ -84,12 +85,50 @@ NOTE: The _umask_ of the process is *not* applied to these bits.
((`NNG_OPT_IPC_SECURITY_DESCRIPTOR`))::
-This write-only option may be used on Windows platforms to configure
-the `SECURITY_DESCRIPTOR` that is used when creating the underying
+(`PSECURITY_DESCRIPTOR`)
+This write-only option may be used on listeners on Windows platforms to
+configure the `SECURITY_DESCRIPTOR` that is used when creating the underlying
named pipe.
The value is a pointer, `PSECURITY_DESCRIPTOR`, and may only be
applied to listeners that have not been started yet.
+((`NNG_OPT_IPC_PEER_UID`))::
+
+(`uint64_t`)
+This read-only option may be read from a pipe to determine the peer user id.
+This is the effective user id of the peer when either the underlying
+`listen()` or `connect()` calls were made, and is not forgeable.
+This option is generally only available on POSIX systems.
+
+((`NNG_OPT_IPC_PEER_GID`))::
+
+(`uint64_t`)
+This read-only option may be read from a pipe to determine the peer primary
+group id.
+This is the effective group id of the peer when either the underlying
+`listen()` or `connect()` calls were made, and is not forgeable.
+This option is generally only available on POSIX systems.
+
+((`NNG_OPT_IPC_PEER_PID`))::
+
+(`uint64_t`)
+This read-only option may be read from a pipe to determine the process id
+of the peer.
+This option is only available on Windows, Linux, and certain other systems.
+
+NOTE: Applications should not assume that the process ID does not change,
+as it is possible (although unsupported!) for a nefarious process to pass a
+file descriptor between processes.
+However, it is not possible for a nefarious application to forge the identity
+of a well-behaved one using this method.
+
+((`NNG_OPT_IPC_PEER_ZONEID`))::
+
+(`uint64_t`)
+This read-only option may be read from a pipe to determine the zone id
+of the peer.
+Zones (and this option) are only supported on Solaris and illumos systems.
+
== SEE ALSO
<<nng_sockaddr.5#,nng_sockaddr(5)>>,
diff --git a/src/core/platform.h b/src/core/platform.h
index 671556d8..6e7acdbf 100644
--- a/src/core/platform.h
+++ b/src/core/platform.h
@@ -341,6 +341,21 @@ extern void nni_plat_ipc_pipe_send(nni_plat_ipc_pipe *, nni_aio *);
// The platform may modify the iovs.
extern void nni_plat_ipc_pipe_recv(nni_plat_ipc_pipe *, nni_aio *);
+// nni_plat_ipc_pipe_get_peer_uid obtains the peer user id, if possible.
+// NB: Only POSIX systems support user IDs.
+extern int nni_plat_ipc_pipe_get_peer_uid(nni_plat_ipc_pipe *, uint64_t *);
+
+// nni_plat_ipc_pipe_get_peer_gid obtains the peer group id, if possible.
+// NB: Only POSIX systems support group IDs.
+extern int nni_plat_ipc_pipe_get_peer_gid(nni_plat_ipc_pipe *, uint64_t *);
+
+// nni_plat_ipc_pipe_get_peer_pid obtains the peer process id, if possible.
+extern int nni_plat_ipc_pipe_get_peer_pid(nni_plat_ipc_pipe *, uint64_t *);
+
+// nni_plat_ipc_pipe_get_peer_zoneid obtains the peer zone id, if possible.
+// NB: Only illumos & SunOS systems have the notion of "zones".
+extern int nni_plat_ipc_pipe_get_peer_zoneid(nni_plat_ipc_pipe *, uint64_t *);
+
//
// UDP support. UDP is not connection oriented, and only has the notion
// of being bound, sendto, and recvfrom. (It is possible to set up a
diff --git a/src/platform/posix/posix_aio.h b/src/platform/posix/posix_aio.h
index 3954f225..7d6a7231 100644
--- a/src/platform/posix/posix_aio.h
+++ b/src/platform/posix/posix_aio.h
@@ -33,6 +33,8 @@ extern int nni_posix_pipedesc_peername(nni_posix_pipedesc *, nni_sockaddr *);
extern int nni_posix_pipedesc_sockname(nni_posix_pipedesc *, nni_sockaddr *);
extern int nni_posix_pipedesc_set_nodelay(nni_posix_pipedesc *, bool);
extern int nni_posix_pipedesc_set_keepalive(nni_posix_pipedesc *, bool);
+extern int nni_posix_pipedesc_get_peerid(
+ nni_posix_pipedesc *, uint64_t *, uint64_t *, uint64_t *, uint64_t *);
extern int nni_posix_epdesc_init(nni_posix_epdesc **, int);
extern void nni_posix_epdesc_set_local(nni_posix_epdesc *, void *, size_t);
diff --git a/src/platform/posix/posix_ipc.c b/src/platform/posix/posix_ipc.c
index c1bb9292..5ba3c8fb 100644
--- a/src/platform/posix/posix_ipc.c
+++ b/src/platform/posix/posix_ipc.c
@@ -183,4 +183,68 @@ nni_plat_ipc_pipe_recv(nni_plat_ipc_pipe *p, nni_aio *aio)
nni_posix_pipedesc_recv((void *) p, aio);
}
+int
+nni_plat_ipc_pipe_get_peer_uid(nni_plat_ipc_pipe *p, uint64_t *uid)
+{
+ int rv;
+ uint64_t ignore;
+
+ if ((rv = nni_posix_pipedesc_get_peerid(
+ (void *) p, uid, &ignore, &ignore, &ignore)) != 0) {
+ return (rv);
+ }
+ return (0);
+}
+
+int
+nni_plat_ipc_pipe_get_peer_gid(nni_plat_ipc_pipe *p, uint64_t *gid)
+{
+ int rv;
+ uint64_t ignore;
+
+ if ((rv = nni_posix_pipedesc_get_peerid(
+ (void *) p, &ignore, gid, &ignore, &ignore)) != 0) {
+ return (rv);
+ }
+ return (0);
+}
+
+int
+nni_plat_ipc_pipe_get_peer_zoneid(nni_plat_ipc_pipe *p, uint64_t *zid)
+{
+ int rv;
+ uint64_t ignore;
+ uint64_t id;
+
+ if ((rv = nni_posix_pipedesc_get_peerid(
+ (void *) p, &ignore, &ignore, &ignore, &id)) != 0) {
+ return (rv);
+ }
+ if (id == (uint64_t) -1) {
+ // NB: -1 is not a legal zone id (illumos/Solaris)
+ return (NNG_ENOTSUP);
+ }
+ *zid = id;
+ return (0);
+}
+
+int
+nni_plat_ipc_pipe_get_peer_pid(nni_plat_ipc_pipe *p, uint64_t *pid)
+{
+ int rv;
+ uint64_t ignore;
+ uint64_t id;
+
+ if ((rv = nni_posix_pipedesc_get_peerid(
+ (void *) p, &ignore, &ignore, &id, &ignore)) != 0) {
+ return (rv);
+ }
+ if (id == (uint64_t) -1) {
+ // NB: -1 is not a legal process id
+ return (NNG_ENOTSUP);
+ }
+ *pid = id;
+ return (0);
+}
+
#endif // NNG_PLATFORM_POSIX
diff --git a/src/platform/posix/posix_pipedesc.c b/src/platform/posix/posix_pipedesc.c
index f9cbb94b..61005ca8 100644
--- a/src/platform/posix/posix_pipedesc.c
+++ b/src/platform/posix/posix_pipedesc.c
@@ -26,6 +26,12 @@
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
+#if defined(NNG_HAVE_GETPEERUCRED)
+#include <ucred.h>
+#elif defined(NNG_HAVE_LOCALPEERCRED)
+#include <sys/ucred.h>
+#include <sys/un.h>
+#endif
// nni_posix_pipedesc is a descriptor kept one per transport pipe (i.e. open
// file descriptor for TCP socket, etc.) This contains the list of pending
@@ -402,6 +408,68 @@ nni_posix_pipedesc_init(nni_posix_pipedesc **pdp, int fd)
return (0);
}
+int
+nni_posix_pipedesc_get_peerid(nni_posix_pipedesc *pd, uint64_t *euid,
+ uint64_t *egid, uint64_t *prid, uint64_t *znid)
+{
+ int fd = pd->node.fd;
+#if defined(NNG_HAVE_GETPEEREID)
+ uid_t uid;
+ gid_t gid;
+
+ if (getpeereid(fd, &uid, &gid) != 0) {
+ return (nni_plat_errno(errno));
+ }
+ *euid = uid;
+ *egid = gid;
+ *prid = (uint64_t) -1;
+ *znid = (uint64_t) -1;
+ return (0);
+#elif defined(NNG_HAVE_GETPEERUCRED)
+ ucred *ucp;
+ if (getpeerucred(fd, &ucp) != 0) {
+ return (nni_plat_errno(errno));
+ }
+ *euid = ucred_geteuid(ucp);
+ *egid = ucred_geteuid(ucp);
+ *prid = ucred_getpid(ucp);
+ *znid = ucred_getzoneid(ucp);
+ ucred_free(ucp);
+ return (0);
+#elif defined(NNG_HAVE_SOPEERCRED)
+ struct ucred uc;
+ socklen_t len = sizeof(uc);
+ if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &uc, &len) != 0) {
+ return (nni_plat_errno(errno));
+ }
+ *euid = uc.uid;
+ *egid = uc.gid;
+ *prid = uc.pid;
+ *znid = (uint64_t) -1;
+ return (0);
+#elif defined(NNG_HAVE_LOCALPEERCRED)
+ struct xucred xu;
+ socklen_t len = sizeof(xu);
+ if (getsockopt(fd, SOL_LOCAL, LOCAL_PEERCRED, &xu, &len) != 0) {
+ return (nni_plat_errno(errno));
+ }
+ *euid = xu.cr_uid;
+ *egid = xu.cr_gid;
+ *prid = (uint64_t) -1; // XXX: macOS has undocumented LOCAL_PEERPID...
+ *znid = (uint64_t) -1;
+ return (0);
+#else
+ if (fd < 0) {
+ return (NNG_ECLOSED);
+ }
+ NNI_ARG_UNUSED(euid);
+ NNI_ARG_UNUSED(egid);
+ NNI_ARG_UNUSED(prid);
+ NNI_ARG_UNUSED(znid);
+ return (NNG_ENOTSUP);
+#endif
+}
+
void
nni_posix_pipedesc_fini(nni_posix_pipedesc *pd)
{
diff --git a/src/platform/windows/win_ipc.c b/src/platform/windows/win_ipc.c
index 7d118672..c6376cc7 100644
--- a/src/platform/windows/win_ipc.c
+++ b/src/platform/windows/win_ipc.c
@@ -16,6 +16,7 @@
struct nni_plat_ipc_pipe {
HANDLE p;
+ int mode;
nni_win_event rcv_ev;
nni_win_event snd_ev;
};
@@ -128,7 +129,7 @@ nni_win_ipc_pipe_finish(nni_win_event *evt, nni_aio *aio)
}
static int
-nni_win_ipc_pipe_init(nni_plat_ipc_pipe **pipep, HANDLE p)
+nni_win_ipc_pipe_init(nni_plat_ipc_pipe **pipep, HANDLE p, int mode)
{
nni_plat_ipc_pipe *pipe;
int rv;
@@ -136,6 +137,7 @@ nni_win_ipc_pipe_init(nni_plat_ipc_pipe **pipep, HANDLE p)
if ((pipe = NNI_ALLOC_STRUCT(pipe)) == NULL) {
return (NNG_ENOMEM);
}
+ pipe->mode = mode;
rv = nni_win_event_init(&pipe->rcv_ev, &nni_win_ipc_pipe_ops, pipe);
if (rv != 0) {
nni_plat_ipc_pipe_fini(pipe);
@@ -189,6 +191,56 @@ nni_plat_ipc_pipe_fini(nni_plat_ipc_pipe *pipe)
}
int
+nni_plat_ipc_pipe_get_peer_uid(nni_plat_ipc_pipe *pipe, uint64_t *id)
+{
+ NNI_ARG_UNUSED(pipe);
+ NNI_ARG_UNUSED(id);
+ return (NNG_ENOTSUP);
+}
+
+int
+nni_plat_ipc_pipe_get_peer_gid(nni_plat_ipc_pipe *pipe, uint64_t *id)
+{
+ NNI_ARG_UNUSED(pipe);
+ NNI_ARG_UNUSED(id);
+ return (NNG_ENOTSUP);
+}
+
+int
+nni_plat_ipc_pipe_get_peer_zoneid(nni_plat_ipc_pipe *pipe, uint64_t *id)
+{
+ NNI_ARG_UNUSED(pipe);
+ NNI_ARG_UNUSED(id);
+ return (NNG_ENOTSUP);
+}
+
+// nni_plat_ipc_pipe_get_peer_gid obtains the peer group id, if possible.
+// NB: Only POSIX systems support group IDs.
+int
+nni_plat_ipc_pipe_get_peer_pid(nni_plat_ipc_pipe *pipe, uint64_t *pid)
+{
+ ULONG id;
+ switch (pipe->mode) {
+ case NNI_EP_MODE_DIAL:
+ if (!GetNamedPipeServerProcessId(pipe->p, &id)) {
+ return (nni_win_error(GetLastError()));
+ }
+ *pid = id;
+ break;
+ case NNI_EP_MODE_LISTEN:
+ if (!GetNamedPipeClientProcessId(pipe->p, &id)) {
+ return (nni_win_error(GetLastError()));
+ }
+ *pid = id;
+ break;
+ default:
+ // Should never occur!
+ return (NNG_EINVAL);
+ }
+ return (0);
+}
+
+int
nni_plat_ipc_ep_init(nni_plat_ipc_ep **epp, const nni_sockaddr *sa, int mode)
{
const char * path;
@@ -331,7 +383,8 @@ nni_win_ipc_acc_finish(nni_win_event *evt, nni_aio *aio)
oldp = ep->p;
ep->p = newp;
- if ((rv = nni_win_ipc_pipe_init(&pipe, oldp)) != 0) {
+ if ((rv = nni_win_ipc_pipe_init(&pipe, oldp, NNI_EP_MODE_LISTEN)) !=
+ 0) {
// The new pipe is already fine for us. Discard
// the old one, since failed to be able to use it.
DisconnectNamedPipe(oldp);
@@ -466,7 +519,8 @@ nni_win_ipc_conn_thr(void *arg)
}
goto fail;
}
- if (((rv = nni_win_ipc_pipe_init(&pipe, p)) != 0) ||
+ if (((rv = nni_win_ipc_pipe_init(
+ &pipe, p, NNI_EP_MODE_DIAL)) != 0) ||
((rv = nni_win_iocp_register(p)) != 0)) {
goto fail;
}
diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c
index 3dbccb50..e5f3d533 100644
--- a/src/transport/ipc/ipc.c
+++ b/src/transport/ipc/ipc.c
@@ -537,6 +537,54 @@ nni_ipc_pipe_get_addr(void *arg, void *buf, size_t *szp, int typ)
return (nni_copyout_sockaddr(&p->sa, buf, szp, typ));
}
+static int
+nni_ipc_pipe_get_peer_uid(void *arg, void *buf, size_t *szp, int typ)
+{
+ nni_ipc_pipe *p = arg;
+ uint64_t id;
+ int rv;
+ if ((rv = nni_plat_ipc_pipe_get_peer_uid(p->ipp, &id)) != 0) {
+ return (rv);
+ }
+ return (nni_copyout_u64(id, buf, szp, typ));
+}
+
+static int
+nni_ipc_pipe_get_peer_gid(void *arg, void *buf, size_t *szp, int typ)
+{
+ nni_ipc_pipe *p = arg;
+ uint64_t id;
+ int rv;
+ if ((rv = nni_plat_ipc_pipe_get_peer_gid(p->ipp, &id)) != 0) {
+ return (rv);
+ }
+ return (nni_copyout_u64(id, buf, szp, typ));
+}
+
+static int
+nni_ipc_pipe_get_peer_pid(void *arg, void *buf, size_t *szp, int typ)
+{
+ nni_ipc_pipe *p = arg;
+ uint64_t id;
+ int rv;
+ if ((rv = nni_plat_ipc_pipe_get_peer_pid(p->ipp, &id)) != 0) {
+ return (rv);
+ }
+ return (nni_copyout_u64(id, buf, szp, typ));
+}
+
+static int
+nni_ipc_pipe_get_peer_zoneid(void *arg, void *buf, size_t *szp, int typ)
+{
+ nni_ipc_pipe *p = arg;
+ uint64_t id;
+ int rv;
+ if ((rv = nni_plat_ipc_pipe_get_peer_zoneid(p->ipp, &id)) != 0) {
+ return (rv);
+ }
+ return (nni_copyout_u64(id, buf, szp, typ));
+}
+
static void
nni_ipc_ep_fini(void *arg)
{
@@ -785,6 +833,26 @@ static nni_tran_pipe_option nni_ipc_pipe_options[] = {
.po_type = NNI_TYPE_SOCKADDR,
.po_getopt = nni_ipc_pipe_get_addr,
},
+ {
+ .po_name = NNG_OPT_IPC_PEER_UID,
+ .po_type = NNI_TYPE_UINT64,
+ .po_getopt = nni_ipc_pipe_get_peer_uid,
+ },
+ {
+ .po_name = NNG_OPT_IPC_PEER_GID,
+ .po_type = NNI_TYPE_UINT64,
+ .po_getopt = nni_ipc_pipe_get_peer_gid,
+ },
+ {
+ .po_name = NNG_OPT_IPC_PEER_PID,
+ .po_type = NNI_TYPE_UINT64,
+ .po_getopt = nni_ipc_pipe_get_peer_pid,
+ },
+ {
+ .po_name = NNG_OPT_IPC_PEER_ZONEID,
+ .po_type = NNI_TYPE_UINT64,
+ .po_getopt = nni_ipc_pipe_get_peer_zoneid,
+ },
// terminate list
{
.po_name = NULL,
diff --git a/src/transport/ipc/ipc.h b/src/transport/ipc/ipc.h
index 42cbdb08..497fb2b5 100644
--- a/src/transport/ipc/ipc.h
+++ b/src/transport/ipc/ipc.h
@@ -28,4 +28,23 @@ NNG_DECL int nng_ipc_register(void);
// this for security.
#define NNG_OPT_IPC_PERMISSIONS "ipc:permissions"
+// Peer UID. This is only available on POSIX style systems.
+#define NNG_OPT_IPC_PEER_UID "ipc:peer-uid"
+
+// Peer GID (primary group). This is only available on POSIX style systems.
+#define NNG_OPT_IPC_PEER_GID "ipc:peer-gid"
+
+// Peer process ID. Available on Windows, Linux, and SunOS.
+// In theory we could obtain this with the first message sent,
+// but we have elected not to do this for now. (Nice RFE for a FreeBSD
+// guru though.)
+#define NNG_OPT_IPC_PEER_PID "ipc:peer-pid"
+
+// Peer Zone ID. Only on SunOS systems. (Linux containers have no
+// definable kernel identity; they are a user-land fabrication made up
+// from various pieces of different namespaces. FreeBSD does have
+// something called JailIDs, but it isn't obvious how to determine this,
+// or even if processes can use IPC across jail boundaries.)
+#define NNG_OPT_IPC_PEER_ZONEID "ipc:peer-zoneid"
+
#endif // NNG_TRANSPORT_IPC_IPC_H
diff --git a/tests/ipc.c b/tests/ipc.c
index 54996ee3..4c8f5e41 100644
--- a/tests/ipc.c
+++ b/tests/ipc.c
@@ -10,11 +10,76 @@
#include "convey.h"
#include "trantest.h"
+#ifdef _WIN32
+#else
+#include <unistd.h>
+#ifdef NNG_HAVE_GETPEERUCRED
+#include <zone.h>
+#endif
+#endif
+
+#include "transport/ipc/ipc.h"
// Inproc tests.
+static int
+check_props(nng_msg *msg)
+{
+ nng_pipe p;
+ size_t z;
+ nng_sockaddr la;
+ nng_sockaddr ra;
+ uint64_t id;
+
+ p = nng_msg_get_pipe(msg);
+ So(nng_pipe_id(p) > 0);
+ So(nng_pipe_getopt_sockaddr(p, NNG_OPT_LOCADDR, &la) == 0);
+ So(la.s_family == NNG_AF_IPC);
+ // untyped
+ z = sizeof(nng_sockaddr);
+ So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == 0);
+ So(z == sizeof(ra));
+ So(ra.s_family == NNG_AF_IPC);
+
+ So(nng_pipe_getopt_size(p, NNG_OPT_REMADDR, &z) == NNG_EBADTYPE);
+ z = 1;
+ So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == NNG_EINVAL);
+
+#ifdef _WIN32
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_UID, &id) ==
+ NNG_ENOTSUP);
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_GID, &id) ==
+ NNG_ENOTSUP);
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_ZONEID, &id) ==
+ NNG_ENOTSUP);
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_PID, &id) == 0);
+ So(id == GetCurrentProcessId());
+#else
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_UID, &id) == 0);
+ So(id == (uint64_t) getuid());
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_GID, &id) == 0);
+ So(id == (uint64_t) getgid());
+
+#if defined(NNG_HAVE_SOPEERCRED) || defined(NNG_HAVE_GETPEERUCRED)
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_PID, &id) == 0);
+ So(id == (uint64_t) getpid());
+#else
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_PID, &id) ==
+ NNG_ENOTSUP);
+#endif
+
+#ifdef NNG_HAVE_GETPEERUCRED
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_ZONEID, &id) == 0);
+ So(id == getzoneid());
+#else
+ So(nng_pipe_getopt_uint64(p, NNG_OPT_IPC_PEER_ZONEID, &id) ==
+ NNG_ENOTSUP);
+#endif
+#endif
+ return (0);
+}
TestMain("IPC Transport", {
- trantest_test_all("ipc:///tmp/nng_ipc_test_%u");
+ trantest_test_extended("ipc:///tmp/nng_ipc_test_%u", check_props);
nng_fini();
})