--- /dev/null
+#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));
+}
+
+}
--- /dev/null
+#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