Remove boost dependency
[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 fs = std::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 (const 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 std::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     fs::path ext_path = fs::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     fs::path ext_path = fs::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   // TODO(jeremy.jang): consider updating cert only when dist cert is changed.
166   // because the package from different author is not allowed to be installed,
167   // so auth cert cannot be changed when update.
168   if (!RegisterCertificates(cert_info, pkgid, uid))
169     return false;
170
171   return true;
172 }
173
174 bool UnregisterAppInPkgmgrForPkgId(const std::string& pkgid, uid_t uid,
175                                    RequestMode request_mode) {
176   manifest_x* manifest = PkgmgrGenerateManifestInfoFromDB(pkgid, uid);
177   if (!manifest) {
178     LOG(ERROR) << "Failed to get manifest_x from DB";
179     return false;
180   }
181   bool res = UnregisterAppInPkgmgr(manifest, pkgid, uid, request_mode);
182   pkgmgr_parser_free_manifest_xml(manifest);
183   return res;
184 }
185
186 bool UnregisterAppInPkgmgr(manifest_x* manifest,
187                            const std::string& pkgid,
188                            uid_t uid,
189                            RequestMode request_mode) {
190   int ret = request_mode != RequestMode::GLOBAL ?
191       pkgmgr_parser_process_usr_manifest_x_for_uninstallation(manifest, uid) :
192       pkgmgr_parser_process_manifest_x_for_uninstallation(manifest);
193   if (ret) {
194     LOG(ERROR) << "Failed to delete manifest from pkgmgr, error code=" << ret;
195     return false;
196   }
197
198   // Certificate info may be not present
199   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
200
201   return true;
202 }
203
204 bool UpdateTepInfoInPkgmgr(const fs::path& tep_path, const std::string& pkgid,
205                         uid_t uid, RequestMode request_mode) {
206   int ret = request_mode != RequestMode::GLOBAL ?
207         pkgmgr_parser_usr_update_tep(
208             pkgid.c_str(), tep_path.c_str(), uid) :
209         pkgmgr_parser_update_tep(
210             pkgid.c_str(), tep_path.c_str());
211
212   if (ret != 0) {
213     LOG(ERROR) << "Failed to upgrade tep info: " << pkgid;
214     return false;
215   }
216
217   return true;
218 }
219
220 bool UpdateInstalledStorageInPkgmgr(Storage storage, const fs::path& ext_path,
221                                     const std::string& pkgid, uid_t uid) {
222   // FIXME: refactor this
223   INSTALL_LOCATION install_location;
224   const char* path;
225   if (storage == Storage::INTERNAL) {
226     install_location = INSTALL_INTERNAL;
227     path = "";
228   } else if (storage == Storage::EXTERNAL) {
229     install_location = INSTALL_EXTERNAL;
230     path = ext_path.c_str();
231   } else {
232     install_location = INSTALL_EXTENDED;
233     path = ext_path.c_str();
234   }
235   int ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(
236       pkgid.c_str(), install_location, path, uid);
237   if (ret != 0) {
238     LOG(ERROR) << "Failed to update installed storage info: " << pkgid;
239     return false;
240   }
241
242   return true;
243 }
244
245 bool DisablePkgInPkgmgr(const std::string& pkgid, uid_t uid,
246                         RequestMode request_mode) {
247   int ret = request_mode != RequestMode::GLOBAL ?
248         pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid.c_str(), uid, 1) :
249         pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 1);
250   if (ret != 0) {
251     LOG(ERROR) << "Failed to disable pkg: " << pkgid;
252     return false;
253   }
254
255   return true;
256 }
257
258 bool EnablePkgInPkgmgr(const std::string& pkgid, uid_t uid,
259     RequestMode request_mode) {
260   int ret = request_mode != RequestMode::GLOBAL ?
261         pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid.c_str(), uid, 0) :
262         pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 0);
263   if (ret != 0) {
264     LOG(ERROR) << "Failed to enable pkg: " << pkgid;
265     return false;
266   }
267
268   return true;
269 }
270
271 bool RegisterPluginInfo(manifest_x* manifest,
272                         uid_t uid,
273                         RequestMode request_mode) {
274   int ret = request_mode != RequestMode::GLOBAL ?
275       pkgmgr_parser_register_pkg_plugin_info_in_usr_db(manifest, uid) :
276       pkgmgr_parser_register_pkg_plugin_info_in_db(manifest);
277   if (ret) {
278     LOG(ERROR) << "Failed to insert plugin info, error code=" << ret;
279     return false;
280   }
281   return true;
282 }
283
284 bool UpdatePluginInfo(manifest_x* manifest,
285                       uid_t uid, RequestMode request_mode) {
286   int ret = request_mode != RequestMode::GLOBAL ?
287       pkgmgr_parser_update_pkg_plugin_info_in_usr_db(manifest, uid) :
288       pkgmgr_parser_update_pkg_plugin_info_in_db(manifest);
289   if (ret) {
290     LOG(ERROR) << "Failed to insert update plugin info, error code=" << ret;
291     return false;
292   }
293   return true;
294 }
295
296 bool UnregisterPluginInfo(const std::string& pkgid,
297                           uid_t uid,
298                           RequestMode request_mode) {
299   int ret = request_mode != RequestMode::GLOBAL ?
300       pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db(pkgid.c_str(), uid) :
301       pkgmgr_parser_unregister_pkg_plugin_info_in_db(pkgid.c_str());
302   if (ret) {
303     LOG(ERROR) << "Failed to remove plugin info, error code=" << ret;
304     return false;
305   }
306   return true;
307 }
308
309 }  // namespace common_installer