serialization: add serialization class 93/199793/12
authorMateusz Moscicki <m.moscicki2@partner.samsung.com>
Thu, 14 Feb 2019 07:04:05 +0000 (08:04 +0100)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Thu, 7 Mar 2019 07:35:22 +0000 (07:35 +0000)
Change-Id: I8eb5d24012b24830c1f8e671805eb091b1d2c9a1

src/dbuspolicy_serializer.cpp [new file with mode: 0644]
src/internal/serializer.cpp [new file with mode: 0644]
src/internal/serializer.hpp [new file with mode: 0644]

diff --git a/src/dbuspolicy_serializer.cpp b/src/dbuspolicy_serializer.cpp
new file mode 100644 (file)
index 0000000..63b0e19
--- /dev/null
@@ -0,0 +1,77 @@
+#include <unistd.h>
+#include <getopt.h>
+
+#include <iostream>
+#include <fstream>
+#include "internal/internal.h"
+#include "internal/serializer.hpp"
+#include "internal/naive_policy_checker.hpp"
+#include "dbuspolicy1/libdbuspolicy1.h"
+#include "libdbuspolicy1-private.h"
+
+using namespace std;
+
+static const struct option options[] = {
+       {"system", no_argument, 0, 0 },
+       {"session", no_argument, 0, 0}
+};
+
+static void print_help(const char *name) {
+       cout << endl;
+       cout << "usage: " << name << " [-o output_filename] <input_filename>" << endl;
+       cout << "       " << name << " {--system|--session} [-o output_filename]" << endl;
+       cout << endl;
+}
+
+int main(int argc, char *argv[])
+{
+       BusType bus_type = BusType::SYSTEM_BUS;
+       bool need_input_filename = true;
+       std::string output_filename = "result.dat";
+       std::string input_filename;
+       int c;
+
+       while (1) {
+               int option_index;
+               c = getopt_long(argc, argv, "o:", options, &option_index);
+               if (c == -1)
+                       break;
+
+               switch(c) {
+               case 0:
+                       if (option_index == 1)
+                               bus_type = BusType::SESSION_BUS;
+                       need_input_filename = false;
+                       break;
+               case 'o':
+                       output_filename = optarg;
+                       break;
+               }
+       }
+
+       if (need_input_filename) {
+               if (optind < argc) {
+                       input_filename = argv[optind];
+               } else {
+                       print_help(argv[0]);
+                       return 1;
+               }
+       } else {
+               switch (bus_type) {
+               case BusType::SYSTEM_BUS:
+                       input_filename = system_bus_conf_file_primary();
+                       break;
+               case BusType::SESSION_BUS:
+                       input_filename = session_bus_conf_file_primary();
+                       break;
+               }
+       }
+
+       cout << "Read from: " << input_filename << " write to: " << output_filename << endl;
+       ldp_xml_parser::Serializer serializer;
+       ofstream output(output_filename, ofstream::binary);
+
+       serializer.serialize(input_filename, output);
+
+       return 0;
+}
diff --git a/src/internal/serializer.cpp b/src/internal/serializer.cpp
new file mode 100644 (file)
index 0000000..c4beffb
--- /dev/null
@@ -0,0 +1,279 @@
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "internal.h"
+#include "naive_policy_checker.hpp"
+#include "naive_policy_db.hpp"
+#include "serializer.hpp"
+#include "include/flatbuffers/flatbuffers.h"
+#include "include/fb_generated.h"
+
+using namespace std;
+
+namespace ldp_xml_parser {
+
+map<Decision, FB::Decision> decisions_map {
+       { Decision::ANY, FB::Decision_ANY },
+       { Decision::DENY, FB::Decision_DENY },
+       { Decision::ALLOW, FB::Decision_ALLOW },
+       { Decision::CHECK, FB::Decision_CHECK }
+};
+
+map<BusAccessType, FB::BusAccessType> bus_access_map {
+       { BusAccessType::USER, FB::BusAccessType_USER },
+       { BusAccessType::GROUP, FB::BusAccessType_GROUP },
+       { BusAccessType::ALL_USERS, FB::BusAccessType_ALL_USERS },
+       { BusAccessType::ALL_GROUPS, FB::BusAccessType_ALL_GROUPS },
+};
+
+map<MessageType, FB::MessageType> message_type_map {
+       { MessageType::ANY, FB::MessageType_ANY },
+       { MessageType::METHOD_CALL, FB::MessageType_METHOD_CALL },
+       { MessageType::METHOD_RETURN, FB::MessageType_METHOD_RETURN },
+       { MessageType::ERROR, FB::MessageType_ERROR },
+       { MessageType::SIGNAL, FB::MessageType_SIGNAL }
+};
+
+template <>
+struct Serializer::type_helper<PolicyOwn> {
+       typedef struct FB::OwnSet set;
+       typedef struct FB::OwnSetBuilder builder;
+       typedef struct FB::PolicyOwn policy;
+       typedef struct FB::PolicyOwnPair pair;
+       static constexpr auto create_set = &FB::CreateOwnSet;
+       static constexpr auto create_policy = &FB::CreatePolicyOwn;
+       static constexpr auto create_policy_pair = &FB::CreatePolicyOwnPair;
+};
+
+template <>
+struct Serializer::type_helper<PolicySend> {
+       typedef struct FB::SendSet set;
+       typedef struct FB::SendSetBuilder builder;
+       typedef struct FB::PolicySend policy;
+       typedef struct FB::PolicySendPair pair;
+       typedef struct FB::ItemSend item;
+       static constexpr auto create_set = &FB::CreateSendSet;
+       static constexpr auto create_policy = &FB::CreatePolicySend;
+       static constexpr auto create_policy_pair = &FB::CreatePolicySendPair;
+       static constexpr auto create_item = &FB::CreateItemSend;
+};
+
+template <>
+struct Serializer::type_helper<PolicyReceive> {
+       typedef struct FB::ReceiveSet set;
+       typedef struct FB::ReceiveSetBuilder builder;
+       typedef struct FB::PolicyReceive policy;
+       typedef struct FB::PolicyReceivePair pair;
+       typedef struct FB::ItemReceive item;
+       static constexpr auto create_set = &FB::CreateReceiveSet;
+       static constexpr auto create_policy = &FB::CreatePolicyReceive;
+       static constexpr auto create_policy_pair = &FB::CreatePolicyReceivePair;
+       static constexpr auto create_item = &FB::CreateItemReceive;
+};
+
+template <>
+struct Serializer::type_helper<PolicyAccess> {
+       typedef struct FB::AccessSet set;
+       typedef struct FB::AccessSetBuilder builder;
+       typedef struct FB::PolicyAccess policy;
+       typedef struct FB::ItemAccess item;
+       static constexpr auto create_set = &FB::CreateAccessSet;
+       static constexpr auto create_policy = &FB::CreatePolicyAccess;
+       static constexpr auto create_item = &FB::CreateItemAccess;
+};
+
+uint8_t* Serializer::serialize(const BusType bus_type, size_t &size) {
+       m_db = &policy_checker().getPolicyDb(bus_type);
+
+       auto own_set = serialize_set<PolicyOwn>();
+       auto send_set = serialize_set<PolicySend>();
+       auto receive_set = serialize_set<PolicyReceive>();
+       auto access_set = serialize_set<PolicyAccess>();
+
+       auto file = FB::CreateFile(m_builder,
+                                  own_set,
+                                  send_set,
+                                  receive_set,
+                                  access_set);
+
+       m_builder.Finish(file);
+       uint8_t* buf = m_builder.GetBufferPointer();
+       size = m_builder.GetSize();
+
+       return buf;
+}
+
+uint8_t* Serializer::serialize(const std::string config_path, size_t &size) {
+       // SYSTEM_BUS here because something had to be choosen
+       if (__internal_init(BusType::SYSTEM_BUS, config_path.c_str()) != 0)
+               cout << "internal_init error" << endl;
+
+       return serialize(BusType::SYSTEM_BUS, size);
+}
+
+void Serializer::serialize(const std::string config_path, ostream &output) {
+       size_t size;
+       uint8_t *buf = serialize(config_path, size);
+
+       output.write(reinterpret_cast<char *>(buf), size);
+}
+
+template <typename T>
+auto Serializer::get_create_set() -> decltype(type_helper<T>::create_set) {
+       return type_helper<T>::create_set;
+}
+
+template <typename T>
+auto Serializer::get_create_policy() -> decltype(type_helper<T>::create_policy) {
+       return type_helper<T>::create_policy;
+}
+
+template <typename T>
+auto Serializer::get_create_policy_pair() -> decltype(type_helper<T>::create_policy_pair) {
+       return type_helper<T>::create_policy_pair;
+}
+
+template <typename T>
+auto Serializer::get_create_item() -> decltype(type_helper<T>::create_item) {
+       return type_helper<T>::create_item;
+}
+
+FbOff<FB::PolicyOwn> Serializer::serialize_tree(const OwnershipTree &tree) {
+       auto tree_item = serialize_tree(tree.getRoot());
+       auto policy = FB::CreatePolicyOwn(m_builder, tree_item);
+
+       return policy;
+}
+
+FbOff<FB::PolicyOwnNode> Serializer::serialize_tree(const shared_ptr<TreeNode> &node) {
+       auto prefix_decision_item = serialize_decision(node->getOwnPrefixDecisionItem());
+       auto decision_item = serialize_decision(node->getOwnDecisionItem());
+
+       std::vector<FbOff<FB::PolicyOwnNode>> children;
+
+       for (const auto &subnode : node->getChildren()) {
+               auto child = serialize_tree(subnode.second);
+               children.push_back(child);
+       }
+
+       auto policy_own = FB::CreatePolicyOwnNode(m_builder,
+                                                 m_builder.CreateString(node->getToken()),
+                                                 prefix_decision_item,
+                                                 decision_item,
+                                                 m_builder.CreateVectorOfSortedTables(&children));
+       return policy_own;
+}
+
+FbOff<FB::DecisionItem> Serializer::serialize_decision(const DecisionItem &item) {
+       return FB::CreateDecisionItem(m_builder,
+                                     decisions_map[item.getDecision()],
+                                     m_builder.CreateString(item.getPrivilege()));
+}
+
+template <>
+auto Serializer::serialize_item<PolicyAccess>(const ItemAccess &item) -> FbOff<FB::ItemAccess> {
+       auto create_item = get_create_item<PolicyAccess>();
+
+       return create_item(m_builder,
+                          item.getUid(),
+                          item.getGid(),
+                          serialize_decision(item.getDecision()),
+                          bus_access_map[item.getType()]);
+}
+
+template <typename T, typename P>
+auto Serializer::serialize_item(const P &item) -> FbOff<typename type_helper<T>::item> {
+       auto create_item = get_create_item<T>();
+       return create_item(m_builder,
+                          serialize_decision(item.getDecision()),
+                          m_builder.CreateString(item.getName()),
+                          m_builder.CreateString(item.getInterface()),
+                          m_builder.CreateString(item.getMember()),
+                          m_builder.CreateString(item.getPath()),
+                          message_type_map[item.getType()],
+                          item.isNamePrefix());
+}
+
+template <typename T>
+auto Serializer::serialize_policy(const T &policy,
+                                 const std::vector<FbOff<typename type_helper<T>::item>> items)
+                                   -> FbOff<typename type_helper<T>::policy> {
+       (void)policy;
+       auto create_policy = get_create_policy<T>();
+       return create_policy(m_builder, m_builder.CreateVector(items));
+}
+
+template <>
+auto Serializer::serialize_policy(const PolicyAccess &policy,
+                                 const std::vector<FbOff<FB::ItemAccess>> items)
+                                   -> FbOff<FB::PolicyAccess> {
+       (void)policy;
+       auto create_policy = get_create_policy<PolicyAccess>();
+       return create_policy(m_builder,
+                            m_builder.CreateVector(items));
+}
+
+template <>
+auto Serializer::serialize_policy(const PolicyOwn &policy)
+                                   -> FbOff<FB::PolicyOwn> {
+       return serialize_tree(policy.getTree());
+}
+
+template <typename T>
+auto Serializer::serialize_policy(const T &policy) -> FbOff<typename type_helper<T>::policy> {
+       std::vector<FbOff<typename type_helper<T>::item>> items;
+
+       for (const auto &item : policy.getItems()) {
+               items.push_back(serialize_item<T>(item));
+       }
+
+       return serialize_policy(policy, items);
+}
+
+template <typename T, typename P>
+auto Serializer::serialize_pair(const long int id, const P policy)
+                                 -> FbOff<typename type_helper<T>::pair> {
+       auto create_policy_pair = get_create_policy_pair<T>();
+       return create_policy_pair(m_builder, id, serialize_policy(policy));
+}
+
+template <typename TP>
+auto Serializer::serialize_set() -> FbOff<typename type_helper<TP>::set> {
+       auto context_default = serialize_policy<TP>(m_db->getPolicyContextDefault<TP>());
+       auto context_mandatory = serialize_policy<TP>(m_db->getPolicyContextMandatory<TP>());
+
+       return serialize_set<TP>(context_default, context_mandatory);
+}
+
+template <>
+auto Serializer::serialize_set<PolicyAccess>(FbOff<FB::PolicyAccess> context_default,
+                                            FbOff<FB::PolicyAccess> context_mandatory)
+                                              -> FbOff<typename type_helper<PolicyAccess>::set>
+{
+       return FB::CreateAccessSet(m_builder, context_default, context_mandatory);
+}
+
+template <typename TP, typename TFP>
+auto Serializer::serialize_set(FbOff<TFP> context_default,
+                              FbOff<TFP> context_mandatory)
+                                -> FbOff<typename type_helper<TP>::set>
+{
+       std::vector<FbOff<typename type_helper<TP>::pair>> user;
+       std::vector<FbOff<typename type_helper<TP>::pair>> group;
+       std::vector<long long> uid;
+       std::vector<long long> gid;
+
+       for (const auto &u : m_db->getPoliciesUser<TP>())
+               user.push_back(serialize_pair<TP>(u.first, u.second));
+
+       for (const auto &g : m_db->getPoliciesGroup<TP>())
+               group.push_back(serialize_pair<TP>(g.first, g.second));
+
+       auto func = get_create_set<TP>();
+       return func(m_builder, context_default, context_mandatory,
+                               m_builder.CreateVectorOfSortedTables(&user),
+                               m_builder.CreateVectorOfSortedTables(&group));
+}
+
+}
diff --git a/src/internal/serializer.hpp b/src/internal/serializer.hpp
new file mode 100644 (file)
index 0000000..12be5b0
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef _SERIALIZER_HPP
+#define _SERIALIZER_HPP
+
+#include <ostream>
+#include <memory>
+#include <string>
+
+#include "include/flatbuffers/flatbuffers.h"
+#include "include/fb_generated.h"
+
+#include "naive_policy_db.hpp"
+#include "policy_containers.hpp"
+
+using namespace std;
+
+namespace ldp_xml_parser
+{
+    enum class SetType : uint8_t {
+           OWN,
+           SEND,
+           RECEIVE,
+           ACCESS
+    };
+
+    template <typename T>
+    using FbOff = flatbuffers::Offset<T>;
+
+    class Serializer {
+    private:
+       template <typename T>
+       struct type_helper;
+
+       const NaivePolicyDb *m_db;
+       flatbuffers::FlatBufferBuilder m_builder;
+
+       template <typename T>
+       auto get_create_set() -> decltype(type_helper<T>::create_set);
+       template <typename T>
+       auto get_create_policy() -> decltype(type_helper<T>::create_policy);
+       template <typename T>
+       auto get_create_policy_pair() -> decltype(type_helper<T>::create_policy_pair);
+       template <typename T>
+       auto get_create_item() -> decltype(type_helper<T>::create_item);
+
+       FbOff<FB::PolicyOwn> serialize_tree(const OwnershipTree &tree);
+       FbOff<FB::PolicyOwnNode> serialize_tree(const shared_ptr<TreeNode> &node);
+       FbOff<FB::DecisionItem> serialize_decision(const DecisionItem &item);
+
+       template <typename T, typename P>
+       auto serialize_item(const P &item) -> FbOff<typename type_helper<T>::item>;
+
+       template <typename T>
+       auto serialize_policy(const T &policy) -> FbOff<typename type_helper<T>::policy>;
+
+       template <typename T>
+       auto serialize_policy(const T &policy,
+                             const std::vector<FbOff<typename type_helper<T>::item>> items)
+                               -> FbOff<typename type_helper<T>::policy>;
+
+       template <typename T, typename P>
+       auto serialize_pair(const long int id, const P policy)
+                             -> FbOff<typename type_helper<T>::pair>;
+
+       template <typename TP>
+       auto serialize_set() -> FbOff<typename type_helper<TP>::set>;
+
+       template <typename TP, typename TFP>
+       auto serialize_set(FbOff<TFP> context_default,
+                          FbOff<TFP> context_mandatory)
+                            -> FbOff<typename type_helper<TP>::set>;
+    public:
+       uint8_t *serialize(const BusType bus_type, size_t &size);
+       uint8_t *serialize(const std::string config_path, size_t &size);
+       void serialize(const std::string config_path, ostream &output);
+       friend class SerializerTests;
+    };
+}
+
+
+#endif