From 736d0a027a8fc9baeb76ae2ebedfd6060a79511f Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Thu, 26 Mar 2020 13:42:11 +0100 Subject: [PATCH] Add access control tests for permissions expiry and move some reused test functions to common utils file. Signed-off-by: Dennis Potman --- src/security/core/tests/CMakeLists.txt | 2 +- src/security/core/tests/access_control.c | 308 +++++++++++++++--- src/security/core/tests/authentication.c | 151 ++------- .../tests/common/etc/default_permissions.p7s | 57 +++- .../tests/common/etc/default_permissions.xml | 33 ++ .../tests/common/security_config_test_utils.c | 48 ++- .../tests/common/security_config_test_utils.h | 4 +- .../{handshake_test_utils.c => test_utils.c} | 128 +++++++- .../{handshake_test_utils.h => test_utils.h} | 15 +- src/security/core/tests/handshake.c | 2 +- 10 files changed, 543 insertions(+), 205 deletions(-) rename src/security/core/tests/common/{handshake_test_utils.c => test_utils.c} (68%) rename src/security/core/tests/common/{handshake_test_utils.h => test_utils.h} (65%) diff --git a/src/security/core/tests/CMakeLists.txt b/src/security/core/tests/CMakeLists.txt index 639b84b..35337ab 100644 --- a/src/security/core/tests/CMakeLists.txt +++ b/src/security/core/tests/CMakeLists.txt @@ -74,7 +74,7 @@ if(ENABLE_SSL) list(APPEND security_core_test_sources "common/security_config_test_utils.c" - "common/handshake_test_utils.c" + "common/test_utils.c" "common/cert_utils.c" "authentication.c" "access_control.c" diff --git a/src/security/core/tests/access_control.c b/src/security/core/tests/access_control.c index 061dfef..508828c 100644 --- a/src/security/core/tests/access_control.c +++ b/src/security/core/tests/access_control.c @@ -21,6 +21,7 @@ #include "dds/ddsrt/environ.h" #include "dds/ddsrt/process.h" #include "dds/ddsrt/heap.h" +#include "dds/ddsrt/io.h" #include "dds/ddsrt/string.h" #include "dds/ddsi/q_config.h" #include "dds/ddsi/ddsi_domaingv.h" @@ -33,6 +34,9 @@ #include "common/access_control_wrapper.h" #include "common/security_config_test_utils.h" #include "common/test_identity.h" +#include "common/test_utils.h" +#include "common/cert_utils.h" +#include "SecurityCoreTests.h" static const char *config = "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}" @@ -43,16 +47,16 @@ static const char *config = " " " " " " - " " - " data:," TEST_IDENTITY1_CERTIFICATE "" - " data:," TEST_IDENTITY1_PRIVATE_KEY "" - " data:," TEST_IDENTITY_CA1_CERTIFICATE "" + " " + " data:,${TEST_IDENTITY_CERTIFICATE}" + " data:,${TEST_IDENTITY_PRIVATE_KEY}" + " data:,${TEST_IDENTITY_CA_CERTIFICATE}" " " " " " " - " ${INCL_GOV:+}${TEST_GOVERNANCE}${INCL_GOV:+}" + " ${INCL_GOV:+}" " ${INCL_PERM_CA:+}${TEST_PERMISSIONS_CA}${INCL_PERM_CA:+}" - " ${INCL_PERM:+}${TEST_PERMISSIONS}${INCL_PERM:+}" + " ${INCL_PERM:+}" " " " " " " @@ -60,48 +64,49 @@ static const char *config = " " ""; -#define DDS_DOMAINID1 0 -#define DDS_DOMAINID2 1 +#define MAX_DOMAINS 10 +#define DDS_DOMAINID -static dds_entity_t g_domain1 = 0; -static dds_entity_t g_participant1 = 0; +static dds_entity_t g_domain[MAX_DOMAINS]; +static dds_entity_t g_participant[MAX_DOMAINS]; +static dds_entity_t g_pubsub[MAX_DOMAINS]; +static dds_entity_t g_topic[MAX_DOMAINS]; +static uint32_t g_topic_nr = 0; -static dds_entity_t g_domain2 = 0; -static dds_entity_t g_participant2 = 0; - -static void access_control_init(bool incl_gov, const char * gov, bool incl_perm, const char * perm, bool incl_ca, const char * ca, bool exp_pp_fail) +static void access_control_init( + const char * id_certs[], const char * id_keys[], const char * id_ca[], bool exp_pp_fail[], size_t n_nodes, + bool incl_gov, const char * gov, + bool incl_perm, const char * perm, + bool incl_ca, const char * ca) { - struct kvp config_vars[] = { - { "INCL_GOV", incl_gov ? "1" : "", 2 }, - { "INCL_PERM", incl_perm ? "1" : "", 2 }, - { "INCL_PERM_CA", incl_ca ? "1" : "", 2 }, - { "TEST_GOVERNANCE", gov, 1 }, - { "TEST_PERMISSIONS", perm, 1 }, - { "TEST_PERMISSIONS_CA", ca, 1 }, - { NULL, NULL, 0 } - }; - - char *conf = ddsrt_expand_vars_sh (config, &expand_lookup_vars_env, config_vars); - CU_ASSERT_EQUAL_FATAL (expand_lookup_unmatched (config_vars), 0); - g_domain1 = dds_create_domain (DDS_DOMAINID1, conf); - g_domain2 = dds_create_domain (DDS_DOMAINID2, conf); - dds_free (conf); - - g_participant1 = dds_create_participant (DDS_DOMAINID1, NULL, NULL); - g_participant2 = dds_create_participant (DDS_DOMAINID2, NULL, NULL); - CU_ASSERT_EQUAL_FATAL (exp_pp_fail, g_participant1 <= 0); - CU_ASSERT_EQUAL_FATAL (exp_pp_fail, g_participant2 <= 0); + CU_ASSERT_FATAL (n_nodes <= MAX_DOMAINS); + for (size_t i = 0; i < n_nodes; i++) + { + struct kvp config_vars[] = { + { "TEST_IDENTITY_CERTIFICATE", id_certs[i], 1 }, + { "TEST_IDENTITY_PRIVATE_KEY", id_keys[i], 1 }, + { "TEST_IDENTITY_CA_CERTIFICATE", id_ca[i], 1 }, + { "INCL_GOV", incl_gov ? "1" : "", 2 }, + { "INCL_PERM", incl_perm ? "1" : "", 2 }, + { "INCL_PERM_CA", incl_ca ? "1" : "", 2 }, + { "TEST_GOVERNANCE", gov, 1 }, + { "TEST_PERMISSIONS", perm, 1 }, + { "TEST_PERMISSIONS_CA", ca, 1 }, + { NULL, NULL, 0 } + }; + char *conf = ddsrt_expand_vars_sh (config, &expand_lookup_vars_env, config_vars); + CU_ASSERT_EQUAL_FATAL (expand_lookup_unmatched (config_vars), 0); + g_domain[i] = dds_create_domain (DDS_DOMAINID + (dds_domainid_t)i, conf); + dds_free (conf); + g_participant[i] = dds_create_participant (DDS_DOMAINID + (dds_domainid_t)i, NULL, NULL); + CU_ASSERT_EQUAL_FATAL (exp_pp_fail[i], g_participant[i] <= 0); + } } -static void access_control_fini(bool delete_pp) +static void access_control_fini(size_t n) { - if (delete_pp) - { - CU_ASSERT_EQUAL_FATAL (dds_delete (g_participant1), DDS_RETCODE_OK); - CU_ASSERT_EQUAL_FATAL (dds_delete (g_participant2), DDS_RETCODE_OK); - } - CU_ASSERT_EQUAL_FATAL (dds_delete (g_domain1), DDS_RETCODE_OK); - CU_ASSERT_EQUAL_FATAL (dds_delete (g_domain2), DDS_RETCODE_OK); + for (size_t i = 0; i < n; i++) + CU_ASSERT_EQUAL_FATAL (dds_delete (g_domain[i]), DDS_RETCODE_OK); } @@ -144,6 +149,221 @@ CU_Theory((const char * test_descr, const char * gov, const char * perm, const c ddssec_access_control, config_parameters_file) { printf("running test config_parameters_file: %s\n", test_descr); - access_control_init (incl_empty_els || strlen (gov), gov, incl_empty_els || strlen (perm), perm, incl_empty_els || strlen (ca), ca, exp_fail); - access_control_fini (!exp_fail); + access_control_init ( + (const char *[]) { TEST_IDENTITY1_CERTIFICATE, TEST_IDENTITY1_CERTIFICATE }, + (const char *[]) { TEST_IDENTITY1_PRIVATE_KEY, TEST_IDENTITY1_PRIVATE_KEY }, + (const char *[]) { TEST_IDENTITY_CA1_CERTIFICATE, TEST_IDENTITY_CA1_CERTIFICATE }, + (bool []) { exp_fail, exp_fail }, 2, + incl_empty_els || strlen (gov), gov, + incl_empty_els || strlen (perm), perm, + incl_empty_els || strlen (ca), ca); + access_control_fini (2); } + +#define S(n) (n) +#define M(n) (S(n)*60) +#define H(n) (M(n)*60) +#define D(n) (H(n)*24) +CU_TheoryDataPoints(ddssec_access_control, permissions_expiry) = { + CU_DataPoints(const char *, + /* */"valid 1 minute from now", + /* | */"valid -1 minute until now", + /* | | */"1s valid, create pp after 1100ms", + /* | | | */"node 2 permissions expired", + /* | | | | */"node 1 3s valid, write/read for 1s delayed 3s", + /* | | | | | */"node 2 3s valid, write/read for 1s delayed 3s"), + CU_DataPoints(int32_t, 0, -M(1), 0, 0, 0, 0), /* node 1 permissions not before (offset from local time) */ + CU_DataPoints(int32_t, M(1), 0, S(1), D(1), S(3), D(1)), /* node 1 permissions not after (offset from local time) */ + CU_DataPoints(int32_t, 0, -M(1), 0, -D(1), 0, 0), /* node 2 permissions not before (offset from local time) */ + CU_DataPoints(int32_t, M(1), 0, S(1), 0, D(1), S(3)), /* node 2 permissions not after (offset from local time) */ + CU_DataPoints(uint32_t, 0, 0, 1100, 0, 0, 0), /* delay (ms) after generating permissions */ + CU_DataPoints(bool, false, true, true, false, false, false), /* expect pp 1 create failure */ + CU_DataPoints(bool, false, true, true, true, false, false), /* expect pp 2 create failure */ + CU_DataPoints(uint32_t, 0, 0, 0, 0, 3000, 3000), /* delay (ms) after creating readers/writers */ + CU_DataPoints(uint32_t, 1, 0, 0, 0, 1000, 1000), /* write/read data during x ms */ + CU_DataPoints(bool, false, false, false, false, true, true), /* expect read data failure */ +}; +CU_Theory( + (const char * test_descr, + int32_t perm1_not_before, int32_t perm1_not_after, int32_t perm2_not_before, int32_t perm2_not_after, + uint32_t delay_perm, bool exp_pp1_fail, bool exp_pp2_fail, uint32_t delay_wr_rd, uint32_t write_read_dur, bool exp_read_fail), + ddssec_access_control, permissions_expiry, .timeout=20) +{ + printf("running test permissions_expiry: %s\n", test_descr); + + char topic_name[100]; + create_topic_name("ddssec_access_control_", g_topic_nr++, topic_name, sizeof (topic_name)); + + /* create ca and id1/id2 certs that will not expire during this test */ + char *ca, *id1, *id2, *id1_subj, *id2_subj; + ca = generate_ca ("ca1", TEST_IDENTITY_CA1_PRIVATE_KEY, 0, D(1)); + id1 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id1", TEST_IDENTITY1_PRIVATE_KEY, 0, D(1), &id1_subj); + id2 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id2", TEST_IDENTITY1_PRIVATE_KEY, 0, D(1), &id2_subj); + + /* localtime will be converted to gmtime in get_permissions_grant */ + dds_time_t now = dds_time (); + char * perm_topic = get_permissions_topic(topic_name); + char * grants[] = { + get_permissions_grant ("id1", id1_subj, now + DDS_SECS(perm1_not_before), now + DDS_SECS(perm1_not_after), perm_topic, perm_topic, NULL), + get_permissions_grant ("id2", id2_subj, now + DDS_SECS(perm2_not_before), now + DDS_SECS(perm2_not_after), perm_topic, perm_topic, NULL) }; + char * perm_config = get_permissions_config (grants, 2, true); + dds_sleepfor (DDS_MSECS (delay_perm)); + + access_control_init ( + (const char *[]) { id1, id2 }, + (const char *[]) { TEST_IDENTITY1_PRIVATE_KEY, TEST_IDENTITY1_PRIVATE_KEY }, + (const char *[]) { ca, ca }, + (bool []) { exp_pp1_fail, exp_pp2_fail }, 2, + true, PF_F COMMON_ETC_PATH("default_governance.p7s"), + true, perm_config, + true, PF_F COMMON_ETC_PATH("default_permissions_ca.pem")); + + if (write_read_dur > 0) + { + dds_entity_t wr = 0, rd = 0; + rd_wr_init (g_participant[0], &g_pubsub[0], &g_topic[0], &wr, g_participant[1], &g_pubsub[1], &g_topic[1], &rd, topic_name); + dds_sleepfor (DDS_MSECS (delay_wr_rd)); + write_read_for (wr, g_participant[1], rd, DDS_MSECS (write_read_dur), false, exp_read_fail); + } + + access_control_fini (2); + + ddsrt_free (perm_topic); + ddsrt_free (grants[0]); + ddsrt_free (grants[1]); + ddsrt_free (perm_config); + ddsrt_free (ca); + ddsrt_free (id1_subj); + ddsrt_free (id2_subj); + ddsrt_free (id1); + ddsrt_free (id2); +} +#undef D +#undef H +#undef M + + +#define N_NODES 4 +#define PERM_EXP_BASE 3 +CU_Test(ddssec_access_control, permissions_expiry_multiple, .timeout=20) +{ + char topic_name[100]; + create_topic_name("ddssec_access_control_", g_topic_nr++, topic_name, sizeof (topic_name)); + + dds_time_t t_perm = dds_time (); + char *ca = generate_ca ("ca1", TEST_IDENTITY_CA1_PRIVATE_KEY, 0, 3600); + char *perm_topic = get_permissions_topic (topic_name); + + // 1st node used as reader, other nodes as writer + const char *id[N_NODES], *pk[N_NODES], *ca_list[N_NODES]; + char * id_subj[N_NODES], *grants[N_NODES]; + bool exp_fail[N_NODES]; + for (int i = 0; i < N_NODES; i++) + { + char *id_name; + ddsrt_asprintf (&id_name, "id_%d", i); + pk[i] = TEST_IDENTITY1_PRIVATE_KEY; + ca_list[i] = ca; + id[i] = generate_identity (ca_list[i], TEST_IDENTITY_CA1_PRIVATE_KEY, id_name, pk[i], 0, 3600, &id_subj[i]); + exp_fail[i] = false; + dds_duration_t v = DDS_SECS(i == 0 ? 3600 : PERM_EXP_BASE + i); /* 1st node is reader and should not expire */ + grants[i] = get_permissions_grant (id_name, id_subj[i], t_perm, t_perm + v, perm_topic, perm_topic, NULL); + ddsrt_free (id_name); + } + + char * perm_config = get_permissions_config (grants, N_NODES, true); + access_control_init ( + id, pk, ca_list, exp_fail, N_NODES, + true, PF_F COMMON_ETC_PATH("default_governance.p7s"), + true, perm_config, + true, PF_F COMMON_ETC_PATH("default_permissions_ca.pem")); + + dds_qos_t * qos = dds_create_qos (); + CU_ASSERT_FATAL (qos != NULL); + dds_qset_history (qos, DDS_HISTORY_KEEP_ALL, -1); + dds_qset_durability (qos, DDS_DURABILITY_TRANSIENT_LOCAL); + dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY); + dds_entity_t sub_tp = dds_create_topic (g_participant[0], &SecurityCoreTests_Type1_desc, topic_name, NULL, NULL); + CU_ASSERT_FATAL (sub_tp > 0); + dds_entity_t sub = dds_create_subscriber (g_participant[0], NULL, NULL); + CU_ASSERT_FATAL (sub > 0); + dds_entity_t rd = dds_create_reader (sub, sub_tp, qos, NULL); + CU_ASSERT_FATAL (rd > 0); + dds_set_status_mask (rd, DDS_DATA_AVAILABLE_STATUS); + + dds_entity_t wr[N_NODES - 1]; + for (int i = 1; i < N_NODES; i++) + { + dds_entity_t pub = dds_create_publisher (g_participant[i], NULL, NULL); + CU_ASSERT_FATAL (pub > 0); + dds_entity_t pub_tp = dds_create_topic (g_participant[i], &SecurityCoreTests_Type1_desc, topic_name, NULL, NULL); + CU_ASSERT_FATAL (pub_tp > 0); + wr[i - 1] = dds_create_writer (pub, pub_tp, qos, NULL); + CU_ASSERT_FATAL (wr[i - 1] > 0); + dds_set_status_mask (wr[i - 1], DDS_PUBLICATION_MATCHED_STATUS); + sync_writer_to_readers(g_participant[i], wr[i - 1], 1); + } + dds_delete_qos (qos); + + SecurityCoreTests_Type1 sample = { 1, 1 }; + SecurityCoreTests_Type1 rd_sample; + void * samples[] = { &rd_sample }; + dds_sample_info_t info[1]; + dds_return_t ret; + + for (int i = 1; i < N_NODES; i++) + { + // sleep until 1s before next writer pp permission expires + dds_duration_t delay = DDS_SECS (PERM_EXP_BASE + i - 1) - (dds_time () - t_perm); + if (delay > 0) + dds_sleepfor (delay); + + printf ("run %d\n", i); + + for (int w = 1; w < N_NODES; w++) + { + sample.id = w; + ret = dds_write (wr[w - 1], &sample); + CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); + printf ("write %d\n", w); + } + + // Expect reader to receive data from writers with non-expired permissions + int n_samples = 0, n_invalid = 0, n_wait = 0; + while (n_samples + n_invalid < N_NODES - 1 && n_wait < 5) + { + ret = dds_take (rd, samples, info, 1, 1); + CU_ASSERT_FATAL (ret >= 0); + if (ret == 0) + { + reader_wait_for_data (g_participant[0], rd, DDS_MSECS (100)); + n_wait++; + } + else if (info[0].instance_state == DDS_IST_ALIVE) + { + printf ("recv sample %d\n", rd_sample.id); + n_samples++; + } + else + { + printf ("recv inv sample\n"); + n_invalid++; + } + } + CU_ASSERT_EQUAL (n_samples, N_NODES - i); + CU_ASSERT (n_invalid < i); + } + + access_control_fini (N_NODES); + + for (int i = 0; i < N_NODES; i++) + { + ddsrt_free (grants[i]); + ddsrt_free (id_subj[i]); + ddsrt_free ((char *)id[i]); + } + ddsrt_free (ca); + ddsrt_free (perm_topic); + ddsrt_free (perm_config); +} +#undef N_NODES diff --git a/src/security/core/tests/authentication.c b/src/security/core/tests/authentication.c index a23f203..1e53a8f 100644 --- a/src/security/core/tests/authentication.c +++ b/src/security/core/tests/authentication.c @@ -19,7 +19,6 @@ #include "dds/version.h" #include "dds/ddsrt/cdtors.h" #include "dds/ddsrt/environ.h" -#include "dds/ddsrt/process.h" #include "dds/ddsrt/heap.h" #include "dds/ddsrt/string.h" #include "dds/ddsi/q_config.h" @@ -31,15 +30,12 @@ #include "common/config_env.h" #include "common/authentication_wrapper.h" -#include "common/handshake_test_utils.h" +#include "common/test_utils.h" #include "common/security_config_test_utils.h" #include "common/test_identity.h" #include "common/cert_utils.h" #include "common/security_config_test_utils.h" -#include "SecurityCoreTests.h" - - #define ID1 TEST_IDENTITY1_CERTIFICATE #define ID1K TEST_IDENTITY1_PRIVATE_KEY #define ID2 TEST_IDENTITY2_CERTIFICATE @@ -152,119 +148,6 @@ static void authentication_init( ddsrt_free (conf2); } -static char *create_topic_name(const char *prefix, uint32_t nr, char *name, size_t size) -{ - ddsrt_pid_t pid = ddsrt_getpid (); - ddsrt_tid_t tid = ddsrt_gettid (); - (void)snprintf(name, size, "%s%d_pid%" PRIdPID "_tid%" PRIdTID "", prefix, nr, pid, tid); - return name; -} - -static void sync_writer_to_reader() -{ - dds_attach_t triggered; - dds_return_t ret; - dds_entity_t waitset_wr = dds_create_waitset (g_participant1); - CU_ASSERT_FATAL (waitset_wr > 0); - dds_publication_matched_status_t pub_matched; - - /* Sync writer to reader. */ - ret = dds_waitset_attach (waitset_wr, g_wr, g_wr); - CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); - while (true) - { - ret = dds_waitset_wait (waitset_wr, &triggered, 1, DDS_SECS(5)); - CU_ASSERT_FATAL (ret >= 1); - CU_ASSERT_EQUAL_FATAL (g_wr, (dds_entity_t)(intptr_t) triggered); - ret = dds_get_publication_matched_status(g_wr, &pub_matched); - CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); - if (pub_matched.total_count >= 1) - break; - }; - dds_delete (waitset_wr); -} - -static void reader_wait_for_data() -{ - dds_attach_t triggered; - dds_return_t ret; - dds_entity_t waitset_rd = dds_create_waitset (g_participant2); - CU_ASSERT_FATAL (waitset_rd > 0); - - ret = dds_waitset_attach (waitset_rd, g_rd, g_rd); - CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); - ret = dds_waitset_wait (waitset_rd, &triggered, 1, DDS_SECS(5)); - CU_ASSERT_EQUAL_FATAL (ret, 1); - CU_ASSERT_EQUAL_FATAL (g_rd, (dds_entity_t)(intptr_t)triggered); - dds_delete (waitset_rd); -} - -static void rd_wr_init() -{ - char name[100]; - dds_qos_t * qos = dds_create_qos (); - CU_ASSERT_FATAL (qos != NULL); - dds_qset_history (qos, DDS_HISTORY_KEEP_ALL, -1); - dds_qset_durability (qos, DDS_DURABILITY_TRANSIENT_LOCAL); - dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY); - - create_topic_name("ddssec_authentication_", g_topic_nr++, name, sizeof (name)); - g_pub = dds_create_publisher (g_participant1, NULL, NULL); - CU_ASSERT_FATAL (g_pub > 0); - g_sub = dds_create_subscriber (g_participant2, NULL, NULL); - CU_ASSERT_FATAL (g_sub > 0); - g_pub_tp = dds_create_topic (g_participant1, &SecurityCoreTests_Type1_desc, name, NULL, NULL); - CU_ASSERT_FATAL (g_pub_tp > 0); - g_sub_tp = dds_create_topic (g_participant2, &SecurityCoreTests_Type1_desc, name, NULL, NULL); - CU_ASSERT_FATAL (g_sub_tp > 0); - g_wr = dds_create_writer (g_pub, g_pub_tp, qos, NULL); - CU_ASSERT_FATAL (g_wr > 0); - dds_set_status_mask (g_wr, DDS_PUBLICATION_MATCHED_STATUS); - g_rd = dds_create_reader (g_sub, g_sub_tp, qos, NULL); - CU_ASSERT_FATAL (g_rd > 0); - dds_set_status_mask (g_rd, DDS_DATA_AVAILABLE_STATUS); - sync_writer_to_reader(); - dds_delete_qos (qos); -} - -static void write_read(dds_duration_t dur, bool exp_write_fail, bool exp_read_fail) -{ - SecurityCoreTests_Type1 sample = { 1, 1 }; - SecurityCoreTests_Type1 rd_sample; - void * samples[] = { &rd_sample }; - dds_sample_info_t info[1]; - dds_return_t ret; - dds_time_t tend = dds_time () + dur; - bool write_fail = false, read_fail = false; - - rd_wr_init (); - do - { - ret = dds_write (g_wr, &sample); - if (ret != DDS_RETCODE_OK) - write_fail = true; - while (true) - { - if ((ret = dds_take (g_rd, samples, info, 1, 1)) == 0) - { - reader_wait_for_data (); - continue; - } - else if (ret < 0) - { - read_fail = true; - break; - } - CU_ASSERT_EQUAL_FATAL (ret, 1); - break; - } - dds_sleepfor (DDS_MSECS (1)); - } - while (dds_time() < tend && !write_fail && !read_fail); - CU_ASSERT_EQUAL_FATAL (write_fail, exp_write_fail); - CU_ASSERT_EQUAL_FATAL (read_fail, exp_read_fail); -} - static void authentication_fini(bool delete_pp1, bool delete_pp2) { if (delete_pp1) @@ -276,7 +159,7 @@ static void authentication_fini(bool delete_pp1, bool delete_pp2) } #define FM_CA "error: unable to get local issuer certificate" -#define FM_INVK "Failed to finalize verify context" +#define FM_INVK "Failed to finalize digest context" CU_TheoryDataPoints(ddssec_authentication, id_ca_certs) = { CU_DataPoints(const char *, /* */"valid ID1-ID1", @@ -341,7 +224,7 @@ CU_Theory((const char * test_descr, const char * id2, const char *key2, const ch bool exp_fail_local, const char * fail_local_msg, bool exp_fail_hs_req, const char * fail_hs_req_msg, bool exp_fail_hs_reply, const char * fail_hs_reply_msg), - ddssec_authentication, id_ca_certs) + ddssec_authentication, id_ca_certs, .timeout=30) { struct Handshake *hs_list; int nhs; @@ -393,12 +276,12 @@ CU_TheoryDataPoints(ddssec_authentication, expired_cert) = { /* | | | | | | */"id1 valid after 1s, delay 1100ms", /* | | | | | | | *//*"ca and id1 expire during session"*/), CU_DataPoints(int32_t, 0, -M(1), 0, 0, 0, 0, 0, /*0*/ ), /* CA1 not before */ - CU_DataPoints(int32_t, D(1), 0, D(1), D(1), M(1), D(1), D(1), /*2*/ ), /* CA1 not after */ - CU_DataPoints(int32_t, 0, 0, -D(1), 0, 0, 0, 1, /*0*/ ), /* ID1 not before */ - CU_DataPoints(int32_t, D(1), D(1), 0, D(1), M(1), 1, D(1), /*2*/ ), /* ID1 not after */ + CU_DataPoints(int32_t, D(1), 0, D(1), D(1), M(1), D(1), D(1), /*2*/ ), /* CA1 not after (offset from local time) */ + CU_DataPoints(int32_t, 0, 0, -D(1), 0, 0, 0, 1, /*0*/ ), /* ID1 not before (offset from local time) */ + CU_DataPoints(int32_t, D(1), D(1), 0, D(1), M(1), 1, D(1), /*2*/ ), /* ID1 not after (offset from local time) */ CU_DataPoints(bool, false, true, true, false, false, true, false, /*false*/ ), /* expect validate local ID1 fail */ - CU_DataPoints(int32_t, 0, 0, 0, -D(1), 0, 0, 0, /*0*/ ), /* ID2 not before */ - CU_DataPoints(int32_t, D(1), D(1), D(1), 0, D(1), 1, D(1), /*D(1)*/ ), /* ID2 not after */ + CU_DataPoints(int32_t, 0, 0, 0, -D(1), 0, 0, 0, /*0*/ ), /* ID2 not before (offset from local time) */ + CU_DataPoints(int32_t, D(1), D(1), D(1), 0, D(1), 1, D(1), /*D(1)*/ ), /* ID2 not after (offset from local time) */ CU_DataPoints(bool, false, true, false, true, false, true, false, /*false*/ ), /* expect validate local ID2 fail */ CU_DataPoints(uint32_t, 0, 0, 0, 0, 0, 1100, 1100, /*0*/ ), /* delay (ms) after generating certificate */ CU_DataPoints(uint32_t, 1, 0, 0, 0, 1, 0, 1, /*3500*/ ), /* write/read data during x ms */ @@ -409,22 +292,32 @@ CU_Theory( int32_t id1_not_before, int32_t id1_not_after, bool id1_local_fail, int32_t id2_not_before, int32_t id2_not_after, bool id2_local_fail, uint32_t delay, uint32_t write_read_dur, bool exp_read_fail), - ddssec_authentication, expired_cert) + ddssec_authentication, expired_cert, .timeout=30) { - char *ca, *id1, *id2, *id1_subj, *id2_subj; printf("running test expired_cert: %s\n", test_descr); + + char topic_name[100]; + create_topic_name("ddssec_authentication_", g_topic_nr++, topic_name, sizeof (topic_name)); + + char *ca, *id1, *id2, *id1_subj, *id2_subj; ca = generate_ca ("ca1", CA1K, ca_not_before, ca_not_after); id1 = generate_identity (ca, CA1K, "id1", ID1K, id1_not_before, id1_not_after, &id1_subj); id2 = generate_identity (ca, CA1K, "id2", ID1K, id2_not_before, id2_not_after, &id2_subj); dds_sleepfor (DDS_MSECS (delay)); - char * grants[] = { get_permissions_grant ("id1", id1_subj), get_permissions_grant ("id2", id2_subj) }; + dds_time_t now = dds_time (); + char * grants[] = { + get_permissions_grant ("id1", id1_subj, now - DDS_SECS(D(1)), now + DDS_SECS(D(1)), NULL, NULL, NULL), + get_permissions_grant ("id2", id2_subj, now - DDS_SECS(D(1)), now + DDS_SECS(D(1)), NULL, NULL, NULL) }; char * perm_config = get_permissions_config (grants, 2, true); authentication_init (id1, ID1K, ca, id2, ID1K, ca, NULL, perm_config, id1_local_fail, id2_local_fail); validate_handshake (DDS_DOMAINID1, id1_local_fail, NULL, NULL, NULL); validate_handshake (DDS_DOMAINID2, id2_local_fail, NULL, NULL, NULL); if (write_read_dur > 0) - write_read (DDS_MSECS (write_read_dur), false, exp_read_fail); + { + rd_wr_init (g_participant1, &g_pub, &g_pub_tp, &g_wr, g_participant2, &g_sub, &g_sub_tp, &g_rd, topic_name); + write_read_for (g_wr, g_participant2, g_rd, DDS_MSECS (write_read_dur), false, exp_read_fail); + } authentication_fini (!id1_local_fail, !id2_local_fail); ddsrt_free (grants[0]); ddsrt_free (grants[1]); diff --git a/src/security/core/tests/common/etc/default_permissions.p7s b/src/security/core/tests/common/etc/default_permissions.p7s index ddc97bc..4c8985b 100644 --- a/src/security/core/tests/common/etc/default_permissions.p7s +++ b/src/security/core/tests/common/etc/default_permissions.p7s @@ -1,9 +1,9 @@ MIME-Version: 1.0 -Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----A38CC2CF99C9B2ECE7711B9937B56A67" +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----82330497FB128B8C3833F86AA2902BC0" This is an S/MIME signed message -------A38CC2CF99C9B2ECE7711B9937B56A67 +------82330497FB128B8C3833F86AA2902BC0 Content-Type: text/plain @@ -76,10 +76,43 @@ Content-Type: text/plain DENY + + emailAddress=carol@cycloneddssecurity.adlinktech.com,CN=Carol Example,O=Example Organization,OU=Organizational Unit Name,L=Locality Name,ST=OV,C=NL + + + 2015-09-15T01:00:00 + 2115-09-15T01:00:00 + + + + + 0 + 230 + + + + + * + + + * + + + + + * + + + * + + + + DENY + -------A38CC2CF99C9B2ECE7711B9937B56A67 +------82330497FB128B8C3833F86AA2902BC0 Content-Type: application/x-pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" @@ -115,16 +148,16 @@ DBdFeGFtcGxlIENBIE9yZ2FuaXphdGlvbjEfMB0GA1UEAwwWRXhhbXBsZSBQZXJt aXNzaW9ucyBDQTE6MDgGCSqGSIb3DQEJARYrYXV0aG9yaXR5QGN5Y2xvbmVkZHNz ZWN1cml0eS5hZGxpbmt0ZWNoLmNvbQIUfoby6818hlJQ+41KUHiM6BZll/0wDQYJ YIZIAWUDBAIBBQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG -9w0BCQUxDxcNMjAwMzI1MDczMTM5WjAvBgkqhkiG9w0BCQQxIgQg3FQPbVj9xFlc -/eoZaddhdX1BXlKZyENrbh7DcCwklVwweQYJKoZIhvcNAQkPMWwwajALBglghkgB +9w0BCQUxDxcNMjAwMzI3MTMyMzM3WjAvBgkqhkiG9w0BCQQxIgQgZQWM3IUTViCR +9e+lYi65rV0rszQ5ZMG9iWStIWhT3UQweQYJKoZIhvcNAQkPMWwwajALBglghkgB ZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggq hkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwIC -ASgwDQYJKoZIhvcNAQEBBQAEggEAWJxDp9TDqXKazAlIj9SZ8mQXhhGoTDeqZbxE -Bs561dHUmQVtA2S85TWGiCffKqWj3wlF5GwZNneYEV1deE3LZFa0o1+/VpeIBSGO -Qs1xKS7zx8IkGok3k88bh+eohDrgpzdLWkZeJ4P7J/3JmCMFdTXuCpuQYhRIrXO0 -pq4ueV2qGyCN6GZS2PC88GV0xeoS62Vj1Xze8omfgDI7KCPhKz6gJSEFUUqIzg7p -Zhqm15qorUoBVXcvMwaG95/xZVfcZzMbmJB/nhwd9KYu9ImkGj6ssSbgr3VR4OkQ -gQUib4aVQJQgBaWEPrgSjRkAp9rMB7R9IW6p2auMA/Gd/kbd7g== +ASgwDQYJKoZIhvcNAQEBBQAEggEAaZ687ayhsPnVPmsrPM4ECEU9/+PZAuFFV094 +Cqa9YLmsnO0jFElZLu2XRx1oNVp8TxG6OVckDINAxQjMO15+k0oqsAqdJFbgFLA/ +YidfEpuhFUjOy938Y46X6tbFj527GfLS8m3vIoYX+E+db1QcGv22RHb/KKSk6Htc +rbgEFV0pmyNK2foHp9ruBdu/nD7mXRo7h/xZdch60zDyeG40bsoKL63wC62sxQ/X +Mjxc1gmyXXr6AAEVzCVGIr9XHgaTNrThLfoWSRGcrLJI4cwevJ+jLJBBj347FmXi +x8nk6a09p7r9fSASX4vRiLDmDbuFwXolfNLS7Op3UKgkhJBm/A== -------A38CC2CF99C9B2ECE7711B9937B56A67-- +------82330497FB128B8C3833F86AA2902BC0-- diff --git a/src/security/core/tests/common/etc/default_permissions.xml b/src/security/core/tests/common/etc/default_permissions.xml index 5802a3e..d59a629 100644 --- a/src/security/core/tests/common/etc/default_permissions.xml +++ b/src/security/core/tests/common/etc/default_permissions.xml @@ -68,5 +68,38 @@ DENY + + emailAddress=carol@cycloneddssecurity.adlinktech.com,CN=Carol Example,O=Example Organization,OU=Organizational Unit Name,L=Locality Name,ST=OV,C=NL + + + 2015-09-15T01:00:00 + 2115-09-15T01:00:00 + + + + + 0 + 230 + + + + + * + + + * + + + + + * + + + * + + + + DENY + diff --git a/src/security/core/tests/common/security_config_test_utils.c b/src/security/core/tests/common/security_config_test_utils.c index ef9f0f8..51a0a9f 100644 --- a/src/security/core/tests/common/security_config_test_utils.c +++ b/src/security/core/tests/common/security_config_test_utils.c @@ -60,22 +60,25 @@ static const char *governance_xml = " " ""; +static const char *topic_xml = + "${TOPIC_NAME}"; + static const char *permissions_xml_grant = " " " ${SUBJECT_NAME}" - " 2015-09-15T01:00:002115-09-15T01:00:00" + " ${NOT_BEFORE:-2015-09-15T01:00:00}${NOT_AFTER:-2115-09-15T01:00:00}" " " " 0230" " " - " *" + " ${PUB_TOPICS:-*}" " *" " " " " - " *" + " ${SUB_TOPICS:-*}" " *" " " " " - " DENY" + " ${DEFAULT_POLICY:-DENY}" " "; static const char *permissions_xml = @@ -212,11 +215,46 @@ char * get_governance_config(struct kvp *config_vars, bool add_prefix) return prefix_data (config_signed, add_prefix); } -char * get_permissions_grant(const char * name, const char * subject) + +char * get_permissions_topic(const char * name) { + struct kvp vars[] = { + { "TOPIC_NAME", name, 1 }, + { NULL, NULL, 0 } + }; + return ddsrt_expand_vars (topic_xml, &expand_lookup_vars, vars); +} + +static char * get_xml_datetime(dds_time_t t, char * buf, size_t len) +{ + struct tm tm; + time_t sec = (time_t)(t / DDS_NSECS_IN_SEC); +#if _WIN32 + (void)gmtime_s(&tm, &sec); +#else + (void)gmtime_r(&sec, &tm); +#endif /* _WIN32 */ + + strftime(buf, len, "%FT%TZ", &tm); + return buf; +} + +char * get_permissions_grant(const char * name, const char * subject, + dds_time_t not_before, dds_time_t not_after, const char * pub_topics, const char * sub_topics, const char * default_policy) +{ + char not_before_str[] = "0000-00-00T00:00:00Z"; + char not_after_str[] = "0000-00-00T00:00:00Z"; + get_xml_datetime(not_before, not_before_str, sizeof(not_before_str)); + get_xml_datetime(not_after, not_after_str, sizeof(not_after_str)); + struct kvp vars[] = { { "GRANT_NAME", name, 1 }, { "SUBJECT_NAME", subject, 1 }, + { "NOT_BEFORE", not_before_str, 1 }, + { "NOT_AFTER", not_after_str, 1 }, + { "PUB_TOPICS", pub_topics, 1 }, + { "SUB_TOPICS", sub_topics, 1 }, + { "DEFAULT_POLICY", default_policy, 1 }, { NULL, NULL, 0 } }; return ddsrt_expand_vars (permissions_xml_grant, &expand_lookup_vars, vars); diff --git a/src/security/core/tests/common/security_config_test_utils.h b/src/security/core/tests/common/security_config_test_utils.h index 056b4d5..87f8e4b 100644 --- a/src/security/core/tests/common/security_config_test_utils.h +++ b/src/security/core/tests/common/security_config_test_utils.h @@ -26,7 +26,9 @@ const char * expand_lookup_vars_env (const char *name, void * data); int32_t expand_lookup_unmatched (const struct kvp * lookup_table); char * get_governance_config (struct kvp *config_vars, bool add_prefix); -char * get_permissions_grant(const char * name, const char * subject); +char * get_permissions_topic(const char * name); +char * get_permissions_grant(const char * name, const char * subject, + dds_time_t not_before, dds_time_t not_after, const char * pub_topics, const char * sub_topics, const char * default_policy); char * get_permissions_config(char * grants[], size_t ngrants, bool add_prefix); #endif /* SECURITY_CORE_TEST_SECURITY_CONFIG_TEST_UTILS_H_ */ diff --git a/src/security/core/tests/common/handshake_test_utils.c b/src/security/core/tests/common/test_utils.c similarity index 68% rename from src/security/core/tests/common/handshake_test_utils.c rename to src/security/core/tests/common/test_utils.c index 6385de2..476490c 100644 --- a/src/security/core/tests/common/handshake_test_utils.c +++ b/src/security/core/tests/common/test_utils.c @@ -14,13 +14,16 @@ #include "CUnit/Test.h" #include "dds/dds.h" +#include "dds/ddsrt/process.h" #include "dds/ddsrt/string.h" +#include "dds/ddsrt/threads.h" #include "dds/ddsrt/heap.h" #include "dds/security/dds_security_api.h" #include "authentication_wrapper.h" -#include "handshake_test_utils.h" +#include "test_utils.h" +#include "SecurityCoreTests.h" -#define TIMEOUT DDS_SECS(2) +#define HS_TIMEOUT DDS_SECS(2) struct Identity localIdentityList[MAX_LOCAL_IDENTITIES]; int numLocal = 0; @@ -131,7 +134,7 @@ static int find_handshake(DDS_Security_HandshakeHandle handle) static void handle_process_message(dds_domainid_t domain_id, DDS_Security_IdentityHandle handshake) { struct message *msg; - if ((msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_PROCESS_HANDSHAKE, 0, 0, handshake, TIMEOUT))) + if ((msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_PROCESS_HANDSHAKE, 0, 0, handshake, HS_TIMEOUT))) { int idx; if ((idx = find_handshake(msg->hsHandle)) >= 0) @@ -148,7 +151,7 @@ static void handle_begin_handshake_request(dds_domainid_t domain_id, struct Hand { struct message *msg; printf("handle begin handshake request %"PRId64"<->%"PRId64"\n", lid, rid); - if ((msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REQUEST, lid, rid, 0, TIMEOUT))) + if ((msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REQUEST, lid, rid, 0, HS_TIMEOUT))) { hs->handle = msg->hsHandle; hs->handshakeResult = msg->result; @@ -164,7 +167,7 @@ static void handle_begin_handshake_reply(dds_domainid_t domain_id, struct Handsh { struct message *msg; printf("handle begin handshake reply %"PRId64"<->%"PRId64"\n", lid, rid); - if ((msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REPLY, lid, rid, 0, TIMEOUT))) + if ((msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REPLY, lid, rid, 0, HS_TIMEOUT))) { hs->handle = msg->hsHandle; hs->handshakeResult = msg->result; @@ -179,7 +182,7 @@ static void handle_begin_handshake_reply(dds_domainid_t domain_id, struct Handsh static void handle_validate_remote_identity(dds_domainid_t domain_id, DDS_Security_IdentityHandle lid, int count) { struct message *msg; - while (count-- > 0 && (msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_VALIDATE_REMOTE_IDENTITY, lid, 0, 0, TIMEOUT))) + while (count-- > 0 && (msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_VALIDATE_REMOTE_IDENTITY, lid, 0, 0, HS_TIMEOUT))) { struct Handshake *hs; add_remote_identity(msg->ridHandle, &msg->rguid); @@ -204,7 +207,7 @@ static void handle_validate_remote_identity(dds_domainid_t domain_id, DDS_Securi static void handle_validate_local_identity(dds_domainid_t domain_id, bool exp_localid_fail, const char * exp_localid_msg) { - struct message *msg = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_VALIDATE_LOCAL_IDENTITY, 0, 0, 0, TIMEOUT); + struct message *msg = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_VALIDATE_LOCAL_IDENTITY, 0, 0, 0, HS_TIMEOUT); CU_ASSERT_FATAL (msg != NULL); CU_ASSERT_FATAL ((msg->result == DDS_SECURITY_VALIDATION_OK) != exp_localid_fail); if (exp_localid_fail && exp_localid_msg) @@ -268,4 +271,113 @@ void handshake_list_fini(struct Handshake *hs_list, int nhs) struct Handshake hs = hs_list[n]; ddsrt_free (hs.err_msg); } -} \ No newline at end of file +} + +void sync_writer_to_readers(dds_entity_t pp_wr, dds_entity_t wr, uint32_t exp_count) +{ + dds_attach_t triggered; + dds_entity_t ws = dds_create_waitset (pp_wr); + CU_ASSERT_FATAL (ws > 0); + dds_publication_matched_status_t pub_matched; + + dds_return_t ret = dds_waitset_attach (ws, wr, wr); + CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); + while (true) + { + ret = dds_waitset_wait (ws, &triggered, 1, DDS_SECS(5)); + CU_ASSERT_FATAL (ret >= 1); + CU_ASSERT_EQUAL_FATAL (wr, (dds_entity_t)(intptr_t) triggered); + ret = dds_get_publication_matched_status(wr, &pub_matched); + CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); + if (pub_matched.total_count >= exp_count) + break; + }; + dds_delete (ws); + CU_ASSERT_EQUAL_FATAL (pub_matched.total_count, exp_count); +} + +char *create_topic_name(const char *prefix, uint32_t nr, char *name, size_t size) +{ + ddsrt_pid_t pid = ddsrt_getpid (); + ddsrt_tid_t tid = ddsrt_gettid (); + (void)snprintf(name, size, "%s%d_pid%" PRIdPID "_tid%" PRIdTID "", prefix, nr, pid, tid); + return name; +} + +bool reader_wait_for_data(dds_entity_t pp, dds_entity_t rd, dds_duration_t dur) +{ + dds_attach_t triggered; + dds_entity_t ws = dds_create_waitset (pp); + CU_ASSERT_FATAL (ws > 0); + dds_return_t ret = dds_waitset_attach (ws, rd, rd); + CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); + ret = dds_waitset_wait (ws, &triggered, 1, dur); + if (ret > 0) + CU_ASSERT_EQUAL_FATAL (rd, (dds_entity_t)(intptr_t)triggered); + dds_delete (ws); + return ret > 0; +} + +void rd_wr_init( + dds_entity_t pp_wr, dds_entity_t *pub, dds_entity_t *pub_tp, dds_entity_t *wr, + dds_entity_t pp_rd, dds_entity_t *sub, dds_entity_t *sub_tp, dds_entity_t *rd, + const char * topic_name) +{ + dds_qos_t * qos = dds_create_qos (); + CU_ASSERT_FATAL (qos != NULL); + dds_qset_history (qos, DDS_HISTORY_KEEP_ALL, -1); + dds_qset_durability (qos, DDS_DURABILITY_TRANSIENT_LOCAL); + dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY); + + *pub = dds_create_publisher (pp_wr, NULL, NULL); + CU_ASSERT_FATAL (*pub > 0); + *sub = dds_create_subscriber (pp_rd, NULL, NULL); + CU_ASSERT_FATAL (*sub > 0); + *pub_tp = dds_create_topic (pp_wr, &SecurityCoreTests_Type1_desc, topic_name, NULL, NULL); + CU_ASSERT_FATAL (*pub_tp > 0); + *sub_tp = dds_create_topic (pp_rd, &SecurityCoreTests_Type1_desc, topic_name, NULL, NULL); + CU_ASSERT_FATAL (*sub_tp > 0); + *wr = dds_create_writer (*pub, *pub_tp, qos, NULL); + CU_ASSERT_FATAL (*wr > 0); + dds_set_status_mask (*wr, DDS_PUBLICATION_MATCHED_STATUS); + *rd = dds_create_reader (*sub, *sub_tp, qos, NULL); + CU_ASSERT_FATAL (*rd > 0); + dds_set_status_mask (*rd, DDS_DATA_AVAILABLE_STATUS); + sync_writer_to_readers(pp_wr, *wr, 1); + dds_delete_qos (qos); +} + +void write_read_for(dds_entity_t wr, dds_entity_t pp_rd, dds_entity_t rd, dds_duration_t dur, bool exp_write_fail, bool exp_read_fail) +{ + SecurityCoreTests_Type1 sample = { 1, 1 }; + SecurityCoreTests_Type1 rd_sample; + void * samples[] = { &rd_sample }; + dds_sample_info_t info[1]; + dds_return_t ret; + dds_time_t tend = dds_time () + dur; + bool write_fail = false, read_fail = false; + + do + { + if (dds_write (wr, &sample) != DDS_RETCODE_OK) + write_fail = true; + + while (!write_fail) + { + if ((ret = dds_take (rd, samples, info, 1, 1)) > 0) + { + CU_ASSERT_EQUAL_FATAL (ret, 1); + break; + } + if (ret < 0 || !reader_wait_for_data (pp_rd, rd, DDS_MSECS (100))) + { + read_fail = true; + break; + } + } + dds_sleepfor (DDS_MSECS (1)); + } + while (dds_time() < tend && !write_fail && !read_fail); + CU_ASSERT_EQUAL (write_fail, exp_write_fail); + CU_ASSERT_EQUAL (read_fail, exp_read_fail); +} diff --git a/src/security/core/tests/common/handshake_test_utils.h b/src/security/core/tests/common/test_utils.h similarity index 65% rename from src/security/core/tests/common/handshake_test_utils.h rename to src/security/core/tests/common/test_utils.h index 0ae3a59..a1c30b4 100644 --- a/src/security/core/tests/common/handshake_test_utils.h +++ b/src/security/core/tests/common/test_utils.h @@ -9,8 +9,8 @@ * * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ -#ifndef SECURITY_CORE_HANDSHAKE_TEST_UTILS_H_ -#define SECURITY_CORE_HANDSHAKE_TEST_UTILS_H_ +#ifndef SECURITY_CORE_TEST_UTILS_H_ +#define SECURITY_CORE_TEST_UTILS_H_ #include "dds/dds.h" #include "dds/ddsrt/sync.h" @@ -20,7 +20,6 @@ #define MAX_LOCAL_IDENTITIES 8 #define MAX_REMOTE_IDENTITIES 8 #define MAX_HANDSHAKES 32 -#define TIMEOUT DDS_SECS(2) union guid { DDS_Security_GUID_t g; @@ -54,5 +53,13 @@ struct Handshake void validate_handshake(dds_domainid_t domain_id, bool exp_localid_fail, const char * exp_localid_msg, struct Handshake *hs_list[], int *nhs); void validate_handshake_nofail (dds_domainid_t domain_id); void handshake_list_fini(struct Handshake *hs_list, int nhs); +char *create_topic_name(const char *prefix, uint32_t nr, char *name, size_t size); +void sync_writer_to_readers(dds_entity_t pp_wr, dds_entity_t wr, uint32_t exp_count); +bool reader_wait_for_data(dds_entity_t pp, dds_entity_t rd, dds_duration_t dur); +void rd_wr_init( + dds_entity_t pp_wr, dds_entity_t *pub, dds_entity_t *pub_tp, dds_entity_t *wr, + dds_entity_t pp_rd, dds_entity_t *sub, dds_entity_t *sub_tp, dds_entity_t *rd, + const char *topic_name); +void write_read_for(dds_entity_t wr, dds_entity_t pp_rd, dds_entity_t rd, dds_duration_t dur, bool exp_write_fail, bool exp_read_fail); -#endif /* SECURITY_CORE_HANDSHAKE_TEST_UTILS_H_ */ +#endif /* SECURITY_CORE_TEST_UTILS_H_ */ diff --git a/src/security/core/tests/handshake.c b/src/security/core/tests/handshake.c index 62ca589..66a77f9 100644 --- a/src/security/core/tests/handshake.c +++ b/src/security/core/tests/handshake.c @@ -30,7 +30,7 @@ #include "common/config_env.h" #include "common/authentication_wrapper.h" #include "common/plugin_wrapper_msg_q.h" -#include "common/handshake_test_utils.h" +#include "common/test_utils.h" #include "common/test_identity.h" static const char *config =