OpenDDS  Snapshot(2023/04/28-20:55)
Governance.cpp
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.OpenDDS.org/license.html
4  */
5 
6 #include "Governance.h"
7 
8 #include "XmlUtils.h"
9 
10 #include <dds/DCPS/debug.h>
11 
12 #include <ace/OS_NS_strings.h>
13 #include <ace/XML_Utils/XercesString.h>
14 
16 
17 namespace OpenDDS {
18 namespace Security {
19 
20 using XML::XStr;
21 using namespace XmlUtils;
22 using namespace DDS::Security;
24 
26 {
27  topic_attrs.is_read_protected = false;
28  topic_attrs.is_write_protected = false;
29  topic_attrs.is_discovery_protected = false;
30  topic_attrs.is_liveliness_protected = false;
31 }
32 
34 {
35 }
36 
37 namespace {
38  bool get_bool_tag_value(const SSL::SignedDocument& doc, const xercesc::DOMNode* node,
39  const ACE_TCHAR* name, bool& value)
40  {
41  if (!parse_bool(node, value)) {
43  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: {access_error} Governance::load: "
44  "\"%s\" value, \"%C\", in \"%C\" is not a valid boolean value\n",
45  name, to_string(node).c_str(), doc.filename().c_str()));
46  }
47  return false;
48  }
49 
50  return true;
51  }
52 
53  bool get_bool_tag(const SSL::SignedDocument& doc, const xercesc::DOMElement* parent,
54  const ACE_TCHAR* name, bool& value)
55  {
56  const xercesc::DOMNodeList* const nodes = parent->getElementsByTagName(XStr(name));
57  if (nodes->getLength() != 1) {
59  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: {access_error} Governance::load: "
60  "expected 1 boolean value \"%s\" in parent element in \"%C\", found %B\n",
61  name, doc.filename().c_str(), nodes->getLength()));
62  }
63  return false;
64  }
65 
66  return get_bool_tag_value(doc, nodes->item(0), name, value);
67  }
68 
69  bool get_protection_kind(const SSL::SignedDocument& doc, const xercesc::DOMElement* parent,
70  const ACE_TCHAR* name, bool& is_protected, CORBA::ULong& attributes,
71  CORBA::ULong enc_attr, CORBA::ULong oa_attr)
72  {
73  const xercesc::DOMNodeList* const nodes = parent->getElementsByTagName(XStr(name));
74  if (nodes->getLength() != 1) {
76  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: {access_error} Governance::load: "
77  "expected 1 proctection kind value named \"%s\" in parent element in \"%C\", found %B\n",
78  name, doc.filename().c_str(), nodes->getLength()));
79  }
80  return false;
81  }
82 
83  const xercesc::DOMNode* const node = nodes->item(0);
84  const std::string value = to_string(node);
85  if (ACE_OS::strcasecmp(value.c_str(), "NONE") == 0) {
86  is_protected = false;
87  } else if (ACE_OS::strcasecmp(value.c_str(), "SIGN") == 0) {
88  is_protected = true;
89  } else if (ACE_OS::strcasecmp(value.c_str(), "ENCRYPT") == 0) {
90  is_protected = true;
91  attributes |= enc_attr;
92  } else if (ACE_OS::strcasecmp(value.c_str(), "SIGN_WITH_ORIGIN_AUTHENTICATION") == 0) {
93  is_protected = true;
94  attributes |= oa_attr;
95  } else if (ACE_OS::strcasecmp(value.c_str(), "ENCRYPT_WITH_ORIGIN_AUTHENTICATION") == 0) {
96  is_protected = true;
97  attributes |= enc_attr;
98  attributes |= oa_attr;
99  } else {
101  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: {access_error} Governance::load: "
102  "invalid %s, \"%C\", in \"%s\"\n",
103  name, value.c_str(), doc.filename().c_str()));
104  }
105  return false;
106  }
107 
108  return true;
109  }
110 }
111 
113 {
114  const std::string& xml = doc.content();
115  ParserPtr parser;
116  if (!get_parser(parser, doc.filename(), xml)) {
118  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: {access_error} Governance::load: "
119  "get_parser failed\n"));
120  }
121  return -1;
122  }
123 
124  // Find the domain rules
125  const xercesc::DOMNodeList* const domainRules = parser->getDocument()->getDocumentElement()->
126  getElementsByTagName(XStr(ACE_TEXT("domain_rule")));
127  for (XMLSize_t r = 0, dr_len = domainRules->getLength(); r < dr_len; ++r) {
128  Governance::DomainRule domain_rule;
130  const xercesc::DOMElement* const domain_rule_el =
131  dynamic_cast<const xercesc::DOMElement*>(domainRules->item(r));
132  if (!domain_rule_el) {
134  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: {access_error} Governance::load: "
135  "domain_rule_el is null\n"));
136  }
137  return -1;
138  }
139 
140  // Process domain ids this domain rule applies to
141  const xercesc::DOMNodeList* const ruleNodes = domain_rule_el->getChildNodes();
142  for (XMLSize_t rn = 0, rn_len = ruleNodes->getLength(); rn < rn_len; rn++) {
143  const xercesc::DOMNode* const ruleNode = ruleNodes->item(rn);
144  const XStr dn_tag = ruleNode->getNodeName();
145  if (ACE_TEXT("domains") == dn_tag) {
146  if (!parse_domain_id_set(ruleNode, domain_rule.domains)) {
148  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: {access_error} Governance::load: "
149  "failed to process domain ids in \"%C\"\n",
150  doc.filename().c_str()));
151  }
152  return -1;
153  }
154  }
155  }
156 
157  // Process allow_unauthenticated_participants
158  if (!get_bool_tag(doc, domain_rule_el, ACE_TEXT("allow_unauthenticated_participants"),
160  return -1;
161  }
162 
163  // Process enable_join_access_control
164  if (!get_bool_tag(doc, domain_rule_el, ACE_TEXT("enable_join_access_control"),
165  domain_rule.domain_attrs.is_access_protected)) {
166  return -1;
167  }
168 
169  // Process discovery_protection_kind
170  if (!get_protection_kind(doc, domain_rule_el, ACE_TEXT("discovery_protection_kind"),
175  return -1;
176  }
177 
178  // Process liveliness_protection_kind
179  if (!get_protection_kind(doc, domain_rule_el, ACE_TEXT("liveliness_protection_kind"),
184  return -1;
185  }
186 
187  // Process rtps_protection_kind
188  if (!get_protection_kind(doc, domain_rule_el, ACE_TEXT("rtps_protection_kind"),
189  domain_rule.domain_attrs.is_rtps_protected,
193  return -1;
194  }
195 
198 
199  // Process topic rules
200  const xercesc::DOMNodeList* topic_rules =
201  domain_rule_el->getElementsByTagName(XStr(ACE_TEXT("topic_rule")));
202  for (XMLSize_t tr = 0, tr_len = topic_rules->getLength(); tr < tr_len; tr++) {
203  const xercesc::DOMNode* topic_rule = topic_rules->item(tr);
204  const xercesc::DOMNodeList* topic_rule_nodes = topic_rule->getChildNodes();
206  for (XMLSize_t trn = 0, trn_len = topic_rule_nodes->getLength(); trn < trn_len; trn++) {
207  const xercesc::DOMNode* topic_rule_node = topic_rule_nodes->item(trn);
208  const std::string name = to_string(topic_rule_node->getNodeName());
209 
210  bool* bool_value = 0;
211  if (name == "topic_expression") {
212  t_rules.topic_expression = to_string(topic_rule_node);
213  } else if (name == "enable_discovery_protection") {
214  bool_value = &t_rules.topic_attrs.is_discovery_protected;
215  } else if (name == "enable_liveliness_protection") {
216  bool_value = &t_rules.topic_attrs.is_liveliness_protected;
217  } else if (name == "enable_read_access_control") {
218  bool_value = &t_rules.topic_attrs.is_read_protected;
219  } else if (name == "enable_write_access_control") {
220  bool_value = &t_rules.topic_attrs.is_write_protected;
221  } else if (name == "metadata_protection_kind") {
222  t_rules.metadata_protection_kind = to_string(topic_rule_node);
223  } else if (name == "data_protection_kind") {
224  t_rules.data_protection_kind = to_string(topic_rule_node);
225  }
226 
227  if (bool_value && !get_bool_tag_value(doc, topic_rule_node,
228  ACE_TEXT_CHAR_TO_TCHAR(name.c_str()), *bool_value)) {
229  return -1;
230  }
231  }
232  domain_rule.topic_rules.push_back(t_rules);
233  }
234 
235  access_rules_.push_back(domain_rule);
236  } // domain_rule
237 
238  return 0;
239 }
240 
241 
242 }
243 }
244 
bool parse_domain_id_set(const xercesc::DOMNode *node, Security::DomainIdSet &domain_id_set)
Definition: XmlUtils.cpp:445
#define ACE_ERROR(X)
const LogLevel::Value value
Definition: debug.cpp:61
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_ORIGIN_AUTHENTICATED
const std::string & filename() const
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_VALID
DDS::Security::ParticipantSecurityAttributes domain_attrs
Definition: Governance.h:40
bool access_error
Permissions and Governance.
Definition: debug.h:132
PluginParticipantSecurityAttributesMask plugin_participant_attributes
ACE_CDR::ULong ULong
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ENCRYPTED
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_BUILTIN_IS_DISCOVERY_ENCRYPTED
char ACE_TCHAR
const std::string & content() const
#define ACE_TEXT_CHAR_TO_TCHAR(STRING)
const char *const name
Definition: debug.cpp:60
ACE_TEXT("TCP_Factory")
int strcasecmp(const char *s, const char *t)
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ORIGIN_AUTHENTICATED
bool parse_bool(const XMLCh *in, bool &value)
Definition: XmlUtils.cpp:150
bool get_parser(ParserPtr &parser, const std::string &filename, const std::string &xml)
Definition: XmlUtils.cpp:71
int load(const SSL::SignedDocument &doc)
Definition: Governance.cpp:112
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
std::string to_string(const xercesc::SAXParseException &ex)
Definition: XmlUtils.cpp:30
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_RTPS_ORIGIN_AUTHENTICATED
DDS::Security::TopicSecurityAttributes topic_attrs
Definition: Governance.h:31
const ParticipantSecurityAttributesMask PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED
LM_ERROR
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
OpenDDS_Dcps_Export SecurityDebug security_debug
Definition: debug.cpp:32