diff options
Diffstat (limited to 'src/service')
-rw-r--r-- | src/service/app.cpp | 57 | ||||
-rw-r--r-- | src/service/app.h | 38 | ||||
-rw-r--r-- | src/service/certs.cpp | 283 | ||||
-rw-r--r-- | src/service/certs.h | 36 | ||||
-rw-r--r-- | src/service/logic.cpp | 1038 | ||||
-rw-r--r-- | src/service/logic.h | 213 | ||||
-rw-r--r-- | src/service/ocsp-service.cpp | 11 | ||||
-rw-r--r-- | src/service/queue.cpp | 27 | ||||
-rw-r--r-- | src/service/queue.h | 34 |
9 files changed, 871 insertions, 866 deletions
diff --git a/src/service/app.cpp b/src/service/app.cpp index c35bc73..3a7bd79 100644 --- a/src/service/app.cpp +++ b/src/service/app.cpp @@ -30,48 +30,51 @@ namespace CCHECKER { app_t::app_t(void): - uid((uid_t)-1), // (uid_t)-1 (0xFF) is defined to be invalid uid. According - // to chown manual page, you cannot change file group of owner - // to (uid_t)-1, so we'll use it as initial, invalid value. - verified(verified_t::UNKNOWN) + uid((uid_t) - 1), // (uid_t)-1 (0xFF) is defined to be invalid uid. According + // to chown manual page, you cannot change file group of owner + // to (uid_t)-1, so we'll use it as initial, invalid value. + verified(verified_t::UNKNOWN) {} app_t::app_t(const std::string &app_id, - const std::string &pkg_id, - uid_t uid, - const signatures_t &signatures): - app_id(app_id), - pkg_id(pkg_id), - uid(uid), - signatures(signatures), - verified(verified_t::UNKNOWN) + const std::string &pkg_id, + uid_t uid, + const signatures_t &signatures): + app_id(app_id), + pkg_id(pkg_id), + uid(uid), + signatures(signatures), + verified(verified_t::UNKNOWN) {} -std::ostream & operator<< (std::ostream &out, const app_t &app) +std::ostream &operator<< (std::ostream &out, const app_t &app) { - out << "app: " << app.app_id << ", pkg: " << app.pkg_id << ", uid: " << app.uid; - return out; + out << "app: " << app.app_id << ", pkg: " << app.pkg_id << ", uid: " << app.uid; + return out; } std::string app_t::str() const { - std::stringstream ss; - ss << *this; - return ss.str(); + std::stringstream ss; + ss << *this; + return ss.str(); } std::string app_t::str_certs(void) const { - std::stringstream ss; + std::stringstream ss; - for (const auto &iter : signatures) { - ss << " { "; - for (const auto iter_cert : iter) { - ss << "\"" << iter_cert << "\", "; - } - ss << " } ,"; - } - return ss.str(); + for (const auto &iter : signatures) { + ss << " { "; + + for (const auto iter_cert : iter) { + ss << "\"" << iter_cert << "\", "; + } + + ss << " } ,"; + } + + return ss.str(); } } //CCHECKER diff --git a/src/service/app.h b/src/service/app.h index df4a860..a12703d 100644 --- a/src/service/app.h +++ b/src/service/app.h @@ -36,25 +36,25 @@ typedef std::list<std::string> chain_t; typedef std::list<chain_t> signatures_t; struct app_t { - enum class verified_t : int32_t { - NO = 0, - YES = 1, - UNKNOWN = 2 - }; - - std::string app_id; - std::string pkg_id; - uid_t uid; - signatures_t signatures; - verified_t verified; - - app_t(void); - app_t(const std::string &app_id, - const std::string &pkg_id, - uid_t uid, - const signatures_t &signatures); - std::string str(void) const; - std::string str_certs(void) const; + enum class verified_t : int32_t { + NO = 0, + YES = 1, + UNKNOWN = 2 + }; + + std::string app_id; + std::string pkg_id; + uid_t uid; + signatures_t signatures; + verified_t verified; + + app_t(void); + app_t(const std::string &app_id, + const std::string &pkg_id, + uid_t uid, + const signatures_t &signatures); + std::string str(void) const; + std::string str_certs(void) const; }; } //CCHECKER diff --git a/src/service/certs.cpp b/src/service/certs.cpp index c06fe6f..8abdc43 100644 --- a/src/service/certs.cpp +++ b/src/service/certs.cpp @@ -39,65 +39,65 @@ namespace CCHECKER { namespace { struct PkgmgrinfoCertInfo { - PkgmgrinfoCertInfo() - { - ret = pkgmgrinfo_pkginfo_create_certinfo(&handle); - } - ~PkgmgrinfoCertInfo() - { - pkgmgrinfo_pkginfo_destroy_certinfo(handle); - } - - pkgmgrinfo_certinfo_h handle; - int ret; + PkgmgrinfoCertInfo() + { + ret = pkgmgrinfo_pkginfo_create_certinfo(&handle); + } + ~PkgmgrinfoCertInfo() + { + pkgmgrinfo_pkginfo_destroy_certinfo(handle); + } + + pkgmgrinfo_certinfo_h handle; + int ret; }; static void get_cert_chain(const char *pkgid, uid_t uid, int sig_type, chain_t &chain) { - LogDebug("Get cert chain start. pkgid : " << pkgid << ", uid : " << uid); - int ret; - int cert_type; - const char *cert_value; - - auto pm_certinfo = std::make_shared<PkgmgrinfoCertInfo>(); - - if (pm_certinfo->ret != PMINFO_R_OK) { - LogError("Get pkgmgrinfo certinfo failed. ret : " << ret); - return; - } - - ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, pm_certinfo->handle, uid); - if (ret != PMINFO_R_OK) { - LogError("Load pkgmgrinfo certinfo failed. ret : " << ret); - return; - } - - // add signer, intermediate, root certificates. - for (int cert_cnt = 0; cert_cnt < 3; cert_cnt++) { - cert_type = sig_type - cert_cnt; - ret = pkgmgrinfo_pkginfo_get_cert_value(pm_certinfo->handle, - static_cast<pkgmgrinfo_cert_type>(cert_type), &cert_value); - - if (ret != PMINFO_R_OK) { - LogError("Get cert value from certinfo failed. ret : " << ret); - return; - } - - if (cert_value == NULL) { - LogDebug("cert_type[" << cert_type << "] is null"); - } else { - LogDebug("Add cert_type[" << cert_type << "] data : " << cert_value); - chain.push_back(cert_value); - } - } - - return; + LogDebug("Get cert chain start. pkgid : " << pkgid << ", uid : " << uid); + int ret; + int cert_type; + const char *cert_value; + auto pm_certinfo = std::make_shared<PkgmgrinfoCertInfo>(); + + if (pm_certinfo->ret != PMINFO_R_OK) { + LogError("Get pkgmgrinfo certinfo failed. ret : " << ret); + return; + } + + ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, pm_certinfo->handle, uid); + + if (ret != PMINFO_R_OK) { + LogError("Load pkgmgrinfo certinfo failed. ret : " << ret); + return; + } + + // add signer, intermediate, root certificates. + for (int cert_cnt = 0; cert_cnt < 3; cert_cnt++) { + cert_type = sig_type - cert_cnt; + ret = pkgmgrinfo_pkginfo_get_cert_value(pm_certinfo->handle, + static_cast<pkgmgrinfo_cert_type>(cert_type), &cert_value); + + if (ret != PMINFO_R_OK) { + LogError("Get cert value from certinfo failed. ret : " << ret); + return; + } + + if (cert_value == NULL) { + LogDebug("cert_type[" << cert_type << "] is null"); + } else { + LogDebug("Add cert_type[" << cert_type << "] data : " << cert_value); + chain.push_back(cert_value); + } + } + + return; } } Certs::Certs() { - m_ckm = CKM::Manager::create(); + m_ckm = CKM::Manager::create(); } Certs::~Certs() @@ -105,100 +105,109 @@ Certs::~Certs() void Certs::get_certificates(app_t &app) { - // build chain using pkgmgr-info - std::map<int, int> sig_type; - sig_type[AUTHOR_SIG] = PMINFO_AUTHOR_SIGNER_CERT; - sig_type[DISTRIBUTOR_SIG] = PMINFO_DISTRIBUTOR_SIGNER_CERT; - sig_type[DISTRIBUTOR2_SIG] = PMINFO_DISTRIBUTOR2_SIGNER_CERT; - - for (auto s : sig_type) { - chain_t chain; - get_cert_chain(app.pkg_id.c_str(), app.uid, s.second, chain); - - if(!chain.empty()) { - LogDebug("Add certificates chain to app. Size of chain : " << chain.size()); - app.signatures.emplace_back(std::move(chain)); - } - } + // build chain using pkgmgr-info + std::map<int, int> sig_type; + sig_type[AUTHOR_SIG] = PMINFO_AUTHOR_SIGNER_CERT; + sig_type[DISTRIBUTOR_SIG] = PMINFO_DISTRIBUTOR_SIGNER_CERT; + sig_type[DISTRIBUTOR2_SIG] = PMINFO_DISTRIBUTOR2_SIGNER_CERT; + + for (auto s : sig_type) { + chain_t chain; + get_cert_chain(app.pkg_id.c_str(), app.uid, s.second, chain); + + if (!chain.empty()) { + LogDebug("Add certificates chain to app. Size of chain : " << chain.size()); + app.signatures.emplace_back(std::move(chain)); + } + } } Certs::ocsp_response_t Certs::check_ocsp_chain(const chain_t &chain) { - CKM::CertificateShPtrVector vect_ckm_chain; - - LogDebug("Size of chain: " << chain.size()); - for (auto &iter : chain) { - CKM::RawBuffer buff(iter.begin(), iter.end()); - auto cert = CKM::Certificate::create(buff, CKM::DataFormat::FORM_DER_BASE64); - vect_ckm_chain.emplace_back(std::move(cert)); - } - - int status = CKM_API_OCSP_STATUS_UNKNOWN; - int ret = m_ckm->ocspCheck(vect_ckm_chain, status); - if (ret != CKM_API_SUCCESS) { - LogError("CKM ckeck OCSP returned " << ret); - // Add handling for different errors codes - // For these we can try to check ocsp again later: - switch (ret) { - case CKM_API_ERROR_NOT_SUPPORTED: - LogDebug("Key-manager OCSP API temporary diabled."); - case CKM_API_ERROR_SOCKET: - case CKM_API_ERROR_BAD_REQUEST: - case CKM_API_ERROR_BAD_RESPONSE: - case CKM_API_ERROR_SEND_FAILED: - case CKM_API_ERROR_RECV_FAILED: - case CKM_API_ERROR_SERVER_ERROR: - case CKM_API_ERROR_OUT_OF_MEMORY: - return Certs::ocsp_response_t::OCSP_CHECK_AGAIN; - // Any other error should be recurrent - checking the same app again - // should give the same result. - default: - return Certs::ocsp_response_t::OCSP_CERT_ERROR; - } - } - - LogDebug("OCSP status: " << status); - switch (status) { - // Remove app from "to-check" list: - case CKM_API_OCSP_STATUS_GOOD: - return Certs::ocsp_response_t::OCSP_APP_OK; - case CKM_API_OCSP_STATUS_UNSUPPORTED: - case CKM_API_OCSP_STATUS_UNKNOWN: - case CKM_API_OCSP_STATUS_INVALID_URL: - return Certs::ocsp_response_t::OCSP_CERT_ERROR; - - //Show popup to user and remove app from "to-check" list - case CKM_API_OCSP_STATUS_REVOKED: - return Certs::ocsp_response_t::OCSP_APP_REVOKED; - - //Keep app for checking it again later: - case CKM_API_OCSP_STATUS_NET_ERROR: - case CKM_API_OCSP_STATUS_INVALID_RESPONSE: - case CKM_API_OCSP_STATUS_REMOTE_ERROR: - case CKM_API_OCSP_STATUS_INTERNAL_ERROR: - return Certs::ocsp_response_t::OCSP_CHECK_AGAIN; - - default: - // This should never happen - return Certs::ocsp_response_t::OCSP_CERT_ERROR; - } + CKM::CertificateShPtrVector vect_ckm_chain; + LogDebug("Size of chain: " << chain.size()); + + for (auto &iter : chain) { + CKM::RawBuffer buff(iter.begin(), iter.end()); + auto cert = CKM::Certificate::create(buff, CKM::DataFormat::FORM_DER_BASE64); + vect_ckm_chain.emplace_back(std::move(cert)); + } + + int status = CKM_API_OCSP_STATUS_UNKNOWN; + int ret = m_ckm->ocspCheck(vect_ckm_chain, status); + + if (ret != CKM_API_SUCCESS) { + LogError("CKM ckeck OCSP returned " << ret); + + // Add handling for different errors codes + // For these we can try to check ocsp again later: + switch (ret) { + case CKM_API_ERROR_NOT_SUPPORTED: + LogDebug("Key-manager OCSP API temporary diabled."); + + case CKM_API_ERROR_SOCKET: + case CKM_API_ERROR_BAD_REQUEST: + case CKM_API_ERROR_BAD_RESPONSE: + case CKM_API_ERROR_SEND_FAILED: + case CKM_API_ERROR_RECV_FAILED: + case CKM_API_ERROR_SERVER_ERROR: + case CKM_API_ERROR_OUT_OF_MEMORY: + return Certs::ocsp_response_t::OCSP_CHECK_AGAIN; + + // Any other error should be recurrent - checking the same app again + // should give the same result. + default: + return Certs::ocsp_response_t::OCSP_CERT_ERROR; + } + } + + LogDebug("OCSP status: " << status); + + switch (status) { + // Remove app from "to-check" list: + case CKM_API_OCSP_STATUS_GOOD: + return Certs::ocsp_response_t::OCSP_APP_OK; + + case CKM_API_OCSP_STATUS_UNSUPPORTED: + case CKM_API_OCSP_STATUS_UNKNOWN: + case CKM_API_OCSP_STATUS_INVALID_URL: + return Certs::ocsp_response_t::OCSP_CERT_ERROR; + + //Show popup to user and remove app from "to-check" list + case CKM_API_OCSP_STATUS_REVOKED: + return Certs::ocsp_response_t::OCSP_APP_REVOKED; + + //Keep app for checking it again later: + case CKM_API_OCSP_STATUS_NET_ERROR: + case CKM_API_OCSP_STATUS_INVALID_RESPONSE: + case CKM_API_OCSP_STATUS_REMOTE_ERROR: + case CKM_API_OCSP_STATUS_INTERNAL_ERROR: + return Certs::ocsp_response_t::OCSP_CHECK_AGAIN; + + default: + // This should never happen + return Certs::ocsp_response_t::OCSP_CERT_ERROR; + } } -Certs::ocsp_response_t Certs::check_ocsp (const app_t &app) +Certs::ocsp_response_t Certs::check_ocsp(const app_t &app) { - bool check_again = false; - - for (auto &iter : app.signatures) { - Certs::ocsp_response_t resp = check_ocsp_chain(iter); - if (resp == Certs::ocsp_response_t::OCSP_APP_REVOKED) - return Certs::ocsp_response_t::OCSP_APP_REVOKED; - if (resp == Certs::ocsp_response_t::OCSP_CHECK_AGAIN) - check_again = true; - } - - if (check_again) - return Certs::ocsp_response_t::OCSP_CHECK_AGAIN; - return Certs::ocsp_response_t::OCSP_APP_OK; + bool check_again = false; + + for (auto &iter : app.signatures) { + Certs::ocsp_response_t resp = check_ocsp_chain(iter); + + if (resp == Certs::ocsp_response_t::OCSP_APP_REVOKED) + return Certs::ocsp_response_t::OCSP_APP_REVOKED; + + if (resp == Certs::ocsp_response_t::OCSP_CHECK_AGAIN) + check_again = true; + } + + if (check_again) + return Certs::ocsp_response_t::OCSP_CHECK_AGAIN; + + return Certs::ocsp_response_t::OCSP_APP_OK; } } // CCHECKER diff --git a/src/service/certs.h b/src/service/certs.h index 4871c39..46c688e 100644 --- a/src/service/certs.h +++ b/src/service/certs.h @@ -34,29 +34,29 @@ namespace CCHECKER { enum sig_t { - AUTHOR_SIG, - DISTRIBUTOR_SIG, - DISTRIBUTOR2_SIG + AUTHOR_SIG, + DISTRIBUTOR_SIG, + DISTRIBUTOR2_SIG }; class Certs { - public: - enum class ocsp_response_t { - OCSP_APP_OK, - OCSP_APP_REVOKED, - OCSP_CHECK_AGAIN, - OCSP_CERT_ERROR - }; - Certs(); - virtual ~Certs(); - void get_certificates (app_t &app); - ocsp_response_t check_ocsp (const app_t &app); +public: + enum class ocsp_response_t { + OCSP_APP_OK, + OCSP_APP_REVOKED, + OCSP_CHECK_AGAIN, + OCSP_CERT_ERROR + }; + Certs(); + virtual ~Certs(); + void get_certificates(app_t &app); + ocsp_response_t check_ocsp(const app_t &app); - protected: // Needed for tests - ocsp_response_t check_ocsp_chain (const chain_t &chain); +protected: // Needed for tests + ocsp_response_t check_ocsp_chain(const chain_t &chain); - //private: - CKM::ManagerShPtr m_ckm; + //private: + CKM::ManagerShPtr m_ckm; }; } // CCHECKER diff --git a/src/service/logic.cpp b/src/service/logic.cpp index 574b9b2..0bef2ee 100644 --- a/src/service/logic.cpp +++ b/src/service/logic.cpp @@ -38,38 +38,38 @@ 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; + 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<PkgmgrinfoEvent> pkgmgrinfo_event_set; @@ -79,395 +79,388 @@ const char *const DB_PATH = DB_INSTALL_DIR"/.cert-checker.db"; Logic::~Logic(void) { - clean(); + clean(); } void Logic::clean(void) { - LogDebug("Cert-checker cleaning start."); - - // wait and join processing thread - if (m_thread.joinable()) { - LogDebug("Waiting for join processing thread"); - { - std::lock_guard<std::mutex> lock(m_mutex_cv); - set_should_exit(); - LogDebug("Notify thread : enforced by cleaning"); - m_to_process.notify_one(); - } - m_thread.join(); - LogDebug("Processing thread joined"); - } - else - LogDebug("No thread to join"); - - if (m_proxy_connman) - g_object_unref(m_proxy_connman); - - if (m_loop) - g_main_loop_unref(m_loop); - - delete m_sqlquery; - - timerStop(); - - LogDebug("Cert-checker cleaning finish."); + LogDebug("Cert-checker cleaning start."); + + // wait and join processing thread + if (m_thread.joinable()) { + LogDebug("Waiting for join processing thread"); + { + std::lock_guard<std::mutex> lock(m_mutex_cv); + set_should_exit(); + LogDebug("Notify thread : enforced by cleaning"); + m_to_process.notify_one(); + } + m_thread.join(); + LogDebug("Processing thread joined"); + } else { + LogDebug("No thread to join"); + } + + if (m_proxy_connman) + g_object_unref(m_proxy_connman); + + if (m_loop) + g_main_loop_unref(m_loop); + + delete m_sqlquery; + timerStop(); + LogDebug("Cert-checker cleaning finish."); } Logic::Logic(void) : - m_loop(g_main_loop_new(NULL, FALSE)), - m_sqlquery(NULL), - m_was_setup_called(false), - m_is_online(false), - m_is_online_enabled(false), - m_should_exit(false), - m_proxy_connman(NULL), - m_pc_install(nullptr, nullptr), - m_pc_uninstall(nullptr, nullptr) + m_loop(g_main_loop_new(NULL, FALSE)), + m_sqlquery(NULL), + m_was_setup_called(false), + m_is_online(false), + m_is_online_enabled(false), + m_should_exit(false), + m_proxy_connman(NULL), + m_pc_install(nullptr, nullptr), + m_pc_uninstall(nullptr, nullptr) { } bool Logic::get_online() const { - return m_is_online; + return m_is_online; } void Logic::set_online(bool online) { - std::lock_guard<std::mutex> lock(m_mutex_cv); - - m_is_online = online; - if (m_is_online) { - m_is_online_enabled = true; - LogDebug("Notify thread : Network connected"); - m_to_process.notify_one(); - } + std::lock_guard<std::mutex> lock(m_mutex_cv); + m_is_online = online; + + if (m_is_online) { + m_is_online_enabled = true; + LogDebug("Notify thread : Network connected"); + m_to_process.notify_one(); + } } error_t Logic::setup_db() { - // TODO: If database doesn't exist -should we create a new one? - Try { - m_sqlquery = new DB::SqlQuery(DB_PATH); - } Catch (runtime_error) { - LogError("Error while creating SqlQuery object"); - return DATABASE_ERROR; - } - - if(!m_sqlquery) { - LogError("Cannot open database"); - return DATABASE_ERROR; - } - - return NO_ERROR; + // TODO: If database doesn't exist -should we create a new one? + Try { + m_sqlquery = new DB::SqlQuery(DB_PATH); + } Catch(runtime_error) { + LogError("Error while creating SqlQuery object"); + return DATABASE_ERROR; + } + + if (!m_sqlquery) { + LogError("Cannot open database"); + return DATABASE_ERROR; + } + + return NO_ERROR; } error_t Logic::setup() { - // Check if setup was called - if (m_was_setup_called) { - LogDebug("Setup is already done."); - return NO_ERROR; - } - m_was_setup_called = true; - - // Check if DB exists and create a new one if it doesn't - error_t err = setup_db(); - if (err != NO_ERROR) { - LogError("Database error"); - return err; - } - - load_database_to_buffer(); - - // run process thread - thread will be waiting on condition variable - m_thread = std::thread(&Logic::process_all, this); - - // Add connman callback - LogDebug("register connman event callback start"); - if (register_dbus_signal_handler(&m_proxy_connman, - "net.connman", - "/", - "net.connman.Manager", - connman_callback) != NO_ERROR) { - LogError("Error in register_connman_signal_handler"); - return REGISTER_CALLBACK_ERROR; - } - LogDebug("register connman event callback success"); - - set_connman_online_state(); - - // Add pkgmgrinfo callback - LogDebug("Register package event handler start"); - - std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> - _pcInstall(pkgmgrinfo_client_new(PMINFO_LISTENING), pkgmgrinfo_client_free); - std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> - _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; - } - - // Init for gio timeout. - m_is_first_run = false; - - LogDebug("Register package event handler success"); - - return NO_ERROR; + // Check if setup was called + if (m_was_setup_called) { + LogDebug("Setup is already done."); + return NO_ERROR; + } + + m_was_setup_called = true; + // Check if DB exists and create a new one if it doesn't + error_t err = setup_db(); + + if (err != NO_ERROR) { + LogError("Database error"); + return err; + } + + load_database_to_buffer(); + // run process thread - thread will be waiting on condition variable + m_thread = std::thread(&Logic::process_all, this); + // Add connman callback + LogDebug("register connman event callback start"); + + if (register_dbus_signal_handler(&m_proxy_connman, + "net.connman", + "/", + "net.connman.Manager", + connman_callback) != NO_ERROR) { + LogError("Error in register_connman_signal_handler"); + return REGISTER_CALLBACK_ERROR; + } + + LogDebug("register connman event callback success"); + set_connman_online_state(); + // Add pkgmgrinfo callback + LogDebug("Register package event handler start"); + std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> + _pcInstall(pkgmgrinfo_client_new(PMINFO_LISTENING), pkgmgrinfo_client_free); + std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> + _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; + } + + // Init for gio timeout. + m_is_first_run = false; + LogDebug("Register package event handler success"); + return NO_ERROR; } void Logic::run(guint timeout) { - LogDebug("Running the main loop"); - - g_timeout_add_seconds(timeout, timeout_cb, m_loop); - g_main_loop_run(m_loop); + LogDebug("Running the main loop"); + g_timeout_add_seconds(timeout, timeout_cb, m_loop); + g_main_loop_run(m_loop); } 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) + 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<Logic *>(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<Logic *>(data)->push_pkgmgrinfo_event(uid, pkgid); - } else { - // TODO(sangwan.kwon) if get untreat event like fail, must quit loop - LogDebug("Untreated event was caught : " << val); - return -1; - } + 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<Logic *>(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<Logic *>(data)->push_pkgmgrinfo_event(uid, pkgid); + } else { + // TODO(sangwan.kwon) if get untreat event like fail, must quit loop + 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*/) + 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; + 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<PkgmgrinfoEvent>::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; - } + PkgmgrinfoEvent event(uid, pkgid); + std::set<PkgmgrinfoEvent>::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, - const char *interface_name, - void (*callback) (GDBusProxy *proxy, - gchar *sender_name, - gchar *signal_name, - GVariant *parameters, - void *logic_ptr) - ) + const char *name, + const char *object_path, + const char *interface_name, + void (*callback)(GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + void *logic_ptr) + ) { - GError *error = NULL; - GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_NONE; - - // Obtain a connection to the System Bus - *proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, - flags, - NULL, /* GDBusInterfaceInfo */ - name, - object_path, - interface_name, - NULL, /* GCancellable */ - &error); - - if (*proxy == NULL) { - if (error) { - LogError("Error creating D-Bus proxy for /'" << interface_name <<"/': " << error->message); - g_error_free(error); - } else { - LogError("Error creating D-Bus proxy for /'" << interface_name <<"/'. Unknown error"); - } - return DBUS_ERROR; - } - - // Connect to g-signal to receive signals from proxy - if (g_signal_connect(*proxy, "g-signal", G_CALLBACK(callback), this) < 1) { - LogError("g_signal_connect error while connecting " << interface_name); - return REGISTER_CALLBACK_ERROR; - } - - return NO_ERROR; + GError *error = NULL; + GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_NONE; + // Obtain a connection to the System Bus + *proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, + flags, + NULL, /* GDBusInterfaceInfo */ + name, + object_path, + interface_name, + NULL, /* GCancellable */ + &error); + + if (*proxy == NULL) { + if (error) { + LogError("Error creating D-Bus proxy for /'" << interface_name << "/': " << error->message); + g_error_free(error); + } else { + LogError("Error creating D-Bus proxy for /'" << interface_name << "/'. Unknown error"); + } + + return DBUS_ERROR; + } + + // Connect to g-signal to receive signals from proxy + if (g_signal_connect(*proxy, "g-signal", G_CALLBACK(callback), this) < 1) { + LogError("g_signal_connect error while connecting " << interface_name); + return REGISTER_CALLBACK_ERROR; + } + + return NO_ERROR; } void Logic::set_connman_online_state() { - GError *error = NULL; - GVariant *response; - - if (m_proxy_connman == NULL) { - LogError("connman proxy is NULL"); - return; - } - - response = g_dbus_proxy_call_sync (m_proxy_connman, - "GetProperties", - NULL, // GetProperties gets no parameters - G_DBUS_CALL_FLAGS_NONE, - -1, // Default timeout - NULL, - &error); - - if (error) { - LogError("Error while calling connman GetProperties() Dbus API: " << error->message); - g_error_free(error); - return; - } - - if (response == NULL) { - // This should never happen - return; - } - - gchar *resp_g = g_variant_print(response, TRUE); - std::string resp_s(resp_g); - LogDebug("response: " << resp_s); - g_free(resp_g); - - // Response should look like this: - // ({'State': <'online'>, 'OfflineMode': <false>, 'SessionMode': <false>},) - if (resp_s.find("'State': <'online'>", 0) != std::string::npos) { - LogDebug("Connman has returned: online"); - set_online(true); - } - - // free memory - g_variant_unref(response); + GError *error = NULL; + GVariant *response; + + if (m_proxy_connman == NULL) { + LogError("connman proxy is NULL"); + return; + } + + response = g_dbus_proxy_call_sync(m_proxy_connman, + "GetProperties", + NULL, // GetProperties gets no parameters + G_DBUS_CALL_FLAGS_NONE, + -1, // Default timeout + NULL, + &error); + + if (error) { + LogError("Error while calling connman GetProperties() Dbus API: " << error->message); + g_error_free(error); + return; + } + + if (response == NULL) { + // This should never happen + return; + } + + gchar *resp_g = g_variant_print(response, TRUE); + std::string resp_s(resp_g); + LogDebug("response: " << resp_s); + g_free(resp_g); + + // Response should look like this: + // ({'State': <'online'>, 'OfflineMode': <false>, 'SessionMode': <false>},) + if (resp_s.find("'State': <'online'>", 0) != std::string::npos) { + LogDebug("Connman has returned: online"); + set_online(true); + } + + // free memory + g_variant_unref(response); } void Logic::connman_callback(GDBusProxy */*proxy*/, - gchar */*sender_name*/, - gchar *signal_name, - GVariant *parameters, - void *logic_ptr) + gchar */*sender_name*/, + gchar *signal_name, + GVariant *parameters, + void *logic_ptr) { - string signal_name_str = string(signal_name); - if (signal_name_str != "PropertyChanged") { - // Invalid param. Nothing to do here. - return; - } - - gchar *parameters_g = g_variant_print(parameters, TRUE); - string params_str = string(parameters_g); - g_free (parameters_g); - - Logic *logic = static_cast<Logic*> (logic_ptr); - - if (params_str == "('State', <'online'>)") { - LogDebug("Device online"); - logic->set_online(true); - } - else if (params_str == "('State', <'offline'>)") { - LogDebug("Device offline"); - logic->set_online(false); - } + string signal_name_str = string(signal_name); + + if (signal_name_str != "PropertyChanged") { + // Invalid param. Nothing to do here. + return; + } + + gchar *parameters_g = g_variant_print(parameters, TRUE); + string params_str = string(parameters_g); + g_free(parameters_g); + Logic *logic = static_cast<Logic *>(logic_ptr); + + if (params_str == "('State', <'online'>)") { + LogDebug("Device online"); + logic->set_online(true); + } else if (params_str == "('State', <'offline'>)") { + LogDebug("Device offline"); + logic->set_online(false); + } } void Logic::load_database_to_buffer() { - LogDebug("Loading database to the buffer"); - m_sqlquery->get_app_list(m_buffer); + LogDebug("Loading database to the buffer"); + m_sqlquery->get_app_list(m_buffer); } /** @@ -475,182 +468,184 @@ void Logic::load_database_to_buffer() **/ void Logic::process_queue(void) { - event_t event; - while(m_queue.pop_event(event)) { - process_event(event); - } + event_t event; + + while (m_queue.pop_event(event)) { + process_event(event); + } } bool Logic::call_ui(const app_t &app) { - UI::UIBackend ui; - - if (ui.call_popup(app)) { // If calling popup or app_controll service will fail, - // do not remove application, and ask about it once again later - LogDebug("Popup shown correctly. Application will be removed from DB and buffer"); - return true; - } - LogDebug("Popup error. Application will be marked to show popup later."); - return false; + UI::UIBackend ui; + + if (ui.call_popup(app)) { // If calling popup or app_controll service will fail, + // do not remove application, and ask about it once again later + LogDebug("Popup shown correctly. Application will be removed from DB and buffer"); + return true; + } + + LogDebug("Popup error. Application will be marked to show popup later."); + return false; } -bool Logic::process_app(app_t& app) { - // Check if app hasn't already been verified. - // If yes then just try to display popup once again, and go the next app. +bool Logic::process_app(app_t &app) +{ + // Check if app hasn't already been verified. + // If yes then just try to display popup once again, and go the next app. #if POPUP - if (app.verified == app_t::verified_t::NO) { - LogDebug(app.str() << " has been verified before. Popup should be shown."); - return call_ui(app); - } -#endif + if (app.verified == app_t::verified_t::NO) { + LogDebug(app.str() << " has been verified before. Popup should be shown."); + return call_ui(app); + } - Certs::ocsp_response_t ret; - ret = m_certs.check_ocsp(app); - - // If OCSP returns success or OCSP checking fails we should remove application from buffer and database - if (ret == Certs::ocsp_response_t::OCSP_APP_OK || - ret == Certs::ocsp_response_t::OCSP_CERT_ERROR) { - LogDebug(app.str() << " OCSP verified (or not available for app's chains)"); - return true; - } - else if (ret == Certs::ocsp_response_t::OCSP_APP_REVOKED) { - LogDebug(app.str() << " certificate has been revoked. Popup should be shown"); - app.verified = app_t::verified_t::NO; +#endif + Certs::ocsp_response_t ret; + ret = m_certs.check_ocsp(app); + + // If OCSP returns success or OCSP checking fails we should remove application from buffer and database + if (ret == Certs::ocsp_response_t::OCSP_APP_OK || + ret == Certs::ocsp_response_t::OCSP_CERT_ERROR) { + LogDebug(app.str() << " OCSP verified (or not available for app's chains)"); + return true; + } else if (ret == Certs::ocsp_response_t::OCSP_APP_REVOKED) { + LogDebug(app.str() << " certificate has been revoked. Popup should be shown"); + app.verified = app_t::verified_t::NO; #if POPUP -// Do not remove app here - just waits for user answer from popup - return call_ui(app); + // Do not remove app here - just waits for user answer from popup + return call_ui(app); #else - return true; + return true; #endif - } - else { - LogDebug(app.str() << " should be checked again later"); - // If check_ocsp returns Certs::ocsp_response_t::OCSP_CHECK_AGAIN - // app should be checked again later - } - return false; + } else { + LogDebug(app.str() << " should be checked again later"); + // If check_ocsp returns Certs::ocsp_response_t::OCSP_CHECK_AGAIN + // app should be checked again later + } + + return false; } void Logic::process_buffer(void) { - for (auto iter = m_buffer.begin(); iter != m_buffer.end();) { - bool remove = process_app(*iter); - auto prev = *iter; - iter++; - if (remove) - remove_app_from_buffer_and_database(prev); - app_processed(); - } + for (auto iter = m_buffer.begin(); iter != m_buffer.end();) { + bool remove = process_app(*iter); + auto prev = *iter; + iter++; + + if (remove) + remove_app_from_buffer_and_database(prev); + + app_processed(); + } } void Logic::push_event(event_t event) { - std::lock_guard<std::mutex> lock(m_mutex_cv); - m_queue.push_event(std::move(event)); - LogDebug("Notify thread : pkgmgr event added"); - m_to_process.notify_one(); + std::lock_guard<std::mutex> lock(m_mutex_cv); + m_queue.push_event(std::move(event)); + LogDebug("Notify thread : pkgmgr event added"); + m_to_process.notify_one(); } void Logic::process_all() { - LogInfo("[thread] Start to process event."); - for(;;) { - std::unique_lock<std::mutex> lock(m_mutex_cv); - - // Wait condition. - if(m_queue.empty() && !m_is_online_enabled) { - LogDebug("[thread] wait condition <queue, Network> : " - << !m_queue.empty() << ", " << get_online()); - m_to_process.wait(lock); // spurious wakeups do not concern us - - LogDebug("[thread] wake up! running stage"); - m_is_first_run = true; - } - - // Value for prevent infinite loop. - m_is_online_enabled = false; - // Move event data from queue to buffer & database. - process_queue(); - - lock.unlock(); - - if (get_online() && !m_buffer.empty()) { - - process_buffer(); - - // This is for OCSP_CHECK_AGAIN case. - if(m_buffer.empty()) { - LogInfo("[thread] Finish processing event."); - g_main_loop_quit(m_loop); - break; - } else { - LogDebug("[thread] Check again : " << m_buffer.size()); - // Timer running periodically - timerStart(TIMEOUT_TIMER); - } - } else if (!get_online()) { - LogDebug("[thread] No network. Buffer won't be processed."); - } else { - LogDebug("[thread] No event since cert-checker started."); - } - - if (m_should_exit) - break; - } + LogInfo("[thread] Start to process event."); + + for (;;) { + std::unique_lock<std::mutex> lock(m_mutex_cv); + + // Wait condition. + if (m_queue.empty() && !m_is_online_enabled) { + LogDebug("[thread] wait condition <queue, Network> : " + << !m_queue.empty() << ", " << get_online()); + m_to_process.wait(lock); // spurious wakeups do not concern us + LogDebug("[thread] wake up! running stage"); + m_is_first_run = true; + } + + // Value for prevent infinite loop. + m_is_online_enabled = false; + // Move event data from queue to buffer & database. + process_queue(); + lock.unlock(); + + if (get_online() && !m_buffer.empty()) { + process_buffer(); + + // This is for OCSP_CHECK_AGAIN case. + if (m_buffer.empty()) { + LogInfo("[thread] Finish processing event."); + g_main_loop_quit(m_loop); + break; + } else { + LogDebug("[thread] Check again : " << m_buffer.size()); + // Timer running periodically + timerStart(TIMEOUT_TIMER); + } + } else if (!get_online()) { + LogDebug("[thread] No network. Buffer won't be processed."); + } else { + LogDebug("[thread] No event since cert-checker started."); + } + + if (m_should_exit) + break; + } } void Logic::job(void) { - std::lock_guard<std::mutex> lock(m_mutex_cv); - - if (m_buffer.empty()) { - LogDebug("[timer] Buffer is empty."); - timerStop(); - } else { - LogDebug("[timer] Notify thread - periodic wakeup"); - m_to_process.notify_one(); - } + std::lock_guard<std::mutex> lock(m_mutex_cv); + + if (m_buffer.empty()) { + LogDebug("[timer] Buffer is empty."); + timerStop(); + } else { + LogDebug("[timer] Notify thread - periodic wakeup"); + m_to_process.notify_one(); + } } void Logic::process_event(const event_t &event) { - LogDebug("Move event from queue to (buffer and db)."); - if (event.event_type == event_t::event_type_t::APP_INSTALL) { - // pulling out certificates from signatures - app_t app = event.app; - m_certs.get_certificates(app); - add_app_to_buffer_and_database(app); - } - else if (event.event_type == event_t::event_type_t::APP_UNINSTALL) { - remove_app_from_buffer_and_database(event.app); - } - else - LogError("Unknown event type"); + LogDebug("Move event from queue to (buffer and db)."); + + if (event.event_type == event_t::event_type_t::APP_INSTALL) { + // pulling out certificates from signatures + app_t app = event.app; + m_certs.get_certificates(app); + add_app_to_buffer_and_database(app); + } else if (event.event_type == event_t::event_type_t::APP_UNINSTALL) { + remove_app_from_buffer_and_database(event.app); + } else { + LogError("Unknown event type"); + } } void Logic::add_app_to_buffer_and_database(const app_t &app) { - // First add app to DB - if(!m_sqlquery->add_app_to_check_list(app)) { - LogError("Failed to add " << app.str() << "to database"); - // We can do nothing about it. We can only log the error. - } - - // Then add app to buffer - skip if already added. - // FIXME: What to do if the same app will be installed twice? - // Add it twice to the buffer, or check if apps in buffer are unique? - // At the moment doubled apps are skipped. - for (auto &iter : m_buffer) { - if (iter.app_id == app.app_id && - iter.pkg_id == app.pkg_id && - iter.uid == app.uid) { - LogDebug(app.str() << " already in buffer. Skip."); - return; - } - } - - // Then add app to buffer - m_buffer.push_back(app); + // First add app to DB + if (!m_sqlquery->add_app_to_check_list(app)) { + LogError("Failed to add " << app.str() << "to database"); + // We can do nothing about it. We can only log the error. + } + + // Then add app to buffer - skip if already added. + // FIXME: What to do if the same app will be installed twice? + // Add it twice to the buffer, or check if apps in buffer are unique? + // At the moment doubled apps are skipped. + for (auto &iter : m_buffer) { + if (iter.app_id == app.app_id && + iter.pkg_id == app.pkg_id && + iter.uid == app.uid) { + LogDebug(app.str() << " already in buffer. Skip."); + return; + } + } + + // Then add app to buffer + m_buffer.push_back(app); } // Notice that this operator doesn't compare list of certificate, because it isn't needed here. @@ -658,45 +653,44 @@ void Logic::add_app_to_buffer_and_database(const app_t &app) // Operator which compares certificates is implemented in tests. bool operator ==(const app_t &app1, const app_t &app2) { - return app1.app_id == app2.app_id && - app1.pkg_id == app2.pkg_id && - app1.uid == app2.uid; + return app1.app_id == app2.app_id && + app1.pkg_id == app2.pkg_id && + app1.uid == app2.uid; } void Logic::remove_app_from_buffer_and_database(const app_t &app) { - // First remove app from DB - m_sqlquery->remove_app_from_check_list(app); - - // Then remove app from buffer - m_buffer.remove(app); + // First remove app from DB + m_sqlquery->remove_app_from_check_list(app); + // Then remove app from buffer + m_buffer.remove(app); } bool Logic::get_should_exit(void) const { - return m_should_exit; + return m_should_exit; } void Logic::set_should_exit(void) { - m_should_exit = true; + m_should_exit = true; } std::atomic<bool> Logic::m_is_first_run(false); bool Logic::is_running() { - return g_main_loop_is_running(m_loop); + return g_main_loop_is_running(m_loop); } gboolean Logic::timeout_cb(gpointer data) { - if (!m_is_first_run) { - LogDebug("No event Since cchecker launched. timeout."); - g_main_loop_quit(static_cast<GMainLoop *>(data)); - } + if (!m_is_first_run) { + LogDebug("No event Since cchecker launched. timeout."); + g_main_loop_quit(static_cast<GMainLoop *>(data)); + } - return FALSE; + return FALSE; } } // namespace CCHECKER diff --git a/src/service/logic.h b/src/service/logic.h index e2d5fd7..eedd2e4 100644 --- a/src/service/logic.h +++ b/src/service/logic.h @@ -51,119 +51,118 @@ class SqlQuery; } // namespace DB enum error_t { - NO_ERROR, - REGISTER_CALLBACK_ERROR, - DBUS_ERROR, - PACKAGE_MANAGER_ERROR, - DATABASE_ERROR, - INTERNAL_ERROR + NO_ERROR, + REGISTER_CALLBACK_ERROR, + DBUS_ERROR, + PACKAGE_MANAGER_ERROR, + DATABASE_ERROR, + INTERNAL_ERROR }; enum pkgmgr_event_t { - EVENT_INSTALL, - EVENT_UNINSTALL + EVENT_INSTALL, + EVENT_UNINSTALL }; class Logic : public Timer { - public: - Logic(void); - virtual ~Logic(void); - error_t setup(void); - void run(guint timeout); - bool is_running(); - virtual void clean(void); - - static void connman_callback(GDBusProxy *proxy, - gchar *sender_name, - gchar *signal_name, - GVariant *parameters, - void *logic_ptr); - - protected: - // Timer function - void job(void) override; - - virtual void process_event(const event_t &event); - virtual void app_processed() {}; // for tests - void set_should_exit(void); - void push_event(event_t event); - void set_online(bool online); - - std::list<app_t> m_buffer; - std::condition_variable m_to_process; - std::mutex m_mutex_cv; - std::thread m_thread; - - private: - error_t setup_db(); - void load_database_to_buffer(); - void add_app_to_buffer_and_database(const app_t &app); - void remove_app_from_buffer_and_database(const app_t &app); - - void set_connman_online_state(); - error_t register_dbus_signal_handler(GDBusProxy **proxy, - const char *name, - const char *object_path, - const char *interface_name, - void (*callback) (GDBusProxy *proxy, - gchar *sender_name, - gchar *signal_name, - GVariant *parameters, - void *logic_ptr) - ); - bool get_online(void) const; - - 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 process_all(void); - void process_queue(void); - bool process_app(app_t& app); - void process_buffer(void); - bool get_should_exit(void) const; - - bool call_ui(const app_t &app); - - static gboolean timeout_cb(gpointer data); - - // main event loop data type - GMainLoop *m_loop; - - Queue m_queue; - Certs m_certs; - DB::SqlQuery *m_sqlquery; - bool m_was_setup_called; - - bool m_is_online; - // TODO: use m_queue for online events - bool m_is_online_enabled; - bool m_should_exit; - static std::atomic<bool> m_is_first_run; - - GDBusProxy *m_proxy_connman; - - // about pkgmgr event - int m_reqid_install; - int m_reqid_uninstall; - std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> m_pc_install; - std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> m_pc_uninstall; +public: + Logic(void); + virtual ~Logic(void); + error_t setup(void); + void run(guint timeout); + bool is_running(); + virtual void clean(void); + + static void connman_callback(GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + void *logic_ptr); + +protected: + // Timer function + void job(void) override; + + virtual void process_event(const event_t &event); + virtual void app_processed() {}; // for tests + void set_should_exit(void); + void push_event(event_t event); + void set_online(bool online); + + std::list<app_t> m_buffer; + std::condition_variable m_to_process; + std::mutex m_mutex_cv; + std::thread m_thread; + +private: + error_t setup_db(); + void load_database_to_buffer(); + void add_app_to_buffer_and_database(const app_t &app); + void remove_app_from_buffer_and_database(const app_t &app); + + void set_connman_online_state(); + error_t register_dbus_signal_handler(GDBusProxy **proxy, + const char *name, + const char *object_path, + const char *interface_name, + void (*callback)(GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + void *logic_ptr)); + bool get_online(void) const; + + 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 process_all(void); + void process_queue(void); + bool process_app(app_t &app); + void process_buffer(void); + bool get_should_exit(void) const; + + bool call_ui(const app_t &app); + + static gboolean timeout_cb(gpointer data); + + // main event loop data type + GMainLoop *m_loop; + + Queue m_queue; + Certs m_certs; + DB::SqlQuery *m_sqlquery; + bool m_was_setup_called; + + bool m_is_online; + // TODO: use m_queue for online events + bool m_is_online_enabled; + bool m_should_exit; + static std::atomic<bool> m_is_first_run; + + GDBusProxy *m_proxy_connman; + + // about pkgmgr event + int m_reqid_install; + int m_reqid_uninstall; + std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> m_pc_install; + std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> m_pc_uninstall; }; } // namespace CCHECKER diff --git a/src/service/ocsp-service.cpp b/src/service/ocsp-service.cpp index 5d6997d..398deb2 100644 --- a/src/service/ocsp-service.cpp +++ b/src/service/ocsp-service.cpp @@ -33,7 +33,7 @@ OcspService::OcspService(const std::string &address) : OcspService::~OcspService() { - if(m_thread.joinable()) + if (m_thread.joinable()) m_thread.join(); } @@ -46,13 +46,12 @@ void OcspService::run(void) void OcspService::onMessageProcess(const ConnShPtr &connection) { LogDebug("Start to process message on ocsp service."); - auto in = connection->receive(); connection->send(this->process(connection, in)); // Run gmainloop for event listening. - if(!m_logic.is_running()) - m_thread = std::thread(&OcspService::run,this); + if (!m_logic.is_running()) + m_thread = std::thread(&OcspService::run, this); LogDebug("Finish processing message on ocsp service."); } @@ -61,11 +60,10 @@ RawBuffer OcspService::process(const ConnShPtr &, RawBuffer &data) { BinaryQueue q; q.push(data); - CommandId cid; q.Deserialize(cid); - LogInfo("Request dispatch on ocsp-service."); + switch (cid) { case CommandId::CC_OCSP_SYN: { if (m_logic.setup() != NO_ERROR) { @@ -76,6 +74,7 @@ RawBuffer OcspService::process(const ConnShPtr &, RawBuffer &data) LogDebug("Success to receive SYN and setup. reply ACK cmd."); return BinaryQueue::Serialize(CommandId::CC_OCSP_ACK).pop(); } + case CommandId::CC_OCSP_ACK: default: throw std::logic_error("Protocol error. unknown command id."); diff --git a/src/service/queue.cpp b/src/service/queue.cpp index 1ae4f1b..06f6268 100644 --- a/src/service/queue.cpp +++ b/src/service/queue.cpp @@ -27,35 +27,36 @@ namespace CCHECKER { event_t::event_t(): - event_type(event_type_t::EVENT_TYPE_UNKNOWN), - app() + event_type(event_type_t::EVENT_TYPE_UNKNOWN), + app() {} event_t::event_t(const app_t &app, event_type_t type): - event_type(type), - app(app) + event_type(type), + app(app) {} void Queue::push_event(const event_t &event) { - std::lock_guard<std::mutex> lock(m_mutex); - m_event_list.push(event); + std::lock_guard<std::mutex> lock(m_mutex); + m_event_list.push(event); } bool Queue::pop_event(event_t &event) { - std::lock_guard<std::mutex> lock(m_mutex); - if (m_event_list.empty()) - return false; + std::lock_guard<std::mutex> lock(m_mutex); - event = std::move(m_event_list.front()); - m_event_list.pop(); - return true; + if (m_event_list.empty()) + return false; + + event = std::move(m_event_list.front()); + m_event_list.pop(); + return true; } bool Queue::empty() { - return m_event_list.empty(); + return m_event_list.empty(); } } //CCHECKER diff --git a/src/service/queue.h b/src/service/queue.h index 9c3eaae..c5ec0d9 100644 --- a/src/service/queue.h +++ b/src/service/queue.h @@ -31,28 +31,28 @@ namespace CCHECKER { struct event_t { - enum class event_type_t { - APP_INSTALL, - APP_UNINSTALL, - EVENT_TYPE_UNKNOWN - }; + enum class event_type_t { + APP_INSTALL, + APP_UNINSTALL, + EVENT_TYPE_UNKNOWN + }; - event_type_t event_type; - app_t app; + event_type_t event_type; + app_t app; - event_t(); - event_t(const app_t &app, event_type_t type); + event_t(); + event_t(const app_t &app, event_type_t type); }; class Queue { - public: - void push_event(const event_t &event); - bool pop_event(event_t &event); - bool empty(); - - private: - std::mutex m_mutex; - std::queue<event_t> m_event_list; +public: + void push_event(const event_t &event); + bool pop_event(event_t &event); + bool empty(); + +private: + std::mutex m_mutex; + std::queue<event_t> m_event_list; }; } // CCHECKER |