• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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 "extension_config.h"
17 
18 #include <fstream>
19 
20 #include "config_policy_utils.h"
21 #include "hilog_tag_wrapper.h"
22 
23 namespace OHOS {
24 namespace AAFwk {
25 namespace {
26 constexpr const char* EXTENSION_CONFIG_DEFAULT_PATH = "/system/etc/ams_extension_config.json";
27 constexpr const char* EXTENSION_CONFIG_FILE_PATH = "/etc/ams_extension_config.json";
28 
29 constexpr const char* EXTENSION_CONFIG_NAME = "ams_extension_config";
30 constexpr const char* EXTENSION_TYPE_NAME = "extension_type_name";
31 constexpr const char* EXTENSION_AUTO_DISCONNECT_TIME = "auto_disconnect_time";
32 
33 constexpr const char* EXTENSION_THIRD_PARTY_APP_BLOCKED_FLAG_NAME = "third_party_app_blocked_flag";
34 constexpr const char* EXTENSION_SERVICE_BLOCKED_LIST_NAME = "service_blocked_list";
35 constexpr const char* EXTENSION_SERVICE_STARTUP_ENABLE_FLAG = "service_startup_enable_flag";
36 constexpr const char* EXTENSION_NETWORK_ENABLE_FLAG = "network_access_enable_flag";
37 constexpr const char* EXTENSION_SA_ENABLE_FLAG = "sa_access_enable_flag";
38 }
39 
GetExtensionConfigPath() const40 std::string ExtensionConfig::GetExtensionConfigPath() const
41 {
42     char buf[MAX_PATH_LEN] = { 0 };
43     char *configPath = GetOneCfgFile(EXTENSION_CONFIG_FILE_PATH, buf, MAX_PATH_LEN);
44     if (configPath == nullptr || configPath[0] == '\0' || strlen(configPath) > MAX_PATH_LEN) {
45         return EXTENSION_CONFIG_DEFAULT_PATH;
46     }
47     return configPath;
48 }
49 
LoadExtensionConfiguration()50 void ExtensionConfig::LoadExtensionConfiguration()
51 {
52     TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
53     nlohmann::json jsonBuf;
54     if (!ReadFileInfoJson(GetExtensionConfigPath().c_str(), jsonBuf)) {
55         TAG_LOGE(AAFwkTag::ABILITYMGR, "parse file failed");
56         return;
57     }
58 
59     LoadExtensionConfig(jsonBuf);
60 }
61 
GetExtensionAutoDisconnectTime(const std::string & extensionTypeName)62 int32_t ExtensionConfig::GetExtensionAutoDisconnectTime(const std::string &extensionTypeName)
63 {
64     std::lock_guard lock(configMapMutex_);
65     if (configMap_.find(extensionTypeName) != configMap_.end()) {
66         return configMap_[extensionTypeName].extensionAutoDisconnectTime;
67     }
68     return DEFAULT_EXTENSION_AUTO_DISCONNECT_TIME;
69 }
70 
IsExtensionStartThirdPartyAppEnable(const std::string & extensionTypeName)71 bool ExtensionConfig::IsExtensionStartThirdPartyAppEnable(const std::string &extensionTypeName)
72 {
73     std::lock_guard lock(configMapMutex_);
74     if (configMap_.find(extensionTypeName) != configMap_.end()) {
75         return configMap_[extensionTypeName].thirdPartyAppEnableFlag;
76     }
77     return EXTENSION_THIRD_PARTY_APP_ENABLE_FLAG_DEFAULT;
78 }
79 
IsExtensionStartServiceEnable(const std::string & extensionTypeName,const std::string & targetUri)80 bool ExtensionConfig::IsExtensionStartServiceEnable(const std::string &extensionTypeName, const std::string &targetUri)
81 {
82     AppExecFwk::ElementName targetElementName;
83     std::lock_guard lock(configMapMutex_);
84     if (configMap_.find(extensionTypeName) != configMap_.end() &&
85         !configMap_[extensionTypeName].serviceEnableFlag) {
86         return false;
87     }
88     if (!targetElementName.ParseURI(targetUri) ||
89         configMap_.find(extensionTypeName) == configMap_.end()) {
90         return EXTENSION_START_SERVICE_ENABLE_FLAG_DEFAULT;
91     }
92     for (const auto& iter : configMap_[extensionTypeName].serviceBlockedList) {
93         AppExecFwk::ElementName iterElementName;
94         if (iterElementName.ParseURI(iter) &&
95             iterElementName.GetBundleName() == targetElementName.GetBundleName() &&
96             iterElementName.GetAbilityName() == targetElementName.GetAbilityName()) {
97             return false;
98         }
99     }
100     return EXTENSION_START_SERVICE_ENABLE_FLAG_DEFAULT;
101 }
102 
LoadExtensionConfig(const nlohmann::json & object)103 void ExtensionConfig::LoadExtensionConfig(const nlohmann::json &object)
104 {
105     if (!object.contains(EXTENSION_CONFIG_NAME) || !object.at(EXTENSION_CONFIG_NAME).is_array()) {
106         TAG_LOGE(AAFwkTag::ABILITYMGR, "extension config null");
107         return;
108     }
109 
110     for (auto &item : object.at(EXTENSION_CONFIG_NAME).items()) {
111         const nlohmann::json& jsonObject = item.value();
112         if (!jsonObject.contains(EXTENSION_TYPE_NAME) || !jsonObject.at(EXTENSION_TYPE_NAME).is_string()) {
113             continue;
114         }
115         std::lock_guard lock(configMapMutex_);
116         std::string extensionTypeName = jsonObject.at(EXTENSION_TYPE_NAME).get<std::string>();
117         LoadExtensionAutoDisconnectTime(jsonObject, extensionTypeName);
118         LoadExtensionThirdPartyAppBlockedList(jsonObject, extensionTypeName);
119         LoadExtensionServiceBlockedList(jsonObject, extensionTypeName);
120         LoadExtensionNetworkEnable(jsonObject, extensionTypeName);
121         LoadExtensionSAEnable(jsonObject, extensionTypeName);
122     }
123 }
124 
LoadExtensionAutoDisconnectTime(const nlohmann::json & object,std::string extensionTypeName)125 void ExtensionConfig::LoadExtensionAutoDisconnectTime(const nlohmann::json &object, std::string extensionTypeName)
126 {
127     if (!object.contains(EXTENSION_AUTO_DISCONNECT_TIME) ||
128         !object.at(EXTENSION_AUTO_DISCONNECT_TIME).is_number()) {
129         TAG_LOGE(AAFwkTag::ABILITYMGR, "auto disconnect time config null");
130         return;
131     }
132     int32_t extensionAutoDisconnectTime = object.at(EXTENSION_AUTO_DISCONNECT_TIME).get<int32_t>();
133     configMap_[extensionTypeName].extensionAutoDisconnectTime = extensionAutoDisconnectTime;
134 }
135 
LoadExtensionThirdPartyAppBlockedList(const nlohmann::json & object,std::string extensionTypeName)136 void ExtensionConfig::LoadExtensionThirdPartyAppBlockedList(const nlohmann::json &object,
137     std::string extensionTypeName)
138 {
139     TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
140     if (!object.contains(EXTENSION_THIRD_PARTY_APP_BLOCKED_FLAG_NAME) ||
141         !object.at(EXTENSION_THIRD_PARTY_APP_BLOCKED_FLAG_NAME).is_boolean()) {
142         TAG_LOGE(AAFwkTag::ABILITYMGR, "third Party config null");
143         return;
144     }
145     bool flag = object.at(EXTENSION_THIRD_PARTY_APP_BLOCKED_FLAG_NAME).get<bool>();
146     configMap_[extensionTypeName].thirdPartyAppEnableFlag = flag;
147     TAG_LOGD(AAFwkTag::ABILITYMGR, "The %{public}s extension's third party app blocked flag is %{public}d",
148         extensionTypeName.c_str(), flag);
149 }
150 
LoadExtensionServiceBlockedList(const nlohmann::json & object,std::string extensionTypeName)151 void ExtensionConfig::LoadExtensionServiceBlockedList(const nlohmann::json &object, std::string extensionTypeName)
152 {
153     TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
154     if (!object.contains(EXTENSION_SERVICE_STARTUP_ENABLE_FLAG) ||
155         !object.at(EXTENSION_SERVICE_STARTUP_ENABLE_FLAG).is_boolean()) {
156         TAG_LOGE(AAFwkTag::ABILITYMGR, "service enable config null");
157         return;
158     }
159     bool serviceEnableFlag = object.at(EXTENSION_SERVICE_STARTUP_ENABLE_FLAG).get<bool>();
160     if (!serviceEnableFlag) {
161         configMap_[extensionTypeName].serviceEnableFlag = serviceEnableFlag;
162         TAG_LOGD(AAFwkTag::ABILITYMGR, "%{public}s Service startup is blocked.", extensionTypeName.c_str());
163         return;
164     }
165     if (!object.contains(EXTENSION_SERVICE_BLOCKED_LIST_NAME) ||
166         !object.at(EXTENSION_SERVICE_BLOCKED_LIST_NAME).is_array()) {
167         TAG_LOGE(AAFwkTag::ABILITYMGR, "service config null");
168         return;
169     }
170     std::unordered_set<std::string> serviceBlockedList;
171     for (auto &item : object.at(EXTENSION_SERVICE_BLOCKED_LIST_NAME).items()) {
172         const nlohmann::json& jsonObject = item.value();
173         if (!jsonObject.is_string()) {
174             continue;
175         }
176         std::string serviceUri = jsonObject.get<std::string>();
177         if (CheckServiceExtensionUriValid(serviceUri)) {
178             serviceBlockedList.emplace(serviceUri);
179         }
180     }
181     configMap_[extensionTypeName].serviceBlockedList = serviceBlockedList;
182     TAG_LOGD(AAFwkTag::ABILITYMGR, "The size of %{public}s extension's service blocked list is %{public}zu",
183         extensionTypeName.c_str(), serviceBlockedList.size());
184 }
185 
LoadExtensionNetworkEnable(const nlohmann::json & object,const std::string & extensionTypeName)186 void ExtensionConfig::LoadExtensionNetworkEnable(const nlohmann::json &object,
187     const std::string &extensionTypeName)
188 {
189     TAG_LOGD(AAFwkTag::ABILITYMGR, "LoadExtensionNetworkEnable call");
190     if (!object.contains(EXTENSION_NETWORK_ENABLE_FLAG) || !object.at(EXTENSION_NETWORK_ENABLE_FLAG).is_boolean()) {
191         TAG_LOGW(AAFwkTag::ABILITYMGR, "network enable flag null");
192         return;
193     }
194     bool flag = object.at(EXTENSION_NETWORK_ENABLE_FLAG).get<bool>();
195     configMap_[extensionTypeName].networkEnableFlag = flag;
196     TAG_LOGD(AAFwkTag::ABILITYMGR, "The %{public}s extension's network enable flag is %{public}d",
197         extensionTypeName.c_str(), flag);
198 }
199 
LoadExtensionSAEnable(const nlohmann::json & object,const std::string & extensionTypeName)200 void ExtensionConfig::LoadExtensionSAEnable(const nlohmann::json &object,
201     const std::string &extensionTypeName)
202 {
203     TAG_LOGD(AAFwkTag::ABILITYMGR, "LoadExtensionSAEnable call");
204     if (!object.contains(EXTENSION_SA_ENABLE_FLAG) || !object.at(EXTENSION_SA_ENABLE_FLAG).is_boolean()) {
205         TAG_LOGW(AAFwkTag::ABILITYMGR, "sa enable flag null");
206         return;
207     }
208     bool flag = object.at(EXTENSION_SA_ENABLE_FLAG).get<bool>();
209     configMap_[extensionTypeName].saEnableFlag = flag;
210     TAG_LOGD(AAFwkTag::ABILITYMGR, "The %{public}s extension's sa enable flag is %{public}d",
211         extensionTypeName.c_str(), flag);
212 }
213 
IsExtensionNetworkEnable(const std::string & extensionTypeName)214 bool ExtensionConfig::IsExtensionNetworkEnable(const std::string &extensionTypeName)
215 {
216     std::lock_guard lock(configMapMutex_);
217     if (configMap_.find(extensionTypeName) != configMap_.end()) {
218         return configMap_[extensionTypeName].networkEnableFlag;
219     }
220     return EXTENSION_NETWORK_ENABLE_FLAG_DEFAULT;
221 }
222 
IsExtensionSAEnable(const std::string & extensionTypeName)223 bool ExtensionConfig::IsExtensionSAEnable(const std::string &extensionTypeName)
224 {
225     std::lock_guard lock(configMapMutex_);
226     if (configMap_.find(extensionTypeName) != configMap_.end()) {
227         return configMap_[extensionTypeName].saEnableFlag;
228     }
229     return EXTENSION_SA_ENABLE_FLAG_DEFAULT;
230 }
231 
ReadFileInfoJson(const std::string & filePath,nlohmann::json & jsonBuf)232 bool ExtensionConfig::ReadFileInfoJson(const std::string &filePath, nlohmann::json &jsonBuf)
233 {
234     if (access(filePath.c_str(), F_OK) != 0) {
235         TAG_LOGD(AAFwkTag::ABILITYMGR, "%{public}s, not existed", filePath.c_str());
236         return false;
237     }
238 
239     std::fstream in;
240     char errBuf[256];
241     errBuf[0] = '\0';
242     in.open(filePath, std::ios_base::in);
243     if (!in.is_open()) {
244         strerror_r(errno, errBuf, sizeof(errBuf));
245         TAG_LOGE(AAFwkTag::ABILITYMGR, "failed due to  %{public}s", errBuf);
246         return false;
247     }
248 
249     in.seekg(0, std::ios::end);
250     int64_t size = in.tellg();
251     if (size <= 0) {
252         TAG_LOGE(AAFwkTag::ABILITYMGR, "empty file");
253         in.close();
254         return false;
255     }
256 
257     in.seekg(0, std::ios::beg);
258     jsonBuf = nlohmann::json::parse(in, nullptr, false);
259     in.close();
260     if (jsonBuf.is_discarded()) {
261         TAG_LOGE(AAFwkTag::ABILITYMGR, "bad profile file");
262         return false;
263     }
264 
265     return true;
266 }
267 
CheckServiceExtensionUriValid(const std::string & uri)268 bool ExtensionConfig::CheckServiceExtensionUriValid(const std::string &uri)
269 {
270     const size_t memberNum = 4;
271     if (std::count(uri.begin(), uri.end(), '/') != memberNum - 1) {
272         TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid uri: %{public}s", uri.c_str());
273         return false;
274     }
275     // correct uri: "/bundleName/moduleName/abilityName"
276     std::string::size_type pos1 = 0;
277     std::string::size_type pos2 = uri.find('/', pos1 + 1);
278     std::string::size_type pos3 = uri.find('/', pos2 + 1);
279     std::string::size_type pos4 = uri.find('/', pos3 + 1);
280     if ((pos3 == pos2 + 1) || (pos4 == pos3 + 1) || (pos4 == uri.size() - 1)) {
281         TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid uri: %{public}s", uri.c_str());
282         return false;
283     }
284     return true;
285 }
286 }
287 }