From ca1b3b3078202c243a890fcb75e60591ac2f2315 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 27 Oct 2020 12:14:10 +0100 Subject: [PATCH 01/16] refactoring: extract common file operations to StorageBackendSerialized Change-Id: I0a3fd26342482d747f44aae08ece46bb2b40a4fc --- Makefile.am | 1 + src/internal/storage_backend_flatbuffers.cpp | 114 ---------------------- src/internal/storage_backend_flatbuffers.hpp | 4 +- src/internal/storage_backend_serialized.cpp | 136 +++++++++++++++++++++++++++ src/internal/storage_backend_serialized.hpp | 60 +++++++++++- 5 files changed, 197 insertions(+), 118 deletions(-) create mode 100644 src/internal/storage_backend_serialized.cpp diff --git a/Makefile.am b/Makefile.am index 0c88727..1848ecd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -66,6 +66,7 @@ COMMON_SRC =\ src/internal/serializer_flatbuffers.cpp \ src/internal/print_content.cpp \ src/internal/storage_backend_flatbuffers.cpp \ + src/internal/storage_backend_serialized.cpp \ src/internal/storage_backend_xml.cpp src_libdbuspolicy1_la_SOURCES =\ diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index b0c6933..4867185 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -16,29 +16,16 @@ #include "include/fb_generated.h" #include "print_content.hpp" #include "serialized_convert.hpp" -#include "serializer.hpp" #include "storage_backend_flatbuffers.hpp" -#include "transaction_guard.hpp" #include "tslog.hpp" #include -#include -#include -#include #include -#include -#include -#include -#include using namespace FB; using ldp_xml_parser::MatchItemSend; namespace ldp_serialized { -// Set max size of serialized file to prevent mmap with unexpected memory size. -// 1MB. Adjustable -#define MAX_SFILE_SIZE (1024 * 1024) - typedef boost::tokenizer> tokenizer; template @@ -124,20 +111,10 @@ ldp_xml_parser::DecisionItem getDecisionItemMaybeNull(const T &item, const P *po } // anonymous namespace class StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl { - int fd{-1}; - uint8_t *mem{static_cast(MAP_FAILED)}; - size_t length{0}; const FB::File *file{nullptr}; - std::unique_ptr serializer; - - void releaseMMap(); - void releaseFD(); - public: - bool init(const char *filename, bool verify); bool initFromData(const uint8_t *mem, size_t size, bool verify); - bool initFromXML(const char *config_name); void release(); ldp_xml_parser::DecisionItem getDecisionFromSendIndex(const MatchItemSend &item, const FB::PolicySend *policy); @@ -217,79 +194,10 @@ ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::StorageBackendFlatbuffer return ldp_xml_parser::DecisionItem(ldp_xml_parser::Decision::ANY); } -void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::releaseMMap() { - assert(MAP_FAILED != mem); - assert(0 != length); - - if (munmap(mem, length) != 0) - tslog::log_error("munmap(): ", tslog::print_errno(errno), "\n"); - - mem = static_cast(MAP_FAILED); - length = 0; -} - -void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::releaseFD() { - assert(-1 != fd); - - if (close(fd) != 0) - tslog::log_error("close(): ", tslog::print_errno(errno), "\n"); - - fd = -1; -} - void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::release() { - if (-1 != fd) { // we need to check it, because we may have initialized the storage directly from File * - releaseMMap(); - releaseFD(); - } - - if (nullptr != serializer.get()) { - serializer.reset(nullptr); - } - file = nullptr; } -bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::init(const char *filename, bool verify) { - assert(nullptr == file); - - auto err = [filename] (const char *what) { - tslog::log_error("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n"); - return false; - }; - - fd = open(filename, O_RDONLY); - if (-1 == fd) - return err("open"); - - auto openGuard = transaction_guard::makeGuard([&] () { releaseFD(); }); - - struct stat buf; - - if (fstat(fd, &buf) == -1) - return err("stat"); - - length = buf.st_size; - if (length > MAX_SFILE_SIZE) { - tslog::log_error("Serialized file size(", length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n"); - return false; - } - - mem = reinterpret_cast(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0)); - if (MAP_FAILED == mem) - return err("mmap"); - - auto mmapGuard = transaction_guard::makeGuard([&] () { releaseMMap(); }); - - if (!initFromData(mem, length, verify)) - return false; - - openGuard.dismiss(); - mmapGuard.dismiss(); - - return true; -} - bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromData(const uint8_t *mem, size_t size, bool verify) { assert(nullptr == file); @@ -314,20 +222,6 @@ bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromData(cons return file != nullptr; } -bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromXML(const char *config_name) { - assert(nullptr == file); - assert(nullptr == serializer.get()); - - serializer.reset(new ldp_serializer::Serializer()); - - size_t serialized_size; - auto data = serializer->serialize(config_name, serialized_size); - if (nullptr == data) - return false; - - return initFromData(data, serialized_size, false); -} - void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::printContent(const bool xml_format) const { print_content::use_xml_format(xml_format); std::cerr << *file; @@ -353,18 +247,10 @@ TYPE_HELPER(Send, send) TYPE_HELPER(Receive, receive) TYPE_HELPER(Access, access) -bool StorageBackendFlatbuffers::init(const char *filename, bool verify) { - return pimpl->init(filename, verify); -} - bool StorageBackendFlatbuffers::initFromData(const uint8_t *serialized_data, size_t length, bool verify) { return pimpl->initFromData(serialized_data, length, verify); } -bool StorageBackendFlatbuffers::initFromXML(const char *config_name) { - return pimpl->initFromXML(config_name); -} - void StorageBackendFlatbuffers::release() { pimpl->release(); } diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index aaba006..6bdd707 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -28,9 +28,7 @@ public: StorageBackendFlatbuffers(); ~StorageBackendFlatbuffers(); - bool init(const char *filename, bool verify = false); - bool initFromData(const uint8_t *serialized_data, size_t length, bool verify = false); - bool initFromXML(const char *config_name); + bool initFromData(const uint8_t *serialized_data, size_t length, bool verify); void release(); void printContent(const bool xml_format = false) const; diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp new file mode 100644 index 0000000..f9fb54f --- /dev/null +++ b/src/internal/storage_backend_serialized.cpp @@ -0,0 +1,136 @@ +/* MIT License + * + * Copyright (c) 2019-2020 Samsung Electronics Co., Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#include "storage_backend_serialized.hpp" +#include "transaction_guard.hpp" +#include "tslog.hpp" +#include +#include +#include +#include +#include +#include + +using namespace ldp_serialized; + +const size_t StorageBackendSerialized::MAX_SFILE_SIZE; + +StorageBackendSerialized::StorageBackendSerialized() +: __mem{static_cast(MAP_FAILED)} +{ +} + +StorageBackendSerialized::~StorageBackendSerialized() { + if (-1 != __fd) { + releaseMMap(); + releaseFD(); + } +} + +bool StorageBackendSerialized::init(const char *filename, bool verify) +{ + auto err = [filename] (const char *what) { + tslog::log_error("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n"); + return false; + }; + + __fd = open(filename, O_RDONLY); + if (-1 == __fd) + return err("open"); + + auto openGuard = transaction_guard::makeGuard([&] () { releaseFD(); }); + + struct stat buf; + + if (fstat(__fd, &buf) == -1) + return err("stat"); + + __length = buf.st_size; + if (__length > MAX_SFILE_SIZE) { + tslog::log_error("Serialized file size(", __length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n"); + return false; + } + + __mem = reinterpret_cast(mmap(NULL, __length, PROT_READ, MAP_PRIVATE, __fd, 0)); + if (MAP_FAILED == __mem) + return err("mmap"); + + auto mmapGuard = transaction_guard::makeGuard([&] () { releaseMMap(); }); + + if (!initFromData(__mem, __length, verify)) + return false; + + openGuard.dismiss(); + mmapGuard.dismiss(); + + return true; +} + +bool StorageBackendSerialized::initFromData(const uint8_t *serialized_data, size_t length, bool verify) +{ + return impl.initFromData(serialized_data, length, verify); +} + +void StorageBackendSerialized::releaseMMap() { + assert(MAP_FAILED != __mem); + assert(0 != __length); + + if (munmap(__mem, __length) != 0) + tslog::log_error("munmap(): ", tslog::print_errno(errno), "\n"); + + __mem = static_cast(MAP_FAILED); + __length = 0; +} + +bool StorageBackendSerialized::initFromXML(const char *config_name) { + assert(nullptr == serializer.get()); + + serializer.reset(new ldp_serializer::Serializer()); + + size_t serialized_size; + auto data = serializer->serialize(config_name, serialized_size); + if (nullptr == data) + return false; + + return initFromData(data, serialized_size, false); +} + +void StorageBackendSerialized::releaseFD() { + assert(-1 != __fd); + + if (close(__fd) != 0) + tslog::log_error("close(): ", tslog::print_errno(errno), "\n"); + + __fd = -1; +} + +void StorageBackendSerialized::release() { + if (-1 != __fd) { + releaseMMap(); + releaseFD(); + } + + if (nullptr != serializer.get()) + serializer.reset(nullptr); + + impl.release(); +} diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp index c3406ac..dc3a861 100644 --- a/src/internal/storage_backend_serialized.hpp +++ b/src/internal/storage_backend_serialized.hpp @@ -21,8 +21,66 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "policy.hpp" #include "storage_backend_flatbuffers.hpp" +#include "serializer.hpp" +#include +#include namespace ldp_serialized { -using StorageBackendSerialized = StorageBackendFlatbuffers; + +class StorageBackendSerialized +{ +public: + StorageBackendSerialized(); + ~StorageBackendSerialized(); + + bool init(const char *filename, bool verify = false); + bool initFromData(const uint8_t *serialized_data, size_t length, bool verify = false); + bool initFromXML(const char *config_name); + void release(); + + void printContent(bool xml_format = false) const + { impl.printContent(xml_format); } + + // Supported template parameters are: + // MatchItemOwn, MatchItemSend, MatchItemReceive + // and - only for Contexts - MatchItemAccess + template + ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const MatchItem &item) const + { return impl.getDecisionItemContextMandatory(item); } + template + ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const MatchItem &item) const + { return impl.getDecisionItemContextDefault(item); } + template + ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const MatchItem &item) const + { return impl.getDecisionItemUser(uid, item); } + template + ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const MatchItem &item) const + { return impl.getDecisionItemGroup(gid, item); } + + // This works with MatchItem set to MatchItemOwn, MatchItemSend or MatchItemReceive + // This is needed for filtering mapGroups. Check NaivePolicyChecker. + template + bool existsPolicyForGroup(gid_t gid) const + { return impl.existsPolicyForGroup(gid); } + +private: + typedef StorageBackendFlatbuffers Backend; + Backend impl; + + // Set max size of serialized file to prevent mmap with unexpected memory size. + // 1MB. Adjustable + static const size_t MAX_SFILE_SIZE{1024 * 1024}; + + int __fd{-1}; + uint8_t *__mem; + size_t __length{0}; + + std::unique_ptr serializer; + + void releaseMMap(); + void releaseFD(); +}; + } -- 2.7.4 From c68a65507bb78b99f267169b28bca93a01fbc25f Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 27 Oct 2020 12:32:03 +0100 Subject: [PATCH 02/16] serialization: add SerializationBackend type Add SerializationBackend type, which is a customization point for choosing serialization backend. At the moment it is set to Flatbuffers. It is the place to select another backend, when it shows up. Change-Id: I2a54f643d5c5bda065fcd193c51ca928f20df203 --- src/internal/serialization_backend.hpp | 37 +++++++++++++++++++++++++++++ src/internal/serializer.hpp | 4 ++-- src/internal/storage_backend_serialized.hpp | 4 ++-- 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 src/internal/serialization_backend.hpp diff --git a/src/internal/serialization_backend.hpp b/src/internal/serialization_backend.hpp new file mode 100644 index 0000000..2b3395a --- /dev/null +++ b/src/internal/serialization_backend.hpp @@ -0,0 +1,37 @@ +#pragma once + +/* MIT License + * + * Copyright (c) 2020 Samsung Electronics Co., Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#include "serializer_flatbuffers.hpp" +#include "storage_backend_flatbuffers.hpp" + +namespace ldp_serialization { + +struct SerializationBackendFlatbuffers { + typedef ldp_serialized::StorageBackendFlatbuffers Storage; + typedef ldp_serializer::SerializerFlatbuffers Serializer; +}; + +typedef SerializationBackendFlatbuffers SerializationBackend; + +} diff --git a/src/internal/serializer.hpp b/src/internal/serializer.hpp index 34c8c9f..e087017 100644 --- a/src/internal/serializer.hpp +++ b/src/internal/serializer.hpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "serializer_flatbuffers.hpp" +#include "serialization_backend.hpp" #include #include @@ -33,7 +33,7 @@ namespace ldp_serializer { class Serializer { - SerializerFlatbuffers impl; + ldp_serialization::SerializationBackend::Serializer impl; public: auto serialize(const ldp_xml::StorageBackendXML &db, size_t &size) { return impl.serialize(db, size); diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp index dc3a861..9a498b5 100644 --- a/src/internal/storage_backend_serialized.hpp +++ b/src/internal/storage_backend_serialized.hpp @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #include "policy.hpp" -#include "storage_backend_flatbuffers.hpp" +#include "serialization_backend.hpp" #include "serializer.hpp" #include #include @@ -66,7 +66,7 @@ public: { return impl.existsPolicyForGroup(gid); } private: - typedef StorageBackendFlatbuffers Backend; + typedef typename ldp_serialization::SerializationBackend::Storage Backend; Backend impl; // Set max size of serialized file to prevent mmap with unexpected memory size. -- 2.7.4 From 4226eab1c76e8d2c8a6edf35e40b82b45f66d729 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 27 Oct 2020 12:41:21 +0100 Subject: [PATCH 03/16] refactoring: print 'serialized' instead of 'flatbuffers' Change-Id: I262f6345277133bb1c0ea16d270a38bfa066695b --- src/dbuspolicy-verifier | 2 +- src/stest_performance.cpp | 2 +- src/test-libdbuspolicy1-access-deny-gdi.cpp | 2 +- src/test-libdbuspolicy1-method-gdi.cpp | 2 +- src/test-libdbuspolicy1-ownership-gdi.cpp | 2 +- src/test-libdbuspolicy1-send_destination_prefix-deny-gdi.cpp | 2 +- src/test-libdbuspolicy1-signal-gdi.cpp | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dbuspolicy-verifier b/src/dbuspolicy-verifier index 4b06995..3a99f9c 100755 --- a/src/dbuspolicy-verifier +++ b/src/dbuspolicy-verifier @@ -24,7 +24,7 @@ do echo Verifying SHA1... sha1sum -c $FNAME.sha1 - echo Verifying FlatBuffers structure... + echo Verifying serialized file structure... dbuspolicy-printer $1 -v shift done diff --git a/src/stest_performance.cpp b/src/stest_performance.cpp index 30a8a56..8d96316 100644 --- a/src/stest_performance.cpp +++ b/src/stest_performance.cpp @@ -224,7 +224,7 @@ void run_fb(const char *conf_file, bool verify, size_t count, bool worst) { StorageBackendSerialized storage; storage.initFromData(buff, size); - printf("FLATBUFFERS:\n"); + printf("SERIALIZED:\n"); if (!worst) run_x_times([&storage](){ send_prefix_test(storage, tests); }, count); else diff --git a/src/test-libdbuspolicy1-access-deny-gdi.cpp b/src/test-libdbuspolicy1-access-deny-gdi.cpp index 7dd22da..515959a 100644 --- a/src/test-libdbuspolicy1-access-deny-gdi.cpp +++ b/src/test-libdbuspolicy1-access-deny-gdi.cpp @@ -172,7 +172,7 @@ bool run_fb(const std::pair access_test) { ldp_serialized::StorageBackendSerialized storage_sys, storage_ses; - printf("FLATBUFFERS:\n"); + printf("SERIALIZED:\n"); storage_sys.initFromData(buff_sys, size_sys); bool res = run_tests_for_bus(storage_sys, policy_checker_system(), system_bus_setup.second, i, passed); diff --git a/src/test-libdbuspolicy1-method-gdi.cpp b/src/test-libdbuspolicy1-method-gdi.cpp index 800a4df..eb3b79d 100644 --- a/src/test-libdbuspolicy1-method-gdi.cpp +++ b/src/test-libdbuspolicy1-method-gdi.cpp @@ -151,7 +151,7 @@ bool run_fb() { ldp_serialized::StorageBackendSerialized storage; storage.initFromData(buff, size); - printf("FLATBUFFERS:\n"); + printf("SERIALIZED:\n"); bool ret = method_test(storage); return ret; } diff --git a/src/test-libdbuspolicy1-ownership-gdi.cpp b/src/test-libdbuspolicy1-ownership-gdi.cpp index ad8b8f6..9236221 100644 --- a/src/test-libdbuspolicy1-ownership-gdi.cpp +++ b/src/test-libdbuspolicy1-ownership-gdi.cpp @@ -129,7 +129,7 @@ bool run_fb() { ldp_serialized::StorageBackendSerialized storage; storage.initFromData(buff, size); - printf("FLATBUFFERS:\n"); + printf("SERIALIZED:\n"); return ownership_test(storage); } diff --git a/src/test-libdbuspolicy1-send_destination_prefix-deny-gdi.cpp b/src/test-libdbuspolicy1-send_destination_prefix-deny-gdi.cpp index ed6e15e..e42095f 100644 --- a/src/test-libdbuspolicy1-send_destination_prefix-deny-gdi.cpp +++ b/src/test-libdbuspolicy1-send_destination_prefix-deny-gdi.cpp @@ -214,7 +214,7 @@ bool run_fb() { ldp_serialized::StorageBackendSerialized storage; storage.initFromData(buff, size); - printf("FLATBUFFERS:\n"); + printf("SERIALIZED:\n"); return send_prefix_test(storage); } diff --git a/src/test-libdbuspolicy1-signal-gdi.cpp b/src/test-libdbuspolicy1-signal-gdi.cpp index 817406c..1627821 100644 --- a/src/test-libdbuspolicy1-signal-gdi.cpp +++ b/src/test-libdbuspolicy1-signal-gdi.cpp @@ -109,7 +109,7 @@ bool run_fb() { ldp_serialized::StorageBackendSerialized storage; storage.initFromData(buff, size); - printf("FLATBUFFERS:\n"); + printf("SERIALIZED:\n"); return signal_test(storage); } -- 2.7.4 From 614713bd783bcfe82a0d8ad252288976f799a2ee Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 27 Oct 2020 13:40:26 +0100 Subject: [PATCH 04/16] refactoring: decouple StorageBackendSerialized and Serializer Change-Id: Ib4fbd8db4a2585694d50bfce33432b170c2cdb96 --- src/internal/naive_policy_checker.cpp | 15 ++++++++++----- src/internal/naive_policy_checker.hpp | 4 ++++ src/internal/storage_backend_serialized.cpp | 16 ---------------- src/internal/storage_backend_serialized.hpp | 5 ----- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index 8939f3f..4e5b634 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -220,19 +220,24 @@ bool NaivePolicyChecker::initDb(const char *config_name, const char *serialized_ assert(config_name[0]); bool result = false; + m_bus_db.release(); - if (serialized_filename) { - if (m_bus_db.init(serialized_filename)) - result = true; - } + if (serialized_filename) + result = m_bus_db.init(serialized_filename); if (!result) { tslog::logWarning(std::string(serialized_filename?:"") .append(": serialized policy file not found, using XML policy file")); // fallback - we have only XML files - result = m_bus_db.initFromXML(config_name); + serializer.reset(new ldp_serializer::Serializer()); + + size_t serialized_size; + auto data = serializer->serialize(config_name, serialized_size); + + if (nullptr != data) + result = m_bus_db.initFromData(data, serialized_size, false); } if (result && tslog::enabled()) { diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index d92fba2..8edc55b 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -26,8 +26,10 @@ #include "policy.hpp" #include "global_nodestruct.hpp" #include "storage_backend_serialized.hpp" +#include "serializer.hpp" #include +#include #include namespace ldp_xml_parser @@ -42,6 +44,8 @@ namespace ldp_xml_parser /** Policy database */ ldp_serialized::StorageBackendSerialized m_bus_db; + /** Serializer - provides serialized data in case no serialized data file is found */ + std::unique_ptr serializer; /** Parses delivered decision. In case of Decision::CHECK calls cynara. * \param[in] decision Decision from checkers diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp index f9fb54f..12959d3 100644 --- a/src/internal/storage_backend_serialized.cpp +++ b/src/internal/storage_backend_serialized.cpp @@ -101,19 +101,6 @@ void StorageBackendSerialized::releaseMMap() { __length = 0; } -bool StorageBackendSerialized::initFromXML(const char *config_name) { - assert(nullptr == serializer.get()); - - serializer.reset(new ldp_serializer::Serializer()); - - size_t serialized_size; - auto data = serializer->serialize(config_name, serialized_size); - if (nullptr == data) - return false; - - return initFromData(data, serialized_size, false); -} - void StorageBackendSerialized::releaseFD() { assert(-1 != __fd); @@ -129,8 +116,5 @@ void StorageBackendSerialized::release() { releaseFD(); } - if (nullptr != serializer.get()) - serializer.reset(nullptr); - impl.release(); } diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp index 9a498b5..9438f86 100644 --- a/src/internal/storage_backend_serialized.hpp +++ b/src/internal/storage_backend_serialized.hpp @@ -23,8 +23,6 @@ #include "policy.hpp" #include "serialization_backend.hpp" -#include "serializer.hpp" -#include #include namespace ldp_serialized { @@ -37,7 +35,6 @@ public: bool init(const char *filename, bool verify = false); bool initFromData(const uint8_t *serialized_data, size_t length, bool verify = false); - bool initFromXML(const char *config_name); void release(); void printContent(bool xml_format = false) const @@ -77,8 +74,6 @@ private: uint8_t *__mem; size_t __length{0}; - std::unique_ptr serializer; - void releaseMMap(); void releaseFD(); }; -- 2.7.4 From 8f572a48df3854f257a9ed2560eb48a39cfadb97 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 27 Oct 2020 14:55:03 +0100 Subject: [PATCH 05/16] refactoring: eliminate StorageBackendFlatbuffersImpl Change-Id: I73f2a898483fb336518f8b9ef28338ef91e55796 --- src/internal/storage_backend_flatbuffers.cpp | 67 ++++++++-------------------- src/internal/storage_backend_flatbuffers.hpp | 5 ++- 2 files changed, 21 insertions(+), 51 deletions(-) diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index 4867185..1cac9ce 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -110,23 +110,10 @@ ldp_xml_parser::DecisionItem getDecisionItemMaybeNull(const T &item, const P *po } // anonymous namespace -class StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl { - const FB::File *file{nullptr}; +template ::policy_set_type> +const M *getPolicySet(const FB::File *file); -public: - bool initFromData(const uint8_t *mem, size_t size, bool verify); - void release(); - - ldp_xml_parser::DecisionItem getDecisionFromSendIndex(const MatchItemSend &item, const FB::PolicySend *policy); - - void printContent(const bool xml_format = false) const; - - template ::policy_set_type> - const M *getPolicySet(); -}; - -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::getDecisionFromSendIndex(const MatchItemSend &item, - const FB::PolicySend *policy) { +ldp_xml_parser::DecisionItem getDecisionFromSendIndex(const MatchItemSend &item, const FB::PolicySend *policy) { const auto *index = policy->index(); @@ -194,11 +181,11 @@ ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::StorageBackendFlatbuffer return ldp_xml_parser::DecisionItem(ldp_xml_parser::Decision::ANY); } -void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::release() { +void StorageBackendFlatbuffers::release() { file = nullptr; } -bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromData(const uint8_t *mem, size_t size, bool verify) { +bool StorageBackendFlatbuffers::initFromData(const uint8_t *mem, size_t size, bool verify) { assert(nullptr == file); if (verify) { @@ -222,13 +209,12 @@ bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromData(cons return file != nullptr; } -void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::printContent(const bool xml_format) const { +void StorageBackendFlatbuffers::printContent(const bool xml_format) const { print_content::use_xml_format(xml_format); std::cerr << *file; } /*************************************************/ - #define TYPE_HELPER(T, t) \ template <> \ struct type_helper { \ @@ -236,7 +222,7 @@ void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::printContent(cons typedef FB::Policy##T policy_type; \ }; \ template <> \ - auto StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::getPolicySet() \ + auto getPolicySet(const FB::File *file) \ -> const typename type_helper::policy_set_type * { \ assert(file); \ return file->m_##t##_set(); \ @@ -247,59 +233,47 @@ TYPE_HELPER(Send, send) TYPE_HELPER(Receive, receive) TYPE_HELPER(Access, access) -bool StorageBackendFlatbuffers::initFromData(const uint8_t *serialized_data, size_t length, bool verify) { - return pimpl->initFromData(serialized_data, length, verify); -} - -void StorageBackendFlatbuffers::release() { - pimpl->release(); -} - -void StorageBackendFlatbuffers::printContent(const bool xml_format) const { - pimpl->printContent(xml_format); -} - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const T &item) const { - return getDecisionItem(item, pimpl->getPolicySet()->context_mandatory()); + return getDecisionItem(item, getPolicySet(file)->context_mandatory()); } template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const MatchItemSend &item) const { - return pimpl->getDecisionFromSendIndex(item, pimpl->getPolicySet()->context_mandatory()); + return getDecisionFromSendIndex(item, getPolicySet(file)->context_mandatory()); } template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const MatchItemSend &item) const { - return pimpl->getDecisionFromSendIndex(item, pimpl->getPolicySet()->context_default()); + return getDecisionFromSendIndex(item, getPolicySet(file)->context_default()); } template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const MatchItemSend &item) const { - auto *policyPair = pimpl->getPolicySet()->user()->LookupByKey(uid); + auto *policyPair = getPolicySet(file)->user()->LookupByKey(uid); if (nullptr == policyPair) return ldp_xml_parser::Decision::ANY; - return pimpl->getDecisionFromSendIndex(item, policyPair->policy()); + return getDecisionFromSendIndex(item, policyPair->policy()); } template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const T &item) const { - return getDecisionItem(item, pimpl->getPolicySet()->context_default()); + return getDecisionItem(item, getPolicySet(file)->context_default()); } template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const T &item) const { - return getDecisionItemMaybeNull(item, pimpl->getPolicySet()->user()->LookupByKey(uid)); + return getDecisionItemMaybeNull(item, getPolicySet(file)->user()->LookupByKey(uid)); } template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemGroup(gid_t gid, const T &item) const { - return getDecisionItemMaybeNull(item, pimpl->getPolicySet()->group()->LookupByKey(gid)); + return getDecisionItemMaybeNull(item, getPolicySet(file)->group()->LookupByKey(gid)); } template bool StorageBackendFlatbuffers::existsPolicyForGroup(gid_t gid) const { - return pimpl->getPolicySet()->group()->LookupByKey(gid) != nullptr; + return getPolicySet(file)->group()->LookupByKey(gid) != nullptr; } #define T_INSTANTIATION(T) \ @@ -324,12 +298,7 @@ T_INSTANTIATION2(Receive) #undef T_INSTANTIATION2 -StorageBackendFlatbuffers::StorageBackendFlatbuffers() - : pimpl{new StorageBackendFlatbuffersImpl} { -} - -StorageBackendFlatbuffers::~StorageBackendFlatbuffers() { - pimpl->release(); -} +StorageBackendFlatbuffers::StorageBackendFlatbuffers() {} +StorageBackendFlatbuffers::~StorageBackendFlatbuffers() {} } diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index 6bdd707..d0946fd 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -15,6 +15,7 @@ */ #pragma once +#include "include/fb_generated.h" #include "policy.hpp" #include @@ -22,8 +23,6 @@ namespace ldp_serialized { class StorageBackendFlatbuffers { - class StorageBackendFlatbuffersImpl; - std::unique_ptr pimpl; public: StorageBackendFlatbuffers(); ~StorageBackendFlatbuffers(); @@ -50,6 +49,8 @@ public: template bool existsPolicyForGroup(gid_t gid) const; +private: + const FB::File *file{nullptr}; }; } -- 2.7.4 From 40dc543f66e96ec549d76ed5954d69afb1c5763f Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 27 Oct 2020 15:08:27 +0100 Subject: [PATCH 06/16] serialization: add new Storage extracting interface Change-Id: I947a1c73e0396034ebd0038fb483f5208a43bba3 --- src/internal/serialization_traits.hpp | 57 ++++++++ src/internal/storage_backend_flatbuffers.hpp | 188 +++++++++++++++++++++++++++ 2 files changed, 245 insertions(+) create mode 100644 src/internal/serialization_traits.hpp diff --git a/src/internal/serialization_traits.hpp b/src/internal/serialization_traits.hpp new file mode 100644 index 0000000..c52c599 --- /dev/null +++ b/src/internal/serialization_traits.hpp @@ -0,0 +1,57 @@ +#pragma once + +/* MIT License + * + * Copyright (c) 2020 Samsung Electronics Co., Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +namespace ldp_serialization { + +/* Specialize HasUserGroup for backend's sets to indicate if they have user and group maps. + * In specialization put std::true_type or std::false_type as the result. + */ +template +struct HasUserGroup; + +/* Specialize ContentType for backend's policies to indicate if their contents type + * In specialization put ldp_serialization::TreeType or ldp_serialization::ItemsType as the result. + */ +struct ItemsType {}; +struct TreeType {}; + +template +struct PolicyContentType; + +/* Specialize PolicyHasIndex for backend's PolicySend to indicate it is indexed. + * In specialization put std::true_type as the result. + */ +template +struct PolicyHasIndex { typedef std::false_type result; }; + +/* Specialize ItemType for backend's item types using SendType, ReceiveType and AccessType as the result field type. + */ +struct SendType {}; +struct ReceiveType {}; +struct AccessType {}; + +template +struct ItemType; + +} diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index d0946fd..ac86258 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -17,6 +17,7 @@ #include "include/fb_generated.h" #include "policy.hpp" +#include "serialization_traits.hpp" #include @@ -49,8 +50,195 @@ public: template bool existsPolicyForGroup(gid_t gid) const; + const FB::File *getFile() const + { return file; } + + auto fileGetOwnSet(const FB::File *file) const + { return file->m_own_set(); } + auto fileGetSendSet(const FB::File *file) const + { return file->m_send_set(); } + auto fileGetReceiveSet(const FB::File *file) const + { return file->m_receive_set(); } + auto fileGetAccessSet(const FB::File *file) const + { return file->m_access_set(); } + + template + auto setGetContextDefault(const Set *set) const + { return set->context_default(); } + + template + auto setGetContextMandatory(const Set *set) const + { return set->context_mandatory(); } + + template + auto setGetUser(const Set *set) const + { return set->user(); } + + template + auto setGetGroup(const Set *set) const + { return set->group(); } + + template + auto setUserGroupGetId(const SetUserGroup *set_user_group) const + { return set_user_group->id(); } + + template + auto setUserGroupGetPolicy(const SetUserGroup *set_user_group) const + { return set_user_group->policy(); } + + template + auto policyGetTree(const Policy *policy) const + { return policy->tree(); } + + template + auto policyGetItems(const Policy *policy) const + { return policy->items(); } + + template + auto policyHasIndex(const Policy *policy) const + { return policy->index() != nullptr && policy->index()->size() > 0; } + + template + auto policyGetIndex(const Policy *policy) const + { return policy->index(); } + + template + auto policyGetPrefixIndex(const Policy *policy) const + { return policy->prefix_index(); } + + auto policyIndexGetBestScore(const FB::NameScoresPair *p) const + { return p->best_score(); } + + auto policyIndexGetItemRefs(const FB::NameScoresPair *p) const + { return p->item_refs(); } + + template + auto containerGetReverseIterator(const Container *container) const + { return container->rbegin(); } + + template + auto containerGetReverseIteratorEnd(const Container *container) const + { return container->rend(); } + + template + auto containerGetIterator(const Container *container) const + { return container->begin(); } + + template + auto containerGetIteratorEnd(const Container *container) const + { return container->end(); } + + template + auto containerGetSize(const Container *container) const + { return container->size(); } + + template + auto containerLookupByIndex(const Container *container, size_t index) const + { return container->Get(index); } + + template + auto containerEmpty(const Container *container) const + { return container->size() == 0; } + + template + auto containerLookupByKey(const Container *container, Key key) const { + auto elem = container->LookupByKey(key); + return std::make_pair(elem != nullptr, elem); + } + + auto decisionItemGetDecision(const FB::DecisionItem *item) const + { return item->decision(); } + + auto decisionItemGetPrivilege(const FB::DecisionItem *item) const + { return item->privilege(); } + + auto ownNodeGetToken(const FB::PolicyOwnNode *node) const + { return node->token(); } + + auto ownNodeGetDecisionItem(const FB::PolicyOwnNode *node) const + { return node->decision_item(); } + + auto ownNodeGetPrefixDecisionItem(const FB::PolicyOwnNode *node) const + { return node->prefix_decision_item(); } + + auto ownNodeGetChildren(const FB::PolicyOwnNode *node) const + { return node->children(); } + + auto itemAccessGetType(const FB::ItemAccess *item) const + { return item->type(); } + + auto itemAccessGetUid(const FB::ItemAccess *item) const + { return item->uid(); } + + auto itemAccessGetGid(const FB::ItemAccess *item) const + { return item->gid(); } + + template + auto itemSrGetName(const ItemSR *item) const + { return item->name(); } + + template + auto itemSrGetIsNamePrefix(const ItemSR *item) const + { return item->is_name_prefix(); } + + template + auto itemSrGetInterface(const ItemSR *item) const + { return item->interface(); } + + template + auto itemSrGetMember(const ItemSR *item) const + { return item->member(); } + + template + auto itemSrGetPath(const ItemSR *item) const + { return item->path(); } + + template + auto itemSrGetMessageType(const ItemSR *item) const + { return item->type(); } + + template + auto itemGetDecisionItem(const Item *item) const + { return item->decision(); } + + const char *stringGetCStr(const flatbuffers::String *str) const + { return str->c_str(); } + + size_t stringGetSize(const flatbuffers::String *str) const + { return str->size(); } + private: const FB::File *file{nullptr}; }; } + +namespace ldp_serialization { +template <> struct HasUserGroup +{ typedef std::true_type result; }; +template <> struct HasUserGroup +{ typedef std::true_type result; }; +template <> struct HasUserGroup +{ typedef std::true_type result; }; +template <> struct HasUserGroup +{ typedef std::false_type result; }; + +template <> struct PolicyContentType +{ typedef TreeType result; }; +template <> struct PolicyContentType +{ typedef ItemsType result; }; +template <> struct PolicyContentType +{ typedef ItemsType result; }; +template <> struct PolicyContentType +{ typedef ItemsType result; }; + +template <> struct PolicyHasIndex +{ typedef std::true_type result; }; + +template <> struct ItemType +{ typedef SendType result; }; +template <> struct ItemType +{ typedef ReceiveType result; }; +template <> struct ItemType +{ typedef AccessType result; }; +} -- 2.7.4 From 6fbd21c76421008477a1c489d962a1130e951c5f Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 27 Oct 2020 16:23:56 +0100 Subject: [PATCH 07/16] refactoring: move local functions to the class Change-Id: I98e3f0ab900be2b487df47f06d131299507cd7a3 --- src/internal/storage_backend_flatbuffers.cpp | 79 ++++++++++++---------------- src/internal/storage_backend_flatbuffers.hpp | 26 ++++++++- 2 files changed, 60 insertions(+), 45 deletions(-) diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index 1cac9ce..b4dd030 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -26,34 +26,30 @@ using ldp_xml_parser::MatchItemSend; namespace ldp_serialized { -typedef boost::tokenizer> tokenizer; - template struct type_helper; -namespace { - -inline boost::string_ref s(const flatbuffers::String *str) { +boost::string_ref StorageBackendFlatbuffers::toStringRef(const flatbuffers::String *str) const { return boost::string_ref(str->c_str(), str->size()); } template -bool match(const T &match, const I *i) { +bool StorageBackendFlatbuffers::match(const T &match, const I *i) const { return match.match(makeMessageType(i->type()), - s(i->interface()), - s(i->path()), - s(i->member()), - s(i->name()), + toStringRef(i->interface()), + toStringRef(i->path()), + toStringRef(i->member()), + toStringRef(i->name()), i->is_name_prefix(), makeDecision(i->decision()->decision())); } -template <> bool match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) { +bool StorageBackendFlatbuffers::match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const { return match.match(makeBusAccessType(item->type()), item->uid(), item->gid()); } template ::policy_type> -ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy) { +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, const P *policy) const { const auto *v = policy->items(); for (auto it = v->rbegin(); it != v->rend(); ++it) { if (match(item, *it)) @@ -62,10 +58,10 @@ ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy) { return ldp_xml_parser::Decision::ANY; } -const DecisionItem *getDecisionItemFromTree(const FB::PolicyOwnNode *node, - tokenizer &tokens, - tokenizer::iterator &iterator) { - if (iterator == tokens.end()) { +auto StorageBackendFlatbuffers::getDecisionItemFromTree(const FB::PolicyOwnNode *node, + const tokenizer::iterator &tokens_end, + tokenizer::iterator &iterator) const { + if (iterator == tokens_end) { if (node->decision_item()->decision() != Decision_ANY) return node->decision_item(); else @@ -77,15 +73,16 @@ const DecisionItem *getDecisionItemFromTree(const FB::PolicyOwnNode *node, return node->prefix_decision_item(); ++iterator; - const DecisionItem *child_decision = getDecisionItemFromTree(child, tokens, iterator); + const DecisionItem *child_decision = getDecisionItemFromTree(child, tokens_end, iterator); if (child_decision->decision() == Decision_ANY) return node->prefix_decision_item(); return child_decision; } -template <> ldp_xml_parser::DecisionItem getDecisionItem(const ldp_xml_parser::MatchItemOwn &item, - const PolicyOwn *policy) { +template <> +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const ldp_xml_parser::MatchItemOwn &item, + const PolicyOwn *policy) const { if (item.getName().length() == 0) return ldp_xml_parser::Decision::DENY; @@ -98,22 +95,17 @@ template <> ldp_xml_parser::DecisionItem getDecisionItem(const ldp_xml_parser::M auto iterator = tokens.begin(); - return makeDecisionItem(getDecisionItemFromTree(node, tokens, iterator)); + return makeDecisionItem(getDecisionItemFromTree(node, tokens.end(), iterator)); } template ::policy_type> -ldp_xml_parser::DecisionItem getDecisionItemMaybeNull(const T &item, const P *policyPair) { +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemMaybeNull(const T &item, const P *policyPair) const { if (nullptr == policyPair) return ldp_xml_parser::Decision::ANY; return getDecisionItem(item, policyPair->policy()); } -} // anonymous namespace - -template ::policy_set_type> -const M *getPolicySet(const FB::File *file); - -ldp_xml_parser::DecisionItem getDecisionFromSendIndex(const MatchItemSend &item, const FB::PolicySend *policy) { +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemFromSendIndex(const MatchItemSend &item, const FB::PolicySend *policy) const { const auto *index = policy->index(); @@ -122,7 +114,7 @@ ldp_xml_parser::DecisionItem getDecisionFromSendIndex(const MatchItemSend &item, std::pair currentBest(nullptr, 0); - auto updateCurrentBest = [¤tBest, &item, &policy](const flatbuffers::Vector *vec) { + auto updateCurrentBest = [&](const flatbuffers::Vector *vec) { // look from the back, the rule is the same as for the full database // we now only check among less elements, because the database is indexed to small lists // item_scores are in increasing order in the index, and they serve also as ids of the policy rules @@ -139,7 +131,7 @@ ldp_xml_parser::DecisionItem getDecisionFromSendIndex(const MatchItemSend &item, } }; - auto searchAndUpdateCurrentBest = [¤tBest, &index, &updateCurrentBest](boost::string_ref name_ref) { + auto searchAndUpdateCurrentBest = [&](boost::string_ref name_ref) { // we need to create C-string for flatbuffers lookups // boost::string_ref gives us correct start, but possibly NUL-terminated in a wrong place, as it does not modify // input string and keeps only the length @@ -222,8 +214,7 @@ void StorageBackendFlatbuffers::printContent(const bool xml_format) const { typedef FB::Policy##T policy_type; \ }; \ template <> \ - auto getPolicySet(const FB::File *file) \ - -> const typename type_helper::policy_set_type * { \ + auto StorageBackendFlatbuffers::getPolicySet() const { \ assert(file); \ return file->m_##t##_set(); \ } @@ -233,47 +224,47 @@ TYPE_HELPER(Send, send) TYPE_HELPER(Receive, receive) TYPE_HELPER(Access, access) -template -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const T &item) const { - return getDecisionItem(item, getPolicySet(file)->context_mandatory()); -} - template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const MatchItemSend &item) const { - return getDecisionFromSendIndex(item, getPolicySet(file)->context_mandatory()); + return getDecisionItemFromSendIndex(item, getPolicySet()->context_mandatory()); } template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const MatchItemSend &item) const { - return getDecisionFromSendIndex(item, getPolicySet(file)->context_default()); + return getDecisionItemFromSendIndex(item, getPolicySet()->context_default()); } template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const MatchItemSend &item) const { - auto *policyPair = getPolicySet(file)->user()->LookupByKey(uid); + auto *policyPair = getPolicySet()->user()->LookupByKey(uid); if (nullptr == policyPair) return ldp_xml_parser::Decision::ANY; - return getDecisionFromSendIndex(item, policyPair->policy()); + return getDecisionItemFromSendIndex(item, policyPair->policy()); +} + +template +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const T &item) const { + return getDecisionItem(item, getPolicySet()->context_mandatory()); } template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const T &item) const { - return getDecisionItem(item, getPolicySet(file)->context_default()); + return getDecisionItem(item, getPolicySet()->context_default()); } template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const T &item) const { - return getDecisionItemMaybeNull(item, getPolicySet(file)->user()->LookupByKey(uid)); + return getDecisionItemMaybeNull(item, getPolicySet()->user()->LookupByKey(uid)); } template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemGroup(gid_t gid, const T &item) const { - return getDecisionItemMaybeNull(item, getPolicySet(file)->group()->LookupByKey(gid)); + return getDecisionItemMaybeNull(item, getPolicySet()->group()->LookupByKey(gid)); } template bool StorageBackendFlatbuffers::existsPolicyForGroup(gid_t gid) const { - return getPolicySet(file)->group()->LookupByKey(gid) != nullptr; + return getPolicySet()->group()->LookupByKey(gid) != nullptr; } #define T_INSTANTIATION(T) \ diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index ac86258..107c55b 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -18,7 +18,7 @@ #include "include/fb_generated.h" #include "policy.hpp" #include "serialization_traits.hpp" - +#include #include namespace ldp_serialized { @@ -207,8 +207,32 @@ public: size_t stringGetSize(const flatbuffers::String *str) const { return str->size(); } + typedef boost::tokenizer> tokenizer; + private: const FB::File *file{nullptr}; + + template + auto getPolicySet() const; + + template + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy) const; + + ldp_xml_parser::DecisionItem getDecisionItemFromSendIndex(const ldp_xml_parser::MatchItemSend &item, const FB::PolicySend *policy) const; + + template + ldp_xml_parser::DecisionItem getDecisionItemMaybeNull(const T &item, const P *policyPair) const; + + auto getDecisionItemFromTree(const FB::PolicyOwnNode *node, + const tokenizer::iterator &tokens_end, + tokenizer::iterator &iterator) const; + + template + bool match(const T &match, const I *i) const; + + bool match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const; + + boost::string_ref toStringRef(const flatbuffers::String *str) const; }; } -- 2.7.4 From 393bbb5dadb6a936e487f10dfae05f905b7d3d6b Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 28 Oct 2020 08:02:08 +0100 Subject: [PATCH 08/16] printing: add generic data extraction interface for XML db Change-Id: Icf05d2d7a8d5077b9efa23aee7c99af8b9264242 --- src/internal/storage_backend_xml_printing.hpp | 81 +++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/internal/storage_backend_xml_printing.hpp diff --git a/src/internal/storage_backend_xml_printing.hpp b/src/internal/storage_backend_xml_printing.hpp new file mode 100644 index 0000000..f2fd66a --- /dev/null +++ b/src/internal/storage_backend_xml_printing.hpp @@ -0,0 +1,81 @@ +#pragma once + +/* MIT License + * + * Copyright (c) 2020 Samsung Electronics Co., Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#include "storage_backend_xml.hpp" + +namespace ldp_xml_parser { + +class StorageBackendXMLPrinting { +public: + auto itemAccessGetType(const ItemAccess &item) const + { return item.getType(); } + + auto itemAccessGetUid(const ItemAccess &item) const + { return item.getUid(); } + + auto itemAccessGetGid(const ItemAccess &item) const + { return item.getGid(); } + + template + auto itemSrGetName(const ItemSR &item) const + { return item.getName(); } + + template + auto itemSrGetIsNamePrefix(const ItemSR &item) const + { return item.isNamePrefix(); } + + template + auto itemSrGetInterface(const ItemSR &item) const + { return item.getInterface(); } + + template + auto itemSrGetMember(const ItemSR &item) const + { return item.getMember(); } + + template + auto itemSrGetPath(const ItemSR &item) const + { return item.getPath(); } + + template + auto itemSrGetMessageType(const ItemSR &item) const + { return item.getType(); } + + template + auto itemGetDecisionItem(const Item &item) const + { return item.getDecision(); } + + auto decisionItemGetDecision(const DecisionItem &item) const + { return item.getDecision(); } + + auto decisionItemGetPrivilege(const DecisionItem &item) const + { return item.getPrivilege(); } + + auto stringGetCStr(const boost::string_ref &str) const + { return str.data(); } + + auto stringGetSize(const boost::string_ref &str) const + { return str.size(); } +}; + +} -- 2.7.4 From 78f6d28c12222f43dc1fef678333d95005a19432 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 28 Oct 2020 08:35:24 +0100 Subject: [PATCH 09/16] refactoring: move FB_ID_* constants Change-Id: Ia5a8b74612361cdbc384f251ec45c4d02a7f4032 --- src/internal/print_content.hpp | 3 --- src/internal/storage_backend_flatbuffers.cpp | 11 +++++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/internal/print_content.hpp b/src/internal/print_content.hpp index 2e93ea6..78f6381 100644 --- a/src/internal/print_content.hpp +++ b/src/internal/print_content.hpp @@ -25,9 +25,6 @@ void use_xml_format(const bool xml); } namespace FB { -const unsigned int FB_ID_OFFSET = 4; -const unsigned int FB_ID_SIZE = 4; - std::ostream &operator<<(std::ostream &stream, const FB::File &file); } diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index b4dd030..868aa1f 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -26,6 +26,13 @@ using ldp_xml_parser::MatchItemSend; namespace ldp_serialized { +namespace { + +const unsigned int FB_ID_OFFSET = 4; +const unsigned int FB_ID_SIZE = 4; + +} // anonymous namespace + template struct type_helper; @@ -183,8 +190,8 @@ bool StorageBackendFlatbuffers::initFromData(const uint8_t *mem, size_t size, bo if (verify) { auto verifier = flatbuffers::Verifier(mem, size); if (!FB::VerifyFileBuffer(verifier) || !FB::FileBufferHasIdentifier(mem)) { - char fid[FB::FB_ID_SIZE + 1] = {0, }; - strncpy(fid, (const char *)(mem + FB::FB_ID_OFFSET), FB::FB_ID_SIZE); + char fid[FB_ID_SIZE + 1] = {0, }; + strncpy(fid, (const char *)(mem + FB_ID_OFFSET), FB_ID_SIZE); if (strcmp(fid, "LDP1") == 0) { tslog::log_error("verification of serialized data: not available\n"); -- 2.7.4 From 861655ed3072bb21cdc2111baddd63845f7a2cd0 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 28 Oct 2020 08:10:29 +0100 Subject: [PATCH 10/16] printing: use generic data extracting interface It eliminates any konwledge of Flatbuffers structures, types, and methods of data extracting from the printing module. Change-Id: I5da411f3878b8cb13e9962a7f6c994063446304a --- src/internal/print_content.cpp | 242 ++---------------------- src/internal/print_content.hpp | 267 ++++++++++++++++++++++++++- src/internal/storage_backend_flatbuffers.cpp | 6 - src/internal/storage_backend_flatbuffers.hpp | 2 - src/internal/storage_backend_serialized.cpp | 5 + src/internal/storage_backend_serialized.hpp | 3 +- 6 files changed, 284 insertions(+), 241 deletions(-) diff --git a/src/internal/print_content.cpp b/src/internal/print_content.cpp index cdded17..0264e9a 100644 --- a/src/internal/print_content.cpp +++ b/src/internal/print_content.cpp @@ -16,251 +16,37 @@ #include "policy.hpp" #include "print_content.hpp" #include "serialized_convert.hpp" -#include +#include "storage_backend_xml_printing.hpp" +#include #include -/************ PRINTING CONTENT ********************/ -std::ostream &print_content_item_own(std::ostream &stream, const std::string &name, bool is_prefix) { - return stream << "ItemOwn: service(" << (name.empty() ? "*" : name) << "), pref(" << is_prefix << ")"; -} - -namespace { -const char* message_access[] = {"USER", "GROUP", "ALL_USERS", "ALL_GROUPS"}; -inline const char* __access_type_to_str(ldp_xml_parser::BusAccessType type) { - return message_access[static_cast(type)]; -} -} - -namespace print_content { -static bool xml_format = false; -void use_xml_format(const bool xml) { - xml_format = xml; -} -} - -template -std::ostream &print_val(std::ostream &stream, const boost::string_ref &name, const T &val) { - return stream << name << "(" << val << ")"; -} - -template -std::ostream &print_next_val(std::ostream &stream, const boost::string_ref &name, const T &val) { - stream << ", "; - return print_val(stream, name, val); -} - -std::ostream &print_content_item_access(std::ostream &stream, - ldp_xml_parser::BusAccessType type, - uid_t uid, - gid_t gid, - const ldp_xml_parser::DecisionItem &decisionItem) { - stream << "ItemAccess: "; - print_val(stream, "type", __access_type_to_str(type)); - print_next_val(stream, "uid", uid); - print_next_val(stream, "gid", gid); - return print_next_val(stream, "decision", decisionItem); -} - -namespace { -static const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL"}; -static inline const char* __message_type_to_str(ldp_xml_parser::MessageType type) { - return message_type[static_cast(type)]; -} -} - -std::ostream &print_content_item_sr(std::ostream &stream, - const boost::string_ref &item_type, - const boost::string_ref &name, - const boost::string_ref &interface, - const boost::string_ref &member, - const boost::string_ref &path, - ldp_xml_parser::MessageType type, - const ldp_xml_parser::DecisionItem &decisionItem, - const bool is_prefix) -{ - stream << item_type << ": "; - if (is_prefix) - print_val(stream, "name_prefix", name); - else - print_val(stream, "name", name); - print_next_val(stream, "inter", interface); - print_next_val(stream, "member", member); - print_next_val(stream, "path", path); - print_next_val(stream, "type", __message_type_to_str(type)); - return print_next_val(stream, "decision", decisionItem); -} - -std::ostream &print_content_item_sr_xml(std::ostream &stream, - const boost::string_ref &item_type, - const boost::string_ref &name, - const boost::string_ref &interface, - const boost::string_ref &member, - const boost::string_ref &path, - ldp_xml_parser::MessageType type, - const ldp_xml_parser::DecisionItem &decisionItem, - const bool is_prefix) -{ - const char *strDecision[] = {"any", "allow", "deny", "check"}; - const char *sr; - std::string type_str; - - if (item_type == "ItemSend") - sr = "send"; - else - sr = "receive"; - - stream << "<" << strDecision[static_cast(decisionItem.getDecision())] << " "; - if (is_prefix) - stream << sr << "_destination_prefix=\"" << name << "\" "; - else if (!name.empty()) - stream << sr << "_" << (item_type == "ItemSend" ? "destination" : "sender") << "=\"" << name << "\" "; - - if (!path.empty()) - stream << sr << "_" << "path=\"" << path << "\" "; - if (!interface.empty()) - stream << sr << "_" << "interface=\"" << interface << "\" "; - if (!member.empty()) - stream << sr << "_" << "member=\"" << member << "\" "; - if (!decisionItem.getPrivilege().empty()) - stream << sr << "_" << "privilege=\"" << decisionItem.getPrivilege() << "\" "; - - type_str = __message_type_to_str(type); - std::transform(type_str.begin(), type_str.end(), type_str.begin(), [](unsigned char c){ return std::tolower(c); }); - - if (type_str != "any") - stream << sr << "_" << "type=\"" << type_str << "\" "; - - return stream << "/>"; -} - -namespace { -static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"}; -static inline const char* __decision_to_str(ldp_xml_parser::Decision dec) { - return message_decision[static_cast(dec)]; -} -} - -std::ostream &print_content_decision_item(std::ostream &stream, - ldp_xml_parser::Decision decision, - const boost::string_ref &privilege) { - stream << __decision_to_str(decision); - if (!privilege.empty()) - stream << ":" << privilege; - return stream; -} - -template -void printContentItem(std::ostream &stream, const T *item); - -template <> void printContentItem(std::ostream &stream, const FB::ItemAccess *item) { - print_content_item_access(stream, ldp_serialized::makeBusAccessType(item->type()), item->uid(), - item->gid(), ldp_serialized::makeDecisionItem(item->decision())); -} - -template -void printContentItemSR(std::ostream &stream, const boost::string_ref &item_type, const T *item) { - auto print_func = (print_content::xml_format ? print_content_item_sr_xml : print_content_item_sr); - print_func(stream, item_type, item->name()->c_str(), item->interface()->c_str(), - item->member()->c_str(), item->path()->c_str(), ldp_serialized::makeMessageType(item->type()), - ldp_serialized::makeDecisionItem(item->decision()), item->is_name_prefix()); -} - -template <> void printContentItem(std::ostream &stream, const FB::ItemSend *item) { - printContentItemSR(stream, "ItemSend", item); -} - -template <> void printContentItem(std::ostream &stream, const FB::ItemReceive *item) { - printContentItemSR(stream, "ItemReceive", item); -} - -template -void printContentPolicy(std::ostream &stream, const T *policy) { - for (const auto *i: *policy->items()) { - printContentItem(stream, i); - stream << std::endl; - } -} - -void printDecisionItem(std::ostream &stream, const FB::DecisionItem *item) { - print_content_decision_item(stream, ldp_serialized::makeDecision(item->decision()), item->privilege()->c_str()); -} - -void printTreeLevel(std::ostream &stream, const FB::PolicyOwnNode *node, unsigned indent) { - for (decltype(indent) i = 0; i < indent; ++i) - stream << "\t"; - stream << "| " << node->token()->c_str() << " (" << node->children()->size() << ") | "; - printDecisionItem(stream, node->decision_item()); - stream << " "; - printDecisionItem(stream, node->prefix_decision_item()); - stream << std::endl; - - for (const auto &i: *node->children()) - printTreeLevel(stream, i, indent+1); -} - -template <> void printContentPolicy(std::ostream &stream, const FB::PolicyOwn *policy) { - printTreeLevel(stream, policy->tree(), 0); -} - -template -void printContentUserGroup(std::ostream &stream, const T *set) { - for (const auto *i: *set->user()) { - stream << "user: " << i->id() << std::endl; - printContentPolicy(stream, i->policy()); - } - - for (const auto *i: *set->group()) { - stream << "group: " << i->id() << std::endl; - printContentPolicy(stream, i->policy()); - } -} - -template <> void printContentUserGroup(std::ostream &, const FB::AccessSet *) {} - -template -void printContentSet(std::ostream &stream, const T *set) { - stream << "context default" << std::endl; - printContentPolicy(stream, set->context_default()); - stream << "context mandatory" << std::endl; - printContentPolicy(stream, set->context_mandatory()); - - printContentUserGroup(stream, set); -} - -namespace FB { -std::ostream &operator<<(std::ostream &stream, const FB::File &file) { - printContentSet(stream, file.m_own_set()); - printContentSet(stream, file.m_send_set()); - printContentSet(stream, file.m_receive_set()); - printContentSet(stream, file.m_access_set()); - return stream; -} -} +using namespace print_content; /********* PRINTING ITEMS PARSED FROM XML *******************/ namespace ldp_xml_parser { std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemOwn &item) { - return print_content_item_own(stream, item.getName(), item.isPrefix()); + auto name = item.getName(); + return stream << "ItemOwn: service(" << (name.empty() ? "*" : name) << "), pref(" << item.isPrefix() << ")"; } std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemSend &item) { - auto print_func = (print_content::xml_format ? print_content_item_sr_xml : print_content_item_sr); - return print_func(stream, "ItemSend", item.getName(), item.getInterface(), item.getMember(), - item.getPath(), item.getType(), item.getDecision(), item.isNamePrefix()); + contentPrinter(ldp_xml_parser::StorageBackendXMLPrinting(), stream).printItem(item, ldp_serialization::SendType()); + return stream; } std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemReceive &item) { - auto print_func = (print_content::xml_format ? print_content_item_sr_xml : print_content_item_sr); - return print_func(stream, "ItemReceive", item.getName(), item.getInterface(), item.getMember(), - item.getPath(), item.getType(), item.getDecision(), item.isNamePrefix()); + contentPrinter(ldp_xml_parser::StorageBackendXMLPrinting(), stream).printItem(item, ldp_serialization::ReceiveType()); + return stream; } std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemAccess &item) { - return print_content_item_access(stream, item.getType(), item.getUid(), item.getGid(), item.getDecision()); + contentPrinter(ldp_xml_parser::StorageBackendXMLPrinting(), stream).printItem(item, ldp_serialization::AccessType()); + return stream; } std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::DecisionItem &item) { - return print_content_decision_item(stream, item.getDecision(), item.getPrivilege()); + contentPrinter(ldp_xml_parser::StorageBackendXMLPrinting(), stream).printDecisionItem(item); + return stream; } std::ostream &operator<<(std::ostream& stream, const MatchItemOwn &item) { @@ -274,7 +60,7 @@ std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemSR stream << name << " "; return stream << "), interface(" << item.interface << "), member(" << item.member << - "), path(" << item.path << "), type(" << __message_type_to_str(item.type) << ")"; + "), path(" << item.path << "), type(" << ContentPrinterXMLData::messageTypeToStr(item.type) << ")"; } std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemSend &item) diff --git a/src/internal/print_content.hpp b/src/internal/print_content.hpp index 78f6381..24369d5 100644 --- a/src/internal/print_content.hpp +++ b/src/internal/print_content.hpp @@ -17,15 +17,276 @@ #include "include/fb_generated.h" #include "policy.hpp" +#include "serialization_traits.hpp" +#include "serialized_convert.hpp" +#include #include +#include namespace print_content { -void use_xml_format(const bool xml); + +class ContentPrinterXMLData { +public: + static constexpr const char *decisionToStr(ldp_xml_parser::Decision dec) { + const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"}; + return message_decision[static_cast(dec)]; + } + + static constexpr const char *accessTypeToStr(ldp_xml_parser::BusAccessType type) { + const char* message_access[] = {"USER", "GROUP", "ALL_USERS", "ALL_GROUPS"}; + return message_access[static_cast(type)]; + } + + static constexpr const char *messageTypeToStr(ldp_xml_parser::MessageType type) { + const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL"}; + return message_type[static_cast(type)]; + } +}; + +template +class ContentPrinter { + const StorageBackendDatabase &__db; + + std::ostream &__stream; + bool __xml_format; + + void printDecisionItem(ldp_xml_parser::Decision decision, + const boost::string_ref &privilege) { + __stream << ContentPrinterXMLData::decisionToStr(decision); + if (!privilege.empty()) + __stream << ":" << privilege; + } + + template + void printVal(const boost::string_ref &name, const T &val) { + __stream << name << "(" << val << ")"; + } + + template + void printValFun(const boost::string_ref &name, const T &fun) { + __stream << name << "("; + fun(); + __stream << ")"; + } + + template + void printNextVal(const boost::string_ref &name, const T &val) { + __stream << ", "; + printVal(name, val); + } + + template + void printNextValFun(const boost::string_ref &name, const T &fun) { + __stream << ", "; + printValFun(name, fun); + } + + void printItemSRXML(boost::string_ref item_type, + boost::string_ref name, + boost::string_ref interface, + boost::string_ref member, + boost::string_ref path, + ldp_xml_parser::MessageType type, + const ldp_xml_parser::Decision &decision, + boost::string_ref decisionPrivilege, + const bool is_prefix) { + const char *strDecision[] = {"any", "allow", "deny", "check"}; + std::string type_str; + + __stream << "<" << strDecision[static_cast(decision)] << " "; + if (is_prefix) + __stream << item_type << "_destination_prefix=\"" << name << "\" "; + else if (!name.empty()) + __stream << item_type << "_" << (item_type == "send" ? "destination" : "sender") << "=\"" << name << "\" "; + + if (!path.empty()) + __stream << item_type << "_" << "path=\"" << path << "\" "; + if (!interface.empty()) + __stream << item_type << "_" << "interface=\"" << interface << "\" "; + if (!member.empty()) + __stream << item_type << "_" << "member=\"" << member << "\" "; + if (!decisionPrivilege.empty()) + __stream << item_type << "_" << "privilege=\"" << decisionPrivilege << "\" "; + + type_str = ContentPrinterXMLData::messageTypeToStr(type); + std::transform(type_str.begin(), type_str.end(), type_str.begin(), [](unsigned char c){ return std::tolower(c); }); + + if (type_str != "any") + __stream << item_type << "_" << "type=\"" << type_str << "\" "; + + __stream << "/>"; + } + + template + boost::string_ref toStringRef(const String &str) const { + return boost::string_ref(__db.stringGetCStr(str), __db.stringGetSize(str)); + } + +public: + ContentPrinter(const StorageBackendDatabase &database, std::ostream &stream, bool xml_format = false) + : __db{database}, + __stream{stream}, + __xml_format{xml_format} + {} + + template + void printDecisionItem(const DecisionItem &decision_item) { + printDecisionItem(ldp_serialized::makeDecision(__db.decisionItemGetDecision(decision_item)), + __db.stringGetCStr(__db.decisionItemGetPrivilege(decision_item))); + } + + template + void printItemSRXML(const ItemSR &item, boost::string_ref item_type) { + auto decisionItem = __db.itemGetDecisionItem(item); + printItemSRXML(item_type, + toStringRef(__db.itemSrGetName(item)), + toStringRef(__db.itemSrGetInterface(item)), + toStringRef(__db.itemSrGetMember(item)), + toStringRef(__db.itemSrGetPath(item)), + ldp_serialized::makeMessageType(__db.itemSrGetMessageType(item)), + ldp_serialized::makeDecision(__db.decisionItemGetDecision(decisionItem)), + toStringRef(__db.decisionItemGetPrivilege(decisionItem)), + __db.itemSrGetIsNamePrefix(item)); + } + + template + void printItemSRText(const ItemSR &item, boost::string_ref item_type) { + __stream << item_type << ": "; + auto name = toStringRef(__db.itemSrGetName(item)); + if (__db.itemSrGetIsNamePrefix(item)) + printVal("name_prefix", name); + else + printVal("name", name); + printNextVal("inter", toStringRef(__db.itemSrGetInterface(item))); + printNextVal("member", toStringRef(__db.itemSrGetMember(item))); + printNextVal("path", toStringRef(__db.itemSrGetPath(item))); + auto message_type = ldp_serialized::makeMessageType(__db.itemSrGetMessageType(item)); + printNextVal("type", ContentPrinterXMLData::messageTypeToStr(message_type)); + printNextValFun("decision", [&] { printDecisionItem(__db.itemGetDecisionItem(item)); }); + } + + template + void printItemSR(const ItemSR &item, boost::string_ref item_type, boost::string_ref item_type_xml) { + if (__xml_format) + printItemSRXML(item, item_type_xml); + else + printItemSRText(item, item_type); + } + + template + void printItem(const Item &item, ldp_serialization::SendType) { + printItemSR(item, "ItemSend", "send"); + } + + template + void printItem(const Item &item, ldp_serialization::ReceiveType) { + printItemSR(item, "ItemReceive", "receive"); + } + + template + void printItem(const Item &item, ldp_serialization::AccessType) { + __stream << "ItemAccess: "; + auto type = ldp_serialized::makeBusAccessType(__db.itemAccessGetType(item)); + printVal("type", ContentPrinterXMLData::accessTypeToStr(type)); + printNextVal("uid", __db.itemAccessGetUid(item)); + printNextVal("gid", __db.itemAccessGetGid(item)); + printNextValFun("decision", [&] { printDecisionItem(__db.itemGetDecisionItem(item)); }); + } + + template + void printItem(const Item &item) + { + printItem(item, typename ldp_serialization::ItemType::result()); + } + + template + void printPolicy(const Policy &policy, ldp_serialization::ItemsType) { + auto items = __db.policyGetItems(policy); + auto end = __db.containerGetIteratorEnd(items); + for (auto i = __db.containerGetIterator(items); i != end; i++) { + printItem(*i); + __stream << std::endl; + } + } + + template + void printTreeLevel(const PolicyOwnNode &node, unsigned level) { + for (decltype(level) i = 0; i < level; ++i) + __stream << "\t"; + + __stream << "| " << __db.stringGetCStr(__db.ownNodeGetToken(node)) << " (" << __db.containerGetSize(__db.ownNodeGetChildren(node)) << ") | "; + printDecisionItem(__db.ownNodeGetDecisionItem(node)); + __stream << " "; + printDecisionItem(__db.ownNodeGetPrefixDecisionItem(node)); + __stream << std::endl; + + auto children = __db.ownNodeGetChildren(node); + auto end = __db.containerGetIteratorEnd(children); + for (auto i = __db.containerGetIterator(children); i != end; i++) + printTreeLevel(*i, level+1); + } + + template + void printPolicy(const Policy &policy, ldp_serialization::TreeType) { + printTreeLevel(__db.policyGetTree(policy), 0); + } + + template + void printPolicy(const Policy &policy) { + printPolicy(policy, typename ldp_serialization::PolicyContentType::result()); + } + + template + void printSetUserGroupMap(const SetUserGroup &set_user_group, const char *message) { + auto end = __db.containerGetIteratorEnd(set_user_group); + for (auto i = __db.containerGetIterator(set_user_group); i != end; i++) { + __stream << message << ": " << __db.setUserGroupGetId(*i) << std::endl; + printPolicy(__db.setUserGroupGetPolicy(*i)); + } + } + + template + void printSetUserGroup(const Set &set, std::true_type) { + printSetUserGroupMap(__db.setGetUser(set), "user"); + printSetUserGroupMap(__db.setGetGroup(set), "group"); + } + + template + void printSetUserGroup(const Set &, std::false_type) + { + // print nothing for sets without user and group maps + } + + template + void printSet(const Set &set) { + __stream << "context default" << std::endl; + printPolicy(__db.setGetContextDefault(set)); + __stream << "context mandatory" << std::endl; + printPolicy(__db.setGetContextMandatory(set)); + + printSetUserGroup(set, typename ldp_serialization::HasUserGroup::result()); + } + + template + std::ostream &printFile(const File &file) { + printSet(__db.fileGetOwnSet(file)); + printSet(__db.fileGetSendSet(file)); + printSet(__db.fileGetReceiveSet(file)); + printSet(__db.fileGetAccessSet(file)); + return __stream; + } + + std::ostream &printContent() { + return printFile(__db.getFile()); + } +}; + +template +auto contentPrinter(const DB &db, std::ostream &stream, bool xml_format = false) { + return ContentPrinter(db, stream, xml_format); } -namespace FB { -std::ostream &operator<<(std::ostream &stream, const FB::File &file); } namespace ldp_xml_parser { diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index 868aa1f..1b0b84e 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ #include "include/fb_generated.h" -#include "print_content.hpp" #include "serialized_convert.hpp" #include "storage_backend_flatbuffers.hpp" #include "tslog.hpp" @@ -208,11 +207,6 @@ bool StorageBackendFlatbuffers::initFromData(const uint8_t *mem, size_t size, bo return file != nullptr; } -void StorageBackendFlatbuffers::printContent(const bool xml_format) const { - print_content::use_xml_format(xml_format); - std::cerr << *file; -} - /*************************************************/ #define TYPE_HELPER(T, t) \ template <> \ diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index 107c55b..f5181ff 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -31,8 +31,6 @@ public: bool initFromData(const uint8_t *serialized_data, size_t length, bool verify); void release(); - void printContent(const bool xml_format = false) const; - // Supported template parameters are: // MatchPolicyOwn, MatchPolicySend, MatchPolicyReceive // and - only for Contexts - MatchPolicyAccess diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp index 12959d3..8337ee0 100644 --- a/src/internal/storage_backend_serialized.cpp +++ b/src/internal/storage_backend_serialized.cpp @@ -20,6 +20,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "print_content.hpp" #include "storage_backend_serialized.hpp" #include "transaction_guard.hpp" #include "tslog.hpp" @@ -90,6 +91,10 @@ bool StorageBackendSerialized::initFromData(const uint8_t *serialized_data, size return impl.initFromData(serialized_data, length, verify); } +void StorageBackendSerialized::printContent(bool xml_format) const { + print_content::contentPrinter(impl, std::cerr, xml_format).printContent(); +} + void StorageBackendSerialized::releaseMMap() { assert(MAP_FAILED != __mem); assert(0 != __length); diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp index 9438f86..1074b76 100644 --- a/src/internal/storage_backend_serialized.hpp +++ b/src/internal/storage_backend_serialized.hpp @@ -37,8 +37,7 @@ public: bool initFromData(const uint8_t *serialized_data, size_t length, bool verify = false); void release(); - void printContent(bool xml_format = false) const - { impl.printContent(xml_format); } + void printContent(bool xml_format = false) const; // Supported template parameters are: // MatchItemOwn, MatchItemSend, MatchItemReceive -- 2.7.4 From f17b5679dc5c6f44c87938430daccfa2eae67cac Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 28 Oct 2020 09:02:06 +0100 Subject: [PATCH 11/16] refactoring: move makeDecisionItem, and use new interface Change-Id: Ibb64103c318ff1cf404dd23bdf837c28da06a120 --- src/internal/serialized_convert.hpp | 5 ----- src/internal/storage_backend_flatbuffers.cpp | 5 +++++ src/internal/storage_backend_flatbuffers.hpp | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/internal/serialized_convert.hpp b/src/internal/serialized_convert.hpp index de00f2f..5d0b8af 100644 --- a/src/internal/serialized_convert.hpp +++ b/src/internal/serialized_convert.hpp @@ -24,11 +24,6 @@ ldp_xml_parser::Decision makeDecision(D d) { return static_cast(d); } -template -inline ldp_xml_parser::DecisionItem makeDecisionItem(const DI *di) { - return ldp_xml_parser::DecisionItem(makeDecision(di->decision()), di->privilege()->c_str()); -} - template ldp_xml_parser::BusAccessType makeBusAccessType(T type) { return static_cast(type); diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index 1b0b84e..6aedb60 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -35,6 +35,11 @@ const unsigned int FB_ID_SIZE = 4; template struct type_helper; +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::makeDecisionItem(const DecisionItem *item) const { + return ldp_xml_parser::DecisionItem(makeDecision(decisionItemGetDecision(item)), + stringGetCStr(decisionItemGetPrivilege(item))); +} + boost::string_ref StorageBackendFlatbuffers::toStringRef(const flatbuffers::String *str) const { return boost::string_ref(str->c_str(), str->size()); } diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index f5181ff..f831282 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -230,6 +230,8 @@ private: bool match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const; + ldp_xml_parser::DecisionItem makeDecisionItem(const FB::DecisionItem *item) const; + boost::string_ref toStringRef(const flatbuffers::String *str) const; }; -- 2.7.4 From 51342eb4206998b74615f3a7956ffb584a03e1a1 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 28 Oct 2020 10:11:29 +0100 Subject: [PATCH 12/16] serialization: use new interface for operations Change-Id: Idfd52382dd4b3acd4d158d7604468e9fcc297a9b --- src/internal/storage_backend_flatbuffers.cpp | 149 +++++++++++++++------------ src/internal/storage_backend_flatbuffers.hpp | 4 +- 2 files changed, 87 insertions(+), 66 deletions(-) diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index 6aedb60..07b1213 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -41,30 +41,31 @@ ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::makeDecisionItem(const D } boost::string_ref StorageBackendFlatbuffers::toStringRef(const flatbuffers::String *str) const { - return boost::string_ref(str->c_str(), str->size()); + return boost::string_ref(stringGetCStr(str), stringGetSize(str)); } template bool StorageBackendFlatbuffers::match(const T &match, const I *i) const { - return match.match(makeMessageType(i->type()), - toStringRef(i->interface()), - toStringRef(i->path()), - toStringRef(i->member()), - toStringRef(i->name()), - i->is_name_prefix(), - makeDecision(i->decision()->decision())); + return match.match(makeMessageType(itemSrGetMessageType(i)), + toStringRef(itemSrGetInterface(i)), + toStringRef(itemSrGetPath(i)), + toStringRef(itemSrGetMember(i)), + toStringRef(itemSrGetName(i)), + itemSrGetIsNamePrefix(i), + makeDecision(decisionItemGetDecision(itemGetDecisionItem(i)))); } bool StorageBackendFlatbuffers::match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const { - return match.match(makeBusAccessType(item->type()), item->uid(), item->gid()); + return match.match(makeBusAccessType(itemAccessGetType(item)), itemAccessGetUid(item), itemAccessGetGid(item)); } template ::policy_type> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, const P *policy) const { - const auto *v = policy->items(); - for (auto it = v->rbegin(); it != v->rend(); ++it) { - if (match(item, *it)) - return makeDecisionItem((*it)->decision()); + const auto *v = policyGetItems(policy); + auto rend = containerGetReverseIteratorEnd(v); + for (auto rit = containerGetReverseIterator(v); rit != rend; ++rit) { + if (match(item, *rit)) + return makeDecisionItem(itemGetDecisionItem(*rit)); } return ldp_xml_parser::Decision::ANY; } @@ -73,20 +74,25 @@ auto StorageBackendFlatbuffers::getDecisionItemFromTree(const FB::PolicyOwnNode const tokenizer::iterator &tokens_end, tokenizer::iterator &iterator) const { if (iterator == tokens_end) { - if (node->decision_item()->decision() != Decision_ANY) - return node->decision_item(); + if (makeDecision(decisionItemGetDecision(ownNodeGetDecisionItem(node))) != ldp_xml_parser::Decision::ANY) + return ownNodeGetDecisionItem(node); else - return node->prefix_decision_item(); + return ownNodeGetPrefixDecisionItem(node); } - auto child = node->children()->LookupByKey(iterator->c_str()); - if (nullptr == child) - return node->prefix_decision_item(); + auto children = ownNodeGetChildren(node); + + if (containerEmpty(children)) + return ownNodeGetPrefixDecisionItem(node); + + auto child = containerLookupByKey(children, iterator->c_str()); + if (!child.first) + return ownNodeGetPrefixDecisionItem(node); ++iterator; - const DecisionItem *child_decision = getDecisionItemFromTree(child, tokens_end, iterator); - if (child_decision->decision() == Decision_ANY) - return node->prefix_decision_item(); + auto child_decision = getDecisionItemFromTree(child.second, tokens_end, iterator); + if (makeDecision(decisionItemGetDecision(child_decision)) == ldp_xml_parser::Decision::ANY) + return ownNodeGetPrefixDecisionItem(node); return child_decision; } @@ -100,69 +106,73 @@ ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const ld boost::char_separator separator("."); tokenizer tokens(item.getName(), separator); - auto node = policy->tree(); - if (nullptr == node) - return ldp_xml_parser::Decision::ANY; - auto iterator = tokens.begin(); - return makeDecisionItem(getDecisionItemFromTree(node, tokens.end(), iterator)); + return makeDecisionItem(getDecisionItemFromTree(policyGetTree(policy), tokens.end(), iterator)); } -template ::policy_type> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemMaybeNull(const T &item, const P *policyPair) const { - if (nullptr == policyPair) +template +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const MatchItem &item, const Map &map, id_t id) const { + if (containerEmpty(map)) return ldp_xml_parser::Decision::ANY; - return getDecisionItem(item, policyPair->policy()); + + auto elem = containerLookupByKey(map, id); + if (!elem.first) + return ldp_xml_parser::Decision::ANY; + return getDecisionItem(item, setUserGroupGetPolicy(elem.second)); } ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemFromSendIndex(const MatchItemSend &item, const FB::PolicySend *policy) const { - const auto *index = policy->index(); - - if (!index || index->size() == 0) // this indicates version earlier than LDP2 + if (!policyHasIndex(policy)) return getDecisionItem(item, policy); // make it old way for old databases - std::pair currentBest(nullptr, 0); + auto index = policyGetIndex(policy); - auto updateCurrentBest = [&](const flatbuffers::Vector *vec) { + uint32_t currentBest = 0; + + auto updateCurrentBest = [¤tBest, &item, &policy, this](const auto &vec) { // look from the back, the rule is the same as for the full database // we now only check among less elements, because the database is indexed to small lists // item_scores are in increasing order in the index, and they serve also as ids of the policy rules - for (auto item_score_it = vec->rbegin(); item_score_it != vec->rend(); item_score_it++) { - const auto *fb_item = policy->items()->Get(*item_score_it - 1); // rules are indexed/scored from 1 - if (*item_score_it > currentBest.second && match(item, fb_item)) { - currentBest.first = fb_item; - currentBest.second = *item_score_it; + for (auto item_score_it = containerGetReverseIterator(vec); + item_score_it != containerGetReverseIteratorEnd(vec); + item_score_it++) { + auto db_items = policyGetItems(policy); + auto db_item = containerLookupByIndex(db_items, *item_score_it - 1); // rules are indexed/scored from 1 + if (*item_score_it > currentBest && match(item, db_item)) { + currentBest = *item_score_it; return; - } else if (*item_score_it <= currentBest.second) { + } else if (*item_score_it <= currentBest) { // there is no need to look further as we can't improve the score anymore return; } } }; - auto searchAndUpdateCurrentBest = [&](boost::string_ref name_ref) { + auto searchAndUpdateCurrentBest = [¤tBest, &index, &updateCurrentBest, this](boost::string_ref name_ref) { // we need to create C-string for flatbuffers lookups // boost::string_ref gives us correct start, but possibly NUL-terminated in a wrong place, as it does not modify // input string and keeps only the length std::string name(name_ref.data(), name_ref.size()); + if (containerEmpty(index)) + return; + // check if there are any rules for the name - const auto *fit = index->LookupByKey(name.c_str()); - if (!fit) + auto fit = containerLookupByKey(index, name.c_str()); + if (!fit.first) return; // check if there's any chance to get better score - if (fit->best_score() <= currentBest.second) + if (policyIndexGetBestScore(fit.second) <= currentBest) return; // look for better score - updateCurrentBest(fit->item_refs()); + updateCurrentBest(policyIndexGetItemRefs(fit.second)); }; - const auto *prefixIndex = policy->prefix_index(); - assert(prefixIndex); + auto prefixIndex = policyGetPrefixIndex(policy); // iterate over names for (const auto &name: item.getNames()) { @@ -177,11 +187,13 @@ ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemFromSendI searchAndUpdateCurrentBest(""); // if a matching rule was found, return the decision - if (currentBest.first) - return makeDecisionItem(currentBest.first->decision()); + if (currentBest > 0) { + auto db_item = containerLookupByIndex(policyGetItems(policy), currentBest - 1); + return makeDecisionItem(itemGetDecisionItem(db_item)); + } // or if no matching rule was not found, return the default decision - return ldp_xml_parser::DecisionItem(ldp_xml_parser::Decision::ANY); + return ldp_xml_parser::Decision::ANY; } void StorageBackendFlatbuffers::release() { @@ -222,7 +234,7 @@ bool StorageBackendFlatbuffers::initFromData(const uint8_t *mem, size_t size, bo template <> \ auto StorageBackendFlatbuffers::getPolicySet() const { \ assert(file); \ - return file->m_##t##_set(); \ + return fileGet##T##Set(getFile()); \ } TYPE_HELPER(Own, own) @@ -232,45 +244,54 @@ TYPE_HELPER(Access, access) template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const MatchItemSend &item) const { - return getDecisionItemFromSendIndex(item, getPolicySet()->context_mandatory()); + return getDecisionItemFromSendIndex(item, setGetContextMandatory(getPolicySet())); } template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const MatchItemSend &item) const { - return getDecisionItemFromSendIndex(item, getPolicySet()->context_default()); + return getDecisionItemFromSendIndex(item, setGetContextDefault(getPolicySet())); } template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const MatchItemSend &item) const { - auto *policyPair = getPolicySet()->user()->LookupByKey(uid); - if (nullptr == policyPair) + auto map = setGetUser(getPolicySet()); + + if (containerEmpty(map)) return ldp_xml_parser::Decision::ANY; - return getDecisionItemFromSendIndex(item, policyPair->policy()); + + auto elem = containerLookupByKey(map, uid); + if (!elem.first) + return ldp_xml_parser::Decision::ANY; + return getDecisionItemFromSendIndex(item, setUserGroupGetPolicy(elem.second)); } template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const T &item) const { - return getDecisionItem(item, getPolicySet()->context_mandatory()); + return getDecisionItem(item, setGetContextMandatory(getPolicySet())); } template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const T &item) const { - return getDecisionItem(item, getPolicySet()->context_default()); + return getDecisionItem(item, setGetContextDefault(getPolicySet())); } template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const T &item) const { - return getDecisionItemMaybeNull(item, getPolicySet()->user()->LookupByKey(uid)); + return getDecisionItem(item, setGetUser(getPolicySet()), uid); } - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemGroup(gid_t gid, const T &item) const { - return getDecisionItemMaybeNull(item, getPolicySet()->group()->LookupByKey(gid)); + return getDecisionItem(item, setGetGroup(getPolicySet()), gid); } template bool StorageBackendFlatbuffers::existsPolicyForGroup(gid_t gid) const { - return getPolicySet()->group()->LookupByKey(gid) != nullptr; + auto map = setGetGroup(getPolicySet()); + + if (containerEmpty(map)) + return false; + + return containerLookupByKey(map, gid).first; } #define T_INSTANTIATION(T) \ diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index f831282..536808a 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -218,8 +218,8 @@ private: ldp_xml_parser::DecisionItem getDecisionItemFromSendIndex(const ldp_xml_parser::MatchItemSend &item, const FB::PolicySend *policy) const; - template - ldp_xml_parser::DecisionItem getDecisionItemMaybeNull(const T &item, const P *policyPair) const; + template + ldp_xml_parser::DecisionItem getDecisionItem(const MatchItem &item, const Map &map, id_t id) const; auto getDecisionItemFromTree(const FB::PolicyOwnNode *node, const tokenizer::iterator &tokens_end, -- 2.7.4 From 4434b9892538978be1fb1ee81c6680b06f8d414e Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 28 Oct 2020 10:40:45 +0100 Subject: [PATCH 13/16] refactoring: generalize operations Change-Id: I6af4d846397b73dc3dfaf45ccf5ebb0fd1ceef46 --- src/internal/storage_backend_flatbuffers.cpp | 33 +++++++--------------------- src/internal/storage_backend_flatbuffers.hpp | 10 +++++++-- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index 07b1213..feba813 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -60,7 +60,7 @@ bool StorageBackendFlatbuffers::match(const ldp_xml_parser::MatchItemAccess &mat } template ::policy_type> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, const P *policy) const { +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, const P *policy, ldp_serialization::ItemsType) const { const auto *v = policyGetItems(policy); auto rend = containerGetReverseIteratorEnd(v); for (auto rit = containerGetReverseIterator(v); rit != rend; ++rit) { @@ -99,7 +99,8 @@ auto StorageBackendFlatbuffers::getDecisionItemFromTree(const FB::PolicyOwnNode template <> ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const ldp_xml_parser::MatchItemOwn &item, - const PolicyOwn *policy) const { + const PolicyOwn *policy, + ldp_serialization::TreeType) const { if (item.getName().length() == 0) return ldp_xml_parser::Decision::DENY; @@ -122,10 +123,10 @@ ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const Ma return getDecisionItem(item, setUserGroupGetPolicy(elem.second)); } -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemFromSendIndex(const MatchItemSend &item, const FB::PolicySend *policy) const { +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const MatchItemSend &item, const FB::PolicySend *policy) const { if (!policyHasIndex(policy)) - return getDecisionItem(item, policy); // make it old way for old databases + return getDecisionItem(item, policy, ldp_serialization::ItemsType()); // make it old way for old databases auto index = policyGetIndex(policy); @@ -242,27 +243,9 @@ TYPE_HELPER(Send, send) TYPE_HELPER(Receive, receive) TYPE_HELPER(Access, access) -template <> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const MatchItemSend &item) const { - return getDecisionItemFromSendIndex(item, setGetContextMandatory(getPolicySet())); -} - -template <> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const MatchItemSend &item) const { - return getDecisionItemFromSendIndex(item, setGetContextDefault(getPolicySet())); -} - -template <> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const MatchItemSend &item) const { - auto map = setGetUser(getPolicySet()); - - if (containerEmpty(map)) - return ldp_xml_parser::Decision::ANY; - - auto elem = containerLookupByKey(map, uid); - if (!elem.first) - return ldp_xml_parser::Decision::ANY; - return getDecisionItemFromSendIndex(item, setUserGroupGetPolicy(elem.second)); +template +ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, P policy) const { + return getDecisionItem(item, policy, typename ldp_serialization::PolicyContentType

