Workaround - sending appid during deinstallation
[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 <pkgmgr_installer.h>
8 #include <tzplatform_config.h>
9 #include <unistd.h>
10
11 #include "common/utils/logging.h"
12
13 namespace bf = boost::filesystem;
14
15 namespace {
16
17 // TODO(sdi2): Check if data->removable is correctly setting
18 // during parsing step.
19 // Same check should be done for preload field.
20
21 // Having a specific step to implement a installer commandline tool
22 // for image build could be usefull also.
23 const char* const kAppinstTags[] = {"removable=true", nullptr, };
24
25 bool RegisterAuthorCertificate(
26     const common_installer::CertificateInfo& cert_info,
27     const std::string& pkgid, uid_t uid) {
28   pkgmgr_instcertinfo_h handle;
29   if (pkgmgr_installer_create_certinfo_set_handle(&handle) < 0) {
30     LOG(ERROR) << "Cannot create pkgmgr_instcertinfo_h";
31     return false;
32   }
33
34   const auto& cert = cert_info.author_certificate.get();
35
36   // TODO(t.iwanek): set other certificates if needed
37
38   if (pkgmgr_installer_set_cert_value(handle, PM_SET_AUTHOR_SIGNER_CERT,
39       const_cast<char*>(cert->getBase64().c_str())) < 0) {
40     pkgmgr_installer_destroy_certinfo_set_handle(handle);
41     LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
42     return false;
43   }
44
45   if (pkgmgr_installer_save_certinfo(pkgid.c_str(), handle, uid) < 0) {
46     pkgmgr_installer_destroy_certinfo_set_handle(handle);
47     LOG(ERROR) << "Failed to save certificate information";
48     return false;
49   }
50
51   pkgmgr_installer_destroy_certinfo_set_handle(handle);
52   return true;
53 }
54
55 int PkgmgrForeachAppCallback(const pkgmgrinfo_appinfo_h handle,
56                               void *user_data) {
57   auto* data = static_cast<std::vector<std::string>*>(user_data);
58   char* app_id = nullptr;
59   if (pkgmgrinfo_appinfo_get_appid(handle, &app_id) != PMINFO_R_OK)
60     return PMINFO_R_ERROR;
61   data->emplace_back(app_id);
62   return PMINFO_R_OK;
63 }
64
65 }  // anonymous namespace
66
67 namespace common_installer {
68
69 bool RegisterAppInPkgmgr(const bf::path& xml_path,
70                          const std::string& pkgid,
71                          const CertificateInfo& cert_info,
72                          uid_t uid,
73                          RequestMode request_mode) {
74   int ret = request_mode != RequestMode::GLOBAL ?
75       pkgmgr_parser_parse_usr_manifest_for_installation(
76           xml_path.c_str(), uid, const_cast<char* const*>(kAppinstTags)) :
77       pkgmgr_parser_parse_manifest_for_installation(
78           xml_path.c_str(), const_cast<char* const*>(kAppinstTags));
79   if (ret) {
80     LOG(ERROR) << "Failed to register package: " << xml_path << ", "
81         "error code=" << ret;
82     return false;
83   }
84
85   if (!!cert_info.author_certificate.get()) {
86     if (!RegisterAuthorCertificate(cert_info, pkgid, uid)) {
87       LOG(ERROR) << "Failed to register author certificate";
88       return false;
89     }
90   }
91
92   return true;
93 }
94
95 bool UpgradeAppInPkgmgr(const bf::path& xml_path, const std::string& pkgid,
96                         const CertificateInfo& cert_info, uid_t uid,
97                         RequestMode request_mode) {
98   int ret = request_mode != RequestMode::GLOBAL ?
99        pkgmgr_parser_parse_usr_manifest_for_upgrade(
100            xml_path.string().c_str(), uid,
101            const_cast<char* const*>(kAppinstTags)) :
102        pkgmgr_parser_parse_manifest_for_upgrade(
103            xml_path.string().c_str(),
104            const_cast<char* const*>(kAppinstTags));
105
106   if (ret != 0) {
107     LOG(ERROR) << "Failed to upgrade package: " << xml_path;
108     return false;
109   }
110
111   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
112   if (!!cert_info.author_certificate.get()) {
113     if (!RegisterAuthorCertificate(cert_info, pkgid, uid)) {
114       return false;
115     }
116   }
117
118   return true;
119 }
120
121 bool UnregisterAppInPkgmgr(const bf::path& xml_path,
122                            const std::string& pkgid,
123                            uid_t uid,
124                            RequestMode request_mode) {
125   int ret = request_mode != RequestMode::GLOBAL ?
126       pkgmgr_parser_parse_usr_manifest_for_uninstallation(
127           xml_path.string().c_str(), uid,
128           const_cast<char* const*>(kAppinstTags)) :
129       pkgmgr_parser_parse_manifest_for_uninstallation(
130           xml_path.string().c_str(), const_cast<char* const*>(kAppinstTags));
131   if (ret) {
132     LOG(ERROR) << "Failed to unregister package: " << xml_path;
133     return false;
134   }
135
136   // Certificate info may be not present
137   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
138
139   return true;
140 }
141
142 std::string QueryCertificateAuthorCertificate(const std::string& pkgid,
143                                               uid_t uid) {
144   pkgmgrinfo_certinfo_h handle;
145   int ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
146   if (ret != PMINFO_R_OK) {
147     LOG(ERROR) << "pkgmgrinfo_pkginfo_create_certinfo failed with error: "
148                << ret;
149     return {};
150   }
151   ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid.c_str(), handle, uid);
152   if (ret != PMINFO_R_OK) {
153     LOG(ERROR) << "pkgmgrinfo_pkginfo_load_certinfo failed with error: " << ret;
154     pkgmgrinfo_pkginfo_destroy_certinfo(handle);
155     return {};
156   }
157   const char* author_cert = nullptr;
158   ret = pkgmgrinfo_pkginfo_get_cert_value(handle, PMINFO_AUTHOR_SIGNER_CERT,
159                                           &author_cert);
160   if (ret != PMINFO_R_OK) {
161     LOG(ERROR) << "pkgmgrinfo_pkginfo_get_cert_value failed with error: "
162                << ret;
163     pkgmgrinfo_pkginfo_destroy_certinfo(handle);
164     return {};
165   }
166   std::string old_author_certificate;
167   if (author_cert)
168     old_author_certificate = author_cert;
169   pkgmgrinfo_pkginfo_destroy_certinfo(handle);
170   return old_author_certificate;
171 }
172
173
174 bool QueryAppidsForPkgId(const std::string& pkg_id,
175                          std::vector<std::string>* result, uid_t uid) {
176   pkgmgrinfo_pkginfo_h package_info;
177   if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid, &package_info)
178       != PMINFO_R_OK) {
179     return false;
180   }
181
182   bool ret = pkgmgrinfo_appinfo_get_usr_list(package_info, PMINFO_ALL_APP,
183       &PkgmgrForeachAppCallback, result, uid) == PMINFO_R_OK;
184   pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
185   return ret;
186 }
187
188 bool IsPackageInstalled(const std::string& pkg_id, RequestMode request_mode) {
189   pkgmgrinfo_pkginfo_h handle;
190   int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(),
191                                                &handle);
192   if (ret != PMINFO_R_OK)
193     return false;
194   bool is_global = false;
195   if (pkgmgrinfo_pkginfo_is_for_all_users(handle, &is_global) != PMINFO_R_OK) {
196     LOG(ERROR) << "pkgmgrinfo_pkginfo_is_for_all_users failed";
197     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
198     return false;
199   }
200   if (request_mode != RequestMode::GLOBAL && is_global) {
201     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
202     return false;
203   }
204
205   pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
206   return true;
207 }
208
209
210 }  // namespace common_installer