Prepare wrt to handle csp policy rules.
[platform/framework/web/wrt.git] / src / api_new / runnable_widget_object.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file    core_module.cpp
18  * @author  Przemyslaw Ciezkowski (p.ciezkowski@samsung.com)
19  * @version 1.0
20  * @brief   File contains defitinions of RunnableWidgetObject implementation.
21  */
22
23 #include <runnable_widget_object.h>
24 #include <privilege-control.h>
25 #include <dpl/exception.h>
26 #include <dpl/wrt-dao-ro/global_config.h>
27 #include <dpl/utils/wrt_global_settings.h>
28 #include <appcore-common.h>
29 #include <profiling_util.h>
30 #include <signal.h>
31 #include "webkit/bundles/plugin_module_support.h"
32 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
33 #include <runnable_widget_object_state.h>
34 #include <wrt_ocsp_api.h>
35 #include <popup-runner/PopupInvoker.h>
36 #include "ewk_context_manager.h"
37
38 #include "webkit_csp_support_mock.h"
39
40 namespace { //Anonymous
41 const std::string ACCESS_DENIED = _("IDS_BR_POP_ACCESS_DENIED");
42 const std::string ALREADY_RUNNING = _("IDS_BR_POP_ALREADY_RUNNING");
43 const std::string INVALID_LOCALE = _("IDS_IM_POP_INVALID_WIDGET_LOCALE");
44 const std::string STILL_AUTHORIZING = _("IDS_IM_POP_AUTHORIZING_ING_ATNT");
45 const unsigned int UID_ROOT = 0;
46 } // namespace anonymous
47
48 namespace WRT {
49 RunnableWidgetObject::RunnableWidgetObject(WidgetModelPtr &model) :
50         m_widgetModel(model),
51         m_view(ViewModule::createView())
52 {
53     //set initial state of runnable object
54     m_guardstate = std::shared_ptr<State::RunnableWidgetObjectState>(
55             new State::InitialState(*this));
56     // If current uid is 'root', change privilege to apps
57     if (UID_ROOT == getuid()) {
58         // Set privilege by tizen id
59         // this code prevent that widget launch with "root" permission,
60         // when developers launch by command in the shell
61         set_privilege(DPL::ToUTF8String(m_widgetModel->TizenId).c_str());
62     }
63 }
64
65 bool RunnableWidgetObject::CheckBeforeLaunch()
66 {
67     State::StateChange change = m_guardstate->allowCheckBeforeLaunch();
68     Assert(m_widgetModel);
69
70 #ifdef WRT_SMACK_ENABLED
71     // TODO - this should be in the very first line of the process's main()
72     // for security reasons; but for now it is easier to place here because
73     // here the pkg name is already known; we don't struggle to move it
74     // near the start of main() because we don't know yet if this will
75     // stay in this process at all: it may be moved to AUL altogether
76     set_process_config(DPL::ToUTF8String(widgetModel->TizenId).c_str());
77 #endif
78
79     // Inform view controller about new widget model displaying
80     ADD_PROFILING_POINT("OCSPCheck", "start");
81
82     wrt_ocsp_widget_verification_status_t response;
83     if (m_widgetModel->Type.Get().appType == WrtDB::APP_TYPE_WAC20) {
84         wrt_ocsp_initialize();
85         wrt_ocsp_verify_widget(WrtDB::WidgetDAOReadOnly::getHandle(
86                                    m_widgetModel->TizenId), &response);
87         wrt_ocsp_shutdown();
88     } else {
89         response = WRT_OCSP_WIDGET_VERIFICATION_STATUS_GOOD;
90     }
91     ADD_PROFILING_POINT("OCSPCheck", "stop");
92
93     LogDebug("WRT OCSP response " << static_cast<int>(response));
94     if (response == WRT_OCSP_WIDGET_VERIFICATION_STATUS_GOOD) {
95         change.commit();
96         return true;
97     } else {
98         if (!GlobalSettings::PopupsTestModeEnabled()) {
99             Wrt::Popup::PopupInvoker().showInfo(
100                 _("IDS_IM_POP_WIDGET_REVOKED_TITLE"),
101                 _("IDS_IM_POP_WIDGET_REVOKED_ERROR"),
102                 _("IDS_IM_BUTTON_OK"));
103         }
104         return false;
105     }
106 }
107
108 bool RunnableWidgetObject::PrepareView(const std::string &startUrl,
109         Evas_Object *window, Ewk_Context* ewkContext)
110 {
111     State::StateChange change = m_guardstate->allowPrepareView();
112     if (!window) {
113         return false;
114     }
115
116     std::string appId = DPL::ToUTF8String(m_widgetModel->TizenId);
117     Try {
118         if(!m_ewkContextManager) {
119             m_ewkContextManager =
120                 EwkContextManager::create(appId, ewkContext, m_view);
121         } else {
122             if (ewkContext &&
123                     ewkContext != m_ewkContextManager->getEwkContext())
124             {
125                 m_ewkContextManager =
126                     EwkContextManager::create(appId, ewkContext, m_view);
127             }
128         }
129     } Catch (DPL::Exception) {
130         LogError("Internal Error during create or initialize Ewk Context");
131         return false;
132     }
133
134 #ifdef CSP_ENABLED
135     LogInfo("Setting CSP default policy");
136     // setting CSP policy rules
137     WKStringRef defaultPolicy = WKStringCreateWithUTF8CString("default-src ‘self’;");
138     CSP_Rules rule;     // = new CSP_Rules;
139     rule.default_src = OVERWRITE;
140     rule.other_src = OVERWRITE;
141     rule.sandbox = OVERWRITE;
142     //trusted apps allow unsafe directives
143     rule.allow_unsafe = true;
144
145     if (0 != apply_csp(ewkContext, defaultPolicy, &rule, NULL))
146         LogWarning("Failed to apply default csp policy");
147
148     DPL::OptionalString policy = m_widgetModel->CspPolicy.Get();
149
150     if (!(policy.IsNull()))
151     {
152         WrtDB::WidgetDAOReadOnly dao(m_widgetModel->TizenId);
153         bool trusted = dao.isTrusted();
154
155         LogDebug("CSP policy present in manifest: " << *policy);
156         LogDebug("Widget trusted: " << trusted);
157
158         //config file policy
159         CSP_Rules manifest_rule;
160         manifest_rule.default_src = trusted ? OVERWRITE : IGNORE;
161         manifest_rule.other_src = SUM;
162         manifest_rule.sandbox = SUM;
163         //trusted apps allow unsafe directives
164         manifest_rule.allow_unsafe = trusted;
165
166         //merging algorithm for http/meta policy
167         CSP_Rules http_rule;
168         http_rule.default_src = INTERSECTION;
169         http_rule.other_src = INTERSECTION;
170         http_rule.sandbox = INTERSECTION;
171         //trusted apps allow unsafe directives
172         http_rule.allow_unsafe = trusted;
173
174         LogDebug("Setting manifest and http/meta policy");
175         if (0 != apply_csp(
176             ewkContext,
177             WKStringCreateWithUTF8CString(DPL::ToUTF8String(*policy).c_str()),
178             &manifest_rule,
179             &http_rule))
180         {
181             LogWarning("Failed to set manifest csp policy");
182         }
183     } else {
184         LogDebug("Config CSP policy is not present");
185     }
186     LogInfo("CSP set.");
187 #endif
188     ADD_PROFILING_POINT("view_logic_init", "start");
189     Ewk_Context* context = m_ewkContextManager->getEwkContext();
190
191     // plugin init
192     PluginModuleSupport::init(context, DPL::ToUTF8String(m_widgetModel->TizenId));
193
194     // view init
195     if(!m_view->createWebView(context, window)) {
196         return false;
197     }
198     m_view->prepareView(m_widgetModel.get(), startUrl);
199     ADD_PROFILING_POINT("view_logic_init", "stop");
200
201     change.commit();
202     return true;
203 }
204
205 void RunnableWidgetObject::Show()
206 {
207     State::StateChange change = m_guardstate->allowShow();
208
209     m_view->showWidget();
210
211     change.commit();
212 }
213
214 void RunnableWidgetObject::Hide()
215 {
216     State::StateChange change = m_guardstate->allowHide();
217
218     m_view->hideWidget();
219
220     change.commit();
221 }
222
223 void RunnableWidgetObject::Suspend()
224 {
225     LogDebug("Suspending widget");
226     State::StateChange change = m_guardstate->allowSuspend();
227     m_view->suspendWidget();
228
229     change.commit();
230 }
231
232 void RunnableWidgetObject::Resume()
233 {
234     LogDebug("Resuming widget");
235     State::StateChange change = m_guardstate->allowResume();
236     m_view->resumeWidget();
237
238     change.commit();
239 }
240
241 void RunnableWidgetObject::Reset()
242 {
243     LogDebug("Reseting widget");
244     State::StateChange change = m_guardstate->allowReset();
245     m_view->resetWidget();
246
247     change.commit();
248 }
249
250 void RunnableWidgetObject::ReloadStartPage()
251 {
252     m_view->reloadStartPage();
253 }
254
255 Evas_Object* RunnableWidgetObject::GetCurrentWebview()
256 {
257     State::StateChange change = m_guardstate->allowGetCurrentWebview();
258
259     Evas_Object* cww = m_view->getCurrentWebview();
260
261     change.commit();
262     return cww;
263 }
264
265 void RunnableWidgetObject::SetUserDelegates(const UserDelegatesPtr& cbs)
266 {
267     State::StateChange change = m_guardstate->allowSetUserDelegates();
268     m_view->setUserCallbacks(cbs);
269     change.commit();
270 }
271
272 void RunnableWidgetObject::Backward()
273 {
274     State::StateChange change = m_guardstate->allowBackward();
275     m_view->backward();
276
277     change.commit();
278 }
279
280 void RunnableWidgetObject::FireJavascriptEvent(int event, void* data)
281 {
282     State::StateChange change = m_guardstate->allowFireJavascriptEvent();
283     m_view->fireJavascriptEvent(event, data);
284
285     change.commit();
286 }
287
288 void RunnableWidgetObject::setNewState(
289     std::shared_ptr<State::RunnableWidgetObjectState> sptr)
290 {
291     LogInfo("RunnableWidgetObject changes state to: " << sptr->toString());
292     m_guardstate = sptr;
293 }
294
295 RunnableWidgetObject::~RunnableWidgetObject()
296 {
297     LogDebug("");
298     PluginModuleSupport::shutdown(m_ewkContextManager->getEwkContext());
299 }
300 } /* namespace WRT */