::result()); } template diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index 536808a..cf7d4e1 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -214,9 +214,15 @@ private: auto getPolicySet() const; template - ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy) const; + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy, ldp_serialization::ItemsType) const; - ldp_xml_parser::DecisionItem getDecisionItemFromSendIndex(const ldp_xml_parser::MatchItemSend &item, const FB::PolicySend *policy) const; + template + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy, ldp_serialization::TreeType) const; + + template + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, P policy) const; + + ldp_xml_parser::DecisionItem getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const FB::PolicySend *policy) const; template ldp_xml_parser::DecisionItem getDecisionItem(const MatchItem &item, const Map &map, id_t id) const; -- 2.7.4 From c6d04cb74ad879df4731acf9c6fc7b17d25ab865 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 28 Oct 2020 11:10:58 +0100 Subject: [PATCH 14/16] refactoring: move generalized operations to StorageBackendSerialized Change-Id: I9abb90ff1d81970d939ca3f80b784c9b7b60ab23 --- src/internal/storage_backend_flatbuffers.cpp | 247 --------------------------- src/internal/storage_backend_flatbuffers.hpp | 53 ------ src/internal/storage_backend_serialized.cpp | 238 ++++++++++++++++++++++++++ src/internal/storage_backend_serialized.hpp | 53 ++++-- 4 files changed, 281 insertions(+), 310 deletions(-) diff --git a/src/internal/storage_backend_flatbuffers.cpp b/src/internal/storage_backend_flatbuffers.cpp index feba813..f2a5bec 100644 --- a/src/internal/storage_backend_flatbuffers.cpp +++ b/src/internal/storage_backend_flatbuffers.cpp @@ -13,12 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "include/fb_generated.h" -#include "serialized_convert.hpp" #include "storage_backend_flatbuffers.hpp" -#include "tslog.hpp" -#include -#include using namespace FB; using ldp_xml_parser::MatchItemSend; @@ -32,171 +27,6 @@ const unsigned int FB_ID_SIZE = 4; } // anonymous namespace -template -struct type_helper; - -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::makeDecisionItem(const DecisionItem *item) const { - return ldp_xml_parser::DecisionItem(makeDecision(decisionItemGetDecision(item)), - stringGetCStr(decisionItemGetPrivilege(item))); -} - -boost::string_ref StorageBackendFlatbuffers::toStringRef(const flatbuffers::String *str) const { - return boost::string_ref(stringGetCStr(str), stringGetSize(str)); -} - -template -bool StorageBackendFlatbuffers::match(const T &match, const I *i) const { - return match.match(makeMessageType(itemSrGetMessageType(i)), - toStringRef(itemSrGetInterface(i)), - toStringRef(itemSrGetPath(i)), - toStringRef(itemSrGetMember(i)), - toStringRef(itemSrGetName(i)), - itemSrGetIsNamePrefix(i), - makeDecision(decisionItemGetDecision(itemGetDecisionItem(i)))); -} - -bool StorageBackendFlatbuffers::match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const { - return match.match(makeBusAccessType(itemAccessGetType(item)), itemAccessGetUid(item), itemAccessGetGid(item)); -} - -template ::policy_type> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, const P *policy, ldp_serialization::ItemsType) const { - const auto *v = policyGetItems(policy); - auto rend = containerGetReverseIteratorEnd(v); - for (auto rit = containerGetReverseIterator(v); rit != rend; ++rit) { - if (match(item, *rit)) - return makeDecisionItem(itemGetDecisionItem(*rit)); - } - return ldp_xml_parser::Decision::ANY; -} - -auto StorageBackendFlatbuffers::getDecisionItemFromTree(const FB::PolicyOwnNode *node, - const tokenizer::iterator &tokens_end, - tokenizer::iterator &iterator) const { - if (iterator == tokens_end) { - if (makeDecision(decisionItemGetDecision(ownNodeGetDecisionItem(node))) != ldp_xml_parser::Decision::ANY) - return ownNodeGetDecisionItem(node); - else - return ownNodeGetPrefixDecisionItem(node); - } - - auto children = ownNodeGetChildren(node); - - if (containerEmpty(children)) - return ownNodeGetPrefixDecisionItem(node); - - auto child = containerLookupByKey(children, iterator->c_str()); - if (!child.first) - return ownNodeGetPrefixDecisionItem(node); - - ++iterator; - auto child_decision = getDecisionItemFromTree(child.second, tokens_end, iterator); - if (makeDecision(decisionItemGetDecision(child_decision)) == ldp_xml_parser::Decision::ANY) - return ownNodeGetPrefixDecisionItem(node); - - return child_decision; -} - -template <> -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const ldp_xml_parser::MatchItemOwn &item, - const PolicyOwn *policy, - ldp_serialization::TreeType) const { - if (item.getName().length() == 0) - return ldp_xml_parser::Decision::DENY; - - boost::char_separator separator("."); - tokenizer tokens(item.getName(), separator); - - auto iterator = tokens.begin(); - - return makeDecisionItem(getDecisionItemFromTree(policyGetTree(policy), tokens.end(), iterator)); -} - -template -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const MatchItem &item, const Map &map, id_t id) const { - if (containerEmpty(map)) - return ldp_xml_parser::Decision::ANY; - - auto elem = containerLookupByKey(map, id); - if (!elem.first) - return ldp_xml_parser::Decision::ANY; - return getDecisionItem(item, setUserGroupGetPolicy(elem.second)); -} - -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const MatchItemSend &item, const FB::PolicySend *policy) const { - - if (!policyHasIndex(policy)) - return getDecisionItem(item, policy, ldp_serialization::ItemsType()); // make it old way for old databases - - auto index = policyGetIndex(policy); - - uint32_t currentBest = 0; - - auto updateCurrentBest = [¤tBest, &item, &policy, this](const auto &vec) { - // look from the back, the rule is the same as for the full database - // we now only check among less elements, because the database is indexed to small lists - // item_scores are in increasing order in the index, and they serve also as ids of the policy rules - for (auto item_score_it = containerGetReverseIterator(vec); - item_score_it != containerGetReverseIteratorEnd(vec); - item_score_it++) { - auto db_items = policyGetItems(policy); - auto db_item = containerLookupByIndex(db_items, *item_score_it - 1); // rules are indexed/scored from 1 - if (*item_score_it > currentBest && match(item, db_item)) { - currentBest = *item_score_it; - return; - } else if (*item_score_it <= currentBest) { - // there is no need to look further as we can't improve the score anymore - return; - } - } - }; - - auto searchAndUpdateCurrentBest = [¤tBest, &index, &updateCurrentBest, this](boost::string_ref name_ref) { - // we need to create C-string for flatbuffers lookups - // boost::string_ref gives us correct start, but possibly NUL-terminated in a wrong place, as it does not modify - // input string and keeps only the length - std::string name(name_ref.data(), name_ref.size()); - - if (containerEmpty(index)) - return; - - // check if there are any rules for the name - auto fit = containerLookupByKey(index, name.c_str()); - if (!fit.first) - return; - - // check if there's any chance to get better score - if (policyIndexGetBestScore(fit.second) <= currentBest) - return; - - // look for better score - updateCurrentBest(policyIndexGetItemRefs(fit.second)); - }; - - auto prefixIndex = policyGetPrefixIndex(policy); - - // iterate over names - for (const auto &name: item.getNames()) { - // find and check the no-prefix rules - searchAndUpdateCurrentBest(name); - - // check the prefix rules - updateCurrentBest(prefixIndex); - } - - // check no-name rules - searchAndUpdateCurrentBest(""); - - // if a matching rule was found, return the decision - if (currentBest > 0) { - auto db_item = containerLookupByIndex(policyGetItems(policy), currentBest - 1); - return makeDecisionItem(itemGetDecisionItem(db_item)); - } - - // or if no matching rule was not found, return the default decision - return ldp_xml_parser::Decision::ANY; -} - void StorageBackendFlatbuffers::release() { file = nullptr; } @@ -225,81 +55,4 @@ bool StorageBackendFlatbuffers::initFromData(const uint8_t *mem, size_t size, bo return file != nullptr; } -/*************************************************/ -#define TYPE_HELPER(T, t) \ - template <> \ - struct type_helper { \ - typedef FB::T##Set policy_set_type; \ - typedef FB::Policy##T policy_type; \ - }; \ - template <> \ - auto StorageBackendFlatbuffers::getPolicySet() const { \ - assert(file); \ - return fileGet##T##Set(getFile()); \ - } - -TYPE_HELPER(Own, own) -TYPE_HELPER(Send, send) -TYPE_HELPER(Receive, receive) -TYPE_HELPER(Access, access) - -template -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItem(const T &item, P policy) const { - return getDecisionItem(item, policy, typename ldp_serialization::PolicyContentType

