From 8f37c086dac8aa986bb3f514eb5f093e632784a3 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 12 Feb 2019 15:20:01 +0100 Subject: [PATCH] refactoring: move "parse" methods to the "parser" Change-Id: Ibd543e118e7546d409f1441e4f7de99b964b4d8f --- src/internal/internal.cpp | 2 +- src/internal/policy.cpp | 190 +++++--------------------------------------- src/internal/policy.hpp | 30 +++---- src/internal/xml_parser.cpp | 174 +++++++++++++++++++++++++++++++++++++--- src/internal/xml_parser.hpp | 17 ++-- 5 files changed, 205 insertions(+), 208 deletions(-) diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index a655f48..82757ec 100755 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -37,7 +37,7 @@ static const char* get_str(const char* const szstr) { int __internal_init(BusType bus_type, const char* const config_name) { policy_checker().clearDb(bus_type); - auto err = static_parser().parsePolicy(bus_type, get_str(config_name)); + auto err = static_parser().parsePolicyConfigFile(bus_type, get_str(config_name)); if (tslog::enabled()) memory_dump(bus_type); return err; diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index 5e46ad2..0847c1b 100755 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -9,9 +9,7 @@ #include "tslog.hpp" #include #include -#include #include -#include #include #include #include @@ -23,22 +21,6 @@ static const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ER static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"}; static const char* message_access[] = {"USER", "GROUP", "ALL_USERS", "ALL_GROUPS"}; -static MessageType __str_to_message_type(const char* str) { - if (!str) - return MessageType::ANY; - - if (!std::strcmp(str, "method_call")) - return MessageType::METHOD_CALL; - else if (!std::strcmp(str, "method_return")) - return MessageType::METHOD_RETURN; - else if (!std::strcmp(str, "error")) - return MessageType::ERROR; - else if (!std::strcmp(str, "signal")) - return MessageType::SIGNAL; - - return MessageType::ANY; -} - 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, @@ -62,141 +44,6 @@ static inline const char* __access_type_to_str(BusAccessType type) { return message_access[static_cast(type)]; } -static uid_t convertToUid(const char* user) { - long val = -1; - errno = 0; - val = std::strtol(user, NULL, 10); - if (!errno && (val != 0 )) - return (uid_t)val; - if ((val == 0 && user[0] == '0' && user[1] == 0)) - return (uid_t)val; - - struct passwd pwent; - struct passwd *pwd; - char buf[1024]; - if (getpwnam_r(user, &pwent, buf, sizeof(buf), &pwd) || !pwd) - return (uid_t)-1; - - return pwd->pw_uid; -} - -static gid_t convertToGid(const char* group) { - long val = -1; - errno = 0; - val = std::strtol(group, NULL, 10); - if (!errno && (val != 0)) - return (gid_t)val; - if ((val == 0 && group[0] == '0' && group[1] == 0)) - return (gid_t)val; - - struct group grent; - struct group *gg; - char buf[1024]; - if (getgrnam_r(group, &grent, buf, sizeof(buf), &gg) || !gg) - return (gid_t)-1; - - return gg->gr_gid; -} - -static bool field_has(const std::string& str, const std::string& substr) { - return (str.find(substr) != std::string::npos); -} - -static const std::map str2decision{ - {"allow", Decision::ALLOW}, - {"deny", Decision::DENY}, - {"check", Decision::CHECK}}; - -void DbAdapter::parsePolicy(bool bus, const char **attr) -{ - policy_type = PolicyType::NONE; - curr_bus = bus; - - for (int i = 0; attr[i]; i += 2) { - parsePolicyAttribute(attr[i], attr[i + 1]); - } -} - -void DbAdapter::parsePolicyAttribute(const char* name, const char* value) -{ - //possible values (from dbus-daemon man): - // context="(default|mandatory)" - // at_console="(true|false)" (deprecated and not used on targets, we ignore it) - // user="username or userid" - // group="group name or gid" - if (std::strcmp(name, "context") == 0) { - if (std::strcmp(value, "mandatory") == 0 ) { - policy_type = PolicyType::CONTEXT; - policy_type_value.context = ContextType::MANDATORY; - } else if (std::strcmp(value, "default") == 0) { - policy_type = PolicyType::CONTEXT; - policy_type_value.context = ContextType::DEFAULT; - } - } else if (std::strcmp(name, "user") == 0) { - policy_type = PolicyType::USER; - policy_type_value.user = convertToUid(value); - } else if (std::strcmp(name, "group") == 0) { - policy_type = PolicyType::GROUP; - policy_type_value.group = convertToGid(value); - } -} - -void DbAdapter::parseRule(const char *name, const char **attr) -{ - if (policy_type == PolicyType::NONE) { - return; - } - if (str2decision.find(std::string(name)) == str2decision.end()) { - return; - } - __builder.addDecision(str2decision.at(std::string(name))); - - for (int i = 0; attr[i]; i += 2) { - parseRuleAttribute(attr[i], attr[i + 1]); - } - - __builder.generateItem(policy_checker().getPolicyDb(curr_bus), policy_type, policy_type_value); -} - -void DbAdapter::parseRuleAttribute(const char *name, const char *value) -{ - if (std::strcmp(value, "*") == 0) - value = nullptr; - - if (field_has(name, "send_")) { - __builder.setSendItem(); - } else if (field_has(name, "receive_")) { - __builder.setReceiveItem(); - } else if (std::strcmp(name, "own") == 0) { - __builder.addOwner(value); - __builder.setPrefix(false); - } else if (std::strcmp(name, "own_prefix") == 0) { - __builder.addOwner(value); - __builder.setPrefix(true); - } else if (std::strcmp(name, "privilege") == 0) { - __builder.addPrivilege(value); - } else if (std::strcmp(name, "user") == 0) { - __builder.addUserAccess(value); - } else if (std::strcmp(name, "group") == 0) { - __builder.addGroupAccess(value); - } - - if (field_has(name, "send_destination_prefix")) - __builder.addName(value, true); - else if (field_has(name, "_destination")) - __builder.addName(value); - else if (field_has(name, "_sender")) - __builder.addName(value); - else if (field_has(name, "_path")) - __builder.addPath(value); - else if (field_has(name, "_interface")) - __builder.addInterface(value); - else if (field_has(name, "_member")) - __builder.addMember(value); - else if (field_has(name, "_type")) - __builder.addMessageType(__str_to_message_type(value)); -} - DecisionItem::DecisionItem(Decision decision, const char* privilege) : __decision(decision) { @@ -350,22 +197,14 @@ const DecisionItem& ItemAccess::getDecision() const { return __decision; } -void ItemAccess::setUser(const char* user) { - if (user == nullptr) { - __type = BusAccessType::ALL_USERS; - } else { - __type = BusAccessType::USER; - __uid = convertToUid(user); - } +void ItemAccess::setUser(uid_t user) { + __type = BusAccessType::USER; + __uid = user; } -void ItemAccess::setGroup(const char* group) { - if (group == nullptr) { - __type = BusAccessType::ALL_GROUPS; - } else { - __type = BusAccessType::GROUP; - __gid = convertToGid(group); - } +void ItemAccess::setGroup(gid_t group) { + __type = BusAccessType::GROUP; + __gid = group; } bool ItemAccess::match(const MatchItemAccess& query) const @@ -466,7 +305,8 @@ void ItemBuilder::reset() { __current_item_type = ItemType::GENERIC; } -void ItemBuilder::generateItem(NaivePolicyDb& db, PolicyType& policy_type, PolicyTypeValue& policy_type_value) { +void ItemBuilder::generateItem(BusType bus_type, PolicyType& policy_type, PolicyTypeValue& policy_type_value) { + NaivePolicyDb &db = policy_checker().getPolicyDb(bus_type); switch (__current_item_type) { case ItemType::OWN: __current_own.__decision = __decision; @@ -529,16 +369,22 @@ void ItemBuilder::addMessageType(MessageType type) { getSendReceiveItem()->__type = type; } -void ItemBuilder::addUserAccess(const char* user) { - setAccessItem(); +void ItemBuilder::setUserAccess(uid_t user) { getAccessItem()->setUser(user); } -void ItemBuilder::addGroupAccess(const char* group) { - setAccessItem(); +void ItemBuilder::setAllUsersAccess() { + getAccessItem()->setAllUsers(); +} + +void ItemBuilder::setGroupAccess(gid_t group) { getAccessItem()->setGroup(group); } +void ItemBuilder::setAllGroupsAccess() { + getAccessItem()->setAllGroups(); +} + void ItemBuilder::addPrivilege(const char* privilege) { __decision.setPrivilege(privilege); } diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp index 1015283..f73b901 100755 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -244,8 +244,10 @@ namespace ldp_xml_parser gid_t __gid{0}; BusAccessType __type{BusAccessType::ALL_USERS}; - void setUser(const char* user); - void setGroup(const char* group); + void setAllUsers() { __type = BusAccessType::ALL_USERS; } + void setUser(uid_t user); + void setAllGroups() { __type = BusAccessType::ALL_GROUPS; } + void setGroup(gid_t group); public: typedef MatchItemAccess match_type; @@ -276,7 +278,7 @@ namespace ldp_xml_parser public: ItemBuilder(); ~ItemBuilder(); - void generateItem(NaivePolicyDb& db, PolicyType& policy_type, PolicyTypeValue& policy_type_value); + void generateItem(BusType bus_type, PolicyType& policy_type, PolicyTypeValue& policy_type_value); void reset(); void setOwnItem(); void setSendItem(); @@ -293,24 +295,10 @@ namespace ldp_xml_parser void addPrivilege(const char* privilege); void addDecision(Decision decision); void setPrefix(bool value); - void addUserAccess(const char* user); - void addGroupAccess(const char* group); - }; - - /** Adapter which allows to access policy db. Contains references to system and session db. */ - class DbAdapter { - private: - ItemBuilder __builder; - PolicyType policy_type; - PolicyTypeValue policy_type_value; - bool curr_bus; - - void parsePolicyAttribute(const char* name, const char* value); - void parseRuleAttribute(const char *name, const char *value); - - public: - void parsePolicy(bool bus, const char **attr); - void parseRule(const char *name, const char **attr); + void setUserAccess(uid_t user); + void setAllUsersAccess(); + void setGroupAccess(gid_t group); + void setAllGroupsAccess(); }; } #endif diff --git a/src/internal/xml_parser.cpp b/src/internal/xml_parser.cpp index caf98be..c3bc869 100644 --- a/src/internal/xml_parser.cpp +++ b/src/internal/xml_parser.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "tslog.hpp" #include "libdbuspolicy1-private.h" @@ -107,7 +109,7 @@ void XmlParser::elementStart(const char *el, const char **attr) { } else if (std::strcmp(el, "policy") == 0) { parseAssert(state == BUSCONFIG); state = POLICY; - __adapter.parsePolicy(curr_bus, attr); + parsePolicyTag(attr); } else if (std::strcmp(el, "includedir") == 0) { parseAssert(state == BUSCONFIG); state = INCLUDEDIR; @@ -126,15 +128,15 @@ void XmlParser::elementStart(const char *el, const char **attr) { } else if (std::strcmp(el, "allow") == 0) { parseAssert(state == POLICY); state = RULE; - __adapter.parseRule(el, attr); + parseRule(Decision::ALLOW, attr); } else if (std::strcmp(el, "deny") == 0) { parseAssert(state == POLICY); state = RULE; - __adapter.parseRule(el, attr); + parseRule(Decision::DENY, attr); } else if (std::strcmp(el, "check") == 0) { parseAssert(state == POLICY); state = RULE; - __adapter.parseRule(el, attr); + parseRule(Decision::CHECK, attr); } } @@ -177,14 +179,14 @@ void XmlParser::elementEnd(const char *el) { } } -int XmlParser::parsePolicy(BusType bus, const std::string& fname) { - tslog::log("XmlParser::parsePolicy called with filename: ", fname, "\n"); +int XmlParser::parsePolicyConfigFile(BusType bus, const std::string& fname) { + tslog::log("XmlParser::parsePolicyConfigFile called with filename: ", fname, "\n"); curr_bus = bus; - parsePolicyInternal(fname); + parsePolicyConfigFileInternal(fname); return ret_code; } -void XmlParser::parsePolicyInternal(const std::string& filename) { +void XmlParser::parsePolicyConfigFileInternal(const std::string& filename) { ret_code = 0; try { parseXmlFile(filename); @@ -205,7 +207,7 @@ void XmlParser::parsePolicyInternal(const std::string& filename) { } std::vector curr_included_files = included_files; // deep copy for (const auto& included_file : curr_included_files) { - parsePolicyInternal(included_file); + parsePolicyConfigFileInternal(included_file); } } @@ -290,4 +292,158 @@ void XmlParser::getIncludedFiles(const std::string& parent_dir, const std::strin } } +void XmlParser::parsePolicyTag(const char **attr) +{ + policy_type = PolicyType::NONE; + + for (int i = 0; attr[i]; i += 2) { + parsePolicyAttribute(attr[i], attr[i + 1]); + } +} + +namespace { +static uid_t convertToUid(const char* user) { + long val = -1; + errno = 0; + val = std::strtol(user, NULL, 10); + if (!errno && (val != 0 )) + return (uid_t)val; + if ((val == 0 && user[0] == '0' && user[1] == 0)) + return (uid_t)val; + + struct passwd pwent; + struct passwd *pwd; + char buf[1024]; + if (getpwnam_r(user, &pwent, buf, sizeof(buf), &pwd) || !pwd) + return (uid_t)-1; + + return pwd->pw_uid; +} + +static gid_t convertToGid(const char* group) { + long val = -1; + errno = 0; + val = std::strtol(group, NULL, 10); + if (!errno && (val != 0)) + return (gid_t)val; + if ((val == 0 && group[0] == '0' && group[1] == 0)) + return (gid_t)val; + + struct group grent; + struct group *gg; + char buf[1024]; + if (getgrnam_r(group, &grent, buf, sizeof(buf), &gg) || !gg) + return (gid_t)-1; + + return gg->gr_gid; +} +} + +void XmlParser::parsePolicyAttribute(const char* name, const char* value) +{ + //possible values (from dbus-daemon man): + // context="(default|mandatory)" + // at_console="(true|false)" (deprecated and not used on targets, we ignore it) + // user="username or userid" + // group="group name or gid" + if (std::strcmp(name, "context") == 0) { + policy_type = PolicyType::CONTEXT; + if (std::strcmp(value, "mandatory") == 0 ) { + policy_type_value.context = ContextType::MANDATORY; + } else if (std::strcmp(value, "default") == 0) { + policy_type_value.context = ContextType::DEFAULT; + } + } else if (std::strcmp(name, "user") == 0) { + policy_type = PolicyType::USER; + policy_type_value.user = convertToUid(value); + } else if (std::strcmp(name, "group") == 0) { + policy_type = PolicyType::GROUP; + policy_type_value.group = convertToGid(value); + } +} + +void XmlParser::parseRule(Decision decision, const char **attr) +{ + if (policy_type == PolicyType::NONE) { + return; + } + + __builder.addDecision(decision); + + for (int i = 0; attr[i]; i += 2) { + parseRuleAttribute(attr[i], attr[i + 1]); + } + + __builder.generateItem(curr_bus, policy_type, policy_type_value); +} + +namespace { +MessageType __str_to_message_type(const char* str) { + if (!str) + return MessageType::ANY; + + if (!std::strcmp(str, "method_call")) + return MessageType::METHOD_CALL; + else if (!std::strcmp(str, "method_return")) + return MessageType::METHOD_RETURN; + else if (!std::strcmp(str, "error")) + return MessageType::ERROR; + else if (!std::strcmp(str, "signal")) + return MessageType::SIGNAL; + + return MessageType::ANY; +} +} + +void XmlParser::parseRuleAttribute(const char *name, const char *value) +{ + auto field_has = [] (const std::string& str, const std::string& substr) { + return (str.find(substr) != std::string::npos); + }; + + if (std::strcmp(value, "*") == 0) + value = nullptr; + + if (field_has(name, "send_")) { + __builder.setSendItem(); + } else if (field_has(name, "receive_")) { + __builder.setReceiveItem(); + } else if (std::strcmp(name, "own") == 0) { + __builder.addOwner(value); + __builder.setPrefix(false); + } else if (std::strcmp(name, "own_prefix") == 0) { + __builder.addOwner(value); + __builder.setPrefix(true); + } else if (std::strcmp(name, "privilege") == 0) { + __builder.addPrivilege(value); + } else if (std::strcmp(name, "user") == 0) { + __builder.setAccessItem(); + if (value) + __builder.setUserAccess(convertToUid(value)); + else + __builder.setAllUsersAccess(); + } else if (std::strcmp(name, "group") == 0) { + __builder.setAccessItem(); + if (value) + __builder.setGroupAccess(convertToGid(value)); + else + __builder.setAllGroupsAccess(); + } + + if (field_has(name, "send_destination_prefix")) + __builder.addName(value, true); + else if (field_has(name, "_destination")) + __builder.addName(value); + else if (field_has(name, "_sender")) + __builder.addName(value); + else if (field_has(name, "_path")) + __builder.addPath(value); + else if (field_has(name, "_interface")) + __builder.addInterface(value); + else if (field_has(name, "_member")) + __builder.addMember(value); + else if (field_has(name, "_type")) + __builder.addMessageType(__str_to_message_type(value)); +} + DEF_NODESTRUCT_GLOBAL(ldp_xml_parser::XmlParser, static_parser); diff --git a/src/internal/xml_parser.hpp b/src/internal/xml_parser.hpp index eba16ad..8ede445 100755 --- a/src/internal/xml_parser.hpp +++ b/src/internal/xml_parser.hpp @@ -33,7 +33,7 @@ namespace ldp_xml_parser { public: /** Parses given config file for declared bus type */ - int parsePolicy(BusType bus_type, const std::string& fname); + int parsePolicyConfigFile(BusType bus_type, const std::string& fname); void elementStart(const char *el, const char **attr); @@ -46,14 +46,11 @@ namespace ldp_xml_parser private: class IncludeItem; - /** Adapter which allows to access parsed policies */ - DbAdapter __adapter; - /** Decides whether a filename describes one of main system.conf/session.conf files */ bool isMainConfFile(const std::string& filename); /** Parses config file and all files included in it (recursively) */ - void parsePolicyInternal(const std::string& filename); + void parsePolicyConfigFileInternal(const std::string& filename); /** Parses config file and returns all files included in it */ void parseXmlFile(const std::string& filename); @@ -64,6 +61,16 @@ namespace ldp_xml_parser /** Get all the .conf files within included subdirectory, POSIX style as boost::filesystem is not header-only */ void getIncludedFiles(const std::string& parent_dir, const std::string& incldir, std::vector& files); + ItemBuilder __builder; + PolicyType policy_type; + PolicyTypeValue policy_type_value; + + void parsePolicyTag(const char **attr); + void parsePolicyAttribute(const char* name, const char* value); + + void parseRule(Decision decision, const char **attr); + void parseRuleAttribute(const char *name, const char *value); + typedef enum { IDLE, BUSCONFIG, INCLUDE, INCLUDEDIR, POLICY, RULE } ParseState; ParseState state; -- 2.7.4