3 * Copyright (c) 2019-2020 Samsung Electronics Co., Ltd
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is furnished
10 * to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 #include "internal/include/fb_generated.h"
23 #include "internal/include/flatbuffers/flatbuffers.h"
24 #include "internal/policy_containers.hpp"
25 #include "internal/serializer.hpp"
30 namespace ldp_xml_parser {
32 static void print_error(const char *fmt...) {
41 std::map<FB::MessageType, const char *> messageTypeMap = {
42 { FB::MessageType_ANY, "ANY" },
43 { FB::MessageType_MIN, "MIN" },
44 { FB::MessageType_MAX, "MAX" },
45 { FB::MessageType_METHOD_RETURN, "METHOD_RETURN" },
46 { FB::MessageType_ERROR, "ERROR" },
47 { FB::MessageType_SIGNAL, "SIGNAL" },
48 { FB::MessageType_METHOD_CALL, "METHOD_CALL" }
51 std::map<FB::Decision, const char *> decisionTypeMap = {
52 { FB::Decision_ANY, "ANY" },
53 { FB::Decision_MIN, "MIN" },
54 { FB::Decision_MAX, "MAX" },
55 { FB::Decision_CHECK, "CHECK" },
56 { FB::Decision_DENY, "DENY" },
57 { FB::Decision_ALLOW, "ALLOW" }
60 std::map<FB::BusAccessType, const char *> busTypeMap = {
61 { FB::BusAccessType_MIN, "MIN" },
62 { FB::BusAccessType_MAX, "MAX" },
63 { FB::BusAccessType_USER, "USER" },
64 { FB::BusAccessType_GROUP, "GROUP" },
65 { FB::BusAccessType_ALL_USERS, "ALL_USERS" },
66 { FB::BusAccessType_ALL_GROUPS, "ALL_GROUPS" },
70 static const char *to_str(const bool value) {
71 return value ? "true" : "false";
74 static const char *to_str(const char *value) {
78 static const char *to_str(const std::string & value) {
82 static const char *to_str(const FB::MessageType value) {
83 return messageTypeMap[value];
86 static const char *to_str(const FB::Decision value) {
87 return decisionTypeMap[value];
90 static const char *to_str(const FB::BusAccessType value) {
91 return busTypeMap[value];
95 static bool compare(const T current, const T expected) {
96 if (current != expected) {
97 // print_error("Current: \"%s\" expected: \"%s\"", to_str(current), to_str(expected));
103 template <typename T>
104 static void print_property(const char *name, const T value) {
105 std::cout << name << ": " << to_str(value) << std::endl;
109 using TH = TestsHelper;
112 const std::string name;
113 const std::string privilege;
114 const FB::Decision decision;
115 const std::string prefix_privilege;
116 const FB::Decision prefix_decision;
118 void printContent() const {
119 TH::print_property("name", name);
120 TH::print_property("privilege", privilege);
121 TH::print_property("decision", decision);
122 TH::print_property("prefix_privilege", prefix_privilege);
123 TH::print_property("prefix_decision", prefix_decision);
126 bool isMatch(const FB::PolicyOwnNode *node, const std::string &token) const {
127 return (TH::compare(node->token()->str(), token) &&
128 TH::compare(node->decision_item()->privilege()->str(), privilege) &&
129 TH::compare(node->decision_item()->decision(), decision) &&
130 TH::compare(node->prefix_decision_item()->privilege()->str(), prefix_privilege) &&
131 TH::compare(node->prefix_decision_item()->decision(), prefix_decision));
136 const std::string name;
137 const std::string interface;
138 const std::string member;
139 const std::string path;
140 const FB::MessageType type;
141 const bool is_name_prefix;
142 const FB::Decision decision;
144 void printContent() const {
145 TH::print_property("name", name);
146 TH::print_property("interface", interface);
147 TH::print_property("member", member);
148 TH::print_property("path", path);
149 TH::print_property("type", type);
150 TH::print_property("is_name_prefix", is_name_prefix);
151 TH::print_property("decision", decision);
154 template <typename T>
155 bool isMatch(const T *item) const {
156 return TH::compare(item->name()->str(), name) &&
157 TH::compare(item->interface()->str(), interface) &&
158 TH::compare(item->member()->str(), member) &&
159 TH::compare(item->path()->str(), path) &&
160 TH::compare(item->type(), type) &&
161 TH::compare(item->is_name_prefix(), is_name_prefix) &&
162 TH::compare(item->decision()->decision(), decision);
166 struct ItemAccessTest {
169 const FB::Decision decision;
170 const std::string privilege;
171 const FB::BusAccessType type;
173 void printContent() const {
174 TH::print_property("uid", uid);
175 TH::print_property("gid", gid);
176 TH::print_property("decision", decision);
177 TH::print_property("privilege", privilege);
178 TH::print_property("type", type);
181 bool isMatch(const FB::ItemAccess *item) const {
182 return TH::compare(item->uid(), uid) &&
183 TH::compare(item->gid(), gid) &&
184 TH::compare(item->decision()->decision(), decision) &&
185 TH::compare(item->decision()->privilege()->str(), privilege) &&
186 TH::compare(item->type(), type);
191 std::vector<NodeTest> context_default_tests = {
192 { "org", "", FB::Decision_ANY, "", FB::Decision_ANY },
193 { "org.tizen", "", FB::Decision_ANY, "", FB::Decision_ANY },
194 { "org.tizen.pok2", "", FB::Decision_ANY, "privilege1", FB::Decision_CHECK },
195 { "org.tizen.pok2.a", "", FB::Decision_ANY, "", FB::Decision_DENY },
196 { "org.tizen.pok2.a.b", "", FB::Decision_ANY, "privilege2", FB::Decision_CHECK },
197 { "org.tizen.pnope", "http://tizen.org/privilege/packagemanager.nope", FB::Decision_CHECK, "", FB::Decision_ANY },
198 { "org.tizen.pok1.a1", "http://tizen.org/privilege/packagemanager.nope", FB::Decision_CHECK, "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK },
199 { "org.tizen.pok1.a", "", FB::Decision_ANY, "", FB::Decision_DENY },
200 { "org.tizen.pok1.a.b4", "http://tizen.org/privilege/packagemanager.nope", FB::Decision_CHECK, "", FB::Decision_ANY },
201 { "org.tizen.pok1.a.b3", "", FB::Decision_ANY, "http://tizen.org/privilege/packagemanager.nope", FB::Decision_CHECK },
202 { "org.tizen.pok1.a.b2", "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK, "", FB::Decision_ANY },
203 { "org.tizen.pok1.a.b1", "", FB::Decision_ANY, "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK },
204 { "org.tizen.pok", "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK, "", FB::Decision_ANY },
207 std::vector<NodeTest> context_mandatory_tests = {};
209 std::vector<NodeTest> user_root_tests = {
210 { "org", "", FB::Decision_ANY, "", FB::Decision_ANY },
211 { "org.tizen", "", FB::Decision_ANY, "", FB::Decision_ANY },
212 { "org.tizen.a1", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
213 { "org.tizen.a1.b", "", FB::Decision_DENY, "", FB::Decision_ANY },
214 { "org.tizen.b", "", FB::Decision_ANY, "", FB::Decision_ANY },
215 { "org.tizen.b.z", "", FB::Decision_ALLOW, "", FB::Decision_ANY },
216 { "org.tizen.b.c", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
217 { "org.tizen.a", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
218 { "org.tizen.a.d", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
219 { "org.tizen.a.c", "", FB::Decision_DENY, "", FB::Decision_ALLOW },
220 { "org.tizen.a.b", "", FB::Decision_ANY, "", FB::Decision_DENY },
221 { "org.tizen.a.b.c2", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
222 { "org.tizen.a.b.c1", "", FB::Decision_ANY, "", FB::Decision_DENY },
223 { "org.tizen.a.b.c1.d", "", FB::Decision_ANY, "", FB::Decision_ANY },
224 { "org.tizen.a.b.c1.d.e", "", FB::Decision_ANY, "", FB::Decision_ANY },
225 { "org.tizen.a.b.c1.d.e.f", "", FB::Decision_ANY, "", FB::Decision_ANY },
226 { "org.tizen.a.b.c1.d.e.f.g", "", FB::Decision_ALLOW, "", FB::Decision_ANY },
227 { "org.tizen.a.b.c3", "", FB::Decision_DENY, "", FB::Decision_ALLOW },
228 { "org.tizen.a.b.c3.d", "", FB::Decision_ANY, "", FB::Decision_DENY },
229 { "org.tizen.a.b.c3.d.esth", "", FB::Decision_ALLOW, "", FB::Decision_ANY },
230 { "org.tizen.a.b.c3.d.e", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
231 { "org.tizen.a.b.c3.d.e.f", "", FB::Decision_DENY, "", FB::Decision_ANY },
232 { "org.tizen.a.b.c3.d.e.f.g", "", FB::Decision_ALLOW, "", FB::Decision_ANY },
233 { "org.tizen.a.b.c", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
234 { "org.tizen.a.b.c.d", "", FB::Decision_ANY, "", FB::Decision_DENY },
235 { "org.tizen.a.b.c.d.esth", "", FB::Decision_ALLOW, "", FB::Decision_ANY },
236 { "org.tizen.a.b.c.d.e", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
237 { "org.tizen.a.b.c.d.e.f", "", FB::Decision_DENY, "", FB::Decision_ANY },
238 { "org.tizen.a.bsth", "", FB::Decision_DENY, "", FB::Decision_ANY },
239 { "org.tizen.ldposd", "", FB::Decision_ALLOW, "", FB::Decision_ANY },
240 { "org.tizen.ldposa", "", FB::Decision_ALLOW, "", FB::Decision_ANY },
241 { "org.tizen.test", "", FB::Decision_ANY, "", FB::Decision_ANY },
242 { "org.tizen.test.dest_prefix", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
243 { "org.tizen.ldpoga", "", FB::Decision_ALLOW, "", FB::Decision_ANY },
244 { "org.tizen.ldpo", "", FB::Decision_ANY, "", FB::Decision_ALLOW },
245 { "org.tizen.ldpogd", "", FB::Decision_ALLOW, "", FB::Decision_ANY },
248 std::vector<ItemSRTest> item_send_context_default_tests {
249 { "", "", "", "", FB::MessageType_METHOD_CALL, false, FB::Decision_DENY },
250 { "org.freedesktop.DBus", "org.freedesktop.DBus", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
251 { "org.freedesktop.DBus", "org.freedesktop.DBus.Introspectable", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
252 { "org.freedesktop.DBus", "org.freedesktop.DBus", "UpdateActivationEnvironment", "", FB::MessageType_ANY, false, FB::Decision_DENY },
253 { "org.freedesktop.DBus", "org.freedesktop.DBus.Debug.Stats", "", "", FB::MessageType_ANY, false, FB::Decision_DENY },
254 { "org.freedesktop.DBus", "org.freedesktop.systemd1.Activator", "", "", FB::MessageType_ANY, false, FB::Decision_DENY },
257 std::vector<ItemSRTest> item_receive_context_default_test {
258 { "", "", "", "", FB::MessageType_METHOD_CALL, false, FB::Decision_ALLOW },
259 { "", "", "", "", FB::MessageType_METHOD_RETURN, false, FB::Decision_ALLOW },
260 { "", "", "", "", FB::MessageType_ERROR, false, FB::Decision_ALLOW },
261 { "", "", "", "", FB::MessageType_SIGNAL, false, FB::Decision_ALLOW },
264 std::vector<ItemSRTest> item_send_root_tests {
265 { "org.tizen.test.dest_prefix.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
266 { "org.tizen.test.dest_prefix.ao", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
267 { "org.tizen.test.dest_prefix.ap.1.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY },
268 { "org.tizen.test.dest_prefix.ap.1.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
269 { "org.tizen.test.dest_prefix.ap.1.d.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
270 { "org.tizen.test.dest_prefix.ap.1.dp.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
271 { "org.tizen.test.dest_prefix.ap.1.dp.a", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
273 { "org.tizen.test.dest_prefix.ap.2.apxdp", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
274 { "org.tizen.test.dest_prefix.ap.2.apxdp.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
275 { "org.tizen.test.dest_prefix.ap.2.apxdp.dp.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
276 { "org.tizen.test.dest_prefix.ap.2.apxdp.dp.ap.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY },
278 { "org.tizen.test.dest_prefix.ap.3.dpxap", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
279 { "org.tizen.test.dest_prefix.ap.3.dpxap.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
280 { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
281 { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
282 { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp.a", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
283 { "org.tizen.test.dest_prefix.ap.3.dpxap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
285 { "org.tizen.test.dest_prefix.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
287 { "org.tizen.test.dest_prefix.do", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY },
288 { "org.tizen.test.dest_prefix.ao.ao", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
290 { "org.tizen.test.dest_prefix.dp.1.a", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
291 { "org.tizen.test.dest_prefix.dp.1.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
293 { "org.tizen.test.dest_prefix.dp.1.a.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
294 { "org.tizen.test.dest_prefix.dp.1.ap.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
295 { "org.tizen.test.dest_prefix.dp.1.ap.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY },
297 { "org.tizen.test.dest_prefix.dp.2.dpxap", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
298 { "org.tizen.test.dest_prefix.dp.2.dpxap.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
299 { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
300 { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp.a", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
302 { "org.tizen.test.dest_prefix.dp.2.dpxap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
303 { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY },
304 { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp.f.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY },
305 { "org.tizen.test.dest_prefix.dp.2.dpxap.f.f.f.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
307 { "org.tizen.test.dest_prefix.dp.3.apxdp", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
308 { "org.tizen.test.dest_prefix.dp.3.apxdp.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
309 { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW },
310 { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
311 { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY },
312 { "org.tizen.test.dest_prefix.dp.3.apxdp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY },
316 std::vector<ItemAccessTest> item_access_context_default_test {
317 { 0, 0, FB::Decision_ALLOW, "", FB::BusAccessType_ALL_USERS },
318 { 1, 0, FB::Decision_DENY, "", FB::BusAccessType_USER },
319 { 2, 0, FB::Decision_DENY, "", FB::BusAccessType_USER },
320 { 0, 20, FB::Decision_ALLOW, "", FB::BusAccessType_GROUP },
321 { 0, 30, FB::Decision_DENY, "", FB::BusAccessType_GROUP },
322 { 3, 0, FB::Decision_ALLOW, "", FB::BusAccessType_USER },
323 { 7, 0, FB::Decision_ALLOW, "", FB::BusAccessType_USER },
324 { 8, 0, FB::Decision_DENY, "", FB::BusAccessType_USER },
325 { 9991, 0, FB::Decision_CHECK, "privilege1", FB::BusAccessType_USER },
326 { 9992, 0, FB::Decision_CHECK, "privilege2", FB::BusAccessType_USER },
327 { 9993, 0, FB::Decision_CHECK, "privilege1", FB::BusAccessType_USER },
328 { 888, 0, FB::Decision_CHECK, "privilege1", FB::BusAccessType_USER },
332 std::vector<ItemAccessTest> item_access_context_mandatory_test {
333 { 6, 0, FB::Decision_DENY, "", FB::BusAccessType_USER },
334 { 7, 0, FB::Decision_DENY, "", FB::BusAccessType_USER },
335 { 8, 0, FB::Decision_ALLOW, "", FB::BusAccessType_USER },
336 { 0, 9992, FB::Decision_CHECK, "privilege1", FB::BusAccessType_GROUP },
337 { 9993, 0, FB::Decision_CHECK, "privilege2", FB::BusAccessType_USER },
340 class SerializerTests {
341 ldp_serializer::Serializer serializer;
342 const FB::File *file;
344 void serialize_xml(const std::string &file_name) {
346 auto buff = serializer.serialize(file_name, size);
348 file = FB::GetFile(buff);
351 bool check_tree(const std::string &token, const FB::PolicyOwnNode *nnode, const NodeTest &test) {
352 size_t dot = token.find('.');
353 if (dot == std::string::npos) {
354 auto node = nnode->children()->LookupByKey(token.c_str());
355 if (node == nullptr) {
356 print_error("node %s not found for:", TH::to_str(token));
361 if (!test.isMatch(node, token)) {
362 print_error("No matching child found for test:");
369 std::string part = token.substr(0, dot);
370 std::string rest = token.substr(dot + 1);
372 auto new_node = nnode->children()->LookupByKey(part.c_str());
373 if (new_node == nullptr) {
374 print_error("node %s not found", TH::to_str(part));
377 return check_tree(rest, new_node, test);
381 bool check_tree(const FB::PolicyOwnNode *tree, const std::vector<NodeTest> &tree_tests) {
382 for (const auto &test : tree_tests) {
383 if (!check_tree(test.name, tree, test))
389 bool check_own_set() {
390 return check_tree(file->m_own_set()->context_default()->tree(), context_default_tests) &&
391 check_tree(file->m_own_set()->context_mandatory()->tree(), context_mandatory_tests) &&
392 check_tree(file->m_own_set()->user()->LookupByKey(0)->policy()->tree(), user_root_tests);
395 template <typename T, typename U>
396 bool checkPolicy(const T *policy, const std::vector<U> &tests) {
397 for (const auto &test : tests) {
399 for (const auto &item : *policy->items()) {
400 if (test.isMatch(item)) {
406 print_error("No matching item found for test:");
414 bool check_send_set() {
415 return checkPolicy(file->m_send_set()->context_default(), item_send_context_default_tests) &&
416 checkPolicy(file->m_send_set()->user()->LookupByKey(0)->policy(), item_send_root_tests);
419 bool check_receive_set() {
420 return checkPolicy(file->m_receive_set()->context_default(), item_receive_context_default_test);
423 bool check_access_set() {
424 return checkPolicy(file->m_access_set()->context_default(), item_access_context_default_test) &&
425 checkPolicy(file->m_access_set()->context_mandatory(), item_access_context_mandatory_test);
429 SerializerTests() : file(nullptr) {}
430 bool run_all_tests(const std::string &config) {
431 serialize_xml(config);
433 return check_own_set() &&
435 check_receive_set() &&
442 auto st = ldp_xml_parser::SerializerTests();
443 if (st.run_all_tests("tests/default_deny/system.conf"))