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 #include <sstream>
16 #include <algorithm>
17 #include "domain_url_util.h"
18 #include "white_list_config_mgr.h"
19 #include "app_domain_verify_hilog.h"
20 #include "app_domain_verify_hisysevent.h"
21 #include "regex.h"
22 #include "uri.h"
23
24 namespace OHOS::AppDomainVerify {
25 const static std::string DYNAMIC_WHITE_LIST_PRE_PATH =
26 "/data/service/el1/public/app_domain_verify_mgr_service/whitelist_pref";
27 const static std::string DEFAULT_WHITE_LIST_PRE_PATH = "/system/etc/app_domain_verify/whitelist_pref";
28 const static std::string REG_DEFAULT_URL_KEY = "regDefaultUrl";
29 const static std::string REG_WHITE_LIST_KEY = "regWhiteList";
30 const static std::string SPLITOR = ",";
31 constexpr int REG_ERR_BUF = 1024;
32 constexpr int NM = 10;
WhiteListConfigMgr()33 WhiteListConfigMgr::WhiteListConfigMgr()
34 {
35 Load();
36 }
~WhiteListConfigMgr()37 WhiteListConfigMgr::~WhiteListConfigMgr()
38 {
39 }
LoadDefault()40 void WhiteListConfigMgr::LoadDefault()
41 {
42 preferences_ = GetPreference(DEFAULT_WHITE_LIST_PRE_PATH);
43 if (preferences_ == nullptr) {
44 UNIVERSAL_ERROR_EVENT(READ_DEFAULT_WHITE_LIST_FAULT);
45 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Load failed.");
46 return;
47 }
48
49 defaultWhiteUrl_ = preferences_->GetString(REG_DEFAULT_URL_KEY, "");
50 if (defaultWhiteUrl_.empty()) {
51 UNIVERSAL_ERROR_EVENT(READ_DEFAULT_WHITE_LIST_FAULT);
52 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Load defaultWhiteUrl empty.");
53 }
54 }
LoadDynamic()55 void WhiteListConfigMgr::LoadDynamic()
56 {
57 preferences_ = GetPreference(DYNAMIC_WHITE_LIST_PRE_PATH);
58 if (preferences_ == nullptr) {
59 UNIVERSAL_ERROR_EVENT(READ_DYNAMIC_WHITE_LIST_FAULT);
60 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Load failed.");
61 return;
62 }
63
64 auto whiteListStr = preferences_->GetString(REG_WHITE_LIST_KEY, "");
65 Split(whiteListStr);
66 }
Load()67 void WhiteListConfigMgr::Load()
68 {
69 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "called");
70 LoadDefault();
71 LoadDynamic();
72 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "called end");
73 }
Split(std::string src)74 void WhiteListConfigMgr::Split(std::string src)
75 {
76 whiteListSet_.clear();
77 if (!SPLITOR.empty()) {
78 size_t pos = 0;
79 while ((pos = src.find(SPLITOR)) != std::string::npos) {
80 // split
81 std::string token = src.substr(0, pos);
82 if (!token.empty()) {
83 whiteListSet_.insert(token);
84 }
85 src.erase(0, pos + SPLITOR.length());
86 }
87 }
88
89 if (!src.empty()) {
90 whiteListSet_.insert(src);
91 }
92 if (whiteListSet_.empty()) {
93 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Split whiteListSet empty.");
94 }
95 }
GetPreference(const std::string & path)96 std::shared_ptr<NativePreferences::Preferences> WhiteListConfigMgr::GetPreference(const std::string& path)
97 {
98 int status;
99 NativePreferences::Options options(path);
100 std::shared_ptr<NativePreferences::Preferences> preferences = NativePreferences::PreferencesHelper::GetPreferences(
101 options, status);
102 if (status != 0) {
103 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::GetPreference failed.");
104 return nullptr;
105 }
106 return preferences;
107 }
Save()108 bool WhiteListConfigMgr::Save()
109 {
110 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "called");
111 if (preferences_ == nullptr) {
112 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MODULE_COMMON, "preferences null");
113 return false;
114 }
115 std::stringstream strSteam;
116 for (const auto& element : whiteListSet_) {
117 strSteam << element << ",";
118 }
119 auto ret = preferences_->PutString(REG_WHITE_LIST_KEY, strSteam.str());
120 if (ret != 0) {
121 UNIVERSAL_ERROR_EVENT(WRITE_DYNAMIC_WHITE_LIST_FAULT);
122 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_COMMON, "put dynamic white list error ret:%{public}d.", ret);
123 return false;
124 }
125 preferences_->Flush();
126 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Save %{public}s ret%{public}d.",
127 strSteam.str().c_str(), ret);
128 return true;
129 }
130
IsInWhiteList(const std::string & url)131 bool WhiteListConfigMgr::IsInWhiteList(const std::string& url)
132 {
133 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
134 std::lock_guard<std::mutex> lock(whiteListLock_);
135 bool ret;
136 if (whiteListSet_.empty()) {
137 ret = IsMatched(url, defaultWhiteUrl_);
138 } else {
139 auto targetPatten = std::find_if(whiteListSet_.begin(), whiteListSet_.end(),
140 [&url](const std::string& urlPatten) { return IsMatched(url, urlPatten); });
141
142 ret = (targetPatten != whiteListSet_.end()) || (IsMatched(url, defaultWhiteUrl_));
143 }
144 APP_DOMAIN_VERIFY_HILOGI(
145 APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "is matched url %{private}s, ret:%{public}d", url.c_str(), ret);
146 return ret;
147 }
UpdateWhiteList(const std::unordered_set<std::string> & whiteList)148 void WhiteListConfigMgr::UpdateWhiteList(const std::unordered_set<std::string>& whiteList)
149 {
150 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called 1");
151 std::unordered_set<std::string> filtedWhiteList;
152 std::for_each(whiteList.begin(), whiteList.end(), [&filtedWhiteList](const std::string& element) {
153 if (!element.empty()) {
154 filtedWhiteList.insert(element);
155 }
156 });
157 std::lock_guard<std::mutex> lock(whiteListLock_);
158 whiteListSet_ = filtedWhiteList;
159 if (!whiteListSet_.empty()) {
160 if (!Save()) {
161 UNIVERSAL_ERROR_EVENT(WRITE_DYNAMIC_WHITE_LIST_FAULT);
162 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "save white list failed.");
163 }
164 }
165 }
166
IsMatched(const std::string & url,const std::string & regPatten)167 bool WhiteListConfigMgr::IsMatched(const std::string& url, const std::string& regPatten)
168 {
169 if (regPatten.empty()) {
170 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "regPatten null");
171 return false;
172 }
173 const char* bematch = url.c_str();
174 char errbuf[REG_ERR_BUF];
175 regex_t reg;
176 int errNum = 0;
177 int nm = NM;
178 regmatch_t pmatch[nm];
179 if (regcomp(®, regPatten.c_str(), REG_EXTENDED) < 0) {
180 regerror(errNum, ®, errbuf, sizeof(errbuf));
181 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "regexec error:%{public}s", errbuf);
182 return false;
183 }
184 errNum = regexec(®, bematch, nm, pmatch, 0);
185 if (errNum == REG_NOMATCH) {
186 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "regexec no match");
187 regfree(®);
188 return false;
189 } else if (errNum) {
190 regerror(errNum, ®, errbuf, sizeof(errbuf));
191 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "regexec error:%{public}s", errbuf);
192 regfree(®);
193 return false;
194 }
195 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "is valid path");
196 regfree(®);
197 return true;
198 }
199
200 }
201