1eace7efcSopenharmony_ci/* 2eace7efcSopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3eace7efcSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4eace7efcSopenharmony_ci * you may not use this file except in compliance with the License. 5eace7efcSopenharmony_ci * You may obtain a copy of the License at 6eace7efcSopenharmony_ci * 7eace7efcSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8eace7efcSopenharmony_ci * 9eace7efcSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10eace7efcSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11eace7efcSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12eace7efcSopenharmony_ci * See the License for the specific language governing permissions and 13eace7efcSopenharmony_ci * limitations under the License. 14eace7efcSopenharmony_ci */ 15eace7efcSopenharmony_ci 16eace7efcSopenharmony_ci#include "extension_config.h" 17eace7efcSopenharmony_ci 18eace7efcSopenharmony_ci#include <fstream> 19eace7efcSopenharmony_ci 20eace7efcSopenharmony_ci#include "config_policy_utils.h" 21eace7efcSopenharmony_ci#include "hilog_tag_wrapper.h" 22eace7efcSopenharmony_ci 23eace7efcSopenharmony_cinamespace OHOS { 24eace7efcSopenharmony_cinamespace AAFwk { 25eace7efcSopenharmony_cinamespace { 26eace7efcSopenharmony_ciconstexpr const char* EXTENSION_CONFIG_DEFAULT_PATH = "/system/etc/ams_extension_config.json"; 27eace7efcSopenharmony_ciconstexpr const char* EXTENSION_CONFIG_FILE_PATH = "/etc/ams_extension_config.json"; 28eace7efcSopenharmony_ci 29eace7efcSopenharmony_ciconstexpr const char* EXTENSION_CONFIG_NAME = "ams_extension_config"; 30eace7efcSopenharmony_ciconstexpr const char* EXTENSION_TYPE_NAME = "extension_type_name"; 31eace7efcSopenharmony_ciconstexpr const char* EXTENSION_AUTO_DISCONNECT_TIME = "auto_disconnect_time"; 32eace7efcSopenharmony_ci 33eace7efcSopenharmony_ciconstexpr const char* EXTENSION_THIRD_PARTY_APP_BLOCKED_FLAG_NAME = "third_party_app_blocked_flag"; 34eace7efcSopenharmony_ciconstexpr const char* EXTENSION_SERVICE_BLOCKED_LIST_NAME = "service_blocked_list"; 35eace7efcSopenharmony_ciconstexpr const char* EXTENSION_SERVICE_STARTUP_ENABLE_FLAG = "service_startup_enable_flag"; 36eace7efcSopenharmony_ci 37eace7efcSopenharmony_ciconst int32_t DEFAULT_EXTENSION_AUTO_DISCONNECT_TIME = -1; 38eace7efcSopenharmony_ci} 39eace7efcSopenharmony_ci 40eace7efcSopenharmony_cistd::string ExtensionConfig::GetExtensionConfigPath() const 41eace7efcSopenharmony_ci{ 42eace7efcSopenharmony_ci char buf[MAX_PATH_LEN] = { 0 }; 43eace7efcSopenharmony_ci char *configPath = GetOneCfgFile(EXTENSION_CONFIG_FILE_PATH, buf, MAX_PATH_LEN); 44eace7efcSopenharmony_ci if (configPath == nullptr || configPath[0] == '\0' || strlen(configPath) > MAX_PATH_LEN) { 45eace7efcSopenharmony_ci return EXTENSION_CONFIG_DEFAULT_PATH; 46eace7efcSopenharmony_ci } 47eace7efcSopenharmony_ci return configPath; 48eace7efcSopenharmony_ci} 49eace7efcSopenharmony_ci 50eace7efcSopenharmony_civoid ExtensionConfig::LoadExtensionConfiguration() 51eace7efcSopenharmony_ci{ 52eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "call"); 53eace7efcSopenharmony_ci nlohmann::json jsonBuf; 54eace7efcSopenharmony_ci if (!ReadFileInfoJson(GetExtensionConfigPath().c_str(), jsonBuf)) { 55eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "parse file failed"); 56eace7efcSopenharmony_ci return; 57eace7efcSopenharmony_ci } 58eace7efcSopenharmony_ci 59eace7efcSopenharmony_ci LoadExtensionConfig(jsonBuf); 60eace7efcSopenharmony_ci} 61eace7efcSopenharmony_ci 62eace7efcSopenharmony_ciint32_t ExtensionConfig::GetExtensionAutoDisconnectTime(std::string extensionTypeName) 63eace7efcSopenharmony_ci{ 64eace7efcSopenharmony_ci if (extensionAutoDisconnectTimeMap_.find(extensionTypeName) != extensionAutoDisconnectTimeMap_.end()) { 65eace7efcSopenharmony_ci return extensionAutoDisconnectTimeMap_[extensionTypeName]; 66eace7efcSopenharmony_ci } 67eace7efcSopenharmony_ci return DEFAULT_EXTENSION_AUTO_DISCONNECT_TIME; 68eace7efcSopenharmony_ci} 69eace7efcSopenharmony_ci 70eace7efcSopenharmony_cibool ExtensionConfig::IsExtensionStartThirdPartyAppEnable(std::string extensionTypeName) 71eace7efcSopenharmony_ci{ 72eace7efcSopenharmony_ci if (thirdPartyAppEnableFlags_.find(extensionTypeName) != thirdPartyAppEnableFlags_.end()) { 73eace7efcSopenharmony_ci return thirdPartyAppEnableFlags_[extensionTypeName]; 74eace7efcSopenharmony_ci } 75eace7efcSopenharmony_ci return true; 76eace7efcSopenharmony_ci} 77eace7efcSopenharmony_ci 78eace7efcSopenharmony_cibool ExtensionConfig::IsExtensionStartServiceEnable(std::string extensionTypeName, std::string targetUri) 79eace7efcSopenharmony_ci{ 80eace7efcSopenharmony_ci AppExecFwk::ElementName targetElementName; 81eace7efcSopenharmony_ci if (serviceEnableFlags_.find(extensionTypeName) != serviceEnableFlags_.end() && 82eace7efcSopenharmony_ci !serviceEnableFlags_[extensionTypeName]) { 83eace7efcSopenharmony_ci return false; 84eace7efcSopenharmony_ci } 85eace7efcSopenharmony_ci if (!targetElementName.ParseURI(targetUri) || 86eace7efcSopenharmony_ci serviceBlockedLists_.find(extensionTypeName) == serviceBlockedLists_.end()) { 87eace7efcSopenharmony_ci return true; 88eace7efcSopenharmony_ci } 89eace7efcSopenharmony_ci for (const auto& iter : serviceBlockedLists_[extensionTypeName]) { 90eace7efcSopenharmony_ci AppExecFwk::ElementName iterElementName; 91eace7efcSopenharmony_ci if (iterElementName.ParseURI(iter) && 92eace7efcSopenharmony_ci iterElementName.GetBundleName() == targetElementName.GetBundleName() && 93eace7efcSopenharmony_ci iterElementName.GetAbilityName() == targetElementName.GetAbilityName()) { 94eace7efcSopenharmony_ci return false; 95eace7efcSopenharmony_ci } 96eace7efcSopenharmony_ci } 97eace7efcSopenharmony_ci return true; 98eace7efcSopenharmony_ci} 99eace7efcSopenharmony_ci 100eace7efcSopenharmony_civoid ExtensionConfig::LoadExtensionConfig(const nlohmann::json &object) 101eace7efcSopenharmony_ci{ 102eace7efcSopenharmony_ci if (!object.contains(EXTENSION_CONFIG_NAME) || !object.at(EXTENSION_CONFIG_NAME).is_array()) { 103eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "extension config null"); 104eace7efcSopenharmony_ci return; 105eace7efcSopenharmony_ci } 106eace7efcSopenharmony_ci 107eace7efcSopenharmony_ci for (auto &item : object.at(EXTENSION_CONFIG_NAME).items()) { 108eace7efcSopenharmony_ci const nlohmann::json& jsonObject = item.value(); 109eace7efcSopenharmony_ci if (!jsonObject.contains(EXTENSION_TYPE_NAME) || !jsonObject.at(EXTENSION_TYPE_NAME).is_string()) { 110eace7efcSopenharmony_ci continue; 111eace7efcSopenharmony_ci } 112eace7efcSopenharmony_ci std::string extensionTypeName = jsonObject.at(EXTENSION_TYPE_NAME).get<std::string>(); 113eace7efcSopenharmony_ci LoadExtensionAutoDisconnectTime(jsonObject, extensionTypeName); 114eace7efcSopenharmony_ci LoadExtensionThirdPartyAppBlockedList(jsonObject, extensionTypeName); 115eace7efcSopenharmony_ci LoadExtensionServiceBlockedList(jsonObject, extensionTypeName); 116eace7efcSopenharmony_ci } 117eace7efcSopenharmony_ci} 118eace7efcSopenharmony_ci 119eace7efcSopenharmony_civoid ExtensionConfig::LoadExtensionAutoDisconnectTime(const nlohmann::json &object, std::string extensionTypeName) 120eace7efcSopenharmony_ci{ 121eace7efcSopenharmony_ci if (!object.contains(EXTENSION_AUTO_DISCONNECT_TIME) || 122eace7efcSopenharmony_ci !object.at(EXTENSION_AUTO_DISCONNECT_TIME).is_number()) { 123eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "auto disconnect time config null"); 124eace7efcSopenharmony_ci return; 125eace7efcSopenharmony_ci } 126eace7efcSopenharmony_ci int32_t extensionAutoDisconnectTime = object.at(EXTENSION_AUTO_DISCONNECT_TIME).get<int32_t>(); 127eace7efcSopenharmony_ci extensionAutoDisconnectTimeMap_[extensionTypeName] = extensionAutoDisconnectTime; 128eace7efcSopenharmony_ci} 129eace7efcSopenharmony_ci 130eace7efcSopenharmony_civoid ExtensionConfig::LoadExtensionThirdPartyAppBlockedList(const nlohmann::json &object, 131eace7efcSopenharmony_ci std::string extensionTypeName) 132eace7efcSopenharmony_ci{ 133eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "call."); 134eace7efcSopenharmony_ci if (!object.contains(EXTENSION_THIRD_PARTY_APP_BLOCKED_FLAG_NAME) || 135eace7efcSopenharmony_ci !object.at(EXTENSION_THIRD_PARTY_APP_BLOCKED_FLAG_NAME).is_boolean()) { 136eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "third Party config null"); 137eace7efcSopenharmony_ci return; 138eace7efcSopenharmony_ci } 139eace7efcSopenharmony_ci thirdPartyAppEnableFlags_[extensionTypeName] = object.at(EXTENSION_THIRD_PARTY_APP_BLOCKED_FLAG_NAME).get<bool>(); 140eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "The %{public}s extension's third party app blocked flag is %{public}d", 141eace7efcSopenharmony_ci extensionTypeName.c_str(), thirdPartyAppEnableFlags_[extensionTypeName]); 142eace7efcSopenharmony_ci} 143eace7efcSopenharmony_ci 144eace7efcSopenharmony_civoid ExtensionConfig::LoadExtensionServiceBlockedList(const nlohmann::json &object, std::string extensionTypeName) 145eace7efcSopenharmony_ci{ 146eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "call."); 147eace7efcSopenharmony_ci if (!object.contains(EXTENSION_SERVICE_STARTUP_ENABLE_FLAG) || 148eace7efcSopenharmony_ci !object.at(EXTENSION_SERVICE_STARTUP_ENABLE_FLAG).is_boolean()) { 149eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "service enable config null"); 150eace7efcSopenharmony_ci return; 151eace7efcSopenharmony_ci } 152eace7efcSopenharmony_ci bool serviceEnableFlag = object.at(EXTENSION_SERVICE_STARTUP_ENABLE_FLAG).get<bool>(); 153eace7efcSopenharmony_ci if (!serviceEnableFlag) { 154eace7efcSopenharmony_ci serviceEnableFlags_[extensionTypeName] = serviceEnableFlag; 155eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "%{public}s Service startup is blocked.", extensionTypeName.c_str()); 156eace7efcSopenharmony_ci return; 157eace7efcSopenharmony_ci } 158eace7efcSopenharmony_ci if (!object.contains(EXTENSION_SERVICE_BLOCKED_LIST_NAME) || 159eace7efcSopenharmony_ci !object.at(EXTENSION_SERVICE_BLOCKED_LIST_NAME).is_array()) { 160eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "service config null"); 161eace7efcSopenharmony_ci return; 162eace7efcSopenharmony_ci } 163eace7efcSopenharmony_ci std::unordered_set<std::string> serviceBlockedList; 164eace7efcSopenharmony_ci for (auto &item : object.at(EXTENSION_SERVICE_BLOCKED_LIST_NAME).items()) { 165eace7efcSopenharmony_ci const nlohmann::json& jsonObject = item.value(); 166eace7efcSopenharmony_ci if (!jsonObject.is_string()) { 167eace7efcSopenharmony_ci continue; 168eace7efcSopenharmony_ci } 169eace7efcSopenharmony_ci std::string serviceUri = jsonObject.get<std::string>(); 170eace7efcSopenharmony_ci if (CheckServiceExtensionUriValid(serviceUri)) { 171eace7efcSopenharmony_ci serviceBlockedList.emplace(serviceUri); 172eace7efcSopenharmony_ci } 173eace7efcSopenharmony_ci } 174eace7efcSopenharmony_ci serviceBlockedLists_[extensionTypeName] = serviceBlockedList; 175eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "The size of %{public}s extension's service blocked list is %{public}zu", 176eace7efcSopenharmony_ci extensionTypeName.c_str(), serviceBlockedList.size()); 177eace7efcSopenharmony_ci} 178eace7efcSopenharmony_ci 179eace7efcSopenharmony_cibool ExtensionConfig::ReadFileInfoJson(const std::string &filePath, nlohmann::json &jsonBuf) 180eace7efcSopenharmony_ci{ 181eace7efcSopenharmony_ci if (access(filePath.c_str(), F_OK) != 0) { 182eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "%{public}s, not existed", filePath.c_str()); 183eace7efcSopenharmony_ci return false; 184eace7efcSopenharmony_ci } 185eace7efcSopenharmony_ci 186eace7efcSopenharmony_ci std::fstream in; 187eace7efcSopenharmony_ci char errBuf[256]; 188eace7efcSopenharmony_ci errBuf[0] = '\0'; 189eace7efcSopenharmony_ci in.open(filePath, std::ios_base::in); 190eace7efcSopenharmony_ci if (!in.is_open()) { 191eace7efcSopenharmony_ci strerror_r(errno, errBuf, sizeof(errBuf)); 192eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "failed due to %{public}s", errBuf); 193eace7efcSopenharmony_ci return false; 194eace7efcSopenharmony_ci } 195eace7efcSopenharmony_ci 196eace7efcSopenharmony_ci in.seekg(0, std::ios::end); 197eace7efcSopenharmony_ci int64_t size = in.tellg(); 198eace7efcSopenharmony_ci if (size <= 0) { 199eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "empty file"); 200eace7efcSopenharmony_ci in.close(); 201eace7efcSopenharmony_ci return false; 202eace7efcSopenharmony_ci } 203eace7efcSopenharmony_ci 204eace7efcSopenharmony_ci in.seekg(0, std::ios::beg); 205eace7efcSopenharmony_ci jsonBuf = nlohmann::json::parse(in, nullptr, false); 206eace7efcSopenharmony_ci in.close(); 207eace7efcSopenharmony_ci if (jsonBuf.is_discarded()) { 208eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "bad profile file"); 209eace7efcSopenharmony_ci return false; 210eace7efcSopenharmony_ci } 211eace7efcSopenharmony_ci 212eace7efcSopenharmony_ci return true; 213eace7efcSopenharmony_ci} 214eace7efcSopenharmony_ci 215eace7efcSopenharmony_cibool ExtensionConfig::CheckServiceExtensionUriValid(const std::string &uri) 216eace7efcSopenharmony_ci{ 217eace7efcSopenharmony_ci const size_t memberNum = 4; 218eace7efcSopenharmony_ci if (std::count(uri.begin(), uri.end(), '/') != memberNum - 1) { 219eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid uri: %{public}s", uri.c_str()); 220eace7efcSopenharmony_ci return false; 221eace7efcSopenharmony_ci } 222eace7efcSopenharmony_ci // correct uri: "/bundleName/moduleName/abilityName" 223eace7efcSopenharmony_ci std::string::size_type pos1 = 0; 224eace7efcSopenharmony_ci std::string::size_type pos2 = uri.find('/', pos1 + 1); 225eace7efcSopenharmony_ci std::string::size_type pos3 = uri.find('/', pos2 + 1); 226eace7efcSopenharmony_ci std::string::size_type pos4 = uri.find('/', pos3 + 1); 227eace7efcSopenharmony_ci if ((pos3 == pos2 + 1) || (pos4 == pos3 + 1) || (pos4 == uri.size() - 1)) { 228eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid uri: %{public}s", uri.c_str()); 229eace7efcSopenharmony_ci return false; 230eace7efcSopenharmony_ci } 231eace7efcSopenharmony_ci return true; 232eace7efcSopenharmony_ci} 233eace7efcSopenharmony_ci} 234eace7efcSopenharmony_ci}