diff --git a/adapter/ohos/Compressor.java b/adapter/ohos/Compressor.java index b36f8ea4a0db159903f2c7313e281d2e67166202..f495db111191656f1c8ef4ca636787c0b333ef1a 100644 --- a/adapter/ohos/Compressor.java +++ b/adapter/ohos/Compressor.java @@ -134,6 +134,10 @@ public class Compressor { private static final String MODULE = "module"; private static final String GENERATE_BUILD_HASH = "generateBuildHash"; private static final String BUILD_HASH = "buildHash"; + private static final String TYPE_APP_PLUGIN = "appPlugin"; + private static final String REQUEST_PERMISSIONS = "requestPermissions"; + private static final String PERMISSION_SUPPORT_PLUGIN = "ohos.permission.kernal.SUPPORT_PLUGIN"; + private static final String EXTENSION_ABILITIES = "extensionAbilities"; private static final String TEMP_DIR = "temp"; private static final String SHA_256 = "SHA-256"; private static final String JSON_SUFFIX = ".json"; @@ -474,6 +478,10 @@ public class Compressor { } } compressHSPMode(utility); + if (!isAppPlugin(utility)) { + LOG.error(PackingToolErrMsg.COMPRESS_HSP_FAILED.toString("plugin package packaging failed.")); + throw new BundleException("Compress hsp failed."); + } buildHash(utility); } @@ -500,6 +508,16 @@ public class Compressor { if (TYPE_SHARED.equals(bundleType)) { LOG.warning("Compress mode is hap, but app type is shared."); } + if (!TYPE_APP_PLUGIN.equals(bundleType)) { + if (!checkPermission(utility)) { + if (!checkPkgContext(utility)) { + LOG.error(PackingToolErrMsg.COMPRESS_HSP_FAILED.toString("plugin package packaging failed.")); + throw new BundleException("Compress hsp failed."); + } + } + } else { + return; + } compressHapModeForModule(utility); buildHash(utility); } else { @@ -508,6 +526,103 @@ public class Compressor { } } + private static boolean checkPermission(Utility utility) throws BundleException { + File file = new File(utility.getJsonPath()); + if (!file.exists()) { + String errMsg = "The --json-path file does not exist."; + LOG.error(PackingToolErrMsg.HAS_GENERATE_BUILD_HASH.toString(errMsg)); + throw new BundleException("Verify has generate build hash failed for --json-path file does not exist."); + } + InputStream json = null; + json = new FileInputStream(file); + JSONObject jsonObject = JSON.parseObject(json, JSONObject.class); + if (jsonObject == null || !jsonObject.containsKey(MODULE)) { + LOG.error(PackingToolErrMsg.HAS_GENERATE_BUILD_HASH.toString("The --json-path file is invalid.")); + throw new BundleException("Parse --json-path file is invalid."); + } + JSONObject moduleJson = jsonObject.getJSONObject(MODULE); + if (moduleJson.containsKey(REQUEST_PERMISSIONS)) { + JSONArray requestPermissions = moduleJson.getJSONArray(REQUEST_PERMISSIONS); + for (int i = 0; i < requestPermissions.size(); ++i) { + JSONObject requestPermission = requestPermissions.getJSONObject(i); + if (isRequestPermission(requestPermission)) { + return false; + } + } + return true; + } + return true; + } + + private static boolean isRequestPermission(JSONObject requestPermission) throws BundleException { + if (requestPermission.containsKey(NAME)) { + String reqPermissionName = getJsonString(requestPermission, NAME); + if (reqPermissionName == PERMISSION_SUPPORT_PLUGIN) { + return true; + } + return false; + } + return false; + } + + private static boolean checkPkgContext(Utility utility) throws BundleException { + if (!utility.getPkgContextPath().isEmpty()) { + File file = new File(utility.getPkgContextPath()); + if (!file.isFile() || !PKG_CONTEXT_INFO.equals(file.getName())) { + String errMsg = "--pkg-context-path file must be the pkgContextInfo.json file."; + LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + return true; + } + return false; + } + + private static boolean isAppPlugin(Utility utility) throws BundleException { + File file = new File(utility.getJsonPath()); + if (!file.exists()) { + String errMsg = "The --json-path file does not exist."; + LOG.error(PackingToolErrMsg.HAS_GENERATE_BUILD_HASH.toString(errMsg)); + throw new BundleException("Verify has generate build hash failed for --json-path file does not exist."); + } + InputStream json = null; + json = new FileInputStream(file); + JSONObject jsonObject = JSON.parseObject(json, JSONObject.class); + if (jsonObject == null || !jsonObject.containsKey(MODULE)) { + LOG.error(PackingToolErrMsg.HAS_GENERATE_BUILD_HASH.toString("The --json-path file is invalid.")); + throw new BundleException("Parse --json-path file is invalid."); + } + Optional optional = FileUtils.getFileContent(utility.getJsonPath()); + String jsonString = optional.get(); + String bundleType = ModuleJsonUtil.parseStageBundleType(jsonString); + if (!TYPE_APP_PLUGIN.equals(bundleType)) { + LOG.warning("bundleType not appPlugin"); + if (checkPermission(utility)) { + return true; + } + if (!checkPkgContext(utility)) { + return false; + } + return true; + } + JSONObject moduleJson = jsonObject.getJSONObject(MODULE); + JSONArray extensionAbilityJsonList = moduleJson.getJSONArray(EXTENSION_ABILITIES); + for (int j = 0; j < extensionAbilityJsonList.size(); j++) { + JSONObject extensionAbilityJson = extensionAbilityJsonList.getJSONObject(j); + if (extensionAbilityJson != null) { + LOG.error("extensionAbilities is not null."); + return false; + } + } + if (!checkPkgContext(utility)) { + return false; + } + if (!checkPermission(utility)) { + return false; + } + return true; + } + private static boolean hasGenerateBuildHash(Utility utility) throws BundleException { File file = new File(utility.getJsonPath()); if (!file.exists()) { diff --git a/packing_tool/frameworks/include/constants.h b/packing_tool/frameworks/include/constants.h index 2654eecb13c3a1862ab8d9a8d7e1fd6052efce04..1de895ff8a3c806a90d4199c62e5765a4c5411f9 100644 --- a/packing_tool/frameworks/include/constants.h +++ b/packing_tool/frameworks/include/constants.h @@ -121,6 +121,7 @@ const std::string FILE_PACK_RES = "pack.res"; const std::string INVALID_PATH = "invalid"; const std::string TYPE_SHARED = "shared"; const std::string BUNDLE_TYPE_APP_SERVICE = "appService"; +const std::string TYPE_APP_PLUGIN = "appPlugin"; const std::string TEMP_HAP_DIR = "tempHapDir"; const std::string TEMP_HSP_DIR = "tempHspDir"; const std::string TEMP_SELECTED_HAP_DIR = "tempSelectedHapDir"; diff --git a/packing_tool/frameworks/include/hap_packager.h b/packing_tool/frameworks/include/hap_packager.h index e418ac168600bb3e0f46405fe65dca75d6025973..c1bfb487861b069970dadfd171ae8bc8270996f5 100644 --- a/packing_tool/frameworks/include/hap_packager.h +++ b/packing_tool/frameworks/include/hap_packager.h @@ -50,6 +50,9 @@ public: bool CompressHapModeForModule(const std::string &jsonPath); bool CompressHapMode(); bool CompressHapModeMultiple(); + bool CheckPermission(); + bool IsPermissionAPlugin(std::unique_ptr& requestPermissionsObj); + bool CheckPkgContext(); protected: int32_t InitAllowedParam() override; diff --git a/packing_tool/frameworks/include/hsp_packager.h b/packing_tool/frameworks/include/hsp_packager.h index 8f9a29e2015a1350d5d383907edde18598993215..25807c5b9323f89c56d363d9d99c0a943e276e39 100644 --- a/packing_tool/frameworks/include/hsp_packager.h +++ b/packing_tool/frameworks/include/hsp_packager.h @@ -43,6 +43,10 @@ public: bool CompressHspModePartFourth(); bool CompressHspModeMultiple(); bool AddCommonFileOrDirectoryToZip(const std::string ¶mPath, const std::string &targetPath); + bool IsAppPlugin(); + bool CheckPermission(); + bool IsPermissionAPlugin(std::unique_ptr& requestPermissionsObj); + bool CheckPkgContext(); protected: int32_t InitAllowedParam() override; diff --git a/packing_tool/frameworks/src/hap_packager.cpp b/packing_tool/frameworks/src/hap_packager.cpp index 09957ffe678bbb26edaa13e7dd5ab9fa955d49a8..3d35d649d8e92477fd30edf235de726a268934af 100644 --- a/packing_tool/frameworks/src/hap_packager.cpp +++ b/packing_tool/frameworks/src/hap_packager.cpp @@ -23,6 +23,11 @@ namespace OHOS { namespace AppPackingTool { +namespace { +const std::string NAME = "name"; +const std::string REQUEST_PERMISSIONS = "requestPermissions"; +const std::string PERMISSION_SUPPORT_PLUGIN = "ohos.permission.kernal.SUPPORT_PLUGIN"; +} HapPackager::HapPackager(const std::map ¶meterMap, std::string &resultReceiver) : Packager(parameterMap, resultReceiver) {} @@ -331,6 +336,13 @@ bool HapPackager::CompressHap() parameterMap_, jsonPath_)) { return false; } + if (Constants::TYPE_APP_PLUGIN == bundleType) { + return false; + } else { + if (!CheckPermission()) { + return false; + } + } } else { if (!CompressHapMode() || !BuildHash(buildHashFinish_, generateBuildHash_, parameterMap_, jsonPath_)) { return false; @@ -339,6 +351,59 @@ bool HapPackager::CompressHap() return true; } +bool HapPackager::CheckPermission() +{ + std::unique_ptr moduleObj; + if (!moduleJson_.GetModuleObject(moduleObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + if (moduleObj->Contains(REQUEST_PERMISSIONS.c_str())) { + std::unique_ptr requestPermissionsObj; + if (moduleObj->GetArray(REQUEST_PERMISSIONS.c_str(), &requestPermissionsObj) != Result::SUCCESS) { + LOGW("Module node get %s array node failed!", REQUEST_PERMISSIONS.c_str()); + return true; + } + if (IsPermissionAPlugin(requestPermissionsObj)) { + return CheckPkgContext(); + } + } + return true; +} + +bool HapPackager::IsPermissionAPlugin(std::unique_ptr& requestPermissionsObj) +{ + for (int32_t i = 0; i < requestPermissionsObj->GetSize(); i++) { + std::unique_ptr requestPermissionObj = requestPermissionsObj->Get(i); + if (requestPermissionObj->Contains(NAME.c_str())) { + std::string requestPermissionName; + if (requestPermissionObj->GetString(NAME.c_str(), &requestPermissionName) != Result::SUCCESS) { + LOGW("get %s failed!", NAME.c_str()); + continue; + } + if (requestPermissionName == PERMISSION_SUPPORT_PLUGIN) { + return true; + } + } + } + return false; +} + +bool HapPackager::CheckPkgContext() +{ + std::map::const_iterator it = parameterMap_.find(Constants::PARAM_PKG_CONTEXT_PATH); + if (it != parameterMap_.end()) { + const std::string filePath = it->second; + if (!fs::is_regular_file(filePath) || + fs::path(filePath).filename().string() != Constants::PKG_CONTEXT_JSON) { + LOGE("host must include pkgContextInfo.json"); + return false; + } + return true; + } + return false; +} + bool HapPackager::CheckStageHap(const std::string &jsonPath) { if (!moduleJson_.CheckStageAsanTsanEnabledValid()) { diff --git a/packing_tool/frameworks/src/hsp_packager.cpp b/packing_tool/frameworks/src/hsp_packager.cpp index 0069ceafabe513d4f809ed777bf0c347a2c109bd..98ca6998c7e89f892883c9dea6c1b6a8a4d5fcf2 100644 --- a/packing_tool/frameworks/src/hsp_packager.cpp +++ b/packing_tool/frameworks/src/hsp_packager.cpp @@ -23,6 +23,12 @@ namespace OHOS { namespace AppPackingTool { +namespace { +const std::string NAME = "name"; +const std::string EXTENSION_ABILITIES = "extensionAbilities"; +const std::string REQUEST_PERMISSIONS = "requestPermissions"; +const std::string PERMISSION_SUPPORT_PLUGIN = "ohos.permission.kernal.SUPPORT_PLUGIN"; +} HspPackager::HspPackager(const std::map ¶meterMap, std::string &resultReceiver) : Packager(parameterMap, resultReceiver) {} @@ -281,9 +287,115 @@ bool HspPackager::CompressHspMode(const std::string &jsonPath) return false; } } + if (!IsAppPlugin()) { + return false; + } return CompressHspModePartSecond(jsonPath); } +bool HspPackager::IsAppPlugin() +{ + std::string bundleType; + if (!moduleJson_.GetStageBundleType(bundleType)) { + LOGW("GetStageBundleType failed"); + return true; + } + if (Constants::TYPE_APP_PLUGIN != bundleType) { + LOGW("bundleType not appPlugin"); + if (CheckPermission()) { + return true; + } + if (!CheckPkgContext()) { + return false; + } + } + std::unique_ptr moduleObj; + if (!moduleJson_.GetModuleObject(moduleObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + if (moduleObj->Contains(EXTENSION_ABILITIES.c_str())) { + std::unique_ptr extensionAbilitiesObj; + if (moduleObj->GetArray(EXTENSION_ABILITIES.c_str(), &extensionAbilitiesObj) != Result::SUCCESS) { + LOGW("Module node get %s array node failed!", EXTENSION_ABILITIES.c_str()); + } + if (extensionAbilitiesObj) { + LOGE("extendAbilities of plugin package must empty"); + return false; + } + } + if (!CheckPkgContext()) { + return false; + } + if (moduleObj->Contains(REQUEST_PERMISSIONS.c_str())) { + std::unique_ptr requestPermissionsObj; + if (moduleObj->GetArray(REQUEST_PERMISSIONS.c_str(), &requestPermissionsObj) != Result::SUCCESS) { + LOGW("Module node get %s array node failed!", REQUEST_PERMISSIONS.c_str()); + return true; + } + if (IsPermissionAPlugin(requestPermissionsObj)) { + LOGE("plugin package cannot be PERMISSION_SUPPORT_PLUGIN"); + return false; + } + } + return false; +} + +bool HspPackager::CheckPermission() +{ + std::unique_ptr moduleObj; + if (!moduleJson_.GetModuleObject(moduleObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + if (moduleObj->Contains(REQUEST_PERMISSIONS.c_str())) { + std::unique_ptr requestPermissionsObj; + if (moduleObj->GetArray(REQUEST_PERMISSIONS.c_str(), &requestPermissionsObj) != Result::SUCCESS) { + LOGW("Module node get %s array node failed!", REQUEST_PERMISSIONS.c_str()); + return true; + } + if (IsPermissionAPlugin(requestPermissionsObj)) { + LOGW("requestPermission is PERMISSION_SUPPORT_PLUGIN"); + return false; + } + } + return true; +} + +bool HspPackager::IsPermissionAPlugin(std::unique_ptr& requestPermissionsObj) +{ + for (int32_t i = 0; i < requestPermissionsObj->GetSize(); i++) { + std::unique_ptr requestPermissionObj = requestPermissionsObj->Get(i); + if (requestPermissionObj->Contains(NAME.c_str())) { + std::string requestPermissionName; + if (requestPermissionObj->GetString(NAME.c_str(), &requestPermissionName) != Result::SUCCESS) { + LOGW("get %s failed!", NAME.c_str()); + continue; + } + if (requestPermissionName == PERMISSION_SUPPORT_PLUGIN) { + return true; + } + } + } + return false; +} + +bool HspPackager::CheckPkgContext() +{ + std::map::const_iterator it = parameterMap_.find(Constants::PARAM_PKG_CONTEXT_PATH); + if (it != parameterMap_.end()) { + const std::string filePath = it->second; + if (!fs::is_regular_file(filePath) || + fs::path(filePath).filename().string() != Constants::PKG_CONTEXT_JSON) { + LOGE("host must include pkgContextInfo.json"); + return false; + } + return true; + } + LOGE("host must include pkgContextInfo.json"); + return false; +} + bool HspPackager::CompressHspModePartSecond(const std::string &jsonPath) { std::map paramFileMap = {