serialization: add storage backend 52/200252/4
authorAdrian Szyndela <adrian.s@samsung.com>
Wed, 20 Feb 2019 13:34:32 +0000 (14:34 +0100)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Thu, 7 Mar 2019 07:36:03 +0000 (07:36 +0000)
Change-Id: I1830ff322a8c14557d46f8f353a7b3d34a43d187

Makefile.am
src/internal/storage_backend_serialized.cpp [new file with mode: 0644]
src/internal/storage_backend_serialized.hpp [new file with mode: 0644]

index dbfdbb0..024f3e4 100644 (file)
@@ -62,7 +62,8 @@ COMMON_SRC =\
        src/internal/xml_parser.cpp \
        src/internal/tslog.cpp \
        src/internal/serializer.cpp \
-       src/internal/print_content.cpp
+       src/internal/print_content.cpp \
+       src/internal/storage_backend_serialized.cpp
 
 src_libdbuspolicy1_la_SOURCES =\
        $(COMMON_SRC) \
diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp
new file mode 100644 (file)
index 0000000..3a6b207
--- /dev/null
@@ -0,0 +1,240 @@
+#include "storage_backend_serialized.hpp"
+#include "print_content.hpp"
+#include "serialized_convert.hpp"
+#include "tslog.hpp"
+
+#include "include/fb_generated.h"
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <boost/tokenizer.hpp>
+
+#include <cerrno>
+#include <cstring>
+
+using namespace FB;
+
+namespace ldp_serialized {
+
+class StorageBackendSerialized::StorageBackendSerializedImpl {
+       int fd{-1};
+       uint8_t *mem{nullptr};
+       size_t length{0};
+       const FB::File *file;
+public:
+       void init(const char *filename);
+       void release();
+
+       void printContent() const;
+
+       template <typename T>
+       T *getPolicySet();
+};
+
+void StorageBackendSerialized::StorageBackendSerializedImpl::release() {
+       if (nullptr != mem) {
+               if (munmap(mem, length) != 0)
+                       tslog::log("munmap(): ", strerror(errno), "\n");
+               mem = nullptr;
+               length = 0;
+       }
+
+       if (-1 != fd) {
+               if (close(fd) != 0)
+                       tslog::log("close(): ", strerror(errno), "\n");
+               fd = -1;
+       }
+
+       file = nullptr;
+}
+
+void StorageBackendSerialized::StorageBackendSerializedImpl::init(const char *filename) {
+       auto err = [filename] (const char *what) {
+               tslog::log("Can't ", what, " ", filename, ": ", strerror(errno), "\n");
+       };
+
+       fd = open(filename, O_RDONLY);
+       if (-1 == fd) {
+               err("open");
+               return;
+       }
+
+       struct stat buf;
+
+       if (fstat(fd, &buf) == -1) {
+               err("stat");
+               close(fd);
+               return;
+       }
+
+       length = buf.st_size;
+
+       mem = reinterpret_cast<uint8_t*>(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0));
+       if (MAP_FAILED == mem) {
+               err("mmap");
+               close(fd);
+               return;
+       }
+// for verification:
+//
+//     if (!VerifyFileBuffer(Verifier(mem, length)))
+//             bailout();
+//
+       file = GetFile(mem);
+}
+
+void StorageBackendSerialized::StorageBackendSerializedImpl::printContent() const {
+       std::cerr << *file;
+}
+
+/*************************************************/
+template <typename T>
+struct type_helper;
+
+#define TYPE_HELPER(T, t) \
+       template <> \
+       struct type_helper<const ldp_xml_parser::MatchItem##T> { \
+               typedef FB::T##Set policy_set_type; \
+               typedef FB::Policy##T policy_type; \
+       }; \
+       template <> \
+       auto StorageBackendSerialized::StorageBackendSerializedImpl::getPolicySet() \
+               -> const typename type_helper<const ldp_xml_parser::MatchItem##T>::policy_set_type * { \
+               assert(file); \
+               return file->m_##t##_set(); \
+       }
+
+TYPE_HELPER(Own, own)
+TYPE_HELPER(Send, send)
+TYPE_HELPER(Receive, receive)
+TYPE_HELPER(Access, access)
+
+void StorageBackendSerialized::init(const char *filename) {
+       pimpl->init(filename);
+}
+
+void StorageBackendSerialized::release() {
+       pimpl->release();
+}
+
+void StorageBackendSerialized::printContent() const {
+       pimpl->printContent();
+}
+
+template <typename T, typename I>
+bool match(const T &t, const I *i) {
+       // TODO!!!!
+       return true;
+}
+
+template <typename T, typename P = typename type_helper<T>::policy_type>
+ldp_xml_parser::DecisionItem getDecisionItem(const T &item, const P *policy) {
+       const auto *v = policy->items();
+       for (auto it = v->rbegin(); it != v->rend(); ++it) {
+               if (match(item, *it))
+                       return makeDecisionItem((*it)->decision());
+       }
+       return ldp_xml_parser::Decision::ANY;
+}
+
+typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
+
+const DecisionItem *getDecisionItemFromTree(const FB::PolicyOwnNode *node,
+                                                                                       tokenizer &tokens,
+                                                                                       tokenizer::iterator &iterator) {
+       if (iterator == tokens.end()) {
+               if (node->decision_item()->decision() != Decision_ANY)
+                       return node->decision_item();
+               else
+                       return node->prefix_decision_item();
+       }
+
+       auto child = node->children()->LookupByKey(iterator->c_str());
+       if (nullptr == child)
+               return node->prefix_decision_item();
+
+       ++iterator;
+       const DecisionItem *child_decision = getDecisionItemFromTree(child, tokens, 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) {
+       if (item.getName().length() == 0)
+               return ldp_xml_parser::Decision::DENY;
+
+       boost::char_separator<char> 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, iterator));
+}
+
+template <typename T, typename P = typename type_helper<T>::policy_type>
+ldp_xml_parser::DecisionItem getDecisionItemMaybeNull(const T &item, const P *policy) {
+       if (nullptr == policy)
+               return ldp_xml_parser::Decision::ANY;
+       return getDecisionItem(item, policy);
+}
+
+template <typename T>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextMandatory(const T &item) const {
+       return getDecisionItem(item, pimpl->getPolicySet<T>()->context_mandatory());
+}
+
+template <typename T>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemContextDefault(const T &item) const {
+       return getDecisionItem(item, pimpl->getPolicySet<T>()->context_default());
+}
+
+template <typename T>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemUser(uid_t uid, const T &item) const {
+       return getDecisionItemMaybeNull(item, pimpl->getPolicySet<T>()->user()->LookupByKey(uid));
+}
+
+template <typename T>
+ldp_xml_parser::DecisionItem StorageBackendSerialized::getDecisionItemGroup(gid_t gid, const T &item) const {
+       return getDecisionItemMaybeNull(item, pimpl->getPolicySet<T>()->group()->LookupByKey(gid));
+}
+
+#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)
+
+#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;
+
+T_INSTANTIATION2(Own)
+T_INSTANTIATION2(Send)
+T_INSTANTIATION2(Receive)
+
+#undef T_INSTANTIATION
+#undef T_INSTANTIATION2
+
+StorageBackendSerialized::StorageBackendSerialized()
+       : pimpl{new StorageBackendSerializedImpl} {
+}
+
+StorageBackendSerialized::~StorageBackendSerialized() {
+       pimpl->release();
+}
+
+}
diff --git a/src/internal/storage_backend_serialized.hpp b/src/internal/storage_backend_serialized.hpp
new file mode 100644 (file)
index 0000000..159994a
--- /dev/null
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "policy.hpp"
+
+#include <memory>
+
+namespace ldp_serialized {
+
+class StorageBackendSerialized {
+       class StorageBackendSerializedImpl;
+       std::unique_ptr<StorageBackendSerializedImpl> pimpl;
+public:
+       StorageBackendSerialized();
+       ~StorageBackendSerialized();
+
+       void init(const char *filename);
+       void release();
+
+       void printContent() const;
+
+       // Supported template parameters are:
+       // MatchPolicyOwn, MatchPolicySend, MatchPolicyReceive
+       // and - only for Contexts - MatchPolicyAccess
+       template <typename T>
+       ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const T &item) const;
+       template <typename T>
+       ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const T &item) const;
+       template <typename T>
+       ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const T &item) const;
+       template <typename T>
+       ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const T &item) const;
+};
+
+}