Unregister package from pkgmgr by pkgid
[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/manifest_util.h"
17
18 namespace bf = boost::filesystem;
19
20
21 namespace {
22
23 using CertInfo = common_installer::CertificateInfo;
24
25 bool RegisterCertificate(pkgmgr_instcertinfo_h handle,
26 const ValidationCore::CertificatePtr& certPtr, pkgmgr_instcert_type type) {
27     if (certPtr) {
28       if (pkgmgr_installer_set_cert_value(handle, type,
29           const_cast<char*>(certPtr->getBase64().c_str())) < 0) {
30         pkgmgr_installer_destroy_certinfo_set_handle(handle);
31         LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
32         return false;
33       }
34     }
35     return true;
36 }
37
38 typedef Property<ValidationCore::CertificatePtr> CertInfo::*PropertyOfCertInf;
39
40 const std::vector<std::pair<PropertyOfCertInf, pkgmgr_instcert_type>>
41     kCertTypePairs = {
42   {&CertInfo::author_certificate, PM_SET_AUTHOR_SIGNER_CERT},
43   {&CertInfo::author_intermediate_certificate, PM_SET_AUTHOR_INTERMEDIATE_CERT},
44   {&CertInfo::author_root_certificate, PM_SET_AUTHOR_ROOT_CERT},
45   {&CertInfo::distributor_certificate, PM_SET_DISTRIBUTOR_SIGNER_CERT},
46   {&CertInfo::distributor_intermediate_certificate,
47       PM_SET_DISTRIBUTOR_INTERMEDIATE_CERT},
48   {&CertInfo::distributor_root_certificate, PM_SET_DISTRIBUTOR_ROOT_CERT},
49   {&CertInfo::distributor2_certificate, PM_SET_DISTRIBUTOR2_SIGNER_CERT},
50   {&CertInfo::distributor2_intermediate_certificate,
51       PM_SET_DISTRIBUTOR2_INTERMEDIATE_CERT},
52   {&CertInfo::distributor2_root_certificate, PM_SET_DISTRIBUTOR2_ROOT_CERT}
53 };
54
55 bool RegisterCertificates(
56     const CertInfo& cert_info,
57     const std::string& pkgid, uid_t uid) {
58   pkgmgr_instcertinfo_h handle;
59   if (pkgmgr_installer_create_certinfo_set_handle(&handle) < 0) {
60     LOG(ERROR) << "Cannot create pkgmgr_instcertinfo_h";
61     return false;
62   }
63   for (auto pair : kCertTypePairs) {
64      auto cert = (cert_info.*(pair.first)).get();
65      auto type = pair.second;
66      if (!RegisterCertificate(handle, cert, type))
67        return false;
68   }
69   if (pkgmgr_installer_save_certinfo(pkgid.c_str(), handle, uid) < 0) {
70     pkgmgr_installer_destroy_certinfo_set_handle(handle);
71     LOG(ERROR) << "Failed to save certificate information";
72     return false;
73   }
74
75   pkgmgr_installer_destroy_certinfo_set_handle(handle);
76   return true;
77 }
78
79 // "preload" : pre-installed package at the first boot state.
80 //             this package exists in both readonly and readwrite.
81 // "system" : this package is "preload" and is not removable.
82 // "update" : this package is "preload" and is updated by downloadable update.
83 // "removable" : this package can be removed.
84 // "readonly" : this package exists in readonly location.
85 bool AssignPackageTags(manifest_x* manifest) {
86   if (!manifest)
87     return false;
88
89   // preload, removalbe and readonly : in parse_preload step.
90   if (manifest->preload && !strcmp(manifest->preload, "true")) {
91     if (manifest->removable && !strcmp(manifest->removable, "false"))
92       manifest->system = strdup("true");
93     else
94       manifest->system = strdup("false");
95   } else {
96     manifest->system = strdup("false");
97   }
98
99   return true;
100 }
101
102 }  // namespace
103
104 namespace common_installer {
105
106 bool RegisterAppInPkgmgr(manifest_x* manifest,
107                          const std::string& pkgid,
108                          const CertificateInfo& cert_info,
109                          uid_t uid,
110                          RequestMode request_mode,
111                          const boost::filesystem::path& tep_path) {
112   // Fill "non-xml" elements
113   if (!tep_path.empty())
114     manifest->tep_name = strdup(tep_path.c_str());
115
116   if (!AssignPackageTags(manifest))
117     return false;
118
119   int ret = request_mode != RequestMode::GLOBAL ?
120       pkgmgr_parser_process_usr_manifest_x_for_installation(manifest, uid) :
121       pkgmgr_parser_process_manifest_x_for_installation(manifest);
122   if (ret) {
123     LOG(ERROR) << "Failed to insert manifest into pkgmgr, error code=" << ret;
124     return false;
125   }
126
127   if (!RegisterCertificates(cert_info, pkgid, uid)) {
128     LOG(ERROR) << "Failed to register author certificate";
129     return false;
130   }
131
132   return true;
133 }
134
135 bool UpgradeAppInPkgmgr(manifest_x* manifest,
136                         const std::string& pkgid,
137                         const CertificateInfo& cert_info,
138                         uid_t uid,
139                         RequestMode request_mode) {
140   if (!AssignPackageTags(manifest))
141     return false;
142
143   int ret = request_mode != RequestMode::GLOBAL ?
144        pkgmgr_parser_process_usr_manifest_x_for_upgrade(manifest, uid) :
145        pkgmgr_parser_process_manifest_x_for_upgrade(manifest);
146
147   if (ret != 0) {
148     LOG(ERROR) << "Failed to update manifest in pkgmgr, error code=" << ret;
149     return false;
150   }
151
152   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
153   if (!RegisterCertificates(cert_info, pkgid, uid))
154     return false;
155
156   return true;
157 }
158
159 bool UnregisterAppInPkgmgrForPkgId(const std::string& pkgid, uid_t uid,
160                                    RequestMode request_mode) {
161   manifest_x* manifest =
162      static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
163   PkgmgrGenerateManifestInfoFromDB(manifest, pkgid, uid);
164   bool res = UnregisterAppInPkgmgr(manifest, pkgid, uid, request_mode);
165   pkgmgr_parser_free_manifest_xml(manifest);
166   return res;
167 }
168
169 bool UnregisterAppInPkgmgr(manifest_x* manifest,
170                            const std::string& pkgid,
171                            uid_t uid,
172                            RequestMode request_mode) {
173   int ret = request_mode != RequestMode::GLOBAL ?
174       pkgmgr_parser_process_usr_manifest_x_for_uninstallation(manifest, uid) :
175       pkgmgr_parser_process_manifest_x_for_uninstallation(manifest);
176   if (ret) {
177     LOG(ERROR) << "Failed to delete manifest from pkgmgr, error code=" << ret;
178     return false;
179   }
180
181   // Certificate info may be not present
182   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
183
184   return true;
185 }
186
187 bool UpdateTepInfoInPkgmgr(const bf::path& tep_path, const std::string& pkgid,
188                         uid_t uid, RequestMode request_mode) {
189   int ret = request_mode != RequestMode::GLOBAL ?
190         pkgmgr_parser_usr_update_tep(
191             pkgid.c_str(), tep_path.string().c_str(), uid) :
192         pkgmgr_parser_update_tep(
193             pkgid.c_str(), tep_path.string().c_str());
194
195   if (ret != 0) {
196     LOG(ERROR) << "Failed to upgrade tep info: " << pkgid;
197     return false;
198   }
199
200   return true;
201 }
202
203 bool DisablePkgInPkgmgr(const std::string& pkgid, uid_t uid,
204                         RequestMode request_mode) {
205   int ret = request_mode != RequestMode::GLOBAL ?
206         pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid.c_str(), uid, 1) :
207         pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 1);
208   if (ret != 0) {
209     LOG(ERROR) << "Failed to disable pkg: " << pkgid;
210     return false;
211   }
212
213   return true;
214 }
215
216 bool EnablePkgInPkgmgr(const std::string& pkgid, uid_t uid,
217                         RequestMode request_mode) {
218   int ret = request_mode != RequestMode::GLOBAL ?
219         pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid.c_str(), uid, 0) :
220         pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 0);
221   if (ret != 0) {
222     LOG(ERROR) << "Failed to enable pkg: " << pkgid;
223     return false;
224   }
225
226   return true;
227 }
228
229 }  // namespace common_installer