::result()); -} - -template -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const T &item) const { - return getDecisionItem(item, setGetContextMandatory(getPolicySet())); -} - -template -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const T &item) const { - return getDecisionItem(item, setGetContextDefault(getPolicySet())); -} - -template -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const T &item) const { - return getDecisionItem(item, setGetUser(getPolicySet()), uid); -} -template -ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemGroup(gid_t gid, const T &item) const { - return getDecisionItem(item, setGetGroup(getPolicySet()), gid); -} - -template -bool StorageBackendFlatbuffers::existsPolicyForGroup(gid_t gid) const { - auto map = setGetGroup(getPolicySet()); - - if (containerEmpty(map)) - return false; - - return containerLookupByKey(map, gid).first; -} - -#define T_INSTANTIATION(T) \ - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextMandatory(const ldp_xml_parser::MatchItem##T &item) const; \ - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemContextDefault(const ldp_xml_parser::MatchItem##T &item) const; - -T_INSTANTIATION(Own) -T_INSTANTIATION(Send) -T_INSTANTIATION(Receive) -T_INSTANTIATION(Access) - -#undef T_INSTANTIATION - -#define T_INSTANTIATION2(T) \ - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemUser(uid_t uid, const ldp_xml_parser::MatchItem##T &item) const; \ - template ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::getDecisionItemGroup(gid_t gid, const ldp_xml_parser::MatchItem##T &item) const; \ - template bool StorageBackendFlatbuffers::existsPolicyForGroup(gid_t) const; - -T_INSTANTIATION2(Own) -T_INSTANTIATION2(Send) -T_INSTANTIATION2(Receive) - -#undef T_INSTANTIATION2 - -StorageBackendFlatbuffers::StorageBackendFlatbuffers() {} -StorageBackendFlatbuffers::~StorageBackendFlatbuffers() {} - } diff --git a/src/internal/storage_backend_flatbuffers.hpp b/src/internal/storage_backend_flatbuffers.hpp index cf7d4e1..d0291aa 100644 --- a/src/internal/storage_backend_flatbuffers.hpp +++ b/src/internal/storage_backend_flatbuffers.hpp @@ -18,36 +18,15 @@ #include "include/fb_generated.h" #include "policy.hpp" #include "serialization_traits.hpp" -#include #include namespace ldp_serialized { class StorageBackendFlatbuffers { public: - StorageBackendFlatbuffers(); - ~StorageBackendFlatbuffers(); - bool initFromData(const uint8_t *serialized_data, size_t length, bool verify); void release(); - // Supported template parameters are: - // MatchPolicyOwn, MatchPolicySend, MatchPolicyReceive - // and - only for Contexts - MatchPolicyAccess - template - ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const T &item) const; - template - ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const T &item) const; - template - ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const T &item) const; - template - ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const T &item) const; - - // This works with T set to MatchItemOwn, MatchItemSend or MatchItemReceive - // This is needed for filtering mapGroups. Check NaivePolicyChecker. - template - bool existsPolicyForGroup(gid_t gid) const; - const FB::File *getFile() const { return file; } @@ -205,40 +184,8 @@ public: size_t stringGetSize(const flatbuffers::String *str) const { return str->size(); } - typedef boost::tokenizer> tokenizer; - private: const FB::File *file{nullptr}; - - template - auto getPolicySet() const; - - template - ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy, ldp_serialization::ItemsType) const; - - template - ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy, ldp_serialization::TreeType) const; - - template - ldp_xml_parser::DecisionItem getDecisionItem(const T &item, P policy) const; - - ldp_xml_parser::DecisionItem getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const FB::PolicySend *policy) const; - - template - ldp_xml_parser::DecisionItem getDecisionItem(const MatchItem &item, const Map &map, id_t id) const; - - auto getDecisionItemFromTree(const FB::PolicyOwnNode *node, - const tokenizer::iterator &tokens_end, - tokenizer::iterator &iterator) const; - - template - bool match(const T &match, const I *i) const; - - bool match(const ldp_xml_parser::MatchItemAccess &match, const FB::ItemAccess *item) const; - - ldp_xml_parser::DecisionItem makeDecisionItem(const FB::DecisionItem *item) const; - - boost::string_ref toStringRef(const flatbuffers::String *str) const; }; } diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp index 8337ee0..ac3c5bc 100644 --- a/src/internal/storage_backend_serialized.cpp +++ b/src/internal/storage_backend_serialized.cpp @@ -21,9 +21,11 @@ * THE SOFTWARE. */ #include "print_content.hpp" +#include "serialized_convert.hpp" #include "storage_backend_serialized.hpp" #include "transaction_guard.hpp" #include "tslog.hpp" +#include #include #include #include @@ -123,3 +125,239 @@ void StorageBackendSerialized::release() { impl.release(); } + +template <> auto StorageBackendSerialized::getPolicySet() const { + return impl.fileGetOwnSet(impl.getFile()); +} + +template <> auto StorageBackendSerialized::getPolicySet() const { + return impl.fileGetSendSet(impl.getFile()); +} + +template <> auto StorageBackendSerialized::getPolicySet() const { + return impl.fileGetReceiveSet(impl.getFile()); +} + +template <> auto StorageBackendSerialized::getPolicySet() const { + return impl.fileGetAccessSet(impl.getFile()); +} + +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::makeDecisionItem(const DI &item) const { + return ldp_xml_parser::DecisionItem(makeDecision(impl.decisionItemGetDecision(item)), + impl.stringGetCStr(impl.decisionItemGetPrivilege(item))); +} + +template +boost::string_ref StorageBackendSerialized::toStringRef(const String &str) const { + return boost::string_ref(impl.stringGetCStr(str), impl.stringGetSize(str)); +} + +template +bool StorageBackendSerialized::match(const T &match, const I &item) const { + return match.match(makeMessageType(impl.itemSrGetMessageType(item)), + toStringRef(impl.itemSrGetInterface(item)), + toStringRef(impl.itemSrGetPath(item)), + toStringRef(impl.itemSrGetMember(item)), + toStringRef(impl.itemSrGetName(item)), + impl.itemSrGetIsNamePrefix(item), + makeDecision(impl.decisionItemGetDecision(impl.itemGetDecisionItem(item)))); +} + +template +bool StorageBackendSerialized::match(const ldp_xml_parser::MatchItemAccess &match, const I &item) const { + return match.match(makeBusAccessType(impl.itemAccessGetType(item)), impl.itemAccessGetUid(item), impl.itemAccessGetGid(item)); +} + +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const T &item, const P &policy, ldp_serialization::ItemsType) const { + auto v = impl.policyGetItems(policy); + auto rend = impl.containerGetReverseIteratorEnd(v); + for (auto rit = impl.containerGetReverseIterator(v); rit != rend; ++rit) { + if (match(item, *rit)) + return makeDecisionItem(impl.itemGetDecisionItem(*rit)); + } + return ldp_xml_parser::Decision::ANY; +} + +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const P &policy) const { + if (!impl.policyHasIndex(policy)) + return getDecisionItem(item, policy, ldp_serialization::ItemsType()); // make it old way for old databases + + auto index = impl.policyGetIndex(policy); + + uint32_t currentBest = 0; + + auto updateCurrentBest = [¤tBest, &item, &policy, this](const auto &vec) { + // look from the back, the rule is the same as for the full database + // we now only check among less elements, because the database is indexed to small lists + // item_scores are in increasing order in the index, and they serve also as ids of the policy rules + for (auto item_score_it = impl.containerGetReverseIterator(vec); + item_score_it != impl.containerGetReverseIteratorEnd(vec); + item_score_it++) { + auto db_items = impl.policyGetItems(policy); + auto db_item = impl.containerLookupByIndex(db_items, *item_score_it - 1); // rules are indexed/scored from 1 + if (*item_score_it > currentBest && match(item, db_item)) { + currentBest = *item_score_it; + return; + } else if (*item_score_it <= currentBest) { + // there is no need to look further as we can't improve the score anymore + return; + } + } + }; + + auto searchAndUpdateCurrentBest = [¤tBest, &index, &updateCurrentBest, this](boost::string_ref name_ref) { + // we need to create C-string for the lookups + // boost::string_ref gives us correct start, but possibly NUL-terminated in a wrong place, as it does not modify + // input string and keeps only the length + std::string name(name_ref.data(), name_ref.size()); + + if (impl.containerEmpty(index)) + return; + + // check if there are any rules for the name + auto fit = impl.containerLookupByKey(index, name.c_str()); + if (!fit.first) + return; + + // check if there's any chance to get better score + if (impl.policyIndexGetBestScore(fit.second) <= currentBest) + return; + + // look for better score + updateCurrentBest(impl.policyIndexGetItemRefs(fit.second)); + }; + + auto prefixIndex = impl.policyGetPrefixIndex(policy); + + // iterate over names + for (const auto &name: item.getNames()) { + // find and check the no-prefix rules + searchAndUpdateCurrentBest(name); + + // check the prefix rules + updateCurrentBest(prefixIndex); + } + + // check no-name rules + searchAndUpdateCurrentBest(""); + + // if a matching rule was found, return the decision + if (currentBest > 0) { + auto db_item = impl.containerLookupByIndex(impl.policyGetItems(policy), currentBest - 1); + return makeDecisionItem(impl.itemGetDecisionItem(db_item)); + } + + // or if no matching rule was not found, return the default decision + return ldp_xml_parser::Decision::ANY; +} + +template +auto StorageBackendSerialized::getDecisionItemFromTree(const OwnNode &node, + const tokenizer::iterator &tokens_end, + tokenizer::iterator &iterator) const { + if (iterator == tokens_end) { + if (makeDecision(impl.decisionItemGetDecision(impl.ownNodeGetDecisionItem(node))) != ldp_xml_parser::Decision::ANY) + return impl.ownNodeGetDecisionItem(node); + else + return impl.ownNodeGetPrefixDecisionItem(node); + } + + auto children = impl.ownNodeGetChildren(node); + + if (impl.containerEmpty(children)) + return impl.ownNodeGetPrefixDecisionItem(node); + + auto child = impl.containerLookupByKey(children, iterator->c_str()); + if (!child.first) + return impl.ownNodeGetPrefixDecisionItem(node); + + ++iterator; + auto child_decision = getDecisionItemFromTree(child.second, tokens_end, iterator); + if (makeDecision(impl.decisionItemGetDecision(child_decision)) == ldp_xml_parser::Decision::ANY) + return impl.ownNodeGetPrefixDecisionItem(node); + + return child_decision; +} + +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const T &item, const P &policy, ldp_serialization::TreeType) const { + if (item.getName().length() == 0) + return ldp_xml_parser::Decision::DENY; + + boost::char_separator separator("."); + tokenizer tokens(item.getName(), separator); + + auto iterator = tokens.begin(); + + return makeDecisionItem(getDecisionItemFromTree(impl.policyGetTree(policy), tokens.end(), iterator)); +} + +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const T &item, const P &policy) const { + return getDecisionItem(item, policy, typename ldp_serialization::PolicyContentType

