diff --git a/rmw_connext_cpp/src/rmw_init.cpp b/rmw_connext_cpp/src/rmw_init.cpp index 12d239b5..9e83ca6d 100644 --- a/rmw_connext_cpp/src/rmw_init.cpp +++ b/rmw_connext_cpp/src/rmw_init.cpp @@ -14,6 +14,8 @@ #include "rmw/init.h" +#include "rcutils/strdup.h" + #include "rmw/impl/cpp/macros.hpp" #include "rmw_connext_shared_cpp/init.hpp" @@ -34,6 +36,10 @@ rmw_init_options_init(rmw_init_options_t * init_options, rcutils_allocator_t all init_options->implementation_identifier = rti_connext_identifier; init_options->allocator = allocator; init_options->impl = nullptr; + init_options->security_options = rmw_get_zero_initialized_security_options(); + init_options->domain_id = RMW_DEFAULT_DOMAIN_ID; + init_options->localhost_only = RMW_LOCALHOST_ONLY_DEFAULT; + init_options->security_context = NULL; return RMW_RET_OK; } @@ -51,20 +57,38 @@ rmw_init_options_copy(const rmw_init_options_t * src, rmw_init_options_t * dst) RMW_SET_ERROR_MSG("expected zero-initialized dst"); return RMW_RET_INVALID_ARGUMENT; } + const rcutils_allocator_t * allocator = &src->allocator; + rmw_ret_t ret = RMW_RET_OK; + + allocator->deallocate(dst->security_context, allocator->state); *dst = *src; - return RMW_RET_OK; + dst->security_context = NULL; + dst->security_options = rmw_get_zero_initialized_security_options(); + + dst->security_context = rcutils_strdup(src->security_context, *allocator); + if (src->security_context && !dst->security_context) { + ret = RMW_RET_BAD_ALLOC; + goto fail; + } + return rmw_security_options_copy(&src->security_options, allocator, &dst->security_options); +fail: + allocator->deallocate(dst->security_context, allocator->state); + return ret; } rmw_ret_t rmw_init_options_fini(rmw_init_options_t * init_options) { RMW_CHECK_ARGUMENT_FOR_NULL(init_options, RMW_RET_INVALID_ARGUMENT); - RCUTILS_CHECK_ALLOCATOR(&(init_options->allocator), return RMW_RET_INVALID_ARGUMENT); + rcutils_allocator_t & allocator = init_options->allocator; + RCUTILS_CHECK_ALLOCATOR(&allocator, return RMW_RET_INVALID_ARGUMENT); RMW_CHECK_TYPE_IDENTIFIERS_MATCH( init_options, init_options->implementation_identifier, rti_connext_identifier, return RMW_RET_INCORRECT_RMW_IMPLEMENTATION); + allocator.deallocate(init_options->security_context, allocator.state); + rmw_security_options_fini(&init_options->security_options, &allocator); *init_options = rmw_get_zero_initialized_init_options(); return RMW_RET_OK; } @@ -82,6 +106,10 @@ rmw_init(const rmw_init_options_t * options, rmw_context_t * context) context->instance_id = options->instance_id; context->implementation_identifier = rti_connext_identifier; context->impl = nullptr; + rmw_ret_t ret = rmw_init_options_copy(options, &context->options); + if (RMW_RET_OK != ret) { + return ret; + } return init(); } diff --git a/rmw_connext_cpp/src/rmw_node.cpp b/rmw_connext_cpp/src/rmw_node.cpp index ad57f633..b1c39048 100644 --- a/rmw_connext_cpp/src/rmw_node.cpp +++ b/rmw_connext_cpp/src/rmw_node.cpp @@ -28,12 +28,10 @@ rmw_create_node( const char * name, const char * namespace_, size_t domain_id, - const rmw_node_security_options_t * security_options, bool localhost_only) { return create_node( - rti_connext_identifier, context, name, namespace_, domain_id, security_options, - localhost_only); + rti_connext_identifier, context, name, namespace_, domain_id, localhost_only); } rmw_ret_t diff --git a/rmw_connext_cpp/src/rmw_node_names.cpp b/rmw_connext_cpp/src/rmw_node_names.cpp index 3226619f..eefef8dc 100644 --- a/rmw_connext_cpp/src/rmw_node_names.cpp +++ b/rmw_connext_cpp/src/rmw_node_names.cpp @@ -30,4 +30,15 @@ rmw_get_node_names( { return get_node_names(rti_connext_identifier, node, node_names, node_namespaces); } + +rmw_ret_t +rmw_get_node_names_with_security_contexts( + const rmw_node_t * node, + rcutils_string_array_t * node_names, + rcutils_string_array_t * node_namespaces, + rcutils_string_array_t * security_contexts) +{ + return get_node_names_with_security_contexts( + rti_connext_identifier, node, node_names, node_namespaces, security_contexts); +} } // extern "C" diff --git a/rmw_connext_dynamic_cpp/src/functions.cpp b/rmw_connext_dynamic_cpp/src/functions.cpp index 200eb308..33524f90 100644 --- a/rmw_connext_dynamic_cpp/src/functions.cpp +++ b/rmw_connext_dynamic_cpp/src/functions.cpp @@ -301,7 +301,7 @@ rmw_create_node( const char * name, const char * namespace_, size_t domain_id, - const rmw_node_security_options_t * security_options, + const rmw_security_options_t * security_options, bool localhost_only) { return create_node( diff --git a/rmw_connext_shared_cpp/include/rmw_connext_shared_cpp/node.hpp b/rmw_connext_shared_cpp/include/rmw_connext_shared_cpp/node.hpp index 4f953995..f29b6415 100644 --- a/rmw_connext_shared_cpp/include/rmw_connext_shared_cpp/node.hpp +++ b/rmw_connext_shared_cpp/include/rmw_connext_shared_cpp/node.hpp @@ -27,7 +27,6 @@ create_node( const char * name, const char * namespace_, size_t domain_id, - const rmw_node_security_options_t * options, bool localhost_only); RMW_CONNEXT_SHARED_CPP_PUBLIC diff --git a/rmw_connext_shared_cpp/include/rmw_connext_shared_cpp/node_names.hpp b/rmw_connext_shared_cpp/include/rmw_connext_shared_cpp/node_names.hpp index 8c2f5516..dc42d3c7 100644 --- a/rmw_connext_shared_cpp/include/rmw_connext_shared_cpp/node_names.hpp +++ b/rmw_connext_shared_cpp/include/rmw_connext_shared_cpp/node_names.hpp @@ -28,6 +28,15 @@ get_node_names( rcutils_string_array_t * node_names, rcutils_string_array_t * node_namespaces); +RMW_CONNEXT_SHARED_CPP_PUBLIC +rmw_ret_t +get_node_names_with_security_contexts( + const char * implementation_identifier, + const rmw_node_t * node, + rcutils_string_array_t * node_names, + rcutils_string_array_t * node_namespaces, + rcutils_string_array_t * security_contexts); + RMW_CONNEXT_SHARED_CPP_PUBLIC rmw_ret_t count_publishers( diff --git a/rmw_connext_shared_cpp/src/node.cpp b/rmw_connext_shared_cpp/src/node.cpp index a5e6dcda..87d4167f 100644 --- a/rmw_connext_shared_cpp/src/node.cpp +++ b/rmw_connext_shared_cpp/src/node.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include "rcutils/filesystem.h" @@ -32,7 +33,6 @@ create_node( const char * name, const char * namespace_, size_t domain_id, - const rmw_node_security_options_t * security_options, bool localhost_only) { RCUTILS_CHECK_ARGUMENT_FOR_NULL(context, NULL); @@ -42,10 +42,6 @@ create_node( implementation_identifier, // TODO(wjwwood): replace this with RMW_RET_INCORRECT_RMW_IMPLEMENTATION when refactored return NULL); - if (!security_options) { - RMW_SET_ERROR_MSG("security_options is null"); - return nullptr; - } DDS::DomainParticipantFactory * dpf_ = DDS::DomainParticipantFactory::get_instance(); if (!dpf_) { RMW_SET_ERROR_MSG("failed to get participant factory"); @@ -77,17 +73,22 @@ create_node( participant_qos.participant_name.name = DDS::String_dup(name); // since the participant name is not part of the DDS spec // the node name is also set in the user_data - size_t length = strlen(name) + strlen("name=;") + - strlen(namespace_) + strlen("namespace=;") + 1; + size_t length = std::snprintf( + nullptr, + 0, + "name=%s;namespace=%s;securitycontext=%s;", + name, namespace_, context->options.security_context) + 1; bool success = participant_qos.user_data.value.length(static_cast(length)); if (!success) { RMW_SET_ERROR_MSG("failed to resize participant user_data"); return NULL; } - int written = snprintf( + int written = std::snprintf( reinterpret_cast(participant_qos.user_data.value.get_contiguous_buffer()), - length, "name=%s;namespace=%s;", name, namespace_); + length, + "name=%s;namespace=%s;securitycontext=%s;", + name, namespace_, context->options.security_context); if (written < 0 || written > static_cast(length) - 1) { RMW_SET_ERROR_MSG("failed to populate user_data buffer"); return NULL; @@ -153,7 +154,7 @@ create_node( char * gov_fn = nullptr; char * perm_fn = nullptr; - if (security_options->security_root_path) { + if (context->options.security_options.security_root_path) { // enable some security stuff status = DDS::PropertyQosPolicyHelper::add_property( participant_qos.property, @@ -183,7 +184,7 @@ create_node( return NULL; } - srp = security_options->security_root_path; // save some typing + srp = context->options.security_options.security_root_path; // save some typing identity_ca_cert_fn = rcutils_join_path(srp, "identity_ca.cert.pem", allocator); if (!identity_ca_cert_fn) { RMW_SET_ERROR_MSG("failed to allocate memory for 'identity_ca_cert_fn'"); @@ -374,6 +375,7 @@ create_node( node_handle->implementation_identifier = implementation_identifier; node_handle->data = node_info; + node_handle->context = context; return node_handle; fail: status = dpf_->delete_participant(participant); diff --git a/rmw_connext_shared_cpp/src/node_names.cpp b/rmw_connext_shared_cpp/src/node_names.cpp index 3ba06e75..ffd364f9 100644 --- a/rmw_connext_shared_cpp/src/node_names.cpp +++ b/rmw_connext_shared_cpp/src/node_names.cpp @@ -28,11 +28,12 @@ #include "rmw_connext_shared_cpp/types.hpp" rmw_ret_t -get_node_names( +get_node_names_impl( const char * implementation_identifier, const rmw_node_t * node, rcutils_string_array_t * node_names, - rcutils_string_array_t * node_namespaces) + rcutils_string_array_t * node_namespaces, + rcutils_string_array_t * security_contexts) { if (!node) { RMW_SET_ERROR_MSG("node handle is null"); @@ -45,6 +46,9 @@ get_node_names( if (rmw_check_zero_rmw_string_array(node_names) != RMW_RET_OK) { return RMW_RET_ERROR; } + if (rmw_check_zero_rmw_string_array(node_namespaces) != RMW_RET_OK) { + return RMW_RET_ERROR; + } DDS::DomainParticipant * participant = static_cast(node->data)->participant; DDS::InstanceHandleSeq handles; @@ -73,6 +77,7 @@ get_node_names( // Such names should not be returned rcutils_string_array_t tmp_names_list = rcutils_get_zero_initialized_string_array(); rcutils_string_array_t tmp_namespaces_list = rcutils_get_zero_initialized_string_array(); + rcutils_string_array_t tmp_security_contexts_list = rcutils_get_zero_initialized_string_array(); int named_nodes_num = 1; @@ -92,6 +97,16 @@ get_node_names( goto cleanup; } + if (security_contexts) { + rcutils_ret = rcutils_string_array_init(&tmp_security_contexts_list, length, &allocator); + + if (rcutils_ret != RCUTILS_RET_OK) { + RMW_SET_ERROR_MSG(rcutils_get_error_string().str); + final_ret = rmw_convert_rcutils_ret_to_rmw_ret(rcutils_ret); + goto cleanup; + } + } + // add yourself tmp_names_list.data[0] = rcutils_strdup(participant_qos.participant_name.name, allocator); if (!tmp_names_list.data[0]) { @@ -105,12 +120,22 @@ get_node_names( final_ret = rmw_convert_rcutils_ret_to_rmw_ret(rcutils_ret); goto cleanup; } + if (security_contexts) { + tmp_security_contexts_list.data[0] = rcutils_strdup( + node->context->options.security_context, allocator); + if (!tmp_namespaces_list.data[0]) { + RMW_SET_ERROR_MSG("could not allocate memory for a security context name"); + final_ret = rmw_convert_rcutils_ret_to_rmw_ret(rcutils_ret); + goto cleanup; + } + } for (auto i = 1; i < length; ++i) { DDS::ParticipantBuiltinTopicData pbtd; auto dds_ret = participant->get_discovered_participant_data(pbtd, handles[i - 1]); std::string name; std::string namespace_; + std::string security_context; if (DDS::RETCODE_OK == dds_ret) { auto data = static_cast(pbtd.user_data.value.get_contiguous_buffer()); std::vector kv(data, data + pbtd.user_data.value.length()); @@ -119,6 +144,7 @@ get_node_names( auto name_found = map.find("name"); auto ns_found = map.find("namespace"); + auto security_context_found = map.find("securitycontext"); if (name_found != map.end()) { name = std::string(name_found->second.begin(), name_found->second.end()); @@ -127,6 +153,11 @@ get_node_names( if (ns_found != map.end()) { namespace_ = std::string(ns_found->second.begin(), ns_found->second.end()); } + + if (security_context_found != map.end()) { + security_context = std::string( + security_context_found->second.begin(), security_context_found->second.end()); + } } // ignore discovered participants without a name @@ -150,6 +181,16 @@ get_node_names( goto cleanup; } + if (security_contexts) { + tmp_security_contexts_list.data[named_nodes_num] = rcutils_strdup( + security_context.c_str(), allocator); + if (!tmp_security_contexts_list.data[named_nodes_num]) { + RMW_SET_ERROR_MSG("could not allocate memory for a node's namespace"); + final_ret = rmw_convert_rcutils_ret_to_rmw_ret(rcutils_ret); + goto cleanup; + } + } + ++named_nodes_num; } @@ -169,9 +210,22 @@ get_node_names( goto cleanup; } + if (security_contexts) { + rcutils_ret = rcutils_string_array_init(security_contexts, named_nodes_num, &allocator); + + if (rcutils_ret != RCUTILS_RET_OK) { + RMW_SET_ERROR_MSG("could not allocate memory for node_namespaces output"); + final_ret = rmw_convert_rcutils_ret_to_rmw_ret(rcutils_ret); + goto cleanup; + } + } + for (auto i = 0; i < named_nodes_num; ++i) { node_names->data[i] = rcutils_strdup(tmp_names_list.data[i], allocator); node_namespaces->data[i] = rcutils_strdup(tmp_namespaces_list.data[i], allocator); + if (security_contexts) { + security_contexts->data[i] = rcutils_strdup(tmp_security_contexts_list.data[i], allocator); + } } rcutils_ret = rcutils_string_array_fini(&tmp_names_list); @@ -212,6 +266,17 @@ get_node_names( } } + if (security_contexts) { + rcutils_ret = rcutils_string_array_fini(security_contexts); + if (rcutils_ret != RCUTILS_RET_OK) { + RCUTILS_LOG_ERROR_NAMED( + "rmw_connext_cpp", + "failed to cleanup during error handling: %s", rcutils_get_error_string().str + ); + rcutils_reset_error(); + } + } + rcutils_ret = rcutils_string_array_fini(&tmp_names_list); if (rcutils_ret != RCUTILS_RET_OK) { RCUTILS_LOG_ERROR_NAMED( @@ -230,5 +295,39 @@ get_node_names( rcutils_reset_error(); } + rcutils_ret = rcutils_string_array_fini(&tmp_security_contexts_list); + if (rcutils_ret != RCUTILS_RET_OK) { + RCUTILS_LOG_ERROR_NAMED( + "rmw_connext_cpp", + "failed to cleanup during error handling: %s", rcutils_get_error_string().str + ); + rcutils_reset_error(); + } + return final_ret; } + +rmw_ret_t +get_node_names( + const char * implementation_identifier, + const rmw_node_t * node, + rcutils_string_array_t * node_names, + rcutils_string_array_t * node_namespaces) +{ + return get_node_names_impl(implementation_identifier, node, node_names, node_namespaces, nullptr); +} + +rmw_ret_t +get_node_names_with_security_contexts( + const char * implementation_identifier, + const rmw_node_t * node, + rcutils_string_array_t * node_names, + rcutils_string_array_t * node_namespaces, + rcutils_string_array_t * security_contexts) +{ + if (rmw_check_zero_rmw_string_array(security_contexts) != RMW_RET_OK) { + return RMW_RET_ERROR; + } + return get_node_names_impl( + implementation_identifier, node, node_names, node_namespaces, security_contexts); +}