Access Control on_revoke_permissions implementation in DDSI
Implement handler for access control on_revoke_permissions. This callback function disconnects and deletes all proxy participant that are using the revoked permissions handle (in case of remote permissions expire) and proxy participant that are connected with a participant for which the permissions expire (local permissions expire). Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
This commit is contained in:
parent
e6500b6528
commit
d53cdce8fe
5 changed files with 103 additions and 34 deletions
|
@ -212,6 +212,8 @@ struct dds_security_context {
|
|||
|
||||
struct pending_match_index security_matches;
|
||||
struct participant_sec_index partiticpant_index;
|
||||
struct dds_security_access_control_listener ac_listener;
|
||||
struct dds_security_authentication_listener auth_listener;
|
||||
};
|
||||
|
||||
typedef struct dds_security_context dds_security_context;
|
||||
|
@ -525,34 +527,44 @@ static void proxypp_pp_match_free(struct ddsi_domaingv *gv, struct dds_security_
|
|||
ddsrt_free(pm);
|
||||
}
|
||||
|
||||
static void pp_proxypp_unrelate(struct dds_security_context *sc, struct participant *pp, const ddsi_guid_t *proxypp_guid)
|
||||
static void pp_proxypp_unrelate_locked(struct dds_security_context *sc, struct participant *pp, const ddsi_guid_t *proxypp_guid)
|
||||
{
|
||||
struct pp_proxypp_match *pm;
|
||||
ddsrt_avl_dpath_t dpath;
|
||||
|
||||
ddsrt_mutex_lock(&pp->sec_attr->lock);
|
||||
if ((pm = ddsrt_avl_clookup_dpath(&pp_proxypp_treedef, &pp->sec_attr->proxy_participants, proxypp_guid, &dpath)) != NULL)
|
||||
{
|
||||
ddsrt_avl_cdelete_dpath(&pp_proxypp_treedef, &pp->sec_attr->proxy_participants, pm, &dpath);
|
||||
pp_proxypp_match_free(sc, pm);
|
||||
}
|
||||
}
|
||||
|
||||
static void pp_proxypp_unrelate(struct dds_security_context *sc, struct participant *pp, const ddsi_guid_t *proxypp_guid)
|
||||
{
|
||||
ddsrt_mutex_lock(&pp->sec_attr->lock);
|
||||
pp_proxypp_unrelate_locked (sc, pp, proxypp_guid);
|
||||
ddsrt_mutex_unlock(&pp->sec_attr->lock);
|
||||
}
|
||||
|
||||
static void proxypp_pp_unrelate_locked(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);
|
||||
struct proxypp_pp_match *pm;
|
||||
ddsrt_avl_dpath_t dpath;
|
||||
|
||||
if ((pm = ddsrt_avl_lookup_dpath(&proxypp_pp_treedef, &proxypp->sec_attr->participants, &pp_crypto_handle, &dpath)) != NULL)
|
||||
{
|
||||
ddsrt_avl_delete_dpath(&proxypp_pp_treedef, &proxypp->sec_attr->participants, pm, &dpath);
|
||||
proxypp_pp_match_free(proxypp->e.gv, sc, pm);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
ddsrt_avl_dpath_t dpath;
|
||||
|
||||
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)
|
||||
{
|
||||
ddsrt_avl_delete_dpath(&proxypp_pp_treedef, &proxypp->sec_attr->participants, pm, &dpath);
|
||||
proxypp_pp_match_free(proxypp->e.gv, sc, pm);
|
||||
}
|
||||
proxypp_pp_unrelate_locked(sc, proxypp, pp_guid, pp_crypto_handle);
|
||||
ddsrt_mutex_unlock(&proxypp->sec_attr->lock);
|
||||
}
|
||||
}
|
||||
|
@ -798,6 +810,70 @@ static void deinit_plugin_suite_config (dds_security_plugin_suite_config *suite_
|
|||
deinit_plugin_config (&suite_config->cryptography);
|
||||
}
|
||||
|
||||
static DDS_Security_boolean on_revoke_permissions_cb(const dds_security_access_control *plugin, const DDS_Security_PermissionsHandle handle)
|
||||
{
|
||||
struct ddsi_domaingv *gv = plugin->gv;
|
||||
struct entidx_enum_participant epp;
|
||||
struct entidx_enum_proxy_participant eproxypp;
|
||||
struct participant *pp;
|
||||
struct proxy_participant *proxypp;
|
||||
bool local_perm = false;
|
||||
thread_state_awake (lookup_thread_state (), gv);
|
||||
|
||||
/* Find participants using this permissions handle */
|
||||
entidx_enum_participant_init (&epp, gv->entity_index);
|
||||
while ((pp = entidx_enum_participant_next (&epp)) != NULL)
|
||||
{
|
||||
struct dds_security_context *sc = q_omg_security_get_secure_context(pp);
|
||||
ddsrt_mutex_lock (&pp->sec_attr->lock);
|
||||
if (pp->sec_attr->permissions_handle == handle)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
ddsrt_avl_citer_t it;
|
||||
local_perm = true;
|
||||
for (struct pp_proxypp_match *ppm = ddsrt_avl_citer_first (&pp_proxypp_treedef, &pp->sec_attr->proxy_participants, &it); ppm; ppm = ddsrt_avl_citer_next (&it), i++)
|
||||
pp_proxypp_unrelate_locked (sc, pp, &ppm->proxypp_guid);
|
||||
}
|
||||
ddsrt_mutex_unlock (&pp->sec_attr->lock);
|
||||
}
|
||||
entidx_enum_participant_fini (&epp);
|
||||
|
||||
/* Find proxy participants using this permissions handle */
|
||||
if (!local_perm)
|
||||
{
|
||||
entidx_enum_proxy_participant_init (&eproxypp, gv->entity_index);
|
||||
while ((proxypp = entidx_enum_proxy_participant_next (&eproxypp)) != NULL)
|
||||
{
|
||||
ddsrt_mutex_lock (&proxypp->sec_attr->lock);
|
||||
uint32_t i = 0;
|
||||
ddsrt_avl_iter_t it;
|
||||
bool del_proxypp = true;
|
||||
for (struct proxypp_pp_match *ppm = ddsrt_avl_iter_first (&proxypp_pp_treedef, &proxypp->sec_attr->participants, &it); ppm; ppm = ddsrt_avl_iter_next (&it), i++)
|
||||
{
|
||||
if (ppm->permissions_handle == handle)
|
||||
proxypp_pp_unrelate_locked (proxypp->sec_attr->sc, proxypp, &ppm->pp_guid, ppm->pp_crypto_handle);
|
||||
else
|
||||
del_proxypp = false;
|
||||
}
|
||||
ddsrt_mutex_unlock (&proxypp->sec_attr->lock);
|
||||
if (del_proxypp)
|
||||
delete_proxy_participant_by_guid (gv, &proxypp->e.guid, ddsrt_time_wallclock (), false);
|
||||
}
|
||||
entidx_enum_proxy_participant_fini (&eproxypp);
|
||||
}
|
||||
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
return true;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean on_revoke_identity_cb(const dds_security_authentication *plugin, const DDS_Security_IdentityHandle handle)
|
||||
{
|
||||
(void)plugin;
|
||||
(void)handle;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
dds_return_t q_omg_security_load (dds_security_context *sc, const dds_qos_t *qos, struct ddsi_domaingv *gv)
|
||||
{
|
||||
dds_security_plugin_suite_config psc;
|
||||
|
@ -836,18 +912,19 @@ dds_return_t q_omg_security_load (dds_security_context *sc, const dds_qos_t *qos
|
|||
}
|
||||
|
||||
/* Add listeners */
|
||||
#if LISTENERS_IMPLEMENTED
|
||||
if (!access_control_context->set_listener (access_control_context, &listener_ac, &ex))
|
||||
DDS_Security_SecurityException ex = DDS_SECURITY_EXCEPTION_INIT;
|
||||
sc->ac_listener.on_revoke_permissions = on_revoke_permissions_cb;
|
||||
if (!sc->access_control_context->set_listener (sc->access_control_context, &sc->ac_listener, &ex))
|
||||
{
|
||||
GVERROR ("Could not set access_control listener: %s\n", ex.message ? ex.message : "<unknown error>");
|
||||
goto error_set_ac_listener;
|
||||
}
|
||||
if (!authentication_context->set_listener (authentication_context, &listener_auth, &ex))
|
||||
sc->auth_listener.on_revoke_identity = on_revoke_identity_cb;
|
||||
if (!sc->authentication_context->set_listener (sc->authentication_context, &sc->auth_listener, &ex))
|
||||
{
|
||||
GVERROR ("Could not set authentication listener: %s\n", ex.message ? ex.message : "<unknown error>");
|
||||
goto err_set_auth_listener;
|
||||
goto error_set_auth_listener;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HANDSHAKE_IMPLEMENTED
|
||||
(void) q_handshake_initialize ();
|
||||
|
@ -858,11 +935,9 @@ dds_return_t q_omg_security_load (dds_security_context *sc, const dds_qos_t *qos
|
|||
GVTRACE ("DDS Security plugins have been loaded\n");
|
||||
return DDS_RETCODE_OK;
|
||||
|
||||
#if LISTENERS_IMPLEMENTED
|
||||
error_set_auth_listener:
|
||||
access_control_context->set_listener (access_control_context, NULL, &ex);
|
||||
sc->access_control_context->set_listener (sc->access_control_context, NULL, &ex);
|
||||
error_set_ac_listener:
|
||||
#endif
|
||||
error_verify:
|
||||
release_plugins (gv, sc);
|
||||
error:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue