1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "inner_shared_bundle_installer.h"
17
18 #include "app_provision_info_manager.h"
19 #include "bundle_mgr_service.h"
20 #include "installd_client.h"
21 #include "ipc_skeleton.h"
22
23 namespace OHOS {
24 namespace AppExecFwk {
25 using namespace OHOS::Security;
26 namespace {
27 const std::string HSP_VERSION_PREFIX = "v";
28 const int32_t MAX_FILE_NUMBER = 2;
29 const std::string COMPILE_SDK_TYPE_OPEN_HARMONY = "OpenHarmony";
30 const std::string DEBUG_APP_IDENTIFIER = "DEBUG_LIB_ID";
31 }
32
InnerSharedBundleInstaller(const std::string & path)33 InnerSharedBundleInstaller::InnerSharedBundleInstaller(const std::string &path)
34 : sharedBundlePath_(path), bundleInstallChecker_(std::make_unique<BundleInstallChecker>())
35 {
36 APP_LOGI("inner shared bundle installer instance is created");
37 }
38
~InnerSharedBundleInstaller()39 InnerSharedBundleInstaller::~InnerSharedBundleInstaller()
40 {
41 APP_LOGI("inner shared bundle installer instance is destroyed");
42 BundleUtil::DeleteTempDirs(toDeleteTempHspPath_);
43 }
44
ParseFiles(const InstallCheckParam & checkParam)45 ErrCode InnerSharedBundleInstaller::ParseFiles(const InstallCheckParam &checkParam)
46 {
47 APP_LOGD("parsing shared bundle files, path : %{private}s", sharedBundlePath_.c_str());
48 ErrCode result = ERR_OK;
49
50 // check file paths
51 std::vector<std::string> inBundlePaths;
52 result = BundleUtil::CheckFilePath({sharedBundlePath_}, inBundlePaths);
53 CHECK_RESULT(result, "hsp files check failed %{public}d");
54
55 if (!checkParam.isPreInstallApp) {
56 // copy the haps to the dir which cannot be accessed from caller
57 result = CopyHspToSecurityDir(inBundlePaths);
58 CHECK_RESULT(result, "copy file failed %{public}d");
59 }
60
61 // check number and type of the hsp and sig files
62 std::vector<std::string> bundlePaths;
63 result = ObtainHspFileAndSignatureFilePath(inBundlePaths, bundlePaths, signatureFileDir_);
64 CHECK_RESULT(result, "obtain hsp file path or signature file path failed due to %{public}d");
65
66 // check syscap
67 result = bundleInstallChecker_->CheckSysCap(bundlePaths);
68 CHECK_RESULT(result, "hap syscap check failed %{public}d");
69
70 // verify signature info for all haps
71 std::vector<Security::Verify::HapVerifyResult> hapVerifyResults;
72 result = bundleInstallChecker_->CheckMultipleHapsSignInfo(bundlePaths, hapVerifyResults);
73 CHECK_RESULT(result, "hap files check signature info failed %{public}d");
74
75 // parse bundle infos
76 result = bundleInstallChecker_->ParseHapFiles(bundlePaths, checkParam, hapVerifyResults, parsedBundles_);
77 CHECK_RESULT(result, "parse haps file failed %{public}d");
78
79 // check install permission
80 result = bundleInstallChecker_->CheckInstallPermission(checkParam, hapVerifyResults);
81 CHECK_RESULT(result, "check install permission failed %{public}d");
82
83 // check hsp install condition
84 result = bundleInstallChecker_->CheckHspInstallCondition(hapVerifyResults);
85 CHECK_RESULT(result, "check hsp install condition failed %{public}d");
86
87 // to send notify of start install shared application
88 sendStartSharedBundleInstallNotify(checkParam, parsedBundles_);
89
90 // check device type
91 result = bundleInstallChecker_->CheckDeviceType(parsedBundles_);
92 CHECK_RESULT(result, "check device type failed %{public}d");
93
94 // check label info
95 result = CheckAppLabelInfo();
96 CHECK_RESULT(result, "check label info failed %{public}d");
97
98 // delivery sign profile to code signature
99 result = DeliveryProfileToCodeSign(hapVerifyResults);
100 CHECK_RESULT(result, "delivery sign profile failed %{public}d");
101
102 // check native file
103 result = bundleInstallChecker_->CheckMultiNativeFile(parsedBundles_);
104 CHECK_RESULT(result, "native so is incompatible in all haps %{public}d");
105
106 // check enterprise bundle
107 /* At this place, hapVerifyResults cannot be empty and unnecessary to check it */
108 isEnterpriseBundle_ = bundleInstallChecker_->CheckEnterpriseBundle(hapVerifyResults[0]);
109 appIdentifier_ = (hapVerifyResults[0].GetProvisionInfo().type == Security::Verify::ProvisionType::DEBUG) ?
110 DEBUG_APP_IDENTIFIER : hapVerifyResults[0].GetProvisionInfo().bundleInfo.appIdentifier;
111 compileSdkType_ = parsedBundles_.empty() ? COMPILE_SDK_TYPE_OPEN_HARMONY :
112 (parsedBundles_.begin()->second).GetBaseApplicationInfo().compileSdkType;
113 AddAppProvisionInfo(bundleName_, hapVerifyResults[0].GetProvisionInfo());
114 return result;
115 }
116
sendStartSharedBundleInstallNotify(const InstallCheckParam & installCheckParam,const std::unordered_map<std::string,InnerBundleInfo> & infos)117 void InnerSharedBundleInstaller::sendStartSharedBundleInstallNotify(const InstallCheckParam &installCheckParam,
118 const std::unordered_map<std::string, InnerBundleInfo> &infos)
119 {
120 if (!installCheckParam.needSendEvent) {
121 APP_LOGW("sendStartSharedBundleInstallNotify needSendEvent is false");
122 return;
123 }
124 for (auto item : infos) {
125 APP_LOGD("sendStartSharedBundleInstallNotify %{public}s %{public}s %{public}s %{public}s",
126 item.second.GetBundleName().c_str(), item.second.GetCurModuleName().c_str(),
127 item.second.GetAppId().c_str(), item.second.GetAppIdentifier().c_str());
128 NotifyBundleEvents installRes = {
129 .bundleName = item.second.GetBundleName(),
130 .modulePackage = item.second.GetCurModuleName(),
131 .type = NotifyType::START_INSTALL,
132 .appId = item.second.GetAppId(),
133 .appIdentifier = item.second.GetAppIdentifier()
134 };
135 if (NotifyBundleStatusOfShared(installRes) != ERR_OK) {
136 APP_LOGW("notify status failed for start install");
137 }
138 }
139 }
140
NotifyBundleStatusOfShared(const NotifyBundleEvents & installRes)141 ErrCode InnerSharedBundleInstaller::NotifyBundleStatusOfShared(const NotifyBundleEvents &installRes)
142 {
143 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
144 if (!dataMgr) {
145 APP_LOGE("Get dataMgr shared_ptr nullptr");
146 return false;
147 }
148 std::shared_ptr<BundleCommonEventMgr> commonEventMgr = std::make_shared<BundleCommonEventMgr>();
149 commonEventMgr->NotifyBundleStatus(installRes, dataMgr);
150 return ERR_OK;
151 }
152
Install(const InstallParam & installParam)153 ErrCode InnerSharedBundleInstaller::Install(const InstallParam &installParam)
154 {
155 if (parsedBundles_.empty()) {
156 APP_LOGD("no bundle to install");
157 return ERR_OK;
158 }
159
160 ErrCode result = ERR_OK;
161 for (auto &item : parsedBundles_) {
162 result = ExtractSharedBundles(item.first, item.second);
163 item.second.SetApplicationFlags(installParam.preinstallSourceFlag);
164 CHECK_RESULT(result, "extract shared bundles failed %{public}d");
165 }
166
167 MergeBundleInfos();
168
169 result = SavePreInstallInfo(installParam);
170 CHECK_RESULT(result, "save pre install info failed %{public}d");
171
172 result = SaveBundleInfoToStorage();
173 CHECK_RESULT(result, "save bundle info to storage failed %{public}d");
174
175 // save specifiedDistributionType and additionalInfo
176 SaveInstallParamInfo(bundleName_, installParam);
177 // check mark install finish
178 result = MarkInstallFinish();
179 if (result != ERR_OK) {
180 APP_LOGE("mark install finish failed %{public}d", result);
181 RollBack();
182 return result;
183 }
184 APP_LOGD("install shared bundle successfully: %{public}s", bundleName_.c_str());
185 return result;
186 }
187
RollBack()188 void InnerSharedBundleInstaller::RollBack()
189 {
190 // delete created directories
191 for (auto iter = createdDirs_.crbegin(); iter != createdDirs_.crend(); ++iter) {
192 ErrCode err = InstalldClient::GetInstance()->RemoveDir(*iter);
193 if (err != ERR_OK) {
194 APP_LOGE("clean dir of %{public}s failed: %{public}s", bundleName_.c_str(), iter->c_str());
195 }
196 }
197
198 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
199 if (dataMgr == nullptr) {
200 APP_LOGE("get dataMgr failed");
201 return;
202 }
203
204 // rollback database
205 if (!isBundleExist_) {
206 if (dataMgr->DeleteSharedBundleInfo(bundleName_)) {
207 APP_LOGE("rollback new bundle failed : %{public}s", bundleName_.c_str());
208 }
209 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->DeleteAppProvisionInfo(bundleName_)) {
210 APP_LOGE("bundleName: %{public}s delete appProvisionInfo failed", bundleName_.c_str());
211 }
212 return;
213 }
214
215 if (dataMgr->UpdateInnerBundleInfo(oldBundleInfo_)) {
216 APP_LOGE("rollback old bundle failed : %{public}s", bundleName_.c_str());
217 }
218 }
219
CheckDependency(const Dependency & dependency) const220 bool InnerSharedBundleInstaller::CheckDependency(const Dependency &dependency) const
221 {
222 if (dependency.bundleName != bundleName_) {
223 APP_LOGE("bundle name not match : %{public}s, %{public}s", bundleName_.c_str(), dependency.bundleName.c_str());
224 return false;
225 }
226
227 for (const auto &item : parsedBundles_) {
228 const auto bundleInfo = item.second;
229 BaseSharedBundleInfo sharedBundle;
230 bool isModuleExist = bundleInfo.GetMaxVerBaseSharedBundleInfo(dependency.moduleName, sharedBundle);
231 if (isModuleExist && dependency.versionCode <= sharedBundle.versionCode) {
232 return true;
233 }
234 }
235
236 APP_LOGE("dependency not match");
237 return false;
238 }
239
SendBundleSystemEvent(const EventInfo & eventTemplate) const240 void InnerSharedBundleInstaller::SendBundleSystemEvent(const EventInfo &eventTemplate) const
241 {
242 EventInfo eventInfo = eventTemplate;
243 eventInfo.bundleName = bundleName_;
244 eventInfo.versionCode = newBundleInfo_.GetBaseBundleInfo().versionCode;
245 eventInfo.callingUid = IPCSkeleton::GetCallingUid();
246 GetInstallEventInfo(eventInfo);
247
248 BundleEventType eventType = isBundleExist_ ? BundleEventType::UPDATE : BundleEventType::INSTALL;
249 EventReport::SendBundleSystemEvent(eventType, eventInfo);
250 }
251
CheckAppLabelInfo()252 ErrCode InnerSharedBundleInstaller::CheckAppLabelInfo()
253 {
254 if (parsedBundles_.empty()) {
255 APP_LOGE("parsedBundles is empty");
256 return ERR_OK;
257 }
258 bundleName_ = parsedBundles_.begin()->second.GetBundleName();
259
260 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
261 if (dataMgr == nullptr) {
262 APP_LOGE("Get dataMgr shared_ptr nullptr");
263 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
264 }
265
266 isBundleExist_ = dataMgr->FetchInnerBundleInfo(bundleName_, oldBundleInfo_);
267 if (isBundleExist_) {
268 ErrCode ret = CheckBundleTypeWithInstalledVersion();
269 CHECK_RESULT(ret, "check bundle type with installed version failed %{public}d");
270
271 // check old InnerBundleInfo together
272 parsedBundles_.emplace(bundleName_, oldBundleInfo_);
273 } else {
274 if (parsedBundles_.begin()->second.GetApplicationBundleType() != BundleType::SHARED) {
275 APP_LOGE("installing bundle is not hsp");
276 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
277 }
278 }
279
280 if (isBundleExist_) {
281 parsedBundles_.erase(bundleName_);
282 }
283 return ERR_OK;
284 }
285
CheckBundleTypeWithInstalledVersion()286 ErrCode InnerSharedBundleInstaller::CheckBundleTypeWithInstalledVersion()
287 {
288 if (oldBundleInfo_.GetApplicationBundleType() != BundleType::SHARED) {
289 APP_LOGE("old bundle is not shared");
290 return ERR_APPEXECFWK_INSTALL_COMPATIBLE_POLICY_NOT_SAME;
291 }
292
293 for (const auto &item : parsedBundles_) {
294 auto& sharedModules = item.second.GetInnerSharedModuleInfos();
295 if (sharedModules.empty() || sharedModules.begin()->second.empty()) {
296 APP_LOGW("inner shared module infos not found (%{public}s)", item.second.GetBundleName().c_str());
297 continue;
298 }
299
300 auto& sharedModule = sharedModules.begin()->second.front();
301 BaseSharedBundleInfo installedSharedModule;
302 if (oldBundleInfo_.GetMaxVerBaseSharedBundleInfo(sharedModule.moduleName, installedSharedModule) &&
303 installedSharedModule.versionCode > sharedModule.versionCode) {
304 APP_LOGE("installing lower version shared package");
305 return ERR_APPEXECFWK_INSTALL_VERSION_DOWNGRADE;
306 }
307 }
308 return ERR_OK;
309 }
310
MkdirIfNotExist(const std::string & dir)311 ErrCode InnerSharedBundleInstaller::MkdirIfNotExist(const std::string &dir)
312 {
313 bool isDirExist = false;
314 ErrCode result = InstalldClient::GetInstance()->IsExistDir(dir, isDirExist);
315 CHECK_RESULT(result, "check if dir exist failed %{public}d");
316 if (!isDirExist) {
317 result = InstalldClient::GetInstance()->CreateBundleDir(dir);
318 CHECK_RESULT(result, "create dir failed %{public}d");
319 createdDirs_.emplace_back(dir);
320 }
321 return result;
322 }
323
ExtractSharedBundles(const std::string & bundlePath,InnerBundleInfo & newInfo)324 ErrCode InnerSharedBundleInstaller::ExtractSharedBundles(const std::string &bundlePath, InnerBundleInfo &newInfo)
325 {
326 ErrCode result = ERR_OK;
327 std::string bundleDir = Constants::BUNDLE_CODE_DIR + ServiceConstants::PATH_SEPARATOR + bundleName_;
328 result = MkdirIfNotExist(bundleDir);
329 CHECK_RESULT(result, "check bundle dir failed %{public}d");
330 newInfo.SetAppCodePath(bundleDir);
331
332 uint32_t versionCode = newInfo.GetVersionCode();
333 std::string versionDir = bundleDir + ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX
334 + std::to_string(versionCode);
335 result = MkdirIfNotExist(versionDir);
336 CHECK_RESULT(result, "check version dir failed %{public}d");
337
338 auto &moduleName = newInfo.GetInnerModuleInfos().begin()->second.moduleName;
339 std::string moduleDir = versionDir + ServiceConstants::PATH_SEPARATOR + moduleName;
340 result = MkdirIfNotExist(moduleDir);
341 CHECK_RESULT(result, "check module dir failed %{public}d");
342
343 result = ProcessNativeLibrary(bundlePath, moduleDir, moduleName, versionDir, newInfo);
344 CHECK_RESULT(result, "ProcessNativeLibrary failed %{public}d");
345
346 if (newInfo.IsPreInstallApp()) {
347 // preInstallApp does not need to copy hsp
348 newInfo.SetModuleHapPath(bundlePath);
349 } else {
350 // save hsp and so files to installation dir
351 std::string realHspPath = moduleDir + ServiceConstants::PATH_SEPARATOR + moduleName +
352 ServiceConstants::HSP_FILE_SUFFIX;
353 result = SaveHspToRealInstallationDir(bundlePath, moduleDir, moduleName, realHspPath);
354 CHECK_RESULT(result, "save hsp file failed %{public}d");
355 newInfo.SetModuleHapPath(realHspPath);
356 }
357 if (newInfo.IsCompressNativeLibs(moduleName)) {
358 // move so to real path
359 result = MoveSoToRealPath(moduleName, versionDir);
360 CHECK_RESULT(result, "move so to real path failed %{public}d");
361 }
362 newInfo.AddModuleSrcDir(moduleDir);
363 newInfo.AddModuleResPath(moduleDir);
364 newInfo.UpdateSharedModuleInfo();
365 return ERR_OK;
366 }
367
UpdateInnerModuleInfo(const std::string packageName,const InnerModuleInfo & innerModuleInfo)368 void InnerSharedBundleInstaller::UpdateInnerModuleInfo(const std::string packageName,
369 const InnerModuleInfo &innerModuleInfo)
370 {
371 newBundleInfo_.ReplaceInnerModuleInfo(packageName, innerModuleInfo);
372 std::string moduleDir = std::string(Constants::BUNDLE_CODE_DIR) + ServiceConstants::PATH_SEPARATOR + bundleName_ +
373 ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX + std::to_string(innerModuleInfo.versionCode) +
374 ServiceConstants::PATH_SEPARATOR + innerModuleInfo.moduleName;
375 bool isDirExist = false;
376 ErrCode result = InstalldClient::GetInstance()->IsExistDir(moduleDir, isDirExist);
377 if (isDirExist) {
378 newBundleInfo_.SetCurrentModulePackage(packageName);
379 newBundleInfo_.AddModuleSrcDir(moduleDir);
380 newBundleInfo_.AddModuleResPath(moduleDir);
381 } else {
382 APP_LOGW("update path failed %{public}s %{public}d", moduleDir.c_str(), result);
383 }
384 }
385
MergeBundleInfos()386 void InnerSharedBundleInstaller::MergeBundleInfos()
387 {
388 auto iter = parsedBundles_.begin();
389 if (isBundleExist_) {
390 newBundleInfo_ = oldBundleInfo_;
391 } else {
392 newBundleInfo_ = iter->second;
393 ++iter;
394 }
395
396 for (; iter != parsedBundles_.end(); ++iter) {
397 const auto ¤tBundle = iter->second;
398 const auto& infos = currentBundle.GetInnerSharedModuleInfos();
399 if (infos.empty()) {
400 continue;
401 }
402
403 const auto& innerModuleInfos = infos.begin()->second;
404 if (!innerModuleInfos.empty()) {
405 const auto& innerModuleInfo = innerModuleInfos.front();
406 newBundleInfo_.InsertInnerSharedModuleInfo(innerModuleInfo.modulePackage, innerModuleInfo);
407 UpdateInnerModuleInfo(innerModuleInfo.modulePackage, innerModuleInfo);
408 }
409 // update version
410 if (newBundleInfo_.GetBaseBundleInfo().versionCode < currentBundle.GetBaseBundleInfo().versionCode) {
411 newBundleInfo_.UpdateBaseBundleInfo(currentBundle.GetBaseBundleInfo(), false);
412 newBundleInfo_.UpdateBaseApplicationInfo(currentBundle.GetBaseApplicationInfo(), false);
413 newBundleInfo_.UpdateReleaseType(currentBundle);
414 }
415 }
416
417 newBundleInfo_.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
418 newBundleInfo_.SetHideDesktopIcon(true);
419 }
420
SavePreInstallInfo(const InstallParam & installParam)421 ErrCode InnerSharedBundleInstaller::SavePreInstallInfo(const InstallParam &installParam)
422 {
423 if (!installParam.needSavePreInstallInfo) {
424 APP_LOGD("no need to save pre install info");
425 return ERR_OK;
426 }
427
428 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
429 if (dataMgr == nullptr) {
430 APP_LOGE("get dataMgr failed");
431 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
432 }
433
434 PreInstallBundleInfo preInstallBundleInfo;
435 if (!dataMgr->GetPreInstallBundleInfo(bundleName_, preInstallBundleInfo)) {
436 preInstallBundleInfo.SetBundleName(bundleName_);
437 }
438 preInstallBundleInfo.SetVersionCode(newBundleInfo_.GetBaseBundleInfo().versionCode);
439 for (const auto &item : parsedBundles_) {
440 preInstallBundleInfo.AddBundlePath(item.first);
441 }
442 #ifdef USE_PRE_BUNDLE_PROFILE
443 preInstallBundleInfo.SetRemovable(installParam.removable);
444 #else
445 preInstallBundleInfo.SetRemovable(newBundleInfo_.IsRemovable());
446 #endif
447 auto applicationInfo = newBundleInfo_.GetBaseApplicationInfo();
448 newBundleInfo_.AdaptMainLauncherResourceInfo(applicationInfo);
449 preInstallBundleInfo.SetLabelId(applicationInfo.labelResource.id);
450 preInstallBundleInfo.SetIconId(applicationInfo.iconResource.id);
451 preInstallBundleInfo.SetModuleName(applicationInfo.labelResource.moduleName);
452 preInstallBundleInfo.SetSystemApp(applicationInfo.isSystemApp);
453 preInstallBundleInfo.SetBundleType(BundleType::SHARED);
454 dataMgr->SavePreInstallBundleInfo(bundleName_, preInstallBundleInfo);
455 return ERR_OK;
456 }
457
SaveBundleInfoToStorage()458 ErrCode InnerSharedBundleInstaller::SaveBundleInfoToStorage()
459 {
460 // update install mark
461 std::string packageName;
462 newBundleInfo_.SetInstallMark(bundleName_, packageName, InstallExceptionStatus::INSTALL_FINISH);
463
464 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
465 if (dataMgr == nullptr) {
466 APP_LOGE("get dataMgr failed");
467 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
468 }
469
470 if (isBundleExist_) {
471 if (!dataMgr->UpdateInnerBundleInfo(newBundleInfo_, false)) {
472 APP_LOGE("save bundle failed : %{public}s", bundleName_.c_str());
473 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
474 }
475 return ERR_OK;
476 }
477
478 dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_START);
479 if (!dataMgr->AddInnerBundleInfo(bundleName_, newBundleInfo_)) {
480 dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_FAIL);
481 APP_LOGE("save bundle failed : %{public}s", bundleName_.c_str());
482 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
483 }
484 dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_SUCCESS);
485 return ERR_OK;
486 }
487
GetInstallEventInfo(EventInfo & eventInfo) const488 void InnerSharedBundleInstaller::GetInstallEventInfo(EventInfo &eventInfo) const
489 {
490 APP_LOGD("GetInstallEventInfo start, bundleName:%{public}s", bundleName_.c_str());
491 eventInfo.fingerprint = newBundleInfo_.GetCertificateFingerprint();
492 eventInfo.appDistributionType = newBundleInfo_.GetAppDistributionType();
493 eventInfo.hideDesktopIcon = newBundleInfo_.IsHideDesktopIcon();
494 eventInfo.timeStamp = BundleUtil::GetCurrentTimeMs();
495
496 // report hapPath and hashValue
497 for (const auto &info : parsedBundles_) {
498 for (const auto &innerModuleInfo : info.second.GetInnerModuleInfos()) {
499 eventInfo.filePath.push_back(innerModuleInfo.second.hapPath);
500 eventInfo.hashValue.push_back(innerModuleInfo.second.hashValue);
501 }
502 }
503 }
504
AddAppProvisionInfo(const std::string & bundleName,const Security::Verify::ProvisionInfo & provisionInfo) const505 void InnerSharedBundleInstaller::AddAppProvisionInfo(const std::string &bundleName,
506 const Security::Verify::ProvisionInfo &provisionInfo) const
507 {
508 AppProvisionInfo appProvisionInfo = bundleInstallChecker_->ConvertToAppProvisionInfo(provisionInfo);
509 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->AddAppProvisionInfo(
510 bundleName, appProvisionInfo)) {
511 APP_LOGW("bundleName: %{public}s add appProvisionInfo failed", bundleName.c_str());
512 }
513 }
514
SaveInstallParamInfo(const std::string & bundleName,const InstallParam & installParam) const515 void InnerSharedBundleInstaller::SaveInstallParamInfo(
516 const std::string &bundleName, const InstallParam &installParam) const
517 {
518 if (!installParam.specifiedDistributionType.empty()) {
519 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetSpecifiedDistributionType(
520 bundleName, installParam.specifiedDistributionType)) {
521 APP_LOGW("bundleName: %{public}s SetSpecifiedDistributionType failed", bundleName.c_str());
522 }
523 }
524 if (!installParam.additionalInfo.empty()) {
525 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetAdditionalInfo(
526 bundleName, installParam.additionalInfo)) {
527 APP_LOGW("bundleName: %{public}s SetAdditionalInfo failed", bundleName.c_str());
528 }
529 }
530 }
531
CopyHspToSecurityDir(std::vector<std::string> & bundlePaths)532 ErrCode InnerSharedBundleInstaller::CopyHspToSecurityDir(std::vector<std::string> &bundlePaths)
533 {
534 for (size_t index = 0; index < bundlePaths.size(); ++index) {
535 auto destination = BundleUtil::CopyFileToSecurityDir(bundlePaths[index], DirType::STREAM_INSTALL_DIR,
536 toDeleteTempHspPath_);
537 if (destination.empty()) {
538 APP_LOGE("copy file %{public}s to security dir failed", bundlePaths[index].c_str());
539 return ERR_APPEXECFWK_INSTALL_COPY_HAP_FAILED;
540 }
541 bundlePaths[index] = destination;
542 }
543 return ERR_OK;
544 }
545
ObtainHspFileAndSignatureFilePath(const std::vector<std::string> & inBundlePaths,std::vector<std::string> & bundlePaths,std::string & signatureFilePath)546 ErrCode InnerSharedBundleInstaller::ObtainHspFileAndSignatureFilePath(const std::vector<std::string> &inBundlePaths,
547 std::vector<std::string> &bundlePaths, std::string &signatureFilePath)
548 {
549 if (inBundlePaths.empty() || inBundlePaths.size() > MAX_FILE_NUMBER) {
550 APP_LOGE("number of files in single shared lib path is illegal");
551 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
552 }
553 if (inBundlePaths.size() == 1) {
554 if (!BundleUtil::EndWith(inBundlePaths[0], ServiceConstants::HSP_FILE_SUFFIX)) {
555 APP_LOGE("invalid file in shared bundle dir");
556 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
557 }
558 bundlePaths.emplace_back(inBundlePaths[0]);
559 return ERR_OK;
560 }
561 int32_t numberOfHsp = 0;
562 int32_t numberOfSignatureFile = 0;
563 for (const auto &path : inBundlePaths) {
564 if ((path.find(ServiceConstants::HSP_FILE_SUFFIX) == std::string::npos) &&
565 (path.find(ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX) == std::string::npos)) {
566 APP_LOGE("only hsp or sig file can be contained in shared bundle dir");
567 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
568 }
569 if (BundleUtil::EndWith(path, ServiceConstants::HSP_FILE_SUFFIX)) {
570 numberOfHsp++;
571 bundlePaths.emplace_back(path);
572 }
573 if (BundleUtil::EndWith(path, ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX)) {
574 numberOfSignatureFile++;
575 signatureFilePath = path;
576 }
577 if ((numberOfHsp >= MAX_FILE_NUMBER) || (numberOfSignatureFile >= MAX_FILE_NUMBER)) {
578 APP_LOGE("only one hsp and one signature file can be contained in a single shared bundle dir");
579 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
580 }
581 }
582 APP_LOGD("signatureFilePath is %{public}s", signatureFilePath.c_str());
583 return ERR_OK;
584 }
585
SaveHspToRealInstallationDir(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & realHspPath)586 ErrCode InnerSharedBundleInstaller::SaveHspToRealInstallationDir(const std::string &bundlePath,
587 const std::string &moduleDir,
588 const std::string &moduleName,
589 const std::string &realHspPath)
590 {
591 // 1. create temp dir
592 ErrCode result = ERR_OK;
593 std::string tempHspDir = moduleDir + ServiceConstants::PATH_SEPARATOR + moduleName;
594 result = MkdirIfNotExist(tempHspDir);
595 CHECK_RESULT(result, "create tempHspDir dir failed %{public}d");
596
597 // 2. copy hsp to installation dir, and then to verify code signature of hsp
598 std::string tempHspPath = tempHspDir + ServiceConstants::PATH_SEPARATOR + moduleName +
599 ServiceConstants::HSP_FILE_SUFFIX;
600 if (!signatureFileDir_.empty()) {
601 result = InstalldClient::GetInstance()->CopyFile(bundlePath, tempHspPath, signatureFileDir_);
602 } else {
603 result = InstalldClient::GetInstance()->MoveHapToCodeDir(bundlePath, tempHspPath);
604 CHECK_RESULT(result, "copy hsp to install dir failed %{public}d");
605 bool isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
606 result = VerifyCodeSignatureForHsp(tempHspPath, appIdentifier_, isEnterpriseBundle_,
607 isCompileSdkOpenHarmony, bundleName_);
608 }
609 CHECK_RESULT(result, "copy hsp to install dir failed %{public}d");
610
611 // 3. move hsp to real installation dir
612 APP_LOGD("move file from temp path %{public}s to real path %{public}s", tempHspPath.c_str(), realHspPath.c_str());
613 result = InstalldClient::GetInstance()->MoveFile(tempHspPath, realHspPath);
614 CHECK_RESULT(result, "move hsp to install dir failed %{public}d");
615
616 // 4. remove temp dir
617 result = InstalldClient::GetInstance()->RemoveDir(tempHspDir);
618 if (result != ERR_OK) {
619 APP_LOGW("remove temp hsp dir %{public}s failed, error is %{public}d", tempHspDir.c_str(), result);
620 }
621 return ERR_OK;
622 }
623
MoveSoToRealPath(const std::string & moduleName,const std::string & versionDir)624 ErrCode InnerSharedBundleInstaller::MoveSoToRealPath(const std::string &moduleName, const std::string &versionDir)
625 {
626 // 1. move so files to real installation dir
627 std::string realSoPath = versionDir + ServiceConstants::PATH_SEPARATOR + nativeLibraryPath_ +
628 ServiceConstants::PATH_SEPARATOR;
629 ErrCode result = MkdirIfNotExist(realSoPath);
630 CHECK_RESULT(result, "check module dir failed %{public}d");
631
632 std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath_);
633 if (tempNativeLibraryPath.empty()) {
634 APP_LOGI("no so libs existed");
635 return ERR_OK;
636 }
637 std::string tempSoPath = versionDir + ServiceConstants::PATH_SEPARATOR + tempNativeLibraryPath;
638 APP_LOGD("move so files from path %{public}s to path %{public}s", tempSoPath.c_str(), realSoPath.c_str());
639 result = InstalldClient::GetInstance()->MoveFiles(tempSoPath, realSoPath);
640 if (result != ERR_OK) {
641 APP_LOGE("move file to real path failed %{public}d", result);
642 return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
643 }
644
645 // 2. remove so temp dir
646 std::string deleteTempDir = versionDir + ServiceConstants::PATH_SEPARATOR + moduleName
647 + ServiceConstants::TMP_SUFFIX;
648 result = InstalldClient::GetInstance()->RemoveDir(deleteTempDir);
649 if (result != ERR_OK) {
650 APP_LOGW("remove hsp temp so dir %{public}s failed, error is %{public}d", deleteTempDir.c_str(), result);
651 }
652 return ERR_OK;
653 }
654
ObtainTempSoPath(const std::string & moduleName,const std::string & nativeLibPath)655 std::string InnerSharedBundleInstaller::ObtainTempSoPath(const std::string &moduleName,
656 const std::string &nativeLibPath)
657 {
658 std::string tempSoPath;
659 if (nativeLibPath.empty()) {
660 APP_LOGE("invalid native libs path");
661 return tempSoPath;
662 }
663 tempSoPath = nativeLibPath;
664 auto pos = tempSoPath.find(moduleName);
665 if (pos == std::string::npos) {
666 tempSoPath = moduleName + ServiceConstants::TMP_SUFFIX + ServiceConstants::PATH_SEPARATOR + tempSoPath;
667 } else {
668 std::string innerTempStr = moduleName + ServiceConstants::TMP_SUFFIX;
669 tempSoPath.replace(pos, moduleName.length(), innerTempStr);
670 }
671 return tempSoPath + ServiceConstants::PATH_SEPARATOR;
672 }
673
ProcessNativeLibrary(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & versionDir,InnerBundleInfo & newInfo)674 ErrCode InnerSharedBundleInstaller::ProcessNativeLibrary(
675 const std::string &bundlePath,
676 const std::string &moduleDir,
677 const std::string &moduleName,
678 const std::string &versionDir,
679 InnerBundleInfo &newInfo)
680 {
681 std::string cpuAbi;
682 if (!newInfo.FetchNativeSoAttrs(moduleName, cpuAbi, nativeLibraryPath_)) {
683 return ERR_OK;
684 }
685 if (newInfo.IsCompressNativeLibs(moduleName)) {
686 std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath_);
687 if (tempNativeLibraryPath.empty()) {
688 APP_LOGE("tempNativeLibraryPath is empty");
689 return ERR_APPEXECFWK_INSTALLD_EXTRACT_FILES_FAILED;
690 }
691 std::string tempSoPath = versionDir + ServiceConstants::PATH_SEPARATOR + tempNativeLibraryPath;
692 APP_LOGD("tempSoPath=%{public}s,cpuAbi=%{public}s, bundlePath=%{public}s",
693 tempSoPath.c_str(), cpuAbi.c_str(), bundlePath.c_str());
694 auto result = InstalldClient::GetInstance()->ExtractModuleFiles(bundlePath, moduleDir, tempSoPath, cpuAbi);
695 CHECK_RESULT(result, "extract module files failed %{public}d");
696 // verify hap or hsp code signature for compressed so files
697 result = VerifyCodeSignatureForNativeFiles(
698 bundlePath, cpuAbi, tempSoPath, signatureFileDir_, newInfo.IsPreInstallApp());
699 CHECK_RESULT(result, "fail to VerifyCodeSignature, error is %{public}d");
700 cpuAbi_ = cpuAbi;
701 tempSoPath_ = tempSoPath;
702 isPreInstalledBundle_ = newInfo.IsPreInstallApp();
703 } else {
704 std::vector<std::string> fileNames;
705 auto result = InstalldClient::GetInstance()->GetNativeLibraryFileNames(bundlePath, cpuAbi, fileNames);
706 CHECK_RESULT(result, "fail to GetNativeLibraryFileNames, error is %{public}d");
707 newInfo.SetNativeLibraryFileNames(moduleName, fileNames);
708 }
709 return ERR_OK;
710 }
711
VerifyCodeSignatureForNativeFiles(const std::string & bundlePath,const std::string & cpuAbi,const std::string & targetSoPath,const std::string & signatureFileDir,bool isPreInstalledBundle) const712 ErrCode InnerSharedBundleInstaller::VerifyCodeSignatureForNativeFiles(const std::string &bundlePath,
713 const std::string &cpuAbi, const std::string &targetSoPath, const std::string &signatureFileDir,
714 bool isPreInstalledBundle) const
715 {
716 if (!isPreInstalledBundle) {
717 APP_LOGD("not pre-install app, skip verify code signature for native files");
718 return ERR_OK;
719 }
720 APP_LOGD("begin to verify code signature for hsp native files");
721 bool isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
722 CodeSignatureParam codeSignatureParam;
723 codeSignatureParam.modulePath = bundlePath;
724 codeSignatureParam.cpuAbi = cpuAbi;
725 codeSignatureParam.targetSoPath = targetSoPath;
726 codeSignatureParam.signatureFileDir = signatureFileDir;
727 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle_;
728 codeSignatureParam.appIdentifier = appIdentifier_;
729 codeSignatureParam.isCompileSdkOpenHarmony = isCompileSdkOpenHarmony;
730 codeSignatureParam.isPreInstalledBundle = isPreInstalledBundle;
731 return InstalldClient::GetInstance()->VerifyCodeSignature(codeSignatureParam);
732 }
733
VerifyCodeSignatureForHsp(const std::string & tempHspPath,const std::string & appIdentifier,bool isEnterpriseBundle,bool isCompileSdkOpenHarmony,const std::string & bundleName) const734 ErrCode InnerSharedBundleInstaller::VerifyCodeSignatureForHsp(const std::string &tempHspPath,
735 const std::string &appIdentifier, bool isEnterpriseBundle, bool isCompileSdkOpenHarmony,
736 const std::string &bundleName) const
737 {
738 APP_LOGD("begin to verify code signature for hsp");
739 CodeSignatureParam codeSignatureParam;
740 codeSignatureParam.modulePath = tempHspPath;
741 codeSignatureParam.cpuAbi = cpuAbi_;
742 codeSignatureParam.targetSoPath = tempSoPath_;
743 codeSignatureParam.appIdentifier = appIdentifier;
744 codeSignatureParam.signatureFileDir = signatureFileDir_;
745 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle;
746 codeSignatureParam.isCompileSdkOpenHarmony = isCompileSdkOpenHarmony;
747 codeSignatureParam.isPreInstalledBundle = isPreInstalledBundle_;
748 return InstalldClient::GetInstance()->VerifyCodeSignatureForHap(codeSignatureParam);
749 }
750
DeliveryProfileToCodeSign(std::vector<Security::Verify::HapVerifyResult> & hapVerifyResults) const751 ErrCode InnerSharedBundleInstaller::DeliveryProfileToCodeSign(
752 std::vector<Security::Verify::HapVerifyResult> &hapVerifyResults) const
753 {
754 if (isBundleExist_) {
755 APP_LOGD("shared bundle %{public}s has been installed and unnecessary to delivery sign profile",
756 bundleName_.c_str());
757 return ERR_OK;
758 }
759 if (hapVerifyResults.empty()) {
760 APP_LOGE("no sign info in the all haps");
761 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
762 }
763
764 Security::Verify::ProvisionInfo provisionInfo = hapVerifyResults[0].GetProvisionInfo();
765 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE ||
766 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL ||
767 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM ||
768 provisionInfo.type == Security::Verify::ProvisionType::DEBUG) {
769 if (provisionInfo.profileBlockLength == 0 || provisionInfo.profileBlock == nullptr) {
770 APP_LOGE("invalid sign profile");
771 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
772 }
773 return InstalldClient::GetInstance()->DeliverySignProfile(provisionInfo.bundleInfo.bundleName,
774 provisionInfo.profileBlockLength, provisionInfo.profileBlock.get());
775 }
776 return ERR_OK;
777 }
778
SetCheckResultMsg(const std::string checkResultMsg) const779 void InnerSharedBundleInstaller::SetCheckResultMsg(const std::string checkResultMsg) const
780 {
781 bundleInstallChecker_->SetCheckResultMsg(checkResultMsg);
782 }
783
MarkInstallFinish()784 ErrCode InnerSharedBundleInstaller::MarkInstallFinish()
785 {
786 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
787 if (dataMgr == nullptr) {
788 APP_LOGE("Get dataMgr shared_ptr nullptr");
789 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
790 }
791 InnerBundleInfo info;
792 if (!dataMgr->FetchInnerBundleInfo(bundleName_, info)) {
793 APP_LOGE("mark finish failed, -n %{public}s not exist", bundleName_.c_str());
794 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
795 }
796 info.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
797 info.SetInstallMark(bundleName_, info.GetCurModuleName(), InstallExceptionStatus::INSTALL_FINISH);
798 if (!dataMgr->UpdateInnerBundleInfo(info, true)) {
799 if (!dataMgr->UpdateInnerBundleInfo(info, true)) {
800 APP_LOGE("save mark failed, -n %{public}s", bundleName_.c_str());
801 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
802 }
803 }
804 return ERR_OK;
805 }
806 } // namespace AppExecFwk
807 } // namespace OHOS
808