support delayed endpoint matching (#315)
* support delayed endpoint matching Signed-off-by: Marcel Jordense <marcel.jordense@adlinktech.com> * Update delayed endpoint matching Signed-off-by: Marcel Jordense <marcel.jordense@adlinktech.com>
This commit is contained in:
		
							parent
							
								
									861f19a2ad
								
							
						
					
					
						commit
						b561cb821f
					
				
					 10 changed files with 1282 additions and 19 deletions
				
			
		| 
						 | 
				
			
			@ -20,6 +20,7 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
 | 
			
		|||
    ddsi_mcgroup.c
 | 
			
		||||
    ddsi_security_omg.c
 | 
			
		||||
    ddsi_portmapping.c
 | 
			
		||||
    ddsi_handshake.c
 | 
			
		||||
    ddsi_serdata.c
 | 
			
		||||
    ddsi_serdata_default.c
 | 
			
		||||
    ddsi_sertopic.c
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +78,7 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
 | 
			
		|||
    ddsi_plist_generic.h
 | 
			
		||||
    ddsi_security_omg.h
 | 
			
		||||
    ddsi_portmapping.h
 | 
			
		||||
    ddsi_handshake.h    
 | 
			
		||||
    ddsi_serdata.h
 | 
			
		||||
    ddsi_sertopic.h
 | 
			
		||||
    ddsi_serdata_default.h
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -112,6 +112,7 @@ struct entidx_enum_proxy_reader { struct entidx_enum st; };
 | 
			
		|||
 | 
			
		||||
void entidx_enum_init (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind) ddsrt_nonnull_all;
 | 
			
		||||
void entidx_enum_init_topic (struct entidx_enum *st, const struct entity_index *gh, enum entity_kind kind, const char *topic, struct match_entities_range_key *max) ddsrt_nonnull_all;
 | 
			
		||||
void entidx_enum_init_topic_w_prefix (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind, const char *topic, const ddsi_guid_prefix_t *prefix, struct match_entities_range_key *max) ddsrt_nonnull_all;
 | 
			
		||||
void *entidx_enum_next_max (struct entidx_enum *st, const struct match_entities_range_key *max) ddsrt_nonnull_all;
 | 
			
		||||
void *entidx_enum_next (struct entidx_enum *st) ddsrt_nonnull_all;
 | 
			
		||||
void entidx_enum_fini (struct entidx_enum *st) ddsrt_nonnull_all;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										197
									
								
								src/core/ddsi/include/dds/ddsi/ddsi_handshake.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								src/core/ddsi/include/dds/ddsi/ddsi_handshake.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,197 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
 | 
			
		||||
 *
 | 
			
		||||
 * This program and the accompanying materials are made available under the
 | 
			
		||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
			
		||||
 * v. 1.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#ifndef DDSI_HANDSHAKE_H
 | 
			
		||||
#define DDSI_HANDSHAKE_H
 | 
			
		||||
 | 
			
		||||
#include "q_unused.h"
 | 
			
		||||
#include "q_entity.h"
 | 
			
		||||
#include "ddsi_security_msg.h"
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct participant;
 | 
			
		||||
struct proxy_participant;
 | 
			
		||||
struct ddsi_handshake;
 | 
			
		||||
struct dssi_hsadmin;
 | 
			
		||||
 | 
			
		||||
enum ddsi_handshake_state {
 | 
			
		||||
    STATE_HANDSHAKE_IN_PROGRESS,
 | 
			
		||||
    STATE_HANDSHAKE_TIMED_OUT,
 | 
			
		||||
    STATE_HANDSHAKE_FAILED,
 | 
			
		||||
    STATE_HANDSHAKE_PROCESSED,
 | 
			
		||||
    STATE_HANDSHAKE_SEND_TOKENS,
 | 
			
		||||
    STATE_HANDSHAKE_OK
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* The handshake will not use the related handshake object after this callback
 | 
			
		||||
 * was executed. This means that it can be deleted in this callback. */
 | 
			
		||||
typedef void (*ddsi_handshake_end_cb_t)(
 | 
			
		||||
    struct q_globals const * const gv,
 | 
			
		||||
    struct ddsi_handshake *handshake,
 | 
			
		||||
    const ddsi_guid_t *lpguid, /* Local participant */
 | 
			
		||||
    const ddsi_guid_t *ppguid, /* Proxy participant */
 | 
			
		||||
    enum ddsi_handshake_state result);
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
 | 
			
		||||
#include "dds/ddsi/ddsi_security_msg.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Release the handshake.
 | 
			
		||||
 *
 | 
			
		||||
 * This function will decrement the refcount associated with the handshake
 | 
			
		||||
 * and delete the handshake when the refcount becomes 0.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] handshake    The handshake.
 | 
			
		||||
 */
 | 
			
		||||
void ddsi_handshake_release(struct ddsi_handshake *handshake);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Handle an authentication handshake message received from the remote participant.
 | 
			
		||||
 *
 | 
			
		||||
 * During the authentication phase handshake messages are being exchanged between the local and
 | 
			
		||||
 * the remote participant. THis function will handle a handshake message received from a remote
 | 
			
		||||
 * participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] handshake  The handshake.
 | 
			
		||||
 * @param[in] pp         The local participant.
 | 
			
		||||
 * @param[in] proxypp    The remote participant.
 | 
			
		||||
 * @param[in] msg        The handshake message received.
 | 
			
		||||
 */
 | 
			
		||||
void ddsi_handshake_handle_message(struct ddsi_handshake *handshake, const struct participant *pp, const struct proxy_participant *proxypp, const struct nn_participant_generic_message *msg);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Notify the handshake that crypto tokens have been received.
 | 
			
		||||
 *
 | 
			
		||||
 * The handshake could be finished at one end while the other side has not yet processed the
 | 
			
		||||
 * final handshake messages. The arrival of crypto tokens signals that the other side has also finished
 | 
			
		||||
 * processing the handshake. This function is used to signal the handshake that crypto tokens have been
 | 
			
		||||
 * received.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] handshake     The handshake.
 | 
			
		||||
 */
 | 
			
		||||
void ddsi_handshake_crypto_tokens_received(struct ddsi_handshake *handshake);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get the shared secret handle.
 | 
			
		||||
 *
 | 
			
		||||
 * During the handshake a shared secret is established which is used to encrypt
 | 
			
		||||
 * and decrypt the crypto token exchange messages. This function will return a
 | 
			
		||||
 * handle to the shared secret which will be passed to the crypto plugin to
 | 
			
		||||
 * determine the session keys used for the echange of the the crypto tokens.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] handshake  The handshake.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns handle to the shared sercet.
 | 
			
		||||
 */
 | 
			
		||||
int64_t ddsi_handshake_get_shared_secret(const struct ddsi_handshake *handshake);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get the handshake handle
 | 
			
		||||
 *
 | 
			
		||||
 * This function returns the handshake handle that was returned by the authentication plugin
 | 
			
		||||
 * when starting the handshake.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  handshake  The handshake.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns The handshake handle.
 | 
			
		||||
 */
 | 
			
		||||
int64_t ddsi_handshake_get_handle(const struct ddsi_handshake *handshake);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Create and start the handshake for the participants
 | 
			
		||||
 *
 | 
			
		||||
 * This function will create a handshake for the specified local
 | 
			
		||||
 * and remote participants when it does not yet exists. It will start the
 | 
			
		||||
 * handshake procedure by calling the corresponding functions of the authentication plugin.
 | 
			
		||||
 * The callback function is called by the handshake when to report events,
 | 
			
		||||
 * for example to indicate that the handshake has finished or has failed.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pp         The local participant.
 | 
			
		||||
 * @param[in] proxypp    The remote participant.
 | 
			
		||||
 * @param[in] callback   The callback function.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void ddsi_handshake_register(const struct participant *pp, const struct proxy_participant *proxypp, ddsi_handshake_end_cb_t callback);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Remove the handshake associated with the specified participants.
 | 
			
		||||
 *
 | 
			
		||||
 * This function will remove the handshake from the handshake administation and release
 | 
			
		||||
 * the handshake. When the handshake argument is not specified the handshake is searched
 | 
			
		||||
 * in the handshake administation.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pp         The local participant.
 | 
			
		||||
 * @param[in] proxypp    The remote participant.
 | 
			
		||||
 * @param[in] handshake  The handshake.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void ddsi_handshake_remove(const struct participant *pp, const struct proxy_participant *proxypp, struct ddsi_handshake *handshake);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Searches for the handshake associated with the specified participants
 | 
			
		||||
 *
 | 
			
		||||
 * This function will search through the handshake administration to find the handshake
 | 
			
		||||
 * corresponding the to specified local and remote participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pp         The local participant.
 | 
			
		||||
 * @param[in] proxypp    The remote participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns The handshake
 | 
			
		||||
 */
 | 
			
		||||
struct ddsi_handshake * ddsi_handshake_find(const struct participant *pp, const struct proxy_participant *proxypp);
 | 
			
		||||
 | 
			
		||||
#else /* DDSI_INCLUDE_SECURITY */
 | 
			
		||||
 | 
			
		||||
