Access control tests
Add test cases for the join_access_control governance setting and for the access control plugin check_create_ and check_remote_ hooks, using a wrapper plugin that simulates failure for each of these, to test the DDSI integration with the access control plugin. This commit also contains fixes for: - an assert on DDS_RETCODE_OK in dds_create_reader and dds_create_writer that cased the application to terminate in case creation of a reader or writer is not allowed by security - do not match a proxy reader that has the 'relay_only' set to true, which is currently unsupported Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
This commit is contained in:
		
							parent
							
								
									080514d45a
								
							
						
					
					
						commit
						19bc6f33cc
					
				
					 21 changed files with 1022 additions and 437 deletions
				
			
		| 
						 | 
				
			
			@ -30,6 +30,7 @@
 | 
			
		|||
#include "dds__builtin.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_sertopic.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_entity_index.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_security_omg.h"
 | 
			
		||||
 | 
			
		||||
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_reader)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -430,6 +431,7 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe
 | 
			
		|||
 | 
			
		||||
  /* Merge qos from topic and subscriber, dds_copy_qos only fails when it is passed a null
 | 
			
		||||
     argument, but that isn't the case here */
 | 
			
		||||
  struct ddsi_domaingv *gv = &sub->m_entity.m_domain->gv;
 | 
			
		||||
  rqos = dds_create_qos ();
 | 
			
		||||
  if (qos)
 | 
			
		||||
    ddsi_xqos_mergein_missing (rqos, qos, DDS_READER_QOS_MASK);
 | 
			
		||||
