Do not silently ignore security QoS settings

When built without support for DDS Security, any attempt to create a
participant QoS settings in the security name space (those prefixed by
"dds.sec.") must fail.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2020-03-23 17:27:29 +01:00 committed by eboasson
parent 4fe9cf290d
commit d4e9300dad
6 changed files with 226 additions and 156 deletions

View file

@ -141,3 +141,43 @@ CU_Test(ddsc_security_config, empty, .init = ddsrt_init, .fini = ddsrt_fini)
CU_ASSERT_FATAL(found == 0x7);
#endif
}
CU_Test(ddsc_security_qos, empty, .init = ddsrt_init, .fini = ddsrt_fini)
{
/* Expected traces when creating participant with some (not all) security QoS
settings. We need to test this one here to be sure that it also refuses to
start when security is configured but the implementation doesn't include
support for it. */
const char *log_expected[] = {
#ifdef DDSI_INCLUDE_SECURITY
"new_participant(*): using security settings from QoS*",
"new_participant(*): required security property * missing*",
#endif
NULL
};
/* Set up the trace sinks to detect the config parsing. */
dds_set_log_mask (DDS_LC_FATAL|DDS_LC_ERROR|DDS_LC_WARNING|DDS_LC_CONFIG);
dds_set_log_sink (&logger, (void *) log_expected);
dds_set_trace_sink (&logger, (void *) log_expected);
/* Create participant with incomplete/nonsensical security configuration: this should always fail */
found = 0;
dds_qos_t *qos = dds_create_qos ();
dds_qset_prop (qos, "dds.sec.nonsense", "");
dds_entity_t domain = dds_create_domain (0, "<Tracing><Category>trace</Category>");
CU_ASSERT_FATAL (domain > 0);
dds_entity_t participant = dds_create_participant (0, qos, NULL);
dds_delete_qos (qos);
CU_ASSERT_FATAL (participant < 0);
(void) dds_delete (domain);
dds_set_log_sink (NULL, NULL);
dds_set_trace_sink (NULL, NULL);
/* All traces should have been provided. */
#ifndef DDSI_INCLUDE_SECURITY
CU_ASSERT_FATAL (found == 0x0);
#else
CU_ASSERT_FATAL (found == 0x3);
#endif
}

View file

@ -184,11 +184,12 @@ bool q_omg_proxy_participant_is_secure(const struct proxy_participant *proxypp);
* @param[in] pp The participant to check if alloweed by security.
* #param[in] domain_id The domain_id
*
* @returns bool
* @retval true Participant is allowed
* @retval false Participant is not allowed
* @returns dds_return_t
* @retval DDS_RETCODE_OK Participant is allowed
* @retval DDS_RETCODE_NOT_ALLOWED_BY_SECURITY
* Participant is not allowed
*/
bool q_omg_security_check_create_participant(struct participant *pp, uint32_t domain_id);
dds_return_t q_omg_security_check_create_participant(struct participant *pp, uint32_t domain_id);
void q_omg_security_participant_set_initialized(struct participant *pp);

View file

