Skip to content

Commit

Permalink
fixes nanomsg#1346 windows ipc winsec fails frequently in CI/CD
Browse files Browse the repository at this point in the history
  • Loading branch information
gdamore authored and JaylinYu committed Nov 29, 2021
1 parent e6a2e68 commit d3fe0b8
Show file tree
Hide file tree
Showing 13 changed files with 334 additions and 299 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ColumnLimit: 79
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignTrailingComments: true
AlignEscapedNewlinesLeft: true
AlignEscapedNewlines: Left
PointerAlignment: Right
ForEachMacros: ['NNI_LIST_FOREACH']
AlwaysBreakAfterReturnType: TopLevelDefinitions
Expand Down
22 changes: 11 additions & 11 deletions src/core/id_test.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2020 Staysail Systems, Inc. <[email protected]>
// Copyright 2021 Staysail Systems, Inc. <[email protected]>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
Expand All @@ -15,8 +15,8 @@ void
test_basic(void)
{
nni_id_map m;
char * five = "five";
char * four = "four";
char *five = "five";
char *four = "four";

nni_id_map_init(&m, 0, 0, false);

Expand Down Expand Up @@ -60,8 +60,8 @@ void
test_collision(void)
{
nni_id_map m;
char * five = "five";
char * four = "four";
char *five = "five";
char *four = "four";

nni_id_map_init(&m, 0, 0, false);

Expand Down Expand Up @@ -141,7 +141,7 @@ test_dynamic(void)

nni_id_map_init(&m, 10, 13, false);

// We can fill the table.
// We can fill the table.
NUTS_PASS(nni_id_alloc(&m, &id, &expect[0]));
NUTS_TRUE(id == 10);
NUTS_PASS(nni_id_alloc(&m, &id, &expect[1]));
Expand Down Expand Up @@ -186,11 +186,11 @@ test_set_out_of_range(void)
void
test_stress(void)
{
void * values[NUM_VALUES];
void *values[NUM_VALUES];
nni_id_map m;
size_t i;
int rv;
void * x;
void *x;
int v;

nni_id_map_init(&m, 0, 0, false);
Expand Down Expand Up @@ -240,15 +240,15 @@ test_stress(void)

// Post stress check.
for (i = 0; i < NUM_VALUES; i++) {
x = nni_id_get(&m, i);
x = nni_id_get(&m, (uint32_t) i);
if (x != values[i]) {
NUTS_TRUE(x == values[i]);
break;
}

// We only use the test macros if we know they are going
// to fail. Otherwise there will be too many errors reported.
rv = nni_id_remove(&m, i);
// to fail. Otherwise, there will be too many errors reported.
rv = nni_id_remove(&m, (uint32_t) i);
if ((x == NULL) && (rv != NNG_ENOENT)) {
NUTS_FAIL(rv, NNG_ENOENT);
} else if ((x != NULL) && (rv != 0)) {
Expand Down
3 changes: 3 additions & 0 deletions src/platform/posix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,7 @@ if (NNG_PLATFORM_POSIX)
else ()
nng_sources(posix_rand_urandom.c)
endif ()

nng_test(posix_ipcwinsec_test)

endif ()
31 changes: 31 additions & 0 deletions src/platform/posix/posix_ipcwinsec_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Copyright 2021 Staysail Systems, Inc. <[email protected]>
// Copyright 2018 Capitar IT Group BV <[email protected]>
//
// 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 <nuts.h>

void
test_ipc_win_sec(void)
{
char address[64];
nng_stream_listener *l;
int x;

nuts_scratch_addr("ipc", sizeof(address), address);
NUTS_PASS(nng_stream_listener_alloc(&l, address));
NUTS_FAIL(nng_stream_listener_set_ptr(
l, NNG_OPT_IPC_SECURITY_DESCRIPTOR, &x),
NNG_ENOTSUP);
nng_stream_listener_free(l);
}

NUTS_TESTS = {
{ "ipc security descriptor", test_ipc_win_sec },
{ NULL, NULL },
};
5 changes: 4 additions & 1 deletion src/platform/windows/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2020 Staysail Systems, Inc. <[email protected]>
# Copyright 2021 Staysail Systems, Inc. <[email protected]>
#
# This software is supplied under the terms of the MIT License, a
# copy of which should be located in the distribution where this
Expand Down Expand Up @@ -46,4 +46,7 @@ if (NNG_PLATFORM_WINDOWS)
win_thread.c
win_udp.c
)

nng_test(win_ipc_sec_test)

endif ()
190 changes: 190 additions & 0 deletions src/platform/windows/win_ipc_sec_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
//
// Copyright 2021 Staysail Systems, Inc. <[email protected]>
// Copyright 2018 Capitar IT Group BV <[email protected]>
//
// 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 <nuts.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 <aclapi.h>

SECURITY_DESCRIPTOR *
sdescAuthUsers(PSID sid, PACL *aclp)
{
SECURITY_DESCRIPTOR *sdesc;
EXPLICIT_ACCESS xa;
ACL *acl;

sdesc = calloc(SECURITY_DESCRIPTOR_MIN_LENGTH, 1);
NUTS_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);
}

void
test_ipc_security_descriptor(void)
{
nng_stream_listener *l;
char address[64];
char pipe[64];
SECURITY_DESCRIPTOR *sd;
SID users;
DWORD size;
PACL acl = NULL;
PACL dacl;
PSECURITY_DESCRIPTOR psd;
PACE_HEADER ace;
PSID psid;
PACCESS_ALLOWED_ACE allowed;
nng_aio *aio;

nuts_scratch_addr("ipc", sizeof(address), address);

NUTS_PASS(nng_stream_listener_alloc(&l, address));
size = sizeof(users);
CreateWellKnownSid(WinAuthenticatedUserSid, NULL, &users, &size);
sd = sdescAuthUsers(&users, &acl);

NUTS_ASSERT(sd != NULL);
NUTS_ASSERT(acl != NULL);
NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));

NUTS_PASS(nng_stream_listener_set_ptr(
l, NNG_OPT_IPC_SECURITY_DESCRIPTOR, sd));
NUTS_PASS(nng_stream_listener_listen(l));
nng_stream_listener_accept(l, aio);

(void) snprintf(pipe, sizeof(pipe), "\\\\.\\pipe\\%s", address+strlen("ipc://"));
HANDLE ph = CreateFileA(pipe, READ_CONTROL, 0, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);

nng_aio_wait(aio);
NUTS_PASS(nng_aio_result(aio));
HANDLE pd = (HANDLE) nng_aio_get_output(aio, 0);

NUTS_ASSERT(ph != INVALID_HANDLE_VALUE);
NUTS_ASSERT(pd != INVALID_HANDLE_VALUE);

NUTS_ASSERT(
GetSecurityInfo(ph, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
NULL, NULL, &dacl, NULL, &psd) == ERROR_SUCCESS);

NUTS_ASSERT(dacl->AceCount == 1);
NUTS_ASSERT(GetAce(dacl, 0, (void **) &ace) == TRUE);
allowed = (PACCESS_ALLOWED_ACE) ace;
psid = (PSID) &allowed->SidStart;
NUTS_ASSERT(IsValidSid(psid));
NUTS_ASSERT(EqualSid(psid, &users) == TRUE);

CloseHandle(pd);
CloseHandle(ph);
free(sd);
LocalFree(acl);
LocalFree(psd);
nng_stream_listener_close(l);
nng_stream_listener_free(l);
}

void
test_ipc_security_descriptor_busy(void)
{
// This test ensures that the descriptor can only be set before
// the listener is started.
nng_stream_listener *l;
char address[64];
SECURITY_DESCRIPTOR *sd;
SID users;
DWORD size;
PACL acl = NULL;

nuts_scratch_addr("ipc", sizeof(address), address);

NUTS_PASS(nng_stream_listener_alloc(&l, address));
size = sizeof(users);
CreateWellKnownSid(WinAuthenticatedUserSid, NULL, &users, &size);
sd = sdescAuthUsers(&users, &acl);

NUTS_ASSERT(sd != NULL);
NUTS_ASSERT(acl != NULL);

NUTS_PASS(nng_stream_listener_listen(l));

NUTS_FAIL(nng_stream_listener_set_ptr(
l, NNG_OPT_IPC_SECURITY_DESCRIPTOR, sd),
NNG_EBUSY);

free(sd);
nng_stream_listener_close(l);
nng_stream_listener_free(l);
}

void
test_ipc_security_descriptor_bogus(void)
{
nng_stream_listener *l;
char address[64];

nuts_scratch_addr("ipc", sizeof(address), address);

NUTS_PASS(nng_stream_listener_alloc(&l, address));

NUTS_FAIL(nng_stream_listener_set_ptr(
l, NNG_OPT_IPC_SECURITY_DESCRIPTOR, NULL),
NNG_EINVAL);

nng_stream_listener_close(l);
nng_stream_listener_free(l);
}

void
test_ipc_security_descriptor_dialer(void)
{
nng_stream_dialer *d;
char address[64];
SECURITY_DESCRIPTOR *sdesc;

nuts_scratch_addr("ipc", sizeof(address), address);
NUTS_PASS(nng_stream_dialer_alloc(&d, address));

sdesc = calloc(SECURITY_DESCRIPTOR_MIN_LENGTH, 1);
NUTS_ASSERT(sdesc != NULL);
InitializeSecurityDescriptor(sdesc, SECURITY_DESCRIPTOR_REVISION);
NUTS_FAIL(nng_stream_dialer_set_ptr(
d, NNG_OPT_IPC_SECURITY_DESCRIPTOR, sdesc),
NNG_ENOTSUP);
free(sdesc);
nng_stream_dialer_free(d);
}

NUTS_TESTS = {
{ "ipc security descriptor", test_ipc_security_descriptor },
{ "ipc security descriptor busy", test_ipc_security_descriptor_busy },
{ "ipc security descriptor bogus",
test_ipc_security_descriptor_bogus },
{ "ipc security descriptor dialer",
test_ipc_security_descriptor_dialer },
{ NULL, NULL },
};
3 changes: 2 additions & 1 deletion src/platform/windows/win_thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,8 @@ nni_plat_thr_set_name(nni_plat_thr *thr, const char *name)
if ((wcs = nni_alloc(len * 2)) == NULL) {
return;
}
(void) MultiByteToWideChar(CP_UTF8, 0, name, len, wcs, len);
(void) MultiByteToWideChar(
CP_UTF8, 0, name, (int) len, wcs, (int) len);
set_thread_desc(h, wcs);
nni_free(wcs, len * 2);
}
Expand Down
Loading

0 comments on commit d3fe0b8

Please sign in to comment.