From 155f8c059d560ee3cf75e991bf5f5a84465933dc Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Wed, 29 Apr 2020 20:53:14 +0200 Subject: [PATCH] Add read-write protection tests Introduced a test that checks for the correct matching behavious for combinations of the read/write access control settings in the governance xml (enable read/write access control in the topic rules) and in the permissions xml (the publish/subscribe grants for a topic). Signed-off-by: Dennis Potman --- src/security/core/tests/access_control.c | 123 ++++++++++++--- src/security/core/tests/authentication.c | 5 +- .../tests/common/security_config_test_utils.c | 142 +++++++++++++----- .../tests/common/security_config_test_utils.h | 14 +- 4 files changed, 210 insertions(+), 74 deletions(-) diff --git a/src/security/core/tests/access_control.c b/src/security/core/tests/access_control.c index 4e5b54e..c508d55 100644 --- a/src/security/core/tests/access_control.c +++ b/src/security/core/tests/access_control.c @@ -90,6 +90,7 @@ static void access_control_init( CU_ASSERT_FATAL (n_nodes <= MAX_DOMAINS); for (size_t i = 0; i < n_nodes; i++) { + print_test_msg ("init domain %"PRIuSIZE"\n", i); struct kvp config_vars[] = { { "TEST_IDENTITY_CERTIFICATE", id_certs[i], 1 }, { "TEST_IDENTITY_PRIVATE_KEY", id_keys[i], 1 }, @@ -256,10 +257,10 @@ CU_Theory( /* 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 * rules_xml = get_permissions_rules (NULL, topic_name, topic_name, NULL, NULL); char * grants[] = { - get_permissions_grant ("id1", id1_subj, NULL, now + DDS_SECS(perm1_not_before), now + DDS_SECS(perm1_not_after), perm_topic, perm_topic, NULL), - get_permissions_grant ("id2", id2_subj, NULL, now + DDS_SECS(perm2_not_before), now + DDS_SECS(perm2_not_after), perm_topic, perm_topic, NULL) }; + get_permissions_grant ("id1", id1_subj, now + DDS_SECS(perm1_not_before), now + DDS_SECS(perm1_not_after), rules_xml, NULL), + get_permissions_grant ("id2", id2_subj, now + DDS_SECS(perm2_not_before), now + DDS_SECS(perm2_not_after), rules_xml, NULL) }; char * perm_config = get_permissions_config (grants, 2, true); dds_sleepfor (DDS_MSECS (delay_perm)); @@ -285,7 +286,7 @@ CU_Theory( write_read_for (wr, g_participant[1], rd, DDS_MSECS (write_read_dur), false, exp_read_fail); } - access_control_fini (2, (void * []) { perm_topic, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 9); + access_control_fini (2, (void * []) { rules_xml, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 9); } @@ -300,7 +301,7 @@ CU_Test(ddssec_access_control, permissions_expiry_multiple, .timeout=20) 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); + char *rules_xml = get_permissions_rules (NULL, topic_name, topic_name, NULL, NULL); // 1st node used as reader, other nodes as writer print_test_msg ("creating permissions grants\n"); @@ -323,7 +324,7 @@ CU_Test(ddssec_access_control, permissions_expiry_multiple, .timeout=20) dds_time_t t_exp = ddsrt_time_add_duration (t_perm, v); if (i >= N_RD) print_test_msg ("w[%d] grant expires at %d.%06d\n", i - N_RD, (int32_t) (t_exp / DDS_NSECS_IN_SEC), (int32_t) (t_exp % DDS_NSECS_IN_SEC) / 1000); - grants[i] = get_permissions_grant (id_name, id_subj[i], NULL, t_perm, t_exp, perm_topic, perm_topic, NULL); + grants[i] = get_permissions_grant (id_name, id_subj[i], t_perm, t_exp, rules_xml, NULL); ddsrt_free (id_name); } @@ -427,7 +428,7 @@ CU_Test(ddssec_access_control, permissions_expiry_multiple, .timeout=20) ddsrt_free ((char *)id[i]); } ddsrt_free (ca); - ddsrt_free (perm_topic); + ddsrt_free (rules_xml); ddsrt_free (perm_config_str); } #undef N_RD @@ -547,12 +548,12 @@ CU_Theory( id1 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id1", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &id1_subj); id2 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id2", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &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 * rules1_xml = get_permissions_rules (perm_inv_pp1 ? "99" : NULL, topic_name, topic_name, NULL, NULL); + char * rules2_xml = get_permissions_rules (perm_inv_pp2 ? "99" : NULL, topic_name, topic_name, NULL, NULL); char * grants[] = { - get_permissions_grant ("id1", id1_subj, perm_inv_pp1 ? "99" : NULL, now, now + DDS_SECS(3600), perm_topic, perm_topic, NULL), - get_permissions_grant ("id2", id2_subj, perm_inv_pp2 ? "99" : NULL, now, now + DDS_SECS(3600), perm_topic, perm_topic, NULL) }; + get_permissions_grant ("id1", id1_subj, now, now + DDS_SECS(3600), rules1_xml, NULL), + get_permissions_grant ("id2", id2_subj, now, now + DDS_SECS(3600), rules2_xml, NULL) }; char * perm_config = get_permissions_config (grants, 2, true); char * gov_topic_rule = get_governance_topic_rule ("*", false, false, true, true, "NONE", "NONE"); @@ -573,7 +574,7 @@ CU_Theory( if (!exp_pp1_fail && !exp_pp2_fail) validate_handshake (DDS_DOMAINID, exp_hs_fail, NULL, NULL, NULL, DDS_SECS(2)); - access_control_fini (2, (void * []) { gov_config_pp1, gov_config_pp2, gov_topic_rule, perm_topic, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 12); + access_control_fini (2, (void * []) { gov_config_pp1, gov_config_pp2, gov_topic_rule, rules1_xml, rules2_xml, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 13); } #define na false @@ -618,12 +619,9 @@ static void test_discovery_liveliness_protection(enum test_discovery_liveliness id1 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id1", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &id1_subj); id2 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id2", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &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, NULL, now, now + DDS_SECS(3600), perm_topic, perm_topic, NULL), - get_permissions_grant ("id2", id2_subj, NULL, now, now + DDS_SECS(3600), perm_topic, perm_topic, NULL) }; + get_permissions_default_grant ("id1", id1_subj, topic_name), + get_permissions_default_grant ("id2", id2_subj, topic_name) }; char * perm_config = get_permissions_config (grants, 2, true); char * gov_topic_rule1 = get_governance_topic_rule (topic_name, dp && enable_protection_pp1, lp && enable_protection_pp1, true, true, "ENCRYPT", "NONE"); @@ -667,7 +665,7 @@ static void test_discovery_liveliness_protection(enum test_discovery_liveliness ddsrt_free (log); } - access_control_fini (2, (void * []) { gov_config1, gov_config2, gov_topic_rule1, gov_topic_rule2, perm_topic, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 13); + access_control_fini (2, (void * []) { gov_config1, gov_config2, gov_topic_rule1, gov_topic_rule2, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 12); } CU_Theory( @@ -702,12 +700,9 @@ static void test_encoding_mismatch( id1 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id1", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &id1_subj); id2 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id2", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &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, NULL, now, now + DDS_SECS(3600), perm_topic, perm_topic, NULL), - get_permissions_grant ("id2", id2_subj, NULL, now, now + DDS_SECS(3600), perm_topic, perm_topic, NULL) }; + get_permissions_default_grant ("id1", id1_subj, topic_name), + get_permissions_default_grant ("id2", id2_subj, topic_name) }; char * perm_config = get_permissions_config (grants, 2, true); char * gov_topic_rule1 = get_governance_topic_rule (topic_name, true, true, true, true, pk_to_str (metadata_pk1), bpk_to_str (payload_pk1)); @@ -739,7 +734,7 @@ static void test_encoding_mismatch( sync_writer_to_readers (g_participant[0], wr, exp_rd_wr_fail ? 0 : 1, DDS_SECS(1)); } - access_control_fini (2, (void * []) { gov_config1, gov_config2, gov_topic_rule1, gov_topic_rule2, perm_topic, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 13); + access_control_fini (2, (void * []) { gov_config1, gov_config2, gov_topic_rule1, gov_topic_rule2, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 12); } static DDS_Security_ProtectionKind pk[] = { PK_N, PK_S, PK_E, PK_SOA, PK_EOA }; @@ -779,3 +774,83 @@ CU_Test(ddssec_access_control, encoding_mismatch_payload, .timeout=30) for (size_t pk2 = pk1 + 1; pk2 < sizeof (bpk) / sizeof (bpk[0]); pk2++) test_encoding_mismatch (false, pk1 != pk2, PK_N, PK_N, PK_N, PK_N, PK_N, PK_N, PK_N, PK_N, bpk[pk1], bpk[pk2]); } + + +static void test_readwrite_protection ( + bool allow_pub, bool allow_sub, bool deny_pub, bool deny_sub, bool write_ac, bool read_ac, + bool exp_pub_pp_fail, bool exp_pub_tp_fail, bool exp_wr_fail, + bool exp_sub_pp_fail, bool exp_sub_tp_fail, bool exp_rd_fail, + bool exp_sync_fail, const char * default_policy) +{ + print_test_msg ("running test readwrite_protection: \n"); + print_test_msg ("- allow_pub=%d | allow_sub=%d | deny_pub=%d | deny_sub=%d | write_ac=%d | read_ac=%d | default_policy=%s\n", allow_pub, allow_sub, deny_pub, deny_sub, write_ac, read_ac, default_policy); + print_test_msg ("- exp_pub_pp_fail=%d | exp_pub_tp_fail=%d | exp_wr_fail=%d | exp_sub_pp_fail=%d | exp_sub_tp_fail=%d | exp_rd_fail=%d | exp_sync_fail=%d\n", exp_pub_pp_fail, exp_pub_tp_fail, exp_wr_fail, exp_sub_pp_fail, exp_sub_tp_fail, exp_rd_fail, exp_sync_fail); + + 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, 3600); + id1 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id1", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &id1_subj); + id2 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id2", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &id2_subj); + + dds_time_t now = dds_time (); + char * rules_xml = get_permissions_rules (NULL, allow_pub ? topic_name : NULL, allow_sub ? topic_name : NULL, deny_pub ? topic_name : NULL, deny_sub ? topic_name : NULL); + char * grants[] = { + get_permissions_grant ("id1", id1_subj, now, now + DDS_SECS(3600), rules_xml, default_policy), + get_permissions_grant ("id2", id2_subj, now, now + DDS_SECS(3600), rules_xml, default_policy) }; + char * perm_config = get_permissions_config (grants, 2, true); + + char * gov_topic_rule = get_governance_topic_rule (topic_name, false, false, read_ac, write_ac, pk_to_str (PK_E), bpk_to_str (BPK_E)); + char * gov_config = get_governance_config (false, true, NULL, NULL, NULL, gov_topic_rule, true); + const char * def_perm_ca = PF_F COMMON_ETC_PATH("default_permissions_ca.pem"); + + access_control_init ( + 2, + (const char *[]) { id1, id2 }, + (const char *[]) { TEST_IDENTITY1_PRIVATE_KEY, TEST_IDENTITY1_PRIVATE_KEY }, + (const char *[]) { ca, ca }, + (bool []) { exp_pub_pp_fail, exp_sub_pp_fail }, NULL, NULL, + (bool []) { true, true }, (const char *[]) { gov_config, gov_config }, + (bool []) { true, true }, (const char *[]) { perm_config, perm_config }, + (bool []) { true, true }, (const char *[]) { def_perm_ca, def_perm_ca }); + + if (!exp_pub_pp_fail && !exp_sub_pp_fail) + { + dds_entity_t pub, sub, pub_tp, sub_tp, wr, rd; + validate_handshake_nofail (DDS_DOMAINID, DDS_MSECS(500)); + rd_wr_init_fail (g_participant[0], &pub, &pub_tp, &wr, g_participant[1], &sub, &sub_tp, &rd, topic_name, exp_pub_tp_fail, exp_wr_fail, exp_sub_tp_fail, exp_rd_fail); + if (!exp_pub_tp_fail && !exp_wr_fail && !exp_sub_tp_fail && !exp_rd_fail) + sync_writer_to_readers (g_participant[0], wr, exp_sync_fail ? 0 : 1, DDS_SECS(1)); + } + + access_control_fini (2, (void * []) { gov_config, gov_topic_rule, rules_xml, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 11); +} + +CU_Test(ddssec_access_control, readwrite_protection, .timeout=60) +{ + for (int allow_pub = 0; allow_pub <= 1; allow_pub++) + for (int allow_sub = 0; allow_sub <= 1; allow_sub++) + for (int deny_pub = 0; deny_pub <= 1 && !(allow_pub && deny_pub); deny_pub++) + for (int deny_sub = 0; deny_sub <= 1 && !(allow_sub && deny_sub); deny_sub++) + for (int write_ac = 0; write_ac <= 1; write_ac++) + for (int read_ac = 0; read_ac <= 1; read_ac++) + for (int default_deny = 0; default_deny <= 1; default_deny++) + { + /* creating local writer/reader fails if write_ac/read_ac enabled and no allow-pub/sub or a deny-pub/sub rule exists */ + bool exp_wr_fail = write_ac && !allow_pub && (deny_pub || default_deny); + bool exp_rd_fail = read_ac && !allow_sub && (deny_sub || default_deny); + /* if both read_ac and write_ac are enabled, and pub and sub not allowed, topic creation should fail */ + bool exp_tp_fail = write_ac && read_ac && !allow_pub && !allow_sub && (deny_pub || deny_sub || default_deny); + /* participant creation should fail under same conditions as topic creation (as opposed to the DDS Security spec, + table 63, that states that participant creation fails when there is not any topic that has enable_read/write_ac + set to false and join_ac is enabled; it seems that the allow_rule condition is missing there) */ + bool exp_pp_fail = write_ac && read_ac && !allow_pub && !allow_sub && default_deny; + /* join-ac is enabled in this test, so check_remote_pp fails (and therefore the reader/writer sync) in case not any allow rule exists */ + bool exp_sync_fail = !allow_pub && !allow_sub && default_deny; + + test_readwrite_protection (allow_pub, allow_sub, deny_pub, deny_sub, write_ac, read_ac, + exp_pp_fail, exp_tp_fail, exp_wr_fail, exp_pp_fail, exp_tp_fail, exp_rd_fail, exp_sync_fail, default_deny ? "DENY" : "ALLOW"); + } +} diff --git a/src/security/core/tests/authentication.c b/src/security/core/tests/authentication.c index bbfb69b..07d637e 100644 --- a/src/security/core/tests/authentication.c +++ b/src/security/core/tests/authentication.c @@ -263,10 +263,9 @@ CU_Theory( id2 = generate_identity (ca, CA1K, "id2", ID1K, id2_not_before, id2_not_after, &id2_subj); dds_sleepfor (DDS_MSECS (delay)); - dds_time_t now = dds_time (); char * grants[] = { - get_permissions_grant ("id1", id1_subj, NULL, now - DDS_SECS(D(1)), now + DDS_SECS(D(1)), NULL, NULL, NULL), - get_permissions_grant ("id2", id2_subj, NULL, now - DDS_SECS(D(1)), now + DDS_SECS(D(1)), NULL, NULL, NULL) }; + get_permissions_default_grant ("id1", id1_subj, topic_name), + get_permissions_default_grant ("id2", id2_subj, topic_name) }; 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, DDS_SECS(2)); 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 74f3e5e..8c46848 100644 --- a/src/security/core/tests/common/security_config_test_utils.c +++ b/src/security/core/tests/common/security_config_test_utils.c @@ -27,6 +27,7 @@ #include "dds/ddsrt/string.h" #include "dds/ddsrt/io.h" #include "common/config_env.h" +#include "common/test_utils.h" #include "security_config_test_utils.h" static const char *topic_rule = @@ -63,24 +64,37 @@ static const char *governance_xml = " " ""; -static const char *topic_xml = - "${TOPIC_NAME}"; +static const char *permissions_xml_pub = + " " + " ${TOPIC_NAME}" + " *" + " "; + +static const char *permissions_xml_sub = + " " + " ${TOPIC_NAME}" + " *" + " "; + +static const char *permissions_xml_allow_rule = + " " + " ${DOMAIN_ID:+}${DOMAIN_ID:-0230}${DOMAIN_ID:+}" + " ${PUBLISH}" + " ${SUBSCRIBE}" + " "; + +static const char *permissions_xml_deny_rule = + " " + " ${DOMAIN_ID:+}${DOMAIN_ID:-0230}${DOMAIN_ID:+}" + " ${PUBLISH}" + " ${SUBSCRIBE}" + " "; static const char *permissions_xml_grant = " " " ${SUBJECT_NAME}" " ${NOT_BEFORE:-2015-09-15T01:00:00}${NOT_AFTER:-2115-09-15T01:00:00}" - " " - " ${DOMAIN_ID:+}${DOMAIN_ID:-0230}${DOMAIN_ID:+}" - " " - " ${PUB_TOPICS:-*}" - " *" - " " - " " - " ${SUB_TOPICS:-*}" - " *" - " " - " " + " ${RULES}" " ${DEFAULT_POLICY:-DENY}" " "; @@ -130,6 +144,20 @@ int32_t expand_lookup_unmatched (const struct kvp * lookup_table) return unmatched; } +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; +} + static char * smime_sign(char * ca_cert_path, char * ca_priv_key_path, const char * data) { // Read CA certificate @@ -232,7 +260,7 @@ char * get_governance_topic_rule(const char * topic_expr, bool discovery_protect return ddsrt_expand_vars (topic_rule, &expand_lookup_vars, vars); } -char * get_governance_config(bool allow_unauth_pp, bool enable_join_ac, const char * discovery_protection_kind, const char * liveliness_protection_kind, +char * get_governance_config (bool allow_unauth_pp, bool enable_join_ac, const char * discovery_protection_kind, const char * liveliness_protection_kind, const char * rtps_protection_kind, const char * topic_rules, bool add_prefix) { struct kvp vars[] = { @@ -248,57 +276,89 @@ char * get_governance_config(bool allow_unauth_pp, bool enable_join_ac, const ch char * config_signed = get_signed_data (config); ddsrt_free (config); - printf("Governance configuration: "); - print_config_vars(vars); + print_test_msg ("governance configuration: "); + print_config_vars (vars); printf("\n"); return prefix_data (config_signed, add_prefix); } - -char * get_permissions_topic(const char * name) +static char * expand_permissions_pubsub (const char * template, const char * topic_name) { struct kvp vars[] = { - { "TOPIC_NAME", name, 1 }, + { "TOPIC_NAME", topic_name, 1 }, { NULL, NULL, 0 } }; - return ddsrt_expand_vars (topic_xml, &expand_lookup_vars, vars); + return ddsrt_expand_vars (template, &expand_lookup_vars, vars); } -static char * get_xml_datetime(dds_time_t t, char * buf, size_t len) +static char * expand_permissions_rule (const char * template, const char * domain_id, const char * pub_xml, const char * sub_xml) { - 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; + struct kvp vars[] = { + { "DOMAIN_ID", domain_id, 3 }, + { "PUBLISH", pub_xml, 1 }, + { "SUBSCRIBE", sub_xml, 1 }, + { NULL, NULL, 0 } + }; + return ddsrt_expand_vars (template, &expand_lookup_vars, vars); } -char * get_permissions_grant(const char * name, const char * subject, const char * domain_id, - 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_rules (const char * domain_id, const char * allow_pub_topic, const char * allow_sub_topic, const char * deny_pub_topic, const char * deny_sub_topic) +{ + char * allow_pub_xml = NULL, * allow_sub_xml = NULL, * deny_pub_xml = NULL, * deny_sub_xml = NULL; + char * allow_rule_xml = NULL, * deny_rule_xml = NULL, * rules_xml; + + if (allow_pub_topic != NULL) allow_pub_xml = expand_permissions_pubsub (permissions_xml_pub, allow_pub_topic); + if (allow_sub_topic != NULL) allow_sub_xml = expand_permissions_pubsub (permissions_xml_sub, allow_sub_topic); + if (deny_pub_topic != NULL) deny_pub_xml = expand_permissions_pubsub (permissions_xml_pub, deny_pub_topic); + if (deny_sub_topic != NULL) deny_sub_xml = expand_permissions_pubsub (permissions_xml_sub, deny_sub_topic); + + if (allow_pub_xml != NULL || allow_sub_xml != NULL) + { + allow_rule_xml = expand_permissions_rule (permissions_xml_allow_rule, domain_id, allow_pub_xml, allow_sub_xml); + if (allow_pub_xml != NULL) ddsrt_free (allow_pub_xml); + if (allow_sub_xml != NULL) ddsrt_free (allow_sub_xml); + } + if (deny_pub_xml != NULL || deny_sub_xml != NULL) + { + deny_rule_xml = expand_permissions_rule (permissions_xml_deny_rule, domain_id, deny_pub_xml, deny_sub_xml); + if (deny_pub_xml != NULL) ddsrt_free (deny_pub_xml); + if (deny_sub_xml != NULL) ddsrt_free (deny_sub_xml); + } + ddsrt_asprintf (&rules_xml, "%s%s", allow_rule_xml != NULL ? allow_rule_xml : "", deny_rule_xml != NULL ? deny_rule_xml : ""); + if (allow_rule_xml != NULL) ddsrt_free (allow_rule_xml); + if (deny_rule_xml != NULL) ddsrt_free (deny_rule_xml); + return rules_xml; +} + +char * get_permissions_grant (const char * grant_name, const char * subject_name, dds_time_t not_before, dds_time_t not_after, const char * rules_xml, 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)); + 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 }, + { "GRANT_NAME", grant_name, 1 }, + { "SUBJECT_NAME", subject_name, 1 }, { "NOT_BEFORE", not_before_str, 1 }, { "NOT_AFTER", not_after_str, 1 }, - { "DOMAIN_ID", domain_id, 3 }, - { "PUB_TOPICS", pub_topics, 1 }, - { "SUB_TOPICS", sub_topics, 1 }, + { "RULES", rules_xml, 1 }, { "DEFAULT_POLICY", default_policy, 1 }, { NULL, NULL, 0 } }; - return ddsrt_expand_vars (permissions_xml_grant, &expand_lookup_vars, vars); + char * res = ddsrt_expand_vars (permissions_xml_grant, &expand_lookup_vars, vars); + CU_ASSERT_FATAL (expand_lookup_unmatched (vars) == 0); + return res; +} + +char * get_permissions_default_grant (const char * grant_name, const char * subject_name, const char * topic_name) +{ + dds_time_t now = dds_time (); + char * rules_xml = get_permissions_rules (NULL, topic_name, topic_name, NULL, NULL); + char * grant_xml = get_permissions_grant (grant_name, subject_name, now, now + DDS_SECS(3600), rules_xml, "DENY"); + ddsrt_free (rules_xml); + return grant_xml; } char * get_permissions_config(char * grants[], size_t ngrants, bool add_prefix) 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 770c979..e70b98e 100644 --- a/src/security/core/tests/common/security_config_test_utils.h +++ b/src/security/core/tests/common/security_config_test_utils.h @@ -25,14 +25,16 @@ const char * expand_lookup_vars (const char *name, void * data); const char * expand_lookup_vars_env (const char *name, void * data); int32_t expand_lookup_unmatched (const struct kvp * lookup_table); -char * get_governance_topic_rule(const char * topic_expr, bool discovery_protection, bool liveliness_protection, +char * get_governance_topic_rule (const char * topic_expr, bool discovery_protection, bool liveliness_protection, bool read_ac, bool write_ac, const char * metadata_protection_kind, const char * data_protection_kind); -char * get_governance_config(bool allow_unauth_pp, bool enable_join_ac, const char * discovery_protection_kind, const char * liveliness_protection_kind, +char * get_governance_config (bool allow_unauth_pp, bool enable_join_ac, const char * discovery_protection_kind, const char * liveliness_protection_kind, const char * rtps_protection_kind, const char * topic_rules, bool add_prefix); -char * get_permissions_topic(const char * name); -char * get_permissions_grant(const char * name, const char * subject, const char * domain_id, - 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); +char * get_permissions_rules (const char * domain_id, const char * allow_pub_topic, const char * allow_sub_topic, + const char * deny_pub_topic, const char * deny_sub_topic); +char * get_permissions_grant (const char * grant_name, const char * subject_name, dds_time_t not_before, dds_time_t not_after, + const char * rules_xml, const char * default_policy); +char * get_permissions_default_grant (const char * grant_name, const char * subject_name, const char * topic_name); +char * get_permissions_config (char * grants[], size_t ngrants, bool add_prefix); #endif /* SECURITY_CORE_TEST_SECURITY_CONFIG_TEST_UTILS_H_ */