External installation
[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 namespace bf = boost::filesystem;
14
15 namespace {
16
17 bool RegisterCertificates(
18     const common_installer::CertificateInfo& cert_info,
19     const std::string& pkgid, uid_t uid) {
20   pkgmgr_instcertinfo_h handle;
21   if (pkgmgr_installer_create_certinfo_set_handle(&handle) < 0) {
22     LOG(ERROR) << "Cannot create pkgmgr_instcertinfo_h";
23     return false;
24   }
25
26   const auto& author_cert = cert_info.author_certificate.get();
27   if (author_cert) {
28     if (pkgmgr_installer_set_cert_value(handle, PM_SET_AUTHOR_SIGNER_CERT,
29         const_cast<char*>(author_cert->getBase64().c_str())) < 0) {
30       pkgmgr_installer_destroy_certinfo_set_handle(handle);
31       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
32       return false;
33     }
34   }
35
36   const auto& author_im_cert = cert_info.author_intermediate_certificate.get();
37   if (author_im_cert) {
38     if (pkgmgr_installer_set_cert_value(handle, PM_SET_AUTHOR_INTERMEDIATE_CERT,
39         const_cast<char*>(author_im_cert->getBase64().c_str())) < 0) {
40       pkgmgr_installer_destroy_certinfo_set_handle(handle);
41       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
42       return false;
43     }
44   }
45
46   const auto& author_root_cert = cert_info.author_root_certificate.get();
47   if (author_root_cert) {
48     if (pkgmgr_installer_set_cert_value(handle, PM_SET_AUTHOR_ROOT_CERT,
49         const_cast<char*>(author_root_cert->getBase64().c_str())) < 0) {
50       pkgmgr_installer_destroy_certinfo_set_handle(handle);
51       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
52       return false;
53     }
54   }
55
56   const auto& dist_cert = cert_info.distributor_certificate.get();
57   if (dist_cert) {
58     if (pkgmgr_installer_set_cert_value(handle, PM_SET_DISTRIBUTOR_SIGNER_CERT,
59         const_cast<char*>(dist_cert->getBase64().c_str())) < 0) {
60       pkgmgr_installer_destroy_certinfo_set_handle(handle);
61       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
62       return false;
63     }
64   }
65
66   const auto& dist_im_cert =
67       cert_info.distributor_intermediate_certificate.get();
68   if (dist_im_cert) {
69     if (pkgmgr_installer_set_cert_value(handle,
70         PM_SET_DISTRIBUTOR_INTERMEDIATE_CERT,
71         const_cast<char*>(dist_im_cert->getBase64().c_str())) < 0) {
72       pkgmgr_installer_destroy_certinfo_set_handle(handle);
73       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
74       return false;
75     }
76   }
77
78   const auto& dist_root_cert = cert_info.distributor_root_certificate.get();
79   if (dist_root_cert) {
80     if (pkgmgr_installer_set_cert_value(handle, PM_SET_DISTRIBUTOR_ROOT_CERT,
81         const_cast<char*>(dist_root_cert->getBase64().c_str())) < 0) {
82       pkgmgr_installer_destroy_certinfo_set_handle(handle);
83       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
84       return false;
85     }
86   }
87
88   const auto& dist2_cert = cert_info.distributor2_certificate.get();
89   if (dist2_cert) {
90     if (pkgmgr_installer_set_cert_value(handle, PM_SET_DISTRIBUTOR2_SIGNER_CERT,
91         const_cast<char*>(dist2_cert->getBase64().c_str())) < 0) {
92       pkgmgr_installer_destroy_certinfo_set_handle(handle);
93       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
94       return false;
95     }
96   }
97
98   const auto& dist2_im_cert =
99       cert_info.distributor2_intermediate_certificate.get();
100   if (dist2_im_cert) {
101     if (pkgmgr_installer_set_cert_value(handle,
102         PM_SET_DISTRIBUTOR2_INTERMEDIATE_CERT,
103         const_cast<char*>(dist2_im_cert->getBase64().c_str())) < 0) {
104       pkgmgr_installer_destroy_certinfo_set_handle(handle);
105       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
106       return false;
107     }
108   }
109
110   const auto& dist2_root_cert = cert_info.distributor2_root_certificate.get();
111   if (dist2_root_cert) {
112     if (pkgmgr_installer_set_cert_value(handle, PM_SET_DISTRIBUTOR2_ROOT_CERT,
113         const_cast<char*>(dist2_root_cert->getBase64().c_str())) < 0) {
114       pkgmgr_installer_destroy_certinfo_set_handle(handle);
115       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
116       return false;
117     }
118   }
119
120   if (pkgmgr_installer_save_certinfo(pkgid.c_str(), handle, uid) < 0) {
121     pkgmgr_installer_destroy_certinfo_set_handle(handle);
122     LOG(ERROR) << "Failed to save certificate information";
123     return false;
124   }
125
126   pkgmgr_installer_destroy_certinfo_set_handle(handle);
127   return true;
128 }
129
130 int PkgmgrForeachAppCallback(const pkgmgrinfo_appinfo_h handle,
131                               void *user_data) {
132   auto* data = static_cast<std::vector<std::string>*>(user_data);
133   char* app_id = nullptr;
134   if (pkgmgrinfo_appinfo_get_appid(handle, &app_id) != PMINFO_R_OK)
135     return PMINFO_R_ERROR;
136   data->emplace_back(app_id);
137   return PMINFO_R_OK;
138 }
139
140 int PkgmgrForeachPrivilegeCallback(const char* privilege_name,
141                                    void* user_data) {
142   auto* data = static_cast<std::vector<std::string>*>(user_data);
143   data->emplace_back(privilege_name);
144   return PMINFO_R_OK;
145 }
146
147 // "preload" : this package was installed at the binary creation.
148 // "system" : this package is "preload" and is not removable.
149 // "update" : this package is "preload" but is updated after first installation.
150 // "removable" : this package can be removed.
151 // "readonly" : this package exists in readonly location.
152 bool AssignPackageTags(manifest_x* manifest,
153                        bool is_update) {
154   if (!strcmp(manifest->preload, "true")) {
155     manifest->removable = strdup("false");
156     manifest->readonly = strdup("true");
157     manifest->system = strdup("true");
158     if (is_update)
159       manifest->update = strdup("true");
160     else
161       manifest->update = strdup("false");
162   } else {
163     manifest->removable = strdup("true");
164     manifest->readonly = strdup("false");
165     manifest->system = strdup("false");
166     manifest->update = strdup("false");
167   }
168
169   return true;
170 }
171
172 }  // anonymous namespace
173
174 namespace common_installer {
175
176 bool RegisterAppInPkgmgr(manifest_x* manifest,
177                          const bf::path& xml_path,
178                          const std::string& pkgid,
179                          const CertificateInfo& cert_info,
180                          uid_t uid,
181                          RequestMode request_mode,
182                          const boost::filesystem::path& tep_path) {
183   // Fill "non-xml" elements
184   if (!tep_path.empty())
185     manifest->tep_name = strdup(tep_path.c_str());
186
187   if (!AssignPackageTags(manifest, false))
188     return false;
189
190   int ret = request_mode != RequestMode::GLOBAL ?
191       pkgmgr_parser_process_usr_manifest_x_for_installation(manifest,
192           xml_path.c_str(), uid) :
193       pkgmgr_parser_process_manifest_x_for_installation(manifest,
194           xml_path.c_str());
195   if (ret) {
196     LOG(ERROR) << "Failed to insert manifest into pkgmgr, error code=" << ret;
197     return false;
198   }
199
200   if (!RegisterCertificates(cert_info, pkgid, uid)) {
201     LOG(ERROR) << "Failed to register author certificate";
202     return false;
203   }
204
205   return true;
206 }
207
208 bool UpgradeAppInPkgmgr(manifest_x* manifest,
209                         const bf::path& xml_path,
210                         const std::string& pkgid,
211                         const CertificateInfo& cert_info,
212                         uid_t uid,
213                         RequestMode request_mode) {
214   if (!AssignPackageTags(manifest, true))
215     return false;
216
217   int ret = request_mode != RequestMode::GLOBAL ?
218        pkgmgr_parser_process_usr_manifest_x_for_upgrade(manifest,
219           xml_path.c_str(), uid) :
220        pkgmgr_parser_process_manifest_x_for_upgrade(manifest, xml_path.c_str());
221
222   if (ret != 0) {
223     LOG(ERROR) << "Failed to update manifest in pkgmgr, error code=" << ret;
224     return false;
225   }
226
227   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
228   if (!RegisterCertificates(cert_info, pkgid, uid))
229     return false;
230
231   return true;
232 }
233
234 bool UnregisterAppInPkgmgr(manifest_x* manifest,
235                            const bf::path& xml_path,
236                            const std::string& pkgid,
237                            uid_t uid,
238                            RequestMode request_mode) {
239   int ret = request_mode != RequestMode::GLOBAL ?
240       pkgmgr_parser_process_usr_manifest_x_for_uninstallation(manifest,
241           xml_path.c_str(), uid) :
242       pkgmgr_parser_process_manifest_x_for_uninstallation(manifest,
243           xml_path.c_str());
244   if (ret) {
245     LOG(ERROR) << "Failed to delete manifest from pkgmgr, error code=" << ret;
246     return false;
247   }
248
249   // Certificate info may be not present
250   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
251
252   return true;
253 }
254
255 std::string QueryCertificateAuthorCertificate(const std::string& pkgid,
256                                               uid_t uid) {
257   pkgmgrinfo_certinfo_h handle;
258   int ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
259   if (ret != PMINFO_R_OK) {
260     LOG(DEBUG) << "pkgmgrinfo_pkginfo_create_certinfo failed with error: "
261                << ret;
262     return {};
263   }
264   ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid.c_str(), handle, uid);
265   if (ret != PMINFO_R_OK) {
266     LOG(DEBUG) << "pkgmgrinfo_pkginfo_load_certinfo failed with error: " << ret;
267     pkgmgrinfo_pkginfo_destroy_certinfo(handle);
268     return {};
269   }
270   const char* author_cert = nullptr;
271   ret = pkgmgrinfo_pkginfo_get_cert_value(handle, PMINFO_AUTHOR_SIGNER_CERT,
272                                           &author_cert);
273   if (ret != PMINFO_R_OK) {
274     LOG(DEBUG) << "pkgmgrinfo_pkginfo_get_cert_value failed with error: "
275                << ret;
276     pkgmgrinfo_pkginfo_destroy_certinfo(handle);
277     return {};
278   }
279   std::string old_author_certificate;
280   if (author_cert)
281     old_author_certificate = author_cert;
282   pkgmgrinfo_pkginfo_destroy_certinfo(handle);
283   return old_author_certificate;
284 }
285
286 std::string QueryTepPath(const std::string& pkgid, uid_t uid) {
287   pkgmgrinfo_pkginfo_h package_info;
288   if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid.c_str(), uid, &package_info)
289       != PMINFO_R_OK)
290     return {};
291   char* tep_name = nullptr;
292   int ret = pkgmgrinfo_pkginfo_get_tep_name(package_info, &tep_name);
293   if (ret != PMINFO_R_OK) {
294     LOG(DEBUG) << "pkgmgrinfo_pkginfo_get_tep_name failed with error: "
295                << ret;
296     pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
297     return {};
298   }
299   std::string tep_name_value;
300   if (tep_name)
301     tep_name_value = tep_name;
302   pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
303   return tep_name_value;
304 }
305
306 std::string QueryZipMountFile(const std::string& pkgid, uid_t uid) {
307   pkgmgrinfo_pkginfo_h package_info;
308   if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid.c_str(), uid, &package_info)
309       != PMINFO_R_OK)
310     return {};
311   char* zip_mount_file = nullptr;
312   int ret = pkgmgrinfo_pkginfo_get_zip_mount_file(package_info,
313           &zip_mount_file);
314   if (ret != PMINFO_R_OK) {
315     LOG(DEBUG) << "pkgmgrinfo_pkginfo_get_zip_mount_file failed with error: "
316                << ret;
317     pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
318     return {};
319   }
320   std::string zip_mount_file_value;
321   if (zip_mount_file)
322     zip_mount_file_value = zip_mount_file;
323   pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
324   return zip_mount_file_value;
325 }
326
327 bool QueryAppidsForPkgId(const std::string& pkg_id,
328                          std::vector<std::string>* result, uid_t uid) {
329   pkgmgrinfo_pkginfo_h package_info;
330   if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid, &package_info)
331       != PMINFO_R_OK) {
332     return false;
333   }
334
335   bool ret = pkgmgrinfo_appinfo_get_usr_list(package_info, PMINFO_ALL_APP,
336       &PkgmgrForeachAppCallback, result, uid) == PMINFO_R_OK;
337   pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
338   return ret;
339 }
340
341 bool QueryPrivilegesForPkgId(const std::string& pkg_id, uid_t uid,
342                              std::vector<std::string>* result) {
343   pkgmgrinfo_pkginfo_h package_info;
344   if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid, &package_info)
345       != PMINFO_R_OK) {
346     return false;
347   }
348
349   bool ret = pkgmgrinfo_pkginfo_foreach_privilege(package_info,
350       &PkgmgrForeachPrivilegeCallback, result) == PMINFO_R_OK;
351   pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
352   return ret;
353 }
354
355 std::string QueryStorageForPkgId(const std::string& pkg_id, uid_t uid) {
356   pkgmgrinfo_pkginfo_h package_info;
357   if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid, &package_info)
358       != PMINFO_R_OK) {
359     return false;
360   }
361
362   pkgmgrinfo_installed_storage storage;
363   bool ok = pkgmgrinfo_pkginfo_get_installed_storage(package_info,
364       &storage) == PMINFO_R_OK;
365   pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
366
367   if (!ok)
368     return "";
369
370   // TODO(t.iwanek): enum is used in pkgmgr API, whereas here we assign internal
371   // values known to pkgmgr
372   if (storage == PMINFO_INTERNAL_STORAGE) {
373     return "installed_internal";
374   } else if (storage == PMINFO_EXTERNAL_STORAGE) {
375     return "installed_external";
376   } else {
377     return "";
378   }
379 }
380
381 bool IsPackageInstalled(const std::string& pkg_id, RequestMode request_mode) {
382   pkgmgrinfo_pkginfo_h handle;
383   int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(),
384                                                &handle);
385   if (ret != PMINFO_R_OK)
386     return false;
387   bool is_global = false;
388   if (pkgmgrinfo_pkginfo_is_for_all_users(handle, &is_global) != PMINFO_R_OK) {
389     LOG(ERROR) << "pkgmgrinfo_pkginfo_is_for_all_users failed";
390     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
391     return false;
392   }
393   if (request_mode != RequestMode::GLOBAL && is_global) {
394     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
395     return false;
396   }
397
398   pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
399   return true;
400 }
401
402 bool IsPackageInstalled(const std::string& pkg_id, uid_t uid) {
403   pkgmgrinfo_pkginfo_h handle;
404   int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid, &handle);
405   if (ret != PMINFO_R_OK)
406     return false;
407
408   bool is_global = false;
409   if (pkgmgrinfo_pkginfo_is_for_all_users(handle, &is_global) != PMINFO_R_OK) {
410     LOG(ERROR) << "pkgmgrinfo_pkginfo_is_for_all_users failed";
411     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
412     return false;
413   }
414
415   if (uid == GLOBAL_USER && is_global) {
416     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
417     return true;
418   }
419
420   if (uid != GLOBAL_USER && is_global) {
421     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
422     return false;
423   }
424
425   pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
426   return true;
427 }
428
429
430 }  // namespace common_installer