#include "naive_policy_checker.hpp"
#include "naive_policy_db.hpp"
#include "tslog.hpp"
+
#include <cstdlib>
#include <sys/types.h>
#include <map>
using namespace ldp_xml_parser;
-static const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL"};
-static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"};
-static const char* message_access[] = {"USER", "GROUP", "ALL_USERS", "ALL_GROUPS"};
-
size_t ldp_xml_parser::get_string_heap_allocated_memory(const std::string& x) {
/* an empty string will have nothing allocated on the heap;
* it can still have some capacity regardless due to short string optimisation,
return x.capacity();
}
-static inline const char* __message_type_to_str(MessageType type) {
- return message_type[static_cast<std::size_t>(type)];
-}
-
-static inline const char* __decision_to_str(Decision dec) {
- return message_decision[static_cast<std::size_t>(dec)];
-}
-
-static inline const char* __access_type_to_str(BusAccessType type) {
- return message_access[static_cast<std::size_t>(type)];
-}
-
DecisionItem::DecisionItem(Decision decision, const char* privilege)
: __decision(decision)
{
PolicyTypeValue::PolicyTypeValue(uid_t us) : user(us) {
}
-
-namespace ldp_xml_parser {
-
-std::ostream &operator<<(std::ostream& stream, const DecisionItem &di)
-{
- return stream << __decision_to_str(di.__decision) << (di.__privilege.empty() ? "" : ":") << di.__privilege;
-}
-
-std::ostream &operator<<(std::ostream& stream, const ItemOwn &item)
-{
- return stream << "ItemOwn: service(" << (item.__name.empty() ? "*" : item.__name) <<
- "), pref(" << item.__is_prefix << ")";
-}
-
-std::ostream &operator<<(std::ostream& stream, const MatchItemOwn &item)
-{
- return stream << (item._name.empty() ? "NULL" : item._name);
-}
-
-std::ostream &operator<<(std::ostream& stream, const MatchItemSR &item)
-{
- stream << ": services(";
- for (int i = 0; i < item.names_num; i++) {
- stream << item.names[i];
- if (i != item.names_num -1)
- stream << " ";
- }
- return stream << "), interface(" << item.interface << "), member(" << item.member <<
- "), path(" << item.path << "), type(" << __message_type_to_str(item.type) << ")";
-}
-
-std::ostream &operator<<(std::ostream& stream, const MatchItemSend &item)
-{
- stream << "MatchItemSend";
- return stream << static_cast<const MatchItemSR>(item);
-}
-
-std::ostream &operator<<(std::ostream& stream, const MatchItemReceive &item)
-{
- stream << "MatchItemReceive";
- return stream << static_cast<const MatchItemSR>(item);
-}
-
-std::ostream &operator<<(std::ostream& stream, const ItemSendReceive &item)
-{
- return stream << ": name(" << item.__name << "), inter(" << item.__interface <<
- "), member(" << item.__member << "), path(" << item.__path << "), type(" <<
- __message_type_to_str(item.__type) << ")";
-}
-
-std::ostream &operator<<(std::ostream& stream, const ItemAccess &item)
-{
- return stream << "ItemAccess: type(" << __access_type_to_str(item.__type) << "), uid(" <<
- item.__uid << "), gid(" << item.__gid << ")";
-}
-
-std::ostream &operator<<(std::ostream& stream, const MatchItemAccess &item)
-{
- stream << "uid: " << item.getUid() << ", gid: ";
- for (auto gid : item.getGids())
- stream << gid << ", ";
- return stream << std::endl;
-}
-
-}
Decision getDecision() const;
const std::string &getPrivilege() const;
size_t getSize() const;
-
- friend std::ostream &operator<<(std::ostream& stream, const DecisionItem &di);
};
- std::ostream &operator<<(std::ostream& stream, const DecisionItem &di);
class MatchItemOwn {
private:
public:
MatchItemOwn(const char *name) : _name(name) {}
const std::string &getName() const { return _name; }
-
- friend std::ostream &operator<<(std::ostream& stream, const MatchItemOwn &item);
};
- std::ostream &operator<<(std::ostream& stream, const MatchItemOwn &item);
/** Class contains info about ownership policy item */
class ItemOwn {
const std::string &getName() const;
bool isPrefix() const;
bool isMatchAll() const;
-
- friend std::ostream &operator<<(std::ostream& stream, const ItemOwn &item);
};
- std::ostream &operator<<(std::ostream& stream, const ItemOwn &item);
/** Struct which allows to contain multiple connection names then compared in s/r policy checker */
struct MatchItemSR {
MatchItemSR(const char* i, const char* me, const char* p, MessageType t);
void addName(const char* name);
bool addNames(const char* name);
-
- friend std::ostream &operator<<(std::ostream& stream, const MatchItemSR &item);
};
class MatchItemSend : public MatchItemSR {
using MatchItemSR::MatchItemSR;
- friend std::ostream &operator<<(std::ostream& stream, const MatchItemSend &item);
};
- std::ostream &operator<<(std::ostream& stream, const MatchItemSend &item);
class MatchItemReceive : public MatchItemSR {
using MatchItemSR::MatchItemSR;
- friend std::ostream &operator<<(std::ostream& stream, const MatchItemReceive &item);
};
- std::ostream &operator<<(std::ostream& stream, const MatchItemReceive &item);
/** Class contains info about item send/receive */
class ItemSendReceive {
MessageType getType() const;
bool isNamePrefix() const;
size_t getSize() const;
- friend std::ostream &operator<<(std::ostream& stream, const ItemSendReceive &item);
};
- std::ostream &operator<<(std::ostream& stream, const ItemSendReceive &item);
template <typename M>
class ItemSR : public ItemSendReceive {
bool match(const M &item) const {
return ItemSendReceive::match(item);
}
-
- friend std::ostream &operator<<(std::ostream& stream, const ItemSR<M> &item) {
- stream << typeid(item).name();
- return stream << static_cast<const ItemSendReceive>(item);
- }
};
typedef ItemSR<MatchItemSend> ItemSend;
MatchItemAccess(const uid_t uid, const std::vector<gid_t> &gids);
uid_t getUid() const;
const std::vector<gid_t>& getGids() const;
-
- friend std::ostream &operator<<(std::ostream& stream, const MatchItemAccess &item);
};
- std::ostream &operator<<(std::ostream& stream, const MatchItemAccess &item);
/** DBus bus access constraint */
class ItemAccess {
gid_t getGid() const;
BusAccessType getType() const;
size_t getSize() const;
- friend std::ostream &operator<<(std::ostream& stream, const ItemAccess &item);
};
- std::ostream &operator<<(std::ostream& stream, const ItemAccess &item);
class NaivePolicyDb;
--- /dev/null
+#include "print_content.hpp"
+#include "serialized_convert.hpp"
+#include "policy.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <ostream>
+
+/************ 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<std::size_t>(type)];
+}
+}
+
+template <typename T>
+std::ostream &print_val(std::ostream &stream, const boost::string_ref &name, const T &val) {
+ return stream << name << "(" << val << ")";
+}
+
+template <typename T>
+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<std::size_t>(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)
+{
+ stream << item_type << ": ";
+ 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);
+}
+
+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<std::size_t>(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 <typename T>
+void printContentItem(std::ostream &stream, const T *item);
+
+template <> void printContentItem(std::ostream &stream, const FB::ItemAccess *item) {
+ print_content_item_access(stream, makeBusAccessType(item->type()), item->uid(),
+ item->gid(), makeDecisionItem(item->decision()));
+}
+
+template <typename T>
+void printContentItemSR(std::ostream &stream, const boost::string_ref &item_type, const T *item) {
+ print_content_item_sr(stream, item_type, item->name()->c_str(), item->interface()->c_str(),
+ item->member()->c_str(), item->path()->c_str(), makeMessageType(item->type()),
+ makeDecisionItem(item->decision()));
+}
+
+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 <typename T>
+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, 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 <typename T>
+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 <typename T>
+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;
+}
+}
+
+/********* 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());
+}
+
+std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemSend &item) {
+ return print_content_item_sr(stream, "ItemSend", item.getName(), item.getInterface(), item.getMember(),
+ item.getPath(), item.getType(), item.getDecision());
+}
+
+std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemReceive &item) {
+ return print_content_item_sr(stream, "ItemReceive", item.getName(), item.getInterface(), item.getMember(),
+ item.getPath(), item.getType(), item.getDecision());
+}
+
+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());
+}
+
+std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::DecisionItem &item) {
+ return print_content_decision_item(stream, item.getDecision(), item.getPrivilege());
+}
+std::ostream &operator<<(std::ostream& stream, const MatchItemOwn &item)
+{
+ return stream << (item.getName().empty() ? "NULL" : item.getName());
+}
+
+std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemSR &item)
+{
+ stream << ": services(";
+ for (int i = 0; i < item.names_num; i++) {
+ stream << item.names[i];
+ if (i != item.names_num -1)
+ stream << " ";
+ }
+ return stream << "), interface(" << item.interface << "), member(" << item.member <<
+ "), path(" << item.path << "), type(" << __message_type_to_str(item.type) << ")";
+}
+
+std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemSend &item)
+{
+ stream << "MatchItemSend";
+ return stream << static_cast<const MatchItemSR>(item);
+}
+
+std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemReceive &item)
+{
+ stream << "MatchItemReceive";
+ return stream << static_cast<const MatchItemSR>(item);
+}
+
+std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemAccess &item)
+{
+ stream << "uid: " << item.getUid() << ", gid: ";
+ for (auto gid : item.getGids())
+ stream << gid << ", ";
+ return stream << std::endl;
+}
+
+}