Initialize Tizen 2.3
[framework/web/wrt-plugins-common.git] / src_wearable / Commons / WrtAccess / WrtAccess.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  * @author      Grzegorz Krawczyk (g.krawczyk@samsung.com)
18  * @version     0.1
19  * @brief
20  */
21
22 #include <memory>
23 #include <sstream>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27
28 #include <dpl/log/log.h>
29 #include <dpl/log/secure_log.h>
30 #include <dpl/scoped_array.h>
31 #include <dpl/scoped_resource.h>
32 #include <dpl/assert.h>
33 #include <Commons/Exception.h>
34 #include "WrtAccess.h"
35 #include <ace_api_client.h>
36 #include <dpl/singleton_safe_impl.h>
37
38 #include "popup-runner.h"
39 IMPLEMENT_SAFE_SINGLETON(WrtDeviceApis::Commons::WrtAccess)
40
41 namespace {
42 /**
43  * Helper class - single parameter and its value
44  */
45 struct AceParam
46 {
47     const char *name;
48     const char *value;
49
50     AceParam() :
51         name(NULL), value(NULL)
52     {}
53
54     AceParam(const char *name, const char *value) :
55         name(name), value(value)
56     {}
57 };
58
59 /**
60  * Helper class - list of params for single dev cap
61  */
62 struct AceParamList
63 {
64     size_t count;
65     AceParam* param;
66     AceParamList() :
67         count(0),
68         param(NULL)
69     {}
70 };
71
72 struct DeviceCapParamPolicy
73 {
74     typedef AceParamList* Type;
75     static Type NullValue()
76     {
77         return NULL;
78     }
79     static void Destroy(Type ptr)
80     {
81         if (ptr) {
82             delete[] ptr->param;
83         }
84         delete[] ptr;
85     }
86 };
87
88 /**
89  * Helper class - modified ScopedArray for ace_param_list_t
90  */
91 class ScopedDeviceCapArray : public DPL::ScopedResource<DeviceCapParamPolicy>
92 {
93   public:
94     explicit ScopedDeviceCapArray(AceParamList *ptr =
95                                       DeviceCapParamPolicy::NullValue()) :
96         DPL::ScopedResource<DeviceCapParamPolicy>(ptr)
97     {}
98
99     AceParamList & operator [](std::ptrdiff_t k) const
100     {
101         AssertMsg(this->m_value != DeviceCapParamPolicy::NullValue(),
102                "Dereference of scoped NULL array!");
103         AssertMsg(k >= 0, "Negative array index");
104
105         return this->m_value[k];
106     }
107 };
108 } // namespace
109
110 namespace WrtDeviceApis {
111 namespace Commons {
112 WrtAccess::WrtAccess() :
113     m_sessionId(GenerateSessionId()),
114     m_pluginOwners(0)
115 {}
116
117 WrtAccess::~WrtAccess()
118 {}
119
120 WrtAccess::SessionId WrtAccess::GenerateSessionId()
121 {
122     const size_t SESSION_ID_LENGTH = 32;
123
124     std::ostringstream pid;
125     pid << static_cast<int>(getpid());
126
127     std::string session_id = pid.str();
128
129     session_id.reserve(session_id.length() + SESSION_ID_LENGTH);
130
131     for (size_t i = 0; i < SESSION_ID_LENGTH; ++i) {
132         int c = random() % 16;
133
134         session_id += (c < 10 ?
135                        static_cast<char>('0' + c) :
136                        static_cast<char>('A' + c - 10));
137     }
138     return session_id;
139 }
140
141 void WrtAccess::initialize(int widgetId)
142 {
143     _D("initialize");
144     if (widgetId < 0) {
145         _E("Invalid widget id");
146         Throw(Exception);
147     }
148
149     m_widgetId = widgetId;
150
151     if (!m_pluginOwners++) {
152         DPL::Log::LogSystemSingleton::Instance().SetTag("SECURITY_DAEMON");
153         ace_return_t ret = ace_client_initialize(Wrt::Popup::run_popup);
154         DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_PLUGINS");
155         Assert(ACE_OK == ret);
156     }
157 }
158
159 void WrtAccess::deinitialize(int /*widgetId*/)
160 {
161     _D("deinitialize");
162
163     if (!--m_pluginOwners) {
164         DPL::Log::LogSystemSingleton::Instance().SetTag("SECURITY_DAEMON");
165         ace_return_t ret = ace_client_shutdown();
166         DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_PLUGINS");
167         Assert(ACE_OK == ret);
168     }
169 }
170
171 int WrtAccess::getWidgetId() const
172 {
173     return m_widgetId;
174 }
175
176 WrtAccess::CheckAccessReturnType WrtAccess::checkAccessControl(const AceFunction& aceFunction) const
177 {
178     AssertMsg(
179         m_pluginOwners, "WrtAccessSingleton needs to be initialized with"
180                         "WidgetId during on_widget_start_callback in each plugin");
181     size_t deviceCount = aceFunction.deviceCapabilities.size();
182
183     DPL::ScopedArray <const char *> deviceScopedArray;
184     ScopedDeviceCapArray paramsScopedArray;
185
186     if (deviceCount) {
187         deviceScopedArray.Reset(new const char*[deviceCount]);
188         paramsScopedArray.Reset(new AceParamList[deviceCount]);
189
190         for (size_t i = 0; i < deviceCount; ++i) {
191             deviceScopedArray[i] =
192                 aceFunction.deviceCapabilities.at(i).devCapName.c_str();
193             paramsScopedArray[i].count =
194                 aceFunction.deviceCapabilities.at(i).devCapParams.size();
195
196             paramsScopedArray[i].param =
197                 new AceParam[paramsScopedArray[i].count];
198
199             for (size_t j = 0; j < paramsScopedArray[i].count; ++j) {
200                 paramsScopedArray[i].param[j].name =
201                     aceFunction.deviceCapabilities.at(i).
202                         devCapParams[j].name.c_str();
203                 paramsScopedArray[i].param[j].value =
204                     aceFunction.deviceCapabilities.at(i).
205                         devCapParams[j].value.c_str();
206             }
207         }
208     }
209
210     size_t featuresCount = aceFunction.features.size();
211
212     DPL::ScopedArray <const char*> featureScopedArray;
213     if (featuresCount) {
214         featureScopedArray.Reset(new const char*[featuresCount]);
215
216         for (size_t i = 0; i < featuresCount; ++i) {
217             featureScopedArray[i] =
218                 aceFunction.features.at(i).name.c_str();
219         }
220     }
221
222     _D("constructing ACE request");
223
224     ace_request_t aceRequest;
225     aceRequest.session_id =
226         const_cast<const ace_session_id_t>(m_sessionId.c_str());
227     aceRequest.widget_handle = getWidgetId();
228     aceRequest.feature_list.count = featuresCount;
229     aceRequest.feature_list.items =
230         const_cast<ace_string_t*>(featureScopedArray.Get());
231     aceRequest.dev_cap_list.count = deviceCount;
232     aceRequest.dev_cap_list.items = new ace_dev_cap_t[deviceCount];
233
234     const char**  devCapNames = deviceScopedArray.Get();
235     AceParamList* paramList = paramsScopedArray.Get();
236
237     unsigned int i;
238     for (i = 0; i < deviceCount; ++i) {
239         aceRequest.dev_cap_list.items[i].name =
240             const_cast<const ace_string_t>(devCapNames[i]);
241         aceRequest.dev_cap_list.items[i].param_list.count = paramList[i].count;
242         aceRequest.dev_cap_list.items[i].param_list.items =
243             new ace_param_t[paramList[i].count];
244         unsigned int j;
245         for (j = 0; j < paramList[i].count; ++j) {
246             aceRequest.dev_cap_list.items[i].param_list.items[j].name =
247                 const_cast<ace_string_t>(paramList[i].param[j].name);
248             aceRequest.dev_cap_list.items[i].param_list.items[j].value =
249                 const_cast<ace_string_t>(paramList[i].param[j].value);
250         }
251     }
252
253     ace_check_result_t aceCheckResult = ACE_PRIVILEGE_DENIED;
254     DPL::Log::LogSystemSingleton::Instance().SetTag("SECURITY_DAEMON");
255     ace_return_t ret = ace_check_access_ex(&aceRequest, &aceCheckResult);
256     DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_PLUGINS");
257     for (i = 0; i < deviceCount; ++i) {
258         delete[] aceRequest.dev_cap_list.items[i].param_list.items;
259     }
260     delete[] aceRequest.dev_cap_list.items;
261
262     if (ACE_OK != ret) {
263         _E("Error in ace check: %d", static_cast<int>(ret));
264         return CHECK_ACCESS_INTERNAL_ERROR;
265     }
266
267     if (aceCheckResult == ACE_ACCESS_GRANTED) {
268         return CHECK_ACCESS_GRANTED;
269     }
270     else if (aceCheckResult == ACE_PRIVILEGE_DENIED) {
271         return CHECK_ACCESS_PRIVILEGE_DENIED;
272     }
273     else if (aceCheckResult == ACE_PRIVACY_DENIED) {
274         return CHECK_ACCESS_PRIVACY_DENIED;
275     }
276
277     return CHECK_ACCESS_INTERNAL_ERROR;
278 }
279 }
280 } // WrtDeviceApisCommon