461ee88bd8177c1d81155bf6055fb22d5931daa8
[platform/core/appfw/app-installers.git] / src / common / pkgmgr_registration.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/pkgmgr_registration.h"
6
7 #include <manifest_parser/utils/logging.h>
8 #include <pkgmgr_installer.h>
9 #include <pkgmgr_parser_db.h>
10 #include <tzplatform_config.h>
11 #include <unistd.h>
12
13 #include <vector>
14 #include <utility>
15
16 #include "common/utils/glist_range.h"
17 #include "common/utils/manifest_util.h"
18
19 namespace bf = boost::filesystem;
20
21
22 namespace {
23
24 using CertInfo = common_installer::CertificateInfo;
25
26 const char kWidgetApp[] = "widgetapp";
27
28 bool RegisterCertificate(pkgmgr_instcertinfo_h handle,
29 const ValidationCore::CertificatePtr& certPtr, pkgmgr_instcert_type type) {
30     if (certPtr) {
31       if (pkgmgr_installer_set_cert_value(handle, type,
32           const_cast<char*>(certPtr->getBase64().c_str())) < 0) {
33         pkgmgr_installer_destroy_certinfo_set_handle(handle);
34         LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
35         return false;
36       }
37     }
38     return true;
39 }
40
41 typedef Property<ValidationCore::CertificatePtr> CertInfo::*PropertyOfCertInf;
42
43 const std::vector<std::pair<PropertyOfCertInf, pkgmgr_instcert_type>>
44     kCertTypePairs = {
45   {&CertInfo::auth_cert, PM_SET_AUTHOR_SIGNER_CERT},
46   {&CertInfo::auth_im_cert, PM_SET_AUTHOR_INTERMEDIATE_CERT},
47   {&CertInfo::auth_root_cert, PM_SET_AUTHOR_ROOT_CERT},
48   {&CertInfo::dist_cert, PM_SET_DISTRIBUTOR_SIGNER_CERT},
49   {&CertInfo::dist_im_cert,
50       PM_SET_DISTRIBUTOR_INTERMEDIATE_CERT},
51   {&CertInfo::dist_root_cert, PM_SET_DISTRIBUTOR_ROOT_CERT},
52   {&CertInfo::dist2_cert, PM_SET_DISTRIBUTOR2_SIGNER_CERT},
53   {&CertInfo::dist2_im_cert,
54       PM_SET_DISTRIBUTOR2_INTERMEDIATE_CERT},
55   {&CertInfo::dist2_root_cert, PM_SET_DISTRIBUTOR2_ROOT_CERT}
56 };
57
58 bool RegisterCertificates(
59     const CertInfo& cert_info,
60     const std::string& pkgid, uid_t uid) {
61   pkgmgr_instcertinfo_h handle;
62   if (pkgmgr_installer_create_certinfo_set_handle(&handle) < 0) {
63     LOG(ERROR) << "Cannot create pkgmgr_instcertinfo_h";
64     return false;
65   }
66   for (auto pair : kCertTypePairs) {
67      auto cert = (cert_info.*(pair.first)).get();
68      auto type = pair.second;
69      if (!RegisterCertificate(handle, cert, type))
70        return false;
71   }
72   if (pkgmgr_installer_save_certinfo(pkgid.c_str(), handle, uid) < 0) {
73     pkgmgr_installer_destroy_certinfo_set_handle(handle);
74     LOG(ERROR) << "Failed to save certificate information";
75     return false;
76   }
77
78   pkgmgr_installer_destroy_certinfo_set_handle(handle);
79   return true;
80 }
81
82 void AdjustWidgetNodisplayAttr(manifest_x* manifest) {
83   for (auto& app : GListRange<application_x*>(manifest->application)) {
84     if (!strcmp(app->component_type, kWidgetApp)) {
85       free(app->nodisplay);
86       // The nodisplay attribute of widget application should be true,
87       // but nodisplay of widget-service framework uses this attribute
88       // as defined at manifest file. So we need to adjust this value
89       // just before register in pkgmgr db.
90       app->nodisplay = strdup("true");
91     }
92   }
93 }
94
95 }  // namespace
96
97 namespace common_installer {
98
99 bool RegisterAppInPkgmgr(manifest_x* manifest,
100                          const std::string& pkgid,
101                          const CertificateInfo& cert_info,
102                          uid_t uid,
103                          Storage storage,
104                          RequestMode request_mode,
105                          const boost::filesystem::path& tep_path) {
106   // Fill "non-xml" elements
107   if (!tep_path.empty())
108     manifest->tep_name = strdup(tep_path.c_str());
109
110   if (storage == Storage::EXTENDED) {
111     bf::path ext_path = bf::path(GetExtendedRootAppPath(uid)) / pkgid;
112     manifest->external_path = strdup(ext_path.c_str());
113   } else if (storage == Storage::EXTERNAL) {
114     App2ExtDynamicService service;
115     std::string image_path = service.GetExternalImagePath(pkgid.c_str(), uid);
116     if (!image_path.empty())
117       manifest->external_path = strdup(image_path.c_str());
118   }
119
120   AdjustWidgetNodisplayAttr(manifest);
121
122   int ret = request_mode != RequestMode::GLOBAL ?
123       pkgmgr_parser_process_usr_manifest_x_for_installation(manifest, uid) :
124       pkgmgr_parser_process_manifest_x_for_installation(manifest);
125   if (ret) {
126     LOG(ERROR) << "Failed to insert manifest into pkgmgr, error code=" << ret;
127     return false;
128   }
129
130   if (!RegisterCertificates(cert_info, pkgid, uid)) {
131     LOG(ERROR) << "Failed to register author certificate";
132     return false;
133   }
134
135   return true;
136 }
137
138 bool UpgradeAppInPkgmgr(manifest_x* manifest,
139                         const std::string& pkgid,
140                         const CertificateInfo& cert_info,
141                         uid_t uid,
142                         Storage storage,
143                         RequestMode request_mode) {
144   if (storage == Storage::EXTENDED) {
145     bf::path ext_path = bf::path(GetExtendedRootAppPath(uid)) / pkgid;
146     manifest->external_path = strdup(ext_path.c_str());
147   } else if (storage == Storage::EXTERNAL) {
148     App2ExtDynamicService service;
149     std::string image_path = service.GetExternalImagePath(pkgid.c_str(), uid);
150     if (!image_path.empty())
151       manifest->external_path = strdup(image_path.c_str());
152   }
153
154   AdjustWidgetNodisplayAttr(manifest);
155
156   int ret = request_mode != RequestMode::GLOBAL ?
157        pkgmgr_parser_process_usr_manifest_x_for_upgrade(manifest, uid) :
158        pkgmgr_parser_process_manifest_x_for_upgrade(manifest);
159
160   if (ret != 0) {
161     LOG(ERROR) << "Failed to update manifest in pkgmgr, error code=" << ret;
162     return false;
163   }
164
165   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
166   if (!RegisterCertificates(cert_info, pkgid, uid))
167     return false;
168
169   return true;
170 }
171
172 bool UnregisterAppInPkgmgrForPkgId(const std::string& pkgid, uid_t uid,
173                                    RequestMode request_mode) {
174   manifest_x* manifest = PkgmgrGenerateManifestInfoFromDB(pkgid, uid);
175   if (!manifest) {
176     LOG(ERROR) << "Failed to get manifest_x from DB";
177     return false;
178   }
179   bool res = UnregisterAppInPkgmgr(manifest, pkgid, uid, request_mode);
180   pkgmgr_parser_free_manifest_xml(manifest);
181   return res;
182 }
183
184 bool UnregisterAppInPkgmgr(manifest_x* manifest,
185                            const std::string& pkgid,
186                            uid_t uid,
187                            RequestMode request_mode) {
188   int ret = request_mode != RequestMode::GLOBAL ?
189       pkgmgr_parser_process_usr_manifest_x_for_uninstallation(manifest, uid) :
190       pkgmgr_parser_process_manifest_x_for_uninstallation(manifest);
191   if (ret) {
192     LOG(ERROR) << "Failed to delete manifest from pkgmgr, error code=" << ret;
193     return false;
194   }
195
196   // Certificate info may be not present
197   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
198
199   return true;
200 }
201
202 bool UpdateTepInfoInPkgmgr(const bf::path& tep_path, const std::string& pkgid,
203                         uid_t uid, RequestMode request_mode) {
204   int ret = request_mode != RequestMode::GLOBAL ?
205         pkgmgr_parser_usr_update_tep(
206             pkgid.c_str(), tep_path.string().c_str(), uid) :
207         pkgmgr_parser_update_tep(
208             pkgid.c_str(), tep_path.string().c_str());
209
210   if (ret != 0) {
211     LOG(ERROR) << "Failed to upgrade tep info: " << pkgid;
212     return false;
213   }
214
215   return true;
216 }
217
218 bool UpdateInstalledStorageInPkgmgr(Storage storage, const bf::path& ext_path,
219                                     const std::string& pkgid, uid_t uid) {
220   // FIXME: refactor this
221   INSTALL_LOCATION install_location;
222   const char* path;
223   if (storage == Storage::INTERNAL) {
224     install_location = INSTALL_INTERNAL;
225     path = "";
226   } else if (storage == Storage::EXTERNAL) {
227     install_location = INSTALL_EXTERNAL;
228     path = ext_path.string().c_str();
229   } else {
230     install_location = INSTALL_EXTENDED;
231     path = ext_path.string().c_str();
232   }
233   int ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(
234       pkgid.c_str(), install_location, path, uid);
235   if (ret != 0) {
236     LOG(ERROR) << "Failed to update installed storage info: " << pkgid;
237     return false;
238   }
239
240   return true;
241 }
242
243 bool DisablePkgInPkgmgr(const std::string& pkgid, uid_t uid,
244                         RequestMode request_mode) {
245   int ret = request_mode != RequestMode::GLOBAL ?
246         pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid.c_str(), uid, 1) :
247         pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 1);
248   if (ret != 0) {
249     LOG(ERROR) << "Failed to disable pkg: " << pkgid;
250     return false;
251   }
252
253   return true;
254 }
255
256 bool EnablePkgInPkgmgr(const std::string& pkgid, uid_t uid,
257     RequestMode request_mode) {
258   int ret = request_mode != RequestMode::GLOBAL ?
259         pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid.c_str(), uid, 0) :
260         pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 0);
261   if (ret != 0) {
262     LOG(ERROR) << "Failed to enable pkg: " << pkgid;
263     return false;
264   }
265
266   return true;
267 }
268
269 bool RegisterPluginInfo(manifest_x* manifest,
270                         uid_t uid,
271                         RequestMode request_mode) {
272   int ret = request_mode != RequestMode::GLOBAL ?
273       pkgmgr_parser_register_pkg_plugin_info_in_usr_db(manifest, uid) :
274       pkgmgr_parser_register_pkg_plugin_info_in_db(manifest);
275   if (ret) {
276     LOG(ERROR) << "Failed to insert plugin info, error code=" << ret;
277     return false;
278   }
279   return true;
280 }
281
282 bool UpdatePluginInfo(manifest_x* manifest,
283                       uid_t uid, RequestMode request_mode) {
284   int ret = request_mode != RequestMode::GLOBAL ?
285       pkgmgr_parser_update_pkg_plugin_info_in_usr_db(manifest, uid) :
286       pkgmgr_parser_update_pkg_plugin_info_in_db(manifest);
287   if (ret) {
288     LOG(ERROR) << "Failed to insert update plugin info, error code=" << ret;
289     return false;
290   }
291   return true;
292 }
293
294 bool UnregisterPluginInfo(const std::string& pkgid,
295                           uid_t uid,
296                           RequestMode request_mode) {
297   int ret = request_mode != RequestMode::GLOBAL ?
298       pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db(pkgid.c_str(), uid) :
299       pkgmgr_parser_unregister_pkg_plugin_info_in_db(pkgid.c_str());
300   if (ret) {
301     LOG(ERROR) << "Failed to remove plugin info, error code=" << ret;
302     return false;
303   }
304   return true;
305 }
306
307 }  // namespace common_installer