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;
|
||||
}
|
||||
|
||||
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,7 +2612,19 @@ 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
|
||||
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);
|
||||
|
@ -2496,6 +2635,7 @@ static void connect_proxy_writer_with_reader (struct proxy_writer *pwr, struct r
|
|||
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