• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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