| 
						 | 
				
			
			@ -437,25 +439,43 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe
 | 
			
		|||
    ddsi_xqos_mergein_missing (rqos, sub->m_entity.m_qos, ~(uint64_t)0);
 | 
			
		||||
  if (tp->m_ktopic->qos)
 | 
			
		||||
    ddsi_xqos_mergein_missing (rqos, tp->m_ktopic->qos, ~(uint64_t)0);
 | 
			
		||||
  ddsi_xqos_mergein_missing (rqos, &sub->m_entity.m_domain->gv.default_xqos_rd, ~(uint64_t)0);
 | 
			
		||||
  ddsi_xqos_mergein_missing (rqos, &gv->default_xqos_rd, ~(uint64_t)0);
 | 
			
		||||
 | 
			
		||||
  if ((rc = ddsi_xqos_valid (&sub->m_entity.m_domain->gv.logconfig, rqos)) < 0 ||
 | 
			
		||||
      (rc = validate_reader_qos(rqos)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    dds_delete_qos (rqos);
 | 
			
		||||
  if ((rc = ddsi_xqos_valid (&gv->logconfig, rqos)) < 0 || (rc = validate_reader_qos(rqos)) != DDS_RETCODE_OK)
 | 
			
		||||
    goto err_bad_qos;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Additional checks required for built-in topics: we don't want to
 | 
			
		||||
     run into a resource limit on a built-in topic, it is a needless
 | 
			
		||||
     complication */
 | 
			
		||||
  if (pseudo_topic && !dds__validate_builtin_reader_qos (tp->m_entity.m_domain, pseudo_topic, rqos))
 | 
			
		||||
  {
 | 
			
		||||
    dds_delete_qos (rqos);
 | 
			
		||||
    rc = DDS_RETCODE_INCONSISTENT_POLICY;
 | 
			
		||||
    goto err_bad_qos;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  thread_state_awake (lookup_thread_state (), gv);
 | 
			
		||||
  const struct ddsi_guid * ppguid = dds_entity_participant_guid (&sub->m_entity);
 | 
			
		||||
  struct participant * pp = entidx_lookup_participant_guid (gv->entity_index, ppguid);
 | 
			
		||||
  if (pp == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    GVLOGDISC ("new_reader - participant "PGUIDFMT" not found\n", PGUID (*ppguid));
 | 
			
		||||
    rc = DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
    goto err_pp_not_found;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  /* Check if DDS Security is enabled */
 | 
			
		||||
  if (q_omg_participant_is_secure (pp))
 | 
			
		||||
  {
 | 
			
		||||
    /* ask to access control security plugin for create reader permissions */
 | 
			
		||||
    if (!q_omg_security_check_create_reader (pp, gv->config.domainId, tp->m_stopic->name, rqos))
 | 
			
		||||
    {
 | 
			
		||||
      rc = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
 | 
			
		||||
      goto err_not_allowed;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* Create reader and associated read cache (if not provided by caller) */
 | 
			
		||||
  struct dds_reader * const rd = dds_alloc (sizeof (*rd));
 | 
			
		||||
  const dds_entity_t reader = dds_entity_init (&rd->m_entity, &sub->m_entity, DDS_KIND_READER, false, rqos, listener, DDS_READER_STATUS_MASK);
 | 
			
		||||
| 
						 | 
				
			
			@ -474,8 +494,7 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe
 | 
			
		|||
     it; and then invoke those listeners that are in the pending set */
 | 
			
		||||
  dds_entity_init_complete (&rd->m_entity);
 | 
			
		||||
 | 
			
		||||
  thread_state_awake (lookup_thread_state (), &sub->m_entity.m_domain->gv);
 | 
			
		||||
  rc = new_reader (&rd->m_rd, &rd->m_entity.m_domain->gv, &rd->m_entity.m_guid, NULL, dds_entity_participant_guid (&sub->m_entity), tp->m_stopic, rqos, &rd->m_rhc->common.rhc, dds_reader_status_cb, rd);
 | 
			
		||||
  rc = new_reader (&rd->m_rd, &rd->m_entity.m_guid, NULL, pp, tp->m_stopic, rqos, &rd->m_rhc->common.rhc, dds_reader_status_cb, rd);
 | 
			
		||||
  assert (rc == DDS_RETCODE_OK); /* FIXME: can be out-of-resources at the very least */
 | 
			
		||||
  thread_state_asleep (lookup_thread_state ());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -487,7 +506,13 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe
 | 
			
		|||
  dds_subscriber_unlock (sub);
 | 
			
		||||
  return reader;
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
err_not_allowed:
 | 
			
		||||
#endif
 | 
			
		||||
err_pp_not_found:
 | 
			
		||||
  thread_state_asleep (lookup_thread_state ());
 | 
			
		||||
err_bad_qos:
 | 
			
		||||
  dds_delete_qos (rqos);
 | 
			
		||||
  dds_topic_allow_set_qos (tp);
 | 
			
		||||
err_pp_mismatch:
 | 
			
		||||
  dds_topic_unpin (tp);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@
 | 
			
		|||
#include "dds/ddsi/q_thread.h"
 | 
			
		||||
#include "dds/ddsi/q_xmsg.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_entity_index.h"
 | 
			
		||||
#include "dds/ddsi/ddsi_security_omg.h"
 | 
			
		||||
#include "dds__writer.h"
 | 
			
		||||
#include "dds__listener.h"
 | 
			
		||||
#include "dds__init.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -312,6 +313,7 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
 | 
			
		|||
  dds_topic_defer_set_qos (tp);
 | 
			
		||||
 | 
			
		||||
  /* Merge Topic & Publisher qos */
 | 
			
		||||
  struct ddsi_domaingv *gv = &pub->m_entity.m_domain->gv;
 | 
			
		||||
  wqos = dds_create_qos ();
 | 
			
		||||
  if (qos)
 | 
			
		||||
    ddsi_xqos_mergein_missing (wqos, qos, DDS_WRITER_QOS_MASK);
 | 
			
		||||
| 
						 | 
				
			
			@ -319,29 +321,47 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
 | 
			
		|||
    ddsi_xqos_mergein_missing (wqos, pub->m_entity.m_qos, ~(uint64_t)0);
 | 
			
		||||
  if (tp->m_ktopic->qos)
 | 
			
		||||
    ddsi_xqos_mergein_missing (wqos, tp->m_ktopic->qos, ~(uint64_t)0);
 | 
			
		||||
  ddsi_xqos_mergein_missing (wqos, &pub->m_entity.m_domain->gv.default_xqos_wr, ~(uint64_t)0);
 | 
			
		||||
  ddsi_xqos_mergein_missing (wqos, &gv->default_xqos_wr, ~(uint64_t)0);
 | 
			
		||||
 | 
			
		||||
  if ((rc = ddsi_xqos_valid (&pub->m_entity.m_domain->gv.logconfig, wqos)) < 0 ||
 | 
			
		||||
      (rc = validate_writer_qos(wqos)) != DDS_RETCODE_OK)
 | 
			
		||||
  {
 | 
			
		||||
    dds_delete_qos(wqos);
 | 
			
		||||
  if ((rc = ddsi_xqos_valid (&gv->logconfig, wqos)) < 0 || (rc = validate_writer_qos(wqos)) != DDS_RETCODE_OK)
 | 
			
		||||
    goto err_bad_qos;
 | 
			
		||||
 | 
			
		||||
  thread_state_awake (lookup_thread_state (), gv);
 | 
			
		||||
  const struct ddsi_guid *ppguid = dds_entity_participant_guid (&pub->m_entity);
 | 
			
		||||
  struct participant *pp = entidx_lookup_participant_guid (gv->entity_index, ppguid);
 | 
			
		||||
  if (pp == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    GVLOGDISC ("new_writer - participant "PGUIDFMT" not found\n", PGUID (*ppguid));
 | 
			
		||||
    rc = DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
    goto err_pp_not_found;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  /* Check if DDS Security is enabled */
 | 
			
		||||
  if (q_omg_participant_is_secure (pp))
 | 
			
		||||
  {
 | 
			
		||||
    /* ask to access control security plugin for create writer permissions */
 | 
			
		||||
    if (!q_omg_security_check_create_writer (pp, gv->config.domainId, tp->m_stopic->name, wqos))
 | 
			
		||||
    {
 | 
			
		||||
      rc = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
 | 
			
		||||
      goto err_not_allowed;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* Create writer */
 | 
			
		||||
  ddsi_tran_conn_t conn = pub->m_entity.m_domain->gv.xmit_conn;
 | 
			
		||||
  ddsi_tran_conn_t conn = gv->xmit_conn;
 | 
			
		||||
  struct dds_writer * const wr = dds_alloc (sizeof (*wr));
 | 
			
		||||
  const dds_entity_t writer = dds_entity_init (&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, false, wqos, listener, DDS_WRITER_STATUS_MASK);
 | 
			
		||||
  wr->m_topic = tp;
 | 
			
		||||
  dds_entity_add_ref_locked (&tp->m_entity);
 | 
			
		||||
  wr->m_xp = nn_xpack_new (conn, get_bandwidth_limit (wqos->transport_priority), pub->m_entity.m_domain->gv.config.xpack_send_async);
 | 
			
		||||
  wr->m_xp = nn_xpack_new (conn, get_bandwidth_limit (wqos->transport_priority), gv->config.xpack_send_async);
 | 
			
		||||
  wrinfo = whc_make_wrinfo (wr, wqos);
 | 
			
		||||
  wr->m_whc = whc_new (&pub->m_entity.m_domain->gv, wrinfo);
 | 
			
		||||
  wr->m_whc = whc_new (gv, wrinfo);
 | 
			
		||||
  whc_free_wrinfo (wrinfo);
 | 
			
		||||
  wr->whc_batch = pub->m_entity.m_domain->gv.config.whc_batch;
 | 
			
		||||
  wr->whc_batch = gv->config.whc_batch;
 | 
			
		||||
 | 
			
		||||
  thread_state_awake (lookup_thread_state (), &pub->m_entity.m_domain->gv);
 | 
			
		||||
  rc = new_writer (&wr->m_wr, &wr->m_entity.m_domain->gv, &wr->m_entity.m_guid, NULL, dds_entity_participant_guid (&pub->m_entity), tp->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
 | 
			
		||||
  rc = new_writer (&wr->m_wr, &wr->m_entity.m_guid, NULL, pp, tp->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
 | 
			
		||||
  assert(rc == DDS_RETCODE_OK);
 | 
			
		||||
  thread_state_asleep (lookup_thread_state ());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -355,7 +375,13 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
 | 
			
		|||
  dds_publisher_unlock (pub);
 | 
			
		||||
  return writer;
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
err_not_allowed:
 | 
			
		||||
#endif
 | 
			
		||||
err_pp_not_found:
 | 
			
		||||
  thread_state_asleep (lookup_thread_state ());
 | 
			
		||||
err_bad_qos:
 | 
			
		||||
  dds_delete_qos(wqos);
 | 
			
		||||
  dds_topic_allow_set_qos (tp);
 | 
			
		||||
err_pp_mismatch:
 | 
			
		||||
  dds_topic_unpin (tp);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,64 +22,37 @@ extern "C" {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
void g_omg_shallow_copy_StringSeq(DDS_Security_StringSeq *dst, const ddsi_stringseq_t *src);
 | 
			
		||||
 | 
			
		||||
void g_omg_shallow_free_StringSeq(DDS_Security_StringSeq *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_copy_PropertySeq(DDS_Security_PropertySeq *dst, const dds_propertyseq_t *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copyin_PropertySeq(DDS_Security_PropertySeq *dst, const dds_propertyseq_t *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copyout_PropertySeq(dds_propertyseq_t *dst, const DDS_Security_PropertySeq *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_PropertySeq(DDS_Security_PropertySeq *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copyin_BinaryPropertySeq(DDS_Security_BinaryPropertySeq *dst, const dds_binarypropertyseq_t *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copyout_BinaryPropertySeq(dds_binarypropertyseq_t *dst, const DDS_Security_BinaryPropertySeq *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_BinaryPropertySeq(DDS_Security_BinaryPropertySeq *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copy_PropertyQosPolicy(DDS_Security_PropertyQosPolicy *dst, const dds_property_qospolicy_t *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copy_security_qos(DDS_Security_Qos *dst, const struct dds_qos *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_PropertyQosPolicy(DDS_Security_PropertyQosPolicy *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_security_qos(DDS_Security_Qos *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_security_dataholder_copyin(nn_dataholder_t *dh, const DDS_Security_DataHolder *holder);
 | 
			
		||||
 | 
			
		||||
void q_omg_security_dataholder_copyout(DDS_Security_DataHolder *holder, const nn_dataholder_t *dh);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copyin_DataHolder(DDS_Security_DataHolder *dst, const nn_dataholder_t *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copyout_DataHolder(nn_dataholder_t *dst, const DDS_Security_DataHolder *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_DataHolder(DDS_Security_DataHolder *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_nn_dataholder(nn_dataholder_t *holder);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copyin_DataHolderSeq(DDS_Security_DataHolderSeq *dst, const nn_dataholderseq_t *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_copyin_DataHolderSeq(DDS_Security_DataHolderSeq *dst, const nn_dataholderseq_t *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copyout_DataHolderSeq(nn_dataholderseq_t *dst, const DDS_Security_DataHolderSeq *src);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_DataHolderSeq(DDS_Security_DataHolderSeq *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_nn_dataholderseq(nn_dataholderseq_t *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copy_ParticipantBuiltinTopicDataSecure(DDS_Security_ParticipantBuiltinTopicDataSecure *dst, const ddsi_guid_t *guid, const ddsi_plist_t *plist);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_ParticipantBuiltinTopicDataSecure(DDS_Security_ParticipantBuiltinTopicDataSecure *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copy_SubscriptionBuiltinTopicDataSecure(DDS_Security_SubscriptionBuiltinTopicDataSecure *dst, const ddsi_guid_t *guid, const struct dds_qos *qos, const nn_security_info_t *secinfo);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_SubscriptionBuiltinTopicDataSecure(DDS_Security_SubscriptionBuiltinTopicDataSecure *obj);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_copy_PublicationBuiltinTopicDataSecure(DDS_Security_PublicationBuiltinTopicDataSecure *dst, const ddsi_guid_t *guid, const struct dds_qos *qos, const nn_security_info_t *secinfo);
 | 
			
		||||
 | 
			
		||||
void q_omg_shallow_free_PublicationBuiltinTopicDataSecure(DDS_Security_PublicationBuiltinTopicDataSecure *obj);
 | 
			
		||||
void q_omg_shallow_copy_TopicBuiltinTopicData(DDS_Security_TopicBuiltinTopicData *dst, const char *topic_name, const char *type_name);
 | 
			
		||||
void q_omg_shallow_free_TopicBuiltinTopicData(DDS_Security_TopicBuiltinTopicData *obj);
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -642,9 +642,8 @@ DDS_EXPORT struct writer *get_builtin_writer (const struct participant *pp, unsi
 | 
			
		|||
   GUID "ppguid". May return NULL if participant unknown or
 | 
			
		||||
   writer/reader already known. */
 | 
			
		||||
 | 
			
		||||
dds_return_t new_writer (struct writer **wr_out, struct ddsi_domaingv *gv, struct ddsi_guid *wrguid, const struct ddsi_guid *group_guid, const struct ddsi_guid *ppguid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc * whc, status_cb_t status_cb, void *status_cb_arg);
 | 
			
		||||
 | 
			
		||||
dds_return_t new_reader (struct reader **rd_out, struct ddsi_domaingv *gv, struct ddsi_guid *rdguid, const struct ddsi_guid *group_guid, const struct ddsi_guid *ppguid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct ddsi_rhc * rhc, status_cb_t status_cb, void *status_cb_arg);
 | 
			
		||||
dds_return_t new_writer (struct writer **wr_out, struct ddsi_guid *wrguid, const struct ddsi_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc * whc, status_cb_t status_cb, void *status_cb_arg);
 | 
			
		||||
dds_return_t new_reader (struct reader **rd_out, struct ddsi_guid *rdguid, const struct ddsi_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct ddsi_rhc * rhc, status_cb_t status_cb, void *status_cb_arg);
 | 
			
		||||
 | 
			
		||||
void update_reader_qos (struct reader *rd, const struct dds_qos *xqos);
 | 
			
		||||
void update_writer_qos (struct writer *wr, const struct dds_qos *xqos);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2136,7 +2136,8 @@ bool q_omg_security_check_remote_writer_permissions(const struct proxy_writer *p
 | 
			
		|||
  struct dds_security_context *sc = q_omg_security_get_secure_context(pp);
 | 
			
		||||
  DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
 | 
			
		||||
  DDS_Security_PublicationBuiltinTopicDataSecure publication_data;
 | 
			
		||||
  bool ok = true;
 | 
			
		||||
  DDS_Security_TopicBuiltinTopicData topic_data;
 | 
			
		||||
  bool result = true;
 | 
			
		||||
 | 
			
		||||
  if (!sc)
 | 
			
		||||
    return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -2167,19 +2168,32 @@ bool q_omg_security_check_remote_writer_permissions(const struct proxy_writer *p
 | 
			
		|||
    else
 | 
			
		||||
    {
 | 
			
		||||
      q_omg_shallow_copy_PublicationBuiltinTopicDataSecure(&publication_data, &pwr->e.guid, pwr->c.xqos, &pwr->c.security_info);
 | 
			
		||||
      ok = sc->access_control_context->check_remote_datawriter(sc->access_control_context, permissions_handle, (int)domain_id, &publication_data, &exception);
 | 
			
		||||
      q_omg_shallow_free_PublicationBuiltinTopicDataSecure(&publication_data);
 | 
			
		||||
      if (!ok)
 | 
			
		||||
      result = sc->access_control_context->check_remote_datawriter(sc->access_control_context, permissions_handle, (int)domain_id, &publication_data, &exception);
 | 
			
		||||
      if (!result)
 | 
			
		||||
      {
 | 
			
		||||
        if (!is_topic_discovery_protected(pp->sec_attr->permissions_handle, sc->access_control_context, publication_data.topic_name))
 | 
			
		||||
          EXCEPTION_ERROR(gv, &exception, "Access control does not allow remote writer "PGUIDFMT": %s", PGUID(pwr->e.guid));
 | 
			
		||||
        else
 | 
			
		||||
          DDS_Security_Exception_reset(&exception);
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        q_omg_shallow_copy_TopicBuiltinTopicData(&topic_data, publication_data.topic_name, publication_data.type_name);
 | 
			
		||||
        result = sc->access_control_context->check_remote_topic(sc->access_control_context, permissions_handle, (int)domain_id, &topic_data, &exception);
 | 
			
		||||
        q_omg_shallow_free_TopicBuiltinTopicData(&topic_data);
 | 
			
		||||
        if (!result)
 | 
			
		||||
        {
 | 
			
		||||
          if (!is_topic_discovery_protected(pp->sec_attr->permissions_handle, sc->access_control_context, publication_data.topic_name))
 | 
			
		||||
            EXCEPTION_ERROR(gv, &exception, "Access control does not allow remote topic %s: %s", publication_data.topic_name);
 | 
			
		||||
          else
 | 
			
		||||
            DDS_Security_Exception_reset(&exception);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      q_omg_shallow_free_PublicationBuiltinTopicDataSecure(&publication_data);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ok;
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void send_reader_crypto_tokens(struct reader *rd, struct proxy_writer *pwr, DDS_Security_DatareaderCryptoHandle local_crypto, DDS_Security_DatawriterCryptoHandle remote_crypto)
 | 
			
		||||
| 
						 | 
				
			
			@ -2363,7 +2377,10 @@ bool q_omg_security_check_remote_reader_permissions(const struct proxy_reader *p
 | 
			
		|||
  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;
 | 
			
		||||
  bool ok = true;
 | 
			
		||||
  DDS_Security_SubscriptionBuiltinTopicDataSecure subscription_data;
 | 
			
		||||
  DDS_Security_TopicBuiltinTopicData topic_data;
 | 
			
		||||
  DDS_Security_boolean sec_relay_only;
 | 
			
		||||
  bool result = true;
 | 
			
		||||
 | 
			
		||||
  /* relay_only is meaningless in all cases except the one where the access control plugin says otherwise */
 | 
			
		||||
  *relay_only = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -2396,25 +2413,34 @@ bool q_omg_security_check_remote_reader_permissions(const struct proxy_reader *p
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      DDS_Security_SubscriptionBuiltinTopicDataSecure subscription_data;
 | 
			
		||||
      DDS_Security_boolean sec_relay_only;
 | 
			
		||||
 | 
			
		||||
      q_omg_shallow_copy_SubscriptionBuiltinTopicDataSecure(&subscription_data, &prd->e.guid, prd->c.xqos, &prd->c.security_info);
 | 
			
		||||
      ok = sc->access_control_context->check_remote_datareader(sc->access_control_context, permissions_handle, (int)domain_id, &subscription_data, &sec_relay_only, &exception);
 | 
			
		||||
      q_omg_shallow_free_SubscriptionBuiltinTopicDataSecure(&subscription_data);
 | 
			
		||||
      if (ok)
 | 
			
		||||
        *relay_only = !!sec_relay_only;
 | 
			
		||||
      else
 | 
			
		||||
      result = sc->access_control_context->check_remote_datareader(sc->access_control_context, permissions_handle, (int)domain_id, &subscription_data, &sec_relay_only, &exception);
 | 
			
		||||
      if (!result)
 | 
			
		||||
      {
 | 
			
		||||
        if (!is_topic_discovery_protected(pp->sec_attr->permissions_handle, sc->access_control_context, subscription_data.topic_name))
 | 
			
		||||
          EXCEPTION_ERROR(gv, &exception, "Access control does not allow remote reader "PGUIDFMT": %s", PGUID(prd->e.guid));
 | 
			
		||||
        else
 | 
			
		||||
          DDS_Security_Exception_reset(&exception);
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        *relay_only = !!sec_relay_only;
 | 
			
		||||
        q_omg_shallow_copy_TopicBuiltinTopicData(&topic_data, subscription_data.topic_name, subscription_data.type_name);
 | 
			
		||||
        result = sc->access_control_context->check_remote_topic(sc->access_control_context, permissions_handle, (int)domain_id, &topic_data, &exception);
 | 
			
		||||
        q_omg_shallow_free_TopicBuiltinTopicData(&topic_data);
 | 
			
		||||
        if (!result)
 | 
			
		||||
        {
 | 
			
		||||
          if (!is_topic_discovery_protected(pp->sec_attr->permissions_handle, sc->access_control_context, subscription_data.topic_name))
 | 
			
		||||
            EXCEPTION_ERROR(gv, &exception, "Access control does not allow remote topic %s: %s", subscription_data.topic_name);
 | 
			
		||||
          else
 | 
			
		||||
            DDS_Security_Exception_reset(&exception);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      q_omg_shallow_free_SubscriptionBuiltinTopicDataSecure(&subscription_data);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ok;
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void q_omg_get_proxy_endpoint_security_info(const struct entity_common *entity, nn_security_info_t *proxypp_sec_info, const ddsi_plist_t *plist, nn_security_info_t *info)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -703,6 +703,24 @@ q_omg_shallow_free_PublicationBuiltinTopicDataSecure(
 | 
			
		|||
  g_omg_shallow_free_StringSeq(&obj->partition.name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
q_omg_shallow_copy_TopicBuiltinTopicData(
 | 
			
		||||
    DDS_Security_TopicBuiltinTopicData *dst,
 | 
			
		||||
    const char *topic_name,
 | 
			
		||||
    const char *type_name)
 | 
			
		||||
{
 | 
			
		||||
  memset(dst, 0, sizeof(DDS_Security_TopicBuiltinTopicData));
 | 
			
		||||
  dst->name = (DDS_Security_string)topic_name;
 | 
			
		||||
  dst->type_name = (DDS_Security_string)type_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
q_omg_shallow_free_TopicBuiltinTopicData(
 | 
			
		||||
    DDS_Security_TopicBuiltinTopicData *obj)
 | 
			
		||||
{
 | 
			
		||||
  DDSRT_UNUSED_ARG(obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* DDSI_INCLUDE_SECURITY */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2771,6 +2771,7 @@ void connect_reader_with_proxy_writer_secure(struct reader *rd, struct proxy_wri
 | 
			
		|||
 | 
			
		||||
static void connect_writer_with_proxy_reader (struct writer *wr, struct proxy_reader *prd, ddsrt_mtime_t tnow)
 | 
			
		||||
{
 | 
			
		||||
  struct ddsi_domaingv *gv = wr->e.gv;
 | 
			
		||||
  const int isb0 = (is_builtin_entityid (wr->e.guid.entityid, NN_VENDORID_ECLIPSE) != 0);
 | 
			
		||||
  const int isb1 = (is_builtin_entityid (prd->e.guid.entityid, prd->c.vendor) != 0);
 | 
			
		||||
  dds_qos_policy_id_t reason;
 | 
			
		||||
| 
						 | 
				
			
			@ -2790,13 +2791,15 @@ static void connect_writer_with_proxy_reader (struct writer *wr, struct proxy_re
 | 
			
		|||
 | 
			
		||||
  if (!q_omg_security_check_remote_reader_permissions (prd, wr->e.gv->config.domainId, wr->c.pp, &relay_only))
 | 
			
		||||
  {
 | 
			
		||||
    EELOGDISC (&wr->e, "connect_writer_with_proxy_reader (wr "PGUIDFMT") with (prd "PGUIDFMT") not allowed by security\n",
 | 
			
		||||
                   PGUID (wr->e.guid), PGUID (prd->e.guid));
 | 
			
		||||
    GVLOGDISC ("connect_writer_with_proxy_reader (wr "PGUIDFMT") with (prd "PGUIDFMT") not allowed by security\n", PGUID (wr->e.guid), PGUID (prd->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else if (relay_only)
 | 
			
		||||
  {
 | 
			
		||||
    GVWARNING ("connect_writer_with_proxy_reader (wr "PGUIDFMT") with (prd "PGUIDFMT") relay_only not supported\n", PGUID (wr->e.guid), PGUID (prd->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else if (!q_omg_security_match_remote_reader_enabled (wr, prd, relay_only, &crypto_handle))
 | 
			
		||||
  {
 | 
			
		||||
    EELOGDISC (&wr->e, "connect_writer_with_proxy_reader (wr "PGUIDFMT") with (prd "PGUIDFMT") waiting for approval by security\n",
 | 
			
		||||
                     PGUID (wr->e.guid), PGUID (prd->e.guid));
 | 
			
		||||
    GVLOGDISC ("connect_writer_with_proxy_reader (wr "PGUIDFMT") with (prd "PGUIDFMT") waiting for approval by security\n", PGUID (wr->e.guid), PGUID (prd->e.guid));
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			@ -3801,28 +3804,11 @@ static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_g
 | 
			
		|||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_return_t new_writer (struct writer **wr_out, struct ddsi_domaingv *gv, struct ddsi_guid *wrguid, const struct ddsi_guid *group_guid, const struct ddsi_guid *ppguid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc * whc, status_cb_t status_cb, void *status_cb_arg)
 | 
			
		||||
dds_return_t new_writer (struct writer **wr_out, struct ddsi_guid *wrguid, const struct ddsi_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc * whc, status_cb_t status_cb, void *status_cb_arg)
 | 
			
		||||
{
 | 
			
		||||
  struct participant *pp;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  uint32_t kind;
 | 
			
		||||
 | 
			
		||||
  if ((pp = entidx_lookup_participant_guid (gv->entity_index, ppguid)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    GVLOGDISC ("new_writer - participant "PGUIDFMT" not found\n", PGUID (*ppguid));
 | 
			
		||||
    return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  /* Check if DDS Security is enabled */
 | 
			
		||||
  if (q_omg_participant_is_secure (pp))
 | 
			
		||||
  {
 | 
			
		||||
    /* ask to access control security plugin for create writer permissions */
 | 
			
		||||
    if (!q_omg_security_check_create_writer (pp, gv->config.domainId, topic->name, xqos))
 | 
			
		||||
      return DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* participant can't be freed while we're mucking around cos we are
 | 
			
		||||
     awake and do not touch the thread's vtime (entidx_lookup already
 | 
			
		||||
     verifies we're awake) */
 | 
			
		||||
| 
						 | 
				
			
			@ -4367,10 +4353,9 @@ static dds_return_t new_reader_guid
 | 
			
		|||
dds_return_t new_reader
 | 
			
		||||
(
 | 
			
		||||
  struct reader **rd_out,
 | 
			
		||||
  struct ddsi_domaingv *gv,
 | 
			
		||||
  struct ddsi_guid *rdguid,
 | 
			
		||||
  const struct ddsi_guid *group_guid,
 | 
			
		||||
  const struct ddsi_guid *ppguid,
 | 
			
		||||
  struct participant *pp,
 | 
			
		||||
  const struct ddsi_sertopic *topic,
 | 
			
		||||
  const struct dds_qos *xqos,
 | 
			
		||||
  struct ddsi_rhc * rhc,
 | 
			
		||||
| 
						 | 
				
			
			@ -4378,26 +4363,9 @@ dds_return_t new_reader
 | 
			
		|||
  void * status_cbarg
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
  struct participant * pp;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  uint32_t kind;
 | 
			
		||||
 | 
			
		||||
  if ((pp = entidx_lookup_participant_guid (gv->entity_index, ppguid)) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    GVLOGDISC ("new_reader - participant "PGUIDFMT" not found\n", PGUID (*ppguid));
 | 
			
		||||
    return DDS_RETCODE_BAD_PARAMETER;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#ifdef DDSI_INCLUDE_SECURITY
 | 
			
		||||
  /* Check if DDS Security is enabled */
 | 
			
		||||
  if (q_omg_participant_is_secure (pp))
 | 
			
		||||
  {
 | 
			
		||||
    /* ask to access control security plugin for create writer permissions */
 | 
			
		||||
    if (!q_omg_security_check_create_reader (pp, gv->config.domainId, topic->name, xqos))
 | 
			
		||||
      return DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  rdguid->prefix = pp->e.guid.prefix;
 | 
			
		||||
  kind = topic->topickind_no_key ? NN_ENTITYID_KIND_READER_NO_KEY : NN_ENTITYID_KIND_READER_WITH_KEY;
 | 
			
		||||
  if ((rc = pp_allocate_entityid (&rdguid->entityid, kind, pp)) < 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue