diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | tests/ipcperms.c | 114 | ||||
| -rw-r--r-- | tests/ipcwinsec.c | 200 |
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 |
