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 
21 namespace OHOS::AppDomainVerify {
22 const static std::string DYNAMIC_WHITE_LIST_PRE_PATH =
23     "/data/service/el1/public/app_domain_verify_mgr_service/whitelist_pref";
24 const static std::string DEFAULT_WHITE_LIST_PRE_PATH = "/system/etc/app_domain_verify/whitelist_pref";
25 const static std::string DEFAULT_URL_KEY = "defaultUrl";
26 const static std::string WHITE_LIST_KEY = "whiteList";
27 const static std::string SPLITOR = ",";
WhiteListConfigMgr()28 WhiteListConfigMgr::WhiteListConfigMgr()
29 {
30     Load();
31 }
~WhiteListConfigMgr()32 WhiteListConfigMgr::~WhiteListConfigMgr()
33 {
34 }
LoadDefault()35 void WhiteListConfigMgr::LoadDefault()
36 {
37     preferences_ = GetPreference(DEFAULT_WHITE_LIST_PRE_PATH);
38     if (preferences_ == nullptr) {
39         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Load failed.");
40         return;
41     }
42 
43     defaultWhiteUrl_ = preferences_->GetString(DEFAULT_URL_KEY, "");
44     if (defaultWhiteUrl_.empty()) {
45         APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Load defaultWhiteUrl empty.");
46     }
47 }
LoadDynamic()48 void WhiteListConfigMgr::LoadDynamic()
49 {
50     preferences_ = GetPreference(DYNAMIC_WHITE_LIST_PRE_PATH);
51     if (preferences_ == nullptr) {
52         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Load failed.");
53         return;
54     }
55 
56     auto whiteListStr = preferences_->GetString(WHITE_LIST_KEY, "");
57     Split(whiteListStr);
58 }
Load()59 void WhiteListConfigMgr::Load()
60 {
61     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "called");
62     std::lock_guard<std::mutex> lock(initLock);
63     LoadDefault();
64     LoadDynamic();
65     init = true;
66     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "called end");
67 }
Split(std::string src)68 void WhiteListConfigMgr::Split(std::string src)
69 {
70     whiteListSet_.clear();
71     if (!SPLITOR.empty()) {
72         size_t pos = 0;
73         while ((pos = src.find(SPLITOR)) != std::string::npos) {
74             // split
75             std::string token = src.substr(0, pos);
76             if (!token.empty()) {
77                 whiteListSet_.insert(token);
78             }
79             src.erase(0, pos + SPLITOR.length());
80         }
81     }
82 
83     if (!src.empty()) {
84         whiteListSet_.insert(src);
85     }
86     if (whiteListSet_.empty()) {
87         APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Split whiteListSet empty.");
88     }
89 }
GetPreference(const std::string & path)90 std::shared_ptr<NativePreferences::Preferences> WhiteListConfigMgr::GetPreference(const std::string& path)
91 {
92     int status;
93     NativePreferences::Options options(path);
94     std::shared_ptr<NativePreferences::Preferences> preferences = NativePreferences::PreferencesHelper::GetPreferences(
95         options, status);
96     if (status != 0) {
97         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::GetPreference failed.");
98         return nullptr;
99     }
100     return preferences;
101 }
Save()102 bool WhiteListConfigMgr::Save()
103 {
104     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "called");
105     if (preferences_ == nullptr) {
106         APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MODULE_COMMON, "preferences null");
107         return false;
108     }
109     std::stringstream strSteam;
110     for (const auto& element : whiteListSet_) {
111         strSteam << element << ",";
112     }
113     auto ret = preferences_->PutString(WHITE_LIST_KEY, strSteam.str());
114     preferences_->Flush();
115     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "WhiteListConfigMgr::Save %{public}s ret%{public}d.",
116         strSteam.str().c_str(), ret);
117     return true;
118 }
119 
IsInWhiteList(const std::string & url)120 bool WhiteListConfigMgr::IsInWhiteList(const std::string& url)
121 {
122     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
123     if (!init) {
124         Load();
125     }
126     std::lock_guard<std::mutex> lock(whiteListLock_);
127     bool ret;
128     if (whiteListSet_.empty()) {
129         ret = (url == defaultWhiteUrl_);
130     } else {
131         ret = (whiteListSet_.count(url) != 0) || (url == defaultWhiteUrl_);
132     }
133     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "is count %{public}d url %{private}s",
134         whiteListSet_.count(url) != 0, url.c_str());
135     return ret;
136 }
UpdateWhiteList(const std::unordered_set<std::string> & whiteList)137 void WhiteListConfigMgr::UpdateWhiteList(const std::unordered_set<std::string>& whiteList)
138 {
139     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
140     if (!init) {
141         Load();
142     }
143     std::unordered_set<std::string> filtedWhiteList;
144     std::for_each(whiteList.begin(), whiteList.end(), [&filtedWhiteList](const std::string& element) {
145         if (UrlUtil::IsValidUrl(element)) {
146             filtedWhiteList.insert(element);
147         }
148     });
149     std::lock_guard<std::mutex> lock(whiteListLock_);
150     whiteListSet_ = filtedWhiteList;
151     if (!whiteListSet_.empty()) {
152         Save();
153     }
154 }
155 
156 }
157