OpenDDS  Snapshot(2023/04/28-20:55)
SubjectName.cpp
Go to the documentation of this file.
1 #include "SubjectName.h"
2 
3 #include <iostream>
4 
6 
7 namespace OpenDDS {
8 namespace Security {
9 namespace SSL {
10 
12 
13  SubjectName::SubjectName(const std::string& in, bool permissive)
14  {
15  parse(in, permissive);
16  }
17 
18  SubjectName::SubjectName(const char* in, bool permissive)
19  {
20  parse(in, permissive);
21  }
22 
23  int SubjectName::parse(const std::string& in, bool permissive)
24  {
25  return parse(in.data(), permissive);
26  }
27 
28  int SubjectName::parse(const char* in, bool permissive)
29  {
30  if (in == NULL) {
31  return -1;
32  }
33 
34  // For now, assume ASCII encoding and not UTF-8
35  if (permissive) {
36  return parse_permissive(in);
37  } else {
38  if (in[0] == '/') {
39  return parse_dce(in);
40  } else {
41  return parse_ldap_v3(in);
42  }
43  }
44  }
45 
46  int SubjectName::simple_avp_seq_parse(const char* in, const char* s_del,
47  const char* a_del, const char* s_trim,
48  const char* a_trim, bool push_back)
49  {
50  std::string input(in);
51  size_t input_end = input.size() - 1;
52  map_.clear();
53 
54  ACE_UNUSED_ARG(push_back);
55 
56  // This parser is meant only to cover basic cases, more advanced cases
57  // will need something different Specifically, this won't correctly handle
58  // all escaped characters or all UTF-8 strings
59 
60  // Use size_t variables to mark positions of token beginnings and ends
61 
62  // We'll use "st" to mark positions for sequence tokens
63  size_t st_begin = 0;
64  size_t st_end = input.find_first_of(s_del);
65 
66  // Loop over all the sequence tokens
67  while (st_begin != std::string::npos) {
68  std::string st = input.substr(
69  st_begin,
70  (st_end == std::string::npos ? input_end + 1 : st_end) - st_begin);
71 
72  // Use once we've found a sequnce token, trim the beginning and end to
73  // get a clean token
74  size_t st_begin_clean = st.find_first_not_of(s_trim);
75  size_t st_end_clean = st.find_last_not_of(s_trim);
76 
77  // If we've found a clean sequence token
78  if (st_begin_clean != std::string::npos &&
79  st_end_clean != std::string::npos) {
80  std::string st_clean =
81  st.substr(st_begin_clean, st_end_clean - st_begin_clean + 1);
82 
83  // We'll use "nt" to mark positions for name tokens
84  size_t nt_begin = 0;
85  size_t nt_end = st_clean.find_first_of(a_del);
86 
87  // If we actually found a delimiter
88  if (nt_end != std::string::npos) {
89  --nt_end;
90 
91  std::string nt = st_clean.substr(nt_begin, nt_end - nt_begin + 1);
92 
93  size_t nt_begin_clean = nt.find_first_not_of(a_trim);
94  size_t nt_end_clean = nt.find_last_not_of(a_trim);
95 
96  // If we found a clean name token
97  if (nt_begin_clean != std::string::npos &&
98  nt_end_clean != std::string::npos) {
99  std::string nt_clean =
100  nt.substr(nt_begin_clean, nt_end_clean - nt_begin_clean + 1);
101 
102  // We'll use "vt" to mark positions for value tokens
103  size_t vt_begin = nt_end + 2; // Skip over the (single) delimiter
104  size_t vt_end = st_clean.size() - 1;
105 
106  std::string vt = st_clean.substr(vt_begin, vt_end - vt_begin + 1);
107 
108  size_t vt_begin_clean = vt.find_first_not_of(a_trim);
109  size_t vt_end_clean = vt.find_last_not_of(a_trim);
110 
111  // If we found a clean value token
112  if (vt_begin_clean != std::string::npos &&
113  vt_end_clean != std::string::npos) {
114  std::string vt_clean =
115  vt.substr(vt_begin_clean, vt_end_clean - vt_begin_clean + 1);
116 
117  // Push our clean pair into the map
118  map_[nt_clean] = vt_clean;
119  }
120  }
121  }
122  }
123 
124  // Prepare for next iteration of loop
125  if (st_end == std::string::npos) {
126  st_begin = std::string::npos;
127  } else {
128  st_begin = st_end + 1;
129  st_end = input.find_first_of(s_del, st_begin);
130  }
131  }
132 
133  return map_.empty() ? 1 : 0;
134  }
135 
136  int SubjectName::parse_permissive(const char* in)
137  {
138  return simple_avp_seq_parse(in, ",/", "=", " ", " ", false);
139  }
140 
141  int SubjectName::parse_dce(const char* in)
142  {
143  return simple_avp_seq_parse(in, "/", "=", " ", " ", true);
144  }
145 
146  int SubjectName::parse_ldap_v3(const char* in)
147  {
148  return simple_avp_seq_parse(in, ",", "=", " ", " ", false);
149  }
150 
151  bool SubjectName::operator==(const SubjectName& rhs) const
152  {
153  bool result = (map_.size() == rhs.map_.size());
154  for (AttrMap::const_iterator i1 = map_.begin(), i2 = rhs.map_.begin();
155  result == true && i1 != map_.end() && i2 != rhs.map_.end();
156  ++i1, ++i2) {
157  if (i1->first.compare(i2->first) != 0 ||
158  i1->second.compare(i2->second) != 0) {
159  result = false;
160  }
161  }
162  return result;
163  }
164 
165  bool SubjectName::operator!=(const SubjectName& rhs) const
166  {
167  return !(*this == rhs);
168  }
169 
170 } // namespace SSL
171 } // namespace Security
172 } // namespace OpenDDS
173 
int simple_avp_seq_parse(const char *in, const char *s_del, const char *a_del, const char *s_trim, const char *a_trim, bool push_back)
Definition: SubjectName.cpp:46
bool operator==(const SubjectName &) const
bool operator!=(const SubjectName &) const
void push_back(Seq &seq, const typename Seq::value_type &val)
std::vector-style push_back() for CORBA Sequences
Definition: Util.h:138
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
int parse(const char *, bool permissive=false)
Definition: SubjectName.cpp:28
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28