[Release] wrt-installer_0.1.114
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_pkg_info_update.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file    task_pkg_info_update.cpp
18  * @author  Soyoung Kim (sy037.kim@samsung.com)
19  * @version 1.0
20  * @brief   Implementation file for installer task information about package
21  * update
22  */
23 #include "task_pkg_info_update.h"
24
25 #include <unistd.h>
26 #include <string>
27
28 #include <fstream>
29 #include <dpl/log/log.h>
30 #include <dpl/wrt-dao-ro/global_config.h>
31 #include <dpl/foreach.h>
32 #include <dpl/sstream.h>
33 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
34 #include <pkgmgr_installer.h>
35 #include <pkgmgr/pkgmgr_parser.h>
36 #include <pkgmgr-info.h>
37 #include <vcore/CryptoHash.h>
38
39 #include <widget_install/job_widget_install.h>
40 #include <widget_install/widget_install_context.h>
41 #include <widget_install/widget_install_errors.h>
42
43 using namespace WrtDB;
44
45 namespace {
46 }
47
48 namespace Jobs {
49 namespace WidgetInstall {
50 TaskPkgInfoUpdate::TaskPkgInfoUpdate(InstallerContext& context) :
51     DPL::TaskDecl<TaskPkgInfoUpdate>(this),
52     m_context(context)
53 {
54     AddStep(&TaskPkgInfoUpdate::StartStep);
55     AddStep(&TaskPkgInfoUpdate::StepPkgInfo);
56     AddStep(&TaskPkgInfoUpdate::StepSetCertiInfo);
57     AddStep(&TaskPkgInfoUpdate::EndStep);
58     AddStep(&TaskPkgInfoUpdate::StepSetEndofInstallation);
59
60     AddAbortStep(&TaskPkgInfoUpdate::StepAbortCertiInfo);
61     AddAbortStep(&TaskPkgInfoUpdate::stepAbortParseManifest);
62 }
63
64 void TaskPkgInfoUpdate::StepPkgInfo()
65 {
66     int code = 0;
67     char* updateTags[3] = {NULL, };
68
69     if (!m_context.mode.removable) {
70         updateTags[0] = "preload=false";
71         updateTags[1] = "removable=false";
72         updateTags[2] = NULL;
73
74     }
75
76     if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
77         m_manifest += "/usr/share/packages/";
78     } else {
79         m_manifest += "/opt/share/packages/";
80     }
81     m_manifest += DPL::ToUTF8String(m_context.widgetConfig.tzPkgid) + ".xml";
82     LogDebug("manifest file : " << m_manifest);
83
84     if (m_context.isUpdateMode || (
85                 m_context.mode.rootPath == InstallMode::RootPath::RO
86                 && m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
87                 && m_context.mode.extension == InstallMode::ExtensionType::DIR)) {
88
89         if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) {
90             code = pkgmgr_parser_parse_manifest_for_upgrade(
91                     m_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags);
92
93             if (code != 0) {
94                 LogError("Manifest parser error: " << code);
95                 ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
96             }
97         }
98     } else {
99         code = pkgmgr_parser_parse_manifest_for_installation(
100                 m_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags);
101
102         if (code != 0) {
103             LogError("Manifest parser error: " << code);
104             ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
105         }
106     }
107
108     m_context.job->UpdateProgress(
109             InstallerContext::INSTALL_PKGINFO_UPDATE,
110             "Manifest Update Finished");
111     LogDebug("Manifest parsed");
112 }
113
114 void TaskPkgInfoUpdate::StepSetCertiInfo()
115 {
116     LogDebug("StepSetCertiInfo");
117
118     if (pkgmgr_installer_create_certinfo_set_handle(&m_pkgHandle) < 0) {
119         LogError("pkgmgrInstallerCreateCertinfoSetHandle fail");
120         ThrowMsg(Exceptions::SetCertificateInfoFailed,
121                  "Failed to create certificate handle");
122     }
123
124     SetCertiInfo(SIGNATURE_AUTHOR);
125     SetCertiInfo(SIGNATURE_DISTRIBUTOR);
126
127     if ((pkgmgr_installer_save_certinfo(
128              const_cast<char*>(DPL::ToUTF8String(
129                                    m_context.widgetConfig.tzPkgid).c_str()),
130              m_pkgHandle)) < 0)
131     {
132         LogError("pkgmgrInstallerSaveCertinfo fail");
133         ThrowMsg(Exceptions::SetCertificateInfoFailed,
134                  "Failed to Installer Save Certinfo");
135     } else {
136         LogDebug("Succeed to save Certinfo");
137     }
138
139     if (pkgmgr_installer_destroy_certinfo_set_handle(m_pkgHandle) < 0) {
140         LogError("pkgmgrInstallerDestroyCertinfoSetHandle fail");
141     }
142 }
143
144 void TaskPkgInfoUpdate::SetCertiInfo(int source)
145 {
146     LogDebug("Set CertiInfo to pkgmgr : " << source);
147     CertificateChainList certificateChainList;
148     m_context.widgetSecurity.getCertificateChainList(certificateChainList,
149             (CertificateSource)source);
150
151     FOREACH(it, certificateChainList)
152     {
153         LogDebug("Insert certinfo to pkgmgr structure");
154
155         ValidationCore::CertificateCollection chain;
156
157         if (false == chain.load(*it)) {
158             LogError("Chain is broken");
159             ThrowMsg(Exceptions::SetCertificateInfoFailed,
160                      "Failed to Installer Save Certinfo");
161         }
162
163         if (!chain.sort()) {
164             LogError("Chain failed at sorting");
165         }
166
167         ValidationCore::CertificateList list = chain.getCertificateList();
168
169         FOREACH(certIt, list)
170         {
171             pkgmgr_instcert_type instCertType;
172
173             if (source == SIGNATURE_DISTRIBUTOR) {
174                 bool distributor1 = false;
175                 if (!(*certIt)->getCommonName().IsNull()) {
176                     std::string
177                         Name(DPL::ToUTF8String(*(*certIt)->getCommonName()));
178                     std::string tizenStr("Tizen");
179                     if (0 == Name.compare(0, tizenStr.length(), tizenStr)) {
180                         distributor1 = true;
181                     }
182                 }
183
184                 if (distributor1) {
185                     LogDebug("Set SIGNATURE_DISTRIBUTOR");
186                     if ((*certIt)->isRootCert()) {
187                         instCertType = PM_SET_DISTRIBUTOR_ROOT_CERT;
188                     } else {
189                         if ((*certIt)->isCA()) {
190                             instCertType = PM_SET_DISTRIBUTOR_INTERMEDIATE_CERT;
191                         } else {
192                             instCertType = PM_SET_DISTRIBUTOR_SIGNER_CERT;
193                         }
194                     }
195                 } else {
196                     LogDebug("Set SIGNATURE_DISTRIBUTOR2");
197                     if ((*certIt)->isRootCert()) {
198                         instCertType = PM_SET_DISTRIBUTOR2_ROOT_CERT;
199                     } else {
200                         if ((*certIt)->isCA()) {
201                             instCertType =
202                                 PM_SET_DISTRIBUTOR2_INTERMEDIATE_CERT;
203                         } else {
204                             instCertType = PM_SET_DISTRIBUTOR2_SIGNER_CERT;
205                         }
206                     }
207                 }
208             } else {
209                 LogDebug("set SIGNATURE_AUTHOR");
210                 if ((*certIt)->isRootCert()) {
211                     instCertType = PM_SET_AUTHOR_ROOT_CERT;
212                 } else {
213                     if ((*certIt)->isCA()) {
214                         instCertType = PM_SET_AUTHOR_INTERMEDIATE_CERT;
215                     } else {
216                         instCertType = PM_SET_AUTHOR_SIGNER_CERT;
217                     }
218                 }
219             }
220             LogDebug("cert type : " << instCertType);
221             if ((pkgmgr_installer_set_cert_value(
222                      m_pkgHandle,
223                      instCertType,
224                      const_cast<char*>(((*certIt)->getBase64()).c_str()))) < 0)
225             {
226                 LogError("pkgmgrInstallerSetCertValue fail");
227                 ThrowMsg(Exceptions::SetCertificateInfoFailed,
228                          "Failed to Set CertValue");
229             }
230         }
231     }
232 }
233
234 void TaskPkgInfoUpdate::StepAbortCertiInfo()
235 {
236     if ((pkgmgr_installer_delete_certinfo(
237              const_cast<char*>(DPL::ToUTF8String(
238                                    m_context.widgetConfig.tzPkgid).c_str()))) <
239         0)
240     {
241         LogError("pkgmgr_installer_delete_certinfo fail");
242     }
243 }
244
245 void TaskPkgInfoUpdate::StartStep()
246 {
247     LogDebug("--------- <TaskPkgInfoUpdate> : START ----------");
248 }
249
250 void TaskPkgInfoUpdate::EndStep()
251 {
252     m_context.job->UpdateProgress(
253             InstallerContext::INSTALL_SET_CERTINFO,
254             "Save certinfo to pkgmgr");
255
256     LogDebug("--------- <TaskPkgInfoUpdate> : END ----------");
257 }
258
259 void TaskPkgInfoUpdate::stepAbortParseManifest()
260 {
261     LogError("[Parse Manifest] Abroting....");
262
263     int code = pkgmgr_parser_parse_manifest_for_uninstallation(
264             m_manifest.c_str(), NULL);
265
266     if (0 != code) {
267         LogWarning("Manifest parser error: " << code);
268         ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
269     }
270     int ret = unlink(m_manifest.c_str());
271     if (0 != ret) {
272         LogWarning("No manifest file found: " << m_manifest);
273     }
274 }
275
276 void TaskPkgInfoUpdate::StepSetEndofInstallation()
277 {
278     m_context.job->UpdateProgress(
279         InstallerContext::INSTALL_END,
280         "End installation");
281 }
282
283 } //namespace WidgetInstall
284 } //namespace Jobs