1 /*
2 * Copyright (c) 2022 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 "bundle_install_checker.h"
17
18 #include <regex>
19
20 #include "bundle_data_mgr.h"
21 #include "bundle_mgr_service.h"
22 #include "bundle_mgr_service_event_handler.h"
23 #include "bundle_parser.h"
24 #include "bundle_permission_mgr.h"
25 #include "bundle_util.h"
26 #include "parameter.h"
27 #include "parameters.h"
28 #include "privilege_extension_ability_type.h"
29 #include "scope_guard.h"
30 #include "systemcapability.h"
31
32 namespace OHOS {
33 namespace AppExecFwk {
34 namespace {
35 const std::string PRIVILEGE_ALLOW_APP_DATA_NOT_CLEARED = "AllowAppDataNotCleared";
36 const std::string PRIVILEGE_ALLOW_APP_MULTI_PROCESS = "AllowAppMultiProcess";
37 const std::string PRIVILEGE_ALLOW_APP_DESKTOP_ICON_HIDE = "AllowAppDesktopIconHide";
38 const std::string PRIVILEGE_ALLOW_ABILITY_PRIORITY_QUERIED = "AllowAbilityPriorityQueried";
39 const std::string PRIVILEGE_ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS = "AllowAbilityExcludeFromMissions";
40 const std::string PRIVILEGE_ALLOW_MISSION_NOT_CLEARED = "AllowMissionNotCleared";
41 const std::string PRIVILEGE_ALLOW_APP_USE_PRIVILEGE_EXTENSION = "AllowAppUsePrivilegeExtension";
42 const std::string PRIVILEGE_ALLOW_FORM_VISIBLE_NOTIFY = "AllowFormVisibleNotify";
43 const std::string PRIVILEGE_ALLOW_APP_SHARE_LIBRARY = "AllowAppShareLibrary";
44 const std::string PRIVILEGE_ALLOW_ENABLE_NOTIFICATION = "AllowEnableNotification";
45 const std::string ALLOW_APP_DATA_NOT_CLEARED = "allowAppDataNotCleared";
46 const std::string ALLOW_APP_MULTI_PROCESS = "allowAppMultiProcess";
47 const std::string ALLOW_APP_DESKTOP_ICON_HIDE = "allowAppDesktopIconHide";
48 const std::string ALLOW_ABILITY_PRIORITY_QUERIED = "allowAbilityPriorityQueried";
49 const std::string ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS = "allowAbilityExcludeFromMissions";
50 const std::string ALLOW_MISSION_NOT_CLEARED = "allowMissionNotCleared";
51 const std::string ALLOW_APP_USE_PRIVILEGE_EXTENSION = "allowAppUsePrivilegeExtension";
52 const std::string ALLOW_FORM_VISIBLE_NOTIFY = "allowFormVisibleNotify";
53 const std::string ALLOW_APP_SHARE_LIBRARY = "allowAppShareLibrary";
54 const std::string ALLOW_ENABLE_NOTIFICATION = "allowEnableNotification";
55 const std::string APP_TEST_BUNDLE_NAME = "com.OpenHarmony.app.test";
56 const std::string BUNDLE_NAME_XTS_TEST = "com.acts.";
57 const std::string APL_NORMAL = "normal";
58 const std::string SLASH = "/";
59 const std::string DOUBLE_SLASH = "//";
60 const std::string SUPPORT_ISOLATION_MODE = "persist.bms.supportIsolationMode";
61 const std::string VALUE_TRUE = "true";
62 const std::string VALUE_TRUE_BOOL = "1";
63 const std::string VALUE_FALSE = "false";
64 const std::string NONISOLATION_ONLY = "nonisolationOnly";
65 const std::string ISOLATION_ONLY = "isolationOnly";
66 const std::string DEVELOPERMODE_STATE = "const.security.developermode.state";
67 const int32_t SLAH_OFFSET = 2;
68 const int32_t THRESHOLD_VAL_LEN = 40;
69 constexpr const char* SYSTEM_APP_SCAN_PATH = "/system/app";
70 constexpr const char* DEVICE_TYPE_OF_DEFAULT = "default";
71 constexpr const char* DEVICE_TYPE_OF_PHONE = "phone";
72 constexpr const char* APP_INSTALL_PATH = "/data/app/el1/bundle";
73
74 const std::unordered_map<Security::Verify::AppDistType, std::string> APP_DISTRIBUTION_TYPE_MAPS = {
75 { Security::Verify::AppDistType::NONE_TYPE, Constants::APP_DISTRIBUTION_TYPE_NONE },
76 { Security::Verify::AppDistType::APP_GALLERY, Constants::APP_DISTRIBUTION_TYPE_APP_GALLERY },
77 { Security::Verify::AppDistType::ENTERPRISE, Constants::APP_DISTRIBUTION_TYPE_ENTERPRISE },
78 { Security::Verify::AppDistType::ENTERPRISE_NORMAL, Constants::APP_DISTRIBUTION_TYPE_ENTERPRISE_NORMAL },
79 { Security::Verify::AppDistType::ENTERPRISE_MDM, Constants::APP_DISTRIBUTION_TYPE_ENTERPRISE_MDM },
80 { Security::Verify::AppDistType::OS_INTEGRATION, Constants::APP_DISTRIBUTION_TYPE_OS_INTEGRATION },
81 { Security::Verify::AppDistType::CROWDTESTING, Constants::APP_DISTRIBUTION_TYPE_CROWDTESTING },
82 };
83
84 const std::unordered_map<std::string, void (*)(AppPrivilegeCapability &appPrivilegeCapability)>
85 PRIVILEGE_MAP = {
86 { PRIVILEGE_ALLOW_APP_DATA_NOT_CLEARED,
__anond5ecdb780202() 87 [] (AppPrivilegeCapability &appPrivilegeCapability) {
88 appPrivilegeCapability.userDataClearable = false;
89 } },
90 { PRIVILEGE_ALLOW_APP_MULTI_PROCESS,
__anond5ecdb780302() 91 [] (AppPrivilegeCapability &appPrivilegeCapability) {
92 appPrivilegeCapability.allowMultiProcess = true;
93 } },
94 { PRIVILEGE_ALLOW_APP_DESKTOP_ICON_HIDE,
__anond5ecdb780402() 95 [] (AppPrivilegeCapability &appPrivilegeCapability) {
96 appPrivilegeCapability.hideDesktopIcon = true;
97 } },
98 { PRIVILEGE_ALLOW_ABILITY_PRIORITY_QUERIED,
__anond5ecdb780502() 99 [] (AppPrivilegeCapability &appPrivilegeCapability) {
100 appPrivilegeCapability.allowQueryPriority = true;
101 } },
102 { PRIVILEGE_ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS,
__anond5ecdb780602() 103 [] (AppPrivilegeCapability &appPrivilegeCapability) {
104 appPrivilegeCapability.allowExcludeFromMissions = true;
105 } },
106 { PRIVILEGE_ALLOW_MISSION_NOT_CLEARED,
__anond5ecdb780702() 107 [] (AppPrivilegeCapability &appPrivilegeCapability) {
108 appPrivilegeCapability.allowMissionNotCleared = true;
109 } },
110 { PRIVILEGE_ALLOW_APP_USE_PRIVILEGE_EXTENSION,
__anond5ecdb780802() 111 [] (AppPrivilegeCapability &appPrivilegeCapability) {
112 appPrivilegeCapability.allowUsePrivilegeExtension = true;
113 } },
114 { PRIVILEGE_ALLOW_FORM_VISIBLE_NOTIFY,
__anond5ecdb780902() 115 [] (AppPrivilegeCapability &appPrivilegeCapability) {
116 appPrivilegeCapability.formVisibleNotify = true;
117 } },
118 { PRIVILEGE_ALLOW_APP_SHARE_LIBRARY,
__anond5ecdb780a02() 119 [] (AppPrivilegeCapability &appPrivilegeCapability) {
120 appPrivilegeCapability.appShareLibrary = true;
121 } },
122 { PRIVILEGE_ALLOW_ENABLE_NOTIFICATION,
__anond5ecdb780b02() 123 [] (AppPrivilegeCapability &appPrivilegeCapability) {
124 appPrivilegeCapability.allowEnableNotification = true;
125 } },
126 };
127
GetAppDistributionType(const Security::Verify::AppDistType & type)128 std::string GetAppDistributionType(const Security::Verify::AppDistType &type)
129 {
130 auto typeIter = APP_DISTRIBUTION_TYPE_MAPS.find(type);
131 if (typeIter == APP_DISTRIBUTION_TYPE_MAPS.end()) {
132 APP_LOGE("wrong AppDistType");
133 return Constants::APP_DISTRIBUTION_TYPE_NONE;
134 }
135
136 return typeIter->second;
137 }
138
GetAppProvisionType(const Security::Verify::ProvisionType & type)139 std::string GetAppProvisionType(const Security::Verify::ProvisionType &type)
140 {
141 if (type == Security::Verify::ProvisionType::DEBUG) {
142 return Constants::APP_PROVISION_TYPE_DEBUG;
143 }
144
145 return Constants::APP_PROVISION_TYPE_RELEASE;
146 }
147
IsPrivilegeExtensionAbilityType(ExtensionAbilityType type)148 bool IsPrivilegeExtensionAbilityType(ExtensionAbilityType type)
149 {
150 return PRIVILEGE_EXTENSION_ABILITY_TYPE.find(type) != PRIVILEGE_EXTENSION_ABILITY_TYPE.end();
151 }
152
IsSystemExtensionAbilityType(ExtensionAbilityType type)153 bool IsSystemExtensionAbilityType(ExtensionAbilityType type)
154 {
155 return SYSTEM_EXTENSION_ABILITY_TYPE.find(type) != SYSTEM_EXTENSION_ABILITY_TYPE.end();
156 }
157 }
158
CheckSysCap(const std::vector<std::string> & bundlePaths)159 ErrCode BundleInstallChecker::CheckSysCap(const std::vector<std::string> &bundlePaths)
160 {
161 APP_LOGD("check hap syscaps start.");
162 if (bundlePaths.empty()) {
163 APP_LOGE("check hap syscaps failed due to empty bundlePaths!");
164 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
165 }
166
167 ErrCode result = ERR_OK;
168 BundleParser bundleParser;
169 for (const auto &bundlePath : bundlePaths) {
170 std::vector<std::string> bundleSysCaps;
171 result = bundleParser.ParseSysCap(bundlePath, bundleSysCaps);
172 if (result != ERR_OK) {
173 APP_LOGE("parse bundle syscap failed, error: %{public}d", result);
174 return result;
175 }
176
177 for (const auto &bundleSysCapItem : bundleSysCaps) {
178 APP_LOGD("check syscap(%{public}s)", bundleSysCapItem.c_str());
179 if (!HasSystemCapability(bundleSysCapItem.c_str())) {
180 APP_LOGE("check syscap failed which %{public}s is not exsit",
181 bundleSysCapItem.c_str());
182 return ERR_APPEXECFWK_INSTALL_CHECK_SYSCAP_FAILED;
183 }
184 }
185 }
186
187 APP_LOGD("finish check hap syscaps");
188 return result;
189 }
190
CheckMultipleHapsSignInfo(const std::vector<std::string> & bundlePaths,std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes)191 ErrCode BundleInstallChecker::CheckMultipleHapsSignInfo(
192 const std::vector<std::string> &bundlePaths,
193 std::vector<Security::Verify::HapVerifyResult>& hapVerifyRes)
194 {
195 APP_LOGD("Check multiple haps signInfo");
196 if (bundlePaths.empty()) {
197 APP_LOGE("check hap sign info failed due to empty bundlePaths!");
198 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
199 }
200 for (const std::string &bundlePath : bundlePaths) {
201 Security::Verify::HapVerifyResult hapVerifyResult;
202 auto verifyRes = BundleVerifyMgr::HapVerify(bundlePath, hapVerifyResult);
203 #ifndef X86_EMULATOR_MODE
204 if (verifyRes != ERR_OK) {
205 APP_LOGE("hap file verify failed");
206 return verifyRes;
207 }
208 #endif
209 hapVerifyRes.emplace_back(hapVerifyResult);
210 }
211
212 if (hapVerifyRes.empty()) {
213 APP_LOGE("no sign info in the all haps!");
214 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
215 }
216
217 if (!CheckProvisionInfoIsValid(hapVerifyRes)) {
218 #ifndef X86_EMULATOR_MODE
219 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
220 #else
221 // on emulator if check signature failed clear appid
222 for (auto &verifyRes : hapVerifyRes) {
223 Security::Verify::ProvisionInfo provisionInfo = verifyRes.GetProvisionInfo();
224 provisionInfo.appId = Constants::EMPTY_STRING;
225 verifyRes.SetProvisionInfo(provisionInfo);
226 }
227 #endif
228 }
229 APP_LOGD("finish check multiple haps signInfo");
230 return ERR_OK;
231 }
232
CheckProvisionInfoIsValid(const std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes)233 bool BundleInstallChecker::CheckProvisionInfoIsValid(
234 const std::vector<Security::Verify::HapVerifyResult> &hapVerifyRes)
235 {
236 auto appId = hapVerifyRes[0].GetProvisionInfo().appId;
237 auto appIdentifier = hapVerifyRes[0].GetProvisionInfo().bundleInfo.appIdentifier;
238 auto apl = hapVerifyRes[0].GetProvisionInfo().bundleInfo.apl;
239 auto appDistributionType = hapVerifyRes[0].GetProvisionInfo().distributionType;
240 auto appProvisionType = hapVerifyRes[0].GetProvisionInfo().type;
241 bool isInvalid = std::any_of(hapVerifyRes.begin(), hapVerifyRes.end(),
242 [appId, apl, appDistributionType, appProvisionType, appIdentifier](const auto &hapVerifyResult) {
243 if (appId != hapVerifyResult.GetProvisionInfo().appId) {
244 APP_LOGE("error: hap files have different appId");
245 return true;
246 }
247 if (apl != hapVerifyResult.GetProvisionInfo().bundleInfo.apl) {
248 APP_LOGE("error: hap files have different apl");
249 return true;
250 }
251 if (appDistributionType != hapVerifyResult.GetProvisionInfo().distributionType) {
252 APP_LOGE("error: hap files have different appDistributionType");
253 return true;
254 }
255 if (appProvisionType != hapVerifyResult.GetProvisionInfo().type) {
256 APP_LOGE("error: hap files have different appProvisionType");
257 return true;
258 }
259 if (appIdentifier != hapVerifyResult.GetProvisionInfo().bundleInfo.appIdentifier) {
260 APP_LOGE("error: hap files have different appIdentifier");
261 return true;
262 }
263 return false;
264 });
265 return !isInvalid;
266 }
267
VaildInstallPermission(const InstallParam & installParam,const std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes)268 bool BundleInstallChecker::VaildInstallPermission(const InstallParam &installParam,
269 const std::vector<Security::Verify::HapVerifyResult> &hapVerifyRes)
270 {
271 PermissionStatus installBundleStatus = installParam.installBundlePermissionStatus;
272 PermissionStatus installEnterpriseBundleStatus = installParam.installEnterpriseBundlePermissionStatus;
273 PermissionStatus installEtpMdmBundleStatus = installParam.installEtpMdmBundlePermissionStatus;
274 bool isCallByShell = installParam.isCallByShell;
275 if (!isCallByShell && installBundleStatus == PermissionStatus::HAVE_PERMISSION_STATUS &&
276 installEnterpriseBundleStatus == PermissionStatus::HAVE_PERMISSION_STATUS &&
277 installEtpMdmBundleStatus == PermissionStatus::HAVE_PERMISSION_STATUS) {
278 return true;
279 }
280 for (uint32_t i = 0; i < hapVerifyRes.size(); ++i) {
281 Security::Verify::ProvisionInfo provisionInfo = hapVerifyRes[i].GetProvisionInfo();
282 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE) {
283 if (isCallByShell && provisionInfo.type != Security::Verify::ProvisionType::DEBUG) {
284 APP_LOGE("enterprise bundle can not be installed by shell");
285 return false;
286 }
287 if (!isCallByShell && installEnterpriseBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS) {
288 APP_LOGE("install enterprise bundle permission denied");
289 return false;
290 }
291 continue;
292 }
293 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL ||
294 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM) {
295 bool result = VaildEnterpriseInstallPermission(installParam, provisionInfo);
296 if (!result) {
297 return false;
298 }
299 continue;
300 }
301 if (installBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS) {
302 APP_LOGE("install permission denied");
303 return false;
304 }
305 }
306 return true;
307 }
308
VaildEnterpriseInstallPermission(const InstallParam & installParam,const Security::Verify::ProvisionInfo & provisionInfo)309 bool BundleInstallChecker::VaildEnterpriseInstallPermission(const InstallParam &installParam,
310 const Security::Verify::ProvisionInfo &provisionInfo)
311 {
312 if (installParam.isSelfUpdate) {
313 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM) {
314 APP_LOGI("Mdm self update");
315 return true;
316 }
317 APP_LOGE("Self update not MDM");
318 return false;
319 }
320 bool isCallByShell = installParam.isCallByShell;
321 PermissionStatus installEtpNormalBundleStatus = installParam.installEtpNormalBundlePermissionStatus;
322 PermissionStatus installEtpMdmBundleStatus = installParam.installEtpMdmBundlePermissionStatus;
323 if (isCallByShell && provisionInfo.type != Security::Verify::ProvisionType::DEBUG) {
324 APP_LOGE("enterprise normal/mdm bundle can not be installed by shell");
325 return false;
326 }
327 if (!isCallByShell &&
328 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL &&
329 installEtpNormalBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS &&
330 installEtpMdmBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS) {
331 APP_LOGE("install enterprise normal bundle permission denied");
332 return false;
333 }
334 if (!isCallByShell &&
335 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM &&
336 installEtpMdmBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS) {
337 APP_LOGE("install enterprise mdm bundle permission denied");
338 return false;
339 }
340 return true;
341 }
342
ParseHapFiles(const std::vector<std::string> & bundlePaths,const InstallCheckParam & checkParam,std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes,std::unordered_map<std::string,InnerBundleInfo> & infos)343 ErrCode BundleInstallChecker::ParseHapFiles(
344 const std::vector<std::string> &bundlePaths,
345 const InstallCheckParam &checkParam,
346 std::vector<Security::Verify::HapVerifyResult> &hapVerifyRes,
347 std::unordered_map<std::string, InnerBundleInfo> &infos)
348 {
349 APP_LOGD("Parse hap file");
350 ErrCode result = ERR_OK;
351 for (uint32_t i = 0; i < bundlePaths.size(); ++i) {
352 InnerBundleInfo newInfo;
353 BundlePackInfo packInfo;
354 Security::Verify::ProvisionInfo provisionInfo = hapVerifyRes[i].GetProvisionInfo();
355 bool isSystemApp = provisionInfo.bundleInfo.appFeature == Constants::HOS_SYSTEM_APP;
356 if (isSystemApp) {
357 newInfo.SetAppType(Constants::AppType::SYSTEM_APP);
358 } else {
359 newInfo.SetAppType(Constants::AppType::THIRD_PARTY_APP);
360 }
361
362 newInfo.SetIsPreInstallApp(checkParam.isPreInstallApp);
363 result = ParseBundleInfo(bundlePaths[i], newInfo, packInfo);
364 if (result != ERR_OK) {
365 APP_LOGE("bundle parse failed %{public}d", result);
366 return result;
367 }
368 #ifndef X86_EMULATOR_MODE
369 result = CheckBundleName(provisionInfo.bundleInfo.bundleName, newInfo.GetBundleName());
370 if (result != ERR_OK) {
371 APP_LOGE("check provision bundleName failed");
372 return result;
373 }
374 #endif
375 if (newInfo.HasEntry()) {
376 if (isContainEntry_) {
377 APP_LOGE("more than one entry hap in the direction!");
378 return ERR_APPEXECFWK_INSTALL_INVALID_NUMBER_OF_ENTRY_HAP;
379 }
380 isContainEntry_ = true;
381 }
382
383 SetEntryInstallationFree(packInfo, newInfo);
384 result = CheckMainElement(newInfo);
385 if (result != ERR_OK) {
386 return result;
387 }
388 AppPrivilegeCapability appPrivilegeCapability;
389 // from provision file
390 ParseAppPrivilegeCapability(provisionInfo, appPrivilegeCapability);
391 // form install_list_capability.json, higher priority than provision file
392 FetchPrivilegeCapabilityFromPreConfig(
393 newInfo.GetBundleName(), provisionInfo.fingerprint, appPrivilegeCapability);
394 // modify fingerprint to appId
395 newInfo.SetProvisionId(provisionInfo.appId);
396 FetchPrivilegeCapabilityFromPreConfig(
397 newInfo.GetBundleName(), newInfo.GetAppId(), appPrivilegeCapability);
398 // allow appIdentifier
399 FetchPrivilegeCapabilityFromPreConfig(
400 newInfo.GetBundleName(), provisionInfo.bundleInfo.appIdentifier, appPrivilegeCapability);
401 // process bundleInfo by appPrivilegeCapability
402 result = ProcessBundleInfoByPrivilegeCapability(appPrivilegeCapability, newInfo);
403 if (result != ERR_OK) {
404 return result;
405 }
406 CollectProvisionInfo(provisionInfo, appPrivilegeCapability, newInfo);
407 #ifdef USE_PRE_BUNDLE_PROFILE
408 GetPrivilegeCapability(checkParam, newInfo);
409 #endif
410 if (provisionInfo.distributionType == Security::Verify::AppDistType::CROWDTESTING) {
411 newInfo.SetAppCrowdtestDeadline(checkParam.crowdtestDeadline);
412 } else {
413 newInfo.SetAppCrowdtestDeadline(Constants::INVALID_CROWDTEST_DEADLINE);
414 }
415 if ((result = CheckSystemSize(bundlePaths[i], checkParam.appType)) != ERR_OK) {
416 APP_LOGE("install failed due to insufficient disk memory");
417 return result;
418 }
419
420 infos.emplace(bundlePaths[i], newInfo);
421 }
422 if ((result = CheckModuleNameForMulitHaps(infos)) != ERR_OK) {
423 APP_LOGE("install failed due to duplicated moduleName");
424 return result;
425 }
426 APP_LOGD("finish parse hap file");
427 return result;
428 }
429
CheckHspInstallCondition(std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes)430 ErrCode BundleInstallChecker::CheckHspInstallCondition(
431 std::vector<Security::Verify::HapVerifyResult> &hapVerifyRes)
432 {
433 ErrCode result = ERR_OK;
434 if ((result = CheckDeveloperMode(hapVerifyRes)) != ERR_OK) {
435 APP_LOGE("install failed due to debug mode");
436 return result;
437 }
438 if ((result = CheckAllowEnterpriseBundle(hapVerifyRes)) != ERR_OK) {
439 APP_LOGE("install failed due to non-enterprise device");
440 return result;
441 }
442 return ERR_OK;
443 }
444
CheckInstallPermission(const InstallCheckParam & checkParam,const std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes)445 ErrCode BundleInstallChecker::CheckInstallPermission(const InstallCheckParam &checkParam,
446 const std::vector<Security::Verify::HapVerifyResult> &hapVerifyRes)
447 {
448 if ((checkParam.installBundlePermissionStatus != PermissionStatus::NOT_VERIFIED_PERMISSION_STATUS ||
449 checkParam.installEnterpriseBundlePermissionStatus != PermissionStatus::NOT_VERIFIED_PERMISSION_STATUS ||
450 checkParam.installEtpNormalBundlePermissionStatus != PermissionStatus::NOT_VERIFIED_PERMISSION_STATUS ||
451 checkParam.installEtpMdmBundlePermissionStatus != PermissionStatus::NOT_VERIFIED_PERMISSION_STATUS) &&
452 !VaildInstallPermissionForShare(checkParam, hapVerifyRes)) {
453 // need vaild permission
454 APP_LOGE("install permission denied");
455 return ERR_APPEXECFWK_INSTALL_PERMISSION_DENIED;
456 }
457 return ERR_OK;
458 }
459
VaildInstallPermissionForShare(const InstallCheckParam & checkParam,const std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes)460 bool BundleInstallChecker::VaildInstallPermissionForShare(const InstallCheckParam &checkParam,
461 const std::vector<Security::Verify::HapVerifyResult> &hapVerifyRes)
462 {
463 PermissionStatus installBundleStatus = checkParam.installBundlePermissionStatus;
464 PermissionStatus installEnterpriseBundleStatus = checkParam.installEnterpriseBundlePermissionStatus;
465 PermissionStatus installEtpMdmBundleStatus = checkParam.installEtpMdmBundlePermissionStatus;
466 bool isCallByShell = checkParam.isCallByShell;
467 if (!isCallByShell && installBundleStatus == PermissionStatus::HAVE_PERMISSION_STATUS &&
468 installEnterpriseBundleStatus == PermissionStatus::HAVE_PERMISSION_STATUS &&
469 installEtpMdmBundleStatus == PermissionStatus::HAVE_PERMISSION_STATUS) {
470 return true;
471 }
472 for (uint32_t i = 0; i < hapVerifyRes.size(); ++i) {
473 Security::Verify::ProvisionInfo provisionInfo = hapVerifyRes[i].GetProvisionInfo();
474 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE) {
475 if (isCallByShell && provisionInfo.type != Security::Verify::ProvisionType::DEBUG) {
476 APP_LOGE("enterprise bundle can not be installed by shell");
477 return false;
478 }
479 if (!isCallByShell && installEnterpriseBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS) {
480 APP_LOGE("install enterprise bundle permission denied");
481 return false;
482 }
483 continue;
484 }
485 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL ||
486 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM) {
487 bool result = VaildEnterpriseInstallPermissionForShare(checkParam, provisionInfo);
488 if (!result) {
489 return false;
490 }
491 continue;
492 }
493 if (installBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS) {
494 APP_LOGE("install permission denied");
495 return false;
496 }
497 }
498 return true;
499 }
500
VaildEnterpriseInstallPermissionForShare(const InstallCheckParam & checkParam,const Security::Verify::ProvisionInfo & provisionInfo)501 bool BundleInstallChecker::VaildEnterpriseInstallPermissionForShare(const InstallCheckParam &checkParam,
502 const Security::Verify::ProvisionInfo &provisionInfo)
503 {
504 bool isCallByShell = checkParam.isCallByShell;
505 PermissionStatus installEtpNormalBundleStatus = checkParam.installEtpNormalBundlePermissionStatus;
506 PermissionStatus installEtpMdmBundleStatus = checkParam.installEtpMdmBundlePermissionStatus;
507 if (isCallByShell && provisionInfo.type != Security::Verify::ProvisionType::DEBUG) {
508 APP_LOGE("enterprise normal/mdm bundle can not be installed by shell");
509 return false;
510 }
511 if (!isCallByShell &&
512 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL &&
513 installEtpNormalBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS &&
514 installEtpMdmBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS) {
515 APP_LOGE("install enterprise normal bundle permission denied");
516 return false;
517 }
518 if (!isCallByShell &&
519 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM &&
520 installEtpMdmBundleStatus != PermissionStatus::HAVE_PERMISSION_STATUS) {
521 APP_LOGE("install enterprise mdm bundle permission denied");
522 return false;
523 }
524 return true;
525 }
526
CheckDependency(std::unordered_map<std::string,InnerBundleInfo> & infos)527 ErrCode BundleInstallChecker::CheckDependency(std::unordered_map<std::string, InnerBundleInfo> &infos)
528 {
529 APP_LOGD("CheckDependency");
530
531 for (const auto &info : infos) {
532 if (info.second.GetInnerModuleInfos().empty()) {
533 continue;
534 }
535 // There is only one innerModuleInfo when installing
536 InnerModuleInfo moduleInfo = info.second.GetInnerModuleInfos().begin()->second;
537 APP_LOGD("current module:%s, dependencies = %s", moduleInfo.moduleName.c_str(),
538 GetJsonStrFromInfo(moduleInfo.dependencies).c_str());
539 bool isModuleExist = false;
540 for (const auto &dependency : moduleInfo.dependencies) {
541 if (!NeedCheckDependency(dependency, info.second)) {
542 APP_LOGD("deliveryWithInstall is false, do not check whether the dependency exists.");
543 continue;
544 }
545
546 std::string bundleName =
547 dependency.bundleName.empty() ? info.second.GetBundleName() : dependency.bundleName;
548 isModuleExist = FindModuleInInstallingPackage(dependency.moduleName, bundleName, infos);
549 if (!isModuleExist) {
550 APP_LOGW("The depend module:%{public}s is not exist in installing package.",
551 dependency.moduleName.c_str());
552 isModuleExist = FindModuleInInstalledPackage(dependency.moduleName, bundleName,
553 info.second.GetVersionCode());
554 if (!isModuleExist) {
555 APP_LOGE("The depend module:%{public}s is not exist.", dependency.moduleName.c_str());
556 return ERR_APPEXECFWK_INSTALL_DEPENDENT_MODULE_NOT_EXIST;
557 }
558 }
559 }
560 }
561
562 return ERR_OK;
563 }
564
NeedCheckDependency(const Dependency & dependency,const InnerBundleInfo & info)565 bool BundleInstallChecker::NeedCheckDependency(const Dependency &dependency, const InnerBundleInfo &info)
566 {
567 APP_LOGD("NeedCheckDependency the moduleName is %{public}s, the bundleName is %{public}s.",
568 dependency.moduleName.c_str(), dependency.bundleName.c_str());
569
570 if (!dependency.bundleName.empty() && dependency.bundleName != info.GetBundleName()) {
571 APP_LOGD("Cross-app dependencies, check dependency with shared bundle installer.");
572 return false;
573 }
574 std::vector<PackageModule> modules = info.GetBundlePackInfo().summary.modules;
575 if (modules.empty()) {
576 APP_LOGD("NeedCheckDependency modules is empty, need check dependency.");
577 return true;
578 }
579 for (const auto &module : modules) {
580 if (module.distro.moduleName == dependency.moduleName) {
581 return module.distro.deliveryWithInstall;
582 }
583 }
584
585 APP_LOGD("NeedCheckDependency the module not found, need check dependency.");
586 return true;
587 }
588
FindModuleInInstallingPackage(const std::string & moduleName,const std::string & bundleName,const std::unordered_map<std::string,InnerBundleInfo> & infos)589 bool BundleInstallChecker::FindModuleInInstallingPackage(
590 const std::string &moduleName,
591 const std::string &bundleName,
592 const std::unordered_map<std::string, InnerBundleInfo> &infos)
593 {
594 APP_LOGD("FindModuleInInstallingPackage the moduleName is %{public}s, the bundleName is %{public}s.",
595 moduleName.c_str(), bundleName.c_str());
596 for (const auto &info : infos) {
597 if (info.second.GetBundleName() == bundleName) {
598 if (info.second.GetInnerModuleInfos().empty()) {
599 continue;
600 }
601 // There is only one innerModuleInfo when installing
602 InnerModuleInfo moduleInfo = info.second.GetInnerModuleInfos().begin()->second;
603 if (moduleInfo.moduleName == moduleName) {
604 return true;
605 }
606 }
607 }
608 return false;
609 }
610
FindModuleInInstalledPackage(const std::string & moduleName,const std::string & bundleName,uint32_t versionCode)611 bool BundleInstallChecker::FindModuleInInstalledPackage(
612 const std::string &moduleName,
613 const std::string &bundleName,
614 uint32_t versionCode)
615 {
616 APP_LOGD("FindModuleInInstalledPackage the moduleName is %{public}s, the bundleName is %{public}s",
617 moduleName.c_str(), bundleName.c_str());
618 std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
619 if (dataMgr == nullptr) {
620 APP_LOGE("Get dataMgr shared_ptr nullptr");
621 return false;
622 }
623
624 ScopeGuard enableGuard([&dataMgr, &bundleName] { dataMgr->EnableBundle(bundleName); });
625 InnerBundleInfo bundleInfo;
626 bool isBundleExist = dataMgr->GetInnerBundleInfo(bundleName, bundleInfo);
627 if (!isBundleExist) {
628 APP_LOGE("the bundle: %{public}s is not install", bundleName.c_str());
629 return false;
630 }
631 if (!bundleInfo.FindModule(moduleName)) {
632 APP_LOGE("the module: %{public}s is not install", moduleName.c_str());
633 return false;
634 }
635 if (bundleInfo.GetVersionCode() != versionCode) {
636 APP_LOGE("the versionCode %{public}d of dependency is not consistent with the installed module",
637 bundleInfo.GetVersionCode());
638 return false;
639 }
640 return true;
641 }
642
CheckBundleName(const std::string & provisionBundleName,const std::string & bundleName)643 ErrCode BundleInstallChecker::CheckBundleName(const std::string &provisionBundleName, const std::string &bundleName)
644 {
645 APP_LOGD("CheckBundleName provisionBundleName:%{public}s, bundleName:%{public}s",
646 provisionBundleName.c_str(), bundleName.c_str());
647 if (provisionBundleName.empty() || bundleName.empty()) {
648 APP_LOGE("CheckBundleName provisionBundleName:%{public}s, bundleName:%{public}s failed",
649 provisionBundleName.c_str(), bundleName.c_str());
650 return ERR_APPEXECFWK_INSTALL_FAILED_BUNDLE_SIGNATURE_VERIFICATION_FAILURE;
651 }
652 if (provisionBundleName == bundleName) {
653 return ERR_OK;
654 }
655 APP_LOGE("CheckBundleName failed provisionBundleName:%{public}s, bundleName:%{public}s",
656 provisionBundleName.c_str(), bundleName.c_str());
657 return ERR_APPEXECFWK_INSTALL_FAILED_BUNDLE_SIGNATURE_VERIFICATION_FAILURE;
658 }
659
CollectProvisionInfo(const Security::Verify::ProvisionInfo & provisionInfo,const AppPrivilegeCapability & appPrivilegeCapability,InnerBundleInfo & newInfo)660 void BundleInstallChecker::CollectProvisionInfo(
661 const Security::Verify::ProvisionInfo &provisionInfo,
662 const AppPrivilegeCapability &appPrivilegeCapability,
663 InnerBundleInfo &newInfo)
664 {
665 newInfo.SetProvisionId(provisionInfo.appId);
666 newInfo.SetAppFeature(provisionInfo.bundleInfo.appFeature);
667 newInfo.SetAppPrivilegeLevel(provisionInfo.bundleInfo.apl);
668 newInfo.SetAllowedAcls(provisionInfo.acls.allowedAcls);
669 newInfo.SetCertificateFingerprint(provisionInfo.fingerprint);
670 newInfo.SetAppDistributionType(GetAppDistributionType(provisionInfo.distributionType));
671 newInfo.SetAppProvisionType(GetAppProvisionType(provisionInfo.type));
672 SetAppProvisionMetadata(provisionInfo.metadatas, newInfo);
673 #ifdef USE_PRE_BUNDLE_PROFILE
674 newInfo.SetUserDataClearable(appPrivilegeCapability.userDataClearable);
675 newInfo.SetHideDesktopIcon(appPrivilegeCapability.hideDesktopIcon);
676 newInfo.SetFormVisibleNotify(appPrivilegeCapability.formVisibleNotify);
677 #endif
678 newInfo.AddOldAppId(newInfo.GetAppId());
679 newInfo.SetAppIdentifier(provisionInfo.bundleInfo.appIdentifier);
680 }
681
SetAppProvisionMetadata(const std::vector<Security::Verify::Metadata> & provisionMetadatas,InnerBundleInfo & newInfo)682 void BundleInstallChecker::SetAppProvisionMetadata(const std::vector<Security::Verify::Metadata> &provisionMetadatas,
683 InnerBundleInfo &newInfo)
684 {
685 if (provisionMetadatas.empty()) {
686 return;
687 }
688 std::vector<Metadata> metadatas;
689 for (const auto &it : provisionMetadatas) {
690 Metadata metadata;
691 metadata.name = it.name;
692 metadata.value = it.value;
693 metadatas.emplace_back(metadata);
694 }
695 newInfo.SetAppProvisionMetadata(metadatas);
696 }
697
GetPrivilegeCapability(const InstallCheckParam & checkParam,InnerBundleInfo & newInfo)698 void BundleInstallChecker::GetPrivilegeCapability(
699 const InstallCheckParam &checkParam, InnerBundleInfo &newInfo)
700 {
701 // Reset privilege capability
702 newInfo.SetKeepAlive(false);
703 newInfo.SetSingleton(false);
704
705 newInfo.SetRemovable(checkParam.removable);
706 PreBundleConfigInfo preBundleConfigInfo;
707 preBundleConfigInfo.bundleName = newInfo.GetBundleName();
708 if (!BMSEventHandler::GetPreInstallCapability(preBundleConfigInfo)) {
709 APP_LOGD("bundleName: %{public}s not exist in pre install capability list", newInfo.GetBundleName().c_str());
710 return;
711 }
712
713 if (!MatchSignature(preBundleConfigInfo.appSignature, newInfo.GetCertificateFingerprint()) &&
714 !MatchSignature(preBundleConfigInfo.appSignature, newInfo.GetAppId()) &&
715 !MatchSignature(preBundleConfigInfo.appSignature, newInfo.GetAppIdentifier()) &&
716 !MatchOldSignatures(newInfo.GetBundleName(), preBundleConfigInfo.appSignature)) {
717 APP_LOGE("bundleName:%{public}s signature not match the capability list", newInfo.GetBundleName().c_str());
718 return;
719 }
720
721 newInfo.SetKeepAlive(preBundleConfigInfo.keepAlive);
722 newInfo.SetSingleton(preBundleConfigInfo.singleton);
723 newInfo.SetRunningResourcesApply(preBundleConfigInfo.runningResourcesApply);
724 newInfo.SetAssociatedWakeUp(preBundleConfigInfo.associatedWakeUp);
725 newInfo.SetAllowCommonEvent(preBundleConfigInfo.allowCommonEvent);
726 newInfo.SetResourcesApply(preBundleConfigInfo.resourcesApply);
727 }
728
SetPackInstallationFree(BundlePackInfo & bundlePackInfo,const InnerBundleInfo & innerBundleInfo) const729 void BundleInstallChecker::SetPackInstallationFree(BundlePackInfo &bundlePackInfo,
730 const InnerBundleInfo &innerBundleInfo) const
731 {
732 if (innerBundleInfo.GetIsNewVersion()) {
733 if (innerBundleInfo.GetApplicationBundleType() != BundleType::ATOMIC_SERVICE) {
734 for (auto &item : bundlePackInfo.summary.modules) {
735 item.distro.installationFree = false;
736 }
737 return;
738 }
739 for (auto &item : bundlePackInfo.summary.modules) {
740 item.distro.installationFree = true;
741 }
742 }
743 }
744
ParseBundleInfo(const std::string & bundleFilePath,InnerBundleInfo & info,BundlePackInfo & packInfo) const745 ErrCode BundleInstallChecker::ParseBundleInfo(
746 const std::string &bundleFilePath,
747 InnerBundleInfo &info,
748 BundlePackInfo &packInfo) const
749 {
750 BundleParser bundleParser;
751 ErrCode result = bundleParser.Parse(bundleFilePath, info);
752 if (result != ERR_OK) {
753 APP_LOGE("parse bundle info failed, error: %{public}d", result);
754 return result;
755 }
756
757 const auto extensions = info.GetInnerExtensionInfos();
758 for (const auto &item : extensions) {
759 if (item.second.type == ExtensionAbilityType::UNSPECIFIED &&
760 !BMSEventHandler::CheckExtensionTypeInConfig(item.second.extensionTypeName)) {
761 APP_LOGE("Parse error, There is no corresponding type in the configuration");
762 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR;
763 }
764 }
765
766 if (!packInfo.GetValid()) {
767 result = bundleParser.ParsePackInfo(bundleFilePath, packInfo);
768 if (result != ERR_OK) {
769 APP_LOGE("parse bundle pack info failed, error: %{public}d", result);
770 return result;
771 }
772
773 SetPackInstallationFree(packInfo, info);
774 info.SetBundlePackInfo(packInfo);
775 packInfo.SetValid(true);
776 }
777
778 return ERR_OK;
779 }
780
SetEntryInstallationFree(const BundlePackInfo & bundlePackInfo,InnerBundleInfo & innerBundleInfo)781 void BundleInstallChecker::SetEntryInstallationFree(
782 const BundlePackInfo &bundlePackInfo,
783 InnerBundleInfo &innerBundleInfo)
784 {
785 APP_LOGI("SetEntryInstallationFree start");
786 if (!bundlePackInfo.GetValid()) {
787 APP_LOGW("no pack.info in the hap file");
788 return;
789 }
790
791 auto packageModule = bundlePackInfo.summary.modules;
792 auto installationFree = std::any_of(packageModule.begin(), packageModule.end(), [&](const auto &module) {
793 return module.distro.moduleType == "entry" && module.distro.installationFree;
794 });
795 if (installationFree) {
796 APP_LOGI("install or update hm service");
797 }
798 if (innerBundleInfo.GetIsNewVersion()) {
799 installationFree = innerBundleInfo.GetApplicationBundleType() == BundleType::ATOMIC_SERVICE;
800 }
801
802 innerBundleInfo.SetEntryInstallationFree(installationFree);
803 if (installationFree && !innerBundleInfo.GetIsNewVersion()) {
804 innerBundleInfo.SetApplicationBundleType(BundleType::ATOMIC_SERVICE);
805 }
806 APP_LOGI("SetEntryInstallationFree end");
807 }
808
CheckSystemSize(const std::string & bundlePath,const Constants::AppType appType) const809 ErrCode BundleInstallChecker::CheckSystemSize(
810 const std::string &bundlePath,
811 const Constants::AppType appType) const
812 {
813 if ((appType == Constants::AppType::SYSTEM_APP) &&
814 (BundleUtil::CheckSystemSize(bundlePath, APP_INSTALL_PATH))) {
815 return ERR_OK;
816 }
817
818 if ((appType == Constants::AppType::THIRD_SYSTEM_APP) &&
819 (BundleUtil::CheckSystemSize(bundlePath, APP_INSTALL_PATH))) {
820 return ERR_OK;
821 }
822
823 if ((appType == Constants::AppType::THIRD_PARTY_APP) &&
824 (BundleUtil::CheckSystemSize(bundlePath, APP_INSTALL_PATH))) {
825 return ERR_OK;
826 }
827
828 APP_LOGE("install failed due to insufficient disk memory");
829 return ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT;
830 }
831
CheckHapHashParams(std::unordered_map<std::string,InnerBundleInfo> & infos,std::map<std::string,std::string> hashParams)832 ErrCode BundleInstallChecker::CheckHapHashParams(
833 std::unordered_map<std::string, InnerBundleInfo> &infos,
834 std::map<std::string, std::string> hashParams)
835 {
836 if (hashParams.empty()) {
837 APP_LOGD("hashParams is empty");
838 return ERR_OK;
839 }
840
841 std::vector<std::string> hapModuleNames;
842 for (auto &info : infos) {
843 std::vector<std::string> moduleNames;
844 info.second.GetModuleNames(moduleNames);
845 if (moduleNames.empty()) {
846 APP_LOGE("hap(%{public}s) moduleName is empty", info.first.c_str());
847 return ERR_APPEXECFWK_INSTALL_FAILED_MODULE_NAME_EMPTY;
848 }
849
850 if (std::find(hapModuleNames.begin(), hapModuleNames.end(), moduleNames[0]) != hapModuleNames.end()) {
851 APP_LOGE("hap moduleName(%{public}s) duplicate", moduleNames[0].c_str());
852 return ERR_APPEXECFWK_INSTALL_FAILED_MODULE_NAME_DUPLICATE;
853 }
854
855 hapModuleNames.emplace_back(moduleNames[0]);
856 auto hashParamIter = hashParams.find(moduleNames[0]);
857 if (hashParamIter != hashParams.end()) {
858 info.second.SetModuleHashValue(hashParamIter->second);
859 hashParams.erase(hashParamIter);
860 }
861 }
862
863 if (!hashParams.empty()) {
864 APP_LOGE("Some hashParam moduleName is not exist in hap moduleNames");
865 return ERR_APPEXECFWK_INSTALL_FAILED_CHECK_HAP_HASH_PARAM;
866 }
867
868 return ERR_OK;
869 }
870
CheckAppLabelInfo(const std::unordered_map<std::string,InnerBundleInfo> & infos)871 ErrCode BundleInstallChecker::CheckAppLabelInfo(
872 const std::unordered_map<std::string, InnerBundleInfo> &infos)
873 {
874 APP_LOGD("Check APP label");
875 ErrCode ret = ERR_OK;
876 std::string bundleName = (infos.begin()->second).GetBundleName();
877 std::string vendor = (infos.begin()->second).GetVendor();
878 uint32_t versionCode = (infos.begin()->second).GetVersionCode();
879 std::string versionName = (infos.begin()->second).GetVersionName();
880 uint32_t minCompatibleVersionCode = (infos.begin()->second).GetMinCompatibleVersionCode();
881 uint32_t target = (infos.begin()->second).GetTargetVersion();
882 std::string releaseType = (infos.begin()->second).GetReleaseType();
883 uint32_t compatible = (infos.begin()->second).GetCompatibleVersion();
884 bool singleton = (infos.begin()->second).IsSingleton();
885 Constants::AppType appType = (infos.begin()->second).GetAppType();
886 bool isStage = (infos.begin()->second).GetIsNewVersion();
887 const std::string targetBundleName = (infos.begin()->second).GetTargetBundleName();
888 int32_t targetPriority = (infos.begin()->second).GetTargetPriority();
889 BundleType bundleType = (infos.begin()->second).GetApplicationBundleType();
890 bool isHmService = (infos.begin()->second).GetEntryInstallationFree();
891 bool debug = (infos.begin()->second).GetBaseApplicationInfo().debug;
892 bool hasEntry = (infos.begin()->second).HasEntry();
893 bool isSameDebugType = true;
894 bool entryDebug = hasEntry ? debug : false;
895
896 for (const auto &info : infos) {
897 // check bundleName
898 if (bundleName != info.second.GetBundleName()) {
899 return ERR_APPEXECFWK_INSTALL_BUNDLENAME_NOT_SAME;
900 }
901 // check version
902 if (bundleType != BundleType::SHARED) {
903 if (versionCode != info.second.GetVersionCode()) {
904 return ERR_APPEXECFWK_INSTALL_VERSIONCODE_NOT_SAME;
905 }
906 if (versionName != info.second.GetVersionName()) {
907 return ERR_APPEXECFWK_INSTALL_VERSIONNAME_NOT_SAME;
908 }
909 if (minCompatibleVersionCode != info.second.GetMinCompatibleVersionCode()) {
910 return ERR_APPEXECFWK_INSTALL_MINCOMPATIBLE_VERSIONCODE_NOT_SAME;
911 }
912 }
913 // check vendor
914 if (vendor != info.second.GetVendor()) {
915 return ERR_APPEXECFWK_INSTALL_VENDOR_NOT_SAME;
916 }
917 // check release type
918 if (target != info.second.GetTargetVersion()) {
919 return ERR_APPEXECFWK_INSTALL_RELEASETYPE_TARGET_NOT_SAME;
920 }
921 if (compatible != info.second.GetCompatibleVersion()) {
922 return ERR_APPEXECFWK_INSTALL_RELEASETYPE_COMPATIBLE_NOT_SAME;
923 }
924 if (releaseType != info.second.GetReleaseType()) {
925 return ERR_APPEXECFWK_INSTALL_RELEASETYPE_NOT_SAME;
926 }
927 if (singleton != info.second.IsSingleton()) {
928 return ERR_APPEXECFWK_INSTALL_SINGLETON_NOT_SAME;
929 }
930 if (appType != info.second.GetAppType()) {
931 return ERR_APPEXECFWK_INSTALL_APPTYPE_NOT_SAME;
932 }
933 // check model type(FA or stage)
934 if (isStage != info.second.GetIsNewVersion()) {
935 APP_LOGE("must be all FA model or all stage model");
936 return ERR_APPEXECFWK_INSTALL_STATE_ERROR;
937 }
938 if (targetBundleName != info.second.GetTargetBundleName()) {
939 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_NOT_SAME;
940 }
941 if (targetPriority != info.second.GetTargetPriority()) {
942 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_PRIORITY_NOT_SAME;
943 }
944 if (bundleType != info.second.GetApplicationBundleType()) {
945 return ERR_APPEXECFWK_BUNDLE_TYPE_NOT_SAME;
946 }
947 if (isHmService != info.second.GetEntryInstallationFree()) {
948 APP_LOGE("application and hm service are not allowed installed simultaneously.");
949 return ERR_APPEXECFWK_INSTALL_TYPE_ERROR;
950 }
951 if (debug != info.second.GetBaseApplicationInfo().debug) {
952 isSameDebugType = false;
953 }
954 if (!hasEntry) {
955 hasEntry = info.second.HasEntry();
956 entryDebug = info.second.GetBaseApplicationInfo().debug;
957 }
958 }
959
960 if (hasEntry && !entryDebug && (debug || !isSameDebugType)) {
961 return ERR_APPEXECFWK_INSTALL_DEBUG_NOT_SAME;
962 }
963 APP_LOGD("finish check APP label");
964 return ret;
965 }
966
CheckMultiNativeFile(std::unordered_map<std::string,InnerBundleInfo> & infos)967 ErrCode BundleInstallChecker::CheckMultiNativeFile(
968 std::unordered_map<std::string, InnerBundleInfo> &infos)
969 {
970 ErrCode result = CheckMultiNativeSo(infos);
971 if (result != ERR_OK) {
972 APP_LOGE("Check multi nativeSo failed, result: %{public}d", result);
973 return result;
974 }
975
976 result = CheckMultiArkNativeFile(infos);
977 if (result != ERR_OK) {
978 APP_LOGE("Check multi arkNativeFile failed, result: %{public}d", result);
979 return result;
980 }
981
982 return ERR_OK;
983 }
984
CheckMultiArkNativeFile(std::unordered_map<std::string,InnerBundleInfo> & infos)985 ErrCode BundleInstallChecker::CheckMultiArkNativeFile(
986 std::unordered_map<std::string, InnerBundleInfo> &infos)
987 {
988 std::string arkNativeFileAbi = (infos.begin()->second).GetArkNativeFileAbi();
989 for (const auto &info : infos) {
990 if (info.second.GetArkNativeFileAbi().empty()) {
991 continue;
992 }
993 if (arkNativeFileAbi.empty()) {
994 arkNativeFileAbi = info.second.GetArkNativeFileAbi();
995 continue;
996 }
997 if (arkNativeFileAbi != info.second.GetArkNativeFileAbi()) {
998 return ERR_APPEXECFWK_INSTALL_AN_INCOMPATIBLE;
999 }
1000 }
1001
1002 // Ensure the an is consistent in multiple haps
1003 if (!arkNativeFileAbi.empty()) {
1004 for (auto &info : infos) {
1005 info.second.SetArkNativeFileAbi(arkNativeFileAbi);
1006 }
1007 }
1008
1009 return ERR_OK;
1010 }
1011
CheckMultiNativeSo(std::unordered_map<std::string,InnerBundleInfo> & infos)1012 ErrCode BundleInstallChecker::CheckMultiNativeSo(
1013 std::unordered_map<std::string, InnerBundleInfo> &infos)
1014 {
1015 std::string nativeLibraryPath = (infos.begin()->second).GetNativeLibraryPath();
1016 std::string cpuAbi = (infos.begin()->second).GetCpuAbi();
1017 for (const auto &info : infos) {
1018 if (info.second.GetNativeLibraryPath().empty()) {
1019 continue;
1020 }
1021 if (nativeLibraryPath.empty()) {
1022 nativeLibraryPath = info.second.GetNativeLibraryPath();
1023 cpuAbi = info.second.GetCpuAbi();
1024 continue;
1025 }
1026 if (nativeLibraryPath != info.second.GetNativeLibraryPath()
1027 || cpuAbi != info.second.GetCpuAbi()) {
1028 return ERR_APPEXECFWK_INSTALL_SO_INCOMPATIBLE;
1029 }
1030 }
1031
1032 // Ensure the so is consistent in multiple haps
1033 if (!nativeLibraryPath.empty()) {
1034 for (auto &info : infos) {
1035 info.second.SetNativeLibraryPath(nativeLibraryPath);
1036 info.second.SetCpuAbi(cpuAbi);
1037 }
1038 }
1039
1040 return ERR_OK;
1041 }
1042
ResetProperties()1043 void BundleInstallChecker::ResetProperties()
1044 {
1045 isContainEntry_ = false;
1046 }
1047
ParseAppPrivilegeCapability(const Security::Verify::ProvisionInfo & provisionInfo,AppPrivilegeCapability & appPrivilegeCapability)1048 void BundleInstallChecker::ParseAppPrivilegeCapability(
1049 const Security::Verify::ProvisionInfo &provisionInfo,
1050 AppPrivilegeCapability &appPrivilegeCapability)
1051 {
1052 for (const auto &appPrivilege : provisionInfo.appPrivilegeCapabilities) {
1053 auto iter = PRIVILEGE_MAP.find(appPrivilege);
1054 if (iter != PRIVILEGE_MAP.end()) {
1055 iter->second(appPrivilegeCapability);
1056 }
1057 }
1058 if ((provisionInfo.bundleInfo.bundleName != APP_TEST_BUNDLE_NAME) &&
1059 (provisionInfo.bundleInfo.bundleName.find(BUNDLE_NAME_XTS_TEST) != 0)) {
1060 appPrivilegeCapability.allowMultiProcess = false;
1061 appPrivilegeCapability.allowUsePrivilegeExtension = false;
1062 appPrivilegeCapability.formVisibleNotify = false;
1063 }
1064
1065 APP_LOGD("AppPrivilegeCapability %{public}s",
1066 appPrivilegeCapability.ToString().c_str());
1067 #ifndef USE_PRE_BUNDLE_PROFILE
1068 appPrivilegeCapability.allowMultiProcess = true;
1069 appPrivilegeCapability.allowUsePrivilegeExtension = true;
1070 #endif
1071 }
1072
CheckModuleNameForMulitHaps(const std::unordered_map<std::string,InnerBundleInfo> & infos) const1073 ErrCode BundleInstallChecker::CheckModuleNameForMulitHaps(
1074 const std::unordered_map<std::string, InnerBundleInfo> &infos) const
1075 {
1076 std::set<std::string> moduleSet;
1077 for (const auto &info : infos) {
1078 std::vector<std::string> moduleVec = info.second.GetDistroModuleName();
1079 if (moduleVec.empty()) {
1080 APP_LOGE("moduleName vector is empty");
1081 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
1082 }
1083 moduleSet.insert(moduleVec[0]);
1084 }
1085
1086 if (moduleSet.size() != infos.size()) {
1087 APP_LOGE("someone moduleName is not unique in the haps");
1088 return ERR_APPEXECFWK_INSTALL_NOT_UNIQUE_DISTRO_MODULE_NAME;
1089 }
1090 return ERR_OK;
1091 }
1092
IsExistedDistroModule(const InnerBundleInfo & newInfo,const InnerBundleInfo & info) const1093 bool BundleInstallChecker::IsExistedDistroModule(const InnerBundleInfo &newInfo, const InnerBundleInfo &info) const
1094 {
1095 std::string moduleName = newInfo.GetCurModuleName();
1096 std::string packageName = newInfo.GetCurrentModulePackage();
1097 if (packageName.empty() || moduleName.empty()) {
1098 APP_LOGE("IsExistedDistroModule failed due to invalid packageName or moduleName");
1099 return false;
1100 }
1101 std::string oldModuleName = info.GetModuleNameByPackage(packageName);
1102 // if FA update to Stage, allow module name inconsistent
1103 bool isFAToStage = !info.GetIsNewVersion() && newInfo.GetIsNewVersion();
1104 if (!isFAToStage) {
1105 // if not FA update to Stage, check consistency of module name
1106 if (moduleName.compare(oldModuleName) != 0) {
1107 APP_LOGE("no moduleName in the innerModuleInfo");
1108 return false;
1109 }
1110 }
1111 // check consistency of module type
1112 std::string newModuleType = newInfo.GetModuleTypeByPackage(packageName);
1113 std::string oldModuleType = info.GetModuleTypeByPackage(packageName);
1114 if (newModuleType.compare(oldModuleType) != 0) {
1115 APP_LOGE("moduleType is different between the new hap and the original hap");
1116 return false;
1117 }
1118
1119 return true;
1120 }
1121
IsContainModuleName(const InnerBundleInfo & newInfo,const InnerBundleInfo & info) const1122 bool BundleInstallChecker::IsContainModuleName(const InnerBundleInfo &newInfo, const InnerBundleInfo &info) const
1123 {
1124 std::string moduleName = newInfo.GetCurModuleName();
1125 std::vector<std::string> moduleVec = info.GetDistroModuleName();
1126 if (moduleName.empty() || moduleVec.empty()) {
1127 APP_LOGE("IsContainModuleName failed due to invalid moduleName or modulevec");
1128 return false;
1129 }
1130 return (find(moduleVec.cbegin(), moduleVec.cend(), moduleName) == moduleVec.cend()) ? false : true;
1131 }
1132
CheckMainElement(const InnerBundleInfo & info)1133 ErrCode BundleInstallChecker::CheckMainElement(const InnerBundleInfo &info)
1134 {
1135 const std::map<std::string, InnerModuleInfo> &innerModuleInfos = info.GetInnerModuleInfos();
1136 if (innerModuleInfos.empty()) {
1137 return ERR_OK;
1138 }
1139 if (innerModuleInfos.cbegin()->second.distro.moduleType == Profile::MODULE_TYPE_SHARED) {
1140 return ERR_OK;
1141 }
1142 if (info.GetEntryInstallationFree() && innerModuleInfos.cbegin()->second.mainAbility.empty()) {
1143 APP_LOGE("atomic service's mainElement can't be empty.");
1144 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR;
1145 }
1146 return ERR_OK;
1147 }
1148
GetPrivilegeCapabilityValue(const std::vector<std::string> & existInJson,const std::string & key,bool existInPreJson,bool existInProvision)1149 bool BundleInstallChecker::GetPrivilegeCapabilityValue(
1150 const std::vector<std::string> &existInJson,
1151 const std::string &key,
1152 bool existInPreJson,
1153 bool existInProvision)
1154 {
1155 if (find(existInJson.cbegin(), existInJson.cend(), key) != existInJson.cend()) {
1156 return existInPreJson;
1157 }
1158 return existInProvision;
1159 }
1160
FetchPrivilegeCapabilityFromPreConfig(const std::string & bundleName,const std::string & appSignature,AppPrivilegeCapability & appPrivilegeCapability)1161 void BundleInstallChecker::FetchPrivilegeCapabilityFromPreConfig(
1162 const std::string &bundleName,
1163 const std::string &appSignature,
1164 AppPrivilegeCapability &appPrivilegeCapability)
1165 {
1166 #ifdef USE_PRE_BUNDLE_PROFILE
1167 APP_LOGD("bundleName: %{public}s, FetchPrivilegeCapabilityFromPreConfig start", bundleName.c_str());
1168 PreBundleConfigInfo configInfo;
1169 configInfo.bundleName = bundleName;
1170 if (!BMSEventHandler::GetPreInstallCapability(configInfo)) {
1171 APP_LOGD("bundleName: %{public}s is not exist in pre install capability list", bundleName.c_str());
1172 return;
1173 }
1174 if (!MatchSignature(configInfo.appSignature, appSignature)) {
1175 if (!MatchOldSignatures(bundleName, configInfo.appSignature)) {
1176 APP_LOGE("bundleName: %{public}s signature verify failed in capability list", bundleName.c_str());
1177 return;
1178 }
1179 }
1180 appPrivilegeCapability.allowUsePrivilegeExtension = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1181 ALLOW_APP_USE_PRIVILEGE_EXTENSION,
1182 configInfo.allowUsePrivilegeExtension, appPrivilegeCapability.allowUsePrivilegeExtension);
1183
1184 appPrivilegeCapability.allowMultiProcess = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1185 ALLOW_APP_MULTI_PROCESS,
1186 configInfo.allowMultiProcess, appPrivilegeCapability.allowMultiProcess);
1187
1188 appPrivilegeCapability.hideDesktopIcon = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1189 ALLOW_APP_DESKTOP_ICON_HIDE,
1190 configInfo.hideDesktopIcon, appPrivilegeCapability.hideDesktopIcon);
1191
1192 appPrivilegeCapability.allowQueryPriority = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1193 ALLOW_ABILITY_PRIORITY_QUERIED,
1194 configInfo.allowQueryPriority, appPrivilegeCapability.allowQueryPriority);
1195
1196 appPrivilegeCapability.allowExcludeFromMissions = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1197 ALLOW_ABILITY_EXCLUDE_FROM_MISSIONS,
1198 configInfo.allowExcludeFromMissions, appPrivilegeCapability.allowExcludeFromMissions);
1199
1200 appPrivilegeCapability.allowMissionNotCleared = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1201 ALLOW_MISSION_NOT_CLEARED,
1202 configInfo.allowMissionNotCleared, appPrivilegeCapability.allowMissionNotCleared);
1203
1204 appPrivilegeCapability.formVisibleNotify = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1205 ALLOW_FORM_VISIBLE_NOTIFY,
1206 configInfo.formVisibleNotify, appPrivilegeCapability.formVisibleNotify);
1207
1208 appPrivilegeCapability.userDataClearable = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1209 ALLOW_APP_DATA_NOT_CLEARED,
1210 configInfo.userDataClearable, appPrivilegeCapability.userDataClearable);
1211
1212 appPrivilegeCapability.appShareLibrary = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1213 ALLOW_APP_SHARE_LIBRARY,
1214 configInfo.appShareLibrary, appPrivilegeCapability.appShareLibrary);
1215 appPrivilegeCapability.allowEnableNotification = GetPrivilegeCapabilityValue(configInfo.existInJsonFile,
1216 ALLOW_ENABLE_NOTIFICATION,
1217 configInfo.allowEnableNotification, appPrivilegeCapability.allowEnableNotification);
1218 APP_LOGD("AppPrivilegeCapability %{public}s", appPrivilegeCapability.ToString().c_str());
1219 #endif
1220 }
1221
MatchOldSignatures(const std::string & bundleName,const std::vector<std::string> & appSignatures)1222 bool BundleInstallChecker::MatchOldSignatures(const std::string &bundleName,
1223 const std::vector<std::string> &appSignatures)
1224 {
1225 std::vector<std::string> oldAppIds;
1226 std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
1227 if (!dataMgr->GetOldAppIds(bundleName, oldAppIds)) {
1228 APP_LOGE("Get OldAppIds failed.");
1229 return false;
1230 }
1231 for (const auto &signature : appSignatures) {
1232 if (std::find(oldAppIds.begin(), oldAppIds.end(), signature) != oldAppIds.end()) {
1233 return true;
1234 }
1235 }
1236
1237 return false;
1238 }
1239
MatchSignature(const std::vector<std::string> & appSignatures,const std::string & signature)1240 bool BundleInstallChecker::MatchSignature(
1241 const std::vector<std::string> &appSignatures, const std::string &signature)
1242 {
1243 if (appSignatures.empty() || signature.empty()) {
1244 APP_LOGW("appSignature of signature is empty");
1245 return false;
1246 }
1247
1248 return std::find(
1249 appSignatures.begin(), appSignatures.end(), signature) != appSignatures.end();
1250 }
1251
ProcessBundleInfoByPrivilegeCapability(const AppPrivilegeCapability & appPrivilegeCapability,InnerBundleInfo & innerBundleInfo)1252 ErrCode BundleInstallChecker::ProcessBundleInfoByPrivilegeCapability(
1253 const AppPrivilegeCapability &appPrivilegeCapability,
1254 InnerBundleInfo &innerBundleInfo)
1255 {
1256 // process application
1257 ApplicationInfo applicationInfo = innerBundleInfo.GetBaseApplicationInfo();
1258 if (!appPrivilegeCapability.allowMultiProcess || applicationInfo.process.empty()) {
1259 applicationInfo.process = applicationInfo.bundleName;
1260 }
1261 applicationInfo.allowEnableNotification = appPrivilegeCapability.allowEnableNotification;
1262 innerBundleInfo.SetBaseApplicationInfo(applicationInfo);
1263 BundleInfo bundleInfo = innerBundleInfo.GetBaseBundleInfo();
1264 // process allow app share library
1265 if (applicationInfo.bundleType == BundleType::SHARED && !appPrivilegeCapability.appShareLibrary) {
1266 APP_LOGE("not allow app share library");
1267 return ERR_APPEXECFWK_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED;
1268 }
1269 // process ability
1270 auto &abilityInfos = innerBundleInfo.FetchAbilityInfos();
1271 for (auto iter = abilityInfos.begin(); iter != abilityInfos.end(); ++iter) {
1272 #ifdef USE_PRE_BUNDLE_PROFILE
1273 if (!appPrivilegeCapability.allowQueryPriority) {
1274 iter->second.priority = 0;
1275 }
1276 if (!appPrivilegeCapability.allowExcludeFromMissions) {
1277 iter->second.excludeFromMissions = false;
1278 }
1279 if (!appPrivilegeCapability.allowMissionNotCleared) {
1280 iter->second.unclearableMission = false;
1281 }
1282 #else
1283 if (!applicationInfo.isSystemApp || !bundleInfo.isPreInstallApp) {
1284 iter->second.priority = 0;
1285 iter->second.excludeFromMissions = false;
1286 }
1287 #endif
1288 }
1289 // process ExtensionAbility
1290 auto &extensionAbilityInfos = innerBundleInfo.FetchInnerExtensionInfos();
1291 for (auto iter = extensionAbilityInfos.begin(); iter != extensionAbilityInfos.end(); ++iter) {
1292 bool privilegeType = IsPrivilegeExtensionAbilityType(iter->second.type);
1293 if (privilegeType && !appPrivilegeCapability.allowUsePrivilegeExtension) {
1294 APP_LOGE("not allow use privilege extension");
1295 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR;
1296 }
1297
1298 bool systemType = IsSystemExtensionAbilityType(iter->second.type);
1299 if (systemType && !applicationInfo.isSystemApp) {
1300 APP_LOGE("not allow use system extension");
1301 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR;
1302 }
1303
1304 #ifdef USE_PRE_BUNDLE_PROFILE
1305 if (!appPrivilegeCapability.allowQueryPriority) {
1306 iter->second.priority = 0;
1307 }
1308 #else
1309 if (!applicationInfo.isSystemApp || !bundleInfo.isPreInstallApp) {
1310 iter->second.priority = 0;
1311 }
1312 #endif
1313 if (appPrivilegeCapability.allowMultiProcess) {
1314 APP_LOGD("bundleName: %{public}s support allowMultiProcess", iter->second.bundleName.c_str());
1315 auto hapModuleInfo = innerBundleInfo.GetInnerModuleInfoByModuleName(iter->second.moduleName);
1316 if (hapModuleInfo && !hapModuleInfo->process.empty()) {
1317 iter->second.process = hapModuleInfo->process;
1318 }
1319 }
1320 }
1321 // process InnerModuleInfo
1322 auto &innerModuleInfos = innerBundleInfo.FetchInnerModuleInfos();
1323 for (auto iter = innerModuleInfos.begin(); iter != innerModuleInfos.end(); ++iter) {
1324 if (iter->second.isModuleJson && (!appPrivilegeCapability.allowMultiProcess || iter->second.process.empty())) {
1325 iter->second.process = applicationInfo.bundleName;
1326 }
1327 }
1328 return ERR_OK;
1329 }
1330
CheckDeviceType(std::unordered_map<std::string,InnerBundleInfo> & infos) const1331 ErrCode BundleInstallChecker::CheckDeviceType(std::unordered_map<std::string, InnerBundleInfo> &infos) const
1332 {
1333 std::string deviceType = GetDeviceType();
1334 APP_LOGD("deviceType is %{public}s", deviceType.c_str());
1335 for (const auto &info : infos) {
1336 std::vector<std::string> devVec = info.second.GetDeviceType(info.second.GetCurrentModulePackage());
1337 if (devVec.empty()) {
1338 APP_LOGW("deviceTypes is empty");
1339 continue;
1340 }
1341
1342 if ((deviceType == DEVICE_TYPE_OF_PHONE) &&
1343 (find(devVec.begin(), devVec.end(), DEVICE_TYPE_OF_DEFAULT) != devVec.end())) {
1344 APP_LOGW("current deviceType is phone and bundle is matched with default");
1345 continue;
1346 }
1347
1348 if ((deviceType == DEVICE_TYPE_OF_DEFAULT) &&
1349 (find(devVec.begin(), devVec.end(), DEVICE_TYPE_OF_PHONE) != devVec.end())) {
1350 APP_LOGW("current deviceType is default and bundle is matched with phone");
1351 continue;
1352 }
1353
1354 if (find(devVec.begin(), devVec.end(), deviceType) == devVec.end()) {
1355 APP_LOGE("%{public}s is not supported", deviceType.c_str());
1356 return ERR_APPEXECFWK_INSTALL_DEVICE_TYPE_NOT_SUPPORTED;
1357 }
1358 }
1359 return ERR_OK;
1360 }
1361
ConvertToAppProvisionInfo(const Security::Verify::ProvisionInfo & provisionInfo) const1362 AppProvisionInfo BundleInstallChecker::ConvertToAppProvisionInfo(
1363 const Security::Verify::ProvisionInfo &provisionInfo) const
1364 {
1365 AppProvisionInfo appProvisionInfo;
1366 appProvisionInfo.versionCode = provisionInfo.versionCode;
1367 appProvisionInfo.versionName = provisionInfo.versionName;
1368 if (provisionInfo.type == Security::Verify::ProvisionType::DEBUG) {
1369 appProvisionInfo.type = Constants::APP_PROVISION_TYPE_DEBUG;
1370 appProvisionInfo.certificate = provisionInfo.bundleInfo.developmentCertificate;
1371 } else {
1372 appProvisionInfo.type = Constants::APP_PROVISION_TYPE_RELEASE;
1373 appProvisionInfo.certificate = provisionInfo.bundleInfo.distributionCertificate;
1374 }
1375 appProvisionInfo.appDistributionType = GetAppDistributionType(provisionInfo.distributionType);
1376 appProvisionInfo.apl = provisionInfo.bundleInfo.apl.empty() ? APL_NORMAL : provisionInfo.bundleInfo.apl;
1377 appProvisionInfo.developerId = provisionInfo.bundleInfo.developerId;
1378 appProvisionInfo.issuer = provisionInfo.issuer;
1379 appProvisionInfo.uuid = provisionInfo.uuid;
1380 appProvisionInfo.validity.notBefore = provisionInfo.validity.notBefore;
1381 appProvisionInfo.validity.notAfter = provisionInfo.validity.notAfter;
1382 appProvisionInfo.appIdentifier = provisionInfo.bundleInfo.appIdentifier;
1383 return appProvisionInfo;
1384 }
1385
GetBundleNameFromUri(const std::string & uri)1386 std::string GetBundleNameFromUri(const std::string &uri)
1387 {
1388 std::size_t firstSlashPos = uri.find(DOUBLE_SLASH);
1389 if (firstSlashPos == std::string::npos) {
1390 APP_LOGE("dataproxy uri is invalid");
1391 return Constants::EMPTY_STRING;
1392 }
1393
1394 std::size_t secondSlashPos = uri.find(SLASH, firstSlashPos + SLAH_OFFSET);
1395 if (secondSlashPos == std::string::npos) {
1396 APP_LOGE("dataproxy uri is invalid");
1397 return Constants::EMPTY_STRING;
1398 }
1399
1400 std::string bundleName = uri.substr(firstSlashPos + SLAH_OFFSET, secondSlashPos - firstSlashPos - SLAH_OFFSET);
1401 return bundleName;
1402 }
1403
CheckProxyPermissionLevel(const std::string & permissionName) const1404 bool BundleInstallChecker::CheckProxyPermissionLevel(const std::string &permissionName) const
1405 {
1406 // no permission name, only for self usage
1407 if (permissionName.empty()) {
1408 return true;
1409 }
1410 PermissionDef permissionDef;
1411 ErrCode ret = BundlePermissionMgr::GetPermissionDef(permissionName, permissionDef);
1412 if (ret != ERR_OK) {
1413 APP_LOGE("getPermissionDef failed");
1414 return false;
1415 }
1416 if (permissionDef.availableLevel < Security::AccessToken::ATokenAplEnum::APL_SYSTEM_BASIC) {
1417 APP_LOGE("permission %{public}s level too low", permissionName.c_str());
1418 return false;
1419 }
1420 return true;
1421 }
1422
CheckProxyDatas(const InnerBundleInfo & innerBundleInfo) const1423 ErrCode BundleInstallChecker::CheckProxyDatas(const InnerBundleInfo &innerBundleInfo) const
1424 {
1425 auto bundleName = innerBundleInfo.GetBundleName();
1426 auto moduleInfos = innerBundleInfo.GetInnerModuleInfos();
1427 if (moduleInfos.empty()) {
1428 return ERR_OK;
1429 }
1430 for (const auto &moduleInfo : moduleInfos) {
1431 for (const auto &proxyData : moduleInfo.second.proxyDatas) {
1432 auto name = GetBundleNameFromUri(proxyData.uri);
1433 if (bundleName != name) {
1434 APP_LOGE("bundleName from uri %{public}s different from origin bundleName %{public}s",
1435 name.c_str(), bundleName.c_str());
1436 return ERR_APPEXECFWK_INSTALL_CHECK_PROXY_DATA_URI_FAILED;
1437 }
1438 if (innerBundleInfo.IsSystemApp()) {
1439 continue;
1440 }
1441 if (!CheckProxyPermissionLevel(proxyData.requiredReadPermission)
1442 || !CheckProxyPermissionLevel(proxyData.requiredWritePermission)) {
1443 return ERR_APPEXECFWK_INSTALL_CHECK_PROXY_DATA_PERMISSION_FAILED;
1444 }
1445 }
1446 }
1447 return ERR_OK;
1448 }
1449
CheckSupportIsolation(const char * szIsolationModeThresholdMb,const std::string & isolationMode)1450 bool CheckSupportIsolation(const char *szIsolationModeThresholdMb, const std::string &isolationMode)
1451 {
1452 if ((std::strcmp(szIsolationModeThresholdMb, VALUE_TRUE.c_str()) == 0) ||
1453 (std::strcmp(szIsolationModeThresholdMb, VALUE_TRUE_BOOL.c_str()) == 0)) {
1454 if (isolationMode == NONISOLATION_ONLY) {
1455 APP_LOGE("check isolation mode failed.");
1456 return false;
1457 }
1458 } else {
1459 if (isolationMode == ISOLATION_ONLY) {
1460 APP_LOGE("check isolation mode failed.");
1461 return false;
1462 }
1463 }
1464 return true;
1465 }
1466
CheckIsolationMode(const std::unordered_map<std::string,InnerBundleInfo> & infos) const1467 ErrCode BundleInstallChecker::CheckIsolationMode(const std::unordered_map<std::string, InnerBundleInfo> &infos) const
1468 {
1469 for (const auto &info : infos) {
1470 auto moduleInfos = info.second.GetInnerModuleInfos();
1471 for (const auto &moduleInfo : moduleInfos) {
1472 std::string isolationMode = moduleInfo.second.isolationMode;
1473 char szIsolationModeThresholdMb[THRESHOLD_VAL_LEN] = {0};
1474 int32_t ret = GetParameter(SUPPORT_ISOLATION_MODE.c_str(), "",
1475 szIsolationModeThresholdMb, THRESHOLD_VAL_LEN);
1476 if (ret <= 0) {
1477 APP_LOGW("GetParameter failed");
1478 }
1479 if (!CheckSupportIsolation(szIsolationModeThresholdMb, isolationMode)) {
1480 APP_LOGE("check isolation mode failed.");
1481 return ERR_APPEXECFWK_INSTALL_ISOLATION_MODE_FAILED;
1482 }
1483 }
1484 }
1485 return ERR_OK;
1486 }
1487
CheckSignatureFileDir(const std::string & signatureFileDir) const1488 ErrCode BundleInstallChecker::CheckSignatureFileDir(const std::string &signatureFileDir) const
1489 {
1490 if (!BundleUtil::CheckFileName(signatureFileDir)) {
1491 APP_LOGE("code signature file dir is invalid");
1492 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID;
1493 }
1494 if (!BundleUtil::CheckFileType(signatureFileDir, Constants::CODE_SIGNATURE_FILE_SUFFIX)) {
1495 APP_LOGE("signatureFileDir is not suffixed with .sig");
1496 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID;
1497 }
1498 // signatureFileDir not support relevant dir
1499 if (signatureFileDir.find(Constants::RELATIVE_PATH) != std::string::npos) {
1500 APP_LOGE("signatureFileDir is invalid");
1501 return ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID;
1502 }
1503 return ERR_OK;
1504 }
1505
CheckDeveloperMode(const std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes) const1506 ErrCode BundleInstallChecker::CheckDeveloperMode(
1507 const std::vector<Security::Verify::HapVerifyResult> &hapVerifyRes) const
1508 {
1509 if (system::GetBoolParameter(DEVELOPERMODE_STATE, true)) {
1510 APP_LOGI("check developer mode success");
1511 return ERR_OK;
1512 }
1513 for (uint32_t i = 0; i < hapVerifyRes.size(); ++i) {
1514 Security::Verify::ProvisionInfo provisionInfo = hapVerifyRes[i].GetProvisionInfo();
1515 if (provisionInfo.type == Security::Verify::ProvisionType::DEBUG) {
1516 APP_LOGE("debug bundle can only be installed in developer mode");
1517 return ERR_APPEXECFWK_INSTALL_DEBUG_BUNDLE_NOT_ALLOWED;
1518 }
1519 }
1520 return ERR_OK;
1521 }
1522
CheckAllowEnterpriseBundle(const std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes) const1523 ErrCode BundleInstallChecker::CheckAllowEnterpriseBundle(
1524 const std::vector<Security::Verify::HapVerifyResult> &hapVerifyRes) const
1525 {
1526 if (system::GetBoolParameter(Constants::ALLOW_ENTERPRISE_BUNDLE, false)) {
1527 return ERR_OK;
1528 }
1529 for (uint32_t i = 0; i < hapVerifyRes.size(); ++i) {
1530 Security::Verify::ProvisionInfo provisionInfo = hapVerifyRes[i].GetProvisionInfo();
1531 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL ||
1532 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM) {
1533 APP_LOGE("enterprise normal/mdm bundle cannot be installed on non-enterprise device");
1534 return ERR_APPEXECFWK_INSTALL_ENTERPRISE_BUNDLE_NOT_ALLOWED;
1535 }
1536 }
1537 return ERR_OK;
1538 }
1539
CheckEnterpriseBundle(Security::Verify::HapVerifyResult & hapVerifyRes) const1540 bool BundleInstallChecker::CheckEnterpriseBundle(Security::Verify::HapVerifyResult &hapVerifyRes) const
1541 {
1542 Security::Verify::ProvisionInfo provisionInfo = hapVerifyRes.GetProvisionInfo();
1543 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL ||
1544 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM ||
1545 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE) {
1546 return true;
1547 }
1548 return false;
1549 }
1550 } // namespace AppExecFwk
1551 } // namespace OHOS