From 2fd047a105f5cb211dcbc23bd5d8d37f941395e7 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Fri, 9 Sep 2016 16:34:17 +0900 Subject: [PATCH 01/16] svace:change strcat to strncat Change-Id: I546599c8f5c850eda6374a792492e7db1e9dcf7a Signed-off-by: sanghyeok.oh --- src/internal/policy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index bed844a..5251fd2 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -462,8 +462,8 @@ 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, " "); + std::strncat(tmp, names[i].name, sizeof(tmp) - strlen(tmp) - 1); + std::strncat(tmp, " ", sizeof(tmp) - strlen(tmp) - 1); } 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; -- 2.7.4 From 3cbf2cfa8d17e5f63fa1091f5e7fda67646e0dea Mon Sep 17 00:00:00 2001 From: Krystian Kisielak Date: Mon, 29 Aug 2016 15:13:46 +0200 Subject: [PATCH 02/16] Added doxygen documentation. Change-Id: I097ff1090998637d5c51ffbfa6023bfd0c04e405 Signed-off-by: Krystian Kisielak --- doc/main_page.dox | 63 +++++++++++++++++++++ doxygen.cfg | 18 ++++-- src/dbuspolicy1/libdbuspolicy1.h | 98 +++++++++++++++++---------------- src/internal/internal.cpp | 4 ++ src/internal/internal.h | 66 ++++++++++++++++++++++ src/internal/libdbuspolicy1-private.hpp | 1 + src/internal/naive_policy_checker.cpp | 19 ++++++- src/internal/naive_policy_checker.hpp | 88 +++++++++++++++++++++++++++++ src/internal/naive_policy_db.cpp | 14 ++++- src/internal/naive_policy_db.hpp | 97 +++++++++++++++++++++++++++++++- src/internal/policy.cpp | 5 ++ src/internal/policy.hpp | 29 +++++++++- src/internal/tslog.cpp | 5 ++ src/internal/tslog.hpp | 10 +++- src/internal/xml_parser.cpp | 4 ++ src/internal/xml_parser.hpp | 19 +++++-- src/libdbuspolicy1.c | 21 ------- 17 files changed, 472 insertions(+), 89 deletions(-) create mode 100644 doc/main_page.dox diff --git a/doc/main_page.dox b/doc/main_page.dox new file mode 100644 index 0000000..299c4d3 --- /dev/null +++ b/doc/main_page.dox @@ -0,0 +1,63 @@ +/** + \mainpage Libdbuspolicy documentation + +\section intro_sec Introduction + +Dbuspolicy is library which allows to check policies for ownership, send and receive rules. + +\section Implementation + +\subsection step1 Step 1: Init + +Policy is parsed from xml file/files and added to policy databases. In send/receive policy rules are stored in vector, in ownership policy as a prefix tree. +Handle to policy db is created. + +\subsection step2 Step 2: Looking for rule + +Depending on the type of query(ownership/send/receive) distinct functions are called to check policy. First policies of each types (MANDATORY, user, group, DEFAULT) are accesed by checker.\n +Then each of them is searched for given item. At the end returned decision is parsed. In case of decision CHECK Cynara is run. + + +\section desc_sec Description + +Libdbuspolicy uses dbus-daemon logics. Policies are created from policy section from dbus .conf files. +Config file syntax is precisely described in section "CONFIGURATION FILE" at: +dbus-daemon documentation. \n + An example of syntax is shown below: + +\code{.xml} + + + + + + + + + + + + + + + + + + + + + + + + + + + +\endcode + + + */ diff --git a/doxygen.cfg b/doxygen.cfg index ff1c452..0b1c67d 100644 --- a/doxygen.cfg +++ b/doxygen.cfg @@ -4,14 +4,20 @@ GENERATE_LATEX = NO GENERATE_MAN = NO GENERATE_RTF = NO CASE_SENSE_NAMES = NO -INPUT = src/dbuspolicy1/libdbuspolicy1.h +INPUT = doc/main_page.dox src/internal/ src/dbuspolicy1 src/libdbuspolicy1.c +EXCLUDE = src/internal/xml_policy.hpp JAVADOC_AUTOBRIEF = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES TYPEDEF_HIDES_STRUCT = YES -INLINE_SOURCES = YES -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -SEARCHENGINE = NO -COMPACT_LATEX = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +SEARCHENGINE = YES +COMPACT_LATEX = YES LATEX_HIDE_INDICES = YES +HAVE_DOT = NO +EXTRACT_ALL = YES +RECURSIVE = NO +QUIET = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO diff --git a/src/dbuspolicy1/libdbuspolicy1.h b/src/dbuspolicy1/libdbuspolicy1.h index b6ffdae..d923a94 100644 --- a/src/dbuspolicy1/libdbuspolicy1.h +++ b/src/dbuspolicy1/libdbuspolicy1.h @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * \file libdbuspolicy1.h +/** API usually used in libdbus/libglib. + \defgroup API API */ #ifndef _LIBDBUSPOLICY1_H_ #define _LIBDBUSPOLICY1_H_ @@ -50,38 +49,42 @@ extern "C" { struct udesc; -/*! - Initialize libdbuspolicy configuration context - \param bus_path path to the kdbus bus (system or session) +/** + * Initialize libdbuspolicy configuration context + * \param[in] bus_path path to the kdbus bus (system or session) - \note This function should be called only on well known kdbus buses - - the system bus (/sys/fs/kdbus/0-system/bus) and session bus - (/sys/fs/kdbus/getuid()-user/bus). If any other bus is specified - function will not succeed. + * \note This function should be called only on well known kdbus buses + * - the system bus (/sys/fs/kdbus/0-system/bus) and session bus + * (/sys/fs/kdbus/getuid()-user/bus). If any other bus is specified + * function will not succeed. - \return On success pointer to configuration context is returned. On - error NULL is returned. + * \return On success pointer to configuration context is returned. On + * error NULL is returned. + * \ingroup API */ void* dbuspolicy1_init(const char *bus_path); -/*! - Free libdbuspolicy configuration context - \param configuration pointer with policy configuration acquired using dbuspolicy1_init +/** + * Free libdbuspolicy configuration context + * \ingroup API + * \param[in] configuration Pointer with policy configuration acquired using dbuspolicy1_init */ void dbuspolicy1_free(void* configuration); -/*! - Check policy for outgoing message - \param configuration pointer with policy configuration - \param destination list of message destinations - \param sender list of message sender names - \param path path - \param interface interface name - \param member member name - \param message_type message type - \param error_name (future implementation) - \param reply_serial (future implementation) - \param requested_reply (future implementation) +/** + * Check policy for outgoing message + * \ingroup API + * \param[in] configuration Pointer with policy configuration + * \param[in] destination List of message destinations + * \param[in] sender List of message sender names + * \param[in] path Path + * \param[in] interface Interface name + * \param[in] member Member name + * \param[in] message_type Message type + * \param[in] error_name (future implementation) + * \param[in] reply_serial (future implementation) + * \param[in] requested_reply (future implementation) + * \return Allow/deny or negative error code */ int dbuspolicy1_check_out(void* configuration, const char *destination, @@ -94,21 +97,22 @@ int dbuspolicy1_check_out(void* configuration, int reply_serial, int requested_reply); -/*! - Check policy for incoming message - \param configuration pointer with policy configuration - \param destination list of message destinations - \param sender list of message sender names - \param sender_label sender label (should be manually extracted from incomming message) - \param sender_uid sender uid (should be manually extracted from incomming message) - \param sender_gid sender gid (should be manually extracted from incomming message) - \param path path - \param interface interface name - \param member member name - \param message_type message type - \param error_name (future implementation) - \param reply_serial (future implementation) - \param requested_reply (future implementation) +/** Check policy for incoming message + * \ingroup API + * \param[in] configuration Pointer with policy configuration + * \param[in] destination List of message destinations + * \param[in] sender List of message sender names + * \param[in] sender_label Sender label (should be manually extracted from incoming message) + * \param[in] sender_uid Sender uid (should be manually extracted from incoming message) + * \param[in] sender_gid Sender gid (should be manually extracted from incoming message) + * \param[in] path Path + * \param[in] interface Interface name + * \param[in] member Member name + * \param[in] message_type Message type + * \param[in] error_name (future implementation) + * \param[in] reply_serial (future implementation) + * \param[in] requested_reply (future implementation) + * \returns Allow/deny or negative error code */ int dbuspolicy1_check_in(void* configuration, const char *destination, @@ -124,10 +128,12 @@ int dbuspolicy1_check_in(void* configuration, int reply_serial, int requested_reply); -/*! - Check policy for service ownership - \param configuration pointer with policy configuration - \param service service name +/** + * Check policy for service ownership + * \ingroup API + * \param[in] configuration Pointer with policy configuration + * \param[in] service Service name + * \returns Allow/deny or negative error code */ int dbuspolicy1_can_own(void* configuration, const char* const service); diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index 2849ea0..1445f7b 100644 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -13,6 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/** + * \file + * \ingroup Implementation + */ #include #include diff --git a/src/internal/internal.h b/src/internal/internal.h index 270b13a..787b380 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -14,6 +14,15 @@ * limitations under the License. */ + +/** + \defgroup Implementation Implementation + Internal implementation of policy. + */ +/** + * \file + * \ingroup Implementation + */ #ifndef _LIBDBUSPOLICY1_INTERNAL_H_ #define _LIBDBUSPOLICY1_INTERNAL_H_ @@ -23,13 +32,38 @@ extern "C" { #define KDBUS_CONN_MAX_NAMES 256 +/** Initializes policies from given policy configuration file name + * \param[in] bus_type Bus type (system/session) + * \param[in] config_name Configuration file name + */ int __internal_init(bool bus_type, const char* const config_name); + +/** Inits tslog. */ void __internal_init_once(void); + extern pthread_mutex_t g_mutex; + +/** Flushes logs. */ void __internal_init_flush_logs(void); + +/** Enables logger mutex */ void __internal_enter(void); + +/** Disables logger mutex */ void __internal_exit(void); +/** Checks if user can send message to given location. + * \param[in] bus_type Bus type (system/session) + * \param[in] user User id + * \param[in] group User group id + * \param[in] label Sender label + * \param[in] destination Message destination + * \param[in] path Path + * \param[in] interface Interface name + * \param[in] member Member name + * \param[in] type Message type + * \return 1 on allow, 0 on deny, negative error code otherwise + */ int __internal_can_send(bool bus_type, const uid_t user, const gid_t group, @@ -40,6 +74,18 @@ int __internal_can_send(bool bus_type, const char* const member, int type); +/** Checks if user can send messages (multiple destinations). + * \param[in] bus_type Bus type (system/session) + * \param[in] user User id + * \param[in] group User group id + * \param[in] label Sender label + * \param[in] destination Message destination + * \param[in] path Path + * \param[in] interface Interface name + * \param[in] member Member name + * \param[in] type Message type + * \return 1 on allow, 0 on deny, negative error code otherwise + */ int __internal_can_send_multi_dest(bool bus_type, const uid_t user, const gid_t group, @@ -50,6 +96,18 @@ int __internal_can_send_multi_dest(bool bus_type, const char* const member, int type); +/** Check if user can receive messages. + * \param[in] bus_type Bus type (system/session) + * \param[in] user User id + * \param[in] group User group id + * \param[in] label User label + * \param[in] sender Sender of received message + * \param[in] path Path + * \param[in] interface Interface name + * \param[in] member Member name + * \param[in] type Message type + * \return 1 on allow, 0 on deny, negative error code otherwise + */ int __internal_can_recv(bool bus_type, uid_t user, gid_t group, @@ -60,6 +118,14 @@ int __internal_can_recv(bool bus_type, const char* const member, int type); +/** Checks if given user can own interface with given label + * \param[in] bus_type Bus type (system/session) + * \param[in] user User id + * \param[in] group User group id + * \param[in] label Label given to Cynara + * \param[in] service Name to own + * \return 1 on allow, 0 on deny, negative error code otherwise + */ int __internal_can_own(bool bus_type, uid_t user, gid_t group, diff --git a/src/internal/libdbuspolicy1-private.hpp b/src/internal/libdbuspolicy1-private.hpp index 83bd79c..14b9d09 100644 --- a/src/internal/libdbuspolicy1-private.hpp +++ b/src/internal/libdbuspolicy1-private.hpp @@ -26,6 +26,7 @@ namespace arraySizeDetail { #define TABSIZE(...) (::arraySizeDetail::size(__VA_ARGS__)) namespace { + /** Contains error code and string corresponding to it */ class ErrCode { int m_err; std::string m_err_str; diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index 39702e5..71ab8c1 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -2,6 +2,11 @@ #include "cynara.hpp" #include "tslog.hpp" +/** + * \file + * \ingroup Implementation + */ + using namespace ldp_xml_parser; static void __log_item(const MatchItemSR& item) @@ -65,6 +70,10 @@ NaivePolicyChecker::~NaivePolicyChecker() { + + + + DecisionResult NaivePolicyChecker::check(bool bus_type, uid_t uid, gid_t gid, @@ -112,10 +121,12 @@ Decision NaivePolicyChecker::checkPolicySR(const NaivePolicyDb::PolicySR& policy return Decision::ANY; } -Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& policy, const ItemOwn& item, const char*& privilege) { +Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& policy, const ItemOwn& item, const char*& privilege) +{ if (tslog::verbose()) { - __log_item(item); + std::cout << "Checking policy for name: " << std::string(!(item.getName()) ? item.getName() : "NULL") << std::endl; } + const char *name = item.getName(); const struct TreeNode *node = policy.getTreeRoot(); int childIndex = 0; @@ -125,6 +136,9 @@ Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& poli childIndex = char_map[*name]; if (childIndex > 64) { /* name contains forbidden char */ + if (tslog::verbose()) { + std::cout << "Name: " << std::string(!(item.getName()) ? (item.getName()) : "NULL") << " contains forbidden character!" << std::endl; + } privilege = NULL; return Decision::DENY; } @@ -146,6 +160,7 @@ Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& poli } name++; } + return node->__decisionItem.getDecision(); } diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index a54302d..b80c23f 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -13,6 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +/** + * \file + * \ingroup Implementation + */ + + #ifndef _NAIVE_DECISIONER_H #define _NAIVE_DECISIONER_H @@ -21,25 +28,71 @@ namespace ldp_xml_parser { + /* Class which checks rights in policies retrieved from policy db + * \ingroup Implementation + */ class NaivePolicyChecker { private: + + /** Policy databases for system and session bus */ NaivePolicyDb m_bus_db[2]; + + /** Adapter to policies database */ DbAdapter* m_adapter; + + /** Retrieves policy db + * \param[in] type Type of database (system/session bus) + * \return Returns reference to chosen bus policy db + * \ingroup Implementation + */ NaivePolicyDb& getPolicyDb(bool type); + /** Checks send/receive policy for given item + * \param[in] policy Policy to check + * \param[in] item Item to check + * \param[in] privilege Privilege string + * \return Returns decision retrieved from policy + * \ingroup Implementation + * \callgraph + */ Decision checkPolicySR(const NaivePolicyDb::PolicySR& policy, const MatchItemSR& item, const char*& privilege); + /** Checks ownership policy for given item + * \param[in] policy Policy to check + * \param[in] item Item to check + * \param[in] privilege Privilege string + * \return Returns decision retrieved from policy + * \ingroup Implementation + */ Decision checkPolicyOwn(const NaivePolicyDb::PolicyOwn& policy, const ItemOwn& item, const char*& privilege); + /** Parses delivered decision. In case of Decision::CHECK calls cynara. + * \param[in] decision Decision from checkers + * \param[in] uid User id + * \param[in] label User label + * \param[in] privilege Privilege string + * \return Returns deny=0, allow=1 or cynara error + * \ingroup Implementation + */ DecisionResult parseDecision(Decision decision, uid_t uid, const char* label, const char* privilege); + /** Checks send/receive policy for given item + * \param[in] bus_type Bus type (system/session) + * \param[in] uid User id + * \param[in] gid User group id + * \param[in] label User label + * \param[in] item Item to check + * \param[in] type Item type + * \return Returns deny=0, allow=1 or cynara error + * \ingroup Implementation + */ DecisionResult checkItemSR(bool bus_type, uid_t uid, gid_t gid, @@ -47,6 +100,16 @@ namespace ldp_xml_parser const MatchItemSR& item, const ItemType type); + /** Checks send/receive policy for given item + * \param[in] bus_type Bus type (system/session) + * \param[in] uid User id + * \param[in] gid User group id + * \param[in] label User label + * \param[in] item Item to check + * \param[in] type Item type + * \return Returns deny=0, allow=1 or cynara error + * \ingroup Implementation + */ DecisionResult checkItemOwn(bool bus_type, uid_t uid, gid_t gid, @@ -55,12 +118,37 @@ namespace ldp_xml_parser const ItemType type); public: ~NaivePolicyChecker(); + + /** Generates adapter for db with policies + * \ingroup Implementation + */ DbAdapter& generateAdapter(); + + /** Checks ownership policy for given item + * \param[in] bus_type Bus type (system/session) + * \param[in] uid User id + * \param[in] gid User group id + * \param[in] label User label + * \param[in] name Name to own + * \return Returns deny=0, allow=1 or cynara error + * \ingroup Implementation + */ DecisionResult check(bool bus_type, uid_t uid, gid_t gid, const char* const label, const char* const name); + + /** Checks send/receive policy for given item + * \param[in] bus_type Bus type (system/session) + * \param[in] uid User id + * \param[in] gid User group id + * \param[in] label User label + * \param[in] matcher Structure with multiple names to check + * \param[in] type Item type + * \return Returns deny=0, allow=1 or cynara error + * \ingroup Implementation + */ DecisionResult check(bool bus_type, uid_t uid, gid_t gid, diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index a82cced..a796660 100644 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -2,6 +2,11 @@ #include "cynara.hpp" #include "tslog.hpp" +/** + * \file + * \ingroup Implementation + */ + using namespace ldp_xml_parser; @@ -166,9 +171,15 @@ const struct TreeNode* NaivePolicyDb::PolicyOwn::getTreeRoot() const{ assert(treeRootPtr); return treeRootPtr; } + void NaivePolicyDb::PolicyOwn::addItem(ItemOwn* item) { const char *name = item->getName(); - + if (tslog::enabled()){ + if(name) + std::cout << "Adding item: " << name << " with decision: " << (int) item->getDecision().getDecision() << std::endl; + else + std::cout << "Adding item: NULL with decision: " << (int) item->getDecision().getDecision() << std::endl; + } if (!name) { /* For '*' name*/ if(item->getDecision().getDecision() != Decision::ANY){ @@ -216,7 +227,6 @@ void NaivePolicyDb::PolicyOwn::addItem(ItemOwn* item) { node->__is_prefix = item->isPrefix(); } - bool NaivePolicyDb::getPolicySR(const NaivePolicyDb::PolicyTypeSetSR& set, const PolicyType policy_type, const PolicyTypeValue policy_type_value, diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp index 3b8a655..5efd301 100644 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -20,28 +20,43 @@ #include #include "policy.hpp" + +/** + * \file + * \ingroup Implementation + */ + namespace ldp_xml_parser { + /** Database class, contains policies for ownership and send/receive */ class NaivePolicyDb { public: + /** Class containing policy with send/receive rules */ class PolicySR { private: + /** Vector with policy items */ std::vector m_items; public: + /** Iterator used to get access to policy items */ class PolicyConstIterator { private: + /** Vector with policy items */ const std::vector& m_items; + /** Assistant iterator */ int m_index; public: + /** Public method allowing access to policy items */ PolicyConstIterator(const std::vector& items, int position); ItemSendReceive* const& operator*() const; PolicyConstIterator& operator++(); bool operator!=(const PolicyConstIterator& it) const; }; - + /** Iterator used to get access to policy items */ class PolicyIterator { private: + /** Vector with policy items */ std::vector& m_items; + /** Assistant iterator */ int m_index; public: PolicyIterator(std::vector& items, int position); @@ -54,74 +69,150 @@ namespace ldp_xml_parser PolicyIterator end(); PolicyConstIterator begin() const; PolicyConstIterator end() const; + + /** Adds given item to policy. + * \param[in] item Item to add to policy + */ void addItem(ItemSendReceive* item); }; - + /** Class containing policy with ownership rules */ class PolicyOwn { private: + /** Pointer to policy tree root */ struct TreeNode *treeRootPtr = NULL; + + /** Removes given node and its descendants + * \param[in] node Node to remove from tree + */ void nodeRemove(TreeNode **node); public: PolicyOwn(); ~PolicyOwn(); + /** Adds given item to tree by retrieving its name, decision and checking is it prefix. + * \param[in] item Item to add to policy + */ void addItem(ItemOwn* item); + + /** Retrieves policy tree root + * \return Pointer to tree root + */ const TreeNode* getTreeRoot() const; }; ~NaivePolicyDb(); + /** Gets policy with ownership rules from DB + * \param[in] item_type Item Type + * \param[in] policy_type Policy type + * \param[in] policy_type_value Policy type value + * \param[out] policy Received policy + * \return True if there is such policy, false elsewhere + */ bool getPolicy(const ItemType item_type, const PolicyType policy_type, const PolicyTypeValue policy_type_value, const PolicyOwn*& policy) const; + /** Gets policy with send/receive rules from DB + * \param[in] item_type Item Type + * \param[in] policy_type Policy type + * \param[in] policy_type_value Policy type value + * \param[out] policy Received policy + * \return True if there is such policy, false elsewhere + */ bool getPolicy(const ItemType item_type, const PolicyType policy_type, const PolicyTypeValue policy_type_value, const PolicySR*& policy) const; + /** Adds item to ownership policy + * \param[in] policy_type Policy type + * \param[in] policy_type_value Policy type value + * \param[in] item Item to add + */ void addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, ItemOwn* const item); + /** Adds item to send/receive policy + * \param[in] policy_type Policy type + * \param[in] policy_type_value Policy type value + * \param[in] item Item to add + */ void addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, ItemSendReceive* const item); private: - + /** Contains maps for different ownership policy types (uid, gid, DEFAULT, MANDATORY) */ struct PolicyTypeSetOwn { + /** Policies for all contexts */ PolicyOwn context[static_cast(ContextType::MAX)]; + /** Map with policies for different users */ std::map user; + /** Map with policies for different groups */ std::map group; }; + /** Contains maps for different send/receive policy types (uid, gid, DEFAULT, MANDATORY) */ struct PolicyTypeSetSR { + /** Policies for all contexts */ PolicySR context[static_cast(ContextType::MAX)]; + /** Map with policies for different users */ std::map user; + /** Map with policies for different groups */ std::map group; }; + /** Set of ownership policies */ PolicyTypeSetOwn m_own_set; + /** Set of send policies */ PolicyTypeSetSR m_send_set; + /** Set of receive policies */ PolicyTypeSetSR m_receive_set; + /** Adds given item to send/receive policy + * \param[in] set Set to add item to + * \param[in] policy_type Policy type + * \param[in] policy_type_value Policy type value + * \param[in] item Item to add + */ void addItem(PolicyTypeSetSR& set, const PolicyType policy_type, const PolicyTypeValue policy_type_value, ItemSendReceive* const item); + /** Gets requested policy from send/receive policies + * \param[in] set Set to add item to + * \param[in] policy_type Policy type + * \param[in] policy_type_value Policy type value + * \param[out] policy Received policy + * \return False if there is no such policy, true elsewhere + */ bool getPolicySR(const PolicyTypeSetSR& set, const PolicyType policy_type, const PolicyTypeValue policy_type_value, const PolicySR*& policy) const; + /** Adds given item to ownership policy + * \param[in] set Set to add item to + * \param[in] policy_type Policy type + * \param[in] policy_type_value Policy type value + * \param[in] item Item to add + */ void addItem(PolicyTypeSetOwn& set, const PolicyType policy_type, const PolicyTypeValue policy_type_value, ItemOwn* const item); + /** Gets requested policy from ownership policies + * \param[in] set Set to add item to + * \param[in] policy_type Policy type + * \param[in] policy_type_value Policy type value + * \param[out] policy Received policy + * \return False if there is no such policy, true elsewhere + */ bool getPolicyOwn(const PolicyTypeSetOwn& set, const PolicyType policy_type, const PolicyTypeValue policy_type_value, diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index bed844a..2497a63 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -1,3 +1,8 @@ +/** + * \file + * \ingroup Implementation + */ + #include "policy.hpp" #include "naive_policy_db.hpp" #include "tslog.hpp" diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp index 55834cc..4e17722 100644 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -13,6 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + + +/** + * \file + * \ingroup Implementation + */ + #ifndef _POLICY_H #define _POLICY_H @@ -20,12 +27,14 @@ #include #include #include + #define MAX_LOG_LINE 1024 +/** Maximum tree node children. It is connected with proper characters which can be used in name.*/ #define MAX_CHILDREN 65 namespace ldp_xml_parser { - + /** Char map used in ownership policy. Single character from given name is mapped to index of tree node child*/ 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, @@ -34,7 +43,7 @@ namespace ldp_xml_parser 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}; - + /** Type of sent message*/ enum class MessageType : uint8_t { ANY = 0, METHOD_CALL, @@ -43,12 +52,14 @@ namespace ldp_xml_parser SIGNAL }; + /** Sent message direction */ enum class MessageDirection : uint8_t { ANY, SEND, RECEIVE }; + /** Item type. (different items have different content of class */ enum class ItemType : uint8_t { GENERIC, OWN, @@ -56,18 +67,21 @@ namespace ldp_xml_parser RECEIVE }; + /** Policy type, either context, user or group */ enum class PolicyType : uint8_t { CONTEXT, USER, GROUP }; + /** Context type for context policy type */ enum class ContextType : uint8_t { DEFAULT, MANDATORY, MAX }; + /** Decision returned by policy checkers. Is parsed later */ enum class Decision : uint8_t { ANY, ALLOW, @@ -75,12 +89,14 @@ namespace ldp_xml_parser CHECK }; + /** Final decision of libdbus policy. Either allow, deny or error code */ enum class DecisionResult : int8_t { CYNARA_ERROR = -3, DENY = 0, ALLOW }; + /** Contains value corresponding to each of policy types */ union PolicyTypeValue { PolicyTypeValue(); PolicyTypeValue(ContextType type); @@ -92,6 +108,7 @@ namespace ldp_xml_parser class ItemBuilder; + /** Class contains decision and privilege string */ class DecisionItem { private: Decision __decision; @@ -106,6 +123,7 @@ namespace ldp_xml_parser const char* toString(char* str) const; }; + /** Class contains info about ownership policy item */ class ItemOwn { private: DecisionItem __decision; @@ -124,6 +142,7 @@ namespace ldp_xml_parser bool isPrefix() const; }; + /** Node of tree used in ownership policy. */ struct TreeNode{ DecisionItem __decisionItem; char __nameChar; @@ -131,12 +150,14 @@ namespace ldp_xml_parser struct TreeNode *children[MAX_CHILDREN]; }; + /** Name structure for send/receive policy */ struct NameSR { const char* name; int len; NameSR(const char* m = NULL, int l = 0); }; + /** Struct which allows to contain multiple connection names then compared in s/r policy checker */ struct MatchItemSR { int names_num; NameSR names[KDBUS_CONN_MAX_NAMES+1]; @@ -152,6 +173,7 @@ namespace ldp_xml_parser const char* toString(char* str) const; }; + /** Class contains info about item send/receive */ class ItemSendReceive { private: DecisionItem __decision; @@ -180,6 +202,8 @@ namespace ldp_xml_parser }; class NaivePolicyDb; + + /** Allows to create items from given name, decision etc. */ class ItemBuilder { private: DecisionItem __decision; @@ -208,6 +232,7 @@ namespace ldp_xml_parser void setPrefix(bool value); }; + /** Adapter which allows to access policy db. Contains references to system and session db. */ class DbAdapter { private: enum state { diff --git a/src/internal/tslog.cpp b/src/internal/tslog.cpp index fa5b579..cd6d18e 100644 --- a/src/internal/tslog.cpp +++ b/src/internal/tslog.cpp @@ -1,3 +1,8 @@ +/** + * \file + * \ingroup Implementation + */ + #include "tslog.hpp" namespace tslog { diff --git a/src/internal/tslog.hpp b/src/internal/tslog.hpp index 07fc383..62aea11 100644 --- a/src/internal/tslog.hpp +++ b/src/internal/tslog.hpp @@ -13,6 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/** + * \file + * \ingroup Implementation + */ #ifndef _TSLOG_HPP #define _TSLOG_HPP @@ -26,12 +30,16 @@ typedef std::ostream& (*t_ManFun)(std::ostream&); namespace tslog { - + /** 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(); + /** Checks if logs are enabled */ bool enabled(); + + /** Checks if verbosity is enabled */ bool verbose(); } diff --git a/src/internal/xml_parser.cpp b/src/internal/xml_parser.cpp index 5606a33..afd14ca 100644 --- a/src/internal/xml_parser.cpp +++ b/src/internal/xml_parser.cpp @@ -1,3 +1,7 @@ +/** + * \file + * \ingroup Implementation + */ #include "xml_parser.hpp" std::set ldp_xml_parser::XmlParser::__parsed; diff --git a/src/internal/xml_parser.hpp b/src/internal/xml_parser.hpp index ff1a723..4e417b1 100644 --- a/src/internal/xml_parser.hpp +++ b/src/internal/xml_parser.hpp @@ -13,6 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/** + * \file + * \ingroup Implementation + */ #ifndef _XML_PARSER_HPP #define _XML_PARSER_HPP @@ -29,26 +33,29 @@ namespace ldp_xml_parser { + /** Class which have methods parsing policy rules contained in xml files */ class XmlParser : boost::noncopyable { public: + /** Parses given config file for declared bus type */ ErrCode parsePolicy(bool bus, std::string const &fname) { ErrCode err = parse(bus, fname); return err; } - + /** Registers DBAdapter */ void registerAdapter(DbAdapter& adapter) { __adapter = &adapter; } private: - //IO operation + /** Vector containing parsed policy */ static std::set __parsed; + /** Adapter which allows to acces parsed policies */ DbAdapter* __adapter; - //Data obtained from XML + /** Parses config file and all files included in it */ ErrCode parse(bool bus, std::string const &filename) { ErrCode err; std::vector incl_files; @@ -61,7 +68,7 @@ namespace ldp_xml_parser } return err; } - + /** Parses given xml file and files included in it */ ErrCode parse(bool bus, bool first, const std::string& filename, std::vector& included_files) { std::pair errparam; std::vector incl_dirs; @@ -81,7 +88,7 @@ namespace ldp_xml_parser return errparam.first; } - //Get all the .conf files within included subdirectory, POSIX style as boost::filesystem is not header-only + /** Get all the .conf files within included subdirectory, POSIX style as boost::filesystem is not header-only */ void getIncludedFiles(const std::string& filename, const std::string& incldir, std::vector& files) { DIR *dir; struct dirent *ent; @@ -109,7 +116,7 @@ namespace ldp_xml_parser std::cout << "could not open directory " << dname << '\n'; } } - + /** Acceses given configuration file/files */ std::pair parseXml(bool bus, const std::string& filename, std::vector& incl_dirs) { std::pair ret; diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 79b858b..431827a 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -271,13 +271,6 @@ DBUSPOLICY1_EXPORT void __dbuspolicy1_change_creds(void* configuration, uid_t ui static bool configuration_bus_type(struct kconn const *configuration) { return configuration != g_conn; } -/** - * dbuspolicy1_can_send - * @param: <> - * @return: <> - * - * Description. - **/ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, const char *destination, const char *sender, @@ -388,13 +381,6 @@ end: return r; } -/** - * dbuspolicy1_can_send - * @param: <> - * @return: <> - * - * Description. - **/ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, const char *destination, const char *sender, @@ -428,13 +414,6 @@ end: return r; } -/** - * dbuspolicy1_can_send - * @param: <> - * @return: <> - * - * Description. - **/ DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* const service) { int r; -- 2.7.4 From 225b641f1ffdc7b6f30822104b109e278f7b54a4 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Fri, 23 Sep 2016 16:05:31 +0200 Subject: [PATCH 03/16] Minor fix to failed test output Change-Id: I4302b4d836852021a93078ed0a717a5caff6df01 Signed-off-by: Michal Bloch --- src/test-libdbuspolicy1-method.cpp | 2 +- src/test-libdbuspolicy1-ownership.cpp | 2 +- src/test-libdbuspolicy1-signal.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test-libdbuspolicy1-method.cpp b/src/test-libdbuspolicy1-method.cpp index 3c24cb5..7ed039b 100644 --- a/src/test-libdbuspolicy1-method.cpp +++ b/src/test-libdbuspolicy1-method.cpp @@ -54,7 +54,7 @@ struct MethodTest method_tests[]={ 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); + (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() { diff --git a/src/test-libdbuspolicy1-ownership.cpp b/src/test-libdbuspolicy1-ownership.cpp index 11d3cb0..12685ea 100644 --- a/src/test-libdbuspolicy1-ownership.cpp +++ b/src/test-libdbuspolicy1-ownership.cpp @@ -50,7 +50,7 @@ struct OwnershipTest ownership_tests[]={ 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); + (unsigned long)t->user, (unsigned long)t->group, t->label, t->service, ((int)t->expected_result), (int)result); } bool ownership_test() { diff --git a/src/test-libdbuspolicy1-signal.cpp b/src/test-libdbuspolicy1-signal.cpp index 22e9d92..5eeb840 100644 --- a/src/test-libdbuspolicy1-signal.cpp +++ b/src/test-libdbuspolicy1-signal.cpp @@ -26,7 +26,7 @@ struct SignalTest signal_tests[]={ 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); + (unsigned long)t->user, (unsigned long)t->group, t->label, t->dest, t->interface, ((int)t->expected_result), (int)result); } bool signal_test() { -- 2.7.4 From d34f4580119ff422c06a9b1e6ae8a34b57c992e4 Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Thu, 29 Sep 2016 13:59:14 +0200 Subject: [PATCH 04/16] -Wextra -Werror Change-Id: I1b74a76cff3ecb38b646a3dd9a7327d25e5fa1d7 --- configure.ac | 14 ++++---------- src/internal/cynara_mockup.cpp | 3 +++ src/internal/naive_policy_checker.cpp | 23 ++++++++--------------- src/internal/naive_policy_checker.hpp | 3 +-- src/internal/naive_policy_db.cpp | 7 +++---- src/internal/naive_policy_db.hpp | 4 +--- src/internal/policy.cpp | 6 ++---- src/internal/policy.hpp | 17 ++++++++++++----- src/internal/xml_parser.hpp | 8 ++++---- src/libdbuspolicy1.c | 14 +++++++++++--- 10 files changed, 49 insertions(+), 50 deletions(-) diff --git a/configure.ac b/configure.ac index 3a0e44f..9c5aa73 100644 --- a/configure.ac +++ b/configure.ac @@ -74,21 +74,15 @@ AC_CHECK_FUNCS([ \ my_CFLAGS="\ -Wall \ --Wchar-subscripts \ --Wformat-security \ --Wmissing-declarations \ --Wmissing-prototypes \ --Wnested-externs \ --Wpointer-arith \ --Wshadow \ --Wsign-compare \ --Wstrict-prototypes \ --Wtype-limits \ +-Wextra \ +-Werror \ " AC_SUBST([my_CFLAGS]) my_CXXFLAGS="\ -Wall \ +-Wextra \ +-Werror \ -std=c++11 \ " diff --git a/src/internal/cynara_mockup.cpp b/src/internal/cynara_mockup.cpp index 520761f..8b701cd 100644 --- a/src/internal/cynara_mockup.cpp +++ b/src/internal/cynara_mockup.cpp @@ -23,5 +23,8 @@ Cynara& Cynara::getInstance() { CynaraResult Cynara::check(const char* label, const char* privilege, const char* uid) { + (void)label; + (void)privilege; + (void)uid; return CynaraResult::ALLOW; } diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index 71ab8c1..f136fa4 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -13,14 +13,7 @@ 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 <checkItemOwn(bus_type, uid, gid, label, name, ItemType::OWN); + return this->checkItemOwn(bus_type, uid, gid, label, name); } DecisionResult NaivePolicyChecker::check(bool bus_type, @@ -133,7 +126,7 @@ Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& poli assert(node); Decision ret = Decision::ANY; while ((name != NULL) && (*name != '\0')) { - childIndex = char_map[*name]; + childIndex = char_map[static_cast(*name)]; if (childIndex > 64) { /* name contains forbidden char */ if (tslog::verbose()) { @@ -164,25 +157,25 @@ Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& poli return node->__decisionItem.getDecision(); } -DecisionResult NaivePolicyChecker::checkItemOwn(bool bus_type, uid_t uid, gid_t gid, const char* label, const ItemOwn& item, const ItemType type) { +DecisionResult NaivePolicyChecker::checkItemOwn(bool bus_type, uid_t uid, gid_t gid, const char* label, const ItemOwn& item) { 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)) + if (policy_db.getPolicy(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)) + if (policy_db.getPolicy(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)) + if (policy_db.getPolicy(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)) + if (policy_db.getPolicy(PolicyType::CONTEXT, PolicyTypeValue(ContextType::DEFAULT), curr_policy)) ret = checkPolicyOwn(*curr_policy, item, privilege); } if (ret != Decision::ANY) { diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index b80c23f..8504a14 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -114,8 +114,7 @@ namespace ldp_xml_parser uid_t uid, gid_t gid, const char* label, - const ItemOwn& item, - const ItemType type); + const ItemOwn& item); public: ~NaivePolicyChecker(); diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index a796660..8a10c80 100644 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -75,8 +75,7 @@ void NaivePolicyDb::addItem(const PolicyType policy_type, -bool NaivePolicyDb::getPolicy(const ItemType item_type, - const PolicyType policy_type, +bool NaivePolicyDb::getPolicy(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); @@ -194,7 +193,7 @@ void NaivePolicyDb::PolicyOwn::addItem(ItemOwn* item) { const char *tmp = name; while (tmp && *tmp != '\0') { - if (char_map[*tmp] > 64) { + if (char_map[static_cast(*tmp)] > 64) { /* Forbidden char */ return; } @@ -202,7 +201,7 @@ void NaivePolicyDb::PolicyOwn::addItem(ItemOwn* item) { } int childIndex = 0; while (name && *name != '\0') { - childIndex = char_map[*name]; + childIndex = char_map[static_cast(*name)]; if (node->children[childIndex] == NULL) { node->children[childIndex] = new struct TreeNode; node->children[childIndex]->__decisionItem = {Decision::ANY, NULL}; diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp index 5efd301..161d24c 100644 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -103,14 +103,12 @@ namespace ldp_xml_parser ~NaivePolicyDb(); /** Gets policy with ownership rules from DB - * \param[in] item_type Item Type * \param[in] policy_type Policy type * \param[in] policy_type_value Policy type value * \param[out] policy Received policy * \return True if there is such policy, false elsewhere */ - bool getPolicy(const ItemType item_type, - const PolicyType policy_type, + bool getPolicy(const PolicyType policy_type, const PolicyTypeValue policy_type_value, const PolicyOwn*& policy) const; diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index 9a0a99c..5089349 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -285,7 +285,7 @@ bool MatchItemSR::addNames(const char* name) { char c; int len; j = i; - if (tslog::verbose() && !(name[i] >= 'a'&& name[i] <= 'z') || (name[i] >= 'A'&& name[i] <= 'Z') || (name[i] >= '0'&& name[i] <= '9') || name[i] == ' ') { + if (tslog::verbose() && !((name[i] >= 'a'&& name[i] <= 'z') || (name[i] >= 'A'&& name[i] <= 'Z') || (name[i] >= '0'&& name[i] <= '9') || name[i] == ' ')) { std::cout<<"Wrong name("< incl_files; - err = parse(bus, true, filename, incl_files); + err = parse(bus, filename, incl_files); if (err.is_ok()) for (const auto& x : incl_files) { - err = parse(bus, false, x, incl_files); + err = parse(bus, x, incl_files); if (err.is_error()) break; } return err; } /** Parses given xml file and files included in it */ - ErrCode parse(bool bus, bool first, const std::string& filename, std::vector& included_files) { + ErrCode parse(bool bus, 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, incl_dirs); - for (int i = 0; i < incl_dirs.size(); i++) { + for (unsigned i = 0; i < incl_dirs.size(); i++) { getIncludedFiles(filename, incl_dirs[i], included_files); } diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index b6c35a9..1721185 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -82,7 +82,7 @@ static int kdbus_hello(bool bus_type, uint64_t hello_flags, uint64_t attach_flag { struct kdbus_cmd_hello* cmd; struct kdbus_cmd_free cmd_free; - volatile struct kdbus_item* item; + struct kdbus_item* item; int fd = g_conn[bus_type].fd; int size = ALIGN8(sizeof(struct kdbus_cmd_hello)) + ALIGN8(offsetof(struct kdbus_item, data) + sizeof(CONNECTION_LABEL)); @@ -280,6 +280,7 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) #ifdef LIBDBUSPOLICY_TESTS_API DBUSPOLICY1_EXPORT void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label) { + (void)configuration; g_udesc.uid = uid; g_udesc.gid = gid; if (label) @@ -300,6 +301,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, int reply_serial, int requested_reply) { + (void)error_name; + (void)reply_serial; + (void)requested_reply; + char const *label = NULL; const char* k_names[KDBUS_CONN_MAX_NAMES+1]; int k_i = 0; @@ -373,8 +378,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, break; case KDBUS_ITEM_OWNED_NAME: empty_names = false; - if (r <= 0) - k_names[k_i++] = item->name.name; + k_names[k_i++] = item->name.name; break; } } @@ -413,6 +417,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, int reply_serial, int requested_reply) { + (void)error_name; + (void)reply_serial; + (void)requested_reply; + int r; bool bus_type = configuration_bus_type(configuration); -- 2.7.4 From 4dedf324a83b658ff20ebd27f687bc2f1a36ab93 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Mon, 24 Oct 2016 18:06:43 +0200 Subject: [PATCH 05/16] Remove a redundant line Change-Id: Ic41712669be7b626c0eee19a0177b45b495f21d0 Signed-off-by: Michal Bloch (cherry picked from commit a4e6142895b50cc6faf03670a579e48696b5bb9c) --- Makefile.am | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index a46bb38..30eec82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -91,8 +91,6 @@ src_libinternal_a_SOURCES =\ src/internal/tslog.cpp \ src/internal/cynara_mockup.cpp -libinternal_a_LIBADD = $(CYNARA_LIBS) - src_test_libdbuspolicy1_ownership_LDADD = $(CYNARA_LIBS) \ src/libinternal.a -- 2.7.4 From 19512268ab20711d4a8b06385f4d636b84d47405 Mon Sep 17 00:00:00 2001 From: Krystian Kisielak Date: Fri, 2 Sep 2016 15:40:41 +0200 Subject: [PATCH 06/16] Removes file xml_policy.hpp. It is part of old implementation and is no longer used. Change-Id: Ife804864f767ddd92a979e983cd45164e89c6315 Signed-off-by: Krystian Kisielak (cherry picked from commit 9cce1d8723e29a83db77f1d90d8fac74f19eb6cc) --- src/internal/xml_policy.hpp | 570 -------------------------------------------- 1 file changed, 570 deletions(-) delete mode 100644 src/internal/xml_policy.hpp diff --git a/src/internal/xml_policy.hpp b/src/internal/xml_policy.hpp deleted file mode 100644 index 2e790ed..0000000 --- a/src/internal/xml_policy.hpp +++ /dev/null @@ -1,570 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef _XML_POLICY_HPP -#define _XML_POLICY_HPP - -#include -#include -#include -#include -#include "libdbuspolicy1-private.hpp" -#include "tslog.hpp" -#include "cynara.hpp" - -enum class TreeType : uint8_t { - SEND, - RECV, - OWN -}; - -namespace ldp_xml_parser -{ - namespace { - static const std::string ROOT_FIELD = "busconfig"; - static const std::string ROOT_POLICY = "policy"; - } //namespace - - class XmlPolicy : boost::noncopyable - { - enum class CtxType { DEFAULT, SPECIFIC, MANDATORY }; - - class Key { - public: - static constexpr const char* ANY = "__"; - static constexpr const char* MRY = "!!"; - static constexpr const char* DEF = "??"; - static constexpr const char DELIM = '\\'; - static const size_t IDX_USER = 0; - static const size_t IDX_GROUP = 1; - static const size_t IDX_DEST = 2; - static const size_t IDX_SENDER = IDX_DEST; - static const size_t IDX_SERVICE = IDX_DEST; - static const size_t IDX_PATH = 3; - static const size_t IDX_IFACE = 4; - static const size_t IDX_MEMBER = 5; - static const size_t IDX_TYPE = 6; - - static const size_t IDX_TOTAL_LENGTH = IDX_TYPE + 1; - static const size_t IDX_OWN_LENGTH = IDX_SERVICE + 1; - static const size_t IDX_DEFAULT = IDX_GROUP + 1; - - std::vector m_path_content; - std::string m_privilege; - bool m_bsend; - bool m_brecv; - bool m_bown; - bool m_bcheck; - bool m_ballow; - static size_t m_weight; - - Key(bool bus) - : m_path_content(std::vector(IDX_TOTAL_LENGTH, ANY)), - m_bsend(false), - m_brecv(false), - m_bown(false), - m_bcheck(false), - m_ballow(false) {} - - ~Key() {} - - void reset_attributes() { - m_bsend = m_brecv = m_bown = m_bcheck = m_ballow = false; - std::fill(m_path_content.begin() + IDX_DEFAULT, m_path_content.end(), ANY); - } - - const std::string get_path() const { - std::string path = "R"; - auto it_cend = m_bown ? m_path_content.cbegin() + IDX_OWN_LENGTH : m_path_content.cend(); - for(auto it = m_path_content.cbegin(); it != it_cend; ++it) - (path += Key::DELIM) += *it; - return path; - } - }; - - class Leaf { - bool m_decision; - bool m_check; - std::string m_privilege; - size_t m_weight; - - public: - Leaf() : m_decision(false), m_check(false), m_privilege(""), m_weight(0) {}; - - Leaf(bool decision, bool check, const std::string& privilege, size_t weight) - : m_decision(decision), m_check(check), m_privilege(privilege), m_weight(weight) {} - - bool get_decision() const { - return m_decision; - } - - bool get_check() const { - return m_check; - } - - const std::string& get_privilege() const { - return m_privilege; - } - - size_t get_weight() const { - return m_weight; - } - - friend std::ostream& operator<<(std::ostream& os, const Leaf& lf) { - if(lf.m_check) - os << "check," << lf.m_privilege << "," << lf.m_weight; - else - os << (lf.m_decision ? "true" : "false") << "," << lf.m_weight; - return os; - } - - friend std::istream& operator>>(std::istream& is, Leaf& lf) { - std::string s; - is >> s; - boost::char_separator sep(","); - boost::tokenizer> tokens(s, sep); - const auto size = std::distance(tokens.begin(), tokens.end()); - for(auto it = tokens.begin(); it != tokens.end(); ++it) { - const auto it_last = std::next(tokens.begin(), size - 1); - if(it == tokens.begin()) { - if(size > 2) - lf.m_check = (*it == "check") ? true : false; - else - lf.m_decision = (*it == "true") ? true : false; - } else if(it == it_last) - lf.m_weight = std::stoul(*it); - else if(size > 2) - lf.m_privilege = *it; - } - return is; - } - }; - - static char const *get_context_str(const CtxType& ctx_type) { - switch(ctx_type) { - case CtxType::DEFAULT: return "(default)"; break; - case CtxType::SPECIFIC: return "(specific)"; break; - case CtxType::MANDATORY: return "(mandatory)"; break; - default: return ""; break; - } - } - - static const std::string get_field_str(const std::string& field) { - return field == "" ? Key::ANY : field; - } - - //Data obtained from XML parsing - decision trees - boost::property_tree::ptree m_dec_trees[2][3]; - - boost::property_tree::ptree &get_decision_tree(bool bus, TreeType tree_type) { - return m_dec_trees[bus][static_cast(tree_type)]; - } - - boost::property_tree::ptree* get_decision_tree(bool bus, const Key& key) { - TreeType tree_type; - if(key.m_bsend) tree_type = TreeType::SEND; - else if(key.m_brecv) tree_type = TreeType::RECV; - else if(key.m_bown) tree_type = TreeType::OWN; - else return NULL; - - return &get_decision_tree(bus, tree_type); - } - - void print_decision_tree(const boost::property_tree::ptree& pt, int level = 0) { - for(const auto& v : pt) { - print_field(v, level); - print_decision_tree(v.second, level + 1); - } - } - - void print_decision_key(bool bus, const Key& key) { - if (tslog::verbose()) { - std::string s = bus + " "; - if(key.m_bsend && !key.m_brecv) s += "--> #"; - if(!key.m_bsend && key.m_brecv) s += "<-- #"; - if(!key.m_bsend && !key.m_brecv && key.m_bown) s += "OWN #"; - std::string prv = key.m_bcheck ? key.m_privilege : ""; - std::cout << s - << (key.m_bcheck ? "check " : std::to_string(key.m_ballow)) - << prv - << " : " - << key.get_path() - << " (weight: " - << key.m_weight - << ")\n"; - } - } - - void update_decision_tree(bool bus, const Key& key) { - if(!key.get_path().empty()) { - print_decision_key(bus, key); - - //update - boost::property_tree::ptree* const p_tree = get_decision_tree(bus, key); - if(p_tree) { - boost::property_tree::ptree::path_type tpath(key.get_path(), Key::DELIM); - p_tree->put(tpath, Leaf(key.m_ballow, key.m_bcheck, key.m_privilege, key.m_weight)); - } - } - } - - void update_decision_path(const boost::property_tree::ptree::value_type& v, - Key& key, - CtxType& current_ctx, - bool& allden, - bool& bcheck, - bool& attr) { - if(v.first == "allow") { - allden = true; - bcheck = false; - attr = false; - key.reset_attributes(); - } else if(v.first == "deny") { - allden = false; - bcheck = false; - attr = false; - key.reset_attributes(); - } else if(v.first == "check") { - allden = false; - bcheck = true; - attr = false; - key.reset_attributes(); - } else if(v.first == "") { - attr = true; - ++key.m_weight; - } else { - if(attr) { - std::string data_str = v.second.data() == "*" ? Key::ANY : v.second.data(); - if(v.first == "context") { - if(data_str == "mandatory") { - key.m_path_content[Key::IDX_USER] = Key::MRY; - key.m_path_content[Key::IDX_GROUP] = Key::MRY; - current_ctx = CtxType::MANDATORY; - } else if(data_str == "default") { - key.m_path_content[Key::IDX_USER] = Key::DEF; - key.m_path_content[Key::IDX_GROUP] = Key::DEF; - current_ctx = CtxType::DEFAULT; - } - } else if(v.first == "user") { - if(current_ctx == CtxType::SPECIFIC) - key.m_path_content[Key::IDX_USER] = data_str; - } else if(v.first == "group") { - if(current_ctx == CtxType::SPECIFIC) - key.m_path_content[Key::IDX_GROUP] = data_str; - } else { - if(field_has(v, "send_")) - key.m_bsend = true; - if(field_has(v, "receive_")) - key.m_brecv = true; - if(v.first == "own") { - key.m_bown = true; - key.m_path_content[Key::IDX_SERVICE] = data_str; - } - if(v.first == "own_prefix") { - key.m_bown = true; - key.m_path_content[Key::IDX_SERVICE] = data_str + "*"; - } - if(field_has(v, "_destination")) - key.m_path_content[Key::IDX_DEST] = data_str; - if(field_has(v, "_sender")) - key.m_path_content[Key::IDX_SENDER] = data_str; - if(field_has(v, "_path")) - key.m_path_content[Key::IDX_PATH] = data_str; - if(field_has(v, "_interface")) - key.m_path_content[Key::IDX_IFACE] = data_str; - if(field_has(v, "_member")) - key.m_path_content[Key::IDX_MEMBER] = data_str; - if(field_has(v, "_type")) - key.m_path_content[Key::IDX_TYPE] = data_str; - if(v.first == "privilege") - key.m_privilege = data_str; - - key.m_bcheck = bcheck; - key.m_ballow = allden; - } - } - } - } - - bool field_has(const boost::property_tree::ptree::value_type& v, const std::string& substr) { - return (v.first.find(substr) != std::string::npos); - } - - void print_field(const boost::property_tree::ptree::value_type& v, int level) { - std::cout << ((level > 0) ? std::string((level - 1) * 8, ' ') + std::string(8, '.') : "") - << v.first - << " : " - << v.second.data() - << '\n'; - } - - void xml_traversal(bool bus, - const boost::property_tree::ptree& pt, - Key& key, - CtxType& current_ctx, - bool allden = false, - bool bcheck = false, - bool attr = false, - int level = 0) { - static const int Q_XML_MAX_LEVEL = 10; - - if(level < Q_XML_MAX_LEVEL) { - for(const auto& v : pt) { - if(v.first == "") { continue; } - - update_decision_path(v, key, current_ctx, allden, bcheck, attr); - //if (tslog::verbose()) print_field(v, level); - xml_traversal(bus, v.second, key, current_ctx, allden, bcheck, attr, level + 1); - } - - if(!pt.empty() && attr && level > 1) - update_decision_tree(bus, key); - } else if (tslog::enabled()) - std::cout << "XML traversal max level reached: " << level << '\n'; - } - - void print_indexing_path(size_t idx, const std::string& path, const Leaf& leaf = Leaf(), bool empty = true) { - if (tslog::verbose()) { - std::string s; - if(!empty) { - s = " : <"; - s += (leaf.get_check() - ? std::string("check: ") + std::to_string(leaf.get_check()) + ", privilege: " + leaf.get_privilege() - : std::string("decision: ") + std::to_string(leaf.get_decision())); - s += (std::string(", weight: ") + std::to_string(leaf.get_weight())); - s += std::string(">"); - } - - std::cout << "path #" - << idx - << " : " - << path - << s - << '\n'; - } - } - - void prepare_indexing_path(const std::vector& idx_v, - size_t pattern, - const size_t usrgrp_obfuscate_order, - const bool obfuscate_params, - const CtxType& ctx_type, - std::string& path) { - - constexpr size_t offset = Key::IDX_DEFAULT; - path = "R"; - - if(ctx_type == CtxType::SPECIFIC) { - path += Key::DELIM; - if (usrgrp_obfuscate_order & 1) // 1 3 - path += Key::ANY; - else - path += get_field_str(idx_v[Key::IDX_USER]); - path += Key::DELIM; - if ((usrgrp_obfuscate_order+1) & 2) // 1 2 - path += get_field_str(idx_v[Key::IDX_GROUP]); - else - path += Key::ANY; - } else - for(size_t i = 0; i < offset; ++i) - (path += Key::DELIM) += ctx_type == CtxType::MANDATORY ? Key::MRY : Key::DEF; - - const size_t n = idx_v.size() - offset; - for (size_t i = 0; i < n; ++i) { - path += Key::DELIM; - if (obfuscate_params && pattern & 1) - path += Key::ANY; - else - path += get_field_str(idx_v[i + offset]); - pattern >>= 1; - } - } - - ErrCode service_leaf_found(const Leaf& leaf, const std::string& label, const std::vector& idx_v) { - ErrCode err; - if(leaf.get_check()) { - if (tslog::verbose()) - std::cout << __func__ - << ": cynara check needed for privilege " << leaf.get_privilege() - << ", weight " << leaf.get_weight() - << '\n'; - - //cynara check - try { - bool br = _ldp_cynara::Cynara::check(label, leaf.get_privilege(), idx_v[Key::IDX_USER]); - err = ErrCode::ok(br); - } catch(const std::runtime_error& ex) { - err = ErrCode::error(ex.what()); - } - } else { - err = ErrCode::ok(leaf.get_decision()); - } - - return err; - } - - ErrCode index_decision_tree(const boost::property_tree::ptree& pt, - const std::vector& idx_v, - const std::string& label, - const bool obfuscate_params, - const CtxType& ctx_type) { - ErrCode err; - bool found = false; - size_t weight = 0; - const size_t offset = Key::IDX_DEFAULT; - const size_t m = (ctx_type == CtxType::SPECIFIC) ? (1 << offset) : 1; - for(size_t usrgrp_ob_or = 0; usrgrp_ob_or < m; ++usrgrp_ob_or) { - Leaf leaf_found; - const size_t n = 1 << (idx_v.size() - offset); - for(size_t p = 0; p < n; ++p) { - std::string path; - try { - prepare_indexing_path(idx_v, p, usrgrp_ob_or, obfuscate_params, ctx_type, path); - boost::property_tree::ptree::path_type tpath(path, Key::DELIM); - - auto dec = pt.get(tpath); - - print_indexing_path(p, path, dec, false); - found = true; - if(dec.get_weight() >= weight) { - weight = dec.get_weight(); - leaf_found = dec; - } - } catch(const boost::property_tree::ptree_error& ex) { - //Path doesn't exist, continue - print_indexing_path(p, path); - if(!found) { err = ErrCode::error("No path"); } - } catch(...) { - print_indexing_path(p, path); - if (tslog::verbose()) - std::cout << "Unknown exception while indexing decision tree!\n"; - if(!found) { err = ErrCode::error("Unknown err, no path"); } - } - } - - if(found) { - err = service_leaf_found(leaf_found, label, idx_v); - if (tslog::verbose()) - std::cout << __func__ << ": returning decision #" << err.get() << " " << err.get_str() << ", weight " << leaf_found.get_weight() << '\n'; - break; - } - } - - return err; - } - - ErrCode index_decision_tree_lat(const boost::property_tree::ptree& pt, - const std::vector& idx_v, - const std::string& label, - const bool obfuscate_params, - const CtxType& ctx_type) { - ErrCode err; - - if (tslog::enabled()) { - std::cout << "context: " << get_context_str(ctx_type) << ", indexing arguments: "; - std::copy(idx_v.begin(), idx_v.end(), std::ostream_iterator(std::cout, ", ")); - std::cout << '\n'; - } - - //Examine policy data and make decision - err = index_decision_tree(pt, idx_v, label, obfuscate_params, ctx_type); - - if (tslog::enabled()) - std::cout << __func__ << ": #" << err.get() << " " << err.get_str() << " " << get_context_str(ctx_type) << '\n'; - return err; - } - - ErrCode can_do_action(bool bus, - TreeType tree_type, - const std::vector& idx_v, - const std::string& label = "", - const bool analyze_prefix = false) { - ErrCode err; - boost::property_tree::ptree const &p_tree = get_decision_tree(bus, tree_type); - err = index_decision_tree_lat(p_tree, idx_v, label, !analyze_prefix, CtxType::MANDATORY); - if(!err.is_ok()) { - err = index_decision_tree_lat(p_tree, idx_v, label, !analyze_prefix, CtxType::SPECIFIC); - if(!err.is_ok()) - err = index_decision_tree_lat(p_tree, idx_v, label, !analyze_prefix, CtxType::DEFAULT); - } - if (tslog::enabled()) - std::cout << __func__ << ": #" << err.get() << " " << err.get_str() << '\n'; - return err; - } - - public: - XmlPolicy() { - Key::m_weight = 0; - } - - void update(bool bus, const boost::property_tree::ptree& pt) { - const auto& children = pt.get_child(ROOT_FIELD); - for(const auto& x : children) { - if(x.first == ROOT_POLICY) { - Key key(bus); - CtxType current_ctx = CtxType::SPECIFIC; - xml_traversal(bus, x.second, key, current_ctx); - } - } - } - - ErrCode can_send_to(bool bus, const std::vector& idx_v, const std::string label) { - return can_do_action(bus, TreeType::SEND, idx_v, label); - } - - ErrCode can_recv_from(bool bus, const std::vector& idx_v, const std::string label) { - return can_do_action(bus, TreeType::RECV, idx_v, label); - } - - ErrCode can_own_what(bool bus, const std::vector& idx_v) { - ErrCode err; - - //Evaluate own_prefix - std::vector iv = idx_v; - const std::string srv = iv[iv.size() - 1]; - const size_t srv_size = srv.size(); - for(size_t n = 1; n <= srv_size; ++n) { - const std::string sub = srv.substr(0, n) + "*"; - if (tslog::enabled()) - std::cout << "own_prefix: " << sub << '\n'; - iv.pop_back(); - iv.push_back(sub); - err = can_do_action(bus, TreeType::OWN, iv, "", true); - if(err.is_ok()) - break; - } - - //Evaluate own - if(err.is_error()) - err = can_do_action(bus, TreeType::OWN, idx_v); - - return err; - } - - void print_decision_trees(bool bus) { - if (tslog::verbose()) - for (unsigned i = 0; i < TABSIZE(m_dec_trees[bus]); ++i) - for(auto const& y : m_dec_trees[bus][i]) { - std::cout << i << " " << y.first << " " << (y.second.empty() ? "(empty)" : "") << '\n'; - print_decision_tree(y.second); - } - } - - }; //XmlPolicy - size_t XmlPolicy::Key::m_weight = 0; -} //namespace - -#endif -- 2.7.4 From 596937f8c0f92a311d93117627e583631ceced91 Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Mon, 7 Nov 2016 13:43:48 +0100 Subject: [PATCH 07/16] remove unused PolicyIterator Change-Id: I06de62c3359186b094b51def7beff47752bfa998 (cherry picked from commit b9c833dbfa425b51f93feff09a827b4222bb7820) --- src/internal/naive_policy_checker.cpp | 4 ++-- src/internal/naive_policy_db.cpp | 37 ++--------------------------------- src/internal/naive_policy_db.hpp | 23 ++++------------------ 3 files changed, 8 insertions(+), 56 deletions(-) diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index f136fa4..5ebaac1 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -135,12 +135,12 @@ Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& poli privilege = NULL; return Decision::DENY; } - /* Current node is prefix, remeber decision */ + /* Current node is prefix, remember decision */ if (node->__is_prefix) { ret = node->__decisionItem.getDecision(); privilege = node->__decisionItem.getPrivilege(); } - /* Node for this letter dont exist */ + /* Node for this letter don't exist */ if (node->children[childIndex] == NULL) { if(ret != Decision::ANY) return ret; diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index 8a10c80..74783d2 100644 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -96,11 +96,11 @@ bool NaivePolicyDb::getPolicy(const ItemType item_type, } -NaivePolicyDb::PolicySR::PolicyConstIterator::PolicyConstIterator(const std::vector< ItemSendReceive* > & items, int position) +NaivePolicyDb::PolicySR::PolicyConstIterator::PolicyConstIterator(const std::vector< ItemSendReceive const *> & items, int position) : m_items(items), m_index(position) { } -ItemSendReceive* const& NaivePolicyDb::PolicySR::PolicyConstIterator::operator*() const { +ItemSendReceive const *const& NaivePolicyDb::PolicySR::PolicyConstIterator::operator*() const { return m_items[m_index]; } @@ -117,39 +117,6 @@ bool NaivePolicyDb::PolicySR::PolicyConstIterator::operator!=(const PolicyConstI } -NaivePolicyDb::PolicySR::PolicyIterator::PolicyIterator(std::vector< ItemSendReceive* > & items, int position) - : m_items(items), m_index(position) { -} - - -ItemSendReceive*& NaivePolicyDb::PolicySR::PolicyIterator::operator*() { - return m_items[m_index]; -} - - -typename NaivePolicyDb::PolicySR::PolicyIterator& NaivePolicyDb::PolicySR::PolicyIterator::operator++() { - if (m_index >= 0) - --m_index; - return *this; -} - - -bool NaivePolicyDb::PolicySR::PolicyIterator::operator!=(const PolicyIterator& it) const { - return m_index != it.m_index; -} - - -NaivePolicyDb::PolicySR::PolicyIterator NaivePolicyDb::PolicySR::begin() { - int s = m_items.size() - 1; - return NaivePolicyDb::PolicySR::PolicyIterator(m_items, s); -} - - -NaivePolicyDb::PolicySR::PolicyIterator NaivePolicyDb::PolicySR::end() { - return NaivePolicyDb::PolicySR::PolicyIterator(m_items, -1); -} - - NaivePolicyDb::PolicySR::PolicyConstIterator NaivePolicyDb::PolicySR::begin() const { int s = m_items.size() - 1; return NaivePolicyDb::PolicySR::PolicyConstIterator(m_items, s); diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp index 161d24c..7162d91 100644 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -35,38 +35,23 @@ namespace ldp_xml_parser class PolicySR { private: /** Vector with policy items */ - std::vector m_items; + std::vector m_items; public: /** Iterator used to get access to policy items */ class PolicyConstIterator { private: /** Vector with policy items */ - const std::vector& m_items; + const std::vector& m_items; /** Assistant iterator */ int m_index; public: /** Public method allowing access to policy items */ - PolicyConstIterator(const std::vector& items, int position); - ItemSendReceive* const& operator*() const; + PolicyConstIterator(const std::vector& items, int position); + ItemSendReceive const *const& operator*() const; PolicyConstIterator& operator++(); bool operator!=(const PolicyConstIterator& it) const; }; - /** Iterator used to get access to policy items */ - class PolicyIterator { - private: - /** Vector with policy items */ - std::vector& m_items; - /** Assistant iterator */ - int m_index; - public: - PolicyIterator(std::vector& items, int position); - ItemSendReceive*& operator*(); - PolicyIterator& operator++(); - bool operator!=(const PolicyIterator& it) const; - }; - PolicyIterator begin(); - PolicyIterator end(); PolicyConstIterator begin() const; PolicyConstIterator end() const; -- 2.7.4 From 1549df0b26957a918dea2a1c94ee6f410f88dab0 Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Mon, 7 Nov 2016 17:05:44 +0100 Subject: [PATCH 08/16] turn DbAdapter into direct member of XmlParser Change-Id: Ic807550cabd2cad3177c35a6af14d142b29eaf0b (cherry picked from commit 1c8bd17ca32a21ca16f2bf625fe788eacf2e0a72) --- src/internal/internal.cpp | 3 --- src/internal/naive_policy_checker.cpp | 13 +++---------- src/internal/naive_policy_checker.hpp | 16 ++++++++-------- src/internal/policy.cpp | 16 ++++++---------- src/internal/policy.hpp | 6 +----- src/internal/xml_parser.hpp | 10 +++------- 6 files changed, 21 insertions(+), 43 deletions(-) diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index 1445f7b..12c54fa 100644 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -28,8 +28,6 @@ #include "../libdbuspolicy1-private.h" -static ldp_xml_parser::NaivePolicyChecker policy_checker; - static const char* get_str(const char* const szstr) { return (szstr != NULL) ? szstr : ""; } @@ -37,7 +35,6 @@ static const char* get_str(const char* const szstr) { int __internal_init(bool bus_type, const char* const config_name) { ldp_xml_parser::XmlParser p; - p.registerAdapter(policy_checker.generateAdapter()); auto err = p.parsePolicy(bus_type, get_str(config_name)); return err.get(); } diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index 5ebaac1..2fd0b4a 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -9,6 +9,8 @@ using namespace ldp_xml_parser; +ldp_xml_parser::NaivePolicyChecker policy_checker; + static void __log_item(const MatchItemSR& item) { char tmp[MAX_LOG_LINE]; @@ -16,12 +18,6 @@ static void __log_item(const MatchItemSR& item) std::cout << "checkpolicy for: " << i_str <checkItemSR(bus_type, uid, gid, label, matcher, type); } + Decision NaivePolicyChecker::checkPolicySR(const NaivePolicyDb::PolicySR& policy, const MatchItemSR& item, const char*& privilege) diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index 8504a14..3471cae 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -37,9 +37,6 @@ namespace ldp_xml_parser /** Policy databases for system and session bus */ NaivePolicyDb m_bus_db[2]; - /** Adapter to policies database */ - DbAdapter* m_adapter; - /** Retrieves policy db * \param[in] type Type of database (system/session bus) * \return Returns reference to chosen bus policy db @@ -115,14 +112,14 @@ namespace ldp_xml_parser gid_t gid, const char* label, const ItemOwn& item); - public: - ~NaivePolicyChecker(); - /** Generates adapter for db with policies - * \ingroup Implementation + /** Provides db handle for parsing purposes */ - DbAdapter& generateAdapter(); + inline NaivePolicyDb &db(bool sessionBus) { return m_bus_db[sessionBus]; } + + friend class DbAdapter; // give adapters access to db() + public: /** Checks ownership policy for given item * \param[in] bus_type Bus type (system/session) * \param[in] uid User id @@ -156,4 +153,7 @@ namespace ldp_xml_parser ItemType type); }; } + +extern ldp_xml_parser::NaivePolicyChecker policy_checker; + #endif diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index 5089349..752750f 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -4,6 +4,7 @@ */ #include "policy.hpp" +#include "naive_policy_checker.hpp" #include "naive_policy_db.hpp" #include "tslog.hpp" #include @@ -42,11 +43,10 @@ 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) { +DbAdapter::DbAdapter() : __attr(false), __tag_state(NONE) { } -uid_t DbAdapter::convertToUid(const char* user) { +static uid_t convertToUid(const char* user) { long val = -1; errno = 0; val = std::strtol(user, NULL, 10); @@ -64,7 +64,7 @@ uid_t DbAdapter::convertToUid(const char* user) { return pwd->pw_uid; } -gid_t DbAdapter::convertToGid(const char* group) { +static gid_t convertToGid(const char* group) { long val = -1; errno = 0; val = std::strtol(group, NULL, 10); @@ -182,12 +182,8 @@ 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) { - 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) + __builder.generateItem(policy_checker.db(bus), policy_type, policy_type_value); } } diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp index de8619a..5f4d84f 100644 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -247,8 +247,6 @@ namespace ldp_xml_parser POLICY, ALLOW_DENY_CHECK }; - NaivePolicyDb& __system_db; - NaivePolicyDb& __session_db; bool __attr; state __tag_state; ItemBuilder __builder; @@ -265,10 +263,8 @@ namespace ldp_xml_parser bool attr = false, int level = 0); public: - DbAdapter(NaivePolicyDb& system, NaivePolicyDb& session); + DbAdapter(); 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); }; } #endif diff --git a/src/internal/xml_parser.hpp b/src/internal/xml_parser.hpp index 6582479..f874320 100644 --- a/src/internal/xml_parser.hpp +++ b/src/internal/xml_parser.hpp @@ -43,17 +43,13 @@ namespace ldp_xml_parser ErrCode err = parse(bus, fname); return err; } - /** Registers DBAdapter */ - void registerAdapter(DbAdapter& adapter) { - __adapter = &adapter; - } private: /** Vector containing parsed policy */ static std::set __parsed; - /** Adapter which allows to acces parsed policies */ - DbAdapter* __adapter; + /** Adapter which allows to access parsed policies */ + DbAdapter __adapter; /** Parses config file and all files included in it */ ErrCode parse(bool bus, std::string const &filename) { @@ -125,7 +121,7 @@ namespace ldp_xml_parser boost::property_tree::ptree pt; read_xml(filename, pt); if (!pt.empty()) { - __adapter->updateDb(bus, pt, incl_dirs); + __adapter.updateDb(bus, pt, incl_dirs); } } catch (const boost::property_tree::xml_parser::xml_parser_error& ex) { ret.first = ErrCode::error(ex.what()); -- 2.7.4 From cc6c4ae57015ac860c7eddddedfa6a804c2c29ab Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Mon, 7 Nov 2016 19:03:53 +0100 Subject: [PATCH 09/16] circumvent destruction of ::policy_checker, remove destructors that are empty or never called Motivated by KONA bugs (ex. DF161028-00875). VD product environment apparently likes calling libdbuspolicy1 public functions while exit handlers are being called (and thus global objects are being destroyed). Solution: circumvent destruction of relevant globals altogether. Change-Id: Ibeab05ed83cc24dc6a5da926fb542f31d8a33af1 (cherry picked from commit 1e961ec457d48198118bbff42204d668d714bccb) --- src/internal/internal.cpp | 8 ++++---- src/internal/naive_policy_checker.cpp | 2 +- src/internal/naive_policy_checker.hpp | 14 +++++++++++++- src/internal/naive_policy_db.cpp | 7 ------- src/internal/naive_policy_db.hpp | 3 --- src/internal/policy.cpp | 5 +---- src/internal/policy.hpp | 1 - 7 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp index 12c54fa..fb2676f 100644 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -82,7 +82,7 @@ int __internal_can_send(bool bus_type, std::cout << "Destination too long: " << destination << std::endl; return false; } - 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, matcher, ldp_xml_parser::ItemType::SEND)); } int __internal_can_send_multi_dest(bool bus_type, @@ -101,7 +101,7 @@ int __internal_can_send_multi_dest(bool bus_type, 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, matcher, ldp_xml_parser::ItemType::SEND)); } int __internal_can_recv(bool bus_type, @@ -120,7 +120,7 @@ int __internal_can_recv(bool bus_type, 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)); + return static_cast(policy_checker().check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::RECEIVE)); } int __internal_can_own(bool bus_type, @@ -129,5 +129,5 @@ int __internal_can_own(bool bus_type, const char* const label, const char* const service) { - return static_cast(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 2fd0b4a..0c7cb71 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -9,7 +9,7 @@ using namespace ldp_xml_parser; -ldp_xml_parser::NaivePolicyChecker policy_checker; +DEF_NODESTRUCT_GLOBAL(ldp_xml_parser::NaivePolicyChecker, policy_checker) static void __log_item(const MatchItemSR& item) { diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index 3471cae..2e330ee 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -154,6 +154,18 @@ namespace ldp_xml_parser }; } -extern ldp_xml_parser::NaivePolicyChecker policy_checker; +/** Declare a global variable that is constructed (via gcc's __attribute__((constructor))) but never destroyed. */ +#define DCL_NODESTRUCT_GLOBAL(TYPE,NAME)\ + namespace detail_NODESTRUCT_GLOBAL { alignas(TYPE) extern uint8_t NAME[sizeof(TYPE)]; }\ + /* awkwardly written to silence gcc's -Wstrict-aliasing because _Pragma("GCC diagnostic ignored \"-Wstrict-aliasing\"") is bugged */\ + static inline TYPE &NAME() { auto p = static_cast(&detail_NODESTRUCT_GLOBAL::NAME[0]); return *reinterpret_cast(p); }\ + namespace detailInit_NODESTRUCT_GLOBAL { __attribute__((constructor)) static void NAME() { new(&::NAME()) TYPE(); } } + +/** Define a global variable that is constructed (via gcc's __attribute__((constructor))) but never destroyed. */ +#define DEF_NODESTRUCT_GLOBAL(TYPE,NAME)\ + namespace detail_NODESTRUCT_GLOBAL { alignas(TYPE) uint8_t NAME[sizeof(TYPE)]; } + + +DCL_NODESTRUCT_GLOBAL(ldp_xml_parser::NaivePolicyChecker, policy_checker) #endif diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index 74783d2..e213c70 100644 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -11,9 +11,6 @@ using namespace ldp_xml_parser; -NaivePolicyDb::~NaivePolicyDb() { -} - NaivePolicyDb::PolicyOwn::PolicyOwn(){ treeRootPtr = new struct TreeNode; treeRootPtr->__decisionItem = {Decision::ANY, NULL}; @@ -24,10 +21,6 @@ NaivePolicyDb::PolicyOwn::PolicyOwn(){ } } -NaivePolicyDb::PolicyOwn::~PolicyOwn(){ - nodeRemove(&treeRootPtr); -} - void NaivePolicyDb::PolicyOwn::nodeRemove(TreeNode **node){ if (!*node) { return; diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp index 7162d91..d4bf231 100644 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -73,7 +73,6 @@ namespace ldp_xml_parser void nodeRemove(TreeNode **node); public: PolicyOwn(); - ~PolicyOwn(); /** Adds given item to tree by retrieving its name, decision and checking is it prefix. * \param[in] item Item to add to policy */ @@ -85,8 +84,6 @@ namespace ldp_xml_parser const TreeNode* getTreeRoot() const; }; - ~NaivePolicyDb(); - /** Gets policy with ownership rules from DB * \param[in] policy_type Policy type * \param[in] policy_type_value Policy type value diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index 752750f..d4ab166 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -183,7 +183,7 @@ void DbAdapter::xmlTraversal(bool bus, xmlTraversal(bus, v.second, t, policy_type, policy_type_value, attr, level + 1); } if (!pt.empty() && level > 1) - __builder.generateItem(policy_checker.db(bus), policy_type, policy_type_value); + __builder.generateItem(policy_checker().db(bus), policy_type, policy_type_value); } } @@ -265,9 +265,6 @@ MatchItemSR::MatchItemSR(const char* i, const char* me, const char* p, MessageTy : names_num(0), interface(i), member(me), path(p), type(t), direction(d) { } -MatchItemSR::~MatchItemSR(){ -} - void MatchItemSR::addName(const char* name) { names[names_num++] = NameSR(name, std::strlen(name)); } diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp index 5f4d84f..344c841 100644 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -176,7 +176,6 @@ namespace ldp_xml_parser 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; -- 2.7.4 From 57eae5c7fa39b22664cb0137ca1623d4956ce9ed Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Wed, 9 Nov 2016 09:59:35 +0100 Subject: [PATCH 10/16] remove unnecessary cynara_finish() call Change-Id: Ifcf14f42b8fc2b65c8a5598525b7b0a905f42aee (cherry picked from commit dadb0935c68e2d09cbedbda1b3afd552f75abc43) --- src/internal/cynara.cpp | 21 ++------------------- src/internal/cynara.hpp | 6 +----- src/internal/cynara_mockup.cpp | 16 ---------------- 3 files changed, 3 insertions(+), 40 deletions(-) diff --git a/src/internal/cynara.cpp b/src/internal/cynara.cpp index 6fe6b76..8be1c11 100644 --- a/src/internal/cynara.cpp +++ b/src/internal/cynara.cpp @@ -7,20 +7,6 @@ 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); @@ -33,10 +19,8 @@ bool Cynara::init() { return true; } -Cynara& Cynara::getInstance() { - static Cynara __self; - return __self; -} +static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER; +static Cynara c; CynaraResult Cynara::check(const char* label, const char* privilege, const char* uid) { const char* _label = ""; @@ -50,7 +34,6 @@ CynaraResult Cynara::check(const char* label, const char* privilege, const char* if (uid) _uid = uid; pthread_mutex_lock(&__mutex); - Cynara& c = Cynara::getInstance(); if (!c.init()) { ret = CynaraResult::ERROR_INIT; } else { diff --git a/src/internal/cynara.hpp b/src/internal/cynara.hpp index 84fbbd2..510b850 100644 --- a/src/internal/cynara.hpp +++ b/src/internal/cynara.hpp @@ -32,15 +32,11 @@ namespace ldp_cynara { }; class Cynara { private: - static pthread_mutex_t __mutex; cynara* __cynara; const char* __session; - bool __inited; - Cynara(); - ~Cynara(); + bool __inited = false; bool init(); - static Cynara& getInstance(); public: static CynaraResult check(const char* label, const char* privilege, const char* uid); diff --git a/src/internal/cynara_mockup.cpp b/src/internal/cynara_mockup.cpp index 8b701cd..d472cdb 100644 --- a/src/internal/cynara_mockup.cpp +++ b/src/internal/cynara_mockup.cpp @@ -6,22 +6,6 @@ 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) { (void)label; (void)privilege; -- 2.7.4 From bb7d32bb63f1d0fc463255000fbc773a119314a9 Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Thu, 29 Sep 2016 15:13:18 +0200 Subject: [PATCH 11/16] tests: Add test package for libdbuspolicy This patch introduces several modification that allows test package building. * Test version of libdbuspolicy shared library reads policy files from /usr/lib/dbus-tests/config/ instead of /etc/dbus-1/ ... * new package libdbuspolicy1-test contains test version of libdbuspolicy library with test policies and test binaries. * test-runner binary is compatible with dbus tests framework. Change-Id: I87bffc8bd24c05180441d74df546d4148a238ef1 (cherry picked from commit 42f084f08653aa5020342451c3c1a82aebf65a7a) --- Makefile.am | 19 + configure.ac | 1 + packaging/libdbuspolicy_tests.spec | 59 ++++ src/cynara_prepare.sh | 8 + src/dbus_daemon.c | 236 +++++++++++++ src/libdbuspolicy1.c | 7 + src/stest_common.c | 31 ++ src/stest_common.h | 21 ++ src/stest_cynara.c | 30 ++ src/stest_method_call.c | 77 ++++ src/stest_ownership.c | 56 +++ src/stest_signal.c | 23 ++ src/test_runner.c | 699 +++++++++++++++++++++++++++++++++++++ src/test_runner.h | 69 ++++ 14 files changed, 1336 insertions(+) create mode 100644 packaging/libdbuspolicy_tests.spec create mode 100644 src/cynara_prepare.sh create mode 100644 src/dbus_daemon.c create mode 100644 src/stest_common.c create mode 100644 src/stest_common.h create mode 100644 src/stest_cynara.c create mode 100644 src/stest_method_call.c create mode 100644 src/stest_ownership.c create mode 100644 src/stest_signal.c create mode 100644 src/test_runner.c create mode 100644 src/test_runner.h diff --git a/Makefile.am b/Makefile.am index 30eec82..941f6e6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -100,6 +100,25 @@ src_test_libdbuspolicy1_signal_LDADD = $(CYNARA_LIBS) \ src_test_libdbuspolicy1_method_LDADD = $(CYNARA_LIBS) \ src/libinternal.a +if ENABLE_STANDALONE_TESTS +bin_PROGRAMS = test_runner +test_runner_SOURCES = src/test_runner.c + +alonetestdir = ${bindir}/tests/ +alonetest_PROGRAMS = dbus_daemon stest_ownership stest_method_call stest_signal stest_cynara + +dbus_daemon_SOURCES = src/dbus_daemon.c +stest_ownership_SOURCES = src/stest_ownership.c src/stest_common.c +stest_method_call_SOURCES = src/stest_method_call.c src/stest_common.c +stest_signal_SOURCES = src/stest_signal.c src/stest_common.c +stest_cynara_SOURCES = src/stest_cynara.c src/stest_common.c + +stest_ownership_LDADD = src/libdbuspolicy1.la +stest_method_call_LDADD = src/libdbuspolicy1.la +stest_signal_LDADD = src/libdbuspolicy1.la +stest_cynara_LDADD = src/libdbuspolicy1.la +endif + if ENABLE_DOXYGEN CLEANFILES += documentation diff --git a/configure.ac b/configure.ac index 9c5aa73..6d6dbf4 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,7 @@ AS_IF([test "x$enable_debug" = "xyes"], [ 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) +AM_CONDITIONAL([ENABLE_STANDALONE_TESTS], [test x$with_tests = xyes]) if test "x$with_tests" = "xyes"; then AC_DEFINE(LIBDBUSPOLICY_TESTS_API, 1, [Define if tests are enabled]) fi diff --git a/packaging/libdbuspolicy_tests.spec b/packaging/libdbuspolicy_tests.spec new file mode 100644 index 0000000..d8c7feb --- /dev/null +++ b/packaging/libdbuspolicy_tests.spec @@ -0,0 +1,59 @@ +Name: libdbuspolicy-tests +Summary: Helper library +License: Apache-2.0 +Group: Base/IPC +Version: 1.0.0 +Release: 0 +Source: %{name}-%{version}.tar.gz +BuildRequires: boost-devel +BuildRequires: pkgconfig(cynara-client) + + +%description +This package contains contains integration tests for libdbuspolicy. + +%prep +%setup -q + +%build + +%reconfigure --libdir=%{_libdir} --prefix=/usr --enable-tests + +make +make check + +%install +make DESTDIR=%{buildroot} install +rm %{buildroot}%{_libdir}/libdbuspolicy1.la +rm %{buildroot}%{_includedir}/dbuspolicy/libdbuspolicy1.h +rm %{buildroot}%{_libdir}/pkgconfig/libdbuspolicy1.pc +rm %{buildroot}%{_libdir}/libdbuspolicy1.so + +mkdir -p %{buildroot}%{_libdir}/dbus-tests/lib/%{name} +mv %{buildroot}%{_libdir}/libdbuspolicy1.so.* %{buildroot}%{_libdir}/dbus-tests/lib/%{name} + +mkdir -p %{buildroot}%{_libdir}/dbus-tests/runner +mv %{buildroot}%{_bindir}/test_runner %{buildroot}%{_libdir}/dbus-tests/runner/%{name} + +mkdir -p %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name} +mv %{buildroot}%{_bindir}/tests/* %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name}/ + +mkdir -p %{buildroot}%{_libdir}/dbus-tests/configs/%{name} +install -m 0644 tests/system.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/ + +mkdir -p %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ +install -m 0644 tests/system.d/ownerships.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ +install -m 0644 tests/system.d/signals.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ +install -m 0644 tests/system.d/methods.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ +install -m 0644 tests/system.d/cynara.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ +install -m 0654 src/cynara_prepare.sh %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name}/ + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%{_libdir}/dbus-tests/lib/%{name}/libdbuspolicy1.so.* +%{_libdir}/dbus-tests/runner/%{name} +%{_libdir}/dbus-tests/test-suites/%{name}/* +%{_libdir}/dbus-tests/configs/%{name}/* diff --git a/src/cynara_prepare.sh b/src/cynara_prepare.sh new file mode 100644 index 0000000..acc2401 --- /dev/null +++ b/src/cynara_prepare.sh @@ -0,0 +1,8 @@ +#!/bin/sh +if [ -z "${1}" ]; then + cyad -e "MANIFESTS" -u 200 -c L -p t -r y + cyad -e "USER_TYPE_ADMIN" -u 200 -c L -p t -r y +else + cyad -s -k "MANIFESTS" -u 200 -c L -p t -t $1 + cyad -s -k "USER_TYPE_ADMIN" -u 200 -c L -p t -t $1 +fi diff --git a/src/dbus_daemon.c b/src/dbus_daemon.c new file mode 100644 index 0000000..058106e --- /dev/null +++ b/src/dbus_daemon.c @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kdbus.h" + +#define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus" + +#define KDBUS_ALIGN8(l) (((l) + 7) & ~7) +#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) +#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) +#define KDBUS_ITEM_NEXT(item) \ + (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size)) +#define KDBUS_FOREACH(iter, first, _size) \ + for (iter = (first); \ + ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ + ((uint8_t *)(iter) >= (uint8_t *)(first)); \ + iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size))) + +#define POOL_SIZE (16 * 1024 * 1024) + +#define err_r(_r, _msg) fprintf(stderr, "log: %d, %s, %s, %d, %s\n",(_r), (_msg), __func__, __LINE__, __FILE__) +#define err(_msg) err_r(errno, (_msg)) + +static uint8_t* pool; +static char* server_names[16]; +int ready_fd = 0; + +static inline int kdbus_cmd_hello(int bus_fd, struct kdbus_cmd_hello *cmd) +{ + int ret = ioctl(bus_fd, KDBUS_CMD_HELLO, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline int kdbus_cmd_free(int conn_fd, struct kdbus_cmd_free *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_FREE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline int kdbus_cmd_name_acquire(int conn_fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_NAME_ACQUIRE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static void bus_poool_free_slice(int fd, uint64_t offset) +{ + struct kdbus_cmd_free cmd = { + .size = sizeof(cmd), + .offset = offset, + }; + int r; + r = kdbus_cmd_free(fd, &cmd); + if (r < 0) + err_r(r, "cannot free pool slice"); +} + +static int bus_open_connection(const char *name, + uint64_t recv_flags) +{ + struct kdbus_cmd_hello hello; + int r; + int fd; + + fd = open(name, O_RDWR | O_CLOEXEC); + if (fd < 0) { + r = err("cannot open bus"); + goto error; + } + + memset(&hello, 0, sizeof(hello)); + hello.size = sizeof(hello); + hello.attach_flags_send = _KDBUS_ATTACH_ALL; + hello.attach_flags_recv = recv_flags; + hello.pool_size = POOL_SIZE; + r = kdbus_cmd_hello(fd, &hello); + if (r < 0) { + err_r(r, "HELLO failed"); + goto error; + } + + bus_poool_free_slice(fd, hello.offset); + + /* + * Map the pool of the connection. Its size has been set in the + * command struct above. See kdbus.pool(7). + */ + pool = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0); + if (pool == MAP_FAILED) { + r = err("cannot mmap pool"); + goto error; + } + + return fd; + +error: + return -1; +} + + + +static int bus_acquire_name(int fd, const char *name) +{ + struct kdbus_item *item; + struct kdbus_cmd *cmd; + size_t size; + int r; + + /* + * This function acquires a well-known name on the bus through the + * KDBUS_CMD_NAME_ACQUIRE ioctl. This ioctl takes an argument of type + * 'struct kdbus_cmd', which is assembled below. See kdbus.name(7). + */ + size = sizeof(*cmd); + size += KDBUS_ITEM_SIZE(strlen(name) + 1); + + cmd = alloca(size); + memset(cmd, 0, size); + cmd->size = size; + + /* + * The command requires an item of type KDBUS_ITEM_NAME, and its + * content must be a valid bus name. + */ + item = cmd->items; + item->type = KDBUS_ITEM_NAME; + item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; + strcpy(item->str, name); + + /* + * Employ the command on the connection owner file descriptor. + */ + r = kdbus_cmd_name_acquire(fd, cmd); + if (r < 0) + return err_r(r, "cannot acquire name"); + + return 0; +} + + +int parse_args(int argc, char** argv) +{ + char state = 0; + unsigned long int uid = 0; + unsigned long int gid = 0; + int i = 1; + int r = 0; + int fdl = -1; + int count = 0; + + while (i < argc) + { + if (argv[i][0] == '-') + state = argv[i][1]; + else { + switch (state) { + + case 'n': + server_names[count++] = argv[i]; + break; + + case 'u': + uid = strtoul(argv[i],NULL,10); + r = setuid((uid_t)uid); + if (r< 0) { + fprintf(stderr, "Cannot set uid"); + exit(-3245); + } + break; + + case 'g': + gid = strtoul(argv[i],NULL,10); + r = setgid((gid_t)gid); + if (r< 0) { + fprintf(stderr, "Cannot set gid"); + exit(-3245); + } + break; + + case 'l': + fdl = open("/proc/self/attr/current", 0, S_IWUSR); + if (fdl < 0) + { + fprintf(stderr,"Cannot open /proc/self/attr/current\n"); + exit(-345); + } + + r = write(fdl, argv[i], strlen(argv[i])); + if (r < 0) + { + fprintf(stderr, "Cannot write to /proc/self/attr/current\n"); + close(fdl); + exit(-345); + } + close(fdl); + break; + case 'q': + ready_fd = strtol(argv[i], NULL, 10); + break; + } + } + i++; + } + return 0; +} + +int main(int argc, char* argv[]) { + int j = 0; + int fd; + parse_args(argc, argv); + fd = bus_open_connection(KDBUS_SYSTEM_BUS_PATH, KDBUS_ATTACH_PIDS); + if (fd < 0) { + return -1; + } + + while(server_names[j] != '\0') + { + if (bus_acquire_name(fd, server_names[j])) + return -1; + j++; + } + + close(ready_fd); + + for(;;); + return 0; +} diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 1721185..11817ad 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -51,6 +51,13 @@ #define UID_INVALID ((uid_t) -1) #define GID_INVALID ((gid_t) -1) +#ifdef LIBDBUSPOLICY_TESTS_API +#undef SYSTEM_BUS_CONF_FILE_PRIMARY +#undef SESSION_BUS_CONF_FILE_PRIMARY +#define SYSTEM_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/system.conf" +#define SESSION_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/session.conf" +#endif + /** A process ID */ typedef unsigned long dbus_pid_t; /** A user ID */ diff --git a/src/stest_common.c b/src/stest_common.c new file mode 100644 index 0000000..8cb9f35 --- /dev/null +++ b/src/stest_common.c @@ -0,0 +1,31 @@ +#include +#include +#include + +uint64_t test_cases_mask = ~(0ULL); +int test_count = 0; + +void assert_printf(int res, int tc, const char* value, int line, const char* file) +{ + if (res) { + printf("[r][%d]1\n", tc); + } else { + printf("[r][%d]0\n", tc); + fprintf(stderr, "[r][%d]0<-w=%s, line=%d, file=%s\n", tc, value, line, file); + } +} + +void prepare_mask(int argc, char* argv[]) +{ + if (argc > 1) + { + int i = 1; + test_cases_mask = 0; + for (;i < argc; i++) { + int val = strtol(argv[i], NULL, 10); + if (val >= 0) + test_cases_mask |= (1< + +#define assert(v) \ + do { \ + if (test_cases_mask & (1 << test_count)) \ + { \ + int ___r = (v); \ + assert_printf(___r, test_count, #v, __LINE__, __FILE__); \ + } \ + test_count++; \ + } while (0) + +enum { + false, + true +}; + +extern uint64_t test_cases_mask; +extern int test_count; +void prepare_mask(int argc, char* argv[]); +void assert_printf(int res, int tc, const char* value, int line, const char* file); diff --git a/src/stest_cynara.c b/src/stest_cynara.c new file mode 100644 index 0000000..db885f8 --- /dev/null +++ b/src/stest_cynara.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include "stest_common.h" + +#define NEGATIVE_MATCH "negative" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + int result = true; + + prepare_mask(argc,argv); + + if (!strncmp(argv[0], NEGATIVE_MATCH, sizeof(NEGATIVE_MATCH)-1)) + result = false; + + printf("---result: %d %s\n\n", result, argv[0]); + assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); + + __dbuspolicy1_change_creds(c,200,0,"L"); + assert(dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", "L", 200, 0, NULL, "cynara.interface", "cynara.method", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == result); + + assert(dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", "L", 200, 0, NULL, "cynara.interface", "cynara.method", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == result); + return 0; +} diff --git a/src/stest_method_call.c b/src/stest_method_call.c new file mode 100644 index 0000000..7507659 --- /dev/null +++ b/src/stest_method_call.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include "stest_common.h" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + + prepare_mask(argc,argv); + + assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", NULL, "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", NULL, 0, 0, "", "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "" ,"org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test9", "org.test.test10", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test9", "org.test.test10", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_out(c, "org.test.test10", "org.test.test9", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + assert(dbuspolicy1_check_in(c, "org.test.test10", "org.test.test9", "", 0, 0, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + return 0; +} diff --git a/src/stest_ownership.c b/src/stest_ownership.c new file mode 100644 index 0000000..a6c191b --- /dev/null +++ b/src/stest_ownership.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include "stest_common.h" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + + prepare_mask(argc,argv); + + assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + assert(dbuspolicy1_can_own(c, "org.test.test1")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + assert(dbuspolicy1_can_own(c, "org.test.test1")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + assert(!dbuspolicy1_can_own(c, "org.test.test2")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + assert(!dbuspolicy1_can_own(c, "org.test.test2")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + assert(!dbuspolicy1_can_own(c, "org.test.test3")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + assert(!dbuspolicy1_can_own(c, "org.test.test3")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + assert(!dbuspolicy1_can_own(c, "org.test.test4")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + assert(dbuspolicy1_can_own(c, "org.test.test4")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + assert(!dbuspolicy1_can_own(c, "org.test.test5")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + assert(dbuspolicy1_can_own(c, "org.test.test6")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + assert(dbuspolicy1_can_own(c, "org.test.test7")); + + assert(dbuspolicy1_can_own(c, "a.b.c")); + assert(dbuspolicy1_can_own(c, "a.b")); + assert(!dbuspolicy1_can_own(c, "c")); + assert(!dbuspolicy1_can_own(c, "a.c")); + assert(!dbuspolicy1_can_own(c, "b.c")); + + return 0; +} diff --git a/src/stest_signal.c b/src/stest_signal.c new file mode 100644 index 0000000..165c90e --- /dev/null +++ b/src/stest_signal.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include "stest_common.h" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + + prepare_mask(argc,argv); + + assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); + + __dbuspolicy1_change_creds(c,0,0,NULL); + assert(dbuspolicy1_check_out(c, "", "bli.bla.blubb test.test1 test.tes3", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5010,0,NULL); + assert(dbuspolicy1_check_out(c, "", "bli.bla.blubb", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == false); + + return 0; +} diff --git a/src/test_runner.c b/src/test_runner.c new file mode 100644 index 0000000..81c4e0e --- /dev/null +++ b/src/test_runner.c @@ -0,0 +1,699 @@ +/* This file contains test-runner for libdbuspolicy + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Author: Kazimierz Krosman + * + * 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. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_runner.h" + +enum { + PIPE_READ, + PIPE_WRITE, +}; + +/*****************CUSTOM SECTION***********************************/ +/*custom function that parse stdout of binary and result of binary*/ +void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); +void parse_one_test_one_binary(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); +char** prepare_args_for_binary(const struct binary* b, const char* test_name); +int daemon_init(void); +int daemon_clear(void); +int cynara_init(void); +int cynara_clear(void); +int cynara_n_init(void); +int cynara_n_clear(void); + +static struct test_case ownership_test_cases[] = { + {"0", "Libdbuspolicy1 init function call"}, + {"1", "Simple check for ownership in default context"}, + {"2", "Simple check for ownership in default context"}, + {"3", "Ownership check in user context"}, + {"4", "Ownership check in user context (negative test)"}, + {"5", "Ownership check in mandatory context with user context (context priority check)"}, + {"6", "Ownership check in mandatory context with user context (for another user)"}, + {"7", "Ownership check for not root user context (negative test)"}, + {"8", "Ownership check for not root user context"}, + {"9", "Ownership check for group context"}, + {"10", "Ownership check for all context (priority check)"}, + {"11", "Ownership check for all context (priority check)"}, + {"12", "Ownership check for own_prefix case (1)"}, + {"13", "Ownership check for own_prefix case (2)"}, + {"14", "Ownership check for own_prefix case (negative test)"}, + {"15", "Ownership check for own_prefix case (negative test)"}, + {"16", "Ownership check for own_prefix case (negative test)"}, + {NULL, NULL} +}; + +static struct test_case method_call_test_cases[] = { + {"0", "Libdbuspolicy1 init function call"}, + {"1", "check_out test"}, + {"2", "check_in test"}, + {"3", "check_out test"}, + {"4", "check_in test"}, + {"5", "check_out test"}, + {"6", "check_in test"}, + {"7", "check_out test"}, + {"8", "check_in test"}, + {"9", "check_out test"}, + {"10", "check_in test"}, + {"11", "check_out test"}, + {"12", "check_in test"}, + {"13", "check_out test"}, + {"14", "check_in test"}, + {"15", "check_out test"}, + {"16", "check_in test"}, + {"17", "check_out test"}, + {"18", "check_in test"}, + {"19", "check_out test"}, + {"20", "check_in test"}, + {NULL, NULL} +}; + +static struct test_case signal_test_cases[] = { + {"1", "Libdbuspolicy1 init"}, + {"2", "Check out for signal"}, + {"3", "Check out for signal (negative)"}, + {NULL, NULL} +}; + +static struct test_case cynara_test_cases[] = { + {"0", "Libdbuspolicy1 init function call"}, + {"1", "Check cynara for result"}, + {"2", "Check cynara for result (second attempt to use cache)"}, + {NULL, NULL} +}; + +static struct test_case negative_cynara_test_cases[] = { + {"0", "Libdbuspolicy1 init function call"}, + {"1", "Check cynara for result (negative test)"}, + {"2", "Check cynara for result (second attempt to use cache) (negative test)"}, + {NULL, NULL} +}; + +/* This table is used to start binaries */ +struct binary tests[] = { +/*path, name, TC_table, timeout in us, prepare_args_handler, parse_function_handler, init_handler, clean_handler*/ + {TEST_PATH "stest_ownership", "ownership", ownership_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, + {TEST_PATH "stest_method_call", "method_call", method_call_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, + {TEST_PATH "stest_signal", "signal", signal_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, + {TEST_PATH "stest_cynara", "cynara", cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_init, cynara_clear}, + {TEST_PATH "stest_cynara", "negative_cynara", negative_cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_n_init, cynara_n_clear}, +}; + + +static const char result_pattern[] = "[r][%0]%1"; +static struct state { + unsigned int i; // index of input buffer + unsigned int j; // index in results[n] + unsigned int n; //index in results buffer (0 or 1) + char results[2][MAX_COMMENT]; +} g_state; + +static void sm_reset(void) +{ + memset(&g_state, 0, sizeof (g_state)); +} + +static int sm_update(char* buffer, int i) +{ + int l = strlen(buffer) + 1; + while (i < l && g_state.i < sizeof(result_pattern) - 1) { + if (result_pattern[g_state.i] == '%') { + g_state.n = result_pattern[g_state.i+1] - '0'; + if (g_state.n > 1) { + sm_reset(); + i--; + } else if (isalnum(buffer[i])) { + g_state.results[g_state.n][g_state.j++] = buffer[i]; + } else if (buffer[i] == result_pattern[g_state.i+2] || buffer[i] == '\n') { + g_state.results[g_state.n][g_state.j] = 0; + g_state.i += 3; + g_state.j = 0; + if (g_state.n == 1) + return i; + } else { + g_state.i = 0; + g_state.j = 0; + } + } else if (result_pattern[g_state.i] == buffer[i]) { + g_state.i++; + } else { + sm_reset(); + } + i++; + } + + if (g_state.i >= sizeof(result_pattern) - 1) { + g_state.results[g_state.n][g_state.j] = 0; + g_state.i += 3; + g_state.j = 0; + if (g_state.n == 1) + return i; + } + + return 0; +} + +static const char* sm_get_result(int i) +{ + return g_state.results[i]; +} + +static pid_t daemon_pids[4] ={0}; +static int daemons_pipe[4][2]; +static char* daemon_argv1[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n","org.test.test3", NULL}; +static char* daemon_argv2[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test2", "-g", "100", "-u", "5001", NULL}; +static char* daemon_argv3[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test12", "org.test.test9", NULL}; +static char* daemon_argv4[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n", "org.test.test13", "org.test.test10", "org.test.test11", "-g", "100", "-u", "5001", NULL}; +static char** daemons[] = { daemon_argv1, daemon_argv2, daemon_argv3, daemon_argv4}; + +int daemon_init(void) +{ + int i = 0; + int ready_proc = 0; + struct timeval tv; + fd_set rfds; + int nfds = -1; + int proc_num = sizeof(daemons)/sizeof(daemons[0]); + + for (;i < proc_num;i++) { + if (pipe(daemons_pipe[i]) < 0) { + perror("cannot create pipe"); + goto error1; + } + + daemon_pids[i] = fork(); + if (!daemon_pids[i]) { + char fdd[15]; + sprintf(fdd,"%d",daemons_pipe[i][PIPE_WRITE]); + daemons[i][2] = fdd; + close (daemons_pipe[i][PIPE_READ]); + (void)execv(daemons[i][0],daemons[i]); + exit(0); + } else if (daemon_pids[i] > 0){ + close (daemons_pipe[i][PIPE_WRITE]); + } else + goto error1; + } + + tv.tv_sec = 1; + tv.tv_usec = 0; + while(1) { + FD_ZERO(&rfds); + for (i = 0; i < proc_num;i++) { + if (daemons_pipe[i][PIPE_READ] > -1) + FD_SET(daemons_pipe[i][PIPE_READ], &rfds); + } + + if (ready_proc >= proc_num) + break; + + nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); + if (nfds > 0) { + for (i = 0; i < proc_num;i++) { + if (daemons_pipe[i][PIPE_READ] > -1 && FD_ISSET(daemons_pipe[i][PIPE_READ], &rfds)) { + ++ready_proc; + close (daemons_pipe[i][PIPE_READ]); + daemons_pipe[i][PIPE_READ] = -1; + } + } + } else + goto error1; + } + + return 1; +error1: + daemon_clear(); + return 0; +} + +int daemon_clear(void) +{ + unsigned int i = 0; + for (;i < sizeof(daemons)/sizeof(daemons[0]);i++) { + if (daemon_pids[i]) + kill(daemon_pids[i], SIGKILL); + } + return 0; +} + +static int call_script(char* path, char* argv[]) +{ + int status; + int r; + pid_t pid = fork(); + + if (pid < 0) + return 0; + else if (!pid) { + (void)execv(path, argv); + exit(-1); + } + + r = waitpid(pid, &status, 0); + if (r > 0) { + if (WIFEXITED(status)) + return !(WEXITSTATUS(status)); + else if (WIFCONTINUED(status)) + kill(pid, SIGKILL); + } + + /* fail */ + return 0; +} + +int cynara_n_init(void) +{ + char* argv[] = {CYNARA_PATH, "DENY", NULL}; + return call_script(argv[0],argv); +} + +int cynara_n_clear(void) +{ + return cynara_clear(); +} + +int cynara_init(void) +{ + char* argv[] = {CYNARA_PATH, "ALLOW", NULL}; + return call_script(argv[0],argv); +} + +int cynara_clear(void) +{ + char* argv[] = {CYNARA_PATH, NULL}; + return call_script(argv[0],argv); +} + +static char* args[3]; +char** prepare_args_for_binary(const struct binary* b, const char* test_name) +{ + args[0] = (char*)b->name; + if (!test_name[0]) + args[1] = NULL; + else { + args[1] = (char*)test_name; + args[2] = NULL; + } + return args; +} + + +/* + * Example of test_result detector function implementation + */ +void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option) +{ + char test_id[MAX_COMMENT]; + + switch(state_change) { + case INIT_TEST: + sm_reset(); + break; + case NEW_STDOUT: + { + int k = 0; + buffer[state_option] = 0; + get_test_id(test_id, b, test_name); + fprintf(stderr, "[stdout][%s]%s\n",test_id, buffer); + while ( (k = sm_update(buffer, k))) { + const char* t_name = sm_get_result(0); + const char* result_code = sm_get_result(1); + bool is_successful = result_code[0] == '1' && result_code[1] == 0; + const char* result_text = is_successful ? "PASS" : "FAIL"; + + get_test_id(test_id, b, t_name); + add_test_result(test_id, result_text, "", is_successful); + sm_reset(); + } + } + break; + case NEW_STDERR: + buffer[state_option] = 0; + get_test_id(test_id, b, test_name); + fprintf(stderr, "[stderr][%s]%s\n",test_id, buffer); + break; + case RESULT_CODE: + if (state_option != 0) + add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Test exited with error code", 0); + break; + case RESULT_SIGNAL: + add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Finished by SIGNAL", 0); + break; + case RESULT_TIMEOUT: + add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Test TIMEOUT", 0); + break; + } +} + +/****************************END of CUSTOM FUNCTIONS************************/ + + +static struct option long_options[] = { + {"list", no_argument, 0, 'l'}, + {"run", required_argument, 0, 'r'}, + {"description", required_argument, 0, 'd'}, + {0, 0, 0, 0 } +}; + +static int stdin_pipe[2]; +static int stdout_pipe[2]; +static int stderr_pipe[2]; +static struct test_result test_results[MAX_TC_NUM]; +static int test_results_i; +static char buffer[MAX_BUFFER]; +static const char* requested_tc[MAX_TC_NUM]; + +char* get_test_id(char* dest, const struct binary* b, const char* test_name) +{ + int len = strlen(b->name); + memcpy(dest, b->name, len); + memcpy(dest + len, test_name, strlen(test_name)+1); + return dest; +} + +static void print_description(const char* name, const char* description) +{ + printf("%s;%s\n",name, description); +} + +static void print_list(const char* test_name) +{ + unsigned int i; + char full_name[MAX_COMMENT]; + for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { + int j = 0; + int l = strlen(tests[i].name); + memcpy(full_name, tests[i].name, l+1); + if (test_name && strncmp(test_name, full_name, l) != 0) + continue; + + while (tests[i].test_cases[j].name) { + memcpy(full_name + l, tests[i].test_cases[j].name, strlen(tests[i].test_cases[j].name) + 1); + if (!test_name || strcmp(full_name, test_name) == 0) + print_description(full_name,tests[i].test_cases[j].description); + j++; + } + } +} + + +static void stop_binary(const struct binary* b, pid_t pid, const char* test_name) +{ + int status = 0; + int res = 0; + res = waitpid(pid, &status, 0); + if (res == 0) { + //timeouted + kill(pid, SIGKILL); + res = waitpid(pid, &status, WNOHANG); + b->parse(b, test_name, buffer, RESULT_TIMEOUT, res); + } else if (res < 0) { + //errno check + kill(pid, SIGKILL); + res = waitpid(pid, &status, WNOHANG); + b->parse(b, test_name, buffer, RESULT_ERROR, res); + } else if (res > 0) { + if (WIFEXITED(status)) { + b->parse(b, test_name, buffer, RESULT_CODE, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + b->parse(b, test_name, buffer, RESULT_SIGNAL, WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + b->parse(b, test_name, buffer, RESULT_SIGNAL, WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + kill(pid, SIGKILL); + b->parse(b, test_name, buffer, RESULT_SIGNAL, -1); + } + } +} + +static void parse_output_with_timeout(const struct binary* b, pid_t pid, const char* test_name) +{ + struct timeval tv; + fd_set rfds; + int nfds; + int res; + tv.tv_sec = b->timeout/(1000*1000); + tv.tv_usec = (b->timeout-tv.tv_sec*1000*1000); + while (1) { + FD_ZERO(&rfds); + FD_SET(stdout_pipe[PIPE_READ], &rfds); + FD_SET(stderr_pipe[PIPE_READ], &rfds); + nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); + if (nfds == -1) { + if (errno != EINTR) + break; + } else if (nfds > 0) { + if (FD_ISSET(stdout_pipe[PIPE_READ], &rfds)) { + res = read(stdout_pipe[PIPE_READ], buffer, MAX_BUFFER-1); + if (res == 0 || (res < 0 && errno != EINTR)) + break; + else if (res >=0) + b->parse(b, test_name, buffer, NEW_STDOUT, res); + } + + if (FD_ISSET(stderr_pipe[PIPE_READ], &rfds)) { + res = read(stderr_pipe[PIPE_READ], buffer, MAX_BUFFER-1); + if (res == 0 || (res < 0 && errno != EINTR)) + break; + b->parse(b, test_name, buffer, NEW_STDERR, res); + } + } else { + //timeout + break; + } + } + stop_binary(b, pid, test_name); +} + +static int create_child(const char* path, char* const arguments[]) +{ + int child; + int nResult; + if (pipe(stdin_pipe) < 0) { + perror("allocating pipe for child input redirect failed"); + goto error1; + } + + if (pipe(stdout_pipe) < 0) { + perror("allocating pipe for child output redirect failed"); + goto error2; + } + + if (pipe(stderr_pipe) < 0) { + perror("allocating pipe for child output redirect failed"); + goto error3; + } + + child = fork(); + if (!child) { + char ld_path[512]; + sprintf(ld_path, "/usr/lib/dbus-tests/lib/libdbuspolicy-tests/:"); + // redirect stdin + if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1) { + perror("redirecting stdin failed"); + return -1; + } + + // redirect stdout + if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1) { + perror("redirecting stdout failed"); + return -1; + } + + // redirect stderr + if (dup2(stderr_pipe[PIPE_WRITE], STDERR_FILENO) == -1) { + perror("redirecting stderr failed"); + return -1; + } + + // all these are for use by parent only + close(stdin_pipe[PIPE_READ]); + close(stdin_pipe[PIPE_WRITE]); + close(stdout_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); + close(stderr_pipe[PIPE_READ]); + close(stderr_pipe[PIPE_WRITE]); + + char* ld_path_b = getenv("LD_LIBRARY_PATH"); + if (ld_path_b != NULL) + memcpy(ld_path + strlen(ld_path), ld_path_b, strlen(ld_path_b)+1); + setenv("LD_LIBRARY_PATH", ld_path, 1); + // run child process image + nResult = execv(path, arguments); + + // if we get here at all, an error occurred, but we are in the child + // process, so just exit + perror("exec of the child process failed"); + exit(nResult); + } else if (child > 0) { + // parent continues here + + // close unused file descriptors, these are for child only + close(stdin_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); + close(stderr_pipe[PIPE_WRITE]); + } else { + // failed to create child + goto error4; + } + + return child; + +error4: + close(stderr_pipe[PIPE_READ]); + close(stderr_pipe[PIPE_WRITE]); +error3: + close(stdout_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); +error2: + close(stdin_pipe[PIPE_READ]); + close(stdin_pipe[PIPE_WRITE]); +error1: + return -1; +} + +static void run_test(const struct binary* b, const char* test_name) +{ + int res = -1; + char** arg; + char test_id[MAX_COMMENT]; + + assert(b); + assert(b->name); + assert(b->path); + assert(test_name); + + arg = b->prepare_args(b, test_name); + + if (b->init) + if (!b->init()) { + add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot init test", 0); + return; + } + + res = create_child(b->path, arg); + if (res > 0) + parse_output_with_timeout(b, res, test_name); + else + add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot start test", 0); + + if (b->clean) + b->clean(); +} + +static void parse_run_test(const char* tc) { + unsigned int i = 0; + for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { + int len = strlen(tests[i].name); + if (strncmp(tc, tests[i].name, len) == 0) { + if (tc[len] == '*' || tc[len] == '\0') + run_test(&tests[i], ""); + else + run_test(&tests[i], tc + len); + } + } +} + +static int parse_option(int argc, char* argv[]) +{ + int ch = 0; + int c = 0; + while ((ch = getopt_long(argc, argv, "lr:d:", long_options, NULL)) != -1) { + switch (ch) { + case 'l': + print_list(NULL); + return 1; + case 'r': + if (c >= MAX_TC_NUM - 1) //NULL at the end + return 0; + + if (optarg) + requested_tc[c++] = optarg; + + break; + case 'd': + print_list(optarg); + return 1; + } + } + return 0; +} + +//output_new/fail/success +void add_test_result(const char* test_id, const char* result, const char* comment, int res) +{ + test_results[test_results_i].is_positive = res; + strcpy(test_results[test_results_i].result, result); + strcpy(test_results[test_results_i].comment, comment); + strcpy(test_results[test_results_i++].name, test_id); +} + +static void prepare_results(void) +{ + //todo +} + +static void print_results() +{ + int i = 0; + for (i = 0; i < test_results_i; i++) + { + printf("%s;%s;%s\n", test_results[i].name, test_results[i].result, test_results[i].comment); + } +} + +int main(int argc, char* argv[]) +{ + unsigned int i; + signal(SIGPIPE, SIG_IGN); + if (parse_option(argc, argv)) + return 0; + + prepare_results(); + + if (!requested_tc[0]) { + for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) + run_test(&tests[i], ""); + } else { + i = 0; + while(requested_tc[i]) { + parse_run_test(requested_tc[i]); + i++; + } + } + + print_results(); + return 0; +} diff --git a/src/test_runner.h b/src/test_runner.h new file mode 100644 index 0000000..3c79a99 --- /dev/null +++ b/src/test_runner.h @@ -0,0 +1,69 @@ +/* This file is part of test-runner (see template.c) + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Author: Kazimierz Krosman + * + * 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 TEST_RUNNER_H +#define TEST_RUNNER_H +#include + +#define TC_NAME "libdbuspolicy-tests" +#define TEST_PATH "/usr/lib/dbus-tests/test-suites/libdbuspolicy-tests/" +#define CYNARA_PATH TEST_PATH "cynara_prepare.sh" +#define MAX_TC_NUM 1024 +#define MAX_BUFFER (64*1024) +#define MAX_COMMENT 1024 + +enum { + INIT_TEST, + NEW_STDOUT, + NEW_STDERR, + RESULT_CODE, + RESULT_SIGNAL, + RESULT_ERROR, + RESULT_TIMEOUT +}; + +struct test_result { + bool is_positive; + char comment[MAX_COMMENT]; + char result[MAX_COMMENT]; + char name[MAX_COMMENT]; +}; + +struct test_case { + const char* name; + const char* description; +}; + +struct binary { + const char* path; + const char* name; + /* can be filled by asking binary */ + struct test_case* test_cases; + int timeout; + + char** (*prepare_args) (const struct binary* b, const char* test_name); + void (*parse) (const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); + int (*init)(void); + int (*clean)(void); +}; + +char* get_test_id(char* dest, const struct binary* b, const char* test_name); +void add_test_result(const char* test_id, const char* result, const char* comment, int res); + + +#endif /* TEST_RUNNER_H */ -- 2.7.4 From 7f61079c4eba4616c5785dad7b248cf5ed730253 Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Thu, 24 Nov 2016 15:37:09 +0100 Subject: [PATCH 12/16] libdbuspolicy.spec: disable tests [fix critical runtime breakage] Change-Id: I9c3be5ccbbd1f5326542d11ac818b350038076f6 (cherry picked from commit d260c0a6cb0ca0e6552e0370bfd93eff85b0107c) --- packaging/libdbuspolicy.spec | 3 --- 1 file changed, 3 deletions(-) diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index 590dd18..f9e6e7e 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -38,9 +38,6 @@ cp %{SOURCE1001} . %build %reconfigure --libdir=%{_libdir} --prefix=/usr \ -%if 0%{?test_version} ---enable-tests \ -%endif %if 0%{?enable_doxygen:1} --enable-doxygen %endif -- 2.7.4 From a821a95b097c78485203bf0eb93c661f1ec91294 Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Tue, 22 Nov 2016 16:43:04 +0100 Subject: [PATCH 13/16] remove unused g_udesc.{user,group} Change-Id: I767b9c7b095692466c0bb4d25cb8ed707e088a23 (cherry picked from commit 3b8cddc1e85c5cde1c9ed30a5d374e70c959c318) --- src/libdbuspolicy1.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 11817ad..d1de0ca 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -73,9 +73,7 @@ struct kconn { } g_conn[2]; struct udesc { - char user[256]; dbus_uid_t uid; - char group[256]; dbus_gid_t gid; char label[256]; } g_udesc; @@ -143,10 +141,6 @@ 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; @@ -155,7 +149,6 @@ static bool dbuspolicy_init_once(void) if (attr_fd < 0) return -1; r = read(attr_fd, buf, sizeof(buf)); - close(attr_fd); if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */ @@ -163,19 +156,7 @@ static bool dbuspolicy_init_once(void) 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; - - if (getgrgid_r(g_udesc.gid, &grent, buf, sizeof(buf), &gg)) - return true; - - 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); __internal_init_once(); -- 2.7.4 From 403485eb64bf0479426c5932ae2685199760b20d Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Tue, 22 Nov 2016 17:21:16 +0100 Subject: [PATCH 14/16] retrieve label on every cynara check Change-Id: I5e6fb0f44589ebb295af1db43b8aa5f1838d3c72 (cherry picked from commit fe403b9aa7ad1ff7e56327af2d88477b26094746) --- src/internal/cynara.cpp | 29 ++++++++++++++++++++++++++--- src/internal/internal.h | 1 + src/libdbuspolicy1.c | 32 +++++++++++--------------------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/internal/cynara.cpp b/src/internal/cynara.cpp index 8be1c11..02cb574 100644 --- a/src/internal/cynara.cpp +++ b/src/internal/cynara.cpp @@ -1,9 +1,11 @@ -#include "cynara.hpp" -#include "libdbuspolicy1-private.hpp" +#include #include #include #include #include +#include "cynara.hpp" +#include "internal.h" +#include "libdbuspolicy1-private.hpp" using namespace ldp_cynara; @@ -22,12 +24,33 @@ bool Cynara::init() { static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER; static Cynara c; +#ifdef LIBDBUSPOLICY_TESTS_API +extern char label_override[4096]; +extern bool have_label_override; +#endif + 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) + char buf[4096]; +#ifdef LIBDBUSPOLICY_TESTS_API + if (have_label_override) _label = label_override; else +#endif + if (SELF_LABEL == label) { + int attr_fd = open("/proc/self/attr/current", O_RDONLY); + if (attr_fd < 0) + return CynaraResult::ERROR_CHECK; + int r = read(attr_fd, buf, sizeof(buf)-1); + close(attr_fd); + if (r < 0) + return CynaraResult::ERROR_CHECK; + if (r) { + buf[r] = 0; + _label = buf; + } + } else if (label) _label = label; if (privilege) _privilege = privilege; diff --git a/src/internal/internal.h b/src/internal/internal.h index 787b380..be72bfa 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -31,6 +31,7 @@ extern "C" { #endif #define KDBUS_CONN_MAX_NAMES 256 +#define SELF_LABEL ((void*)-1) /** Initializes policies from given policy configuration file name * \param[in] bus_type Bus type (system/session) diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index d1de0ca..b37b1ac 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -75,7 +75,6 @@ struct kconn { struct udesc { dbus_uid_t uid; dbus_gid_t gid; - char label[256]; } g_udesc; static int kdbus_open_bus(const char *path) @@ -141,22 +140,8 @@ static uint64_t kdbus_unique_id(char const *name) static bool dbuspolicy_init_once(void) { - 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)); - close(attr_fd); - - 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); __internal_init_once(); @@ -267,12 +252,17 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) } #ifdef LIBDBUSPOLICY_TESTS_API +char label_override[4096]; +bool have_label_override; DBUSPOLICY1_EXPORT void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label) { (void)configuration; g_udesc.uid = uid; g_udesc.gid = gid; - if (label) - strcpy (g_udesc.label, label); + if (label) { + strncpy(label_override, label, sizeof(label_override)); + label_override[sizeof(label_override)-1] = 0; + have_label_override = 1; + } } #endif @@ -372,10 +362,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, } if (empty_names) - r = __internal_can_send(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, destination, path, interface, member, message_type); + r = __internal_can_send(bus_type, g_udesc.uid, g_udesc.gid, SELF_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); + r = __internal_can_send_multi_dest(bus_type, g_udesc.uid, g_udesc.gid, SELF_LABEL, k_names, path, interface, member, message_type); } if (r <= 0) goto end; @@ -419,7 +409,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, 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); + r = __internal_can_recv(bus_type, g_udesc.uid, g_udesc.gid, SELF_LABEL, sender, path, interface, member, message_type); if (r <= 0) goto end; } @@ -433,7 +423,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, SELF_LABEL, service); __internal_exit(); return r; } -- 2.7.4 From 376f38dafa0b7ee5eae3d8f0ba0333c84a79742d Mon Sep 17 00:00:00 2001 From: sanghyeok oh Date: Thu, 1 Dec 2016 21:05:33 -0800 Subject: [PATCH 15/16] Revert "tests: Add test package for libdbuspolicy" This reverts commit bb7d32bb63f1d0fc463255000fbc773a119314a9. Change-Id: I6bc92edf4cd438c07f6ed99acf4e8bfe531d1d1a --- Makefile.am | 19 - configure.ac | 1 - packaging/libdbuspolicy_tests.spec | 59 ---- src/cynara_prepare.sh | 8 - src/dbus_daemon.c | 236 ------------- src/libdbuspolicy1.c | 7 - src/stest_common.c | 31 -- src/stest_common.h | 21 -- src/stest_cynara.c | 30 -- src/stest_method_call.c | 77 ---- src/stest_ownership.c | 56 --- src/stest_signal.c | 23 -- src/test_runner.c | 699 ------------------------------------- src/test_runner.h | 69 ---- 14 files changed, 1336 deletions(-) delete mode 100644 packaging/libdbuspolicy_tests.spec delete mode 100644 src/cynara_prepare.sh delete mode 100644 src/dbus_daemon.c delete mode 100644 src/stest_common.c delete mode 100644 src/stest_common.h delete mode 100644 src/stest_cynara.c delete mode 100644 src/stest_method_call.c delete mode 100644 src/stest_ownership.c delete mode 100644 src/stest_signal.c delete mode 100644 src/test_runner.c delete mode 100644 src/test_runner.h diff --git a/Makefile.am b/Makefile.am index 941f6e6..30eec82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -100,25 +100,6 @@ src_test_libdbuspolicy1_signal_LDADD = $(CYNARA_LIBS) \ src_test_libdbuspolicy1_method_LDADD = $(CYNARA_LIBS) \ src/libinternal.a -if ENABLE_STANDALONE_TESTS -bin_PROGRAMS = test_runner -test_runner_SOURCES = src/test_runner.c - -alonetestdir = ${bindir}/tests/ -alonetest_PROGRAMS = dbus_daemon stest_ownership stest_method_call stest_signal stest_cynara - -dbus_daemon_SOURCES = src/dbus_daemon.c -stest_ownership_SOURCES = src/stest_ownership.c src/stest_common.c -stest_method_call_SOURCES = src/stest_method_call.c src/stest_common.c -stest_signal_SOURCES = src/stest_signal.c src/stest_common.c -stest_cynara_SOURCES = src/stest_cynara.c src/stest_common.c - -stest_ownership_LDADD = src/libdbuspolicy1.la -stest_method_call_LDADD = src/libdbuspolicy1.la -stest_signal_LDADD = src/libdbuspolicy1.la -stest_cynara_LDADD = src/libdbuspolicy1.la -endif - if ENABLE_DOXYGEN CLEANFILES += documentation diff --git a/configure.ac b/configure.ac index 6d6dbf4..9c5aa73 100644 --- a/configure.ac +++ b/configure.ac @@ -50,7 +50,6 @@ AS_IF([test "x$enable_debug" = "xyes"], [ 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) -AM_CONDITIONAL([ENABLE_STANDALONE_TESTS], [test x$with_tests = xyes]) if test "x$with_tests" = "xyes"; then AC_DEFINE(LIBDBUSPOLICY_TESTS_API, 1, [Define if tests are enabled]) fi diff --git a/packaging/libdbuspolicy_tests.spec b/packaging/libdbuspolicy_tests.spec deleted file mode 100644 index d8c7feb..0000000 --- a/packaging/libdbuspolicy_tests.spec +++ /dev/null @@ -1,59 +0,0 @@ -Name: libdbuspolicy-tests -Summary: Helper library -License: Apache-2.0 -Group: Base/IPC -Version: 1.0.0 -Release: 0 -Source: %{name}-%{version}.tar.gz -BuildRequires: boost-devel -BuildRequires: pkgconfig(cynara-client) - - -%description -This package contains contains integration tests for libdbuspolicy. - -%prep -%setup -q - -%build - -%reconfigure --libdir=%{_libdir} --prefix=/usr --enable-tests - -make -make check - -%install -make DESTDIR=%{buildroot} install -rm %{buildroot}%{_libdir}/libdbuspolicy1.la -rm %{buildroot}%{_includedir}/dbuspolicy/libdbuspolicy1.h -rm %{buildroot}%{_libdir}/pkgconfig/libdbuspolicy1.pc -rm %{buildroot}%{_libdir}/libdbuspolicy1.so - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/lib/%{name} -mv %{buildroot}%{_libdir}/libdbuspolicy1.so.* %{buildroot}%{_libdir}/dbus-tests/lib/%{name} - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/runner -mv %{buildroot}%{_bindir}/test_runner %{buildroot}%{_libdir}/dbus-tests/runner/%{name} - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name} -mv %{buildroot}%{_bindir}/tests/* %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name}/ - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/configs/%{name} -install -m 0644 tests/system.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/ - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/ownerships.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/signals.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/methods.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/cynara.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0654 src/cynara_prepare.sh %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name}/ - -%post -p /sbin/ldconfig -%postun -p /sbin/ldconfig - -%files -%defattr(-,root,root) -%{_libdir}/dbus-tests/lib/%{name}/libdbuspolicy1.so.* -%{_libdir}/dbus-tests/runner/%{name} -%{_libdir}/dbus-tests/test-suites/%{name}/* -%{_libdir}/dbus-tests/configs/%{name}/* diff --git a/src/cynara_prepare.sh b/src/cynara_prepare.sh deleted file mode 100644 index acc2401..0000000 --- a/src/cynara_prepare.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -if [ -z "${1}" ]; then - cyad -e "MANIFESTS" -u 200 -c L -p t -r y - cyad -e "USER_TYPE_ADMIN" -u 200 -c L -p t -r y -else - cyad -s -k "MANIFESTS" -u 200 -c L -p t -t $1 - cyad -s -k "USER_TYPE_ADMIN" -u 200 -c L -p t -t $1 -fi diff --git a/src/dbus_daemon.c b/src/dbus_daemon.c deleted file mode 100644 index 058106e..0000000 --- a/src/dbus_daemon.c +++ /dev/null @@ -1,236 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kdbus.h" - -#define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus" - -#define KDBUS_ALIGN8(l) (((l) + 7) & ~7) -#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) -#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) -#define KDBUS_ITEM_NEXT(item) \ - (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size)) -#define KDBUS_FOREACH(iter, first, _size) \ - for (iter = (first); \ - ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ - ((uint8_t *)(iter) >= (uint8_t *)(first)); \ - iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size))) - -#define POOL_SIZE (16 * 1024 * 1024) - -#define err_r(_r, _msg) fprintf(stderr, "log: %d, %s, %s, %d, %s\n",(_r), (_msg), __func__, __LINE__, __FILE__) -#define err(_msg) err_r(errno, (_msg)) - -static uint8_t* pool; -static char* server_names[16]; -int ready_fd = 0; - -static inline int kdbus_cmd_hello(int bus_fd, struct kdbus_cmd_hello *cmd) -{ - int ret = ioctl(bus_fd, KDBUS_CMD_HELLO, cmd); - return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; -} - -static inline int kdbus_cmd_free(int conn_fd, struct kdbus_cmd_free *cmd) -{ - int ret = ioctl(conn_fd, KDBUS_CMD_FREE, cmd); - return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; -} - -static inline int kdbus_cmd_name_acquire(int conn_fd, struct kdbus_cmd *cmd) -{ - int ret = ioctl(conn_fd, KDBUS_CMD_NAME_ACQUIRE, cmd); - return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; -} - -static void bus_poool_free_slice(int fd, uint64_t offset) -{ - struct kdbus_cmd_free cmd = { - .size = sizeof(cmd), - .offset = offset, - }; - int r; - r = kdbus_cmd_free(fd, &cmd); - if (r < 0) - err_r(r, "cannot free pool slice"); -} - -static int bus_open_connection(const char *name, - uint64_t recv_flags) -{ - struct kdbus_cmd_hello hello; - int r; - int fd; - - fd = open(name, O_RDWR | O_CLOEXEC); - if (fd < 0) { - r = err("cannot open bus"); - goto error; - } - - memset(&hello, 0, sizeof(hello)); - hello.size = sizeof(hello); - hello.attach_flags_send = _KDBUS_ATTACH_ALL; - hello.attach_flags_recv = recv_flags; - hello.pool_size = POOL_SIZE; - r = kdbus_cmd_hello(fd, &hello); - if (r < 0) { - err_r(r, "HELLO failed"); - goto error; - } - - bus_poool_free_slice(fd, hello.offset); - - /* - * Map the pool of the connection. Its size has been set in the - * command struct above. See kdbus.pool(7). - */ - pool = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0); - if (pool == MAP_FAILED) { - r = err("cannot mmap pool"); - goto error; - } - - return fd; - -error: - return -1; -} - - - -static int bus_acquire_name(int fd, const char *name) -{ - struct kdbus_item *item; - struct kdbus_cmd *cmd; - size_t size; - int r; - - /* - * This function acquires a well-known name on the bus through the - * KDBUS_CMD_NAME_ACQUIRE ioctl. This ioctl takes an argument of type - * 'struct kdbus_cmd', which is assembled below. See kdbus.name(7). - */ - size = sizeof(*cmd); - size += KDBUS_ITEM_SIZE(strlen(name) + 1); - - cmd = alloca(size); - memset(cmd, 0, size); - cmd->size = size; - - /* - * The command requires an item of type KDBUS_ITEM_NAME, and its - * content must be a valid bus name. - */ - item = cmd->items; - item->type = KDBUS_ITEM_NAME; - item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - strcpy(item->str, name); - - /* - * Employ the command on the connection owner file descriptor. - */ - r = kdbus_cmd_name_acquire(fd, cmd); - if (r < 0) - return err_r(r, "cannot acquire name"); - - return 0; -} - - -int parse_args(int argc, char** argv) -{ - char state = 0; - unsigned long int uid = 0; - unsigned long int gid = 0; - int i = 1; - int r = 0; - int fdl = -1; - int count = 0; - - while (i < argc) - { - if (argv[i][0] == '-') - state = argv[i][1]; - else { - switch (state) { - - case 'n': - server_names[count++] = argv[i]; - break; - - case 'u': - uid = strtoul(argv[i],NULL,10); - r = setuid((uid_t)uid); - if (r< 0) { - fprintf(stderr, "Cannot set uid"); - exit(-3245); - } - break; - - case 'g': - gid = strtoul(argv[i],NULL,10); - r = setgid((gid_t)gid); - if (r< 0) { - fprintf(stderr, "Cannot set gid"); - exit(-3245); - } - break; - - case 'l': - fdl = open("/proc/self/attr/current", 0, S_IWUSR); - if (fdl < 0) - { - fprintf(stderr,"Cannot open /proc/self/attr/current\n"); - exit(-345); - } - - r = write(fdl, argv[i], strlen(argv[i])); - if (r < 0) - { - fprintf(stderr, "Cannot write to /proc/self/attr/current\n"); - close(fdl); - exit(-345); - } - close(fdl); - break; - case 'q': - ready_fd = strtol(argv[i], NULL, 10); - break; - } - } - i++; - } - return 0; -} - -int main(int argc, char* argv[]) { - int j = 0; - int fd; - parse_args(argc, argv); - fd = bus_open_connection(KDBUS_SYSTEM_BUS_PATH, KDBUS_ATTACH_PIDS); - if (fd < 0) { - return -1; - } - - while(server_names[j] != '\0') - { - if (bus_acquire_name(fd, server_names[j])) - return -1; - j++; - } - - close(ready_fd); - - for(;;); - return 0; -} diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 11817ad..1721185 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -51,13 +51,6 @@ #define UID_INVALID ((uid_t) -1) #define GID_INVALID ((gid_t) -1) -#ifdef LIBDBUSPOLICY_TESTS_API -#undef SYSTEM_BUS_CONF_FILE_PRIMARY -#undef SESSION_BUS_CONF_FILE_PRIMARY -#define SYSTEM_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/system.conf" -#define SESSION_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/session.conf" -#endif - /** A process ID */ typedef unsigned long dbus_pid_t; /** A user ID */ diff --git a/src/stest_common.c b/src/stest_common.c deleted file mode 100644 index 8cb9f35..0000000 --- a/src/stest_common.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include - -uint64_t test_cases_mask = ~(0ULL); -int test_count = 0; - -void assert_printf(int res, int tc, const char* value, int line, const char* file) -{ - if (res) { - printf("[r][%d]1\n", tc); - } else { - printf("[r][%d]0\n", tc); - fprintf(stderr, "[r][%d]0<-w=%s, line=%d, file=%s\n", tc, value, line, file); - } -} - -void prepare_mask(int argc, char* argv[]) -{ - if (argc > 1) - { - int i = 1; - test_cases_mask = 0; - for (;i < argc; i++) { - int val = strtol(argv[i], NULL, 10); - if (val >= 0) - test_cases_mask |= (1< - -#define assert(v) \ - do { \ - if (test_cases_mask & (1 << test_count)) \ - { \ - int ___r = (v); \ - assert_printf(___r, test_count, #v, __LINE__, __FILE__); \ - } \ - test_count++; \ - } while (0) - -enum { - false, - true -}; - -extern uint64_t test_cases_mask; -extern int test_count; -void prepare_mask(int argc, char* argv[]); -void assert_printf(int res, int tc, const char* value, int line, const char* file); diff --git a/src/stest_cynara.c b/src/stest_cynara.c deleted file mode 100644 index db885f8..0000000 --- a/src/stest_cynara.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include -#include -#include "stest_common.h" - -#define NEGATIVE_MATCH "negative" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - int result = true; - - prepare_mask(argc,argv); - - if (!strncmp(argv[0], NEGATIVE_MATCH, sizeof(NEGATIVE_MATCH)-1)) - result = false; - - printf("---result: %d %s\n\n", result, argv[0]); - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c,200,0,"L"); - assert(dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", "L", 200, 0, NULL, "cynara.interface", "cynara.method", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == result); - - assert(dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", "L", 200, 0, NULL, "cynara.interface", "cynara.method", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == result); - return 0; -} diff --git a/src/stest_method_call.c b/src/stest_method_call.c deleted file mode 100644 index 7507659..0000000 --- a/src/stest_method_call.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include "stest_common.h" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - - prepare_mask(argc,argv); - - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", NULL, "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", NULL, 0, 0, "", "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "" ,"org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test9", "org.test.test10", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test9", "org.test.test10", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test10", "org.test.test9", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test10", "org.test.test9", "", 0, 0, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - return 0; -} diff --git a/src/stest_ownership.c b/src/stest_ownership.c deleted file mode 100644 index a6c191b..0000000 --- a/src/stest_ownership.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include "stest_common.h" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - - prepare_mask(argc,argv); - - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test1")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test1")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test2")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test2")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test3")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test3")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test4")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test4")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test5")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test6")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test7")); - - assert(dbuspolicy1_can_own(c, "a.b.c")); - assert(dbuspolicy1_can_own(c, "a.b")); - assert(!dbuspolicy1_can_own(c, "c")); - assert(!dbuspolicy1_can_own(c, "a.c")); - assert(!dbuspolicy1_can_own(c, "b.c")); - - return 0; -} diff --git a/src/stest_signal.c b/src/stest_signal.c deleted file mode 100644 index 165c90e..0000000 --- a/src/stest_signal.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include "stest_common.h" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - - prepare_mask(argc,argv); - - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "", "bli.bla.blubb test.test1 test.tes3", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5010,0,NULL); - assert(dbuspolicy1_check_out(c, "", "bli.bla.blubb", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == false); - - return 0; -} diff --git a/src/test_runner.c b/src/test_runner.c deleted file mode 100644 index 81c4e0e..0000000 --- a/src/test_runner.c +++ /dev/null @@ -1,699 +0,0 @@ -/* This file contains test-runner for libdbuspolicy - * - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * Author: Kazimierz Krosman - * - * 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. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "test_runner.h" - -enum { - PIPE_READ, - PIPE_WRITE, -}; - -/*****************CUSTOM SECTION***********************************/ -/*custom function that parse stdout of binary and result of binary*/ -void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); -void parse_one_test_one_binary(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); -char** prepare_args_for_binary(const struct binary* b, const char* test_name); -int daemon_init(void); -int daemon_clear(void); -int cynara_init(void); -int cynara_clear(void); -int cynara_n_init(void); -int cynara_n_clear(void); - -static struct test_case ownership_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "Simple check for ownership in default context"}, - {"2", "Simple check for ownership in default context"}, - {"3", "Ownership check in user context"}, - {"4", "Ownership check in user context (negative test)"}, - {"5", "Ownership check in mandatory context with user context (context priority check)"}, - {"6", "Ownership check in mandatory context with user context (for another user)"}, - {"7", "Ownership check for not root user context (negative test)"}, - {"8", "Ownership check for not root user context"}, - {"9", "Ownership check for group context"}, - {"10", "Ownership check for all context (priority check)"}, - {"11", "Ownership check for all context (priority check)"}, - {"12", "Ownership check for own_prefix case (1)"}, - {"13", "Ownership check for own_prefix case (2)"}, - {"14", "Ownership check for own_prefix case (negative test)"}, - {"15", "Ownership check for own_prefix case (negative test)"}, - {"16", "Ownership check for own_prefix case (negative test)"}, - {NULL, NULL} -}; - -static struct test_case method_call_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "check_out test"}, - {"2", "check_in test"}, - {"3", "check_out test"}, - {"4", "check_in test"}, - {"5", "check_out test"}, - {"6", "check_in test"}, - {"7", "check_out test"}, - {"8", "check_in test"}, - {"9", "check_out test"}, - {"10", "check_in test"}, - {"11", "check_out test"}, - {"12", "check_in test"}, - {"13", "check_out test"}, - {"14", "check_in test"}, - {"15", "check_out test"}, - {"16", "check_in test"}, - {"17", "check_out test"}, - {"18", "check_in test"}, - {"19", "check_out test"}, - {"20", "check_in test"}, - {NULL, NULL} -}; - -static struct test_case signal_test_cases[] = { - {"1", "Libdbuspolicy1 init"}, - {"2", "Check out for signal"}, - {"3", "Check out for signal (negative)"}, - {NULL, NULL} -}; - -static struct test_case cynara_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "Check cynara for result"}, - {"2", "Check cynara for result (second attempt to use cache)"}, - {NULL, NULL} -}; - -static struct test_case negative_cynara_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "Check cynara for result (negative test)"}, - {"2", "Check cynara for result (second attempt to use cache) (negative test)"}, - {NULL, NULL} -}; - -/* This table is used to start binaries */ -struct binary tests[] = { -/*path, name, TC_table, timeout in us, prepare_args_handler, parse_function_handler, init_handler, clean_handler*/ - {TEST_PATH "stest_ownership", "ownership", ownership_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, - {TEST_PATH "stest_method_call", "method_call", method_call_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, - {TEST_PATH "stest_signal", "signal", signal_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, - {TEST_PATH "stest_cynara", "cynara", cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_init, cynara_clear}, - {TEST_PATH "stest_cynara", "negative_cynara", negative_cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_n_init, cynara_n_clear}, -}; - - -static const char result_pattern[] = "[r][%0]%1"; -static struct state { - unsigned int i; // index of input buffer - unsigned int j; // index in results[n] - unsigned int n; //index in results buffer (0 or 1) - char results[2][MAX_COMMENT]; -} g_state; - -static void sm_reset(void) -{ - memset(&g_state, 0, sizeof (g_state)); -} - -static int sm_update(char* buffer, int i) -{ - int l = strlen(buffer) + 1; - while (i < l && g_state.i < sizeof(result_pattern) - 1) { - if (result_pattern[g_state.i] == '%') { - g_state.n = result_pattern[g_state.i+1] - '0'; - if (g_state.n > 1) { - sm_reset(); - i--; - } else if (isalnum(buffer[i])) { - g_state.results[g_state.n][g_state.j++] = buffer[i]; - } else if (buffer[i] == result_pattern[g_state.i+2] || buffer[i] == '\n') { - g_state.results[g_state.n][g_state.j] = 0; - g_state.i += 3; - g_state.j = 0; - if (g_state.n == 1) - return i; - } else { - g_state.i = 0; - g_state.j = 0; - } - } else if (result_pattern[g_state.i] == buffer[i]) { - g_state.i++; - } else { - sm_reset(); - } - i++; - } - - if (g_state.i >= sizeof(result_pattern) - 1) { - g_state.results[g_state.n][g_state.j] = 0; - g_state.i += 3; - g_state.j = 0; - if (g_state.n == 1) - return i; - } - - return 0; -} - -static const char* sm_get_result(int i) -{ - return g_state.results[i]; -} - -static pid_t daemon_pids[4] ={0}; -static int daemons_pipe[4][2]; -static char* daemon_argv1[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n","org.test.test3", NULL}; -static char* daemon_argv2[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test2", "-g", "100", "-u", "5001", NULL}; -static char* daemon_argv3[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test12", "org.test.test9", NULL}; -static char* daemon_argv4[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n", "org.test.test13", "org.test.test10", "org.test.test11", "-g", "100", "-u", "5001", NULL}; -static char** daemons[] = { daemon_argv1, daemon_argv2, daemon_argv3, daemon_argv4}; - -int daemon_init(void) -{ - int i = 0; - int ready_proc = 0; - struct timeval tv; - fd_set rfds; - int nfds = -1; - int proc_num = sizeof(daemons)/sizeof(daemons[0]); - - for (;i < proc_num;i++) { - if (pipe(daemons_pipe[i]) < 0) { - perror("cannot create pipe"); - goto error1; - } - - daemon_pids[i] = fork(); - if (!daemon_pids[i]) { - char fdd[15]; - sprintf(fdd,"%d",daemons_pipe[i][PIPE_WRITE]); - daemons[i][2] = fdd; - close (daemons_pipe[i][PIPE_READ]); - (void)execv(daemons[i][0],daemons[i]); - exit(0); - } else if (daemon_pids[i] > 0){ - close (daemons_pipe[i][PIPE_WRITE]); - } else - goto error1; - } - - tv.tv_sec = 1; - tv.tv_usec = 0; - while(1) { - FD_ZERO(&rfds); - for (i = 0; i < proc_num;i++) { - if (daemons_pipe[i][PIPE_READ] > -1) - FD_SET(daemons_pipe[i][PIPE_READ], &rfds); - } - - if (ready_proc >= proc_num) - break; - - nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); - if (nfds > 0) { - for (i = 0; i < proc_num;i++) { - if (daemons_pipe[i][PIPE_READ] > -1 && FD_ISSET(daemons_pipe[i][PIPE_READ], &rfds)) { - ++ready_proc; - close (daemons_pipe[i][PIPE_READ]); - daemons_pipe[i][PIPE_READ] = -1; - } - } - } else - goto error1; - } - - return 1; -error1: - daemon_clear(); - return 0; -} - -int daemon_clear(void) -{ - unsigned int i = 0; - for (;i < sizeof(daemons)/sizeof(daemons[0]);i++) { - if (daemon_pids[i]) - kill(daemon_pids[i], SIGKILL); - } - return 0; -} - -static int call_script(char* path, char* argv[]) -{ - int status; - int r; - pid_t pid = fork(); - - if (pid < 0) - return 0; - else if (!pid) { - (void)execv(path, argv); - exit(-1); - } - - r = waitpid(pid, &status, 0); - if (r > 0) { - if (WIFEXITED(status)) - return !(WEXITSTATUS(status)); - else if (WIFCONTINUED(status)) - kill(pid, SIGKILL); - } - - /* fail */ - return 0; -} - -int cynara_n_init(void) -{ - char* argv[] = {CYNARA_PATH, "DENY", NULL}; - return call_script(argv[0],argv); -} - -int cynara_n_clear(void) -{ - return cynara_clear(); -} - -int cynara_init(void) -{ - char* argv[] = {CYNARA_PATH, "ALLOW", NULL}; - return call_script(argv[0],argv); -} - -int cynara_clear(void) -{ - char* argv[] = {CYNARA_PATH, NULL}; - return call_script(argv[0],argv); -} - -static char* args[3]; -char** prepare_args_for_binary(const struct binary* b, const char* test_name) -{ - args[0] = (char*)b->name; - if (!test_name[0]) - args[1] = NULL; - else { - args[1] = (char*)test_name; - args[2] = NULL; - } - return args; -} - - -/* - * Example of test_result detector function implementation - */ -void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option) -{ - char test_id[MAX_COMMENT]; - - switch(state_change) { - case INIT_TEST: - sm_reset(); - break; - case NEW_STDOUT: - { - int k = 0; - buffer[state_option] = 0; - get_test_id(test_id, b, test_name); - fprintf(stderr, "[stdout][%s]%s\n",test_id, buffer); - while ( (k = sm_update(buffer, k))) { - const char* t_name = sm_get_result(0); - const char* result_code = sm_get_result(1); - bool is_successful = result_code[0] == '1' && result_code[1] == 0; - const char* result_text = is_successful ? "PASS" : "FAIL"; - - get_test_id(test_id, b, t_name); - add_test_result(test_id, result_text, "", is_successful); - sm_reset(); - } - } - break; - case NEW_STDERR: - buffer[state_option] = 0; - get_test_id(test_id, b, test_name); - fprintf(stderr, "[stderr][%s]%s\n",test_id, buffer); - break; - case RESULT_CODE: - if (state_option != 0) - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Test exited with error code", 0); - break; - case RESULT_SIGNAL: - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Finished by SIGNAL", 0); - break; - case RESULT_TIMEOUT: - add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Test TIMEOUT", 0); - break; - } -} - -/****************************END of CUSTOM FUNCTIONS************************/ - - -static struct option long_options[] = { - {"list", no_argument, 0, 'l'}, - {"run", required_argument, 0, 'r'}, - {"description", required_argument, 0, 'd'}, - {0, 0, 0, 0 } -}; - -static int stdin_pipe[2]; -static int stdout_pipe[2]; -static int stderr_pipe[2]; -static struct test_result test_results[MAX_TC_NUM]; -static int test_results_i; -static char buffer[MAX_BUFFER]; -static const char* requested_tc[MAX_TC_NUM]; - -char* get_test_id(char* dest, const struct binary* b, const char* test_name) -{ - int len = strlen(b->name); - memcpy(dest, b->name, len); - memcpy(dest + len, test_name, strlen(test_name)+1); - return dest; -} - -static void print_description(const char* name, const char* description) -{ - printf("%s;%s\n",name, description); -} - -static void print_list(const char* test_name) -{ - unsigned int i; - char full_name[MAX_COMMENT]; - for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { - int j = 0; - int l = strlen(tests[i].name); - memcpy(full_name, tests[i].name, l+1); - if (test_name && strncmp(test_name, full_name, l) != 0) - continue; - - while (tests[i].test_cases[j].name) { - memcpy(full_name + l, tests[i].test_cases[j].name, strlen(tests[i].test_cases[j].name) + 1); - if (!test_name || strcmp(full_name, test_name) == 0) - print_description(full_name,tests[i].test_cases[j].description); - j++; - } - } -} - - -static void stop_binary(const struct binary* b, pid_t pid, const char* test_name) -{ - int status = 0; - int res = 0; - res = waitpid(pid, &status, 0); - if (res == 0) { - //timeouted - kill(pid, SIGKILL); - res = waitpid(pid, &status, WNOHANG); - b->parse(b, test_name, buffer, RESULT_TIMEOUT, res); - } else if (res < 0) { - //errno check - kill(pid, SIGKILL); - res = waitpid(pid, &status, WNOHANG); - b->parse(b, test_name, buffer, RESULT_ERROR, res); - } else if (res > 0) { - if (WIFEXITED(status)) { - b->parse(b, test_name, buffer, RESULT_CODE, WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - b->parse(b, test_name, buffer, RESULT_SIGNAL, WTERMSIG(status)); - } else if (WIFSTOPPED(status)) { - b->parse(b, test_name, buffer, RESULT_SIGNAL, WSTOPSIG(status)); - } else if (WIFCONTINUED(status)) { - kill(pid, SIGKILL); - b->parse(b, test_name, buffer, RESULT_SIGNAL, -1); - } - } -} - -static void parse_output_with_timeout(const struct binary* b, pid_t pid, const char* test_name) -{ - struct timeval tv; - fd_set rfds; - int nfds; - int res; - tv.tv_sec = b->timeout/(1000*1000); - tv.tv_usec = (b->timeout-tv.tv_sec*1000*1000); - while (1) { - FD_ZERO(&rfds); - FD_SET(stdout_pipe[PIPE_READ], &rfds); - FD_SET(stderr_pipe[PIPE_READ], &rfds); - nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); - if (nfds == -1) { - if (errno != EINTR) - break; - } else if (nfds > 0) { - if (FD_ISSET(stdout_pipe[PIPE_READ], &rfds)) { - res = read(stdout_pipe[PIPE_READ], buffer, MAX_BUFFER-1); - if (res == 0 || (res < 0 && errno != EINTR)) - break; - else if (res >=0) - b->parse(b, test_name, buffer, NEW_STDOUT, res); - } - - if (FD_ISSET(stderr_pipe[PIPE_READ], &rfds)) { - res = read(stderr_pipe[PIPE_READ], buffer, MAX_BUFFER-1); - if (res == 0 || (res < 0 && errno != EINTR)) - break; - b->parse(b, test_name, buffer, NEW_STDERR, res); - } - } else { - //timeout - break; - } - } - stop_binary(b, pid, test_name); -} - -static int create_child(const char* path, char* const arguments[]) -{ - int child; - int nResult; - if (pipe(stdin_pipe) < 0) { - perror("allocating pipe for child input redirect failed"); - goto error1; - } - - if (pipe(stdout_pipe) < 0) { - perror("allocating pipe for child output redirect failed"); - goto error2; - } - - if (pipe(stderr_pipe) < 0) { - perror("allocating pipe for child output redirect failed"); - goto error3; - } - - child = fork(); - if (!child) { - char ld_path[512]; - sprintf(ld_path, "/usr/lib/dbus-tests/lib/libdbuspolicy-tests/:"); - // redirect stdin - if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1) { - perror("redirecting stdin failed"); - return -1; - } - - // redirect stdout - if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1) { - perror("redirecting stdout failed"); - return -1; - } - - // redirect stderr - if (dup2(stderr_pipe[PIPE_WRITE], STDERR_FILENO) == -1) { - perror("redirecting stderr failed"); - return -1; - } - - // all these are for use by parent only - close(stdin_pipe[PIPE_READ]); - close(stdin_pipe[PIPE_WRITE]); - close(stdout_pipe[PIPE_READ]); - close(stdout_pipe[PIPE_WRITE]); - close(stderr_pipe[PIPE_READ]); - close(stderr_pipe[PIPE_WRITE]); - - char* ld_path_b = getenv("LD_LIBRARY_PATH"); - if (ld_path_b != NULL) - memcpy(ld_path + strlen(ld_path), ld_path_b, strlen(ld_path_b)+1); - setenv("LD_LIBRARY_PATH", ld_path, 1); - // run child process image - nResult = execv(path, arguments); - - // if we get here at all, an error occurred, but we are in the child - // process, so just exit - perror("exec of the child process failed"); - exit(nResult); - } else if (child > 0) { - // parent continues here - - // close unused file descriptors, these are for child only - close(stdin_pipe[PIPE_READ]); - close(stdout_pipe[PIPE_WRITE]); - close(stderr_pipe[PIPE_WRITE]); - } else { - // failed to create child - goto error4; - } - - return child; - -error4: - close(stderr_pipe[PIPE_READ]); - close(stderr_pipe[PIPE_WRITE]); -error3: - close(stdout_pipe[PIPE_READ]); - close(stdout_pipe[PIPE_WRITE]); -error2: - close(stdin_pipe[PIPE_READ]); - close(stdin_pipe[PIPE_WRITE]); -error1: - return -1; -} - -static void run_test(const struct binary* b, const char* test_name) -{ - int res = -1; - char** arg; - char test_id[MAX_COMMENT]; - - assert(b); - assert(b->name); - assert(b->path); - assert(test_name); - - arg = b->prepare_args(b, test_name); - - if (b->init) - if (!b->init()) { - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot init test", 0); - return; - } - - res = create_child(b->path, arg); - if (res > 0) - parse_output_with_timeout(b, res, test_name); - else - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot start test", 0); - - if (b->clean) - b->clean(); -} - -static void parse_run_test(const char* tc) { - unsigned int i = 0; - for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { - int len = strlen(tests[i].name); - if (strncmp(tc, tests[i].name, len) == 0) { - if (tc[len] == '*' || tc[len] == '\0') - run_test(&tests[i], ""); - else - run_test(&tests[i], tc + len); - } - } -} - -static int parse_option(int argc, char* argv[]) -{ - int ch = 0; - int c = 0; - while ((ch = getopt_long(argc, argv, "lr:d:", long_options, NULL)) != -1) { - switch (ch) { - case 'l': - print_list(NULL); - return 1; - case 'r': - if (c >= MAX_TC_NUM - 1) //NULL at the end - return 0; - - if (optarg) - requested_tc[c++] = optarg; - - break; - case 'd': - print_list(optarg); - return 1; - } - } - return 0; -} - -//output_new/fail/success -void add_test_result(const char* test_id, const char* result, const char* comment, int res) -{ - test_results[test_results_i].is_positive = res; - strcpy(test_results[test_results_i].result, result); - strcpy(test_results[test_results_i].comment, comment); - strcpy(test_results[test_results_i++].name, test_id); -} - -static void prepare_results(void) -{ - //todo -} - -static void print_results() -{ - int i = 0; - for (i = 0; i < test_results_i; i++) - { - printf("%s;%s;%s\n", test_results[i].name, test_results[i].result, test_results[i].comment); - } -} - -int main(int argc, char* argv[]) -{ - unsigned int i; - signal(SIGPIPE, SIG_IGN); - if (parse_option(argc, argv)) - return 0; - - prepare_results(); - - if (!requested_tc[0]) { - for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) - run_test(&tests[i], ""); - } else { - i = 0; - while(requested_tc[i]) { - parse_run_test(requested_tc[i]); - i++; - } - } - - print_results(); - return 0; -} diff --git a/src/test_runner.h b/src/test_runner.h deleted file mode 100644 index 3c79a99..0000000 --- a/src/test_runner.h +++ /dev/null @@ -1,69 +0,0 @@ -/* This file is part of test-runner (see template.c) - * - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * Author: Kazimierz Krosman - * - * 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 TEST_RUNNER_H -#define TEST_RUNNER_H -#include - -#define TC_NAME "libdbuspolicy-tests" -#define TEST_PATH "/usr/lib/dbus-tests/test-suites/libdbuspolicy-tests/" -#define CYNARA_PATH TEST_PATH "cynara_prepare.sh" -#define MAX_TC_NUM 1024 -#define MAX_BUFFER (64*1024) -#define MAX_COMMENT 1024 - -enum { - INIT_TEST, - NEW_STDOUT, - NEW_STDERR, - RESULT_CODE, - RESULT_SIGNAL, - RESULT_ERROR, - RESULT_TIMEOUT -}; - -struct test_result { - bool is_positive; - char comment[MAX_COMMENT]; - char result[MAX_COMMENT]; - char name[MAX_COMMENT]; -}; - -struct test_case { - const char* name; - const char* description; -}; - -struct binary { - const char* path; - const char* name; - /* can be filled by asking binary */ - struct test_case* test_cases; - int timeout; - - char** (*prepare_args) (const struct binary* b, const char* test_name); - void (*parse) (const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); - int (*init)(void); - int (*clean)(void); -}; - -char* get_test_id(char* dest, const struct binary* b, const char* test_name); -void add_test_result(const char* test_id, const char* result, const char* comment, int res); - - -#endif /* TEST_RUNNER_H */ -- 2.7.4 From 259df82e824f82949e024f8852a310d6a08e9271 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Tue, 6 Dec 2016 21:22:59 +0900 Subject: [PATCH 16/16] svace:handling wrong policy syntax Change-Id: I6230b4487625240a0ee9f422c0203f0ec33a5d19 Signed-off-by: sanghyeok.oh --- src/internal/policy.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) mode change 100644 => 100755 src/internal/policy.cpp diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp old mode 100644 new mode 100755 index d4ab166..3bc5fce --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -19,6 +19,9 @@ static const char* message_dir[] = { "ANY", "SEND", "RECEIVE"}; static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"}; static MessageType __str_to_message_type(const char* str) { + if (!str) + return MessageType::ANY; + if (!std::strcmp(str, "method_call")) return MessageType::METHOD_CALL; else if (!std::strcmp(str, "method_return")) @@ -113,23 +116,22 @@ void DbAdapter::updateDecision(const boost::property_tree::ptree::value_type& v, 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; + if (value) { + 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 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() != "*") -- 2.7.4