@ -322,7 +322,9 @@ DDS_EXPORT void ddsi_xqos_addtomsg (struct nn_xmsg *m, const dds_qos_t *xqos, ui
DDS_EXPORT void ddsi_xqos_log (uint32_t cat, const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos);
DDS_EXPORT size_t ddsi_xqos_print (char * __restrict buf, size_t bufsize, const dds_qos_t *xqos);
DDS_EXPORT dds_qos_t *ddsi_xqos_dup (const dds_qos_t *src);
DDS_EXPORT bool ddsi_xqos_has_prop (const dds_qos_t *xqos, const char *pname, bool startswith, bool check_non_empty);
DDS_EXPORT bool ddsi_xqos_has_prop_prefix (const dds_qos_t *xqos, const char *nameprefix);
DDS_EXPORT bool ddsi_xqos_find_prop (const dds_qos_t *xqos, const char *name, const char **value);
#ifdef DDSI_INCLUDE_SECURITY
struct omg_security_configuration_type;
DDS_EXPORT void ddsi_xqos_mergein_security_config (dds_qos_t *xqos, const struct omg_security_configuration_type *cfg);

View file

@ -3179,16 +3179,30 @@ dds_qos_t * ddsi_xqos_dup (const dds_qos_t *src)
return dst;
}
bool ddsi_xqos_has_prop (const dds_qos_t *xqos, const char *pname, bool startswith, bool check_non_empty)
bool ddsi_xqos_has_prop_prefix (const dds_qos_t *xqos, const char *nameprefix)
{
if (!(xqos->present & QP_PROPERTY_LIST))
return false;
const size_t len = strlen (nameprefix);
for (uint32_t i = 0; i < xqos->property.value.n; i++)
{
if (strncmp (xqos->property.value.props[i].name, nameprefix, len) == 0)
return true;
}
return false;
}
for (uint32_t i = 0; i < xqos->property.value.n; i++) {
if (startswith && (strncmp(xqos->property.value.props[i].name, pname, strlen(pname)) == 0)) {
return !check_non_empty || strlen(xqos->property.value.props[i].value) != 0;
} else if (!startswith && (strcmp(xqos->property.value.props[i].name, pname) == 0)) {
return !check_non_empty || strlen(xqos->property.value.props[i].value) != 0;
bool ddsi_xqos_find_prop (const dds_qos_t *xqos, const char *name, const char **value)
{
if (!(xqos->present & QP_PROPERTY_LIST))
return false;
for (uint32_t i = 0; i < xqos->property.value.n; i++)
{
if (strcmp (xqos->property.value.props[i].name, name) == 0)
{
if (value)
*value = xqos->property.value.props[i].value;
return true;
}
}
return false;

View file

@ -844,9 +844,9 @@ bool q_omg_participant_allow_unauthenticated(struct participant *pp)
return ((pp->sec_attr != NULL) && pp->sec_attr->attr.allow_unauthenticated_participants);
}
bool q_omg_security_check_create_participant(struct participant *pp, uint32_t domain_id)
dds_return_t q_omg_security_check_create_participant(struct participant *pp, uint32_t domain_id)
{
bool allowed = false;
dds_return_t ret = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
struct dds_security_context *sc = q_omg_security_get_secure_context(pp);
DDS_Security_IdentityHandle identity_handle = DDS_SECURITY_HANDLE_NIL;
DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
@ -860,7 +860,7 @@ bool q_omg_security_check_create_participant(struct participant *pp, uint32_t do
ddsi_guid_t adjusted_guid;
if (!sc)
return true;
return DDS_RETCODE_OK;
/* Validate local identity */
ETRACE (pp, "validate_local_identity: candidate_guid: "PGUIDFMT" ", PGUID (pp->e.guid));
@ -953,7 +953,7 @@ bool q_omg_security_check_create_participant(struct participant *pp, uint32_t do
ETRACE (pp, "\n");
allowed = true;
ret = DDS_RETCODE_OK;
no_crypto:
no_sec_attr:
@ -963,11 +963,11 @@ no_credentials:
if (credential_token.class_id)
(void)sc->access_control_context->return_permissions_credential_token(sc->access_control_context, &credential_token, NULL);
not_allowed:
if (!allowed)
if (ret != DDS_RETCODE_OK)
participant_sec_attributes_free(sec_attr);
validation_failed:
q_omg_shallow_free_security_qos(&par_qos);
return allowed;
return ret;
}
void q_omg_security_participant_set_initialized(struct participant *pp)

View file

@ -204,7 +204,6 @@ int is_builtin_endpoint (ddsi_entityid_t id, nn_vendorid_t vendorid)
}
#ifdef DDSI_INCLUDE_SECURITY
static int is_builtin_volatile_endpoint (ddsi_entityid_t id)
{
switch (id.u) {
@ -217,13 +216,13 @@ static int is_builtin_volatile_endpoint (ddsi_entityid_t id)
return 0;
}
#else
#ifndef NDEBUG
static int is_builtin_volatile_endpoint (ddsi_entityid_t id)
{
DDSRT_UNUSED_ARG(id);
return 0;
}
#endif
#endif
bool is_local_orphan_endpoint (const struct entity_common *e)
@ -633,9 +632,63 @@ static void add_security_builtin_endpoints(struct participant *pp, ddsi_guid_t *
}
#endif
static void add_builtin_endpoints(struct participant *pp, ddsi_guid_t *subguid, const ddsi_guid_t *group_guid, struct ddsi_domaingv *gv, bool add_writers, bool add_readers)
{
if (add_writers)
{
struct whc_writer_info *wrinfo = whc_make_wrinfo (NULL, &gv->builtin_endpoint_xqos_wr);
/* SEDP writers: */
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER;
/* PMD writer: */
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER;
if (gv->config.do_topic_discovery)
{
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_TOPIC_ANNOUNCER;
}
whc_free_wrinfo (wrinfo);
}
/* SPDP, SEDP, PMD readers: */
if (add_readers)
{
subguid->entityid = to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->spdp_endpoint_xqos, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER;
}
#ifdef DDSI_INCLUDE_SECURITY
if (q_omg_participant_is_secure (pp))
add_security_builtin_endpoints (pp, subguid, group_guid, gv, add_writers, add_readers);
#endif
}
#ifdef DDSI_INCLUDE_SECURITY
static void connect_participant_secure(struct ddsi_domaingv *gv, struct participant *pp)
{
struct proxy_participant *proxypp;
@ -749,6 +802,81 @@ static void participant_remove_wr_lease_locked (struct participant * pp, struct
}
}
#ifdef DDSI_INCLUDE_SECURITY
static dds_return_t check_and_load_security_config (struct ddsi_domaingv * const gv, const ddsi_guid_t *ppguid, dds_qos_t *qos)
{
/* If some security properties (name starts with dds.sec. conform DDS Security spec 7.2.4.1)
are present in the QoS, all must be and they will be used. If none are, take the settings
from the configuration if it has them. When no security configuration exists anywhere,
create an unsecured participant.
This may modify "qos" */
if (ddsi_xqos_has_prop_prefix (qos, "dds.sec."))
{
char const * const req[] = {
DDS_SEC_PROP_AUTH_IDENTITY_CA,
DDS_SEC_PROP_AUTH_PRIV_KEY,
DDS_SEC_PROP_AUTH_IDENTITY_CERT,
DDS_SEC_PROP_ACCESS_PERMISSIONS_CA,
DDS_SEC_PROP_ACCESS_GOVERNANCE,
DDS_SEC_PROP_ACCESS_PERMISSIONS,
DDS_SEC_PROP_AUTH_LIBRARY_PATH,
DDS_SEC_PROP_AUTH_LIBRARY_INIT,
DDS_SEC_PROP_AUTH_LIBRARY_FINALIZE,
DDS_SEC_PROP_CRYPTO_LIBRARY_PATH,
DDS_SEC_PROP_CRYPTO_LIBRARY_INIT,
DDS_SEC_PROP_CRYPTO_LIBRARY_FINALIZE,
DDS_SEC_PROP_ACCESS_LIBRARY_PATH,
DDS_SEC_PROP_ACCESS_LIBRARY_INIT,
DDS_SEC_PROP_ACCESS_LIBRARY_FINALIZE
};
GVLOGDISC ("new_participant("PGUIDFMT"): using security settings from QoS\n", PGUID (*ppguid));
/* check if all required security properties exist in qos; report all missing ones, not just the first */
dds_return_t ret = DDS_RETCODE_OK;
for (size_t i = 0; i < sizeof(req) / sizeof(req[0]); i++)
{
const char *value;
if (!ddsi_xqos_find_prop (qos, req[i], &value) || strlen (value) == 0)
{
GVERROR ("new_participant("PGUIDFMT"): required security property %s missing in Property QoS\n", PGUID (*ppguid), req[i]);
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
}
}
if (ret != DDS_RETCODE_OK)
return ret;
}
else if (gv->config.omg_security_configuration)
{
/* For security, configuration can be provided through the configuration. However, the specification
(and the plugins) expect it to be in the QoS, so merge it in. */
GVLOGDISC ("new_participant("PGUIDFMT"): using security settings from configuration\n", PGUID (*ppguid));
ddsi_xqos_mergein_security_config (qos, &gv->config.omg_security_configuration->cfg);
}
else
{
/* No security configuration */
return DDS_RETCODE_OK;
}
if (q_omg_is_security_loaded (gv->security_context))
{
GVLOGDISC ("new_participant("PGUIDFMT"): security is already loaded for this domain\n", PGUID (*ppguid));
return DDS_RETCODE_OK;
}
else if (q_omg_security_load (gv->security_context, qos) < 0)
{
GVERROR ("Could not load security\n");
return DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
}
else
{
return DDS_RETCODE_OK;
}
}
#endif
dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv, unsigned flags, const ddsi_plist_t *plist)
{
struct participant *pp;
@ -828,77 +956,18 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
#ifdef DDSI_INCLUDE_SECURITY
pp->sec_attr = NULL;
/*
* if there there are security properties check them .
* if there are no security properties, then merge from security configuration if there is
*/
/* check for existing security properties (name starts with dds.sec. conform DDS Security spec 7.2.4.1)
* and return if any is found */
if ((ret = check_and_load_security_config (gv, ppguid, &pp->plist->qos)) != DDS_RETCODE_OK)
goto not_allowed;
if ((ret = q_omg_security_check_create_participant (pp, gv->config.domainId)) != DDS_RETCODE_OK)
goto not_allowed;
*ppguid = pp->e.guid;
#else
if (ddsi_xqos_has_prop_prefix (&pp->plist->qos, "dds.sec."))
{
bool ready_to_load_security = false;
if (ddsi_xqos_has_prop(&pp->plist->qos, "dds.sec.", true, false)) {
char *req[] = {DDS_SEC_PROP_AUTH_IDENTITY_CA,
DDS_SEC_PROP_AUTH_PRIV_KEY,
DDS_SEC_PROP_AUTH_IDENTITY_CERT,
DDS_SEC_PROP_ACCESS_PERMISSIONS_CA,
DDS_SEC_PROP_ACCESS_GOVERNANCE,
DDS_SEC_PROP_ACCESS_PERMISSIONS,
DDS_SEC_PROP_AUTH_LIBRARY_PATH,
DDS_SEC_PROP_AUTH_LIBRARY_INIT,
DDS_SEC_PROP_AUTH_LIBRARY_FINALIZE,
DDS_SEC_PROP_CRYPTO_LIBRARY_PATH,
DDS_SEC_PROP_CRYPTO_LIBRARY_INIT,
DDS_SEC_PROP_CRYPTO_LIBRARY_FINALIZE,
DDS_SEC_PROP_ACCESS_LIBRARY_PATH,
DDS_SEC_PROP_ACCESS_LIBRARY_INIT,
DDS_SEC_PROP_ACCESS_LIBRARY_FINALIZE};
GVLOGDISC ("new_participant("
PGUIDFMT
"): using security settings from QoS\n", PGUID(*ppguid));
/* check if all required security properties exist in qos */
for (size_t i = 0; i < sizeof(req) / sizeof(req[0]); i++) {
if (!ddsi_xqos_has_prop(&pp->plist->qos, req[i], false, true)) {
GVERROR ("new_participant("
PGUIDFMT
"): required security property %s missing in Property QoS\n", PGUID(*ppguid), req[i]);
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
}
}
if (ret == DDS_RETCODE_OK) {
ready_to_load_security = true;
} else {
goto new_pp_err_secprop;
}
} else if (gv->config.omg_security_configuration) {
/* For security, configuration can be provided through the configuration.
* However, the specification (and the plugins) expect it to be in the QoS. */
GVLOGDISC ("new_participant("
PGUIDFMT
"): using security settings from configuration\n", PGUID(*ppguid));
ddsi_xqos_mergein_security_config(&pp->plist->qos, &gv->config.omg_security_configuration->cfg);
ready_to_load_security = true;
}
if( q_omg_is_security_loaded( gv->security_context ) == false ){
if (ready_to_load_security && q_omg_security_load(gv->security_context, &pp->plist->qos) < 0) {
GVERROR("Could not load security\n");
ret = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
goto new_pp_err_secprop;
}
} else {
GVLOGDISC ("new_participant("
PGUIDFMT
"): security is already loaded for this domain\n", PGUID(*ppguid));
}
if (!q_omg_security_check_create_participant (pp, gv->config.domainId))
{
ret = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
goto not_allowed;
}
*ppguid = pp->e.guid;
/* disallow creating a participant with a security configuration if there is support for security
has been left out */
ret = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
goto not_allowed;
}
#endif
@ -927,9 +996,7 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
subguid.prefix = pp->e.guid.prefix;
memset (&group_guid, 0, sizeof (group_guid));
/* SPDP writer */
/* Note: skip SEDP <=> skip SPDP because of the way ddsi_discovery.c does things
currently. */
/* SPDP is very much special and must be done first */
if (!(flags & RTPS_PF_NO_BUILTIN_WRITERS))
{
subguid.entityid = to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER);
@ -938,70 +1005,15 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
whc_free_wrinfo (wrinfo);
/* But we need the as_disc address set for SPDP, because we need to
send it to everyone regardless of the existence of readers. */
force_as_disc_address(gv, &subguid);
force_as_disc_address (gv, &subguid);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER;
}
/* Make it globally visible, else the endpoint matching won't work. */
entidx_insert_participant_guid (gv->entity_index, pp);
/* SEDP writers: */
wrinfo = whc_make_wrinfo (NULL, &gv->builtin_endpoint_xqos_wr);
if (!(flags & RTPS_PF_NO_BUILTIN_WRITERS))
{
subguid.entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER);
new_writer_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER;
subguid.entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER);
new_writer_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER;
}
if (gv->config.do_topic_discovery)
{
/* TODO: make this one configurable, we don't want all participants to publish all topics (or even just those that they use themselves) */
subguid.entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER);
new_writer_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_TOPIC_ANNOUNCER;
}
/* PMD writer: */
if (!(flags & RTPS_PF_NO_BUILTIN_WRITERS))
{
subguid.entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER);
new_writer_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER;
}
whc_free_wrinfo (wrinfo);
/* SPDP, SEDP, PMD readers: */
if (!(flags & RTPS_PF_NO_BUILTIN_READERS))
{
subguid.entityid = to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER);
new_reader_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->spdp_endpoint_xqos, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR;
subguid.entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER);
new_reader_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR;
subguid.entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER);
new_reader_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR;
subguid.entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER);
new_reader_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER;
}
#ifdef DDSI_INCLUDE_SECURITY
if (q_omg_participant_is_secure(pp))
{
add_security_builtin_endpoints(pp, &subguid, &group_guid, gv, !(flags & RTPS_PF_NO_BUILTIN_WRITERS), !(flags & RTPS_PF_NO_BUILTIN_READERS));
}
#endif
/* add all built-in endpoints other than the SPDP writer */
add_builtin_endpoints (pp, &subguid, &group_guid, gv, !(flags & RTPS_PF_NO_BUILTIN_WRITERS), !(flags & RTPS_PF_NO_BUILTIN_READERS));
/* If the participant doesn't have the full set of builtin writers
it depends on the privileged participant, which must exist, hence
@ -1009,7 +1021,8 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
If it is the privileged participant, set the global variable
pointing to it.
Except when the participant is only locally available. */
if (!(flags & RTPS_PF_ONLY_LOCAL)) {
if (!(flags & RTPS_PF_ONLY_LOCAL))
{
ddsrt_mutex_lock (&gv->privileged_pp_lock);
if ((pp->bes & builtin_writers_besmask) != builtin_writers_besmask)
{
@ -1066,16 +1079,16 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
}
#ifdef DDSI_INCLUDE_SECURITY
if (q_omg_participant_is_secure(pp))
if (q_omg_participant_is_secure (pp))
{
connect_participant_secure (gv, pp);
}
#endif
return ret;
#ifdef DDSI_INCLUDE_SECURITY
not_allowed:
new_pp_err_secprop:
if (ppconn)
ddsi_conn_free (ppconn);
ddsi_plist_fini (pp->plist);
ddsrt_free (pp->plist);
inverse_uint32_set_fini (&pp->avail_entityids.x);
@ -1085,7 +1098,6 @@ new_pp_err_secprop:
ddsrt_mutex_lock (&gv->participant_set_lock);
gv->nparticipants--;
ddsrt_mutex_unlock (&gv->participant_set_lock);
#endif
new_pp_err:
return ret;
}
@ -4886,6 +4898,7 @@ void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *pp
const bool is_secure = ((bes & NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER) != 0);
assert (!is_secure || (plist->present & PP_IDENTITY_TOKEN));
assert (is_secure || (bes & ~NN_BES_MASK_NON_SECURITY) == 0);
(void) is_secure;
assert (ppguid->entityid.u == NN_ENTITYID_PARTICIPANT);
assert (entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid) == NULL);