AccessControlBuiltInImpl.cpp

Go to the documentation of this file.
00001 /*
00002 *
00003 *
00004 * Distributed under the OpenDDS License.
00005 * See: http://www.opendds.org/license.html
00006 */
00007 
00008 #include "dds/DCPS/security/AccessControlBuiltInImpl.h"
00009 #include "dds/DCPS/security/CommonUtilities.h"
00010 #include "dds/DdsDcpsInfrastructureC.h"
00011 #include "ace/config-macros.h"
00012 #include "ace/OS_NS_strings.h"
00013 #include "dds/DCPS/security/TokenWriter.h"
00014 #include "SSL/SubjectName.h"
00015 #include "dds/DCPS/Service_Participant.h"
00016 #include "ace/Reactor.h"
00017 #include "tao/debug.h"
00018 
00019 #include "AccessControlBuiltInImpl.h"
00020 
00021 #include <time.h>
00022 
00023 #include <fstream>
00024 #include <sstream>
00025 #include <iostream>
00026 #include <stdexcept>
00027 #include <iterator>
00028 #include <cstring>
00029 #include <iomanip>
00030 
00031 
00032 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00033 
00034 namespace OpenDDS {
00035 namespace Security {
00036 
00037 typedef Governance::GovernanceAccessRules::iterator gov_iter;
00038 typedef Permissions::PermissionGrantRules::iterator perm_grant_iter;
00039 typedef Permissions::TopicRules::iterator perm_topic_rules_iter;
00040 typedef Permissions::Partitions::iterator perm_partitions_iter;
00041 typedef Permissions::TopicPsRules::iterator perm_topic_ps_rules_iter;
00042 typedef Permissions::PartitionPsList::iterator perm_partition_ps_iter;
00043 
00044 static const std::string PermissionsTokenClassId("DDS:Access:Permissions:1.0");
00045 static const std::string AccessControl_Plugin_Name("DDS:Access:Permissions");
00046 static const std::string AccessControl_Major_Version("1");
00047 static const std::string AccessControl_Minor_Version("0");
00048 
00049 static const std::string PermissionsCredentialTokenClassId("DDS:Access:PermissionsCredential");
00050 
00051 
00052 
00053 AccessControlBuiltInImpl::AccessControlBuiltInImpl()
00054   : local_rp_timer_(*this)
00055   , remote_rp_timer_(*this)
00056   , handle_mutex_()
00057   , gen_handle_mutex_()
00058   , next_handle_(1)
00059   , listener_ptr_(NULL)
00060 {  }
00061 
00062 AccessControlBuiltInImpl::~AccessControlBuiltInImpl()
00063 {
00064 }
00065 
00066 ::DDS::Security::PermissionsHandle AccessControlBuiltInImpl::validate_local_permissions(
00067   ::DDS::Security::Authentication_ptr auth_plugin,
00068   ::DDS::Security::IdentityHandle identity,
00069   ::DDS::Security::DomainId_t domain_id,
00070   const ::DDS::DomainParticipantQos & participant_qos,
00071   ::DDS::Security::SecurityException & ex)
00072 {
00073   if (0 == auth_plugin) {
00074     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Null Authentication plugin");
00075     return DDS::HANDLE_NIL;
00076   }
00077 
00078   if (DDS::HANDLE_NIL == identity) {
00079     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Invalid identity");
00080     return DDS::HANDLE_NIL;
00081   }
00082 
00083   DDS::Security::IdentityToken id_token;
00084 
00085   if (auth_plugin->get_identity_token(id_token, identity, ex) == false) {
00086     return DDS::HANDLE_NIL;
00087   }
00088 
00089   LocalAccessCredentialData::shared_ptr local_access_credential_data = DCPS::make_rch<LocalAccessCredentialData>();
00090 
00091   if (! local_access_credential_data->load(participant_qos.property.value, ex)) {
00092     return DDS::HANDLE_NIL;
00093   }
00094 
00095   const SSL::Certificate& local_ca = local_access_credential_data->get_ca_cert();
00096   const SSL::SignedDocument& local_gov = local_access_credential_data->get_governance_doc();
00097 
00098   int err = local_gov.verify_signature(local_ca);
00099   if (err) {
00100     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Governance signature not verified");
00101     return DDS::HANDLE_NIL;
00102   }
00103 
00104   Governance::shared_ptr governance = DCPS::make_rch<Governance>();
00105 
00106   err = governance->load(local_gov);
00107   if (err) {
00108     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Invalid governance file");
00109     return DDS::HANDLE_NIL;
00110   }
00111 
00112   const SSL::SignedDocument& local_perm = local_access_credential_data->get_permissions_doc();
00113   Permissions::shared_ptr permissions = DCPS::make_rch<Permissions>();
00114 
00115   err = permissions->load(local_perm);
00116   if (err) {
00117     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Invalid permission file");
00118     return DDS::HANDLE_NIL;
00119   }
00120 
00121   // Compare the subject name for validation
00122 
00123   TokenReader tr(id_token);
00124   const char* id_sn = tr.get_property_value("dds.cert.sn");
00125 
00126   OpenDDS::Security::SSL::SubjectName sn_id;
00127   OpenDDS::Security::SSL::SubjectName sn_perm;
00128 
00129   const std::string& perm_sn = permissions->subject_name();
00130 
00131   if (id_sn == NULL || perm_sn.empty() ||
00132       sn_id.parse(id_sn) != 0 ||
00133       sn_perm.parse(perm_sn, true) != 0 ||
00134       sn_id != sn_perm) {
00135     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Permissions subject name does not match identity subject name");
00136     return DDS::HANDLE_NIL;
00137   }
00138 
00139   // Verify signature of permissions file
00140   err = local_perm.verify_signature(local_ca);
00141   if (err) {
00142     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_local_permissions: Permissions signature not verified");
00143     return DDS::HANDLE_NIL;
00144   } else {
00145     if (OpenDDS::DCPS::DCPS_debug_level > 0) {
00146       ACE_DEBUG((LM_DEBUG, ACE_TEXT(
00147         "(%P|%t) AccessControlBuiltInImpl::validate_local_permissions: Permissions document verified.\n")));
00148     }
00149   }
00150 
00151   // Set and store the permissions credential token while we have the raw content
00152   DDS::Security::PermissionsCredentialToken permissions_cred_token;
00153   TokenWriter pctWriter(permissions_cred_token, PermissionsCredentialTokenClassId);
00154 
00155   pctWriter.add_property("dds.perm.cert", local_perm.get_original());
00156 
00157   // Set and store the permissions token
00158   DDS::Security::PermissionsToken permissions_token;
00159   TokenWriter writer(permissions_token, PermissionsTokenClassId);
00160 
00161   // If all checks are successful load the content into cache
00162   Permissions::AcPerms& perm_data = permissions->data();
00163   perm_data.domain_id = domain_id;
00164   perm_data.perm_token = permissions_token;
00165   perm_data.perm_cred_token = permissions_cred_token;
00166 
00167   ::CORBA::Long perm_handle = generate_handle();
00168 
00169   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, 0);
00170 
00171   AccessData cache_this;
00172   cache_this.perm = permissions;
00173   cache_this.gov = governance;
00174   cache_this.local_access_credential_data = local_access_credential_data;
00175 
00176   local_ac_perms_.insert(std::make_pair(perm_handle, cache_this));
00177   local_identity_map_.insert(std::make_pair(identity, perm_handle));
00178 
00179   return perm_handle;
00180 }
00181 
00182 ::DDS::Security::PermissionsHandle AccessControlBuiltInImpl::validate_remote_permissions(
00183   ::DDS::Security::Authentication_ptr auth_plugin,
00184   ::DDS::Security::IdentityHandle local_identity_handle,
00185   ::DDS::Security::IdentityHandle /*remote_identity_handle*/,
00186   const ::DDS::Security::PermissionsToken & remote_permissions_token,
00187   const ::DDS::Security::AuthenticatedPeerCredentialToken & remote_credential_token,
00188   ::DDS::Security::SecurityException & ex)
00189 {
00190   if (0 == auth_plugin) {
00191     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Null Authentication plugin");
00192     return DDS::HANDLE_NIL;
00193   }
00194 
00195   if (DDS::HANDLE_NIL == local_identity_handle) {
00196     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Invalid Local Identity");
00197     return DDS::HANDLE_NIL;
00198   }
00199 
00200   ACIdentityMap::iterator iter = local_identity_map_.find(local_identity_handle);
00201 
00202   if (iter == local_identity_map_.end()) {
00203     CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: No matching local identity handle present");
00204     return DDS::HANDLE_NIL;
00205   }
00206 
00207   // Extract Governance and domain id data for new permissions entry
00208   ::DDS::Security::PermissionsHandle local_ph = iter->second;
00209 
00210   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, 0);
00211 
00212   ACPermsMap::iterator piter = local_ac_perms_.find(local_ph);
00213 
00214   if (piter == local_ac_perms_.end()) {
00215     CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: No matching local permissions handle present");
00216     return DDS::HANDLE_NIL;
00217   }
00218 
00219   // permissions file
00220   OpenDDS::Security::TokenReader remote_perm_wrapper(remote_credential_token);
00221   SSL::SignedDocument remote_perm_doc;
00222 
00223   int err = remote_perm_doc.deserialize(remote_perm_wrapper.get_bin_property_value("c.perm"));
00224   if (err)
00225   {
00226     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Failed to deserialize c.perm into signed-document");
00227     return DDS::HANDLE_NIL;
00228   }
00229 
00230   Permissions::shared_ptr permissions = DCPS::make_rch<Permissions>();
00231 
00232   err = permissions->load(remote_perm_doc);
00233   if (err)
00234   {
00235     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Invalid permission file");
00236     return DDS::HANDLE_NIL;
00237   }
00238 
00239   const LocalAccessCredentialData::shared_ptr& local_access_credential_data = piter->second.local_access_credential_data;
00240 
00241   // Validate the signature of the remote permissions
00242   const SSL::Certificate& local_ca = local_access_credential_data->get_ca_cert();
00243   std::string ca_subject;
00244 
00245   local_ca.subject_name_to_str(ca_subject);
00246 
00247   err = remote_perm_doc.verify_signature(local_ca);
00248   if (err) {
00249     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Remote permissions signature not verified");
00250     return DDS::HANDLE_NIL;
00251   }
00252 
00253   // The remote permissions signature is verified
00254   if (OpenDDS::DCPS::DCPS_debug_level > 0) {
00255     ACE_DEBUG((LM_DEBUG, ACE_TEXT(
00256       "(%P|%t) AccessControlBuiltInImpl::validate_remote_permissions: Remote permissions document verified.\n")));
00257   }
00258 
00259   //Extract and compare the remote subject name for validation
00260   TokenReader remote_credential_tr(remote_credential_token);
00261   const DDS::OctetSeq& cid = remote_credential_tr.get_bin_property_value("c.id");
00262 
00263   if (cid.length() == 0) {
00264     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: Invalid remote credential identity");
00265     return DDS::HANDLE_NIL;
00266   }
00267 
00268   SSL::Certificate::unique_ptr remote_cert(new SSL::Certificate);
00269   remote_cert->deserialize(cid);
00270 
00271   std::string remote_identity_sn;
00272   remote_cert->subject_name_to_str(remote_identity_sn);
00273 
00274   OpenDDS::Security::SSL::SubjectName sn_id_remote;
00275   OpenDDS::Security::SSL::SubjectName sn_perm_remote;
00276 
00277   const std::string& remote_perm_sn = permissions->subject_name();
00278   if (remote_identity_sn.empty() || remote_perm_sn.empty() ||
00279       sn_id_remote.parse(remote_identity_sn) != 0 ||
00280       sn_perm_remote.parse(remote_perm_sn, true) != 0 ||
00281       sn_id_remote != sn_perm_remote) {
00282     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::validate_remote_permissions: "
00283                                         "Remote permissions subject name does not match remote identity subject name");
00284     return DDS::HANDLE_NIL;
00285   }
00286 
00287   // Set and store the permissions credential token while we have the raw content
00288 
00289   Permissions::AcPerms& perm_data = permissions->data();
00290   perm_data.domain_id = piter->second.perm->data().domain_id;
00291   perm_data.perm_token = remote_permissions_token;
00292   perm_data.perm_cred_token = remote_credential_token;
00293 
00294   ::CORBA::Long perm_handle = generate_handle();
00295 
00296   AccessData cache_this;
00297   cache_this.perm = permissions;
00298   cache_this.gov = piter->second.gov;
00299   cache_this.local_access_credential_data = local_access_credential_data;
00300 
00301   local_ac_perms_.insert(std::make_pair(perm_handle, cache_this));
00302   return perm_handle;
00303 }
00304 
00305 ::CORBA::Boolean AccessControlBuiltInImpl::check_create_participant(
00306   ::DDS::Security::PermissionsHandle permissions_handle,
00307   ::DDS::Security::DomainId_t /*domain_id*/,
00308   const ::DDS::DomainParticipantQos & /*qos*/,
00309   ::DDS::Security::SecurityException & ex)
00310 {
00311   if (DDS::HANDLE_NIL == permissions_handle) {
00312     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_participant: Invalid permissions handle");
00313     return false;
00314   }
00315 
00316 /*
00317  *  The rules of this method need to be evaluated in this order, however, we need to check
00318  *  to make sure the permission handle exists in our store prior to assessing these rules
00319 */
00320   /* From Table 63 of the spec.
00321      This operation shall use the permissions_handle to retrieve
00322      the cached Permissions and Governance information.
00323              If the Governance specifies any topics on the
00324      DomainParticipant domain_id with
00325      enable_read_access_control set to FALSE or with
00326      enable_write_access_control set to FALSE, then the
00327      operation shall succeed and return TRUE.
00328              If the ParticipantSecurityAttributes has
00329      is_access_protected set to FALSE, then the operation shall
00330      succeed and return TRUE.
00331              Otherwise the operation shall return FALSE.
00332  */
00333 
00334   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
00335 
00336   ACPermsMap::iterator piter = local_ac_perms_.find(permissions_handle);
00337 
00338   if (piter == local_ac_perms_.end()) {
00339     CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::check_create_participant: No matching permissions handle present");
00340     return false;
00341   }
00342 
00343   ::DDS::Security::DomainId_t domain_to_find = piter->second.perm->data().domain_id;
00344 
00345   gov_iter begin = piter->second.gov->access_rules().begin();
00346   gov_iter end = piter->second.gov->access_rules().end();
00347 
00348   for (gov_iter giter = begin; giter != end; ++giter) {
00349     size_t d = giter->domain_list.count(domain_to_find);
00350 
00351     if (d > 0) {
00352       Governance::TopicAccessRules::iterator tr_iter;
00353 
00354       for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
00355         if (tr_iter->topic_attrs.is_read_protected == false ||
00356             tr_iter->topic_attrs.is_write_protected == false ) {
00357           return true;
00358         }
00359       }
00360 
00361       if (giter->domain_attrs.is_access_protected == false) return true;
00362     }
00363   }
00364 
00365   return false;
00366 }
00367 
00368 ::CORBA::Boolean AccessControlBuiltInImpl::check_create_datawriter(
00369   ::DDS::Security::PermissionsHandle permissions_handle,
00370   ::DDS::Security::DomainId_t domain_id,
00371   const char * topic_name,
00372   const ::DDS::DataWriterQos & /*qos*/,
00373   const ::DDS::PartitionQosPolicy & partition,
00374   const ::DDS::Security::DataTags & /*data_tag*/,
00375   ::DDS::Security::SecurityException & ex)
00376 {
00377   if (DDS::HANDLE_NIL == permissions_handle) {
00378     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Invalid permissions handle");
00379     return false;
00380   }
00381   if (0 == topic_name) {
00382     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Invalid Topic Name");
00383     return false;
00384   }
00385 
00386   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
00387 
00388   ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
00389 
00390   if (ac_iter == local_ac_perms_.end()) {
00391     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: No matching permissions handle present");
00392     return false;
00393   }
00394 
00395   gov_iter begin = ac_iter->second.gov->access_rules().begin();
00396   gov_iter end = ac_iter->second.gov->access_rules().end();
00397 
00398   for (gov_iter giter = begin; giter != end; ++giter) {
00399     size_t d = giter->domain_list.count(domain_id);
00400 
00401     if (d > 0) {
00402       Governance::TopicAccessRules::iterator tr_iter;
00403 
00404       for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
00405         if ( ::ACE::wild_match(topic_name, tr_iter->topic_expression.c_str(), true,false)) {
00406           if (tr_iter->topic_attrs.is_write_protected == false ) {
00407             return true;
00408           }
00409         }
00410       }
00411     }
00412   }
00413 
00414   // Check the Permissions file
00415   time_t delta_time;
00416 
00417   if (!validate_date_time(ac_iter, delta_time, ex)) {
00418     return false;
00419   }
00420 
00421   Permissions::PublishSubscribe_t publish = Permissions::PUBLISH;
00422   CORBA::Boolean successful = search_local_permissions(topic_name, domain_id, partition, publish, ac_iter, ex);
00423 
00424   if (!successful) {
00425     return false;
00426   }
00427 
00428   if (!local_rp_timer_.is_scheduled()) {
00429     // Start timer
00430     ACE_Time_Value timer_length(delta_time);
00431 
00432     if (!local_rp_timer_.start_timer(timer_length, permissions_handle)) {
00433       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Permissions timer could not be created.");
00434       return false;
00435     }
00436   }
00437 
00438   return true;
00439 }
00440 
00441 ::CORBA::Boolean AccessControlBuiltInImpl::check_create_datareader(
00442   ::DDS::Security::PermissionsHandle permissions_handle,
00443   ::DDS::Security::DomainId_t domain_id,
00444   const char * topic_name,
00445   const ::DDS::DataReaderQos & /*qos*/,
00446   const ::DDS::PartitionQosPolicy & partition,
00447   const ::DDS::Security::DataTags & /*data_tag*/,
00448   ::DDS::Security::SecurityException & ex)
00449 {
00450   if (DDS::HANDLE_NIL == permissions_handle) {
00451     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: Invalid permissions handle");
00452     return false;
00453   }
00454 
00455   if (0 == topic_name) {
00456     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: Invalid Topic Name");
00457     return false;
00458   }
00459 
00460   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
00461 
00462   ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
00463 
00464   if (ac_iter == local_ac_perms_.end()) {
00465     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: No matching permissions handle present");
00466     return false;
00467   }
00468 
00469   gov_iter begin = ac_iter->second.gov->access_rules().begin();
00470   gov_iter end = ac_iter->second.gov->access_rules().end();
00471 
00472   for (gov_iter giter = begin; giter != end; ++giter) {
00473     size_t d = giter->domain_list.count(domain_id);
00474 
00475     if (d > 0) {
00476       Governance::TopicAccessRules::iterator tr_iter;
00477 
00478       for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
00479         if ( ::ACE::wild_match(topic_name, tr_iter->topic_expression.c_str(), true, false)) {
00480           if (tr_iter->topic_attrs.is_read_protected == false ) {
00481             return true;
00482           }
00483         }
00484 
00485       }
00486 
00487     }
00488   }
00489 
00490   // Check the Permissions file
00491   time_t delta_time;
00492 
00493   if (!validate_date_time(ac_iter, delta_time, ex)) {
00494     return false;
00495   }
00496 
00497   Permissions::PublishSubscribe_t subscribe = Permissions::SUBSCRIBE;
00498   CORBA::Boolean successful = search_local_permissions(topic_name, domain_id, partition, subscribe, ac_iter, ex);
00499 
00500   if (!successful) {
00501     return false;
00502   }
00503 
00504   if (!local_rp_timer_.is_scheduled()) {
00505     ACE_Time_Value timer_length(delta_time);
00506 
00507     if (!local_rp_timer_.start_timer(timer_length, permissions_handle)) {
00508       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: Permissions timer could not be created.");
00509       return false;
00510     }
00511   }
00512 
00513   return true;
00514 }
00515 
00516 ::CORBA::Boolean AccessControlBuiltInImpl::check_create_topic(
00517   ::DDS::Security::PermissionsHandle permissions_handle,
00518   ::DDS::Security::DomainId_t /*domain_id*/,
00519   const char * topic_name,
00520   const ::DDS::TopicQos & /*qos*/,
00521   ::DDS::Security::SecurityException & ex)
00522 {
00523   if (DDS::HANDLE_NIL == permissions_handle) {
00524     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: Invalid permissions handle");
00525     return false;
00526   }
00527   if (0 == topic_name) {
00528     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: Invalid Topic Name");
00529     return false;
00530   }
00531 
00532   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
00533 
00534   ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
00535 
00536   if (ac_iter == local_ac_perms_.end()) {
00537     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: No matching permissions handle present");
00538     return false;
00539   }
00540 
00541   // Check the Governance file for allowable topic attributes
00542 
00543   ::DDS::Security::DomainId_t domain_to_find = ac_iter->second.perm->data().domain_id;
00544 
00545   gov_iter begin = ac_iter->second.gov->access_rules().begin();
00546   gov_iter end = ac_iter->second.gov->access_rules().end();
00547 
00548   for (gov_iter giter = begin; giter != end; ++giter) {
00549     size_t d = giter->domain_list.count(domain_to_find);
00550 
00551     if (d) {
00552       Governance::TopicAccessRules::iterator tr_iter;
00553 
00554       for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
00555         if (::ACE::wild_match(topic_name, tr_iter->topic_expression.c_str(), true, false)) {
00556           if (tr_iter->topic_attrs.is_read_protected == false ||
00557               tr_iter->topic_attrs.is_write_protected == false) {
00558             return true;
00559           }
00560         }
00561       }
00562     }
00563   }
00564 
00565   // Check the Permissions file for grants
00566   time_t delta_time;
00567 
00568   if (!validate_date_time(ac_iter, delta_time, ex)) {
00569     return false;
00570   }
00571 
00572   Permissions::PermissionGrantRules::iterator pm_iter;
00573 
00574   for (pm_iter = ac_iter->second.perm->data().perm_rules.begin(); pm_iter != ac_iter->second.perm->data().perm_rules.end(); ++pm_iter) {
00575     perm_topic_rules_iter ptr_iter; // allow/deny rules
00576 
00577     for (ptr_iter = pm_iter->PermissionTopicRules.begin(); ptr_iter != pm_iter->PermissionTopicRules.end(); ++ptr_iter) {
00578       size_t  d = ptr_iter->domain_list.count(domain_to_find);
00579 
00580       if ((d > 0) && (ptr_iter->ad_type == Permissions::ALLOW)) {
00581         perm_topic_ps_rules_iter tpsr_iter;
00582 
00583         for (tpsr_iter = ptr_iter->topic_ps_rules.begin(); tpsr_iter != ptr_iter->topic_ps_rules.end(); ++tpsr_iter) {
00584           std::vector<std::string>::iterator tl_iter; // topic list
00585 
00586           for (tl_iter = tpsr_iter->topic_list.begin(); tl_iter != tpsr_iter->topic_list.end(); ++tl_iter) {
00587             if (::ACE::wild_match(topic_name, (*tl_iter).c_str(), true, false))
00588               return true;
00589           }
00590         }
00591       }
00592     }
00593 
00594     // There is no matching rule for topic_name so use the value in default_permission
00595     if (strcmp(pm_iter->default_permission.c_str(), "ALLOW") == 0) {
00596       return true;
00597     }
00598     else {
00599       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_topic: No matching rule for topic, default permission is DENY.");
00600       return false;
00601     }
00602   }
00603 
00604   //TODO: QoS rules are not implemented
00605 
00606   return false;
00607 }
00608 
00609 ::CORBA::Boolean AccessControlBuiltInImpl::check_local_datawriter_register_instance(
00610   ::DDS::Security::PermissionsHandle permissions_handle,
00611   ::DDS::DataWriter_ptr writer,
00612   ::DDS::Security::DynamicData_ptr key,
00613   ::DDS::Security::SecurityException & ex)
00614 {
00615   if (DDS::HANDLE_NIL == permissions_handle) {
00616     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_register_instance: Invalid permissions handle");
00617     return false;
00618   }
00619   if (0 == writer) {
00620     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_register_instance: Invalid Writer");
00621     return false;
00622   }
00623   if (0 == key) {
00624     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_register_instance: Invalid Topic Key");
00625     return false;
00626   }
00627 
00628   return true;
00629 }
00630 
00631 ::CORBA::Boolean AccessControlBuiltInImpl::check_local_datawriter_dispose_instance(
00632   ::DDS::Security::PermissionsHandle permissions_handle,
00633   ::DDS::DataWriter_ptr writer,
00634   ::DDS::Security::DynamicData_ptr key,
00635   ::DDS::Security::SecurityException & ex)
00636 {
00637   if (DDS::HANDLE_NIL == permissions_handle) {
00638     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_dispose_instance: Invalid permissions handle");
00639     return false;
00640   }
00641   if (0 == writer) {
00642     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_dispose_instance: Invalid Writer");
00643     return false;
00644   }
00645   if (0 == key) {
00646     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_dispose_instance: Invalid Topic Key");
00647     return false;
00648   }
00649 
00650   return true;
00651 }
00652 
00653 ::CORBA::Boolean AccessControlBuiltInImpl::check_remote_participant(
00654   ::DDS::Security::PermissionsHandle permissions_handle,
00655   ::DDS::Security::DomainId_t domain_id,
00656   const ::DDS::Security::ParticipantBuiltinTopicDataSecure & participant_data,
00657   ::DDS::Security::SecurityException & ex)
00658 {
00659   if (DDS::HANDLE_NIL == permissions_handle) {
00660     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Invalid permissions handle");
00661     return false;
00662   }
00663 
00664   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
00665 
00666   ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
00667 
00668   if (ac_iter == local_ac_perms_.end()) {
00669     CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::check_remote_participant: No matching permissions handle present");
00670     return false;
00671   }
00672 
00673   gov_iter begin = ac_iter->second.gov->access_rules().begin();
00674   gov_iter end = ac_iter->second.gov->access_rules().end();
00675 
00676   for (gov_iter giter = begin; giter != end; ++giter) {
00677     size_t d = giter->domain_list.count(domain_id);
00678 
00679     if (d > 0) {
00680       if (giter->domain_attrs.is_access_protected == false) return true;
00681     }
00682   }
00683 
00684   // Check the PluginClassName and MajorVersion of the local permmissions vs. remote  See Table 63 of spec
00685   const std::string remote_class_id = participant_data.base.permissions_token.class_id.in();
00686 
00687   std::string local_plugin_class_name,
00688               remote_plugin_class_name;
00689   int local_major_ver,
00690       local_minor_ver,
00691       remote_major_ver,
00692       remote_minor_ver;
00693 
00694   if (remote_class_id.length() > 0) {
00695     parse_class_id(remote_class_id, remote_plugin_class_name, remote_major_ver, remote_minor_ver);
00696   }
00697   else {
00698     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Invalid remote class ID");
00699     return false;
00700   }
00701 
00702   for (ACPermsMap::iterator local_iter = local_ac_perms_.begin(); local_iter != local_ac_perms_.end(); ++local_iter) {
00703     if (local_iter->second.perm->data().domain_id == domain_id) {
00704       if (local_iter->first != permissions_handle) {
00705         std::string local_class_id = local_iter->second.perm->data().perm_token.class_id.in();
00706 
00707         if (local_class_id.length() > 0) {
00708           parse_class_id(local_class_id, local_plugin_class_name, local_major_ver, local_minor_ver);
00709         }
00710         else {
00711           CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Invalid local class ID");
00712           return false;
00713         }
00714 
00715         break;
00716       }
00717     }
00718   }
00719 
00720   if (strcmp(local_plugin_class_name.c_str(), remote_plugin_class_name.c_str()) == 0) {
00721     if (local_major_ver != remote_major_ver) {
00722       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Class ID major versions do not match");
00723       return false;
00724     }
00725   }
00726   else {
00727     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_participant: Class ID plugin class name do not match");
00728     return false;
00729   }
00730 
00731   // Check permissions topic grants
00732 
00733   Permissions::PermissionGrantRules::iterator pgr_iter;
00734 
00735   // Check topic rules for the given domain id.
00736 
00737   for (pgr_iter = ac_iter->second.perm->data().perm_rules.begin(); pgr_iter != ac_iter->second.perm->data().perm_rules.end(); ++pgr_iter) {
00738     // Cycle through topic rules to find an allow
00739     perm_topic_rules_iter ptr_iter;
00740 
00741     for (ptr_iter = pgr_iter->PermissionTopicRules.begin(); ptr_iter != pgr_iter->PermissionTopicRules.end(); ++ptr_iter) {
00742       size_t z = (ptr_iter->domain_list.count(domain_id));
00743 
00744       if ((z > 0) && (ptr_iter->ad_type == Permissions::ALLOW)) {
00745         return true;
00746       }
00747     }
00748   }
00749 
00750   return false;
00751 }
00752 
00753 ::CORBA::Boolean AccessControlBuiltInImpl::check_remote_datawriter(
00754   ::DDS::Security::PermissionsHandle permissions_handle,
00755   ::DDS::Security::DomainId_t domain_id,
00756   const ::DDS::Security::PublicationBuiltinTopicDataSecure & publication_data,
00757   ::DDS::Security::SecurityException & ex)
00758 {
00759   if (DDS::HANDLE_NIL == permissions_handle) {
00760     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter: Invalid permissions handle");
00761     return false;
00762   }
00763 
00764   if (publication_data.base.base.topic_name == "") {
00765     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter: Invalid topic name");
00766     return false;
00767   }
00768 
00769   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
00770 
00771   ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
00772 
00773   if (ac_iter == local_ac_perms_.end()) {
00774     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter: No matching permissions handle present");
00775     return false;
00776   }
00777 
00778   gov_iter begin = ac_iter->second.gov->access_rules().begin();
00779   gov_iter end = ac_iter->second.gov->access_rules().end();
00780 
00781   for (gov_iter giter = begin; giter != end; ++giter) {
00782     size_t d = giter->domain_list.count(domain_id);
00783 
00784     if (d > 0) {
00785       Governance::TopicAccessRules::iterator tr_iter;
00786 
00787       for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
00788         if (::ACE::wild_match(publication_data.base.base.topic_name, tr_iter->topic_expression.c_str(), true, false)) {
00789           if (tr_iter->topic_attrs.is_write_protected == false) {
00790             return true;
00791           }
00792         }
00793       }
00794     }
00795   }
00796 
00797   time_t delta_time;
00798 
00799   if (!validate_date_time(ac_iter, delta_time, ex)) {
00800     return false;
00801   }
00802 
00803   Permissions::PublishSubscribe_t publish = Permissions::PUBLISH;
00804 
00805   CORBA::Boolean successful = search_remote_permissions(publication_data.base.base.topic_name, domain_id, ac_iter, publish, ex);
00806 
00807   if (!successful) {
00808     return false;
00809   }
00810 
00811   if (!remote_rp_timer_.is_scheduled()) {
00812     ACE_Time_Value timer_length(delta_time);
00813 
00814     if (!remote_rp_timer_.start_timer(timer_length, permissions_handle)) {
00815       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: Permissions timer could not be created.");
00816       return false;
00817     }
00818   }
00819 
00820   return true;
00821 }
00822 
00823 ::CORBA::Boolean AccessControlBuiltInImpl::check_remote_datareader(
00824   ::DDS::Security::PermissionsHandle permissions_handle,
00825   ::DDS::Security::DomainId_t domain_id,
00826   const ::DDS::Security::SubscriptionBuiltinTopicDataSecure & subscription_data,
00827   ::CORBA::Boolean & relay_only,
00828   ::DDS::Security::SecurityException & ex)
00829 {
00830   if (DDS::HANDLE_NIL == permissions_handle) {
00831     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datareader: Invalid permissions handle");
00832     return false;
00833   }
00834 
00835   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
00836 
00837   ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
00838 
00839   if (ac_iter == local_ac_perms_.end()) {
00840     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: No matching permissions handle present");
00841     return false;
00842   }
00843 
00844   // Default this to false for now
00845   relay_only = false;
00846 
00847   gov_iter begin = ac_iter->second.gov->access_rules().begin();
00848   gov_iter end = ac_iter->second.gov->access_rules().end();
00849 
00850   for (gov_iter giter = begin; giter != end; ++giter) {
00851     size_t d = giter->domain_list.count(domain_id);
00852 
00853     if (d > 0) {
00854       Governance::TopicAccessRules::iterator tr_iter;
00855 
00856       for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
00857         if (::ACE::wild_match(subscription_data.base.base.topic_name, tr_iter->topic_expression.c_str(), true, false)) {
00858           if (tr_iter->topic_attrs.is_read_protected == false) {
00859             return true;
00860           }
00861         }
00862       }
00863 
00864     }
00865   }
00866 
00867   time_t delta_time;
00868 
00869   if (!validate_date_time(ac_iter, delta_time, ex)) {
00870     return false;
00871   }
00872 
00873   Permissions::PublishSubscribe_t subscribe = Permissions::SUBSCRIBE;
00874 
00875   CORBA::Boolean successful = search_remote_permissions(subscription_data.base.base.topic_name, domain_id, ac_iter, subscribe, ex);
00876 
00877   if (!successful) {
00878     return false;
00879   }
00880 
00881   if (!remote_rp_timer_.is_scheduled()) {
00882     ACE_Time_Value timer_length(delta_time);
00883 
00884     if (!remote_rp_timer_.start_timer(timer_length, permissions_handle)) {
00885       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datareader: Permissions timer could not be created.");
00886       return false;
00887     }
00888   }
00889 
00890   return true;
00891 }
00892 
00893 ::CORBA::Boolean AccessControlBuiltInImpl::check_remote_topic(
00894   ::DDS::Security::PermissionsHandle permissions_handle,
00895   ::DDS::Security::DomainId_t domain_id,
00896   const ::DDS::TopicBuiltinTopicData & topic_data,
00897   ::DDS::Security::SecurityException & ex)
00898 {
00899   // NOTE: permissions_handle is for the remote DomainParticipant.
00900   if (DDS::HANDLE_NIL == permissions_handle) {
00901     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Invalid permissions handle");
00902     return false;
00903   }
00904 
00905   if (topic_data.name == "") {
00906     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Invalid topic data");
00907     return false;
00908   }
00909 
00910   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
00911 
00912   ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
00913 
00914   if (ac_iter == local_ac_perms_.end()) {
00915     CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::check_remote_topic: No matching permissions handle present");
00916     return false;
00917   }
00918 
00919   // Compare the PluginClassName and MajorVersion of the local permissions_token
00920   // with those in the remote_permissions_token.
00921   const std::string remote_class_id = ac_iter->second.perm->data().perm_token.class_id.in();
00922 
00923   std::string local_plugin_class_name,
00924               remote_plugin_class_name;
00925   int local_major_ver,
00926       local_minor_ver,
00927       remote_major_ver,
00928       remote_minor_ver;
00929 
00930   if (remote_class_id.length() > 0) {
00931     parse_class_id(remote_class_id, remote_plugin_class_name, remote_major_ver, remote_minor_ver);
00932   }
00933   else {
00934     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Invalid remote class ID");
00935     return false;
00936   }
00937 
00938   for (ACPermsMap::iterator local_iter = local_ac_perms_.begin(); local_iter != local_ac_perms_.end(); ++local_iter) {
00939     if (local_iter->second.perm->data().domain_id == domain_id) {
00940       if (local_iter->first != permissions_handle) {
00941         std::string local_class_id = local_iter->second.perm->data().perm_token.class_id.in();
00942 
00943         if (local_class_id.length() > 0) {
00944           parse_class_id(local_class_id, local_plugin_class_name, local_major_ver, local_minor_ver);
00945         }
00946         else {
00947           CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Invalid local class ID");
00948           return false;
00949         }
00950 
00951         break;
00952       }
00953     }
00954   }
00955 
00956   if (strcmp(local_plugin_class_name.c_str(), remote_plugin_class_name.c_str()) == 0) {
00957     if (local_major_ver != remote_major_ver) {
00958       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Class ID major versions do not match");
00959       return false;
00960     }
00961   }
00962   else {
00963     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: Class ID plugin class name do not match");
00964     return false;
00965   }
00966 
00967   // Check the Governance file for allowable topic attributes
00968 
00969   gov_iter begin = ac_iter->second.gov->access_rules().begin();
00970   gov_iter end = ac_iter->second.gov->access_rules().end();
00971 
00972   for (gov_iter giter = begin; giter != end; ++giter) {
00973     size_t d = giter->domain_list.count(domain_id);
00974 
00975     if (d) {
00976       Governance::TopicAccessRules::iterator tr_iter;
00977 
00978       for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
00979         if (::ACE::wild_match(topic_data.name, tr_iter->topic_expression.c_str(), true, false)) {
00980           if (tr_iter->topic_attrs.is_read_protected == false ||
00981               tr_iter->topic_attrs.is_write_protected == false) {
00982             return true;
00983           }
00984         }
00985       }
00986     }
00987   }
00988 
00989   // Check the Permissions file for grants
00990   time_t delta_time;
00991 
00992   if (!validate_date_time(ac_iter, delta_time, ex)) {
00993     return false;
00994   }
00995 
00996   Permissions::PermissionGrantRules::iterator pm_iter;
00997 
00998   for (pm_iter = ac_iter->second.perm->data().perm_rules.begin(); pm_iter != ac_iter->second.perm->data().perm_rules.end(); ++pm_iter) {
00999     perm_topic_rules_iter ptr_iter; // allow/deny rules
01000 
01001     for (ptr_iter = pm_iter->PermissionTopicRules.begin(); ptr_iter != pm_iter->PermissionTopicRules.end(); ++ptr_iter) {
01002       size_t  d = ptr_iter->domain_list.count(domain_id);
01003 
01004       if ((d > 0) && (ptr_iter->ad_type == Permissions::ALLOW)) {
01005         perm_topic_ps_rules_iter tpsr_iter;
01006 
01007         for (tpsr_iter = ptr_iter->topic_ps_rules.begin(); tpsr_iter != ptr_iter->topic_ps_rules.end(); ++tpsr_iter) {
01008           if (tpsr_iter->ps_type == Permissions::PUBLISH || tpsr_iter->ps_type == Permissions::SUBSCRIBE) {
01009             std::vector<std::string>::iterator tl_iter; // topic list
01010 
01011             for (tl_iter = tpsr_iter->topic_list.begin(); tl_iter != tpsr_iter->topic_list.end(); ++tl_iter) {
01012               if (::ACE::wild_match(topic_data.name, (*tl_iter).c_str(), true, false))
01013                 return true;
01014             }
01015           }
01016         }
01017       }
01018     }
01019 
01020     // There is no matching rule for topic_name so use the value in default_permission
01021     if (strcmp(pm_iter->default_permission.c_str(), "ALLOW") == 0) {
01022       return true;
01023     }
01024     else {
01025       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_topic: No matching rule for topic, default permission is DENY.");
01026       return false;
01027     }
01028   }
01029 
01030   //TODO: QoS rules are not implemented
01031 
01032   return false;
01033 }
01034 
01035 ::CORBA::Boolean AccessControlBuiltInImpl::check_local_datawriter_match(
01036   ::DDS::Security::PermissionsHandle writer_permissions_handle,
01037   ::DDS::Security::PermissionsHandle reader_permissions_handle,
01038   const ::DDS::Security::PublicationBuiltinTopicDataSecure & /*publication_data*/,
01039   const ::DDS::Security::SubscriptionBuiltinTopicDataSecure & /*subscription_data*/,
01040   ::DDS::Security::SecurityException & ex)
01041 {
01042   if (DDS::HANDLE_NIL == writer_permissions_handle) {
01043     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_match: Invalid writer permissions handle");
01044     return false;
01045   }
01046   if (DDS::HANDLE_NIL == reader_permissions_handle) {
01047     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datawriter_match: Invalid reader permissions handle");
01048     return false;
01049   }
01050 
01051   return true;
01052 }
01053 
01054 ::CORBA::Boolean AccessControlBuiltInImpl::check_local_datareader_match(
01055   ::DDS::Security::PermissionsHandle reader_permissions_handle,
01056   ::DDS::Security::PermissionsHandle writer_permissions_handle,
01057   const ::DDS::Security::SubscriptionBuiltinTopicDataSecure & /*subscription_data*/,
01058   const ::DDS::Security::PublicationBuiltinTopicDataSecure & /*publication_data*/,
01059   ::DDS::Security::SecurityException & ex)
01060 {
01061   if (DDS::HANDLE_NIL == writer_permissions_handle) {
01062     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datareader_match: Invalid writer permissions handle");
01063     return false;
01064   }
01065   if (DDS::HANDLE_NIL == reader_permissions_handle) {
01066     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_local_datareader_match: Invalid reader permissions handle");
01067     return false;
01068   }
01069 
01070   return true;
01071 }
01072 
01073 ::CORBA::Boolean AccessControlBuiltInImpl::check_remote_datawriter_register_instance(
01074   ::DDS::Security::PermissionsHandle permissions_handle,
01075   ::DDS::DataReader_ptr reader,
01076   ::DDS::InstanceHandle_t publication_handle,
01077   ::DDS::Security::DynamicData_ptr key,
01078   ::DDS::InstanceHandle_t instance_handle,
01079   ::DDS::Security::SecurityException & ex)
01080 {
01081   if (DDS::HANDLE_NIL == permissions_handle ||
01082       DDS::HANDLE_NIL == publication_handle ||
01083       DDS::HANDLE_NIL == instance_handle) {
01084     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_register_instance: Invalid handle");
01085     return false;
01086   }
01087   if (0 == reader) {
01088     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_register_instance: Invalid Reader pointer");
01089     return false;
01090   }
01091   if (0 == key) {
01092     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_register_instance: Invalid Topic Key");
01093     return false;
01094   }
01095 
01096   return true;
01097 }
01098 
01099 ::CORBA::Boolean AccessControlBuiltInImpl::check_remote_datawriter_dispose_instance(
01100   ::DDS::Security::PermissionsHandle permissions_handle,
01101   ::DDS::DataReader_ptr reader,
01102   ::DDS::InstanceHandle_t publication_handle,
01103   ::DDS::Security::DynamicData_ptr key,
01104   ::DDS::Security::SecurityException & ex)
01105 {
01106   if (DDS::HANDLE_NIL == permissions_handle ||
01107       DDS::HANDLE_NIL == publication_handle) {
01108     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_dispose_instance: Invalid handle");
01109     return false;
01110   }
01111   if (0 == reader) {
01112     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_dispose_instance: Invalid Reader pointer");
01113     return false;
01114   }
01115   if (0 == key) {
01116     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter_dispose_instance: Invalid Topic Key");
01117     return false;
01118   }
01119   return true;
01120 }
01121 
01122 ::CORBA::Boolean AccessControlBuiltInImpl::get_permissions_token(
01123   ::DDS::Security::PermissionsToken & permissions_token,
01124   ::DDS::Security::PermissionsHandle handle,
01125   ::DDS::Security::SecurityException & ex)
01126 {
01127   if (DDS::HANDLE_NIL == handle) {
01128     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_permissions_token: Invalid permissions handle");
01129     return false;
01130   }
01131 
01132   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
01133 
01134   ACPermsMap::iterator iter = local_ac_perms_.find(handle);
01135 
01136   if (iter != local_ac_perms_.end()) {
01137     permissions_token = iter->second.perm->data().perm_token;
01138     return true;
01139   } else {
01140     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_permissions_token: No PermissionToken found");
01141     return false;
01142   }
01143 }
01144 
01145 ::CORBA::Boolean AccessControlBuiltInImpl::get_permissions_credential_token(
01146   ::DDS::Security::PermissionsCredentialToken & permissions_credential_token,
01147   ::DDS::Security::PermissionsHandle handle,
01148   ::DDS::Security::SecurityException & ex)
01149 {
01150   if (DDS::HANDLE_NIL == handle) {
01151     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_permissions_credential_token: Invalid permissions handle");
01152     return false;
01153   }
01154 
01155   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
01156 
01157   ACPermsMap::iterator iter = local_ac_perms_.find(handle);
01158 
01159   if (iter != local_ac_perms_.end()) {
01160     permissions_credential_token = iter->second.perm->data().perm_cred_token;
01161     return true;
01162   } else {
01163     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_permissions_credential_token: No PermissionToken found");
01164     return false;
01165   }
01166 
01167   return true;
01168 }
01169 
01170 ::CORBA::Boolean AccessControlBuiltInImpl::set_listener(
01171   ::DDS::Security::AccessControlListener_ptr listener,
01172   ::DDS::Security::SecurityException & ex)
01173 {
01174   if (0 == listener) {
01175     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::set_listener: Invalid Listener pointer");
01176     return false;
01177   }
01178 
01179   ACE_Guard<ACE_Thread_Mutex> guard(handle_mutex_);
01180 
01181   listener_ptr_ = listener;
01182   return true;
01183 }
01184 
01185 ::CORBA::Boolean AccessControlBuiltInImpl::return_permissions_token(
01186   const ::DDS::Security::PermissionsToken & token,
01187   ::DDS::Security::SecurityException & ex)
01188 {
01189   ACE_UNUSED_ARG(token);
01190   ACE_UNUSED_ARG(ex);
01191 
01192   return true;
01193 }
01194 
01195 ::CORBA::Boolean AccessControlBuiltInImpl::return_permissions_credential_token(
01196   const ::DDS::Security::PermissionsCredentialToken & permissions_credential_token,
01197   ::DDS::Security::SecurityException & ex)
01198 {
01199   ACE_UNUSED_ARG(permissions_credential_token);
01200   ACE_UNUSED_ARG(ex);
01201 
01202   return true;
01203 }
01204 
01205 ::CORBA::Boolean AccessControlBuiltInImpl::get_participant_sec_attributes(
01206   ::DDS::Security::PermissionsHandle permissions_handle,
01207   ::DDS::Security::ParticipantSecurityAttributes & attributes,
01208   ::DDS::Security::SecurityException & ex)
01209 {
01210   if (DDS::HANDLE_NIL == permissions_handle) {
01211     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_participant_sec_attributes: Invalid permissions handle");
01212     return false;
01213   }
01214 
01215   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
01216 
01217   ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
01218 
01219   if (ac_iter == local_ac_perms_.end()) {
01220     CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::get_participant_sec_attributes: No matching permissions handle present");
01221     return false;
01222   }
01223 
01224   // Check the Governance file for allowable topic attributes
01225   ::DDS::Security::DomainId_t domain_to_find = ac_iter->second.perm->data().domain_id;
01226 
01227   gov_iter begin = ac_iter->second.gov->access_rules().begin();
01228   gov_iter end = ac_iter->second.gov->access_rules().end();
01229 
01230   for (gov_iter giter = begin; giter != end; ++giter) {
01231     size_t d = giter->domain_list.count(domain_to_find);
01232 
01233     if (d > 0) {
01234       attributes = giter->domain_attrs;
01235       return true;
01236     }
01237   }
01238 
01239   return false;
01240 }
01241 
01242 ::CORBA::Boolean AccessControlBuiltInImpl::get_topic_sec_attributes(
01243   ::DDS::Security::PermissionsHandle permissions_handle,
01244   const char * topic_name,
01245   ::DDS::Security::TopicSecurityAttributes & attributes,
01246   ::DDS::Security::SecurityException & ex)
01247 {
01248   if (DDS::HANDLE_NIL == permissions_handle) {
01249     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_topic_sec_attributes: Invalid permissions handle");
01250     return false;
01251   }
01252   if (0 == topic_name) {
01253     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_topic_sec_attributes: Invalid topic name");
01254     return false;
01255   }
01256 
01257   // Extract Governance and the permissions data for the requested handle
01258 
01259   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, false);
01260 
01261   ACPermsMap::iterator piter = local_ac_perms_.find(permissions_handle);
01262 
01263   if (piter == local_ac_perms_.end()) {
01264     CommonUtilities::set_security_error(ex,-1, 0, "AccessControlBuiltInImpl::get_topic_sec_attributes: No matching permissions handle present");
01265     return false;
01266   }
01267 
01268   ::DDS::Security::DomainId_t domain_to_find = piter->second.perm->data().domain_id;
01269 
01270   gov_iter begin = piter->second.gov->access_rules().begin();
01271   gov_iter end = piter->second.gov->access_rules().end();
01272 
01273   for (gov_iter giter = begin; giter != end; ++giter) {
01274     size_t d = giter->domain_list.count(domain_to_find);
01275 
01276     if (d > 0) {
01277       Governance::TopicAccessRules::iterator tr_iter;
01278 
01279       for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
01280         if (::ACE::wild_match(topic_name,tr_iter->topic_expression.c_str(), true, false)) {
01281           attributes = tr_iter->topic_attrs;
01282           return true;
01283         }
01284       }
01285     }
01286   }
01287 
01288   return false;
01289 }
01290 
01291 ::CORBA::Boolean AccessControlBuiltInImpl::get_datawriter_sec_attributes(
01292   ::DDS::Security::PermissionsHandle permissions_handle,
01293   const char * topic_name,
01294   const ::DDS::PartitionQosPolicy & partition,
01295   const ::DDS::Security::DataTagQosPolicy & data_tag,
01296   ::DDS::Security::EndpointSecurityAttributes & attributes,
01297   ::DDS::Security::SecurityException & ex)
01298 {
01299   // The spec claims there is supposed to be a topic name parameter
01300   // to this function which is not in the IDL at this time
01301 
01302   if (DDS::HANDLE_NIL == permissions_handle) {
01303     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_datawriter_sec_attributes: Invalid permissions handle");
01304     return false;
01305   }
01306 
01307   if (0 == topic_name) {
01308     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_datawriter_sec_attributes: Invalid topic name");
01309     return false;
01310   }
01311 
01312   if (!get_sec_attributes(permissions_handle, topic_name, partition, data_tag, attributes, ex)) {
01313     return false;
01314   }
01315 
01316   return true;
01317 }
01318 
01319 ::CORBA::Boolean AccessControlBuiltInImpl::get_datareader_sec_attributes(
01320   ::DDS::Security::PermissionsHandle permissions_handle,
01321   const char * topic_name,
01322   const ::DDS::PartitionQosPolicy & partition,
01323   const ::DDS::Security::DataTagQosPolicy & data_tag,
01324   ::DDS::Security::EndpointSecurityAttributes & attributes,
01325   ::DDS::Security::SecurityException & ex)
01326 {
01327   if (DDS::HANDLE_NIL == permissions_handle) {
01328     CommonUtilities::set_security_error(ex, -1, 0, "Invalid permissions handle");
01329     return false;
01330   }
01331 
01332   if (0 == topic_name) {
01333     CommonUtilities::set_security_error(ex, -1, 0, "Invalid topic name");
01334     return false;
01335   }
01336 
01337   if (!get_sec_attributes(permissions_handle, topic_name, partition, data_tag, attributes, ex)) {
01338     return false;
01339   }
01340 
01341   return true;
01342 }
01343 
01344 ::CORBA::Boolean AccessControlBuiltInImpl::return_participant_sec_attributes(
01345   const ::DDS::Security::ParticipantSecurityAttributes & attributes,
01346   ::DDS::Security::SecurityException & ex)
01347 {
01348   ACE_UNUSED_ARG(attributes);
01349   ACE_UNUSED_ARG(ex);
01350 
01351   return true;
01352 }
01353 
01354 ::CORBA::Boolean AccessControlBuiltInImpl::return_datawriter_sec_attributes(
01355   const ::DDS::Security::EndpointSecurityAttributes & attributes,
01356   ::DDS::Security::SecurityException & ex)
01357 {
01358   ACE_UNUSED_ARG(attributes);
01359   ACE_UNUSED_ARG(ex);
01360 
01361   return true;
01362 }
01363 
01364 ::CORBA::Boolean AccessControlBuiltInImpl::return_datareader_sec_attributes(
01365   const ::DDS::Security::EndpointSecurityAttributes & attributes,
01366   ::DDS::Security::SecurityException & ex)
01367 {
01368   ACE_UNUSED_ARG(attributes);
01369   ACE_UNUSED_ARG(ex);
01370 
01371   return true;
01372 }
01373 
01374 ::CORBA::Long AccessControlBuiltInImpl::generate_handle()
01375 {
01376   ACE_Guard<ACE_Thread_Mutex> guard(gen_handle_mutex_);
01377   return CommonUtilities::increment_handle(next_handle_);
01378 }
01379 
01380 // NOTE: This function will return the time value as UTC
01381 // Format from DDS Security spec 1.1 is:
01382 //   CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
01383 time_t AccessControlBuiltInImpl::convert_permissions_time(std::string timeString)
01384 {
01385   // Check for a valid length time string, which is 19 characters (up through seconds)
01386   if (timeString.length() < 19) {
01387     return 0;
01388   }
01389 
01390   //time_t permission_time_t;
01391   tm permission_tm;
01392   std::string temp_str;
01393 
01394   memset(&permission_tm, 0, sizeof(tm));
01395   // Year
01396   temp_str = timeString.substr(0, 4);
01397   permission_tm.tm_year = (atoi(temp_str.c_str()) - 1900);
01398   temp_str.clear();
01399   // Month
01400   temp_str = timeString.substr(5, 2);
01401   permission_tm.tm_mon = (atoi(temp_str.c_str()) - 1);
01402   temp_str.clear();
01403   // Day
01404   temp_str = timeString.substr(8, 2);
01405   permission_tm.tm_mday = atoi(temp_str.c_str());
01406   temp_str.clear();
01407   // Hour
01408   temp_str = timeString.substr(11, 2);
01409   permission_tm.tm_hour = atoi(temp_str.c_str());
01410   temp_str.clear();
01411   // Minutes
01412   temp_str = timeString.substr(14, 2);
01413   permission_tm.tm_min = atoi(temp_str.c_str());
01414   temp_str.clear();
01415   // Seconds
01416   temp_str = timeString.substr(17, 2);
01417   permission_tm.tm_sec = atoi(temp_str.c_str());
01418 
01419   // Check if there is time zone information in the string, Z is in the 20th character
01420   if (timeString.length() > 20) {
01421     temp_str.clear();
01422     temp_str = timeString.substr(19, 1);
01423 
01424     // The only adjustments that need to be made are if the character
01425     // is a '+' or '-'
01426     if (strcmp(temp_str.c_str(), "Z") == 0) {
01427       //int hours_adj = 0;
01428       //int mins_adj = 0;
01429 
01430       temp_str.clear();
01431       temp_str = timeString.substr(20, 1);
01432 
01433       if (strcmp(temp_str.c_str(), "+") == 0) {
01434         temp_str.clear();
01435         temp_str = timeString.substr(21, 2);
01436         //hours_adj = atoi(temp_str.c_str());
01437         permission_tm.tm_hour -= atoi(temp_str.c_str());
01438         temp_str.clear();
01439         temp_str = timeString.substr(24, 2);
01440         //mins_adj = atoi(temp_str.c_str());
01441         permission_tm.tm_min -= atoi(temp_str.c_str());
01442         //permission_time_t -= (hours_adj + mins_adj);
01443       }
01444       else if (strcmp(temp_str.c_str(), "-") == 0) {
01445         temp_str.clear();
01446         temp_str = timeString.substr(21, 2);
01447         //hours_adj = atoi(temp_str.c_str());
01448         permission_tm.tm_hour += atoi(temp_str.c_str());
01449         temp_str.clear();
01450         temp_str = timeString.substr(24, 2);
01451         //mins_adj = atoi(temp_str.c_str());
01452         permission_tm.tm_min += atoi(temp_str.c_str());
01453         //permission_time_t += (hours_adj + mins_adj);
01454       }
01455     }
01456 
01457   }
01458 
01459   permission_tm.tm_isdst = -1;
01460 
01461   //return permission_time_t;
01462   return mktime(&permission_tm);
01463 }
01464 
01465 ::CORBA::Boolean AccessControlBuiltInImpl::validate_date_time(const ACPermsMap::iterator ac_iter,
01466   time_t & delta_time,
01467   ::DDS::Security::SecurityException & ex)
01468 {
01469   time_t after_time,
01470          before_time,
01471          cur_utc_time;
01472   time_t current_date_time = time(0);
01473 
01474   perm_grant_iter pbegin = ac_iter->second.perm->data().perm_rules.begin();
01475   perm_grant_iter pend = ac_iter->second.perm->data().perm_rules.end();
01476 
01477   for (perm_grant_iter pm_iter = pbegin; pm_iter != pend; ++pm_iter) {
01478     before_time = convert_permissions_time(pm_iter->validity.not_before);
01479 
01480     if (before_time == 0) {
01481       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Permissions not_before time is invalid.");
01482       return false;
01483     }
01484 
01485     // Adjust the current time to UTC/GMT
01486     tm *current_time_tm = gmtime(&current_date_time);
01487     cur_utc_time = mktime(current_time_tm);
01488 
01489     if (cur_utc_time < before_time) {
01490       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Permissions grant hasn't started yet.");
01491       return false;
01492     }
01493 
01494     after_time = convert_permissions_time(pm_iter->validity.not_after);
01495 
01496     if (after_time == 0) {
01497       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Permissions not_after time is invalid.");
01498       return false;
01499     }
01500 
01501     if (cur_utc_time > after_time) {
01502       CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_create_datawriter: Permissions grant has expired.");
01503       return false;
01504     }
01505 
01506   }
01507 
01508   delta_time = after_time - cur_utc_time;
01509   return true;
01510 }
01511 
01512 CORBA::Boolean AccessControlBuiltInImpl::get_sec_attributes(::DDS::Security::PermissionsHandle permissions_handle,
01513                                                             const char * topic_name,
01514                                                             const::DDS::PartitionQosPolicy & /*partition*/,
01515                                                             const::DDS::Security::DataTagQosPolicy & /*data_tag*/,
01516                                                             ::DDS::Security::EndpointSecurityAttributes & attributes,
01517                                                             ::DDS::Security::SecurityException & ex)
01518 {
01519   ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, handle_mutex_, 1);
01520 
01521   ACPermsMap::iterator ac_iter = local_ac_perms_.find(permissions_handle);
01522 
01523   if (ac_iter == local_ac_perms_.end()) {
01524     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_datawriter_sec_attributes: No matching permissions handle present");
01525     return false;
01526   }
01527 
01528   ::DDS::Security::DomainId_t domain_to_find = ac_iter->second.perm->data().domain_id;
01529 
01530   gov_iter begin = ac_iter->second.gov->access_rules().begin();
01531   gov_iter end = ac_iter->second.gov->access_rules().end();
01532 
01533   for (gov_iter giter = begin; giter != end; ++giter) {
01534     size_t d = giter->domain_list.count(domain_to_find);
01535 
01536     if (d > 0) {
01537       if (std::strcmp(topic_name, "DCPSParticipantVolatileMessageSecure") == 0) {
01538         attributes.base.is_write_protected = false;
01539         attributes.base.is_read_protected = false;
01540         attributes.base.is_liveliness_protected = false;
01541         attributes.base.is_discovery_protected = false;
01542         attributes.is_submessage_protected = true;
01543         attributes.is_payload_protected = false;
01544         attributes.is_key_protected = false;
01545         return true;
01546       }
01547 
01548       if (std::strcmp(topic_name, "DCPSParticipantStatelessMessage") == 0) {
01549         attributes.base.is_write_protected = false;
01550         attributes.base.is_read_protected = false;
01551         attributes.base.is_liveliness_protected = false;
01552         attributes.base.is_discovery_protected = false;
01553         attributes.is_submessage_protected = false;
01554         attributes.is_payload_protected = false;
01555         attributes.is_key_protected = false;
01556         return true;
01557       }
01558 
01559       if (std::strcmp(topic_name, "DCPSParticipantMessageSecure") == 0) {
01560         attributes.base.is_write_protected = false;
01561         attributes.base.is_read_protected = false;
01562         attributes.base.is_liveliness_protected = false;
01563         attributes.base.is_discovery_protected = false;
01564         attributes.is_submessage_protected = giter->domain_attrs.is_liveliness_protected;
01565         attributes.is_payload_protected = false;
01566         attributes.is_key_protected = false;
01567 
01568         if (giter->domain_attrs.plugin_participant_attributes & ::DDS::Security::PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ENCRYPTED) {
01569           attributes.plugin_endpoint_attributes |= ::DDS::Security::PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
01570         }
01571 
01572         if (giter->domain_attrs.plugin_participant_attributes & ::DDS::Security::PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ORIGIN_AUTHENTICATED) {
01573           attributes.plugin_endpoint_attributes |= ::DDS::Security::PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED;
01574         }
01575 
01576         return true;
01577       }
01578 
01579       if (std::strcmp(topic_name, "DCPSParticipantSecure") == 0 ||
01580           std::strcmp(topic_name, "DCPSPublicationsSecure") == 0 ||
01581           std::strcmp(topic_name, "DCPSSubscriptionsSecure") == 0) {
01582         attributes.base.is_write_protected = false;
01583         attributes.base.is_read_protected = false;
01584         attributes.base.is_liveliness_protected = false;
01585         attributes.base.is_discovery_protected = false;
01586         attributes.is_submessage_protected = giter->domain_attrs.is_discovery_protected;
01587         attributes.is_payload_protected = false;
01588         attributes.is_key_protected = false;
01589 
01590         if (giter->domain_attrs.plugin_participant_attributes & ::DDS::Security::PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_BUILTIN_IS_DISCOVERY_ENCRYPTED) {
01591           attributes.plugin_endpoint_attributes |= ::DDS::Security::PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
01592         }
01593 
01594         if (giter->domain_attrs.plugin_participant_attributes & ::DDS::Security::PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_ORIGIN_AUTHENTICATED) {
01595           attributes.plugin_endpoint_attributes |= ::DDS::Security::PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED;
01596         }
01597 
01598         return true;
01599       }
01600 
01601       Governance::TopicAccessRules::iterator tr_iter;
01602 
01603       for (tr_iter = giter->topic_rules.begin(); tr_iter != giter->topic_rules.end(); ++tr_iter) {
01604         if (::ACE::wild_match(topic_name, tr_iter->topic_expression.c_str(), true, false)) {
01605 
01606           // Process the TopicSecurityAttributes base
01607           attributes.base.is_write_protected = tr_iter->topic_attrs.is_write_protected;
01608           attributes.base.is_read_protected = tr_iter->topic_attrs.is_read_protected;
01609           attributes.base.is_liveliness_protected = tr_iter->topic_attrs.is_liveliness_protected;
01610           attributes.base.is_discovery_protected = tr_iter->topic_attrs.is_discovery_protected;
01611 
01612           // Process metadata protection attributes
01613           if (tr_iter->metadata_protection_kind == "NONE") {
01614             attributes.is_submessage_protected = false;
01615           }
01616           else {
01617             attributes.is_submessage_protected = true;
01618 
01619             if (tr_iter->metadata_protection_kind == "ENCRYPT" ||
01620               tr_iter->metadata_protection_kind == "ENCRYPT_WITH_ORIGIN_AUTHENTICATION") {
01621               attributes.plugin_endpoint_attributes |= ::DDS::Security::PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
01622             }
01623 
01624             if (tr_iter->metadata_protection_kind == "SIGN_WITH_ORIGIN_AUTHENTICATION" ||
01625               tr_iter->metadata_protection_kind == "ENCRYPT_WITH_ORIGIN_AUTHENTICATION") {
01626               attributes.plugin_endpoint_attributes |= ::DDS::Security::PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED;
01627             }
01628           }
01629 
01630           // Process data protection attributes
01631 
01632           if (tr_iter->data_protection_kind == "NONE") {
01633             attributes.is_payload_protected = false;
01634             attributes.is_key_protected = false;
01635           }
01636           else if (tr_iter->data_protection_kind == "SIGN") {
01637             attributes.is_payload_protected = true;
01638             attributes.is_key_protected = false;
01639           }
01640           else if (tr_iter->data_protection_kind == "ENCRYPT") {
01641             attributes.is_payload_protected = true;
01642             attributes.is_key_protected = true;
01643             attributes.plugin_endpoint_attributes |= ::DDS::Security::PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED;
01644           }
01645 
01646           return true;
01647         }
01648       }
01649     }
01650   }
01651 
01652   CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::get_datawriter_sec_attributes: Invalid topic name");
01653   return false;
01654 }
01655 
01656 CORBA::Boolean AccessControlBuiltInImpl::search_local_permissions(
01657   const char * topic_name,
01658   const ::DDS::Security::DomainId_t domain_id,
01659   const ::DDS::PartitionQosPolicy & partition,
01660   const Permissions::PublishSubscribe_t pub_or_sub,
01661   const ACPermsMap::iterator ac_iter,
01662   ::DDS::Security::SecurityException & ex)
01663 {
01664   std::string default_value;
01665 
01666   perm_grant_iter pbegin = ac_iter->second.perm->data().perm_rules.begin();
01667   perm_grant_iter pend = ac_iter->second.perm->data().perm_rules.end();
01668 
01669   for (perm_grant_iter pm_iter = pbegin; pm_iter != pend; ++pm_iter) {
01670     perm_grant_iter pbegin = ac_iter->second.perm->data().perm_rules.begin();
01671     perm_grant_iter pend = ac_iter->second.perm->data().perm_rules.end();
01672 
01673     for (perm_grant_iter pm_iter = pbegin; pm_iter != pend; ++pm_iter) {
01674       default_value = pm_iter->default_permission;
01675 
01676       perm_topic_rules_iter ptr_iter; // allow/deny rules
01677       perm_partitions_iter pp_iter;
01678       int matched_allow_partitions = 0;
01679       int matched_deny_partitions = 0;
01680       CORBA::ULong num_param_partitions = 0;
01681 
01682       for (ptr_iter = pm_iter->PermissionTopicRules.begin(); ptr_iter != pm_iter->PermissionTopicRules.end(); ++ptr_iter) {
01683         size_t  d = ptr_iter->domain_list.count(domain_id);
01684 
01685         if ((d > 0) && (ptr_iter->ad_type == Permissions::ALLOW)) {
01686           perm_topic_ps_rules_iter tpsr_iter;
01687 
01688           for (tpsr_iter = ptr_iter->topic_ps_rules.begin(); tpsr_iter != ptr_iter->topic_ps_rules.end(); ++tpsr_iter) {
01689 //            if (tpsr_iter->ps_type == Permissions::PUBLISH) {
01690             if (tpsr_iter->ps_type == pub_or_sub) {
01691               std::vector<std::string>::iterator tl_iter; // topic list
01692 
01693               for (tl_iter = tpsr_iter->topic_list.begin(); tl_iter != tpsr_iter->topic_list.end(); ++tl_iter) {
01694                 if (::ACE::wild_match(topic_name, (*tl_iter).c_str(), true, false)) {
01695                   // Topic matches now check that the partitions match
01696                   if (partition.name.length() > 0) {
01697                     // First look for the ad_type & ps_type in the partitions
01698                     for (pp_iter = pm_iter->PermissionPartitions.begin(); pp_iter != pm_iter->PermissionPartitions.end(); pp_iter++) {
01699                       size_t pd = pp_iter->domain_list.count(domain_id);
01700 
01701                       if ((pd > 0) && (pp_iter->ad_type == Permissions::ALLOW)) {
01702                         perm_partition_ps_iter pps_iter;
01703 
01704                         for (pps_iter = pp_iter->partition_ps.begin(); pps_iter != pp_iter->partition_ps.end(); ++pps_iter) {
01705 //                          if (pps_iter->ps_type == Permissions::PUBLISH) {
01706                           if (pps_iter->ps_type == pub_or_sub) {
01707                             std::vector<std::string>::iterator pl_iter; // partition list
01708                             num_param_partitions = pps_iter->partition_list.size();
01709 
01710                             for (pl_iter = pps_iter->partition_list.begin(); pl_iter != pps_iter->partition_list.end(); ++pl_iter) {
01711                               // Check the pl_iter value against the list of partitions in the partition parameter
01712                               for (CORBA::ULong i = 0; i < partition.name.length(); ++i) {
01713                                 if (::ACE::wild_match(partition.name[i], (*pl_iter).c_str(), true, false)) {
01714                                   matched_allow_partitions++;
01715                                   break;
01716                                 }
01717                               }
01718                             }
01719                           }
01720                         }
01721                       }
01722                     }
01723                   }
01724                   else { // No partitions to match
01725                     return true;
01726                   }
01727 
01728                 }
01729               }
01730             }
01731           }
01732         }
01733         else if ((d > 0) && (ptr_iter->ad_type == Permissions::DENY)) {
01734           perm_topic_ps_rules_iter tpsr_iter;
01735 
01736           for (tpsr_iter = ptr_iter->topic_ps_rules.begin(); tpsr_iter != ptr_iter->topic_ps_rules.end(); ++tpsr_iter) {
01737 //            if (tpsr_iter->ps_type == Permissions::PUBLISH) {
01738             if (tpsr_iter->ps_type == pub_or_sub) {
01739               std::vector<std::string>::iterator tl_iter; // topic list
01740 
01741               for (tl_iter = tpsr_iter->topic_list.begin(); tl_iter != tpsr_iter->topic_list.end(); ++tl_iter) {
01742                 if (::ACE::wild_match(topic_name, (*tl_iter).c_str(), true, false)) {
01743                   // Topic matches now check that the partitions match
01744                   if (partition.name.length() > 0) {
01745                     // First look for the ad_type & ps_type in the partitions
01746                     for (pp_iter = pm_iter->PermissionPartitions.begin(); pp_iter != pm_iter->PermissionPartitions.end(); pp_iter++) {
01747                       size_t pd = pp_iter->domain_list.count(domain_id);
01748 
01749                       if ((pd > 0) && (pp_iter->ad_type == Permissions::DENY)) {
01750                         perm_partition_ps_iter pps_iter;
01751 
01752                         for (pps_iter = pp_iter->partition_ps.begin(); pps_iter != pp_iter->partition_ps.end(); ++pps_iter) {
01753 //                          if (pps_iter->ps_type == Permissions::PUBLISH) {
01754                           if (pps_iter->ps_type == pub_or_sub) {
01755                             std::vector<std::string>::iterator pl_iter; // partition list
01756 
01757                             for (pl_iter = pps_iter->partition_list.begin(); pl_iter != pps_iter->partition_list.end(); ++pl_iter) {
01758                               // Check the pl_iter value against the list of partitions in the partition parameter
01759                               for (CORBA::ULong i = 0; i < partition.name.length(); ++i) {
01760                                 if (::ACE::wild_match(partition.name[i], (*pl_iter).c_str(), true, false)) {
01761                                   matched_deny_partitions++;
01762                                   break;
01763                                 }
01764                               }
01765                             }
01766                           }
01767                         }
01768                       }
01769                     }
01770                   }
01771                   else {
01772                     return false;
01773                   }
01774                 }
01775               }
01776             }
01777           }
01778 
01779         } // end of DENY
01780       }
01781 
01782       // If a topic and partition match were found, return the appropriate value.
01783       if ((matched_allow_partitions > 0) && (matched_deny_partitions > 0)) {
01784         CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl: Topic is in both allow and deny.");
01785         return false;
01786       }
01787       else {
01788         if (matched_allow_partitions > 0) {
01789           if (num_param_partitions > partition.name.length()) {
01790             CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl: Requested more partitions than available in permissions file.");
01791             return false;
01792           }
01793           else {
01794             return true;
01795           }
01796         }
01797         else if (matched_deny_partitions > 0) {
01798           return false;
01799         }
01800 
01801       }
01802 
01803     }
01804   }
01805 
01806   // If this point in the code is reached it means that either there are no PermissionTopicRules
01807   // or the topic_name does not exist in the topic_list so return the value of default_permission
01808   if (strcmp(default_value.c_str(), "ALLOW") == 0) {
01809     return true;
01810   }
01811   else {
01812     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl: No matching rule for topic, default permission is DENY.");
01813     return false;
01814   }
01815 }
01816 
01817 CORBA::Boolean AccessControlBuiltInImpl::search_remote_permissions(
01818   const char * topic_name,
01819   const ::DDS::Security::DomainId_t domain_id,
01820   const ACPermsMap::iterator ac_iter,
01821   const Permissions::PublishSubscribe_t pub_or_sub,
01822   ::DDS::Security::SecurityException & ex)
01823 {
01824   perm_grant_iter pm_iter;
01825   std::string default_value;
01826 
01827   for (pm_iter = ac_iter->second.perm->data().perm_rules.begin(); pm_iter != ac_iter->second.perm->data().perm_rules.end(); ++pm_iter) {
01828     default_value = pm_iter->default_permission;
01829 
01830     perm_topic_rules_iter ptr_iter; // allow/deny rules
01831 
01832     for (ptr_iter = pm_iter->PermissionTopicRules.begin(); ptr_iter != pm_iter->PermissionTopicRules.end(); ++ptr_iter) {
01833       size_t  d = ptr_iter->domain_list.count(domain_id);
01834 
01835       if ((d > 0) && (ptr_iter->ad_type == Permissions::ALLOW)) {
01836         perm_topic_ps_rules_iter tpsr_iter;
01837 
01838         for (tpsr_iter = ptr_iter->topic_ps_rules.begin(); tpsr_iter != ptr_iter->topic_ps_rules.end(); ++tpsr_iter) {
01839           if (tpsr_iter->ps_type == pub_or_sub) {
01840             std::vector<std::string>::iterator tl_iter; // topic list
01841 
01842             for (tl_iter = tpsr_iter->topic_list.begin(); tl_iter != tpsr_iter->topic_list.end(); ++tl_iter) {
01843               if (::ACE::wild_match(topic_name, (*tl_iter).c_str(), true, false)) {
01844                 return true;
01845               }
01846             }
01847           }  // end if (tpsr_iter->ps_type)
01848         } // end for
01849       }
01850       else if ((d > 0) && (ptr_iter->ad_type == Permissions::DENY)) {
01851         perm_topic_ps_rules_iter tpsr_iter;
01852 
01853         for (tpsr_iter = ptr_iter->topic_ps_rules.begin(); tpsr_iter != ptr_iter->topic_ps_rules.end(); ++tpsr_iter) {
01854           if (tpsr_iter->ps_type == pub_or_sub) {
01855             std::vector<std::string>::iterator tl_iter; // topic list
01856 
01857             for (tl_iter = tpsr_iter->topic_list.begin(); tl_iter != tpsr_iter->topic_list.end(); ++tl_iter) {
01858               if (::ACE::wild_match(topic_name, (*tl_iter).c_str(), true, false)) {
01859                 CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter: Permissions is DENY");
01860                 return false;
01861               }
01862             }
01863           }
01864         }
01865 
01866       } // end of DENY
01867     }
01868 
01869   }
01870 
01871   // If this point in the code is reached it means that either there are no PermissionTopicRules
01872   // or the topic_name does not exist in the topic_list so return the value of default_permission
01873   if (strcmp(default_value.c_str(), "ALLOW") == 0) {
01874     return true;
01875   }
01876   else {
01877     CommonUtilities::set_security_error(ex, -1, 0, "AccessControlBuiltInImpl::check_remote_datawriter: Topic not in Permissions, default is DENY");
01878     return false;
01879   }
01880 }
01881 
01882 void AccessControlBuiltInImpl::parse_class_id(
01883   const std::string class_id,
01884   std::string & plugin_class_name,
01885   int & major_version,
01886   int & minor_version)
01887 {
01888   const std::string delimiter = ":";
01889 
01890   major_version = 1;
01891   minor_version = 0;
01892 
01893   size_t pos = class_id.find_last_of(delimiter);
01894 
01895   if ((pos > 0UL) && (pos != class_id.length() - 1)) {
01896     plugin_class_name = class_id.substr(0, (pos - 1));
01897 
01898     const std::string period = ".";
01899 
01900     size_t period_pos = class_id.find_last_of(period);
01901 
01902     if (period_pos > 0UL) {
01903       std::string mv_string = class_id.substr((pos + 1), (period_pos - 1));
01904 
01905       major_version = atoi(mv_string.c_str());
01906 
01907       if (period_pos != class_id.length() - 1) {
01908         mv_string = class_id.substr((period_pos + 1), (class_id.length() - 1));
01909         minor_version = atoi(mv_string.c_str());
01910       }
01911     }
01912   }
01913   else {
01914     plugin_class_name.clear();
01915   }
01916 
01917 }
01918 
01919 AccessControlBuiltInImpl::RevokePermissionsTimer::RevokePermissionsTimer(AccessControlBuiltInImpl& impl)
01920     : impl_(impl)
01921     , scheduled_(false)
01922     , timer_id_(0)
01923     , reactor_(0)
01924 { }
01925 
01926 AccessControlBuiltInImpl::RevokePermissionsTimer::~RevokePermissionsTimer()
01927 {
01928   if (scheduled_) {
01929       reactor_->cancel_timer(this);
01930   }
01931 }
01932 
01933 bool AccessControlBuiltInImpl::RevokePermissionsTimer::start_timer(const ACE_Time_Value length, ::DDS::Security::PermissionsHandle pm_handle)
01934 {
01935   ACE_GUARD_RETURN(ACE_Thread_Mutex,
01936       guard,
01937       this->lock_,
01938       false);
01939 
01940   ::DDS::Security::PermissionsHandle *eh_params_ptr =
01941       new ::DDS::Security::PermissionsHandle(pm_handle);
01942 
01943   reactor_ = TheServiceParticipant->timer();
01944 
01945   if (reactor_ != NULL) {
01946     timer_id_ = reactor_->schedule_timer(this, eh_params_ptr, length);
01947 
01948     if (timer_id_ != -1) {
01949       scheduled_ = true;
01950       delete eh_params_ptr;
01951       return true;
01952     }
01953 
01954   }
01955 
01956   delete eh_params_ptr;
01957   return false;
01958 }
01959 
01960 int AccessControlBuiltInImpl::RevokePermissionsTimer::handle_timeout(const ACE_Time_Value & tv, const void * arg)
01961 {
01962   ACE_UNUSED_ARG(tv);
01963   ACE_GUARD_RETURN(ACE_Thread_Mutex,
01964       guard,
01965       this->lock_,
01966       -1);
01967 
01968   ::DDS::Security::PermissionsHandle *pm_handle = (::DDS::Security::PermissionsHandle *)arg;
01969 
01970   scheduled_ = false;
01971 
01972   ACPermsMap::iterator iter = impl_.local_ac_perms_.find(*pm_handle);
01973 
01974   if (iter == impl_.local_ac_perms_.end()) {
01975     ACE_DEBUG((LM_ERROR, ACE_TEXT(
01976         "(%P|%t) AccessControlBuiltInImpl::Revoke_Permissions_Timer::handle_timeout: pm_handle %d not found!\n"), *pm_handle));
01977     return -1;
01978   }
01979 
01980   impl_.local_ac_perms_.erase(iter);
01981 
01982   // If a listener exists, call on_revoke_permissions
01983   if (impl_.listener_ptr_ != NULL) {
01984     if (!impl_.listener_ptr_->on_revoke_permissions(&impl_, *pm_handle)) {
01985       ACE_DEBUG((LM_ERROR, ACE_TEXT(
01986           "(%P|%t) AccessControlBuiltInImpl::Revoke_Permissions_Timer::handle_timeout: on_revoke_permissions failed for pm_handle %d!\n"), *pm_handle));
01987       return -1;
01988     }
01989   }
01990 
01991   if (OpenDDS::DCPS::DCPS_debug_level > 0) {
01992     ACE_DEBUG((LM_DEBUG, ACE_TEXT(
01993       "(%P|%t) AccessControlBuiltInImpl::Revoke_Permissions_Timer::handle_timeout: Completed...\n")));
01994   }
01995 
01996   return 0;
01997 }
01998 
01999 } // namespace Security
02000 } // namespace OpenDDS
02001 
02002 OPENDDS_END_VERSIONED_NAMESPACE_DECL
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 9 Aug 2018 for OpenDDS by  doxygen 1.6.1