diff options
author | Pawel Niemirski <p.niemirski@samsung.com> | 2017-05-19 09:59:32 +0200 |
---|---|---|
committer | Pawel Niemirski <p.niemirski@samsung.com> | 2017-05-31 13:47:21 +0200 |
commit | 9e4fba5aca67a2614f30371abf12022074007022 (patch) | |
tree | 312ecd2bc9c24b50aafe6fb16d0dc36aa45c005d | |
parent | 1fe74d89aa9f612ba479a76676ecdf649d8b9d50 (diff) | |
download | browser-9e4fba5aca67a2614f30371abf12022074007022.tar.gz browser-9e4fba5aca67a2614f30371abf12022074007022.tar.bz2 browser-9e4fba5aca67a2614f30371abf12022074007022.zip |
[PWE] Implement "request,certificate,confirm" smart callback for PWA apps
Due to certificate error (e.g. untrusted certificate or wrong time),
some pages can be untrusted. This is why some resources can be blocked
by the engine resulting in missing images and styles.
In org.tizen.browser, a confirmation popup takes place whenever
certificate issue happens, so user is able to decide whether
to use resources from untrusted site or not.
However, such mechanism is unavailable for PWA applications, therefore
the engine is responsible for making decisions on certificate issue
and it blocks all sub-resources with certificate error by default.
This CL implements "request,certificate,confirm" smart callback for PWA
to give user opportunity of making decisions on untrusted PWA apps.
Bug: suprem.sec.samsung.net/jira/browse/RWASP-1181
Change-Id: I81734bc614bd9bab7c25c7dae0eb1d6e631aaf68
Signed-off-by: Pawel Niemirski <p.niemirski@samsung.com>
-rwxr-xr-x | services/SimpleUI/SimpleUI.cpp | 26 | ||||
-rwxr-xr-x | services/WebEngineMin/WebEngineMin.cpp | 86 | ||||
-rwxr-xr-x | services/WebEngineMin/WebEngineMin.h | 10 |
3 files changed, 118 insertions, 4 deletions
diff --git a/services/SimpleUI/SimpleUI.cpp b/services/SimpleUI/SimpleUI.cpp index 6d5c7b0..44e0cee 100755 --- a/services/SimpleUI/SimpleUI.cpp +++ b/services/SimpleUI/SimpleUI.cpp @@ -231,12 +231,22 @@ void SimpleUI::preparePWAServices() { core::ServiceManager::getInstance().getService( "org.tizen.browser.storageservice", "libStorageService.so")); - +#if PWE_SHUB + m_certificateContents = std::dynamic_pointer_cast< + services::CertificateContents, core::AbstractService>( + core::ServiceManager::getInstance().getService( + "org.tizen.browser.certificateservice", + "libCertificateService.so")); +#endif connectPWASignals(); m_platformInputManager->init(m_window.get()); m_webPageMin->init(m_viewManager.getContent()); m_webEngine->init(m_webPageMin->getContent()); +#if PWE_SHUB + assert(m_certificateContents.get()); + m_certificateContents->init(); +#endif } int SimpleUI::exec(const std::string& url, const std::string& caller, @@ -959,6 +969,10 @@ void SimpleUI::connectPWASignals() { [this] {return m_pwa.getPWAinfo().serviceWorkerUri;}); m_webEngine->getPWAURI.connect( [this] {return m_pwa.getPWAinfo().uri;}); + m_webEngine->confirmationRequest.connect( + [this](const auto& conf) { + this->handleConfirmationRequest(conf); + }); #endif m_webEngine->getPWAInstanceIDSignal.connect( [this] {return m_pushPwaData.getInstanceId();}); @@ -984,6 +998,9 @@ void SimpleUI::connectPWASignals() { BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); return m_storageService->getPWAStorage().getPermissionsMap(); }); +#if PWE_SHUB + connectCertificateSignals(); +#endif } void SimpleUI::connectModelSignals() { @@ -1777,7 +1794,11 @@ void SimpleUI::handleConfirmationRequest( if (webConfirmation->getConfirmationType() == basic_webengine::WebConfirmation::ConfirmationType::CertificateConfirmation) { +#if PWE_SHUB + if (m_pwa.isActive() || m_webPageUI->stateEquals(WPUState::MAIN_WEB_PAGE)) { +#else if (m_webPageUI->stateEquals(WPUState::MAIN_WEB_PAGE)) { +#endif auto cert = std::dynamic_pointer_cast< basic_webengine::CertificateConfirmation, basic_webengine::WebConfirmation>(webConfirmation); @@ -1788,6 +1809,9 @@ void SimpleUI::handleConfirmationRequest( tizen_browser::basic_webengine::WebConfirmation::ConfirmationResult::Confirmed); m_webEngine->confirmationResult(webConfirmation); } else { +#if PWE_SHUB + if (!m_pwa.isActive()) +#endif m_webPageUI->getURIEntry().changeUri(webConfirmation->getURI()); TextPopup* popup = TextPopup::createPopup( m_viewManager.getContent()); diff --git a/services/WebEngineMin/WebEngineMin.cpp b/services/WebEngineMin/WebEngineMin.cpp index 658ed13..8d99159 100755 --- a/services/WebEngineMin/WebEngineMin.cpp +++ b/services/WebEngineMin/WebEngineMin.cpp @@ -8,6 +8,10 @@ #include "ServiceManager.h" #include "URIschemes.h" +#if PWE_SHUB +#include "boost/format.hpp" +#endif + namespace tizen_browser { namespace basic_webengine { @@ -43,7 +47,9 @@ WebEngineMin::~WebEngineMin() evas_object_smart_callback_del_full(m_ewkView, "policy,navigation,decide", __policy_navigation_decide_cb, this); evas_object_smart_callback_del_full(m_ewkView, "create,window,url", __newWindowRequestUrl, this); evas_object_smart_callback_del_full(m_ewkView, "policy,newwindow,decide", __policy_newwindow_decide_cb, this); - +#if PWE_SHUB + evas_object_smart_callback_del_full(m_ewkView, "request,certificate,confirm", __requestCertificationConfirm, this); +#endif evas_object_del(m_ewkView); } } @@ -112,7 +118,9 @@ void WebEngineMin::init(Evas_Object* guiParent) evas_object_smart_callback_add(m_ewkView, "policy,response,decide", __policy_response_decide_cb, this); evas_object_smart_callback_add(m_ewkView, "create,window,url", __newWindowRequestUrl, this); evas_object_smart_callback_add(m_ewkView, "policy,newwindow,decide", __policy_newwindow_decide_cb, this); - +#if PWE_SHUB + evas_object_smart_callback_add(m_ewkView, "request,certificate,confirm", __requestCertificationConfirm, this); +#endif auto permissions = *getPermissionsMap(); Eina_List* permList = nullptr; for (const auto& it : permissions) { @@ -267,6 +275,80 @@ void WebEngineMin::__policy_response_decide_cb(void *data, Evas_Object * /* obj } } +#if PWE_SHUB +// Copied from WebView.cpp +void WebEngineMin::__requestCertificationConfirm(void *data , Evas_Object * /* obj */, void *event_info) +{ + BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); + + WebEngineMin *self = reinterpret_cast<WebEngineMin *>(data); + Ewk_Certificate_Policy_Decision *request = reinterpret_cast<Ewk_Certificate_Policy_Decision *>(event_info); + if (!request) { + BROWSER_LOGW("[%s:%d] Wrong event_info!", __PRETTY_FUNCTION__, __LINE__); + return; + } + + int error = ewk_certificate_policy_decision_error_get(request); + if (error == EWK_CERTIFICATE_POLICY_DECISION_ERROR_PINNED_KEY_NOT_IN_CHAIN) { + ewk_certificate_policy_decision_allowed_set(request, EINA_FALSE); + BROWSER_LOGW("[%s:%d] EWK_CERTIFICATE_POLICY_DECISION_ERROR_PINNED_KEY_NOT_IN_CHAIN", __PRETTY_FUNCTION__, __LINE__); + self->unsecureConnection(); + return; + } + + self->suspend(); + ewk_certificate_policy_decision_suspend(request); + + std::string url = tools::extractDomain(self->m_loadingURL); + + ///\todo add translations + std::string message = (boost::format("There are problems with the security certificate for this site.<br>%1%") % url).str(); + + CertificateConfirmationPtr c = std::make_shared<CertificateConfirmation>(1/*tab_ID*/, url, message); + const char *pem = ewk_certificate_policy_decision_certificate_pem_get(request); + c->setPem(std::string(pem)); + c->setData(reinterpret_cast<void*>(request)); + + // store + self->m_confirmationCertificatenMap[c] = request; + self->confirmationRequest(c); +} + +// Copied from WebView.cpp +void WebEngineMin::confirmationResult(WebConfirmationPtr confirmation) +{ + BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); + + if (confirmation->getConfirmationType() == WebConfirmation::ConfirmationType::CertificateConfirmation) { + //FIXME: https://bugs.tizen.org/jira/browse/TT-229 + CertificateConfirmationPtr cert = std::dynamic_pointer_cast<CertificateConfirmation, WebConfirmation>(confirmation); + + // The below line doesn't serve any purpose now, but it may become + // relevant when implementing https://bugs.tizen.org/jira/browse/TT-229 + Ewk_Certificate_Policy_Decision *request = m_confirmationCertificatenMap[cert]; + Eina_Bool result; + + if (cert->getResult() == WebConfirmation::ConfirmationResult::Confirmed) { + result = EINA_TRUE; + } else if (cert->getResult() == WebConfirmation::ConfirmationResult::Rejected) { + result = EINA_FALSE; + } else { + BROWSER_LOGE("Wrong ConfirmationResult"); + return; + } + + // set certificate confirmation + ewk_certificate_policy_decision_allowed_set(request, result); + resume(); + + // remove from map + m_confirmationCertificatenMap.erase(cert); + } else { + BROWSER_LOGW("[%s:%d] Unknown WebConfirmation::ConfirmationType!", __PRETTY_FUNCTION__, __LINE__); + } +} +#endif + TabId WebEngineMin::addTab(const std::string& uri, const boost::optional<int>, const std::string&, diff --git a/services/WebEngineMin/WebEngineMin.h b/services/WebEngineMin/WebEngineMin.h index af81d10..beb88e9 100755 --- a/services/WebEngineMin/WebEngineMin.h +++ b/services/WebEngineMin/WebEngineMin.h @@ -92,7 +92,11 @@ public: void reload() override { } void back() override { } void forward() override { } - void confirmationResult(WebConfirmationPtr) override { } +#if PWE_SHUB + void confirmationResult(WebConfirmationPtr) override; +#else + void confirmationResult(WebConfirmationPtr) override { }; +#endif void setIMEState(const bool&) override { } void clearCache() override { } void clearCookies() override { } @@ -116,6 +120,7 @@ private: #if PWE_SHUB static void _register_service_worker_result_cb(Ewk_Context *context, const char* scope_url, const char* script_url, Eina_Bool result, void* data); + static void __requestCertificationConfirm(void *data, Evas_Object *obj, void *event_info); #endif static void __notification_reply_cb(void *data, Evas_Object *obj, void *event_info); static void __newWindowRequest(void *data, Evas_Object *, void*); @@ -128,6 +133,9 @@ private: Ewk_Context* m_ewkContext; std::string m_loadingURL; std::shared_ptr<DownloadControl> m_downloadControl; +#if PWE_SHUB + std::map<CertificateConfirmationPtr, Ewk_Certificate_Policy_Decision *> m_confirmationCertificatenMap; +#endif int m_policyCounter; static const std::string COOKIES_PATH; |