From 18e4ddb82a037b7c31b488ffcd96a36a8f32218c Mon Sep 17 00:00:00 2001 From: "sangwan.kwon" Date: Mon, 15 Feb 2016 17:38:28 +0900 Subject: Change package event handler API * Dbus API -> pkgmgrinfo API Change-Id: Ia7a8d84e7eaf35d5be5d077b753ec1915b1b49d0 Signed-off-by: sangwan.kwon --- packaging/cert-checker.spec | 4 +- src/CMakeLists.txt | 2 + src/include/cchecker/logic.h | 45 ++++--- src/logic.cpp | 284 +++++++++++++++++++++++++++---------------- tests/CMakeLists.txt | 2 + 5 files changed, 215 insertions(+), 122 deletions(-) diff --git a/packaging/cert-checker.spec b/packaging/cert-checker.spec index bfd5dc0..c7ae00c 100644 --- a/packaging/cert-checker.spec +++ b/packaging/cert-checker.spec @@ -1,6 +1,6 @@ Name: cert-checker Summary: OCSP checking on application installation -Version: 0.0.1 +Version: 0.0.2 Release: 1 Group: System/Security License: Apache-2.0 @@ -21,6 +21,8 @@ BuildRequires: pkgconfig(key-manager) BuildRequires: pkgconfig(libsystemd-journal) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(pkgmgr) +BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: boost-devel %description diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 76a91d1..b12f8d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,8 @@ PKG_CHECK_MODULES(CERT_CHECKER_DEP libsystemd-journal libtzplatform-config sqlite3 + pkgmgr + pkgmgr-info ) SET(CERT_CHECKER_SRC_PATH ${PROJECT_SOURCE_DIR}/src) diff --git a/src/include/cchecker/logic.h b/src/include/cchecker/logic.h index 6700333..1ad9cd4 100644 --- a/src/include/cchecker/logic.h +++ b/src/include/cchecker/logic.h @@ -29,11 +29,15 @@ #include #include #include +#include #include #include #include +#include +#include + namespace CCHECKER { namespace DB { @@ -61,23 +65,12 @@ class Logic { error_t setup(void); virtual void clean(void); - static void pkgmgr_install_callback(GDBusProxy *proxy, - gchar *sender_name, - gchar *signal_name, - GVariant *parameters, - void *logic_ptr); - static void pkgmgr_uninstall_callback(GDBusProxy *proxy, - gchar *sender_name, - gchar *signal_name, - GVariant *parameters, - void *logic_ptr); static void connman_callback(GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, void *logic_ptr); - protected: error_t setup_db(); void load_database_to_buffer(); @@ -87,7 +80,6 @@ class Logic { void remove_app_from_buffer_and_database(const app_t &app); void set_connman_online_state(); - void pkgmgr_callback_internal(GVariant *parameters, pkgmgr_event_t event); error_t register_dbus_signal_handler(GDBusProxy **proxy, const char *name, const char *object_path, @@ -99,6 +91,28 @@ class Logic { void *logic_ptr) ); + static int pkgmgrinfo_event_handler_static( + uid_t uid, + int reqid, + const char *pkgtype, + const char *pkgid, + const char *key, + const char *val, + const void *pmsg, + void *data); + + int pkgmgrinfo_event_handler( + uid_t uid, + int reqid, + const char *pkgtype, + const char *pkgid, + const char *key, + const char *val, + const void *pmsg, + void *data); + + int push_pkgmgrinfo_event(uid_t uid, const char *pkgid); + void push_event(event_t event); void process_all(void); @@ -132,8 +146,11 @@ class Logic { bool m_should_exit; GDBusProxy *m_proxy_connman; - GDBusProxy *m_proxy_pkgmgr_install; - GDBusProxy *m_proxy_pkgmgr_uninstall; + + int m_reqid_install; + int m_reqid_uninstall; + std::unique_ptr m_pc_install; + std::unique_ptr m_pc_uninstall; }; } // CCHECKER diff --git a/src/logic.cpp b/src/logic.cpp index 346a19c..6326e1d 100644 --- a/src/logic.cpp +++ b/src/logic.cpp @@ -27,11 +27,49 @@ #include #include +#include + using namespace std; namespace CCHECKER { namespace { +struct PkgmgrinfoEvent { + PkgmgrinfoEvent(uid_t _uid, const char *_pkgid) + : uid(_uid) + , pkgid(_pkgid) {} + + inline bool operator==(const PkgmgrinfoEvent &rhs) const + { + return uid == rhs.uid && pkgid.compare(rhs.pkgid) == 0; + } + + inline bool operator<(const PkgmgrinfoEvent &rhs) const + { + if (uid < rhs.uid) + return true; + else if (uid < rhs.uid) + return false; + else + return pkgid.compare(rhs.pkgid) < 0; + } + + inline bool operator>(const PkgmgrinfoEvent &rhs) const + { + if (uid > rhs.uid) + return true; + else if (uid < rhs.uid) + return false; + else + return pkgid.compare(rhs.pkgid) > 0; + } + + uid_t uid; + std::string pkgid; + pkgmgr_event_t type; +}; + +std::set pkgmgrinfo_event_set; const char *const DB_PATH = tzplatform_mkpath(TZ_SYS_DB, ".cert-checker.db"); } @@ -60,10 +98,7 @@ void Logic::clean(void) if (m_proxy_connman) g_object_unref(m_proxy_connman); - if (m_proxy_pkgmgr_install) - g_object_unref(m_proxy_pkgmgr_install); - if (m_proxy_pkgmgr_uninstall) - g_object_unref(m_proxy_pkgmgr_uninstall); + delete m_sqlquery; } @@ -74,8 +109,8 @@ Logic::Logic(void) : m_is_online_enabled(false), m_should_exit(false), m_proxy_connman(NULL), - m_proxy_pkgmgr_install(NULL), - m_proxy_pkgmgr_uninstall(NULL) + m_pc_install(nullptr, nullptr), + m_pc_uninstall(nullptr, nullptr) {} bool Logic::get_online() const @@ -134,33 +169,6 @@ error_t Logic::setup() // run process thread - thread will be waiting on condition variable m_thread = std::thread(&Logic::process_all, this); - // FIXME: pkgmanager API signal handling was temporarily replaced - // by dbus API - - // Add pkgmgr install callback - LogDebug("register pkgmgr install event callback start"); - if (register_dbus_signal_handler(&m_proxy_pkgmgr_install, - "org.tizen.slp.pkgmgr_status", - "/org/tizen/slp/pkgmgr/install", - "org.tizen.slp.pkgmgr.install", - pkgmgr_install_callback) != NO_ERROR) { - LogError("Error in register_pkgmgr_install_signal_handler"); - return REGISTER_CALLBACK_ERROR; - } - LogDebug("register pkgmgr install event callback success"); - - // Add pkgmgr uninstall callback - LogDebug("register pkgmgr uninstall event callback start"); - if (register_dbus_signal_handler(&m_proxy_pkgmgr_uninstall, - "org.tizen.slp.pkgmgr_status", - "/org/tizen/slp/pkgmgr/uninstall", - "org.tizen.slp.pkgmgr.uninstall", - pkgmgr_uninstall_callback) != NO_ERROR) { - LogError("Error in register_pkgmgr_uninstall_signal_handler"); - return REGISTER_CALLBACK_ERROR; - } - LogDebug("register pkgmgr uninstall event callback success"); - // Add connman callback LogDebug("register connman event callback start"); if (register_dbus_signal_handler(&m_proxy_connman, @@ -175,9 +183,145 @@ error_t Logic::setup() set_connman_online_state(); + // Add pkgmgrinfo callback + LogDebug("Register package event handler start"); + + std::unique_ptr + _pcInstall(pkgmgrinfo_client_new(PMINFO_LISTENING), pkgmgrinfo_client_free); + std::unique_ptr + _pcUninstall(pkgmgrinfo_client_new(PMINFO_LISTENING), pkgmgrinfo_client_free); + m_pc_install = std::move(_pcInstall); + m_pc_uninstall = std::move(_pcUninstall); + + if (!m_pc_install || !m_pc_uninstall) { + LogError("Get pkgmgrinfo client failed"); + return REGISTER_CALLBACK_ERROR; + } + + int ret_status_install; + int ret_status_uninstall; + ret_status_install = pkgmgrinfo_client_set_status_type( + m_pc_install.get(), PKGMGR_CLIENT_STATUS_INSTALL); + ret_status_uninstall = pkgmgrinfo_client_set_status_type( + m_pc_uninstall.get(), PKGMGR_CLIENT_STATUS_UNINSTALL); + + if (ret_status_install == PMINFO_R_ERROR || ret_status_uninstall == PMINFO_R_ERROR) { + LogError("Set pkgmgrinfo status fail"); + return REGISTER_CALLBACK_ERROR; + } + m_reqid_install = pkgmgrinfo_client_listen_status( + m_pc_install.get(), pkgmgrinfo_event_handler_static, this); + m_reqid_uninstall = pkgmgrinfo_client_listen_status( + m_pc_uninstall.get(), pkgmgrinfo_event_handler_static, this); + + if (m_reqid_install < 0 || m_reqid_uninstall < 0) { + LogError("Register pacakge install event handler fail"); + return REGISTER_CALLBACK_ERROR; + } + + LogDebug("Register package event handler success"); + return NO_ERROR; } +int Logic::pkgmgrinfo_event_handler_static( + uid_t uid, + int reqid, + const char *pkgtype, + const char *pkgid, + const char *key, + const char *val, + const void *pmsg, + void *data) +{ + LogDebug("pkgmgrinfo event handler start!!"); + if (data == nullptr) + return -1; + + std::string keyStr(key); + std::string valStr(val); + LogDebug("pkgmgrinfo event was caught. type : " << valStr << ", status : " << keyStr); + + if ((valStr.compare("install") == 0 || valStr.compare("uninstall") == 0) + && keyStr.compare("start") == 0) { + return static_cast(data)->pkgmgrinfo_event_handler( + uid, reqid, pkgtype, pkgid, key, val, pmsg, data); + } else if (keyStr.compare("end") == 0 && valStr.compare("ok") == 0) { + return static_cast(data)->push_pkgmgrinfo_event(uid, pkgid); + } else { + LogDebug("Untreated event was caught : " << val); + return -1; + } +} + +int Logic::pkgmgrinfo_event_handler( + uid_t uid, + int reqid, + const char */*pkgtype*/, + const char *pkgid, + const char *key, + const char *val, + const void */*pmsg*/, + void */*data*/) +{ + if (pkgid == nullptr || key == nullptr || val == nullptr) { + LogError("Invalid parameter."); + return -1; + } + + std::string keyStr(key); + std::string valStr(val); + + LogDebug("uid: " << uid << " pkgid: " << pkgid << " key: " << keyStr << " val: " << valStr); + + PkgmgrinfoEvent event(uid, pkgid); + + if(valStr.compare("install") == 0) { + if (reqid != m_reqid_install) { + LogError("pkgmgrinfo event reqid unmatched"); + return -1; + } + event.type = EVENT_INSTALL; + } else if(valStr.compare("uninstall") == 0) { + if (reqid != m_reqid_uninstall) { + LogError("pkgmgrinfo event reqid unmatched"); + return -1; + } + event.type = EVENT_UNINSTALL; + } + + pkgmgrinfo_event_set.insert(event); + + return 0; +} + +int Logic::push_pkgmgrinfo_event(uid_t uid, const char *pkgid) +{ + PkgmgrinfoEvent event(uid, pkgid); + std::set::iterator pkgmgrinfo_event_iter = pkgmgrinfo_event_set.find(event); + + if (pkgmgrinfo_event_iter != pkgmgrinfo_event_set.end()) { + // FIXME: No information about app_id in the signal. Use stub. + app_t app(TEMP_APP_ID, pkgid, uid, {}); + + if (pkgmgrinfo_event_iter->type == EVENT_INSTALL) { + LogDebug("Successfully Installed. uid: " << uid << ", pkgid: " << pkgid); + push_event(event_t(app, event_t::event_type_t::APP_INSTALL)); + } else if (pkgmgrinfo_event_iter->type == EVENT_UNINSTALL) { + LogDebug("Successfully Uninstalled. uid: " << uid << ", pkgid: " << pkgid); + push_event(event_t(app, event_t::event_type_t::APP_UNINSTALL)); + } + + LogDebug("push pkgmgrifo success. pkgid: " << pkgid << ", uid: " << uid); + pkgmgrinfo_event_set.erase(event); + return 0; + } else { + // if update status, return fail + LogDebug("push pkgmgrifo fail. pkgid: " << pkgid << ", uid: " << uid); + return -1; + } +} + error_t Logic::register_dbus_signal_handler(GDBusProxy **proxy, const char *name, const char *object_path, @@ -266,80 +410,6 @@ void Logic::set_connman_online_state() g_variant_unref(response); } -// FIXME: pkgmgr callback doesn't receive signals with successful installation/uninstallation. -// For now it will be replaced by low-level signal handling from DBUS. -void Logic::pkgmgr_install_callback(GDBusProxy */*proxy*/, - gchar */*sender_name*/, - gchar */*signal_name*/, - GVariant *parameters, - void *logic_ptr) -{ - LogDebug("----------------- pkgmgr_install_callback -----------------\n"); - - Logic *logic = static_cast (logic_ptr); - logic->pkgmgr_callback_internal(parameters, EVENT_INSTALL); -} - -void Logic::pkgmgr_uninstall_callback(GDBusProxy */*proxy*/, - gchar */*sender_name*/, - gchar */*signal_name*/, - GVariant *parameters, - void *logic_ptr) -{ - LogDebug("----------------- pkgmgr_uninstall_callback -----------------\n"); - - Logic *logic = static_cast (logic_ptr); - logic->pkgmgr_callback_internal(parameters, EVENT_UNINSTALL); -} - -void Logic::pkgmgr_callback_internal(GVariant *parameters, - pkgmgr_event_t event) -{ - gchar *parameters_g = g_variant_print(parameters, TRUE); - std::string params_str = std::string(parameters_g); - LogDebug("params: " << params_str); - g_free (parameters_g); - - /* DBus message format from pkgmgr: - * uint32 5001 - * string "/usr/share/widget_demo/mancala.wgt_-427832739" - * string "wgt" - * string "yKrWwxz1KX" - * string "end" - * string "ok" - * - * Check if numbers of children (vaules) fits - should be 6: - */ - int num = g_variant_n_children(parameters); - if (num != 6) { - LogError("Wrong number of children in g_variant: " << num << ", but should be 6."); - return; - } - - guint32 uid = g_variant_get_uint32(g_variant_get_child_value(parameters, 0)); - const gchar *pkgid = g_variant_get_string(g_variant_get_child_value(parameters, 3), NULL); - const gchar *state = g_variant_get_string(g_variant_get_child_value(parameters, 4), NULL); - const gchar *status = g_variant_get_string(g_variant_get_child_value(parameters, 5), NULL); - - // FIXME: No information about app_id in the signal. Use stub. - app_t app(TEMP_APP_ID, pkgid, uid, {}); - - if (std::string(state) == "end" && std::string(status) == "ok") { - if (event == EVENT_INSTALL) { - LogDebug("Install: uid : " << uid << ", pkgid: " << pkgid << - ", state: " << state << ", status: " << status); - push_event(event_t(app, event_t::event_type_t::APP_INSTALL)); - } - else if (event == EVENT_UNINSTALL) { - LogDebug("Uninstall: uid : " << uid << ", pkgid: " << pkgid << - ", state: " << state << ", status: " << status); - push_event(event_t(app, event_t::event_type_t::APP_UNINSTALL)); - } - } - else - LogDebug("Wrong state (" << std::string(state) << ") or status (" << std::string(status) << ")"); -} - void Logic::connman_callback(GDBusProxy */*proxy*/, gchar */*sender_name*/, gchar *signal_name, diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 511aeb9..4f3337b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -13,6 +13,8 @@ PKG_CHECK_MODULES(CERT_CHECKER_TESTS_DEP libsystemd-journal libtzplatform-config sqlite3 + pkgmgr + pkgmgr-info ) FIND_PACKAGE(Threads REQUIRED) -- cgit v1.2.3