Implement pkg enable/disable
[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
15 namespace bf = boost::filesystem;
16
17 namespace {
18
19 bool RegisterCertificates(
20     const common_installer::CertificateInfo& cert_info,
21     const std::string& pkgid, uid_t uid) {
22   pkgmgr_instcertinfo_h handle;
23   if (pkgmgr_installer_create_certinfo_set_handle(&handle) < 0) {
24     LOG(ERROR) << "Cannot create pkgmgr_instcertinfo_h";
25     return false;
26   }
27
28   const auto& author_cert = cert_info.author_certificate.get();
29   if (author_cert) {
30     if (pkgmgr_installer_set_cert_value(handle, PM_SET_AUTHOR_SIGNER_CERT,
31         const_cast<char*>(author_cert->getBase64().c_str())) < 0) {
32       pkgmgr_installer_destroy_certinfo_set_handle(handle);
33       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
34       return false;
35     }
36   }
37
38   const auto& author_im_cert = cert_info.author_intermediate_certificate.get();
39   if (author_im_cert) {
40     if (pkgmgr_installer_set_cert_value(handle, PM_SET_AUTHOR_INTERMEDIATE_CERT,
41         const_cast<char*>(author_im_cert->getBase64().c_str())) < 0) {
42       pkgmgr_installer_destroy_certinfo_set_handle(handle);
43       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
44       return false;
45     }
46   }
47
48   const auto& author_root_cert = cert_info.author_root_certificate.get();
49   if (author_root_cert) {
50     if (pkgmgr_installer_set_cert_value(handle, PM_SET_AUTHOR_ROOT_CERT,
51         const_cast<char*>(author_root_cert->getBase64().c_str())) < 0) {
52       pkgmgr_installer_destroy_certinfo_set_handle(handle);
53       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
54       return false;
55     }
56   }
57
58   const auto& dist_cert = cert_info.distributor_certificate.get();
59   if (dist_cert) {
60     if (pkgmgr_installer_set_cert_value(handle, PM_SET_DISTRIBUTOR_SIGNER_CERT,
61         const_cast<char*>(dist_cert->getBase64().c_str())) < 0) {
62       pkgmgr_installer_destroy_certinfo_set_handle(handle);
63       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
64       return false;
65     }
66   }
67
68   const auto& dist_im_cert =
69       cert_info.distributor_intermediate_certificate.get();
70   if (dist_im_cert) {
71     if (pkgmgr_installer_set_cert_value(handle,
72         PM_SET_DISTRIBUTOR_INTERMEDIATE_CERT,
73         const_cast<char*>(dist_im_cert->getBase64().c_str())) < 0) {
74       pkgmgr_installer_destroy_certinfo_set_handle(handle);
75       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
76       return false;
77     }
78   }
79
80   const auto& dist_root_cert = cert_info.distributor_root_certificate.get();
81   if (dist_root_cert) {
82     if (pkgmgr_installer_set_cert_value(handle, PM_SET_DISTRIBUTOR_ROOT_CERT,
83         const_cast<char*>(dist_root_cert->getBase64().c_str())) < 0) {
84       pkgmgr_installer_destroy_certinfo_set_handle(handle);
85       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
86       return false;
87     }
88   }
89
90   const auto& dist2_cert = cert_info.distributor2_certificate.get();
91   if (dist2_cert) {
92     if (pkgmgr_installer_set_cert_value(handle, PM_SET_DISTRIBUTOR2_SIGNER_CERT,
93         const_cast<char*>(dist2_cert->getBase64().c_str())) < 0) {
94       pkgmgr_installer_destroy_certinfo_set_handle(handle);
95       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
96       return false;
97     }
98   }
99
100   const auto& dist2_im_cert =
101       cert_info.distributor2_intermediate_certificate.get();
102   if (dist2_im_cert) {
103     if (pkgmgr_installer_set_cert_value(handle,
104         PM_SET_DISTRIBUTOR2_INTERMEDIATE_CERT,
105         const_cast<char*>(dist2_im_cert->getBase64().c_str())) < 0) {
106       pkgmgr_installer_destroy_certinfo_set_handle(handle);
107       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
108       return false;
109     }
110   }
111
112   const auto& dist2_root_cert = cert_info.distributor2_root_certificate.get();
113   if (dist2_root_cert) {
114     if (pkgmgr_installer_set_cert_value(handle, PM_SET_DISTRIBUTOR2_ROOT_CERT,
115         const_cast<char*>(dist2_root_cert->getBase64().c_str())) < 0) {
116       pkgmgr_installer_destroy_certinfo_set_handle(handle);
117       LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
118       return false;
119     }
120   }
121
122   if (pkgmgr_installer_save_certinfo(pkgid.c_str(), handle, uid) < 0) {
123     pkgmgr_installer_destroy_certinfo_set_handle(handle);
124     LOG(ERROR) << "Failed to save certificate information";
125     return false;
126   }
127
128   pkgmgr_installer_destroy_certinfo_set_handle(handle);
129   return true;
130 }
131
132 // "preload" : this package was installed at the binary creation.
133 // "system" : this package is "preload" and is not removable.
134 // "update" : this package is "preload" but is updated after first installation.
135 // "removable" : this package can be removed.
136 // "readonly" : this package exists in readonly location.
137 bool AssignPackageTags(manifest_x* manifest,
138                        bool is_update) {
139   if (!strcmp(manifest->preload, "true")) {
140     manifest->removable = strdup("false");
141     manifest->readonly = strdup("true");
142     manifest->system = strdup("true");
143     if (is_update)
144       manifest->update = strdup("true");
145     else
146       manifest->update = strdup("false");
147   } else {
148     manifest->removable = strdup("true");
149     manifest->readonly = strdup("false");
150     manifest->system = strdup("false");
151     manifest->update = strdup("false");
152   }
153
154   return true;
155 }
156
157 }  // anonymous namespace
158
159 namespace common_installer {
160
161 bool RegisterAppInPkgmgr(manifest_x* manifest,
162                          const bf::path& xml_path,
163                          const std::string& pkgid,
164                          const CertificateInfo& cert_info,
165                          uid_t uid,
166                          RequestMode request_mode,
167                          const boost::filesystem::path& tep_path) {
168   // Fill "non-xml" elements
169   if (!tep_path.empty())
170     manifest->tep_name = strdup(tep_path.c_str());
171
172   if (!AssignPackageTags(manifest, false))
173     return false;
174
175   int ret = request_mode != RequestMode::GLOBAL ?
176       pkgmgr_parser_process_usr_manifest_x_for_installation(manifest,
177           xml_path.c_str(), uid) :
178       pkgmgr_parser_process_manifest_x_for_installation(manifest,
179           xml_path.c_str());
180   if (ret) {
181     LOG(ERROR) << "Failed to insert manifest into pkgmgr, error code=" << ret;
182     return false;
183   }
184
185   if (!RegisterCertificates(cert_info, pkgid, uid)) {
186     LOG(ERROR) << "Failed to register author certificate";
187     return false;
188   }
189
190   return true;
191 }
192
193 bool UpgradeAppInPkgmgr(manifest_x* manifest,
194                         const bf::path& xml_path,
195                         const std::string& pkgid,
196                         const CertificateInfo& cert_info,
197                         uid_t uid,
198                         RequestMode request_mode) {
199   if (!AssignPackageTags(manifest, true))
200     return false;
201
202   int ret = request_mode != RequestMode::GLOBAL ?
203        pkgmgr_parser_process_usr_manifest_x_for_upgrade(manifest,
204           xml_path.c_str(), uid) :
205        pkgmgr_parser_process_manifest_x_for_upgrade(manifest, xml_path.c_str());
206
207   if (ret != 0) {
208     LOG(ERROR) << "Failed to update manifest in pkgmgr, error code=" << ret;
209     return false;
210   }
211
212   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
213   if (!RegisterCertificates(cert_info, pkgid, uid))
214     return false;
215
216   return true;
217 }
218
219 bool UnregisterAppInPkgmgr(manifest_x* manifest,
220                            const bf::path& xml_path,
221                            const std::string& pkgid,
222                            uid_t uid,
223                            RequestMode request_mode) {
224   int ret = request_mode != RequestMode::GLOBAL ?
225       pkgmgr_parser_process_usr_manifest_x_for_uninstallation(manifest,
226           xml_path.c_str(), uid) :
227       pkgmgr_parser_process_manifest_x_for_uninstallation(manifest,
228           xml_path.c_str());
229   if (ret) {
230     LOG(ERROR) << "Failed to delete manifest from pkgmgr, error code=" << ret;
231     return false;
232   }
233
234   // Certificate info may be not present
235   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
236
237   return true;
238 }
239
240 bool UpdateTepInfoInPkgmgr(const bf::path& tep_path, const std::string& pkgid,
241                         uid_t uid, RequestMode request_mode) {
242   int ret = request_mode != RequestMode::GLOBAL ?
243         pkgmgr_parser_usr_update_tep(
244             pkgid.c_str(), tep_path.string().c_str(), uid) :
245         pkgmgr_parser_update_tep(
246             pkgid.c_str(), tep_path.string().c_str());
247
248   if (ret != 0) {
249     LOG(ERROR) << "Failed to upgrade tep info: " << pkgid;
250     return false;
251   }
252
253   return true;
254 }
255
256 bool DisablePkgInPkgmgr(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, 1) :
260         pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 1);
261   if (ret != 0) {
262     LOG(ERROR) << "Failed to disable pkg: " << pkgid;
263     return false;
264   }
265
266   return true;
267 }
268
269 bool EnablePkgInPkgmgr(const std::string& pkgid, uid_t uid,
270                         RequestMode request_mode) {
271   int ret = request_mode != RequestMode::GLOBAL ?
272         pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid.c_str(), uid, 0) :
273         pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 0);
274   if (ret != 0) {
275     LOG(ERROR) << "Failed to enable pkg: " << pkgid;
276     return false;
277   }
278
279   return true;
280 }
281
282 }  // namespace common_installer