From 366fdf52afc17355e024c493c5421abf5f63278d Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 10 Apr 2019 16:25:24 +0200 Subject: [PATCH 01/16] refactoring: group kconn ops into a class This moves functions dealing with kconn into the kconn class. Change-Id: I27422ae661071ec33d27bced8b2954ea744d16d0 --- src/libdbuspolicy1.cpp | 133 ++++++++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 58 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index eb8a802..f6cf758 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -150,12 +150,63 @@ private: NaivePolicyChecker &_checker; }; -struct kconn { +/* + * kconn is a class which binds together a kdbus connection and a corresponding policy checker. + * It has two flavors: + * - global objects for system bus and session bus with private connections (static get() method); + * - objects created on demand when a client shares his kdbus connection with the library (static get_shared() method). + * + * Because the pointer to such object is passed (through void *) to a client, and then clients + * pass the pointer to dbuspolicy1_* functions, we always need to maintain the same type, + * regardless of the flavor. + * + * Thread-safety is ensured by C++ and static initialization in static member functions. + */ +class kconn { +public: KdbusConnection conn; - ldp_xml_parser::NaivePolicyChecker *checker; -} g_conn[2]; + NaivePolicyChecker &checker; + bool can_be_freed; -static std::once_flag init_once_conn[2]; + kconn(NaivePolicyChecker &ch, const char *resolved_path) + : checker{ch}, can_be_freed{false} + { + if (conn.connect(resolved_path, 0, _KDBUS_ATTACH_ALL, 0) < 0) { + assert(false && "failed kdbus_connect"); + } + } + + kconn(NaivePolicyChecker &ch, int fd) + : checker{ch}, can_be_freed{true} + { + conn.shared_init_fd(fd); + } + + static inline kconn &get(BusType bus_type, const char *resolved_path) { + if (SYSTEM_BUS == bus_type) + return system(resolved_path); + return session(resolved_path); + } + + static inline kconn *get_shared(BusType bus_type, int fd) + { + kconn *result = new kconn(Checker::get(bus_type).checker(), fd); + if (nullptr == result) + LOGE("Error: failed to allocate memory for policy configuration"); + return result; + } + +private: + static kconn &system(const char *resolved_path) { + static kconn c{Checker::system().checker(), resolved_path}; + return c; + } + static kconn &session(const char *resolved_path) { + static kconn c{Checker::session().checker(), resolved_path}; + return c; + } + +}; static std::shared_ptr bus_type_from_path(const char *bus_path, BusType &bus_type) { @@ -224,40 +275,8 @@ static std::shared_ptr bus_path_resolve(const char *bus_path, BusTyp return resolved_path; } -static void init_global_conn_locked(BusType bus_type, std::shared_ptr resolved_path) -{ - struct kconn *kconn = &g_conn[bus_type]; - kconn->checker = &Checker::get(bus_type).checker(); - - if (kconn->conn.connect(resolved_path.get(), 0, _KDBUS_ATTACH_ALL, 0) < 0) { - assert(false && "failed kdbus_connect"); - } -} - -static struct kconn *get_global_conn(BusType bus_type, std::shared_ptr resolved_path) noexcept -{ - std::call_once(init_once_conn[bus_type], init_global_conn_locked, bus_type, resolved_path); - - return &g_conn[bus_type]; -} - -static kconn *init_shared_fd(BusType bus_type, int fd) -{ - kconn *result = new kconn; - if (nullptr == result) { - LOGE("Error: failed to allocate memory for policy configuration"); - return nullptr; - } - result->conn.shared_init_fd(fd); - result->checker = &Checker::get(bus_type).checker(); - return result; -} - DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd) { - static_assert(SYSTEM_BUS == 0, "SYSTEM_BUS not 0"); - static_assert(SESSION_BUS == 1, "SESSION_BUS not 1"); - BusType bus_type = SESSION_BUS; uid_t bus_owner = 0; @@ -269,12 +288,12 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd) g_udesc.init(); - struct kconn *result = nullptr; + kconn *result = nullptr; if (Checker::get(bus_type).can_open_owned_by(bus_owner)) { if (-1 == fd) { - result = get_global_conn(bus_type, resolved_path); + result = &kconn::get(bus_type, resolved_path.get()); } else { - result = init_shared_fd(bus_type, fd); + result = kconn::get_shared(bus_type, fd); } } @@ -298,11 +317,9 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_init_set_pool(void *configuration, void *poo DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) { - for (size_t i = 0; i < sizeof(g_conn)/sizeof(g_conn[0]); i++) - if (configuration == &g_conn[i]) - return; - - delete KCONN(configuration); + auto kconn = KCONN(configuration); + if (kconn->can_be_freed) + delete kconn; } /* @@ -361,7 +378,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, auto m_type = toMessageType(message_type); MatchItemSend sendItem(interface, member, path, m_type, destinationInfo.names()); - auto decision = kconn->checker->check(g_udesc.uid, g_udesc.gid, g_udesc.label, sendItem); + auto decision = kconn->checker.check(g_udesc.uid, g_udesc.gid, g_udesc.label, sendItem); if (DecisionResult::ALLOW != decision) return decisionToRetCode(decision); @@ -374,10 +391,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, return r; MatchItemReceive receiveItem(interface, member, path, m_type, senderInfo.names()); - return decisionToRetCode(kconn->checker->check(destinationInfo.uid(), - destinationInfo.gid(), - destinationInfo.label(), - receiveItem)); + return decisionToRetCode(kconn->checker.check(destinationInfo.uid(), + destinationInfo.gid(), + destinationInfo.label(), + receiveItem)); } DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, @@ -405,7 +422,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, auto m_type = toMessageType(message_type); MatchItemSend sendItem(interface, member, path, m_type, info.names()); - auto decision = kconn->checker->check(sender_uid, sender_gid, sender_label, sendItem); + auto decision = kconn->checker.check(sender_uid, sender_gid, sender_label, sendItem); if (DecisionResult::ALLOW != decision) return decisionToRetCode(decision); @@ -417,18 +434,18 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, KdbusBusNames names; MatchItemReceive receiveItem(interface, member, path, m_type, names.addSpaceSeparatedNames(sender)); - return decisionToRetCode(kconn->checker->check(g_udesc.uid, - g_udesc.gid, - g_udesc.label, - receiveItem)); + return decisionToRetCode(kconn->checker.check(g_udesc.uid, + g_udesc.gid, + g_udesc.label, + receiveItem)); } DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* const service) { tslog::LogLock log_lock; auto kconn = KCONN(configuration); - return decisionToRetCode(kconn->checker->check(g_udesc.uid, - g_udesc.gid, - g_udesc.label, - MatchItemOwn(service))); + return decisionToRetCode(kconn->checker.check(g_udesc.uid, + g_udesc.gid, + g_udesc.label, + MatchItemOwn(service))); } -- 2.7.4 From befaa9f2b51f8da01fa34f3cc07540fe207fc6d4 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 10 Apr 2019 16:04:13 +0200 Subject: [PATCH 02/16] refactoring: group path resolving ops into a class This introduces BusPathResolver class. Change-Id: I56d22e0b6b5e565415b1ff6d070986efa97c7502 --- src/libdbuspolicy1.cpp | 129 ++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 67 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index f6cf758..394e685 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -36,9 +36,6 @@ #include #include -#define KDBUS_PATH_PREFIX "/sys/fs/kdbus/" -#define KDBUS_SYSTEM_BUS_PATH KDBUS_PATH_PREFIX"0-system/bus" - using ldp_xml_parser::DecisionResult; using ldp_xml_parser::MatchItemSend; using ldp_xml_parser::MatchItemReceive; @@ -208,90 +205,88 @@ private: }; -static std::shared_ptr bus_type_from_path(const char *bus_path, BusType &bus_type) -{ - assert(bus_path); - - std::shared_ptr p(realpath(bus_path, nullptr), [](const char *a) { free(const_cast(a)); }); - if (!p) - return nullptr; - - if (0 == strcmp(p.get(), KDBUS_SYSTEM_BUS_PATH)) { - bus_type = SYSTEM_BUS; - return p; - } - - if (0 == strncmp(p.get(), KDBUS_PATH_PREFIX, strlen(KDBUS_PATH_PREFIX))) { - bus_type = SESSION_BUS; - return p; - } - - return nullptr; -} - -// We will never get 0 as a session bus owner (0 uses "0-system" bus), -// so it's OK to assume that bus_owner==0 always means error. -static uid_t bus_owner_from_path(const char *resolved_path) noexcept -{ - boost::string_ref user_suffix("-user/bus"); - boost::string_ref ps(resolved_path); - - if (!ps.ends_with(user_suffix)) - return 0; - - ps.remove_suffix(user_suffix.length()); - - size_t last_slash = ps.find_last_of('/'); - if (last_slash == boost::string_ref::npos || last_slash == ps.length() - 1) - return 0; - - ps = ps.substr(last_slash+1); +/* + * This class encapsulates functions used to analyze passed path to kdbus bus file. + * It recognizes system and session paths. + * If it recognizes path as a session bus, then it extracts owner's uid. + */ +class BusPathResolver { + std::shared_ptr resolved_path; + BusType type{SESSION_BUS}; + uid_t owner{0}; + bool ok{false}; + + // We will never get 0 as a session bus owner (0 uses "0-system" bus), + // so it's OK to assume that bus_owner==0 always means error. + bool extract_bus_owner() noexcept + { + boost::string_ref user_suffix("-user/bus"); + boost::string_ref ps(resolved_path.get()); - errno = 0; - uid_t bus_owner = strtol(ps.data(), NULL, 10); - if (errno) - return 0; + if (!ps.ends_with(user_suffix)) + return false; - return bus_owner; -} + ps.remove_suffix(user_suffix.length()); -static std::shared_ptr bus_path_resolve(const char *bus_path, BusType &bus_type, uid_t &bus_owner) -{ - assert(bus_path); + size_t last_slash = ps.find_last_of('/'); + if (last_slash == boost::string_ref::npos || last_slash == ps.length() - 1) + return false; - auto resolved_path = bus_type_from_path(bus_path, bus_type); + ps = ps.substr(last_slash+1); - if (nullptr == resolved_path) - return nullptr; + errno = 0; + uid_t bus_owner = strtol(ps.data(), NULL, 10); + if (errno) + return false; - if (bus_type == SESSION_BUS) { - auto result = bus_owner_from_path(resolved_path.get()); - if (result > 0) - bus_owner = result; - else - return nullptr; + owner = bus_owner; + type = SESSION_BUS; + return true; } +#define STR_SIZE(x) (x), sizeof(x)-1 + static constexpr boost::string_ref KDBUS_PATH_PREFIX{STR_SIZE("/sys/fs/kdbus/")}; + static constexpr boost::string_ref KDBUS_SYSTEM_BUS_PATH{STR_SIZE("/sys/fs/kdbus/0-system/bus")}; +#undef STR_SIZE - return resolved_path; -} +public: + BusPathResolver(const char *bus_path) + : resolved_path(realpath(bus_path, nullptr), [](const char *a) { free(const_cast(a)); }) + { + if (!resolved_path) + return; + + // recognize bus type + if (KDBUS_SYSTEM_BUS_PATH == resolved_path.get()) { + type = SYSTEM_BUS; + ok = true; + } else if (boost::string_ref(resolved_path.get()).starts_with(KDBUS_PATH_PREFIX)) { + ok = extract_bus_owner(); + } + } + operator bool() { return ok; } + const char *path() { return resolved_path.get(); } + BusType bus_type() { return type; } + uid_t bus_owner() { return owner; } +}; DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd) { - BusType bus_type = SESSION_BUS; - uid_t bus_owner = 0; + assert(bus_path); - auto resolved_path = bus_path_resolve(bus_path, bus_type, bus_owner); - if (nullptr == resolved_path) { + BusPathResolver path_resolver(bus_path); + if (!path_resolver) { LOGE("Error resolving bus path: %s", bus_path); return nullptr; } g_udesc.init(); + auto bus_type = path_resolver.bus_type(); + kconn *result = nullptr; - if (Checker::get(bus_type).can_open_owned_by(bus_owner)) { + if (Checker::get(bus_type).can_open_owned_by(path_resolver.bus_owner())) { if (-1 == fd) { - result = &kconn::get(bus_type, resolved_path.get()); + result = &kconn::get(bus_type, path_resolver.path()); } else { result = kconn::get_shared(bus_type, fd); } -- 2.7.4 From 9384276e586409f2910e3132a8ba9af93c56d2ab Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 10 Apr 2019 16:04:52 +0200 Subject: [PATCH 03/16] refactoring: group helper functions into a namespace This groups helper functions into an anonymous namespace. Change-Id: I1bf32e719f4268886014757a1423ef2c24b4c242 --- src/libdbuspolicy1.cpp | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index 394e685..222ed9a 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -302,20 +302,9 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) return dbuspolicy1_init_shared(bus_path, -1); } -inline kconn *KCONN(void *config) { return static_cast(config); } -inline KdbusConnection &KDBUS_CONN(void *config) { return KCONN(config)->conn; } - -DBUSPOLICY1_EXPORT void dbuspolicy1_init_set_pool(void *configuration, void *pool) -{ - KDBUS_CONN(configuration).shared_init_pool(pool); -} - -DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) -{ - auto kconn = KCONN(configuration); - if (kconn->can_be_freed) - delete kconn; -} +// helper functions +namespace { +constexpr kconn *KCONN(void *config) { return static_cast(config); } /* * This function prepares contents of info.names() for initialization of MatchItems. @@ -323,7 +312,7 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) * If it fails, names are added from the 'name' parameter, which is treaten * as a string containing names separated by single space. */ -static int prepareNames(const char *name, KdbusConnectionInfo &info, +inline int prepareNames(const char *name, KdbusConnectionInfo &info, KdbusConnection::conn_info_type info_type) { if (name && *name) { int r = info.get(name, info_type); @@ -336,13 +325,26 @@ static int prepareNames(const char *name, KdbusConnectionInfo &info, return 0; } -static inline int decisionToRetCode(DecisionResult decision) { +constexpr int decisionToRetCode(DecisionResult decision) { return static_cast(decision); } -static inline ldp_xml_parser::MessageType toMessageType(int type) { +constexpr ldp_xml_parser::MessageType toMessageType(int type) { return static_cast(type); } +} // namespace + +DBUSPOLICY1_EXPORT void dbuspolicy1_init_set_pool(void *configuration, void *pool) +{ + KCONN(configuration)->conn.shared_init_pool(pool); +} + +DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) +{ + auto kconn = KCONN(configuration); + if (kconn->can_be_freed) + delete kconn; +} DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, const char *destination, -- 2.7.4 From 5d2b87a4218d64a6a5c528de9ef86166ee02f428 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Mon, 15 Apr 2019 13:47:37 +0200 Subject: [PATCH 04/16] serializer: add option for checking for updates Developers may need to check if they already updated their serialized policy file. This adds -j option which does not write anything to the output file, but rather just checks if the generated file would have the same contents as an existing output file. Change-Id: I28ab3e992416d25c04206279275f007c0ca08919 --- src/dbuspolicy_serializer.cpp | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/dbuspolicy_serializer.cpp b/src/dbuspolicy_serializer.cpp index 7ca1c41..a575c6c 100644 --- a/src/dbuspolicy_serializer.cpp +++ b/src/dbuspolicy_serializer.cpp @@ -1,8 +1,10 @@ #include #include +#include #include #include +#include #include "internal/serializer.hpp" #include "internal/naive_policy_checker.hpp" #include "dbuspolicy1/libdbuspolicy1.h" @@ -17,23 +19,46 @@ static const struct option options[] = { static void print_help(const char *name) { cout << endl; - cout << "usage: " << name << " [-o output_filename] " << endl; - cout << " " << name << " {--system|--session} [-o output_filename]" << endl; + cout << "usage: " << name << " [-j] [-o output_filename] " << endl; + cout << " " << name << " {--system|--session} [-j] [-o output_filename]" << endl; cout << endl; cout << "If not specified, output_filename is input_filename.serialized" << endl; + cout << " -j - don't write anything, just check if the output file is valid and up to date" << endl; cout << endl; } +static int check(const char *input_filename, const std::string &output_filename) { + bool ok = false; + + cout << "Read from: " << input_filename << ", checking " << output_filename << "..." << endl; + ldp_xml_parser::Serializer serializer; + ostringstream output; + serializer.serialize(input_filename, output); + + ifstream serialized(output_filename, ifstream::binary|ifstream::ate); + + if (serialized && output.tellp() == serialized.tellg()) { + serialized.seekg(0, ifstream::beg); + + ok = equal(istreambuf_iterator(serialized), + istreambuf_iterator(), + output.str().begin()); + } + cout << output_filename << " is " << (ok ? "valid and up to date" : "not updated or invalid") << endl; + return ok ? 0 : 1; +} + int main(int argc, char *argv[]) { bool need_input_filename = true; + bool just_check = false; std::string output_filename; const char *input_filename = system_bus_conf_file_primary(); int c; while (1) { int option_index; - c = getopt_long(argc, argv, "o:", options, &option_index); + c = getopt_long(argc, argv, "o:j", options, &option_index); if (c == -1) break; @@ -46,6 +71,9 @@ int main(int argc, char *argv[]) case 'o': output_filename = optarg; break; + case 'j': + just_check = true; + break; } } @@ -61,6 +89,9 @@ int main(int argc, char *argv[]) if (output_filename.empty()) output_filename = std::string(input_filename) + ".serialized"; + if (just_check) + return check(input_filename, output_filename); + cout << "Read from: " << input_filename << " write to: " << output_filename << endl; ldp_xml_parser::Serializer serializer; ofstream output(output_filename, ofstream::binary); -- 2.7.4 From 6ab233eaee2b90a2b96aa8f42cade6f572d6b8be Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 15:57:49 +0900 Subject: [PATCH 05/16] tslog: modified to support log level Change-Id: I9f5a4b9cae82737db6037ce56cf7b75bf8e8af0a Signed-off-by: sanghyeok.oh --- src/dbuspolicy_serializer.cpp | 2 ++ src/internal/serializer.cpp | 2 +- src/internal/tslog.cpp | 29 ++++++++++++++++++++--------- src/internal/tslog.hpp | 31 ++++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/dbuspolicy_serializer.cpp b/src/dbuspolicy_serializer.cpp index 7ca1c41..a08c6a1 100644 --- a/src/dbuspolicy_serializer.cpp +++ b/src/dbuspolicy_serializer.cpp @@ -67,5 +67,7 @@ int main(int argc, char *argv[]) serializer.serialize(input_filename, output); + cout << "Write " << output.tellp() << " bytes" << endl; + return 0; } diff --git a/src/internal/serializer.cpp b/src/internal/serializer.cpp index 578157a..ac6841a 100644 --- a/src/internal/serializer.cpp +++ b/src/internal/serializer.cpp @@ -115,7 +115,7 @@ uint8_t* Serializer::serialize(const ldp_xml::StorageBackendXML &db, size_t &siz } uint8_t* Serializer::serialize(const std::string config_path, size_t &size) { - tslog::init(); + tslog::init(tslog::ldp_log_level::DEFAULT); ldp_xml::StorageBackendXML xmlStorage; if (!xmlStorage.init(config_path.c_str())) { diff --git a/src/internal/tslog.cpp b/src/internal/tslog.cpp index aa5a5f9..06ba0c0 100644 --- a/src/internal/tslog.cpp +++ b/src/internal/tslog.cpp @@ -23,7 +23,7 @@ namespace tslog { -int8_t g_verbosity{-1}; +ldp_log_level g_verbosity{ldp_log_level::SILENT}; pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; bool get_log_env(char const *name) { @@ -31,15 +31,14 @@ bool get_log_env(char const *name) { return ldp_log_mode && '0' != *ldp_log_mode; } -void init() { - g_verbosity = get_log_env("LDP_LOG") ? get_log_env("LDP_VERBOSE") : -1; +void init(ldp_log_level level) { + g_verbosity = get_log_env("LDP_LOG") ? (get_log_env("LDP_VERBOSE") ? ldp_log_level::DEBUG : ldp_log_level::VERBOSE): level; } -bool enabled() { return g_verbosity >= 0; } -bool verbose() { return g_verbosity > 0; } +bool enabled(ldp_log_level level) { return level <= g_verbosity; } -void flush() { - if (tslog::enabled()) { +void flush(ldp_log_level level) { + if (tslog::enabled(level)) { pthread_mutex_lock(&g_mutex); std::cout << std::flush; pthread_mutex_unlock(&g_mutex); @@ -58,13 +57,25 @@ void logWarning(const std::string &warning) LOGW("%s", warning.c_str()); } +void logDebug(const std::string &debug) +{ + log(debug, "\n"); + LOGD("%s", debug.c_str()); +} + +void logVerbose(const std::string &verbose) +{ + log_verbose(verbose, "\n"); + LOGD("%s", verbose.c_str()); +} + std::ostream &operator<<(std::ostream &stream, const print_errno &p) { char buf[256]; return stream << strerror_r(p.err, buf, sizeof(buf)); } -LogLock::LogLock() { - locked = tslog::enabled(); +LogLock::LogLock(ldp_log_level level) { + locked = tslog::enabled(level); if (locked) pthread_mutex_lock(&g_mutex); } diff --git a/src/internal/tslog.hpp b/src/internal/tslog.hpp index bcf6cf6..f2b4f59 100644 --- a/src/internal/tslog.hpp +++ b/src/internal/tslog.hpp @@ -29,22 +29,29 @@ namespace tslog { + enum class ldp_log_level { + SILENT, + ERROR, + WARNING, + DEFAULT = WARNING, + DEBUG, + VERBOSE + }; /** Checks value of environmental variable with given name */ bool get_log_env(char const *name); /** Checks environmental variables and sets global variable defining if logs are enabled */ - void init(); + void init(ldp_log_level level = ldp_log_level::SILENT); /** Checks if logs are enabled */ - bool enabled(); - - /** Checks if verbosity is enabled */ - bool verbose(); + bool enabled(ldp_log_level level = ldp_log_level::DEBUG); - void flush(); + void flush(ldp_log_level level = ldp_log_level::ERROR); void logError(const std::string &error); void logWarning(const std::string &warning); + void logDebug(const std::string &debug); + void logVerbose(const std::string &verbose); template void log_to_stream(std::ostream &stream, const Args &...args) { @@ -52,10 +59,16 @@ namespace tslog } template - void log(const Args &...args) { if (enabled()) log_to_stream(std::cout, args...); } + void log(const Args &...args) { if (enabled(ldp_log_level::DEBUG)) log_to_stream(std::cout, args...); } + + template + void log_error(const Args &...args) { if (enabled(ldp_log_level::ERROR)) log_to_stream(std::cout, args...); } + + template + void log_warning(const Args &...args) { if (enabled(ldp_log_level::WARNING)) log_to_stream(std::cout, args...); } template - void log_verbose(const Args &...args) { if (verbose()) log_to_stream(std::cout, args...); } + void log_verbose(const Args &...args) { if (enabled(ldp_log_level::VERBOSE)) log_to_stream(std::cout, args...); } struct print_errno { int err; @@ -70,7 +83,7 @@ namespace tslog class LogLock { bool locked; public: - LogLock(); + LogLock(ldp_log_level level = ldp_log_level::ERROR); ~LogLock(); }; } -- 2.7.4 From 244f5de93725b8520f2550663a85cfb1b2022861 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 15:58:35 +0900 Subject: [PATCH 06/16] tslog: change name log to log_debug Change-Id: Ib362f0cd385298a20443f90f9d4b78bcad84a8cc Signed-off-by: sanghyeok.oh --- src/internal/groups_proxy.cpp | 6 +++--- src/internal/storage_backend_serialized.cpp | 10 +++++----- src/internal/storage_backend_xml.cpp | 2 +- src/internal/tslog.cpp | 6 +++--- src/internal/tslog.hpp | 2 +- src/internal/xml_parser.cpp | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/internal/groups_proxy.cpp b/src/internal/groups_proxy.cpp index d3e4e55..1ed0453 100644 --- a/src/internal/groups_proxy.cpp +++ b/src/internal/groups_proxy.cpp @@ -30,11 +30,11 @@ std::vector get_groups(const uid_t uid, const gid_t gid) { struct passwd pwd; if (getpwuid_r(uid, &pwd, buf.data(), buf.size(), &user_pw)) { - tslog::log("getpwuid_r failed uid:", uid, " gid: ", gid, "\n"); + tslog::log_error("getpwuid_r failed uid:", uid, " gid: ", gid, "\n"); return {}; } if (!user_pw) { - tslog::log("getpwuid_r failed. no matching password record was found uid:", uid, " gid: ", gid, "\n"); + tslog::log_error("getpwuid_r failed. no matching password record was found uid:", uid, " gid: ", gid, "\n"); return {}; } @@ -49,7 +49,7 @@ std::vector get_groups(const uid_t uid, const gid_t gid) { auto groups = std::vector (ngroups); int r = getgrouplist(user_pw->pw_name, gid, groups.data(), &ngroups); if (r < 0) { - tslog::log("getgrouplist failed uid:", uid, " gid: ", gid, "\n"); + tslog::log_error("getgrouplist failed uid:", uid, " gid: ", gid, "\n"); groups.clear(); } return groups; diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp index b6b7409..f5c03e1 100644 --- a/src/internal/storage_backend_serialized.cpp +++ b/src/internal/storage_backend_serialized.cpp @@ -67,7 +67,7 @@ void StorageBackendSerialized::StorageBackendSerializedImpl::releaseMMap() { assert(0 != length); if (munmap(mem, length) != 0) - tslog::log("munmap(): ", tslog::print_errno(errno), "\n"); + tslog::log_error("munmap(): ", tslog::print_errno(errno), "\n"); mem = static_cast(MAP_FAILED); length = 0; @@ -77,7 +77,7 @@ void StorageBackendSerialized::StorageBackendSerializedImpl::releaseFD() { assert(-1 != fd); if (close(fd) != 0) - tslog::log("close(): ", tslog::print_errno(errno), "\n"); + tslog::log_error("close(): ", tslog::print_errno(errno), "\n"); fd = -1; } @@ -99,7 +99,7 @@ bool StorageBackendSerialized::StorageBackendSerializedImpl::init(const char *fi assert(nullptr == file); auto err = [filename] (const char *what) { - tslog::log("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n"); + tslog::log_error("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n"); return false; }; @@ -116,7 +116,7 @@ bool StorageBackendSerialized::StorageBackendSerializedImpl::init(const char *fi length = buf.st_size; if (length > MAX_SFILE_SIZE) { - tslog::log("Serialized file size(", length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n"); + tslog::log_error("Serialized file size(", length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n"); return false; } @@ -129,7 +129,7 @@ bool StorageBackendSerialized::StorageBackendSerializedImpl::init(const char *fi if (verify) { auto verifier = flatbuffers::Verifier(mem, length); if (!FB::VerifyFileBuffer(verifier)) { - tslog::log("verification of serialized data: failed\n"); + tslog::log_error("verification of serialized data: failed\n"); return false; } } diff --git a/src/internal/storage_backend_xml.cpp b/src/internal/storage_backend_xml.cpp index 95ee1b6..ec1b494 100644 --- a/src/internal/storage_backend_xml.cpp +++ b/src/internal/storage_backend_xml.cpp @@ -138,7 +138,7 @@ template void StorageBackendXML::addItem(const ldp_xml_parser::PolicyType policy_type, const ldp_xml_parser::PolicyTypeValue policy_type_value, T &item) { - tslog::log("Add item: ", item, ", decision: ", item.getDecision(), "\n"); + tslog::log_debug("Add item: ", item, ", decision: ", item.getDecision(), "\n"); pimpl->getPolicySetFromMatchItem().addItem(policy_type, policy_type_value, item); } diff --git a/src/internal/tslog.cpp b/src/internal/tslog.cpp index 06ba0c0..28a9808 100644 --- a/src/internal/tslog.cpp +++ b/src/internal/tslog.cpp @@ -47,19 +47,19 @@ void flush(ldp_log_level level) { void logError(const std::string &error) { - log(error, "\n"); + log_error(error, "\n"); LOGE("%s", error.c_str()); } void logWarning(const std::string &warning) { - log(warning, "\n"); + log_warning(warning, "\n"); LOGW("%s", warning.c_str()); } void logDebug(const std::string &debug) { - log(debug, "\n"); + log_debug(debug, "\n"); LOGD("%s", debug.c_str()); } diff --git a/src/internal/tslog.hpp b/src/internal/tslog.hpp index f2b4f59..f04fd16 100644 --- a/src/internal/tslog.hpp +++ b/src/internal/tslog.hpp @@ -59,7 +59,7 @@ namespace tslog } template - void log(const Args &...args) { if (enabled(ldp_log_level::DEBUG)) log_to_stream(std::cout, args...); } + void log_debug(const Args &...args) { if (enabled(ldp_log_level::DEBUG)) log_to_stream(std::cout, args...); } template void log_error(const Args &...args) { if (enabled(ldp_log_level::ERROR)) log_to_stream(std::cout, args...); } diff --git a/src/internal/xml_parser.cpp b/src/internal/xml_parser.cpp index 984dd53..77d0619 100644 --- a/src/internal/xml_parser.cpp +++ b/src/internal/xml_parser.cpp @@ -186,7 +186,7 @@ void XmlParser::elementEnd(const char *el) { } int XmlParser::parsePolicyConfigFile() { - tslog::log("XmlParser::parsePolicyConfigFile called with filename: ", main_filename, "\n"); + tslog::log_debug("XmlParser::parsePolicyConfigFile called with filename: ", main_filename); parsePolicyConfigFileInternal(main_filename); return ret_code; } @@ -250,7 +250,7 @@ std::unique_ptr file2str(const char *filename) { void XmlParser::parseXmlFile(const char *filename) { included_files.clear(); - tslog::log("Processing: ", filename, " ...\n"); + tslog::log_debug("Processing: ", filename, " ...\n"); tslog::log_verbose("=== XML PARSING BEGIN === : ", filename, '\n'); curr_dir = getDir(filename); @@ -297,7 +297,7 @@ void XmlParser::getIncludedFiles(const std::string& parent_dir, const std::strin std::cout << '\n'; } } else { - tslog::log("could not open directory ", dname, '\n'); + tslog::log_error("could not open directory ", dname, '\n'); } } -- 2.7.4 From 5e7e166f164accf34025f5f702b4f9908ee9c29d Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 15:59:07 +0900 Subject: [PATCH 07/16] xml_parser: modified log to print out filename Change-Id: I63510b0b15e21aa8d583b98cb29b18d08bada5ab Signed-off-by: sanghyeok.oh --- src/internal/xml_parser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal/xml_parser.cpp b/src/internal/xml_parser.cpp index 77d0619..faa2dfe 100644 --- a/src/internal/xml_parser.cpp +++ b/src/internal/xml_parser.cpp @@ -196,14 +196,14 @@ void XmlParser::parsePolicyConfigFileInternal(const char *filename) { try { parseXmlFile(filename); } catch (const std::runtime_error& ex) { - tslog::logError(std::string("Error parsing xml: Exception occured: ").append(ex.what()).c_str()); + tslog::logError(std::string(filename).append(": Error parsing xml: Exception occured: ").append(ex.what()).c_str()); if (isMainConfFile(filename)) { tslog::logError("Exiting parsing"); ret_code = -1; return; } } catch (...) { - tslog::logError("Error parsing xml: Exception occured: "); + tslog::logError(std::string(filename).append(" :Error parsing xml: Exception occured: ")); if (isMainConfFile(filename)) { tslog::logError("Exiting parsing"); ret_code = -1; -- 2.7.4 From 2a8585c01cb6285966dc5511bf403e9660f569c7 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 15:59:45 +0900 Subject: [PATCH 08/16] serialization: printer: change log level from silent to default Change-Id: I294e9b3f202002922ed266504ab99ff048ddb94c Signed-off-by: sanghyeok.oh --- src/dbuspolicy_printer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dbuspolicy_printer.cpp b/src/dbuspolicy_printer.cpp index e64101b..18ed6ce 100644 --- a/src/dbuspolicy_printer.cpp +++ b/src/dbuspolicy_printer.cpp @@ -17,9 +17,11 @@ int main(int argc, const char **argv) { return 1; } + tslog::init(tslog::ldp_log_level::DEFAULT); + ldp_serialized::StorageBackendSerialized storage; - if (!storage.init(argv[1]), true) + if (!storage.init(argv[1], true)) return 1; storage.printContent(); -- 2.7.4 From f4dc600a226b1ee9105f6de4bf662c21a11dd605 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 16:00:22 +0900 Subject: [PATCH 09/16] serialization: make input consistency between printer and serializer Change-Id: I7ef136fde2a3b7cdd3cf117ccdc32fc5e0dce52c Signed-off-by: sanghyeok.oh --- src/dbuspolicy_printer.cpp | 47 ++++++++++++++++++++++++++++++++++++++++--- src/dbuspolicy_serializer.cpp | 3 ++- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/dbuspolicy_printer.cpp b/src/dbuspolicy_printer.cpp index 18ed6ce..8b5f2c8 100644 --- a/src/dbuspolicy_printer.cpp +++ b/src/dbuspolicy_printer.cpp @@ -1,27 +1,68 @@ #include "internal/print_content.hpp" #include "internal/storage_backend_serialized.hpp" #include +#include +#include "libdbuspolicy1-private.h" using namespace std; +static const struct option options[] = { + {"system", no_argument, 0, 0 }, + {"session", no_argument, 0, 0}, + {0, 0, 0, 0} +}; + static void print_help(const char *name) { cout << endl; - cout << "usage: " << name << " " << endl; + cout << "usage: " << name << " [-i input_filename]" << endl; + cout << " " << name << " {--system|--session}" << endl; cout << endl; } -int main(int argc, const char **argv) { +int main(int argc, char *argv[]) { + std::string input_filename; + int c; if (argc < 2) { print_help(argv[0]); return 1; } + while (1) { + int option_index; + c = getopt_long(argc, argv, "i:", options, &option_index); + if (c == -1) + break; + + switch(c) { + case 0: + if (option_index == 0) + input_filename = system_bus_conf_file_primary(); + else + input_filename = session_bus_conf_file_primary(); + input_filename.append(".serialized"); + break; + case 'i': + input_filename = optarg; + break; + case '?': + break; + } + if (!input_filename.empty()) + break; + } + + if (input_filename.empty()) { + cout << "No input filename" << endl; + print_help(argv[0]); + return 1; + } + tslog::init(tslog::ldp_log_level::DEFAULT); ldp_serialized::StorageBackendSerialized storage; - if (!storage.init(argv[1], true)) + if (!storage.init(input_filename.c_str(), true)) return 1; storage.printContent(); diff --git a/src/dbuspolicy_serializer.cpp b/src/dbuspolicy_serializer.cpp index a08c6a1..90a4f55 100644 --- a/src/dbuspolicy_serializer.cpp +++ b/src/dbuspolicy_serializer.cpp @@ -12,7 +12,8 @@ using namespace std; static const struct option options[] = { {"system", no_argument, 0, 0 }, - {"session", no_argument, 0, 0} + {"session", no_argument, 0, 0}, + {0, 0, 0, 0} }; static void print_help(const char *name) { -- 2.7.4 From ec779167655d76662ac6461f28a4c9fc7b628901 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Tue, 30 Apr 2019 16:50:05 +0900 Subject: [PATCH 10/16] serialization: change tool name For readability and easy typing dbuspolicyserializer > dbuspolicy-serializer dbuspolicyprinter > dbuspolicy-printer Change-Id: I3a416805d66f31c16465a3a2854ceda15d783e9f Signed-off-by: sanghyeok.oh --- Makefile.am | 24 ++++++++++++------------ packaging/libdbuspolicy.spec | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Makefile.am b/Makefile.am index c544561..f568ad8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -79,40 +79,40 @@ src_libdbuspolicy1_la_LDFLAGS = $(AM_LDFLAGS) \ -Wl,--version-script=$(top_srcdir)/src/libdbuspolicy1.sym EXTRA_src_libdbuspolicy1_la_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym -dbuspolicyserializer_SOURCES =\ +dbuspolicy_serializer_SOURCES =\ src/dbuspolicy_serializer.cpp -dbuspolicyserializer_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" +dbuspolicy_serializer_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" -# dbuspolicyserializer_LDFLAGS = $(AM_LDFLAGS) \ +# dbuspolicy_serializer_LDFLAGS = $(AM_LDFLAGS) \ # -version-info $(LIBDBUSPOLICY1_CURRENT):$(LIBDBUSPOLICY1_REVISION):$(LIBDBUSPOLICY1_AGE) \ # $(CYNARA_LIBS) \ # $(DLOG_LIBS) \ # -Wl,--version-script=$(top_srcdir)/src/libdbuspolicy1.sym -dbuspolicyserializer_LDADD = src/libinternal.a \ +dbuspolicy_serializer_LDADD = src/libinternal.a \ $(CYNARA_LIBS) \ $(DLOG_LIBS) \ -lexpat -EXTRA_dbuspolicyserializer_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym +EXTRA_dbuspolicy_serializer_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym -dbuspolicyserializerdir = /bin/ +dbuspolicy_serializerdir = /bin/ -dbuspolicyprinter_SOURCES =\ +dbuspolicy_printer_SOURCES =\ src/dbuspolicy_printer.cpp -dbuspolicyprinter_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" +dbuspolicy_printer_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" -dbuspolicyprinter_LDADD = src/libinternal.a \ +dbuspolicy_printer_LDADD = src/libinternal.a \ $(CYNARA_LIBS) \ $(DLOG_LIBS) \ -lexpat -EXTRA_dbuspolicyprinter_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym +EXTRA_dbuspolicy_printer_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym -bin_PROGRAMS = dbuspolicyserializer dbuspolicyprinter -dbuspolicyprinterdir = /bin/ +bin_PROGRAMS = dbuspolicy-serializer dbuspolicy-printer +dbuspolicy_printerdir = /bin/ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = src/libdbuspolicy1.pc diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index 4f067b6..493a3bb 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -32,7 +32,7 @@ policy handling (with SMACK support). This package contains development files. %description serializer -dbuspolicyserializer is a tool to serialize dbus policy +dbuspolicy-serializer is a tool to serialize dbus policy %description tests This package contains contains integration tests for libdbuspolicy. @@ -113,8 +113,8 @@ libtool --mode=install install -m 0755 %{runnername} %{btestrunnerdir} %manifest %{name}.manifest %license LICENSE.APACHE2.0 %defattr(-,root,root) -%{_bindir}/dbuspolicyserializer -%{_bindir}/dbuspolicyprinter +%{_bindir}/dbuspolicy-serializer +%{_bindir}/dbuspolicy-printer %if 0%{?enable_doxygen:1} %files doc -- 2.7.4 From 60aed661110746922500a855194adfe4d66a9112 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Wed, 24 Apr 2019 14:10:05 +0200 Subject: [PATCH 11/16] tizen: Add new package to perform data verification on boot emergency.target is started on verification failure. Change-Id: I5c67e624d76440f9667602930aecb5adff233ecc --- packaging/libdbuspolicy-verify-data.service | 15 ++++++++++++++ packaging/libdbuspolicy-verify-data.target | 5 +++++ packaging/libdbuspolicy.spec | 32 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 packaging/libdbuspolicy-verify-data.service create mode 100644 packaging/libdbuspolicy-verify-data.target diff --git a/packaging/libdbuspolicy-verify-data.service b/packaging/libdbuspolicy-verify-data.service new file mode 100644 index 0000000..f52f10a --- /dev/null +++ b/packaging/libdbuspolicy-verify-data.service @@ -0,0 +1,15 @@ +[Unit] +Description=Verify libdbuspolicy serialized data correctness +DefaultDependencies=no +OnFailure=emergency.target +OnFailureJobMode=replace-irreversibly + +[Service] +Type=oneshot +RemainAfterExit=true +StandardInput=null +StandardOutput=kmsg+console +StandardError=kmsg+console +ExecStart=/usr/bin/dbuspolicy-serializer -j --system +ExecStart=/usr/bin/dbuspolicy-serializer -j --session +ExecStartPost=/bin/systemctl isolate graphical.target diff --git a/packaging/libdbuspolicy-verify-data.target b/packaging/libdbuspolicy-verify-data.target new file mode 100644 index 0000000..ea64083 --- /dev/null +++ b/packaging/libdbuspolicy-verify-data.target @@ -0,0 +1,5 @@ +[Unit] +Description=Verify D-Bus policy mode +Requires=libdbuspolicy-verify-data.service +After=libdbuspolicy-verify-data.service +AllowIsolate=yes diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index 493a3bb..813c109 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -6,6 +6,8 @@ Version: 1.1.0 Release: 0 Source: %{name}-%{version}.tar.gz Source1001: %{name}.manifest +Source2001: libdbuspolicy-verify-data.target +Source2002: libdbuspolicy-verify-data.service BuildRequires: boost-devel BuildRequires: libexpat-devel BuildRequires: pkgconfig(cynara-client) @@ -18,6 +20,10 @@ Summary: Helper library for fine-grained userspace policy handling-develo %package serializer Summary: Tool to serialize dbus policy +%package assert-data-valid +Requires: %{name}-serializer +Summary: Systemd units to perform boot-time serialized data verification + %package tests Summary: Helper library for fine-grained userspace policy handling-development package Requires: %{name} = %{version} @@ -34,6 +40,11 @@ development files. %description serializer dbuspolicy-serializer is a tool to serialize dbus policy +%description assert-data-valid +Perform boot-time serialized data verification, fail the boot if vierification fails +. +Note that installing this package actually replaces systemd default.target. Use with care. + %description tests This package contains contains integration tests for libdbuspolicy. @@ -53,6 +64,8 @@ Doxygen documentation for libdbuspolicy. %prep %setup -q cp %{SOURCE1001} . +cp %{SOURCE2001} ./libdbuspolicy-verify-data.target +cp %{SOURCE2002} ./libdbuspolicy-verify-data.service %build %reconfigure --libdir=%{_libdir} --prefix=/usr --enable-tests \ @@ -92,9 +105,22 @@ libtool --mode=install install -m 0755 stest_* dbus_daemon %{btestsuitedir} mkdir -p %{btestrunnerdir} libtool --mode=install install -m 0755 %{runnername} %{btestrunnerdir} +mkdir -p -m755 %{buildroot}%{_unitdir} +install -m644 libdbuspolicy-verify-data.target %{buildroot}/%{_unitdir}/ +install -m644 libdbuspolicy-verify-data.service %{buildroot}/%{_unitdir}/ + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig +%posttrans assert-data-valid +rm -f %{_unitdir}/.%{name}.backup.default.target +mv %{_unitdir}/default.target %{_unitdir}/.%{name}.backup.default.target +ln -sf libdbuspolicy-verify-data.target %{_unitdir}/default.target + +%preun assert-data-valid +rm -f %{_unitdir}/default.target +mv %{_unitdir}/.%{name}.backup.default.target %{_unitdir}/default.target + %files %manifest %{name}.manifest %license LICENSE.APACHE2.0 @@ -116,6 +142,12 @@ libtool --mode=install install -m 0755 %{runnername} %{btestrunnerdir} %{_bindir}/dbuspolicy-serializer %{_bindir}/dbuspolicy-printer +%files assert-data-valid +%manifest %{name}.manifest +%license LICENSE.APACHE2.0 +%{_unitdir}/libdbuspolicy-verify-data.target +%{_unitdir}/libdbuspolicy-verify-data.service + %if 0%{?enable_doxygen:1} %files doc %license LICENSE.APACHE2.0 -- 2.7.4 From 52216298d282454ca94985130f37d5f69465cc9c Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 30 Apr 2019 15:07:21 +0200 Subject: [PATCH 12/16] serializer: add SHA1 and FlatBuffers verification Change-Id: I8c78971f8b6481d1cd00c54dce7b2f0466f1ce61 --- Makefile.am | 5 +++- packaging/libdbuspolicy-verify-data.service | 3 +-- packaging/libdbuspolicy.spec | 2 ++ src/dbuspolicy-verifier | 30 +++++++++++++++++++++++ src/dbuspolicy_printer.cpp | 37 ++++++++++++++++++++--------- src/dbuspolicy_serializer.cpp | 28 ++++++++++++++++++---- src/internal/serializer.cpp | 3 ++- src/internal/serializer.hpp | 2 +- 8 files changed, 90 insertions(+), 20 deletions(-) create mode 100755 src/dbuspolicy-verifier diff --git a/Makefile.am b/Makefile.am index f568ad8..0a5d9e4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -93,7 +93,8 @@ dbuspolicy_serializer_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" dbuspolicy_serializer_LDADD = src/libinternal.a \ $(CYNARA_LIBS) \ $(DLOG_LIBS) \ - -lexpat + -lexpat \ + -lcrypto EXTRA_dbuspolicy_serializer_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym @@ -114,6 +115,8 @@ EXTRA_dbuspolicy_printer_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym bin_PROGRAMS = dbuspolicy-serializer dbuspolicy-printer dbuspolicy_printerdir = /bin/ +dist_bin_SCRIPTS = src/dbuspolicy-verifier + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = src/libdbuspolicy1.pc EXTRA_DIST += src/libdbuspolicy1.pc.in diff --git a/packaging/libdbuspolicy-verify-data.service b/packaging/libdbuspolicy-verify-data.service index f52f10a..bbfd0a2 100644 --- a/packaging/libdbuspolicy-verify-data.service +++ b/packaging/libdbuspolicy-verify-data.service @@ -10,6 +10,5 @@ RemainAfterExit=true StandardInput=null StandardOutput=kmsg+console StandardError=kmsg+console -ExecStart=/usr/bin/dbuspolicy-serializer -j --system -ExecStart=/usr/bin/dbuspolicy-serializer -j --session +ExecStart=/usr/bin/dbuspolicy-verifier --system --session ExecStartPost=/bin/systemctl isolate graphical.target diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index 813c109..3b1ce0a 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -19,6 +19,7 @@ Summary: Helper library for fine-grained userspace policy handling-develo %package serializer Summary: Tool to serialize dbus policy +BuildRequires: libopenssl-devel libopenssl %package assert-data-valid Requires: %{name}-serializer @@ -147,6 +148,7 @@ mv %{_unitdir}/.%{name}.backup.default.target %{_unitdir}/default.target %license LICENSE.APACHE2.0 %{_unitdir}/libdbuspolicy-verify-data.target %{_unitdir}/libdbuspolicy-verify-data.service +%{_bindir}/dbuspolicy-verifier %if 0%{?enable_doxygen:1} %files doc diff --git a/src/dbuspolicy-verifier b/src/dbuspolicy-verifier new file mode 100755 index 0000000..4b06995 --- /dev/null +++ b/src/dbuspolicy-verifier @@ -0,0 +1,30 @@ +#!/bin/sh + +set -e + +FNAME= + +if [ -z "$1" ] +then + echo 'Usage: $0 {--system|--session|serialized_file_name}' + exit 1 +fi + +while [ -n "$1" ] +do + if [ "$1" == "--system" ] + then + FNAME=/usr/share/dbus-1/system.conf.serialized + elif [ "$1" == "--session" ] + then + FNAME=/usr/share/dbus-1/session.conf.serialized + else + FNAME=$1 + fi + + echo Verifying SHA1... + sha1sum -c $FNAME.sha1 + echo Verifying FlatBuffers structure... + dbuspolicy-printer $1 -v + shift +done diff --git a/src/dbuspolicy_printer.cpp b/src/dbuspolicy_printer.cpp index 8b5f2c8..4ea8c30 100644 --- a/src/dbuspolicy_printer.cpp +++ b/src/dbuspolicy_printer.cpp @@ -14,23 +14,25 @@ static const struct option options[] = { static void print_help(const char *name) { cout << endl; - cout << "usage: " << name << " [-i input_filename]" << endl; - cout << " " << name << " {--system|--session}" << endl; + cout << "usage: " << name << " [-i input_filename] [-v]" << endl; + cout << " " << name << " {--system|--session} [-v]" << endl; + cout << " -v - just verify, don't print anything" << endl; cout << endl; } int main(int argc, char *argv[]) { std::string input_filename; int c; + bool just_verify = false; if (argc < 2) { print_help(argv[0]); - return 1; + return EXIT_FAILURE; } while (1) { int option_index; - c = getopt_long(argc, argv, "i:", options, &option_index); + c = getopt_long(argc, argv, "i:v", options, &option_index); if (c == -1) break; @@ -45,27 +47,40 @@ int main(int argc, char *argv[]) { case 'i': input_filename = optarg; break; - case '?': + case 'v': + just_verify = true; break; + case '?': + print_help(argv[0]); + return EXIT_FAILURE; } - if (!input_filename.empty()) - break; } + if (optind < argc) + input_filename = argv[optind]; + if (input_filename.empty()) { cout << "No input filename" << endl; print_help(argv[0]); - return 1; + return EXIT_FAILURE; } tslog::init(tslog::ldp_log_level::DEFAULT); ldp_serialized::StorageBackendSerialized storage; - if (!storage.init(input_filename.c_str(), true)) - return 1; + if (!storage.init(input_filename.c_str(), true)) { + if (just_verify) + cout << input_filename << ": FAILED" << endl; + return EXIT_FAILURE; + } + + if (just_verify) { + cout << input_filename << ": OK" << endl; + return EXIT_SUCCESS; + } storage.printContent(); - return 0; + return EXIT_SUCCESS; } diff --git a/src/dbuspolicy_serializer.cpp b/src/dbuspolicy_serializer.cpp index 21f268d..cd172d2 100644 --- a/src/dbuspolicy_serializer.cpp +++ b/src/dbuspolicy_serializer.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -10,6 +11,8 @@ #include "dbuspolicy1/libdbuspolicy1.h" #include "libdbuspolicy1-private.h" +#include + using namespace std; static const struct option options[] = { @@ -46,7 +49,7 @@ static int check(const char *input_filename, const std::string &output_filename) output.str().begin()); } cout << output_filename << " is " << (ok ? "valid and up to date" : "not updated or invalid") << endl; - return ok ? 0 : 1; + return ok ? EXIT_SUCCESS : EXIT_FAILURE; } int main(int argc, char *argv[]) @@ -83,7 +86,7 @@ int main(int argc, char *argv[]) input_filename = argv[optind]; } else { print_help(argv[0]); - return 1; + return EXIT_FAILURE; } } @@ -97,9 +100,26 @@ int main(int argc, char *argv[]) ldp_xml_parser::Serializer serializer; ofstream output(output_filename, ofstream::binary); - serializer.serialize(input_filename, output); + uint8_t *data = serializer.serialize(input_filename, output); + + if (output.fail()) { + cout << "Write FAILED." << endl; + return EXIT_FAILURE; + } cout << "Write " << output.tellp() << " bytes" << endl; - return 0; + array digest; + string sha1_filename = output_filename + ".sha1"; + ofstream output_sha1(sha1_filename); + + SHA1(data, output.tellp(), digest.data()); + + output_sha1 << hex; + for_each(digest.begin(), digest.end(), [&](uint16_t c) { output_sha1 << setw(2) << setfill('0') << c; }); + output_sha1 << " *" << output_filename << endl; + + cout << "SHA1 written to " << sha1_filename << endl; + + return EXIT_SUCCESS; } diff --git a/src/internal/serializer.cpp b/src/internal/serializer.cpp index ac6841a..7d244c8 100644 --- a/src/internal/serializer.cpp +++ b/src/internal/serializer.cpp @@ -126,11 +126,12 @@ uint8_t* Serializer::serialize(const std::string config_path, size_t &size) { return serialize(xmlStorage, size); } -void Serializer::serialize(const std::string config_path, std::ostream &output) { +uint8_t *Serializer::serialize(const std::string config_path, std::ostream &output) { size_t size; uint8_t *buf = serialize(config_path, size); output.write(reinterpret_cast(buf), size); + return buf; } template diff --git a/src/internal/serializer.hpp b/src/internal/serializer.hpp index 62de2fd..b5a7f68 100644 --- a/src/internal/serializer.hpp +++ b/src/internal/serializer.hpp @@ -83,7 +83,7 @@ namespace ldp_xml_parser public: uint8_t *serialize(const ldp_xml::StorageBackendXML &db, size_t &size); uint8_t *serialize(const std::string config_path, size_t &size); - void serialize(const std::string config_path, std::ostream &output); + uint8_t *serialize(const std::string config_path, std::ostream &output); friend class SerializerTests; }; } -- 2.7.4 From f994b5e17bfab4f3d556cacbd10b281116c3f9ca Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Mon, 6 May 2019 13:57:56 +0200 Subject: [PATCH 13/16] serialization: file version verification This adds flatbuffers file identifier and uses it during verification. Change-Id: I2d49607d8c5ca0b9678e9bc68a9dc6201ef4c7b5 --- src/dbuspolicy_printer.cpp | 2 +- src/internal/include/fb.fbs | 2 ++ src/internal/include/fb_generated.h | 23 ++++++++++++++++------- src/internal/serializer.cpp | 2 +- src/internal/storage_backend_serialized.cpp | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/dbuspolicy_printer.cpp b/src/dbuspolicy_printer.cpp index 4ea8c30..25a45fa 100644 --- a/src/dbuspolicy_printer.cpp +++ b/src/dbuspolicy_printer.cpp @@ -69,7 +69,7 @@ int main(int argc, char *argv[]) { ldp_serialized::StorageBackendSerialized storage; - if (!storage.init(input_filename.c_str(), true)) { + if (!storage.init(input_filename.c_str(), just_verify)) { if (just_verify) cout << input_filename << ": FAILED" << endl; return EXIT_FAILURE; diff --git a/src/internal/include/fb.fbs b/src/internal/include/fb.fbs index c0e88c8..8fce719 100644 --- a/src/internal/include/fb.fbs +++ b/src/internal/include/fb.fbs @@ -108,3 +108,5 @@ table DecisionItem { } root_type File; + +file_identifier "LDP1"; diff --git a/src/internal/include/fb_generated.h b/src/internal/include/fb_generated.h index 95d8eec..ce371e4 100644 --- a/src/internal/include/fb_generated.h +++ b/src/internal/include/fb_generated.h @@ -74,7 +74,7 @@ inline const char * const *EnumNamesDecision() { inline const char *EnumNameDecision(Decision e) { if (e < Decision_ANY || e > Decision_CHECK) return ""; - const size_t index = static_cast(e); + const size_t index = static_cast(e); return EnumNamesDecision()[index]; } @@ -110,7 +110,7 @@ inline const char * const *EnumNamesBusAccessType() { inline const char *EnumNameBusAccessType(BusAccessType e) { if (e < BusAccessType_USER || e > BusAccessType_ALL_GROUPS) return ""; - const size_t index = static_cast(e); + const size_t index = static_cast(e); return EnumNamesBusAccessType()[index]; } @@ -149,7 +149,7 @@ inline const char * const *EnumNamesMessageType() { inline const char *EnumNameMessageType(MessageType e) { if (e < MessageType_ANY || e > MessageType_SIGNAL) return ""; - const size_t index = static_cast(e); + const size_t index = static_cast(e); return EnumNamesMessageType()[index]; } @@ -1417,26 +1417,35 @@ inline const FB::File *GetSizePrefixedFile(const void *buf) { return flatbuffers::GetSizePrefixedRoot(buf); } +inline const char *FileIdentifier() { + return "LDP1"; +} + +inline bool FileBufferHasIdentifier(const void *buf) { + return flatbuffers::BufferHasIdentifier( + buf, FileIdentifier()); +} + inline bool VerifyFileBuffer( flatbuffers::Verifier &verifier) { - return verifier.VerifyBuffer(nullptr); + return verifier.VerifyBuffer(FileIdentifier()); } inline bool VerifySizePrefixedFileBuffer( flatbuffers::Verifier &verifier) { - return verifier.VerifySizePrefixedBuffer(nullptr); + return verifier.VerifySizePrefixedBuffer(FileIdentifier()); } inline void FinishFileBuffer( flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset root) { - fbb.Finish(root); + fbb.Finish(root, FileIdentifier()); } inline void FinishSizePrefixedFileBuffer( flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset root) { - fbb.FinishSizePrefixed(root); + fbb.FinishSizePrefixed(root, FileIdentifier()); } } // namespace FB diff --git a/src/internal/serializer.cpp b/src/internal/serializer.cpp index 7d244c8..b2b5de9 100644 --- a/src/internal/serializer.cpp +++ b/src/internal/serializer.cpp @@ -107,7 +107,7 @@ uint8_t* Serializer::serialize(const ldp_xml::StorageBackendXML &db, size_t &siz receive_set, access_set); - m_builder.Finish(file); + m_builder.Finish(file, FB::FileIdentifier()); uint8_t* buf = m_builder.GetBufferPointer(); size = m_builder.GetSize(); diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp index f5c03e1..7c880d9 100644 --- a/src/internal/storage_backend_serialized.cpp +++ b/src/internal/storage_backend_serialized.cpp @@ -128,7 +128,7 @@ bool StorageBackendSerialized::StorageBackendSerializedImpl::init(const char *fi if (verify) { auto verifier = flatbuffers::Verifier(mem, length); - if (!FB::VerifyFileBuffer(verifier)) { + if (!FB::VerifyFileBuffer(verifier) || !FB::FileBufferHasIdentifier(mem)) { tslog::log_error("verification of serialized data: failed\n"); return false; } -- 2.7.4 From 329ae0e418694821a4e46005e93ed3a8b5a16c62 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Mon, 6 May 2019 13:03:09 +0200 Subject: [PATCH 14/16] serializer: define order of including files in includedir In the reference documentation has an undefined order of including files from a directory. This makes the order unoficially and implicitly defined to make generated serialized files equal for the same set of files. It does not mean that users may now rely on it. The order is alphabetical. Change-Id: I07fd137e6a9646a541387bb0ef205edfc012f5f9 --- src/internal/xml_parser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/internal/xml_parser.cpp b/src/internal/xml_parser.cpp index faa2dfe..b188d0a 100644 --- a/src/internal/xml_parser.cpp +++ b/src/internal/xml_parser.cpp @@ -290,6 +290,7 @@ void XmlParser::getIncludedFiles(const std::string& parent_dir, const std::strin } } closedir(dir); + sort(files.begin(), files.end()); if (tslog::enabled()) { std::cout << "\nincludedir: " << incldir << ", " << files.size() << " included files found:\n"; -- 2.7.4 From 3c5fd8246e295562148841868b616ebb6848e0f4 Mon Sep 17 00:00:00 2001 From: Baumann Date: Mon, 6 May 2019 16:28:48 +0200 Subject: [PATCH 15/16] add missing PolicyOwn::ItemType Change-Id: I04fc8c0a51d3ff717834f9985acd883800be074e --- src/internal/policy_containers.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/internal/policy_containers.hpp b/src/internal/policy_containers.hpp index 6b42e59..0516d73 100644 --- a/src/internal/policy_containers.hpp +++ b/src/internal/policy_containers.hpp @@ -49,6 +49,8 @@ private: class OwnershipTree ownership_tree; public: + typedef ItemOwn item_type; + /** Adds given item to tree by retrieving its name, decision and checking is it prefix. * \param[in] item Item to add to policy */ -- 2.7.4 From faefe5774dcc5d327acc8487dd5f8efe58bb7040 Mon Sep 17 00:00:00 2001 From: Baumann Date: Wed, 15 May 2019 12:46:46 +0200 Subject: [PATCH 16/16] Makefile now conforms to libtool naming standard Change-Id: I61f5d06ca5aeb5aa63875cc087c438b6b93ecc9a --- Makefile.am | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0a5d9e4..4e1f706 100644 --- a/Makefile.am +++ b/Makefile.am @@ -90,7 +90,7 @@ dbuspolicy_serializer_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" # $(DLOG_LIBS) \ # -Wl,--version-script=$(top_srcdir)/src/libdbuspolicy1.sym -dbuspolicy_serializer_LDADD = src/libinternal.a \ +dbuspolicy_serializer_LDADD = src/libinternal.la \ $(CYNARA_LIBS) \ $(DLOG_LIBS) \ -lexpat \ @@ -105,7 +105,7 @@ dbuspolicy_printer_SOURCES =\ dbuspolicy_printer_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" -dbuspolicy_printer_LDADD = src/libinternal.a \ +dbuspolicy_printer_LDADD = src/libinternal.la \ $(CYNARA_LIBS) \ $(DLOG_LIBS) \ -lexpat @@ -152,14 +152,14 @@ src_test_libdbuspolicy1_send_destination_prefix_deny_SOURCES = src/test-libdbusp src_test_libdbuspolicy1_send_destination_prefix_deny_gdi_SOURCES = src/test-libdbuspolicy1-send_destination_prefix-deny-gdi.cpp src_test_serializer_SOURCES = src/test-serializer.cpp -noinst_LTLIBRARIES = src/libinternal.a -src_libinternal_a_SOURCES =\ +noinst_LTLIBRARIES = src/libinternal.la +src_libinternal_la_SOURCES =\ $(COMMON_SRC) \ src/internal/cynara_mockup.cpp \ src/internal/groups_mockup.cpp \ src/primary-conf-files.c -TESTS_LDADD = src/libinternal.a \ +TESTS_LDADD = src/libinternal.la \ $(CYNARA_LIBS) \ $(DLOG_LIBS) \ -lexpat @@ -179,8 +179,8 @@ src_test_libdbuspolicy1_send_destination_prefix_deny_gdi_LDADD = $(TESTS_LDADD) src_test_serializer_LDADD = $(TESTS_LDADD) if ENABLE_STANDALONE_TESTS -noinst_LTLIBRARIES += src/libinternalfortests.a -src_libinternalfortests_a_SOURCES =\ +noinst_LTLIBRARIES += src/libinternalfortests.la +src_libinternalfortests_la_SOURCES =\ $(COMMON_SRC) \ src/internal/cynara.cpp \ src/internal/groups_proxy.cpp \ @@ -202,13 +202,13 @@ stest_memory_SOURCES = src/stest_memory.c stest_performance_SOURCES = src/stest_performance.cpp stest_load_perf_SOURCES = src/stest_load_perf.cpp -stest_ownership_LDADD = src/libinternalfortests.a -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) -stest_method_call_LDADD = src/libinternalfortests.a -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) -stest_signal_LDADD = src/libinternalfortests.a -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) -stest_cynara_LDADD = src/libinternalfortests.a -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) -stest_memory_LDADD = src/libinternalfortests.a -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) -stest_performance_LDADD = src/libinternal.a -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) -stest_load_perf_LDADD = src/libinternal.a -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) +stest_ownership_LDADD = src/libinternalfortests.la -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) +stest_method_call_LDADD = src/libinternalfortests.la -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) +stest_signal_LDADD = src/libinternalfortests.la -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) +stest_cynara_LDADD = src/libinternalfortests.la -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) +stest_memory_LDADD = src/libinternalfortests.la -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) +stest_performance_LDADD = src/libinternal.la -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) +stest_load_perf_LDADD = src/libinternal.la -lexpat -lstdc++ $(CYNARA_LIBS) $(DLOG_LIBS) stest_load_perf_CPPFLAGS = -ggdb ${AM_CPPFLAGS} -O0 all-tests:: $(alonetest_PROGRAMS) $(runner_PROGRAMS) -- 2.7.4