From edcbe1b22e3bea4c93261df7906bccc5ef7840a1 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Tue, 12 May 2020 20:28:11 +0200 Subject: [PATCH] Add a test that checks if all tokens and attributes are returned to the access control plugin Signed-off-by: Dennis Potman --- .../ddsi/include/dds/ddsi/ddsi_security_omg.h | 4 +- src/core/ddsi/src/ddsi_security_omg.c | 21 ++- src/security/core/tests/access_control.c | 45 ++++- .../tests/common/access_control_wrapper.c | 166 +++++++++++++++++- .../tests/common/access_control_wrapper.h | 9 + src/security/core/tests/common/test_utils.c | 33 ++-- src/security/core/tests/common/test_utils.h | 8 +- src/security/core/tests/crypto.c | 2 +- src/security/core/tests/handshake.c | 4 +- .../core/tests/secure_communication.c | 2 +- 10 files changed, 260 insertions(+), 34 deletions(-) diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h b/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h index e7c3214..460a4ad 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h @@ -109,8 +109,8 @@ struct reader_sec_attributes { bool plugin_attr; }; -struct dds_security_authentication *q_omg_participant_get_authentication(const struct participant *pp); - +DDS_EXPORT struct dds_security_access_control *q_omg_participant_get_access_control(const struct participant *pp); +DDS_EXPORT struct dds_security_authentication *q_omg_participant_get_authentication(const struct participant *pp); DDS_EXPORT struct dds_security_cryptography *q_omg_participant_get_cryptography(const struct participant *pp); void q_omg_vlog_exception(const struct ddsrt_log_cfg *lc, uint32_t cat, DDS_Security_SecurityException *exception, const char *file, uint32_t line, const char *func, const char *fmt, va_list ap); diff --git a/src/core/ddsi/src/ddsi_security_omg.c b/src/core/ddsi/src/ddsi_security_omg.c index a0d186a..d064105 100644 --- a/src/core/ddsi/src/ddsi_security_omg.c +++ b/src/core/ddsi/src/ddsi_security_omg.c @@ -284,6 +284,13 @@ static struct dds_security_context * q_omg_security_get_secure_context(const str return NULL; } +struct dds_security_access_control *q_omg_participant_get_access_control(const struct participant *pp) +{ + if (pp && pp->e.gv->security_context && q_omg_is_security_loaded(pp->e.gv->security_context)) + return pp->e.gv->security_context->access_control_context; + return NULL; +} + struct dds_security_authentication *q_omg_participant_get_authentication(const struct participant *pp) { if (pp && pp->e.gv->security_context && q_omg_is_security_loaded(pp->e.gv->security_context)) @@ -291,6 +298,13 @@ struct dds_security_authentication *q_omg_participant_get_authentication(const s return NULL; } +struct dds_security_cryptography *q_omg_participant_get_cryptography(const struct participant *pp) +{ + if (pp && pp->e.gv->security_context && q_omg_is_security_loaded(pp->e.gv->security_context)) + return pp->e.gv->security_context->crypto_context; + return NULL; +} + static struct dds_security_context * q_omg_security_get_secure_context_from_proxypp(const struct proxy_participant *proxypp) { if (proxypp && proxypp->e.gv->security_context && q_omg_is_security_loaded(proxypp->e.gv->security_context)) @@ -705,13 +719,6 @@ get_first_matched_proxypp_crypto_handle(struct participant_sec_attributes *attr) return handle; } -struct dds_security_cryptography *q_omg_participant_get_cryptography(const struct participant *pp) -{ - if (pp && pp->e.gv->security_context && q_omg_is_security_loaded(pp->e.gv->security_context)) - return pp->e.gv->security_context->crypto_context; - return NULL; -} - bool q_omg_is_security_loaded (dds_security_context *sc) { return (sc->crypto_context != NULL || sc->authentication_context != NULL || sc->access_control_context != NULL); diff --git a/src/security/core/tests/access_control.c b/src/security/core/tests/access_control.c index ea08591..19912ea 100644 --- a/src/security/core/tests/access_control.c +++ b/src/security/core/tests/access_control.c @@ -613,7 +613,7 @@ static void test_discovery_liveliness_protection(enum test_discovery_liveliness print_test_msg ("crypto handle for %s: %ld\n", builtin_wr_descr, secure_pub_wr_handle); CU_ASSERT_EQUAL_FATAL (exp_secure_pub_wr_handle, secure_pub_wr_handle != 0); - struct dds_security_cryptography_impl * crypto_context_pub = get_crypto_context (g_participant[0]); + struct dds_security_cryptography_impl * crypto_context_pub = get_cryptography_context (g_participant[0]); CU_ASSERT_FATAL (crypto_context_pub != NULL); struct crypto_encode_decode_data *log = get_encode_decode_log (crypto_context_pub, ENCODE_DATAWRITER_SUBMESSAGE, secure_pub_wr_handle); @@ -814,3 +814,46 @@ CU_Test(ddssec_access_control, readwrite_protection, .timeout=60) 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"); } } + + +CU_Test(ddssec_access_control, check_returns) +{ + char topic_name[100]; + create_topic_name ("ddssec_access_control_", g_topic_nr++, topic_name, sizeof (topic_name)); + + 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); + + char * grants[] = { + 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_rule = get_governance_topic_rule (NULL, true, true, true, true, PK_E, BPK_E); + char * gov_config = get_governance_config (false, true, PK_E, PK_E, PK_E, 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 []) { false, false }, + (const char *[]) { "init_test_access_control_check_returns", "init_test_access_control_wrapped" }, + (const char *[]) { "finalize_test_access_control_check_returns", "finalize_test_access_control_wrapped" }, + (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 }); + + dds_entity_t pub, sub, pub_tp, sub_tp, wr, rd; + rd_wr_init (g_participant[0], &pub, &pub_tp, &wr, g_participant[1], &sub, &sub_tp, &rd, topic_name); + sync_writer_to_readers (g_participant[0], wr, 1, DDS_SECS (1)); + sync_reader_to_writers (g_participant[1], rd, 1, DDS_SECS (1)); + + struct dds_security_access_control_impl * ac_context = get_access_control_context (g_participant[0]); + CU_ASSERT_FATAL (check_returns (ac_context)); + + access_control_fini (2, (void * []) { gov_config, gov_topic_rule, grants[0], grants[1], perm_config, ca, id1_subj, id2_subj, id1, id2 }, 10); +} diff --git a/src/security/core/tests/common/access_control_wrapper.c b/src/security/core/tests/common/access_control_wrapper.c index 327dae3..7a80087 100644 --- a/src/security/core/tests/common/access_control_wrapper.c +++ b/src/security/core/tests/common/access_control_wrapper.c @@ -12,6 +12,7 @@ #include #include #include "dds/dds.h" +#include "dds/ddsrt/circlist.h" #include "dds/ddsrt/heap.h" #include "dds/ddsrt/sync.h" #include "dds/ddsrt/string.h" @@ -27,7 +28,8 @@ enum ac_plugin_mode { PLUGIN_MODE_ALL_OK, PLUGIN_MODE_WRAPPED, PLUGIN_MODE_NOT_ALLOWED, - PLUGIN_MODE_MISSING_FUNC + PLUGIN_MODE_MISSING_FUNC, + PLUGIN_MODE_CHECK_RETURNS, }; enum ac_plugin_not_allowed { @@ -56,6 +58,12 @@ enum ac_plugin_not_allowed { #define NOT_ALLOWED_REMOTE_READER_RELAY_ONLY (1u << NOT_ALLOWED_ID_REMOTE_READER_RELAY_ONLY) #define NOT_ALLOWED_REMOTE_PERM (1u << NOT_ALLOWED_ID_REMOTE_PERM) +struct returns_log_data { + struct ddsrt_circlist_elem e; + void * obj; +}; + + /** * Implementation structure for storing encapsulated members of the instance * while giving only the interface definition to user @@ -65,8 +73,75 @@ struct dds_security_access_control_impl { dds_security_access_control *instance; enum ac_plugin_mode mode; uint32_t not_allowed_mask; + ddsrt_mutex_t returns_log_lock; + struct ddsrt_circlist returns_log; + bool invalid_return; }; + +static void init_returns_log(struct dds_security_access_control_impl *impl) +{ + ddsrt_mutex_init (&impl->returns_log_lock); + ddsrt_circlist_init (&impl->returns_log); +} + +static void fini_returns_log(struct dds_security_access_control_impl *impl) +{ + ddsrt_mutex_lock (&impl->returns_log_lock); + while (!ddsrt_circlist_isempty (&impl->returns_log)) + { + struct ddsrt_circlist_elem *list_elem = ddsrt_circlist_oldest (&impl->returns_log); + ddsrt_circlist_remove (&impl->returns_log, list_elem); + ddsrt_free (list_elem); + } + ddsrt_mutex_unlock (&impl->returns_log_lock); + ddsrt_mutex_destroy (&impl->returns_log_lock); +} + +static void register_return_obj (struct dds_security_access_control_impl * impl, void * obj) +{ + assert(impl->mode == PLUGIN_MODE_CHECK_RETURNS); + ddsrt_mutex_lock (&impl->returns_log_lock); + struct returns_log_data * attr_data = ddsrt_malloc (sizeof (*attr_data)); + attr_data->obj = obj; + ddsrt_circlist_append(&impl->returns_log, &attr_data->e); + printf("log obj %p\n", obj); + ddsrt_mutex_unlock (&impl->returns_log_lock); +} + +static void unregister_return_obj (struct dds_security_access_control_impl * impl, void * obj) +{ + assert(impl->mode == PLUGIN_MODE_CHECK_RETURNS); + ddsrt_mutex_lock (&impl->returns_log_lock); + struct ddsrt_circlist_elem *elem0 = ddsrt_circlist_oldest (&impl->returns_log), *elem = elem0; + while (elem != NULL) + { + struct returns_log_data *data = DDSRT_FROM_CIRCLIST (struct returns_log_data, e, elem); + if (data->obj == obj) + { + ddsrt_circlist_remove (&impl->returns_log, elem); + ddsrt_mutex_unlock (&impl->returns_log_lock); + ddsrt_free (elem); + printf("return obj %p\n", obj); + return; + } + elem = elem->next; + if (elem == elem0) + break; + } + impl->invalid_return = true; + ddsrt_mutex_unlock (&impl->returns_log_lock); +} + +bool check_returns (struct dds_security_access_control_impl * impl) +{ + assert(impl->mode == PLUGIN_MODE_CHECK_RETURNS); + ddsrt_mutex_lock (&impl->returns_log_lock); + bool result = impl->invalid_return || !ddsrt_circlist_isempty (&impl->returns_log); + ddsrt_mutex_unlock (&impl->returns_log_lock); + return result; +} + static DDS_Security_PermissionsHandle validate_local_permissions( dds_security_access_control *instance, const dds_security_authentication *auth_plugin, @@ -87,7 +162,13 @@ static DDS_Security_PermissionsHandle validate_local_permissions( } /* fall through */ case PLUGIN_MODE_WRAPPED: - return impl->instance->validate_local_permissions(impl->instance, auth_plugin, identity, domain_id, participant_qos, ex); + case PLUGIN_MODE_CHECK_RETURNS: + { + DDS_Security_PermissionsHandle handle = impl->instance->validate_local_permissions(impl->instance, auth_plugin, identity, domain_id, participant_qos, ex); + if (impl->mode == PLUGIN_MODE_CHECK_RETURNS) + register_return_obj (impl, (void *) handle); + return handle; + } default: return 1; @@ -115,8 +196,14 @@ static DDS_Security_PermissionsHandle validate_remote_permissions( } /* fall through */ case PLUGIN_MODE_WRAPPED: - return impl->instance->validate_remote_permissions(impl->instance, auth_plugin, local_identity_handle, remote_identity_handle, + case PLUGIN_MODE_CHECK_RETURNS: + { + DDS_Security_PermissionsHandle handle = impl->instance->validate_remote_permissions(impl->instance, auth_plugin, local_identity_handle, remote_identity_handle, remote_permissions_token, remote_credential_token, ex); + if (impl->mode == PLUGIN_MODE_CHECK_RETURNS) + register_return_obj (impl, (void *) handle); + return handle; + } default: return 0; @@ -142,6 +229,7 @@ static DDS_Security_boolean check_create_participant( } /* fall through */ case PLUGIN_MODE_WRAPPED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_create_participant(impl->instance, permissions_handle, domain_id, participant_qos, ex); default: @@ -174,6 +262,7 @@ static DDS_Security_boolean check_create_datawriter( } /* fall through */ case PLUGIN_MODE_WRAPPED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_create_datawriter(impl->instance, permissions_handle, domain_id, topic_name, writer_qos, partition, data_tag, ex); default: @@ -203,6 +292,7 @@ static DDS_Security_boolean check_create_datareader( } /* fall through */ case PLUGIN_MODE_WRAPPED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_create_datareader(impl->instance, permissions_handle, domain_id, topic_name, reader_qos, partition, data_tag, ex); default: @@ -230,6 +320,7 @@ static DDS_Security_boolean check_create_topic( } /* fall through */ case PLUGIN_MODE_WRAPPED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_create_topic(impl->instance, permissions_handle, domain_id, topic_name, qos, ex); default: @@ -249,6 +340,7 @@ static DDS_Security_boolean check_local_datawriter_register_instance( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_local_datawriter_register_instance(impl->instance, permissions_handle, writer, key, ex); default: @@ -268,6 +360,7 @@ static DDS_Security_boolean check_local_datawriter_dispose_instance( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_local_datawriter_dispose_instance(impl->instance, permissions_handle, writer, key, ex); default: @@ -294,6 +387,7 @@ static DDS_Security_boolean check_remote_participant( } /* fall through */ case PLUGIN_MODE_WRAPPED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_remote_participant(impl->instance, permissions_handle, domain_id, participant_data, ex); default: @@ -320,6 +414,7 @@ static DDS_Security_boolean check_remote_datawriter( } /* fall through */ case PLUGIN_MODE_WRAPPED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_remote_datawriter(impl->instance, permissions_handle, domain_id, publication_data, ex); default: @@ -350,6 +445,7 @@ static DDS_Security_boolean check_remote_datareader( } /* fall through */ case PLUGIN_MODE_WRAPPED: + case PLUGIN_MODE_CHECK_RETURNS: { bool ret; if ((ret = impl->instance->check_remote_datareader(impl->instance, permissions_handle, domain_id, subscription_data, relay_only, ex))) @@ -389,6 +485,7 @@ static DDS_Security_boolean check_remote_topic( } /* fall through */ case PLUGIN_MODE_WRAPPED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_remote_topic(impl->instance, permissions_handle, domain_id, topic_data, ex); default: @@ -409,6 +506,7 @@ static DDS_Security_boolean check_local_datawriter_match( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_local_datawriter_match(impl->instance, writer_permissions_handle, reader_permissions_handle, publication_data, subscription_data, ex); default: @@ -429,6 +527,7 @@ static DDS_Security_boolean check_local_datareader_match( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_local_datareader_match(impl->instance, reader_permissions_handle, writer_permissions_handle, subscription_data, publication_data, ex); default: @@ -450,6 +549,7 @@ static DDS_Security_boolean check_remote_datawriter_register_instance( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_remote_datawriter_register_instance(impl->instance, permissions_handle, reader, publication_handle, key, instance_handle, ex); default: @@ -470,6 +570,7 @@ static DDS_Security_boolean check_remote_datawriter_dispose_instance( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->check_remote_datawriter_dispose_instance(impl->instance, permissions_handle, reader, publication_handle, key, ex); default: @@ -486,6 +587,9 @@ static DDS_Security_boolean get_permissions_token( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + register_return_obj (impl, (void*) permissions_token); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->get_permissions_token(impl->instance, permissions_token, handle, ex); @@ -506,6 +610,9 @@ static DDS_Security_boolean get_permissions_credential_token( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + register_return_obj (impl, (void*) permissions_credential_token); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->get_permissions_credential_token(impl->instance, permissions_credential_token, handle, ex); @@ -525,6 +632,7 @@ static DDS_Security_boolean set_listener( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: + case PLUGIN_MODE_CHECK_RETURNS: return impl->instance->set_listener (impl->instance, listener, ex); default: @@ -540,6 +648,9 @@ static DDS_Security_boolean return_permissions_token( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + unregister_return_obj (impl, (void*) token); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->return_permissions_token (impl->instance, token, ex); @@ -558,6 +669,9 @@ static DDS_Security_boolean return_permissions_credential_token( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + unregister_return_obj (impl, (void*) permissions_credential_token); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->return_permissions_credential_token(impl->instance, permissions_credential_token, ex); @@ -576,6 +690,9 @@ static DDS_Security_boolean get_participant_sec_attributes( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + register_return_obj (impl, (void*) attributes); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->get_participant_sec_attributes(impl->instance, permissions_handle, attributes, ex); @@ -595,6 +712,9 @@ static DDS_Security_boolean get_topic_sec_attributes( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + register_return_obj (impl, (void*) attributes); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->get_topic_sec_attributes(impl->instance, permissions_handle, topic_name, attributes, ex); @@ -616,6 +736,9 @@ static DDS_Security_boolean get_datawriter_sec_attributes( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + register_return_obj (impl, (void*) attributes); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->get_datawriter_sec_attributes(impl->instance, permissions_handle, topic_name, partition, data_tag, attributes, ex); @@ -637,6 +760,9 @@ static DDS_Security_boolean get_datareader_sec_attributes( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + register_return_obj (impl, (void*) attributes); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->get_datareader_sec_attributes(impl->instance, permissions_handle, topic_name, partition, data_tag, attributes, ex); @@ -654,6 +780,9 @@ static DDS_Security_boolean return_participant_sec_attributes( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + unregister_return_obj (impl, (void*) attributes); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->return_participant_sec_attributes(impl->instance, attributes, ex); @@ -671,6 +800,9 @@ static DDS_Security_boolean return_topic_sec_attributes( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + unregister_return_obj (impl, (void*) attributes); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->return_topic_sec_attributes(impl->instance, attributes, ex); @@ -688,6 +820,9 @@ static DDS_Security_boolean return_datawriter_sec_attributes( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + unregister_return_obj (impl, (void*) attributes); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->return_datawriter_sec_attributes(impl->instance, attributes, ex); @@ -705,6 +840,9 @@ static DDS_Security_boolean return_datareader_sec_attributes( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + unregister_return_obj (impl, (void*) attributes); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->return_datareader_sec_attributes(impl->instance, attributes, ex); @@ -722,6 +860,9 @@ static DDS_Security_boolean return_permissions_handle( struct dds_security_access_control_impl *impl = (struct dds_security_access_control_impl *)instance; switch (impl->mode) { + case PLUGIN_MODE_CHECK_RETURNS: + unregister_return_obj (impl, (void*) permissions_handle); + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_NOT_ALLOWED: return impl->instance->return_permissions_handle(impl->instance, permissions_handle, ex); @@ -863,3 +1004,22 @@ int finalize_test_access_control_not_allowed(void *context) assert(impl->mode == PLUGIN_MODE_NOT_ALLOWED); return finalize_test_access_control_common(impl, true); } + +int init_test_access_control_check_returns(const char *argument, void **context, struct ddsi_domaingv *gv) +{ + struct dds_security_access_control_impl *impl = init_test_access_control_common(argument, true, gv); + if (!impl) + return DDS_SECURITY_FAILED; + impl->mode = PLUGIN_MODE_CHECK_RETURNS; + init_returns_log (impl); + *context = impl; + return DDS_SECURITY_SUCCESS; +} + +int finalize_test_access_control_check_returns(void *context) +{ + struct dds_security_access_control_impl* impl = (struct dds_security_access_control_impl*) context; + assert(impl->mode == PLUGIN_MODE_CHECK_RETURNS); + fini_returns_log (impl); + return finalize_test_access_control_common(impl, true); +} diff --git a/src/security/core/tests/common/access_control_wrapper.h b/src/security/core/tests/common/access_control_wrapper.h index 6f733fc..8dc0ecd 100644 --- a/src/security/core/tests/common/access_control_wrapper.h +++ b/src/security/core/tests/common/access_control_wrapper.h @@ -20,6 +20,10 @@ mode. This prefix is used to exclude built-in topics from being disallowed. */ #define AC_WRAPPER_TOPIC_PREFIX "ddssec_access_control_" +struct dds_security_access_control_impl; + +SECURITY_EXPORT bool check_returns (struct dds_security_access_control_impl * impl); + /* Init in all-ok mode: all functions return success without calling the actual plugin */ SECURITY_EXPORT int init_test_access_control_all_ok(const char *argument, void **context, struct ddsi_domaingv *gv); SECURITY_EXPORT int finalize_test_access_control_all_ok(void *context); @@ -49,4 +53,9 @@ INIT_NOT_ALLOWED_DECL(remote_permissions_not_allowed) SECURITY_EXPORT int finalize_test_access_control_not_allowed(void *context); +/* Init in attribute get and return logging mode */ +SECURITY_EXPORT int init_test_access_control_check_returns(const char *argument, void **context, struct ddsi_domaingv *gv); +SECURITY_EXPORT int finalize_test_access_control_check_returns(void *context); + + #endif /* SECURITY_CORE_TEST_ACCESS_CONTROL_WRAPPER_H_ */ diff --git a/src/security/core/tests/common/test_utils.c b/src/security/core/tests/common/test_utils.c index eff8f51..c17f1cd 100644 --- a/src/security/core/tests/common/test_utils.c +++ b/src/security/core/tests/common/test_utils.c @@ -495,23 +495,24 @@ void write_read_for(dds_entity_t wr, dds_entity_t pp_rd, dds_entity_t rd, dds_du CU_ASSERT_EQUAL_FATAL (read_fail, exp_read_fail); } -struct dds_security_cryptography_impl * get_crypto_context(dds_entity_t participant) -{ - struct dds_entity *pp_entity = NULL; - struct participant *pp; - struct dds_security_cryptography_impl *context; - dds_return_t ret; +#define GET_SECURITY_PLUGIN_CONTEXT(name_) \ + struct dds_security_##name_##_impl * get_##name_##_context(dds_entity_t participant) \ + { \ + struct dds_entity *pp_entity = NULL; \ + dds_return_t ret = dds_entity_lock (participant, DDS_KIND_PARTICIPANT, &pp_entity); \ + CU_ASSERT_EQUAL_FATAL (ret, 0); \ + thread_state_awake (lookup_thread_state(), &pp_entity->m_domain->gv); \ + struct participant *pp = entidx_lookup_participant_guid (pp_entity->m_domain->gv.entity_index, &pp_entity->m_guid); \ + CU_ASSERT_FATAL (pp != NULL); \ + struct dds_security_##name_##_impl *context = (struct dds_security_##name_##_impl *) q_omg_participant_get_##name_ (pp); \ + thread_state_asleep (lookup_thread_state ()); \ + dds_entity_unlock (pp_entity); \ + return context; \ + } - ret = dds_entity_lock (participant, DDS_KIND_PARTICIPANT, &pp_entity); - CU_ASSERT_EQUAL_FATAL (ret, 0); - thread_state_awake (lookup_thread_state(), &pp_entity->m_domain->gv); - pp = entidx_lookup_participant_guid (pp_entity->m_domain->gv.entity_index, &pp_entity->m_guid); - CU_ASSERT_FATAL (pp != NULL); - context = (struct dds_security_cryptography_impl *) q_omg_participant_get_cryptography (pp); - thread_state_asleep (lookup_thread_state ()); - dds_entity_unlock (pp_entity); - return context; -} +GET_SECURITY_PLUGIN_CONTEXT(access_control) +GET_SECURITY_PLUGIN_CONTEXT(authentication) +GET_SECURITY_PLUGIN_CONTEXT(cryptography) const char * pk_to_str(DDS_Security_ProtectionKind pk) { diff --git a/src/security/core/tests/common/test_utils.h b/src/security/core/tests/common/test_utils.h index 7fe1487..8b930c3 100644 --- a/src/security/core/tests/common/test_utils.h +++ b/src/security/core/tests/common/test_utils.h @@ -82,10 +82,16 @@ void rd_wr_init_fail ( bool exp_pubtp_fail, bool exp_wr_fail, bool exp_subtp_fail, bool exp_rd_fail); 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); -struct dds_security_cryptography_impl * get_crypto_context (dds_entity_t participant); const char * pk_to_str (DDS_Security_ProtectionKind pk); const char * bpk_to_str (DDS_Security_BasicProtectionKind bpk); DDS_Security_DatawriterCryptoHandle get_builtin_writer_crypto_handle(dds_entity_t participant, unsigned entityid); DDS_Security_DatawriterCryptoHandle get_writer_crypto_handle(dds_entity_t writer); +#define GET_SECURITY_PLUGIN_CONTEXT_DECL(name_) \ + struct dds_security_##name_##_impl * get_##name_##_context(dds_entity_t participant); +GET_SECURITY_PLUGIN_CONTEXT_DECL(access_control) +GET_SECURITY_PLUGIN_CONTEXT_DECL(authentication) +GET_SECURITY_PLUGIN_CONTEXT_DECL(cryptography) + + #endif /* SECURITY_CORE_TEST_UTILS_H_ */ diff --git a/src/security/core/tests/crypto.c b/src/security/core/tests/crypto.c index 098b0d7..ca41f2f 100644 --- a/src/security/core/tests/crypto.c +++ b/src/security/core/tests/crypto.c @@ -156,7 +156,7 @@ CU_Theory((const char * test_descr, DDS_Security_BasicProtectionKind payload_pk, /* set forced plain data for payload/submsg/rtps */ DDS_Security_DatawriterCryptoHandle wr_handle = get_writer_crypto_handle (wr); - struct dds_security_cryptography_impl * crypto_impl = get_crypto_context (g_participant1); + struct dds_security_cryptography_impl * crypto_impl = get_cryptography_context (g_participant1); set_force_plain_data (crypto_impl, wr_handle, rtps_pk != PK_N, submsg_pk != PK_N, payload_pk != BPK_N); /* sync and write/take sample */ diff --git a/src/security/core/tests/handshake.c b/src/security/core/tests/handshake.c index 26d6d9a..0891d34 100644 --- a/src/security/core/tests/handshake.c +++ b/src/security/core/tests/handshake.c @@ -143,11 +143,11 @@ CU_Test(ddssec_handshake, check_tokens) write_read_for (g_wr, g_participant2, g_rd, DDS_MSECS (100), false, false); // Get subscriber and publisher crypto tokens - struct dds_security_cryptography_impl * crypto_context_pub = get_crypto_context (g_participant1); + struct dds_security_cryptography_impl * crypto_context_pub = get_cryptography_context (g_participant1); CU_ASSERT_FATAL (crypto_context_pub != NULL); struct ddsrt_circlist *pub_tokens = get_crypto_tokens (crypto_context_pub); - struct dds_security_cryptography_impl * crypto_context_sub = get_crypto_context (g_participant2); + struct dds_security_cryptography_impl * crypto_context_sub = get_cryptography_context (g_participant2); CU_ASSERT_FATAL (crypto_context_sub != NULL); struct ddsrt_circlist *sub_tokens = get_crypto_tokens (crypto_context_sub); diff --git a/src/security/core/tests/secure_communication.c b/src/security/core/tests/secure_communication.c index 94f8c13..52dd62d 100644 --- a/src/security/core/tests/secure_communication.c +++ b/src/security/core/tests/secure_communication.c @@ -119,7 +119,7 @@ static dds_entity_t create_pp (dds_domainid_t domain_id, const struct domain_sec dds_entity_t pp = dds_create_participant (domain_id, qos, NULL); CU_ASSERT_FATAL (pp > 0); dds_delete_qos (qos); - struct dds_security_cryptography_impl * crypto_context = get_crypto_context (pp); + struct dds_security_cryptography_impl * crypto_context = get_cryptography_context (pp); CU_ASSERT_FATAL (crypto_context != NULL); assert (set_crypto_params); set_crypto_params (crypto_context, domain_config);