Fix detecting update
[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 }  // anonymous namespace
56
57 namespace common_installer {
58
59 bool RegisterAppInPkgmgr(const bf::path& xml_path,
60                          const std::string& pkgid,
61                          const CertificateInfo& cert_info, uid_t uid) {
62   int ret = uid != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
63       pkgmgr_parser_parse_usr_manifest_for_installation(
64           xml_path.c_str(), uid, const_cast<char* const*>(kAppinstTags)) :
65       pkgmgr_parser_parse_manifest_for_installation(
66           xml_path.c_str(), const_cast<char* const*>(kAppinstTags));
67   if (ret) {
68     LOG(ERROR) << "Failed to register package: " << xml_path << ", "
69         "error code=" << ret;
70     return false;
71   }
72
73   if (!!cert_info.author_certificate.get()) {
74     if (!RegisterAuthorCertificate(cert_info, pkgid, uid)) {
75       LOG(ERROR) << "Failed to register author certificate";
76       return false;
77     }
78   }
79
80   return true;
81 }
82
83 bool UpgradeAppInPkgmgr(const bf::path& xml_path, const std::string& pkgid,
84                         const CertificateInfo& cert_info, uid_t uid) {
85   int ret = uid != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
86        pkgmgr_parser_parse_usr_manifest_for_upgrade(
87            xml_path.string().c_str(), uid,
88            const_cast<char* const*>(kAppinstTags)) :
89        pkgmgr_parser_parse_manifest_for_upgrade(
90            xml_path.string().c_str(),
91            const_cast<char* const*>(kAppinstTags));
92
93   if (ret != 0) {
94     LOG(ERROR) << "Failed to upgrade package: " << xml_path;
95     return false;
96   }
97
98   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
99   if (!!cert_info.author_certificate.get()) {
100     if (!RegisterAuthorCertificate(cert_info, pkgid, uid)) {
101       return false;
102     }
103   }
104
105   return true;
106 }
107
108 bool UnregisterAppInPkgmgr(const bf::path& xml_path,
109                            const std::string& pkgid, uid_t uid) {
110   int ret = uid != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
111       pkgmgr_parser_parse_usr_manifest_for_uninstallation(
112           xml_path.string().c_str(), uid,
113           const_cast<char* const*>(kAppinstTags)) :
114       pkgmgr_parser_parse_manifest_for_uninstallation(
115           xml_path.string().c_str(), const_cast<char* const*>(kAppinstTags));
116   if (ret) {
117     LOG(ERROR) << "Failed to unregister package: " << xml_path;
118     return false;
119   }
120
121   // Certificate info may be not present
122   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
123
124   return true;
125 }
126
127 std::string QueryCertificateAuthorCertificate(const std::string& pkgid,
128                                               uid_t uid) {
129   pkgmgrinfo_certinfo_h handle;
130   int ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
131   if (ret != PMINFO_R_OK) {
132     LOG(ERROR) << "pkgmgrinfo_pkginfo_create_certinfo failed with error: "
133                << ret;
134     return {};
135   }
136   ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid.c_str(), handle, uid);
137   if (ret != PMINFO_R_OK) {
138     LOG(ERROR) << "pkgmgrinfo_pkginfo_load_certinfo failed with error: " << ret;
139     pkgmgrinfo_pkginfo_destroy_certinfo(handle);
140     return {};
141   }
142   const char* author_cert = nullptr;
143   ret = pkgmgrinfo_pkginfo_get_cert_value(handle, PMINFO_AUTHOR_SIGNER_CERT,
144                                           &author_cert);
145   if (ret != PMINFO_R_OK) {
146     LOG(ERROR) << "pkgmgrinfo_pkginfo_get_cert_value failed with error: "
147                << ret;
148     pkgmgrinfo_pkginfo_destroy_certinfo(handle);
149     return {};
150   }
151   std::string old_author_certificate;
152   if (author_cert)
153     old_author_certificate = author_cert;
154   pkgmgrinfo_pkginfo_destroy_certinfo(handle);
155   return old_author_certificate;
156 }
157
158 bool IsPackageInstalled(const std::string& pkg_id, uid_t uid) {
159   pkgmgrinfo_pkginfo_h handle;
160   int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(),
161                                                &handle);
162   if (ret != PMINFO_R_OK)
163     return false;
164   bool is_global = false;
165   if (pkgmgrinfo_pkginfo_is_for_all_users(handle, &is_global) != PMINFO_R_OK) {
166     LOG(ERROR) << "pkgmgrinfo_pkginfo_is_for_all_users failed";
167     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
168     return false;
169   }
170   bool global_user = uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
171   if (!global_user && is_global) {
172     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
173     return false;
174   }
175
176   pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
177   return true;
178 }
179
180
181 }  // namespace common_installer