1 /*
2 * Copyright (c) 2023 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 "form_module_checker.h"
17
18 #include <functional>
19 #include <memory>
20 #include <string>
21 #include <vector>
22 #include <fstream>
23 #include <filesystem>
24
25 #include "fms_log_wrapper.h"
26 #include "nlohmann/json.hpp"
27 #include "config_policy_utils.h"
28
29 const std::string FORM_MODULE_WHITE_LIST_PATH = "/etc/form_fwk_module_white_list.json";
30 const std::string KEY_MODULE_ALLOW = "moduleAllowList";
31
32 std::vector<std::string> FormModuleChecker::modulesFromCfg_ = FormModuleChecker::GetModuleAllowList();
33
CheckApiAllowList(const std::string & apiPath)34 bool FormModuleChecker::CheckApiAllowList(const std::string& apiPath)
35 {
36 const std::vector<std::string> allowList = {
37 "i18n.System.getSystemLanguage",
38 "i18n.System.is24HourClock",
39 "intl.Locale.*",
40 "intl.DateTimeFormat.*",
41 "effectKit.*",
42 "font.registerFont",
43 "multimedia.image.PixelMapFormat.*",
44 "multimedia.image.Size.*",
45 "multimedia.image.AlphaType.*",
46 "multimedia.image.ScaleMode.*",
47 "multimedia.image.Region.*",
48 "multimedia.image.PositionArea.*",
49 "multimedia.image.ImageInfo.*",
50 "multimedia.image.DecodingOptions.*",
51 "multimedia.image.InitializationOptions.*",
52 "multimedia.image.SourceOptions.*",
53 "multimedia.image.createImageSource",
54 "multimedia.image.PixelMap.*",
55 "multimedia.image.ImageSource.*",
56 "arkui.shape.*"
57 };
58
59 for (const auto& item : allowList) {
60 if (CheckApiWithSuffix(apiPath, item)) {
61 return true;
62 }
63 }
64
65 return false;
66 }
67
CheckApiWithSuffix(const std::string & apiPath,const std::string & item)68 bool FormModuleChecker::CheckApiWithSuffix(const std::string& apiPath, const std::string& item)
69 {
70 if (item.compare(0, apiPath.size(), apiPath) == 0) {
71 HILOG_DEBUG("api allowed by allowlist: '%{public}s' matches '%{public}s'", apiPath.c_str(), item.c_str());
72 return true;
73 }
74 const int32_t kSuffixLength = 2;
75 if (item.size() >= kSuffixLength && item.substr(item.size() - kSuffixLength) == ".*") {
76 const std::string path = item.substr(0, item.rfind('.'));
77 if (apiPath.compare(0, path.size(), path) == 0) {
78 HILOG_DEBUG("api allowed by allowlist: '%{public}s' matches '%{public}s'", apiPath.c_str(), item.c_str());
79 return true;
80 }
81 }
82 return false;
83 }
84
CheckModuleLoadable(const char * moduleName,std::unique_ptr<ApiAllowListChecker> & apiAllowListChecker)85 bool FormModuleChecker::CheckModuleLoadable(const char *moduleName,
86 std::unique_ptr<ApiAllowListChecker> &apiAllowListChecker)
87 {
88 if (std::string(moduleName) == "mediaquery") {
89 HILOG_INFO("load mediaquery");
90 return true;
91 }
92 if (IsModuelAllowToLoad(moduleName)) {
93 HILOG_INFO("module has been allowed by the allowlist in form, module name = %{public}s", moduleName);
94 if (apiAllowListChecker == nullptr) {
95 apiAllowListChecker = std::make_unique<ApiAllowListChecker>([](const std::string& apiPath) {
96 return CheckApiAllowList(apiPath);
97 });
98 }
99 return true;
100 }
101 HILOG_INFO("module can't load in form,moduleName= %{public}s", moduleName);
102 return false;
103 }
104
IsModuelAllowToLoad(const std::string & moduleName)105 bool FormModuleChecker::IsModuelAllowToLoad(const std::string& moduleName)
106 {
107 for (const auto& item : modulesFromCfg_) {
108 if (item == moduleName) {
109 return true;
110 }
111 }
112 const std::vector<std::string> moduleAllowList = {
113 "i18n",
114 "intl",
115 "effectKit",
116 "font",
117 "multimedia.image",
118 "arkui.shape"
119 };
120
121 for (const auto& item : moduleAllowList) {
122 if (item == moduleName) {
123 return true;
124 }
125 }
126
127 return false;
128 }
129
GetModuleAllowList()130 std::vector<std::string> FormModuleChecker::GetModuleAllowList()
131 {
132 HILOG_INFO("read moduleAllowList from config file");
133 std::vector<std::string> result;
134 char buf[MAX_PATH_LEN];
135 char* path = GetOneCfgFile(FORM_MODULE_WHITE_LIST_PATH.c_str(), buf, MAX_PATH_LEN);
136 if (path == nullptr || *path == '\0') {
137 HILOG_ERROR("config file not found");
138 return result;
139 }
140 std::ifstream file(path);
141 if (!file.is_open()) {
142 HILOG_ERROR("failed to open config file");
143 return result;
144 }
145 HILOG_INFO("success to open config file");
146 nlohmann::json jsonData;
147 file >> jsonData;
148 if (jsonData.contains(KEY_MODULE_ALLOW) && jsonData[KEY_MODULE_ALLOW].is_array()) {
149 for (const auto& module : jsonData[KEY_MODULE_ALLOW]) {
150 HILOG_INFO("read moduleAllowList module: %{public}s", std::string(module).c_str());
151 result.push_back(module);
152 }
153 }
154 file.close();
155 return result;
156 }
157