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