#include "dds/ddsi/q_unused.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline void ddsi_handshake_release(UNUSED_ARG(struct ddsi_handshake *handshake))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void ddsi_handshake_crypto_tokens_received(UNUSED_ARG(struct ddsi_handshake *handshake))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int64_t ddsi_handshake_get_shared_secret(UNUSED_ARG(const struct ddsi_handshake *handshake))
 | 
			
		||||
{
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int64_t ddsi_handshake_get_handle(UNUSED_ARG(const struct ddsi_handshake *handshake))
 | 
			
		||||
{
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void ddsi_handshake_register(UNUSED_ARG(const struct participant *pp), UNUSED_ARG(const struct proxy_participant *proxypp), UNUSED_ARG(ddsi_handshake_end_cb_t callback))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void ddsi_handshake_remove(UNUSED_ARG(const struct participant *pp), UNUSED_ARG(const struct proxy_participant *proxypp), UNUSED_ARG(struct ddsi_handshake *handshake))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline struct ddsi_handshake * ddsi_handshake_find(UNUSED_ARG(const struct participant *pp), UNUSED_ARG(const struct proxy_participant *proxypp))
 | 
			
		||||
{
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* DDSI_INCLUDE_SECURITY */
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* DDSI_HANDSHAKE_H */
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +12,8 @@
 | 
			
		|||
#ifndef DDSI_SECURITY_MSG_H
 | 
			
		||||
#define DDSI_SECURITY_MSG_H
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
 | 
			
		||||
#include "dds/ddsi/q_plist.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_guid.h"
 | 
			
		||||
#include "dds/ddsrt/retcode.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,4 +110,6 @@ volatile_secure_data_filter(
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* DDSI_SECURITY_MSG_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,6 +57,17 @@ bool q_omg_security_enabled(void);
 | 
			
		|||
 */
 | 
			
		||||
bool q_omg_participant_is_secure(const struct participant *pp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check if security is enabled for the proxy participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] proxypp  Proxy participant to check if it is secure.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns bool
 | 
			
		||||
 * @retval true   Proxy participant is secure
 | 
			
		||||
 * @retval false  Proxy participant is not secure
 | 
			
		||||
 */
 | 
			
		||||
bool q_omg_proxy_participant_is_secure(const struct proxy_participant *proxypp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get the security handle of the given local participant.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -490,6 +501,195 @@ secure_conn_write(
 | 
			
		|||
    nn_msg_sec_info_t *sec_info,
 | 
			
		||||
    ddsi_tran_write_fn_t conn_write_cb);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check if the participant and the proxy participant
 | 
			
		||||
 *        have compatible security info settings.
 | 
			
		||||
 *
 | 
			
		||||
 * Associated with a secure participant is the ParticipantSecurityInfo parameter.
 | 
			
		||||
 * This parameter contains the setting of the security attributes and the associated
 | 
			
		||||
 * plugin security attributes of the secure participant.
 | 
			
		||||
 * This function will check if the received ParticipantSecurityInfo parameter is
 | 
			
		||||
 * compatible with the local ParticipantSecurityInfo parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pp      The participant.
 | 
			
		||||
 * @param[in] proxypp The proxy participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns bool
 | 
			
		||||
 * @retval true   The participant and the proxy participant have compatible
 | 
			
		||||
 *                security info settings.
 | 
			
		||||
 * @retval false  Otherwise.
 | 
			
		||||
 */
 | 
			
		||||
bool q_omg_is_similar_participant_security_info(struct participant *pp, struct proxy_participant *proxypp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check if the participant allows communication with unauthenticated
 | 
			
		||||
 *        participants
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pp  The participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns bool
 | 
			
		||||
 * @retval true   The participant allows unauthenticated communication
 | 
			
		||||
 * @retval false  Otherwise.
 | 
			
		||||
 */
 | 
			
		||||
bool q_omg_participant_allow_unauthenticated(struct participant *pp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Register participant with security plugin and check if the
 | 
			
		||||
 *        participant is allowed by security.
 | 
			
		||||
 *
 | 
			
		||||
 * This function will register the participant with the authentication
 | 
			
		||||
 * plugin which will check if the provided security QoS parameters are
 | 
			
		||||
 * correct, e.g. is the provided certificate valid, etc.
 | 
			
		||||
 * When that is successful it is checked with access control if the
 | 
			
		||||
 * participant has the correct permissions and is allowed to be created.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pp        The participant.
 | 
			
		||||
 * @param[in] domain_id The domain id.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns bool
 | 
			
		||||
 * @retval true   The security check on the participant succeeded.
 | 
			
		||||
 * @retval false  The security check on the participant failed.
 | 
			
		||||
 */
 | 
			
		||||
bool q_omg_security_check_create_participant(struct participant *pp, uint32_t domain_id);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Initialize the proxy participant security attributes
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] proxypp  The proxy participant.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void q_omg_security_init_remote_participant(struct proxy_participant *proxypp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check the if the proxy participant is allowed by checking the security permissions.
 | 
			
		||||
 *
 | 
			
		||||
 * The access control plugin is ask to verify if the proxy participant is allowed to
 | 
			
		||||
 * communicate with the local participant. When the proxy participant is allowed the
 | 
			
		||||
 * function will return a valid permission handle which is provided by the access control plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] domain_id The domain id
 | 
			
		||||
 * @param[in] pp        The participant
 | 
			
		||||
 * @param[in] proxypp   The proxy participant
 | 
			
		||||
 *
 | 
			
		||||
 * @returns permission handle
 | 
			
		||||
 * @retval !0    The proxy participant is allowed
 | 
			
		||||
 * @retval 0     The proxy participant is not allowed.
 | 
			
		||||
 */
 | 
			
		||||
int64_t q_omg_security_check_remote_participant_permissions(uint32_t domain_id, struct participant *pp, struct proxy_participant *proxypp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Registers the matched proxy participant with the crypto plugin
 | 
			
		||||
 *
 | 
			
		||||
 * When the proxy participant is authenticated and allowed by access control then the match between the local and
 | 
			
		||||
 * the remote participant must be registered with the cypto factory provided by the crypto plugin. The
 | 
			
		||||
 * shared secret handle obtained from the authentication phase and the permission handle returned when validating
 | 
			
		||||
 * the proxy participant with access control plugin have to be provided.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pp                 The participant.
 | 
			
		||||
 * @param[in] proxypp            The proxy participant.
 | 
			
		||||
 * @param[in] shared_secret      The shared_secret handle.
 | 
			
		||||
 * @param[in] proxy_permissions  The permission handle associated with the proxy participant.
 | 
			
		||||
 */
 | 
			
		||||
void q_omg_security_register_remote_participant(struct participant *pp, struct proxy_participant *proxypp, int64_t shared_secret, int64_t proxy_permissions);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Removes a registered proxy participant from administation of the authentication,
 | 
			
		||||
 *        access control and crypto plugins.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] proxypp            The proxy participant.
 | 
			
		||||
 */
 | 
			
		||||
void q_omg_security_deregister_remote_participant(struct proxy_participant *proxypp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Generate and send the crypto tokens needed for encoding RTPS messages.
 | 
			
		||||
 *
 | 
			
		||||
 * When the security settings indicate that RTPS message encoding or signing is
 | 
			
		||||
 * configured for the participant then this function will ask the cypto echange for
 | 
			
		||||
 * the corresponding cypto tokens and send these to the proxy participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pp                 The participant.
 | 
			
		||||
 * @param[in] proxypp            The proxy participant.
 | 
			
		||||
 */
 | 
			
		||||
void q_omg_security_participant_send_tokens(struct participant *pp, struct proxy_participant *proxypp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check if the remote writer is allowed to communicate with endpoints of the
 | 
			
		||||
 *        local participant.
 | 
			
		||||
 *
 | 
			
		||||
 * This function will check with the access control plugin if the remote writer
 | 
			
		||||
 * is allowed to communicate with this participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pwr       The remote writer.
 | 
			
		||||
 * @param[in] domain_id The domain id.
 | 
			
		||||
 * @param[in] pp        The local participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns bool
 | 
			
		||||
 * @retval true   The remote writer is allowed to communicate.
 | 
			
		||||
 * @retval false  Otherwise.
 | 
			
		||||
 */
 | 
			
		||||
bool q_omg_security_check_remote_writer_permissions(const struct proxy_writer *pwr, uint32_t domain_id, struct participant *pp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check if the remote reader is allowed to communicate with endpoints of the
 | 
			
		||||
 *        local participant.
 | 
			
		||||
 *
 | 
			
		||||
 * This function will check with the access control plugin if the remote reader
 | 
			
		||||
 * is allowed to communicate with this participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] prd       The remote reader.
 | 
			
		||||
 * @param[in] domain_id The domain id.
 | 
			
		||||
 * @param[in] pp        The local participant.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns bool
 | 
			
		||||
 * @retval true   The remote reader is allowed to communicate.
 | 
			
		||||
 * @retval false  Otherwise.
 | 
			
		||||
 */
 | 
			
		||||
bool q_omg_security_check_remote_reader_permissions(const struct proxy_reader *prd, uint32_t domain_id, struct participant *pp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check it the remote writer is allowed to communicate with the local reader.
 | 
			
		||||
 *
 | 
			
		||||
 * When a remote writer is allowed by access control it has to be checked if the remote
 | 
			
		||||
 * writer is allowed to communicate with a particular local reader. This function will
 | 
			
		||||
 * check if the provided security end-point attributes are compatible, When the security
 | 
			
		||||
 * attributes are compatible then the function will register the reader and remote writer
 | 
			
		||||
 * match with the crypto factory and will also ask the crypto exchange to generate the
 | 
			
		||||
 * crypto tokens associate with the local reader which will be sent to the remote entity.
 | 
			
		||||
 * Note that the reader crypto tokens are used to encrypt the reader specific submessages
 | 
			
		||||
 * when submessage encoding or signing is configured.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] rd   The local reader.
 | 
			
		||||
 * @param[in] pwr  The remote writer.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns bool
 | 
			
		||||
 * @retval true   The local reader and remote writer are allowed to communicate.
 | 
			
		||||
 * @retval false  Otherwise.
 | 
			
		||||
 */
 | 
			
		||||
bool q_omg_security_match_remote_writer_enabled(struct reader *rd, struct proxy_writer *pwr);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check it the local writer is allowed to communicate with the remote reader.
 | 
			
		||||
 *
 | 
			
		||||
 * When a remote reader is allowed by access control it has to be checked if the local
 | 
			
		||||
 * writer is allowed to communicate with a particular local writer. This function will
 | 
			
		||||
 * check if the provided security end-point attributes are compatible, When the security
 | 
			
		||||
 * attributes are compatible then the function will register the writer and remote reader
 | 
			
		||||
 * match with the crypto factory and will also ask the crypto exchange to generate the
 | 
			
		||||
 * crypto tokens associate with the local writer which will be sent to the remote entity.
 | 
			
		||||
 * Note that the writer crypto tokens are used to encrypt the writer specific submessages
 | 
			
		||||
 * when submessage encoding or signing is configured and also the crypto tokens used
 | 
			
		||||
 * for encoding the payload of data or datafrag messages.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] wr   The local writer.
 | 
			
		||||
 * @param[in] prd  The remote reader.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns bool
 | 
			
		||||
 * @retval true   The local writer and remote reader are allowed to communicate.
 | 
			
		||||
 * @retval false  Otherwise.
 | 
			
		||||
 */
 | 
			
		||||
bool q_omg_security_match_remote_reader_enabled(struct writer *wr, struct proxy_reader *prd);
 | 
			
		||||
 | 
			
		||||
#else /* DDSI_INCLUDE_SECURITY */
 | 
			
		||||
 | 
			
		||||
#include "dds/ddsi/q_unused.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -507,6 +707,13 @@ q_omg_participant_is_secure(
 | 
			
		|||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool
 | 
			
		||||
q_omg_proxy_participant_is_secure(
 | 
			
		||||
  UNUSED_ARG(const struct proxy_participant *proxypp))
 | 
			
		||||
{
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline unsigned
 | 
			
		||||
determine_subscription_writer(
 | 
			
		||||
  UNUSED_ARG(const struct reader *rd))
 | 
			
		||||
| 
						 | 
				
			
			@ -530,6 +737,65 @@ is_proxy_participant_deletion_allowed(
 | 
			
		|||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool q_omg_is_similar_participant_security_info(UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp))
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool q_omg_participant_allow_unauthenticated(UNUSED_ARG(struct participant *pp))
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool
 | 
			
		||||
q_omg_security_check_create_participant(UNUSED_ARG(struct participant *pp), UNUSED_ARG(uint32_t domain_id))
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void q_omg_security_init_remote_participant(UNUSED_ARG(struct proxy_participant *proxypp))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int64_t q_omg_security_check_remote_participant_permissions(UNUSED_ARG(uint32_t domain_id), UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp))
 | 
			
		||||
{
 | 
			
		||||
  return 0LL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void q_omg_security_register_remote_participant(UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp), UNUSED_ARG(int64_t shared_secret), UNUSED_ARG(int64_t proxy_permissions))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void q_omg_security_deregister_remote_participant(UNUSED_ARG(struct proxy_participant *proxypp))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void q_omg_security_participant_send_tokens(UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool q_omg_security_match_remote_writer_enabled(UNUSED_ARG(struct reader *rd), UNUSED_ARG(struct proxy_writer *pwr))
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool q_omg_security_match_remote_reader_enabled(UNUSED_ARG(struct writer *wr), UNUSED_ARG(struct proxy_reader *prd))
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool
 | 
			
		||||
q_omg_security_check_remote_writer_permissions(UNUSED_ARG(const struct proxy_writer *pwr), UNUSED_ARG(uint32_t domain_id), UNUSED_ARG(struct participant *pp))
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool
 | 
			
		||||
q_omg_security_check_remote_reader_permissions(UNUSED_ARG(const struct proxy_reader *prd), UNUSED_ARG(uint32_t domain_id), UNUSED_ARG(struct participant *pp))
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void
 | 
			
		||||
set_proxy_participant_security_info(
 | 
			
		||||
  UNUSED_ARG(struct proxy_participant *prd),
 | 
			
		||||
| 
						 | 
				
			
			@ -551,7 +817,6 @@ set_proxy_writer_security_info(
 | 
			
		|||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline bool
 | 
			
		||||
decode_Data(
 | 
			
		||||
  UNUSED_ARG(const struct q_globals *gv),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,11 +20,13 @@
 | 
			
		|||
#include "dds/ddsi/q_rtps.h"
 | 
			
		||||
#include "dds/ddsi/q_plist.h"
 | 
			
		||||
#include "dds/ddsi/q_protocol.h"
 | 
			
		||||
#include "dds/ddsi/q_plist.h"
 | 
			
		||||
#include "dds/ddsi/q_lat_estim.h"
 | 
			
		||||
#include "dds/ddsi/q_hbcontrol.h"
 | 
			
		||||
#include "dds/ddsi/q_feature_check.h"
 | 
			
		||||
#include "dds/ddsi/q_inverse_uint32_set.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_serdata_default.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_handshake.h"
 | 
			
		||||
 | 
			
		||||
#include "dds/ddsi/ddsi_tran.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -214,6 +216,11 @@ struct participant
 | 
			
		|||
  int32_t builtin_refc; /* number of built-in endpoints in this participant [refc_lock] */
 | 
			
		||||
  int builtins_deleted; /* whether deletion of built-in endpoints has been initiated [refc_lock] */
 | 
			
		||||
  ddsrt_fibheap_t ldur_auto_wr; /* Heap that contains lease duration for writers with automatic liveliness in this participant */
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  int64_t local_identity_handle;   /* OMG DDS Security related member */
 | 
			
		||||
  int64_t permissions_handle; /* OMG DDS Security related member */
 | 
			
		||||
  struct participant_sec_attributes *sec_attr;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct endpoint_common {
 | 
			
		||||
| 
						 | 
				
			
			@ -356,7 +363,9 @@ struct proxy_participant
 | 
			
		|||
  unsigned proxypp_have_cm: 1;
 | 
			
		||||
  unsigned owns_lease: 1;
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  int64_t remote_identity_handle;   /* OMG DDS Security related member */
 | 
			
		||||
  nn_security_info_t security_info;
 | 
			
		||||
  struct proxy_participant_sec_attributes *sec_attr;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -712,6 +721,10 @@ void rebuild_or_clear_writer_addrsets(struct q_globals *gv, int rebuild);
 | 
			
		|||
 | 
			
		||||
void local_reader_ary_setfastpath_ok (struct local_reader_ary *x, bool fastpath_ok);
 | 
			
		||||
 | 
			
		||||
void connect_writer_with_proxy_reader_secure(struct writer *wr, struct proxy_reader *prd, nn_mtime_t tnow);
 | 
			
		||||
void connect_reader_with_proxy_writer_secure(struct reader *rd, struct proxy_writer *pwr, nn_mtime_t tnow);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct ddsi_writer_info;
 | 
			
		||||
DDS_EXPORT void ddsi_make_writer_info(struct ddsi_writer_info *wrinfo, const struct entity_common *e, const struct dds_qos *xqos, uint32_t statusinfo);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -439,6 +439,18 @@ void entidx_enum_init_topic (struct entidx_enum *st, const struct entity_index *
 | 
			
		|||
    st->cur = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void entidx_enum_init_topic_w_prefix (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind, const char *topic, const ddsi_guid_prefix_t *prefix, struct match_entities_range_key *max)
 | 
			
		||||
{
 | 
			
		||||
  assert (kind == EK_READER || kind == EK_WRITER || kind == EK_PROXY_READER || kind == EK_PROXY_WRITER);
 | 
			
		||||
  struct match_entities_range_key min;
 | 
			
		||||
  match_endpoint_range (kind, topic, &min, max);
 | 
			
		||||
  min.entity.e.guid.prefix = *prefix;
 | 
			
		||||
  max->entity.e.guid.prefix = *prefix;
 | 
			
		||||
  entidx_enum_init_minmax_int (st, ei, &min);
 | 
			
		||||
  if (st->cur && all_entities_compare (st->cur, &max->entity) > 0)
 | 
			
		||||
    st->cur = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void entidx_enum_init (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind)
 | 
			
		||||
{
 | 
			
		||||
  struct match_entities_range_key min;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										109
									
								
								src/core/ddsi/src/ddsi_handshake.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/core/ddsi/src/ddsi_handshake.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,109 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
 | 
			
		||||
 *
 | 
			
		||||
 * This program and the accompanying materials are made available under the
 | 
			
		||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
			
		||||
 * v. 1.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "dds/ddsi/ddsi_handshake.h"
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
 | 
			
		||||
#include "dds/security/dds_security_api.h"
 | 
			
		||||
#include "dds/ddsrt/hopscotch.h"
 | 
			
		||||
 | 
			
		||||
struct ddsi_handshake
 | 
			
		||||
{
 | 
			
		||||
  enum ddsi_handshake_state state;
 | 
			
		||||
 | 
			
		||||
  ddsi_guid_t local_pguid;  /* the guid of the local participant */
 | 
			
		||||
  ddsi_guid_t remote_pguid; /* the guid of the remote participant */
 | 
			
		||||
  ddsi_handshake_end_cb_t end_cb;
 | 
			
		||||
  struct q_globals *gv;
 | 
			
		||||
  ddsrt_mutex_t lock;
 | 
			
		||||
  ddsrt_cond_t cv;
 | 
			
		||||
 | 
			
		||||
  ddsrt_atomic_uint32_t refc;
 | 
			
		||||
 | 
			
		||||
  DDS_Security_IdentityHandle local_identity_handle;
 | 
			
		||||
  DDS_Security_IdentityHandle remote_identity_handle;
 | 
			
		||||
  DDS_Security_HandshakeHandle handshake_handle;
 | 
			
		||||
 | 
			
		||||
  DDS_Security_HandshakeMessageToken handshake_message_in_token;
 | 
			
		||||
  nn_message_identity_t handshake_message_in_id;
 | 
			
		||||
  DDS_Security_HandshakeMessageToken *handshake_message_out;
 | 
			
		||||
  DDS_Security_AuthRequestMessageToken local_auth_request_token;
 | 
			
		||||
  DDS_Security_AuthRequestMessageToken *remote_auth_request_token;
 | 
			
		||||
  DDS_Security_OctetSeq pdata;
 | 
			
		||||
  DDS_Security_SharedSecretHandle shared_secret;
 | 
			
		||||
  int handled_handshake_message;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ddsi_handshake_handle_message(struct ddsi_handshake *handshake, const struct participant *pp, const struct proxy_participant *proxypp, const struct nn_participant_generic_message *msg)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(handshake);
 | 
			
		||||
  DDSRT_UNUSED_ARG(pp);
 | 
			
		||||
  DDSRT_UNUSED_ARG(proxypp);
 | 
			
		||||
  DDSRT_UNUSED_ARG(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ddsi_handshake_crypto_tokens_received(struct ddsi_handshake *handshake)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(handshake);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64_t ddsi_handshake_get_shared_secret(const struct ddsi_handshake *handshake)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(handshake);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64_t ddsi_handshake_get_handle(const struct ddsi_handshake *handshake)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(handshake);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ddsi_handshake_register(const struct participant *pp, const struct proxy_participant *proxypp, ddsi_handshake_end_cb_t callback)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(pp);
 | 
			
		||||
  DDSRT_UNUSED_ARG(proxypp);
 | 
			
		||||
  DDSRT_UNUSED_ARG(callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ddsi_handshake_remove(const struct participant *pp, const struct proxy_participant *proxypp, struct ddsi_handshake *handshake)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(pp);
 | 
			
		||||
  DDSRT_UNUSED_ARG(proxypp);
 | 
			
		||||
  DDSRT_UNUSED_ARG(handshake);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ddsi_handshake * ddsi_handshake_find(const struct participant *pp, const struct proxy_participant *proxypp)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(pp);
 | 
			
		||||
  DDSRT_UNUSED_ARG(proxypp);
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
extern inline void ddsi_handshake_release(UNUSED_ARG(struct ddsi_handshake *handshake));
 | 
			
		||||
extern inline void ddsi_handshake_crypto_tokens_received(UNUSED_ARG(struct ddsi_handshake *handshake));
 | 
			
		||||
extern inline int64_t ddsi_handshake_get_shared_secret(UNUSED_ARG(const struct ddsi_handshake *handshake));
 | 
			
		||||
extern inline int64_t ddsi_handshake_get_handle(UNUSED_ARG(const struct ddsi_handshake *handshake));
 | 
			
		||||
extern inline void ddsi_handshake_register(UNUSED_ARG(const struct participant *pp), UNUSED_ARG(const struct proxy_participant *proxypp), UNUSED_ARG(ddsi_handshake_end_cb_t callback));
 | 
			
		||||
extern inline void ddsi_handshake_remove(UNUSED_ARG(const struct participant *pp), UNUSED_ARG(const struct proxy_participant *proxypp), UNUSED_ARG(struct ddsi_handshake *handshake));
 | 
			
		||||
extern inline struct ddsi_handshake * ddsi_handshake_find(UNUSED_ARG(const struct participant *pp), UNUSED_ARG(const struct proxy_participant *proxypp));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* DDSI_INCLUDE_DDS_SECURITY */
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +92,15 @@ q_omg_participant_is_secure(
 | 
			
		|||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
q_omg_proxy_participant_is_secure(
 | 
			
		||||
    const struct proxy_participant *proxypp)
 | 
			
		||||
{
 | 
			
		||||
  /* TODO: Register remote participant */
 | 
			
		||||
  DDSRT_UNUSED_ARG(proxypp);
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
q_omg_writer_is_discovery_protected(
 | 
			
		||||
  const struct writer *wr)
 | 
			
		||||
| 
						 | 
				
			
			@ -147,6 +156,12 @@ q_omg_get_reader_security_info(
 | 
			
		|||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
q_omg_security_init_remote_participant(struct proxy_participant *proxypp)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(proxypp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
q_omg_proxyparticipant_is_authenticated(
 | 
			
		||||
  const struct proxy_participant *proxy_pp)
 | 
			
		||||
| 
						 | 
				
			
			@ -174,6 +189,14 @@ q_omg_security_get_remote_participant_handle(
 | 
			
		|||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
q_omg_participant_allow_unauthenticated(struct participant *pp)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(pp);
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned
 | 
			
		||||
determine_subscription_writer(
 | 
			
		||||
  const struct reader *rd)
 | 
			
		||||
| 
						 | 
				
			
			@ -196,6 +219,21 @@ determine_publication_writer(
 | 
			
		|||
  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)
 | 
			
		||||
{
 | 
			
		||||
  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)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(proxypp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
is_proxy_participant_deletion_allowed(
 | 
			
		||||
  struct q_globals * const gv,
 | 
			
		||||
| 
						 | 
				
			
			@ -225,6 +263,93 @@ is_proxy_participant_deletion_allowed(
 | 
			
		|||
  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)
 | 
			
		||||
{
 | 
			
		||||
  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)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(pp);
 | 
			
		||||
  DDSRT_UNUSED_ARG(proxypp);
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
q_omg_security_check_create_participant(struct participant *pp, uint32_t 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)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(pp);
 | 
			
		||||
  DDSRT_UNUSED_ARG(proxypp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
q_omg_security_is_remote_rtps_protected(
 | 
			
		||||
  struct proxy_participant *proxy_pp,
 | 
			
		||||
| 
						 | 
				
			
			@ -792,7 +917,7 @@ validate_msg_decoding(
 | 
			
		|||
   * that is expected. */
 | 
			
		||||
  if (q_omg_security_is_remote_rtps_protected(proxypp, e->guid.entityid) && !rst->rtps_encoded)
 | 
			
		||||
  {
 | 
			
		||||
    return 0;
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -1182,6 +1307,9 @@ 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);
 | 
			
		||||
 | 
			
		||||
extern inline bool q_omg_participant_is_secure(
 | 
			
		||||
| 
						 | 
				
			
			@ -1190,6 +1318,12 @@ extern inline bool q_omg_participant_is_secure(
 | 
			
		|||
extern inline unsigned determine_subscription_writer(
 | 
			
		||||
  UNUSED_ARG(const struct reader *rd));
 | 
			
		||||
 | 
			
		||||
extern inline bool q_omg_security_match_remote_writer_enabled(UNUSED_ARG(struct reader *rd), UNUSED_ARG(struct proxy_writer *pwr));
 | 
			
		||||
extern inline bool q_omg_security_match_remote_reader_enabled(UNUSED_ARG(struct writer *wr), UNUSED_ARG(struct proxy_reader *prd));
 | 
			
		||||
 | 
			
		||||
extern inline bool q_omg_security_check_remote_writer_permissions(UNUSED_ARG(const struct proxy_writer *pwr), UNUSED_ARG(uint32_t domain_id), UNUSED_ARG(struct participant *pp));
 | 
			
		||||
extern inline bool q_omg_security_check_remote_reader_permissions(UNUSED_ARG(const struct proxy_reader *prd), UNUSED_ARG(uint32_t domain_id), UNUSED_ARG(struct participant *par));
 | 
			
		||||
 | 
			
		||||
extern inline unsigned determine_publication_writer(
 | 
			
		||||
  UNUSED_ARG(const struct writer *wr));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1198,6 +1332,24 @@ extern inline bool is_proxy_participant_deletion_allowed(
 | 
			
		|||
  UNUSED_ARG(const struct ddsi_guid *guid),
 | 
			
		||||
  UNUSED_ARG(const ddsi_entityid_t pwr_entityid));
 | 
			
		||||
 | 
			
		||||
extern inline bool q_omg_is_similar_participant_security_info(UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp));
 | 
			
		||||
 | 
			
		||||
extern inline bool q_omg_participant_allow_unauthenticated(UNUSED_ARG(struct participant *pp));
 | 
			
		||||
 | 
			
		||||
extern inline bool q_omg_security_check_create_participant(UNUSED_ARG(struct participant *pp), UNUSED_ARG(uint32_t domain_id));
 | 
			
		||||
 | 
			
		||||
/* initialize the proxy participant security attributes */
 | 
			
		||||
extern inline void q_omg_security_init_remote_participant(UNUSED_ARG(struct proxy_participant *proxypp));
 | 
			
		||||
 | 
			
		||||
/* ask to access control security plugin for the remote participant permissions */
 | 
			
		||||
extern inline int64_t q_omg_security_check_remote_participant_permissions(UNUSED_ARG(uint32_t domain_id), UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp));
 | 
			
		||||
 | 
			
		||||
extern inline void q_omg_security_register_remote_participant(UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp), UNUSED_ARG(int64_t shared_secret), UNUSED_ARG(int64_t proxy_permissions));
 | 
			
		||||
 | 
			
		||||
extern inline void q_omg_security_deregister_remote_participant(UNUSED_ARG(struct proxy_participant *proxypp));
 | 
			
		||||
 | 
			
		||||
extern inline void q_omg_security_participant_send_tokens(UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp));
 | 
			
		||||
 | 
			
		||||
extern inline void set_proxy_participant_security_info(
 | 
			
		||||
  UNUSED_ARG(struct proxy_participant *prd),
 | 
			
		||||
  UNUSED_ARG(const nn_plist_t *plist));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,10 +105,19 @@ static const unsigned prismtech_builtin_writers_besmask =
 | 
			
		|||
  NN_DISC_BUILTIN_ENDPOINT_CM_PUBLISHER_WRITER |
 | 
			
		||||
  NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_WRITER;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc *whc, status_cb_t status_cb, void *status_cbarg);
 | 
			
		||||
static dds_return_t new_reader_guid (struct reader **rd_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct ddsi_rhc *rhc, status_cb_t status_cb, void *status_cbarg);
 | 
			
		||||
static struct participant *ref_participant (struct participant *pp, const struct ddsi_guid *guid_of_refing_entity);
 | 
			
		||||
static void unref_participant (struct participant *pp, const struct ddsi_guid *guid_of_refing_entity);
 | 
			
		||||
static struct entity_common *entity_common_from_proxy_endpoint_common (const struct proxy_endpoint_common *c);
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
static const unsigned BES_MASK_NON_SECURITY = 0xf000ffff;
 | 
			
		||||
 | 
			
		||||
static void handshake_end_cb(struct q_globals const * const gv, struct ddsi_handshake *handshake, const struct ddsi_guid *lpguid, const struct ddsi_guid *ppguid, enum ddsi_handshake_state result);
 | 
			
		||||
static void downgrade_to_nonsecure(struct proxy_participant *proxypp);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int gcreq_participant (struct participant *pp);
 | 
			
		||||
static int gcreq_writer (struct writer *wr);
 | 
			
		||||
| 
						 | 
				
			
			@ -201,6 +210,22 @@ int is_builtin_endpoint (ddsi_entityid_t id, nn_vendorid_t vendorid)
 | 
			
		|||
  return is_builtin_entityid (id, vendorid) && id.u != NN_ENTITYID_PARTICIPANT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
 | 
			
		||||
static int is_builtin_volatile_endpoint (ddsi_entityid_t id)
 | 
			
		||||
{
 | 
			
		||||
  switch (id.u) {
 | 
			
		||||
  case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER:
 | 
			
		||||
  case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER:
 | 
			
		||||
    return 1;
 | 
			
		||||
  default:
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
bool is_local_orphan_endpoint (const struct entity_common *e)
 | 
			
		||||
{
 | 
			
		||||
  return (e->guid.prefix.u[0] == 0 && e->guid.prefix.u[1] == 0 && e->guid.prefix.u[2] == 0 &&
 | 
			
		||||
| 
						 | 
				
			
			@ -570,6 +595,47 @@ static void add_security_builtin_endpoints(struct participant *pp, ddsi_guid_t *
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
 | 
			
		||||
static void connect_participant_secure(struct q_globals *gv, struct participant *pp)
 | 
			
		||||
{
 | 
			
		||||
  struct proxy_participant *proxypp;
 | 
			
		||||
  struct entidx_enum_proxy_participant it;
 | 
			
		||||
 | 
			
		||||
  if (q_omg_participant_is_secure(pp))
 | 
			
		||||
  {
 | 
			
		||||
    entidx_enum_proxy_participant_init (&it, gv->entity_index);
 | 
			
		||||
    while ((proxypp = entidx_enum_proxy_participant_next (&it)) != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* Do not start handshaking when security info doesn't match. */
 | 
			
		||||
      if (q_omg_is_similar_participant_security_info(pp, proxypp))
 | 
			
		||||
      {
 | 
			
		||||
        ddsi_handshake_register(pp, proxypp, handshake_end_cb);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    entidx_enum_proxy_participant_fini (&it);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void disconnect_participant_secure(struct participant *pp)
 | 
			
		||||
{
 | 
			
		||||
  struct proxy_participant *proxypp;
 | 
			
		||||
  struct entidx_enum_proxy_participant it;
 | 
			
		||||
  struct q_globals * const gv = pp->e.gv;
 | 
			
		||||
 | 
			
		||||
  if (q_omg_participant_is_secure(pp))
 | 
			
		||||
  {
 | 
			
		||||
    entidx_enum_proxy_participant_init (&it, gv->entity_index);
 | 
			
		||||
    while ((proxypp = entidx_enum_proxy_participant_next (&it)) != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      ddsi_handshake_remove(pp, proxypp, NULL);
 | 
			
		||||
    }
 | 
			
		||||
    entidx_enum_proxy_participant_fini (&it);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct q_globals *gv, unsigned flags, const nn_plist_t *plist)
 | 
			
		||||
{
 | 
			
		||||
  struct participant *pp;
 | 
			
		||||
| 
						 | 
				
			
			@ -660,6 +726,16 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct q_globals *
 | 
			
		|||
        goto new_pp_err_secprop;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (nn_xqos_has_prop (&pp->plist->qos, "dds.sec.", true))
 | 
			
		||||
  {
 | 
			
		||||
    if (!q_omg_security_check_create_participant (pp, gv->config.domainId))
 | 
			
		||||
    {
 | 
			
		||||
      ret = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
 | 
			
		||||
      goto not_allowed;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (gv->logconfig.c.mask & DDS_LC_DISCOVERY)
 | 
			
		||||
| 
						 | 
				
			
			@ -856,9 +932,18 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct q_globals *
 | 
			
		|||
    tsched.v = (pp->lease_duration == T_NEVER) ? T_NEVER : 0;
 | 
			
		||||
    pp->pmd_update_xevent = qxev_pmd_update (gv->xevents, tsched, &pp->e.guid);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  if (q_omg_participant_is_secure(pp))
 | 
			
		||||
  {
 | 
			
		||||
    connect_participant_secure (gv, pp);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
not_allowed:
 | 
			
		||||
new_pp_err_secprop:
 | 
			
		||||
  nn_plist_fini (pp->plist);
 | 
			
		||||
  ddsrt_free (pp->plist);
 | 
			
		||||
| 
						 | 
				
			
			@ -1099,6 +1184,9 @@ dds_return_t delete_participant (struct q_globals *gv, const struct ddsi_guid *p
 | 
			
		|||
    return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
  builtintopic_write (gv->builtin_topic_interface, &pp->e, now(), false);
 | 
			
		||||
  remember_deleted_participant_guid (gv->deleted_participants, &pp->e.guid);
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  disconnect_participant_secure (pp);
 | 
			
		||||
#endif
 | 
			
		||||
  entidx_remove_participant_guid (gv->entity_index, pp);
 | 
			
		||||
  gcreq_participant (pp);
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -2449,6 +2537,31 @@ static bool topickind_qos_match_p_lock (struct entity_common *rd, const dds_qos_
 | 
			
		|||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void connect_writer_with_proxy_reader_secure(struct writer *wr, struct proxy_reader *prd, nn_mtime_t tnow)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(tnow);
 | 
			
		||||
  proxy_reader_add_connection (prd, wr);
 | 
			
		||||
  writer_add_connection (wr, prd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void connect_reader_with_proxy_writer_secure(struct reader *rd, struct proxy_writer *pwr, nn_mtime_t tnow)
 | 
			
		||||
{
 | 
			
		||||
  nn_count_t init_count;
 | 
			
		||||
  struct proxy_writer_alive_state alive_state;
 | 
			
		||||
 | 
			
		||||
  /* Initialize the reader's tracking information for the writer liveliness state to something
 | 
			
		||||
     sensible, but that may be outdated by the time the reader gets added to the writer's list
 | 
			
		||||
     of matching readers. */
 | 
			
		||||
  proxy_writer_get_alive_state (pwr, &alive_state);
 | 
			
		||||
  reader_add_connection (rd, pwr, &init_count,  &alive_state);
 | 
			
		||||
  proxy_writer_add_connection (pwr, rd, tnow, init_count);
 | 
			
		||||
 | 
			
		||||
  /* Once everything is set up: update with the latest state, any updates to the alive state
 | 
			
		||||
     happening in parallel will cause this to become a no-op. */
 | 
			
		||||
  proxy_writer_get_alive_state (pwr, &alive_state);
 | 
			
		||||
  reader_update_notify_pwr_alive_state (rd, pwr, &alive_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void connect_writer_with_proxy_reader (struct writer *wr, struct proxy_reader *prd, nn_mtime_t tnow)
 | 
			
		||||
{
 | 
			
		||||
  const int isb0 = (is_builtin_entityid (wr->e.guid.entityid, NN_VENDORID_ECLIPSE) != 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -2464,8 +2577,22 @@ static void connect_writer_with_proxy_reader (struct writer *wr, struct proxy_re
 | 
			
		|||
    writer_qos_mismatch (wr, reason);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  proxy_reader_add_connection (prd, wr);
 | 
			
		||||
  writer_add_connection (wr, prd);
 | 
			
		||||
 | 
			
		||||
  if (!q_omg_security_check_remote_reader_permissions (prd, wr->e.gv->config.domainId, wr->c.pp))
 | 
			
		||||
  {
 | 
			
		||||
    EELOGDISC (&wr->e, "connect_writer_with_proxy_reader (wr "PGUIDFMT") with (prd "PGUIDFMT") not allowed by security\n",
 | 
			
		||||
                   PGUID (wr->e.guid), PGUID (prd->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else if (!q_omg_security_match_remote_reader_enabled (wr, prd))
 | 
			
		||||
  {
 | 
			
		||||
    EELOGDISC (&wr->e, "connect_writer_with_proxy_reader (wr "PGUIDFMT") with (prd "PGUIDFMT") waiting for approval by security\n",
 | 
			
		||||
                     PGUID (wr->e.guid), PGUID (prd->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    proxy_reader_add_connection (prd, wr);
 | 
			
		||||
    writer_add_connection (wr, prd);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void connect_proxy_writer_with_reader (struct proxy_writer *pwr, struct reader *rd, nn_mtime_t tnow)
 | 
			
		||||
| 
						 | 
				
			
			@ -2485,17 +2612,30 @@ static void connect_proxy_writer_with_reader (struct proxy_writer *pwr, struct r
 | 
			
		|||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Initialze the reader's tracking information for the writer liveliness state to something
 | 
			
		||||
     sensible, but that may be outdated by the time the reader gets added to the writer's list
 | 
			
		||||
     of matching readers. */
 | 
			
		||||
  proxy_writer_get_alive_state (pwr, &alive_state);
 | 
			
		||||
  reader_add_connection (rd, pwr, &init_count, &alive_state);
 | 
			
		||||
  proxy_writer_add_connection (pwr, rd, tnow, init_count);
 | 
			
		||||
  if (!q_omg_security_check_remote_writer_permissions(pwr, rd->e.gv->config.domainId, rd->c.pp))
 | 
			
		||||
  {
 | 
			
		||||
    EELOGDISC (&rd->e, "connect_proxy_writer_with_reader (pwr "PGUIDFMT") with (rd "PGUIDFMT") not allowed by security\n",
 | 
			
		||||
        PGUID (pwr->e.guid), PGUID (rd->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else if (!q_omg_security_match_remote_writer_enabled(rd, pwr))
 | 
			
		||||
  {
 | 
			
		||||
    EELOGDISC (&rd->e, "connect_proxy_writer_with_reader (pwr "PGUIDFMT") with  (rd "PGUIDFMT") waiting for approval by security\n",
 | 
			
		||||
        PGUID (pwr->e.guid), PGUID (rd->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    /* Initialize the reader's tracking information for the writer liveliness state to something
 | 
			
		||||
       sensible, but that may be outdated by the time the reader gets added to the writer's list
 | 
			
		||||
       of matching readers. */
 | 
			
		||||
    proxy_writer_get_alive_state (pwr, &alive_state);
 | 
			
		||||
    reader_add_connection (rd, pwr, &init_count, &alive_state);
 | 
			
		||||
    proxy_writer_add_connection (pwr, rd, tnow, init_count);
 | 
			
		||||
 | 
			
		||||
  /* Once everything is set up: update with the latest state, any updates to the alive state
 | 
			
		||||
     happening in parallel will cause this to become a no-op. */
 | 
			
		||||
  proxy_writer_get_alive_state (pwr, &alive_state);
 | 
			
		||||
  reader_update_notify_pwr_alive_state (rd, pwr, &alive_state);
 | 
			
		||||
    /* Once everything is set up: update with the latest state, any updates to the alive state
 | 
			
		||||
       happening in parallel will cause this to become a no-op. */
 | 
			
		||||
    proxy_writer_get_alive_state (pwr, &alive_state);
 | 
			
		||||
    reader_update_notify_pwr_alive_state (rd, pwr, &alive_state);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool ignore_local_p (const ddsi_guid_t *guid1, const ddsi_guid_t *guid2, const struct dds_qos *xqos1, const struct dds_qos *xqos2)
 | 
			
		||||
| 
						 | 
				
			
			@ -2733,6 +2873,126 @@ static void match_proxy_reader_with_writers (struct proxy_reader *prd, nn_mtime_
 | 
			
		|||
  generic_do_match(&prd->e, tnow, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
 | 
			
		||||
static void match_volatile_secure_endpoints (struct participant *pp, struct proxy_participant *proxypp)
 | 
			
		||||
{
 | 
			
		||||
  struct reader *rd;
 | 
			
		||||
  struct writer *wr;
 | 
			
		||||
  struct proxy_reader *prd;
 | 
			
		||||
  struct proxy_writer *pwr;
 | 
			
		||||
  ddsi_guid_t guid;
 | 
			
		||||
  nn_mtime_t tnow = now_mt ();
 | 
			
		||||
 | 
			
		||||
  EELOGDISC (&pp->e, "match volatile endpoints (pp "PGUIDFMT") with (proxypp "PGUIDFMT")\n",
 | 
			
		||||
             PGUID(pp->e.guid), PGUID(proxypp->e.guid));
 | 
			
		||||
 | 
			
		||||
  guid = pp->e.guid;
 | 
			
		||||
  guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER;
 | 
			
		||||
  rd = entidx_lookup_reader_guid (pp->e.gv->entity_index, &guid);
 | 
			
		||||
  assert(rd);
 | 
			
		||||
  guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER;
 | 
			
		||||
  wr = entidx_lookup_writer_guid (pp->e.gv->entity_index, &guid);
 | 
			
		||||
  assert(wr);
 | 
			
		||||
 | 
			
		||||
  guid = proxypp->e.guid;
 | 
			
		||||
  guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER;
 | 
			
		||||
  prd = entidx_lookup_proxy_reader_guid (pp->e.gv->entity_index, &guid);
 | 
			
		||||
  assert(rd);
 | 
			
		||||
  guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER;
 | 
			
		||||
  pwr = entidx_lookup_proxy_writer_guid (pp->e.gv->entity_index, &guid);
 | 
			
		||||
  assert(wr);
 | 
			
		||||
 | 
			
		||||
  connect_proxy_writer_with_reader_wrapper(&pwr->e, &rd->e, tnow);
 | 
			
		||||
  connect_writer_with_proxy_reader_wrapper(&wr->e, &prd->e, tnow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct entity_common * get_entity_parent(struct entity_common *e)
 | 
			
		||||
{
 | 
			
		||||
  switch (e->kind)
 | 
			
		||||
  {
 | 
			
		||||
  case EK_WRITER:
 | 
			
		||||
     return &((struct writer *)e)->c.pp->e;
 | 
			
		||||
   case EK_READER:
 | 
			
		||||
     return &((struct reader *)e)->c.pp->e;
 | 
			
		||||
   case EK_PROXY_WRITER:
 | 
			
		||||
     return &((struct proxy_writer *)e)->c.proxypp->e;
 | 
			
		||||
   case EK_PROXY_READER:
 | 
			
		||||
     return &((struct proxy_reader *)e)->c.proxypp->e;
 | 
			
		||||
   case EK_PARTICIPANT:
 | 
			
		||||
   case EK_PROXY_PARTICIPANT:
 | 
			
		||||
     return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void update_proxy_participant_endpoint_matching (struct proxy_participant *proxypp, struct participant *pp)
 | 
			
		||||
{
 | 
			
		||||
  struct entity_index * const entidx = pp->e.gv->entity_index;
 | 
			
		||||
  struct proxy_endpoint_common *cep;
 | 
			
		||||
  ddsi_guid_t guid;
 | 
			
		||||
  ddsi_entityid_t *endpoint_ids;
 | 
			
		||||
  uint32_t num = 0, i;
 | 
			
		||||
  nn_mtime_t tnow = now_mt ();
 | 
			
		||||
 | 
			
		||||
  EELOGDISC (&proxypp->e, "update_proxy_participant_endpoint_matching (proxypp "PGUIDFMT" pp "PGUIDFMT")\n",
 | 
			
		||||
             PGUID (proxypp->e.guid), PGUID (pp->e.guid));
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&proxypp->e.lock);
 | 
			
		||||
  endpoint_ids = ddsrt_malloc(proxypp->refc * sizeof(ddsi_entityid_t));
 | 
			
		||||
  for (cep = proxypp->endpoints; cep != NULL; cep = cep->next_ep)
 | 
			
		||||
  {
 | 
			
		||||
    struct entity_common *e = entity_common_from_proxy_endpoint_common (cep);
 | 
			
		||||
    endpoint_ids[num++] = e->guid.entityid;
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&proxypp->e.lock);
 | 
			
		||||
 | 
			
		||||
  guid.prefix = proxypp->e.guid.prefix;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < num; i++)
 | 
			
		||||
  {
 | 
			
		||||
    struct entity_common *e;
 | 
			
		||||
    enum entity_kind mkind;
 | 
			
		||||
 | 
			
		||||
    guid.entityid = endpoint_ids[i];
 | 
			
		||||
    if ((e = entidx_lookup_guid_untyped(proxypp->e.gv->entity_index, &guid)) == NULL)
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    mkind = generic_do_match_mkind (e->kind, false);
 | 
			
		||||
    if (!is_builtin_entityid (e->guid.entityid, NN_VENDORID_ECLIPSE))
 | 
			
		||||
    {
 | 
			
		||||
      struct entidx_enum it;
 | 
			
		||||
      struct entity_common *em;
 | 
			
		||||
      struct match_entities_range_key max;
 | 
			
		||||
      const char *tp = entity_topic_name (e);
 | 
			
		||||
 | 
			
		||||
      entidx_enum_init_topic_w_prefix (&it, entidx, mkind, tp, &pp->e.guid.prefix, &max);
 | 
			
		||||
      while ((em = entidx_enum_next_max (&it, &max)) != NULL)
 | 
			
		||||
      {
 | 
			
		||||
        if (&pp->e == get_entity_parent(e))
 | 
			
		||||
          generic_do_match_connect (e, em, tnow, false);
 | 
			
		||||
      }
 | 
			
		||||
      entidx_enum_fini (&it);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      const ddsi_entityid_t tgt_ent = builtin_entityid_match (e->guid.entityid);
 | 
			
		||||
      const ddsi_guid_t tgt_guid = { pp->e.guid.prefix, tgt_ent };
 | 
			
		||||
 | 
			
		||||
      if (!is_builtin_volatile_endpoint (tgt_ent))
 | 
			
		||||
      {
 | 
			
		||||
        struct entity_common *ep;
 | 
			
		||||
        if ((ep = entidx_lookup_guid (entidx, &tgt_guid, mkind)) != NULL)
 | 
			
		||||
          generic_do_match_connect (e, ep, tnow, false);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ddsrt_free(endpoint_ids);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ENDPOINT --------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
static void new_reader_writer_common (const struct ddsrt_log_cfg *logcfg, const struct ddsi_guid *guid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos)
 | 
			
		||||
| 
						 | 
				
			
			@ -4048,7 +4308,7 @@ static void add_proxy_builtin_endpoints(
 | 
			
		|||
 | 
			
		||||
  /* Register lease for auto liveliness, but be careful not to accidentally re-register
 | 
			
		||||
     DDSI2's lease, as we may have become dependent on DDSI2 any time after
 | 
			
		||||
     ephash_insert_proxy_participant_guid even if privileged_pp_guid was NULL originally */
 | 
			
		||||
     entidx_insert_proxy_participant_guid even if privileged_pp_guid was NULL originally */
 | 
			
		||||
  ddsrt_mutex_lock (&proxypp->e.lock);
 | 
			
		||||
 | 
			
		||||
  if (proxypp->owns_lease)
 | 
			
		||||
| 
						 | 
				
			
			@ -4124,6 +4384,142 @@ static void proxy_participant_remove_pwr_lease_locked (struct proxy_participant
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
 | 
			
		||||
void handshake_end_cb
 | 
			
		||||
(
 | 
			
		||||
  struct q_globals const * const gv,
 | 
			
		||||
  struct ddsi_handshake *handshake,
 | 
			
		||||
  const struct ddsi_guid *lpguid,
 | 
			
		||||
  const struct ddsi_guid *ppguid,
 | 
			
		||||
  enum ddsi_handshake_state result)
 | 
			
		||||
{
 | 
			
		||||
  struct proxy_participant *proxypp;
 | 
			
		||||
  struct participant *pp;
 | 
			
		||||
  int64_t shared_secret;
 | 
			
		||||
  int64_t permissions_hdl;
 | 
			
		||||
 | 
			
		||||
  assert(handshake);
 | 
			
		||||
  assert(lpguid);
 | 
			
		||||
  assert(ppguid);
 | 
			
		||||
 | 
			
		||||
  assert(gv);
 | 
			
		||||
 | 
			
		||||
  proxypp = entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid);
 | 
			
		||||
  if (!proxypp)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  pp = entidx_lookup_participant_guid (gv->entity_index, lpguid);
 | 
			
		||||
  if (!pp)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  switch(result)
 | 
			
		||||
  {
 | 
			
		||||
  case STATE_HANDSHAKE_PROCESSED:
 | 
			
		||||
    shared_secret = ddsi_handshake_get_shared_secret(handshake);
 | 
			
		||||
    DDS_CLOG (DDS_LC_DISCOVERY, &gv->logconfig, "handshake (lguid="PGUIDFMT" rguid="PGUIDFMT") processed\n", PGUID (*lpguid), PGUID (*ppguid));
 | 
			
		||||
    permissions_hdl = q_omg_security_check_remote_participant_permissions(gv->config.domainId, pp, proxypp);
 | 
			
		||||
    if (permissions_hdl != 0) {
 | 
			
		||||
      q_omg_security_register_remote_participant(pp, proxypp, shared_secret, permissions_hdl);
 | 
			
		||||
      match_volatile_secure_endpoints(pp, proxypp);
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case STATE_HANDSHAKE_SEND_TOKENS:
 | 
			
		||||
    DDS_CLOG (DDS_LC_DISCOVERY, &gv->logconfig, "handshake (lguid="PGUIDFMT" rguid="PGUIDFMT") send tokens\n", PGUID (*lpguid), PGUID (*ppguid));
 | 
			
		||||
    q_omg_security_participant_send_tokens(pp, proxypp);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case STATE_HANDSHAKE_OK:
 | 
			
		||||
    DDS_CLOG (DDS_LC_DISCOVERY, &gv->logconfig, "handshake (lguid="PGUIDFMT" rguid="PGUIDFMT") succeeded\n", PGUID (*lpguid), PGUID (*ppguid));
 | 
			
		||||
    update_proxy_participant_endpoint_matching(proxypp, pp);
 | 
			
		||||
    ddsi_handshake_remove(pp, proxypp, handshake);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case STATE_HANDSHAKE_TIMED_OUT:
 | 
			
		||||
    DDS_CERROR (&gv->logconfig, "handshake (lguid="PGUIDFMT" rguid="PGUIDFMT") failed: (%d) Timed out\n", PGUID (*lpguid), PGUID (*ppguid), (int)result);
 | 
			
		||||
    if (q_omg_participant_allow_unauthenticated(pp)) {
 | 
			
		||||
      downgrade_to_nonsecure(proxypp);
 | 
			
		||||
      update_proxy_participant_endpoint_matching(proxypp, pp);
 | 
			
		||||
    }
 | 
			
		||||
    ddsi_handshake_remove(pp, proxypp, handshake);
 | 
			
		||||
    break;
 | 
			
		||||
  case STATE_HANDSHAKE_FAILED:
 | 
			
		||||
    DDS_CERROR (&gv->logconfig, "handshake (lguid="PGUIDFMT" rguid="PGUIDFMT") failed: (%d) Failed\n", PGUID (*lpguid), PGUID (*ppguid), (int)result);
 | 
			
		||||
    if (q_omg_participant_allow_unauthenticated(pp)) {
 | 
			
		||||
      downgrade_to_nonsecure(proxypp);
 | 
			
		||||
      update_proxy_participant_endpoint_matching(proxypp, pp);
 | 
			
		||||
    }
 | 
			
		||||
    ddsi_handshake_remove(pp, proxypp, handshake);
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    DDS_CERROR (&gv->logconfig, "handshake (lguid="PGUIDFMT" rguid="PGUIDFMT") failed: (%d) Unknown failure\n", PGUID (*lpguid), PGUID (*ppguid), (int)result);
 | 
			
		||||
    ddsi_handshake_remove(pp, proxypp, handshake);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int proxy_participant_check_security_info(struct q_globals *gv, struct proxy_participant *proxypp)
 | 
			
		||||
{
 | 
			
		||||
  int r = 0;
 | 
			
		||||
  struct participant *pp;
 | 
			
		||||
  struct entidx_enum_participant est;
 | 
			
		||||
 | 
			
		||||
  entidx_enum_participant_init (&est, gv->entity_index);
 | 
			
		||||
  while (((pp = entidx_enum_participant_next (&est)) != NULL) && (r == 0)) {
 | 
			
		||||
    if (q_omg_is_similar_participant_security_info(pp, proxypp)) {
 | 
			
		||||
      r = 1;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  entidx_enum_participant_fini(&est);
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void proxy_participant_create_handshakes(struct q_globals *gv, struct proxy_participant *proxypp)
 | 
			
		||||
{
 | 
			
		||||
  struct participant *pp;
 | 
			
		||||
  struct entidx_enum_participant est;
 | 
			
		||||
 | 
			
		||||
  entidx_enum_participant_init (&est, gv->entity_index);
 | 
			
		||||
  while (((pp = entidx_enum_participant_next (&est)) != NULL)) {
 | 
			
		||||
    if (q_omg_participant_is_secure(pp))
 | 
			
		||||
    {
 | 
			
		||||
      ddsi_handshake_register(pp, proxypp, handshake_end_cb);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  entidx_enum_participant_fini(&est);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
 | 
			
		||||
static void free_proxy_participant(struct proxy_participant *proxypp)
 | 
			
		||||
{
 | 
			
		||||
  q_omg_security_deregister_remote_participant(proxypp);
 | 
			
		||||
  unref_addrset (proxypp->as_default);
 | 
			
		||||
  unref_addrset (proxypp->as_meta);
 | 
			
		||||
  nn_plist_fini (proxypp->plist);
 | 
			
		||||
  ddsrt_free (proxypp->plist);
 | 
			
		||||
  if (proxypp->owns_lease)
 | 
			
		||||
  {
 | 
			
		||||
    struct lease * minl_auto = ddsrt_atomic_ldvoidp (&proxypp->minl_auto);
 | 
			
		||||
    ddsrt_fibheap_delete (&lease_fhdef_proxypp, &proxypp->leaseheap_auto, proxypp->lease);
 | 
			
		||||
    assert (ddsrt_fibheap_min (&lease_fhdef_proxypp, &proxypp->leaseheap_auto) == NULL);
 | 
			
		||||
    assert (ddsrt_fibheap_min (&lease_fhdef_proxypp, &proxypp->leaseheap_man) == NULL);
 | 
			
		||||
    assert (ddsrt_atomic_ldvoidp (&proxypp->minl_man) == NULL);
 | 
			
		||||
    assert (!compare_guid (&minl_auto->entity->guid, &proxypp->e.guid));
 | 
			
		||||
    lease_unregister (minl_auto);
 | 
			
		||||
    lease_free (minl_auto);
 | 
			
		||||
    lease_free (proxypp->lease);
 | 
			
		||||
  }
 | 
			
		||||
  entity_common_fini (&proxypp->e);
 | 
			
		||||
  ddsrt_free (proxypp);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void new_proxy_participant
 | 
			
		||||
(
 | 
			
		||||
  struct q_globals *gv,
 | 
			
		||||
| 
						 | 
				
			
			@ -4145,6 +4541,9 @@ void new_proxy_participant
 | 
			
		|||
     runs on a single thread, it can't go wrong. FIXME, maybe? The
 | 
			
		||||
     same holds for the other functions for creating entities. */
 | 
			
		||||
  struct proxy_participant *proxypp;
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  bool secure = false;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  assert (ppguid->entityid.u == NN_ENTITYID_PARTICIPANT);
 | 
			
		||||
  assert (entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid) == NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -4229,7 +4628,17 @@ void new_proxy_participant
 | 
			
		|||
  nn_xqos_mergein_missing (&proxypp->plist->qos, &gv->default_plist_pp.qos, ~(uint64_t)0);
 | 
			
		||||
  ddsrt_avl_init (&proxypp_groups_treedef, &proxypp->groups);
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  proxypp->remote_identity_handle = 0;
 | 
			
		||||
  proxypp->sec_attr = NULL;
 | 
			
		||||
  secure = ((bes & NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER) != 0);
 | 
			
		||||
  if (!secure)
 | 
			
		||||
  {
 | 
			
		||||
    /* Make sure we don't create any security builtin endpoint when it's considered unsecure. */
 | 
			
		||||
    proxypp->bes &= BES_MASK_NON_SECURITY;
 | 
			
		||||
  }
 | 
			
		||||
  set_proxy_participant_security_info(proxypp, plist);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (custom_flags & CF_INC_KERNEL_SEQUENCE_NUMBERS)
 | 
			
		||||
    proxypp->kernel_sequence_numbers = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -4253,12 +4662,52 @@ void new_proxy_participant
 | 
			
		|||
  else
 | 
			
		||||
    proxypp->proxypp_have_cm = 0;
 | 
			
		||||
 | 
			
		||||
  /* Proxy participant must be in the hash tables for
 | 
			
		||||
     new_proxy_{writer,reader} to work */
 | 
			
		||||
  entidx_insert_proxy_participant_guid (gv->entity_index, proxypp);
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  if (secure)
 | 
			
		||||
  {
 | 
			
		||||
    /* Secure participant detected: start handshake. */
 | 
			
		||||
    if ((plist->present & PP_IDENTITY_TOKEN))
 | 
			
		||||
    {
 | 
			
		||||
      /* initialize the security attributes associated with the proxy participant */
 | 
			
		||||
      q_omg_security_init_remote_participant(proxypp);
 | 
			
		||||
 | 
			
		||||
  /* TODO: Do security checks on the proxy participant. Either add the endpoints or delete the proxy. */
 | 
			
		||||
      /* check if the proxy participant has a match with a local participant */
 | 
			
		||||
      if (proxy_participant_check_security_info(gv, proxypp))
 | 
			
		||||
      {
 | 
			
		||||
        /* Proxy participant must be in the hash tables for new_proxy_{writer,reader} to work */
 | 
			
		||||
        entidx_insert_proxy_participant_guid (gv->entity_index, proxypp);
 | 
			
		||||
        /* Create builtin endpoints, of which a few are used in the handshake. */
 | 
			
		||||
        add_proxy_builtin_endpoints(gv, ppguid, proxypp, timestamp);
 | 
			
		||||
        /* create authentication handshakes for each local secure participant */
 | 
			
		||||
        proxy_participant_create_handshakes(gv, proxypp);
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        DDS_CWARNING(&gv->logconfig, "Remote secure participant "PGUIDFMT" not allowed\n", PGUID (*ppguid));
 | 
			
		||||
        free_proxy_participant(proxypp);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      /* Do not communicate with un-secure participants. */
 | 
			
		||||
      DDS_CWARNING(&gv->logconfig, "Don't communicate with secure participant "PGUIDFMT" which does not provide an identity token\n", PGUID (*ppguid));
 | 
			
		||||
      free_proxy_participant(proxypp);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    /* Remote is un-secure. Try the discovery anyway. Maybe there's a local secure
 | 
			
		||||
     * participant that allowed communication with remote non-secure ones
 | 
			
		||||
     */
 | 
			
		||||
    entidx_insert_proxy_participant_guid (gv->entity_index, proxypp);
 | 
			
		||||
    add_proxy_builtin_endpoints(gv, ppguid, proxypp, timestamp);
 | 
			
		||||
    DDS_CLOG (DDS_LC_INFO, &gv->logconfig, "Un-secure participant "PGUIDFMT" tries to connect.\n", PGUID (*ppguid));
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  /* Proxy participant must be in the hash tables for new_proxy_{writer,reader} to work */
 | 
			
		||||
  entidx_insert_proxy_participant_guid (gv->entity_index, proxypp);
 | 
			
		||||
  add_proxy_builtin_endpoints(gv, ppguid, proxypp, timestamp);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, seqno_t seq, const struct nn_plist *datap, enum update_proxy_participant_source source, nn_wctime_t timestamp)
 | 
			
		||||
| 
						 | 
				
			
			@ -4356,6 +4805,10 @@ static void unref_proxy_participant (struct proxy_participant *proxypp, struct p
 | 
			
		|||
    }
 | 
			
		||||
    ddsrt_mutex_unlock (&proxypp->e.lock);
 | 
			
		||||
    ELOGDISC (proxypp, "unref_proxy_participant("PGUIDFMT"): refc=0, freeing\n", PGUID (proxypp->e.guid));
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
    q_omg_security_deregister_remote_participant(proxypp);
 | 
			
		||||
#endif
 | 
			
		||||
    unref_addrset (proxypp->as_default);
 | 
			
		||||
    unref_addrset (proxypp->as_meta);
 | 
			
		||||
    nn_plist_fini (proxypp->plist);
 | 
			
		||||
| 
						 | 
				
			
			@ -4478,6 +4931,61 @@ static void delete_ppt (struct proxy_participant *proxypp, nn_wctime_t timestamp
 | 
			
		|||
  gcreq_proxy_participant (proxypp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
 | 
			
		||||
struct setab {
 | 
			
		||||
  enum entity_kind kind;
 | 
			
		||||
  uint32_t id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void downgrade_to_nonsecure(struct proxy_participant *proxypp)
 | 
			
		||||
{
 | 
			
		||||
  const nn_wctime_t tnow = now();
 | 
			
		||||
  struct ddsi_guid guid;
 | 
			
		||||
  static const struct setab setab[] = {
 | 
			
		||||
      {EK_PROXY_WRITER, NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER},
 | 
			
		||||
      {EK_PROXY_READER, NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER},
 | 
			
		||||
      {EK_PROXY_WRITER, NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER},
 | 
			
		||||
      {EK_PROXY_READER, NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER},
 | 
			
		||||
      {EK_PROXY_WRITER, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER},
 | 
			
		||||
      {EK_PROXY_READER, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER},
 | 
			
		||||
      {EK_PROXY_WRITER, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER},
 | 
			
		||||
      {EK_PROXY_READER, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER},
 | 
			
		||||
      {EK_PROXY_WRITER, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER},
 | 
			
		||||
      {EK_PROXY_READER, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER},
 | 
			
		||||
      {EK_PROXY_WRITER, NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER},
 | 
			
		||||
      {EK_PROXY_READER, NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER}
 | 
			
		||||
  };
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  DDS_CWARNING (&proxypp->e.gv->logconfig, "downgrade participant "PGUIDFMT" to non-secure\n", PGUID (proxypp->e.guid));
 | 
			
		||||
 | 
			
		||||
  guid.prefix = proxypp->e.guid.prefix;
 | 
			
		||||
  /* Remove security related endpoints. */
 | 
			
		||||
  for (i = 0; i < (int)(sizeof(setab)/sizeof(*setab)); i++)
 | 
			
		||||
  {
 | 
			
		||||
    guid.entityid.u = setab[i].id;
 | 
			
		||||
    switch (setab[i].kind)
 | 
			
		||||
    {
 | 
			
		||||
    case EK_PROXY_READER:
 | 
			
		||||
      (void)delete_proxy_reader (proxypp->e.gv, &guid, tnow, 0);
 | 
			
		||||
      break;
 | 
			
		||||
    case EK_PROXY_WRITER:
 | 
			
		||||
      (void)delete_proxy_writer (proxypp->e.gv, &guid, tnow, 0);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      assert(0);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Cleanup all kinds of related security information. */
 | 
			
		||||
  q_omg_security_deregister_remote_participant(proxypp);
 | 
			
		||||
  proxypp->bes &= BES_MASK_NON_SECURITY;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct proxy_purge_data {
 | 
			
		||||
  struct proxy_participant *proxypp;
 | 
			
		||||
  const nn_locator_t *loc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue