From 44f0b122fa257e98454b21f7219d47db6e8ca47a Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Wed, 27 Apr 2016 16:00:32 +0200 Subject: [PATCH 01/16] Fix: ensure Smack label is null terminated in internal representation Change-Id: Ifbb8d651b407111668ba61d1e279938fb6509589 --- src/libdbuspolicy1.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index b97c68d..5178e88 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -233,13 +233,15 @@ static int dbuspolicy_init_udesc(struct kconn* kc, unsigned int bus_type, struct attr_fd = open("/proc/self/attr/current", O_RDONLY); if (attr_fd < 0) return -1; - r = read(attr_fd, p_udesc->label, 256); + r = read(attr_fd, buf, sizeof(buf)); close(attr_fd); - if (r < 0) /* read */ + if (r < 0 || r >= (long int)sizeof(p_udesc->label)) /* read */ return -1; + snprintf(p_udesc->label, r + 1 /* additional byte for \0 */, "%s", buf); + p_udesc->uid = getuid(); p_udesc->gid = getgid(); -- 2.7.4 From 4e46a80e1ebaa6daeb909e750314794828493c87 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Wed, 27 Apr 2016 16:03:03 +0200 Subject: [PATCH 02/16] Janitorial: use snprintf() for string operations snprintf() guarantees terminating \0 byte for given size. Change-Id: I65cb90ea4466d0356cc02919d269da8843a7302f --- src/libdbuspolicy1.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 5178e88..e10d43b 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -228,7 +228,6 @@ static int dbuspolicy_init_udesc(struct kconn* kc, unsigned int bus_type, struct char buf[1024]; int attr_fd; int r; - int len; attr_fd = open("/proc/self/attr/current", O_RDONLY); if (attr_fd < 0) @@ -254,13 +253,8 @@ static int dbuspolicy_init_udesc(struct kconn* kc, unsigned int bus_type, struct if (!pwd || !gg) return -1; - len = sizeof(p_udesc->user) - 1; - strncpy(p_udesc->user, pwd->pw_name, len); - p_udesc->group[len] = 0; - - len = sizeof(p_udesc->group) - 1; - strncpy(p_udesc->group, gg->gr_name, len); - p_udesc->group[len] = 0; + snprintf(p_udesc->user, sizeof(p_udesc->user), "%s", pwd->pw_name); + snprintf(p_udesc->group, sizeof(p_udesc->group), "%s", gg->gr_name); p_udesc->bus_type = bus_type; p_udesc->conn = kc; -- 2.7.4 From f2e9323ecfcd034cd012e768d3a3d73927179387 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 28 Apr 2016 14:06:38 +0200 Subject: [PATCH 03/16] Initialize policy database based on bus path Currently library has no reliable way of determining which path was already opened by libdbus/glib when only bus type is given. This commit changes API to allow client libraries pass bus path directly eliminating possible ambiguities. Change-Id: I732c391898f661b923fa61d4a2aebb402fb0ec3c --- src/dbuspolicy1/libdbuspolicy1.h | 16 +++++++++--- src/libdbuspolicy1.c | 53 ++++++++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/dbuspolicy1/libdbuspolicy1.h b/src/dbuspolicy1/libdbuspolicy1.h index a0f7dcd..0037fc7 100644 --- a/src/dbuspolicy1/libdbuspolicy1.h +++ b/src/dbuspolicy1/libdbuspolicy1.h @@ -46,13 +46,21 @@ extern "C" { struct udesc; /*! - libdbuspolicy init - \param bus_type bus type (SYSTEM or SESSION) + Initialize libdbuspolicy configuration context + \param bus_path path to the kdbus bus (system or session) + + \note This function should be called only on well known kdbus buses + - the system bus (/sys/fs/kdbus/0-system/bus) and session bus + (/sys/fs/kdbus/getuid()-user/bus). If any other bus is specified + function will not succeed. + + \return On success pointer to configuration context is returned. On + error NULL is returned. */ -void* dbuspolicy1_init(unsigned int bus_type); +void* dbuspolicy1_init(const char *bus_path); /*! - libdbuspolicy free + Free libdbuspolicy configuration context \param configuration pointer with policy configuration acquired using dbuspolicy1_init */ void dbuspolicy1_free(void* configuration); diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index e10d43b..68f13a9 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -30,12 +30,15 @@ #include #include #include +#include #include #include "libdbuspolicy1-private.h" #include "internal/internal.h" +#define KDBUS_PATH_PREFIX "/sys/fs/kdbus/" #define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus" + #define KDBUS_POOL_SIZE (16 * 1024UL * 1024UL) #define ALIGN8(l) (((l) + 7) & ~7) @@ -90,9 +93,9 @@ struct udesc { }; -static int kdbus_open_system_bus(void) +static int kdbus_open_bus(const char *path) { - return open(KDBUS_SYSTEM_BUS_PATH, O_RDWR|O_NOCTTY|O_LARGEFILE|O_CLOEXEC ); + return open(path, O_RDWR|O_NOCTTY|O_LARGEFILE|O_CLOEXEC); } static int kdbus_hello(struct kconn *kc, uint64_t hello_flags, uint64_t attach_flags_send, uint64_t attach_flags_recv) @@ -262,25 +265,55 @@ static int dbuspolicy_init_udesc(struct kconn* kc, unsigned int bus_type, struct return 0; } -/** - * dbuspolicy1_init - * @config_name: name of the XML configuration file - * - * Set the configuration file used by the calling application - **/ -DBUSPOLICY1_EXPORT void* dbuspolicy1_init(unsigned int bus_type) +static int bus_path_resolve(const char *bus_path, char *resolved_path, unsigned resolved_path_size, unsigned int *bus_type) +{ + char rp[PATH_MAX]; + char *p; + const char user_suffix[] = "-user/bus"; + int suffix_pos; + + p = realpath(bus_path, rp); + if (!p) + return -1; + + if (0 != strncmp(p, KDBUS_PATH_PREFIX, strlen(KDBUS_PATH_PREFIX))) + return -1; + + if (0 == strcmp(p, KDBUS_SYSTEM_BUS_PATH)) { + *bus_type = SYSTEM_BUS; + } else { + suffix_pos = strlen(p) - strlen(user_suffix); + if (suffix_pos < 0) + return -1; + + if (0 != strcmp(p + suffix_pos, user_suffix)) + return -1; + + *bus_type = SESSION_BUS; + } + + snprintf(resolved_path, resolved_path_size, "%s", p); + return 0; +} + +DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) { uint64_t hello_flags = 0; uint64_t attach_flags_send = _KDBUS_ATTACH_ANY; uint64_t attach_flags_recv = _KDBUS_ATTACH_ALL; struct kconn* kc = NULL; struct udesc* p_udesc = NULL; + unsigned int bus_type = -1; + char resolved_path[PATH_MAX] = { 0 }; + + if (bus_path_resolve(bus_path, resolved_path, sizeof(resolved_path), &bus_type) < 0) + goto err; kc = (struct kconn*) calloc(1, sizeof(struct kconn)); if (!kc) goto err; - if ((kc->fd = kdbus_open_system_bus()) < 0) + if ((kc->fd = kdbus_open_bus(resolved_path)) < 0) goto err; if (kdbus_hello(kc, hello_flags, attach_flags_send, attach_flags_recv) < 0) -- 2.7.4 From bc76cd6e15bd66b6c13a29a64a29a68d3bfe225f Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Wed, 13 Apr 2016 10:58:43 +0200 Subject: [PATCH 04/16] Fixed series of bugs and optimalised arguments preparation Fixed kdbus pool memory managment. Refactored tslog (getenv called only once). Removed duplicated credential information. Dropped unused timeouts. Added lockless calls when logs are disabled. Removed udesc allocation. Decreased KDBUS_POOL_SIZE from 16M to 1M. Minor fixes. Change-Id: I1e5fda8df4dbd1dd6dfecae60aff6d7d67705a3b --- src/dbuspolicy1/libdbuspolicy1.h | 3 - src/internal/internal.cpp | 65 +++- src/internal/internal.h | 11 +- src/internal/libdbuspolicy1-private.hpp | 11 +- src/internal/timer.hpp | 77 ----- src/internal/tslog.hpp | 89 +----- src/internal/xml_parser.hpp | 227 +++++--------- src/internal/xml_policy.hpp | 359 +++++++++------------- src/libdbuspolicy1-private.h | 3 + src/libdbuspolicy1.c | 515 ++++++++++++++------------------ 10 files changed, 515 insertions(+), 845 deletions(-) delete mode 100644 src/internal/timer.hpp diff --git a/src/dbuspolicy1/libdbuspolicy1.h b/src/dbuspolicy1/libdbuspolicy1.h index 0037fc7..ae9b0c2 100644 --- a/src/dbuspolicy1/libdbuspolicy1.h +++ b/src/dbuspolicy1/libdbuspolicy1.h @@ -29,9 +29,6 @@ extern "C" { #define SYSTEM_BUS_CONF_FILE_SECONDARY "/etc/dbus-1/system-local.conf" #define SESSION_BUS_CONF_FILE_SECONDARY "/etc/dbus-1/session-local.conf" -#define SYSTEM_BUS 1 -#define SESSION_BUS 2 - /** used when check policy for message prepared to send */ #define DBUSPOLICY_DIRECTION_SENDING 0 diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index 274d321..e26c510 100644 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -23,14 +23,20 @@ extern "C" { #endif -static const char* get_bus(int bus_type) { - return (bus_type == SYSTEM_BUS) ? "SYSTEM" : "SESSION"; -} - static const char* get_str(const char* const szstr) { return (szstr != NULL) ? szstr : ""; } +static std::string get_strv(const char *s) { + unsigned i = 0; + if (s) { + i = -1; + char c; + while ((c = s[++i]) && ' ' != c); + } + return std::string{s, i}; +} + static const char* get_message_type(int type) { const char* sztype; switch(type) { @@ -43,14 +49,41 @@ static const char* get_message_type(int type) { return sztype; } -int __internal_init(unsigned int bus_type, const char* const config_name) +int __internal_init(bool bus_type, const char* const config_name) { - _ldp_xml_parser::XmlAsyncParser p; - auto err = p.parse_policy(get_bus(bus_type), get_str(config_name)); + _ldp_xml_parser::XmlParser p; + auto err = p.parse_policy(bus_type, get_str(config_name)); return err.get(); } -int __internal_can_send(unsigned int bus_type, +pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; + +void __internal_init_once() +{ + tslog::init(); +} + +void __internal_init_flush_logs() +{ + if (tslog::enabled()) { + pthread_mutex_lock(&g_mutex); + std::cout << std::flush; + pthread_mutex_unlock(&g_mutex); + } +} + +void __internal_enter() +{ + if (tslog::enabled()) + pthread_mutex_lock(&g_mutex); +} +void __internal_exit() +{ + if (tslog::enabled()) + pthread_mutex_unlock(&g_mutex); +} + +int __internal_can_send(bool bus_type, const char* const user, const char* const group, const char* const label, @@ -60,12 +93,12 @@ int __internal_can_send(unsigned int bus_type, const char* const member, int type) { - _ldp_xml_parser::XmlAsyncParser p; - auto err = p.can_send(get_bus(bus_type), get_str(user), get_str(group), get_str(label), get_str(destination), get_str(path), get_str(interface), get_str(member), get_message_type(type)); + _ldp_xml_parser::XmlParser p; + auto err = p.can_send(bus_type, get_str(user), get_str(group), get_str(label), get_strv(destination), get_str(path), get_str(interface), get_str(member), get_message_type(type)); return err.get(); } -int __internal_can_recv(unsigned int bus_type, +int __internal_can_recv(bool bus_type, const char* const user, const char* const group, const char* const label, @@ -75,18 +108,18 @@ int __internal_can_recv(unsigned int bus_type, const char* const member, int type) { - _ldp_xml_parser::XmlAsyncParser p; - auto err = p.can_recv(get_bus(bus_type), get_str(user), get_str(group), get_str(label), get_str(sender), get_str(path), get_str(interface), get_str(member), get_message_type(type)); + _ldp_xml_parser::XmlParser p; + auto err = p.can_recv(bus_type, get_str(user), get_str(group), get_str(label), get_strv(sender), get_str(path), get_str(interface), get_str(member), get_message_type(type)); return err.get(); } -int __internal_can_own(unsigned int bus_type, +int __internal_can_own(bool bus_type, const char* const user, const char* const group, const char* const service) { - _ldp_xml_parser::XmlAsyncParser p; - auto err = p.can_own(get_bus(bus_type), get_str(user), get_str(group), get_str(service)); + _ldp_xml_parser::XmlParser p; + auto err = p.can_own(bus_type, get_str(user), get_str(group), get_str(service)); return err.get(); } diff --git a/src/internal/internal.h b/src/internal/internal.h index 84a1069..0914abe 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -22,8 +22,13 @@ extern "C" { #endif int __internal_init(unsigned int bus_type, const char* const config_name); +void __internal_init_once(void); +extern pthread_mutex_t g_mutex; +void __internal_init_flush_logs(void); +void __internal_enter(void); +void __internal_exit(void); -int __internal_can_send(unsigned int bus_type, +int __internal_can_send(bool bus_type, const char* const user, const char* const group, const char* const label, @@ -33,7 +38,7 @@ int __internal_can_send(unsigned int bus_type, const char* const member, int type); -int __internal_can_recv(unsigned int bus_type, +int __internal_can_recv(bool bus_type, const char* const user, const char* const group, const char* const label, @@ -43,7 +48,7 @@ int __internal_can_recv(unsigned int bus_type, const char* const member, int type); -int __internal_can_own(unsigned int bus_type, +int __internal_can_own(bool bus_type, const char* const user, const char* const group, const char* const service); diff --git a/src/internal/libdbuspolicy1-private.hpp b/src/internal/libdbuspolicy1-private.hpp index 4b467b4..0cef333 100644 --- a/src/internal/libdbuspolicy1-private.hpp +++ b/src/internal/libdbuspolicy1-private.hpp @@ -19,6 +19,12 @@ #include +namespace arraySizeDetail { + template constexpr size_t size(T const (&)[S]) { return S; } + template constexpr size_t size(std::initializer_list const &l) { return l.size(); } +} +#define TABSIZE(...) (::arraySizeDetail::size(__VA_ARGS__)) + namespace { class ErrCode { int m_err; @@ -26,7 +32,6 @@ namespace { ErrCode(int e, const std::string& s) : m_err(e), m_err_str(s) {} public: ErrCode() : m_err(0), m_err_str("") {} - virtual ~ErrCode() {} static ErrCode ok() { return ErrCode(0, "OK"); @@ -41,10 +46,6 @@ namespace { return ErrCode(-1, what); } - static ErrCode timeout(const std::string& what) { - return ErrCode(-99, std::string("Timeout: ") + what); - } - int get() const { return m_err; } diff --git a/src/internal/timer.hpp b/src/internal/timer.hpp deleted file mode 100644 index 2d856b3..0000000 --- a/src/internal/timer.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef _TIMER_HPP -#define _TIMER_HPP -#include - -namespace _ldp_timer -{ - template - class Duration : public BaseTimeUnit { - public: - void setNanoTime(std::chrono::nanoseconds nano) { - BaseTimeUnit d = std::chrono::duration_cast(nano); - BaseTimeUnit::operator =(d); - } - - double getSeconds() { - typename BaseTimeUnit::period p; - return 1.0 * BaseTimeUnit::count() * p.num/p.den; - } - - uint64_t getNativeTime() { - return BaseTimeUnit::count(); - } - - friend std::ostream& operator<< (std::ostream& os, - const Duration& d) { - typename BaseTimeUnit::period p; - std::string unit; - switch(p.den/p.num) { - case 1000000000: unit = "ns"; break; - case 1000000: unit = "us"; break; - case 1000: unit = "ms"; break; - case 1: unit = "s"; break; - } - - os << d.count() << " " << unit; - return os; - } - }; - - typedef Duration nanosec; - typedef Duration microsec; - typedef Duration millisec; - typedef Duration sec; - - template - class Timer { - typedef std::chrono::steady_clock CLK; - CLK::time_point tbegin; - _T* const pOT; - public: - Timer(_T* const pTP) - : tbegin(CLK::now()), pOT(pTP) {} - - virtual ~Timer() { - if(pOT) - pOT->setNanoTime(CLK::now() - tbegin); - } - }; -} - -#endif // _TIMER_HPP diff --git a/src/internal/tslog.hpp b/src/internal/tslog.hpp index 3452dbc..dd57976 100644 --- a/src/internal/tslog.hpp +++ b/src/internal/tslog.hpp @@ -19,87 +19,26 @@ #include #include -#include +#include #include -namespace _ldp_tslog -{ - typedef std::ostream& (*t_ManFun)(std::ostream&); - - namespace { - static constexpr bool LOG_DEFAULT_ENABLE = false; - static constexpr bool LOG_DEFAULT_VERBOSE = false; - static const std::string LDP_ENV_VERBOSE_NAME = "LDP_VERBOSE"; - static const std::string LDP_ENV_LOG_NAME = "LDP_LOG"; - - const bool get_log_env(const std::string& name) { - bool bret; - char* ldp_log_mode = getenv(name.c_str()); - if(ldp_log_mode) { - const std::string slog(ldp_log_mode); - bret = (slog == "0") ? false : true; - } else { - bret = (name == LDP_ENV_LOG_NAME) ? LOG_DEFAULT_ENABLE : LOG_DEFAULT_VERBOSE; - } - return bret; - } - } - - const bool get_verbose() { - return get_log_env(LDP_ENV_VERBOSE_NAME); - } - - const bool get_enable() { - return get_log_env(LDP_ENV_LOG_NAME); - } - - class TsLog - { - private: - static bool m_verbose; - static std::mutex m_mtx; - std::ostream& m_os; - bool m_enable; +typedef std::ostream& (*t_ManFun)(std::ostream&); - template - TsLog& lckLog(const T& t) { - if(m_enable) { - std::unique_lock lck(m_mtx); - m_os << t; - } - return *this; - } - - public: - TsLog() = delete; - - explicit TsLog(std::ostream& os, bool enable = true) - : m_os(os), m_enable(enable) {} - - virtual ~TsLog() {} +namespace tslog +{ + int8_t g_verbosity; // <0 disable 0 brief >0 verbose - template - TsLog& operator<< (const T& t) { - return lckLog(t); - } + bool get_log_env(char const *name) { + char const *ldp_log_mode = getenv(name); + return ldp_log_mode && '0' != *ldp_log_mode; + } - TsLog& operator<< (t_ManFun f) { - return lckLog(f); - } + void init() { + g_verbosity = get_log_env("LDP_LOG") ? get_log_env("LDP_VERBOSE") : -1; + } - }; - std::mutex TsLog::m_mtx; + bool enabled() { return g_verbosity >= 0; } + bool verbose() { return g_verbosity > 0; } } -namespace { - //Thread-safe loggers - _ldp_tslog::TsLog tout(std::cout, _ldp_tslog::get_enable()); - _ldp_tslog::TsLog terr(std::cerr, _ldp_tslog::get_enable()); - - namespace verbose { - _ldp_tslog::TsLog tout(std::cout, _ldp_tslog::get_enable() && _ldp_tslog::get_verbose()); - _ldp_tslog::TsLog terr(std::cerr, _ldp_tslog::get_enable() && _ldp_tslog::get_verbose()); - } -} //namespace - #endif diff --git a/src/internal/xml_parser.hpp b/src/internal/xml_parser.hpp index 05df566..61e60e4 100644 --- a/src/internal/xml_parser.hpp +++ b/src/internal/xml_parser.hpp @@ -17,39 +17,26 @@ #ifndef _XML_PARSER_HPP #define _XML_PARSER_HPP -#include -#include -#include +#include #include #include #include -#include #include #include -#include "timer.hpp" #include "xml_policy.hpp" namespace _ldp_xml_parser { - class XmlAsyncParser : boost::noncopyable + class XmlParser : boost::noncopyable { public: - XmlAsyncParser() { - } - - virtual ~XmlAsyncParser() { - } - - ErrCode parse_policy(const std::string bus, - const std::string fname, - const std::chrono::milliseconds timeout = std::chrono::milliseconds(std::numeric_limits::max())) { - set_policy_bus_filename(bus, fname); - m_xml_policy.init(); - ErrCode err = parse(timeout); + ErrCode parse_policy(bool bus, + std::string const &fname) { + ErrCode err = parse(bus, fname); return err; } - ErrCode can_send(const std::string bus, + ErrCode can_send(bool bus, const std::string user, const std::string group, const std::string label, @@ -62,7 +49,7 @@ namespace _ldp_xml_parser return m_xml_policy.can_send_to(bus, idx_v, label); } - ErrCode can_recv(const std::string bus, + ErrCode can_recv(bool bus, const std::string user, const std::string group, const std::string label, @@ -75,7 +62,7 @@ namespace _ldp_xml_parser return m_xml_policy.can_recv_from(bus, idx_v, label); } - ErrCode can_own(const std::string bus, + ErrCode can_own(bool bus, const std::string user, const std::string group, const std::string service) { @@ -86,173 +73,95 @@ namespace _ldp_xml_parser private: //IO operation - std::string m_bus; - std::string m_filename; - static std::map m_hashes; - static std::mutex m_io_xml_mtx; + static std::set m_parsed; //Data obtained from XML static XmlPolicy m_xml_policy; - //Called by calling user thread - void set_policy_bus_filename(const std::string& bus, const std::string& fname) { - m_filename = fname; - m_bus = bus; - } - - const std::string& get_policy_bus() const { - return m_bus; - } - - const std::string& get_policy_filename() const { - return m_filename; - } - - ErrCode parse(const std::chrono::milliseconds timeout) { + ErrCode parse(bool bus, std::string const &filename) { ErrCode err; std::vector incl_files; - err = parse(get_policy_filename(), incl_files, timeout); - if(err.is_ok()) { + err = parse(bus, true, filename, incl_files); + if (err.is_ok()) for(const auto& x : incl_files) { - err = parse(x, incl_files, timeout); - if(err.is_error()) { break; } + err = parse(bus, false, x, incl_files); + if (err.is_error()) break; } - } - if(err.is_ok()) { - m_xml_policy.print_decision_trees(); - } + if(err.is_ok()) + m_xml_policy.print_decision_trees(bus); return err; } - ErrCode parse(const std::string& filename, std::vector& included_files, const std::chrono::milliseconds timeout) { + ErrCode parse(bool bus, bool first, const std::string& filename, std::vector& included_files) { std::pair errparam; - verbose::tout << "=== XML PARSING BEGIN === : " << filename << std::endl; + if (tslog::verbose()) + std::cout << "=== XML PARSING BEGIN === : " << filename << '\n'; - auto fut = std::async(std::launch::async, &XmlAsyncParser::async_xml_parse, this, filename); - - auto r = fut.wait_for(timeout); - if(r == std::future_status::ready) { - errparam = fut.get(); - if(errparam.first.get() >= 0) { - get_included_files(filename, errparam.second, included_files); - } - } else if(r == std::future_status::timeout) { - errparam.first = ErrCode::timeout("XML parsing timeout"); - } + errparam = xml_parse(bus, filename); + if (first && errparam.first.get() >= 0 && errparam.second != "") + get_included_files(filename, errparam.second, included_files); - verbose::tout << "=== XML PARSING END ===" << std::endl << std::endl; - tout << "Processing of " << filename << " -> [" << errparam.first.get() << ", " << errparam.first.get_str() << "]" << std::endl; + if (tslog::enabled()) { + if (tslog::verbose()) + std::cout << "=== XML PARSING END ===\n\n"; + std::cout << "Processing of " << filename << " -> [" << errparam.first.get() << ", " << errparam.first.get_str() << "]\n"; + } return errparam.first; } //Get all the .conf files within included subdirectory, POSIX style as boost::filesystem is not header-only void get_included_files(const std::string& filename, const std::string& incldir, std::vector& files) { - if(get_policy_filename() == filename && incldir != "") { - DIR *dir; - struct dirent *ent; - std::string fname; - std::copy(filename.begin(), filename.end(), fname.begin()); - std::string dname = dirname(const_cast(fname.c_str())); - dname += (std::string("/") + incldir); - files.clear(); - if((dir = opendir(dname.c_str())) != NULL) { - while((ent = readdir(dir)) != NULL) { - std::string s(ent->d_name); - if(s.find(".conf") != std::string::npos) { - files.push_back(dname + std::string("/") + s); - } - } - closedir(dir); - - tout << std::endl << "includedir for " << filename << " is " << incldir << ", " << files.size() << " included files found:" << std::endl; - if(_ldp_tslog::get_enable()) { std::copy(files.begin(), files.end(), std::ostream_iterator(std::cout, "\n")); } - tout << std::endl; - } else { - terr << "could not open directory " << dname << std::endl; - } - } - } - - //All 'async_*' methods are executed in library's internal worker threads - std::pair async_xml_parse(const std::string& filename) { + DIR *dir; + struct dirent *ent; + std::string fname; + std::copy(filename.begin(), filename.end(), fname.begin()); + std::string dname = dirname(const_cast(fname.c_str())); + dname += (std::string("/") + incldir); + files.clear(); + if((dir = opendir(dname.c_str())) != NULL) { + while((ent = readdir(dir)) != NULL) { + std::string s(ent->d_name); + if(s.find(".conf") != std::string::npos) { + files.push_back(dname + std::string("/") + s); + } + } + closedir(dir); + + if (tslog::enabled()) { + std::cout << "\nincludedir for " << filename << " is " << incldir << ", " << files.size() << " included files found:\n"; + std::copy(files.begin(), files.end(), std::ostream_iterator(std::cout, "\n")); + std::cout << '\n'; + } + } else if (tslog::enabled()) + std::cout << "could not open directory " << dname << '\n'; + } + + std::pair xml_parse(bool bus, const std::string& filename) { std::pair ret; - _ldp_timer::microsec latency; - try { - boost::property_tree::ptree pt; + if (m_parsed.insert(filename).second) + try { + boost::property_tree::ptree pt; + read_xml(filename, pt); + if (!pt.empty()) { + m_xml_policy.update(bus, pt); + ret.second = pt.get("busconfig.includedir", ""); + } + } catch(const boost::property_tree::xml_parser::xml_parser_error& ex) { + ret.first = ErrCode::error(ex.what()); + } catch(const boost::property_tree::ptree_error& ex) { + ret.first = ErrCode::error(ex.what()); + } catch(...) { + ret.first = ErrCode::error(filename + std::string(": unknown error while parsing XML")); + } - //XML file IO critical section - { - std::unique_lock lck(m_io_xml_mtx); - _ldp_timer::Timer<_ldp_timer::microsec> t(&latency); - - std::size_t hash; - if(async_xml_parsing_needed(filename, hash)) { - read_xml(filename, pt); - async_xml_hash_update(filename, hash); - } - } - - m_xml_policy.update(get_policy_bus(), pt); - - ret.second = pt.get("busconfig.includedir", ""); - - ret.first = ErrCode::ok(); - } catch(const boost::property_tree::xml_parser::xml_parser_error& ex) { - ret.first = ErrCode::error(ex.what()); - } catch(const boost::property_tree::ptree_error& ex) { - ret.first = ErrCode::error(ex.what()); - } catch(...) { - ret.first = ErrCode::error(filename + std::string(": unknown error while parsing XML")); - } - - tout << "XML processing latency: " << latency << std::endl; - return ret; - } - - std::size_t async_xml_hash(const std::string& filename) { - std::size_t seed = 0; - std::ifstream ifs(filename); - for(std::string line; getline(ifs, line); ) { - boost::hash_combine(seed, line); - } - ifs.close(); - - return seed; - } - - void async_xml_hash_update(const std::string& filename, const std::size_t hash) { - auto r = m_hashes.insert(std::pair(filename, hash)); - if(r.second == false) { - auto it = r.first; - it->second = hash; - } - } - - bool async_xml_parsing_needed(const std::string& filename, std::size_t& hash) { - bool ret = false; - hash = async_xml_hash(filename); - auto it = m_hashes.find(filename); - if(it != m_hashes.end()) { - if(hash == it->second) { - ret = false; - } else { - ret = true; - } - } else { - ret = true; - } return ret; } - }; - std::map XmlAsyncParser::m_hashes; - std::mutex XmlAsyncParser::m_io_xml_mtx; - XmlPolicy XmlAsyncParser::m_xml_policy; } //namespace #endif diff --git a/src/internal/xml_policy.hpp b/src/internal/xml_policy.hpp index 63fe956..48fa7f9 100644 --- a/src/internal/xml_policy.hpp +++ b/src/internal/xml_policy.hpp @@ -20,11 +20,17 @@ #include #include #include +#include #include "libdbuspolicy1-private.hpp" -#include "timer.hpp" #include "tslog.hpp" #include "cynara.hpp" +enum class TreeType : uint8_t { + SEND, + RECV, + OWN +}; + namespace _ldp_xml_parser { namespace { @@ -56,7 +62,6 @@ namespace _ldp_xml_parser static const size_t IDX_OWN_LENGTH = IDX_SERVICE + 1; static const size_t IDX_DEFAULT = IDX_GROUP + 1; - std::string m_bus; std::vector m_path_content; std::string m_privilege; bool m_bsend; @@ -66,9 +71,8 @@ namespace _ldp_xml_parser bool m_ballow; static size_t m_weight; - Key(const std::string& bus) - : m_bus(bus), - m_path_content(std::vector(IDX_TOTAL_LENGTH, ANY)), + Key(bool bus) + : m_path_content(std::vector(IDX_TOTAL_LENGTH, ANY)), m_bsend(false), m_brecv(false), m_bown(false), @@ -85,9 +89,8 @@ namespace _ldp_xml_parser const std::string get_path() const { std::string path = "R"; auto it_cend = m_bown ? m_path_content.cbegin() + IDX_OWN_LENGTH : m_path_content.cend(); - for(auto it = m_path_content.cbegin(); it != it_cend; ++it) { - path += (std::string(1, Key::DELIM) + *it); - } + for(auto it = m_path_content.cbegin(); it != it_cend; ++it) + (path += Key::DELIM) += *it; return path; } }; @@ -121,11 +124,10 @@ namespace _ldp_xml_parser } friend std::ostream& operator<<(std::ostream& os, const Leaf& lf) { - if(lf.m_check) { + if(lf.m_check) os << "check," << lf.m_privilege << "," << lf.m_weight; - } else { + else os << (lf.m_decision ? "true" : "false") << "," << lf.m_weight; - } return os; } @@ -138,24 +140,20 @@ namespace _ldp_xml_parser for(auto it = tokens.begin(); it != tokens.end(); ++it) { const auto it_last = std::next(tokens.begin(), size - 1); if(it == tokens.begin()) { - if(size > 2) { + if(size > 2) lf.m_check = (*it == "check") ? true : false; - } else { + else lf.m_decision = (*it == "true") ? true : false; - } - } else if(it == it_last) { + } else if(it == it_last) lf.m_weight = std::stoul(*it); - } else { - if(size > 2) { - lf.m_privilege = *it; - } - } + else if(size > 2) + lf.m_privilege = *it; } return is; } }; - static const std::string get_context_str(const CtxType& ctx_type) { + static char const *get_context_str(const CtxType& ctx_type) { switch(ctx_type) { case CtxType::DEFAULT: return "(default)"; break; case CtxType::SPECIFIC: return "(specific)"; break; @@ -165,34 +163,24 @@ namespace _ldp_xml_parser } static const std::string get_field_str(const std::string& field) { - return (field == "") ? Key::ANY : field; + return field == "" ? Key::ANY : field; } //Data obtained from XML parsing - decision trees - typedef std::map Trees_t; - std::map m_dec_trees; - std::mutex m_xml_policy_mtx; - - boost::property_tree::ptree* get_decision_tree(const std::string& bus, const std::string& tree_type) { - boost::property_tree::ptree* p_tree = NULL; - - auto it1 = m_dec_trees.find(bus); - if(it1 != m_dec_trees.end()) { - auto it2 = it1->second.find(tree_type); - if(it2 != it1->second.end()) { - p_tree = &it2->second; - } - } - return p_tree; + boost::property_tree::ptree m_dec_trees[2][3]; + + boost::property_tree::ptree &get_decision_tree(bool bus, TreeType tree_type) { + return m_dec_trees[bus][static_cast(tree_type)]; } - boost::property_tree::ptree* get_decision_tree(const Key& key) { - std::string tree_type; - if(key.m_bsend) { tree_type = "SEND"; } - else if(key.m_brecv) { tree_type = "RECV"; } - else if(key.m_bown) { tree_type = "OWN"; } + boost::property_tree::ptree* get_decision_tree(bool bus, const Key& key) { + TreeType tree_type; + if(key.m_bsend) tree_type = TreeType::SEND; + else if(key.m_brecv) tree_type = TreeType::RECV; + else if(key.m_bown) tree_type = TreeType::OWN; + else return NULL; - return get_decision_tree(key.m_bus, tree_type); + return &get_decision_tree(bus, tree_type); } void print_decision_tree(const boost::property_tree::ptree& pt, int level = 0) { @@ -202,31 +190,30 @@ namespace _ldp_xml_parser } } - void print_decision_key(const Key& key) { - if(_ldp_tslog::get_verbose()) { - std::string s = key.m_bus + " "; - if(key.m_bsend && !key.m_brecv) { s += "--> #"; } - if(!key.m_bsend && key.m_brecv) { s += "<-- #"; } - if(!key.m_bsend && !key.m_brecv && key.m_bown) { s += "OWN #"; } + void print_decision_key(bool bus, const Key& key) { + if (tslog::verbose()) { + std::string s = bus + " "; + if(key.m_bsend && !key.m_brecv) s += "--> #"; + if(!key.m_bsend && key.m_brecv) s += "<-- #"; + if(!key.m_bsend && !key.m_brecv && key.m_bown) s += "OWN #"; std::string prv = key.m_bcheck ? key.m_privilege : ""; - verbose::tout << s + std::cout << s << (key.m_bcheck ? "check " : std::to_string(key.m_ballow)) << prv << " : " << key.get_path() << " (weight: " << key.m_weight - << ")" - << std::endl; + << ")\n"; } } - void update_decision_tree(const Key& key) { + void update_decision_tree(bool bus, const Key& key) { if(!key.get_path().empty()) { - print_decision_key(key); + print_decision_key(bus, key); //update - boost::property_tree::ptree* const p_tree = get_decision_tree(key); + boost::property_tree::ptree* const p_tree = get_decision_tree(bus, key); if(p_tree) { boost::property_tree::ptree::path_type tpath(key.get_path(), Key::DELIM); p_tree->put(tpath, Leaf(key.m_ballow, key.m_bcheck, key.m_privilege, key.m_weight)); @@ -260,7 +247,7 @@ namespace _ldp_xml_parser ++key.m_weight; } else { if(attr) { - std::string data_str = (v.second.data() == "*") ? Key::ANY : v.second.data(); + std::string data_str = v.second.data() == "*" ? Key::ANY : v.second.data(); if(v.first == "context") { if(data_str == "mandatory") { key.m_path_content[Key::IDX_USER] = Key::MRY; @@ -272,20 +259,16 @@ namespace _ldp_xml_parser current_ctx = CtxType::DEFAULT; } } else if(v.first == "user") { - if(current_ctx == CtxType::SPECIFIC) { + if(current_ctx == CtxType::SPECIFIC) key.m_path_content[Key::IDX_USER] = data_str; - } } else if(v.first == "group") { - if(current_ctx == CtxType::SPECIFIC) { + if(current_ctx == CtxType::SPECIFIC) key.m_path_content[Key::IDX_GROUP] = data_str; - } } else { - if(field_has(v, "send_")) { + if(field_has(v, "send_")) key.m_bsend = true; - } - if(field_has(v, "receive_")) { + if(field_has(v, "receive_")) key.m_brecv = true; - } if(v.first == "own") { key.m_bown = true; key.m_path_content[Key::IDX_SERVICE] = data_str; @@ -294,27 +277,20 @@ namespace _ldp_xml_parser key.m_bown = true; key.m_path_content[Key::IDX_SERVICE] = data_str + "*"; } - if(field_has(v, "_destination")) { + if(field_has(v, "_destination")) key.m_path_content[Key::IDX_DEST] = data_str; - } - if(field_has(v, "_sender")) { + if(field_has(v, "_sender")) key.m_path_content[Key::IDX_SENDER] = data_str; - } - if(field_has(v, "_path")) { + if(field_has(v, "_path")) key.m_path_content[Key::IDX_PATH] = data_str; - } - if(field_has(v, "_interface")) { + if(field_has(v, "_interface")) key.m_path_content[Key::IDX_IFACE] = data_str; - } - if(field_has(v, "_member")) { + if(field_has(v, "_member")) key.m_path_content[Key::IDX_MEMBER] = data_str; - } - if(field_has(v, "_type")) { + if(field_has(v, "_type")) key.m_path_content[Key::IDX_TYPE] = data_str; - } - if(v.first == "privilege") { + if(v.first == "privilege") key.m_privilege = data_str; - } key.m_bcheck = bcheck; key.m_ballow = allden; @@ -328,14 +304,15 @@ namespace _ldp_xml_parser } void print_field(const boost::property_tree::ptree::value_type& v, int level) { - verbose::tout << ((level > 0) ? std::string((level - 1) * 8, ' ') + std::string(8, '.') : "") - << v.first - << " : " - << v.second.data() - << std::endl; + std::cout << ((level > 0) ? std::string((level - 1) * 8, ' ') + std::string(8, '.') : "") + << v.first + << " : " + << v.second.data() + << '\n'; } - void xml_traversal(const boost::property_tree::ptree& pt, + void xml_traversal(bool bus, + const boost::property_tree::ptree& pt, Key& key, CtxType& current_ctx, bool allden = false, @@ -349,20 +326,18 @@ namespace _ldp_xml_parser if(v.first == "") { continue; } update_decision_path(v, key, current_ctx, allden, bcheck, attr); - //print_field(v, level); - xml_traversal(v.second, key, current_ctx, allden, bcheck, attr, level + 1); + //if (tslog::verbose()) print_field(v, level); + xml_traversal(bus, v.second, key, current_ctx, allden, bcheck, attr, level + 1); } - if(!pt.empty() && attr && level > 1) { - update_decision_tree(key); - } - } else { - terr << "XML traversal max level reached: " << level << std::endl; - } + if(!pt.empty() && attr && level > 1) + update_decision_tree(bus, key); + } else if (tslog::enabled()) + std::cout << "XML traversal max level reached: " << level << '\n'; } void print_indexing_path(size_t idx, const std::string& path, const Leaf& leaf = Leaf(), bool empty = true) { - if(_ldp_tslog::get_verbose()) { + if (tslog::verbose()) { std::string s; if(!empty) { s = " : <"; @@ -373,72 +348,59 @@ namespace _ldp_xml_parser s += std::string(">"); } - verbose::tout << "path #" - << idx - << " : " - << path - << s - << std::endl; + std::cout << "path #" + << idx + << " : " + << path + << s + << '\n'; } } void prepare_indexing_path(const std::vector& idx_v, - const size_t pattern, + size_t pattern, const size_t usrgrp_obfuscate_order, const bool obfuscate_params, const CtxType& ctx_type, std::string& path) { - const size_t offset = Key::IDX_DEFAULT; + constexpr size_t offset = Key::IDX_DEFAULT; path = "R"; if(ctx_type == CtxType::SPECIFIC) { - switch(usrgrp_obfuscate_order) { - case 0: - path += (std::string(1, Key::DELIM) + get_field_str(idx_v[Key::IDX_USER])); - path += (std::string(1, Key::DELIM) + Key::ANY); - break; - case 1: - path += (std::string(1, Key::DELIM) + Key::ANY); - path += (std::string(1, Key::DELIM) + get_field_str(idx_v[Key::IDX_GROUP])); - break; - case 2: - path += (std::string(1, Key::DELIM) + get_field_str(idx_v[Key::IDX_USER])); - path += (std::string(1, Key::DELIM) + get_field_str(idx_v[Key::IDX_GROUP])); - break; - case 3: - default: - path += (std::string(1, Key::DELIM) + Key::ANY); - path += (std::string(1, Key::DELIM) + Key::ANY); - break; - } - } else { - for(size_t i = 0; i < offset; ++i) { - const std::string as = (ctx_type == CtxType::MANDATORY) ? Key::MRY : Key::DEF; - path += (std::string(1, Key::DELIM) + as); - } - } + path += Key::DELIM; + if (usrgrp_obfuscate_order & 1) // 1 3 + path += Key::ANY; + else + path += get_field_str(idx_v[Key::IDX_USER]); + path += Key::DELIM; + if ((usrgrp_obfuscate_order+1) & 2) // 1 2 + path += get_field_str(idx_v[Key::IDX_GROUP]); + else + path += Key::ANY; + } else + for(size_t i = 0; i < offset; ++i) + (path += Key::DELIM) += ctx_type == CtxType::MANDATORY ? Key::MRY : Key::DEF; - const size_t m = 1; const size_t n = idx_v.size() - offset; - for(size_t i = 0; i < n; ++i) { - std::string s = get_field_str(idx_v[i + offset]); + for (size_t i = 0; i < n; ++i) { path += Key::DELIM; - if(obfuscate_params && (pattern & (m << i))) { - path += Key::ANY; - } else { - path += s; - } + if (obfuscate_params && pattern & 1) + path += Key::ANY; + else + path += get_field_str(idx_v[i + offset]); + pattern >>= 1; } } ErrCode service_leaf_found(const Leaf& leaf, const std::string& label, const std::vector& idx_v) { ErrCode err; if(leaf.get_check()) { - verbose::tout << __func__ - << ": cynara check needed for privilege " << leaf.get_privilege() - << ", weight " << leaf.get_weight() - << std::endl; + if (tslog::verbose()) + std::cout << __func__ + << ": cynara check needed for privilege " << leaf.get_privilege() + << ", weight " << leaf.get_weight() + << '\n'; //cynara check try { @@ -487,14 +449,16 @@ namespace _ldp_xml_parser if(!found) { err = ErrCode::error("No path"); } } catch(...) { print_indexing_path(p, path); - verbose::tout << "Unknown exception while indexing decision tree!" << std::endl; + if (tslog::verbose()) + std::cout << "Unknown exception while indexing decision tree!\n"; if(!found) { err = ErrCode::error("Unknown err, no path"); } } } if(found) { err = service_leaf_found(leaf_found, label, idx_v); - verbose::tout << __func__ << ": returning decision #" << err.get() << " " << err.get_str() << ", weight " << leaf_found.get_weight() << std::endl; + if (tslog::verbose()) + std::cout << __func__ << ": returning decision #" << err.get() << " " << err.get_str() << ", weight " << leaf_found.get_weight() << '\n'; break; } } @@ -509,85 +473,63 @@ namespace _ldp_xml_parser const CtxType& ctx_type) { ErrCode err; - tout << "context: " << get_context_str(ctx_type) << ", indexing arguments: "; - if(_ldp_tslog::get_enable()) { std::copy(idx_v.begin(), idx_v.end(), std::ostream_iterator(std::cout, ", ")); } - tout << std::endl; + if (tslog::enabled()) { + std::cout << "context: " << get_context_str(ctx_type) << ", indexing arguments: "; + std::copy(idx_v.begin(), idx_v.end(), std::ostream_iterator(std::cout, ", ")); + std::cout << '\n'; + } //Examine policy data and make decision - _ldp_timer::microsec latency; - { - _ldp_timer::Timer<_ldp_timer::microsec> t(&latency); - err = index_decision_tree(pt, idx_v, label, obfuscate_params, ctx_type); - } + err = index_decision_tree(pt, idx_v, label, obfuscate_params, ctx_type); - tout << __func__ << ": #" << err.get() << " " << err.get_str() << " " << get_context_str(ctx_type) << std::endl; - tout << "tree indexing latency: " << latency << std::endl; + if (tslog::enabled()) + std::cout << __func__ << ": #" << err.get() << " " << err.get_str() << " " << get_context_str(ctx_type) << '\n'; return err; } - ErrCode can_do_action(const std::string& bus, - const std::string& tree_type, + ErrCode can_do_action(bool bus, + TreeType tree_type, const std::vector& idx_v, const std::string& label = "", const bool analyze_prefix = false) { - std::unique_lock lck(m_xml_policy_mtx); ErrCode err; - boost::property_tree::ptree* const p_tree = get_decision_tree(bus, tree_type); - if(p_tree) { - err = index_decision_tree_lat(*p_tree, idx_v, label, !analyze_prefix, CtxType::MANDATORY); - if(!err.is_ok()) { - err = index_decision_tree_lat(*p_tree, idx_v, label, !analyze_prefix, CtxType::SPECIFIC); - if(!err.is_ok()) { - err = index_decision_tree_lat(*p_tree, idx_v, label, !analyze_prefix, CtxType::DEFAULT); - } - } - } else { - err = ErrCode::error("Get decision tree returned NULL ptr"); - } - tout << __func__ << ": #" << err.get() << " " << err.get_str() << std::endl; + boost::property_tree::ptree const &p_tree = get_decision_tree(bus, tree_type); + err = index_decision_tree_lat(p_tree, idx_v, label, !analyze_prefix, CtxType::MANDATORY); + if(!err.is_ok()) { + err = index_decision_tree_lat(p_tree, idx_v, label, !analyze_prefix, CtxType::SPECIFIC); + if(!err.is_ok()) + err = index_decision_tree_lat(p_tree, idx_v, label, !analyze_prefix, CtxType::DEFAULT); + } + if (tslog::enabled()) + std::cout << __func__ << ": #" << err.get() << " " << err.get_str() << '\n'; return err; } public: XmlPolicy() { - Trees_t t; - t.emplace("SEND", typename Trees_t::mapped_type()); - t.emplace("RECV", typename Trees_t::mapped_type()); - t.emplace("OWN", typename Trees_t::mapped_type()); - m_dec_trees.emplace("SYSTEM", t); - m_dec_trees.emplace("SESSION", t); - } - - virtual ~XmlPolicy() {} - - void init() { - std::unique_lock lck(m_xml_policy_mtx); Key::m_weight = 0; } - void update(const std::string& bus, const boost::property_tree::ptree& pt) { - if(!pt.empty()) { - std::unique_lock lck(m_xml_policy_mtx); - const auto& children = pt.get_child(ROOT_FIELD); - for(const auto& x : children) { - if(x.first == ROOT_POLICY) { - Key key(bus); - CtxType current_ctx = CtxType::SPECIFIC; - xml_traversal(x.second, key, current_ctx); - } - } - } + void update(bool bus, const boost::property_tree::ptree& pt) { + const auto& children = pt.get_child(ROOT_FIELD); + for(const auto& x : children) { + if(x.first == ROOT_POLICY) { + Key key(bus); + CtxType current_ctx = CtxType::SPECIFIC; + xml_traversal(bus, x.second, key, current_ctx); + } + } } - ErrCode can_send_to(const std::string bus, const std::vector& idx_v, const std::string label) { - return can_do_action(bus, "SEND", idx_v, label); + ErrCode can_send_to(bool bus, const std::vector& idx_v, const std::string label) { + return can_do_action(bus, TreeType::SEND, idx_v, label); } - ErrCode can_recv_from(const std::string bus, const std::vector& idx_v, const std::string label) { - return can_do_action(bus, "RECV", idx_v, label); + ErrCode can_recv_from(bool bus, const std::vector& idx_v, const std::string label) { + return can_do_action(bus, TreeType::RECV, idx_v, label); } - ErrCode can_own_what(const std::string bus, const std::vector& idx_v) { + ErrCode can_own_what(bool bus, const std::vector& idx_v) { ErrCode err; //Evaluate own_prefix @@ -596,34 +538,29 @@ namespace _ldp_xml_parser const size_t srv_size = srv.size(); for(size_t n = 1; n <= srv_size; ++n) { const std::string sub = srv.substr(0, n) + "*"; - verbose::tout << "own_prefix: " << sub << std::endl; + if (tslog::enabled()) + std::cout << "own_prefix: " << sub << '\n'; iv.pop_back(); iv.push_back(sub); - err = can_do_action(bus, "OWN", iv, "", true); - if(err.is_ok()) { + err = can_do_action(bus, TreeType::OWN, iv, "", true); + if(err.is_ok()) break; - } } //Evaluate own - if(err.is_error()) { - err = can_do_action(bus, "OWN", idx_v); - } + if(err.is_error()) + err = can_do_action(bus, TreeType::OWN, idx_v); return err; } - void print_decision_trees() { - if(_ldp_tslog::get_verbose()) { - std::unique_lock lck(m_xml_policy_mtx); - - for(const auto& x : m_dec_trees) { - for(const auto& y : x.second) { - verbose::tout << x.first << " " << y.first << " " << (y.second.empty() ? "(empty)" : "") << std::endl; + void print_decision_trees(bool bus) { + if (tslog::verbose()) + for (unsigned i = 0; i < TABSIZE(m_dec_trees[bus]); ++i) + for(auto const& y : m_dec_trees[bus][i]) { + std::cout << i << " " << y.first << " " << (y.second.empty() ? "(empty)" : "") << '\n'; print_decision_tree(y.second); } - } - } } }; //XmlPolicy diff --git a/src/libdbuspolicy1-private.h b/src/libdbuspolicy1-private.h index 58e27bd..24c3d02 100644 --- a/src/libdbuspolicy1-private.h +++ b/src/libdbuspolicy1-private.h @@ -26,4 +26,7 @@ #define DBUSPOLICY1_EXPORT __attribute__ ((visibility("default"))) +typedef uint8_t dbus_name_len; +#define MAX_DBUS_NAME_LEN 255 + #endif diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 68f13a9..0ff7d6b 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "libdbuspolicy1-private.h" @@ -38,30 +39,30 @@ #define KDBUS_PATH_PREFIX "/sys/fs/kdbus/" #define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus" +#define KDBUS_POOL_SIZE (1024UL * 1024UL) -#define KDBUS_POOL_SIZE (16 * 1024UL * 1024UL) +#define SYSTEM_BUS 0 +#define SESSION_BUS 1 #define ALIGN8(l) (((l) + 7) & ~7) +#define ALIGNDN8(l) ((l) & ~7) #define UID_INVALID ((uid_t) -1) #define GID_INVALID ((gid_t) -1) -#define FOREACH_STRV(i,l, s, os)\ -for(\ -({\ -i=0;\ -l = strlen(s);\ -name = malloc(sizeof(char*)*(l+1));\ -strncpy(os, s, sizeof(char*)*(l+1)-1);\ -});\ -i < l;\ -i++) - -#define GET_NEXT_STR(i,s,os)\ - os = s+i;\ - for(;s[i] && s[i] != ' ';i++);\ - s[i] = 0; - +static char const *foreach_strv_advance(char const *str) { + char c; + while ((c = *str++)) + if (' ' == c) + return str; + return NULL; +} +/* iterate over STR; iterate once with "" if !STR or !*STR */ +#define FOREACH_STRV_DEFAULT(ITERLVALPTR,STR) for (\ + ITERLVALPTR = (!STR || !*STR) ? "" : STR;\ + ITERLVALPTR;\ + ITERLVALPTR = foreach_strv_advance(ITERLVALPTR)\ +) /** A process ID */ typedef unsigned long dbus_pid_t; @@ -70,159 +71,64 @@ typedef unsigned long dbus_uid_t; /** A group ID */ typedef unsigned long dbus_gid_t; -struct kcreds { - uid_t uid; - gid_t gid; - char* label; - char** names; -}; - struct kconn { int fd; uint64_t id; char *pool; -}; +} g_conn[2]; + struct udesc { - unsigned int bus_type; char user[256]; dbus_uid_t uid; char group[256]; dbus_gid_t gid; char label[256]; - struct kconn* conn; -}; - +} g_udesc; static int kdbus_open_bus(const char *path) { return open(path, O_RDWR|O_NOCTTY|O_LARGEFILE|O_CLOEXEC); } -static int kdbus_hello(struct kconn *kc, uint64_t hello_flags, uint64_t attach_flags_send, uint64_t attach_flags_recv) +static int kdbus_hello(bool bus_type, uint64_t hello_flags, uint64_t attach_flags_send, uint64_t attach_flags_recv) { - struct kdbus_cmd_hello kcmd_hello; - int r; + struct kdbus_cmd_hello cmd; + int fd = g_conn[bus_type].fd; - memset(&kcmd_hello, 0, sizeof(kcmd_hello)); - kcmd_hello.flags = hello_flags; - kcmd_hello.attach_flags_send = attach_flags_send; - kcmd_hello.attach_flags_recv = attach_flags_recv; - kcmd_hello.size = sizeof(kcmd_hello); - kcmd_hello.pool_size = KDBUS_POOL_SIZE; + cmd.size = sizeof(cmd); + cmd.flags = hello_flags; + cmd.attach_flags_send = attach_flags_send; + cmd.attach_flags_recv = attach_flags_recv; + cmd.pool_size = KDBUS_POOL_SIZE; - r = ioctl(kc->fd, KDBUS_CMD_HELLO, &kcmd_hello); - if (r < 0) + if (ioctl(fd, KDBUS_CMD_HELLO, &cmd) < 0) return -errno; - kc->id = (uint64_t)kcmd_hello.id; - kc->pool = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kc->fd, 0); - if (kc->pool == MAP_FAILED) + g_conn[bus_type].id = cmd.id; + if (MAP_FAILED == (g_conn[bus_type].pool = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0))) return -errno; return 0; } -static int kdbus_is_unique_id(const char* name) +static bool kdbus_is_unique_id(const char* name) { - return (strlen(name)>3 && name[0]==':' && isdigit(name[1]) && name[2]=='.'); + return ':' == name[0]; } -static int kdbus_get_creds_from_name(struct kconn* kc, struct kcreds* kcr, const char* name) +static uint64_t kdbus_unique_id(char const *name) { - unsigned long long int unique_id; - struct kdbus_cmd_info* cmd; - struct kdbus_info* conn_info; - struct kdbus_item *item; - char** tmp_names; - int j, r, l, counter; - unsigned int size; - - counter = 0; - kcr->names = calloc(counter+1, sizeof(char *)); - - kcr->uid = UID_INVALID; - kcr->gid = GID_INVALID; - kcr->label = NULL; - - if (kdbus_is_unique_id(name)) { - l = sizeof(unique_id); - unique_id = strtoull(name+3, NULL, 10); - size = sizeof(struct kdbus_cmd_info); - cmd = aligned_alloc(8, size); - memset(cmd, 0, sizeof(struct kdbus_cmd_info)); - cmd->id = unique_id; - cmd->size = size; - cmd->attach_flags = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_SECLABEL | KDBUS_ATTACH_NAMES; - } else { - l = strlen(name) + 1; - size = offsetof(struct kdbus_cmd_info, items) + ALIGN8((l) + offsetof(struct kdbus_item, data)); - cmd = aligned_alloc(8, size); - memset(cmd, 0, sizeof(struct kdbus_cmd_info)); - cmd->items[0].size = l + offsetof(struct kdbus_item, data); - cmd->items[0].type = KDBUS_ITEM_NAME; - memcpy(cmd->items[0].str, name, l); - cmd->size = size; - cmd->attach_flags = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_SECLABEL | KDBUS_ATTACH_NAMES; - } - - r = ioctl(kc->fd, KDBUS_CMD_CONN_INFO, cmd); - if (r < 0) - return -errno; - - conn_info = (struct kdbus_info *) ((uint8_t *) kc->pool + cmd->offset); - - for(item = conn_info->items; - ((uint8_t *)(item) < (uint8_t *)(conn_info) + (conn_info)->size) && - ((uint8_t *) item >= (uint8_t *) conn_info); - item = ((typeof(item))(((uint8_t *)item) + ALIGN8((item)->size))) ) - { - switch (item->type) - { - case KDBUS_ITEM_CREDS: - if (item->creds.euid != UID_INVALID) - { - kcr->uid = (uid_t) item->creds.euid; - } - if (item->creds.egid != GID_INVALID) - { - kcr->gid = (gid_t) item->creds.egid; - } - break; - case KDBUS_ITEM_SECLABEL: - kcr->label = strdup(item->str); - break; - case KDBUS_ITEM_OWNED_NAME: - counter++; - tmp_names = calloc(counter+1, sizeof(char*)); - for (j = 0;kcr->names[j]; j++) - { - tmp_names[j] = kcr->names[j]; - } - tmp_names[j] = strdup(item->name.name); - free(kcr->names); - kcr->names = tmp_names; - break; - } - } - - return 0; -} - -static void kcreds_free(struct kcreds* kcr) -{ - int i = 0; - if (kcr == NULL) - return; - - free(kcr->label); - for (i=0; kcr->names[i];i++) - free(kcr->names[i]); - free(kcr->names[i]); - free(kcr->names); - free(kcr); + uint64_t res; + unsigned i = 2; + int c; + while (!(c = name[++i] - '0')); + res = c; + while ((c = (int)(name[++i]) - '0') > 0) + res = res*10 + c; + return res; } -static int dbuspolicy_init_udesc(struct kconn* kc, unsigned int bus_type, struct udesc* p_udesc) +static bool dbuspolicy_init_once(void) { struct passwd pwent; struct passwd *pwd; @@ -239,30 +145,28 @@ static int dbuspolicy_init_udesc(struct kconn* kc, unsigned int bus_type, struct close(attr_fd); - if (r < 0 || r >= (long int)sizeof(p_udesc->label)) /* read */ - return -1; - - snprintf(p_udesc->label, r + 1 /* additional byte for \0 */, "%s", buf); + if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */ + return true; - p_udesc->uid = getuid(); - p_udesc->gid = getgid(); + snprintf(g_udesc.label, r + 1 /* additional byte for \0 */, "%s", buf); + if (getpwuid_r(g_udesc.uid, &pwent, buf, sizeof(buf), &pwd)) + return true; - if (getpwuid_r(p_udesc->uid, &pwent, buf, sizeof(buf), &pwd)) - return -1; - - if (getgrgid_r(p_udesc->gid, &grent, buf, sizeof(buf), &gg)) - return -1; + if (getgrgid_r(g_udesc.gid, &grent, buf, sizeof(buf), &gg)) + return true; if (!pwd || !gg) return -1; - snprintf(p_udesc->user, sizeof(p_udesc->user), "%s", pwd->pw_name); - snprintf(p_udesc->group, sizeof(p_udesc->group), "%s", gg->gr_name); + snprintf(g_udesc.user, sizeof(g_udesc.user), "%s", pwd->pw_name); + snprintf(g_udesc.group, sizeof(g_udesc.group), "%s", gg->gr_name); - p_udesc->bus_type = bus_type; - p_udesc->conn = kc; + g_udesc.uid = getuid(); + g_udesc.gid = getgid(); - return 0; + __internal_init_once(); + + return false; } static int bus_path_resolve(const char *bus_path, char *resolved_path, unsigned resolved_path_size, unsigned int *bus_type) @@ -296,62 +200,62 @@ static int bus_path_resolve(const char *bus_path, char *resolved_path, unsigned return 0; } +static bool init_once_done = false; + DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) { - uint64_t hello_flags = 0; - uint64_t attach_flags_send = _KDBUS_ATTACH_ANY; - uint64_t attach_flags_recv = _KDBUS_ATTACH_ALL; - struct kconn* kc = NULL; - struct udesc* p_udesc = NULL; - unsigned int bus_type = -1; - char resolved_path[PATH_MAX] = { 0 }; - - if (bus_path_resolve(bus_path, resolved_path, sizeof(resolved_path), &bus_type) < 0) - goto err; - - kc = (struct kconn*) calloc(1, sizeof(struct kconn)); - if (!kc) - goto err; - - if ((kc->fd = kdbus_open_bus(resolved_path)) < 0) - goto err; - - if (kdbus_hello(kc, hello_flags, attach_flags_send, attach_flags_recv) < 0) - goto err; - - if (__internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_PRIMARY : SESSION_BUS_CONF_FILE_PRIMARY) < 0 - && __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_SECONDARY : SESSION_BUS_CONF_FILE_SECONDARY) < 0) - goto err; - - p_udesc = (struct udesc*)malloc(sizeof(struct udesc)); - if (!p_udesc) - goto err; - - if (dbuspolicy_init_udesc(kc, bus_type, p_udesc) < 0) - goto err; - - return p_udesc; - + unsigned int bus_type = -1; + char resolved_path[PATH_MAX] = { 0 }; + int rp, rs; + bool rb; + + _Static_assert(SYSTEM_BUS == 0, "SYSTEM_BUS not 0"); + _Static_assert(SESSION_BUS == 1, "SESSION_BUS not 0"); + + if (bus_path_resolve(bus_path, resolved_path, sizeof(resolved_path), &bus_type) < 0) + return NULL; + + if (bus_type) + bus_type = SESSION_BUS; + + rb = false; + pthread_mutex_lock(&g_mutex); + if (!init_once_done) { + init_once_done = true; + rb = dbuspolicy_init_once(); + } + pthread_mutex_unlock(&g_mutex); + if (rb) + goto err_close; + + if ((g_conn[bus_type].fd = kdbus_open_bus(resolved_path)) < 0) + goto err; + + if (kdbus_hello(bus_type, 0, _KDBUS_ATTACH_ALL, 0) < 0) + goto err_close; + + rp = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_PRIMARY : SESSION_BUS_CONF_FILE_PRIMARY); + rs = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_SECONDARY : SESSION_BUS_CONF_FILE_SECONDARY); + __internal_init_flush_logs(); + if ((rp & rs) < 0) /* when both negative */ + goto err_close; + + return &g_conn[bus_type]; + +err_close: + close(g_conn[bus_type].fd); err: - if (kc && kc->fd != -1) - close(kc->fd); - free(kc); - free(p_udesc); - - return NULL; + return NULL; } DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) { - struct udesc* p_udesc = (struct udesc*)configuration; - if(p_udesc) { - close(p_udesc->conn->fd); - free(p_udesc->conn); - free(p_udesc); - p_udesc = NULL; - } + if (configuration) + close(((typeof(&g_conn[0]))configuration)->fd); } +static bool configuration_bus_type(struct kconn const *configuration) { return configuration != g_conn; } + /** * dbuspolicy1_can_send * @param: <> @@ -370,62 +274,103 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, int reply_serial, int requested_reply) { - struct udesc* const p_udesc = (struct udesc*)configuration; - int i, rs, rr, l, r = 0; - struct kcreds* p_creds = NULL; - char gid[25], uid[25]; - char* name = NULL; - char empty_names = 1; - - rs = 0; - rr = 1; - - if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL || (destination != NULL && *destination != '\0') ) { - p_creds = calloc(1, sizeof(struct kcreds)); - r = kdbus_get_creds_from_name(p_udesc->conn, p_creds, destination); - if(r < 0) { - kcreds_free(p_creds); - return 0; - } - - snprintf(uid, 24, "%lu", (unsigned long int)p_creds->uid); - snprintf(gid, 24, "%lu", (unsigned long int)p_creds->gid); - if (!p_creds->names[0]) - empty_names = 0; - - for (i=0;p_creds->names[i];i++) - { - rs = __internal_can_send(p_udesc->bus_type, p_udesc->user, p_udesc->group, p_udesc->label, p_creds->names[i], path, interface, member, message_type); - if (rs > 0) - break; - } - } + char const *label = NULL; + int r; + uid_t uid_n = UID_INVALID; + gid_t gid_n = GID_INVALID; + bool free_offset = false; + bool empty_names = true; + bool bus_type = configuration_bus_type(configuration); + union { + struct kdbus_cmd_info cmd_info; + struct kdbus_cmd_free cmd_free; + uint8_t _buffer_[sizeof(struct kdbus_cmd_info) + offsetof(struct kdbus_item, data) + ALIGN8(MAX_DBUS_NAME_LEN+1)]; + } cmd; + + __internal_enter(); + + if (DBUSPOLICY_MESSAGE_TYPE_SIGNAL != message_type || (destination && *destination)) { + struct kdbus_info *conn_info; + struct kdbus_item *item; + uintptr_t items_end; + + cmd.cmd_info.flags = 0; + cmd.cmd_info.attach_flags = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_NAMES | (DBUSPOLICY_MESSAGE_TYPE_SIGNAL != message_type ? KDBUS_ATTACH_SECLABEL : 0); + + if (kdbus_is_unique_id(destination)) { + cmd.cmd_info.size = sizeof(cmd.cmd_info); + cmd.cmd_info.id = kdbus_unique_id(destination); + } else { + int l = strlen(destination); + cmd.cmd_info.size = sizeof(struct kdbus_cmd_info) + offsetof(struct kdbus_item, data) + ALIGN8(l+1); + cmd.cmd_info.id = 0; + cmd.cmd_info.items->size = offsetof(struct kdbus_item, data) + l+1; + cmd.cmd_info.items->type = KDBUS_ITEM_NAME; + *(uint64_t*)ALIGNDN8((uintptr_t)cmd.cmd_info.items->str + l) = 0; /* trailing zero + padding */ + memcpy(cmd.cmd_info.items->str, destination, l); + } + + r = ioctl(g_conn[bus_type].fd, KDBUS_CMD_CONN_INFO, &cmd.cmd_info); + if (r < 0) { + r = -errno; + goto end; + } + + cmd.cmd_free.size = sizeof(cmd.cmd_free); + /* flags already 0 */ + _Static_assert(sizeof(cmd.cmd_info.flags) == sizeof(cmd.cmd_free.flags), "cmd_info/cmd_free: flag sizeof differs"); + _Static_assert(offsetof(typeof(cmd.cmd_info), flags) == offsetof(typeof(cmd.cmd_free), flags), "cmd_info/cmd_free: flag offsetof differs"); + cmd.cmd_free.offset = cmd.cmd_info.offset; + + free_offset = true; + + conn_info = (struct kdbus_info *) ((uint8_t *) g_conn[bus_type].pool + cmd.cmd_info.offset); + items_end = (uintptr_t)conn_info + (unsigned)conn_info->size; + + _Static_assert((unsigned)KDBUS_ITEM_CREDS == KDBUS_ITEM_CREDS, "KDBUS_ITEM_CREDS not preserved when cast to unsigned"); + _Static_assert((unsigned)KDBUS_ITEM_SECLABEL == KDBUS_ITEM_SECLABEL, "KDBUS_ITEM_SECLABEL not preserved when cast to unsigned"); + _Static_assert((unsigned)KDBUS_ITEM_OWNED_NAME == KDBUS_ITEM_OWNED_NAME, "KDBUS_ITEM_OWNED_NAME not preserved when cast to unsigned"); + + for (item = conn_info->items; (uintptr_t)item < items_end; item = (typeof(item))ALIGN8((uintptr_t)item + (unsigned)item->size)) + switch ((unsigned)item->type) + { + case KDBUS_ITEM_CREDS: + uid_n = item->creds.euid; + gid_n = item->creds.egid; + break; + case KDBUS_ITEM_SECLABEL: + label = item->str; + break; + case KDBUS_ITEM_OWNED_NAME: + empty_names = false; + if (r <= 0) + r = __internal_can_send(bus_type, g_udesc.user, g_udesc.group, g_udesc.label, item->name.name, path, interface, member, message_type); + break; + } + } if (empty_names) - rs = __internal_can_send(p_udesc->bus_type, p_udesc->user, p_udesc->group, p_udesc->label, destination, path, interface, member, message_type); - - if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { - rr = 0; - - if (!sender || !(*sender)) - rr = __internal_can_recv(p_udesc->bus_type, uid, gid, p_creds->label, sender, path, interface, member, message_type); - else - FOREACH_STRV(i, l, sender, name) { - char* source; - GET_NEXT_STR(i, name, source); - rr = __internal_can_recv(p_udesc->bus_type, uid, gid, p_creds->label, source, path, interface, member, message_type); - if (rr > 0) - break; - } + r = __internal_can_send(bus_type, g_udesc.user, g_udesc.group, g_udesc.label, destination, path, interface, member, message_type); + + if (r > 0 && message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { + char gid[25], uid[25]; + char const *ptr; + snprintf(uid, sizeof(uid), "%lu", (unsigned long)uid_n); + snprintf(gid, sizeof(gid), "%lu", (unsigned long)gid_n); + + FOREACH_STRV_DEFAULT(ptr, sender) + if (0 < (r = __internal_can_recv(bus_type, uid, gid, label, ptr, path, interface, member, message_type))) + break; } - free(name); - kcreds_free(p_creds); + if (free_offset) + ioctl(g_conn[bus_type].fd, KDBUS_CMD_FREE, &cmd.cmd_free); - if(rs > 0 && rr > 0) { r = 1; } - if(rs < 0 || rr < 0) { r = -1; } +end: + __internal_exit(); return r; } + /** * dbuspolicy1_can_send * @param: <> @@ -447,55 +392,29 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, int reply_serial, int requested_reply) { - struct udesc* const p_udesc = (struct udesc*)configuration; - int i, rs, rr, l, r = 0; - struct kcreds* p_creds = NULL; + char const *ptr; + int r; char gid[25], uid[25]; - char* name = NULL; - - rs = 0; - rr = 1; - - snprintf(uid, 24, "%lu", (unsigned long int)sender_uid); - snprintf(gid, 24, "%lu", (unsigned long int)sender_gid); - - if (!destination || !(*destination)) - rs = __internal_can_send(p_udesc->bus_type, uid, gid, sender_label, destination, path, interface, member, message_type); - else - FOREACH_STRV(i, l, destination, name) { - char* dest; - GET_NEXT_STR(i, name, dest); - - rs = __internal_can_send(p_udesc->bus_type, uid, gid, sender_label, dest, path, interface, member, message_type); - if (rs > 0) - break; - } - free(name); - name = NULL; - - if(message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { - rr = 0; - - if (!sender || !(*sender)) - rr = __internal_can_recv(p_udesc->bus_type, p_udesc->user, p_udesc->group, p_udesc->label, sender, path, interface, member, message_type); - else - FOREACH_STRV(i, l, sender, name) { - char* source; - GET_NEXT_STR(i, name, source); - rr = __internal_can_recv(p_udesc->bus_type, p_udesc->user, p_udesc->group, p_udesc->label, source, path, interface, member, message_type); - if(rr > 0) - break; - } - free(name); - } - kcreds_free(p_creds); + bool bus_type = configuration_bus_type(configuration); + + snprintf(uid, sizeof(uid), "%lu", (unsigned long)sender_uid); + snprintf(gid, sizeof(gid), "%lu", (unsigned long)sender_gid); + + __internal_enter(); - if(rs > 0 && rr > 0) { r = 1; } - if(rs < 0 || rr < 0) { r = -1; } + FOREACH_STRV_DEFAULT(ptr, destination) + if (0 < (r = __internal_can_send(bus_type, uid, gid, sender_label, ptr, path, interface, member, message_type))) + break; + + if (r > 0 && message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) + FOREACH_STRV_DEFAULT(ptr, sender) + if (0 < (r = __internal_can_recv(bus_type, g_udesc.user, g_udesc.group, g_udesc.label, ptr, path, interface, member, message_type))) + break; + + __internal_exit(); return r; } - /** * dbuspolicy1_can_send * @param: <> @@ -505,6 +424,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, **/ DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* const service) { - struct udesc* const p_udesc = (struct udesc*)configuration; - return __internal_can_own(p_udesc->bus_type, p_udesc->user, p_udesc->group, service); + int r; + bool bus_type = configuration_bus_type(configuration); + __internal_enter(); + r = __internal_can_own(bus_type, g_udesc.user, g_udesc.group, service); + __internal_exit(); + return r; } -- 2.7.4 From 62b1c6efb1952ccdd416433f3dbb1c30cce1c51b Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Fri, 27 May 2016 11:24:06 +0200 Subject: [PATCH 05/16] Allow incremental build Change-Id: Id8c02912d1ddf0d3a86bb5e5f999a1dbce035943 --- packaging/libdbuspolicy.spec | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index 591b048..3234296 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -28,11 +28,7 @@ development files. cp %{SOURCE1001} . %build -./autogen.sh -./configure \ - --libdir=%{_libdir} \ - --prefix=/usr - +%reconfigure --libdir=%{_libdir} --prefix=/usr make %install -- 2.7.4 From 32bc86464494593a4676cf4548f5ac845bb5269e Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Fri, 20 May 2016 13:15:10 +0200 Subject: [PATCH 06/16] Tree policy engine decision checker replacement Tree policy engine decision checker was replaced by naive search algorithm. For each check call, libdbuspolicy iterate via policy rules in the reverse order. First rule that matches request is used to return decision. Multiple sender's and receiver's names are proceeded during search procedure (algorithm try to match current rule for each name). Previous version search all database for each name. Added unit tests (make check) Change-Id: Ie78ae8eec285a7042d275d02333372bca4d76d28 --- Makefile.am | 51 +++- configure.ac | 7 + packaging/libdbuspolicy.spec | 6 +- src/dbuspolicy1/libdbuspolicy1.h | 4 +- src/internal/cynara.cpp | 72 +++++ src/internal/cynara.hpp | 86 ++---- src/internal/cynara_mockup.cpp | 27 ++ src/internal/internal.cpp | 98 ++++--- src/internal/internal.h | 54 ++-- src/internal/naive_policy_checker.cpp | 144 ++++++++++ src/internal/naive_policy_checker.hpp | 61 ++++ src/internal/naive_policy_db.cpp | 145 ++++++++++ src/internal/naive_policy_db.hpp | 86 ++++++ src/internal/policy.cpp | 528 ++++++++++++++++++++++++++++++++++ src/internal/policy.hpp | 194 +++++++++++++ src/internal/tslog.cpp | 17 ++ src/internal/tslog.hpp | 14 +- src/internal/xml_parser.cpp | 3 + src/internal/xml_parser.hpp | 48 +--- src/libdbuspolicy1.c | 92 +++--- src/libdbuspolicy1.sym | 11 +- src/test-libdbuspolicy1-method.cpp | 82 ++++++ src/test-libdbuspolicy1-ownership.cpp | 71 +++++ src/test-libdbuspolicy1-signal.cpp | 51 ++++ tests/system.conf | 83 ++++++ tests/system.d/cynara.test.conf | 10 + tests/system.d/methods.test.conf | 41 +++ tests/system.d/ownerships.test.conf | 35 +++ tests/system.d/signals.test.conf | 13 + 29 files changed, 1891 insertions(+), 243 deletions(-) create mode 100644 src/internal/cynara.cpp create mode 100644 src/internal/cynara_mockup.cpp create mode 100644 src/internal/naive_policy_checker.cpp create mode 100644 src/internal/naive_policy_checker.hpp create mode 100644 src/internal/naive_policy_db.cpp create mode 100644 src/internal/naive_policy_db.hpp create mode 100644 src/internal/policy.cpp create mode 100644 src/internal/policy.hpp create mode 100644 src/internal/tslog.cpp create mode 100644 src/internal/xml_parser.cpp create mode 100644 src/test-libdbuspolicy1-method.cpp create mode 100644 src/test-libdbuspolicy1-ownership.cpp create mode 100644 src/test-libdbuspolicy1-signal.cpp create mode 100644 tests/system.conf create mode 100644 tests/system.d/cynara.test.conf create mode 100644 tests/system.d/methods.test.conf create mode 100644 tests/system.d/ownerships.test.conf create mode 100644 tests/system.d/signals.test.conf diff --git a/Makefile.am b/Makefile.am index d457aaa..12f16c5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,9 +20,9 @@ AM_CFLAGS = ${my_CFLAGS} \ AM_LDFLAGS = \ -Wl,--gc-sections \ -Wl,--as-needed \ - $(CYNARA_CFLAGS) \ -$(CYNARA_LIBS)\ - -pthread + $(CYNARA_CFLAGS) \ + $(CYNARA_LIBS)\ + -pthread SED_PROCESS = \ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(SED) \ @@ -46,7 +46,13 @@ lib_LTLIBRARIES = src/libdbuspolicy1.la src_libdbuspolicy1_la_SOURCES =\ src/libdbuspolicy1-private.h \ src/libdbuspolicy1.c \ - src/internal/internal.cpp + src/internal/internal.cpp \ + src/internal/naive_policy_checker.cpp \ + src/internal/naive_policy_db.cpp \ + src/internal/policy.cpp \ + src/internal/xml_parser.cpp \ + src/internal/tslog.cpp \ + src/internal/cynara.cpp EXTRA_DIST += src/libdbuspolicy1.sym @@ -61,8 +67,37 @@ pkgconfig_DATA = src/libdbuspolicy1.pc EXTRA_DIST += src/libdbuspolicy1.pc.in CLEANFILES += src/libdbuspolicy1.pc -TESTS = src/test-libdbuspolicy1 +TESTS = src/test-libdbuspolicy1-ownership \ + src/test-libdbuspolicy1-signal \ + src/test-libdbuspolicy1-method + +check_PROGRAMS = src/test-libdbuspolicy1-ownership \ + src/test-libdbuspolicy1-signal \ + src/test-libdbuspolicy1-method + +src_test_libdbuspolicy1_ownership_SOURCES = src/test-libdbuspolicy1-ownership.cpp +src_test_libdbuspolicy1_signal_SOURCES = src/test-libdbuspolicy1-signal.cpp +src_test_libdbuspolicy1_method_SOURCES = src/test-libdbuspolicy1-method.cpp + +noinst_LTLIBRARIES = src/libinternal.a +src_libinternal_a_SOURCES =\ + src/libdbuspolicy1-private.h \ + src/internal/internal.cpp \ + src/libdbuspolicy1.c \ + src/internal/naive_policy_checker.cpp \ + src/internal/naive_policy_db.cpp \ + src/internal/policy.cpp \ + src/internal/xml_parser.cpp \ + src/internal/tslog.cpp \ + src/internal/cynara_mockup.cpp + +libinternal_a_LIBADD = $(CYNARA_LIBS) + +src_test_libdbuspolicy1_ownership_LDADD = $(CYNARA_LIBS) \ + src/libinternal.a + +src_test_libdbuspolicy1_signal_LDADD = $(CYNARA_LIBS) \ + src/libinternal.a -check_PROGRAMS = src/test-libdbuspolicy1 -src_test_libdbuspolicy1_SOURCES = src/test-libdbuspolicy1.c -src_test_libdbuspolicy1_LDADD = src/libdbuspolicy1.la $(CYNARA_LIBS) +src_test_libdbuspolicy1_method_LDADD = $(CYNARA_LIBS) \ + src/libinternal.a diff --git a/configure.ac b/configure.ac index 440b0c2..8e9a190 100644 --- a/configure.ac +++ b/configure.ac @@ -47,6 +47,13 @@ AS_IF([test "x$enable_debug" = "xyes"], [ AC_DEFINE(ENABLE_DEBUG, [1], [Debug messages.]) ]) +AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests], [Add API function that allows to change credentials during execution]), + [with_tests=yes], + with_tests=no) +if test "x$with_tests" = "xyes"; then + AC_DEFINE(LIBDBUSPOLICY_TESTS_API, 1, [Define if tests are enabled]) +fi + AC_CHECK_FUNCS([ \ __secure_getenv \ secure_getenv\ diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index 3234296..9713e86 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -28,8 +28,12 @@ development files. cp %{SOURCE1001} . %build -%reconfigure --libdir=%{_libdir} --prefix=/usr +%reconfigure --libdir=%{_libdir} --prefix=/usr \ +%if 0%{?test_version} +--enable-tests +%endif make +make check %install make DESTDIR=%{buildroot} install diff --git a/src/dbuspolicy1/libdbuspolicy1.h b/src/dbuspolicy1/libdbuspolicy1.h index ae9b0c2..cc0040e 100644 --- a/src/dbuspolicy1/libdbuspolicy1.h +++ b/src/dbuspolicy1/libdbuspolicy1.h @@ -26,8 +26,8 @@ extern "C" { #define SYSTEM_BUS_CONF_FILE_PRIMARY "/usr/share/dbus-1/system.conf" #define SESSION_BUS_CONF_FILE_PRIMARY "/usr/share/dbus-1/session.conf" -#define SYSTEM_BUS_CONF_FILE_SECONDARY "/etc/dbus-1/system-local.conf" -#define SESSION_BUS_CONF_FILE_SECONDARY "/etc/dbus-1/session-local.conf" +#define SYSTEM_BUS_CONF_FILE_SECONDARY "/etc/dbus-1/system.conf" +#define SESSION_BUS_CONF_FILE_SECONDARY "/etc/dbus-1/session.conf" /** used when check policy for message prepared to send */ #define DBUSPOLICY_DIRECTION_SENDING 0 diff --git a/src/internal/cynara.cpp b/src/internal/cynara.cpp new file mode 100644 index 0000000..ce191c0 --- /dev/null +++ b/src/internal/cynara.cpp @@ -0,0 +1,72 @@ +#include "cynara.hpp" +#include "libdbuspolicy1-private.hpp" +#include +#include +#include +#include + +using namespace _ldp_cynara; + +pthread_mutex_t Cynara::__mutex = PTHREAD_MUTEX_INITIALIZER; + +Cynara::Cynara() : __inited(false) { +} + +Cynara::~Cynara() { + int r = cynara_finish(__cynara); + if (r != CYNARA_API_SUCCESS) { + //TODO: reaction + //destructor is usually called when proccess is closed + //there is no good way to serve this case. + } +} + +bool Cynara::init() { + if (!__inited) { + int r = cynara_initialize(&__cynara, NULL); + if (r != CYNARA_API_SUCCESS) + return false; + + __session = cynara_session_from_pid(getpid()); + __inited = true; + } + return true; +} + +Cynara& Cynara::getInstance() { + static Cynara __self; + return __self; +} + +CynaraResult Cynara::check(const char* label, const char* privilege, const char* uid) { + + const char* _label=""; + const char* _uid=""; + const char* _privilege=""; + CynaraResult ret; + + if (label) + _label=label; + + if (privilege) + _privilege=privilege; + + if (uid) + _uid=uid; + + pthread_mutex_lock(&__mutex); + Cynara& c = Cynara::getInstance(); + if (!c.init()) + ret = CynaraResult::ERROR_INIT; + else { + int r = cynara_check (c.__cynara, _label, c.__session, _uid, _privilege); + if (r == CYNARA_API_ACCESS_ALLOWED) + ret = CynaraResult::ALLOW; + else if (r == CYNARA_API_ACCESS_DENIED) + ret = CynaraResult::DENY; + else + ret = CynaraResult::ERROR_CHECK; + } + pthread_mutex_unlock(&__mutex); + return ret; +} diff --git a/src/internal/cynara.hpp b/src/internal/cynara.hpp index 7f74f35..684e2a9 100644 --- a/src/internal/cynara.hpp +++ b/src/internal/cynara.hpp @@ -19,73 +19,31 @@ #include #include +#include + +#include namespace _ldp_cynara { + enum class CynaraResult : uint8_t { + ALLOW, + DENY, + ERROR_CHECK, + ERROR_INIT + }; class Cynara { - private: - cynara* __cynara; - std::string __session; - - Cynara() { - int r = cynara_initialize(&__cynara, NULL); - if (r != CYNARA_API_SUCCESS) - throw std::runtime_error("Cynara initialization failed"); - - __session = cynara_session_from_pid(getpid()); - } - - ~Cynara() { - int r = cynara_finish(__cynara); - if (r != CYNARA_API_SUCCESS) { - //TODO: reaction - } - } - - static Cynara& get_instance() { - static Cynara __self; - return __self; - } - - public: - static std::string get_session() { - Cynara& c = Cynara::get_instance(); - c.__session = cynara_session_from_pid(getpid()); - return c.__session; - } - - static bool check(std::string label, std::string privilege, std::string uid, std::string session = "") { - Cynara& c = Cynara::get_instance(); - const char* _label=""; - const char* _session=""; - const char* _uid=""; - const char* _privilege=""; - - /** - workaround. C-str() returns wrong pointer to str - when std::string == "" - */ - if (!label.empty()) - _label=label.c_str(); - - if (session == "") - session = c.__session; - if (!session.empty()) - _session=session.c_str(); - - if (!privilege.empty()) - _privilege=privilege.c_str(); - - if (!uid.empty()) - _uid=uid.c_str(); - - int r = cynara_check (c.__cynara, _label, _session, _uid, _privilege); - if (r == CYNARA_API_ACCESS_ALLOWED) - return true; - else if (r == CYNARA_API_ACCESS_DENIED) - return false; - else - throw std::runtime_error("Cynara check failed"); - } + private: + static pthread_mutex_t __mutex; + cynara* __cynara; + const char* __session; + bool __inited; + Cynara(); + ~Cynara(); + + bool init(); + static Cynara& getInstance(); + public: + + static CynaraResult check(const char* label, const char* privilege, const char* uid); }; } //namespace #endif diff --git a/src/internal/cynara_mockup.cpp b/src/internal/cynara_mockup.cpp new file mode 100644 index 0000000..4392df2 --- /dev/null +++ b/src/internal/cynara_mockup.cpp @@ -0,0 +1,27 @@ +#include "cynara.hpp" +#include "libdbuspolicy1-private.hpp" +#include +#include +#include + +using namespace _ldp_cynara; + +Cynara::Cynara() { +} + +Cynara::~Cynara() { +} + +bool Cynara::init() { + return true; +} + +Cynara& Cynara::getInstance() { + static Cynara __self; + return __self; +} + + +CynaraResult Cynara::check(const char* label, const char* privilege, const char* uid) { + return CynaraResult::ALLOW; +} diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index e26c510..2b030fc 100644 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -18,40 +18,45 @@ #include #include #include "xml_parser.hpp" +#include "policy.hpp" +#include "naive_policy_checker.hpp" +#include "internal.h" -#ifdef __cplusplus -extern "C" { -#endif +#include "../libdbuspolicy1-private.h" + +static _ldp_xml_parser::NaivePolicyChecker policy_checker; static const char* get_str(const char* const szstr) { return (szstr != NULL) ? szstr : ""; } -static std::string get_strv(const char *s) { - unsigned i = 0; +static const char** get_strv(const char *s, const char** result) { + int i = 0; + unsigned k = 0; if (s) { - i = -1; - char c; - while ((c = s[++i]) && ' ' != c); + while (s[i] && k < KDBUS_CONN_MAX_NAMES + 1) { + char c; + while ((c = s[i++]) && ' ' != c); + result[k++] = s; + s += i; + i = 0; + } + if (k >= KDBUS_CONN_MAX_NAMES + 1) + return NULL; + if (k) + result[k++] = NULL; } - return std::string{s, i}; -} - -static const char* get_message_type(int type) { - const char* sztype; - switch(type) { - case DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL: sztype = "method_call"; break; - case DBUSPOLICY_MESSAGE_TYPE_METHOD_RETURN: sztype = "method_return"; break; - case DBUSPOLICY_MESSAGE_TYPE_ERROR: sztype = "error"; break; - case DBUSPOLICY_MESSAGE_TYPE_SIGNAL: sztype = "signal"; break; - default: sztype = ""; break; - } - return sztype; + if (!k) { + result[0] = ""; + result[1] = NULL; + } + return result; } int __internal_init(bool bus_type, const char* const config_name) { _ldp_xml_parser::XmlParser p; + p.registerAdapter(policy_checker.generateAdapter()); auto err = p.parse_policy(bus_type, get_str(config_name)); return err.get(); } @@ -84,8 +89,8 @@ void __internal_exit() } int __internal_can_send(bool bus_type, - const char* const user, - const char* const group, + const uid_t user, + const gid_t group, const char* const label, const char* const destination, const char* const path, @@ -93,14 +98,32 @@ int __internal_can_send(bool bus_type, const char* const member, int type) { - _ldp_xml_parser::XmlParser p; - auto err = p.can_send(bus_type, get_str(user), get_str(group), get_str(label), get_strv(destination), get_str(path), get_str(interface), get_str(member), get_message_type(type)); - return err.get(); + const char* names[KDBUS_CONN_MAX_NAMES+1]; + const char** ns = get_strv(destination, names); + if (!ns) { + if (tslog::verbose()) + std::cout << "Destination too long: "<(type), _ldp_xml_parser::MessageDirection::SEND); +} + +int __internal_can_send_multi_dest(bool bus_type, + const uid_t user, + const gid_t group, + const char* const label, + const char** const destination, + const char* const path, + const char* const interface, + const char* const member, + int type) +{ + return policy_checker.check(bus_type, user, group, label, destination, interface, member, path, static_cast<_ldp_xml_parser::MessageType>(type), _ldp_xml_parser::MessageDirection::SEND); } int __internal_can_recv(bool bus_type, - const char* const user, - const char* const group, + const uid_t user, + const gid_t group, const char* const label, const char* const sender, const char* const path, @@ -108,21 +131,16 @@ int __internal_can_recv(bool bus_type, const char* const member, int type) { - _ldp_xml_parser::XmlParser p; - auto err = p.can_recv(bus_type, get_str(user), get_str(group), get_str(label), get_strv(sender), get_str(path), get_str(interface), get_str(member), get_message_type(type)); - return err.get(); + const char* names[KDBUS_CONN_MAX_NAMES+1]; + const char** ns = get_strv(sender, names); + return policy_checker.check(bus_type, user, group, label, ns, interface, member, path, static_cast<_ldp_xml_parser::MessageType>(type), _ldp_xml_parser::MessageDirection::RECEIVE); } int __internal_can_own(bool bus_type, - const char* const user, - const char* const group, + const uid_t user, + const gid_t group, + const char* const label, const char* const service) { - _ldp_xml_parser::XmlParser p; - auto err = p.can_own(bus_type, get_str(user), get_str(group), get_str(service)); - return err.get(); + return policy_checker.check(bus_type, user, group, label, service); } - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/src/internal/internal.h b/src/internal/internal.h index 0914abe..270b13a 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -21,7 +21,9 @@ extern "C" { #endif -int __internal_init(unsigned int bus_type, const char* const config_name); +#define KDBUS_CONN_MAX_NAMES 256 + +int __internal_init(bool bus_type, const char* const config_name); void __internal_init_once(void); extern pthread_mutex_t g_mutex; void __internal_init_flush_logs(void); @@ -29,30 +31,40 @@ void __internal_enter(void); void __internal_exit(void); int __internal_can_send(bool bus_type, - const char* const user, - const char* const group, - const char* const label, - const char* const destination, - const char* const path, - const char* const interface, - const char* const member, - int type); + const uid_t user, + const gid_t group, + const char* const label, + const char* const destination, + const char* const path, + const char* const interface, + const char* const member, + int type); + +int __internal_can_send_multi_dest(bool bus_type, + const uid_t user, + const gid_t group, + const char* const label, + const char** const destination, + const char* const path, + const char* const interface, + const char* const member, + int type); int __internal_can_recv(bool bus_type, - const char* const user, - const char* const group, - const char* const label, - const char* const sender, - const char* const path, - const char* const interface, - const char* const member, - int type); + uid_t user, + gid_t group, + const char* const label, + const char* const sender, + const char* const path, + const char* const interface, + const char* const member, + int type); int __internal_can_own(bool bus_type, - const char* const user, - const char* const group, - const char* const service); - + uid_t user, + gid_t group, + const char* const label, + const char* const service); #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp new file mode 100644 index 0000000..5cf9d05 --- /dev/null +++ b/src/internal/naive_policy_checker.cpp @@ -0,0 +1,144 @@ +#include "naive_policy_checker.hpp" +#include "cynara.hpp" +#include "tslog.hpp" +using namespace _ldp_xml_parser; + +DbAdapter& NaivePolicyChecker::generateAdapter() { + if (!m_adapter) + m_adapter = new DbAdapter (m_bus_db[0], m_bus_db[1]); + + return *m_adapter; +} + +Decision NaivePolicyChecker::checkPolicy(const NaivePolicyDb::Policy& policy, + const Item& item, + const char*& privilege) +{ + if (tslog::verbose()) { + char tmp[MAX_LOG_LINE]; + const char* i_str = item.toString(tmp); + std::cout << "checkpolicy for: " << i_str <toString(tmp); + std::cout << "-readed: " << i_str <match(&item)) { + if (tslog::verbose()) { + char tmp[MAX_LOG_LINE]; + const char* i_str = i->toString(tmp); + std::cout << "-matched: " << i_str <getPrivilege(); + return i->getDecision(); + } + } + + return Decision::ANY; +} + +NaivePolicyDb& NaivePolicyChecker::getPolicyDb(bool type) { + return m_bus_db[type]; +} + +bool NaivePolicyChecker::parseDecision(Decision decision, + uid_t uid, + const char* label, + const char* privilege) { + + char uid_str[17]; + if (tslog::verbose()) { + std::cout<<"----Decision made\n"; + } + switch (decision) + { + case Decision::ALLOW: + return true; + case Decision::ANY: + case Decision::DENY: + return false; + case Decision::CHECK: + std::sprintf(uid_str, "%lu", (unsigned long)uid); + return _ldp_cynara::Cynara::check(label, privilege, uid_str) == _ldp_cynara::CynaraResult::ALLOW; + } + + return false; +} + +NaivePolicyChecker::~NaivePolicyChecker() { + delete m_adapter; +} + +bool NaivePolicyChecker::checkItem(bool bus_type, uid_t uid, gid_t gid, const char* label, const Item& item) { + NaivePolicyDb& policy_db = getPolicyDb(bus_type); + ItemType type = item.getType(); + Decision ret = Decision::ANY; + const char* privilege; + const NaivePolicyDb::Policy* curr_policy = NULL; + + if (ret == Decision::ANY) { + curr_policy = policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::MANDATORY)); + if (curr_policy) + ret = checkPolicy(*curr_policy, item, privilege); + } + + if (ret == Decision::ANY) { + curr_policy = policy_db.getPolicy(type, PolicyType::USER, PolicyTypeValue(uid)); + if (curr_policy) + ret = checkPolicy(*curr_policy, item, privilege); + } + + if (ret == Decision::ANY) { + curr_policy = policy_db.getPolicy(type, PolicyType::GROUP, PolicyTypeValue(gid)); + if (curr_policy) + ret = checkPolicy(*curr_policy, item, privilege); + } + + if (ret == Decision::ANY) { + curr_policy = policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT)); + if (curr_policy) + ret = checkPolicy(*curr_policy, item, privilege); + } + + if (ret != Decision::ANY) + return parseDecision(ret, uid, label, privilege); + else + return false; +} + +bool NaivePolicyChecker::check(bool bus_type, + uid_t uid, + gid_t gid, + const char* const label, + const char* const name) { + try { + ItemOwn item = ItemOwn(name); + return checkItem(bus_type, uid, gid, label, item); + } catch (std::runtime_error& err) { + if (tslog::enabled()) + std::cout << err.what() << std::endl; + } + return false; +} + +bool NaivePolicyChecker::check(bool bus_type, + uid_t uid, + gid_t gid, + const char* const label, + const char** const names, + const char* const interface, + const char* const member, + const char* const path, + MessageType message_type, + MessageDirection message_dir) { + try { + ItemSendReceive item = ItemSendReceive(names, interface, member, path, message_type, message_dir); + return checkItem(bus_type, uid, gid, label, item); + } catch (std::runtime_error& err) { + if (tslog::enabled()) + std::cout << err.what() << std::endl; + } + return false; +} diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp new file mode 100644 index 0000000..4f6478f --- /dev/null +++ b/src/internal/naive_policy_checker.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +#ifndef _NAIVE_DECISIONER_H +#define _NAIVE_DECISIONER_H + +#include "policy.hpp" +#include "naive_policy_db.hpp" + +namespace _ldp_xml_parser +{ + class NaivePolicyChecker { + private: + NaivePolicyDb m_bus_db[2]; + DbAdapter* m_adapter; + NaivePolicyDb& getPolicyDb(bool type); + Decision checkPolicy(const NaivePolicyDb::Policy& policy, + const Item& item, + const char*& privilege); + bool parseDecision(Decision decision, + uid_t uid, + const char* label, + const char* privilege); + bool checkItem(bool bus_type, + uid_t uid, + gid_t gid, + const char* label, + const Item& item); + public: + ~NaivePolicyChecker(); + DbAdapter& generateAdapter(); + bool check(bool bus_type, + uid_t uid, + gid_t gid, + const char* const label, + const char* const name); + bool check(bool bus_type, + uid_t uid, + gid_t gid, + const char* const label, + const char** const names, + const char* const interface, + const char* const member, + const char* const path, + MessageType message_type, + MessageDirection message_dir); + }; +} +#endif diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp new file mode 100644 index 0000000..ae3c571 --- /dev/null +++ b/src/internal/naive_policy_db.cpp @@ -0,0 +1,145 @@ +#include "naive_policy_db.hpp" +#include +#include "tslog.hpp" + +using namespace _ldp_xml_parser; + +NaivePolicyDb::Policy::PolicyConstIterator::PolicyConstIterator(const std::vector& items, int position) + : m_items(items), m_index(position) { +} + + Item* const& NaivePolicyDb::Policy::PolicyConstIterator::operator*() const { + return m_items[m_index]; +} + +NaivePolicyDb::Policy::PolicyConstIterator& NaivePolicyDb::Policy::PolicyConstIterator::operator++() { + if (m_index >= 0) + --m_index; + return *this; +} + +bool NaivePolicyDb::Policy::PolicyConstIterator::operator!=(const PolicyConstIterator& it) const { + return m_index != it.m_index; +} + +NaivePolicyDb::Policy::PolicyIterator::PolicyIterator(std::vector& items, int position) + : m_items(items), m_index(position) { +} + +Item*& NaivePolicyDb::Policy::PolicyIterator::operator*() { + return m_items[m_index]; +} + +NaivePolicyDb::Policy::PolicyIterator& NaivePolicyDb::Policy::PolicyIterator::operator++() { + if (m_index >= 0) + --m_index; + return *this; +} + +bool NaivePolicyDb::Policy::PolicyIterator::operator!=(const PolicyIterator& it) const { + return m_index != it.m_index; +} + +NaivePolicyDb::Policy::PolicyIterator NaivePolicyDb::Policy::begin() { + int s = m_items.size() - 1; + return NaivePolicyDb::Policy::PolicyIterator(m_items, s); +} +NaivePolicyDb::Policy::PolicyIterator NaivePolicyDb::Policy::end() { + return NaivePolicyDb::Policy::PolicyIterator(m_items, -1); +} +NaivePolicyDb::Policy::PolicyConstIterator NaivePolicyDb::Policy::begin() const { + int s = m_items.size() - 1; + return NaivePolicyDb::Policy::PolicyConstIterator(m_items, s); +} +NaivePolicyDb::Policy::PolicyConstIterator NaivePolicyDb::Policy::end() const { + return NaivePolicyDb::Policy::PolicyConstIterator(m_items, -1); +} + +void NaivePolicyDb::Policy::addItem(Item* item) { + m_items.push_back(item); +} + +NaivePolicyDb::~NaivePolicyDb() { + +} + +const NaivePolicyDb::Policy* NaivePolicyDb::getPolicy(const ItemType item_type, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value) { + PolicyTypeSet* set = NULL; + switch (item_type) { + case ItemType::OWN: + set = &m_own_set; + break; + case ItemType::SEND: + set = &m_send_set; + break; + case ItemType::RECEIVE: + set = &m_receive_set; + break; + default: + break; + } + if (tslog::enabled()) + std::cout<<"---policy_type ="; + switch (policy_type) { + case PolicyType::CONTEXT: + if (tslog::enabled()) + std::cout << "CONTEXT =" << (int)policy_type_value.context << std::endl; + return &set->context[static_cast(policy_type_value.context) ]; + case PolicyType::USER: + if (tslog::enabled()) + std::cout << "USER =" << (int)policy_type_value.user << std::endl; + return &set->user[policy_type_value.user]; + case PolicyType::GROUP: + if (tslog::enabled()) + std::cout << "GROUP = " << (int)policy_type_value.group << std::endl; + return &set->group[policy_type_value.group]; + } + if (tslog::enabled()) + std::cout << "NO POLICY\n"; + return NULL; +} + +void NaivePolicyDb::addItem(NaivePolicyDb::PolicyTypeSet& set, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + Item* const item) { + switch (policy_type) { + case PolicyType::CONTEXT: + set.context[static_cast(policy_type_value.context)].addItem(item); + break; + case PolicyType::USER: + set.user[policy_type_value.user].addItem(item); + break; + case PolicyType::GROUP: + set.group[policy_type_value.group].addItem(item); + break; + } +} + +void NaivePolicyDb::addItem(const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + Item* const item) { + const ItemSendReceive* it; + + if (tslog::enabled()) { + char tmp[MAX_LOG_LINE]; + const char* i_str = item->toString(tmp); + std::cout<<"Add item: "<< i_str <(item)) + addItem(m_own_set, policy_type, policy_type_value, item); + else if ((it = dynamic_cast(item))) { + const MessageDirection dir = it->getDirection(); + if (dir == MessageDirection::SEND) + addItem(m_send_set, policy_type, policy_type_value, item); + else if (dir == MessageDirection::RECEIVE) + addItem(m_receive_set, policy_type, policy_type_value, item); + else { + addItem(m_send_set, policy_type, policy_type_value, item); + addItem(m_receive_set, policy_type, policy_type_value, item); + } + } +} diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp new file mode 100644 index 0000000..015eb13 --- /dev/null +++ b/src/internal/naive_policy_db.hpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +#ifndef _NAIVE_DB_H +#define _NAIVE_DB_H + +#include +#include +#include "policy.hpp" + +namespace _ldp_xml_parser +{ + class NaivePolicyDb { + public: + class Policy { + private: + std::vector m_items; + public: + class PolicyConstIterator { + private: + const std::vector& m_items; + int m_index; + public: + PolicyConstIterator(const std::vector& items, int position); + Item* const& operator*() const; + PolicyConstIterator& operator++(); + bool operator!=(const PolicyConstIterator& it) const; + }; + + class PolicyIterator { + private: + std::vector& m_items; + int m_index; + public: + PolicyIterator(std::vector& items, int position); + Item*& operator*(); + PolicyIterator& operator++(); + bool operator!=(const PolicyIterator& it) const; + }; + + PolicyIterator begin(); + PolicyIterator end(); + PolicyConstIterator begin() const; + PolicyConstIterator end() const; + void addItem(Item* item); + }; + + ~NaivePolicyDb(); + + const Policy* getPolicy(const ItemType item_type, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value); + + void addItem(const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + Item* const item); + private: + struct PolicyTypeSet { + Policy context[static_cast(ContextType::MAX)]; + std::map user; + std::map group; + }; + + PolicyTypeSet m_own_set; + PolicyTypeSet m_send_set; + PolicyTypeSet m_receive_set; + void addItem(PolicyTypeSet& set, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + Item* const item); + }; +} + +#endif diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp new file mode 100644 index 0000000..dcbde77 --- /dev/null +++ b/src/internal/policy.cpp @@ -0,0 +1,528 @@ +#include "policy.hpp" +#include "naive_policy_db.hpp" +//#include "tslog.hpp" +#include +#include +#include +#include + +using namespace _ldp_xml_parser; + +static const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL"}; +static const char* message_dir[] = { "ANY", "SEND", "RECEIVE"}; +static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"}; + +static bool __compare_str(const char* a, const char* b) { + + while(*a && *b && *a != ' ' && *b != ' ') { + if (*a != *b) + return false; + a++; b++; + } + return ((*a == 0 || *a == ' ') && (*b == 0 || *b != ' ')); +} + +static MessageType __str_to_message_type(const char* str) { + 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; +} + +static inline const char* __message_type_to_str(MessageType type) { + return message_type[static_cast(type)]; +} + +static inline const char* __message_dir_to_str(MessageDirection type) { + return message_dir[static_cast(type)]; +} + +static inline const char* __decision_to_str(Decision dec) { + return message_decision[static_cast(dec)]; +} + +DbAdapter::DbAdapter(NaivePolicyDb& system, NaivePolicyDb& session) + : __system_db(system), __session_db(session), __attr(false), __tag_state(NONE) { +} + +uid_t DbAdapter::convertToUid(const char* user) { + errno = 0; + long val = std::strtol(user, NULL, 10); + if (!errno) + 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; +} + +gid_t DbAdapter::convertToGid(const char* group) { + errno = 0; + long val = std::strtol(group, NULL, 10); + if (!errno) + 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 boost::property_tree::ptree::value_type& v, const std::string& substr) { + return (v.first.find(substr) != std::string::npos); +} + +void DbAdapter::updateDecision(const boost::property_tree::ptree::value_type& v, + PolicyType& policy_type, + PolicyTypeValue& policy_type_value, + state& t, + bool& attr) { + const char* value = NULL; + if(v.first == "allow" && t == POLICY) { + __builder.reset(); + __builder.addDecision(Decision::ALLOW); + t = ALLOW_DENY_CHECK; + attr = false; + } else if(v.first == "deny" && t == POLICY) { + __builder.reset(); + __builder.addDecision(Decision::DENY); + t = ALLOW_DENY_CHECK; + attr = false; + } else if(v.first == "check" && t == POLICY) { + __builder.reset(); + __builder.addDecision(Decision::CHECK); + t = ALLOW_DENY_CHECK; + attr = false; + } else if(v.first == "") { + attr = true; + } else if(attr && t == POLICY) { + if (v.second.data() != "*") + value = v.second.data().c_str(); + + if(v.first == "context") { + 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(v.first == "user") { + policy_type = PolicyType::USER; + policy_type_value.user = convertToUid(value); + } else if(v.first == "group") { + policy_type = PolicyType::GROUP; + policy_type_value.group = convertToGid(value); + } else { + attr = false; + t = NONE; + } + } else if (attr && t == ALLOW_DENY_CHECK) { + if (v.second.data() != "*") + value = v.second.data().c_str(); + + if(field_has(v, "send_")) { + __builder.addDirection(MessageDirection::SEND); + } else if(field_has(v, "receive_")) { + __builder.addDirection(MessageDirection::RECEIVE); + } else if(v.first == "own") { + __builder.addOwner(value); + __builder.setPrefix(false); + } else if(v.first == "own_prefix") { + __builder.addOwner(value); + __builder.setPrefix(true); + } else if(v.first == "privilege") + __builder.addPrivilege(value); + + if(field_has(v, "_destination")) + __builder.addName(value); + else if(field_has(v, "_sender")) + __builder.addName(value); + else if(field_has(v, "_path")) + __builder.addPath(value); + else if(field_has(v, "_interface")) + __builder.addInterface(value); + else if(field_has(v, "_member")) + __builder.addMember(value); + else if(field_has(v, "_type")) + __builder.addMessageType(__str_to_message_type(value)); + } else { + attr = false; + t = NONE; + } +} + +void DbAdapter::xmlTraversal(bool bus, + const boost::property_tree::ptree& pt, + DbAdapter::state tag, + PolicyType& policy_type, + PolicyTypeValue& policy_type_value, + bool attr, + int level) { + static const int Q_XML_MAX_LEVEL = 10; + if(level < Q_XML_MAX_LEVEL) { + for(const auto& v : pt) { + if(v.first == "") { continue; } + state t = tag; + updateDecision(v, policy_type, policy_type_value, t, attr); + xmlTraversal(bus, v.second, t, policy_type, policy_type_value, attr, level + 1); + } + + if(!pt.empty() && level > 1) { + Item* it = __builder.generateItem(); + if (it) { + if (bus) + __session_db.addItem(policy_type, policy_type_value, it); + else + __system_db.addItem(policy_type, policy_type_value, it); + } + } + } +} + +void DbAdapter::updateDb(bool bus, boost::property_tree::ptree& xmlTree) { + const auto& children = xmlTree.get_child("busconfig"); + PolicyType policy_type; + PolicyTypeValue policy_type_value; + for(const auto& x : children) { + if(x.first == "policy") { + __tag_state = POLICY; + __attr = false; + xmlTraversal(bus, x.second, POLICY, policy_type, policy_type_value); + } + } +} + +Item::Item(Decision decision, const char* privilege, bool isOwner) + : _decision(decision), _privilege(privilege), _is_owner(isOwner) { + +} + +Item::~Item() { + if (_is_owner) { + delete[] _privilege; + } +} + +bool Item::match(const Item& item) const { + return match(&item); +} + +bool Item::match(const Item* item) const { + return true; +} + +Decision Item::getDecision() const { + return _decision; +} + +const char* Item::getPrivilege() const { + return _privilege; +} + +ItemType Item::getType() const { + return ItemType::GENERIC; +} + +const char* Item::toString(char* str) const { + snprintf(str, MAX_LOG_LINE, "Item: dec(%s) owner(%d) priv(%s)", __decision_to_str(_decision), _is_owner, _privilege); + return str; +} + +ItemOwn::ItemOwn(const char* name, + bool is_prefix, + Decision decision, + const char* privilege) +: Item(decision, privilege), __name(name), __is_prefix(is_prefix) { +} + +ItemOwn::~ItemOwn() { + if (_is_owner) { + delete[] __name; + } +} +ItemType ItemOwn::getType() const { + return ItemType::OWN; +} +bool ItemOwn::match(const Item* item) const { + const ItemOwn* it = dynamic_cast(item); + if (__is_prefix) { + int i = 0; + if (!__name) + return false; + + for (i = 0; __name[i] && it->__name[i]; i++) + if (__name[i] != it->__name[i]) + return false; + + if (__name[i] != 0) + return false; + + return true; + } else if (!__name) + return true; + else { + return std::strcmp(__name, it->__name) == 0; + } +} + +const char* ItemOwn::toString(char* str) const { + char parent[MAX_LOG_LINE]; + const char* t = Item::toString(parent); + snprintf(str, MAX_LOG_LINE, "ItemOwn: service(%s), pref(%d) <- %s", __name, __is_prefix, t); + return str; +} + +ItemSendReceive::ItemSendReceive(const char** names, + const char* interface, + const char* member, const char* path, + MessageType type, MessageDirection direction, + Decision decision, + const char* privilege) + : Item(decision, privilege), + __names(names), + __interface(interface), + __member(member), + __path(path), + __type(type), + __direction(direction) { +} +const char* ItemSendReceive::toString(char* str) const { + char parent[MAX_LOG_LINE]; + char buff[MAX_LOG_LINE]; + char* curr = buff; + const char* t = Item::toString(parent); + int i = 0; + int k = 0; + while(__names && __names[i]){ + for (k = 0; __names[i][k] && __names[i][k] != ' ';k++){ + *curr = __names[i][k]; + curr +=1; + } + *curr = ' '; + curr += 1; + i++; + } + *curr = 0; + curr += 1; + snprintf(str, MAX_LOG_LINE, "ItemSR: name(%s), inter(%s), member(%s), path(%s), type(%s), dir(%s) <- %s", buff, __interface, __member, __path, __message_type_to_str(__type), __message_dir_to_str(__direction), t); + return str; +} +ItemSendReceive::~ItemSendReceive() { + if (_is_owner) { + delete[] __interface; + delete[] __member; + delete[] __path; + + if (__names) { + int i = 0; + while (__names[i]) + delete[] __names[i++]; + delete[] __names; + } + } +} + +bool ItemSendReceive::match(const Item* item) const { + const ItemSendReceive* it = dynamic_cast(item); + + if (__type != MessageType::ANY && __type != it->__type) + return false; + + if (__direction != it->__direction) + return false; + + if (__interface && it->__interface && std::strcmp(__interface, it->__interface)) + return false; + + if (__path && it->__path && std::strcmp(__path, it->__path)) + return false; + + if (__member && it->__member && std::strcmp(__member, it->__member)) + return false; + + if (__names && __names[0]) { + int i = 0; + bool f = false; + if (it->__names) { + while (it->__names[i]) { + if (__compare_str(it->__names[i++], __names[0])) { + f = true; + break; + } + } + if (!f) + return false; + } + } + + return true; +} + +ItemType ItemSendReceive::getType() const { + if (__direction == MessageDirection::SEND) + return ItemType::SEND; + else + return ItemType::RECEIVE; +} + + +MessageDirection ItemSendReceive::getDirection() const { + return __direction; +} + +ItemOwn* ItemBuilder::getOwnItem() { + if (!__current) { + __current = new ItemOwn(); + prepareItem(); + } + return dynamic_cast(__current); +} + +ItemSendReceive* ItemBuilder::getSendReceiveItem() { + if (!__current) { + __current = new ItemSendReceive(); + prepareItem(); + } + return dynamic_cast(__current); +} + +ItemBuilder::ItemBuilder() : __current(NULL), __delayed_privilege(NULL) { +} + +ItemBuilder::~ItemBuilder(){ + if (__delayed_privilege) + delete[] __delayed_privilege; + if (__current) + delete __current; +} + +void ItemBuilder::reset() { + if (__delayed_privilege) + delete[] __delayed_privilege; + if (__current) + delete __current; + + __current = NULL; + __delayed_privilege = NULL; +} + +char* ItemBuilder::duplicate(const char* str) { + char* ret; + int i = 0; + int len; + + if (!str) + return NULL; + + len = strlen(str) + 1; + ret = new char[len]; + for (i = 0; i < len; i++) + ret[i] = str[i]; + + return ret; +} + +void ItemBuilder::prepareItem() { + __current->_is_owner = true; + if (__delayed_privilege) + __current->_privilege = __delayed_privilege; + + __current->_decision = __delayed_decision; + __delayed_privilege = NULL; +} + +Item* ItemBuilder::generateItem() { + Item* ret = __current; + __current = NULL; + __delayed_decision = Decision::ANY; + __delayed_privilege = NULL; + return ret; +} + +void ItemBuilder::addOwner(const char* owner) { + ItemOwn* o = getOwnItem(); + if (o->__name) + delete o->__name; + o->__name = duplicate(owner); +} + +void ItemBuilder::addName(const char* name) { + ItemSendReceive* sr = getSendReceiveItem(); + if (sr->__names) { + delete sr->__names[0]; + delete[] sr->__names; + } + if (!name) + sr->__names = NULL; + else { + sr->__names = new const char*[2]; + sr->__names[0] = duplicate(name); + sr->__names[1] = NULL; + } +} + +void ItemBuilder::addInterface(const char* interface) { + ItemSendReceive* sr = getSendReceiveItem(); + sr->__interface = duplicate(interface); +} + +void ItemBuilder::addMember(const char* member) { + ItemSendReceive* sr = getSendReceiveItem(); + sr->__member = duplicate(member); +} + +void ItemBuilder::addPath(const char* path) { + ItemSendReceive* sr = getSendReceiveItem(); + sr->__path = duplicate(path); +} + +void ItemBuilder::addMessageType(MessageType type) { + ItemSendReceive* sr = getSendReceiveItem(); + sr->__type = type; +} + +void ItemBuilder::addDirection(MessageDirection direction) { + ItemSendReceive* sr = getSendReceiveItem(); + sr->__direction = direction; +} + +void ItemBuilder::addPrivilege(const char* privilege) { + if (!__current) + __delayed_privilege = duplicate(privilege); + else + __current->_privilege = duplicate(privilege); +} + +void ItemBuilder::addDecision(Decision decision) { + if (!__current) + __delayed_decision = decision; + else + __current->_decision = decision; +} + +void ItemBuilder::setPrefix(bool value) { + ItemOwn* o = getOwnItem(); + o->__is_prefix = value; +} + +PolicyTypeValue::PolicyTypeValue() : context(ContextType::DEFAULT) { +} + +PolicyTypeValue::PolicyTypeValue(ContextType type) : context(type) { +} + +PolicyTypeValue::PolicyTypeValue(uid_t us) : user(us) { +} diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp new file mode 100644 index 0000000..848c53c --- /dev/null +++ b/src/internal/policy.hpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +#ifndef _POLICY_H +#define _POLICY_H + +#include +#include +#include +#define MAX_LOG_LINE 1024 + +namespace _ldp_xml_parser +{ + enum class MessageType : uint8_t { + ANY = 0, + METHOD_CALL, + METHOD_RETURN, + ERROR, + SIGNAL + }; + + enum class MessageDirection : uint8_t { + ANY, + SEND, + RECEIVE + }; + + enum class ItemType : uint8_t{ + GENERIC, + OWN, + SEND, + RECEIVE + }; + + enum class PolicyType : uint8_t { + CONTEXT, + USER, + GROUP + }; + + enum class ContextType : uint8_t { + DEFAULT, + MANDATORY, + MAX + }; + + enum class Decision : uint8_t { + ANY, + ALLOW, + DENY, + CHECK + }; + + union PolicyTypeValue { + PolicyTypeValue(); + PolicyTypeValue(ContextType type); + PolicyTypeValue(uid_t us); + ContextType context; + uid_t user; + gid_t group; + }; + + class ItemBuilder; + + class Item { + protected: + Decision _decision; + const char* _privilege; + bool _is_owner; + public: + friend class ItemBuilder; + Item(Decision decision = Decision::ANY, const char* privilege = NULL, bool isOwner = false); + virtual ~Item(); + virtual bool match(const Item& item) const; + virtual bool match(const Item* item) const; + virtual Decision getDecision() const; + virtual const char* getPrivilege() const; + virtual ItemType getType() const; + virtual const char* toString(char* str) const; + }; + + class ItemOwn : public Item { + private: + const char* __name; + bool __is_prefix; + public: + friend class ItemBuilder; + ItemOwn(const char* name = NULL, + bool is_prefix = false, + Decision decision = Decision::ANY, + const char* privilege = NULL); + virtual ~ItemOwn(); + virtual bool match(const Item* item) const; + virtual ItemType getType() const; + virtual const char* toString(char* str) const; + }; + + class ItemSendReceive : public Item { + const char** __names; + const char* __interface; + const char* __member; + const char* __path; + MessageType __type; + MessageDirection __direction; + public: + friend class ItemBuilder; + ItemSendReceive(const char** names = NULL, + const char* interface = NULL, + const char* member = NULL, + const char* path = NULL, + MessageType type = MessageType::ANY, + MessageDirection direction = MessageDirection::ANY, + Decision decision = Decision::ANY, + const char* privilege = NULL); + virtual ~ItemSendReceive(); + virtual bool match(const Item* item) const; + MessageDirection getDirection() const; + virtual ItemType getType() const; + virtual const char* toString(char* str) const; + }; + + class ItemBuilder { + private: + Item* __current; + Decision __delayed_decision; + const char* __delayed_privilege; + ItemOwn* getOwnItem(); + ItemSendReceive* getSendReceiveItem(); + char* duplicate(const char* str); + void prepareItem(); + public: + ItemBuilder(); + ~ItemBuilder(); + Item* generateItem(); + void reset(); + void addUser(const char* name); + void addGroup(const char* name); + void addOwner(const char* owner); + void addName(const char* name); + void addInterface(const char* interface); + void addMember(const char* member); + void addPath(const char* path); + void addMessageType(MessageType type); + void addDirection(MessageDirection direction); + void addPrivilege(const char* privilege); + void addDecision(Decision decision); + void setPrefix(bool value); + }; + + class NaivePolicyDb; + class DbAdapter { + private: + enum state { + NONE, + POLICY, + ALLOW_DENY_CHECK + }; + NaivePolicyDb& __system_db; + NaivePolicyDb& __session_db; + bool __attr; + state __tag_state; + ItemBuilder __builder; + void updateDecision(const boost::property_tree::ptree::value_type& v, + PolicyType& policy_type, + PolicyTypeValue& policy_type_value, + state& tag, + bool& attr); + void xmlTraversal(bool bus, + const boost::property_tree::ptree& pt, + state tag, + PolicyType& policy_type, + PolicyTypeValue& policy_type_value, + bool attr = false, + int level = 0); + public: + DbAdapter(NaivePolicyDb& system, NaivePolicyDb& session); + void updateDb(bool bus, boost::property_tree::ptree& xmlTree); + static uid_t convertToUid(const char* user); + static gid_t convertToGid(const char* group); + }; +} +#endif diff --git a/src/internal/tslog.cpp b/src/internal/tslog.cpp new file mode 100644 index 0000000..fa5b579 --- /dev/null +++ b/src/internal/tslog.cpp @@ -0,0 +1,17 @@ +#include "tslog.hpp" + +namespace tslog { +int8_t g_verbosity; +} + +bool tslog::get_log_env(char const *name) { + char const *ldp_log_mode = getenv(name); + return ldp_log_mode && '0' != *ldp_log_mode; +} + +void tslog::init() { + g_verbosity = get_log_env("LDP_LOG") ? get_log_env("LDP_VERBOSE") : -1; +} + +bool tslog::enabled() { return g_verbosity >= 0; } +bool tslog::verbose() { return g_verbosity > 0; } diff --git a/src/internal/tslog.hpp b/src/internal/tslog.hpp index dd57976..07fc383 100644 --- a/src/internal/tslog.hpp +++ b/src/internal/tslog.hpp @@ -26,19 +26,13 @@ typedef std::ostream& (*t_ManFun)(std::ostream&); namespace tslog { - int8_t g_verbosity; // <0 disable 0 brief >0 verbose - bool get_log_env(char const *name) { - char const *ldp_log_mode = getenv(name); - return ldp_log_mode && '0' != *ldp_log_mode; - } + bool get_log_env(char const *name); - void init() { - g_verbosity = get_log_env("LDP_LOG") ? get_log_env("LDP_VERBOSE") : -1; - } + void init(); - bool enabled() { return g_verbosity >= 0; } - bool verbose() { return g_verbosity > 0; } + bool enabled(); + bool verbose(); } #endif diff --git a/src/internal/xml_parser.cpp b/src/internal/xml_parser.cpp new file mode 100644 index 0000000..2c793f6 --- /dev/null +++ b/src/internal/xml_parser.cpp @@ -0,0 +1,3 @@ +#include "xml_parser.hpp" + +std::set _ldp_xml_parser::XmlParser::m_parsed; diff --git a/src/internal/xml_parser.hpp b/src/internal/xml_parser.hpp index 61e60e4..948f2c6 100644 --- a/src/internal/xml_parser.hpp +++ b/src/internal/xml_parser.hpp @@ -23,7 +23,10 @@ #include #include #include -#include "xml_policy.hpp" +//#include "xml_policy.hpp" +#include "libdbuspolicy1-private.hpp" +#include "tslog.hpp" +#include "policy.hpp" namespace _ldp_xml_parser { @@ -36,47 +39,16 @@ namespace _ldp_xml_parser return err; } - ErrCode can_send(bool bus, - const std::string user, - const std::string group, - const std::string label, - const std::string destination, - const std::string path, - const std::string interface, - const std::string member, - const std::string type) { - std::vector idx_v = { user, group, destination, path, interface, member, type }; - return m_xml_policy.can_send_to(bus, idx_v, label); + void registerAdapter(DbAdapter& adapter) { + m_adapter = &adapter; } - ErrCode can_recv(bool bus, - const std::string user, - const std::string group, - const std::string label, - const std::string sender, - const std::string path, - const std::string interface, - const std::string member, - const std::string type) { - std::vector idx_v = { user, group, sender, path, interface, member, type }; - return m_xml_policy.can_recv_from(bus, idx_v, label); - } - - ErrCode can_own(bool bus, - const std::string user, - const std::string group, - const std::string service) { - std::vector idx_v = { user, group, service }; - return m_xml_policy.can_own_what(bus, idx_v); - } - - private: //IO operation static std::set m_parsed; + DbAdapter* m_adapter; //Data obtained from XML - static XmlPolicy m_xml_policy; ErrCode parse(bool bus, std::string const &filename) { ErrCode err; @@ -88,10 +60,6 @@ namespace _ldp_xml_parser err = parse(bus, false, x, incl_files); if (err.is_error()) break; } - - if(err.is_ok()) - m_xml_policy.print_decision_trees(bus); - return err; } @@ -148,7 +116,7 @@ namespace _ldp_xml_parser boost::property_tree::ptree pt; read_xml(filename, pt); if (!pt.empty()) { - m_xml_policy.update(bus, pt); + m_adapter->updateDb(bus, pt); ret.second = pt.get("busconfig.includedir", ""); } } catch(const boost::property_tree::xml_parser::xml_parser_error& ex) { diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 0ff7d6b..1878d9e 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -49,21 +49,6 @@ #define UID_INVALID ((uid_t) -1) #define GID_INVALID ((gid_t) -1) -static char const *foreach_strv_advance(char const *str) { - char c; - while ((c = *str++)) - if (' ' == c) - return str; - return NULL; -} - -/* iterate over STR; iterate once with "" if !STR or !*STR */ -#define FOREACH_STRV_DEFAULT(ITERLVALPTR,STR) for (\ - ITERLVALPTR = (!STR || !*STR) ? "" : STR;\ - ITERLVALPTR;\ - ITERLVALPTR = foreach_strv_advance(ITERLVALPTR)\ -) - /** A process ID */ typedef unsigned long dbus_pid_t; /** A user ID */ @@ -148,22 +133,22 @@ static bool dbuspolicy_init_once(void) if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */ return true; + g_udesc.uid = getuid(); + g_udesc.gid = getgid(); + snprintf(g_udesc.label, r + 1 /* additional byte for \0 */, "%s", buf); if (getpwuid_r(g_udesc.uid, &pwent, buf, sizeof(buf), &pwd)) - return true; + return true; if (getgrgid_r(g_udesc.gid, &grent, buf, sizeof(buf), &gg)) - return true; + return true; if (!pwd || !gg) - return -1; + return false; snprintf(g_udesc.user, sizeof(g_udesc.user), "%s", pwd->pw_name); snprintf(g_udesc.group, sizeof(g_udesc.group), "%s", gg->gr_name); - g_udesc.uid = getuid(); - g_udesc.gid = getgid(); - __internal_init_once(); return false; @@ -224,7 +209,6 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) init_once_done = true; rb = dbuspolicy_init_once(); } - pthread_mutex_unlock(&g_mutex); if (rb) goto err_close; @@ -237,14 +221,17 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) rp = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_PRIMARY : SESSION_BUS_CONF_FILE_PRIMARY); rs = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_SECONDARY : SESSION_BUS_CONF_FILE_SECONDARY); __internal_init_flush_logs(); + if ((rp & rs) < 0) /* when both negative */ goto err_close; + pthread_mutex_unlock(&g_mutex); return &g_conn[bus_type]; err_close: close(g_conn[bus_type].fd); err: + pthread_mutex_unlock(&g_mutex); return NULL; } @@ -254,6 +241,15 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) close(((typeof(&g_conn[0]))configuration)->fd); } +#ifdef LIBDBUSPOLICY_TESTS_API +DBUSPOLICY1_EXPORT void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label) { + g_udesc.uid = uid; + g_udesc.gid = gid; + if (label) + strcpy (g_udesc.label, label); +} +#endif + static bool configuration_bus_type(struct kconn const *configuration) { return configuration != g_conn; } /** @@ -275,6 +271,8 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, int requested_reply) { char const *label = NULL; + const char* k_names[KDBUS_CONN_MAX_NAMES+1]; + int k_i = 0; int r; uid_t uid_n = UID_INVALID; gid_t gid_n = GID_INVALID; @@ -344,29 +342,27 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, case KDBUS_ITEM_OWNED_NAME: empty_names = false; if (r <= 0) - r = __internal_can_send(bus_type, g_udesc.user, g_udesc.group, g_udesc.label, item->name.name, path, interface, member, message_type); + k_names[k_i++] = item->name.name; break; } } if (empty_names) - r = __internal_can_send(bus_type, g_udesc.user, g_udesc.group, g_udesc.label, destination, path, interface, member, message_type); - - if (r > 0 && message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { - char gid[25], uid[25]; - char const *ptr; - snprintf(uid, sizeof(uid), "%lu", (unsigned long)uid_n); - snprintf(gid, sizeof(gid), "%lu", (unsigned long)gid_n); + r = __internal_can_send(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, destination, path, interface, member, message_type); + else { + k_names[k_i++] = NULL; + r = __internal_can_send_multi_dest(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, k_names, path, interface, member, message_type); + } + if (r <= 0) + goto end; - FOREACH_STRV_DEFAULT(ptr, sender) - if (0 < (r = __internal_can_recv(bus_type, uid, gid, label, ptr, path, interface, member, message_type))) - break; - } + if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) + r = __internal_can_recv(bus_type, uid_n, gid_n, label, sender, path, interface, member, message_type); +end: if (free_offset) ioctl(g_conn[bus_type].fd, KDBUS_CMD_FREE, &cmd.cmd_free); -end: __internal_exit(); return r; } @@ -392,26 +388,22 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, int reply_serial, int requested_reply) { - char const *ptr; int r; - char gid[25], uid[25]; bool bus_type = configuration_bus_type(configuration); - snprintf(uid, sizeof(uid), "%lu", (unsigned long)sender_uid); - snprintf(gid, sizeof(gid), "%lu", (unsigned long)sender_gid); - __internal_enter(); - FOREACH_STRV_DEFAULT(ptr, destination) - if (0 < (r = __internal_can_send(bus_type, uid, gid, sender_label, ptr, path, interface, member, message_type))) - break; - - if (r > 0 && message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) - FOREACH_STRV_DEFAULT(ptr, sender) - if (0 < (r = __internal_can_recv(bus_type, g_udesc.user, g_udesc.group, g_udesc.label, ptr, path, interface, member, message_type))) - break; + r = __internal_can_send(bus_type, sender_uid, sender_gid, sender_label, destination, path, interface, member, message_type); + if (r <= 0) + goto end; - __internal_exit(); + if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { + r = __internal_can_recv(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, sender, path, interface, member, message_type); + if (r <= 0) + goto end; + } +end: + __internal_exit(); return r; } @@ -427,7 +419,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* cons int r; bool bus_type = configuration_bus_type(configuration); __internal_enter(); - r = __internal_can_own(bus_type, g_udesc.user, g_udesc.group, service); + r = __internal_can_own(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, service); __internal_exit(); return r; } diff --git a/src/libdbuspolicy1.sym b/src/libdbuspolicy1.sym index 051e64e..c472731 100644 --- a/src/libdbuspolicy1.sym +++ b/src/libdbuspolicy1.sym @@ -5,15 +5,12 @@ global: dbuspolicy1_check_in; dbuspolicy1_check_out; dbuspolicy1_can_own; + __dbuspolicy1_change_creds; local: *; }; -LIBDBUSPOLICY1_3 { +LIBDBUSPOLICY1_1_TEST { global: - dbuspolicy1_thing_ref; - dbuspolicy1_thing_unref; - dbuspolicy1_thing_get_ctx; - dbuspolicy1_thing_new_from_string; - dbuspolicy1_thing_get_some_list_entry; -} LIBDBUSPOLICY1_1; + __dbuspolicy1_change_creds; +}; diff --git a/src/test-libdbuspolicy1-method.cpp b/src/test-libdbuspolicy1-method.cpp new file mode 100644 index 0000000..8aa3738 --- /dev/null +++ b/src/test-libdbuspolicy1-method.cpp @@ -0,0 +1,82 @@ + +#include +#include +#include +#include +#include "internal/internal.h" +#include "internal/policy.hpp" + +using namespace _ldp_xml_parser; + +const char* system_path = "tests/system.conf"; + +struct MethodTest { + bool expected_result; + uid_t user; + gid_t group; + const char* label; + const char* name; + const char* path; + const char* interface; + const char* member; + MessageType type; + MessageDirection recv_send; +}; + +struct MethodTest method_tests[]={ + (struct MethodTest){true, 0, 0, "test", "org.test.test2", NULL, "org.test.Itest1", "DoIt", MessageType::METHOD_CALL, MessageDirection::SEND}, + (struct MethodTest){true, 0, 0, "test", "org.test.test3", NULL, "org.test.Itest1", "DoIt", MessageType::METHOD_CALL, MessageDirection::RECEIVE}, + + (struct MethodTest){true, 5001, 100, "test", "org.test.test3", NULL, "org.test.Itest1", "DoIt", MessageType::METHOD_CALL, MessageDirection::RECEIVE}, + (struct MethodTest){true, 0, 0, "test", "org.test.test2", NULL, "org.test.Itest1", "DoIt", MessageType::METHOD_CALL, MessageDirection::SEND}, + + (struct MethodTest){false, 0, 0, "test", "org.test.test2", NULL, "org.test.Itest1", "DontDoIt", MessageType::METHOD_CALL, MessageDirection::SEND}, + (struct MethodTest){true, 0, 0, "test", "org.test.test3", NULL, "org.test.Itest1", "DontDoIt", MessageType::METHOD_CALL, MessageDirection::RECEIVE}, + + (struct MethodTest){false, 0, 0, "test", "org.test.test2", NULL, "org.test.Itest1", "DontDoIt", MessageType::METHOD_CALL, MessageDirection::SEND}, + (struct MethodTest){false, 5001, 100, "test", "org.test.test3", NULL, "org.test.Itest1", "DontDoIt", MessageType::METHOD_CALL, MessageDirection::RECEIVE}, + + (struct MethodTest){true, 0, 0, "test", "test.te34.fg4 a.b.c.d.e org.test.test2", NULL, "org.test.Itest1", "NotKnown", MessageType::METHOD_CALL, MessageDirection::SEND}, + (struct MethodTest){false, 0, 0, "test", "test.te34.fg4 a.b.c.d.e", NULL, "org.test.Itest1", "NotKnown", MessageType::METHOD_CALL, MessageDirection::SEND}, + (struct MethodTest){true, 0, 0, "test", "org.test.test3", NULL, "org.test.Itest1", "NotKnown", MessageType::METHOD_CALL, MessageDirection::RECEIVE}, + + (struct MethodTest){true, 0, 0, "test", "org.test.test2", NULL, "org.test.Itest1", "NotKnown", MessageType::METHOD_CALL, MessageDirection::SEND}, + (struct MethodTest){false, 5001, 100, "test", "org.test.test3", NULL, "org.test.Itest1", "NotKnown", MessageType::METHOD_CALL, MessageDirection::RECEIVE}, + + (struct MethodTest){false, 0, 0, "test", "org.test.test2", NULL, "org.test.Itest2", "NotKnown", MessageType::METHOD_CALL, MessageDirection::SEND}, + (struct MethodTest){true, 5001, 100, "test", "org.test.test3", NULL, "org.test.Itest2", "NotKnown", MessageType::METHOD_CALL, MessageDirection::RECEIVE}, +}; + +void methodTest_print(struct MethodTest* t, bool result) { + printf("uid = %lu, gid = %lu, label = %s, name = %s, path = %s, interface = %s, member = %s, expected = %d, result = %d (type=%d)", + (unsigned long)t->user, (unsigned long)t->group, t->label, t->name, t->path, t->interface, t->member, !((int)t->expected_result), (int)result, t->recv_send); +} + +bool method_test() { + unsigned i = 0; + bool flag = true; + bool ret = true; + __internal_init(false, "tests/system.conf"); + for (i = 0;i < sizeof(method_tests)/sizeof(struct MethodTest);i++) { + if (method_tests[i].recv_send == MessageDirection::SEND) + { + ret = __internal_can_send(false, method_tests[i].user, method_tests[i].group, method_tests[i].label, method_tests[i].name, method_tests[i].path, method_tests[i].interface, method_tests[i].member, static_cast(method_tests[i].type)); + } else if (method_tests[i].recv_send == MessageDirection::RECEIVE) { + ret = __internal_can_recv(false, method_tests[i].user, method_tests[i].group, method_tests[i].label, method_tests[i].name, method_tests[i].path, method_tests[i].interface, method_tests[i].member, static_cast(method_tests[i].type)); + } + if ( (int)((method_tests[i].expected_result)) != ret) { + printf("[ERROR][%d] method test failed: %d %d ", i, (int)((method_tests[i].expected_result)), ret); + methodTest_print(&method_tests[i], ret); + printf("\n"); + flag = false; + } + } + return flag; +} + +int main () { + __internal_init_once(); + if (!method_test()) + return -1; +return 0; +} diff --git a/src/test-libdbuspolicy1-ownership.cpp b/src/test-libdbuspolicy1-ownership.cpp new file mode 100644 index 0000000..30c3fa7 --- /dev/null +++ b/src/test-libdbuspolicy1-ownership.cpp @@ -0,0 +1,71 @@ + +#include +#include +#include +#include +#include "internal/internal.h" + +const char* system_path = "tests/system.conf"; + +struct OwnershipTest { + bool expected_result; + uid_t user; + gid_t group; + const char* label; + const char* service; +}; + +struct OwnershipTest ownership_tests[]={ + (struct OwnershipTest){true, 0, 0, "test", "org.test.test1"}, + (struct OwnershipTest){true, 5009, 0, "test", "org.test.test1"}, + + (struct OwnershipTest){false, 0, 0, "test", "org.test.test2"}, + (struct OwnershipTest){false, 5009, 0, "test", "org.test.test2"}, + + (struct OwnershipTest){false, 0, 0, "test", "org.test.test3"}, + (struct OwnershipTest){false, 5009, 0, "test", "org.test.test3"}, + + (struct OwnershipTest){false, 0, 0, "test", "org.test.test4"}, + (struct OwnershipTest){true, 5009, 0, "test", "org.test.test4"}, + + (struct OwnershipTest){false, 0, 0, "test", "org.test.test5"}, + + (struct OwnershipTest){true, 0, 0, "test", "org.test.test6"}, + + (struct OwnershipTest){true, 0, 0, "test", "org.test.test7"}, + + (struct OwnershipTest){true, 0, 0, "test", "a.b.c"}, + (struct OwnershipTest){true, 0, 0, "test", "a.b"}, + (struct OwnershipTest){false, 0, 0, "test", "c"}, + (struct OwnershipTest){false, 0, 0, "test", "a.c"}, + (struct OwnershipTest){false, 0, 0, "test", "b.c"}, +}; + +void ownershipTest_print(struct OwnershipTest* t, bool result) { + printf("uid = %lu, gid = %lu, label = %s, service = %s, expected = %d, result = %d", + (unsigned long)t->user, (unsigned long)t->group, t->label, t->service, !((int)t->expected_result), (int)result); +} + +bool ownership_test() { + unsigned i = 0; + bool flag = true; + bool ret = true; + __internal_init(false, "tests/system.conf"); + for (i = 0;i < sizeof(ownership_tests)/sizeof(struct OwnershipTest);i++) { + ret = __internal_can_own(false, ownership_tests[i].user, ownership_tests[i].group, ownership_tests[i].label, ownership_tests[i].service); + if ( (int)((ownership_tests[i].expected_result)) != ret) { + printf("[ERROR][%d] ownership test failed: %d %d ", i, (int)((ownership_tests[i].expected_result)), ret); + ownershipTest_print(&ownership_tests[i], ret); + printf("\n"); + flag = false; + } + } + return flag; +} + +int main () { + __internal_init_once(); + if (!ownership_test()) + return -1; +return 0; +} diff --git a/src/test-libdbuspolicy1-signal.cpp b/src/test-libdbuspolicy1-signal.cpp new file mode 100644 index 0000000..19cc2e9 --- /dev/null +++ b/src/test-libdbuspolicy1-signal.cpp @@ -0,0 +1,51 @@ + +#include +#include +#include +#include +#include "internal/internal.h" + +const char* system_path = "tests/system.conf"; + +struct SignalTest { + bool expected_result; + uid_t user; + gid_t group; + const char* label; + const char* dest; + const char* interface; +}; + +struct SignalTest signal_tests[]={ + (struct SignalTest){true, 0, 0, "test", "bli.bla.blubb test.test1 test.tes3", "/an/object/path"}, + (struct SignalTest){false, 5010, 0, "test", "bli.bla.blubb", "/an/object/path"}, +}; + +void signalTest_print(struct SignalTest* t, bool result) { + printf("uid = %lu, gid = %lu, label = %s, dest = %s, interface = %s, expected = %d, result = %d", + (unsigned long)t->user, (unsigned long)t->group, t->label, t->dest, t->interface, !((int)t->expected_result), (int)result); +} + +bool signal_test() { + unsigned i = 0; + bool flag = true; + bool ret = true; + __internal_init(false, "tests/system.conf"); + for (i = 0;i < sizeof(signal_tests)/sizeof(struct SignalTest);i++) { + ret = __internal_can_send(false, signal_tests[i].user, signal_tests[i].group, signal_tests[i].label, signal_tests[i].dest, NULL, signal_tests[i].interface, NULL, DBUSPOLICY_MESSAGE_TYPE_SIGNAL); + if ( (int)((signal_tests[i].expected_result)) != ret) { + printf("[ERROR][%d] signal test failed: %d %d ", i, (int)((signal_tests[i].expected_result)), ret); + signalTest_print(&signal_tests[i], ret); + printf("\n"); + flag = false; + } + } + return flag; +} + +int main () { + __internal_init_once(); + if (!signal_test()) + return -1; +return 0; +} diff --git a/tests/system.conf b/tests/system.conf new file mode 100644 index 0000000..0ba5b64 --- /dev/null +++ b/tests/system.conf @@ -0,0 +1,83 @@ + + + + + + + + + system + + + dbus + + + + + + + + + /usr/lib/dbus/dbus-daemon-launch-helper + + + /var/run/dbus/pid + + + + + + EXTERNAL + + + kernel:path=/sys/fs/kdbus/0-system/bus;unix:path=/var/run/dbus/system_bus_socket + + + + + + + + + + + + + + + + + + + + + + + + + + + + system.d + + + system-local.conf + + contexts/dbus_contexts + + diff --git a/tests/system.d/cynara.test.conf b/tests/system.d/cynara.test.conf new file mode 100644 index 0000000..e988385 --- /dev/null +++ b/tests/system.d/cynara.test.conf @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/tests/system.d/methods.test.conf b/tests/system.d/methods.test.conf new file mode 100644 index 0000000..7928557 --- /dev/null +++ b/tests/system.d/methods.test.conf @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/system.d/ownerships.test.conf b/tests/system.d/ownerships.test.conf new file mode 100644 index 0000000..7a6e625 --- /dev/null +++ b/tests/system.d/ownerships.test.conf @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/system.d/signals.test.conf b/tests/system.d/signals.test.conf new file mode 100644 index 0000000..e44decf --- /dev/null +++ b/tests/system.d/signals.test.conf @@ -0,0 +1,13 @@ + + + + + + + + + + + + -- 2.7.4 From 4b067f8dd7e2a60117b18525678a360a76a51924 Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Fri, 20 May 2016 17:23:39 +0200 Subject: [PATCH 07/16] libdbuspolicyt refactoring to meet Tizen coding style Change-Id: I9765dd74342d695d50b223185c71a84d7f0f1aa3 --- src/dbuspolicy1/libdbuspolicy1.h | 42 +++---- src/internal/cynara.cpp | 2 +- src/internal/cynara.hpp | 2 +- src/internal/cynara_mockup.cpp | 2 +- src/internal/internal.cpp | 44 +++---- src/internal/naive_policy_checker.cpp | 4 +- src/internal/naive_policy_checker.hpp | 2 +- src/internal/naive_policy_db.cpp | 2 +- src/internal/naive_policy_db.hpp | 2 +- src/internal/policy.cpp | 2 +- src/internal/policy.hpp | 2 +- src/internal/xml_parser.cpp | 2 +- src/internal/xml_parser.hpp | 22 ++-- src/internal/xml_policy.hpp | 2 +- src/libdbuspolicy1.c | 226 +++++++++++++++++----------------- src/test-libdbuspolicy1-method.cpp | 2 +- 16 files changed, 180 insertions(+), 180 deletions(-) diff --git a/src/dbuspolicy1/libdbuspolicy1.h b/src/dbuspolicy1/libdbuspolicy1.h index cc0040e..1b15b19 100644 --- a/src/dbuspolicy1/libdbuspolicy1.h +++ b/src/dbuspolicy1/libdbuspolicy1.h @@ -76,15 +76,15 @@ void dbuspolicy1_free(void* configuration); \param requested_reply (future implementation) */ int dbuspolicy1_check_out(void* configuration, - const char *destination, - const char *sender, - const char *path, - const char *interface, - const char *member, - int message_type, - const char *error_name, - int reply_serial, - int requested_reply); + const char *destination, + const char *sender, + const char *path, + const char *interface, + const char *member, + int message_type, + const char *error_name, + int reply_serial, + int requested_reply); /*! Check policy for incoming message @@ -103,18 +103,18 @@ int dbuspolicy1_check_out(void* configuration, \param requested_reply (future implementation) */ int dbuspolicy1_check_in(void* configuration, - const char *destination, - const char *sender, - const char *sender_label, - uid_t sender_uid, - gid_t sender_gid, - const char *path, - const char *interface, - const char *member, - int message_type, - const char *error_name, - int reply_serial, - int requested_reply); + const char *destination, + const char *sender, + const char *sender_label, + uid_t sender_uid, + gid_t sender_gid, + const char *path, + const char *interface, + const char *member, + int message_type, + const char *error_name, + int reply_serial, + int requested_reply); /*! Check policy for service ownership diff --git a/src/internal/cynara.cpp b/src/internal/cynara.cpp index ce191c0..ca4c79d 100644 --- a/src/internal/cynara.cpp +++ b/src/internal/cynara.cpp @@ -5,7 +5,7 @@ #include #include -using namespace _ldp_cynara; +using namespace ldp_cynara; pthread_mutex_t Cynara::__mutex = PTHREAD_MUTEX_INITIALIZER; diff --git a/src/internal/cynara.hpp b/src/internal/cynara.hpp index 684e2a9..84fbbd2 100644 --- a/src/internal/cynara.hpp +++ b/src/internal/cynara.hpp @@ -23,7 +23,7 @@ #include -namespace _ldp_cynara { +namespace ldp_cynara { enum class CynaraResult : uint8_t { ALLOW, DENY, diff --git a/src/internal/cynara_mockup.cpp b/src/internal/cynara_mockup.cpp index 4392df2..520761f 100644 --- a/src/internal/cynara_mockup.cpp +++ b/src/internal/cynara_mockup.cpp @@ -4,7 +4,7 @@ #include #include -using namespace _ldp_cynara; +using namespace ldp_cynara; Cynara::Cynara() { } diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index 2b030fc..b17cdec 100644 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -24,7 +24,7 @@ #include "../libdbuspolicy1-private.h" -static _ldp_xml_parser::NaivePolicyChecker policy_checker; +static ldp_xml_parser::NaivePolicyChecker policy_checker; static const char* get_str(const char* const szstr) { return (szstr != NULL) ? szstr : ""; @@ -55,9 +55,9 @@ static const char** get_strv(const char *s, const char** result) { int __internal_init(bool bus_type, const char* const config_name) { - _ldp_xml_parser::XmlParser p; + ldp_xml_parser::XmlParser p; p.registerAdapter(policy_checker.generateAdapter()); - auto err = p.parse_policy(bus_type, get_str(config_name)); + auto err = p.parsePolicy(bus_type, get_str(config_name)); return err.get(); } @@ -89,14 +89,14 @@ void __internal_exit() } int __internal_can_send(bool bus_type, - const uid_t user, - const gid_t group, - const char* const label, - const char* const destination, - const char* const path, - const char* const interface, - const char* const member, - int type) + const uid_t user, + const gid_t group, + const char* const label, + const char* const destination, + const char* const path, + const char* const interface, + const char* const member, + int type) { const char* names[KDBUS_CONN_MAX_NAMES+1]; const char** ns = get_strv(destination, names); @@ -105,20 +105,20 @@ int __internal_can_send(bool bus_type, std::cout << "Destination too long: "<(type), _ldp_xml_parser::MessageDirection::SEND); + return policy_checker.check(bus_type, user, group, label, ns, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND); } int __internal_can_send_multi_dest(bool bus_type, - const uid_t user, - const gid_t group, - const char* const label, - const char** const destination, - const char* const path, - const char* const interface, - const char* const member, - int type) + const uid_t user, + const gid_t group, + const char* const label, + const char** const destination, + const char* const path, + const char* const interface, + const char* const member, + int type) { - return policy_checker.check(bus_type, user, group, label, destination, interface, member, path, static_cast<_ldp_xml_parser::MessageType>(type), _ldp_xml_parser::MessageDirection::SEND); + return policy_checker.check(bus_type, user, group, label, destination, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND); } int __internal_can_recv(bool bus_type, @@ -133,7 +133,7 @@ int __internal_can_recv(bool bus_type, { const char* names[KDBUS_CONN_MAX_NAMES+1]; const char** ns = get_strv(sender, names); - return policy_checker.check(bus_type, user, group, label, ns, interface, member, path, static_cast<_ldp_xml_parser::MessageType>(type), _ldp_xml_parser::MessageDirection::RECEIVE); + return policy_checker.check(bus_type, user, group, label, ns, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::RECEIVE); } int __internal_can_own(bool bus_type, diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index 5cf9d05..8fc311a 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -1,7 +1,7 @@ #include "naive_policy_checker.hpp" #include "cynara.hpp" #include "tslog.hpp" -using namespace _ldp_xml_parser; +using namespace ldp_xml_parser; DbAdapter& NaivePolicyChecker::generateAdapter() { if (!m_adapter) @@ -61,7 +61,7 @@ bool NaivePolicyChecker::parseDecision(Decision decision, return false; case Decision::CHECK: std::sprintf(uid_str, "%lu", (unsigned long)uid); - return _ldp_cynara::Cynara::check(label, privilege, uid_str) == _ldp_cynara::CynaraResult::ALLOW; + return ldp_cynara::Cynara::check(label, privilege, uid_str) == ldp_cynara::CynaraResult::ALLOW; } return false; diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index 4f6478f..4f75466 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -19,7 +19,7 @@ #include "policy.hpp" #include "naive_policy_db.hpp" -namespace _ldp_xml_parser +namespace ldp_xml_parser { class NaivePolicyChecker { private: diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index ae3c571..bccf9e3 100644 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -2,7 +2,7 @@ #include #include "tslog.hpp" -using namespace _ldp_xml_parser; +using namespace ldp_xml_parser; NaivePolicyDb::Policy::PolicyConstIterator::PolicyConstIterator(const std::vector& items, int position) : m_items(items), m_index(position) { diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp index 015eb13..fdbd0c1 100644 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -20,7 +20,7 @@ #include #include "policy.hpp" -namespace _ldp_xml_parser +namespace ldp_xml_parser { class NaivePolicyDb { public: diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index dcbde77..021a4be 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -6,7 +6,7 @@ #include #include -using namespace _ldp_xml_parser; +using namespace ldp_xml_parser; static const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL"}; static const char* message_dir[] = { "ANY", "SEND", "RECEIVE"}; diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp index 848c53c..4909e4e 100644 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -21,7 +21,7 @@ #include #define MAX_LOG_LINE 1024 -namespace _ldp_xml_parser +namespace ldp_xml_parser { enum class MessageType : uint8_t { ANY = 0, diff --git a/src/internal/xml_parser.cpp b/src/internal/xml_parser.cpp index 2c793f6..5606a33 100644 --- a/src/internal/xml_parser.cpp +++ b/src/internal/xml_parser.cpp @@ -1,3 +1,3 @@ #include "xml_parser.hpp" -std::set _ldp_xml_parser::XmlParser::m_parsed; +std::set ldp_xml_parser::XmlParser::__parsed; diff --git a/src/internal/xml_parser.hpp b/src/internal/xml_parser.hpp index 948f2c6..26aee38 100644 --- a/src/internal/xml_parser.hpp +++ b/src/internal/xml_parser.hpp @@ -28,26 +28,26 @@ #include "tslog.hpp" #include "policy.hpp" -namespace _ldp_xml_parser +namespace ldp_xml_parser { class XmlParser : boost::noncopyable { public: - ErrCode parse_policy(bool bus, + ErrCode parsePolicy(bool bus, std::string const &fname) { ErrCode err = parse(bus, fname); return err; } void registerAdapter(DbAdapter& adapter) { - m_adapter = &adapter; + __adapter = &adapter; } private: //IO operation - static std::set m_parsed; + static std::set __parsed; - DbAdapter* m_adapter; + DbAdapter* __adapter; //Data obtained from XML ErrCode parse(bool bus, std::string const &filename) { @@ -69,9 +69,9 @@ namespace _ldp_xml_parser if (tslog::verbose()) std::cout << "=== XML PARSING BEGIN === : " << filename << '\n'; - errparam = xml_parse(bus, filename); + errparam = parseXml(bus, filename); if (first && errparam.first.get() >= 0 && errparam.second != "") - get_included_files(filename, errparam.second, included_files); + getIncludedFiles(filename, errparam.second, included_files); if (tslog::enabled()) { if (tslog::verbose()) @@ -82,7 +82,7 @@ namespace _ldp_xml_parser } //Get all the .conf files within included subdirectory, POSIX style as boost::filesystem is not header-only - void get_included_files(const std::string& filename, const std::string& incldir, std::vector& files) { + void getIncludedFiles(const std::string& filename, const std::string& incldir, std::vector& files) { DIR *dir; struct dirent *ent; std::string fname; @@ -108,15 +108,15 @@ namespace _ldp_xml_parser std::cout << "could not open directory " << dname << '\n'; } - std::pair xml_parse(bool bus, const std::string& filename) { + std::pair parseXml(bool bus, const std::string& filename) { std::pair ret; - if (m_parsed.insert(filename).second) + if (__parsed.insert(filename).second) try { boost::property_tree::ptree pt; read_xml(filename, pt); if (!pt.empty()) { - m_adapter->updateDb(bus, pt); + __adapter->updateDb(bus, pt); ret.second = pt.get("busconfig.includedir", ""); } } catch(const boost::property_tree::xml_parser::xml_parser_error& ex) { diff --git a/src/internal/xml_policy.hpp b/src/internal/xml_policy.hpp index 48fa7f9..2e790ed 100644 --- a/src/internal/xml_policy.hpp +++ b/src/internal/xml_policy.hpp @@ -31,7 +31,7 @@ enum class TreeType : uint8_t { OWN }; -namespace _ldp_xml_parser +namespace ldp_xml_parser { namespace { static const std::string ROOT_FIELD = "busconfig"; diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 1878d9e..7ad44dd 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -57,48 +57,48 @@ typedef unsigned long dbus_uid_t; typedef unsigned long dbus_gid_t; struct kconn { - int fd; - uint64_t id; - char *pool; + int fd; + uint64_t id; + char *pool; } g_conn[2]; struct udesc { - char user[256]; - dbus_uid_t uid; - char group[256]; - dbus_gid_t gid; - char label[256]; + char user[256]; + dbus_uid_t uid; + char group[256]; + dbus_gid_t gid; + char label[256]; } g_udesc; static int kdbus_open_bus(const char *path) { - return open(path, O_RDWR|O_NOCTTY|O_LARGEFILE|O_CLOEXEC); + return open(path, O_RDWR|O_NOCTTY|O_LARGEFILE|O_CLOEXEC); } static int kdbus_hello(bool bus_type, uint64_t hello_flags, uint64_t attach_flags_send, uint64_t attach_flags_recv) { - struct kdbus_cmd_hello cmd; + struct kdbus_cmd_hello cmd; int fd = g_conn[bus_type].fd; - cmd.size = sizeof(cmd); - cmd.flags = hello_flags; - cmd.attach_flags_send = attach_flags_send; - cmd.attach_flags_recv = attach_flags_recv; - cmd.pool_size = KDBUS_POOL_SIZE; + cmd.size = sizeof(cmd); + cmd.flags = hello_flags; + cmd.attach_flags_send = attach_flags_send; + cmd.attach_flags_recv = attach_flags_recv; + cmd.pool_size = KDBUS_POOL_SIZE; - if (ioctl(fd, KDBUS_CMD_HELLO, &cmd) < 0) - return -errno; + if (ioctl(fd, KDBUS_CMD_HELLO, &cmd) < 0) + return -errno; - g_conn[bus_type].id = cmd.id; - if (MAP_FAILED == (g_conn[bus_type].pool = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0))) - return -errno; + g_conn[bus_type].id = cmd.id; + if (MAP_FAILED == (g_conn[bus_type].pool = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0))) + return -errno; - return 0; + return 0; } static bool kdbus_is_unique_id(const char* name) { - return ':' == name[0]; + return ':' == name[0]; } static uint64_t kdbus_unique_id(char const *name) @@ -115,74 +115,74 @@ static uint64_t kdbus_unique_id(char const *name) static bool dbuspolicy_init_once(void) { - struct passwd pwent; - struct passwd *pwd; - struct group grent; - struct group *gg; - char buf[1024]; - int attr_fd; - int r; + struct passwd pwent; + struct passwd *pwd; + struct group grent; + struct group *gg; + char buf[1024]; + int attr_fd; + int r; - attr_fd = open("/proc/self/attr/current", O_RDONLY); - if (attr_fd < 0) - return -1; - r = read(attr_fd, buf, sizeof(buf)); + attr_fd = open("/proc/self/attr/current", O_RDONLY); + if (attr_fd < 0) + return -1; + r = read(attr_fd, buf, sizeof(buf)); - close(attr_fd); + close(attr_fd); - if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */ - return true; + if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */ + return true; - g_udesc.uid = getuid(); - g_udesc.gid = getgid(); + g_udesc.uid = getuid(); + g_udesc.gid = getgid(); - snprintf(g_udesc.label, r + 1 /* additional byte for \0 */, "%s", buf); - if (getpwuid_r(g_udesc.uid, &pwent, buf, sizeof(buf), &pwd)) - return true; + snprintf(g_udesc.label, r + 1 /* additional byte for \0 */, "%s", buf); + if (getpwuid_r(g_udesc.uid, &pwent, buf, sizeof(buf), &pwd)) + return true; - if (getgrgid_r(g_udesc.gid, &grent, buf, sizeof(buf), &gg)) - return true; + if (getgrgid_r(g_udesc.gid, &grent, buf, sizeof(buf), &gg)) + return true; - if (!pwd || !gg) - return false; + if (!pwd || !gg) + return false; - snprintf(g_udesc.user, sizeof(g_udesc.user), "%s", pwd->pw_name); - snprintf(g_udesc.group, sizeof(g_udesc.group), "%s", gg->gr_name); + snprintf(g_udesc.user, sizeof(g_udesc.user), "%s", pwd->pw_name); + snprintf(g_udesc.group, sizeof(g_udesc.group), "%s", gg->gr_name); __internal_init_once(); - return false; + return false; } static int bus_path_resolve(const char *bus_path, char *resolved_path, unsigned resolved_path_size, unsigned int *bus_type) { - char rp[PATH_MAX]; - char *p; - const char user_suffix[] = "-user/bus"; - int suffix_pos; + char rp[PATH_MAX]; + char *p; + const char user_suffix[] = "-user/bus"; + int suffix_pos; - p = realpath(bus_path, rp); - if (!p) - return -1; + p = realpath(bus_path, rp); + if (!p) + return -1; - if (0 != strncmp(p, KDBUS_PATH_PREFIX, strlen(KDBUS_PATH_PREFIX))) - return -1; + if (0 != strncmp(p, KDBUS_PATH_PREFIX, strlen(KDBUS_PATH_PREFIX))) + return -1; - if (0 == strcmp(p, KDBUS_SYSTEM_BUS_PATH)) { - *bus_type = SYSTEM_BUS; - } else { - suffix_pos = strlen(p) - strlen(user_suffix); - if (suffix_pos < 0) - return -1; + if (0 == strcmp(p, KDBUS_SYSTEM_BUS_PATH)) { + *bus_type = SYSTEM_BUS; + } else { + suffix_pos = strlen(p) - strlen(user_suffix); + if (suffix_pos < 0) + return -1; - if (0 != strcmp(p + suffix_pos, user_suffix)) - return -1; + if (0 != strcmp(p + suffix_pos, user_suffix)) + return -1; - *bus_type = SESSION_BUS; - } + *bus_type = SESSION_BUS; + } - snprintf(resolved_path, resolved_path_size, "%s", p); - return 0; + snprintf(resolved_path, resolved_path_size, "%s", p); + return 0; } static bool init_once_done = false; @@ -260,15 +260,15 @@ static bool configuration_bus_type(struct kconn const *configuration) { return c * Description. **/ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, - const char *destination, - const char *sender, - const char *path, - const char *interface, - const char *member, - int message_type, - const char *error_name, - int reply_serial, - int requested_reply) + const char *destination, + const char *sender, + const char *path, + const char *interface, + const char *member, + int message_type, + const char *error_name, + int reply_serial, + int requested_reply) { char const *label = NULL; const char* k_names[KDBUS_CONN_MAX_NAMES+1]; @@ -332,23 +332,23 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, for (item = conn_info->items; (uintptr_t)item < items_end; item = (typeof(item))ALIGN8((uintptr_t)item + (unsigned)item->size)) switch ((unsigned)item->type) { - case KDBUS_ITEM_CREDS: - uid_n = item->creds.euid; - gid_n = item->creds.egid; - break; - case KDBUS_ITEM_SECLABEL: - label = item->str; - break; - case KDBUS_ITEM_OWNED_NAME: - empty_names = false; - if (r <= 0) - k_names[k_i++] = item->name.name; - break; + case KDBUS_ITEM_CREDS: + uid_n = item->creds.euid; + gid_n = item->creds.egid; + break; + case KDBUS_ITEM_SECLABEL: + label = item->str; + break; + case KDBUS_ITEM_OWNED_NAME: + empty_names = false; + if (r <= 0) + k_names[k_i++] = item->name.name; + break; } } - if (empty_names) - r = __internal_can_send(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, destination, path, interface, member, message_type); + if (empty_names) + r = __internal_can_send(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, destination, path, interface, member, message_type); else { k_names[k_i++] = NULL; r = __internal_can_send_multi_dest(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, k_names, path, interface, member, message_type); @@ -364,7 +364,7 @@ end: ioctl(g_conn[bus_type].fd, KDBUS_CMD_FREE, &cmd.cmd_free); __internal_exit(); - return r; + return r; } /** @@ -375,36 +375,36 @@ end: * Description. **/ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, - const char *destination, - const char *sender, - const char *sender_label, - uid_t sender_uid, - gid_t sender_gid, - const char *path, - const char *interface, - const char *member, - int message_type, - const char *error_name, - int reply_serial, - int requested_reply) + const char *destination, + const char *sender, + const char *sender_label, + uid_t sender_uid, + gid_t sender_gid, + const char *path, + const char *interface, + const char *member, + int message_type, + const char *error_name, + int reply_serial, + int requested_reply) { - int r; + int r; bool bus_type = configuration_bus_type(configuration); __internal_enter(); - r = __internal_can_send(bus_type, sender_uid, sender_gid, sender_label, destination, path, interface, member, message_type); + r = __internal_can_send(bus_type, sender_uid, sender_gid, sender_label, destination, path, interface, member, message_type); if (r <= 0) goto end; if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { r = __internal_can_recv(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, sender, path, interface, member, message_type); - if (r <= 0) - goto end; - } + if (r <= 0) + goto end; + } end: - __internal_exit(); - return r; + __internal_exit(); + return r; } /** @@ -419,7 +419,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* cons int r; bool bus_type = configuration_bus_type(configuration); __internal_enter(); - r = __internal_can_own(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, service); + r = __internal_can_own(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, service); __internal_exit(); return r; } diff --git a/src/test-libdbuspolicy1-method.cpp b/src/test-libdbuspolicy1-method.cpp index 8aa3738..d1116da 100644 --- a/src/test-libdbuspolicy1-method.cpp +++ b/src/test-libdbuspolicy1-method.cpp @@ -6,7 +6,7 @@ #include "internal/internal.h" #include "internal/policy.hpp" -using namespace _ldp_xml_parser; +using namespace ldp_xml_parser; const char* system_path = "tests/system.conf"; -- 2.7.4 From 54a071e9e09e08497ac6c01c511372f722638b38 Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Mon, 30 May 2016 15:43:01 +0200 Subject: [PATCH 08/16] Fix: xml parser + minor fixes Fixed xml parser bug that causes that only first works as it should. Removed deadlock in init when logs are enabled Minor refactors Change-Id: I94c97efff478cf919cc5809f106bca1bb1465889 --- src/internal/policy.cpp | 5 +++-- src/internal/policy.hpp | 2 +- src/internal/xml_parser.hpp | 20 +++++++++++--------- src/libdbuspolicy1.c | 10 +++++++--- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index 021a4be..da65a5c 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -1,6 +1,5 @@ #include "policy.hpp" #include "naive_policy_db.hpp" -//#include "tslog.hpp" #include #include #include @@ -192,7 +191,7 @@ void DbAdapter::xmlTraversal(bool bus, } } -void DbAdapter::updateDb(bool bus, boost::property_tree::ptree& xmlTree) { +void DbAdapter::updateDb(bool bus, boost::property_tree::ptree& xmlTree, std::vector& incl_dirs) { const auto& children = xmlTree.get_child("busconfig"); PolicyType policy_type; PolicyTypeValue policy_type_value; @@ -201,6 +200,8 @@ void DbAdapter::updateDb(bool bus, boost::property_tree::ptree& xmlTree) { __tag_state = POLICY; __attr = false; xmlTraversal(bus, x.second, POLICY, policy_type, policy_type_value); + } else if (x.first == "includedir") { + incl_dirs.push_back(x.second.data()); } } } diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp index 4909e4e..aa93cc8 100644 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -186,7 +186,7 @@ namespace ldp_xml_parser int level = 0); public: DbAdapter(NaivePolicyDb& system, NaivePolicyDb& session); - void updateDb(bool bus, boost::property_tree::ptree& xmlTree); + void updateDb(bool bus, boost::property_tree::ptree& xmlTree, std::vector& incl_dirs); static uid_t convertToUid(const char* user); static gid_t convertToGid(const char* group); }; diff --git a/src/internal/xml_parser.hpp b/src/internal/xml_parser.hpp index 26aee38..0dfb668 100644 --- a/src/internal/xml_parser.hpp +++ b/src/internal/xml_parser.hpp @@ -23,7 +23,6 @@ #include #include #include -//#include "xml_policy.hpp" #include "libdbuspolicy1-private.hpp" #include "tslog.hpp" #include "policy.hpp" @@ -65,13 +64,14 @@ namespace ldp_xml_parser ErrCode parse(bool bus, bool first, const std::string& filename, std::vector& included_files) { std::pair errparam; - + std::vector incl_dirs; if (tslog::verbose()) std::cout << "=== XML PARSING BEGIN === : " << filename << '\n'; - errparam = parseXml(bus, filename); - if (first && errparam.first.get() >= 0 && errparam.second != "") - getIncludedFiles(filename, errparam.second, included_files); + errparam = parseXml(bus, filename, incl_dirs); + for (int i = 0; i < incl_dirs.size(); i++) { + getIncludedFiles(filename, incl_dirs[i], included_files); + } if (tslog::enabled()) { if (tslog::verbose()) @@ -88,7 +88,10 @@ namespace ldp_xml_parser std::string fname; std::copy(filename.begin(), filename.end(), fname.begin()); std::string dname = dirname(const_cast(fname.c_str())); - dname += (std::string("/") + incldir); + if (incldir[0] != '/') + dname += (std::string("/") + incldir); + else + dname = incldir; files.clear(); if((dir = opendir(dname.c_str())) != NULL) { while((ent = readdir(dir)) != NULL) { @@ -108,7 +111,7 @@ namespace ldp_xml_parser std::cout << "could not open directory " << dname << '\n'; } - std::pair parseXml(bool bus, const std::string& filename) { + std::pair parseXml(bool bus, const std::string& filename, std::vector& incl_dirs) { std::pair ret; if (__parsed.insert(filename).second) @@ -116,8 +119,7 @@ namespace ldp_xml_parser boost::property_tree::ptree pt; read_xml(filename, pt); if (!pt.empty()) { - __adapter->updateDb(bus, pt); - ret.second = pt.get("busconfig.includedir", ""); + __adapter->updateDb(bus, pt, incl_dirs); } } catch(const boost::property_tree::xml_parser::xml_parser_error& ex) { ret.first = ErrCode::error(ex.what()); diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 7ad44dd..c274833 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -219,13 +219,17 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) goto err_close; rp = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_PRIMARY : SESSION_BUS_CONF_FILE_PRIMARY); - rs = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_SECONDARY : SESSION_BUS_CONF_FILE_SECONDARY); + if (rp < 0) + rs = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_SECONDARY : SESSION_BUS_CONF_FILE_SECONDARY); + else + rs = 1; + + pthread_mutex_unlock(&g_mutex); __internal_init_flush_logs(); - if ((rp & rs) < 0) /* when both negative */ + if (rp < 0 && rs < 0) /* when both negative */ goto err_close; - pthread_mutex_unlock(&g_mutex); return &g_conn[bus_type]; err_close: -- 2.7.4 From 2dbfad71132cfc164257f53391b6ef7c6b3bfcd0 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Tue, 14 Jun 2016 18:04:05 +0900 Subject: [PATCH 09/16] svace Change-Id: I745773662dc8578fce7590bd1b3bc2bde3ede5ed Signed-off-by: sanghyeok.oh --- src/internal/naive_policy_checker.cpp | 2 +- src/internal/policy.cpp | 10 ++++++++-- src/libdbuspolicy1.c | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index 8fc311a..6489a6d 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -60,7 +60,7 @@ bool NaivePolicyChecker::parseDecision(Decision decision, case Decision::DENY: return false; case Decision::CHECK: - std::sprintf(uid_str, "%lu", (unsigned long)uid); + std::snprintf(uid_str, sizeof(uid_str) - 1, "%lu", (unsigned long)uid); return ldp_cynara::Cynara::check(label, privilege, uid_str) == ldp_cynara::CynaraResult::ALLOW; } diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index da65a5c..20076e5 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -59,7 +59,7 @@ uid_t DbAdapter::convertToUid(const char* user) { struct passwd pwent; struct passwd *pwd; char buf[1024]; - if (getpwnam_r(user, &pwent, buf, sizeof(buf), &pwd) && pwd) + if (getpwnam_r(user, &pwent, buf, sizeof(buf), &pwd) || !pwd) return (uid_t)-1; return pwd->pw_uid; @@ -73,7 +73,7 @@ gid_t DbAdapter::convertToGid(const char* group) { struct group grent; struct group *gg; char buf[1024]; - if (getgrnam_r(group, &grent, buf, sizeof(buf), &gg) && gg) + if (getgrnam_r(group, &grent, buf, sizeof(buf), &gg) || !gg) return (gid_t)-1; return gg->gr_gid; @@ -259,6 +259,9 @@ ItemType ItemOwn::getType() const { } bool ItemOwn::match(const Item* item) const { const ItemOwn* it = dynamic_cast(item); + if (!it) + return false; + if (__is_prefix) { int i = 0; if (!__name) @@ -339,6 +342,9 @@ ItemSendReceive::~ItemSendReceive() { bool ItemSendReceive::match(const Item* item) const { const ItemSendReceive* it = dynamic_cast(item); + if (!it) + return false; + if (__type != MessageType::ANY && __type != it->__type) return false; diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index c274833..867ce2e 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -107,7 +107,7 @@ static uint64_t kdbus_unique_id(char const *name) unsigned i = 2; int c; while (!(c = name[++i] - '0')); - res = c; + res = (uint64_t)c; while ((c = (int)(name[++i]) - '0') > 0) res = res*10 + c; return res; -- 2.7.4 From 4687157241e6c616a337130b842e6f6fb5a5379e Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Wed, 1 Jun 2016 19:06:14 +0200 Subject: [PATCH 10/16] Added test description to make test better described Change-Id: I90909b035da16dce39ac28278c1561ecf0396335 --- src/test-libdbuspolicy1-method.cpp | 5 +++++ src/test-libdbuspolicy1-ownership.cpp | 6 +++++- src/test-libdbuspolicy1-signal.cpp | 5 ++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/test-libdbuspolicy1-method.cpp b/src/test-libdbuspolicy1-method.cpp index d1116da..58424d1 100644 --- a/src/test-libdbuspolicy1-method.cpp +++ b/src/test-libdbuspolicy1-method.cpp @@ -23,6 +23,11 @@ struct MethodTest { MessageDirection recv_send; }; +/** + * This test set tests ability to parse xml db + * and check method call allowance in many use cases + */ + struct MethodTest method_tests[]={ (struct MethodTest){true, 0, 0, "test", "org.test.test2", NULL, "org.test.Itest1", "DoIt", MessageType::METHOD_CALL, MessageDirection::SEND}, (struct MethodTest){true, 0, 0, "test", "org.test.test3", NULL, "org.test.Itest1", "DoIt", MessageType::METHOD_CALL, MessageDirection::RECEIVE}, diff --git a/src/test-libdbuspolicy1-ownership.cpp b/src/test-libdbuspolicy1-ownership.cpp index 30c3fa7..bf97fc5 100644 --- a/src/test-libdbuspolicy1-ownership.cpp +++ b/src/test-libdbuspolicy1-ownership.cpp @@ -14,7 +14,11 @@ struct OwnershipTest { const char* label; const char* service; }; - +/** + * This test set tests ability to parse xml db + * and check ownership privilege in many use cases + * including prefix feature + */ struct OwnershipTest ownership_tests[]={ (struct OwnershipTest){true, 0, 0, "test", "org.test.test1"}, (struct OwnershipTest){true, 5009, 0, "test", "org.test.test1"}, diff --git a/src/test-libdbuspolicy1-signal.cpp b/src/test-libdbuspolicy1-signal.cpp index 19cc2e9..af38490 100644 --- a/src/test-libdbuspolicy1-signal.cpp +++ b/src/test-libdbuspolicy1-signal.cpp @@ -15,7 +15,10 @@ struct SignalTest { const char* dest; const char* interface; }; - +/** + * This test set tests ability to parse xml db + * and check signal call allowance in many use cases + */ struct SignalTest signal_tests[]={ (struct SignalTest){true, 0, 0, "test", "bli.bla.blubb test.test1 test.tes3", "/an/object/path"}, (struct SignalTest){false, 5010, 0, "test", "bli.bla.blubb", "/an/object/path"}, -- 2.7.4 From f47c8614ec26f3a10e876a58981b783aa7e5bd84 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Fri, 15 Jul 2016 14:20:13 +0900 Subject: [PATCH 11/16] add LICENSE.APACHE2.0 Change-Id: Icb8da89c7d0413a6b2bdb79cb59cb75edb9f9b5c --- LICENSE.APACHE2.0 | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 LICENSE.APACHE2.0 diff --git a/LICENSE.APACHE2.0 b/LICENSE.APACHE2.0 new file mode 100644 index 0000000..8aa906c --- /dev/null +++ b/LICENSE.APACHE2.0 @@ -0,0 +1,205 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + -- 2.7.4 From 3ff857655b4edcdd9e2f47c9a2e03d499d6983bd Mon Sep 17 00:00:00 2001 From: Krystian Kisielak Date: Fri, 22 Jul 2016 15:23:09 +0200 Subject: [PATCH 12/16] Fix copying to empty string. Change-Id: I0d2e111372cbe62fc3ebe9b4211e90b89a335dbf --- src/internal/xml_parser.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/internal/xml_parser.hpp b/src/internal/xml_parser.hpp index 0dfb668..7265172 100644 --- a/src/internal/xml_parser.hpp +++ b/src/internal/xml_parser.hpp @@ -85,8 +85,7 @@ namespace ldp_xml_parser void getIncludedFiles(const std::string& filename, const std::string& incldir, std::vector& files) { DIR *dir; struct dirent *ent; - std::string fname; - std::copy(filename.begin(), filename.end(), fname.begin()); + std::string fname(filename); std::string dname = dirname(const_cast(fname.c_str())); if (incldir[0] != '/') dname += (std::string("/") + incldir); -- 2.7.4 From ef999c25049fffac00b3bf78f84e4cb05414e641 Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Wed, 10 Aug 2016 13:02:04 +0200 Subject: [PATCH 13/16] Change in API to return internal errors by libdbuspolicy Libdbuspolicy now returns error codes via main API (check_out and check_int functions): DBUSPOLICY_RESULT_ALLOW 1 DBUSPOLICY_RESULT_DENY 0 DBUSPOLICY_RESULT_DEST_NOT_AVAILABLE -1 DBUSPOLICY_RESULT_KDBUS_ERROR -2 DBUSPOLICY_RESULT_CYNARA_ERROR -3 it is needed by gdbus and libdbus to make better descripted logs. Change-Id: I060de3ec0a767ee56dfd5ae8f6aa4475dd25ffa4 --- src/dbuspolicy1/libdbuspolicy1.h | 6 ++++++ src/internal/internal.cpp | 8 ++++---- src/internal/naive_policy_checker.cpp | 30 +++++++++++++++++++----------- src/internal/naive_policy_checker.hpp | 8 ++++---- src/internal/policy.hpp | 6 ++++++ src/libdbuspolicy1.c | 5 ++++- 6 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/dbuspolicy1/libdbuspolicy1.h b/src/dbuspolicy1/libdbuspolicy1.h index 1b15b19..14e5377 100644 --- a/src/dbuspolicy1/libdbuspolicy1.h +++ b/src/dbuspolicy1/libdbuspolicy1.h @@ -40,6 +40,12 @@ extern "C" { #define DBUSPOLICY_MESSAGE_TYPE_ERROR 3 #define DBUSPOLICY_MESSAGE_TYPE_SIGNAL 4 +#define DBUSPOLICY_RESULT_ALLOW 1 +#define DBUSPOLICY_RESULT_DENY 0 +#define DBUSPOLICY_RESULT_DEST_NOT_AVAILABLE -1 +#define DBUSPOLICY_RESULT_KDBUS_ERROR -2 +#define DBUSPOLICY_RESULT_CYNARA_ERROR -3 + struct udesc; /*! diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index b17cdec..84f25b1 100644 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -105,7 +105,7 @@ int __internal_can_send(bool bus_type, std::cout << "Destination too long: "<(type), ldp_xml_parser::MessageDirection::SEND); + return static_cast(policy_checker.check(bus_type, user, group, label, ns, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND)); } int __internal_can_send_multi_dest(bool bus_type, @@ -118,7 +118,7 @@ int __internal_can_send_multi_dest(bool bus_type, const char* const member, int type) { - return policy_checker.check(bus_type, user, group, label, destination, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND); + return static_cast(policy_checker.check(bus_type, user, group, label, destination, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND)); } int __internal_can_recv(bool bus_type, @@ -133,7 +133,7 @@ int __internal_can_recv(bool bus_type, { const char* names[KDBUS_CONN_MAX_NAMES+1]; const char** ns = get_strv(sender, names); - return policy_checker.check(bus_type, user, group, label, ns, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::RECEIVE); + return static_cast(policy_checker.check(bus_type, user, group, label, ns, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::RECEIVE)); } int __internal_can_own(bool bus_type, @@ -142,5 +142,5 @@ int __internal_can_own(bool bus_type, const char* const label, const char* const service) { - return policy_checker.check(bus_type, user, group, label, service); + return static_cast(policy_checker.check(bus_type, user, group, label, service)); } diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index 6489a6d..bc2a75d 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -43,7 +43,7 @@ NaivePolicyDb& NaivePolicyChecker::getPolicyDb(bool type) { return m_bus_db[type]; } -bool NaivePolicyChecker::parseDecision(Decision decision, +DecisionResult NaivePolicyChecker::parseDecision(Decision decision, uid_t uid, const char* label, const char* privilege) { @@ -55,23 +55,31 @@ bool NaivePolicyChecker::parseDecision(Decision decision, switch (decision) { case Decision::ALLOW: - return true; + return DecisionResult::ALLOW; case Decision::ANY: case Decision::DENY: - return false; + return DecisionResult::DENY; case Decision::CHECK: + { std::snprintf(uid_str, sizeof(uid_str) - 1, "%lu", (unsigned long)uid); - return ldp_cynara::Cynara::check(label, privilege, uid_str) == ldp_cynara::CynaraResult::ALLOW; + ldp_cynara::CynaraResult ret = ldp_cynara::Cynara::check(label, privilege, uid_str); + if (ret == ldp_cynara::CynaraResult::ALLOW) + return DecisionResult::ALLOW; + else if (ret == ldp_cynara::CynaraResult::DENY) + return DecisionResult::DENY; + else + return DecisionResult::CYNARA_ERROR; + } } - return false; + return DecisionResult::DENY; } NaivePolicyChecker::~NaivePolicyChecker() { delete m_adapter; } -bool NaivePolicyChecker::checkItem(bool bus_type, uid_t uid, gid_t gid, const char* label, const Item& item) { +DecisionResult NaivePolicyChecker::checkItem(bool bus_type, uid_t uid, gid_t gid, const char* label, const Item& item) { NaivePolicyDb& policy_db = getPolicyDb(bus_type); ItemType type = item.getType(); Decision ret = Decision::ANY; @@ -105,10 +113,10 @@ bool NaivePolicyChecker::checkItem(bool bus_type, uid_t uid, gid_t gid, const ch if (ret != Decision::ANY) return parseDecision(ret, uid, label, privilege); else - return false; + return DecisionResult::DENY; } -bool NaivePolicyChecker::check(bool bus_type, +DecisionResult NaivePolicyChecker::check(bool bus_type, uid_t uid, gid_t gid, const char* const label, @@ -120,10 +128,10 @@ bool NaivePolicyChecker::check(bool bus_type, if (tslog::enabled()) std::cout << err.what() << std::endl; } - return false; + return DecisionResult::DENY; } -bool NaivePolicyChecker::check(bool bus_type, +DecisionResult NaivePolicyChecker::check(bool bus_type, uid_t uid, gid_t gid, const char* const label, @@ -140,5 +148,5 @@ bool NaivePolicyChecker::check(bool bus_type, if (tslog::enabled()) std::cout << err.what() << std::endl; } - return false; + return DecisionResult::DENY; } diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index 4f75466..7e351a3 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -29,11 +29,11 @@ namespace ldp_xml_parser Decision checkPolicy(const NaivePolicyDb::Policy& policy, const Item& item, const char*& privilege); - bool parseDecision(Decision decision, + DecisionResult parseDecision(Decision decision, uid_t uid, const char* label, const char* privilege); - bool checkItem(bool bus_type, + DecisionResult checkItem(bool bus_type, uid_t uid, gid_t gid, const char* label, @@ -41,12 +41,12 @@ namespace ldp_xml_parser public: ~NaivePolicyChecker(); DbAdapter& generateAdapter(); - bool check(bool bus_type, + DecisionResult check(bool bus_type, uid_t uid, gid_t gid, const char* const label, const char* const name); - bool check(bool bus_type, + DecisionResult check(bool bus_type, uid_t uid, gid_t gid, const char* const label, diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp index aa93cc8..e76e3f2 100644 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -63,6 +63,12 @@ namespace ldp_xml_parser CHECK }; + enum class DecisionResult : int8_t { + CYNARA_ERROR = -3, + DENY = 0, + ALLOW + }; + union PolicyTypeValue { PolicyTypeValue(); PolicyTypeValue(ContextType type); diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 867ce2e..d37d285 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -314,7 +314,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, r = ioctl(g_conn[bus_type].fd, KDBUS_CMD_CONN_INFO, &cmd.cmd_info); if (r < 0) { - r = -errno; + if (errno == ENXIO || errno == ESRCH) + r = DBUSPOLICY_RESULT_DEST_NOT_AVAILABLE; + else + r = DBUSPOLICY_RESULT_KDBUS_ERROR; goto end; } -- 2.7.4 From d0d155e042e5548ff93e21cf576eba6b294e6d81 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Fri, 12 Aug 2016 11:51:05 +0200 Subject: [PATCH 14/16] kdbus: synchronize kdbus interface header between repositories Change-Id: I8e47edf8c61699a99523dead09bb3ef321894d31 --- src/kdbus.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/kdbus.h b/src/kdbus.h index fc1d77d..4fc44cb 100644 --- a/src/kdbus.h +++ b/src/kdbus.h @@ -5,8 +5,8 @@ * your option) any later version. */ -#ifndef _KDBUS_UAPI_H_ -#define _KDBUS_UAPI_H_ +#ifndef _UAPI_KDBUS_H_ +#define _UAPI_KDBUS_H_ #include #include @@ -374,6 +374,7 @@ enum kdbus_item_type { KDBUS_ITEM_ATTACH_FLAGS_RECV, KDBUS_ITEM_ID, KDBUS_ITEM_NAME, + KDBUS_ITEM_DST_ID, /* keep these item types in sync with KDBUS_ATTACH_* flags */ _KDBUS_ITEM_ATTACH_BASE = 0x1000, @@ -544,7 +545,7 @@ struct kdbus_msg_info { * reply to this message. The * KDBUS_CMD_SEND ioctl() will block * until the reply is received, and - * offset_reply in struct kdbus_msg will + * reply in struct kdbus_cmd_send will * yield the offset in the sender's pool * where the reply can be found. * This flag is only valid if @@ -853,6 +854,8 @@ enum kdbus_make_flags { * @KDBUS_NAME_QUEUE: Name should be queued if busy * @KDBUS_NAME_IN_QUEUE: Name is queued * @KDBUS_NAME_ACTIVATOR: Name is owned by a activator connection + * @KDBUS_NAME_PRIMARY: Primary owner of the name + * @KDBUS_NAME_ACQUIRED: Name was acquired/queued _now_ */ enum kdbus_name_flags { KDBUS_NAME_REPLACE_EXISTING = 1ULL << 0, @@ -860,6 +863,8 @@ enum kdbus_name_flags { KDBUS_NAME_QUEUE = 1ULL << 2, KDBUS_NAME_IN_QUEUE = 1ULL << 3, KDBUS_NAME_ACTIVATOR = 1ULL << 4, + KDBUS_NAME_PRIMARY = 1ULL << 5, + KDBUS_NAME_ACQUIRED = 1ULL << 6, }; /** @@ -976,4 +981,4 @@ enum kdbus_ioctl_type { struct kdbus_cmd_match), }; -#endif /* _KDBUS_UAPI_H_ */ +#endif /* _UAPI_KDBUS_H_ */ -- 2.7.4 From dc3048a8de00c01514c14ef465a87b8ca9a7c704 Mon Sep 17 00:00:00 2001 From: Krystian Kisielak Date: Fri, 10 Jun 2016 12:01:59 +0200 Subject: [PATCH 15/16] Prefix tree search for ownership rules, removed virtual methods. Change-Id: I90909b035da16dce39ac28278c1561eca0396335 Signed-off-by: Krystian Kisielak --- src/internal/internal.cpp | 97 +++++----- src/internal/naive_policy_checker.cpp | 240 +++++++++++++++++-------- src/internal/naive_policy_checker.hpp | 44 +++-- src/internal/naive_policy_db.cpp | 329 ++++++++++++++++++++++++++-------- src/internal/naive_policy_db.hpp | 101 ++++++++--- src/internal/policy.cpp | 329 ++++++++++++++++------------------ src/internal/policy.hpp | 108 +++++++---- 7 files changed, 792 insertions(+), 456 deletions(-) diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index 84f25b1..ec3e7cb 100644 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -27,38 +27,15 @@ static ldp_xml_parser::NaivePolicyChecker policy_checker; static const char* get_str(const char* const szstr) { - return (szstr != NULL) ? szstr : ""; -} - -static const char** get_strv(const char *s, const char** result) { - int i = 0; - unsigned k = 0; - if (s) { - while (s[i] && k < KDBUS_CONN_MAX_NAMES + 1) { - char c; - while ((c = s[i++]) && ' ' != c); - result[k++] = s; - s += i; - i = 0; - } - if (k >= KDBUS_CONN_MAX_NAMES + 1) - return NULL; - if (k) - result[k++] = NULL; - } - if (!k) { - result[0] = ""; - result[1] = NULL; - } - return result; + return (szstr != NULL) ? szstr : ""; } int __internal_init(bool bus_type, const char* const config_name) { - ldp_xml_parser::XmlParser p; + ldp_xml_parser::XmlParser p; p.registerAdapter(policy_checker.generateAdapter()); - auto err = p.parsePolicy(bus_type, get_str(config_name)); - return err.get(); + auto err = p.parsePolicy(bus_type, get_str(config_name)); + return err.get(); } pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -98,49 +75,59 @@ int __internal_can_send(bool bus_type, const char* const member, int type) { - const char* names[KDBUS_CONN_MAX_NAMES+1]; - const char** ns = get_strv(destination, names); - if (!ns) { + ldp_xml_parser::MatchItemSR matcher (interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND); + if (!matcher.addNames(destination)) { if (tslog::verbose()) std::cout << "Destination too long: "<(policy_checker.check(bus_type, user, group, label, ns, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND)); + + return static_cast(policy_checker.check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::SEND)); } int __internal_can_send_multi_dest(bool bus_type, - const uid_t user, - const gid_t group, - const char* const label, - const char** const destination, - const char* const path, - const char* const interface, - const char* const member, - int type) + const uid_t user, + const gid_t group, + const char* const label, + const char** const destination, + const char* const path, + const char* const interface, + const char* const member, + int type) { - return static_cast(policy_checker.check(bus_type, user, group, label, destination, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND)); + int i = 0; + ldp_xml_parser::MatchItemSR matcher (interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND); + if (destination) + while (destination[i++]) { + matcher.addName(destination[i]); + } + return static_cast(policy_checker.check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::SEND)); } int __internal_can_recv(bool bus_type, - const uid_t user, - const gid_t group, - const char* const label, - const char* const sender, - const char* const path, - const char* const interface, - const char* const member, - int type) + const uid_t user, + const gid_t group, + const char* const label, + const char* const sender, + const char* const path, + const char* const interface, + const char* const member, + int type) { - const char* names[KDBUS_CONN_MAX_NAMES+1]; - const char** ns = get_strv(sender, names); - return static_cast(policy_checker.check(bus_type, user, group, label, ns, interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::RECEIVE)); + ldp_xml_parser::MatchItemSR matcher (interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::RECEIVE); + if (!matcher.addNames(sender)) { + if (tslog::verbose()) + std::cout << "Sender too long: "<(policy_checker.check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::RECEIVE)); } int __internal_can_own(bool bus_type, - const uid_t user, - const gid_t group, - const char* const label, - const char* const service) + const uid_t user, + const gid_t group, + const char* const label, + const char* const service) { return static_cast(policy_checker.check(bus_type, user, group, label, service)); } diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index bc2a75d..45244d4 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -1,8 +1,23 @@ #include "naive_policy_checker.hpp" #include "cynara.hpp" #include "tslog.hpp" + using namespace ldp_xml_parser; +static void __log_item(const MatchItemSR& item) +{ + char tmp[MAX_LOG_LINE]; + const char* i_str = item.toString(tmp); + std::cout << "checkpolicy for ownership: " << i_str <toString(tmp); - std::cout << "-readed: " << i_str <match(&item)) { - if (tslog::verbose()) { - char tmp[MAX_LOG_LINE]; - const char* i_str = i->toString(tmp); - std::cout << "-matched: " << i_str <getPrivilege(); - return i->getDecision(); - } - } - return Decision::ANY; -} NaivePolicyDb& NaivePolicyChecker::getPolicyDb(bool type) { return m_bus_db[type]; @@ -71,7 +59,6 @@ DecisionResult NaivePolicyChecker::parseDecision(Decision decision, return DecisionResult::CYNARA_ERROR; } } - return DecisionResult::DENY; } @@ -79,74 +66,177 @@ NaivePolicyChecker::~NaivePolicyChecker() { delete m_adapter; } -DecisionResult NaivePolicyChecker::checkItem(bool bus_type, uid_t uid, gid_t gid, const char* label, const Item& item) { + + +DecisionResult NaivePolicyChecker::check(bool bus_type, + uid_t uid, + gid_t gid, + const char* const label, + const char* const name) { + return this->checkItemOwn(bus_type, uid, gid, label, name, ItemType::OWN); +} + +DecisionResult NaivePolicyChecker::check(bool bus_type, + uid_t uid, + gid_t gid, + const char* const label, + MatchItemSR& matcher, + ItemType type) { + return this->checkItemSR(bus_type, uid, gid, label, matcher, type); +} + +Decision NaivePolicyChecker::checkPolicySR(const NaivePolicyDb::PolicySR& policy, + const MatchItemSR& item, + const char*& privilege) +{ + if (tslog::verbose()) { + __log_item(item); + } + + for (auto i : policy) { + if (tslog::verbose()) { + char tmp[MAX_LOG_LINE]; + const char* i_str = i->getDecision().toString(tmp); + std::cout << "-readed: " << i_str; + i_str = i->toString(tmp); + std::cout << " " << i_str <match(item)) { + if (tslog::verbose()) { + char tmp[MAX_LOG_LINE]; + const char* i_str = i->getDecision().toString(tmp); + std::cout << "-matched: " << i_str; + const char* i_str2 = i->toString(tmp); + std::cout << " " << i_str2 <getDecision().getPrivilege(); + return i->getDecision().getDecision(); + } + } + + return Decision::ANY; +} + +Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& policy, const ItemOwn& item, const char*& privilege) { + + if (tslog::verbose()) { + __log_item(item); + } + const char *name = item.getName(); + const struct TreeNode *node = policy.getTreeRoot(); + int childIndex = 0; + assert(node); + Decision ret = Decision::ANY; + + while((name != NULL)&& (*name != '\0')){ + + + childIndex = char_map[*name]; + if(childIndex > 64){ + /*name contains forbidden char*/ + privilege = NULL; + return Decision::DENY; + } + /*Current node is prefix, remeber decision*/ + if(node->__is_prefix){ + ret = node->__decisionItem.getDecision();; + privilege = node->__decisionItem.getPrivilege(); + } + + /*Node for this letter dont exist*/ + if(node->children[childIndex] == NULL){ + goto out; + } + else{/*if it exists check for next letter in its child*/ + node = node->children[childIndex]; + } + + name++; + + } +out: + if(ret == Decision::ANY){ + privilege = node->__decisionItem.getPrivilege(); + return node->__decisionItem.getDecision(); + } + else + + return ret; + +} + + + + +DecisionResult NaivePolicyChecker::checkItemOwn(bool bus_type, uid_t uid, gid_t gid, const char* label, const ItemOwn& item, const ItemType type) { + NaivePolicyDb& policy_db = getPolicyDb(bus_type); - ItemType type = item.getType(); Decision ret = Decision::ANY; const char* privilege; - const NaivePolicyDb::Policy* curr_policy = NULL; - + const NaivePolicyDb::PolicyOwn* curr_policy = NULL; if (ret == Decision::ANY) { - curr_policy = policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::MANDATORY)); - if (curr_policy) - ret = checkPolicy(*curr_policy, item, privilege); + + if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::MANDATORY), curr_policy)) + + ret = checkPolicyOwn(*curr_policy, item, privilege); } if (ret == Decision::ANY) { - curr_policy = policy_db.getPolicy(type, PolicyType::USER, PolicyTypeValue(uid)); - if (curr_policy) - ret = checkPolicy(*curr_policy, item, privilege); + + if (policy_db.getPolicy(type, PolicyType::USER, PolicyTypeValue(uid), curr_policy)) + + ret = checkPolicyOwn(*curr_policy, item, privilege); } if (ret == Decision::ANY) { - curr_policy = policy_db.getPolicy(type, PolicyType::GROUP, PolicyTypeValue(gid)); - if (curr_policy) - ret = checkPolicy(*curr_policy, item, privilege); + + if (policy_db.getPolicy(type, PolicyType::GROUP, PolicyTypeValue(gid), curr_policy)) + + ret = checkPolicyOwn(*curr_policy, item, privilege); } if (ret == Decision::ANY) { - curr_policy = policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT)); - if (curr_policy) - ret = checkPolicy(*curr_policy, item, privilege); + + if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), curr_policy)) + + ret = checkPolicyOwn(*curr_policy, item, privilege); } + if (ret != Decision::ANY){ - if (ret != Decision::ANY) return parseDecision(ret, uid, label, privilege); + } else return DecisionResult::DENY; } -DecisionResult NaivePolicyChecker::check(bool bus_type, - uid_t uid, - gid_t gid, - const char* const label, - const char* const name) { - try { - ItemOwn item = ItemOwn(name); - return checkItem(bus_type, uid, gid, label, item); - } catch (std::runtime_error& err) { - if (tslog::enabled()) - std::cout << err.what() << std::endl; +DecisionResult NaivePolicyChecker::checkItemSR(bool bus_type, uid_t uid, gid_t gid, const char* label, const MatchItemSR& item, const ItemType type) { + NaivePolicyDb& policy_db = getPolicyDb(bus_type); + Decision ret = Decision::ANY; + const char* privilege; + const NaivePolicyDb::PolicySR* curr_policy = NULL; + + if (ret == Decision::ANY) { + if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::MANDATORY), curr_policy)) + ret = checkPolicySR(*curr_policy, item, privilege); } - return DecisionResult::DENY; -} -DecisionResult NaivePolicyChecker::check(bool bus_type, - uid_t uid, - gid_t gid, - const char* const label, - const char** const names, - const char* const interface, - const char* const member, - const char* const path, - MessageType message_type, - MessageDirection message_dir) { - try { - ItemSendReceive item = ItemSendReceive(names, interface, member, path, message_type, message_dir); - return checkItem(bus_type, uid, gid, label, item); - } catch (std::runtime_error& err) { - if (tslog::enabled()) - std::cout << err.what() << std::endl; + if (ret == Decision::ANY) { + if (policy_db.getPolicy(type, PolicyType::USER, PolicyTypeValue(uid), curr_policy)) + ret = checkPolicySR(*curr_policy, item, privilege); } - return DecisionResult::DENY; + + if (ret == Decision::ANY) { + if (policy_db.getPolicy(type, PolicyType::GROUP, PolicyTypeValue(gid), curr_policy)) + ret = checkPolicySR(*curr_policy, item, privilege); + } + + if (ret == Decision::ANY) { + if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), curr_policy)) + ret = checkPolicySR(*curr_policy, item, privilege); + } + + if (ret != Decision::ANY) + return parseDecision(ret, uid, label, privilege); + else + return DecisionResult::DENY; } diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index 7e351a3..59dc2d1 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -26,36 +26,46 @@ namespace ldp_xml_parser NaivePolicyDb m_bus_db[2]; DbAdapter* m_adapter; NaivePolicyDb& getPolicyDb(bool type); - Decision checkPolicy(const NaivePolicyDb::Policy& policy, - const Item& item, + + Decision checkPolicySR(const NaivePolicyDb::PolicySR& policy, + const MatchItemSR& item, + const char*& privilege); + + Decision checkPolicyOwn(const NaivePolicyDb::PolicyOwn& policy, + const ItemOwn& item, const char*& privilege); DecisionResult parseDecision(Decision decision, uid_t uid, const char* label, const char* privilege); - DecisionResult checkItem(bool bus_type, + + DecisionResult checkItemSR(bool bus_type, + uid_t uid, + gid_t gid, + const char* label, + const MatchItemSR& item, + const ItemType type); + + DecisionResult checkItemOwn(bool bus_type, uid_t uid, gid_t gid, const char* label, - const Item& item); + const ItemOwn& item, + const ItemType type); public: ~NaivePolicyChecker(); DbAdapter& generateAdapter(); DecisionResult check(bool bus_type, - uid_t uid, - gid_t gid, - const char* const label, - const char* const name); + uid_t uid, + gid_t gid, + const char* const label, + const char* const name); DecisionResult check(bool bus_type, - uid_t uid, - gid_t gid, - const char* const label, - const char** const names, - const char* const interface, - const char* const member, - const char* const path, - MessageType message_type, - MessageDirection message_dir); + uid_t uid, + gid_t gid, + const char* const label, + MatchItemSR& matcher, + ItemType type); }; } #endif diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index bccf9e3..c9fd4f6 100644 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -1,110 +1,265 @@ #include "naive_policy_db.hpp" -#include +#include "cynara.hpp" #include "tslog.hpp" using namespace ldp_xml_parser; -NaivePolicyDb::Policy::PolicyConstIterator::PolicyConstIterator(const std::vector& items, int position) + + +NaivePolicyDb::~NaivePolicyDb() { + +} + +NaivePolicyDb::PolicyOwn::PolicyOwn(){ + + treeRootPtr = new struct TreeNode; + treeRootPtr->__decisionItem = {Decision::ANY, NULL}; + treeRootPtr->__nameChar = '\0'; + treeRootPtr->__is_prefix = false; + for(int i = 0; i < MAX_CHILDREN; i++){ + treeRootPtr->children[i] = NULL; + } + + +} + +NaivePolicyDb::PolicyOwn::~PolicyOwn(){ + nodeRemove(&treeRootPtr); +} + +void NaivePolicyDb::PolicyOwn::nodeRemove(TreeNode **node){ + if(!*node){ + return; + } + for(int i = 0 ; ichildren[i] != NULL){ + nodeRemove(&(*node)->children[i]); + } + } + delete *node; + *node = NULL; +} + +void NaivePolicyDb::addItem(const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + ItemSendReceive* const item) { + if (tslog::enabled()) { + char tmp[MAX_LOG_LINE]; + const char* i_str = item->toString(tmp); + std::cout<<"Add item: "<< i_str <getDirection(); + if (dir == MessageDirection::SEND) + addItem(m_send_set, policy_type, policy_type_value, item); + else if (dir == MessageDirection::RECEIVE) + addItem(m_receive_set, policy_type, policy_type_value, item); + else { + addItem(m_send_set, policy_type, policy_type_value, item); + addItem(m_receive_set, policy_type, policy_type_value, item); + } +} + +void NaivePolicyDb::addItem(const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + ItemOwn* const item) { + if (tslog::enabled()) { + char tmp[MAX_LOG_LINE]; + const char* i_str = item->toString(tmp); + std::cout<<"Add item: "<< i_str <getPolicyOwn(m_own_set, policy_type, policy_type_value, policy); +} + +bool NaivePolicyDb::getPolicy(const ItemType item_type, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + const NaivePolicyDb::PolicySR*& policy) const { + switch (item_type) { + case ItemType::SEND: + return this->getPolicySR(m_send_set, policy_type, policy_type_value, policy); + case ItemType::RECEIVE: + return this->getPolicySR(m_receive_set, policy_type, policy_type_value, policy); + default: + return false; + } +} + + +NaivePolicyDb::PolicySR::PolicyConstIterator::PolicyConstIterator(const std::vector< ItemSendReceive* > & items, int position) : m_items(items), m_index(position) { } - Item* const& NaivePolicyDb::Policy::PolicyConstIterator::operator*() const { +ItemSendReceive* const& NaivePolicyDb::PolicySR::PolicyConstIterator::operator*() const { return m_items[m_index]; } -NaivePolicyDb::Policy::PolicyConstIterator& NaivePolicyDb::Policy::PolicyConstIterator::operator++() { + +typename NaivePolicyDb::PolicySR::PolicyConstIterator& NaivePolicyDb::PolicySR::PolicyConstIterator::operator++() { if (m_index >= 0) --m_index; return *this; } -bool NaivePolicyDb::Policy::PolicyConstIterator::operator!=(const PolicyConstIterator& it) const { + +bool NaivePolicyDb::PolicySR::PolicyConstIterator::operator!=(const PolicyConstIterator& it) const { return m_index != it.m_index; } -NaivePolicyDb::Policy::PolicyIterator::PolicyIterator(std::vector& items, int position) + +NaivePolicyDb::PolicySR::PolicyIterator::PolicyIterator(std::vector< ItemSendReceive* > & items, int position) : m_items(items), m_index(position) { } -Item*& NaivePolicyDb::Policy::PolicyIterator::operator*() { + +ItemSendReceive*& NaivePolicyDb::PolicySR::PolicyIterator::operator*() { return m_items[m_index]; } -NaivePolicyDb::Policy::PolicyIterator& NaivePolicyDb::Policy::PolicyIterator::operator++() { + +typename NaivePolicyDb::PolicySR::PolicyIterator& NaivePolicyDb::PolicySR::PolicyIterator::operator++() { if (m_index >= 0) --m_index; return *this; } -bool NaivePolicyDb::Policy::PolicyIterator::operator!=(const PolicyIterator& it) const { + +bool NaivePolicyDb::PolicySR::PolicyIterator::operator!=(const PolicyIterator& it) const { return m_index != it.m_index; } -NaivePolicyDb::Policy::PolicyIterator NaivePolicyDb::Policy::begin() { + +NaivePolicyDb::PolicySR::PolicyIterator NaivePolicyDb::PolicySR::begin() { int s = m_items.size() - 1; - return NaivePolicyDb::Policy::PolicyIterator(m_items, s); + return NaivePolicyDb::PolicySR::PolicyIterator(m_items, s); } -NaivePolicyDb::Policy::PolicyIterator NaivePolicyDb::Policy::end() { - return NaivePolicyDb::Policy::PolicyIterator(m_items, -1); + + +NaivePolicyDb::PolicySR::PolicyIterator NaivePolicyDb::PolicySR::end() { + return NaivePolicyDb::PolicySR::PolicyIterator(m_items, -1); } -NaivePolicyDb::Policy::PolicyConstIterator NaivePolicyDb::Policy::begin() const { + + +NaivePolicyDb::PolicySR::PolicyConstIterator NaivePolicyDb::PolicySR::begin() const { int s = m_items.size() - 1; - return NaivePolicyDb::Policy::PolicyConstIterator(m_items, s); + return NaivePolicyDb::PolicySR::PolicyConstIterator(m_items, s); } -NaivePolicyDb::Policy::PolicyConstIterator NaivePolicyDb::Policy::end() const { - return NaivePolicyDb::Policy::PolicyConstIterator(m_items, -1); + + +NaivePolicyDb::PolicySR::PolicyConstIterator NaivePolicyDb::PolicySR::end() const { + return NaivePolicyDb::PolicySR::PolicyConstIterator(m_items, -1); } -void NaivePolicyDb::Policy::addItem(Item* item) { + +void NaivePolicyDb::PolicySR::addItem(ItemSendReceive* item) { m_items.push_back(item); } -NaivePolicyDb::~NaivePolicyDb() { +const struct TreeNode* NaivePolicyDb::PolicyOwn::getTreeRoot() const{ + assert(treeRootPtr); + return treeRootPtr; } +void NaivePolicyDb::PolicyOwn::addItem(ItemOwn* item) { -const NaivePolicyDb::Policy* NaivePolicyDb::getPolicy(const ItemType item_type, - const PolicyType policy_type, - const PolicyTypeValue policy_type_value) { - PolicyTypeSet* set = NULL; - switch (item_type) { - case ItemType::OWN: - set = &m_own_set; - break; - case ItemType::SEND: - set = &m_send_set; - break; - case ItemType::RECEIVE: - set = &m_receive_set; - break; - default: - break; + const char *name = item->getName(); + /*TODO move this few layers up*/ + if(!name){ + return; + } + + struct TreeNode *node = treeRootPtr; + assert(node); + + const char *tmp = name; + while(tmp && *tmp != '\0'){ + if(char_map[*tmp]>64){ + /*Forbidden char*/ + return; + } + tmp++; + } + int childIndex = 0; + while(name && *name != '\0'){ + + childIndex = char_map[*name]; + + if(node->children[childIndex] == NULL){ + + node->children[childIndex] = new struct TreeNode; + + node->children[childIndex]->__decisionItem = {Decision::ANY, NULL}; + node->children[childIndex]->__nameChar = *name; + node->children[childIndex]->__is_prefix = false; + + for(int k = 0; k < MAX_CHILDREN; k++){ + node->children[childIndex]->children[k] = NULL; + } + + node = node->children[childIndex]; + } + + else { + node = node->children[childIndex]; + } + + name++; } + node->__decisionItem = item->getDecision(); + node->__is_prefix = item->isPrefix(); +} + + +bool NaivePolicyDb::getPolicySR(const NaivePolicyDb::PolicyTypeSetSR& set, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + const NaivePolicyDb::PolicySR*& policy) const +{ if (tslog::enabled()) std::cout<<"---policy_type ="; - switch (policy_type) { - case PolicyType::CONTEXT: - if (tslog::enabled()) - std::cout << "CONTEXT =" << (int)policy_type_value.context << std::endl; - return &set->context[static_cast(policy_type_value.context) ]; - case PolicyType::USER: - if (tslog::enabled()) - std::cout << "USER =" << (int)policy_type_value.user << std::endl; - return &set->user[policy_type_value.user]; - case PolicyType::GROUP: - if (tslog::enabled()) - std::cout << "GROUP = " << (int)policy_type_value.group << std::endl; - return &set->group[policy_type_value.group]; + try { + switch (policy_type) { + case PolicyType::CONTEXT: + if (tslog::enabled()) + std::cout << "CONTEXT =" << (int)policy_type_value.context << std::endl; + policy = &set.context[static_cast(policy_type_value.context) ]; + return true; + case PolicyType::USER: + if (tslog::enabled()) + std::cout << "USER =" << (int)policy_type_value.user << std::endl; + policy = &set.user.at(policy_type_value.user); + return true; + case PolicyType::GROUP: + if (tslog::enabled()) + std::cout << "GROUP = " << (int)policy_type_value.group << std::endl; + policy = &set.group.at(policy_type_value.group); + return true; + } + } catch (std::out_of_range&) + { + if (tslog::verbose()) + std::cout << "GetPolicy: Out of Range exception\n"; } if (tslog::enabled()) std::cout << "NO POLICY\n"; - return NULL; + return false; } -void NaivePolicyDb::addItem(NaivePolicyDb::PolicyTypeSet& set, - const PolicyType policy_type, - const PolicyTypeValue policy_type_value, - Item* const item) { + +void NaivePolicyDb::addItem(NaivePolicyDb::PolicyTypeSetSR& set, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + ItemSendReceive* const item) { switch (policy_type) { case PolicyType::CONTEXT: set.context[static_cast(policy_type_value.context)].addItem(item); @@ -118,28 +273,56 @@ void NaivePolicyDb::addItem(NaivePolicyDb::PolicyTypeSet& set, } } -void NaivePolicyDb::addItem(const PolicyType policy_type, - const PolicyTypeValue policy_type_value, - Item* const item) { - const ItemSendReceive* it; - if (tslog::enabled()) { - char tmp[MAX_LOG_LINE]; - const char* i_str = item->toString(tmp); - std::cout<<"Add item: "<< i_str <(item)) - addItem(m_own_set, policy_type, policy_type_value, item); - else if ((it = dynamic_cast(item))) { - const MessageDirection dir = it->getDirection(); - if (dir == MessageDirection::SEND) - addItem(m_send_set, policy_type, policy_type_value, item); - else if (dir == MessageDirection::RECEIVE) - addItem(m_receive_set, policy_type, policy_type_value, item); - else { - addItem(m_send_set, policy_type, policy_type_value, item); - addItem(m_receive_set, policy_type, policy_type_value, item); - } + +void NaivePolicyDb::addItem(NaivePolicyDb::PolicyTypeSetOwn& set, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + ItemOwn* const item) { + switch (policy_type) { + case PolicyType::CONTEXT: + set.context[static_cast(policy_type_value.context)].addItem(item); + break; + case PolicyType::USER: + set.user[policy_type_value.user].addItem(item); + break; + case PolicyType::GROUP: + set.group[policy_type_value.group].addItem(item); + break; } } diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp index fdbd0c1..320cbbc 100644 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -24,28 +24,30 @@ namespace ldp_xml_parser { class NaivePolicyDb { public: - class Policy { + + + class PolicySR { private: - std::vector m_items; + std::vector m_items; public: class PolicyConstIterator { private: - const std::vector& m_items; + const std::vector& m_items; int m_index; public: - PolicyConstIterator(const std::vector& items, int position); - Item* const& operator*() const; + PolicyConstIterator(const std::vector& items, int position); + ItemSendReceive* const& operator*() const; PolicyConstIterator& operator++(); bool operator!=(const PolicyConstIterator& it) const; }; class PolicyIterator { private: - std::vector& m_items; + std::vector& m_items; int m_index; public: - PolicyIterator(std::vector& items, int position); - Item*& operator*(); + PolicyIterator(std::vector& items, int position); + ItemSendReceive*& operator*(); PolicyIterator& operator++(); bool operator!=(const PolicyIterator& it) const; }; @@ -54,33 +56,82 @@ namespace ldp_xml_parser PolicyIterator end(); PolicyConstIterator begin() const; PolicyConstIterator end() const; - void addItem(Item* item); + void addItem(ItemSendReceive* item); + }; + + + class PolicyOwn { + private: + struct TreeNode *treeRootPtr = NULL; + void nodeRemove(TreeNode **node); + public: + PolicyOwn(); + ~PolicyOwn(); + void addItem(ItemOwn* item); + const TreeNode* getTreeRoot() const; + }; ~NaivePolicyDb(); - const Policy* getPolicy(const ItemType item_type, - const PolicyType policy_type, - const PolicyTypeValue policy_type_value); + bool getPolicy(const ItemType item_type, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + const PolicyOwn*& policy) const; + + bool getPolicy(const ItemType item_type, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + const PolicySR*& policy) const; + + void addItem(const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + ItemOwn* const item); void addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, - Item* const item); + ItemSendReceive* const item); + private: - struct PolicyTypeSet { - Policy context[static_cast(ContextType::MAX)]; - std::map user; - std::map group; + + struct PolicyTypeSetOwn { + PolicyOwn context[static_cast(ContextType::MAX)]; + std::map user; + std::map group; + }; + + struct PolicyTypeSetSR { + PolicySR context[static_cast(ContextType::MAX)]; + std::map user; + std::map group; }; - PolicyTypeSet m_own_set; - PolicyTypeSet m_send_set; - PolicyTypeSet m_receive_set; - void addItem(PolicyTypeSet& set, - const PolicyType policy_type, - const PolicyTypeValue policy_type_value, - Item* const item); + PolicyTypeSetOwn m_own_set; + PolicyTypeSetSR m_send_set; + PolicyTypeSetSR m_receive_set; + + void addItem(PolicyTypeSetSR& set, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + ItemSendReceive* const item); + + bool getPolicySR(const PolicyTypeSetSR& set, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + const PolicySR*& policy) const; + + void addItem(PolicyTypeSetOwn& set, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + ItemOwn* const item); + + bool getPolicyOwn(const PolicyTypeSetOwn& set, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + const PolicyOwn*& policy) const; + }; -} + +} #endif diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index 20076e5..6eaf8a7 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -11,16 +11,6 @@ static const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ER static const char* message_dir[] = { "ANY", "SEND", "RECEIVE"}; static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"}; -static bool __compare_str(const char* a, const char* b) { - - while(*a && *b && *a != ' ' && *b != ' ') { - if (*a != *b) - return false; - a++; b++; - } - return ((*a == 0 || *a == ' ') && (*b == 0 || *b != ' ')); -} - static MessageType __str_to_message_type(const char* str) { if (!std::strcmp(str, "method_call")) return MessageType::METHOD_CALL; @@ -178,15 +168,11 @@ void DbAdapter::xmlTraversal(bool bus, updateDecision(v, policy_type, policy_type_value, t, attr); xmlTraversal(bus, v.second, t, policy_type, policy_type_value, attr, level + 1); } - if(!pt.empty() && level > 1) { - Item* it = __builder.generateItem(); - if (it) { - if (bus) - __session_db.addItem(policy_type, policy_type_value, it); - else - __system_db.addItem(policy_type, policy_type_value, it); - } + if (bus) + __builder.generateItem(__session_db, policy_type, policy_type_value); + else + __builder.generateItem(__system_db, policy_type, policy_type_value); } } } @@ -206,169 +192,160 @@ void DbAdapter::updateDb(bool bus, boost::property_tree::ptree& xmlTree, std::ve } } -Item::Item(Decision decision, const char* privilege, bool isOwner) - : _decision(decision), _privilege(privilege), _is_owner(isOwner) { - +DecisionItem::DecisionItem(Decision decision, const char* privilege) + : __decision(decision), __privilege(privilege) +{ } -Item::~Item() { - if (_is_owner) { - delete[] _privilege; - } +DecisionItem::~DecisionItem() +{ + if (__privilege) + delete[] __privilege; } -bool Item::match(const Item& item) const { - return match(&item); +Decision DecisionItem::getDecision() const { + return __decision; } -bool Item::match(const Item* item) const { - return true; -} - -Decision Item::getDecision() const { - return _decision; -} - -const char* Item::getPrivilege() const { - return _privilege; +const char* DecisionItem::getPrivilege() const { + return __privilege; } -ItemType Item::getType() const { +ItemType DecisionItem::getType() const { return ItemType::GENERIC; } -const char* Item::toString(char* str) const { - snprintf(str, MAX_LOG_LINE, "Item: dec(%s) owner(%d) priv(%s)", __decision_to_str(_decision), _is_owner, _privilege); +const char* DecisionItem::toString(char* str) const { + snprintf(str, MAX_LOG_LINE, "Item: dec(%s) priv(%s)", __decision_to_str(__decision), __privilege); return str; } ItemOwn::ItemOwn(const char* name, - bool is_prefix, Decision decision, const char* privilege) -: Item(decision, privilege), __name(name), __is_prefix(is_prefix) { -} + : __decision(DecisionItem(decision, privilege)), __name(name) { -ItemOwn::~ItemOwn() { - if (_is_owner) { - delete[] __name; - } } + ItemType ItemOwn::getType() const { return ItemType::OWN; } -bool ItemOwn::match(const Item* item) const { - const ItemOwn* it = dynamic_cast(item); - if (!it) - return false; - if (__is_prefix) { - int i = 0; - if (!__name) - return false; +const char* ItemOwn::toString(char* str) const { + snprintf(str, MAX_LOG_LINE, "ItemOwn: service(%s), pref(%d)", __name, __is_prefix); + return str; +} - for (i = 0; __name[i] && it->__name[i]; i++) - if (__name[i] != it->__name[i]) - return false; +const char* ItemOwn::getName() const { + return __name; +} - if (__name[i] != 0) - return false; +bool ItemOwn::isPrefix() const { + return __is_prefix; +} - return true; - } else if (!__name) - return true; - else { - return std::strcmp(__name, it->__name) == 0; - } +const DecisionItem& ItemOwn::getDecision() const { + return __decision; } -const char* ItemOwn::toString(char* str) const { - char parent[MAX_LOG_LINE]; - const char* t = Item::toString(parent); - snprintf(str, MAX_LOG_LINE, "ItemOwn: service(%s), pref(%d) <- %s", __name, __is_prefix, t); - return str; +NameSR::NameSR(const char* m, int l) : name(m), len(l) +{ } -ItemSendReceive::ItemSendReceive(const char** names, - const char* interface, - const char* member, const char* path, - MessageType type, MessageDirection direction, - Decision decision, - const char* privilege) - : Item(decision, privilege), - __names(names), - __interface(interface), - __member(member), - __path(path), - __type(type), - __direction(direction) { +MatchItemSR::MatchItemSR(const char* i, const char* me, const char* p, MessageType t, MessageDirection d) + : names_num(0), interface(i), member(me), path(p), type(t), direction(d) { } -const char* ItemSendReceive::toString(char* str) const { - char parent[MAX_LOG_LINE]; - char buff[MAX_LOG_LINE]; - char* curr = buff; - const char* t = Item::toString(parent); + +MatchItemSR::~MatchItemSR(){ +} + +void MatchItemSR::addName(const char* name) { + names[names_num++] = NameSR(name, std::strlen(name)); +} + +bool MatchItemSR::addNames(const char* name) { int i = 0; - int k = 0; - while(__names && __names[i]){ - for (k = 0; __names[i][k] && __names[i][k] != ' ';k++){ - *curr = __names[i][k]; - curr +=1; - } - *curr = ' '; - curr += 1; - i++; + int j = 0; + + if (name) { + assert((name[i] > 'a'&& name[i] < 'z') || (name[i] > 'A'&& name[i] < 'Z') || (name[i] > '0'&& name[i] < '9')); + while (name[i] && names_num < KDBUS_CONN_MAX_NAMES + 1) { + char c; + int len; + j = i; + while ((c = name[i++]) && ' ' != c); + if (!c) { + --i; + len = i-j; + } else + len = i-j-1; + names[names_num++] = NameSR(name + j, len); + } + if (names_num >= KDBUS_CONN_MAX_NAMES + 1) + return false; } - *curr = 0; - curr += 1; - snprintf(str, MAX_LOG_LINE, "ItemSR: name(%s), inter(%s), member(%s), path(%s), type(%s), dir(%s) <- %s", buff, __interface, __member, __path, __message_type_to_str(__type), __message_dir_to_str(__direction), t); + return true; +} + +ItemSendReceive::ItemSendReceive(const char* name, + const char* interface, + const char* member, + const char* path, + MessageType type, + MessageDirection direction, + Decision decision, + const char* privilege) + : __name(NameSR(name, name?std::strlen(name):0)), + __interface(interface), + __member(member), + __path(path), + __type(type), + __direction(direction) { + +} + +const char* ItemSendReceive::toString(char* str) const { + snprintf(str, MAX_LOG_LINE, "ItemSR: name(%s), inter(%s), member(%s), path(%s), type(%s), dir(%s)", __name.name, __interface, __member, __path, __message_type_to_str(__type), __message_dir_to_str(__direction)); return str; } + ItemSendReceive::~ItemSendReceive() { - if (_is_owner) { - delete[] __interface; - delete[] __member; - delete[] __path; - - if (__names) { - int i = 0; - while (__names[i]) - delete[] __names[i++]; - delete[] __names; - } + delete[] __interface; + delete[] __member; + delete[] __path; + + if (__name.len > 0) { + delete[] __name.name; } } -bool ItemSendReceive::match(const Item* item) const { - const ItemSendReceive* it = dynamic_cast(item); - - if (!it) - return false; - - if (__type != MessageType::ANY && __type != it->__type) +bool ItemSendReceive::match(const MatchItemSR& item) const { + if (__type != MessageType::ANY && __type != item.type) return false; - if (__direction != it->__direction) + if (__direction != item.direction) return false; - if (__interface && it->__interface && std::strcmp(__interface, it->__interface)) + if (__interface && item.interface && std::strcmp(__interface, item.interface)) return false; - if (__path && it->__path && std::strcmp(__path, it->__path)) + if (__path && item.path && std::strcmp(__path, item.path)) return false; - if (__member && it->__member && std::strcmp(__member, it->__member)) + if (__member && item.member && std::strcmp(__member, item.member)) return false; - if (__names && __names[0]) { + if (__name.len > 0 ) { int i = 0; bool f = false; - if (it->__names) { - while (it->__names[i]) { - if (__compare_str(it->__names[i++], __names[0])) { + if (item.names_num > 0) { + while (i < item.names_num) { + if (item.names[i].len == __name.len && + !memcmp(item.names[i].name, __name.name, item.names[i].len)) { f = true; break; } + i++; } if (!f) return false; @@ -390,40 +367,37 @@ MessageDirection ItemSendReceive::getDirection() const { return __direction; } +const DecisionItem& ItemSendReceive::getDecision() const { + return __decision; +} + ItemOwn* ItemBuilder::getOwnItem() { - if (!__current) { - __current = new ItemOwn(); - prepareItem(); - } - return dynamic_cast(__current); + __current_item_type = ItemType::OWN; + return &__current_own; } ItemSendReceive* ItemBuilder::getSendReceiveItem() { - if (!__current) { - __current = new ItemSendReceive(); - prepareItem(); + if (!__current_sr) { + __current_sr = new ItemSendReceive(); } - return dynamic_cast(__current); + __current_item_type = ItemType::SEND; + return __current_sr; } -ItemBuilder::ItemBuilder() : __current(NULL), __delayed_privilege(NULL) { +ItemBuilder::ItemBuilder() : __current_own(NULL), __current_sr(NULL) { } ItemBuilder::~ItemBuilder(){ - if (__delayed_privilege) - delete[] __delayed_privilege; - if (__current) - delete __current; + if (__current_sr) + delete __current_sr; + } void ItemBuilder::reset() { - if (__delayed_privilege) - delete[] __delayed_privilege; - if (__current) - delete __current; - - __current = NULL; - __delayed_privilege = NULL; + __decision.__decision = Decision::ANY; + __decision.__privilege = NULL; + __current_sr = NULL; + __current_own = NULL; } char* ItemBuilder::duplicate(const char* str) { @@ -442,21 +416,15 @@ char* ItemBuilder::duplicate(const char* str) { return ret; } -void ItemBuilder::prepareItem() { - __current->_is_owner = true; - if (__delayed_privilege) - __current->_privilege = __delayed_privilege; - - __current->_decision = __delayed_decision; - __delayed_privilege = NULL; -} - -Item* ItemBuilder::generateItem() { - Item* ret = __current; - __current = NULL; - __delayed_decision = Decision::ANY; - __delayed_privilege = NULL; - return ret; +void ItemBuilder::generateItem(NaivePolicyDb& db, PolicyType& policy_type, PolicyTypeValue& policy_type_value) { + if (__current_item_type == ItemType::OWN) { + __current_own.__decision = __decision; + db.addItem(policy_type, policy_type_value, &__current_own); + } else if (__current_sr) { + __current_sr->__decision = __decision; + db.addItem(policy_type, policy_type_value, __current_sr); + } + reset(); } void ItemBuilder::addOwner(const char* owner) { @@ -468,17 +436,28 @@ void ItemBuilder::addOwner(const char* owner) { void ItemBuilder::addName(const char* name) { ItemSendReceive* sr = getSendReceiveItem(); - if (sr->__names) { - delete sr->__names[0]; - delete[] sr->__names; + if (sr->__name.len > 0) { + delete[] sr->__name.name; + sr->__name.len = 0; } + if (!name) - sr->__names = NULL; + sr->__name.name = NULL; else { - sr->__names = new const char*[2]; - sr->__names[0] = duplicate(name); - sr->__names[1] = NULL; + sr->__name.name = duplicate(name); + sr->__name.len = std::strlen(name); + } +} + +const char* MatchItemSR::toString(char* str) const { + char tmp[MAX_LOG_LINE]; + tmp[0] = 0; + for (int i = 0; i < names_num; i++) { + std::strcat(tmp, names[i].name); + std::strcat(tmp, " "); } + snprintf(str, MAX_LOG_LINE, "matcher: services(%s), interface(%s), member(%s), path(%s), type(%s), direction(%s)", tmp, interface, member, path, __message_type_to_str(type), __message_dir_to_str(direction) ); + return str; } void ItemBuilder::addInterface(const char* interface) { @@ -507,17 +486,11 @@ void ItemBuilder::addDirection(MessageDirection direction) { } void ItemBuilder::addPrivilege(const char* privilege) { - if (!__current) - __delayed_privilege = duplicate(privilege); - else - __current->_privilege = duplicate(privilege); + __decision.__privilege = duplicate(privilege); } void ItemBuilder::addDecision(Decision decision) { - if (!__current) - __delayed_decision = decision; - else - __current->_decision = decision; + __decision.__decision = decision; } void ItemBuilder::setPrefix(bool value) { diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp index e76e3f2..55834cc 100644 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -18,11 +18,23 @@ #include #include +#include #include #define MAX_LOG_LINE 1024 +#define MAX_CHILDREN 65 namespace ldp_xml_parser { + + const char char_map[128] {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 10, 12, 65, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 65, 65, 65, 65, 65, 65, + 65, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 65, 65, 65, 11, + 65, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 65, 65, 65, 65, 65}; + enum class MessageType : uint8_t { ANY = 0, METHOD_CALL, @@ -37,7 +49,7 @@ namespace ldp_xml_parser RECEIVE }; - enum class ItemType : uint8_t{ + enum class ItemType : uint8_t { GENERIC, OWN, SEND, @@ -80,41 +92,70 @@ namespace ldp_xml_parser class ItemBuilder; - class Item { - protected: - Decision _decision; - const char* _privilege; - bool _is_owner; + class DecisionItem { + private: + Decision __decision; + const char* __privilege; public: friend class ItemBuilder; - Item(Decision decision = Decision::ANY, const char* privilege = NULL, bool isOwner = false); - virtual ~Item(); - virtual bool match(const Item& item) const; - virtual bool match(const Item* item) const; - virtual Decision getDecision() const; - virtual const char* getPrivilege() const; - virtual ItemType getType() const; - virtual const char* toString(char* str) const; + DecisionItem(Decision decision = Decision::ANY, const char* privilege = NULL); + ~DecisionItem(); + Decision getDecision() const; + const char* getPrivilege() const; + ItemType getType() const; + const char* toString(char* str) const; }; - class ItemOwn : public Item { + class ItemOwn { private: + DecisionItem __decision; const char* __name; bool __is_prefix; public: friend class ItemBuilder; ItemOwn(const char* name = NULL, - bool is_prefix = false, Decision decision = Decision::ANY, const char* privilege = NULL); - virtual ~ItemOwn(); - virtual bool match(const Item* item) const; - virtual ItemType getType() const; - virtual const char* toString(char* str) const; + bool match(const char* const name) const; + ItemType getType() const; + const char* toString(char* str) const; + const DecisionItem& getDecision() const; + const char* getName() const; + bool isPrefix() const; + }; + + struct TreeNode{ + DecisionItem __decisionItem; + char __nameChar; + bool __is_prefix; + struct TreeNode *children[MAX_CHILDREN]; + }; + + struct NameSR { + const char* name; + int len; + NameSR(const char* m = NULL, int l = 0); + }; + + struct MatchItemSR { + int names_num; + NameSR names[KDBUS_CONN_MAX_NAMES+1]; + const char* interface; + const char* member; + const char* path; + MessageType type; + MessageDirection direction; + MatchItemSR(const char* i = NULL, const char* me = NULL, const char* p = NULL, MessageType t = MessageType::ANY, MessageDirection d = MessageDirection::ANY); + ~MatchItemSR(); + void addName(const char* name); + bool addNames(const char* name); + const char* toString(char* str) const; }; - class ItemSendReceive : public Item { - const char** __names; + class ItemSendReceive { + private: + DecisionItem __decision; + NameSR __name; const char* __interface; const char* __member; const char* __path; @@ -122,7 +163,7 @@ namespace ldp_xml_parser MessageDirection __direction; public: friend class ItemBuilder; - ItemSendReceive(const char** names = NULL, + ItemSendReceive(const char* name = NULL, const char* interface = NULL, const char* member = NULL, const char* path = NULL, @@ -130,26 +171,28 @@ namespace ldp_xml_parser MessageDirection direction = MessageDirection::ANY, Decision decision = Decision::ANY, const char* privilege = NULL); - virtual ~ItemSendReceive(); - virtual bool match(const Item* item) const; + ~ItemSendReceive(); + bool match(const MatchItemSR& item) const; MessageDirection getDirection() const; - virtual ItemType getType() const; - virtual const char* toString(char* str) const; + ItemType getType() const; + const char* toString(char* str) const; + const DecisionItem& getDecision() const; }; + class NaivePolicyDb; class ItemBuilder { private: - Item* __current; - Decision __delayed_decision; - const char* __delayed_privilege; + DecisionItem __decision; + ItemOwn __current_own; + ItemType __current_item_type; + ItemSendReceive* __current_sr; ItemOwn* getOwnItem(); ItemSendReceive* getSendReceiveItem(); char* duplicate(const char* str); - void prepareItem(); public: ItemBuilder(); ~ItemBuilder(); - Item* generateItem(); + void generateItem(NaivePolicyDb& db, PolicyType& policy_type, PolicyTypeValue& policy_type_value); void reset(); void addUser(const char* name); void addGroup(const char* name); @@ -165,7 +208,6 @@ namespace ldp_xml_parser void setPrefix(bool value); }; - class NaivePolicyDb; class DbAdapter { private: enum state { -- 2.7.4 From 655f28c7dfc6a74b1de2c51facb4f701f85419a0 Mon Sep 17 00:00:00 2001 From: Krystian Kisielak Date: Tue, 23 Aug 2016 10:44:34 +0200 Subject: [PATCH 16/16] Fixes coding style issues. Change-Id: Ibbbaab71538906fa123156c3260707b9edef4bcc Signed-off-by: Krystian Kisielak --- src/dbuspolicy1/libdbuspolicy1.h | 1 - src/internal/cynara.cpp | 23 ++++---- src/internal/internal.cpp | 11 ++-- src/internal/libdbuspolicy1-private.hpp | 1 - src/internal/naive_policy_checker.cpp | 95 +++++++++++---------------------- src/internal/naive_policy_checker.hpp | 1 + src/internal/naive_policy_db.cpp | 53 +++++++----------- src/internal/naive_policy_db.hpp | 6 --- src/internal/policy.cpp | 63 +++++++++++----------- src/internal/xml_parser.hpp | 20 +++---- src/test-libdbuspolicy1-method.cpp | 4 +- src/test-libdbuspolicy1-ownership.cpp | 4 +- src/test-libdbuspolicy1-signal.cpp | 4 +- 13 files changed, 112 insertions(+), 174 deletions(-) diff --git a/src/dbuspolicy1/libdbuspolicy1.h b/src/dbuspolicy1/libdbuspolicy1.h index 14e5377..35da6fe 100644 --- a/src/dbuspolicy1/libdbuspolicy1.h +++ b/src/dbuspolicy1/libdbuspolicy1.h @@ -39,7 +39,6 @@ extern "C" { #define DBUSPOLICY_MESSAGE_TYPE_METHOD_RETURN 2 #define DBUSPOLICY_MESSAGE_TYPE_ERROR 3 #define DBUSPOLICY_MESSAGE_TYPE_SIGNAL 4 - #define DBUSPOLICY_RESULT_ALLOW 1 #define DBUSPOLICY_RESULT_DENY 0 #define DBUSPOLICY_RESULT_DEST_NOT_AVAILABLE -1 diff --git a/src/internal/cynara.cpp b/src/internal/cynara.cpp index ca4c79d..6fe6b76 100644 --- a/src/internal/cynara.cpp +++ b/src/internal/cynara.cpp @@ -39,27 +39,22 @@ Cynara& Cynara::getInstance() { } CynaraResult Cynara::check(const char* label, const char* privilege, const char* uid) { - - const char* _label=""; - const char* _uid=""; - const char* _privilege=""; + const char* _label = ""; + const char* _uid = ""; + const char* _privilege = ""; CynaraResult ret; - if (label) - _label=label; - + _label = label; if (privilege) - _privilege=privilege; - + _privilege = privilege; if (uid) - _uid=uid; - + _uid = uid; pthread_mutex_lock(&__mutex); Cynara& c = Cynara::getInstance(); - if (!c.init()) + if (!c.init()) { ret = CynaraResult::ERROR_INIT; - else { - int r = cynara_check (c.__cynara, _label, c.__session, _uid, _privilege); + } else { + int r = cynara_check(c.__cynara, _label, c.__session, _uid, _privilege); if (r == CYNARA_API_ACCESS_ALLOWED) ret = CynaraResult::ALLOW; else if (r == CYNARA_API_ACCESS_DENIED) diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index ec3e7cb..ff19d1b 100644 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -75,13 +75,12 @@ int __internal_can_send(bool bus_type, const char* const member, int type) { - ldp_xml_parser::MatchItemSR matcher (interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND); + ldp_xml_parser::MatchItemSR matcher(interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND); if (!matcher.addNames(destination)) { if (tslog::verbose()) - std::cout << "Destination too long: "<(policy_checker.check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::SEND)); } @@ -96,7 +95,7 @@ int __internal_can_send_multi_dest(bool bus_type, int type) { int i = 0; - ldp_xml_parser::MatchItemSR matcher (interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND); + ldp_xml_parser::MatchItemSR matcher(interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::SEND); if (destination) while (destination[i++]) { matcher.addName(destination[i]); @@ -114,10 +113,10 @@ int __internal_can_recv(bool bus_type, const char* const member, int type) { - ldp_xml_parser::MatchItemSR matcher (interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::RECEIVE); + ldp_xml_parser::MatchItemSR matcher(interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::RECEIVE); if (!matcher.addNames(sender)) { if (tslog::verbose()) - std::cout << "Sender too long: "<(policy_checker.check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::RECEIVE)); diff --git a/src/internal/libdbuspolicy1-private.hpp b/src/internal/libdbuspolicy1-private.hpp index 0cef333..83bd79c 100644 --- a/src/internal/libdbuspolicy1-private.hpp +++ b/src/internal/libdbuspolicy1-private.hpp @@ -69,7 +69,6 @@ namespace { bool is_error() const { return (m_err < 0); } - }; } //namespace diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index 45244d4..ca07111 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -25,8 +25,6 @@ DbAdapter& NaivePolicyChecker::generateAdapter() { return *m_adapter; } - - NaivePolicyDb& NaivePolicyChecker::getPolicyDb(bool type) { return m_bus_db[type]; } @@ -35,29 +33,28 @@ DecisionResult NaivePolicyChecker::parseDecision(Decision decision, uid_t uid, const char* label, const char* privilege) { - char uid_str[17]; if (tslog::verbose()) { - std::cout<<"----Decision made\n"; + std::cout << "----Decision made\n"; } switch (decision) { - case Decision::ALLOW: - return DecisionResult::ALLOW; - case Decision::ANY: - case Decision::DENY: - return DecisionResult::DENY; - case Decision::CHECK: - { - std::snprintf(uid_str, sizeof(uid_str) - 1, "%lu", (unsigned long)uid); - ldp_cynara::CynaraResult ret = ldp_cynara::Cynara::check(label, privilege, uid_str); - if (ret == ldp_cynara::CynaraResult::ALLOW) + case Decision::ALLOW: return DecisionResult::ALLOW; - else if (ret == ldp_cynara::CynaraResult::DENY) + case Decision::ANY: + case Decision::DENY: return DecisionResult::DENY; - else - return DecisionResult::CYNARA_ERROR; - } + case Decision::CHECK: + { + std::snprintf(uid_str, sizeof(uid_str) - 1, "%lu", (unsigned long)uid); + ldp_cynara::CynaraResult ret = ldp_cynara::Cynara::check(label, privilege, uid_str); + if (ret == ldp_cynara::CynaraResult::ALLOW) + return DecisionResult::ALLOW; + else if (ret == ldp_cynara::CynaraResult::DENY) + return DecisionResult::DENY; + else + return DecisionResult::CYNARA_ERROR; + } } return DecisionResult::DENY; } @@ -92,7 +89,6 @@ Decision NaivePolicyChecker::checkPolicySR(const NaivePolicyDb::PolicySR& policy if (tslog::verbose()) { __log_item(item); } - for (auto i : policy) { if (tslog::verbose()) { char tmp[MAX_LOG_LINE]; @@ -113,12 +109,10 @@ Decision NaivePolicyChecker::checkPolicySR(const NaivePolicyDb::PolicySR& policy return i->getDecision().getDecision(); } } - return Decision::ANY; } Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& policy, const ItemOwn& item, const char*& privilege) { - if (tslog::verbose()) { __log_item(item); } @@ -127,114 +121,85 @@ Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& poli int childIndex = 0; assert(node); Decision ret = Decision::ANY; - - while((name != NULL)&& (*name != '\0')){ - - + while ((name != NULL) && (*name != '\0')) { childIndex = char_map[*name]; - if(childIndex > 64){ - /*name contains forbidden char*/ + if (childIndex > 64) { + /* name contains forbidden char */ privilege = NULL; return Decision::DENY; } - /*Current node is prefix, remeber decision*/ - if(node->__is_prefix){ + /* Current node is prefix, remeber decision */ + if (node->__is_prefix) { ret = node->__decisionItem.getDecision();; privilege = node->__decisionItem.getPrivilege(); } - - /*Node for this letter dont exist*/ - if(node->children[childIndex] == NULL){ + /* Node for this letter dont exist */ + if (node->children[childIndex] == NULL) { goto out; - } - else{/*if it exists check for next letter in its child*/ + } else { /* if it exists check for next letter in its child */ node = node->children[childIndex]; } - name++; - } out: - if(ret == Decision::ANY){ + if (ret == Decision::ANY) { privilege = node->__decisionItem.getPrivilege(); return node->__decisionItem.getDecision(); - } - else - + } else { return ret; - + } } - - - DecisionResult NaivePolicyChecker::checkItemOwn(bool bus_type, uid_t uid, gid_t gid, const char* label, const ItemOwn& item, const ItemType type) { - NaivePolicyDb& policy_db = getPolicyDb(bus_type); Decision ret = Decision::ANY; const char* privilege; const NaivePolicyDb::PolicyOwn* curr_policy = NULL; if (ret == Decision::ANY) { - if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::MANDATORY), curr_policy)) - ret = checkPolicyOwn(*curr_policy, item, privilege); } - if (ret == Decision::ANY) { - if (policy_db.getPolicy(type, PolicyType::USER, PolicyTypeValue(uid), curr_policy)) - ret = checkPolicyOwn(*curr_policy, item, privilege); } - if (ret == Decision::ANY) { - if (policy_db.getPolicy(type, PolicyType::GROUP, PolicyTypeValue(gid), curr_policy)) - ret = checkPolicyOwn(*curr_policy, item, privilege); } - if (ret == Decision::ANY) { - if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), curr_policy)) - ret = checkPolicyOwn(*curr_policy, item, privilege); } - if (ret != Decision::ANY){ - + if (ret != Decision::ANY) { return parseDecision(ret, uid, label, privilege); - } - else + } else { return DecisionResult::DENY; + } } + DecisionResult NaivePolicyChecker::checkItemSR(bool bus_type, uid_t uid, gid_t gid, const char* label, const MatchItemSR& item, const ItemType type) { NaivePolicyDb& policy_db = getPolicyDb(bus_type); Decision ret = Decision::ANY; const char* privilege; const NaivePolicyDb::PolicySR* curr_policy = NULL; - if (ret == Decision::ANY) { if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::MANDATORY), curr_policy)) ret = checkPolicySR(*curr_policy, item, privilege); } - if (ret == Decision::ANY) { if (policy_db.getPolicy(type, PolicyType::USER, PolicyTypeValue(uid), curr_policy)) ret = checkPolicySR(*curr_policy, item, privilege); } - if (ret == Decision::ANY) { if (policy_db.getPolicy(type, PolicyType::GROUP, PolicyTypeValue(gid), curr_policy)) ret = checkPolicySR(*curr_policy, item, privilege); } - if (ret == Decision::ANY) { if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), curr_policy)) ret = checkPolicySR(*curr_policy, item, privilege); } - if (ret != Decision::ANY) return parseDecision(ret, uid, label, privilege); else diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index 59dc2d1..a54302d 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -34,6 +34,7 @@ namespace ldp_xml_parser Decision checkPolicyOwn(const NaivePolicyDb::PolicyOwn& policy, const ItemOwn& item, const char*& privilege); + DecisionResult parseDecision(Decision decision, uid_t uid, const char* label, diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index c9fd4f6..a623059 100644 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -7,20 +7,16 @@ using namespace ldp_xml_parser; NaivePolicyDb::~NaivePolicyDb() { - } NaivePolicyDb::PolicyOwn::PolicyOwn(){ - treeRootPtr = new struct TreeNode; treeRootPtr->__decisionItem = {Decision::ANY, NULL}; treeRootPtr->__nameChar = '\0'; treeRootPtr->__is_prefix = false; - for(int i = 0; i < MAX_CHILDREN; i++){ + for (int i = 0; i < MAX_CHILDREN; i++) { treeRootPtr->children[i] = NULL; } - - } NaivePolicyDb::PolicyOwn::~PolicyOwn(){ @@ -28,11 +24,11 @@ NaivePolicyDb::PolicyOwn::~PolicyOwn(){ } void NaivePolicyDb::PolicyOwn::nodeRemove(TreeNode **node){ - if(!*node){ + if (!*node) { return; } - for(int i = 0 ; ichildren[i] != NULL){ + for (int i = 0 ; i < MAX_CHILDREN; i++) { + if ((*node)->children[i] != NULL) { nodeRemove(&(*node)->children[i]); } } @@ -46,15 +42,15 @@ void NaivePolicyDb::addItem(const PolicyType policy_type, if (tslog::enabled()) { char tmp[MAX_LOG_LINE]; const char* i_str = item->toString(tmp); - std::cout<<"Add item: "<< i_str <getDirection(); - if (dir == MessageDirection::SEND) + if (dir == MessageDirection::SEND) { addItem(m_send_set, policy_type, policy_type_value, item); - else if (dir == MessageDirection::RECEIVE) + } else if (dir == MessageDirection::RECEIVE) { addItem(m_receive_set, policy_type, policy_type_value, item); - else { + } else { addItem(m_send_set, policy_type, policy_type_value, item); addItem(m_receive_set, policy_type, policy_type_value, item); } @@ -66,7 +62,7 @@ void NaivePolicyDb::addItem(const PolicyType policy_type, if (tslog::enabled()) { char tmp[MAX_LOG_LINE]; const char* i_str = item->toString(tmp); - std::cout<<"Add item: "<< i_str <getName(); - /*TODO move this few layers up*/ - if(!name){ + + if (!name) { return; } @@ -182,37 +177,29 @@ void NaivePolicyDb::PolicyOwn::addItem(ItemOwn* item) { assert(node); const char *tmp = name; - while(tmp && *tmp != '\0'){ - if(char_map[*tmp]>64){ - /*Forbidden char*/ + while (tmp && *tmp != '\0') { + if (char_map[*tmp] > 64) { + /* Forbidden char */ return; } tmp++; } int childIndex = 0; - while(name && *name != '\0'){ - + while (name && *name != '\0') { childIndex = char_map[*name]; - - if(node->children[childIndex] == NULL){ - + if (node->children[childIndex] == NULL) { node->children[childIndex] = new struct TreeNode; - node->children[childIndex]->__decisionItem = {Decision::ANY, NULL}; node->children[childIndex]->__nameChar = *name; node->children[childIndex]->__is_prefix = false; - - for(int k = 0; k < MAX_CHILDREN; k++){ + for (int k = 0; k < MAX_CHILDREN; k++) { node->children[childIndex]->children[k] = NULL; } node = node->children[childIndex]; - } - - else { + } else { node = node->children[childIndex]; } - name++; } node->__decisionItem = item->getDecision(); @@ -226,7 +213,7 @@ bool NaivePolicyDb::getPolicySR(const NaivePolicyDb::PolicyTypeSetSR& set, const NaivePolicyDb::PolicySR*& policy) const { if (tslog::enabled()) - std::cout<<"---policy_type ="; + std::cout << "---policy_type ="; try { switch (policy_type) { case PolicyType::CONTEXT: @@ -280,7 +267,7 @@ bool NaivePolicyDb::getPolicyOwn(const NaivePolicyDb::PolicyTypeSetOwn& set, const NaivePolicyDb::PolicyOwn*& policy) const { if (tslog::enabled()) - std::cout<<"---policy_type ="; + std::cout << "---policy_type ="; try { switch (policy_type) { case PolicyType::CONTEXT: diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp index 320cbbc..3b8a655 100644 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -24,8 +24,6 @@ namespace ldp_xml_parser { class NaivePolicyDb { public: - - class PolicySR { private: std::vector m_items; @@ -69,7 +67,6 @@ namespace ldp_xml_parser ~PolicyOwn(); void addItem(ItemOwn* item); const TreeNode* getTreeRoot() const; - }; ~NaivePolicyDb(); @@ -129,9 +126,6 @@ namespace ldp_xml_parser const PolicyType policy_type, const PolicyTypeValue policy_type_value, const PolicyOwn*& policy) const; - }; - - } #endif diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index 6eaf8a7..9bcdb63 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -79,39 +79,39 @@ void DbAdapter::updateDecision(const boost::property_tree::ptree::value_type& v, state& t, bool& attr) { const char* value = NULL; - if(v.first == "allow" && t == POLICY) { + if (v.first == "allow" && t == POLICY) { __builder.reset(); __builder.addDecision(Decision::ALLOW); t = ALLOW_DENY_CHECK; attr = false; - } else if(v.first == "deny" && t == POLICY) { + } else if (v.first == "deny" && t == POLICY) { __builder.reset(); __builder.addDecision(Decision::DENY); t = ALLOW_DENY_CHECK; attr = false; - } else if(v.first == "check" && t == POLICY) { + } else if (v.first == "check" && t == POLICY) { __builder.reset(); __builder.addDecision(Decision::CHECK); t = ALLOW_DENY_CHECK; attr = false; - } else if(v.first == "") { + } else if (v.first == "") { attr = true; - } else if(attr && t == POLICY) { + } else if (attr && t == POLICY) { if (v.second.data() != "*") value = v.second.data().c_str(); - if(v.first == "context") { - if(std::strcmp(value,"mandatory") == 0 ) { + if (v.first == "context") { + if (std::strcmp(value, "mandatory") == 0 ) { policy_type = PolicyType::CONTEXT; policy_type_value.context = ContextType::MANDATORY; - } else if(std::strcmp(value, "default") == 0) { + } else if (std::strcmp(value, "default") == 0) { policy_type = PolicyType::CONTEXT; policy_type_value.context = ContextType::DEFAULT; } - } else if(v.first == "user") { + } else if (v.first == "user") { policy_type = PolicyType::USER; policy_type_value.user = convertToUid(value); - } else if(v.first == "group") { + } else if (v.first == "group") { policy_type = PolicyType::GROUP; policy_type_value.group = convertToGid(value); } else { @@ -122,30 +122,31 @@ void DbAdapter::updateDecision(const boost::property_tree::ptree::value_type& v, if (v.second.data() != "*") value = v.second.data().c_str(); - if(field_has(v, "send_")) { + if (field_has(v, "send_")) { __builder.addDirection(MessageDirection::SEND); - } else if(field_has(v, "receive_")) { + } else if (field_has(v, "receive_")) { __builder.addDirection(MessageDirection::RECEIVE); - } else if(v.first == "own") { + } else if (v.first == "own") { __builder.addOwner(value); __builder.setPrefix(false); - } else if(v.first == "own_prefix") { + } else if (v.first == "own_prefix") { __builder.addOwner(value); __builder.setPrefix(true); - } else if(v.first == "privilege") + } else if (v.first == "privilege") { __builder.addPrivilege(value); + } - if(field_has(v, "_destination")) + if (field_has(v, "_destination")) __builder.addName(value); - else if(field_has(v, "_sender")) + else if (field_has(v, "_sender")) __builder.addName(value); - else if(field_has(v, "_path")) + else if (field_has(v, "_path")) __builder.addPath(value); - else if(field_has(v, "_interface")) + else if (field_has(v, "_interface")) __builder.addInterface(value); - else if(field_has(v, "_member")) + else if (field_has(v, "_member")) __builder.addMember(value); - else if(field_has(v, "_type")) + else if (field_has(v, "_type")) __builder.addMessageType(__str_to_message_type(value)); } else { attr = false; @@ -161,14 +162,14 @@ void DbAdapter::xmlTraversal(bool bus, bool attr, int level) { static const int Q_XML_MAX_LEVEL = 10; - if(level < Q_XML_MAX_LEVEL) { + if (level < Q_XML_MAX_LEVEL) { for(const auto& v : pt) { - if(v.first == "") { continue; } + if (v.first == "") { continue; } state t = tag; updateDecision(v, policy_type, policy_type_value, t, attr); xmlTraversal(bus, v.second, t, policy_type, policy_type_value, attr, level + 1); } - if(!pt.empty() && level > 1) { + if (!pt.empty() && level > 1) { if (bus) __builder.generateItem(__session_db, policy_type, policy_type_value); else @@ -181,8 +182,8 @@ void DbAdapter::updateDb(bool bus, boost::property_tree::ptree& xmlTree, std::ve const auto& children = xmlTree.get_child("busconfig"); PolicyType policy_type; PolicyTypeValue policy_type_value; - for(const auto& x : children) { - if(x.first == "policy") { + for (const auto& x : children) { + if (x.first == "policy") { __tag_state = POLICY; __attr = false; xmlTraversal(bus, x.second, POLICY, policy_type, policy_type_value); @@ -224,7 +225,6 @@ ItemOwn::ItemOwn(const char* name, Decision decision, const char* privilege) : __decision(DecisionItem(decision, privilege)), __name(name) { - } ItemType ItemOwn::getType() const { @@ -277,8 +277,9 @@ bool MatchItemSR::addNames(const char* name) { if (!c) { --i; len = i-j; - } else + } else { len = i-j-1; + } names[names_num++] = NameSR(name + j, len); } if (names_num >= KDBUS_CONN_MAX_NAMES + 1) @@ -301,7 +302,6 @@ ItemSendReceive::ItemSendReceive(const char* name, __path(path), __type(type), __direction(direction) { - } const char* ItemSendReceive::toString(char* str) const { @@ -390,7 +390,6 @@ ItemBuilder::ItemBuilder() : __current_own(NULL), __current_sr(NULL) { ItemBuilder::~ItemBuilder(){ if (__current_sr) delete __current_sr; - } void ItemBuilder::reset() { @@ -441,9 +440,9 @@ void ItemBuilder::addName(const char* name) { sr->__name.len = 0; } - if (!name) + if (!name) { sr->__name.name = NULL; - else { + } else { sr->__name.name = duplicate(name); sr->__name.len = std::strlen(name); } diff --git a/src/internal/xml_parser.hpp b/src/internal/xml_parser.hpp index 7265172..ff1a723 100644 --- a/src/internal/xml_parser.hpp +++ b/src/internal/xml_parser.hpp @@ -55,7 +55,7 @@ namespace ldp_xml_parser err = parse(bus, true, filename, incl_files); if (err.is_ok()) - for(const auto& x : incl_files) { + for (const auto& x : incl_files) { err = parse(bus, false, x, incl_files); if (err.is_error()) break; } @@ -85,17 +85,16 @@ namespace ldp_xml_parser void getIncludedFiles(const std::string& filename, const std::string& incldir, std::vector& files) { DIR *dir; struct dirent *ent; - std::string fname(filename); - std::string dname = dirname(const_cast(fname.c_str())); + std::string dname = dirname(const_cast(filename.c_str())); if (incldir[0] != '/') dname += (std::string("/") + incldir); else dname = incldir; files.clear(); - if((dir = opendir(dname.c_str())) != NULL) { - while((ent = readdir(dir)) != NULL) { + if ((dir = opendir(dname.c_str())) != NULL) { + while ((ent = readdir(dir)) != NULL) { std::string s(ent->d_name); - if(s.find(".conf") != std::string::npos) { + if (s.find(".conf") != std::string::npos) { files.push_back(dname + std::string("/") + s); } } @@ -106,8 +105,9 @@ namespace ldp_xml_parser std::copy(files.begin(), files.end(), std::ostream_iterator(std::cout, "\n")); std::cout << '\n'; } - } else if (tslog::enabled()) + } else if (tslog::enabled()) { std::cout << "could not open directory " << dname << '\n'; + } } std::pair parseXml(bool bus, const std::string& filename, std::vector& incl_dirs) { @@ -120,11 +120,11 @@ namespace ldp_xml_parser if (!pt.empty()) { __adapter->updateDb(bus, pt, incl_dirs); } - } catch(const boost::property_tree::xml_parser::xml_parser_error& ex) { + } catch (const boost::property_tree::xml_parser::xml_parser_error& ex) { ret.first = ErrCode::error(ex.what()); - } catch(const boost::property_tree::ptree_error& ex) { + } catch (const boost::property_tree::ptree_error& ex) { ret.first = ErrCode::error(ex.what()); - } catch(...) { + } catch (...) { ret.first = ErrCode::error(filename + std::string(": unknown error while parsing XML")); } diff --git a/src/test-libdbuspolicy1-method.cpp b/src/test-libdbuspolicy1-method.cpp index 58424d1..3c24cb5 100644 --- a/src/test-libdbuspolicy1-method.cpp +++ b/src/test-libdbuspolicy1-method.cpp @@ -62,7 +62,7 @@ bool method_test() { bool flag = true; bool ret = true; __internal_init(false, "tests/system.conf"); - for (i = 0;i < sizeof(method_tests)/sizeof(struct MethodTest);i++) { + for (i = 0; i < sizeof(method_tests)/sizeof(struct MethodTest); i++) { if (method_tests[i].recv_send == MessageDirection::SEND) { ret = __internal_can_send(false, method_tests[i].user, method_tests[i].group, method_tests[i].label, method_tests[i].name, method_tests[i].path, method_tests[i].interface, method_tests[i].member, static_cast(method_tests[i].type)); @@ -79,7 +79,7 @@ bool method_test() { return flag; } -int main () { +int main() { __internal_init_once(); if (!method_test()) return -1; diff --git a/src/test-libdbuspolicy1-ownership.cpp b/src/test-libdbuspolicy1-ownership.cpp index bf97fc5..56f5c24 100644 --- a/src/test-libdbuspolicy1-ownership.cpp +++ b/src/test-libdbuspolicy1-ownership.cpp @@ -55,7 +55,7 @@ bool ownership_test() { bool flag = true; bool ret = true; __internal_init(false, "tests/system.conf"); - for (i = 0;i < sizeof(ownership_tests)/sizeof(struct OwnershipTest);i++) { + for (i = 0; i < sizeof(ownership_tests)/sizeof(struct OwnershipTest); i++) { ret = __internal_can_own(false, ownership_tests[i].user, ownership_tests[i].group, ownership_tests[i].label, ownership_tests[i].service); if ( (int)((ownership_tests[i].expected_result)) != ret) { printf("[ERROR][%d] ownership test failed: %d %d ", i, (int)((ownership_tests[i].expected_result)), ret); @@ -67,7 +67,7 @@ bool ownership_test() { return flag; } -int main () { +int main() { __internal_init_once(); if (!ownership_test()) return -1; diff --git a/src/test-libdbuspolicy1-signal.cpp b/src/test-libdbuspolicy1-signal.cpp index af38490..22e9d92 100644 --- a/src/test-libdbuspolicy1-signal.cpp +++ b/src/test-libdbuspolicy1-signal.cpp @@ -34,7 +34,7 @@ bool signal_test() { bool flag = true; bool ret = true; __internal_init(false, "tests/system.conf"); - for (i = 0;i < sizeof(signal_tests)/sizeof(struct SignalTest);i++) { + for (i = 0; i < sizeof(signal_tests)/sizeof(struct SignalTest); i++) { ret = __internal_can_send(false, signal_tests[i].user, signal_tests[i].group, signal_tests[i].label, signal_tests[i].dest, NULL, signal_tests[i].interface, NULL, DBUSPOLICY_MESSAGE_TYPE_SIGNAL); if ( (int)((signal_tests[i].expected_result)) != ret) { printf("[ERROR][%d] signal test failed: %d %d ", i, (int)((signal_tests[i].expected_result)), ret); @@ -46,7 +46,7 @@ bool signal_test() { return flag; } -int main () { +int main() { __internal_init_once(); if (!signal_test()) return -1; -- 2.7.4