From 32bc86464494593a4676cf4548f5ac845bb5269e Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Fri, 20 May 2016 13:15:10 +0200 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 09/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 10/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 7f46292ad55761734fa6955ca5766b81a969a6ec Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Mon, 22 Aug 2016 13:19:38 +0200 Subject: [PATCH 11/16] kdbus_unique_id fix Change-Id: Ice25972fdc38e032f8d06ccb66eec8e3f202337a --- src/libdbuspolicy1.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index d37d285..f214ca9 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -104,12 +104,12 @@ static bool kdbus_is_unique_id(const char* name) static uint64_t kdbus_unique_id(char const *name) { uint64_t res; - unsigned i = 2; + unsigned i = 1; int c; while (!(c = name[++i] - '0')); - res = (uint64_t)c; - while ((c = (int)(name[++i]) - '0') > 0) - res = res*10 + c; + res = (unsigned)c; + while ((c = name[++i] - '0') >= 0) + res = res*10 + (unsigned)c; return res; } -- 2.7.4 From 9aeef4e65c84d437a4f5b88a616c9ae796391f99 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Tue, 23 Aug 2016 12:00:30 +0900 Subject: [PATCH 12/16] bug fix:wrong index of kdbus_unique_id Change-Id: I374bf3de298adf49d67e48b199590a1aa164d0a5 Signed-off-by: sanghyeok.oh --- src/libdbuspolicy1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index f214ca9..41df563 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -104,8 +104,10 @@ static bool kdbus_is_unique_id(const char* name) static uint64_t kdbus_unique_id(char const *name) { uint64_t res; - unsigned i = 1; + unsigned i = 2; int c; + + /* unique id : ':1.001010'. starting index is 3 */ while (!(c = name[++i] - '0')); res = (unsigned)c; while ((c = name[++i] - '0') >= 0) -- 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 13/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 From c3398bfaf4ace588f9b979893848cc09ff9dabd9 Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Wed, 24 Aug 2016 16:48:55 +0200 Subject: [PATCH 14/16] Fix: enable libdbuspolicy for multiple init. Change-Id: I5ffea43051cb5bd51320333fde273815e12801ae --- src/libdbuspolicy1.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 41df563..79b858b 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -60,6 +60,7 @@ struct kconn { int fd; uint64_t id; char *pool; + int counter; } g_conn[2]; struct udesc { @@ -213,25 +214,27 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) } if (rb) goto err_close; + if (g_conn[bus_type].counter == 0) { + if ((g_conn[bus_type].fd = kdbus_open_bus(resolved_path)) < 0) + goto err; - 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; - 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); + 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; - rp = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_PRIMARY : SESSION_BUS_CONF_FILE_PRIMARY); - 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; + if (rp < 0 && rs < 0) /* when both negative */ + goto err_close; + } + g_conn[bus_type].counter++; pthread_mutex_unlock(&g_mutex); __internal_init_flush_logs(); - if (rp < 0 && rs < 0) /* when both negative */ - goto err_close; - return &g_conn[bus_type]; err_close: @@ -243,8 +246,18 @@ err: DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) { - if (configuration) - close(((typeof(&g_conn[0]))configuration)->fd); + if (configuration) { + struct kconn* k = (struct kconn*)configuration; + pthread_mutex_lock(&g_mutex); + + --k->counter; + if (k->counter <= 0) { + munmap(k->pool, KDBUS_POOL_SIZE); + close(k->fd); + } + + pthread_mutex_unlock(&g_mutex); + } } #ifdef LIBDBUSPOLICY_TESTS_API @@ -313,7 +326,6 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, *(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) { if (errno == ENXIO || errno == ESRCH) -- 2.7.4 From 1b4d4f2311ae31440417fafd3233177d39bfd768 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Mon, 29 Aug 2016 14:03:54 +0900 Subject: [PATCH 15/16] revert changes:revert commit id dc3048a8de00c01514c14ef465a87b8ca9a7c704 previous submit has bug, and revert it "Prefix tree search for ownership rules, removed virtual methods." id : dc3048a8de00c01514c14ef465a87b8ca9a7c704 Change-Id: I0a73eab24c95f1a6cc3a4e37a9ffb0d2da943e3f Signed-off-by: sanghyeok.oh --- src/internal/internal.cpp | 98 +++++---- src/internal/naive_policy_checker.cpp | 253 +++++++++------------- src/internal/naive_policy_checker.hpp | 45 ++-- src/internal/naive_policy_db.cpp | 318 +++++++--------------------- src/internal/naive_policy_db.hpp | 95 +++------ src/internal/policy.cpp | 384 ++++++++++++++++++---------------- src/internal/policy.hpp | 108 +++------- 7 files changed, 510 insertions(+), 791 deletions(-) mode change 100644 => 100755 src/internal/internal.cpp mode change 100644 => 100755 src/internal/naive_policy_checker.cpp mode change 100644 => 100755 src/internal/naive_policy_checker.hpp mode change 100644 => 100755 src/internal/naive_policy_db.cpp mode change 100644 => 100755 src/internal/naive_policy_db.hpp mode change 100644 => 100755 src/internal/policy.cpp mode change 100644 => 100755 src/internal/policy.hpp diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp old mode 100644 new mode 100755 index ff19d1b..84f25b1 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -27,15 +27,38 @@ static ldp_xml_parser::NaivePolicyChecker policy_checker; static const char* get_str(const char* const szstr) { - return (szstr != NULL) ? 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; } 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; @@ -75,58 +98,49 @@ 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); - if (!matcher.addNames(destination)) { + 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: " << destination << std::endl; + std::cout << "Destination too long: "<(policy_checker.check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::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, - 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) { - 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)); + 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, - 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) { - 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: " << sender << std::endl; - return false; - } - return static_cast(policy_checker.check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::RECEIVE)); + 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)); } 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 old mode 100644 new mode 100755 index ca07111..bc2a75d --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -1,23 +1,8 @@ #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]; } @@ -33,29 +47,31 @@ 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: + 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) return DecisionResult::ALLOW; - case Decision::ANY: - case Decision::DENY: + else if (ret == ldp_cynara::CynaraResult::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) - return DecisionResult::ALLOW; - else if (ret == ldp_cynara::CynaraResult::DENY) - return DecisionResult::DENY; - else - return DecisionResult::CYNARA_ERROR; - } + else + return DecisionResult::CYNARA_ERROR; + } } + return DecisionResult::DENY; } @@ -63,145 +79,74 @@ NaivePolicyChecker::~NaivePolicyChecker() { delete m_adapter; } - - -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) { +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; const char* privilege; - const NaivePolicyDb::PolicyOwn* curr_policy = NULL; + const NaivePolicyDb::Policy* 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); + curr_policy = policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::MANDATORY)); + if (curr_policy) + ret = checkPolicy(*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); + curr_policy = policy_db.getPolicy(type, PolicyType::USER, PolicyTypeValue(uid)); + if (curr_policy) + ret = checkPolicy(*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); + curr_policy = policy_db.getPolicy(type, PolicyType::GROUP, PolicyTypeValue(gid)); + if (curr_policy) + ret = checkPolicy(*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); + curr_policy = policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT)); + if (curr_policy) + ret = checkPolicy(*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); +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; } - if (ret == Decision::ANY) { - if (policy_db.getPolicy(type, PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), 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) - return parseDecision(ret, uid, label, privilege); - else - return DecisionResult::DENY; + return DecisionResult::DENY; } diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp old mode 100644 new mode 100755 index a54302d..7e351a3 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -26,47 +26,36 @@ namespace ldp_xml_parser NaivePolicyDb m_bus_db[2]; DbAdapter* m_adapter; NaivePolicyDb& getPolicyDb(bool type); - - Decision checkPolicySR(const NaivePolicyDb::PolicySR& policy, - const MatchItemSR& item, - const char*& privilege); - - Decision checkPolicyOwn(const NaivePolicyDb::PolicyOwn& policy, - const ItemOwn& item, + Decision checkPolicy(const NaivePolicyDb::Policy& policy, + const Item& item, const char*& privilege); - DecisionResult parseDecision(Decision decision, uid_t uid, const char* label, const char* privilege); - - DecisionResult checkItemSR(bool bus_type, + DecisionResult checkItem(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 ItemOwn& item, - const ItemType type); + const Item& item); 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, - MatchItemSR& matcher, - ItemType 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 old mode 100644 new mode 100755 index a623059..bccf9e3 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -1,252 +1,110 @@ #include "naive_policy_db.hpp" -#include "cynara.hpp" +#include #include "tslog.hpp" 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++) { - treeRootPtr->children[i] = NULL; - } -} - -NaivePolicyDb::PolicyOwn::~PolicyOwn(){ - nodeRemove(&treeRootPtr); -} - -void NaivePolicyDb::PolicyOwn::nodeRemove(TreeNode **node){ - if (!*node) { - return; - } - for (int i = 0 ; i < MAX_CHILDREN; i++) { - if ((*node)->children[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 << std::endl; - } - - const MessageDirection dir = item->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 << std::endl; - } - - addItem(m_own_set, policy_type, policy_type_value, item); -} - - - -bool NaivePolicyDb::getPolicy(const ItemType item_type, - const PolicyType policy_type, - const PolicyTypeValue policy_type_value, - const NaivePolicyDb::PolicyOwn*& policy) const { - return this->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) +NaivePolicyDb::Policy::PolicyConstIterator::PolicyConstIterator(const std::vector& items, int position) : m_items(items), m_index(position) { } -ItemSendReceive* const& NaivePolicyDb::PolicySR::PolicyConstIterator::operator*() const { + Item* const& NaivePolicyDb::Policy::PolicyConstIterator::operator*() const { return m_items[m_index]; } - -typename NaivePolicyDb::PolicySR::PolicyConstIterator& NaivePolicyDb::PolicySR::PolicyConstIterator::operator++() { +NaivePolicyDb::Policy::PolicyConstIterator& NaivePolicyDb::Policy::PolicyConstIterator::operator++() { if (m_index >= 0) --m_index; return *this; } - -bool NaivePolicyDb::PolicySR::PolicyConstIterator::operator!=(const PolicyConstIterator& it) const { +bool NaivePolicyDb::Policy::PolicyConstIterator::operator!=(const PolicyConstIterator& it) const { return m_index != it.m_index; } - -NaivePolicyDb::PolicySR::PolicyIterator::PolicyIterator(std::vector< ItemSendReceive* > & items, int position) +NaivePolicyDb::Policy::PolicyIterator::PolicyIterator(std::vector& items, int position) : m_items(items), m_index(position) { } - -ItemSendReceive*& NaivePolicyDb::PolicySR::PolicyIterator::operator*() { +Item*& NaivePolicyDb::Policy::PolicyIterator::operator*() { return m_items[m_index]; } - -typename NaivePolicyDb::PolicySR::PolicyIterator& NaivePolicyDb::PolicySR::PolicyIterator::operator++() { +NaivePolicyDb::Policy::PolicyIterator& NaivePolicyDb::Policy::PolicyIterator::operator++() { if (m_index >= 0) --m_index; return *this; } - -bool NaivePolicyDb::PolicySR::PolicyIterator::operator!=(const PolicyIterator& it) const { +bool NaivePolicyDb::Policy::PolicyIterator::operator!=(const PolicyIterator& it) const { return m_index != it.m_index; } - -NaivePolicyDb::PolicySR::PolicyIterator NaivePolicyDb::PolicySR::begin() { +NaivePolicyDb::Policy::PolicyIterator NaivePolicyDb::Policy::begin() { int s = m_items.size() - 1; - return NaivePolicyDb::PolicySR::PolicyIterator(m_items, s); + return NaivePolicyDb::Policy::PolicyIterator(m_items, s); } - - -NaivePolicyDb::PolicySR::PolicyIterator NaivePolicyDb::PolicySR::end() { - return NaivePolicyDb::PolicySR::PolicyIterator(m_items, -1); +NaivePolicyDb::Policy::PolicyIterator NaivePolicyDb::Policy::end() { + return NaivePolicyDb::Policy::PolicyIterator(m_items, -1); } - - -NaivePolicyDb::PolicySR::PolicyConstIterator NaivePolicyDb::PolicySR::begin() const { +NaivePolicyDb::Policy::PolicyConstIterator NaivePolicyDb::Policy::begin() const { int s = m_items.size() - 1; - return NaivePolicyDb::PolicySR::PolicyConstIterator(m_items, s); + return NaivePolicyDb::Policy::PolicyConstIterator(m_items, s); } - - -NaivePolicyDb::PolicySR::PolicyConstIterator NaivePolicyDb::PolicySR::end() const { - return NaivePolicyDb::PolicySR::PolicyConstIterator(m_items, -1); +NaivePolicyDb::Policy::PolicyConstIterator NaivePolicyDb::Policy::end() const { + return NaivePolicyDb::Policy::PolicyConstIterator(m_items, -1); } - -void NaivePolicyDb::PolicySR::addItem(ItemSendReceive* item) { +void NaivePolicyDb::Policy::addItem(Item* 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 char *name = item->getName(); - - 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++; +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; } - 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 ="; - 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"; + 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 false; + return NULL; } - -void NaivePolicyDb::addItem(NaivePolicyDb::PolicyTypeSetSR& set, - const PolicyType policy_type, - const PolicyTypeValue policy_type_value, - ItemSendReceive* const item) { +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); @@ -260,56 +118,28 @@ void NaivePolicyDb::addItem(NaivePolicyDb::PolicyTypeSetSR& set, } } +void NaivePolicyDb::addItem(const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + Item* const item) { + const ItemSendReceive* it; -bool NaivePolicyDb::getPolicyOwn(const NaivePolicyDb::PolicyTypeSetOwn& set, - const PolicyType policy_type, - const PolicyTypeValue policy_type_value, - const NaivePolicyDb::PolicyOwn*& policy) const -{ - if (tslog::enabled()) - std::cout << "---policy_type ="; - 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()) { + char tmp[MAX_LOG_LINE]; + const char* i_str = item->toString(tmp); + std::cout<<"Add item: "<< i_str <(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; + if (dynamic_cast(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 old mode 100644 new mode 100755 index 3b8a655..fdbd0c1 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -24,28 +24,28 @@ namespace ldp_xml_parser { class NaivePolicyDb { public: - class PolicySR { + class Policy { 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); - ItemSendReceive* const& operator*() const; + 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; + std::vector& m_items; int m_index; public: - PolicyIterator(std::vector& items, int position); - ItemSendReceive*& operator*(); + PolicyIterator(std::vector& items, int position); + Item*& operator*(); PolicyIterator& operator++(); bool operator!=(const PolicyIterator& it) const; }; @@ -54,78 +54,33 @@ namespace ldp_xml_parser PolicyIterator end(); PolicyConstIterator begin() const; PolicyConstIterator end() const; - 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; + void addItem(Item* item); }; ~NaivePolicyDb(); - 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; + 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, - ItemOwn* const item); - - void addItem(const PolicyType policy_type, - const PolicyTypeValue policy_type_value, - ItemSendReceive* const item); - + Item* const item); private: - - 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; + struct PolicyTypeSet { + Policy context[static_cast(ContextType::MAX)]; + std::map user; + std::map group; }; - 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; + 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 old mode 100644 new mode 100755 index 9bcdb63..20076e5 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -11,6 +11,16 @@ 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; @@ -79,39 +89,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,31 +132,30 @@ 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; @@ -162,18 +171,22 @@ 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 (bus) - __builder.generateItem(__session_db, policy_type, policy_type_value); - else - __builder.generateItem(__system_db, policy_type, policy_type_value); + + 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); + } } } } @@ -182,8 +195,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); @@ -193,159 +206,169 @@ void DbAdapter::updateDb(bool bus, boost::property_tree::ptree& xmlTree, std::ve } } -DecisionItem::DecisionItem(Decision decision, const char* privilege) - : __decision(decision), __privilege(privilege) -{ +Item::Item(Decision decision, const char* privilege, bool isOwner) + : _decision(decision), _privilege(privilege), _is_owner(isOwner) { + } -DecisionItem::~DecisionItem() -{ - if (__privilege) - delete[] __privilege; +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 DecisionItem::getDecision() const { - return __decision; +Decision Item::getDecision() const { + return _decision; } -const char* DecisionItem::getPrivilege() const { - return __privilege; +const char* Item::getPrivilege() const { + return _privilege; } -ItemType DecisionItem::getType() const { +ItemType Item::getType() const { return ItemType::GENERIC; } -const char* DecisionItem::toString(char* str) const { - snprintf(str, MAX_LOG_LINE, "Item: dec(%s) priv(%s)", __decision_to_str(__decision), __privilege); +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) - : __decision(DecisionItem(decision, privilege)), __name(name) { +: 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 (!it) + return false; -const char* ItemOwn::toString(char* str) const { - snprintf(str, MAX_LOG_LINE, "ItemOwn: service(%s), pref(%d)", __name, __is_prefix); - return str; -} - -const char* ItemOwn::getName() const { - return __name; -} - -bool ItemOwn::isPrefix() const { - return __is_prefix; -} + if (__is_prefix) { + int i = 0; + if (!__name) + return false; -const DecisionItem& ItemOwn::getDecision() const { - return __decision; -} + for (i = 0; __name[i] && it->__name[i]; i++) + if (__name[i] != it->__name[i]) + return false; -NameSR::NameSR(const char* m, int l) : name(m), len(l) -{ -} + if (__name[i] != 0) + return false; -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) { + return true; + } else if (!__name) + return true; + else { + return std::strcmp(__name, it->__name) == 0; + } } -MatchItemSR::~MatchItemSR(){ +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; } -void MatchItemSR::addName(const char* name) { - names[names_num++] = NameSR(name, std::strlen(name)); +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) { } - -bool MatchItemSR::addNames(const char* name) { +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 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; + 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++; } - 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)); + *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() { - delete[] __interface; - delete[] __member; - delete[] __path; - - if (__name.len > 0) { - delete[] __name.name; + 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 MatchItemSR& item) const { - if (__type != MessageType::ANY && __type != item.type) +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; - if (__direction != item.direction) + if (__direction != it->__direction) return false; - if (__interface && item.interface && std::strcmp(__interface, item.interface)) + if (__interface && it->__interface && std::strcmp(__interface, it->__interface)) return false; - if (__path && item.path && std::strcmp(__path, item.path)) + if (__path && it->__path && std::strcmp(__path, it->__path)) return false; - if (__member && item.member && std::strcmp(__member, item.member)) + if (__member && it->__member && std::strcmp(__member, it->__member)) return false; - if (__name.len > 0 ) { + if (__names && __names[0]) { int i = 0; bool f = false; - 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)) { + if (it->__names) { + while (it->__names[i]) { + if (__compare_str(it->__names[i++], __names[0])) { f = true; break; } - i++; } if (!f) return false; @@ -367,36 +390,40 @@ MessageDirection ItemSendReceive::getDirection() const { return __direction; } -const DecisionItem& ItemSendReceive::getDecision() const { - return __decision; -} - ItemOwn* ItemBuilder::getOwnItem() { - __current_item_type = ItemType::OWN; - return &__current_own; + if (!__current) { + __current = new ItemOwn(); + prepareItem(); + } + return dynamic_cast(__current); } ItemSendReceive* ItemBuilder::getSendReceiveItem() { - if (!__current_sr) { - __current_sr = new ItemSendReceive(); + if (!__current) { + __current = new ItemSendReceive(); + prepareItem(); } - __current_item_type = ItemType::SEND; - return __current_sr; + return dynamic_cast(__current); } -ItemBuilder::ItemBuilder() : __current_own(NULL), __current_sr(NULL) { +ItemBuilder::ItemBuilder() : __current(NULL), __delayed_privilege(NULL) { } ItemBuilder::~ItemBuilder(){ - if (__current_sr) - delete __current_sr; + if (__delayed_privilege) + delete[] __delayed_privilege; + if (__current) + delete __current; } void ItemBuilder::reset() { - __decision.__decision = Decision::ANY; - __decision.__privilege = NULL; - __current_sr = NULL; - __current_own = NULL; + if (__delayed_privilege) + delete[] __delayed_privilege; + if (__current) + delete __current; + + __current = NULL; + __delayed_privilege = NULL; } char* ItemBuilder::duplicate(const char* str) { @@ -415,15 +442,21 @@ char* ItemBuilder::duplicate(const char* str) { 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::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) { @@ -435,28 +468,17 @@ void ItemBuilder::addOwner(const char* owner) { void ItemBuilder::addName(const char* name) { ItemSendReceive* sr = getSendReceiveItem(); - if (sr->__name.len > 0) { - delete[] sr->__name.name; - sr->__name.len = 0; + if (sr->__names) { + delete sr->__names[0]; + delete[] sr->__names; } - - if (!name) { - sr->__name.name = NULL; - } else { - 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, " "); + if (!name) + sr->__names = NULL; + else { + sr->__names = new const char*[2]; + sr->__names[0] = duplicate(name); + sr->__names[1] = NULL; } - 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) { @@ -485,11 +507,17 @@ void ItemBuilder::addDirection(MessageDirection direction) { } void ItemBuilder::addPrivilege(const char* privilege) { - __decision.__privilege = duplicate(privilege); + if (!__current) + __delayed_privilege = duplicate(privilege); + else + __current->_privilege = duplicate(privilege); } void ItemBuilder::addDecision(Decision decision) { - __decision.__decision = decision; + if (!__current) + __delayed_decision = decision; + else + __current->_decision = decision; } void ItemBuilder::setPrefix(bool value) { diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp old mode 100644 new mode 100755 index 55834cc..e76e3f2 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -18,23 +18,11 @@ #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, @@ -49,7 +37,7 @@ namespace ldp_xml_parser RECEIVE }; - enum class ItemType : uint8_t { + enum class ItemType : uint8_t{ GENERIC, OWN, SEND, @@ -92,70 +80,41 @@ namespace ldp_xml_parser class ItemBuilder; - class DecisionItem { - private: - Decision __decision; - const char* __privilege; + class Item { + protected: + Decision _decision; + const char* _privilege; + bool _is_owner; public: friend class ItemBuilder; - 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; + 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 { + class ItemOwn : public Item { 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); - 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; + virtual ~ItemOwn(); + virtual bool match(const Item* item) const; + virtual ItemType getType() const; + virtual const char* toString(char* str) const; }; - class ItemSendReceive { - private: - DecisionItem __decision; - NameSR __name; + class ItemSendReceive : public Item { + const char** __names; const char* __interface; const char* __member; const char* __path; @@ -163,7 +122,7 @@ namespace ldp_xml_parser MessageDirection __direction; public: friend class ItemBuilder; - ItemSendReceive(const char* name = NULL, + ItemSendReceive(const char** names = NULL, const char* interface = NULL, const char* member = NULL, const char* path = NULL, @@ -171,28 +130,26 @@ namespace ldp_xml_parser MessageDirection direction = MessageDirection::ANY, Decision decision = Decision::ANY, const char* privilege = NULL); - ~ItemSendReceive(); - bool match(const MatchItemSR& item) const; + virtual ~ItemSendReceive(); + virtual bool match(const Item* item) const; MessageDirection getDirection() const; - ItemType getType() const; - const char* toString(char* str) const; - const DecisionItem& getDecision() const; + virtual ItemType getType() const; + virtual const char* toString(char* str) const; }; - class NaivePolicyDb; class ItemBuilder { private: - DecisionItem __decision; - ItemOwn __current_own; - ItemType __current_item_type; - ItemSendReceive* __current_sr; + Item* __current; + Decision __delayed_decision; + const char* __delayed_privilege; ItemOwn* getOwnItem(); ItemSendReceive* getSendReceiveItem(); char* duplicate(const char* str); + void prepareItem(); public: ItemBuilder(); ~ItemBuilder(); - void generateItem(NaivePolicyDb& db, PolicyType& policy_type, PolicyTypeValue& policy_type_value); + Item* generateItem(); void reset(); void addUser(const char* name); void addGroup(const char* name); @@ -208,6 +165,7 @@ namespace ldp_xml_parser void setPrefix(bool value); }; + class NaivePolicyDb; class DbAdapter { private: enum state { -- 2.7.4 From 895811c77cb228db2ff58bebed4536f1be89ed1e Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Mon, 29 Aug 2016 13:05:05 +0200 Subject: [PATCH 16/16] Revert "revert changes:revert commit id dc3048a8de00c01514c14ef465a87b8ca9a7c704" This reverts commit 1b4d4f2311ae31440417fafd3233177d39bfd768. This revert is not nessesary- it requiers only simple fix. Change-Id: I4591012edd0d039b1eb7bb382cf0b34b8e5e6771 --- src/internal/internal.cpp | 98 ++++----- src/internal/naive_policy_checker.cpp | 253 +++++++++++++--------- src/internal/naive_policy_checker.hpp | 45 ++-- src/internal/naive_policy_db.cpp | 318 +++++++++++++++++++++------- src/internal/naive_policy_db.hpp | 95 ++++++--- src/internal/policy.cpp | 384 ++++++++++++++++------------------ src/internal/policy.hpp | 108 +++++++--- 7 files changed, 791 insertions(+), 510 deletions(-) mode change 100755 => 100644 src/internal/internal.cpp mode change 100755 => 100644 src/internal/naive_policy_checker.cpp mode change 100755 => 100644 src/internal/naive_policy_checker.hpp mode change 100755 => 100644 src/internal/naive_policy_db.cpp mode change 100755 => 100644 src/internal/naive_policy_db.hpp mode change 100755 => 100644 src/internal/policy.cpp mode change 100755 => 100644 src/internal/policy.hpp diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp old mode 100755 new mode 100644 index 84f25b1..ff19d1b --- 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,58 @@ 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: " << sender << std::endl; + return false; + } + return static_cast(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 old mode 100755 new mode 100644 index bc2a75d..ca07111 --- 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]; } @@ -47,31 +33,29 @@ 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; } @@ -79,74 +63,145 @@ 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 + } 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; } - 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; + +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; + 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 + return DecisionResult::DENY; } diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp old mode 100755 new mode 100644 index 7e351a3..a54302d --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -26,36 +26,47 @@ 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 Item& item); + const MatchItemSR& item, + const ItemType type); + + DecisionResult checkItemOwn(bool bus_type, + uid_t uid, + gid_t gid, + const char* label, + 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 old mode 100755 new mode 100644 index bccf9e3..a623059 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -1,110 +1,252 @@ #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 ; i < MAX_CHILDREN; i++) { + if ((*node)->children[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 << std::endl; + } + + const MessageDirection dir = item->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 << std::endl; + } + + addItem(m_own_set, policy_type, policy_type_value, item); +} + + + +bool NaivePolicyDb::getPolicy(const ItemType item_type, + const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + const NaivePolicyDb::PolicyOwn*& policy) const { + return this->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 char *name = item->getName(); -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 (!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]; + std::cout << "---policy_type ="; + 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 +260,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 old mode 100755 new mode 100644 index fdbd0c1..3b8a655 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -24,28 +24,28 @@ 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 +54,78 @@ 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, - Item* const item); + ItemOwn* const item); + + void addItem(const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + 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 old mode 100755 new mode 100644 index 20076e5..9bcdb63 --- 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; @@ -89,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 { @@ -132,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; @@ -171,22 +162,18 @@ 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) { - 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 (!pt.empty() && level > 1) { + if (bus) + __builder.generateItem(__session_db, policy_type, policy_type_value); + else + __builder.generateItem(__system_db, policy_type, policy_type_value); } } } @@ -195,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); @@ -206,169 +193,159 @@ 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; - } -} - -bool Item::match(const Item& item) const { - return match(&item); -} - -bool Item::match(const Item* item) const { - return true; +DecisionItem::~DecisionItem() +{ + if (__privilege) + delete[] __privilege; } -Decision Item::getDecision() const { - return _decision; +Decision DecisionItem::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,36 @@ 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 +415,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 +435,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; - else { - sr->__names = new const char*[2]; - sr->__names[0] = duplicate(name); - sr->__names[1] = NULL; + + if (!name) { + sr->__name.name = NULL; + } else { + 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 +485,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 old mode 100755 new mode 100644 index e76e3f2..55834cc --- 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