doompanning/external/nng/tests/ipcwinsec.c
2023-02-03 21:18:59 +01:00

192 lines
4.9 KiB
C

//
// Copyright 2021 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 <nng/nng.h>
#include <nng/protocol/reqrep0/rep.h>
#include <nng/protocol/reqrep0/req.h>
#include <nng/transport/ipc/ipc.h>
#include "convey.h"
#include "stubs.h"
#include "trantest.h"
#define ADDR "/tmp/ipc_winsec_test"
// Inproc tests.
#ifndef _WIN32
TestMain("IPC Security Descriptor", {
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", {
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, (void **) &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