Line data Source code
1 : #include "SubjectName.h"
2 :
3 : #include <iostream>
4 :
5 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
6 :
7 : namespace OpenDDS {
8 : namespace Security {
9 : namespace SSL {
10 :
11 93 : SubjectName::SubjectName() {}
12 :
13 0 : SubjectName::SubjectName(const std::string& in, bool permissive)
14 : {
15 0 : parse(in, permissive);
16 0 : }
17 :
18 52 : SubjectName::SubjectName(const char* in, bool permissive)
19 : {
20 52 : parse(in, permissive);
21 52 : }
22 :
23 34 : int SubjectName::parse(const std::string& in, bool permissive)
24 : {
25 34 : return parse(in.data(), permissive);
26 : }
27 :
28 117 : int SubjectName::parse(const char* in, bool permissive)
29 : {
30 117 : if (in == NULL) {
31 0 : return -1;
32 : }
33 :
34 : // For now, assume ASCII encoding and not UTF-8
35 117 : if (permissive) {
36 0 : return parse_permissive(in);
37 : } else {
38 117 : if (in[0] == '/') {
39 74 : return parse_dce(in);
40 : } else {
41 43 : return parse_ldap_v3(in);
42 : }
43 : }
44 : }
45 :
46 117 : 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 117 : std::string input(in);
51 117 : size_t input_end = input.size() - 1;
52 117 : 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 117 : size_t st_begin = 0;
64 117 : size_t st_end = input.find_first_of(s_del);
65 :
66 : // Loop over all the sequence tokens
67 738 : while (st_begin != std::string::npos) {
68 : std::string st = input.substr(
69 : st_begin,
70 621 : (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 621 : size_t st_begin_clean = st.find_first_not_of(s_trim);
75 621 : size_t st_end_clean = st.find_last_not_of(s_trim);
76 :
77 : // If we've found a clean sequence token
78 621 : if (st_begin_clean != std::string::npos &&
79 : st_end_clean != std::string::npos) {
80 : std::string st_clean =
81 547 : 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 547 : size_t nt_begin = 0;
85 547 : size_t nt_end = st_clean.find_first_of(a_del);
86 :
87 : // If we actually found a delimiter
88 547 : if (nt_end != std::string::npos) {
89 547 : --nt_end;
90 :
91 547 : std::string nt = st_clean.substr(nt_begin, nt_end - nt_begin + 1);
92 :
93 547 : size_t nt_begin_clean = nt.find_first_not_of(a_trim);
94 547 : size_t nt_end_clean = nt.find_last_not_of(a_trim);
95 :
96 : // If we found a clean name token
97 547 : if (nt_begin_clean != std::string::npos &&
98 : nt_end_clean != std::string::npos) {
99 : std::string nt_clean =
100 547 : 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 547 : size_t vt_begin = nt_end + 2; // Skip over the (single) delimiter
104 547 : size_t vt_end = st_clean.size() - 1;
105 :
106 547 : std::string vt = st_clean.substr(vt_begin, vt_end - vt_begin + 1);
107 :
108 547 : size_t vt_begin_clean = vt.find_first_not_of(a_trim);
109 547 : size_t vt_end_clean = vt.find_last_not_of(a_trim);
110 :
111 : // If we found a clean value token
112 547 : if (vt_begin_clean != std::string::npos &&
113 : vt_end_clean != std::string::npos) {
114 : std::string vt_clean =
115 547 : vt.substr(vt_begin_clean, vt_end_clean - vt_begin_clean + 1);
116 :
117 : // Push our clean pair into the map
118 547 : map_[nt_clean] = vt_clean;
119 547 : }
120 547 : }
121 547 : }
122 547 : }
123 :
124 : // Prepare for next iteration of loop
125 621 : if (st_end == std::string::npos) {
126 117 : st_begin = std::string::npos;
127 : } else {
128 504 : st_begin = st_end + 1;
129 504 : st_end = input.find_first_of(s_del, st_begin);
130 : }
131 621 : }
132 :
133 234 : return map_.empty() ? 1 : 0;
134 117 : }
135 :
136 0 : int SubjectName::parse_permissive(const char* in)
137 : {
138 0 : return simple_avp_seq_parse(in, ",/", "=", " ", " ", false);
139 : }
140 :
141 74 : int SubjectName::parse_dce(const char* in)
142 : {
143 74 : return simple_avp_seq_parse(in, "/", "=", " ", " ", true);
144 : }
145 :
146 43 : int SubjectName::parse_ldap_v3(const char* in)
147 : {
148 43 : return simple_avp_seq_parse(in, ",", "=", " ", " ", false);
149 : }
150 :
151 46 : bool SubjectName::operator==(const SubjectName& rhs) const
152 : {
153 46 : bool result = (map_.size() == rhs.map_.size());
154 46 : for (AttrMap::const_iterator i1 = map_.begin(), i2 = rhs.map_.begin();
155 239 : result == true && i1 != map_.end() && i2 != rhs.map_.end();
156 193 : ++i1, ++i2) {
157 386 : if (i1->first.compare(i2->first) != 0 ||
158 193 : i1->second.compare(i2->second) != 0) {
159 0 : result = false;
160 : }
161 : }
162 46 : return result;
163 : }
164 :
165 0 : bool SubjectName::operator!=(const SubjectName& rhs) const
166 : {
167 0 : return !(*this == rhs);
168 : }
169 :
170 : } // namespace SSL
171 : } // namespace Security
172 : } // namespace OpenDDS
173 :
174 : OPENDDS_END_VERSIONED_NAMESPACE_DECL
|