diff --git a/src/core/ddsc/tests/lifespan.c b/src/core/ddsc/tests/lifespan.c index 7190a71..fea4079 100644 --- a/src/core/ddsc/tests/lifespan.c +++ b/src/core/ddsc/tests/lifespan.c @@ -161,4 +161,4 @@ CU_Test(ddsc_lifespan, basic, .init=lifespan_init, .fini=lifespan_fini) check_whc_state(g_writer, -1, -1); dds_delete_qos(qos); -} \ No newline at end of file +} 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 db0514e..220c29b 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h @@ -181,7 +181,7 @@ is_proxy_participant_deletion_allowed( */ bool q_omg_security_is_remote_rtps_protected( - struct proxy_participant *proxy_pp, + const struct proxy_participant *proxy_pp, ddsi_entityid_t entityid); /** @@ -197,7 +197,7 @@ q_omg_security_is_remote_rtps_protected( */ bool q_omg_security_is_local_rtps_protected( - struct participant *pp, + const struct participant *pp, ddsi_entityid_t entityid); /** @@ -256,10 +256,10 @@ q_omg_security_encode_rtps_message( int64_t src_handle, ddsi_guid_t *src_guid, const unsigned char *src_buf, - const unsigned int src_len, - unsigned char **dst_buf, - unsigned int *dst_len, - int64_t dst_handle); + size_t src_len, + unsigned char **dst_buf, + size_t *dst_len, + int64_t dst_handle); /** * @brief Encode payload when necessary. @@ -406,8 +406,8 @@ bool validate_msg_decoding( const struct entity_common *e, const struct proxy_endpoint_common *c, - struct proxy_participant *proxypp, - struct receiver_state *rst, + const struct proxy_participant *proxypp, + const struct receiver_state *rst, SubmessageKind_t prev_smid); /** @@ -426,13 +426,13 @@ validate_msg_decoding( * @param[in] dst_prefix Prefix of the destination entity. * @param[in] byteswap Do the bytes need swapping? * - * @returns int - * @retval >= 0 Decoding succeeded. - * @retval < 0 Decoding failed. + * @returns bool + * @retval true Decoding succeeded. + * @retval false Decoding failed. */ -int +bool decode_SecPrefix( - struct receiver_state *rst, + const struct receiver_state *rst, unsigned char *submsg, size_t submsg_size, unsigned char * const msg_end, @@ -500,7 +500,7 @@ secure_conn_write( bool dst_one, nn_msg_sec_info_t *sec_info, ddsi_tran_write_fn_t conn_write_cb); - + /** * @brief Loads the security plugins with the given configuration. @@ -518,12 +518,12 @@ secure_conn_write( dds_return_t q_omg_security_load( struct dds_security_context *security_context, const dds_qos_t *qos ); -void q_omg_security_init( struct dds_security_context **sc); +void q_omg_security_init( struct dds_security_context **sc, const struct ddsrt_log_cfg *logcfg); void q_omg_security_deinit( struct dds_security_context **sc); bool q_omg_is_security_loaded( struct dds_security_context *sc ); - + /** * @brief Check if the participant and the proxy participant diff --git a/src/core/ddsi/include/dds/ddsi/q_globals.h b/src/core/ddsi/include/dds/ddsi/q_globals.h index 4d12f96..e261652 100644 --- a/src/core/ddsi/include/dds/ddsi/q_globals.h +++ b/src/core/ddsi/include/dds/ddsi/q_globals.h @@ -302,7 +302,6 @@ struct q_globals { #ifdef DDSI_INCLUDE_SECURITY struct dds_security_context *security_context; #endif - }; #if defined (__cplusplus) diff --git a/src/core/ddsi/src/ddsi_security_omg.c b/src/core/ddsi/src/ddsi_security_omg.c index 0759f73..c08b649 100644 --- a/src/core/ddsi/src/ddsi_security_omg.c +++ b/src/core/ddsi/src/ddsi_security_omg.c @@ -36,8 +36,6 @@ #include "dds/ddsi/q_xevent.h" #include "dds/ddsi/q_plist.h" - - #define AUTH_NAME "Authentication" #define AC_NAME "Access Control" #define CRYPTO_NAME "Cryptographic" @@ -54,49 +52,45 @@ struct dds_security_context { dds_security_access_control *access_control_context; ddsrt_mutex_t omg_security_lock; uint32_t next_plugin_id; + + const struct ddsrt_log_cfg *logcfg; }; typedef struct dds_security_context dds_security_context; +static bool q_omg_writer_is_payload_protected (const struct writer *wr); -static bool -q_omg_writer_is_payload_protected( - const struct writer *wr); - - - - -static bool endpoint_is_DCPSParticipantSecure(const ddsi_guid_t *guid) +static bool endpoint_is_DCPSParticipantSecure (const ddsi_guid_t *guid) { return ((guid->entityid.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER) || - (guid->entityid.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER) ); + (guid->entityid.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER)); } -static bool endpoint_is_DCPSPublicationsSecure(const ddsi_guid_t *guid) +static bool endpoint_is_DCPSPublicationsSecure (const ddsi_guid_t *guid) { return ((guid->entityid.u == NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER) || - (guid->entityid.u == NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER) ); + (guid->entityid.u == NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER)); } -static bool endpoint_is_DCPSSubscriptionsSecure(const ddsi_guid_t *guid) +static bool endpoint_is_DCPSSubscriptionsSecure (const ddsi_guid_t *guid) { return ((guid->entityid.u == NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER) || - (guid->entityid.u == NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER) ); + (guid->entityid.u == NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER)); } -static bool endpoint_is_DCPSParticipantStatelessMessage(const ddsi_guid_t *guid) +static bool endpoint_is_DCPSParticipantStatelessMessage (const ddsi_guid_t *guid) { return ((guid->entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER) || - (guid->entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER) ); + (guid->entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER)); } -static bool endpoint_is_DCPSParticipantMessageSecure(const ddsi_guid_t *guid) +static bool endpoint_is_DCPSParticipantMessageSecure (const ddsi_guid_t *guid) { return ((guid->entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER) || - (guid->entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER) ); + (guid->entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER)); } -static bool endpoint_is_DCPSParticipantVolatileMessageSecure(const ddsi_guid_t *guid) +static bool endpoint_is_DCPSParticipantVolatileMessageSecure (const ddsi_guid_t *guid) { #if 1 /* TODO: volatile endpoint. */ @@ -104,266 +98,227 @@ static bool endpoint_is_DCPSParticipantVolatileMessageSecure(const ddsi_guid_t * return false; #else return ((guid->entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER) || - (guid->entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER) ); + (guid->entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER)); #endif } -bool q_omg_is_security_loaded( dds_security_context *sc ){ - if( sc->crypto_context == NULL && sc->authentication_context == NULL && sc->access_control_context == NULL){ - return false; - } else { - return true; - } -} - -void q_omg_security_init( dds_security_context **sc ) +bool q_omg_is_security_loaded (dds_security_context *sc) { - - - *sc = ddsrt_malloc( sizeof( dds_security_context)); - memset( *sc, 0, sizeof( dds_security_context)); - //if( participant_reference_count == 0 ){ - - (*sc)->auth_plugin.name = AUTH_NAME; - (*sc)->ac_plugin.name = AC_NAME; - (*sc)->crypto_plugin.name = CRYPTO_NAME; - - (void)ddsrt_mutex_init(&(*sc)->omg_security_lock); - DDS_LOG(DDS_LC_TRACE,"DDS Security init\n"); -#if HANDSHAKE_IMPLEMENTED - //remote_participant_crypto_handle_list_init(); -#endif - //} - - //participant_reference_count++; + return (sc->crypto_context != NULL || sc->authentication_context != NULL || sc->access_control_context != NULL); } +void q_omg_security_init (dds_security_context **sc, const struct ddsrt_log_cfg *logcfg) +{ + *sc = ddsrt_malloc (sizeof (dds_security_context)); + memset (*sc, 0, sizeof (dds_security_context)); + (*sc)->auth_plugin.name = AUTH_NAME; + (*sc)->ac_plugin.name = AC_NAME; + (*sc)->crypto_plugin.name = CRYPTO_NAME; + + ddsrt_mutex_init (&(*sc)->omg_security_lock); + (*sc)->logcfg = logcfg; + + //DDS_CTRACE ((*sc)->logcfg, "DDS Security init\n"); +#if HANDSHAKE_IMPLEMENTED + //remote_participant_crypto_handle_list_init(); +#endif +} /** * Releases all plugins */ -static void release_plugins( dds_security_context *security_context ) +static void release_plugins (dds_security_context *sc) { #if HANDSHAKE_IMPLEMENTED - q_handshake_terminate(); + q_handshake_terminate (); #endif + if (dds_security_plugin_release (&sc->auth_plugin, sc->authentication_context)) + DDS_CERROR (sc->logcfg, "Error occured releasing %s plugin", sc->auth_plugin.name); - if (dds_security_plugin_release( &security_context->auth_plugin, security_context->authentication_context )) { - DDS_ERROR("Error occured releasing %s plugin", security_context->auth_plugin.name); - } + if (dds_security_plugin_release (&sc->crypto_plugin, sc->crypto_context)) + DDS_CERROR (sc->logcfg, "Error occured releasing %s plugin", sc->crypto_plugin.name); - if (dds_security_plugin_release( &security_context->crypto_plugin, security_context->crypto_context )) { - DDS_ERROR("Error occured releasing %s plugin", security_context->crypto_plugin.name); - } + if (dds_security_plugin_release (&sc->ac_plugin, sc->access_control_context)) + DDS_CERROR (sc->logcfg, "Error occured releasing %s plugin", sc->ac_plugin.name); - if (dds_security_plugin_release( &security_context->ac_plugin, security_context->access_control_context )) { - DDS_ERROR("Error occured releasing %s plugin", security_context->ac_plugin.name); - } - - security_context->authentication_context = NULL; - security_context->access_control_context = NULL; - security_context->crypto_context = NULL; + sc->authentication_context = NULL; + sc->access_control_context = NULL; + sc->crypto_context = NULL; } - -void q_omg_security_deinit( struct dds_security_context **security_context) { - - assert( security_context != NULL ); - assert( *security_context != NULL ); +void q_omg_security_deinit (struct dds_security_context **sc) +{ + assert (sc != NULL); + assert (*sc != NULL); #if HANDSHAKE_IMPLEMENTED - //remote_participant_crypto_handle_list_deinit(); + //remote_participant_crypto_handle_list_deinit(); #endif - if( (*security_context)->authentication_context != NULL && (*security_context)->access_control_context != NULL && (*security_context)->crypto_context != NULL ){ - release_plugins( *security_context ); - } - ddsrt_mutex_destroy(&(*security_context)->omg_security_lock); - ddsrt_free( *security_context ); - *security_context = NULL; - - DDS_LOG(DDS_LC_TRACE,"DDS Security deinit\n"); -} - - - -static void -dds_qos_to_security_plugin_configuration( - const dds_qos_t *qos, - dds_security_plugin_suite_config *suite_config) -{ - uint32_t i; - -#define CHECK_SECURITY_PROPERTY( security_property, target ) \ - if(strcmp (qos->property.value.props[i].name, security_property) == 0){ \ - target = ddsrt_strdup( qos->property.value.props[i].value ); \ - } - - for (i = 0; i < qos->property.value.n; i++) { - CHECK_SECURITY_PROPERTY( DDS_SEC_PROP_AUTH_LIBRARY_PATH, suite_config->authentication.library_path ) - else CHECK_SECURITY_PROPERTY( DDS_SEC_PROP_AUTH_LIBRARY_INIT, suite_config->authentication.library_init ) - else CHECK_SECURITY_PROPERTY( DDS_SEC_PROP_AUTH_LIBRARY_FINALIZE, suite_config->authentication.library_finalize ) - else CHECK_SECURITY_PROPERTY( DDS_SEC_PROP_CRYPTO_LIBRARY_PATH, suite_config->cryptography.library_path ) - else CHECK_SECURITY_PROPERTY( DDS_SEC_PROP_CRYPTO_LIBRARY_INIT, suite_config->cryptography.library_init ) - else CHECK_SECURITY_PROPERTY( DDS_SEC_PROP_CRYPTO_LIBRARY_FINALIZE, suite_config->cryptography.library_finalize ) - else CHECK_SECURITY_PROPERTY( DDS_SEC_PROP_ACCESS_LIBRARY_PATH, suite_config->access_control.library_path ) - else CHECK_SECURITY_PROPERTY( DDS_SEC_PROP_ACCESS_LIBRARY_INIT, suite_config->access_control.library_init ) - else CHECK_SECURITY_PROPERTY( DDS_SEC_PROP_ACCESS_LIBRARY_FINALIZE, suite_config->access_control.library_finalize ) + if ((*sc)->authentication_context != NULL && (*sc)->access_control_context != NULL && (*sc)->crypto_context != NULL){ + release_plugins (*sc); } -#undef CHECK_SECURITY_PROPERTY + ddsrt_mutex_destroy (&(*sc)->omg_security_lock); + + //DDS_CTRACE ((*sc)->logcfg, "DDS Security deinit\n"); + ddsrt_free (*sc); + *sc = NULL; } -static void deinit_plugin_config(dds_security_plugin_config *plugin_config){ - ddsrt_free( plugin_config->library_path ); - ddsrt_free( plugin_config->library_init ); - ddsrt_free( plugin_config->library_finalize ); -} - -static void deinit_plugin_suite_config(dds_security_plugin_suite_config *suite_config ){ - deinit_plugin_config( &suite_config->access_control ); - deinit_plugin_config( &suite_config->authentication ); - deinit_plugin_config( &suite_config->cryptography ); - -} - -dds_return_t q_omg_security_load( dds_security_context *security_context, - const dds_qos_t *qos) +static void dds_qos_to_security_plugin_configuration (const dds_qos_t *qos, dds_security_plugin_suite_config *suite_config) { - dds_return_t ret = DDS_RETCODE_ERROR; + const struct { const char *name; size_t offset; } tab[] = { + { DDS_SEC_PROP_AUTH_LIBRARY_PATH, offsetof (dds_security_plugin_suite_config, authentication.library_path) }, + { DDS_SEC_PROP_AUTH_LIBRARY_INIT, offsetof (dds_security_plugin_suite_config, authentication.library_init) }, + { DDS_SEC_PROP_AUTH_LIBRARY_FINALIZE, offsetof (dds_security_plugin_suite_config, authentication.library_finalize) }, + { DDS_SEC_PROP_CRYPTO_LIBRARY_PATH, offsetof (dds_security_plugin_suite_config, cryptography.library_path) }, + { DDS_SEC_PROP_CRYPTO_LIBRARY_INIT, offsetof (dds_security_plugin_suite_config, cryptography.library_init) }, + { DDS_SEC_PROP_CRYPTO_LIBRARY_FINALIZE, offsetof (dds_security_plugin_suite_config, cryptography.library_finalize) }, + { DDS_SEC_PROP_ACCESS_LIBRARY_PATH, offsetof (dds_security_plugin_suite_config, access_control.library_path) }, + { DDS_SEC_PROP_ACCESS_LIBRARY_INIT, offsetof (dds_security_plugin_suite_config, access_control.library_init) }, + { DDS_SEC_PROP_ACCESS_LIBRARY_FINALIZE, offsetof (dds_security_plugin_suite_config, access_control.library_finalize) } + }; - ddsrt_mutex_lock(&security_context->omg_security_lock); + for (size_t i = 0; i < qos->property.value.n; i++) + for (size_t j = 0; j < sizeof (tab) / sizeof (tab[0]); j++) + if (strcmp (qos->property.value.props[i].name, tab[j].name) == 0) + *((char **) ((char *) suite_config + tab[j].offset)) = ddsrt_strdup (qos->property.value.props[i].value); +} - dds_security_plugin_suite_config plugin_suite_config; +static void deinit_plugin_config (dds_security_plugin_config *plugin_config) +{ + ddsrt_free (plugin_config->library_path); + ddsrt_free (plugin_config->library_init); + ddsrt_free (plugin_config->library_finalize); +} + +static void deinit_plugin_suite_config (dds_security_plugin_suite_config *suite_config) +{ + deinit_plugin_config (&suite_config->access_control); + deinit_plugin_config (&suite_config->authentication); + deinit_plugin_config (&suite_config->cryptography); +} + +dds_return_t q_omg_security_load (dds_security_context *sc, const dds_qos_t *qos) +{ + dds_security_plugin_suite_config psc; + memset (&psc, 0, sizeof (psc)); + + ddsrt_mutex_lock (&sc->omg_security_lock); - memset ( &plugin_suite_config, 0, sizeof(dds_security_plugin_suite_config)); /* Get plugin information */ - - dds_qos_to_security_plugin_configuration( qos, &plugin_suite_config); + dds_qos_to_security_plugin_configuration (qos, &psc); /* Check configuration content */ - if( dds_security_check_plugin_configuration( &plugin_suite_config ) == DDS_RETCODE_OK ){ - - if (dds_security_load_security_library( - &(plugin_suite_config.authentication), &security_context->auth_plugin, - (void**) &security_context->authentication_context) == DDS_RETCODE_OK) { - - if (dds_security_load_security_library( - &(plugin_suite_config.access_control), &security_context->ac_plugin, - (void**) &security_context->access_control_context) == DDS_RETCODE_OK ) { - - if (dds_security_load_security_library( - &(plugin_suite_config.cryptography), &security_context->crypto_plugin, - (void**) &security_context->crypto_context) == DDS_RETCODE_OK ) { - /* now check if all plugin functions are implemented */ - if( dds_security_verify_plugin_functions( - security_context->authentication_context,&security_context->auth_plugin, - security_context->crypto_context,&security_context->crypto_plugin, - security_context->access_control_context, &security_context->ac_plugin) == DDS_RETCODE_OK){ - - /* Add listeners */ -#if LISTENERS_IMPLEMENTED - if ( access_control_context->set_listener(access_control_context, &listener_ac, &ex)) { - if ( authentication_context->set_listener(authentication_context, &listener_auth, &ex)) { -#if HANDSHAKE_IMPLEMENTED - (void)q_handshake_initialize(); -#endif - } else { - DDS_ERROR("Could not set authentication listener: %s\n", - ex.message ? ex.message : ""); - } - - } else { - DDS_ERROR("Could not set access_control listener: %s\n", - ex.message ? ex.message : ""); - } -#endif //LISTENERS_IMPLEMENTED - - //tried_to_load = true; - //ret = last_load_result = DDS_RETCODE_OK; - ret = DDS_RETCODE_OK; - //omg_security_plugin_loaded = true; - DDS_INFO( "DDS Security plugins have been loaded\n" ); - } else { - release_plugins( security_context ); - } - - } else{ - DDS_ERROR("Could not load %s library\n", security_context->crypto_plugin.name); - } - }else{ - DDS_ERROR("Could not load %s library\n", security_context->ac_plugin.name); - } - - } - else{ - DDS_ERROR("Could not load %s plugin.\n", security_context->auth_plugin.name); - - } + if (dds_security_check_plugin_configuration (&psc, sc->logcfg) != DDS_RETCODE_OK) + goto error; + if (dds_security_load_security_library (&psc.authentication, &sc->auth_plugin, (void **) &sc->authentication_context, sc->logcfg) != DDS_RETCODE_OK) + { + DDS_CERROR (sc->logcfg, "Could not load %s plugin.\n", sc->auth_plugin.name); + goto error; + } + if (dds_security_load_security_library (&psc.access_control, &sc->ac_plugin, (void **) &sc->access_control_context, sc->logcfg) != DDS_RETCODE_OK) + { + DDS_CERROR (sc->logcfg, "Could not load %s library\n", sc->ac_plugin.name); + goto error; + } + if (dds_security_load_security_library (&psc.cryptography, &sc->crypto_plugin, (void **) &sc->crypto_context, sc->logcfg) != DDS_RETCODE_OK) + { + DDS_CERROR (sc->logcfg, "Could not load %s library\n", sc->crypto_plugin.name); + goto error; } - deinit_plugin_suite_config( &plugin_suite_config ); + /* now check if all plugin functions are implemented */ + if (dds_security_verify_plugin_functions ( + sc->authentication_context, &sc->auth_plugin, + sc->crypto_context, &sc->crypto_plugin, + sc->access_control_context, &sc->ac_plugin, + sc->logcfg) != DDS_RETCODE_OK) + { + goto error_verify; + } - ddsrt_mutex_unlock( &security_context->omg_security_lock ); + /* Add listeners */ +#if LISTENERS_IMPLEMENTED + if (!access_control_context->set_listener (access_control_context, &listener_ac, &ex)) + { + DDS_CERROR (sc->logcfg, "Could not set access_control listener: %s\n", ex.message ? ex.message : ""); + goto error_set_ac_listener; + } + if (!authentication_context->set_listener (authentication_context, &listener_auth, &ex)) + { + DDS_CERROR (sc->logcfg, "Could not set authentication listener: %s\n", ex.message ? ex.message : ""); + goto err_set_auth_listener; + } +#endif +#if HANDSHAKE_IMPLEMENTED + (void) q_handshake_initialize (); +#endif - return ret; + deinit_plugin_suite_config (&psc); + ddsrt_mutex_unlock (&sc->omg_security_lock); + DDS_CLOG (DDS_LC_TRACE, sc->logcfg, "DDS Security plugins have been loaded\n"); + return DDS_RETCODE_OK; + +#if LISTENERS_IMPLEMENTED +error_set_auth_listener: + access_control_context->set_listener (access_control_context, NULL, &ex); +error_set_ac_listener: +#endif +error_verify: + release_plugins (sc); +error: + deinit_plugin_suite_config (&psc); + ddsrt_mutex_unlock (&sc->omg_security_lock); + return DDS_RETCODE_ERROR; } -bool -q_omg_participant_is_secure( - const struct participant *pp) +bool q_omg_participant_is_secure (const struct participant *pp) { /* TODO: Register local participant. */ - DDSRT_UNUSED_ARG(pp); + DDSRT_UNUSED_ARG (pp); return false; } -bool -q_omg_proxy_participant_is_secure( - const struct proxy_participant *proxypp) +bool q_omg_proxy_participant_is_secure (const struct proxy_participant *proxypp) { /* TODO: Register remote participant */ - DDSRT_UNUSED_ARG(proxypp); + DDSRT_UNUSED_ARG (proxypp); return false; } -static bool -q_omg_writer_is_discovery_protected( - const struct writer *wr) +static bool q_omg_writer_is_discovery_protected (const struct writer *wr) { /* TODO: Register local writer. */ - DDSRT_UNUSED_ARG(wr); + DDSRT_UNUSED_ARG (wr); return false; } -static bool -q_omg_reader_is_discovery_protected( - const struct reader *rd) +static bool q_omg_reader_is_discovery_protected (const struct reader *rd) { /* TODO: Register local reader. */ - DDSRT_UNUSED_ARG(rd); + DDSRT_UNUSED_ARG (rd); return false; } -bool -q_omg_get_writer_security_info( - const struct writer *wr, - nn_security_info_t *info) +bool q_omg_get_writer_security_info (const struct writer *wr, nn_security_info_t *info) { - assert(wr); - assert(info); + assert (wr); + assert (info); /* TODO: Register local writer. */ - DDSRT_UNUSED_ARG(wr); + DDSRT_UNUSED_ARG (wr); info->plugin_security_attributes = 0; - if (q_omg_writer_is_payload_protected(wr)) + if (q_omg_writer_is_payload_protected (wr)) { - info->security_attributes = NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID| - NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_PROTECTED; + info->security_attributes = + NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID | + NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_PROTECTED; } else { @@ -372,108 +327,84 @@ q_omg_get_writer_security_info( return true; } -bool -q_omg_get_reader_security_info( - const struct reader *rd, - nn_security_info_t *info) +bool q_omg_get_reader_security_info (const struct reader *rd, nn_security_info_t *info) { - assert(rd); - assert(info); + assert (rd); + assert (info); /* TODO: Register local reader. */ - DDSRT_UNUSED_ARG(rd); + DDSRT_UNUSED_ARG (rd); info->plugin_security_attributes = 0; info->security_attributes = 0; return false; } -void -q_omg_security_init_remote_participant(struct proxy_participant *proxypp) +void q_omg_security_init_remote_participant (struct proxy_participant *proxypp) { - DDSRT_UNUSED_ARG(proxypp); + DDSRT_UNUSED_ARG (proxypp); } -static bool -q_omg_proxyparticipant_is_authenticated( - const struct proxy_participant *proxy_pp) +static bool q_omg_proxyparticipant_is_authenticated (const struct proxy_participant *proxy_pp) { /* TODO: Handshake */ - DDSRT_UNUSED_ARG(proxy_pp); + DDSRT_UNUSED_ARG (proxy_pp); return false; } -int64_t -q_omg_security_get_local_participant_handle( - struct participant *pp) +int64_t q_omg_security_get_local_participant_handle (struct participant *pp) { /* TODO: Local registration */ - DDSRT_UNUSED_ARG(pp); + DDSRT_UNUSED_ARG (pp); return 0; } -int64_t -q_omg_security_get_remote_participant_handle( - struct proxy_participant *proxypp) +int64_t q_omg_security_get_remote_participant_handle (struct proxy_participant *proxypp) { /* TODO: Handshake */ DDSRT_UNUSED_ARG(proxypp); return 0; } -bool -q_omg_participant_allow_unauthenticated(struct participant *pp) +bool q_omg_participant_allow_unauthenticated (struct participant *pp) { - DDSRT_UNUSED_ARG(pp); - + DDSRT_UNUSED_ARG (pp); return true; } -unsigned -determine_subscription_writer( - const struct reader *rd) +unsigned determine_subscription_writer (const struct reader *rd) { - if (q_omg_reader_is_discovery_protected(rd)) - { + if (q_omg_reader_is_discovery_protected (rd)) return NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER; - } - return NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER; + else + return NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER; } -unsigned -determine_publication_writer( - const struct writer *wr) +unsigned determine_publication_writer (const struct writer *wr) { - if (q_omg_writer_is_discovery_protected(wr)) - { + if (q_omg_writer_is_discovery_protected (wr)) return NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER; - } - return NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER; + else + return NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER; } -void -q_omg_security_register_remote_participant(struct participant *pp, struct proxy_participant *proxypp, int64_t shared_secret, int64_t proxy_permissions) +void q_omg_security_register_remote_participant (struct participant *pp, struct proxy_participant *proxypp, int64_t shared_secret, int64_t proxy_permissions) { - DDSRT_UNUSED_ARG(pp); - DDSRT_UNUSED_ARG(proxypp); - DDSRT_UNUSED_ARG(shared_secret); - DDSRT_UNUSED_ARG(proxy_permissions); + DDSRT_UNUSED_ARG (pp); + DDSRT_UNUSED_ARG (proxypp); + DDSRT_UNUSED_ARG (shared_secret); + DDSRT_UNUSED_ARG (proxy_permissions); } -void -q_omg_security_deregister_remote_participant(struct proxy_participant *proxypp) +void q_omg_security_deregister_remote_participant (struct proxy_participant *proxypp) { - DDSRT_UNUSED_ARG(proxypp); + DDSRT_UNUSED_ARG (proxypp); } -bool -is_proxy_participant_deletion_allowed( - struct q_globals * const gv, - const struct ddsi_guid *guid, - const ddsi_entityid_t pwr_entityid) +bool is_proxy_participant_deletion_allowed (struct q_globals * const gv, const struct ddsi_guid *guid, const ddsi_entityid_t pwr_entityid) { struct proxy_participant *proxypp; - assert(gv); - assert(guid); + assert (gv); + assert (guid); /* TODO: Check if the proxy writer guid prefix matches that of the proxy * participant. Deletion is not allowed when they're not equal. */ @@ -484,131 +415,104 @@ is_proxy_participant_deletion_allowed( /* Not from a secure proxy writer. * Only allow deletion when proxy participant is not authenticated. */ - proxypp = entidx_lookup_proxy_participant_guid(gv->entity_index, guid); + proxypp = entidx_lookup_proxy_participant_guid (gv->entity_index, guid); if (!proxypp) { GVLOGDISC (" unknown"); return false; } - return (!q_omg_proxyparticipant_is_authenticated(proxypp)); + return (!q_omg_proxyparticipant_is_authenticated (proxypp)); } /* ask to access control security plugin for the remote participant permissions */ -int64_t -q_omg_security_check_remote_participant_permissions(uint32_t domain_id, struct participant *pp, struct proxy_participant *proxypp) +int64_t q_omg_security_check_remote_participant_permissions (uint32_t domain_id, struct participant *pp, struct proxy_participant *proxypp) { - DDSRT_UNUSED_ARG(domain_id); - DDSRT_UNUSED_ARG(pp); - DDSRT_UNUSED_ARG(proxypp); - + DDSRT_UNUSED_ARG (domain_id); + DDSRT_UNUSED_ARG (pp); + DDSRT_UNUSED_ARG (proxypp); return 0; } -bool -q_omg_is_similar_participant_security_info(struct participant *pp, struct proxy_participant *proxypp) +bool q_omg_is_similar_participant_security_info (struct participant *pp, struct proxy_participant *proxypp) { - DDSRT_UNUSED_ARG(pp); - DDSRT_UNUSED_ARG(proxypp); - + DDSRT_UNUSED_ARG (pp); + DDSRT_UNUSED_ARG (proxypp); return true; } -bool -q_omg_security_check_create_participant(struct participant *pp, uint32_t domain_id) +bool q_omg_security_check_create_participant (struct participant *pp, uint32_t domain_id) { - DDSRT_UNUSED_ARG(pp); - DDSRT_UNUSED_ARG(domain_id); + DDSRT_UNUSED_ARG (pp); + DDSRT_UNUSED_ARG (domain_id); return true; } -void -q_omg_security_participant_send_tokens(struct participant *pp, struct proxy_participant *proxypp) +void q_omg_security_participant_send_tokens (struct participant *pp, struct proxy_participant *proxypp) { - DDSRT_UNUSED_ARG(pp); - DDSRT_UNUSED_ARG(proxypp); + DDSRT_UNUSED_ARG (pp); + DDSRT_UNUSED_ARG (proxypp); } -bool -q_omg_security_match_remote_writer_enabled(struct reader *rd, struct proxy_writer *pwr) +bool q_omg_security_match_remote_writer_enabled (struct reader *rd, struct proxy_writer *pwr) { - DDSRT_UNUSED_ARG(rd); - DDSRT_UNUSED_ARG(pwr); - - assert(rd); - assert(pwr); - + DDSRT_UNUSED_ARG (rd); + DDSRT_UNUSED_ARG (pwr); + assert (rd); + assert (pwr); return true; } -bool -q_omg_security_match_remote_reader_enabled(struct writer *wr, struct proxy_reader *prd) +bool q_omg_security_match_remote_reader_enabled (struct writer *wr, struct proxy_reader *prd) { - DDSRT_UNUSED_ARG(wr); - DDSRT_UNUSED_ARG(prd); - - assert(wr); - assert(prd); - + DDSRT_UNUSED_ARG (wr); + DDSRT_UNUSED_ARG (prd); + assert (wr); + assert (prd); return true; } -bool -q_omg_security_check_remote_writer_permissions(const struct proxy_writer *pwr, uint32_t domain_id, struct participant *pp) +bool q_omg_security_check_remote_writer_permissions (const struct proxy_writer *pwr, uint32_t domain_id, struct participant *pp) { - DDSRT_UNUSED_ARG(pwr); - DDSRT_UNUSED_ARG(domain_id); - DDSRT_UNUSED_ARG(pp); - - assert(pwr); - assert(pp); - assert(pwr->c.proxypp); - + DDSRT_UNUSED_ARG (pwr); + DDSRT_UNUSED_ARG (domain_id); + DDSRT_UNUSED_ARG (pp); + assert (pwr); + assert (pp); + assert (pwr->c.proxypp); return true; } -bool -q_omg_security_check_remote_reader_permissions(const struct proxy_reader *prd, uint32_t domain_id, struct participant *pp) +bool q_omg_security_check_remote_reader_permissions (const struct proxy_reader *prd, uint32_t domain_id, struct participant *pp) { - DDSRT_UNUSED_ARG(prd); - DDSRT_UNUSED_ARG(domain_id); - DDSRT_UNUSED_ARG(pp); - - assert(prd); - assert(pp); - assert(prd->c.proxypp); - + DDSRT_UNUSED_ARG (prd); + DDSRT_UNUSED_ARG (domain_id); + DDSRT_UNUSED_ARG (pp); + assert (prd); + assert (pp); + assert (prd->c.proxypp); return true; } -bool -q_omg_security_is_remote_rtps_protected( - struct proxy_participant *proxy_pp, - ddsi_entityid_t entityid) +bool q_omg_security_is_remote_rtps_protected (const struct proxy_participant *proxy_pp, ddsi_entityid_t entityid) { /* TODO: Handshake */ - DDSRT_UNUSED_ARG(proxy_pp); - DDSRT_UNUSED_ARG(entityid); + DDSRT_UNUSED_ARG (proxy_pp); + DDSRT_UNUSED_ARG (entityid); return false; } -bool -q_omg_security_is_local_rtps_protected( - struct participant *pp, - ddsi_entityid_t entityid) +bool q_omg_security_is_local_rtps_protected (const struct participant *pp, ddsi_entityid_t entityid) { /* TODO: Handshake */ - DDSRT_UNUSED_ARG(pp); - DDSRT_UNUSED_ARG(entityid); + DDSRT_UNUSED_ARG (pp); + DDSRT_UNUSED_ARG (entityid); return false; } -void -set_proxy_participant_security_info( - struct proxy_participant *proxypp, - const nn_plist_t *plist) +void set_proxy_participant_security_info (struct proxy_participant *proxypp, const nn_plist_t *plist) { - assert(proxypp); - assert(plist); + assert (proxypp); + assert (plist); if (plist->present & PP_PARTICIPANT_SECURITY_INFO) { proxypp->security_info.security_attributes = plist->participant_security_info.security_attributes; proxypp->security_info.plugin_security_attributes = plist->participant_security_info.plugin_security_attributes; @@ -618,17 +522,10 @@ set_proxy_participant_security_info( } } -static void -q_omg_get_proxy_endpoint_security_info( - const struct entity_common *entity, - nn_security_info_t *proxypp_sec_info, - const nn_plist_t *plist, - nn_security_info_t *info) +static void q_omg_get_proxy_endpoint_security_info (const struct entity_common *entity, nn_security_info_t *proxypp_sec_info, const nn_plist_t *plist, nn_security_info_t *info) { - bool proxypp_info_available; - - proxypp_info_available = (proxypp_sec_info->security_attributes != 0) || - (proxypp_sec_info->plugin_security_attributes != 0); + const bool proxypp_info_available = + (proxypp_sec_info->security_attributes != 0 || proxypp_sec_info->plugin_security_attributes != 0); /* * If Security info is present, use that. @@ -641,26 +538,21 @@ q_omg_get_proxy_endpoint_security_info( info->security_attributes = plist->endpoint_security_info.security_attributes; info->plugin_security_attributes = plist->endpoint_security_info.plugin_security_attributes; } - else if (endpoint_is_DCPSParticipantSecure(&(entity->guid)) || - endpoint_is_DCPSPublicationsSecure(&(entity->guid)) || - endpoint_is_DCPSSubscriptionsSecure(&(entity->guid)) ) + else if (endpoint_is_DCPSParticipantSecure (&entity->guid)|| + endpoint_is_DCPSPublicationsSecure (&entity->guid) || + endpoint_is_DCPSSubscriptionsSecure (&entity->guid)) { + /* Discovery protection flags */ info->plugin_security_attributes = NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID; info->security_attributes = NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID; if (proxypp_info_available) { if (proxypp_sec_info->security_attributes & NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_PROTECTED) - { info->security_attributes |= NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED; - } if (proxypp_sec_info->plugin_security_attributes & NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_ENCRYPTED) - { info->plugin_security_attributes |= NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED; - } if (proxypp_sec_info->plugin_security_attributes & NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_AUTHENTICATED) - { info->plugin_security_attributes |= NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED; - } } else { @@ -669,24 +561,19 @@ q_omg_get_proxy_endpoint_security_info( info->plugin_security_attributes |= NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED; } } - else if (endpoint_is_DCPSParticipantMessageSecure(&(entity->guid))) + else if (endpoint_is_DCPSParticipantMessageSecure (&entity->guid)) { + /* Liveliness protection flags */ info->plugin_security_attributes = NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID; info->security_attributes = NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID; if (proxypp_info_available) { if (proxypp_sec_info->security_attributes & NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_PROTECTED) - { info->security_attributes |= NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED; - } if (proxypp_sec_info->plugin_security_attributes & NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ENCRYPTED) - { info->plugin_security_attributes |= NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED; - } if (proxypp_sec_info->plugin_security_attributes & NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_AUTHENTICATED) - { info->plugin_security_attributes |= NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED; - } } else { @@ -695,15 +582,15 @@ q_omg_get_proxy_endpoint_security_info( info->plugin_security_attributes |= NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED; } } - else if (endpoint_is_DCPSParticipantStatelessMessage(&(entity->guid))) + else if (endpoint_is_DCPSParticipantStatelessMessage (&entity->guid)) { info->security_attributes = NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID; info->plugin_security_attributes = 0; } - else if (endpoint_is_DCPSParticipantVolatileMessageSecure(&(entity->guid))) + else if (endpoint_is_DCPSParticipantVolatileMessageSecure (&entity->guid)) { - info->security_attributes = NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID | - NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED; + info->security_attributes = + NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID | NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED; info->plugin_security_attributes = 0; } else @@ -713,421 +600,281 @@ q_omg_get_proxy_endpoint_security_info( } } -void -set_proxy_reader_security_info( - struct proxy_reader *prd, - const nn_plist_t *plist) +void set_proxy_reader_security_info (struct proxy_reader *prd, const nn_plist_t *plist) { - assert(prd); - q_omg_get_proxy_endpoint_security_info(&(prd->e), - &(prd->c.proxypp->security_info), - plist, - &(prd->c.security_info)); + assert (prd); + q_omg_get_proxy_endpoint_security_info (&prd->e, &prd->c.proxypp->security_info, plist, &prd->c.security_info); } -void -set_proxy_writer_security_info( - struct proxy_writer *pwr, - const nn_plist_t *plist) +void set_proxy_writer_security_info (struct proxy_writer *pwr, const nn_plist_t *plist) { - assert(pwr); - q_omg_get_proxy_endpoint_security_info(&(pwr->e), - &(pwr->c.proxypp->security_info), - plist, - &(pwr->c.security_info)); + assert (pwr); + q_omg_get_proxy_endpoint_security_info (&pwr->e, &pwr->c.proxypp->security_info, plist, &pwr->c.security_info); } -static bool -q_omg_security_encode_datareader_submessage( - struct reader *rd, - const ddsi_guid_prefix_t *dst_prefix, - const unsigned char *src_buf, - const unsigned int src_len, - unsigned char **dst_buf, - unsigned int *dst_len) +static bool q_omg_security_encode_datareader_submessage (struct reader *rd, const ddsi_guid_prefix_t *dst_prefix, const unsigned char *src_buf, size_t src_len, unsigned char **dst_buf, size_t *dst_len) { /* TODO: Use proper keys to actually encode (need key-exchange). */ - DDSRT_UNUSED_ARG(rd); - DDSRT_UNUSED_ARG(dst_prefix); - DDSRT_UNUSED_ARG(src_buf); - DDSRT_UNUSED_ARG(src_len); - DDSRT_UNUSED_ARG(dst_buf); - DDSRT_UNUSED_ARG(dst_len); + DDSRT_UNUSED_ARG (rd); + DDSRT_UNUSED_ARG (dst_prefix); + DDSRT_UNUSED_ARG (src_buf); + DDSRT_UNUSED_ARG (src_len); + DDSRT_UNUSED_ARG (dst_buf); + DDSRT_UNUSED_ARG (dst_len); return false; } -static bool -q_omg_security_encode_datawriter_submessage( - struct writer *wr, - const ddsi_guid_prefix_t *dst_prefix, - const unsigned char *src_buf, - const unsigned int src_len, - unsigned char **dst_buf, - unsigned int *dst_len) +static bool q_omg_security_encode_datawriter_submessage (struct writer *wr, const ddsi_guid_prefix_t *dst_prefix, const unsigned char *src_buf, size_t src_len, unsigned char **dst_buf, size_t *dst_len) { /* TODO: Use proper keys to actually encode (need key-exchange). */ - DDSRT_UNUSED_ARG(wr); - DDSRT_UNUSED_ARG(dst_prefix); - DDSRT_UNUSED_ARG(src_buf); - DDSRT_UNUSED_ARG(src_len); - DDSRT_UNUSED_ARG(dst_buf); - DDSRT_UNUSED_ARG(dst_len); + DDSRT_UNUSED_ARG (wr); + DDSRT_UNUSED_ARG (dst_prefix); + DDSRT_UNUSED_ARG (src_buf); + DDSRT_UNUSED_ARG (src_len); + DDSRT_UNUSED_ARG (dst_buf); + DDSRT_UNUSED_ARG (dst_len); return false; } -static bool -q_omg_security_decode_submessage( - const ddsi_guid_prefix_t* const src_prefix, - const ddsi_guid_prefix_t* const dst_prefix, - const unsigned char *src_buf, - const unsigned int src_len, - unsigned char **dst_buf, - unsigned int *dst_len) +static bool q_omg_security_decode_submessage (const ddsi_guid_prefix_t * const src_prefix, const ddsi_guid_prefix_t * const dst_prefix, const unsigned char *src_buf, size_t src_len, unsigned char **dst_buf, size_t *dst_len) { /* TODO: Use proper keys to actually decode (need key-exchange). */ - DDSRT_UNUSED_ARG(src_prefix); - DDSRT_UNUSED_ARG(dst_prefix); - DDSRT_UNUSED_ARG(src_buf); - DDSRT_UNUSED_ARG(src_len); - DDSRT_UNUSED_ARG(dst_buf); - DDSRT_UNUSED_ARG(dst_len); + DDSRT_UNUSED_ARG (src_prefix); + DDSRT_UNUSED_ARG (dst_prefix); + DDSRT_UNUSED_ARG (src_buf); + DDSRT_UNUSED_ARG (src_len); + DDSRT_UNUSED_ARG (dst_buf); + DDSRT_UNUSED_ARG (dst_len); return false; } -static bool -q_omg_security_encode_serialized_payload( - const struct writer *wr, - const unsigned char *src_buf, - const unsigned int src_len, - unsigned char **dst_buf, - unsigned int *dst_len) +static bool q_omg_security_encode_serialized_payload (const struct writer *wr, const unsigned char *src_buf, size_t src_len, unsigned char **dst_buf, size_t *dst_len) { /* TODO: Use proper keys to actually encode (need key-exchange). */ - DDSRT_UNUSED_ARG(wr); - DDSRT_UNUSED_ARG(src_buf); - DDSRT_UNUSED_ARG(src_len); - DDSRT_UNUSED_ARG(dst_buf); - DDSRT_UNUSED_ARG(dst_len); + DDSRT_UNUSED_ARG (wr); + DDSRT_UNUSED_ARG (src_buf); + DDSRT_UNUSED_ARG (src_len); + DDSRT_UNUSED_ARG (dst_buf); + DDSRT_UNUSED_ARG (dst_len); return false; } -static bool -q_omg_security_decode_serialized_payload( - struct proxy_writer *pwr, - const unsigned char *src_buf, - const unsigned int src_len, - unsigned char **dst_buf, - unsigned int *dst_len) +static bool q_omg_security_decode_serialized_payload (struct proxy_writer *pwr, const unsigned char *src_buf, size_t src_len, unsigned char **dst_buf, size_t *dst_len) { /* TODO: Use proper keys to actually decode (need key-exchange). */ - DDSRT_UNUSED_ARG(pwr); - DDSRT_UNUSED_ARG(src_buf); - DDSRT_UNUSED_ARG(src_len); - DDSRT_UNUSED_ARG(dst_buf); - DDSRT_UNUSED_ARG(dst_len); + DDSRT_UNUSED_ARG (pwr); + DDSRT_UNUSED_ARG (src_buf); + DDSRT_UNUSED_ARG (src_len); + DDSRT_UNUSED_ARG (dst_buf); + DDSRT_UNUSED_ARG (dst_len); return false; } -bool -q_omg_security_encode_rtps_message( - int64_t src_handle, - ddsi_guid_t *src_guid, - const unsigned char *src_buf, - const unsigned int src_len, - unsigned char **dst_buf, - unsigned int *dst_len, - int64_t dst_handle) +bool q_omg_security_encode_rtps_message (int64_t src_handle, ddsi_guid_t *src_guid, const unsigned char *src_buf, size_t src_len, unsigned char **dst_buf, size_t *dst_len, int64_t dst_handle) { /* TODO: Use proper keys to actually encode (need key-exchange). */ - DDSRT_UNUSED_ARG(src_handle); - DDSRT_UNUSED_ARG(src_guid); - DDSRT_UNUSED_ARG(src_buf); - DDSRT_UNUSED_ARG(src_len); - DDSRT_UNUSED_ARG(dst_buf); - DDSRT_UNUSED_ARG(dst_len); - DDSRT_UNUSED_ARG(dst_handle); + DDSRT_UNUSED_ARG (src_handle); + DDSRT_UNUSED_ARG (src_guid); + DDSRT_UNUSED_ARG (src_buf); + DDSRT_UNUSED_ARG (src_len); + DDSRT_UNUSED_ARG (dst_buf); + DDSRT_UNUSED_ARG (dst_len); + DDSRT_UNUSED_ARG (dst_handle); return false; } -static bool -q_omg_security_decode_rtps_message( - struct proxy_participant *proxypp, - const unsigned char *src_buf, - const unsigned int src_len, - unsigned char **dst_buf, - unsigned int *dst_len) +static bool q_omg_security_decode_rtps_message (struct proxy_participant *proxypp, const unsigned char *src_buf, size_t src_len, unsigned char **dst_buf, size_t *dst_len) { /* TODO: Use proper keys to actually decode (need key-exchange). */ - DDSRT_UNUSED_ARG(proxypp); - DDSRT_UNUSED_ARG(src_buf); - DDSRT_UNUSED_ARG(src_len); - DDSRT_UNUSED_ARG(dst_buf); - DDSRT_UNUSED_ARG(dst_len); + DDSRT_UNUSED_ARG (proxypp); + DDSRT_UNUSED_ARG (src_buf); + DDSRT_UNUSED_ARG (src_len); + DDSRT_UNUSED_ARG (dst_buf); + DDSRT_UNUSED_ARG (dst_len); return false; } -static bool -q_omg_writer_is_payload_protected( - const struct writer *wr) +static bool q_omg_writer_is_payload_protected (const struct writer *wr) { /* TODO: Local registration. */ - DDSRT_UNUSED_ARG(wr); + DDSRT_UNUSED_ARG (wr); return false; } -static bool -q_omg_writer_is_submessage_protected( - struct writer *wr) +static bool q_omg_writer_is_submessage_protected (struct writer *wr) { /* TODO: Local registration. */ - DDSRT_UNUSED_ARG(wr); + DDSRT_UNUSED_ARG (wr); return false; } -static bool -q_omg_reader_is_submessage_protected( - struct reader *rd) +static bool q_omg_reader_is_submessage_protected (struct reader *rd) { /* TODO: Local registration. */ - DDSRT_UNUSED_ARG(rd); + DDSRT_UNUSED_ARG (rd); return false; } -bool -encode_payload( - struct writer *wr, - ddsrt_iovec_t *vec, - unsigned char **buf) +bool encode_payload (struct writer *wr, ddsrt_iovec_t *vec, unsigned char **buf) { - bool ok = true; *buf = NULL; - if (q_omg_writer_is_payload_protected(wr)) - { - /* Encrypt the data. */ - unsigned char *enc_buf; - unsigned int enc_len; - ok = q_omg_security_encode_serialized_payload( - wr, - vec->iov_base, - (unsigned int)vec->iov_len, - &enc_buf, - &enc_len); - if (ok) - { - /* Replace the iov buffer, which should always be aliased. */ - vec->iov_base = (char *)enc_buf; - vec->iov_len = enc_len; - /* Remember the pointer to be able to free the memory. */ - *buf = enc_buf; - } - } - return ok; + if (!q_omg_writer_is_payload_protected (wr)) + return true; + + unsigned char *enc_buf; + size_t enc_len; + if (!q_omg_security_encode_serialized_payload (wr, vec->iov_base, vec->iov_len, &enc_buf, &enc_len)) + return false; + + /* Replace the iov buffer, which should always be aliased. */ + vec->iov_base = (char *) enc_buf; + vec->iov_len = (ddsrt_iov_len_t) enc_len; + assert ((size_t) vec->iov_len == enc_len); + *buf = enc_buf; + return true; } -static bool -decode_payload( - const struct q_globals *gv, - struct nn_rsample_info *sampleinfo, - unsigned char *payloadp, - uint32_t *payloadsz, - size_t *submsg_len) +static bool decode_payload (const struct q_globals *gv, struct nn_rsample_info *sampleinfo, unsigned char *payloadp, uint32_t *payloadsz, size_t *submsg_len) { - bool ok = true; - - assert(payloadp); - assert(payloadsz); - assert(*payloadsz); - assert(submsg_len); - assert(sampleinfo); + assert (payloadp); + assert (payloadsz); + assert (*payloadsz); + assert (submsg_len); + assert (sampleinfo); if (sampleinfo->pwr == NULL) - { /* No specified proxy writer means no encoding. */ return true; - } /* Only decode when the attributes tell us so. */ if ((sampleinfo->pwr->c.security_info.security_attributes & NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_PROTECTED) - == NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_PROTECTED) + != NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_PROTECTED) + return true; + + unsigned char *dst_buf = NULL; + size_t dst_len = 0; + if (!q_omg_security_decode_serialized_payload (sampleinfo->pwr, payloadp, *payloadsz, &dst_buf, &dst_len)) { - unsigned char *dst_buf = NULL; - unsigned int dst_len = 0; - - /* Decrypt the payload. */ - if (q_omg_security_decode_serialized_payload(sampleinfo->pwr, payloadp, *payloadsz, &dst_buf, &dst_len)) - { - /* Expect result to always fit into the original buffer. */ - assert(*payloadsz >= dst_len); - - /* Reduce submessage and payload lengths. */ - *submsg_len -= (*payloadsz - dst_len); - *payloadsz = dst_len; - - /* Replace the encrypted payload with the decrypted. */ - memcpy(payloadp, dst_buf, dst_len); - ddsrt_free(dst_buf); - } - else - { - GVWARNING("decode_payload: failed to decrypt data from "PGUIDFMT"", PGUID (sampleinfo->pwr->e.guid)); - ok = false; - } + GVWARNING ("decode_payload: failed to decrypt data from "PGUIDFMT"", PGUID (sampleinfo->pwr->e.guid)); + return false; } - return ok; + /* Expect result to always fit into the original buffer. */ + assert (*payloadsz >= dst_len); + + /* Reduce submessage and payload lengths. */ + *submsg_len -= *payloadsz - (uint32_t) dst_len; + *payloadsz = (uint32_t) dst_len; + memcpy (payloadp, dst_buf, dst_len); + ddsrt_free (dst_buf); + return true; } -bool -decode_Data( - const struct q_globals *gv, - struct nn_rsample_info *sampleinfo, - unsigned char *payloadp, - uint32_t payloadsz, - size_t *submsg_len) +bool decode_Data (const struct q_globals *gv, struct nn_rsample_info *sampleinfo, unsigned char *payloadp, uint32_t payloadsz, size_t *submsg_len) { - int ok = true; /* Only decode when there's actual data. */ - if (payloadp && (payloadsz > 0)) + if (payloadp == NULL || payloadsz == 0) + return true; + else if (!decode_payload (gv, sampleinfo, payloadp, &payloadsz, submsg_len)) + return false; + else { - ok = decode_payload(gv, sampleinfo, payloadp, &payloadsz, submsg_len); - if (ok) - { - /* It's possible that the payload size (and thus the sample size) has been reduced. */ - sampleinfo->size = payloadsz; - } - } - return ok; -} - -bool -decode_DataFrag( - const struct q_globals *gv, - struct nn_rsample_info *sampleinfo, - unsigned char *payloadp, - uint32_t payloadsz, - size_t *submsg_len) -{ - int ok = true; - /* Only decode when there's actual data. */ - if (payloadp && (payloadsz > 0)) - { - ok = decode_payload(gv, sampleinfo, payloadp, &payloadsz, submsg_len); - /* Do not touch the sampleinfo->size in contradiction to decode_Data() (it has been calculated differently). */ - } - return ok; -} - - -void -encode_datareader_submsg( - struct nn_xmsg *msg, - struct nn_xmsg_marker sm_marker, - struct proxy_writer *pwr, - const struct ddsi_guid *rd_guid) -{ - struct reader *rd = entidx_lookup_reader_guid(pwr->e.gv->entity_index, rd_guid); - struct participant *pp = NULL; - /* Only encode when needed. */ - if( rd != NULL ){ - pp = rd->c.pp; - } - if (!pp && q_omg_participant_is_secure( pp )) - { - if (q_omg_reader_is_submessage_protected(rd)) - { - unsigned char *src_buf; - unsigned int src_len; - unsigned char *dst_buf; - unsigned int dst_len; - - /* Make one blob of the current sub-message by appending the serialized payload. */ - nn_xmsg_submsg_append_refd_payload(msg, sm_marker); - - /* Get the sub-message buffer. */ - src_buf = (unsigned char*)nn_xmsg_submsg_from_marker(msg, sm_marker); - src_len = (unsigned int)nn_xmsg_submsg_size(msg, sm_marker); - - /* Do the actual encryption. */ - if (q_omg_security_encode_datareader_submessage(rd, &(pwr->e.guid.prefix), src_buf, src_len, &dst_buf, &dst_len)) - { - /* Replace the old sub-message with the new encoded one(s). */ - nn_xmsg_submsg_replace(msg, sm_marker, dst_buf, dst_len); - ddsrt_free(dst_buf); - } - else - { - /* The sub-message should have been encoded, which failed. - * Remove it to prevent it from being send. */ - nn_xmsg_submsg_remove(msg, sm_marker); - } - } + /* It's possible that the payload size (and thus the sample size) has been reduced. */ + sampleinfo->size = payloadsz; + return true; } } -void -encode_datawriter_submsg( - struct nn_xmsg *msg, - struct nn_xmsg_marker sm_marker, - struct writer *wr) +bool decode_DataFrag (const struct q_globals *gv, struct nn_rsample_info *sampleinfo, unsigned char *payloadp, uint32_t payloadsz, size_t *submsg_len) { - struct participant *pp = wr->c.pp; - /* Only encode when needed. */ - if (q_omg_participant_is_secure( pp )) + /* Only decode when there's actual data; do not touch the sampleinfo->size in + contradiction to decode_Data() (it has been calculated differently). */ + if (payloadp == NULL || payloadsz == 0) + return true; + else + return decode_payload (gv, sampleinfo, payloadp, &payloadsz, submsg_len); +} + +void encode_datareader_submsg (struct nn_xmsg *msg, struct nn_xmsg_marker sm_marker, struct proxy_writer *pwr, const struct ddsi_guid *rd_guid) +{ + /* FIXME: avoid this lookup */ + struct reader * const rd = entidx_lookup_reader_guid (pwr->e.gv->entity_index, rd_guid); + /* surely a reader can only be protected if the participant has security enabled? */ + if (rd == NULL || !q_omg_reader_is_submessage_protected (rd)) { - if (q_omg_writer_is_submessage_protected(wr)) - { - unsigned char *src_buf; - unsigned int src_len; - unsigned char *dst_buf; - unsigned int dst_len; - ddsi_guid_prefix_t dst_guid_prefix; - ddsi_guid_prefix_t *dst = NULL; + assert (rd == NULL || !q_omg_participant_is_secure (rd->c.pp)); + return; + } + assert (q_omg_participant_is_secure (rd->c.pp)); - /* Make one blob of the current sub-message by appending the serialized payload. */ - nn_xmsg_submsg_append_refd_payload(msg, sm_marker); + unsigned char *src_buf; + size_t src_len; + unsigned char *dst_buf; + size_t dst_len; - /* Get the sub-message buffer. */ - src_buf = (unsigned char*)nn_xmsg_submsg_from_marker(msg, sm_marker); - src_len = (unsigned int)nn_xmsg_submsg_size(msg, sm_marker); + /* Make one blob of the current sub-message by appending the serialized payload. */ + nn_xmsg_submsg_append_refd_payload (msg, sm_marker); - if (nn_xmsg_getdst1prefix(msg, &dst_guid_prefix)) - { - dst = &dst_guid_prefix; - } + /* Get the sub-message buffer. */ + src_buf = nn_xmsg_submsg_from_marker (msg, sm_marker); + src_len = nn_xmsg_submsg_size (msg, sm_marker); - /* Do the actual encryption. */ - if (q_omg_security_encode_datawriter_submessage(wr, dst, src_buf, src_len, &dst_buf, &dst_len)) - { - /* Replace the old sub-message with the new encoded one(s). */ - nn_xmsg_submsg_replace(msg, sm_marker, dst_buf, dst_len); - ddsrt_free(dst_buf); - } - else - { - /* The sub-message should have been encoded, which failed. - * Remove it to prevent it from being send. */ - nn_xmsg_submsg_remove(msg, sm_marker); - } - } + if (q_omg_security_encode_datareader_submessage (rd, &pwr->e.guid.prefix, src_buf, src_len, &dst_buf, &dst_len)) + { + nn_xmsg_submsg_replace (msg, sm_marker, dst_buf, dst_len); + ddsrt_free (dst_buf); + } + else + { + /* The sub-message should have been encoded, which failed. Remove it to prevent it from being send. */ + nn_xmsg_submsg_remove (msg, sm_marker); } } - - -bool -validate_msg_decoding( - const struct entity_common *e, - const struct proxy_endpoint_common *c, - struct proxy_participant *proxypp, - struct receiver_state *rst, - SubmessageKind_t prev_smid) +void encode_datawriter_submsg (struct nn_xmsg *msg, struct nn_xmsg_marker sm_marker, struct writer *wr) { - assert(e); - assert(c); - assert(proxypp); - assert(rst); + /* Only encode when needed. Surely a writer can only be protected if the participant has security enabled? */ + assert (!q_omg_writer_is_submessage_protected (wr) || q_omg_participant_is_secure (wr->c.pp)); + if (!q_omg_writer_is_submessage_protected (wr)) + return; + + unsigned char *src_buf; + size_t src_len; + unsigned char *dst_buf; + size_t dst_len; + ddsi_guid_prefix_t dst_guid_prefix; + ddsi_guid_prefix_t *dst = NULL; + + /* Make one blob of the current sub-message by appending the serialized payload. */ + nn_xmsg_submsg_append_refd_payload (msg, sm_marker); + + /* Get the sub-message buffer. */ + src_buf = nn_xmsg_submsg_from_marker (msg, sm_marker); + src_len = nn_xmsg_submsg_size (msg, sm_marker); + + if (nn_xmsg_getdst1prefix (msg, &dst_guid_prefix)) + dst = &dst_guid_prefix; + + if (q_omg_security_encode_datawriter_submessage (wr, dst, src_buf, src_len, &dst_buf, &dst_len)) + { + nn_xmsg_submsg_replace (msg, sm_marker, dst_buf, dst_len); + ddsrt_free (dst_buf); + } + else + { + /* The sub-message should have been encoded, which failed. Remove it to prevent it from being send. */ + nn_xmsg_submsg_remove (msg, sm_marker); + } +} + +bool validate_msg_decoding (const struct entity_common *e, const struct proxy_endpoint_common *c, const struct proxy_participant *proxypp, const struct receiver_state *rst, SubmessageKind_t prev_smid) +{ + assert (e); + assert (c); + assert (proxypp); + assert (rst); /* If this endpoint is expected to have submessages protected, it means that the * previous submessage id (prev_smid) has to be SMID_SEC_PREFIX. That caused the @@ -1136,17 +883,15 @@ validate_msg_decoding( * However, we have to check if the prev_smid is actually SMID_SEC_PREFIX, otherwise * a rascal can inject data as just a clear submessage. */ if ((c->security_info.security_attributes & NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED) - == NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED) + == NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED) { if (prev_smid != SMID_SEC_PREFIX) - { return false; - } } /* At this point, we should also check if the complete RTPS message was encoded when * that is expected. */ - if (q_omg_security_is_remote_rtps_protected(proxypp, e->guid.entityid) && !rst->rtps_encoded) + if (q_omg_security_is_remote_rtps_protected (proxypp, e->guid.entityid) && !rst->rtps_encoded) { return false; } @@ -1154,214 +899,233 @@ validate_msg_decoding( return true; } -static int -validate_submsg(struct q_globals *gv, unsigned char smid, unsigned char *submsg, unsigned char * const end, int byteswap) +static int32_t validate_submsg (struct q_globals *gv, SubmessageKind_t smid, const unsigned char *submsg, unsigned char const * const end, int byteswap) { - int result = -1; - if ((submsg + RTPS_SUBMESSAGE_HEADER_SIZE) <= end) + assert (end >= submsg); + if ((size_t) (end - submsg) < RTPS_SUBMESSAGE_HEADER_SIZE) { - SubmessageHeader_t *hdr = (SubmessageHeader_t*)submsg; - if ((smid == 0 /* don't care */) || (hdr->submessageId == smid)) - { - unsigned short size = hdr->octetsToNextHeader; - if (byteswap) - { - size = ddsrt_bswap2u(size); - } - result = (int)size + (int)RTPS_SUBMESSAGE_HEADER_SIZE; - if ((submsg + result) > end) - { - result = -1; - } - } - else - { - GVWARNING("Unexpected submsg 0x%02x (0x%02x expected)", hdr->submessageId, smid); - } + GVWARNING ("Submsg 0x%02x does not fit message", smid); + return -1; } - else + + SubmessageHeader_t const * const hdr = (SubmessageHeader_t *) submsg; + if (hdr->submessageId != smid && smid != SMID_PAD) { - GVWARNING("Submsg 0x%02x does not fit message", smid); + GVWARNING("Unexpected submsg 0x%02x (0x%02x expected)", hdr->submessageId, smid); + return -1; + } + + uint16_t size = hdr->octetsToNextHeader; + if (byteswap) + size = ddsrt_bswap2u (size); + const int32_t result = (int32_t) size + (int32_t) RTPS_SUBMESSAGE_HEADER_SIZE; + if (end - submsg < result) + { + GVWARNING ("Submsg 0x%02x does not fit message", smid); + return -1; } return result; } - -static int -padding_submsg(struct q_globals *gv, unsigned char *start, unsigned char *end, int byteswap) +static int32_t padding_submsg (struct q_globals *gv, unsigned char *start, unsigned char *end, int byteswap) { - SubmessageHeader_t *padding = (SubmessageHeader_t*)start; - size_t size = (size_t)(end - start); - int result = -1; - - assert(start <= end); - - if (size > sizeof(SubmessageHeader_t)) - { - result = (int)size; - padding->submessageId = SMID_PAD; - padding->flags = (byteswap ? !(DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) : (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN)); - padding->octetsToNextHeader = (unsigned short)(size - sizeof(SubmessageHeader_t)); - if (byteswap) - { - padding->octetsToNextHeader = ddsrt_bswap2u(padding->octetsToNextHeader); - } - } - else + assert (end >= start); + const size_t size = (size_t) (end - start); + if (size < RTPS_SUBMESSAGE_HEADER_SIZE) { GVWARNING("Padding submessage doesn't fit"); + return -1; } - return result; + + assert (size <= UINT16_MAX + RTPS_SUBMESSAGE_HEADER_SIZE); + SubmessageHeader_t * const padding = (SubmessageHeader_t *) start; + padding->submessageId = SMID_PAD; + DDSRT_STATIC_ASSERT (SMFLAG_ENDIANNESS == 1); + padding->flags = (byteswap ? !(DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) : (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN)); + padding->octetsToNextHeader = (uint16_t) (size - RTPS_SUBMESSAGE_HEADER_SIZE); + if (byteswap) + padding->octetsToNextHeader = ddsrt_bswap2u (padding->octetsToNextHeader); + return (int32_t) size; } -int -decode_SecPrefix( - struct receiver_state *rst, - unsigned char *submsg, - size_t submsg_size, - unsigned char * const msg_end, - const ddsi_guid_prefix_t * const src_prefix, - const ddsi_guid_prefix_t * const dst_prefix, - int byteswap) +static bool decode_SecPrefix_patched_hdr_flags (const struct receiver_state *rst, unsigned char *submsg, size_t submsg_size, unsigned char * const msg_end, const ddsi_guid_prefix_t * const src_prefix, const ddsi_guid_prefix_t * const dst_prefix, int byteswap) { - int result = -1; - int totalsize = (int)submsg_size; + int smsize = -1; + size_t totalsize = submsg_size; unsigned char *body_submsg; unsigned char *prefix_submsg; unsigned char *postfix_submsg; - SubmessageHeader_t *hdr = (SubmessageHeader_t*)submsg; - uint8_t flags = hdr->flags; - - if (byteswap) - { - if ((DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN)) - hdr->flags |= 0x01; - else - hdr->flags &= 0xFE; - } /* First sub-message is the SEC_PREFIX. */ prefix_submsg = submsg; /* Next sub-message is SEC_BODY when encrypted or the original submessage when only signed. */ body_submsg = submsg + submsg_size; - result = validate_submsg(rst->gv, 0 /* don't care smid */, body_submsg, msg_end, byteswap); - if (result > 0) + if ((smsize = validate_submsg (rst->gv, SMID_PAD, body_submsg, msg_end, byteswap)) <= 0) + return false; + totalsize += (size_t) smsize; + + /* Third sub-message should be the SEC_POSTFIX. */ + postfix_submsg = submsg + totalsize; + if ((smsize = validate_submsg (rst->gv, SMID_SEC_POSTFIX, postfix_submsg, msg_end, byteswap)) <= 0) + return false; + totalsize += (size_t) smsize; + + /* Decode all three submessages. */ + unsigned char *dst_buf; + size_t dst_len; + const bool decoded = q_omg_security_decode_submessage (src_prefix, dst_prefix, submsg, totalsize, &dst_buf, &dst_len); + if (decoded && dst_buf) { - totalsize += result; - - /* Third sub-message should be the SEC_POSTFIX. */ - postfix_submsg = submsg + totalsize; - result = validate_submsg(rst->gv, SMID_SEC_POSTFIX, postfix_submsg, msg_end, byteswap); - if (result > 0) + /* + * The 'normal' submessage sequence handling will continue after the + * given security SEC_PREFIX. + */ + SubmessageHeader_t const * const body_submsg_hdr = (SubmessageHeader_t const *) body_submsg; + if (body_submsg_hdr->submessageId == SMID_SEC_BODY) { - bool decoded; - unsigned char *dst_buf; - unsigned int dst_len; + /* + * Copy the decoded buffer into the original message, replacing (part + * of) SEC_BODY. + * + * By replacing the SEC_BODY with the decoded submessage, everything + * can continue as if there was never an encoded submessage. + */ + assert (totalsize >= submsg_size); + assert (dst_len <= totalsize - submsg_size); + memcpy (body_submsg, dst_buf, dst_len); - totalsize += result; - - /* Decode all three submessages. */ - decoded = q_omg_security_decode_submessage(src_prefix, dst_prefix, submsg, (unsigned int)totalsize, &dst_buf, &dst_len); - if (decoded && dst_buf) - { - /* - * The 'normal' submessage sequence handling will continue after the - * given security SEC_PREFIX. - */ - if (*body_submsg == SMID_SEC_BODY) - { - /* - * Copy the decoded buffer into the original message, replacing (part - * of) SEC_BODY. - * - * By replacing the SEC_BODY with the decoded submessage, everything - * can continue as if there was never an encoded submessage. - */ - assert((int)dst_len <= ((int)totalsize - (int)submsg_size)); - memcpy(body_submsg, dst_buf, dst_len); - - /* Remainder of SEC_BODY & SEC_POSTFIX should be padded to keep the submsg sequence going. */ - result = padding_submsg(rst->gv, body_submsg + dst_len, prefix_submsg + totalsize, byteswap); - } - else - { - /* - * When only signed, then the submessage is already available and - * SMID_SEC_POSTFIX will be ignored. - * So, we don't really have to do anything. - */ - } - ddsrt_free(dst_buf); - } - else - { - /* - * Decoding or signing failed. - * - * Replace the security submessages with padding. This also removes a plain - * submessage when a signature check failed. - */ - result = padding_submsg(rst->gv, body_submsg, prefix_submsg + totalsize, byteswap); - } - } - } - /* Restore flags. */ - hdr->flags = flags; - return result; -} - -static nn_rtps_msg_state_t -check_rtps_message_is_secure( - struct q_globals *gv, - Header_t *hdr, - unsigned char *buff, - bool isstream, - struct proxy_participant **proxypp) -{ - nn_rtps_msg_state_t ret = NN_RTPS_MSG_STATE_ERROR; - - SubmessageHeader_t *submsg; - uint32_t offset = RTPS_MESSAGE_HEADER_SIZE + (isstream ? sizeof(MsgLen_t) : 0); - - submsg = (SubmessageHeader_t *)(buff + offset); - if (submsg->submessageId == SMID_SRTPS_PREFIX) - { - ddsi_guid_t guid; - - guid.prefix = hdr->guid_prefix; - guid.entityid.u = NN_ENTITYID_PARTICIPANT; - - GVTRACE(" from "PGUIDFMT, PGUID(guid)); - - *proxypp = entidx_lookup_proxy_participant_guid(gv->entity_index, &guid); - if (*proxypp) - { - if (q_omg_proxyparticipant_is_authenticated(*proxypp)) - { - ret = NN_RTPS_MSG_STATE_ENCODED; - } - else - { - GVTRACE ("received encoded rtps message from unauthenticated participant"); - } + /* Remainder of SEC_BODY & SEC_POSTFIX should be padded to keep the submsg sequence going. */ + smsize = padding_submsg (rst->gv, body_submsg + dst_len, prefix_submsg + totalsize, byteswap); } else { - GVTRACE ("received encoded rtps message from unknown participant"); + /* + * When only signed, then the submessage is already available and + * SMID_SEC_POSTFIX will be ignored. + * So, we don't really have to do anything. + */ } - GVTRACE("\n"); + ddsrt_free (dst_buf); } else { - ret = NN_RTPS_MSG_STATE_PLAIN; + /* + * Decoding or signing failed. + * + * Replace the security submessages with padding. This also removes a plain + * submessage when a signature check failed. + */ + smsize = padding_submsg (rst->gv, body_submsg, prefix_submsg + totalsize, byteswap); } - return ret; + return (smsize > 0); +} + +bool decode_SecPrefix (const struct receiver_state *rst, unsigned char *submsg, size_t submsg_size, unsigned char * const msg_end, const ddsi_guid_prefix_t * const src_prefix, const ddsi_guid_prefix_t * const dst_prefix, int byteswap) +{ + /* FIXME: eliminate the patching of hdr->flags if possible */ + SubmessageHeader_t *hdr = (SubmessageHeader_t *) submsg; + const uint8_t saved_flags = hdr->flags; + if (byteswap) + { + if (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) + hdr->flags |= 0x01; + else + hdr->flags &= 0xFE; + } + bool result = decode_SecPrefix_patched_hdr_flags (rst, submsg, submsg_size, msg_end, src_prefix, dst_prefix, byteswap); + hdr->flags = saved_flags; + return result; +} + +static nn_rtps_msg_state_t check_rtps_message_is_secure (struct q_globals *gv, Header_t *hdr, const unsigned char *buff, bool isstream, struct proxy_participant **proxypp) +{ + const uint32_t offset = RTPS_MESSAGE_HEADER_SIZE + (isstream ? sizeof (MsgLen_t) : 0); + const SubmessageHeader_t *submsg = (const SubmessageHeader_t *) (buff + offset); + if (submsg->submessageId != SMID_SRTPS_PREFIX) + return NN_RTPS_MSG_STATE_PLAIN; + + ddsi_guid_t guid; + guid.prefix = hdr->guid_prefix; + guid.entityid.u = NN_ENTITYID_PARTICIPANT; + + GVTRACE (" from "PGUIDFMT, PGUID (guid)); + + if ((*proxypp = entidx_lookup_proxy_participant_guid (gv->entity_index, &guid)) == NULL) + { + GVTRACE ("received encoded rtps message from unknown participant\n"); + return NN_RTPS_MSG_STATE_ERROR; + } + else if (!q_omg_proxyparticipant_is_authenticated (*proxypp)) + { + GVTRACE ("received encoded rtps message from unauthenticated participant\n"); + return NN_RTPS_MSG_STATE_ERROR; + } + else + { + return NN_RTPS_MSG_STATE_ENCODED; + } +} + +static nn_rtps_msg_state_t +decode_rtps_message_awake ( + struct nn_rmsg **rmsg, + Header_t **hdr, + unsigned char **buff, + ssize_t *sz, + struct nn_rbufpool *rbpool, + bool isstream, + struct proxy_participant *proxypp) +{ + unsigned char *dstbuf; + unsigned char *srcbuf; + size_t srclen, dstlen; + + /* Currently the decode_rtps_message returns a new allocated buffer. + * This could be optimized by providing a pre-allocated nn_rmsg buffer to + * copy the decoded rtps message in. + */ + if (isstream) + { + /* Remove MsgLen Submessage which was only needed for a stream to determine the end of the message */ + assert (*sz > (ssize_t) sizeof (MsgLen_t)); + srcbuf = *buff + sizeof (MsgLen_t); + srclen = (size_t) *sz - sizeof (MsgLen_t); + memmove (srcbuf, *buff, RTPS_MESSAGE_HEADER_SIZE); + } + else + { + assert (*sz > 0); + srcbuf = *buff; + srclen = (size_t) *sz; + } + + if (!q_omg_security_decode_rtps_message (proxypp, srcbuf, srclen, &dstbuf, &dstlen)) + return NN_RTPS_MSG_STATE_ERROR; + else + { + assert (dstlen <= UINT32_MAX); + + nn_rmsg_commit (*rmsg); + *rmsg = nn_rmsg_new (rbpool); + *buff = NN_RMSG_PAYLOAD (*rmsg); + + memcpy(*buff, dstbuf, dstlen); + nn_rmsg_setsize (*rmsg, (uint32_t) dstlen); + + ddsrt_free (dstbuf); + + *hdr = (Header_t *) *buff; + (*hdr)->guid_prefix = nn_ntoh_guid_prefix ((*hdr)->guid_prefix); + *sz = (ssize_t) dstlen; + assert ((size_t) *sz == dstlen); + return NN_RTPS_MSG_STATE_ENCODED; + } } nn_rtps_msg_state_t -decode_rtps_message( +decode_rtps_message ( struct thread_state1 * const ts1, struct q_globals *gv, struct nn_rmsg **rmsg, @@ -1371,54 +1135,12 @@ decode_rtps_message( struct nn_rbufpool *rbpool, bool isstream) { - nn_rtps_msg_state_t ret = NN_RTPS_MSG_STATE_ERROR; - struct proxy_participant *proxypp = NULL; - unsigned char *dstbuf; - unsigned char *srcbuf; - uint32_t srclen, dstlen; - bool decoded; - - /* Currently the decode_rtps_message returns a new allocated buffer. - * This could be optimized by providing a pre-allocated nn_rmsg buffer to - * copy the decoded rtps message in. - */ + struct proxy_participant *proxypp; + nn_rtps_msg_state_t ret; thread_state_awake_fixed_domain (ts1); - ret = check_rtps_message_is_secure(gv, *hdr, *buff, isstream, &proxypp); + ret = check_rtps_message_is_secure (gv, *hdr, *buff, isstream, &proxypp); if (ret == NN_RTPS_MSG_STATE_ENCODED) - { - if (isstream) - { - /* Remove MsgLen Submessage which was only needed for a stream to determine the end of the message */ - srcbuf = *buff + sizeof(MsgLen_t); - srclen = (uint32_t)((size_t)(*sz) - sizeof(MsgLen_t)); - memmove(srcbuf, *buff, RTPS_MESSAGE_HEADER_SIZE); - } - else - { - srcbuf = *buff; - srclen = (uint32_t)*sz; - } - - decoded = q_omg_security_decode_rtps_message(proxypp, srcbuf, srclen, &dstbuf, &dstlen); - if (decoded) - { - nn_rmsg_commit (*rmsg); - *rmsg = nn_rmsg_new (rbpool); - - *buff = (unsigned char *) NN_RMSG_PAYLOAD (*rmsg); - - memcpy(*buff, dstbuf, dstlen); - nn_rmsg_setsize (*rmsg, dstlen); - - ddsrt_free(dstbuf); - - *hdr = (Header_t*) *buff; - (*hdr)->guid_prefix = nn_ntoh_guid_prefix ((*hdr)->guid_prefix); - *sz = (ssize_t)dstlen; - } else { - ret = NN_RTPS_MSG_STATE_ERROR; - } - } + ret = decode_rtps_message_awake (rmsg, hdr, buff, sz, rbpool, isstream, proxypp); thread_state_asleep (ts1); return ret; } @@ -1435,15 +1157,12 @@ secure_conn_write( nn_msg_sec_info_t *sec_info, ddsi_tran_write_fn_t conn_write_cb) { - ssize_t ret = -1; - - unsigned i; Header_t *hdr; ddsi_guid_t guid; unsigned char stbuf[2048]; unsigned char *srcbuf; - unsigned char *dstbuf = NULL; - uint32_t srclen, dstlen; + unsigned char *dstbuf; + size_t srclen, dstlen; int64_t dst_handle = 0; assert(iov); @@ -1461,41 +1180,40 @@ secure_conn_write( } } - hdr = (Header_t *)iov[0].iov_base; - guid.prefix = nn_ntoh_guid_prefix(hdr->guid_prefix); + hdr = (Header_t *) iov[0].iov_base; + guid.prefix = nn_ntoh_guid_prefix (hdr->guid_prefix); guid.entityid.u = NN_ENTITYID_PARTICIPANT; /* first determine the size of the message, then select the * on-stack buffer or allocate one on the heap ... */ srclen = 0; - for (i = 0; i < (unsigned)niov; i++) + for (size_t i = 0; i < niov; i++) { /* Do not copy MsgLen submessage in case of a stream connection */ - if ((i != 1) || !conn->m_stream) - srclen += (uint32_t) iov[i].iov_len; + if (i != 1 || !conn->m_stream) + srclen += iov[i].iov_len; } if (srclen <= sizeof (stbuf)) - { srcbuf = stbuf; - } else - { srcbuf = ddsrt_malloc (srclen); - } /* ... then copy data into buffer */ srclen = 0; - for (i = 0; i < (unsigned)niov; i++) + for (size_t i = 0; i < niov; i++) { - if ((i != 1) || !conn->m_stream) + if (i != 1 || !conn->m_stream) { - memcpy(srcbuf + srclen, iov[i].iov_base, iov[i].iov_len); - srclen += (uint32_t) iov[i].iov_len; + memcpy (srcbuf + srclen, iov[i].iov_base, iov[i].iov_len); + srclen += iov[i].iov_len; } } - if (q_omg_security_encode_rtps_message(sec_info->src_pp_handle, &guid, srcbuf, srclen, &dstbuf, &dstlen, dst_handle)) + ssize_t ret = -1; + if (!q_omg_security_encode_rtps_message (sec_info->src_pp_handle, &guid, srcbuf, srclen, &dstbuf, &dstlen, dst_handle)) + ret = -1; + else { ddsrt_iovec_t tmp_iov[3]; size_t tmp_niov; @@ -1503,34 +1221,32 @@ secure_conn_write( if (conn->m_stream) { /* Add MsgLen submessage after Header */ - msg_len->length = dstlen + (uint32_t)sizeof(*msg_len); + assert (dstlen <= UINT32_MAX - sizeof (*msg_len)); + msg_len->length = (uint32_t) (dstlen + sizeof (*msg_len)); tmp_iov[0].iov_base = dstbuf; tmp_iov[0].iov_len = RTPS_MESSAGE_HEADER_SIZE; - tmp_iov[1].iov_base = (void*) msg_len; + tmp_iov[1].iov_base = (void *) msg_len; tmp_iov[1].iov_len = sizeof (*msg_len); tmp_iov[2].iov_base = dstbuf + RTPS_MESSAGE_HEADER_SIZE; - tmp_iov[2].iov_len = dstlen - RTPS_MESSAGE_HEADER_SIZE; + tmp_iov[2].iov_len = (ddsrt_iov_len_t) (dstlen - RTPS_MESSAGE_HEADER_SIZE); tmp_niov = 3; } else { - msg_len->length = dstlen; + assert (dstlen <= UINT32_MAX); + msg_len->length = (uint32_t) dstlen; tmp_iov[0].iov_base = dstbuf; - tmp_iov[0].iov_len = dstlen; + tmp_iov[0].iov_len = (ddsrt_iov_len_t) dstlen; tmp_niov = 1; } ret = conn_write_cb (conn, dst, tmp_niov, tmp_iov, flags); + ddsrt_free (dstbuf); } if (srcbuf != stbuf) - { ddsrt_free (srcbuf); - } - - ddsrt_free(dstbuf); - return ret; } @@ -1538,7 +1254,6 @@ secure_conn_write( #include "dds/ddsi/ddsi_security_omg.h" - extern inline bool q_omg_participant_is_secure(UNUSED_ARG(const struct participant *pp)); extern inline bool q_omg_proxy_participant_is_secure(const struct proxy_participant *proxypp); extern inline bool q_omg_security_enabled(void); diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index d519ed6..498e069 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -1084,7 +1084,7 @@ int rtps_init (struct q_globals *gv) add_property_to_xqos(&gv->builtin_volatile_xqos_rd, "dds.sec.builtin_endpoint_name", "BuiltinParticipantVolatileMessageSecureReader"); add_property_to_xqos(&gv->builtin_volatile_xqos_wr, "dds.sec.builtin_endpoint_name", "BuiltinParticipantVolatileMessageSecureWriter"); - q_omg_security_init( &gv->security_context ); + q_omg_security_init( &gv->security_context, &gv->logconfig ); #endif make_special_topics (gv); diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index 0714714..42f874d 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -3068,7 +3068,7 @@ static int handle_submsg_sequence state = "parse:sec_prefix"; { GVTRACE ("SEC_PREFIX"); - if (decode_SecPrefix(rst, submsg, submsg_size, end, &rst->src_guid_prefix, &rst->dst_guid_prefix, byteswap) < 0) + if (!decode_SecPrefix(rst, submsg, submsg_size, end, &rst->src_guid_prefix, &rst->dst_guid_prefix, byteswap)) goto malformed; } break; diff --git a/src/security/builtin_plugins/cryptographic/src/crypto_defs.h b/src/security/builtin_plugins/cryptographic/src/crypto_defs.h index a0fdf2a..5947f29 100644 --- a/src/security/builtin_plugins/cryptographic/src/crypto_defs.h +++ b/src/security/builtin_plugins/cryptographic/src/crypto_defs.h @@ -111,4 +111,4 @@ typedef enum RTPS_Message_Type RTPS_Message_Type_SRTPS_POSTFIX = 0x34 } RTPS_Message_Type; -#endif /* CRYPTO_DEFS_H */ \ No newline at end of file +#endif /* CRYPTO_DEFS_H */ diff --git a/src/security/builtin_plugins/tests/common/src/crypto_helper.h b/src/security/builtin_plugins/tests/common/src/crypto_helper.h index ad64fcb..775a1d7 100644 --- a/src/security/builtin_plugins/tests/common/src/crypto_helper.h +++ b/src/security/builtin_plugins/tests/common/src/crypto_helper.h @@ -35,4 +35,5 @@ int master_salt_not_empty(master_key_material *keymat); int master_key_not_empty(master_key_material *keymat); int master_receiver_specific_key_not_empty(master_key_material *keymat); -#endif /* DDS_SECURITY_BUITIN_TEST_CRYPTO_HELPER_H */ \ No newline at end of file +#endif /* DDS_SECURITY_BUITIN_TEST_CRYPTO_HELPER_H */ + diff --git a/src/security/builtin_plugins/tests/common/src/handshake_helper.h b/src/security/builtin_plugins/tests/common/src/handshake_helper.h index b6e2e38..ac3ec24 100644 --- a/src/security/builtin_plugins/tests/common/src/handshake_helper.h +++ b/src/security/builtin_plugins/tests/common/src/handshake_helper.h @@ -87,4 +87,4 @@ check_shared_secret( EVP_PKEY *dh_local_private, DDS_Security_HandshakeHandle handshake_handle); -#endif \ No newline at end of file +#endif diff --git a/src/security/builtin_plugins/tests/validate_local_identity/src/validate_local_identity_utests.c b/src/security/builtin_plugins/tests/validate_local_identity/src/validate_local_identity_utests.c index b4c7067..5d17ebd 100644 --- a/src/security/builtin_plugins/tests/validate_local_identity/src/validate_local_identity_utests.c +++ b/src/security/builtin_plugins/tests/validate_local_identity/src/validate_local_identity_utests.c @@ -2106,4 +2106,4 @@ CU _ Test(validate_local_identity,with_extended_certificate_check) } -#endif \ No newline at end of file +#endif diff --git a/src/security/core/include/dds/security/core/dds_security_plugins.h b/src/security/core/include/dds/security/core/dds_security_plugins.h index da5d2ad..3a28e43 100644 --- a/src/security/core/include/dds/security/core/dds_security_plugins.h +++ b/src/security/core/include/dds/security/core/dds_security_plugins.h @@ -20,6 +20,8 @@ #include #include "dds/security/dds_security_api.h" +struct ddsrt_log_cfg; + typedef struct dds_security_plugin { ddsrt_dynlib_t lib_handle; plugin_init func_init; @@ -50,16 +52,19 @@ DDS_EXPORT dds_return_t dds_security_plugin_release( void *context ); DDS_EXPORT dds_return_t dds_security_check_plugin_configuration( - const dds_security_plugin_suite_config *security_suite_config ); + const dds_security_plugin_suite_config *security_suite_config, + const struct ddsrt_log_cfg *logcfg); DDS_EXPORT dds_return_t dds_security_load_security_library( const dds_security_plugin_config *plugin_config, - dds_security_plugin *security_plugin, void **security_plugin_context); + dds_security_plugin *security_plugin, void **security_plugin_context, + const struct ddsrt_log_cfg *logcfg); DDS_EXPORT dds_return_t dds_security_verify_plugin_functions( dds_security_authentication *authentication_context, dds_security_plugin *auth_plugin, dds_security_cryptography *crypto_context, dds_security_plugin *crypto_plugin, - dds_security_access_control *access_control_context, dds_security_plugin *ac_plugin); + dds_security_access_control *access_control_context, dds_security_plugin *ac_plugin, + const struct ddsrt_log_cfg *logcfg); #endif /* SECURITY_CORE_PLUGINS_H_ */ diff --git a/src/security/core/src/dds_security_plugins.c b/src/security/core/src/dds_security_plugins.c index 942e94b..bfc75a4 100644 --- a/src/security/core/src/dds_security_plugins.c +++ b/src/security/core/src/dds_security_plugins.c @@ -10,395 +10,257 @@ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ #include +#include -#include "dds/ddsrt/misc.h" - -#include "dds/security/core/dds_security_utils.h" #include "dds/security/core/dds_security_plugins.h" -#include "dds/security/dds_security_api.h" -#include "dds/ddsi/q_unused.h" -#include "dds/ddsi/ddsi_security_msg.h" -#include "dds/ddsi/ddsi_security_omg.h" - - -#include "dds/ddsi/q_config.h" -#include "dds/ddsi/q_log.h" +#include "dds/ddsrt/log.h" #include "dds/ddsrt/atomics.h" #include "dds/ddsrt/heap.h" #include "dds/ddsrt/dynlib.h" -#include "dds/ddsrt/process.h" -#include "dds/ddsrt/string.h" -#include "dds/ddsrt/sync.h" -#include "dds/ddsrt/hopscotch.h" - -#include "dds/ddsi/q_entity.h" -#include "dds/ddsi/q_bswap.h" -#include "dds/ddsi/q_xevent.h" -#include "dds/ddsi/q_time.h" -#include "dds/ddsi/q_plist.h" #include "dds/ddsrt/io.h" - - -#define AUTH_NAME "Authentication" -#define AC_NAME "Access Control" -#define CRYPTO_NAME "Cryptographic" - -dds_return_t dds_security_check_plugin_configuration( - const dds_security_plugin_suite_config *security_suite_config ) +static bool check_plugin_configuration (const dds_security_plugin_config *config, const char *name, const struct ddsrt_log_cfg *logcfg) { - - dds_return_t result = DDS_RETCODE_ERROR; - - if (security_suite_config->access_control.library_path == NULL) { - DDS_ERROR("AccessControl security plugin library path is not defined"); - } else if (strlen(security_suite_config->access_control.library_path) - == 0) { - DDS_ERROR("AccessControl security plugin library path is empty "); - } else if (security_suite_config->access_control.library_init == NULL) { - DDS_ERROR("AccessControl security plugin init function is not defined"); - } else if (strlen(security_suite_config->access_control.library_init) - == 0) { - DDS_ERROR("AccessControl security plugin init function is empty "); - } else if (security_suite_config->access_control.library_finalize == NULL) { - DDS_ERROR( - "AccessControl security plugin finalize function is not defined "); - } else if (strlen(security_suite_config->access_control.library_finalize) - == 0) { - DDS_ERROR("AccessControl security plugin finalize function is empty"); - } else if (security_suite_config->authentication.library_path == NULL) { - DDS_ERROR( - "Authentication security plugin library path is not defined in the configuration "); - } else if (strlen(security_suite_config->authentication.library_path) - == 0) { - DDS_ERROR("Authentication security plugin library path is empty "); - } else if (security_suite_config->authentication.library_init == NULL) { - DDS_ERROR("Authentication security plugin init function is not defined "); - } else if (strlen(security_suite_config->authentication.library_init) - == 0) { - DDS_ERROR("Authentication security plugin init function is empty "); - } else if (security_suite_config->authentication.library_finalize == NULL) { - DDS_ERROR( - "Authentication security plugin finalize function is not defined "); - } else if (strlen(security_suite_config->authentication.library_finalize) - == 0) { - DDS_ERROR("Authentication security plugin finalize function is empty"); - } else if (security_suite_config->cryptography.library_path == NULL) { - DDS_ERROR( - "Cryptography security plugin library path is not defined in the configuration "); - } else if (strlen(security_suite_config->cryptography.library_path) - == 0) { - DDS_ERROR("Cryptography security plugin library path is empty "); - } else if (security_suite_config->cryptography.library_init == NULL) { - DDS_ERROR("Cryptography security plugin init function is not defined "); - } else if (strlen(security_suite_config->cryptography.library_init) - == 0) { - DDS_ERROR("Cryptography security plugin init function is empty "); - } else if (security_suite_config->cryptography.library_finalize == NULL) { - DDS_ERROR("Cryptography security plugin finalize function is not defined "); - } else if (strlen(security_suite_config->cryptography.library_finalize) - == 0) { - DDS_ERROR("Cryptography security plugin finalize function is empty"); - } else { - result = DDS_RETCODE_OK; - } - - return result; -} - -/* - * checks the function pointer value and CHANGES the out-result value if it is NULL - */ -static bool verify_function(void *function_ptr, dds_security_plugin *plugin, - const char *function_name) -{ - - if ( function_ptr == NULL ) { - DDS_ERROR("Could not find the function for %s: %s \n", plugin->name, - function_name); + if (config->library_path == NULL || *config->library_path == 0) { + DDS_CERROR (logcfg, "%s security plugin library path is undefined or empty\n", name); return false; } - else { - return true; + if (config->library_init == NULL || *config->library_init == 0) { + DDS_CERROR (logcfg, "%s security plugin init function is undefined or empty\n", name); + return false; } + if (config->library_finalize == NULL || *config->library_finalize == 0) { + DDS_CERROR (logcfg, "%s security plugin finalize function is undefined or empty\n", name); + return false; + } + return true; +} + +dds_return_t dds_security_check_plugin_configuration (const dds_security_plugin_suite_config *security_suite_config, const struct ddsrt_log_cfg *logcfg) +{ + if (check_plugin_configuration (&security_suite_config->access_control, "AccessControl", logcfg) && + check_plugin_configuration (&security_suite_config->authentication, "Authentication", logcfg) && + check_plugin_configuration (&security_suite_config->cryptography, "Cryptography", logcfg)) + return DDS_RETCODE_OK; + else + return DDS_RETCODE_ERROR; +} + +static bool verify_function (const void *function_ptr, dds_security_plugin *plugin, const char *function_name, const struct ddsrt_log_cfg *logcfg) +{ + if (function_ptr != NULL) + return true; + else + { + DDS_CERROR (logcfg, "Could not find the function for %s: %s\n", plugin->name, function_name); + return false; + } +} + +struct verify_plugin_functions_tab { + size_t off; + const char *name; +}; + +static bool verify_plugin_functions (const void *context, dds_security_plugin *plugin, const struct verify_plugin_functions_tab *entries, size_t nentries, const struct ddsrt_log_cfg *logcfg) +{ + for (size_t i = 0; i < nentries; i++) + { + const char *p = (const char *) context + entries[i].off; + if (!verify_function (*((void **) p), plugin, entries[i].name, logcfg)) + return false; + } + return true; } dds_return_t dds_security_verify_plugin_functions( dds_security_authentication *authentication_context, dds_security_plugin *auth_plugin, dds_security_cryptography *crypto_context, dds_security_plugin *crypto_plugin, - dds_security_access_control *access_control_context, dds_security_plugin *ac_plugin) + dds_security_access_control *access_control_context, dds_security_plugin *ac_plugin, + const struct ddsrt_log_cfg *logcfg) { - - if( - verify_function(authentication_context->validate_local_identity, auth_plugin, - "validate_local_identity" ) && - verify_function(authentication_context->get_identity_token, auth_plugin, - "get_identity_token" ) && - verify_function(authentication_context->get_identity_status_token, - auth_plugin, "get_identity_status_token" ) && - verify_function(authentication_context->set_permissions_credential_and_token, - auth_plugin, "set_permissions_credential_and_token" ) && - verify_function(authentication_context->validate_remote_identity, - auth_plugin, "validate_remote_identity" ) && - verify_function(authentication_context->begin_handshake_request, auth_plugin, - "begin_handshake_request" ) && - verify_function(authentication_context->begin_handshake_reply, auth_plugin, - "begin_handshake_reply" ) && - verify_function(authentication_context->process_handshake, auth_plugin, - "process_handshake" ) && - verify_function(authentication_context->get_shared_secret, auth_plugin, - "get_shared_secret" ) && - verify_function( - authentication_context->get_authenticated_peer_credential_token, - auth_plugin, "get_authenticated_peer_credential_token" ) && - verify_function(authentication_context->set_listener, auth_plugin, - "set_listener" ) && - verify_function(authentication_context->return_identity_token, auth_plugin, - "return_identity_token" ) && - verify_function(authentication_context->return_identity_status_token, - auth_plugin, "return_identity_status_token" ) && - - verify_function( - authentication_context->return_authenticated_peer_credential_token, - auth_plugin, "return_authenticated_peer_credential_token" ) && - verify_function(authentication_context->return_handshake_handle, auth_plugin, - "return_handshake_handle" ) && - verify_function(authentication_context->return_identity_handle, auth_plugin, - "return_identity_handle" ) && - verify_function(authentication_context->return_sharedsecret_handle, - auth_plugin, "return_sharedsecret_handle" ) && - - verify_function(access_control_context->validate_local_permissions, - ac_plugin, "validate_local_permissions" ) && - verify_function(access_control_context->validate_remote_permissions, - ac_plugin, "validate_remote_permissions" ) && - verify_function(access_control_context->check_create_participant, ac_plugin, - "check_create_participant" ) && - verify_function(access_control_context->check_create_datawriter, ac_plugin, - "check_create_datawriter" ) && - verify_function(access_control_context->check_create_datareader, ac_plugin, - "check_create_datareader" ) && - - verify_function(access_control_context->check_create_topic, ac_plugin, - "check_create_topic" ) && - verify_function( - access_control_context->check_local_datawriter_register_instance, - ac_plugin, "check_local_datawriter_register_instance" ) && - verify_function( - access_control_context->check_local_datawriter_dispose_instance, - ac_plugin, "check_local_datawriter_dispose_instance" ) && - verify_function(access_control_context->check_remote_participant, ac_plugin, - "check_remote_participant" ) && - verify_function(access_control_context->check_remote_datawriter, ac_plugin, - "check_remote_datawriter" ) && - verify_function(access_control_context->check_remote_datareader, ac_plugin, - "check_remote_datareader" ) && - verify_function(access_control_context->check_remote_topic, ac_plugin, - "check_remote_topic" ) && - verify_function(access_control_context->check_local_datawriter_match, - ac_plugin, "check_local_datawriter_match" ) && - verify_function(access_control_context->check_local_datareader_match, - ac_plugin, "check_local_datareader_match" ) && - verify_function( - access_control_context->check_remote_datawriter_register_instance, - ac_plugin, "check_remote_datawriter_register_instance" ) && - verify_function( - access_control_context->check_remote_datawriter_dispose_instance, - ac_plugin, "check_remote_datawriter_dispose_instance" ) && - verify_function(access_control_context->get_permissions_token, ac_plugin, - "get_permissions_token" ) && - verify_function(access_control_context->get_permissions_credential_token, - ac_plugin, "get_permissions_credential_token" ) && - verify_function(access_control_context->set_listener, ac_plugin, - "set_listener" ) && - verify_function(access_control_context->return_permissions_token, ac_plugin, - "return_permissions_token" ) && - verify_function(access_control_context->return_permissions_credential_token, - ac_plugin, "return_permissions_credential_token" ) && - verify_function(access_control_context->get_participant_sec_attributes, - ac_plugin, "get_participant_sec_attributes" ) && - verify_function(access_control_context->get_topic_sec_attributes, ac_plugin, - "get_topic_sec_attributes" ) && - verify_function(access_control_context->get_datawriter_sec_attributes, - ac_plugin, "get_datawriter_sec_attributes" ) && - verify_function(access_control_context->get_datareader_sec_attributes, - ac_plugin, "get_datareader_sec_attributes" ) && - verify_function(access_control_context->return_participant_sec_attributes, - ac_plugin, "return_participant_sec_attributes" ) && - verify_function(access_control_context->return_datawriter_sec_attributes, - ac_plugin, "return_datawriter_sec_attributes" ) && - verify_function(access_control_context->return_datareader_sec_attributes, - ac_plugin, "return_datareader_sec_attributes" ) && - verify_function(access_control_context->return_permissions_handle, - ac_plugin, "return_permissions_handle" ) && - - verify_function( - crypto_context->crypto_key_factory->register_local_participant, - crypto_plugin, "register_local_participant" ) && - verify_function( - crypto_context->crypto_key_factory->register_matched_remote_participant, - crypto_plugin, "register_matched_remote_participant" ) && - verify_function(crypto_context->crypto_key_factory->register_local_datawriter, - crypto_plugin, "register_local_datawriter" ) && - verify_function( - crypto_context->crypto_key_factory->register_matched_remote_datareader, - crypto_plugin, "register_matched_remote_datareader" ) && - verify_function(crypto_context->crypto_key_factory->register_local_datareader, - crypto_plugin, "register_local_datareader" ) && - verify_function( - crypto_context->crypto_key_factory->register_matched_remote_datawriter, - crypto_plugin, "register_matched_remote_datawriter" ) && - verify_function(crypto_context->crypto_key_factory->unregister_participant, - crypto_plugin, "unregister_participant" ) && - verify_function(crypto_context->crypto_key_factory->unregister_datawriter, - crypto_plugin, "unregister_datawriter" ) && - verify_function(crypto_context->crypto_key_factory->unregister_datareader, - crypto_plugin, "unregister_datareader" ) && - - verify_function( - crypto_context->crypto_key_exchange->create_local_participant_crypto_tokens, - crypto_plugin, "create_local_participant_crypto_tokens" ) && - verify_function( - crypto_context->crypto_key_exchange->set_remote_participant_crypto_tokens, - crypto_plugin, "set_remote_participant_crypto_tokens" ) && - verify_function( - crypto_context->crypto_key_exchange->create_local_datawriter_crypto_tokens, - crypto_plugin, "create_local_datawriter_crypto_tokens" ) && - verify_function( - crypto_context->crypto_key_exchange->set_remote_datawriter_crypto_tokens, - crypto_plugin, "set_remote_datawriter_crypto_tokens" ) && - verify_function( - crypto_context->crypto_key_exchange->create_local_datareader_crypto_tokens, - crypto_plugin, "create_local_datareader_crypto_tokens" ) && - verify_function( - crypto_context->crypto_key_exchange->set_remote_datareader_crypto_tokens, - crypto_plugin, "set_remote_datareader_crypto_tokens" ) && - verify_function(crypto_context->crypto_key_exchange->return_crypto_tokens, - crypto_plugin, "return_crypto_tokens" ) && - - verify_function(crypto_context->crypto_transform->encode_serialized_payload, - crypto_plugin, "encode_serialized_payload" ) && - verify_function( - crypto_context->crypto_transform->encode_datawriter_submessage, - crypto_plugin, "encode_datawriter_submessage" ) && - verify_function( - crypto_context->crypto_transform->encode_datareader_submessage, - crypto_plugin, "encode_datareader_submessage" ) && - verify_function(crypto_context->crypto_transform->encode_rtps_message, - crypto_plugin, "encode_rtps_message" ) && - verify_function(crypto_context->crypto_transform->decode_rtps_message, - crypto_plugin, "decode_rtps_message" ) && - verify_function(crypto_context->crypto_transform->preprocess_secure_submsg, - crypto_plugin, "preprocess_secure_submsg" ) && - verify_function( - crypto_context->crypto_transform->decode_datawriter_submessage, - crypto_plugin, "decode_datawriter_submessage" ) && - verify_function( - crypto_context->crypto_transform->decode_datareader_submessage, - crypto_plugin, "decode_datareader_submessage" ) && - verify_function(crypto_context->crypto_transform->decode_serialized_payload, - crypto_plugin, "decode_serialized_payload" ) ){ +#define FGEN(context, name) { offsetof (context, name), #name } +#define F(name) FGEN (dds_security_authentication, name) + static const struct verify_plugin_functions_tab auth[] = { + F (validate_local_identity), + F (get_identity_token), + F (get_identity_status_token), + F (set_permissions_credential_and_token), + F (validate_remote_identity), + F (begin_handshake_request), + F (begin_handshake_reply), + F (process_handshake), + F (get_shared_secret), + F (get_authenticated_peer_credential_token), + F (set_listener), + F (return_identity_token), + F (return_identity_status_token), + F (return_authenticated_peer_credential_token), + F (return_handshake_handle), + F (return_sharedsecret_handle) + }; +#undef F +#define F(name) FGEN (dds_security_access_control, name) + static const struct verify_plugin_functions_tab ac[] = { + F (validate_local_permissions), + F (validate_remote_permissions), + F (check_create_participant), + F (check_create_datawriter), + F (check_create_datareader), + F (check_create_topic), + F (check_local_datawriter_register_instance), + F (check_local_datawriter_dispose_instance), + F (check_remote_participant), + F (check_remote_datawriter), + F (check_remote_datareader), + F (check_remote_topic), + F (check_local_datawriter_match), + F (check_local_datareader_match), + F (check_remote_datawriter_register_instance), + F (check_remote_datawriter_dispose_instance), + F (get_permissions_token), + F (get_permissions_credential_token), + F (set_listener), + F (return_permissions_token), + F (return_permissions_credential_token), + F (get_participant_sec_attributes), + F (get_topic_sec_attributes), + F (get_datawriter_sec_attributes), + F (get_datareader_sec_attributes), + F (return_participant_sec_attributes), + F (return_datawriter_sec_attributes), + F (return_datareader_sec_attributes), + F (return_permissions_handle) + }; +#undef F +#define F(name) FGEN (dds_security_crypto_key_factory, name) + static const struct verify_plugin_functions_tab cryptoF[] = { + F (register_local_participant), + F (register_matched_remote_participant), + F (register_local_datawriter), + F (register_matched_remote_datareader), + F (register_local_datareader), + F (register_matched_remote_datawriter), + F (unregister_participant), + F (unregister_datawriter), + F (unregister_datareader) + }; +#undef F +#define F(name) FGEN (dds_security_crypto_key_exchange, name) + static const struct verify_plugin_functions_tab cryptoX[] = { + F (create_local_participant_crypto_tokens), + F (set_remote_participant_crypto_tokens), + F (create_local_datawriter_crypto_tokens), + F (set_remote_datawriter_crypto_tokens), + F (create_local_datareader_crypto_tokens), + F (set_remote_datareader_crypto_tokens), + F (return_crypto_tokens) + }; +#undef F +#define F(name) FGEN (dds_security_crypto_transform, name) + static const struct verify_plugin_functions_tab cryptoT[] = { + F (encode_serialized_payload), + F (encode_datawriter_submessage), + F (encode_datareader_submessage), + F (encode_rtps_message), + F (decode_rtps_message), + F (preprocess_secure_submsg), + F (decode_datawriter_submessage), + F (decode_datareader_submessage), + F (decode_serialized_payload) + }; +#undef F +#define C(context, plugin, table) verify_plugin_functions (context, plugin, table, sizeof (table) / sizeof (table[0]), logcfg) + if (C (authentication_context, auth_plugin, auth) && + C (access_control_context, ac_plugin, ac) && + C (crypto_context->crypto_key_factory, crypto_plugin, cryptoF) && + C (crypto_context->crypto_key_exchange, crypto_plugin, cryptoX) && + C (crypto_context->crypto_transform, crypto_plugin, cryptoT)) + { return DDS_RETCODE_OK; } - else { + else + { return DDS_RETCODE_ERROR; } - +#undef C } /** * All fields of the library properties are supposed to be non-empty */ -dds_return_t dds_security_load_security_library( - const dds_security_plugin_config *plugin_config, - dds_security_plugin *security_plugin, - void **security_plugin_context) +dds_return_t dds_security_load_security_library (const dds_security_plugin_config *plugin_config, dds_security_plugin *security_plugin, void **security_plugin_context, const struct ddsrt_log_cfg *logcfg) { - dds_return_t ret = DDS_RETCODE_ERROR; - dds_return_t lib_ret = DDS_RETCODE_ERROR; - char * init_parameters = ""; + dds_return_t lib_ret; + char *init_parameters = ""; char *library_str; - assert( plugin_config->library_path ); - assert( plugin_config->library_init ); - assert( plugin_config->library_finalize ); + assert (plugin_config->library_path); + assert (plugin_config->library_init); + assert (plugin_config->library_finalize); - if ( strlen(plugin_config->library_path) > 0 ) { + security_plugin->lib_handle = NULL; + if (*plugin_config->library_path == 0) + return DDS_RETCODE_ERROR; - //library_str = ddsrt_malloc(strlen(plugin_config->library_path) + 1); - - if (strncmp(plugin_config->library_path, "file://", 7) == 0) { - (void)ddsrt_asprintf(&library_str, "%s", &plugin_config->library_path[7]); - } else { - (void)ddsrt_asprintf(&library_str, "%s", plugin_config->library_path); - } - - lib_ret = ddsrt_dlopen( library_str, true, &security_plugin->lib_handle); - ddsrt_free(library_str); - if( lib_ret == DDS_RETCODE_OK && security_plugin->lib_handle){ - - /* Get init and fini functions . */ - if ( ddsrt_dlsym(security_plugin->lib_handle, plugin_config->library_init, (void **)&security_plugin->func_init) == DDS_RETCODE_OK){ - if ( ddsrt_dlsym(security_plugin->lib_handle, plugin_config->library_finalize, (void **)&security_plugin->func_finalize) == DDS_RETCODE_OK){ - - /* Initialize plugin. */ - if ( security_plugin->func_init != NULL) { - lib_ret = security_plugin->func_init(init_parameters, (void **) security_plugin_context); - - if (lib_ret == DDS_RETCODE_OK){ /* error occured on init */ - return DDS_RETCODE_OK; - } else{ - DDS_ERROR("Error occured while initializing %s plugin\n", - security_plugin->name); - goto library_error; - } - } - - } - else { - DDS_ERROR("Could not find the function: %s\n", plugin_config->library_finalize); - goto library_error; - } - - - } - else{ - DDS_ERROR("Could not find the function: %s\n",plugin_config->library_init); - goto library_error; - } - - } else { - char buffer[256]; - ddsrt_dlerror(buffer, sizeof(buffer)); - DDS_ERROR("Could not load %s library: %s\n", security_plugin->name, buffer); - goto load_error; - } - - - return ret; + const size_t poff = (strncmp (plugin_config->library_path, "file://", 7) == 0) ? 7 : 0; + (void) ddsrt_asprintf (&library_str, "%s", plugin_config->library_path + poff); + lib_ret = ddsrt_dlopen (library_str, true, &security_plugin->lib_handle); + ddsrt_free (library_str); + if (lib_ret != DDS_RETCODE_OK) + { + char buffer[256]; + ddsrt_dlerror (buffer, sizeof (buffer)); + DDS_CERROR (logcfg, "Could not load %s library: %s\n", security_plugin->name, buffer); + goto load_error; } + void *tmp; + if (ddsrt_dlsym (security_plugin->lib_handle, plugin_config->library_init, &tmp) != DDS_RETCODE_OK) + { + DDS_CERROR (logcfg, "Could not find the function: %s\n", plugin_config->library_init); + goto library_error; + } + security_plugin->func_init = (plugin_init) tmp; + + if (ddsrt_dlsym (security_plugin->lib_handle, plugin_config->library_finalize, &tmp) != DDS_RETCODE_OK) + { + DDS_CERROR (logcfg, "Could not find the function: %s\n", plugin_config->library_finalize); + goto library_error; + } + security_plugin->func_finalize = (plugin_finalize) tmp; + + if (security_plugin->func_init != 0) + { + if (security_plugin->func_init (init_parameters, (void **) security_plugin_context) != DDS_RETCODE_OK) + { + DDS_CERROR (logcfg, "Error occured while initializing %s plugin\n", security_plugin->name); + goto library_error; + } + } + return DDS_RETCODE_OK; library_error: - ddsrt_dlclose(security_plugin->lib_handle); + ddsrt_dlclose (security_plugin->lib_handle); security_plugin->lib_handle = NULL; load_error: - return ret; + return DDS_RETCODE_ERROR; } -dds_return_t dds_security_plugin_release( const dds_security_plugin *security_plugin, void *context ){ - dds_return_t result= DDS_RETCODE_OK; - assert( security_plugin->lib_handle ); - assert( security_plugin->func_finalize ); +dds_return_t dds_security_plugin_release (const dds_security_plugin *security_plugin, void *context) +{ + dds_return_t result = DDS_RETCODE_OK; + assert (security_plugin->lib_handle); + assert (security_plugin->func_finalize); /* if get error from either finalize OR close, return error */ - if( security_plugin->func_finalize( context ) != DDS_RETCODE_OK){ + if (security_plugin->func_finalize (context) != DDS_RETCODE_OK) + { DDS_ERROR("Error occured while finaizing %s plugin", security_plugin->name); result = DDS_RETCODE_ERROR; } - if( ddsrt_dlclose( security_plugin->lib_handle ) != DDS_RETCODE_OK){ + if (ddsrt_dlclose (security_plugin->lib_handle) != DDS_RETCODE_OK){ result = DDS_RETCODE_ERROR; } return result; } -