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:
Marcel Jordense 2020-04-03 13:42:16 +02:00 committed by eboasson
parent 829e33ac82
commit 534eac2a11
5 changed files with 439 additions and 290 deletions

View file

@ -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

View file

@ -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 );

View file

@ -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) {
if (match->tokens)
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);
ddsrt_mutex_lock(&index->lock);
if ((match = ddsrt_avl_lookup_ipath(&pending_match_index_treedef, &index->pending_matches, &guids, &ipath)) == NULL)
{
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);
}
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;
if (crypto_handle)
match->crypto_handle = crypto_handle;
ddsrt_mutex_lock(&list->lock);
match = find_entity_match_locked(list, src, dst);
if (!match)
if (tokens)
{
match = entity_match_new(src, dst);
ddsrt_avl_insert(&entity_match_treedef, &list->matches, match);
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(&list->lock);
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;
ddsrt_mutex_lock(&index->lock);
match = ddsrt_avl_find_min(&pending_match_index_treedef, &index->pending_matches);
while (match)
{
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 entity_match_free_wrapper(void *arg)
static void clear_pending_matches_by_remote_guid(dds_security_context *sc, struct pending_match_index *index, const ddsi_guid_t *remote_guid)
{
struct security_entity_match *match = arg;
entity_match_free(match);
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 security_match_index_free(struct dds_security_match_index *list)
static void pending_match_index_init(const struct ddsi_domaingv *gv, struct pending_match_index *index)
{
if (list)
{
ddsrt_avl_free (&entity_match_treedef, &list->matches, entity_match_free_wrapper);
ddsrt_mutex_destroy(&list->lock);
ddsrt_free(list);
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)
{
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));
}
else
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, 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));
ret = false;
}
else
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,31 +1934,28 @@ 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));
DDS_Security_DataHolderSeq_free(tseq);
}
@ -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)
{
/* 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);
*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));
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)
{
/* 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);
*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)
{
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)
{
*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
{
pending_match->crypto_handle = *crypto_handle;
send_tokens = true;
if (match->tokens)
if (pending_match->tokens)
{
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))
{
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));
}
else
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);
}
}
}
}
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,19 +2223,21 @@ 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)
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)
{
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);
}
}
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)
@ -2260,20 +2379,21 @@ 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))
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));
entity_match_free(match);
}
}
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)
@ -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)
{
/* 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);
*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)
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)
{
/* 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);
*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)
{
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)
{
*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
{
pending_match->crypto_handle = *crypto_handle;
send_tokens = true;
if (match->tokens)
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)
{
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))
{
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));
}
else
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 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);
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,43 +2597,35 @@ 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);
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));
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))
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));
match->matched = true;
crypto_handle = match->crypto_handle;
}
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);
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);

View file

@ -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);
}

View file

@ -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);