::result()); +} + +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextMandatory(const MatchItem &item) const { + return getDecisionItem(item, impl.setGetContextMandatory(getPolicySet())); +} + +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextDefault(const MatchItem &item) const { + return getDecisionItem(item, impl.setGetContextDefault(getPolicySet())); +} + +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItem(const MatchItem &item, const Map &map, id_t id) const { + if (impl.containerEmpty(map)) + return ldp_xml_parser::Decision::ANY; + + auto elem = impl.containerLookupByKey(map, id); + if (!elem.first) + return ldp_xml_parser::Decision::ANY; + return getDecisionItem(item, impl.setUserGroupGetPolicy(elem.second)); +} + +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemUser(uid_t uid, const MatchItem &item) const { + return getDecisionItem(item, impl.setGetUser(getPolicySet()), uid); +} +template +ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemGroup(gid_t gid, const MatchItem &item) const { + return getDecisionItem(item, impl.setGetGroup(getPolicySet()), gid); +} + +template +bool StorageBackendSerialized::existsPolicyForGroup(gid_t gid) const { + auto map = impl.setGetGroup(getPolicySet()); + + if (impl.containerEmpty(map)) + return false; + + return impl.containerLookupByKey(map, gid).first; +} + +#define T_INSTANTIATION(T) \ + template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextMandatory(const ldp_xml_parser::MatchItem##T &item) const; \ + template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextDefault(const ldp_xml_parser::MatchItem##T &item) const; + +T_INSTANTIATION(Own) +T_INSTANTIATION(Send) +T_INSTANTIATION(Receive) +T_INSTANTIATION(Access) + +#undef T_INSTANTIATION + +#define T_INSTANTIATION2(T) \ + template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemUser(uid_t uid, const ldp_xml_parser::MatchItem##T &item) const; \ + template ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemGroup(gid_t gid, const ldp_xml_parser::MatchItem##T &item) const; \ + template bool StorageBackendSerialized::existsPolicyForGroup(gid_t) const; + +T_INSTANTIATION2(Own) +T_INSTANTIATION2(Send) +T_INSTANTIATION2(Receive) + +#undef T_INSTANTIATION2 diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp index 1074b76..e010b72 100644 --- a/src/internal/storage_backend_serialized.hpp +++ b/src/internal/storage_backend_serialized.hpp @@ -23,6 +23,7 @@ #include "policy.hpp" #include "serialization_backend.hpp" +#include #include namespace ldp_serialized { @@ -43,23 +44,18 @@ public: // MatchItemOwn, MatchItemSend, MatchItemReceive // and - only for Contexts - MatchItemAccess template - ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const MatchItem &item) const - { return impl.getDecisionItemContextMandatory(item); } + ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const MatchItem &item) const; template - ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const MatchItem &item) const - { return impl.getDecisionItemContextDefault(item); } + ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const MatchItem &item) const; template - ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const MatchItem &item) const - { return impl.getDecisionItemUser(uid, item); } + ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const MatchItem &item) const; template - ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const MatchItem &item) const - { return impl.getDecisionItemGroup(gid, item); } + ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const MatchItem &item) const; // This works with MatchItem set to MatchItemOwn, MatchItemSend or MatchItemReceive // This is needed for filtering mapGroups. Check NaivePolicyChecker. template - bool existsPolicyForGroup(gid_t gid) const - { return impl.existsPolicyForGroup(gid); } + bool existsPolicyForGroup(gid_t gid) const; private: typedef typename ldp_serialization::SerializationBackend::Storage Backend; @@ -75,6 +71,43 @@ private: void releaseMMap(); void releaseFD(); + + template + auto getPolicySet() const; + + template + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P &policy, ldp_serialization::ItemsType) const; + + template + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P &policy, ldp_serialization::TreeType) const; + + template + ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P &policy) const; + + template + ldp_xml_parser::DecisionItem getDecisionItem(const ldp_xml_parser::MatchItemSend &item, const P &policy) const; + + template + ldp_xml_parser::DecisionItem getDecisionItem(const MatchItem &item, const Map &map, id_t id) const; + + typedef boost::tokenizer> tokenizer; + + template + auto getDecisionItemFromTree(const OwnNode &node, + const tokenizer::iterator &tokens, + tokenizer::iterator &iterator) const; + + template + bool match(const T &match, const I &item) const; + + template + bool match(const ldp_xml_parser::MatchItemAccess &match, const I &item) const; + + template + ldp_xml_parser::DecisionItem makeDecisionItem(const DI &item) const; + + template + boost::string_ref toStringRef(const String &str) const; }; } -- 2.7.4 From 2d5b17ac874f01acb92b522a109537e0607f68b2 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Mon, 19 Oct 2020 10:33:00 +0200 Subject: [PATCH 15/16] refactoring: create indexes in StorageBackendXML This moves creating of indexes from serializers to StorageBackendXML. This way it's standardized, in a single place. Serializers now serialize the indexes from the StorageBackendXML instead of creating their own. Change-Id: Ie2aec8a8cbace425f2e74c402cb99c25f21a27d1 --- Makefile.am | 1 + src/internal/policy_containers.cpp | 43 +++++++++++++++++++++++++++++++++ src/internal/policy_containers.hpp | 18 +++++++++++++- src/internal/serializer_flatbuffers.cpp | 31 +++++------------------- src/internal/storage_backend_xml.cpp | 18 +++++++++++++- 5 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 src/internal/policy_containers.cpp diff --git a/Makefile.am b/Makefile.am index 1848ecd..f17af0b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -64,6 +64,7 @@ COMMON_SRC =\ src/internal/tslog.cpp \ src/internal/serializer.cpp \ src/internal/serializer_flatbuffers.cpp \ + src/internal/policy_containers.cpp \ src/internal/print_content.cpp \ src/internal/storage_backend_flatbuffers.cpp \ src/internal/storage_backend_serialized.cpp \ diff --git a/src/internal/policy_containers.cpp b/src/internal/policy_containers.cpp new file mode 100644 index 0000000..37f3183 --- /dev/null +++ b/src/internal/policy_containers.cpp @@ -0,0 +1,43 @@ +/* MIT License + * + * Copyright (c) 2019-2020 Samsung Electronics Co., Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#include "policy_containers.hpp" + +using namespace ldp_xml_parser; + +void PolicySend::createIndexes() { + uint32_t cnt = 1; + + for (const auto &item : getItems()) { + // create indexes + if (!item.isNamePrefix()) { + auto &elem = m_index[item.getName()]; // create or get an entry + elem.m_itemRefs.push_back(cnt); // add score/id to the list + // we insert items in increasing score/id order, so we just update the highest score on each add + elem.m_bestScore = cnt; + } else { + // just collect the prefix rules + m_prefixIndex.push_back(cnt); + } + ++cnt; + } +} diff --git a/src/internal/policy_containers.hpp b/src/internal/policy_containers.hpp index 0516d73..f61473a 100644 --- a/src/internal/policy_containers.hpp +++ b/src/internal/policy_containers.hpp @@ -18,6 +18,7 @@ #include "policy.hpp" #include "own_tree.hpp" #include +#include namespace ldp_xml_parser { /****************** PolicyBase: a base for policies ************************/ @@ -37,7 +38,22 @@ public: const std::vector &getItems() const { return m_items; } }; -using PolicySend = PolicyBase; +class PolicySend : public PolicyBase { +protected: + struct IndexEntry { + uint32_t m_bestScore; + std::vector m_itemRefs; + }; + // this maps a name to a pair (highest score + list of scores/ids for this name) + std::map m_index; + // prefix index is just a list of ids + std::vector m_prefixIndex; +public: + void createIndexes(); + const auto &getIndex() const { return m_index; } + const auto &getPrefixIndex() const { return m_prefixIndex; } +}; + using PolicyReceive = PolicyBase; using PolicyAccess = PolicyBase; diff --git a/src/internal/serializer_flatbuffers.cpp b/src/internal/serializer_flatbuffers.cpp index dc38275..a253a48 100644 --- a/src/internal/serializer_flatbuffers.cpp +++ b/src/internal/serializer_flatbuffers.cpp @@ -209,41 +209,22 @@ auto SerializerFlatbuffers::serialize_policy(const PolicySend &policy) -> FbOff { std::vector> items; - // this maps a name to a pair (highest score + list of scores/ids for this name) - std::map>> policyIndex; - // prefix index is just a list of ids - std::vector prefixIndex; - uint32_t cnt = 1; - - for (const auto &item : policy.getItems()) { + for (const auto &item : policy.getItems()) items.push_back(serialize_item(item)); - // create indexes - if (!item.isNamePrefix()) { - auto &elem = policyIndex[item.getName()]; // create or get an entry - elem.second.push_back(cnt); // add score/id to the list - // we insert items in increasing score/id order, so we just update the highest score on each add - elem.first = cnt; - } else { - // just collect the prefix rules - prefixIndex.push_back(cnt); - } - ++cnt; - } - // serialize main index std::vector> index; - for (auto &it: policyIndex) + for (auto &it: policy.getIndex()) index.push_back(FB::CreateNameScoresPairDirect(m_builder, - it.first.data(), // name - it.second.first, // best_score - &it.second.second)); // vector of scores/ids + it.first.data(), // name + it.second.m_bestScore, // best_score + &it.second.m_itemRefs)); // vector of scores/ids return FB::CreatePolicySend(m_builder, m_builder.CreateVector(items), m_builder.CreateVector(index), - m_builder.CreateVector(prefixIndex)); + m_builder.CreateVector(policy.getPrefixIndex())); } template diff --git a/src/internal/storage_backend_xml.cpp b/src/internal/storage_backend_xml.cpp index ec1b494..69ecf21 100644 --- a/src/internal/storage_backend_xml.cpp +++ b/src/internal/storage_backend_xml.cpp @@ -46,6 +46,12 @@ protected: public: const std::map &getPoliciesUser() const { return user; } const std::map &getPoliciesGroup() const { return group; } + void createIndexes() { + for (auto &elem: user) + elem.second.createIndexes(); + for (auto &elem: group) + elem.second.createIndexes(); + } }; /****************** NoUserAndGroupContext ************************/ @@ -56,6 +62,8 @@ protected: template void addItemGroup(gid_t, T &) { assert(false); } + + void createIndexes() {} }; /****************** PolicySet ************************/ @@ -102,6 +110,11 @@ public: const P &getRefPolicyContextMandatory() const { return contextMandatory; } const P &getRefPolicyContextDefault() const { return contextDefault; } + void createIndexes() { + contextMandatory.createIndexes(); + contextDefault.createIndexes(); + UG::createIndexes(); + } }; /****************** StorageBackendXML ************************/ @@ -145,7 +158,10 @@ void StorageBackendXML::addItem(const ldp_xml_parser::PolicyType policy_type, bool StorageBackendXML::init(const char *filename) { pimpl.reset(new StorageBackendXMLImpl); XmlParser parser(*this, filename); - return parser.parsePolicyConfigFile() == 0; + bool result = parser.parsePolicyConfigFile() == 0; + if (result) + pimpl->getPolicySetFromMatchItem().createIndexes(); + return result; } template -- 2.7.4 From 7c26ebc58999047980f2346c798b9bb9d18076cf Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 14 Oct 2020 10:52:10 +0200 Subject: [PATCH 16/16] tests: switch to the new extracting interface Change-Id: I2167e014c951099ff3ac56af7d2e3f64f5ee102f --- src/internal/serializer_flatbuffers.hpp | 1 - src/internal/storage_backend_serialized.hpp | 2 + src/test-serializer.cpp | 438 ++++++++++++++-------------- 3 files changed, 228 insertions(+), 213 deletions(-) diff --git a/src/internal/serializer_flatbuffers.hpp b/src/internal/serializer_flatbuffers.hpp index 62847fe..c240870 100644 --- a/src/internal/serializer_flatbuffers.hpp +++ b/src/internal/serializer_flatbuffers.hpp @@ -76,7 +76,6 @@ namespace ldp_serializer public: SerializerFlatbuffers() : m_db(nullptr) {} const uint8_t *serialize(const ldp_xml::StorageBackendXML &db, size_t &size); - friend class SerializerTests; }; } diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp index e010b72..4e25978 100644 --- a/src/internal/storage_backend_serialized.hpp +++ b/src/internal/storage_backend_serialized.hpp @@ -57,6 +57,8 @@ public: template bool existsPolicyForGroup(gid_t gid) const; + const auto &getBackend() const { return impl; } + private: typedef typename ldp_serialization::SerializationBackend::Storage Backend; Backend impl; diff --git a/src/test-serializer.cpp b/src/test-serializer.cpp index 8a457da..cf53196 100644 --- a/src/test-serializer.cpp +++ b/src/test-serializer.cpp @@ -19,15 +19,18 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "internal/include/fb_generated.h" -#include "internal/include/flatbuffers/flatbuffers.h" #include "internal/policy_containers.hpp" #include "internal/serializer.hpp" +#include "internal/serialized_convert.hpp" +#include "internal/storage_backend_serialized.hpp" +#include #include #include #include -namespace ldp_xml_parser { +using ldp_serialized::makeDecision; +using ldp_serialized::makeMessageType; +using ldp_serialized::makeBusAccessType; static void print_error(const char *fmt...) { va_list args; @@ -38,32 +41,26 @@ static void print_error(const char *fmt...) { va_end(args); } -std::map messageTypeMap = { - { FB::MessageType_ANY, "ANY" }, - { FB::MessageType_MIN, "MIN" }, - { FB::MessageType_MAX, "MAX" }, - { FB::MessageType_METHOD_RETURN, "METHOD_RETURN" }, - { FB::MessageType_ERROR, "ERROR" }, - { FB::MessageType_SIGNAL, "SIGNAL" }, - { FB::MessageType_METHOD_CALL, "METHOD_CALL" } +std::map messageTypeMap = { + { ldp_xml_parser::MessageType::ANY, "ANY" }, + { ldp_xml_parser::MessageType::METHOD_RETURN, "METHOD_RETURN" }, + { ldp_xml_parser::MessageType::ERROR, "ERROR" }, + { ldp_xml_parser::MessageType::SIGNAL, "SIGNAL" }, + { ldp_xml_parser::MessageType::METHOD_CALL, "METHOD_CALL" } }; -std::map decisionTypeMap = { - { FB::Decision_ANY, "ANY" }, - { FB::Decision_MIN, "MIN" }, - { FB::Decision_MAX, "MAX" }, - { FB::Decision_CHECK, "CHECK" }, - { FB::Decision_DENY, "DENY" }, - { FB::Decision_ALLOW, "ALLOW" } +std::map decisionTypeMap = { + { ldp_xml_parser::Decision::ANY, "ANY" }, + { ldp_xml_parser::Decision::CHECK, "CHECK" }, + { ldp_xml_parser::Decision::DENY, "DENY" }, + { ldp_xml_parser::Decision::ALLOW, "ALLOW" } }; -std::map busTypeMap = { - { FB::BusAccessType_MIN, "MIN" }, - { FB::BusAccessType_MAX, "MAX" }, - { FB::BusAccessType_USER, "USER" }, - { FB::BusAccessType_GROUP, "GROUP" }, - { FB::BusAccessType_ALL_USERS, "ALL_USERS" }, - { FB::BusAccessType_ALL_GROUPS, "ALL_GROUPS" }, +std::map busTypeMap = { + { ldp_xml_parser::BusAccessType::USER, "USER" }, + { ldp_xml_parser::BusAccessType::GROUP, "GROUP" }, + { ldp_xml_parser::BusAccessType::ALL_USERS, "ALL_USERS" }, + { ldp_xml_parser::BusAccessType::ALL_GROUPS, "ALL_GROUPS" }, }; struct TestsHelper { @@ -79,20 +76,20 @@ struct TestsHelper { return value.c_str(); } - static const char *to_str(const FB::MessageType value) { + static const char *to_str(const ldp_xml_parser::MessageType value) { return messageTypeMap[value]; } - static const char *to_str(const FB::Decision value) { + static const char *to_str(const ldp_xml_parser::Decision value) { return decisionTypeMap[value]; } - static const char *to_str(const FB::BusAccessType value) { + static const char *to_str(const ldp_xml_parser::BusAccessType value) { return busTypeMap[value]; } - template - static bool compare(const T current, const T expected) { + template + static bool compare(const T current, const S expected) { if (current != expected) { // print_error("Current: \"%s\" expected: \"%s\"", to_str(current), to_str(expected)); return false; @@ -111,9 +108,9 @@ using TH = TestsHelper; struct NodeTest { const std::string name; const std::string privilege; - const FB::Decision decision; + const ldp_xml_parser::Decision decision; const std::string prefix_privilege; - const FB::Decision prefix_decision; + const ldp_xml_parser::Decision prefix_decision; void printContent() const { TH::print_property("name", name); @@ -122,14 +119,6 @@ struct NodeTest { TH::print_property("prefix_privilege", prefix_privilege); TH::print_property("prefix_decision", prefix_decision); } - - bool isMatch(const FB::PolicyOwnNode *node, const std::string &token) const { - return (TH::compare(node->token()->str(), token) && - TH::compare(node->decision_item()->privilege()->str(), privilege) && - TH::compare(node->decision_item()->decision(), decision) && - TH::compare(node->prefix_decision_item()->privilege()->str(), prefix_privilege) && - TH::compare(node->prefix_decision_item()->decision(), prefix_decision)); - } }; struct ItemSRTest { @@ -137,9 +126,9 @@ struct ItemSRTest { const std::string interface; const std::string member; const std::string path; - const FB::MessageType type; + const ldp_xml_parser::MessageType type; const bool is_name_prefix; - const FB::Decision decision; + const ldp_xml_parser::Decision decision; void printContent() const { TH::print_property("name", name); @@ -150,25 +139,14 @@ struct ItemSRTest { TH::print_property("is_name_prefix", is_name_prefix); TH::print_property("decision", decision); } - - template - bool isMatch(const T *item) const { - return TH::compare(item->name()->str(), name) && - TH::compare(item->interface()->str(), interface) && - TH::compare(item->member()->str(), member) && - TH::compare(item->path()->str(), path) && - TH::compare(item->type(), type) && - TH::compare(item->is_name_prefix(), is_name_prefix) && - TH::compare(item->decision()->decision(), decision); - } }; struct ItemAccessTest { const uid_t uid; const gid_t gid; - const FB::Decision decision; + const ldp_xml_parser::Decision decision; const std::string privilege; - const FB::BusAccessType type; + const ldp_xml_parser::BusAccessType type; void printContent() const { TH::print_property("uid", uid); @@ -177,188 +155,222 @@ struct ItemAccessTest { TH::print_property("privilege", privilege); TH::print_property("type", type); } - - bool isMatch(const FB::ItemAccess *item) const { - return TH::compare(item->uid(), uid) && - TH::compare(item->gid(), gid) && - TH::compare(item->decision()->decision(), decision) && - TH::compare(item->decision()->privilege()->str(), privilege) && - TH::compare(item->type(), type); - } }; - std::vector context_default_tests = { - { "org", "", FB::Decision_ANY, "", FB::Decision_ANY }, - { "org.tizen", "", FB::Decision_ANY, "", FB::Decision_ANY }, - { "org.tizen.pok2", "", FB::Decision_ANY, "privilege1", FB::Decision_CHECK }, - { "org.tizen.pok2.a", "", FB::Decision_ANY, "", FB::Decision_DENY }, - { "org.tizen.pok2.a.b", "", FB::Decision_ANY, "privilege2", FB::Decision_CHECK }, - { "org.tizen.pnope", "http://tizen.org/privilege/packagemanager.nope", FB::Decision_CHECK, "", FB::Decision_ANY }, - { "org.tizen.pok1.a1", "http://tizen.org/privilege/packagemanager.nope", FB::Decision_CHECK, "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK }, - { "org.tizen.pok1.a", "", FB::Decision_ANY, "", FB::Decision_DENY }, - { "org.tizen.pok1.a.b4", "http://tizen.org/privilege/packagemanager.nope", FB::Decision_CHECK, "", FB::Decision_ANY }, - { "org.tizen.pok1.a.b3", "", FB::Decision_ANY, "http://tizen.org/privilege/packagemanager.nope", FB::Decision_CHECK }, - { "org.tizen.pok1.a.b2", "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK, "", FB::Decision_ANY }, - { "org.tizen.pok1.a.b1", "", FB::Decision_ANY, "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK }, - { "org.tizen.pok", "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK, "", FB::Decision_ANY }, + { "org", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.pok2", "", ldp_xml_parser::Decision::ANY, "privilege1", ldp_xml_parser::Decision::CHECK }, + { "org.tizen.pok2.a", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::DENY }, + { "org.tizen.pok2.a.b", "", ldp_xml_parser::Decision::ANY, "privilege2", ldp_xml_parser::Decision::CHECK }, + { "org.tizen.pnope", "http://tizen.org/privilege/packagemanager.nope", ldp_xml_parser::Decision::CHECK, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.pok1.a1", "http://tizen.org/privilege/packagemanager.nope", ldp_xml_parser::Decision::CHECK, "http://tizen.org/privilege/packagemanager.admin", ldp_xml_parser::Decision::CHECK }, + { "org.tizen.pok1.a", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::DENY }, + { "org.tizen.pok1.a.b4", "http://tizen.org/privilege/packagemanager.nope", ldp_xml_parser::Decision::CHECK, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.pok1.a.b3", "", ldp_xml_parser::Decision::ANY, "http://tizen.org/privilege/packagemanager.nope", ldp_xml_parser::Decision::CHECK }, + { "org.tizen.pok1.a.b2", "http://tizen.org/privilege/packagemanager.admin", ldp_xml_parser::Decision::CHECK, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.pok1.a.b1", "", ldp_xml_parser::Decision::ANY, "http://tizen.org/privilege/packagemanager.admin", ldp_xml_parser::Decision::CHECK }, + { "org.tizen.pok", "http://tizen.org/privilege/packagemanager.admin", ldp_xml_parser::Decision::CHECK, "", ldp_xml_parser::Decision::ANY }, }; std::vector context_mandatory_tests = {}; std::vector user_root_tests = { - { "org", "", FB::Decision_ANY, "", FB::Decision_ANY }, - { "org.tizen", "", FB::Decision_ANY, "", FB::Decision_ANY }, - { "org.tizen.a1", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.a1.b", "", FB::Decision_DENY, "", FB::Decision_ANY }, - { "org.tizen.b", "", FB::Decision_ANY, "", FB::Decision_ANY }, - { "org.tizen.b.z", "", FB::Decision_ALLOW, "", FB::Decision_ANY }, - { "org.tizen.b.c", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.a", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.a.d", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.a.c", "", FB::Decision_DENY, "", FB::Decision_ALLOW }, - { "org.tizen.a.b", "", FB::Decision_ANY, "", FB::Decision_DENY }, - { "org.tizen.a.b.c2", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.a.b.c1", "", FB::Decision_ANY, "", FB::Decision_DENY }, - { "org.tizen.a.b.c1.d", "", FB::Decision_ANY, "", FB::Decision_ANY }, - { "org.tizen.a.b.c1.d.e", "", FB::Decision_ANY, "", FB::Decision_ANY }, - { "org.tizen.a.b.c1.d.e.f", "", FB::Decision_ANY, "", FB::Decision_ANY }, - { "org.tizen.a.b.c1.d.e.f.g", "", FB::Decision_ALLOW, "", FB::Decision_ANY }, - { "org.tizen.a.b.c3", "", FB::Decision_DENY, "", FB::Decision_ALLOW }, - { "org.tizen.a.b.c3.d", "", FB::Decision_ANY, "", FB::Decision_DENY }, - { "org.tizen.a.b.c3.d.esth", "", FB::Decision_ALLOW, "", FB::Decision_ANY }, - { "org.tizen.a.b.c3.d.e", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.a.b.c3.d.e.f", "", FB::Decision_DENY, "", FB::Decision_ANY }, - { "org.tizen.a.b.c3.d.e.f.g", "", FB::Decision_ALLOW, "", FB::Decision_ANY }, - { "org.tizen.a.b.c", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.a.b.c.d", "", FB::Decision_ANY, "", FB::Decision_DENY }, - { "org.tizen.a.b.c.d.esth", "", FB::Decision_ALLOW, "", FB::Decision_ANY }, - { "org.tizen.a.b.c.d.e", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.a.b.c.d.e.f", "", FB::Decision_DENY, "", FB::Decision_ANY }, - { "org.tizen.a.bsth", "", FB::Decision_DENY, "", FB::Decision_ANY }, - { "org.tizen.ldposd", "", FB::Decision_ALLOW, "", FB::Decision_ANY }, - { "org.tizen.ldposa", "", FB::Decision_ALLOW, "", FB::Decision_ANY }, - { "org.tizen.test", "", FB::Decision_ANY, "", FB::Decision_ANY }, - { "org.tizen.test.dest_prefix", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.ldpoga", "", FB::Decision_ALLOW, "", FB::Decision_ANY }, - { "org.tizen.ldpo", "", FB::Decision_ANY, "", FB::Decision_ALLOW }, - { "org.tizen.ldpogd", "", FB::Decision_ALLOW, "", FB::Decision_ANY }, + { "org", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a1", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a1.b", "", ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.b", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.b.z", "", ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.b.c", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a.d", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a.c", "", ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a.b", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::DENY }, + { "org.tizen.a.b.c2", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a.b.c1", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::DENY }, + { "org.tizen.a.b.c1.d", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a.b.c1.d.e", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a.b.c1.d.e.f", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a.b.c1.d.e.f.g", "", ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a.b.c3", "", ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a.b.c3.d", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::DENY }, + { "org.tizen.a.b.c3.d.esth", "", ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a.b.c3.d.e", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a.b.c3.d.e.f", "", ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a.b.c3.d.e.f.g", "", ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a.b.c", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a.b.c.d", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::DENY }, + { "org.tizen.a.b.c.d.esth", "", ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a.b.c.d.e", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.a.b.c.d.e.f", "", ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.a.bsth", "", ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.ldposd", "", ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.ldposa", "", ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.test", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.test.dest_prefix", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.ldpoga", "", ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::Decision::ANY }, + { "org.tizen.ldpo", "", ldp_xml_parser::Decision::ANY, "", ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.ldpogd", "", ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::Decision::ANY }, }; std::vector item_send_context_default_tests { - { "", "", "", "", FB::MessageType_METHOD_CALL, false, FB::Decision_DENY }, - { "org.freedesktop.DBus", "org.freedesktop.DBus", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW }, - { "org.freedesktop.DBus", "org.freedesktop.DBus.Introspectable", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW }, - { "org.freedesktop.DBus", "org.freedesktop.DBus", "UpdateActivationEnvironment", "", FB::MessageType_ANY, false, FB::Decision_DENY }, - { "org.freedesktop.DBus", "org.freedesktop.DBus.Debug.Stats", "", "", FB::MessageType_ANY, false, FB::Decision_DENY }, - { "org.freedesktop.DBus", "org.freedesktop.systemd1.Activator", "", "", FB::MessageType_ANY, false, FB::Decision_DENY }, + { "", "", "", "", ldp_xml_parser::MessageType::METHOD_CALL, false, ldp_xml_parser::Decision::DENY }, + { "org.freedesktop.DBus", "org.freedesktop.DBus", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::ALLOW }, + { "org.freedesktop.DBus", "org.freedesktop.DBus.Introspectable", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::ALLOW }, + { "org.freedesktop.DBus", "org.freedesktop.DBus", "UpdateActivationEnvironment", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, + { "org.freedesktop.DBus", "org.freedesktop.DBus.Debug.Stats", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, + { "org.freedesktop.DBus", "org.freedesktop.systemd1.Activator", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, }; std::vector item_receive_context_default_test { - { "", "", "", "", FB::MessageType_METHOD_CALL, false, FB::Decision_ALLOW }, - { "", "", "", "", FB::MessageType_METHOD_RETURN, false, FB::Decision_ALLOW }, - { "", "", "", "", FB::MessageType_ERROR, false, FB::Decision_ALLOW }, - { "", "", "", "", FB::MessageType_SIGNAL, false, FB::Decision_ALLOW }, + { "", "", "", "", ldp_xml_parser::MessageType::METHOD_CALL, false, ldp_xml_parser::Decision::ALLOW }, + { "", "", "", "", ldp_xml_parser::MessageType::METHOD_RETURN, false, ldp_xml_parser::Decision::ALLOW }, + { "", "", "", "", ldp_xml_parser::MessageType::ERROR, false, ldp_xml_parser::Decision::ALLOW }, + { "", "", "", "", ldp_xml_parser::MessageType::SIGNAL, false, ldp_xml_parser::Decision::ALLOW }, }; std::vector item_send_root_tests { - { "org.tizen.test.dest_prefix.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.ao", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.ap.1.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.ap.1.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.ap.1.d.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.ap.1.dp.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.ap.1.dp.a", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW }, - - { "org.tizen.test.dest_prefix.ap.2.apxdp", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.ap.2.apxdp.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.ap.2.apxdp.dp.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.ap.2.apxdp.dp.ap.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY }, - - { "org.tizen.test.dest_prefix.ap.3.dpxap", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.ap.3.dpxap.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp.a", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.ap.3.dpxap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - - { "org.tizen.test.dest_prefix.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - - { "org.tizen.test.dest_prefix.do", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.ao.ao", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW }, - - { "org.tizen.test.dest_prefix.dp.1.a", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.dp.1.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - - { "org.tizen.test.dest_prefix.dp.1.a.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.dp.1.ap.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.dp.1.ap.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY }, - - { "org.tizen.test.dest_prefix.dp.2.dpxap", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.dp.2.dpxap.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp.a", "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW }, - - { "org.tizen.test.dest_prefix.dp.2.dpxap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp.f.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.dp.2.dpxap.f.f.f.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - - { "org.tizen.test.dest_prefix.dp.3.apxdp", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.dp.3.apxdp.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap", "", "", "", FB::MessageType_ANY, true, FB::Decision_ALLOW }, - { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap.dp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY }, - { "org.tizen.test.dest_prefix.dp.3.apxdp", "", "", "", FB::MessageType_ANY, true, FB::Decision_DENY }, + { "org.tizen.test.dest_prefix.ap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.ao", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.ap.1.d", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.ap.1.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.ap.1.d.ap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.ap.1.dp.ap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.ap.1.dp.a", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::ALLOW }, + + { "org.tizen.test.dest_prefix.ap.2.apxdp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.ap.2.apxdp.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.ap.2.apxdp.dp.ap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.ap.2.apxdp.dp.ap.d", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, + + { "org.tizen.test.dest_prefix.ap.3.dpxap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.ap.3.dpxap.ap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp.ap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp.a", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.ap.3.dpxap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + + { "org.tizen.test.dest_prefix.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + + { "org.tizen.test.dest_prefix.do", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.ao.ao", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::ALLOW }, + + { "org.tizen.test.dest_prefix.dp.1.a", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.dp.1.ap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + + { "org.tizen.test.dest_prefix.dp.1.a.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.dp.1.ap.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.dp.1.ap.d", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, + + { "org.tizen.test.dest_prefix.dp.2.dpxap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.dp.2.dpxap.ap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp.a", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::ALLOW }, + + { "org.tizen.test.dest_prefix.dp.2.dpxap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.d", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp.f.d", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.dp.2.dpxap.f.f.f.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + + { "org.tizen.test.dest_prefix.dp.3.apxdp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.dp.3.apxdp.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::ALLOW }, + { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap.dp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap.d", "", "", "", ldp_xml_parser::MessageType::ANY, false, ldp_xml_parser::Decision::DENY }, + { "org.tizen.test.dest_prefix.dp.3.apxdp", "", "", "", ldp_xml_parser::MessageType::ANY, true, ldp_xml_parser::Decision::DENY }, }; std::vector item_access_context_default_test { - { 0, 0, FB::Decision_ALLOW, "", FB::BusAccessType_ALL_USERS }, - { 1, 0, FB::Decision_DENY, "", FB::BusAccessType_USER }, - { 2, 0, FB::Decision_DENY, "", FB::BusAccessType_USER }, - { 0, 20, FB::Decision_ALLOW, "", FB::BusAccessType_GROUP }, - { 0, 30, FB::Decision_DENY, "", FB::BusAccessType_GROUP }, - { 3, 0, FB::Decision_ALLOW, "", FB::BusAccessType_USER }, - { 7, 0, FB::Decision_ALLOW, "", FB::BusAccessType_USER }, - { 8, 0, FB::Decision_DENY, "", FB::BusAccessType_USER }, - { 9991, 0, FB::Decision_CHECK, "privilege1", FB::BusAccessType_USER }, - { 9992, 0, FB::Decision_CHECK, "privilege2", FB::BusAccessType_USER }, - { 9993, 0, FB::Decision_CHECK, "privilege1", FB::BusAccessType_USER }, - { 888, 0, FB::Decision_CHECK, "privilege1", FB::BusAccessType_USER }, + { 0, 0, ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::BusAccessType::ALL_USERS }, + { 1, 0, ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::BusAccessType::USER }, + { 2, 0, ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::BusAccessType::USER }, + { 0, 20, ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::BusAccessType::GROUP }, + { 0, 30, ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::BusAccessType::GROUP }, + { 3, 0, ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::BusAccessType::USER }, + { 7, 0, ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::BusAccessType::USER }, + { 8, 0, ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::BusAccessType::USER }, + { 9991, 0, ldp_xml_parser::Decision::CHECK, "privilege1", ldp_xml_parser::BusAccessType::USER }, + { 9992, 0, ldp_xml_parser::Decision::CHECK, "privilege2", ldp_xml_parser::BusAccessType::USER }, + { 9993, 0, ldp_xml_parser::Decision::CHECK, "privilege1", ldp_xml_parser::BusAccessType::USER }, + { 888, 0, ldp_xml_parser::Decision::CHECK, "privilege1", ldp_xml_parser::BusAccessType::USER }, }; std::vector item_access_context_mandatory_test { - { 6, 0, FB::Decision_DENY, "", FB::BusAccessType_USER }, - { 7, 0, FB::Decision_DENY, "", FB::BusAccessType_USER }, - { 8, 0, FB::Decision_ALLOW, "", FB::BusAccessType_USER }, - { 0, 9992, FB::Decision_CHECK, "privilege1", FB::BusAccessType_GROUP }, - { 9993, 0, FB::Decision_CHECK, "privilege2", FB::BusAccessType_USER }, + { 6, 0, ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::BusAccessType::USER }, + { 7, 0, ldp_xml_parser::Decision::DENY, "", ldp_xml_parser::BusAccessType::USER }, + { 8, 0, ldp_xml_parser::Decision::ALLOW, "", ldp_xml_parser::BusAccessType::USER }, + { 0, 9992, ldp_xml_parser::Decision::CHECK, "privilege1", ldp_xml_parser::BusAccessType::GROUP }, + { 9993, 0, ldp_xml_parser::Decision::CHECK, "privilege2", ldp_xml_parser::BusAccessType::USER }, }; class SerializerTests { ldp_serializer::Serializer serializer; - const FB::File *file; + ldp_serialized::StorageBackendSerialized _db; + + const auto &db() const { return _db.getBackend(); } + + template + bool isMatch(const NodeTest &test, const PolicyOwnNode &node, const std::string &token) const { + return + TH::compare(token, db().stringGetCStr(db().ownNodeGetToken(node))) && + TH::compare(test.privilege, db().stringGetCStr(db().decisionItemGetPrivilege(db().ownNodeGetDecisionItem(node)))) && + TH::compare(test.decision, makeDecision(db().decisionItemGetDecision(db().ownNodeGetDecisionItem(node)))) && + TH::compare(test.prefix_privilege, db().stringGetCStr(db().decisionItemGetPrivilege(db().ownNodeGetPrefixDecisionItem(node)))) && + TH::compare(test.prefix_decision, makeDecision(db().decisionItemGetDecision(db().ownNodeGetPrefixDecisionItem(node)))); + } + + template + bool isMatch(const ItemSRTest &test, const T &item) const { + return + TH::compare(test.name, db().stringGetCStr(db().itemSrGetName(item))) && + TH::compare(test.interface, db().stringGetCStr(db().itemSrGetInterface(item))) && + TH::compare(test.member, db().stringGetCStr(db().itemSrGetMember(item))) && + TH::compare(test.path, db().stringGetCStr(db().itemSrGetPath(item))) && + TH::compare(test.type, makeMessageType(db().itemSrGetMessageType(item))) && + TH::compare(test.is_name_prefix, db().itemSrGetIsNamePrefix(item)) && + TH::compare(test.decision, makeDecision(db().decisionItemGetDecision(db().itemGetDecisionItem(item)))); + } + + template + bool isMatch(const ItemAccessTest &test, const ItemAccess &item) const { + return + TH::compare(test.uid, db().itemAccessGetUid(item)) && + TH::compare(test.gid, db().itemAccessGetGid(item)) && + TH::compare(test.decision, makeDecision(db().decisionItemGetDecision(db().itemGetDecisionItem(item)))) && + TH::compare(test.privilege, db().stringGetCStr(db().decisionItemGetPrivilege(db().itemGetDecisionItem(item)))) && + TH::compare(test.type, makeBusAccessType(db().itemAccessGetType(item))); + } void serialize_xml(const std::string &file_name) { size_t size; - auto buff = serializer.serialize(file_name, size); + ldp_xml::StorageBackendXML xmlStorage; - file = FB::GetFile(buff); + if (!xmlStorage.init(file_name.c_str())) { + print_error("xmlStorage init error"); + return; + } + + auto buff = serializer.serialize(xmlStorage, size); + + _db.initFromData(buff, size, false); } - bool check_tree(const std::string &token, const FB::PolicyOwnNode *nnode, const NodeTest &test) { + template + bool check_tree(const std::string &token, const PolicyOwnNode &nnode, const NodeTest &test) { size_t dot = token.find('.'); + auto children = db().ownNodeGetChildren(nnode); if (dot == std::string::npos) { - auto node = nnode->children()->LookupByKey(token.c_str()); - if (node == nullptr) { + auto node = db().containerLookupByKey(children, token.c_str()); + if (!node.first) { print_error("node %s not found for:", TH::to_str(token)); test.printContent(); return false; } - if (!test.isMatch(node, token)) { + if (!isMatch(test, node.second, token)) { print_error("No matching child found for test:"); test.printContent(); return false; @@ -369,16 +381,17 @@ class SerializerTests { std::string part = token.substr(0, dot); std::string rest = token.substr(dot + 1); - auto new_node = nnode->children()->LookupByKey(part.c_str()); - if (new_node == nullptr) { + auto new_node = db().containerLookupByKey(children, part.c_str()); + if (!new_node.first) { print_error("node %s not found", TH::to_str(part)); return false; } - return check_tree(rest, new_node, test); + return check_tree(rest, new_node.second, test); } } - bool check_tree(const FB::PolicyOwnNode *tree, const std::vector &tree_tests) { + template + bool check_tree(const PolicyOwnNode &tree, const std::vector &tree_tests) { for (const auto &test : tree_tests) { if (!check_tree(test.name, tree, test)) return false; @@ -387,17 +400,19 @@ class SerializerTests { } bool check_own_set() { - return check_tree(file->m_own_set()->context_default()->tree(), context_default_tests) && - check_tree(file->m_own_set()->context_mandatory()->tree(), context_mandatory_tests) && - check_tree(file->m_own_set()->user()->LookupByKey(0)->policy()->tree(), user_root_tests); + return check_tree(db().policyGetTree(db().setGetContextDefault(db().fileGetOwnSet(db().getFile()))), context_default_tests) && + check_tree(db().policyGetTree(db().setGetContextMandatory(db().fileGetOwnSet(db().getFile()))), context_mandatory_tests) && + check_tree(db().policyGetTree(db().setUserGroupGetPolicy(db().containerLookupByKey(db().setGetUser(db().fileGetOwnSet(db().getFile())), 0).second)), user_root_tests); } template bool checkPolicy(const T *policy, const std::vector &tests) { for (const auto &test : tests) { bool found = false; - for (const auto &item : *policy->items()) { - if (test.isMatch(item)) { + auto items = db().policyGetItems(policy); + auto end = db().containerGetIteratorEnd(items); + for (auto it = db().containerGetIterator(items); it != end; it++) { + if (isMatch(test, *it)) { found = true; break; } @@ -412,21 +427,21 @@ class SerializerTests { } bool check_send_set() { - return checkPolicy(file->m_send_set()->context_default(), item_send_context_default_tests) && - checkPolicy(file->m_send_set()->user()->LookupByKey(0)->policy(), item_send_root_tests); + return checkPolicy(db().setGetContextDefault(db().fileGetSendSet(db().getFile())), item_send_context_default_tests) && + checkPolicy(db().setUserGroupGetPolicy(db().containerLookupByKey(db().setGetUser(db().fileGetSendSet(db().getFile())), 0).second), item_send_root_tests); } bool check_receive_set() { - return checkPolicy(file->m_receive_set()->context_default(), item_receive_context_default_test); + return checkPolicy(db().setGetContextDefault(db().fileGetReceiveSet(db().getFile())), item_receive_context_default_test); } bool check_access_set() { - return checkPolicy(file->m_access_set()->context_default(), item_access_context_default_test) && - checkPolicy(file->m_access_set()->context_mandatory(), item_access_context_mandatory_test); + return checkPolicy(db().setGetContextDefault(db().fileGetAccessSet(db().getFile())), item_access_context_default_test) && + checkPolicy(db().setGetContextMandatory(db().fileGetAccessSet(db().getFile())), item_access_context_mandatory_test); } public: - SerializerTests() : file(nullptr) {} + SerializerTests() {} bool run_all_tests(const std::string &config) { serialize_xml(config); @@ -436,10 +451,9 @@ public: check_access_set(); } }; -} int main() { - auto st = ldp_xml_parser::SerializerTests(); + auto st = SerializerTests(); if (st.run_all_tests("tests/default_deny/system.conf")) return 0; return -1; -- 2.7.4