eca33058ca3081a2b1b863b7c322a3347812be18
[framework/security/security-server.git] / ace_install / src / ace_api_install.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        ace_api_install.cpp
18  * @author      Tomasz Swierczek (t.swierczek@samsung.com)
19  * @version     1.0
20  * @brief       This file contains implementation ACE installator API
21  */
22
23 #include <string>
24 #include <utility>
25 #include <string.h>
26 #include <dpl/log/log.h>
27 #include <dpl/foreach.h>
28 #include <dpl/string.h>
29 #include "SecurityCommunicationClient.h"
30 #include <ace-dao-rw/AceDAO.h>
31 #include "ace_server_api.h"
32
33 #include "ace_api_install.h"
34
35 static WrtSecurity::Communication::Client *communicationClient = NULL;
36
37 // helper functions
38
39 static AceDB::AppTypes to_db_app_type(ace_widget_type_t widget_type)
40 {
41     switch (widget_type) {
42     case WAC20:
43         return AceDB::AppTypes::WAC20;
44     case Tizen:
45         return AceDB::AppTypes::Tizen;
46     default:
47         return AceDB::AppTypes::Unknown;
48     }
49 }
50
51 static ace_widget_type_t to_ace_widget_type(AceDB::AppTypes app_type)
52 {
53     switch (app_type) {
54     case AceDB::AppTypes::WAC20:
55         return WAC20;
56     case AceDB::AppTypes::Tizen:
57         return Tizen;
58     default:
59         LogError("Invalid app type for widget");
60         return WAC20;
61     }
62 }
63
64 ace_return_t ace_install_initialize(void)
65 {
66     if (NULL != communicationClient) {
67         LogError("ace_api_install already initialized");
68         return ACE_INTERNAL_ERROR;
69     }
70     AceDB::AceDAO::attachToThreadRW();
71     Try {
72         communicationClient = new WrtSecurity::Communication::Client(
73                    WrtSecurity::AceServerApi::INTERFACE_NAME());
74     } Catch (WrtSecurity::Communication::Client::Exception::SecurityCommunicationClientException) {
75         LogError("Can't connect to daemon");
76         return ACE_INTERNAL_ERROR;
77     }
78     return ACE_OK;
79 }
80
81 ace_return_t ace_install_shutdown(void)
82 {
83     if (NULL == communicationClient) {
84         LogError("ace_api_install not initialized");
85         return ACE_INTERNAL_ERROR;
86     }
87     delete communicationClient;
88     communicationClient = NULL;
89     AceDB::AceDAO::detachFromThread();
90     return ACE_OK;
91 }
92
93 ace_return_t ace_update_policy(void)
94 {
95     Try {
96         communicationClient->call(WrtSecurity::AceServerApi::UPDATE_POLICY_METHOD());
97     } Catch (WrtSecurity::Communication::Client::Exception::SecurityCommunicationClientException) {
98         LogError("Problem with connection to daemon");
99         return ACE_INTERNAL_ERROR;
100     }
101     return ACE_OK;
102 }
103
104 ace_return_t ace_free_requested_dev_caps(ace_requested_dev_cap_list_t* caps)
105 {
106     if (NULL == caps || NULL == caps->items) {
107         LogError("Invalid arguments");
108         return ACE_INVALID_ARGUMENTS;
109     }
110     unsigned int i;
111     for (i = 0; i < caps->count; ++i) {
112         delete [] caps->items[i].device_capability;
113     }
114     delete [] caps->items;
115     return ACE_OK;
116 }
117
118 ace_return_t ace_get_requested_dev_caps(ace_widget_handle_t handle,
119                                         ace_requested_dev_cap_list_t* caps)
120 {
121     if (NULL == caps) {
122         LogError("Invalid arguments");
123         return ACE_INVALID_ARGUMENTS;
124     }
125     AceDB::RequestedDevCapsMap permissions;
126     Try {
127         AceDB::AceDAO::getRequestedDevCaps(
128                 handle, &permissions);
129     } Catch(AceDB::AceDAOReadOnly::Exception::DatabaseError) {
130         return ACE_INTERNAL_ERROR;
131     }
132     caps->items = new ace_requested_dev_cap_t[permissions.size()];
133     caps->count = permissions.size();
134     unsigned int i = 0;
135     FOREACH (it, permissions) {
136         std::string devCapRequested = DPL::ToUTF8String(it->first);
137         caps->items[i].device_capability =
138                 new char[strlen(devCapRequested.c_str())+1];
139         strcpy(caps->items[i].device_capability, devCapRequested.c_str());
140         caps->items[i].smack_granted = it->second ? ACE_TRUE : ACE_FALSE;
141         ++i;
142     }
143     return ACE_OK;
144 }
145
146 ace_return_t ace_set_requested_dev_caps(
147         ace_widget_handle_t handle,
148         const ace_requested_dev_cap_list_t* caps)
149 {
150     if (NULL == caps) {
151         LogError("Invalid arguments");
152         return ACE_INVALID_ARGUMENTS;
153     }
154     AceDB::RequestedDevCapsMap db_permissions;
155     unsigned int i;
156     for (i = 0; i < caps->count; ++i) {
157         std::string devCap = std::string(caps->items[i].device_capability);
158         db_permissions.insert(std::make_pair(DPL::FromUTF8String(devCap),
159                               caps->items[i].smack_granted == ACE_TRUE));
160     }
161     Try {
162         AceDB::AceDAO::setRequestedDevCaps(
163                 handle, db_permissions);
164     } Catch(AceDB::AceDAOReadOnly::Exception::DatabaseError) {
165         return ACE_INTERNAL_ERROR;
166     }
167     return ACE_OK;
168 }
169
170 ace_return_t ace_set_accepted_feature(
171         ace_widget_handle_t handle,
172         const ace_feature_list_t *feature)
173 {
174     if (NULL == feature) {
175         LogError("Invalid argument");
176         return ACE_INVALID_ARGUMENTS;
177     }
178     AceDB::FeatureNameVector fvector;
179     ace_size_t i;
180     for (i = 0; i < feature->count; ++i) {
181         fvector.push_back(
182             DPL::FromUTF8String(feature->items[i]));
183     }
184     Try {
185         AceDB::AceDAO::setAcceptedFeature(handle, fvector);
186     } Catch(AceDB::AceDAOReadOnly::Exception::DatabaseError) {
187         return ACE_INTERNAL_ERROR;
188     }
189     return ACE_OK;
190 }
191
192 ace_return_t ace_rem_accepted_feature(
193         ace_widget_handle_t handle)
194 {
195     Try {
196         AceDB::AceDAO::removeAcceptedFeature(handle);
197     } Catch(AceDB::AceDAOReadOnly::Exception::DatabaseError) {
198         return ACE_INTERNAL_ERROR;
199     }
200     return ACE_OK;
201 }
202
203 ace_return_t ace_register_widget(ace_widget_handle_t handle,
204                                  struct widget_info *info,
205                                  ace_certificate_data* cert_data[])
206 {
207     LogDebug("enter");
208
209     if (NULL == info || AceDB::AceDAOReadOnly::isWidgetInstalled(handle))
210         return ACE_INVALID_ARGUMENTS;
211
212     AceDB::WidgetRegisterInfo wri;
213     wri.type = to_db_app_type(info->type);
214
215     if (info->id)
216         wri.widget_id = DPL::FromUTF8String(info->id);
217     if (info->version)
218         wri.version = DPL::FromUTF8String(info->version);
219     if (info->author)
220         wri.authorName = DPL::FromUTF8String(info->author);
221     if (info->shareHerf)
222         wri.shareHref = DPL::FromUTF8String(info->shareHerf);
223
224     AceDB::WidgetCertificateDataList dataList;
225     if (NULL != cert_data) {
226         AceDB::WidgetCertificateData wcd;
227         ace_certificate_data* cd;
228         int i = 0;
229         while (cert_data[i] != NULL)
230         {
231             cd = cert_data[i++]; //increment
232             switch(cd->type) {
233             case ROOT:
234                 wcd.type = AceDB::WidgetCertificateData::Type::ROOT;
235                 break;
236             case ENDENTITY:
237                 wcd.type = AceDB::WidgetCertificateData::Type::ENDENTITY;
238                 break;
239             }
240             switch(cd->owner) {
241             case AUTHOR:
242                 wcd.owner = AceDB::WidgetCertificateData::Owner::AUTHOR;
243                 break;
244             case DISTRIBUTOR:
245                 wcd.owner = AceDB::WidgetCertificateData::Owner::DISTRIBUTOR;
246                 break;
247             case UNKNOWN: default:
248                 wcd.owner = AceDB::WidgetCertificateData::Owner::UNKNOWN;
249                 break;
250             }
251             wcd.chainId = cd->chain_id;
252             if (cd->md5_fp)
253                 wcd.strMD5Fingerprint = cd->md5_fp;
254             if (cd->sha1_fp)
255                 wcd.strSHA1Fingerprint = cd->sha1_fp;
256             if (cd->common_name)
257                 wcd.strCommonName = DPL::FromUTF8String(cd->common_name);
258             dataList.push_back(wcd);
259         }
260         LogDebug("All data set. Inserting into database.");
261     }
262
263     Try {
264         AceDB::AceDAO::registerWidgetInfo((WidgetHandle)(handle), wri, dataList);
265         LogDebug("AceDB entry done");
266     } Catch(AceDB::AceDAOReadOnly::Exception::DatabaseError) {
267         return ACE_INTERNAL_ERROR;
268     }
269     return ACE_OK;
270 }
271
272 ace_return_t ace_unregister_widget(ace_widget_handle_t handle)
273 {
274     Try {
275         AceDB::AceDAO::unregisterWidgetInfo((WidgetHandle)(handle));
276     } Catch(AceDB::AceDAOReadOnly::Exception::DatabaseError) {
277         return ACE_INTERNAL_ERROR;
278     }
279     return ACE_OK;
280 }
281
282 ace_return_t ace_is_widget_installed(ace_widget_handle_t handle, bool *installed)
283 {
284     Try {
285         *installed = AceDB::AceDAO::isWidgetInstalled((WidgetHandle)(handle));
286     } Catch(AceDB::AceDAOReadOnly::Exception::DatabaseError) {
287         return ACE_INTERNAL_ERROR;
288     }
289     return ACE_OK;
290 }
291
292 ace_return_t ace_get_widget_type(ace_widget_handle_t handle,
293                                  ace_widget_type_t* type)
294 {
295     if (NULL == type) {
296         LogError("Invalid arguments");
297         return ACE_INVALID_ARGUMENTS;
298     }
299     Try {
300         AceDB::AppTypes db_type = AceDB::AceDAO::getWidgetType(handle);
301         *type = to_ace_widget_type(db_type);
302     } Catch(AceDB::AceDAOReadOnly::Exception::DatabaseError) {
303         return ACE_INTERNAL_ERROR;
304     }
305     return ACE_OK;
306 }
307
308 ace_return_t ace_get_policy_result(const ace_resource_t resource,
309                                    ace_widget_handle_t handle,
310                                    ace_policy_result_t* result)
311 {
312     if (NULL == result) {
313         LogError("Invalid arguments");
314         return ACE_INVALID_ARGUMENTS;
315     }
316     int serializedPolicyResult = 0;
317     Try {
318        std::string resource_str(resource);
319        communicationClient->call(WrtSecurity::AceServerApi::CHECK_ACCESS_INSTALL_METHOD(),
320                         handle,
321                         resource_str,
322                         &serializedPolicyResult);
323    } Catch (WrtSecurity::Communication::Client::Exception::SecurityCommunicationClientException) {
324        LogError("Can't connect to daemon");
325        return ACE_INTERNAL_ERROR;
326    }
327    PolicyResult policyResult = PolicyResult::
328            deserialize(serializedPolicyResult);
329    OptionalPolicyEffect effect = policyResult.getEffect();
330    if (effect.IsNull()) {
331        *result = ACE_UNDEFINED;
332    } else if (*effect == PolicyEffect::DENY) {
333        *result = ACE_DENY;
334    } else if (*effect == PolicyEffect::PERMIT) {
335        *result = ACE_PERMIT;
336    } else if (*effect == PolicyEffect::PROMPT_ONESHOT ||
337               *effect == PolicyEffect::PROMPT_BLANKET ||
338               *effect == PolicyEffect::PROMPT_SESSION){
339        *result = ACE_PROMPT;
340    } else {
341        *result = ACE_UNDEFINED;
342    }
343
344    return ACE_OK;
345 }