Permissions.cpp

Go to the documentation of this file.
00001 /*
00002  * Distributed under the OpenDDS License.
00003  * See: http://www.OpenDDS.org/license.html
00004  */
00005 
00006 #include "Permissions.h"
00007 
00008 #include "xercesc/parsers/XercesDOMParser.hpp"
00009 #include "xercesc/dom/DOM.hpp"
00010 #include "xercesc/sax/HandlerBase.hpp"
00011 #include "xercesc/framework/MemBufInputSource.hpp"
00012 
00013 #include "ace/OS_NS_strings.h"
00014 #include "ace/XML_Utils/XercesString.h"
00015 
00016 #include <stdexcept>
00017 
00018 namespace OpenDDS {
00019 namespace Security {
00020 
00021 Permissions::Permissions()
00022   : perm_data_(), subject_name_()
00023 {
00024 
00025 }
00026 
00027 bool Permissions::extract_subject_name(const SSL::SignedDocument& doc)
00028 {
00029   doc.get_original_minus_smime(subject_name_);
00030 
00031   const std::string start_str("<subject_name>"), end_str("</subject_name>");
00032 
00033   size_t found_begin = subject_name_.find(start_str);
00034 
00035   if (found_begin != std::string::npos) {
00036     subject_name_.erase(0, found_begin + start_str.length());
00037     const char* t = " \t\n\r\f\v";
00038     subject_name_.erase(0, subject_name_.find_first_not_of(t));
00039 
00040   } else {
00041     return false;
00042   }
00043 
00044   size_t found_end = subject_name_.find(end_str);
00045 
00046   if (found_end != std::string::npos) {
00047     subject_name_.erase(found_end);
00048   } else {
00049     return false;
00050   }
00051 
00052   return true;
00053 }
00054 
00055 namespace {
00056   std::string toString(const XMLCh* in)
00057   {
00058     char* c = xercesc::XMLString::transcode(in);
00059     const std::string s(c);
00060     xercesc::XMLString::release(&c);
00061     return s;
00062   }
00063 
00064   int toInt(const XMLCh* in)
00065   {
00066     unsigned int i = 0;
00067     xercesc::XMLString::textToBin(in, i);
00068     return static_cast<int>(i);
00069   }
00070 }
00071 
00072 int Permissions::load(const SSL::SignedDocument& doc)
00073 {
00074   using XML::XStr;
00075   static const char* gMemBufId = "gov buffer id";
00076 
00077   if (!extract_subject_name(doc))
00078   {
00079     ACE_ERROR((LM_ERROR, "Permissions::load: WARNING, Could not extract subject name from permissions file"));
00080     return -1;
00081   }
00082 
00083   DCPS::unique_ptr<xercesc::XercesDOMParser> parser(new xercesc::XercesDOMParser());
00084   parser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);
00085   parser->setDoNamespaces(true);    // optional
00086   parser->setCreateCommentNodes(false);
00087 
00088   DCPS::unique_ptr<xercesc::ErrorHandler> errHandler((xercesc::ErrorHandler*) new xercesc::HandlerBase());
00089   parser->setErrorHandler(errHandler.get());
00090 
00091   std::string cleaned;
00092   doc.get_original_minus_smime(cleaned);
00093   xercesc::MemBufInputSource contentbuf((const XMLByte*) cleaned.c_str(),
00094                                         cleaned.size(),
00095                                         gMemBufId);
00096   try {
00097     parser->parse(contentbuf);
00098   }
00099   catch (const xercesc::XMLException& toCatch) {
00100     char* message = xercesc::XMLString::transcode(toCatch.getMessage());
00101     ACE_DEBUG((LM_ERROR, ACE_TEXT(
00102         "(%P|%t) AccessControlBuiltInImpl::load_permissions_file: Exception message is %C.\n"), message));
00103     xercesc::XMLString::release(&message);
00104     return -1;
00105   }
00106   catch (const xercesc::DOMException& toCatch) {
00107     char* message = xercesc::XMLString::transcode(toCatch.msg);
00108     ACE_DEBUG((LM_ERROR, ACE_TEXT(
00109         "(%P|%t) AccessControlBuiltInImpl::load_permissions_file: Exception message is: %C.\n"), message));
00110     xercesc::XMLString::release(&message);
00111     return -1;
00112   }
00113   catch (...) {
00114     ACE_DEBUG((LM_ERROR, ACE_TEXT(
00115         "(%P|%t) AccessControlBuiltInImpl::load_permissions_file: Unexpected Permissions XML Parser Exception.\n")));
00116     return -1;
00117   }
00118 
00119 
00120   // Successfully parsed the permissions file
00121 
00122   xercesc::DOMDocument* xmlDoc = parser->getDocument();
00123 
00124   xercesc::DOMElement* elementRoot = xmlDoc->getDocumentElement();
00125   if ( !elementRoot ) throw(std::runtime_error( "empty XML document" ));
00126 
00127 
00128   //TODO:  WARNING - this implementation only supports 1 permissions/grant set
00129  // Different from governance from here forward
00130   // Find the validity rules
00131   xercesc::DOMNodeList * grantRules = xmlDoc->getElementsByTagName(XStr("grant"));
00132 
00133   //PermissionGrantRules grant_rules_list_holder_;
00134 
00135   for (XMLSize_t r = 0; r < grantRules->getLength(); r++) {
00136     PermissionGrantRule rule_holder_;
00137 
00138     // Pull out the grant name for this grant
00139     xercesc::DOMNamedNodeMap * rattrs = grantRules->item(r)->getAttributes();
00140     rule_holder_.grant_name = toString(rattrs->item(0)->getTextContent());
00141 
00142     // Pull out subject name, validity, and default
00143     xercesc::DOMNodeList * grantNodes = grantRules->item(r)->getChildNodes();
00144 
00145     for ( XMLSize_t gn = 0; gn < grantNodes->getLength(); gn++) {
00146       const XStr g_tag = grantNodes->item(gn)->getNodeName();
00147 
00148       if (g_tag == "subject_name") {
00149         rule_holder_.subject = toString(grantNodes->item(gn)->getTextContent());
00150       } else if (g_tag == "validity") {
00151         //Validity_t gn_validity;
00152         xercesc::DOMNodeList *validityNodes = grantNodes->item(gn)->getChildNodes();
00153 
00154         for (XMLSize_t vn = 0; vn < validityNodes->getLength(); vn++) {
00155           const XStr v_tag = validityNodes->item(vn)->getNodeName();
00156 
00157           if (v_tag == "not_before") {
00158             rule_holder_.validity.not_before = toString(
00159                       (validityNodes->item(vn)->getTextContent()));
00160           } else if (v_tag == "not_after") {
00161             rule_holder_.validity.not_after = toString(
00162                       (validityNodes->item(vn)->getTextContent()));
00163           }
00164         }
00165       } else if (g_tag == "default") {
00166         rule_holder_.default_permission = toString(grantNodes->item(gn)->getTextContent());
00167       }
00168     }
00169     // Pull out allow/deny rules
00170     xercesc::DOMNodeList * adGrantNodes = grantRules->item(r)->getChildNodes();
00171 
00172     for (XMLSize_t gn = 0; gn < adGrantNodes->getLength(); gn++) {
00173       const XStr g_tag = adGrantNodes->item(gn)->getNodeName();
00174 
00175       if (g_tag == "allow_rule" || g_tag == "deny_rule") {
00176         PermissionTopicRule ptr_holder_;
00177         PermissionsPartition pp_holder_;
00178 
00179         ptr_holder_.ad_type = (g_tag == "allow_rule") ? ALLOW : DENY;
00180         pp_holder_.ad_type = (g_tag == "allow_rule") ? ALLOW : DENY;
00181 
00182         xercesc::DOMNodeList * adNodeChildren = adGrantNodes->item(gn)->getChildNodes();
00183 
00184         for (XMLSize_t anc = 0; anc < adNodeChildren->getLength(); anc++) {
00185           const XStr anc_tag = adNodeChildren->item(anc)->getNodeName();
00186 
00187           if (anc_tag == "domains") {   //domain list
00188             xercesc::DOMNodeList * domainIdNodes = adNodeChildren->item(anc)->getChildNodes();
00189 
00190             for (XMLSize_t did = 0; did < domainIdNodes->getLength(); did++) {
00191               if ("id" == XStr(domainIdNodes->item(did)->getNodeName())) {
00192                 ptr_holder_.domain_list.insert(toInt(domainIdNodes->item(did)->getTextContent()));
00193                 pp_holder_.domain_list.insert(toInt(domainIdNodes->item(did)->getTextContent()));
00194               }
00195               else if ("id_range" == XStr(domainIdNodes->item(did)->getNodeName())) {
00196                 int min_value = 0;
00197                 int max_value = 0;
00198                 xercesc::DOMNodeList * domRangeIdNodes = domainIdNodes->item(did)->getChildNodes();
00199 
00200                 for (XMLSize_t drid = 0; drid < domRangeIdNodes->getLength(); drid++) {
00201                   if ("min" == XStr(domRangeIdNodes->item(drid)->getNodeName())) {
00202                     min_value = toInt(domRangeIdNodes->item(drid)->getTextContent());
00203                   }
00204                   else if ("max" == XStr(domRangeIdNodes->item(drid)->getNodeName())) {
00205                     max_value = toInt(domRangeIdNodes->item(drid)->getTextContent());
00206 
00207                     if ((min_value == 0) || (min_value > max_value)) {
00208                       ACE_DEBUG((LM_ERROR, ACE_TEXT(
00209                           "(%P|%t) AccessControlBuiltInImpl::load_permissions_file: Permission XML Domain Range invalid.\n")));
00210                       return -1;
00211                     }
00212 
00213                     for (int i = min_value; i <= max_value; i++) {
00214                       ptr_holder_.domain_list.insert(i);
00215                       pp_holder_.domain_list.insert(i);
00216                     }
00217                   }
00218                 }
00219               }
00220             }
00221 
00222           } else if (anc_tag == "publish" || anc_tag == "subscribe") {   // pub sub nodes
00223             PermissionTopicPsRule anc_ps_rule_holder_;
00224             PermissionPartitionPs anc_ps_partition_holder_;
00225 
00226             anc_ps_rule_holder_.ps_type = (anc_tag == "publish") ? PUBLISH : SUBSCRIBE;
00227             anc_ps_partition_holder_.ps_type = anc_ps_rule_holder_.ps_type;
00228             xercesc::DOMNodeList * topicListNodes = adNodeChildren->item(anc)->getChildNodes();
00229 
00230             for (XMLSize_t tln = 0; tln < topicListNodes->getLength(); tln++) {
00231               if ("topics" == XStr(topicListNodes->item(tln)->getNodeName())) {
00232                 xercesc::DOMNodeList * topicNodes = topicListNodes->item(tln)->getChildNodes();
00233 
00234                 for (XMLSize_t tn = 0; tn < topicNodes->getLength(); tn++) {
00235                   if ("topic" == XStr(topicNodes->item(tn)->getNodeName())) {
00236                     anc_ps_rule_holder_.topic_list.push_back(toString(topicNodes->item(tn)->getTextContent()));
00237                   }
00238                 }
00239 
00240               }
00241               else if ("partitions" == XStr(topicListNodes->item(tln)->getNodeName())) {
00242                 xercesc::DOMNodeList * partitionNodes = topicListNodes->item(tln)->getChildNodes();
00243 
00244                 for (XMLSize_t pn = 0; pn < partitionNodes->getLength(); pn++) {
00245                   if ("partition" == XStr(partitionNodes->item(pn)->getNodeName())) {
00246                     anc_ps_partition_holder_.partition_list.push_back(toString(partitionNodes->item(pn)->getTextContent()));
00247                   }
00248                 }
00249               }
00250             }
00251 
00252             ptr_holder_.topic_ps_rules.push_back(anc_ps_rule_holder_);
00253             pp_holder_.partition_ps.push_back(anc_ps_partition_holder_);
00254           }
00255         }
00256 
00257         rule_holder_.PermissionTopicRules.push_back(ptr_holder_);
00258         rule_holder_.PermissionPartitions.push_back(pp_holder_);
00259       }
00260     }
00261 
00262     perm_data_.perm_rules.push_back(rule_holder_);
00263   } // grant_rules
00264 
00265   return 0;
00266 }
00267 
00268 
00269 }
00270 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1