aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/ipcperms.c114
-rw-r--r--tests/ipcwinsec.c200
3 files changed, 316 insertions, 0 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 6db01e82..3cfc89fa 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -136,6 +136,8 @@ add_nng_test(httpserver 30 NNG_SUPP_HTTP)
add_nng_test(idhash 5 ON)
add_nng_test(inproc 5 NNG_TRANSPORT_INPROC)
add_nng_test(ipc 5 NNG_TRANSPORT_IPC)
+add_nng_test(ipcperms 5 NNG_TRANSPORT_IPC)
+add_nng_test(ipcwinsec 5 NNG_TRANSPORT_IPC)
add_nng_test(list 5 ON)
add_nng_test(message 5 ON)
add_nng_test(multistress 60 ON)
diff --git a/tests/ipcperms.c b/tests/ipcperms.c
new file mode 100644
index 00000000..84801efd
--- /dev/null
+++ b/tests/ipcperms.c
@@ -0,0 +1,114 @@
+//
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+//
+// This software is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+#include "convey.h"
+#include "trantest.h"
+
+#include "nng.h"
+
+#include "protocol/reqrep0/rep.h"
+#include "protocol/reqrep0/req.h"
+#include "transport/ipc/ipc.h"
+
+#include "stubs.h"
+
+#ifndef _WIN32
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <unistd.h>
+#endif
+
+#define ADDR "/tmp/ipc_perms_test"
+
+// Inproc tests.
+
+#ifdef _WIN32
+TestMain("IPC Permissions", {
+
+ atexit(nng_fini);
+ Convey("Given a socket and an IPC listener", {
+ nng_socket s;
+ nng_listener l;
+
+ So(nng_rep0_open(&s) == 0);
+ Reset({ nng_close(s); });
+ So(nng_listener_create(&l, s, "ipc://" ADDR) == 0);
+ Convey("We cannot set perms on Windows", {
+ So(nng_listener_setopt_int(l, NNG_OPT_IPC_PERMISSIONS,
+ 0444) == NNG_ENOTSUP);
+ });
+ });
+})
+#else
+TestMain("IPC Permissions", {
+ atexit(nng_fini);
+
+ Convey("Given a socket and an IPC listener", {
+ nng_socket s;
+ nng_listener l;
+
+ So(nng_rep0_open(&s) == 0);
+ Reset({
+ nng_close(s);
+ unlink(ADDR);
+ });
+ So(nng_listener_create(&l, s, "ipc://" ADDR) == 0);
+ Convey("We can set perms on POSIX", {
+ struct stat st;
+ So(nng_listener_setopt_int(
+ l, NNG_OPT_IPC_PERMISSIONS, 0444) == 0);
+ So(nng_listener_start(l, 0) == 0);
+ So(stat(ADDR, &st) == 0);
+ So((st.st_mode & 0777) == 0444);
+
+ Convey("And permissions are honored", {
+ struct sockaddr_un sa;
+ int cfd;
+
+ if (geteuid() == 0) {
+ Skip("Running as root");
+ }
+ strcpy(sa.sun_path, ADDR);
+ sa.sun_family = AF_UNIX;
+ So((cfd = socket(AF_UNIX, SOCK_STREAM, 0)) >=
+ 0);
+ Reset({ close(cfd); });
+ So(connect(cfd, (void *) &sa, sizeof(sa)) < 0);
+ So(errno == EACCES);
+ });
+ });
+
+ Convey("We cannot set perms after it is started", {
+ So(nng_listener_start(l, 0) == 0);
+ So(nng_listener_setopt_int(
+ l, NNG_OPT_IPC_PERMISSIONS, 0444) == NNG_EBUSY);
+ });
+
+ Convey("We cannot set bogus permissions", {
+ So(nng_listener_setopt_int(l, NNG_OPT_IPC_PERMISSIONS,
+ S_IFREG) == NNG_EINVAL);
+ });
+ });
+
+ Convey("We cannot set perms on an IPC dialer", {
+ nng_socket s;
+ nng_dialer d;
+
+ So(nng_rep0_open(&s) == 0);
+ Reset({ nng_close(s); });
+ So(nng_dialer_create(&d, s, "ipc://" ADDR) == 0);
+ So(nng_dialer_setopt_int(d, NNG_OPT_IPC_PERMISSIONS, 0444) ==
+ NNG_ENOTSUP);
+ });
+})
+#endif \ No newline at end of file
diff --git a/tests/ipcwinsec.c b/tests/ipcwinsec.c
new file mode 100644
index 00000000..80ec163c
--- /dev/null
+++ b/tests/ipcwinsec.c
@@ -0,0 +1,200 @@
+//
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+//
+// This software is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+#include "convey.h"
+#include "trantest.h"
+
+#include "nng.h"
+
+#include "protocol/reqrep0/rep.h"
+#include "protocol/reqrep0/req.h"
+#include "transport/ipc/ipc.h"
+
+#include "stubs.h"
+
+#define ADDR "/tmp/ipc_winsec_test"
+
+// Inproc tests.
+
+#ifndef _WIN32
+TestMain("IPC Security Descriptor", {
+
+ atexit(nng_fini);
+ Convey("Given a socket and an IPC listener", {
+ nng_socket s;
+ nng_listener l;
+ int x;
+
+ So(nng_rep0_open(&s) == 0);
+ Reset({ nng_close(s); });
+ So(nng_listener_create(&l, s, "ipc://" ADDR) == 0);
+ Convey("We cannot set Windows SECURITY_DESCRIPTOR on POSIX", {
+ So(nng_listener_setopt_ptr(l,
+ NNG_OPT_IPC_SECURITY_DESCRIPTOR,
+ &x) == NNG_ENOTSUP);
+ });
+ });
+})
+#else
+
+#include <assert.h>
+
+// Microsoft prefers CamelCase header names, but relies on case insensitive
+// file systems to make that work. The rest of the world (min-gw64 included)
+// uses case sensitive names and lowercase.
+
+#include <accctrl.h>
+
+#include <sddl.h>
+
+#include <aclapi.h>
+
+SECURITY_DESCRIPTOR *
+sdescAuthUsers(PSID sid, PACL *aclp)
+{
+ SECURITY_DESCRIPTOR *sdesc;
+ EXPLICIT_ACCESS xa;
+ ACL * acl;
+
+ sdesc = calloc(SECURITY_DESCRIPTOR_MIN_LENGTH, 1);
+ assert(sdesc != NULL);
+
+ InitializeSecurityDescriptor(sdesc, SECURITY_DESCRIPTOR_REVISION);
+
+ xa.grfAccessPermissions = GENERIC_READ | GENERIC_WRITE;
+ xa.grfAccessMode = SET_ACCESS;
+ xa.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+ xa.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ xa.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ xa.Trustee.ptstrName = (LPSTR) sid;
+
+ SetEntriesInAcl(1, &xa, NULL, &acl);
+ *aclp = acl;
+
+ SetSecurityDescriptorDacl(sdesc, TRUE, acl, FALSE);
+ return (sdesc);
+}
+
+TestMain("IPC Security Descriptor", {
+ atexit(nng_fini);
+
+ Convey("Given a socket and an IPC listener", {
+ nng_socket s;
+ nng_listener l;
+
+ So(nng_rep0_open(&s) == 0);
+ Reset({ nng_close(s); });
+
+ So(nng_listener_create(&l, s, "ipc://" ADDR) == 0);
+ Convey("We can set security descriptor on Windows", {
+
+ SECURITY_DESCRIPTOR *sdesc;
+ SID users;
+ DWORD size;
+ PACL acl = NULL;
+
+ size = sizeof(users);
+ CreateWellKnownSid(
+ WinAuthenticatedUserSid, NULL, &users, &size);
+
+ sdesc = sdescAuthUsers(&users, &acl);
+ assert(sdesc != NULL);
+ assert(acl != NULL);
+ Reset({
+ free(sdesc);
+ LocalFree(acl);
+ });
+
+ So(nng_listener_setopt_ptr(l,
+ NNG_OPT_IPC_SECURITY_DESCRIPTOR, sdesc) == 0);
+ So(nng_listener_start(l, 0) == 0);
+
+ Convey("And they are effective", {
+ PACL dacl;
+ PSECURITY_DESCRIPTOR sd;
+ PACE_HEADER ace;
+ PSID asid;
+ PACCESS_ALLOWED_ACE allowed;
+
+ HANDLE ph = CreateFileA("\\\\.\\\\pipe\\" ADDR,
+ READ_CONTROL, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED, NULL);
+
+ So(ph != INVALID_HANDLE_VALUE);
+ Reset({ CloseHandle(ph); });
+
+ So(GetSecurityInfo(ph, SE_KERNEL_OBJECT,
+ DACL_SECURITY_INFORMATION, NULL, NULL,
+ &dacl, NULL, &sd) == ERROR_SUCCESS);
+ Reset({ LocalFree(sd); });
+
+ So(dacl->AceCount == 1);
+ So(GetAce(dacl, 0, &ace) == TRUE);
+ allowed = (PACCESS_ALLOWED_ACE) ace;
+ asid = (PSID) &allowed->SidStart;
+ So(IsValidSid(asid));
+ So(EqualSid(asid, &users) == TRUE);
+ });
+ });
+
+ Convey("We cannot set security descriptor after started", {
+
+ SECURITY_DESCRIPTOR *sdesc;
+ SID users;
+ DWORD size;
+ PACL acl = NULL;
+
+ size = sizeof(users);
+ CreateWellKnownSid(
+ WinAuthenticatedUserSid, NULL, &users, &size);
+
+ sdesc = sdescAuthUsers(&users, &acl);
+ assert(sdesc != NULL);
+ assert(acl != NULL);
+ Reset({
+ free(sdesc);
+ LocalFree(acl);
+ });
+
+ So(nng_listener_start(l, 0) == 0);
+ So(nng_listener_setopt_ptr(l,
+ NNG_OPT_IPC_SECURITY_DESCRIPTOR,
+ sdesc) == NNG_EBUSY);
+ });
+
+ Convey("We cannot set bogus security", {
+ So(nng_listener_setopt_ptr(l,
+ NNG_OPT_IPC_SECURITY_DESCRIPTOR,
+ NULL) == NNG_EINVAL);
+ });
+ });
+
+ Convey("We cannot set security descriptor on an IPC dialer", {
+ nng_socket s;
+ nng_dialer d;
+ SECURITY_DESCRIPTOR *sdesc;
+
+ sdesc = calloc(SECURITY_DESCRIPTOR_MIN_LENGTH, 1);
+ assert(sdesc != NULL);
+ InitializeSecurityDescriptor(
+ sdesc, SECURITY_DESCRIPTOR_REVISION);
+
+ So(nng_rep0_open(&s) == 0);
+ Reset({
+ nng_close(s);
+ free(sdesc);
+ });
+
+ So(nng_dialer_create(&d, s, "ipc://" ADDR) == 0);
+ So(nng_dialer_setopt_ptr(d, NNG_OPT_IPC_SECURITY_DESCRIPTOR,
+ sdesc) == NNG_ENOTSUP);
+ });
+})
+#endif \ No newline at end of file