From ef90c11e8dcc9b37c04157a22be952dfb90cff1e Mon Sep 17 00:00:00 2001 From: martinbremmer <37294015+martinbremmer@users.noreply.github.com> Date: Tue, 1 Oct 2019 12:43:33 +0200 Subject: [PATCH] Added DDS Security msg parameters. (#263) * Added DDS Security msg parameters. Signed-off-by: Martin Bremmer * Added ENABLE_SECURITY cmake option and DDSI_INCLUDE_SECURITY compile switch. Signed-off-by: Martin Bremmer --- .travis.yml | 27 ++--- src/core/CMakeLists.txt | 17 ++- src/core/ddsi/include/dds/ddsi/q_plist.h | 71 +++++++++++++ src/core/ddsi/include/dds/ddsi/q_protocol.h | 4 + src/core/ddsi/src/q_config.c | 2 +- src/core/ddsi/src/q_plist.c | 63 ++++++++--- src/core/ddsi/tests/plist.c | 112 +++++++++++++++++++- 7 files changed, 261 insertions(+), 35 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d59e91..2335a4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -133,30 +133,32 @@ windows_vs2017: &windows_vs2017 jobs: include: - <<: *linux_gcc8 - env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, GENERATOR="Unix Makefiles", COVERITY_SCAN=true ] + env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles", COVERITY_SCAN=true ] if: type = cron - <<: *linux_gcc8 - env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, GENERATOR="Unix Makefiles" ] + env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ] - <<: *linux_gcc8 - env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, GENERATOR="Unix Makefiles" ] + env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ] - <<: *linux_gcc8 - env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=NO, GENERATOR="Unix Makefiles" ] + env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=NO, SECURITY=YES, GENERATOR="Unix Makefiles" ] - <<: *linux_gcc8 - env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, GENERATOR="Unix Makefiles" ] + env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ] - <<: *linux_clang - env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, GENERATOR="Unix Makefiles" ] + env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ] - <<: *linux_clang - env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, GENERATOR="Unix Makefiles" ] + env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=NO, GENERATOR="Unix Makefiles" ] + - <<: *linux_clang + env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ] - <<: *osx_xcode10_3 - env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, GENERATOR="Unix Makefiles" ] + env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ] - <<: *osx_xcode10_3 - env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, GENERATOR="Unix Makefiles" ] + env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ] - <<: *windows_vs2017 - env: [ ARCH=x86, ASAN=none, BUILD_TYPE=Debug, SSL=YES, GENERATOR="Visual Studio 15 2017" ] + env: [ ARCH=x86, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Visual Studio 15 2017" ] - <<: *windows_vs2017 - env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, GENERATOR="Visual Studio 15 2017 Win64" ] + env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Visual Studio 15 2017 Win64" ] - <<: *windows_vs2017 - env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, GENERATOR="Visual Studio 15 2017 Win64" ] + env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Visual Studio 15 2017 Win64" ] before_script: - conan profile new default --detect @@ -186,6 +188,7 @@ script: -DCMAKE_INSTALL_PREFIX=$(pwd)/install -DUSE_SANITIZER=${ASAN} -DENABLE_SSL=${SSL} + -DENABLE_SECURITY=${SECURITY} -DBUILD_TESTING=on -DWERROR=on -G "${GENERATOR}" .. diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 255ee90..1ae731b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -53,17 +53,28 @@ if(ENABLE_SSL) endif() endif() +# Support the OMG DDS Security within ddsc adds quite a bit of code. +option(ENABLE_SECURITY "Enable OMG DDS Security support" ON) +if(NOT ENABLE_SECURITY) + message(STATUS "Building without OMG DDS Security support") +else() + add_definitions(-DDDSI_INCLUDE_SECURITY) + target_link_libraries(ddsc PRIVATE security_api) + target_include_directories( + ddsc PUBLIC + $>) +endif() + include(ddsi/CMakeLists.txt) include(ddsc/CMakeLists.txt) -target_link_libraries(ddsc PRIVATE ddsrt security_api) +target_link_libraries(ddsc PRIVATE ddsrt) target_compile_definitions( ddsc PUBLIC $>) target_include_directories( ddsc PUBLIC - $> - $>) + $>) # SOVERSION should increase on incompatible ABI change set_target_properties(ddsc PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) diff --git a/src/core/ddsi/include/dds/ddsi/q_plist.h b/src/core/ddsi/include/dds/ddsi/q_plist.h index 4a9d6f3..8a77283 100644 --- a/src/core/ddsi/include/dds/ddsi/q_plist.h +++ b/src/core/ddsi/include/dds/ddsi/q_plist.h @@ -59,6 +59,10 @@ extern "C" { /* Security extensions. */ #define PP_IDENTITY_TOKEN ((uint64_t)1 << 41) #define PP_PERMISSIONS_TOKEN ((uint64_t)1 << 42) +#define PP_ENDPOINT_SECURITY_INFO ((uint64_t)1 << 43) +#define PP_PARTICIPANT_SECURITY_INFO ((uint64_t)1 << 44) +#define PP_IDENTITY_STATUS_TOKEN ((uint64_t)1 << 45) +#define PP_DATA_TAGS ((uint64_t)1 << 46) /* Set for unrecognized parameters that are in the reserved space or in our own vendor-specific space that have the PID_UNRECOGNIZED_INCOMPATIBLE_FLAG set (see DDSI 2.1 9.6.2.2.1) */ @@ -100,6 +104,21 @@ typedef struct nn_keyhash { unsigned char value[16]; } nn_keyhash_t; +#ifdef DDSI_INCLUDE_SECURITY +typedef struct nn_tag { + char *name; + char *value; +} nn_tag_t; + +typedef struct nn_tagseq { + uint32_t n; + nn_tag_t *tags; +} nn_tagseq_t; + +typedef struct nn_datatags { + nn_tagseq_t tags; +} nn_datatags_t; +#endif #ifdef DDSI_INCLUDE_SSM typedef struct nn_reader_favours_ssm { @@ -107,6 +126,50 @@ typedef struct nn_reader_favours_ssm { } nn_reader_favours_ssm_t; #endif +#ifdef DDSI_INCLUDE_SECURITY +typedef struct nn_dataholder +{ + char *class_id; + dds_propertyseq_t properties; + dds_binarypropertyseq_t binary_properties; +} nn_dataholder_t; + +typedef nn_dataholder_t nn_token_t; + +/* Used for both nn_participant_security_info and nn_endpoint_security_info. */ +typedef struct nn_security_info +{ + uint32_t security_attributes; + uint32_t plugin_security_attributes; +} nn_security_info_t; + +#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_READ_PROTECTED (1u << 0) +#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_WRITE_PROTECTED (1u << 1) +#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_PROTECTED (1u << 2) +#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED (1u << 3) +#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_PROTECTED (1u << 4) +#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_KEY_PROTECTED (1u << 5) +#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_PROTECTED (1u << 6) +#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID (1u << 31) + +#define NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED (1u << 0) +#define NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED (1u << 1) +#define NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED (1u << 2) + +#define NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_RTPS_PROTECTED (1u << 0) +#define NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_PROTECTED (1u << 1) +#define NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_PROTECTED (1u << 2) +#define NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_VALID (1u << 31) + +#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED (1u << 0) +#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_ENCRYPTED (1u << 1) +#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ENCRYPTED (1u << 2) +#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_RTPS_AUTHENTICATED (1u << 3) +#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_AUTHENTICATED (1u << 4) +#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_AUTHENTICATED (1u << 5) +#endif + + typedef struct nn_prismtech_participant_version_info { uint32_t version; @@ -159,6 +222,14 @@ typedef struct nn_plist { uint32_t process_id; char *type_description; nn_sequence_number_t coherent_set_seqno; +#ifdef DDSI_INCLUDE_SECURITY + nn_token_t identity_token; + nn_token_t permissions_token; + nn_security_info_t endpoint_security_info; + nn_security_info_t participant_security_info; + nn_token_t identity_status_token; + nn_datatags_t data_tags; +#endif #ifdef DDSI_INCLUDE_SSM nn_reader_favours_ssm_t reader_favours_ssm; #endif diff --git a/src/core/ddsi/include/dds/ddsi/q_protocol.h b/src/core/ddsi/include/dds/ddsi/q_protocol.h index 93bda9a..9ebf7c5 100644 --- a/src/core/ddsi/include/dds/ddsi/q_protocol.h +++ b/src/core/ddsi/include/dds/ddsi/q_protocol.h @@ -390,6 +390,10 @@ DDSRT_WARNING_MSVC_ON(4200) /* Security related PID values. */ #define PID_IDENTITY_TOKEN 0x1001u #define PID_PERMISSIONS_TOKEN 0x1002u +#define PID_DATA_TAGS 0x1003u +#define PID_ENDPOINT_SECURITY_INFO 0x1004u +#define PID_PARTICIPANT_SECURITY_INFO 0x1005u +#define PID_IDENTITY_STATUS_TOKEN 0x1006u #ifdef DDSI_INCLUDE_SSM /* To indicate whether a reader favours the use of SSM. Iff the diff --git a/src/core/ddsi/src/q_config.c b/src/core/ddsi/src/q_config.c index 8a0982b..fd1a911 100644 --- a/src/core/ddsi/src/q_config.c +++ b/src/core/ddsi/src/q_config.c @@ -52,7 +52,7 @@ typedef enum update_result (*update_fun_t) (struct cfgst *cfgst, void *parent, s typedef void (*free_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem); typedef void (*print_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources); -#ifdef DDSI_INCLUDE_SECURITY +#ifdef DDSI_INCLUDE_ENCRYPTION struct q_security_plugins q_security_plugin = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #endif diff --git a/src/core/ddsi/src/q_plist.c b/src/core/ddsi/src/q_plist.c index 50a9721..74114f5 100644 --- a/src/core/ddsi/src/q_plist.c +++ b/src/core/ddsi/src/q_plist.c @@ -1172,6 +1172,14 @@ static const struct piddesc piddesc_omg[] = { PPV (ENDPOINT_GUID, endpoint_guid, XG), #ifdef DDSI_INCLUDE_SSM PPV (READER_FAVOURS_SSM, reader_favours_ssm, Xu), +#endif +#ifdef DDSI_INCLUDE_SECURITY + PP (ENDPOINT_SECURITY_INFO, endpoint_security_info, Xu, Xu), + PP (PARTICIPANT_SECURITY_INFO, participant_security_info, Xu, Xu), + PP (IDENTITY_TOKEN, identity_token, XS, XQ, XbPROP, XS, XS, XSTOP, XQ, XbPROP, XS, XO, XSTOP), + PP (PERMISSIONS_TOKEN, permissions_token, XS, XQ, XbPROP, XS, XS, XSTOP, XQ, XbPROP, XS, XO, XSTOP), + PP (IDENTITY_STATUS_TOKEN, identity_status_token, XS, XQ, XbPROP, XS, XS, XSTOP, XQ, XbPROP, XS, XO, XSTOP), + PP (DATA_TAGS, data_tags, XQ, XS, XS, XSTOP), #endif { PID_STATUSINFO, PDF_FUNCTION, PP_STATUSINFO, "STATUSINFO", offsetof (struct nn_plist, statusinfo), membersize (struct nn_plist, statusinfo), @@ -1288,11 +1296,21 @@ struct piddesc_index { nn_plist_init_tables. FIXME: should compute them at build-time */ +#define DEFAULT_PROC_ARRAY_SIZE 19 #ifdef DDSI_INCLUDE_SSM -static const struct piddesc *piddesc_omg_index[115]; -#else /* status info is the highest */ -static const struct piddesc *piddesc_omg_index[114]; +#define DEFAULT_OMG_PIDS_ARRAY_SIZE (PID_READER_FAVOURS_SSM + 1) +#else +#define DEFAULT_OMG_PIDS_ARRAY_SIZE (PID_STATUSINFO + 1) #endif +#ifdef DDSI_INCLUDE_SECURITY +#define SECURITY_OMG_PIDS_ARRAY_SIZE (PID_IDENTITY_STATUS_TOKEN - PID_IDENTITY_TOKEN + 1) +#define SECURITY_PROC_ARRAY_SIZE 4 +#else +#define SECURITY_OMG_PIDS_ARRAY_SIZE 0 +#define SECURITY_PROC_ARRAY_SIZE 0 +#endif + +static const struct piddesc *piddesc_omg_index[DEFAULT_OMG_PIDS_ARRAY_SIZE + SECURITY_OMG_PIDS_ARRAY_SIZE]; static const struct piddesc *piddesc_eclipse_index[19]; static const struct piddesc *piddesc_prismtech_index[19]; @@ -1318,13 +1336,22 @@ static const struct piddesc_index piddesc_vendor_index[] = { /* List of entries that require unalias, fini processing; initialized by nn_plist_init_tables; will assert when table too small or too large */ -static const struct piddesc *piddesc_unalias[19]; -static const struct piddesc *piddesc_fini[19]; +static const struct piddesc *piddesc_unalias[DEFAULT_PROC_ARRAY_SIZE + SECURITY_PROC_ARRAY_SIZE]; +static const struct piddesc *piddesc_fini[DEFAULT_PROC_ARRAY_SIZE + SECURITY_PROC_ARRAY_SIZE]; static ddsrt_once_t table_init_control = DDSRT_ONCE_INIT; -static nn_parameterid_t pid_without_flags (nn_parameterid_t pid) +static size_t pid_to_index (nn_parameterid_t pid) { - return (nn_parameterid_t) (pid & ~(PID_VENDORSPECIFIC_FLAG | PID_UNRECOGNIZED_INCOMPATIBLE_FLAG)); + /* pid without flags. */ + size_t idx = (size_t)(pid & ~(PID_VENDORSPECIFIC_FLAG | PID_UNRECOGNIZED_INCOMPATIBLE_FLAG)); +#ifdef DDSI_INCLUDE_SECURITY + if ((idx >= PID_IDENTITY_TOKEN) && (idx <= PID_IDENTITY_STATUS_TOKEN)) + { + /* Security PIDs start after the 'normal' PIDs. */ + idx = (idx - PID_IDENTITY_TOKEN) + DEFAULT_OMG_PIDS_ARRAY_SIZE; + } +#endif + return idx; } static int piddesc_cmp_qos_addr (const void *va, const void *vb) @@ -1348,12 +1375,13 @@ static void nn_plist_init_tables_real (void) continue; struct piddesc const **index = piddesc_vendor_index[i].index; #ifndef NDEBUG - nn_parameterid_t maxpid = 0; + size_t maxpididx = 0; bool only_qos_seen = true; #endif for (size_t j = 0; table[j].pid != PID_SENTINEL; j++) { - nn_parameterid_t pid = pid_without_flags (table[j].pid); + nn_parameterid_t pid = table[j].pid; + size_t pididx = pid_to_index(pid); #ifndef NDEBUG /* Table must first list QoS, then other parameters */ assert (only_qos_seen || !(table[j].flags & PDF_QOS)); @@ -1361,19 +1389,19 @@ static void nn_plist_init_tables_real (void) only_qos_seen = false; /* Track max PID so we can verify the table is no larger than necessary */ - if (pid > maxpid) - maxpid = pid; + if (pididx > maxpididx) + maxpididx = pididx; #endif /* PAD is used for entries that are never visible on the wire and the decoder assumes the PAD entries will be skipped because they don't map to an entry */ if (pid == PID_PAD) continue; - assert (pid <= piddesc_vendor_index[i].index_max); - assert (index[pid] == NULL || index[pid] == &table[j]); - index[pid] = &table[j]; + assert (pididx <= piddesc_vendor_index[i].index_max); + assert (index[pididx] == NULL || index[pididx] == &table[j]); + index[pididx] = &table[j]; } - assert (maxpid == piddesc_vendor_index[i].index_max); + assert (maxpididx == piddesc_vendor_index[i].index_max); } /* PIDs requiring unalias; there is overlap between the tables @@ -2094,9 +2122,10 @@ static dds_return_t init_one_parameter (nn_plist_t *plist, nn_ipaddress_params_t index = &piddesc_vendor_index[dd->vendorid.id[1]]; const struct piddesc *entry; - if (pid_without_flags (pid) > index->index_max || (entry = index->index[pid_without_flags (pid)]) == NULL) + size_t pididx = pid_to_index(pid); + if (pididx > index->index_max || (entry = index->index[pididx]) == NULL) return return_unrecognized_pid (plist, pid); - assert (pid_without_flags (pid) == pid_without_flags (entry->pid)); + assert (pid_to_index (pid) == pid_to_index (entry->pid)); if (pid != entry->pid) { DDS_CERROR (logcfg, "error processing parameter list (vendor %u.%u, version %u.%u): pid %"PRIx16" mapped to pid %"PRIx16"\n", diff --git a/src/core/ddsi/tests/plist.c b/src/core/ddsi/tests/plist.c index 603d07a..a9b96a0 100644 --- a/src/core/ddsi/tests/plist.c +++ b/src/core/ddsi/tests/plist.c @@ -19,9 +19,9 @@ CU_Test (ddsi_plist, unalias_copy_merge) { - /* one int, one string and one string sequence covers most cases */ + /* one int, one string, one string sequence and one struct sequence covers most cases */ nn_plist_t p0, p0memcpy; - char *p0strs[3]; + char *p0strs[7]; nn_plist_init_empty (&p0); p0.present = PP_PRISMTECH_PROCESS_ID | PP_ENTITY_NAME; p0.aliased = PP_ENTITY_NAME; @@ -34,18 +34,43 @@ CU_Test (ddsi_plist, unalias_copy_merge) p0strs[0] = p0.qos.partition.strs[0] = "aap"; p0strs[1] = p0.qos.partition.strs[1] = "noot"; p0strs[2] = p0.qos.partition.strs[2] = "mies"; +#ifdef DDSI_INCLUDE_SECURITY + p0.present |= PP_IDENTITY_TOKEN; + p0.aliased |= PP_IDENTITY_TOKEN; + p0.identity_token.class_id = "class_id"; + p0.identity_token.properties.n = 2; + p0.identity_token.properties.props = ddsrt_malloc (p0.identity_token.properties.n * sizeof (*p0.identity_token.properties.props)); + p0.identity_token.properties.props[0].propagate = false; + p0strs[3] = p0.identity_token.properties.props[0].name = "name0"; + p0strs[4] = p0.identity_token.properties.props[0].value = "value0"; + p0.identity_token.properties.props[1].propagate = true; + p0strs[5] = p0.identity_token.properties.props[1].name = "name1"; + p0strs[6] = p0.identity_token.properties.props[1].value = "value1"; + p0.identity_token.binary_properties.n = 0; + p0.identity_token.binary_properties.props = NULL; +#endif memcpy (&p0memcpy, &p0, sizeof (p0)); /* manually alias one, so we can free it*/ nn_plist_t p0alias; memcpy (&p0alias, &p0, sizeof (p0)); p0alias.qos.partition.strs = ddsrt_memdup (p0alias.qos.partition.strs, p0.qos.partition.n * sizeof (*p0.qos.partition.strs)); +#ifdef DDSI_INCLUDE_SECURITY + p0alias.identity_token.properties.props = ddsrt_memdup (p0alias.identity_token.properties.props, + p0.identity_token.properties.n * sizeof (*p0.identity_token.properties.props)); +#endif nn_plist_fini (&p0alias); CU_ASSERT (memcmp (&p0, &p0memcpy, sizeof (p0)) == 0); CU_ASSERT_STRING_EQUAL (p0.entity_name, "nemo"); CU_ASSERT_STRING_EQUAL (p0.qos.partition.strs[0], p0strs[0]); CU_ASSERT_STRING_EQUAL (p0.qos.partition.strs[1], p0strs[1]); CU_ASSERT_STRING_EQUAL (p0.qos.partition.strs[2], p0strs[2]); +#ifdef DDSI_INCLUDE_SECURITY + CU_ASSERT_STRING_EQUAL (p0.identity_token.properties.props[0].name, p0strs[3]); + CU_ASSERT_STRING_EQUAL (p0.identity_token.properties.props[0].value, p0strs[4]); + CU_ASSERT_STRING_EQUAL (p0.identity_token.properties.props[1].name, p0strs[5]); + CU_ASSERT_STRING_EQUAL (p0.identity_token.properties.props[1].value, p0strs[6]); +#endif /* copy an aliased one; the original must be unchanged, the copy unaliased */ nn_plist_t p1; @@ -67,6 +92,24 @@ CU_Test (ddsi_plist, unalias_copy_merge) CU_ASSERT_STRING_EQUAL (p1.qos.partition.strs[0], p0.qos.partition.strs[0]); CU_ASSERT_STRING_EQUAL (p1.qos.partition.strs[1], p0.qos.partition.strs[1]); CU_ASSERT_STRING_EQUAL (p1.qos.partition.strs[2], p0.qos.partition.strs[2]); +#ifdef DDSI_INCLUDE_SECURITY + CU_ASSERT (p1.identity_token.class_id != p0.identity_token.class_id); + CU_ASSERT_STRING_EQUAL (p1.identity_token.class_id, p0.identity_token.class_id); + CU_ASSERT (p1.identity_token.properties.n == p0.identity_token.properties.n); + CU_ASSERT (p1.identity_token.properties.props != p0.identity_token.properties.props); + CU_ASSERT (p1.identity_token.properties.props[0].name != p0.identity_token.properties.props[0].name); + CU_ASSERT (p1.identity_token.properties.props[0].value != p0.identity_token.properties.props[0].value); + CU_ASSERT (p1.identity_token.properties.props[0].propagate == p0.identity_token.properties.props[0].propagate); + CU_ASSERT (p1.identity_token.properties.props[1].name != p0.identity_token.properties.props[1].name); + CU_ASSERT (p1.identity_token.properties.props[1].value != p0.identity_token.properties.props[1].value); + CU_ASSERT (p1.identity_token.properties.props[1].propagate == p0.identity_token.properties.props[1].propagate); + CU_ASSERT_STRING_EQUAL (p1.identity_token.properties.props[0].name, p0.identity_token.properties.props[0].name); + CU_ASSERT_STRING_EQUAL (p1.identity_token.properties.props[0].value, p0.identity_token.properties.props[0].value); + CU_ASSERT_STRING_EQUAL (p1.identity_token.properties.props[1].name, p0.identity_token.properties.props[1].name); + CU_ASSERT_STRING_EQUAL (p1.identity_token.properties.props[1].value, p0.identity_token.properties.props[1].value); + CU_ASSERT (p1.identity_token.binary_properties.n == 0); + CU_ASSERT (p1.identity_token.binary_properties.props == NULL); +#endif /* merge-in missing ones from an aliased copy: original must remain unchanged; existing ones should stay without touching "aliased" only new ones are @@ -94,6 +137,24 @@ CU_Test (ddsi_plist, unalias_copy_merge) CU_ASSERT_STRING_EQUAL (p2.qos.partition.strs[0], p0.qos.partition.strs[0]); CU_ASSERT_STRING_EQUAL (p2.qos.partition.strs[1], p0.qos.partition.strs[1]); CU_ASSERT_STRING_EQUAL (p2.qos.partition.strs[2], p0.qos.partition.strs[2]); +#ifdef DDSI_INCLUDE_SECURITY + CU_ASSERT (p2.identity_token.class_id != p0.identity_token.class_id); + CU_ASSERT_STRING_EQUAL (p2.identity_token.class_id, p0.identity_token.class_id); + CU_ASSERT (p2.identity_token.properties.n == p0.identity_token.properties.n); + CU_ASSERT (p2.identity_token.properties.props != p0.identity_token.properties.props); + CU_ASSERT (p2.identity_token.properties.props[0].name != p0.identity_token.properties.props[0].name); + CU_ASSERT (p2.identity_token.properties.props[0].value != p0.identity_token.properties.props[0].value); + CU_ASSERT (p2.identity_token.properties.props[0].propagate == p0.identity_token.properties.props[0].propagate); + CU_ASSERT (p2.identity_token.properties.props[1].name != p0.identity_token.properties.props[1].name); + CU_ASSERT (p2.identity_token.properties.props[1].value != p0.identity_token.properties.props[1].value); + CU_ASSERT (p2.identity_token.properties.props[1].propagate == p0.identity_token.properties.props[1].propagate); + CU_ASSERT_STRING_EQUAL (p2.identity_token.properties.props[0].name, p0.identity_token.properties.props[0].name); + CU_ASSERT_STRING_EQUAL (p2.identity_token.properties.props[0].value, p0.identity_token.properties.props[0].value); + CU_ASSERT_STRING_EQUAL (p2.identity_token.properties.props[1].name, p0.identity_token.properties.props[1].name); + CU_ASSERT_STRING_EQUAL (p2.identity_token.properties.props[1].value, p0.identity_token.properties.props[1].value); + CU_ASSERT (p2.identity_token.binary_properties.n == 0); + CU_ASSERT (p2.identity_token.binary_properties.props == NULL); +#endif /* unalias of p0, partition.strs mustn't change, because it, unlike its elements, wasn't aliased */ nn_plist_unalias (&p0); @@ -112,6 +173,17 @@ CU_Test (ddsi_plist, unalias_copy_merge) CU_ASSERT_STRING_EQUAL (p0.qos.partition.strs[0], p0strs[0]); CU_ASSERT_STRING_EQUAL (p0.qos.partition.strs[1], p0strs[1]); CU_ASSERT_STRING_EQUAL (p0.qos.partition.strs[2], p0strs[2]); +#ifdef DDSI_INCLUDE_SECURITY + CU_ASSERT (p0.identity_token.properties.props[0].name != p0strs[3]); + CU_ASSERT (p0.identity_token.properties.props[0].value != p0strs[4]); + CU_ASSERT (p0.identity_token.properties.props[1].name != p0strs[5]); + CU_ASSERT (p0.identity_token.properties.props[1].value != p0strs[6]); + CU_ASSERT_STRING_EQUAL (p0.identity_token.properties.props[0].name, p0strs[3]); + CU_ASSERT_STRING_EQUAL (p0.identity_token.properties.props[0].value, p0strs[4]); + CU_ASSERT_STRING_EQUAL (p0.identity_token.properties.props[1].name, p0strs[5]); + CU_ASSERT_STRING_EQUAL (p0.identity_token.properties.props[1].value, p0strs[6]); +#endif + memcpy (&p0memcpy, &p0, sizeof (p0)); /* copy an aliased one; the original must be unchanged, the copy unaliased */ @@ -134,6 +206,24 @@ CU_Test (ddsi_plist, unalias_copy_merge) CU_ASSERT_STRING_EQUAL (p3.qos.partition.strs[0], p0.qos.partition.strs[0]); CU_ASSERT_STRING_EQUAL (p3.qos.partition.strs[1], p0.qos.partition.strs[1]); CU_ASSERT_STRING_EQUAL (p3.qos.partition.strs[2], p0.qos.partition.strs[2]); +#ifdef DDSI_INCLUDE_SECURITY + CU_ASSERT (p3.identity_token.class_id != p0.identity_token.class_id); + CU_ASSERT_STRING_EQUAL (p3.identity_token.class_id, p0.identity_token.class_id); + CU_ASSERT (p3.identity_token.properties.n == p0.identity_token.properties.n); + CU_ASSERT (p3.identity_token.properties.props != p0.identity_token.properties.props); + CU_ASSERT (p3.identity_token.properties.props[0].name != p0.identity_token.properties.props[0].name); + CU_ASSERT (p3.identity_token.properties.props[0].value != p0.identity_token.properties.props[0].value); + CU_ASSERT (p3.identity_token.properties.props[0].propagate == p0.identity_token.properties.props[0].propagate); + CU_ASSERT (p3.identity_token.properties.props[1].name != p0.identity_token.properties.props[1].name); + CU_ASSERT (p3.identity_token.properties.props[1].value != p0.identity_token.properties.props[1].value); + CU_ASSERT (p3.identity_token.properties.props[1].propagate == p0.identity_token.properties.props[1].propagate); + CU_ASSERT_STRING_EQUAL (p3.identity_token.properties.props[0].name, p0.identity_token.properties.props[0].name); + CU_ASSERT_STRING_EQUAL (p3.identity_token.properties.props[0].value, p0.identity_token.properties.props[0].value); + CU_ASSERT_STRING_EQUAL (p3.identity_token.properties.props[1].name, p0.identity_token.properties.props[1].name); + CU_ASSERT_STRING_EQUAL (p3.identity_token.properties.props[1].value, p0.identity_token.properties.props[1].value); + CU_ASSERT (p3.identity_token.binary_properties.n == 0); + CU_ASSERT (p3.identity_token.binary_properties.props == NULL); +#endif /* merge-in missing ones from an aliased copy: original must remain unchanged; existing ones should stay without touching "aliased" only new ones are @@ -161,6 +251,24 @@ CU_Test (ddsi_plist, unalias_copy_merge) CU_ASSERT_STRING_EQUAL (p4.qos.partition.strs[0], p0.qos.partition.strs[0]); CU_ASSERT_STRING_EQUAL (p4.qos.partition.strs[1], p0.qos.partition.strs[1]); CU_ASSERT_STRING_EQUAL (p4.qos.partition.strs[2], p0.qos.partition.strs[2]); +#ifdef DDSI_INCLUDE_SECURITY + CU_ASSERT (p4.identity_token.class_id != p0.identity_token.class_id); + CU_ASSERT_STRING_EQUAL (p4.identity_token.class_id, p0.identity_token.class_id); + CU_ASSERT (p4.identity_token.properties.n == p0.identity_token.properties.n); + CU_ASSERT (p4.identity_token.properties.props != p0.identity_token.properties.props); + CU_ASSERT (p4.identity_token.properties.props[0].name != p0.identity_token.properties.props[0].name); + CU_ASSERT (p4.identity_token.properties.props[0].value != p0.identity_token.properties.props[0].value); + CU_ASSERT (p4.identity_token.properties.props[0].propagate == p0.identity_token.properties.props[0].propagate); + CU_ASSERT (p4.identity_token.properties.props[1].name != p0.identity_token.properties.props[1].name); + CU_ASSERT (p4.identity_token.properties.props[1].value != p0.identity_token.properties.props[1].value); + CU_ASSERT (p4.identity_token.properties.props[1].propagate == p0.identity_token.properties.props[1].propagate); + CU_ASSERT_STRING_EQUAL (p4.identity_token.properties.props[0].name, p0.identity_token.properties.props[0].name); + CU_ASSERT_STRING_EQUAL (p4.identity_token.properties.props[0].value, p0.identity_token.properties.props[0].value); + CU_ASSERT_STRING_EQUAL (p4.identity_token.properties.props[1].name, p0.identity_token.properties.props[1].name); + CU_ASSERT_STRING_EQUAL (p4.identity_token.properties.props[1].value, p0.identity_token.properties.props[1].value); + CU_ASSERT (p4.identity_token.binary_properties.n == 0); + CU_ASSERT (p4.identity_token.binary_properties.props == NULL); +#endif nn_plist_fini (&p0); nn_plist_fini (&p1);