OpenDDS  Snapshot(2023/04/28-20:55)
AccessControlBuiltInImpl.cpp
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.opendds.org/license.html
4  */
5 
7 
9 #include "CommonUtilities.h"
10 #include "TokenWriter.h"
11 #include "SSL/SubjectName.h"
12 
14 
15 #include <dds/DdsDcpsInfrastructureC.h>
16 
17 #include <ace/ACE.h>
18 #include <ace/config-macros.h>
19 #include <ace/OS_NS_strings.h>
20 #include <ace/Reactor.h>
21 
22 #include <time.h>
23 #include <fstream>
24 #include <sstream>
25 #include <iostream>
26 #include <stdexcept>
27 #include <iterator>
28 #include <cstring>
29 #include <iomanip>
30 
32 
33 namespace OpenDDS {
34 namespace Security {
35 
36 using DCPS::TimeDuration;
37 
38 typedef Governance::GovernanceAccessRules::iterator gov_iter;
39 typedef Permissions::Grants::iterator grant_iter;
40 typedef Permissions::Rules::iterator perm_topic_rules_iter;
41 typedef Permissions::Actions::iterator perm_topic_actions_iter;
42 
43 static const std::string PermissionsTokenClassId("DDS:Access:Permissions:1.0");
44 static const std::string AccessControl_Plugin_Name("DDS:Access:Permissions");
45 static const std::string AccessControl_Major_Version("1");
46 static const std::string AccessControl_Minor_Version("0");
47 
48 static const std::string PermissionsCredentialTokenClassId("DDS:Access:PermissionsCredential");
49 
50 bool AccessControlBuiltInImpl::pattern_match(const char* string, const char* pattern)
51 {
52  return ACE::wild_match(string, pattern, true, true);
53 }
54 
56  : handle_mutex_()
58  , next_handle_(1)
59  , listener_ptr_(0)
60 { }
61 
63 {
64  if (DCPS::security_debug.bookkeeping) {
65  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
66  ACE_TEXT("AccessControlBuiltInImpl::~AccessControlBuiltInImpl local_ac_perms_ %B local_identity_map_ %B\n"),
67  local_ac_perms_.size(),
68  local_identity_map_.size()));
69  }
70 }
71 
73  ::DDS::Security::Authentication_ptr auth_plugin,
75  ::DDS::Security::DomainId_t domain_id,
76  const ::DDS::DomainParticipantQos & participant_qos,
78 {
79  if (0 == auth_plugin) {
80  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Null Authentication plugin");
81  return DDS::HANDLE_NIL;
82  }
83 
84  if (DDS::HANDLE_NIL == identity) {
85  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Invalid identity");
86  return DDS::HANDLE_NIL;
87  }
88 
90 
91  if (!auth_plugin->get_identity_token(id_token, identity, ex)) {
92  return DDS::HANDLE_NIL;
93  }
94 
95  LocalAccessCredentialData::shared_ptr local_access_credential_data = DCPS::make_rch<LocalAccessCredentialData>();
96 
97  if (! local_access_credential_data->load(participant_qos.property.value, ex)) {
98  return DDS::HANDLE_NIL;
99  }
100 
101  if (!local_access_credential_data->verify(ex)) {
102  return DDS::HANDLE_NIL;
103  }
104 
105  const SSL::SignedDocument& local_gov = local_access_credential_data->get_governance_doc();
106  Governance::shared_ptr governance = DCPS::make_rch<Governance>();
107 
108  if (governance->load(local_gov)) {
109  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Invalid governance file");
110  return DDS::HANDLE_NIL;
111  }
112 
113  const SSL::SignedDocument& local_perm = local_access_credential_data->get_permissions_doc();
114  Permissions::shared_ptr permissions = DCPS::make_rch<Permissions>();
115 
116  if (permissions->load(local_perm)) {
117  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Invalid permission file");
118  return DDS::HANDLE_NIL;
119  }
120 
121  TokenReader tr(id_token);
122  const char* id_sn = tr.get_property_value(dds_cert_sn);
123 
125 
126  if (!id_sn || sn_id.parse(id_sn) != 0 || !permissions->has_grant(sn_id)) {
127  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: No permissions subject name matches identity subject name");
128  return DDS::HANDLE_NIL;
129  }
130 
131  // Set and store the permissions credential token while we have the raw content
132  DDS::Security::PermissionsCredentialToken permissions_cred_token;
133  TokenWriter pctWriter(permissions_cred_token, PermissionsCredentialTokenClassId);
134 
135  pctWriter.add_property("dds.perm.cert", local_perm.original());
136 
137  // Set and store the permissions token
138  DDS::Security::PermissionsToken permissions_token;
139  TokenWriter writer(permissions_token, PermissionsTokenClassId);
140 
141  // If all checks are successful load the content into cache
142  permissions->perm_token_ = permissions_token;
143  permissions->perm_cred_token_ = permissions_cred_token;
144 
145  const int perm_handle = generate_handle();
146 
148 
149  AccessData cache_this;
150  cache_this.identity = identity;
151  cache_this.subject = sn_id;
152  cache_this.domain_id = domain_id;
153  cache_this.perm = permissions;
154  cache_this.gov = governance;
155  cache_this.local_access_credential_data = local_access_credential_data;
156 
157  local_ac_perms_.insert(std::make_pair(perm_handle, cache_this));
158  if (DCPS::security_debug.bookkeeping) {
159  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
160  ACE_TEXT("AccessControlBuiltInImpl::validate_local_permissions local_ac_perms_ (total %B)\n"),
161  local_ac_perms_.size()));
162  }
163  local_identity_map_.insert(std::make_pair(identity, perm_handle));
164  if (DCPS::security_debug.bookkeeping) {
165  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
166  ACE_TEXT("AccessControlBuiltInImpl::validate_local_permissions local_identity_map_ (total %B)\n"),
167  local_identity_map_.size()));
168  }
169 
170  return perm_handle;
171 }
172 
174  ::DDS::Security::Authentication_ptr auth_plugin,
175  ::DDS::Security::IdentityHandle local_identity_handle,
176  ::DDS::Security::IdentityHandle remote_identity_handle,
177  const ::DDS::Security::PermissionsToken & remote_permissions_token,
180 {
181  if (0 == auth_plugin) {
182  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Null Authentication plugin");
183  return DDS::HANDLE_NIL;
184  }
185 
186  if (DDS::HANDLE_NIL == local_identity_handle) {
187  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Invalid Local Identity");
188  return DDS::HANDLE_NIL;
189  }
190 
192 
193  ACIdentityMap::iterator iter = local_identity_map_.find(local_identity_handle);
194 
195  if (iter == local_identity_map_.end()) {
196  CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: No matching local identity handle present");
197  return DDS::HANDLE_NIL;
198  }
199 
200  ACPermsMap::iterator piter = local_ac_perms_.find(iter->second);
201 
202  if (piter == local_ac_perms_.end()) {
203  CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: No matching local permissions handle present");
204  return DDS::HANDLE_NIL;
205  }
206 
207  // permissions file
208  TokenReader remote_perm_wrapper(remote_credential_token);
209  SSL::SignedDocument remote_perm_doc(remote_perm_wrapper.get_bin_property_value("c.perm"));
210 
211  const LocalAccessCredentialData::shared_ptr& local_access_credential_data = piter->second.local_access_credential_data;
212 
213  // Validate the signature of the remote permissions
214  const SSL::Certificate& local_ca = local_access_credential_data->get_ca_cert();
215  std::string ca_subject;
216 
217  local_ca.subject_name_to_str(ca_subject);
218 
219  if (!remote_perm_doc.verify(local_ca)) {
220  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Remote permissions signature not verified");
221  return DDS::HANDLE_NIL;
222  }
223 
224  // The remote permissions signature is verified
227  "(%P|%t) AccessControlBuiltInImpl::validate_remote_permissions: Remote permissions document verified.\n")));
228  }
229 
230  Permissions::shared_ptr remote_permissions = DCPS::make_rch<Permissions>();
231  if (remote_permissions->load(remote_perm_doc)) {
232  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Invalid permission file");
233  return DDS::HANDLE_NIL;
234  }
235 
236  //Extract and compare the remote subject name for validation
237  TokenReader remote_credential_tr(remote_credential_token);
238  const DDS::OctetSeq& cid = remote_credential_tr.get_bin_property_value("c.id");
239 
240  if (cid.length() == 0) {
241  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Invalid remote credential identity");
242  return DDS::HANDLE_NIL;
243  }
244 
246  remote_cert->deserialize(cid);
247 
248  std::string remote_identity_sn;
249  remote_cert->subject_name_to_str(remote_identity_sn);
250 
251  SSL::SubjectName sn_id_remote;
252 
253  if (remote_identity_sn.empty() || sn_id_remote.parse(remote_identity_sn) != 0 || !remote_permissions->has_grant(sn_id_remote)) {
254  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: "
255  "Remote identity subject name does not match any subject name in remote permissions grants");
256  return DDS::HANDLE_NIL;
257  }
258 
259  // Set and store the permissions credential token while we have the raw content
260  remote_permissions->perm_token_ = remote_permissions_token;
261  remote_permissions->perm_cred_token_ = remote_credential_token;
262 
263 
264  AccessData cache_this;
265  cache_this.identity = remote_identity_handle;
266  cache_this.subject = sn_id_remote;
267  cache_this.domain_id = piter->second.domain_id;
268  cache_this.perm = remote_permissions;
269  cache_this.gov = piter->second.gov;
270  cache_this.local_access_credential_data = local_access_credential_data;
271 
272  const int perm_handle = generate_handle();
273  local_ac_perms_.insert(std::make_pair(perm_handle, cache_this));
274  if (DCPS::security_debug.bookkeeping) {
275  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
276  ACE_TEXT("AccessControlBuiltInImpl::validate_remote_permissions local_ac_perms_ (total %B)\n"),
277  local_ac_perms_.size()));
278  }
279  return perm_handle;
280 }
281 
283  ::DDS::Security::PermissionsHandle permissions_handle,
284  ::DDS::Security::DomainId_t domain_id,
285  const ::DDS::DomainParticipantQos & /*qos*/,
287 {
288  if (DDS::HANDLE_NIL == permissions_handle) {
289  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_participant: Invalid permissions handle");
290  }
291 
292 /*
293  * The rules of this method need to be evaluated in this order, however, we need to check
294  * to make sure the permission handle exists in our store prior to assessing these rules
295 */
296  /* From Table 63 of the spec.
297  This operation shall use the permissions_handle to retrieve
298  the cached Permissions and Governance information.
299  If the Governance specifies any topics on the
300  DomainParticipant domain_id with
301  enable_read_access_control set to FALSE or with
302  enable_write_access_control set to FALSE, then the
303  operation shall succeed and return TRUE.
304  If the ParticipantSecurityAttributes has
305  is_access_protected set to FALSE, then the operation shall
306  succeed and return TRUE.
307  Otherwise the operation shall return FALSE.
308  */
309 
311 
312  ACPermsMap::iterator piter = local_ac_perms_.find(permissions_handle);
313 
314  if (piter == local_ac_perms_.end()) {
315  return CommonUtilities::set_security_error(ex, -1, 0,
316  "AccessControlBuiltInImpl::check_create_participant: "
317  "No matching permissions handle present");
318  }
319 
320  if (domain_id != piter->second.domain_id) {
321  return CommonUtilities::set_security_error(ex, -1, 0,
322  "AccessControlBuiltInImpl::check_create_participant: "
323  "Domain does not match validated permissions handle");
324  }
325 
326  gov_iter begin = piter->second.gov->access_rules().begin();
327  gov_iter end = piter->second.gov->access_rules().end();
328 
329  for (gov_iter giter = begin; giter != end; ++giter) {
330 
331  if (giter->domains.has(domain_id)) {
332  Governance::TopicAccessRules::iterator tr_iter;
333 
334  for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
335  if (!tr_iter->topic_attrs.is_read_protected || !tr_iter->topic_attrs.is_write_protected) {
336  return true;
337  }
338  }
339 
340  if (!giter->domain_attrs.is_access_protected) {
341  return true;
342  }
343  }
344  }
345 
346  return CommonUtilities::set_security_error(ex, -1, 0,
347  "AccessControlBuiltInImpl::check_create_participant: "
348  "No governance exists for this domain");
349 }
350 
352  ::DDS::Security::PermissionsHandle permissions_handle,
353  ::DDS::Security::DomainId_t domain_id,
354  const char * topic_name,
355  const ::DDS::DataWriterQos & /*qos*/,
356  const ::DDS::PartitionQosPolicy & partition,
357  const ::DDS::Security::DataTags & /*data_tag*/,
359 {
360  if (DDS::HANDLE_NIL == permissions_handle) {
361  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Invalid permissions handle");
362  }
363  if (0 == topic_name) {
364  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Invalid Topic Name");
365  }
366 
368 
369  ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
370 
371  if (ac_iter == local_ac_perms_.end()) {
372  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: No matching permissions handle present");
373  }
374 
375  gov_iter begin = ac_iter->second.gov->access_rules().begin();
376  gov_iter end = ac_iter->second.gov->access_rules().end();
377 
378  for (gov_iter giter = begin; giter != end; ++giter) {
379 
380  if (giter->domains.has(domain_id)) {
381  Governance::TopicAccessRules::iterator tr_iter;
382 
383  for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
384  if (pattern_match(topic_name, tr_iter->topic_expression.c_str())) {
385  if (!tr_iter->topic_attrs.is_write_protected) {
386  return true;
387  }
388  }
389  }
390  }
391  }
392 
393  // Check the Permissions file
394 
395  const Permissions::Grant_rch grant = ac_iter->second.perm->find_grant(ac_iter->second.subject);
396  if (!grant) {
397  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Permissions grant not found");
398  }
399 
400  if (!validate_date_time(grant->validity, ex)) {
401  return false;
402  }
403 
404  if (!search_permissions(topic_name, domain_id, partition, Permissions::PUBLISH, *grant, ex)) {
405  return false;
406  }
407 
408  make_task(local_rp_task_)->insert(permissions_handle, grant->validity.not_after);
409 
410  return true;
411 }
412 
414  ::DDS::Security::PermissionsHandle permissions_handle,
415  ::DDS::Security::DomainId_t domain_id,
416  const char * topic_name,
417  const ::DDS::DataReaderQos & /*qos*/,
418  const ::DDS::PartitionQosPolicy & partition,
419  const ::DDS::Security::DataTags & /*data_tag*/,
421 {
422  if (DDS::HANDLE_NIL == permissions_handle) {
423  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: Invalid permissions handle");
424  }
425 
426  if (0 == topic_name) {
427  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: Invalid Topic Name");
428  }
429 
431 
432  ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
433 
434  if (ac_iter == local_ac_perms_.end()) {
435  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: No matching permissions handle present");
436  }
437 
438  gov_iter begin = ac_iter->second.gov->access_rules().begin();
439  gov_iter end = ac_iter->second.gov->access_rules().end();
440 
441  for (gov_iter giter = begin; giter != end; ++giter) {
442 
443  if (giter->domains.has(domain_id)) {
444  Governance::TopicAccessRules::iterator tr_iter;
445 
446  for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
447  if (pattern_match(topic_name, tr_iter->topic_expression.c_str())) {
448  if (!tr_iter->topic_attrs.is_read_protected) {
449  return true;
450  }
451  }
452  }
453  }
454  }
455 
456  // Check the Permissions file
457 
458  const Permissions::Grant_rch grant = ac_iter->second.perm->find_grant(ac_iter->second.subject);
459  if (!grant) {
460  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: Permissions grant not found");
461  }
462 
463  if (!validate_date_time(grant->validity, ex)) {
464  return false;
465  }
466 
467  if (!search_permissions(topic_name, domain_id, partition, Permissions::SUBSCRIBE, *grant, ex)) {
468  return false;
469  }
470 
471  make_task(local_rp_task_)->insert(permissions_handle, grant->validity.not_after);
472 
473  return true;
474 }
475 
477  ::DDS::Security::PermissionsHandle permissions_handle,
478  ::DDS::Security::DomainId_t domain_id,
479  const char * topic_name,
480  const ::DDS::TopicQos & /*qos*/,
482 {
483  if (DDS::HANDLE_NIL == permissions_handle) {
484  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: Invalid permissions handle");
485  }
486  if (0 == topic_name) {
487  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: Invalid Topic Name");
488  }
489 
491 
492  ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
493 
494  if (ac_iter == local_ac_perms_.end()) {
495  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: No matching permissions handle present");
496  }
497 
498  // Check the Governance file for allowable topic attributes
499 
500  if (domain_id != ac_iter->second.domain_id) {
501  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: Requested domain ID does not match permissions handle");
502  }
503 
504  ::DDS::Security::DomainId_t domain_to_find = ac_iter->second.domain_id;
505 
506  gov_iter begin = ac_iter->second.gov->access_rules().begin();
507  gov_iter end = ac_iter->second.gov->access_rules().end();
508 
509  for (gov_iter giter = begin; giter != end; ++giter) {
510 
511  if (giter->domains.has(domain_to_find)) {
512  Governance::TopicAccessRules::iterator tr_iter;
513 
514  for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
515  if (pattern_match(topic_name, tr_iter->topic_expression.c_str())) {
516  if (!tr_iter->topic_attrs.is_read_protected || !tr_iter->topic_attrs.is_write_protected) {
517  return true;
518  }
519  }
520  }
521  }
522  }
523 
524  const Permissions::Grant_rch grant = ac_iter->second.perm->find_grant(ac_iter->second.subject);
525  if (!grant) {
526  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: grant not found");
527  }
528 
529  if (!validate_date_time(grant->validity, ex)) {
530  return false;
531  }
532 
534  bool found_deny = false;
535  // Iterate over allow / deny rules
536  for (perm_topic_rules_iter ptr_iter = grant->rules.begin(); ptr_iter != grant->rules.end(); ++ptr_iter) {
537 
538  if (ptr_iter->domains.has(domain_to_find)) {
539 
540  perm_topic_actions_iter tpsr_iter;
541  for (tpsr_iter = ptr_iter->actions.begin(); tpsr_iter != ptr_iter->actions.end(); ++tpsr_iter) {
542 
543  std::vector<std::string>::iterator tl_iter;
544  for (tl_iter = tpsr_iter->topics.begin(); tl_iter != tpsr_iter->topics.end(); ++tl_iter) {
545 
546  if (pattern_match(topic_name, tl_iter->c_str())) {
547  if (ptr_iter->ad_type == Permissions::ALLOW) {
548  return true;
549  }
550  if (found_deny && denied_type != tpsr_iter->ps_type) {
551  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: Both publish and subscribe are denied for this topic.");
552  } else if (!found_deny) {
553  found_deny = true;
554  denied_type = tpsr_iter->ps_type;
555  }
556  }
557  }
558  }
559  }
560  }
561 
562  // There is no matching rule for topic_name so use the value in default_permission
563  if (grant->default_permission == Permissions::ALLOW) {
564  return true;
565  } else {
566  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: No matching rule for topic, default permission is DENY.");
567  }
568 }
569 
571  ::DDS::Security::PermissionsHandle permissions_handle,
572  ::DDS::DataWriter_ptr writer,
573  ::DDS::DynamicData_ptr key,
575 {
576  if (DDS::HANDLE_NIL == permissions_handle) {
577  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_register_instance: Invalid permissions handle");
578  }
579  if (0 == writer) {
580  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_register_instance: Invalid Writer");
581  }
582  if (0 == key) {
583  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_register_instance: Invalid Topic Key");
584  }
585 
586  return true;
587 }
588 
590  ::DDS::Security::PermissionsHandle permissions_handle,
591  ::DDS::DataWriter_ptr writer,
592  ::DDS::DynamicData_ptr key,
594 {
595  if (DDS::HANDLE_NIL == permissions_handle) {
596  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_dispose_instance: Invalid permissions handle");
597  }
598  if (0 == writer) {
599  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_dispose_instance: Invalid Writer");
600  }
601  if (0 == key) {
602  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_dispose_instance: Invalid Topic Key");
603  }
604 
605  return true;
606 }
607 
609  ::DDS::Security::PermissionsHandle permissions_handle,
610  ::DDS::Security::DomainId_t domain_id,
611  const ::DDS::Security::ParticipantBuiltinTopicDataSecure & participant_data,
613 {
614  if (DDS::HANDLE_NIL == permissions_handle) {
615  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Invalid permissions handle");
616  }
617 
619 
620  ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
621 
622  if (ac_iter == local_ac_perms_.end()) {
623  return CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::check_remote_participant: No matching permissions handle present");
624  }
625 
626  gov_iter begin = ac_iter->second.gov->access_rules().begin();
627  gov_iter end = ac_iter->second.gov->access_rules().end();
628 
629  for (gov_iter giter = begin; giter != end; ++giter) {
630  if (giter->domains.has(domain_id) && !giter->domain_attrs.is_access_protected) {
631  return true;
632  }
633  }
634 
635  // Check the PluginClassName and MajorVersion of the local permissions vs. remote See Table 63 of spec
636  const std::string remote_class_id = participant_data.base.permissions_token.class_id.in();
637 
638  std::string local_plugin_class_name,
639  remote_plugin_class_name;
640  int local_major_ver = 0,
641  local_minor_ver,
642  remote_major_ver,
643  remote_minor_ver;
644 
645  if (remote_class_id.length() > 0) {
646  parse_class_id(remote_class_id, remote_plugin_class_name, remote_major_ver, remote_minor_ver);
647  } else {
648  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Invalid remote class ID");
649  }
650 
651  for (ACPermsMap::iterator local_iter = local_ac_perms_.begin(); local_iter != local_ac_perms_.end(); ++local_iter) {
652  if (local_iter->second.domain_id == domain_id && local_iter->first != permissions_handle) {
653  const std::string local_class_id = local_iter->second.perm->perm_token_.class_id.in();
654 
655  if (local_class_id.length() > 0) {
656  parse_class_id(local_class_id, local_plugin_class_name, local_major_ver, local_minor_ver);
657  break;
658  } else {
659  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Invalid local class ID");
660  }
661  }
662  }
663 
664  if (strcmp(local_plugin_class_name.c_str(), remote_plugin_class_name.c_str())) {
665  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Class ID plugin class name do not match");
666  }
667 
668  if (local_major_ver != remote_major_ver) {
669  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Class ID major versions do not match");
670  }
671 
672  const Permissions::Grant_rch grant = ac_iter->second.perm->find_grant(ac_iter->second.subject);
673  if (!grant) {
674  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Permissions grant not found");
675  }
676 
677  for (perm_topic_rules_iter ptr_iter = grant->rules.begin(); ptr_iter != grant->rules.end(); ++ptr_iter) {
678  if (ptr_iter->domains.has(domain_id) && ptr_iter->ad_type == Permissions::ALLOW) {
679  return true;
680  }
681  }
682 
683  if (grant->default_permission == Permissions::ALLOW) {
684  return true; // DDSSEC12-85
685  }
686 
687  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Not authorized for domain");
688 }
689 
691  ::DDS::Security::PermissionsHandle permissions_handle,
692  ::DDS::Security::DomainId_t domain_id,
693  const ::DDS::Security::PublicationBuiltinTopicDataSecure & publication_data,
695 {
696  if (DDS::HANDLE_NIL == permissions_handle) {
697  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter: Invalid permissions handle");
698  }
699 
700  if (publication_data.base.base.topic_name[0] == 0) {
701  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter: Invalid topic name");
702  }
703 
705 
706  ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
707 
708  if (ac_iter == local_ac_perms_.end()) {
709  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter: No matching permissions handle present");
710  }
711 
712  gov_iter begin = ac_iter->second.gov->access_rules().begin();
713  gov_iter end = ac_iter->second.gov->access_rules().end();
714 
715  for (gov_iter giter = begin; giter != end; ++giter) {
716 
717  if (giter->domains.has(domain_id)) {
718  Governance::TopicAccessRules::iterator tr_iter;
719 
720  for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
721  if (pattern_match(publication_data.base.base.topic_name, tr_iter->topic_expression.c_str())) {
722  if (!tr_iter->topic_attrs.is_write_protected) {
723  return true;
724  }
725  }
726  }
727  }
728  }
729 
730  const Permissions::Grant_rch grant = ac_iter->second.perm->find_grant(ac_iter->second.subject);
731  if (!grant) {
732  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter: Permissions grant not found");
733  }
734 
735  if (!validate_date_time(grant->validity, ex)) {
736  return false;
737  }
738 
739  if (!search_permissions(publication_data.base.base.topic_name, domain_id,
740  publication_data.base.base.partition, Permissions::PUBLISH,
741  *grant, ex)) {
742  return false;
743  }
744 
745  make_task(remote_rp_task_)->insert(permissions_handle, grant->validity.not_after);
746 
747  return true;
748 }
749 
751  ::DDS::Security::PermissionsHandle permissions_handle,
752  ::DDS::Security::DomainId_t domain_id,
753  const ::DDS::Security::SubscriptionBuiltinTopicDataSecure & subscription_data,
754  ::CORBA::Boolean & relay_only,
756 {
757  if (DDS::HANDLE_NIL == permissions_handle) {
758  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datareader: Invalid permissions handle");
759  }
760 
762 
763  ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
764 
765  if (ac_iter == local_ac_perms_.end()) {
766  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: No matching permissions handle present");
767  }
768 
769  // Default this to false for now
770  relay_only = false;
771 
772  gov_iter begin = ac_iter->second.gov->access_rules().begin();
773  gov_iter end = ac_iter->second.gov->access_rules().end();
774 
775  for (gov_iter giter = begin; giter != end; ++giter) {
776 
777  if (giter->domains.has(domain_id)) {
778  Governance::TopicAccessRules::iterator tr_iter;
779 
780  for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
781  if (pattern_match(subscription_data.base.base.topic_name, tr_iter->topic_expression.c_str())) {
782  if (!tr_iter->topic_attrs.is_read_protected) {
783  return true;
784  }
785  }
786  }
787  }
788  }
789 
790  const Permissions::Grant_rch grant = ac_iter->second.perm->find_grant(ac_iter->second.subject);
791  if (!grant) {
792  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datareader: Permissions grant not found");
793  }
794 
795  if (!validate_date_time(grant->validity, ex)) {
796  return false;
797  }
798 
799  if (!search_permissions(subscription_data.base.base.topic_name, domain_id,
800  subscription_data.base.base.partition, Permissions::SUBSCRIBE,
801  *grant, ex)) {
802  return false;
803  }
804 
805  make_task(remote_rp_task_)->insert(permissions_handle, grant->validity.not_after);
806 
807  return true;
808 }
809 
811  ::DDS::Security::PermissionsHandle permissions_handle,
812  ::DDS::Security::DomainId_t domain_id,
813  const ::DDS::TopicBuiltinTopicData & topic_data,
815 {
816  // NOTE: permissions_handle is for the remote DomainParticipant.
817  if (DDS::HANDLE_NIL == permissions_handle) {
818  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Invalid permissions handle");
819  }
820 
821  if (topic_data.name[0] == 0) {
822  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Invalid topic data");
823  }
824 
826 
827  ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
828 
829  if (ac_iter == local_ac_perms_.end()) {
830  return CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::check_remote_topic: No matching permissions handle present");
831  }
832 
833  // Compare the PluginClassName and MajorVersion of the local permissions_token
834  // with those in the remote_permissions_token.
835  const std::string remote_class_id = ac_iter->second.perm->perm_token_.class_id.in();
836 
837  std::string local_plugin_class_name,
838  remote_plugin_class_name;
839  int local_major_ver = 0,
840  local_minor_ver,
841  remote_major_ver,
842  remote_minor_ver;
843 
844  if (remote_class_id.length() > 0) {
845  parse_class_id(remote_class_id, remote_plugin_class_name, remote_major_ver, remote_minor_ver);
846  } else {
847  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Invalid remote class ID");
848  }
849 
850  for (ACPermsMap::iterator local_iter = local_ac_perms_.begin(); local_iter != local_ac_perms_.end(); ++local_iter) {
851  if (local_iter->second.domain_id == domain_id && local_iter->first != permissions_handle) {
852  const std::string local_class_id = local_iter->second.perm->perm_token_.class_id.in();
853 
854  if (local_class_id.length() > 0) {
855  parse_class_id(local_class_id, local_plugin_class_name, local_major_ver, local_minor_ver);
856  break;
857  } else {
858  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Invalid local class ID");
859  }
860  }
861  }
862 
863  if (strcmp(local_plugin_class_name.c_str(), remote_plugin_class_name.c_str())) {
864  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Class ID plugin class name do not match");
865  }
866 
867  if (local_major_ver != remote_major_ver) {
868  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Class ID major versions do not match");
869  }
870 
871  // Check the Governance file for allowable topic attributes
872 
873  gov_iter begin = ac_iter->second.gov->access_rules().begin();
874  gov_iter end = ac_iter->second.gov->access_rules().end();
875 
876  for (gov_iter giter = begin; giter != end; ++giter) {
877 
878  if (giter->domains.has(domain_id)) {
879  Governance::TopicAccessRules::iterator tr_iter;
880 
881  for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
882  if (pattern_match(topic_data.name, tr_iter->topic_expression.c_str())) {
883  if (!tr_iter->topic_attrs.is_read_protected || !tr_iter->topic_attrs.is_write_protected) {
884  return true;
885  }
886  }
887  }
888  }
889  }
890 
891  const Permissions::Grant_rch grant = ac_iter->second.perm->find_grant(ac_iter->second.subject);
892  if (!grant) {
893  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: grant not found");
894  }
895 
896  if (!validate_date_time(grant->validity, ex)) {
897  return false;
898  }
899 
901  bool found_deny = false;
902  for (perm_topic_rules_iter ptr_iter = grant->rules.begin(); ptr_iter != grant->rules.end(); ++ptr_iter) {
903 
904  if (ptr_iter->domains.has(domain_id)) {
905 
906  // Iterate over pub / sub rules
907  perm_topic_actions_iter tpsr_iter;
908  for (tpsr_iter = ptr_iter->actions.begin(); tpsr_iter != ptr_iter->actions.end(); ++tpsr_iter) {
909 
910  // Check to make sure they can publish or subscribe to the topic
911  // TODO Add support for relay permissions once relay only key exchange is supported
912  if (tpsr_iter->ps_type == Permissions::PUBLISH || tpsr_iter->ps_type == Permissions::SUBSCRIBE) {
913 
914  std::vector<std::string>::iterator tl_iter;
915  for (tl_iter = tpsr_iter->topics.begin(); tl_iter != tpsr_iter->topics.end(); ++tl_iter) {
916 
917  if (pattern_match(topic_data.name, tl_iter->c_str())) {
918  if (ptr_iter->ad_type == Permissions::ALLOW) {
919  return true;
920  }
921  if (found_deny && denied_type != tpsr_iter->ps_type) {
922  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Both publish and subscribe are denied for this topic.");
923  } else if (!found_deny) {
924  found_deny = true;
925  denied_type = tpsr_iter->ps_type;
926  }
927  }
928  }
929  }
930  }
931  }
932  }
933 
934  // There is no matching rule for topic_name so use the value in default_permission
935  if (grant->default_permission == Permissions::ALLOW) {
936  return true;
937  } else {
938  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: No matching rule for topic, default permission is DENY.");
939  }
940 }
941 
943  ::DDS::Security::PermissionsHandle writer_permissions_handle,
944  ::DDS::Security::PermissionsHandle reader_permissions_handle,
945  const ::DDS::Security::PublicationBuiltinTopicDataSecure & /*publication_data*/,
946  const ::DDS::Security::SubscriptionBuiltinTopicDataSecure & /*subscription_data*/,
948 {
949  if (DDS::HANDLE_NIL == writer_permissions_handle) {
950  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_match: Invalid writer permissions handle");
951  }
952  if (DDS::HANDLE_NIL == reader_permissions_handle) {
953  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_match: Invalid reader permissions handle");
954  }
955 
956  return true;
957 }
958 
960  ::DDS::Security::PermissionsHandle reader_permissions_handle,
961  ::DDS::Security::PermissionsHandle writer_permissions_handle,
962  const ::DDS::Security::SubscriptionBuiltinTopicDataSecure & /*subscription_data*/,
963  const ::DDS::Security::PublicationBuiltinTopicDataSecure & /*publication_data*/,
965 {
966  if (DDS::HANDLE_NIL == writer_permissions_handle) {
967  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datareader_match: Invalid writer permissions handle");
968  }
969  if (DDS::HANDLE_NIL == reader_permissions_handle) {
970  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datareader_match: Invalid reader permissions handle");
971  }
972 
973  return true;
974 }
975 
977  ::DDS::Security::PermissionsHandle permissions_handle,
978  ::DDS::DataReader_ptr reader,
979  ::DDS::InstanceHandle_t publication_handle,
980  ::DDS::DynamicData_ptr key,
982 {
983  if (DDS::HANDLE_NIL == permissions_handle ||
984  DDS::HANDLE_NIL == publication_handle) {
985  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_register_instance: Invalid handle");
986  }
987  if (0 == reader) {
988  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_register_instance: Invalid Reader pointer");
989  }
990  // Key could be null if we don't have complete type objects
991  ACE_UNUSED_ARG(key);
992  return true;
993 }
994 
996  ::DDS::Security::PermissionsHandle permissions_handle,
997  ::DDS::DataReader_ptr reader,
998  ::DDS::InstanceHandle_t publication_handle,
999  ::DDS::DynamicData_ptr key,
1001 {
1002  if (DDS::HANDLE_NIL == permissions_handle ||
1003  DDS::HANDLE_NIL == publication_handle) {
1004  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_dispose_instance: Invalid handle");
1005  }
1006  if (0 == reader) {
1007  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_dispose_instance: Invalid Reader pointer");
1008  }
1009  // Key could be null if we don't have complete type objects
1010  ACE_UNUSED_ARG(key);
1011  return true;
1012 }
1013 
1015  ::DDS::Security::PermissionsToken & permissions_token,
1018 {
1019  if (DDS::HANDLE_NIL == handle) {
1020  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_permissions_token: Invalid permissions handle");
1021  return false;
1022  }
1023 
1025 
1026  ACPermsMap::iterator iter = local_ac_perms_.find(handle);
1027 
1028  if (iter != local_ac_perms_.end()) {
1029  permissions_token = iter->second.perm->perm_token_;
1030  return true;
1031  } else {
1032  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_permissions_token: No PermissionToken found");
1033  return false;
1034  }
1035 }
1036 
1038  ::DDS::Security::PermissionsCredentialToken & permissions_credential_token,
1041 {
1042  if (DDS::HANDLE_NIL == handle) {
1043  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_permissions_credential_token: Invalid permissions handle");
1044  return false;
1045  }
1046 
1048 
1049  ACPermsMap::iterator iter = local_ac_perms_.find(handle);
1050 
1051  if (iter != local_ac_perms_.end()) {
1052  permissions_credential_token = iter->second.perm->perm_cred_token_;
1053  return true;
1054  } else {
1055  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_permissions_credential_token: No PermissionToken found");
1056  return false;
1057  }
1058 }
1059 
1061  ::DDS::Security::AccessControlListener_ptr listener,
1063 {
1064  if (0 == listener) {
1065  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::set_listener: Invalid Listener pointer");
1066  return false;
1067  }
1068 
1070 
1071  listener_ptr_ = listener;
1072  return true;
1073 }
1074 
1078 {
1079  if (DDS::HANDLE_NIL == handle) {
1080  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::return_permissiosn_handle: Invalid permissions handle");
1081  return false;
1082  }
1083 
1084  ACPermsMap::iterator ac_iter = local_ac_perms_.find(handle);
1085 
1086  if (ac_iter == local_ac_perms_.end()) {
1087  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::return_permissions_handle: No matching permissions handle present");
1088  return false;
1089  }
1090 
1091  local_ac_perms_.erase(ac_iter);
1092  if (DCPS::security_debug.bookkeeping) {
1093  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
1094  ACE_TEXT("AccessControlBuiltInImpl::return_permissions_handle local_ac_perms_ (total %B)\n"),
1095  local_ac_perms_.size()));
1096  }
1097  make_task(local_rp_task_)->erase(handle);
1098  make_task(remote_rp_task_)->erase(handle);
1099 
1100  return true;
1101 }
1102 
1106 {
1107  ACE_UNUSED_ARG(token);
1108  ACE_UNUSED_ARG(ex);
1109 
1110  return true;
1111 }
1112 
1114  const ::DDS::Security::PermissionsCredentialToken & permissions_credential_token,
1116 {
1117  ACE_UNUSED_ARG(permissions_credential_token);
1118  ACE_UNUSED_ARG(ex);
1119 
1120  return true;
1121 }
1122 
1124  ::DDS::Security::PermissionsHandle permissions_handle,
1127 {
1128  if (DDS::HANDLE_NIL == permissions_handle) {
1129  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_participant_sec_attributes: Invalid permissions handle");
1130  return false;
1131  }
1132 
1134 
1135  ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
1136 
1137  if (ac_iter == local_ac_perms_.end()) {
1138  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_participant_sec_attributes: No matching permissions handle present");
1139  return false;
1140  }
1141 
1142  gov_iter begin = ac_iter->second.gov->access_rules().begin();
1143  gov_iter end = ac_iter->second.gov->access_rules().end();
1144 
1145  for (gov_iter giter = begin; giter != end; ++giter) {
1146 
1147  if (giter->domains.has(ac_iter->second.domain_id)) {
1148  attributes = giter->domain_attrs;
1149  return true;
1150  }
1151  }
1152 
1153  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_participant_sec_attributes: No matching domain in governance");
1154  return false;
1155 }
1156 
1158  ::DDS::Security::PermissionsHandle permissions_handle,
1159  const char * topic_name,
1162 {
1163  if (DDS::HANDLE_NIL == permissions_handle) {
1164  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_topic_sec_attributes: Invalid permissions handle");
1165  return false;
1166  }
1167  if (0 == topic_name) {
1168  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_topic_sec_attributes: Invalid topic name");
1169  return false;
1170  }
1171 
1172  // Extract Governance and the permissions data for the requested handle
1173 
1175 
1176  ACPermsMap::iterator piter = local_ac_perms_.find(permissions_handle);
1177 
1178  if (piter == local_ac_perms_.end()) {
1179  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_topic_sec_attributes: No matching permissions handle present");
1180  return false;
1181  }
1182 
1183  gov_iter begin = piter->second.gov->access_rules().begin();
1184  gov_iter end = piter->second.gov->access_rules().end();
1185 
1186  for (gov_iter giter = begin; giter != end; ++giter) {
1187 
1188  if (giter->domains.has(piter->second.domain_id)) {
1189  Governance::TopicAccessRules::iterator tr_iter;
1190 
1191  for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
1192  if (pattern_match(topic_name, tr_iter->topic_expression.c_str())) {
1193  attributes = tr_iter->topic_attrs;
1194  return true;
1195  }
1196  }
1197  }
1198  }
1199 
1200  CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::get_topic_sec_attributes: No matching domain/topic in governance");
1201  return false;
1202 }
1203 
1205  ::DDS::Security::PermissionsHandle permissions_handle,
1206  const char * topic_name,
1207  const ::DDS::PartitionQosPolicy & partition,
1211 {
1212  // The spec claims there is supposed to be a topic name parameter
1213  // to this function which is not in the IDL at this time
1214 
1215  if (DDS::HANDLE_NIL == permissions_handle) {
1216  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_datawriter_sec_attributes: Invalid permissions handle");
1217  return false;
1218  }
1219 
1220  if (0 == topic_name) {
1221  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_datawriter_sec_attributes: Invalid topic name");
1222  return false;
1223  }
1224 
1225  if (!get_sec_attributes(permissions_handle, topic_name, partition, data_tag, attributes, ex)) {
1226  return false;
1227  }
1228 
1229  return true;
1230 }
1231 
1233  ::DDS::Security::PermissionsHandle permissions_handle,
1234  const char * topic_name,
1235  const ::DDS::PartitionQosPolicy & partition,
1239 {
1240  if (DDS::HANDLE_NIL == permissions_handle) {
1241  CommonUtilities::set_security_error(ex, -1, 0, "Invalid permissions handle");
1242  return false;
1243  }
1244 
1245  if (0 == topic_name) {
1246  CommonUtilities::set_security_error(ex, -1, 0, "Invalid topic name");
1247  return false;
1248  }
1249 
1250  if (!get_sec_attributes(permissions_handle, topic_name, partition, data_tag, attributes, ex)) {
1251  return false;
1252  }
1253 
1254  return true;
1255 }
1256 
1258  const ::DDS::Security::ParticipantSecurityAttributes & attributes,
1260 {
1261  ACE_UNUSED_ARG(attributes);
1262  ACE_UNUSED_ARG(ex);
1263 
1264  return true;
1265 }
1266 
1268  const ::DDS::Security::EndpointSecurityAttributes & attributes,
1270 {
1271  ACE_UNUSED_ARG(attributes);
1272  ACE_UNUSED_ARG(ex);
1273 
1274  return true;
1275 }
1276 
1278  const ::DDS::Security::EndpointSecurityAttributes & attributes,
1280 {
1281  ACE_UNUSED_ARG(attributes);
1282  ACE_UNUSED_ARG(ex);
1283 
1284  return true;
1285 }
1286 
1288 {
1291 }
1292 
1295 {
1296  if (!task) {
1297  task = DCPS::make_rch<RevokePermissionsTask>(TheServiceParticipant->time_source(), TheServiceParticipant->interceptor(), DCPS::ref(*this));
1298  }
1299  return task;
1300 }
1301 
1303  const Permissions::Validity_t& validity,
1305 {
1306  if (validity.not_before == 0) {
1308  "AccessControlBuiltInImpl::validate_date_time: Permissions not_before time is invalid.");
1309  return false;
1310  }
1311 
1312  if (validity.not_after == 0) {
1314  "AccessControlBuiltInImpl::validate_date_time: Permissions not_after time is invalid.");
1315  return false;
1316  }
1317 
1318  // Get the current time as UTC
1319  const time_t now = std::time(0);
1320  std::tm* const now_utc_tm = std::gmtime(&now);
1321  const time_t now_utc = std::mktime(now_utc_tm);
1322 
1323  if (now_utc < validity.not_before) {
1325  "AccessControlBuiltInImpl::validate_date_time: Permissions grant hasn't started yet.");
1326  return false;
1327  }
1328 
1329  if (now_utc > validity.not_after) {
1331  "AccessControlBuiltInImpl::validate_date_time: Permissions grant has expired.");
1332  return false;
1333  }
1334 
1335  return true;
1336 }
1337 
1339  const char * topic_name,
1340  const::DDS::PartitionQosPolicy & /*partition*/,
1344 {
1346 
1347  const ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
1348  if (ac_iter == local_ac_perms_.end()) {
1349  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_datawriter_sec_attributes: No matching permissions handle present");
1350  return false;
1351  }
1352 
1353  const gov_iter begin = ac_iter->second.gov->access_rules().begin();
1354  const gov_iter end = ac_iter->second.gov->access_rules().end();
1355  for (gov_iter giter = begin; giter != end; ++giter) {
1356  if (giter->domains.has(ac_iter->second.domain_id)) {
1357  if (std::strcmp(topic_name, "DCPSParticipantVolatileMessageSecure") == 0) {
1358  attributes.base.is_write_protected = false;
1359  attributes.base.is_read_protected = false;
1360  attributes.base.is_liveliness_protected = false;
1361  attributes.base.is_discovery_protected = false;
1362  attributes.is_submessage_protected = true;
1363  attributes.is_payload_protected = false;
1364  attributes.is_key_protected = false;
1365  return true;
1366  }
1367 
1368  if (std::strcmp(topic_name, "DCPSParticipantStatelessMessage") == 0) {
1369  attributes.base.is_write_protected = false;
1370  attributes.base.is_read_protected = false;
1371  attributes.base.is_liveliness_protected = false;
1372  attributes.base.is_discovery_protected = false;
1373  attributes.is_submessage_protected = false;
1374  attributes.is_payload_protected = false;
1375  attributes.is_key_protected = false;
1376  return true;
1377  }
1378 
1379  if (std::strcmp(topic_name, "DCPSParticipantMessageSecure") == 0) {
1380  attributes.base.is_write_protected = false;
1381  attributes.base.is_read_protected = false;
1382  attributes.base.is_liveliness_protected = false;
1383  attributes.base.is_discovery_protected = false;
1384  attributes.is_submessage_protected = giter->domain_attrs.is_liveliness_protected;
1385  attributes.is_payload_protected = false;
1386  attributes.is_key_protected = false;
1387 
1388  if (giter->domain_attrs.plugin_participant_attributes & ::DDS::Security::PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ENCRYPTED) {
1390  }
1391 
1392  if (giter->domain_attrs.plugin_participant_attributes & ::DDS::Security::PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ORIGIN_AUTHENTICATED) {
1394  }
1395 
1396  return true;
1397  }
1398 
1399  if (std::strcmp(topic_name, "DCPSParticipantSecure") == 0 ||
1400  std::strcmp(topic_name, "DCPSPublicationsSecure") == 0 ||
1401  std::strcmp(topic_name, "DCPSSubscriptionsSecure") == 0 ||
1402  std::strcmp(topic_name, "TypeLookupServiceRequestSecure") == 0 ||
1403  std::strcmp(topic_name, "TypeLookupServiceReplySecure") == 0) {
1404  attributes.base.is_write_protected = false;
1405  attributes.base.is_read_protected = false;
1406  attributes.base.is_liveliness_protected = false;
1407  attributes.base.is_discovery_protected = false;
1408  attributes.is_submessage_protected = giter->domain_attrs.is_discovery_protected;
1409  attributes.is_payload_protected = false;
1410  attributes.is_key_protected = false;
1411 
1412  if (giter->domain_attrs.plugin_participant_attributes & ::DDS::Security::PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_BUILTIN_IS_DISCOVERY_ENCRYPTED) {
1414  }
1415 
1416  if (giter->domain_attrs.plugin_participant_attributes & ::DDS::Security::PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_ORIGIN_AUTHENTICATED) {
1418  }
1419 
1420  return true;
1421  }
1422 
1423  Governance::TopicAccessRules::iterator tr_iter;
1424 
1425  for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
1426  if (pattern_match(topic_name, tr_iter->topic_expression.c_str())) {
1427 
1428  // Process the TopicSecurityAttributes base
1429  attributes.base.is_write_protected = tr_iter->topic_attrs.is_write_protected;
1430  attributes.base.is_read_protected = tr_iter->topic_attrs.is_read_protected;
1431  attributes.base.is_liveliness_protected = tr_iter->topic_attrs.is_liveliness_protected;
1432  attributes.base.is_discovery_protected = tr_iter->topic_attrs.is_discovery_protected;
1433 
1434  // Process metadata protection attributes
1435  if (tr_iter->metadata_protection_kind == "NONE") {
1436  attributes.is_submessage_protected = false;
1437  }
1438  else {
1439  attributes.is_submessage_protected = true;
1440 
1441  if (tr_iter->metadata_protection_kind == "ENCRYPT" ||
1442  tr_iter->metadata_protection_kind == "ENCRYPT_WITH_ORIGIN_AUTHENTICATION") {
1444  }
1445 
1446  if (tr_iter->metadata_protection_kind == "SIGN_WITH_ORIGIN_AUTHENTICATION" ||
1447  tr_iter->metadata_protection_kind == "ENCRYPT_WITH_ORIGIN_AUTHENTICATION") {
1449  }
1450  }
1451 
1452  // Process data protection attributes
1453 
1454  if (tr_iter->data_protection_kind == "NONE") {
1455  attributes.is_payload_protected = false;
1456  attributes.is_key_protected = false;
1457  }
1458  else if (tr_iter->data_protection_kind == "SIGN") {
1459  attributes.is_payload_protected = true;
1460  attributes.is_key_protected = false;
1461  }
1462  else if (tr_iter->data_protection_kind == "ENCRYPT") {
1463  attributes.is_payload_protected = true;
1464  attributes.is_key_protected = true;
1466  }
1467 
1468  return true;
1469  }
1470  }
1471  }
1472  }
1473 
1474  CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_sec_attributes: Invalid topic name");
1475  return false;
1476 }
1477 
1479  const char* topic_name,
1480  const DDS::Security::DomainId_t domain_id,
1481  const DDS::PartitionQosPolicy& partition,
1482  const Permissions::PublishSubscribe_t pub_or_sub,
1483  const Permissions::Grant& grant,
1485 {
1486  for (Permissions::Rules::const_iterator rit = grant.rules.begin(); rit != grant.rules.end(); ++rit) {
1487  if (rit->domains.has(domain_id)) {
1488  for (Permissions::Actions::const_iterator ait = rit->actions.begin(); ait != rit->actions.end(); ++ait) {
1489  if (ait->ps_type == pub_or_sub &&
1490  ait->topic_matches(topic_name) &&
1491  ait->partitions_match(partition.name, rit->ad_type)) {
1492  if (rit->ad_type == Permissions::ALLOW) {
1493  return true;
1494  } else {
1495  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl: DENY rule matched");
1496  }
1497  }
1498  }
1499  }
1500  }
1501 
1502  if (grant.default_permission == Permissions::ALLOW) {
1503  return true;
1504  } else {
1505  return CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl: No matching rule for topic, default permission is DENY.");
1506  }
1507 }
1508 
1510  const std::string& class_id,
1511  std::string & plugin_class_name,
1512  int & major_version,
1513  int & minor_version)
1514 {
1515  const std::string delimiter = ":";
1516 
1517  major_version = 1;
1518  minor_version = 0;
1519 
1520  size_t pos = class_id.find_last_of(delimiter);
1521 
1522  if ((pos > 0UL) && (pos != class_id.length() - 1)) {
1523  plugin_class_name = class_id.substr(0, (pos - 1));
1524 
1525  const std::string period = ".";
1526 
1527  size_t period_pos = class_id.find_last_of(period);
1528 
1529  if (period_pos > 0UL) {
1530  std::string mv_string = class_id.substr((pos + 1), (period_pos - 1));
1531 
1532  major_version = atoi(mv_string.c_str());
1533 
1534  if (period_pos != class_id.length() - 1) {
1535  mv_string = class_id.substr((period_pos + 1), (class_id.length() - 1));
1536  minor_version = atoi(mv_string.c_str());
1537  }
1538  }
1539  }
1540  else {
1541  plugin_class_name.clear();
1542  }
1543 
1544 }
1545 
1547  DCPS::ReactorInterceptor_rch interceptor,
1549  : SporadicTask(time_source, interceptor)
1550  , impl_(impl)
1551 { }
1552 
1554 {
1555  if (DCPS::security_debug.bookkeeping) {
1556  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
1557  ACE_TEXT("AccessControlBuiltInImpl::RevokePermissionsTask::~RevokePermissionsTask %@ handle_to_expiration_ %B expiration_to_handle_ %B\n"),
1558  this,
1559  handle_to_expiration_.size(),
1560  expiration_to_handle_.size()));
1561  }
1562 }
1563 
1564 namespace {
1565  // Some platforms cannot schedule timers far enough into the future
1566  // to accommodate expiration times so the scheduling interval is
1567  // capped at an hour.
1568  const TimeDuration MAX_DURATION = TimeDuration(3600, 0);
1569 }
1570 
1571 void
1573  const time_t& expiration)
1574 {
1575  ACE_GUARD(ACE_Thread_Mutex, guard, lock_);
1576 
1577  if (handle_to_expiration_.count(pm_handle)) {
1578  return;
1579  }
1580 
1581  const time_t current_date_time = time(0);
1582  tm* current_time_tm = gmtime(&current_date_time);
1583  const time_t cur_utc_time = mktime(current_time_tm);
1584  const TimeDuration duration = std::min(TimeDuration(expiration - cur_utc_time), MAX_DURATION);
1585 
1586  const bool empty_before = expiration_to_handle_.empty();
1587 
1588  handle_to_expiration_[pm_handle] = expiration;
1589 
1590  if (DCPS::security_debug.bookkeeping) {
1591  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
1592  ACE_TEXT("AccessControlBuiltInImpl::RevokePermissionsTask::insert handle_to_expiration_ (total %B)\n"),
1593  handle_to_expiration_.size()));
1594  }
1595 
1596  ExpirationToHandle::const_iterator pos =
1597  expiration_to_handle_.insert(ExpirationToHandle::value_type(expiration, pm_handle));
1598 
1599  if (DCPS::security_debug.bookkeeping) {
1600  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
1601  ACE_TEXT("AccessControlBuiltInImpl::RevokePermissionsTask::insert expiration_to_handle_ (total %B)\n"),
1602  expiration_to_handle_.size()));
1603  }
1604 
1605  if (!empty_before && pos == expiration_to_handle_.begin()) {
1606  cancel();
1607  }
1608 
1609  if (pos == expiration_to_handle_.begin()) {
1610  schedule(duration);
1611  }
1612 }
1613 
1614 void
1616 {
1617  ACE_GUARD(ACE_Thread_Mutex, guard, lock_);
1618 
1619  HandleToExpiration::iterator iter = handle_to_expiration_.find(pm_handle);
1620  if (iter == handle_to_expiration_.end()) {
1621  return;
1622  }
1623 
1624  const time_t expiration = iter->second;
1625 
1626  std::pair<ExpirationToHandle::iterator, ExpirationToHandle::iterator> er =
1627  expiration_to_handle_.equal_range(expiration);
1628  while (er.first != er.second) {
1629  if (er.first->second == pm_handle) {
1630  expiration_to_handle_.erase(er.first++);
1631  if (DCPS::security_debug.bookkeeping) {
1632  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
1633  ACE_TEXT("AccessControlBuiltInImpl::RevokePermissionsTask::erase expiration_to_handle_ (total %B)\n"),
1634  expiration_to_handle_.size()));
1635  }
1636  } else {
1637  ++er.first;
1638  }
1639  }
1640 
1641  handle_to_expiration_.erase(pm_handle);
1642  if (DCPS::security_debug.bookkeeping) {
1643  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
1644  ACE_TEXT("AccessControlBuiltInImpl::RevokePermissionsTask::execute handle_to_expiration_ (total %B)\n"),
1645  handle_to_expiration_.size()));
1646  }
1647 }
1648 
1649 void
1651 {
1652  ACE_GUARD(ACE_Thread_Mutex, guard, lock_);
1653 
1654  const time_t current_date_time = time(0);
1655  tm* current_time_tm = gmtime(&current_date_time);
1656  const time_t cur_utc_time = mktime(current_time_tm);
1657 
1658  for (ExpirationToHandle::iterator pos = expiration_to_handle_.begin(), limit = expiration_to_handle_.end();
1659  pos != limit && pos->first < cur_utc_time;) {
1660  const ::DDS::Security::PermissionsHandle pm_handle = pos->second;
1661  ACPermsMap::iterator iter = impl_.local_ac_perms_.find(pm_handle);
1662  if (iter == impl_.local_ac_perms_.end()) {
1663  ACE_DEBUG((LM_ERROR, ACE_TEXT("(%P|%t) AccessControlBuiltInImpl::Revoke_Permissions_Timer::execute: ")
1664  ACE_TEXT("pm_handle %d not found!\n"), pm_handle));
1665  }
1666  impl_.local_ac_perms_.erase(iter);
1667  if (DCPS::security_debug.bookkeeping) {
1668  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
1669  ACE_TEXT("AccessControlBuiltInImpl::RevokePermissionsTask::execute local_ac_perms_ (total %B)\n"),
1670  impl_.local_ac_perms_.size()));
1671  }
1672 
1673  // If a listener exists, call on_revoke_permissions
1674  if (impl_.listener_ptr_ && !impl_.listener_ptr_->on_revoke_permissions(&impl_, pm_handle)) {
1675  ACE_DEBUG((LM_ERROR, ACE_TEXT("(%P|%t) AccessControlBuiltInImpl::Revoke_Permissions_Timer::execute: ")
1676  ACE_TEXT("on_revoke_permissions failed for pm_handle %d!\n"), pm_handle));
1677  }
1678 
1681  ACE_TEXT("(%P|%t) AccessControlBuiltInImpl::Revoke_Permissions_Timer::execute: Completed...\n")));
1682  }
1683 
1684  handle_to_expiration_.erase(pm_handle);
1685  if (DCPS::security_debug.bookkeeping) {
1686  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
1687  ACE_TEXT("AccessControlBuiltInImpl::RevokePermissionsTask::execute handle_to_expiration_ (total %B)\n"),
1688  handle_to_expiration_.size()));
1689  }
1690 
1691  expiration_to_handle_.erase(pos++);
1692  if (DCPS::security_debug.bookkeeping) {
1693  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) {bookkeeping} ")
1694  ACE_TEXT("AccessControlBuiltInImpl::RevokePermissionsTask::execute expiration_to_handle_ (total %B)\n"),
1695  expiration_to_handle_.size()));
1696  }
1697  }
1698 
1699  if (!expiration_to_handle_.empty()) {
1700  const TimeDuration duration = std::min(TimeDuration(expiration_to_handle_.begin()->first - cur_utc_time), MAX_DURATION);
1701  schedule(duration);
1702  }
1703 }
1704 
1707 {
1709 
1710  ACPermsMap::const_iterator pos = local_ac_perms_.find(permissions_handle);
1711  if (pos != local_ac_perms_.end()) {
1712  return pos->second.subject;
1713  }
1714 
1715  return SSL::SubjectName();
1716 }
1717 
1718 } // namespace Security
1719 } // namespace OpenDDS
1720 
virtual bool get_permissions_credential_token(DDS::Security::PermissionsCredentialToken &permissions_credential_token, DDS::Security::PermissionsHandle handle, DDS::Security::SecurityException &ex)
#define ACE_DEBUG(X)
virtual bool return_permissions_credential_token(const DDS::Security::PermissionsCredentialToken &permissions_credential_token, DDS::Security::SecurityException &ex)
ACE_CDR::Long Long
RevokePermissionsTask_rch & make_task(RevokePermissionsTask_rch &task)
#define ACE_GUARD(MUTEX, OBJ, LOCK)
Implements some simple wrapper functions to provide a const API around the Token data structure as sp...
Definition: TokenReader.h:40
const InstanceHandle_t HANDLE_NIL
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_ORIGIN_AUTHENTICATED
RevokePermissionsTask(const DCPS::TimeSource &time_source, DCPS::ReactorInterceptor_rch interceptor, AccessControlBuiltInImpl &impl)
bool validate_date_time(const Permissions::Validity_t &validity, DDS::Security::SecurityException &ex)
virtual bool check_local_datawriter_match(DDS::Security::PermissionsHandle writer_permissions_handle, DDS::Security::PermissionsHandle reader_permissions_handle, const DDS::Security::PublicationBuiltinTopicDataSecure &publication_data, const DDS::Security::SubscriptionBuiltinTopicDataSecure &subscription_data, DDS::Security::SecurityException &ex)
static const std::string PermissionsTokenClassId("DDS:Access:Permissions:1.0")
time_t time(time_t *tloc=0)
virtual bool return_datareader_sec_attributes(const DDS::Security::EndpointSecurityAttributes &attributes, DDS::Security::SecurityException &ex)
virtual bool check_local_datawriter_register_instance(DDS::Security::PermissionsHandle permissions_handle, DDS::DataWriter_ptr writer, DDS::DynamicData_ptr key, DDS::Security::SecurityException &ex)
sequence< octet > key
virtual bool set_listener(DDS::Security::AccessControlListener_ptr listener, DDS::Security::SecurityException &ex)
virtual bool return_permissions_token(const DDS::Security::PermissionsToken &token, DDS::Security::SecurityException &ex)
virtual bool get_datareader_sec_attributes(DDS::Security::PermissionsHandle permissions_handle, const char *topic_name, const DDS::PartitionQosPolicy &partition, const DDS::Security::DataTagQosPolicy &data_tag, DDS::Security::EndpointSecurityAttributes &attributes, DDS::Security::SecurityException &ex)
DDS::DomainId_t DomainId_t
virtual bool check_local_datawriter_dispose_instance(DDS::Security::PermissionsHandle permissions_handle, DDS::DataWriter_ptr writer, DDS::DynamicData_ptr key, DDS::Security::SecurityException &ex)
static const std::string AccessControl_Major_Version("1")
virtual bool check_remote_datawriter(DDS::Security::PermissionsHandle permissions_handle, DDS::Security::DomainId_t domain_id, const DDS::Security::PublicationBuiltinTopicDataSecure &publication_data, DDS::Security::SecurityException &ex)
void insert(DDS::Security::PermissionsHandle pm_handle, const time_t &expiration)
static const std::string PermissionsCredentialTokenClassId("DDS:Access:PermissionsCredential")
virtual bool check_local_datareader_match(DDS::Security::PermissionsHandle reader_permissions_handle, DDS::Security::PermissionsHandle writer_permissions_handle, const DDS::Security::SubscriptionBuiltinTopicDataSecure &subscription_data, const DDS::Security::PublicationBuiltinTopicDataSecure &publication_data, DDS::Security::SecurityException &ex)
virtual bool get_datawriter_sec_attributes(DDS::Security::PermissionsHandle permissions_handle, const char *topic_name, const DDS::PartitionQosPolicy &partition, const DDS::Security::DataTagQosPolicy &data_tag, DDS::Security::EndpointSecurityAttributes &attributes, DDS::Security::SecurityException &ex)
virtual DDS::Security::PermissionsHandle validate_local_permissions(DDS::Security::Authentication_ptr auth_plugin, DDS::Security::IdentityHandle identity, DDS::Security::DomainId_t domain_id, const DDS::DomainParticipantQos &participant_qos, DDS::Security::SecurityException &ex)
reference_wrapper< T > ref(T &r)
Definition: RcHandle_T.h:237
static bool pattern_match(const char *string, const char *pattern)
void schedule(const TimeDuration &delay)
Definition: SporadicTask.h:36
virtual bool check_remote_participant(DDS::Security::PermissionsHandle permissions_handle, DDS::Security::DomainId_t domain_id, const DDS::Security::ParticipantBuiltinTopicDataSecure &participant_data, DDS::Security::SecurityException &ex)
PluginEndpointSecurityAttributesMask plugin_endpoint_attributes
LM_DEBUG
Implements the DDS built-in version of the Access Control plugin for the DDS Security Specification...
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ENCRYPTED
const PluginEndpointSecurityAttributesMask PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED
virtual bool get_topic_sec_attributes(DDS::Security::PermissionsHandle permissions_handle, const char *topic_name, DDS::Security::TopicSecurityAttributes &attributes, DDS::Security::SecurityException &ex)
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_BUILTIN_IS_DISCOVERY_ENCRYPTED
struct tm * gmtime(const time_t *clock)
virtual bool check_remote_datawriter_register_instance(DDS::Security::PermissionsHandle permissions_handle, DDS::DataReader_ptr reader, DDS::InstanceHandle_t publication_handle, DDS::DynamicData_ptr key, DDS::Security::SecurityException &ex)
ACE_CDR::Boolean Boolean
#define ACE_GUARD_RETURN(MUTEX, OBJ, LOCK, RETURN)
virtual bool check_remote_datawriter_dispose_instance(DDS::Security::PermissionsHandle permissions_handle, DDS::DataReader_ptr reader, DDS::InstanceHandle_t publication_handle, DDS::DynamicData_ptr key, DDS::Security::SecurityException &ex)
virtual bool return_permissions_handle(DDS::Security::PermissionsHandle handle, DDS::Security::SecurityException &ex)
virtual bool check_create_datareader(DDS::Security::PermissionsHandle permissions_handle, DDS::Security::DomainId_t domain_id, const char *topic_name, const DDS::DataReaderQos &qos, const DDS::PartitionQosPolicy &partition, const DDS::Security::DataTags &data_tag, DDS::Security::SecurityException &ex)
virtual bool check_create_topic(DDS::Security::PermissionsHandle permissions_handle, DDS::Security::DomainId_t domain_id, const char *topic_name, const DDS::TopicQos &qos, DDS::Security::SecurityException &ex)
void add_property(const char *prop_name, const char *prop_value, bool propagate=true)
Definition: TokenWriter.cpp:38
sequence< octet > OctetSeq
Definition: DdsDcpsCore.idl:64
const char * get_property_value(const std::string &property_name) const
Definition: TokenReader.cpp:42
virtual bool return_participant_sec_attributes(const DDS::Security::ParticipantSecurityAttributes &attributes, DDS::Security::SecurityException &ex)
DataTags DataTagQosPolicy
int strcmp(const char *s, const char *t)
const DDS::OctetSeq & get_bin_property_value(const std::string &property_name) const
Definition: TokenReader.cpp:59
HANDLE_TYPE_NATIVE InstanceHandle_t
Definition: DdsDcpsCore.idl:51
ACE_TEXT("TCP_Factory")
int atoi(const char *s)
virtual bool get_participant_sec_attributes(DDS::Security::PermissionsHandle permissions_handle, DDS::Security::ParticipantSecurityAttributes &attributes, DDS::Security::SecurityException &ex)
DDS::Security::AccessControlListener_ptr listener_ptr_
virtual bool check_create_participant(DDS::Security::PermissionsHandle permissions_handle, DDS::Security::DomainId_t domain_id, const DDS::DomainParticipantQos &qos, DDS::Security::SecurityException &ex)
Governance::GovernanceAccessRules::iterator gov_iter
virtual DDS::Security::PermissionsHandle validate_remote_permissions(DDS::Security::Authentication_ptr auth_plugin, DDS::Security::IdentityHandle local_identity_handle, DDS::Security::IdentityHandle remote_identity_handle, const DDS::Security::PermissionsToken &remote_permissions_token, const DDS::Security::AuthenticatedPeerCredentialToken &remote_credential_token, DDS::Security::SecurityException &ex)
OpenDDS_Dcps_Export unsigned int DCPS_debug_level
Definition: debug.cpp:30
static const std::string AccessControl_Plugin_Name("DDS:Access:Permissions")
static const std::string AccessControl_Minor_Version("0")
virtual bool return_datawriter_sec_attributes(const DDS::Security::EndpointSecurityAttributes &attributes, DDS::Security::SecurityException &ex)
void parse_class_id(const std::string &class_id, std::string &plugin_class_name, int &major_version, int &minor_version)
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ORIGIN_AUTHENTICATED
const DDS::OctetSeq & original() const
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
Permissions::Actions::iterator perm_topic_actions_iter
virtual bool check_remote_topic(DDS::Security::PermissionsHandle permissions_handle, DDS::Security::DomainId_t domain_id, const DDS::TopicBuiltinTopicData &topic_data, DDS::Security::SecurityException &ex)
int subject_name_to_str(std::string &dst, unsigned long flags=XN_FLAG_ONELINE) const
virtual bool check_create_datawriter(DDS::Security::PermissionsHandle permissions_handle, DDS::Security::DomainId_t domain_id, const char *topic_name, const DDS::DataWriterQos &qos, const DDS::PartitionQosPolicy &partition, const DDS::Security::DataTags &data_tag, DDS::Security::SecurityException &ex)
time_t mktime(struct tm *timeptr)
Permissions::Grants::iterator grant_iter
int parse(const char *, bool permissive=false)
Definition: SubjectName.cpp:28
bool get_sec_attributes(DDS::Security::PermissionsHandle permissions_handle, const char *topic_name, const DDS::PartitionQosPolicy &partition, const DDS::Security::DataTagQosPolicy &data_tag, DDS::Security::EndpointSecurityAttributes &attributes, DDS::Security::SecurityException &ex)
Token PermissionsCredentialToken
LocalAccessCredentialData::shared_ptr local_access_credential_data
virtual bool get_permissions_token(DDS::Security::PermissionsToken &permissions_token, DDS::Security::PermissionsHandle handle, DDS::Security::SecurityException &ex)
Permissions::Rules::iterator perm_topic_rules_iter
bool set_security_error(DDS::Security::SecurityException &ex, int code, int minor_code, const char *message)
#define TheServiceParticipant
LM_ERROR
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
bool wild_match(const char *s, const char *pattern, bool case_sensitive=true, bool character_classes=false)
Token AuthenticatedPeerCredentialToken
Implements some simple wrapper functions to provide a non-const API around the Token data structure a...
Definition: TokenWriter.h:43
OpenDDS_Dcps_Export SecurityDebug security_debug
Definition: debug.cpp:32
const PluginEndpointSecurityAttributesMask PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED
SSL::SubjectName get_subject_name(DDS::Security::PermissionsHandle permissions_handle) const
virtual bool check_remote_datareader(DDS::Security::PermissionsHandle permissions_handle, DDS::Security::DomainId_t domain_id, const DDS::Security::SubscriptionBuiltinTopicDataSecure &subscription_data, bool &relay_only, DDS::Security::SecurityException &ex)
const PluginEndpointSecurityAttributesMask PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED
bool search_permissions(const char *topic_name, DDS::Security::DomainId_t domain_id, const DDS::PartitionQosPolicy &partition, Permissions::PublishSubscribe_t pub_or_sub, const Permissions::Grant &grant, DDS::Security::SecurityException &ex)