Revert "Add to pass rivilege level when installing service app."
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_certify_level.cpp
1 /*
2  * Copyright (c) 2013 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_certify_level.cpp
18  * @author  Jihoon Chung (jihoon.chung@samgsung.com)
19  * @version
20  * @brief
21  */
22
23 //SYSTEM INCLUDES
24 #include <string>
25 #include <map>
26 #include <unistd.h>
27
28 //WRT INCLUDES
29 #include <widget_install/task_certify_level.h>
30 #include <widget_install/job_widget_install.h>
31 #include <widget_install/widget_install_errors.h>
32 #include <widget_install/widget_install_context.h>
33 #include <dpl/assert.h>
34 #include <dpl/exception.h>
35 #include <dpl/string.h>
36 #include <dpl/foreach.h>
37 #include <dpl/wrt-dao-ro/global_config.h>
38
39 #include <vcore/CertStoreType.h>
40 #include <vcore/SignatureReader.h>
41 #include <vcore/SignatureFinder.h>
42 #include <vcore/WrtSignatureValidator.h>
43 #include <dpl/utils/wrt_global_settings.h>
44
45 #include <installer_log.h>
46
47 using namespace ValidationCore;
48 using namespace WrtDB;
49
50 namespace Jobs {
51 namespace WidgetInstall {
52 TaskCertifyLevel::TaskCertifyLevel(InstallerContext &inCont) :
53     DPL::TaskDecl<TaskCertifyLevel>(this),
54     m_contextData(inCont)
55 {
56     AddStep(&TaskCertifyLevel::StartStep);
57     AddStep(&TaskCertifyLevel::stepCertifyLevel);
58     AddStep(&TaskCertifyLevel::EndStep);
59 }
60
61 void TaskCertifyLevel::stepCertifyLevel()
62 {
63     _D("================ Step: <<Certify Level>> ENTER ===============");
64     if (!checkConfigurationLevel(getCertifyLevel())) {
65         ThrowMsg(Exceptions::PrivilegeLevelViolation, "setting level violate");
66     }
67     _D("================ Step: <<Certify Level>> DONE ================");
68 }
69
70 void TaskCertifyLevel::getSignatureFiles(const std::string& path,
71                                          SignatureFileInfoSet& file)
72 {
73     SignatureFileInfoSet signatureFiles;
74     SignatureFinder signatureFinder(path);
75     if (SignatureFinder::NO_ERROR != signatureFinder.find(file)) {
76         _E("Error in Signature Finder : %s", path.c_str());
77         ThrowMsg(Exceptions::SignatureNotFound, "Signature not found");
78     }
79 }
80
81 TaskCertifyLevel::Level TaskCertifyLevel::getCertifyLevel()
82 {
83     std::string widgetPath;
84     widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/";
85
86     if (m_contextData.mode.command == InstallMode::Command::REINSTALL) {
87         widgetPath =
88             m_contextData.locations->getPackageInstallationDir() + "/";
89     }
90
91     SignatureFileInfoSet signatureFiles;
92
93     Try {
94         getSignatureFiles(widgetPath, signatureFiles);
95
96         if (signatureFiles.size() <= 0) {
97             widgetPath += std::string(WrtDB::GlobalConfig::GetWidgetSrcPath())
98                 + "/";
99             if (0 == access(widgetPath.c_str(), F_OK)) {
100                 getSignatureFiles(widgetPath, signatureFiles);
101             }
102         }
103     } Catch(Exceptions::SignatureNotFound) {
104         ReThrowMsg(Exceptions::SignatureNotFound, widgetPath);
105     }
106
107     SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
108     _D("Number of signatures: %d", signatureFiles.size());
109
110     Level level = Level::UNKNOWN;
111     for (; iter != signatureFiles.rend(); ++iter) {
112         _D("Checking signature with id=%d", iter->getFileNumber());
113         SignatureData data(widgetPath + iter->getFileName(),
114                            iter->getFileNumber());
115
116         Try {
117             SignatureReader xml;
118             xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
119             xml.read(data);
120
121             WrtSignatureValidator validator(
122                     WrtSignatureValidator::TIZEN,
123                     !GlobalSettings::
124                     OCSPTestModeEnabled(),
125                     !GlobalSettings::
126                     CrlTestModeEnabled(),
127                     false);
128
129             WrtSignatureValidator::Result result =
130                 validator.check(data, widgetPath);
131
132             if (m_contextData.mode.installTime
133                 ==  InstallMode::InstallTime::PRELOAD)
134             {
135                 result = WrtSignatureValidator::SIGNATURE_VERIFIED;
136             }
137
138             if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
139                 ThrowMsg(Exceptions::CertificateExpired,
140                          "Certificate is REVOKED");
141             }
142
143             if (result == WrtSignatureValidator::SIGNATURE_INVALID &&
144                     iter->getFileNumber() <= 1)
145             {
146                 ThrowMsg(Exceptions::SignatureInvalid, "Invalid Package");
147             }
148
149             if (data.isAuthorSignature()) {
150                 _D("Skip author signature");
151             } else {
152                 Level currentCertLevel =
153                     certTypeToLevel(data.getVisibilityLevel());
154                 if (currentCertLevel == Level::UNKNOWN) {
155                     continue;
156                 }
157                 if (currentCertLevel > level) {
158                     level = currentCertLevel;
159                     _D("level %s", enumToString(level).c_str());
160                 }
161             }
162         } Catch(ParserSchemaException::Base) {
163             _E("Error occured in ParserSchema.");
164             ReThrowMsg(Exceptions::SignatureInvalid,
165                        "Error occured in ParserSchema.");
166         }
167     }
168
169     return level;
170 }
171
172 bool TaskCertifyLevel::checkConfigurationLevel(
173     TaskCertifyLevel::Level level)
174 {
175     if (!checkSettingLevel(level)) {
176         return false;
177     }
178     if (!checkAppcontrolHasDisposition(level)) {
179         return false;
180     }
181     return true;
182 }
183
184 bool TaskCertifyLevel::checkSettingLevel(
185     TaskCertifyLevel::Level level)
186 {
187     secureSettingMap data = {
188         {"sound-mode", Level::PARTNER}
189     };
190
191     FOREACH(it, m_contextData.widgetConfig.configInfo.settingsList) {
192         secureSettingIter ret = data.find(DPL::ToUTF8String(it->m_name));
193         if (ret != data.end()) {
194             if (level < ret->second) {
195                 _E("\"%ls\" needs \"%s\" level", it->m_name.c_str(), enumToString(ret->second).c_str());
196                 return false;
197             }
198         }
199     }
200     return true;
201 }
202
203 bool TaskCertifyLevel::checkAppcontrolHasDisposition(
204     TaskCertifyLevel::Level level)
205 {
206     // tizen:disposition -> platform
207     FOREACH(it, m_contextData.widgetConfig.configInfo.appControlList) {
208         if (ConfigParserData::AppControlInfo::Disposition::UNDEFINE !=
209             it->m_disposition)
210         {
211             if (level < Level::PLATFORM) {
212                 _E("\"tizen:disposition\" needs \"%s \" level", enumToString(Level::PLATFORM).c_str());
213                 return false;
214             }
215         }
216     }
217     return true;
218 }
219
220 std::string TaskCertifyLevel::enumToString(
221     TaskCertifyLevel::Level level)
222 {
223     switch (level) {
224 #define X(x, y) case x: return #y;
225         X(Level::UNKNOWN, UNKNOWN)
226         X(Level::PUBLIC, PUBLIC)
227         X(Level::PARTNER, PARTNER)
228         X(Level::PLATFORM, PLATFORM)
229 #undef X
230     default:
231         return "UNKNOWN";
232     }
233 }
234
235 TaskCertifyLevel::Level TaskCertifyLevel::certTypeToLevel(
236     CertStoreId::Type type)
237 {
238     // CertStoreType.h (framework/security/cert-svc)
239     // RootCA's visibility level : public
240     // const Type VIS_PUBLIC = 1 << 6;
241     // RootCA's visibility level : partner
242     // const Type VIS_PARTNER = 1 << 7;
243     // RootCA's visibility level : platform
244     // const Type VIS_PLATFORM = 1 << 10;
245     if (type == CertStoreId::VIS_PUBLIC) {
246         return Level::PUBLIC;
247     } else if (type == CertStoreId::VIS_PARTNER) {
248         return Level::PARTNER;
249     } else if (type == CertStoreId::VIS_PLATFORM) {
250         return Level::PLATFORM;
251     }
252     return Level::UNKNOWN;
253 }
254
255 void TaskCertifyLevel::StartStep()
256 {
257     _D("--------- <TaskCertifyLevel> : START ----------");
258 }
259
260 void TaskCertifyLevel::EndStep()
261 {
262     _D("--------- <TaskCertifyLevel> : END ----------");
263
264     m_contextData.job->UpdateProgress(
265         InstallerContext::INSTALL_CERTIFY_LEVEL_CHECK,
266         "Application Certificate level check Finished");
267 }
268 } //namespace WidgetInstall
269 } //namespace Jobs
270