Remove temporarily stored crypto handles and tokens after entities are matched
Signed-off-by: Marcel Jordense <marcel.jordense@adlinktech.com>
This commit is contained in:
		
							parent
							
								
									829e33ac82
								
							
						
					
					
						commit
						534eac2a11
					
				
					 5 changed files with 439 additions and 290 deletions
				
			
		| 
						 | 
				
			
			@ -329,7 +329,6 @@ struct ddsi_domaingv {
 | 
			
		|||
  /* security globals */
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  struct dds_security_context *security_context;
 | 
			
		||||
  struct dds_security_match_index *security_matches;
 | 
			
		||||
  struct ddsi_hsadmin *hsadmin;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,24 +55,10 @@ typedef struct nn_msg_sec_info {
 | 
			
		|||
  int64_t dst_pp_handle;
 | 
			
		||||
} nn_msg_sec_info_t;
 | 
			
		||||
 | 
			
		||||
struct guid_pair {
 | 
			
		||||
  ddsi_guid_t src;
 | 
			
		||||
  ddsi_guid_t dst;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct security_entity_match {
 | 
			
		||||
  ddsrt_avl_node_t avlnode;
 | 
			
		||||
  struct guid_pair guids;
 | 
			
		||||
  bool matched;
 | 
			
		||||
  bool tokens_sent;
 | 
			
		||||
  int64_t crypto_handle;
 | 
			
		||||
  DDS_Security_ParticipantCryptoTokenSeq *tokens;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dds_security_match_index {
 | 
			
		||||
  ddsrt_mutex_t lock;
 | 
			
		||||
  ddsrt_avl_tree_t matches;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct pp_proxypp_match {
 | 
			
		||||
  ddsrt_avl_node_t avlnode;
 | 
			
		||||
| 
						 | 
				
			
			@ -718,6 +704,36 @@ void q_omg_security_deregister_remote_writer_match(const struct ddsi_domaingv *g
 | 
			
		|||
 */
 | 
			
		||||
void q_omg_security_set_remote_writer_crypto_tokens(struct reader *rd, const ddsi_guid_t *pwr_guid, const nn_dataholderseq_t *tokens);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Release all the security resources associated with the remote writer.
 | 
			
		||||
 *
 | 
			
		||||
 * Cleanup security resource associated with the remote writer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] pwr       The remote writer.
 | 
			
		||||
 */
 | 
			
		||||
void q_omg_security_deregister_remote_writer(const struct proxy_writer *pwr);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Set security information, depending on plist and proxy participant,
 | 
			
		||||
 * into the given proxy reader.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] prd      Proxy reader to set security info on.
 | 
			
		||||
 * @param[in] plist    Paramater list, possibly contains security info.
 | 
			
		||||
 */
 | 
			
		||||
void set_proxy_reader_security_info(struct proxy_reader *prd, const ddsi_plist_t *plist);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Determine the security settings associated with the remote reader.
 | 
			
		||||
 *
 | 
			
		||||
 * From the security information contained in the parameter list from the remote reader
 | 
			
		||||
 * the corresponding security settings are determined and returned in the info parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] prd       The remote reader.
 | 
			
		||||
 * @param[in] plist     The parameter list from the remote reader.
 | 
			
		||||
 * @param[out] info     The security settings associated with the remote reader.
 | 
			
		||||
 */
 | 
			
		||||
void q_omg_get_proxy_reader_security_info(struct proxy_reader *prd, const ddsi_plist_t *plist, nn_security_info_t *info);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check if the reader has the is_discovery_protected flag set
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -820,6 +836,15 @@ void q_omg_security_deregister_remote_reader_match(const struct ddsi_domaingv *g
 | 
			
		|||
 */
 | 
			
		||||
void q_omg_security_set_remote_reader_crypto_tokens(struct writer *wr, const ddsi_guid_t *prd_guid, const nn_dataholderseq_t *tokens);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Release all the security resources associated with the remote reader.
 | 
			
		||||
 *
 | 
			
		||||
 * Cleanup security resource associated with the remote reader.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] prd       The remote reader.
 | 
			
		||||
 */
 | 
			
		||||
void q_omg_security_deregister_remote_reader(const struct proxy_reader *prd);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Encode RTPS message.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -1074,7 +1099,9 @@ void q_omg_security_init( struct ddsi_domaingv *gv );
 | 
			
		|||
 | 
			
		||||
void q_omg_security_stop (struct ddsi_domaingv *gv);
 | 
			
		||||
 | 
			
		||||
void q_omg_security_deinit( struct ddsi_domaingv *gv );
 | 
			
		||||
void q_omg_security_deinit (struct dds_security_context *sc );
 | 
			
		||||
 | 
			
		||||
void q_omg_security_free (struct ddsi_domaingv *gv);
 | 
			
		||||
 | 
			
		||||
bool q_omg_is_security_loaded(  struct dds_security_context *sc );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,11 @@
 | 
			
		|||
#define AC_NAME "Access Control"
 | 
			
		||||
#define CRYPTO_NAME "Cryptographic"
 | 
			
		||||
 | 
			
		||||
/* TODO: This constant which determines the time pending matches are maintained
 | 
			
		||||
 * and not used should be made a configurable parameter,
 | 
			
		||||
 */
 | 
			
		||||
#define PENDING_MATCH_EXPIRY_TIME 300
 | 
			
		||||
 | 
			
		||||
#define EXCEPTION_LOG(sc,e,cat, ...) \
 | 
			
		||||
  q_omg_log_exception(sc->logcfg, cat, e, __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -157,6 +162,43 @@ struct participant_sec_index {
 | 
			
		|||
  ddsrt_avl_ctree_t participants;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* The pending _match_index uses an avl tree to store pending_match's where the
 | 
			
		||||
 * guid_pair is used as the key. The remote_guid is the primary key and
 | 
			
		||||
 * the local_guid is the secondary key. The use of the remote_guid as the primary key
 | 
			
		||||
 * is used in the function clear_pending_matches_by_remote_guid to clear the
 | 
			
		||||
 * pending matches associated with a remote entity.
 | 
			
		||||
 *
 | 
			
		||||
 * The table containing the pending matches is protected by the pending_match_index:lock.
 | 
			
		||||
 * It is allowed to access the fields (crypto_handle and tokens) of a pending_match outside
 | 
			
		||||
 * the pending_match_index:lock provided that the pending_match is protected by the
 | 
			
		||||
 * lock of the entity corresponding to the local_guid.
 | 
			
		||||
 * A pending_match is either created when registering and matching an remote entity and
 | 
			
		||||
 * the corresponding crypto tokens are not available or when the crypto tokens associated
 | 
			
		||||
 * with a remote entity are received but it has not yet been discovered.
 | 
			
		||||
 */
 | 
			
		||||
struct guid_pair {
 | 
			
		||||
  ddsi_guid_t remote_guid;
 | 
			
		||||
  ddsi_guid_t local_guid;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pending_match {
 | 
			
		||||
  ddsrt_avl_node_t avlnode;
 | 
			
		||||
  ddsrt_fibheap_node_t heapnode;
 | 
			
		||||
  struct guid_pair guids;
 | 
			
		||||
  enum entity_kind kind;
 | 
			
		||||
  int64_t crypto_handle;
 | 
			
		||||
  DDS_Security_ParticipantCryptoTokenSeq *tokens;
 | 
			
		||||
  ddsrt_mtime_t expiry;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pending_match_index {
 | 
			
		||||
  ddsrt_mutex_t lock;
 | 
			
		||||
  const struct ddsi_domaingv *gv;
 | 
			
		||||
  ddsrt_avl_tree_t pending_matches;
 | 
			
		||||
  ddsrt_fibheap_t expiry_timers;
 | 
			
		||||
  struct xevent *evt;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dds_security_context {
 | 
			
		||||
  dds_security_plugin auth_plugin;
 | 
			
		||||
  dds_security_plugin ac_plugin;
 | 
			
		||||
| 
						 | 
				
			
			@ -168,6 +210,7 @@ struct dds_security_context {
 | 
			
		|||
  ddsrt_mutex_t omg_security_lock;
 | 
			
		||||
  uint32_t next_plugin_id;
 | 
			
		||||
 | 
			
		||||
  struct pending_match_index security_matches;
 | 
			
		||||
  struct participant_sec_index partiticpant_index;
 | 
			
		||||
 | 
			
		||||
  const struct ddsrt_log_cfg *logcfg;
 | 
			
		||||
| 
						 | 
				
			
			@ -178,15 +221,20 @@ typedef struct dds_security_context dds_security_context;
 | 
			
		|||
static int compare_guid(const void *va, const void *vb);
 | 
			
		||||
static int compare_crypto_handle (const void *va, const void *vb);
 | 
			
		||||
static int compare_guid_pair(const void *va, const void *vb);
 | 
			
		||||
static int compare_pending_match_exptime (const void *va, const void *vb);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const ddsrt_avl_ctreedef_t pp_proxypp_treedef =
 | 
			
		||||
    DDSRT_AVL_CTREEDEF_INITIALIZER (offsetof (struct pp_proxypp_match, avlnode), offsetof (struct pp_proxypp_match, proxypp_guid), compare_guid, 0);
 | 
			
		||||
const ddsrt_avl_treedef_t proxypp_pp_treedef =
 | 
			
		||||
  DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct proxypp_pp_match, avlnode), offsetof (struct proxypp_pp_match, pp_crypto_handle), compare_crypto_handle, 0);
 | 
			
		||||
const ddsrt_avl_treedef_t entity_match_treedef =
 | 
			
		||||
  DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct security_entity_match, avlnode), offsetof (struct security_entity_match, guids), compare_guid_pair, 0);
 | 
			
		||||
const ddsrt_avl_ctreedef_t participant_index_treedef =
 | 
			
		||||
    DDSRT_AVL_CTREEDEF_INITIALIZER (offsetof (struct participant_sec_attributes, avlnode), offsetof (struct participant_sec_attributes, crypto_handle), compare_crypto_handle, 0);
 | 
			
		||||
const ddsrt_avl_treedef_t pending_match_index_treedef =
 | 
			
		||||
  DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct pending_match, avlnode), offsetof (struct pending_match, guids), compare_guid_pair, 0);
 | 
			
		||||
 | 
			
		||||
const ddsrt_fibheap_def_t pending_match_expiry_fhdef = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct pending_match, heapnode), compare_pending_match_exptime);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int compare_crypto_handle (const void *va, const void *vb)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -211,15 +259,22 @@ static int compare_guid(const void *va, const void *vb)
 | 
			
		|||
 | 
			
		||||
static int compare_guid_pair(const void *va, const void *vb)
 | 
			
		||||
{
 | 
			
		||||
  const struct guid_pair *na = va;
 | 
			
		||||
  const struct guid_pair *nb = vb;
 | 
			
		||||
  const struct guid_pair *gpa = va;
 | 
			
		||||
  const struct guid_pair *gpb = vb;
 | 
			
		||||
  int r;
 | 
			
		||||
 | 
			
		||||
  if ((r = guid_compare(&na->src, &nb->src)) == 0)
 | 
			
		||||
    r = guid_compare(&na->dst, &nb->dst);
 | 
			
		||||
  if ((r = guid_compare(&gpa->remote_guid, &gpb->remote_guid)) == 0)
 | 
			
		||||
    r = guid_compare(&gpa->local_guid, &gpb->local_guid);
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int compare_pending_match_exptime (const void *va, const void *vb)
 | 
			
		||||
{
 | 
			
		||||
  const struct pending_match *ma = va;
 | 
			
		||||
  const struct pending_match *mb = vb;
 | 
			
		||||
  return (ma->expiry.v == mb->expiry.v) ? 0 : (ma->expiry.v < mb->expiry.v) ? -1 : 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct dds_security_context * q_omg_security_get_secure_context(const struct participant *pp)
 | 
			
		||||
{
 | 
			
		||||
  if (pp && pp->e.gv->security_context && q_omg_is_security_loaded(pp->e.gv->security_context))
 | 
			
		||||
| 
						 | 
				
			
			@ -258,97 +313,164 @@ void q_omg_log_exception(const struct ddsrt_log_cfg *lc, uint32_t cat, DDS_Secur
 | 
			
		|||
  DDS_Security_Exception_reset(exception);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct security_entity_match * entity_match_new(const ddsi_guid_t *src, const ddsi_guid_t *dst)
 | 
			
		||||
static void free_pending_match(struct pending_match *match)
 | 
			
		||||
{
 | 
			
		||||
  struct security_entity_match *match;
 | 
			
		||||
 | 
			
		||||
  match = ddsrt_malloc(sizeof(*match));
 | 
			
		||||
  match->guids.src = *src;
 | 
			
		||||
  match->guids.dst = *dst;
 | 
			
		||||
  match->matched = false;
 | 
			
		||||
  match->crypto_handle = 0;
 | 
			
		||||
  match->tokens = NULL;
 | 
			
		||||
 | 
			
		||||
  return match;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void entity_match_free(struct security_entity_match *match)
 | 
			
		||||
{
 | 
			
		||||
  if (match) {
 | 
			
		||||
    if (match->tokens)
 | 
			
		||||
      DDS_Security_ParticipantCryptoTokenSeq_free(match->tokens);
 | 
			
		||||
  if (match)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_Security_ParticipantCryptoTokenSeq_free(match->tokens);
 | 
			
		||||
    ddsrt_free(match);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct security_entity_match * find_entity_match_locked(struct dds_security_match_index *list, const ddsi_guid_t *src, const ddsi_guid_t *dst)
 | 
			
		||||
static void pending_match_expiry_cb(struct xevent *xev, void *varg, ddsrt_mtime_t tnow);
 | 
			
		||||
 | 
			
		||||
static struct pending_match * find_or_create_pending_entity_match(struct pending_match_index *index, enum entity_kind kind, const ddsi_guid_t *remote_guid, const ddsi_guid_t *local_guid, int64_t crypto_handle, DDS_Security_ParticipantCryptoTokenSeq *tokens)
 | 
			
		||||
{
 | 
			
		||||
  struct guid_pair guids;
 | 
			
		||||
  struct guid_pair guids = { .remote_guid = *remote_guid, .local_guid = *local_guid};
 | 
			
		||||
  struct pending_match *match;
 | 
			
		||||
  ddsrt_avl_ipath_t ipath;
 | 
			
		||||
 | 
			
		||||
  guids.src = *src;
 | 
			
		||||
  guids.dst = *dst;
 | 
			
		||||
 | 
			
		||||
  return ddsrt_avl_lookup(&entity_match_treedef, &list->matches, &guids);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct security_entity_match * find_or_create_entity_match(struct dds_security_match_index *list, const ddsi_guid_t *src, const ddsi_guid_t *dst)
 | 
			
		||||
{
 | 
			
		||||
  struct security_entity_match *match;
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&list->lock);
 | 
			
		||||
  match = find_entity_match_locked(list, src, dst);
 | 
			
		||||
  if (!match)
 | 
			
		||||
  ddsrt_mutex_lock(&index->lock);
 | 
			
		||||
  if ((match = ddsrt_avl_lookup_ipath(&pending_match_index_treedef, &index->pending_matches, &guids, &ipath)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    match = entity_match_new(src, dst);
 | 
			
		||||
    ddsrt_avl_insert(&entity_match_treedef, &list->matches, match);
 | 
			
		||||
    match = ddsrt_malloc(sizeof(*match));
 | 
			
		||||
    match->crypto_handle = 0;
 | 
			
		||||
    match->tokens = NULL;
 | 
			
		||||
    match->guids = guids;
 | 
			
		||||
    match->kind = kind;
 | 
			
		||||
    match->expiry = DDSRT_MTIME_NEVER;
 | 
			
		||||
    ddsrt_avl_insert_ipath(&pending_match_index_treedef, &index->pending_matches, match, &ipath);
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&list->lock);
 | 
			
		||||
 | 
			
		||||
  if (crypto_handle)
 | 
			
		||||
    match->crypto_handle = crypto_handle;
 | 
			
		||||
 | 
			
		||||
  if (tokens)
 | 
			
		||||
  {
 | 
			
		||||
    match->tokens = tokens;
 | 
			
		||||
    match->expiry = ddsrt_mtime_add_duration(ddsrt_time_monotonic(), DDS_SECS(PENDING_MATCH_EXPIRY_TIME));
 | 
			
		||||
    ddsrt_fibheap_insert(&pending_match_expiry_fhdef, &index->expiry_timers, match);
 | 
			
		||||
    (void)resched_xevent_if_earlier(index->evt, match->expiry);
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&index->lock);
 | 
			
		||||
 | 
			
		||||
  return match;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct security_entity_match * remove_entity_match(struct dds_security_match_index *list, const ddsi_guid_t *src, const ddsi_guid_t *dst)
 | 
			
		||||
static void unregister_and_free_pending_match(dds_security_context *sc, struct pending_match *match)
 | 
			
		||||
{
 | 
			
		||||
  struct security_entity_match *match;
 | 
			
		||||
  struct guid_pair guids;
 | 
			
		||||
  ddsrt_avl_dpath_t path;
 | 
			
		||||
  if (match->crypto_handle != 0)
 | 
			
		||||
  {
 | 
			
		||||
    DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
 | 
			
		||||
    const char *ename;
 | 
			
		||||
    bool r = true;
 | 
			
		||||
 | 
			
		||||
  guids.src = *src;
 | 
			
		||||
  guids.dst = *dst;
 | 
			
		||||
    switch (match->kind)
 | 
			
		||||
    {
 | 
			
		||||
    case EK_PROXY_PARTICIPANT:
 | 
			
		||||
      break;
 | 
			
		||||
    case EK_PROXY_READER:
 | 
			
		||||
      ename = "reader";
 | 
			
		||||
      r = sc->crypto_context->crypto_key_factory->unregister_datareader(sc->crypto_context->crypto_key_factory, match->crypto_handle, &exception);
 | 
			
		||||
      break;
 | 
			
		||||
    case EK_PROXY_WRITER:
 | 
			
		||||
      ename = "writer";
 | 
			
		||||
      r = sc->crypto_context->crypto_key_factory->unregister_datawriter(sc->crypto_context->crypto_key_factory, match->crypto_handle, &exception);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      assert(0);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    if (!r)
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to unregister remote %s crypto "PGUIDFMT" related to "PGUIDFMT, ename, PGUID(match->guids.remote_guid), PGUID(match->guids.local_guid));
 | 
			
		||||
  }
 | 
			
		||||
  free_pending_match(match);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&list->lock);
 | 
			
		||||
  match = ddsrt_avl_lookup_dpath(&entity_match_treedef, &list->matches, &guids, &path);
 | 
			
		||||
static void delete_pending_match(struct pending_match_index *index, struct pending_match *match)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_mutex_lock(&index->lock);
 | 
			
		||||
  ddsrt_avl_delete(&pending_match_index_treedef, &index->pending_matches, match);
 | 
			
		||||
  if (match->expiry.v != DDS_NEVER)
 | 
			
		||||
    ddsrt_fibheap_delete(&pending_match_expiry_fhdef, &index->expiry_timers, match);
 | 
			
		||||
  free_pending_match(match);
 | 
			
		||||
  ddsrt_mutex_unlock(&index->lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pending_match_expiry_cb(struct xevent *xev, void *varg, ddsrt_mtime_t tnow)
 | 
			
		||||
{
 | 
			
		||||
  struct pending_match_index *index = varg;
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&index->lock);
 | 
			
		||||
  struct pending_match *match = ddsrt_fibheap_min(&pending_match_expiry_fhdef, &index->expiry_timers);
 | 
			
		||||
  while (match && match->expiry.v <= tnow.v)
 | 
			
		||||
  {
 | 
			
		||||
    ddsrt_fibheap_delete(&pending_match_expiry_fhdef, &index->expiry_timers, match);
 | 
			
		||||
    ddsrt_avl_delete(&pending_match_index_treedef, &index->pending_matches, match);
 | 
			
		||||
    unregister_and_free_pending_match(index->gv->security_context, match);
 | 
			
		||||
    match = ddsrt_fibheap_min(&pending_match_expiry_fhdef, &index->expiry_timers);
 | 
			
		||||
  }
 | 
			
		||||
  if (match)
 | 
			
		||||
    ddsrt_avl_delete_dpath(&entity_match_treedef, &list->matches, match, &path);
 | 
			
		||||
  ddsrt_mutex_unlock(&list->lock);
 | 
			
		||||
 | 
			
		||||
  return match;
 | 
			
		||||
    resched_xevent_if_earlier(xev, match->expiry);
 | 
			
		||||
  ddsrt_mutex_unlock(&index->lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct dds_security_match_index * security_match_index_new(void)
 | 
			
		||||
static void clear_pending_matches_by_local_guid(dds_security_context *sc, struct pending_match_index *index, const ddsi_guid_t *local_guid)
 | 
			
		||||
{
 | 
			
		||||
  struct dds_security_match_index *list;
 | 
			
		||||
  struct pending_match *match;
 | 
			
		||||
 | 
			
		||||
  list  = ddsrt_malloc (sizeof(*list));
 | 
			
		||||
  ddsrt_mutex_init (&list->lock);
 | 
			
		||||
  ddsrt_avl_init (&entity_match_treedef, &list->matches);
 | 
			
		||||
  return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void entity_match_free_wrapper(void *arg)
 | 
			
		||||
{
 | 
			
		||||
  struct security_entity_match *match = arg;
 | 
			
		||||
  entity_match_free(match);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void security_match_index_free(struct dds_security_match_index *list)
 | 
			
		||||
{
 | 
			
		||||
  if (list)
 | 
			
		||||
  ddsrt_mutex_lock(&index->lock);
 | 
			
		||||
  match = ddsrt_avl_find_min(&pending_match_index_treedef, &index->pending_matches);
 | 
			
		||||
  while (match)
 | 
			
		||||
  {
 | 
			
		||||
    ddsrt_avl_free (&entity_match_treedef, &list->matches, entity_match_free_wrapper);
 | 
			
		||||
    ddsrt_mutex_destroy(&list->lock);
 | 
			
		||||
    ddsrt_free(list);
 | 
			
		||||
    struct pending_match *next = ddsrt_avl_find_succ(&pending_match_index_treedef, &index->pending_matches, match);
 | 
			
		||||
    if (guid_compare(&match->guids.local_guid, local_guid) == 0)
 | 
			
		||||
    {
 | 
			
		||||
      ddsrt_avl_delete(&pending_match_index_treedef, &index->pending_matches, match);
 | 
			
		||||
      if (match->expiry.v != DDS_NEVER)
 | 
			
		||||
        ddsrt_fibheap_delete(&pending_match_expiry_fhdef, &index->expiry_timers, match);
 | 
			
		||||
      next = ddsrt_avl_lookup_succ(&pending_match_index_treedef, &index->pending_matches, &match->guids);
 | 
			
		||||
      unregister_and_free_pending_match(sc, match);
 | 
			
		||||
    }
 | 
			
		||||
    match = next;
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&index->lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void clear_pending_matches_by_remote_guid(dds_security_context *sc, struct pending_match_index *index, const ddsi_guid_t *remote_guid)
 | 
			
		||||
{
 | 
			
		||||
  struct guid_pair template = { .remote_guid = *remote_guid, .local_guid = {.prefix.u = {0, 0, 0}, .entityid.u = 0} };
 | 
			
		||||
  struct pending_match *match;
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&index->lock);
 | 
			
		||||
  match = ddsrt_avl_lookup_succ(&pending_match_index_treedef, &index->pending_matches, &template);
 | 
			
		||||
  while (match && guid_compare(&match->guids.remote_guid, remote_guid) == 0)
 | 
			
		||||
  {
 | 
			
		||||
    struct pending_match *next = ddsrt_avl_lookup_succ(&pending_match_index_treedef, &index->pending_matches, &match->guids);
 | 
			
		||||
    ddsrt_avl_delete(&pending_match_index_treedef, &index->pending_matches, match);
 | 
			
		||||
    if (match->expiry.v != DDS_NEVER)
 | 
			
		||||
      ddsrt_fibheap_delete(&pending_match_expiry_fhdef, &index->expiry_timers, match);
 | 
			
		||||
    unregister_and_free_pending_match(sc, match);
 | 
			
		||||
    match = next;
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&index->lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pending_match_index_init(const struct ddsi_domaingv *gv, struct pending_match_index *index)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_mutex_init(&index->lock);
 | 
			
		||||
  ddsrt_avl_init(&pending_match_index_treedef, &index->pending_matches);
 | 
			
		||||
  ddsrt_fibheap_init(&pending_match_expiry_fhdef, &index->expiry_timers);
 | 
			
		||||
  index->gv = gv;
 | 
			
		||||
  index->evt = qxev_callback(gv->xevents, DDSRT_MTIME_NEVER, pending_match_expiry_cb, index);;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pending_match_index_deinit(struct pending_match_index *index)
 | 
			
		||||
{
 | 
			
		||||
  delete_xevent_callback(index->evt);
 | 
			
		||||
  ddsrt_mutex_destroy(&index->lock);
 | 
			
		||||
  assert(ddsrt_avl_is_empty(&index->pending_matches));
 | 
			
		||||
  ddsrt_avl_free(&pending_match_index_treedef, &index->pending_matches, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct pp_proxypp_match * pp_proxypp_match_new(struct proxy_participant *proxypp, DDS_Security_ParticipantCryptoHandle proxypp_crypto_handle)
 | 
			
		||||
| 
						 | 
				
			
			@ -420,16 +542,12 @@ static void pp_proxypp_unrelate(struct dds_security_context *sc, struct particip
 | 
			
		|||
 | 
			
		||||
static void proxypp_pp_unrelate(struct dds_security_context *sc, struct proxy_participant *proxypp, const ddsi_guid_t *pp_guid, int64_t pp_crypto_handle)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(pp_guid);
 | 
			
		||||
  if (proxypp->sec_attr)
 | 
			
		||||
  {
 | 
			
		||||
    struct proxypp_pp_match *pm;
 | 
			
		||||
    struct security_entity_match *match;
 | 
			
		||||
    ddsrt_avl_dpath_t dpath;
 | 
			
		||||
 | 
			
		||||
    match = remove_entity_match(proxypp->e.gv->security_matches, &proxypp->e.guid, pp_guid);
 | 
			
		||||
    if (match)
 | 
			
		||||
      entity_match_free(match);
 | 
			
		||||
 | 
			
		||||
    ddsrt_mutex_lock(&proxypp->sec_attr->lock);
 | 
			
		||||
    if ((pm = ddsrt_avl_lookup_dpath(&proxypp_pp_treedef, &proxypp->sec_attr->participants, &pp_crypto_handle, &dpath)) != NULL)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -594,12 +712,12 @@ void q_omg_security_init (struct ddsi_domaingv *gv)
 | 
			
		|||
 | 
			
		||||
  ddsrt_mutex_init(&sc->partiticpant_index.lock);
 | 
			
		||||
  ddsrt_avl_cinit(&participant_index_treedef, &sc->partiticpant_index.participants);
 | 
			
		||||
  pending_match_index_init(gv, &sc->security_matches);
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_init (&sc->omg_security_lock);
 | 
			
		||||
  sc->logcfg = &gv->logconfig;
 | 
			
		||||
 | 
			
		||||
  gv->security_context = sc;
 | 
			
		||||
  gv->security_matches = security_match_index_new();
 | 
			
		||||
 | 
			
		||||
  ddsi_handshake_admin_init(gv);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -628,27 +746,24 @@ void q_omg_security_stop (struct ddsi_domaingv *gv)
 | 
			
		|||
  ddsi_handshake_admin_stop(gv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void q_omg_security_deinit (struct ddsi_domaingv *gv)
 | 
			
		||||
void q_omg_security_deinit (struct dds_security_context *sc)
 | 
			
		||||
{
 | 
			
		||||
  pending_match_index_deinit(&sc->security_matches);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void q_omg_security_free (struct ddsi_domaingv *gv)
 | 
			
		||||
{
 | 
			
		||||
  dds_security_context *sc = gv->security_context;
 | 
			
		||||
 | 
			
		||||
  assert (gv->security_context != NULL);
 | 
			
		||||
 | 
			
		||||
  ddsrt_avl_cfree(&participant_index_treedef, &sc->partiticpant_index.participants, 0);
 | 
			
		||||
  ddsrt_mutex_destroy(&sc->partiticpant_index.lock);
 | 
			
		||||
 | 
			
		||||
  if (gv->security_context->authentication_context != NULL && gv->security_context->access_control_context != NULL && gv->security_context->crypto_context != NULL){
 | 
			
		||||
    release_plugins (gv->security_context);
 | 
			
		||||
  if (sc->authentication_context != NULL && sc->access_control_context != NULL && sc->crypto_context != NULL){
 | 
			
		||||
    release_plugins (sc);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ddsi_handshake_admin_deinit(gv);
 | 
			
		||||
 | 
			
		||||
  security_match_index_free(gv->security_matches);
 | 
			
		||||
  gv->security_matches = NULL;
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_destroy (&gv->security_context->omg_security_lock);
 | 
			
		||||
 | 
			
		||||
  ddsrt_free(gv->security_context);
 | 
			
		||||
  ddsrt_mutex_destroy (&sc->omg_security_lock);
 | 
			
		||||
  ddsrt_free(sc);
 | 
			
		||||
  gv->security_context = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1018,6 +1133,8 @@ void q_omg_security_deregister_participant(struct participant *pp)
 | 
			
		|||
    qxev_nt_callback(pp->e.gv->xevents, cleanup_participant_sec_attributes, arg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  clear_pending_matches_by_local_guid(sc, &sc->security_matches, &pp->e.guid);
 | 
			
		||||
 | 
			
		||||
  pp->sec_attr = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1270,6 +1387,8 @@ void q_omg_security_deregister_writer(struct writer *wr)
 | 
			
		|||
 | 
			
		||||
  if (wr->sec_attr)
 | 
			
		||||
  {
 | 
			
		||||
    clear_pending_matches_by_local_guid(sc, &sc->security_matches, &wr->e.guid);
 | 
			
		||||
 | 
			
		||||
    if (wr->sec_attr->crypto_handle != DDS_SECURITY_HANDLE_NIL)
 | 
			
		||||
    {
 | 
			
		||||
      if (!sc->crypto_context->crypto_key_factory->unregister_datawriter(sc->crypto_context->crypto_key_factory, wr->sec_attr->crypto_handle, &exception))
 | 
			
		||||
| 
						 | 
				
			
			@ -1388,6 +1507,9 @@ void q_omg_security_deregister_reader(struct reader *rd)
 | 
			
		|||
  if (rd->sec_attr)
 | 
			
		||||
  {
 | 
			
		||||
    assert(sc);
 | 
			
		||||
 | 
			
		||||
    clear_pending_matches_by_local_guid(sc, &sc->security_matches, &rd->e.guid);
 | 
			
		||||
 | 
			
		||||
    if (rd->sec_attr->crypto_handle != DDS_SECURITY_HANDLE_NIL)
 | 
			
		||||
    {
 | 
			
		||||
      if (!sc->crypto_context->crypto_key_factory->unregister_datareader(sc->crypto_context->crypto_key_factory, rd->sec_attr->crypto_handle, &exception))
 | 
			
		||||
| 
						 | 
				
			
			@ -1648,29 +1770,19 @@ bool q_omg_security_register_remote_participant(struct participant *pp, struct p
 | 
			
		|||
  GVTRACE("match pp->crypto=%"PRId64" proxypp->crypto=%"PRId64" permissions=%"PRId64"\n", pp->sec_attr->crypto_handle, crypto_handle, permissions_handle);
 | 
			
		||||
  match_proxypp_pp(pp, proxypp, permissions_handle, shared_secret);
 | 
			
		||||
 | 
			
		||||
  GVTRACE("create proxypp-pp match pp="PGUIDFMT" proxypp="PGUIDFMT" lidh=%"PRId64, PGUID(pp->e.guid), PGUID(proxypp->e.guid), pp->sec_attr->local_identity_handle);
 | 
			
		||||
  GVTRACE(" create proxypp-pp match pp="PGUIDFMT" proxypp="PGUIDFMT" lidh=%"PRId64"\n", PGUID(pp->e.guid), PGUID(proxypp->e.guid), pp->sec_attr->local_identity_handle);
 | 
			
		||||
 | 
			
		||||
  if (proxypp_is_rtps_protected(proxypp))
 | 
			
		||||
  {
 | 
			
		||||
    struct security_entity_match *m = find_or_create_entity_match(gv->security_matches, &proxypp->e.guid, &pp->e.guid);
 | 
			
		||||
    m->crypto_handle = crypto_handle;
 | 
			
		||||
    if (m->tokens)
 | 
			
		||||
    struct pending_match *match = find_or_create_pending_entity_match(&sc->security_matches, EK_PROXY_PARTICIPANT, &proxypp->e.guid, &pp->e.guid, crypto_handle, NULL);
 | 
			
		||||
    if (match->tokens)
 | 
			
		||||
    {
 | 
			
		||||
      ret = sc->crypto_context->crypto_key_exchange->set_remote_participant_crypto_tokens(sc->crypto_context->crypto_key_exchange, pp->sec_attr->crypto_handle, crypto_handle, m->tokens, &exception);
 | 
			
		||||
      if (ret)
 | 
			
		||||
      {
 | 
			
		||||
        struct security_entity_match *mx;
 | 
			
		||||
        mx = remove_entity_match(proxypp->e.gv->security_matches, &proxypp->e.guid, &pp->e.guid);
 | 
			
		||||
        assert(mx == m);
 | 
			
		||||
        (void)mx;
 | 
			
		||||
        entity_match_free(m);
 | 
			
		||||
        GVTRACE("set participant tokens src("PGUIDFMT") to dst("PGUIDFMT") (by registering remote)\n", PGUID(proxypp->e.guid), PGUID(pp->e.guid));
 | 
			
		||||
      }
 | 
			
		||||
      ret = sc->crypto_context->crypto_key_exchange->set_remote_participant_crypto_tokens(sc->crypto_context->crypto_key_exchange, pp->sec_attr->crypto_handle, crypto_handle, match->tokens, &exception);
 | 
			
		||||
      if (!ret)
 | 
			
		||||
        EXCEPTION_ERROR(sc, &exception, " Failed to set remote participant crypto tokens "PGUIDFMT" --> "PGUIDFMT, PGUID(proxypp->e.guid), PGUID(pp->e.guid));
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        EXCEPTION_ERROR(sc, &exception, "Failed to set remote participant crypto tokens "PGUIDFMT" --> "PGUIDFMT, PGUID(proxypp->e.guid), PGUID(pp->e.guid));
 | 
			
		||||
        ret = false;
 | 
			
		||||
      }
 | 
			
		||||
        GVTRACE(" set participant tokens src("PGUIDFMT") to dst("PGUIDFMT") (by registering remote)\n", PGUID(proxypp->e.guid), PGUID(pp->e.guid));
 | 
			
		||||
      delete_pending_match(&sc->security_matches, match);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      notify_handshake = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -1738,6 +1850,8 @@ void q_omg_security_deregister_remote_participant(struct proxy_participant *prox
 | 
			
		|||
      pm = next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clear_pending_matches_by_remote_guid(sc, &sc->security_matches, &proxypp->e.guid);
 | 
			
		||||
 | 
			
		||||
    if (proxypp->sec_attr->crypto_handle != DDS_SECURITY_HANDLE_NIL)
 | 
			
		||||
    {
 | 
			
		||||
        if (!sc->crypto_context->crypto_key_factory->unregister_participant(sc->crypto_context->crypto_key_factory, proxypp->sec_attr->crypto_handle, &exception))
 | 
			
		||||
| 
						 | 
				
			
			@ -1820,36 +1934,33 @@ void q_omg_security_set_participant_crypto_tokens(struct participant *pp, struct
 | 
			
		|||
  DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
 | 
			
		||||
  struct proxypp_pp_match *pm;
 | 
			
		||||
  DDS_Security_DatawriterCryptoTokenSeq *tseq;
 | 
			
		||||
  struct security_entity_match *m;
 | 
			
		||||
 | 
			
		||||
  if (!sc)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tseq = DDS_Security_DataHolderSeq_alloc();
 | 
			
		||||
  q_omg_copyin_DataHolderSeq(tseq, tokens);
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&proxypp->sec_attr->lock);
 | 
			
		||||
  pm = ddsrt_avl_lookup (&proxypp_pp_treedef, &proxypp->sec_attr->participants, &pp->sec_attr->crypto_handle);
 | 
			
		||||
  ddsrt_mutex_unlock(&proxypp->sec_attr->lock);
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&pp->e.lock);
 | 
			
		||||
  m = find_or_create_entity_match(gv->security_matches, &proxypp->e.guid, &pp->e.guid);
 | 
			
		||||
 | 
			
		||||
  tseq = DDS_Security_DataHolderSeq_alloc();
 | 
			
		||||
  q_omg_copyin_DataHolderSeq(tseq, tokens);
 | 
			
		||||
 | 
			
		||||
  if (!pm)
 | 
			
		||||
  {
 | 
			
		||||
    GVTRACE("remember participant tokens src("PGUIDFMT") dst("PGUIDFMT")\n", PGUID(proxypp->e.guid), PGUID(pp->e.guid));
 | 
			
		||||
    m->tokens = tseq;
 | 
			
		||||
    (void)find_or_create_pending_entity_match(&sc->security_matches, EK_PROXY_PARTICIPANT, &proxypp->e.guid, &pp->e.guid, 0, tseq);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if (sc->crypto_context->crypto_key_exchange->set_remote_participant_crypto_tokens(sc->crypto_context->crypto_key_exchange, pp->sec_attr->crypto_handle, proxypp->sec_attr->crypto_handle, tseq, &exception))
 | 
			
		||||
    {
 | 
			
		||||
      m->matched= true;
 | 
			
		||||
      GVTRACE("set participant tokens src("PGUIDFMT") dst("PGUIDFMT")\n", PGUID(proxypp->e.guid), PGUID(pp->e.guid));
 | 
			
		||||
      GVTRACE(" set participant tokens src("PGUIDFMT") dst("PGUIDFMT")\n", PGUID(proxypp->e.guid), PGUID(pp->e.guid));
 | 
			
		||||
      DDS_Security_DataHolderSeq_free(tseq);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to set remote participant crypto tokens "PGUIDFMT" for participant "PGUIDFMT, PGUID(proxypp->e.guid), PGUID(pp->e.guid));
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, " Failed to set remote participant crypto tokens "PGUIDFMT" for participant "PGUIDFMT, PGUID(proxypp->e.guid), PGUID(pp->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&pp->e.lock);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1986,64 +2097,68 @@ static bool q_omg_security_register_remote_writer_match(struct proxy_writer *pwr
 | 
			
		|||
  struct ddsi_domaingv *gv = pp->e.gv;
 | 
			
		||||
  struct dds_security_context *sc = q_omg_security_get_secure_context(pp);
 | 
			
		||||
  DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
 | 
			
		||||
  struct proxypp_pp_match *pm;
 | 
			
		||||
  struct security_entity_match *match;
 | 
			
		||||
  struct proxypp_pp_match *proxypp_match;
 | 
			
		||||
  struct rd_pwr_match *match;
 | 
			
		||||
  bool send_tokens = false;
 | 
			
		||||
  bool allowed = false;
 | 
			
		||||
 | 
			
		||||
  *crypto_handle = 0;
 | 
			
		||||
 | 
			
		||||
  if ((pm = get_pp_proxypp_match_if_authenticated(pp, proxypp, pwr->e.guid.entityid)) == NULL)
 | 
			
		||||
  if ((proxypp_match = get_pp_proxypp_match_if_authenticated(pp, proxypp, pwr->e.guid.entityid)) == NULL)
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  /* TODO: the security_entity_match should be removed after the the received tokens are stored in the plugin.
 | 
			
		||||
   * Currently the security_entity_match is also used to detect if a match between a reader and writer has
 | 
			
		||||
   * already been completed.
 | 
			
		||||
   */
 | 
			
		||||
  ddsrt_mutex_lock(&rd->e.lock);
 | 
			
		||||
  match = find_or_create_entity_match(gv->security_matches, &pwr->e.guid, &rd->e.guid);
 | 
			
		||||
  if (match->matched)
 | 
			
		||||
    *crypto_handle = match->crypto_handle;
 | 
			
		||||
  else if (match->crypto_handle == 0)
 | 
			
		||||
  if ((match = ddsrt_avl_lookup (&rd_writers_treedef, &rd->writers, &pwr->e.guid)) != NULL)
 | 
			
		||||
    allowed = true;
 | 
			
		||||
  else if (rd->e.guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER)
 | 
			
		||||
  {
 | 
			
		||||
    /* Generate writer crypto info. */
 | 
			
		||||
    match->crypto_handle = sc->crypto_context->crypto_key_factory->register_matched_remote_datawriter(
 | 
			
		||||
        sc->crypto_context->crypto_key_factory, rd->sec_attr->crypto_handle, proxypp->sec_attr->crypto_handle, pm->shared_secret, &exception);
 | 
			
		||||
    /* The builtin ParticipantVolatileSecure endpoints do not exchange tokens.
 | 
			
		||||
     * Simulate that we already got them. */
 | 
			
		||||
 | 
			
		||||
    *crypto_handle = match->crypto_handle;
 | 
			
		||||
 | 
			
		||||
    if (match->crypto_handle == 0)
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to register remote writer "PGUIDFMT" with reader "PGUIDFMT, PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
    else if (rd->e.guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER)
 | 
			
		||||
    *crypto_handle = sc->crypto_context->crypto_key_factory->register_matched_remote_datawriter(
 | 
			
		||||
        sc->crypto_context->crypto_key_factory, rd->sec_attr->crypto_handle, proxypp->sec_attr->crypto_handle, proxypp_match->shared_secret, &exception);
 | 
			
		||||
    if (*crypto_handle != 0)
 | 
			
		||||
    {
 | 
			
		||||
      /* The builtin ParticipantVolatileSecure endpoints do not exchange tokens.
 | 
			
		||||
       * Simulate that we already got them. */
 | 
			
		||||
      match->matched = true;
 | 
			
		||||
      GVTRACE(" volatile secure reader: proxypp_crypto=%"PRId64" rd_crypto=%"PRId64" pwr_crypto=%"PRId64"\n", proxypp->sec_attr->crypto_handle, rd->sec_attr->crypto_handle, match->crypto_handle);
 | 
			
		||||
      GVTRACE(" volatile secure reader: proxypp_crypto=%"PRId64" rd_crypto=%"PRId64" pwr_crypto=%"PRId64"\n", proxypp->sec_attr->crypto_handle, rd->sec_attr->crypto_handle, *crypto_handle);
 | 
			
		||||
      allowed = true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to register remote writer "PGUIDFMT" with reader "PGUIDFMT, PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    struct pending_match *pending_match = find_or_create_pending_entity_match(&sc->security_matches, EK_PROXY_WRITER, &pwr->e.guid, &rd->e.guid, 0, NULL);
 | 
			
		||||
 | 
			
		||||
    /* Generate writer crypto info. */
 | 
			
		||||
    if (pending_match->crypto_handle == 0)
 | 
			
		||||
    {
 | 
			
		||||
      send_tokens = true;
 | 
			
		||||
      if (match->tokens)
 | 
			
		||||
      *crypto_handle = sc->crypto_context->crypto_key_factory->register_matched_remote_datawriter(
 | 
			
		||||
          sc->crypto_context->crypto_key_factory, rd->sec_attr->crypto_handle, proxypp->sec_attr->crypto_handle, proxypp_match->shared_secret, &exception);
 | 
			
		||||
      if (*crypto_handle == 0)
 | 
			
		||||
        EXCEPTION_ERROR(sc, &exception, "Failed to register remote writer "PGUIDFMT" with reader "PGUIDFMT, PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        if (sc->crypto_context->crypto_key_exchange->set_remote_datawriter_crypto_tokens(
 | 
			
		||||
            sc->crypto_context->crypto_key_exchange, rd->sec_attr->crypto_handle, match->crypto_handle, match->tokens, &exception))
 | 
			
		||||
        pending_match->crypto_handle = *crypto_handle;
 | 
			
		||||
        send_tokens = true;
 | 
			
		||||
        if (pending_match->tokens)
 | 
			
		||||
        {
 | 
			
		||||
          match->matched = true;
 | 
			
		||||
          DDS_Security_DataHolderSeq_free(match->tokens);
 | 
			
		||||
          match->tokens = NULL;
 | 
			
		||||
          GVTRACE("match_remote_writer "PGUIDFMT" with reader "PGUIDFMT": tokens available\n", PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
          if (!sc->crypto_context->crypto_key_exchange->set_remote_datawriter_crypto_tokens(
 | 
			
		||||
              sc->crypto_context->crypto_key_exchange, rd->sec_attr->crypto_handle, *crypto_handle, pending_match->tokens, &exception))
 | 
			
		||||
            EXCEPTION_ERROR(sc, &exception, "Failed to set remote writer crypto tokens "PGUIDFMT" --> "PGUIDFMT, PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
          else
 | 
			
		||||
          {
 | 
			
		||||
            GVTRACE("match_remote_writer "PGUIDFMT" with reader "PGUIDFMT": tokens available\n", PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
            allowed = true;
 | 
			
		||||
          }
 | 
			
		||||
          delete_pending_match(&sc->security_matches, pending_match);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
          EXCEPTION_ERROR(sc, &exception, "Failed to set remote writer crypto tokens "PGUIDFMT" --> "PGUIDFMT, PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&rd->e.lock);
 | 
			
		||||
 | 
			
		||||
  if (send_tokens)
 | 
			
		||||
    (void)send_reader_crypto_tokens(rd, pwr, rd->sec_attr->crypto_handle, match->crypto_handle);
 | 
			
		||||
    (void)send_reader_crypto_tokens(rd, pwr, rd->sec_attr->crypto_handle, *crypto_handle);
 | 
			
		||||
 | 
			
		||||
  return match->matched;
 | 
			
		||||
  return allowed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool q_omg_security_match_remote_writer_enabled(struct reader *rd, struct proxy_writer *pwr, int64_t *crypto_handle)
 | 
			
		||||
| 
						 | 
				
			
			@ -2051,6 +2166,8 @@ bool q_omg_security_match_remote_writer_enabled(struct reader *rd, struct proxy_
 | 
			
		|||
  struct ddsi_domaingv *gv = rd->e.gv;
 | 
			
		||||
  nn_security_info_t info;
 | 
			
		||||
 | 
			
		||||
  *crypto_handle = 0;
 | 
			
		||||
 | 
			
		||||
  if (!rd->sec_attr)
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2106,21 +2223,23 @@ void q_omg_security_deregister_remote_writer_match(const struct ddsi_domaingv *g
 | 
			
		|||
{
 | 
			
		||||
  struct dds_security_context *sc = gv->security_context;
 | 
			
		||||
  DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
 | 
			
		||||
  struct security_entity_match *match = NULL;
 | 
			
		||||
 | 
			
		||||
  if (m->crypto_handle != 0)
 | 
			
		||||
  {
 | 
			
		||||
    match = remove_entity_match(gv->security_matches, &m->pwr_guid, rd_guid);
 | 
			
		||||
    if (match)
 | 
			
		||||
    {
 | 
			
		||||
      assert(match->crypto_handle == m->crypto_handle);
 | 
			
		||||
      if (!sc->crypto_context->crypto_key_factory->unregister_datawriter(sc->crypto_context->crypto_key_factory, match->crypto_handle, &exception))
 | 
			
		||||
        EXCEPTION_ERROR(sc, &exception, "Failed to unregster remote writer "PGUIDFMT" for reader "PGUIDFMT, PGUID(m->pwr_guid), PGUID(*rd_guid));
 | 
			
		||||
      entity_match_free(match);
 | 
			
		||||
    }
 | 
			
		||||
    if (!sc->crypto_context->crypto_key_factory->unregister_datawriter(sc->crypto_context->crypto_key_factory, m->crypto_handle, &exception))
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to unregister remote writer "PGUIDFMT" for reader "PGUIDFMT, PGUID(m->pwr_guid), PGUID(*rd_guid));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void q_omg_security_deregister_remote_writer(const struct proxy_writer *pwr)
 | 
			
		||||
{
 | 
			
		||||
  struct ddsi_domaingv *gv = pwr->e.gv;
 | 
			
		||||
  struct dds_security_context *sc = gv->security_context;
 | 
			
		||||
 | 
			
		||||
  if (q_omg_proxy_participant_is_secure(pwr->c.proxypp))
 | 
			
		||||
    clear_pending_matches_by_remote_guid(sc, &sc->security_matches, &pwr->e.guid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool q_omg_security_check_remote_reader_permissions(const struct proxy_reader *prd, uint32_t domain_id, struct participant *pp, bool *relay_only)
 | 
			
		||||
{
 | 
			
		||||
  struct ddsi_domaingv *gv = pp->e.gv;
 | 
			
		||||
| 
						 | 
				
			
			@ -2260,22 +2379,23 @@ void q_omg_security_deregister_remote_reader_match(const struct ddsi_domaingv *g
 | 
			
		|||
{
 | 
			
		||||
  struct dds_security_context *sc = gv->security_context;
 | 
			
		||||
  DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
 | 
			
		||||
  struct security_entity_match *match = NULL;
 | 
			
		||||
 | 
			
		||||
  if (m->crypto_handle)
 | 
			
		||||
  if (m->crypto_handle != 0)
 | 
			
		||||
  {
 | 
			
		||||
    match = remove_entity_match(gv->security_matches, &m->prd_guid, wr_guid);
 | 
			
		||||
    if (match)
 | 
			
		||||
    {
 | 
			
		||||
      assert(match->crypto_handle == m->crypto_handle);
 | 
			
		||||
 | 
			
		||||
      if (!sc->crypto_context->crypto_key_factory->unregister_datareader(sc->crypto_context->crypto_key_factory, match->crypto_handle, &exception))
 | 
			
		||||
        EXCEPTION_ERROR(sc, &exception, "Failed to unregister remote reader "PGUIDFMT" for writer "PGUIDFMT, PGUID(m->prd_guid), PGUID(*wr_guid));
 | 
			
		||||
      entity_match_free(match);
 | 
			
		||||
    }
 | 
			
		||||
    if (!sc->crypto_context->crypto_key_factory->unregister_datareader(sc->crypto_context->crypto_key_factory, m->crypto_handle, &exception))
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to unregister remote reader "PGUIDFMT" for writer "PGUIDFMT, PGUID(m->prd_guid), PGUID(*wr_guid));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void q_omg_security_deregister_remote_reader(const struct proxy_reader *prd)
 | 
			
		||||
{
 | 
			
		||||
  struct ddsi_domaingv *gv = prd->e.gv;
 | 
			
		||||
  struct dds_security_context *sc = gv->security_context;
 | 
			
		||||
 | 
			
		||||
  if (q_omg_proxy_participant_is_secure(prd->c.proxypp))
 | 
			
		||||
    clear_pending_matches_by_remote_guid(sc, &sc->security_matches, &prd->e.guid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void send_writer_crypto_tokens(struct writer *wr, struct proxy_reader *prd, DDS_Security_DatawriterCryptoHandle local_crypto, DDS_Security_DatareaderCryptoHandle remote_crypto)
 | 
			
		||||
{
 | 
			
		||||
  struct dds_security_context *sc = q_omg_security_get_secure_context(wr->c.pp);
 | 
			
		||||
| 
						 | 
				
			
			@ -2309,66 +2429,70 @@ static bool q_omg_security_register_remote_reader_match(struct proxy_reader *prd
 | 
			
		|||
  struct ddsi_domaingv *gv = pp->e.gv;
 | 
			
		||||
  struct dds_security_context *sc = q_omg_security_get_secure_context(pp);
 | 
			
		||||
  DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
 | 
			
		||||
  struct proxypp_pp_match *pm;
 | 
			
		||||
  struct security_entity_match *match;
 | 
			
		||||
  struct proxypp_pp_match *proxypp_match;
 | 
			
		||||
  struct wr_prd_match *match;
 | 
			
		||||
  bool send_tokens = false;
 | 
			
		||||
  bool allowed = false;
 | 
			
		||||
 | 
			
		||||
  *crypto_handle = 0;
 | 
			
		||||
 | 
			
		||||
  if ((pm = get_pp_proxypp_match_if_authenticated(pp, proxypp, prd->e.guid.entityid)) == NULL)
 | 
			
		||||
  if ((proxypp_match = get_pp_proxypp_match_if_authenticated(pp, proxypp, prd->e.guid.entityid)) == NULL)
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  /* TODO: the security_entity_match should be removed after the the received tokens are stored in the plugin.
 | 
			
		||||
   * Currently the security_entity_match is also used to detect if a match between a reader and writer has
 | 
			
		||||
   * already been completed.
 | 
			
		||||
   */
 | 
			
		||||
  ddsrt_mutex_lock(&wr->e.lock);
 | 
			
		||||
  match = find_or_create_entity_match(gv->security_matches, &prd->e.guid, &wr->e.guid);
 | 
			
		||||
  if (match->matched)
 | 
			
		||||
    *crypto_handle = match->crypto_handle;
 | 
			
		||||
  else if (match->crypto_handle == 0)
 | 
			
		||||
  if ((match = ddsrt_avl_lookup (&wr_readers_treedef, &wr->readers, &prd->e.guid)) != NULL)
 | 
			
		||||
    allowed = true;
 | 
			
		||||
  else if (wr->e.guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER || !wr->sec_attr->attr.is_submessage_protected)
 | 
			
		||||
  {
 | 
			
		||||
    /* Generate writer crypto info. */
 | 
			
		||||
    match->crypto_handle = sc->crypto_context->crypto_key_factory->register_matched_remote_datareader(
 | 
			
		||||
        sc->crypto_context->crypto_key_factory, wr->sec_attr->crypto_handle, proxypp->sec_attr->crypto_handle, pm->shared_secret, relay_only, &exception);
 | 
			
		||||
    /* The builtin ParticipantVolatileSecure endpoints do not exchange tokens.
 | 
			
		||||
     * Simulate that we already got them. */
 | 
			
		||||
 | 
			
		||||
    *crypto_handle = match->crypto_handle;
 | 
			
		||||
 | 
			
		||||
    if (match->crypto_handle == 0)
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to register remote reader "PGUIDFMT" with writer "PGUIDFMT, PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
    else if (wr->e.guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER)
 | 
			
		||||
    *crypto_handle = sc->crypto_context->crypto_key_factory->register_matched_remote_datareader(
 | 
			
		||||
        sc->crypto_context->crypto_key_factory, wr->sec_attr->crypto_handle, proxypp->sec_attr->crypto_handle, proxypp_match->shared_secret, relay_only, &exception);
 | 
			
		||||
    if (*crypto_handle != 0)
 | 
			
		||||
    {
 | 
			
		||||
      /* The builtin ParticipantVolatileSecure endpoints do not exchange tokens.
 | 
			
		||||
       * Simulate that we already got them. */
 | 
			
		||||
      match->matched = true;
 | 
			
		||||
      GVTRACE(" volatile secure writer: proxypp_crypto=%"PRId64" wr_crypto=%"PRId64" prd_crypto=%"PRId64"\n", proxypp->sec_attr->crypto_handle, wr->sec_attr->crypto_handle, match->crypto_handle);
 | 
			
		||||
      GVTRACE(" match_remote_reader: proxypp_crypto=%"PRId64" wr_crypto=%"PRId64" prd_crypto=%"PRId64"\n", proxypp->sec_attr->crypto_handle, wr->sec_attr->crypto_handle, *crypto_handle);
 | 
			
		||||
      send_tokens = (wr->e.guid.entityid.u != NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER);
 | 
			
		||||
      allowed = true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to register remote reader "PGUIDFMT" with writer "PGUIDFMT, PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    struct pending_match *pending_match = find_or_create_pending_entity_match(&sc->security_matches, EK_PROXY_READER, &prd->e.guid, &wr->e.guid, 0, NULL);
 | 
			
		||||
 | 
			
		||||
    /* Generate writer crypto info. */
 | 
			
		||||
    if (pending_match->crypto_handle == 0)
 | 
			
		||||
    {
 | 
			
		||||
      send_tokens = true;
 | 
			
		||||
      if (match->tokens)
 | 
			
		||||
      *crypto_handle = sc->crypto_context->crypto_key_factory->register_matched_remote_datareader(
 | 
			
		||||
          sc->crypto_context->crypto_key_factory, wr->sec_attr->crypto_handle, proxypp->sec_attr->crypto_handle, proxypp_match->shared_secret, relay_only, &exception);
 | 
			
		||||
      if (*crypto_handle == 0)
 | 
			
		||||
        EXCEPTION_ERROR(sc, &exception, "Failed to register remote reader "PGUIDFMT" with writer "PGUIDFMT, PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        if (sc->crypto_context->crypto_key_exchange->set_remote_datareader_crypto_tokens(
 | 
			
		||||
            sc->crypto_context->crypto_key_exchange, wr->sec_attr->crypto_handle, match->crypto_handle, match->tokens, &exception))
 | 
			
		||||
        pending_match->crypto_handle = *crypto_handle;
 | 
			
		||||
        send_tokens = true;
 | 
			
		||||
        GVTRACE(" register_remote_reader_match: proxypp_crypto=%"PRId64" wr_crypto=%"PRId64" prd_crypto=%"PRId64"\n", proxypp->sec_attr->crypto_handle, wr->sec_attr->crypto_handle, *crypto_handle);
 | 
			
		||||
        if (pending_match->tokens)
 | 
			
		||||
        {
 | 
			
		||||
          match->matched = true;
 | 
			
		||||
          DDS_Security_DataHolderSeq_free(match->tokens);
 | 
			
		||||
          match->tokens = NULL;;
 | 
			
		||||
          GVTRACE("match_remote_reader "PGUIDFMT" with writer "PGUIDFMT": tokens available\n", PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
          if (!sc->crypto_context->crypto_key_exchange->set_remote_datareader_crypto_tokens(
 | 
			
		||||
              sc->crypto_context->crypto_key_exchange, wr->sec_attr->crypto_handle, *crypto_handle, pending_match->tokens, &exception))
 | 
			
		||||
            EXCEPTION_ERROR(sc, &exception, "Failed to set remote reader crypto tokens "PGUIDFMT" --> "PGUIDFMT, PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
          else
 | 
			
		||||
          {
 | 
			
		||||
            GVTRACE(" match_remote_reader "PGUIDFMT" with writer "PGUIDFMT": tokens available\n", PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
            allowed = true;
 | 
			
		||||
          }
 | 
			
		||||
          delete_pending_match(&sc->security_matches, pending_match);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
          EXCEPTION_ERROR(sc, &exception, "Failed to set remote reader crypto tokens "PGUIDFMT" --> "PGUIDFMT, PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
      }
 | 
			
		||||
      else if (!wr->sec_attr->attr.is_submessage_protected)
 | 
			
		||||
        match->matched = true;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&wr->e.lock);
 | 
			
		||||
 | 
			
		||||
  if (send_tokens)
 | 
			
		||||
    (void)send_writer_crypto_tokens(wr, prd, wr->sec_attr->crypto_handle, match->crypto_handle);
 | 
			
		||||
    (void)send_writer_crypto_tokens(wr, prd, wr->sec_attr->crypto_handle, *crypto_handle);
 | 
			
		||||
 | 
			
		||||
  return match->matched;
 | 
			
		||||
  return allowed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool q_omg_security_match_remote_reader_enabled(struct writer *wr, struct proxy_reader *prd, bool relay_only, int64_t *crypto_handle)
 | 
			
		||||
| 
						 | 
				
			
			@ -2376,6 +2500,8 @@ bool q_omg_security_match_remote_reader_enabled(struct writer *wr, struct proxy_
 | 
			
		|||
  struct ddsi_domaingv *gv = wr->e.gv;
 | 
			
		||||
  nn_security_info_t info;
 | 
			
		||||
 | 
			
		||||
  *crypto_handle = 0;
 | 
			
		||||
 | 
			
		||||
  if (!wr->sec_attr)
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2432,43 +2558,35 @@ void q_omg_security_set_remote_writer_crypto_tokens(struct reader *rd, const dds
 | 
			
		|||
  struct dds_security_context *sc = q_omg_security_get_secure_context(rd->c.pp);
 | 
			
		||||
  struct ddsi_domaingv *gv = rd->e.gv;
 | 
			
		||||
  DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
 | 
			
		||||
  struct security_entity_match *match;
 | 
			
		||||
  struct pending_match *match;
 | 
			
		||||
  struct proxy_writer *pwr = NULL;
 | 
			
		||||
  int64_t crypto_handle = 0;
 | 
			
		||||
 | 
			
		||||
  if (!sc)
 | 
			
		||||
     return;
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&rd->e.lock);
 | 
			
		||||
  match = find_or_create_entity_match(gv->security_matches, pwr_guid, &rd->e.guid);
 | 
			
		||||
  if (match->matched)
 | 
			
		||||
  {
 | 
			
		||||
    ddsrt_mutex_unlock(&rd->e.lock);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_Security_DatawriterCryptoTokenSeq * tseq = DDS_Security_DataHolderSeq_alloc();
 | 
			
		||||
  q_omg_copyin_DataHolderSeq(tseq, tokens);
 | 
			
		||||
 | 
			
		||||
  if ((pwr = entidx_lookup_proxy_writer_guid(gv->entity_index, pwr_guid)) == NULL || match->crypto_handle == 0 )
 | 
			
		||||
  {
 | 
			
		||||
  ddsrt_mutex_lock(&rd->e.lock);
 | 
			
		||||
  match = find_or_create_pending_entity_match(&sc->security_matches, EK_PROXY_WRITER, pwr_guid, &rd->e.guid, 0, tseq);
 | 
			
		||||
  if ((pwr = entidx_lookup_proxy_writer_guid(gv->entity_index, pwr_guid)) == NULL || match->crypto_handle == 0)
 | 
			
		||||
    GVTRACE("remember writer tokens src("PGUIDFMT") dst("PGUIDFMT")\n", PGUID(*pwr_guid), PGUID(rd->e.guid));
 | 
			
		||||
    match->tokens = tseq;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if (sc->crypto_context->crypto_key_exchange->set_remote_datawriter_crypto_tokens(sc->crypto_context->crypto_key_exchange, rd->sec_attr->crypto_handle, match->crypto_handle, tseq, &exception))
 | 
			
		||||
    if (!sc->crypto_context->crypto_key_exchange->set_remote_datawriter_crypto_tokens(sc->crypto_context->crypto_key_exchange, rd->sec_attr->crypto_handle, match->crypto_handle, tseq, &exception))
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to set remote writer crypto tokens "PGUIDFMT" for reader "PGUIDFMT, PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      GVTRACE("set_remote_writer_crypto_tokens "PGUIDFMT" with reader "PGUIDFMT"\n", PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
      match->matched = true;
 | 
			
		||||
      crypto_handle = match->crypto_handle;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to set remote writer crypto tokens "PGUIDFMT" for reader "PGUIDFMT, PGUID(pwr->e.guid), PGUID(rd->e.guid));
 | 
			
		||||
    DDS_Security_DataHolderSeq_free(tseq);
 | 
			
		||||
    delete_pending_match(&sc->security_matches, match);
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&rd->e.lock);
 | 
			
		||||
 | 
			
		||||
  if (match->matched)
 | 
			
		||||
    connect_reader_with_proxy_writer_secure(rd, pwr, ddsrt_time_monotonic (), match->crypto_handle);
 | 
			
		||||
  if (crypto_handle != 0)
 | 
			
		||||
    connect_reader_with_proxy_writer_secure(rd, pwr, ddsrt_time_monotonic (), crypto_handle);
 | 
			
		||||
 | 
			
		||||
  if (pwr)
 | 
			
		||||
    notify_handshake_recv_token(rd->c.pp, pwr->c.proxypp);
 | 
			
		||||
| 
						 | 
				
			
			@ -2479,46 +2597,38 @@ void q_omg_security_set_remote_reader_crypto_tokens(struct writer *wr, const dds
 | 
			
		|||
  struct dds_security_context *sc = q_omg_security_get_secure_context(wr->c.pp);
 | 
			
		||||
  struct ddsi_domaingv *gv = wr->e.gv;
 | 
			
		||||
  DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
 | 
			
		||||
  struct security_entity_match *match;
 | 
			
		||||
  struct pending_match *match;
 | 
			
		||||
  struct proxy_reader *prd = NULL;
 | 
			
		||||
  int64_t crypto_handle = 0;
 | 
			
		||||
 | 
			
		||||
  if (!sc)
 | 
			
		||||
     return;
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&wr->e.lock);
 | 
			
		||||
  match = find_or_create_entity_match(gv->security_matches, prd_guid, &wr->e.guid);
 | 
			
		||||
  if (match->matched)
 | 
			
		||||
  {
 | 
			
		||||
    ddsrt_mutex_unlock(&wr->e.lock);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DDS_Security_DatawriterCryptoTokenSeq *tseq = DDS_Security_DataHolderSeq_alloc();
 | 
			
		||||
  q_omg_copyin_DataHolderSeq(tseq, tokens);
 | 
			
		||||
   DDS_Security_DatawriterCryptoTokenSeq *tseq = DDS_Security_DataHolderSeq_alloc();
 | 
			
		||||
   q_omg_copyin_DataHolderSeq(tseq, tokens);
 | 
			
		||||
 | 
			
		||||
  if (((prd = entidx_lookup_proxy_reader_guid(gv->entity_index, prd_guid)) == NULL) || (match->crypto_handle == 0))
 | 
			
		||||
  {
 | 
			
		||||
    GVTRACE("remember reader tokens src("PGUIDFMT") dst("PGUIDFMT")\n", PGUID(*prd_guid), PGUID(wr->e.guid));
 | 
			
		||||
    match->tokens = tseq;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if (sc->crypto_context->crypto_key_exchange->set_remote_datareader_crypto_tokens(sc->crypto_context->crypto_key_exchange, wr->sec_attr->crypto_handle, match->crypto_handle, tseq, &exception))
 | 
			
		||||
    {
 | 
			
		||||
      GVTRACE("set_remote_reader_crypto_tokens "PGUIDFMT" with writer "PGUIDFMT"\n", PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
      match->matched = true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      EXCEPTION_ERROR(sc, &exception, "Failed to set remote reader crypto tokens "PGUIDFMT" for writer "PGUIDFMT, PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
    DDS_Security_DataHolderSeq_free(tseq);
 | 
			
		||||
  }
 | 
			
		||||
  ddsrt_mutex_unlock(&wr->e.lock);
 | 
			
		||||
   ddsrt_mutex_lock(&wr->e.lock);
 | 
			
		||||
   match = find_or_create_pending_entity_match(&sc->security_matches, EK_PROXY_READER, prd_guid, &wr->e.guid, 0, tseq);
 | 
			
		||||
   if (((prd = entidx_lookup_proxy_reader_guid(gv->entity_index, prd_guid)) == NULL) || (match->crypto_handle == 0))
 | 
			
		||||
     GVTRACE("remember reader tokens src("PGUIDFMT") dst("PGUIDFMT")\n", PGUID(*prd_guid), PGUID(wr->e.guid));
 | 
			
		||||
   else
 | 
			
		||||
   {
 | 
			
		||||
     if (!sc->crypto_context->crypto_key_exchange->set_remote_datareader_crypto_tokens(sc->crypto_context->crypto_key_exchange, wr->sec_attr->crypto_handle, match->crypto_handle, tseq, &exception))
 | 
			
		||||
       EXCEPTION_ERROR(sc, &exception, "Failed to set remote reader crypto tokens "PGUIDFMT" for writer "PGUIDFMT, PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
     else
 | 
			
		||||
     {
 | 
			
		||||
       GVTRACE("set_remote_reader_crypto_tokens "PGUIDFMT" with writer "PGUIDFMT"\n", PGUID(prd->e.guid), PGUID(wr->e.guid));
 | 
			
		||||
       crypto_handle = match->crypto_handle;
 | 
			
		||||
     }
 | 
			
		||||
     delete_pending_match(&sc->security_matches, match);
 | 
			
		||||
   }
 | 
			
		||||
   ddsrt_mutex_unlock(&wr->e.lock);
 | 
			
		||||
 | 
			
		||||
  if (match->matched)
 | 
			
		||||
    connect_writer_with_proxy_reader_secure(wr, prd, ddsrt_time_monotonic (), match->crypto_handle);
 | 
			
		||||
   if (crypto_handle != 0)
 | 
			
		||||
     connect_writer_with_proxy_reader_secure(wr, prd, ddsrt_time_monotonic (), crypto_handle);
 | 
			
		||||
 | 
			
		||||
  if (prd)
 | 
			
		||||
    notify_handshake_recv_token(wr->c.pp, prd->c.proxypp);
 | 
			
		||||
   if (prd)
 | 
			
		||||
     notify_handshake_recv_token(wr->c.pp, prd->c.proxypp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool q_omg_reader_is_discovery_protected(const struct reader *rd)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5638,6 +5638,9 @@ static void gc_delete_proxy_writer (struct gcreq *gcreq)
 | 
			
		|||
  local_reader_ary_fini (&pwr->rdary);
 | 
			
		||||
  if (pwr->c.xqos->liveliness.lease_duration != DDS_INFINITY)
 | 
			
		||||
    lease_free (pwr->lease);
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  q_omg_security_deregister_remote_writer(pwr);
 | 
			
		||||
#endif
 | 
			
		||||
  proxy_endpoint_common_fini (&pwr->e, &pwr->c);
 | 
			
		||||
  nn_defrag_free (pwr->defrag);
 | 
			
		||||
  nn_reorder_free (pwr->reorder);
 | 
			
		||||
| 
						 | 
				
			
			@ -5869,6 +5872,9 @@ static void gc_delete_proxy_reader (struct gcreq *gcreq)
 | 
			
		|||
    writer_drop_connection (&m->wr_guid, prd);
 | 
			
		||||
    free_prd_wr_match (m);
 | 
			
		||||
  }
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  q_omg_security_deregister_remote_reader(prd);
 | 
			
		||||
#endif
 | 
			
		||||
  proxy_endpoint_common_fini (&prd->e, &prd->c);
 | 
			
		||||
  ddsrt_free (prd);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1199,8 +1199,6 @@ int rtps_init (struct ddsi_domaingv *gv)
 | 
			
		|||
   * the entities (see DDS Security spec chapter 8.8.8.1). */
 | 
			
		||||
  add_property_to_xqos(&gv->builtin_volatile_xqos_rd, "dds.sec.builtin_endpoint_name", "BuiltinParticipantVolatileMessageSecureReader");
 | 
			
		||||
  add_property_to_xqos(&gv->builtin_volatile_xqos_wr, "dds.sec.builtin_endpoint_name", "BuiltinParticipantVolatileMessageSecureWriter");
 | 
			
		||||
 | 
			
		||||
  q_omg_security_init(gv);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_init (&gv->sertopics_lock);
 | 
			
		||||
| 
						 | 
				
			
			@ -1470,6 +1468,10 @@ int rtps_init (struct ddsi_domaingv *gv)
 | 
			
		|||
#endif
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  q_omg_security_init(gv);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  gv->as_disc = new_addrset ();
 | 
			
		||||
  if (gv->config.allowMulticast & AMC_SPDP)
 | 
			
		||||
    add_to_addrset (gv, gv->as_disc, &gv->loc_spdp_mc);
 | 
			
		||||
| 
						 | 
				
			
			@ -1559,7 +1561,8 @@ err_unicast_sockets:
 | 
			
		|||
  ddsrt_mutex_destroy (&gv->sertopics_lock);
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  q_omg_security_stop (gv); // should be a no-op as it starts lazily
 | 
			
		||||
  q_omg_security_deinit (gv);
 | 
			
		||||
  q_omg_security_deinit(gv->security_context);
 | 
			
		||||
  q_omg_security_free (gv);
 | 
			
		||||
  ddsi_xqos_fini (&gv->builtin_stateless_xqos_wr);
 | 
			
		||||
  ddsi_xqos_fini (&gv->builtin_stateless_xqos_rd);
 | 
			
		||||
  ddsi_xqos_fini (&gv->builtin_volatile_xqos_wr);
 | 
			
		||||
| 
						 | 
				
			
			@ -1835,6 +1838,10 @@ void rtps_fini (struct ddsi_domaingv *gv)
 | 
			
		|||
  nn_dqueue_free (gv->user_dqueue);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  q_omg_security_deinit (gv->security_context);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  xeventq_free (gv->xevents);
 | 
			
		||||
 | 
			
		||||
  if (gv->config.xpack_send_async)
 | 
			
		||||
| 
						 | 
				
			
			@ -1918,7 +1925,7 @@ void rtps_fini (struct ddsi_domaingv *gv)
 | 
			
		|||
  ddsrt_mutex_destroy (&gv->sertopics_lock);
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  q_omg_security_deinit (gv);
 | 
			
		||||
  q_omg_security_free (gv);
 | 
			
		||||
  ddsi_xqos_fini (&gv->builtin_stateless_xqos_wr);
 | 
			
		||||
  ddsi_xqos_fini (&gv->builtin_stateless_xqos_rd);
 | 
			
		||||
  ddsi_xqos_fini (&gv->builtin_volatile_xqos_wr);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue