1 /*
2  * Copyright (c) 2022-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 <regex>
17 #include "net_http_proxy_tracker.h"
18 
19 #include "base64_utils.h"
20 #include "net_datashare_utils.h"
21 #include "net_manager_constants.h"
22 #include "net_mgr_log_wrapper.h"
23 #include "netmanager_base_common_utils.h"
24 
25 namespace OHOS {
26 namespace NetManagerStandard {
27 namespace {
28 constexpr const char *EXCLUSIONS_SPLIT_SYMBOL = ",";
29 constexpr const char *DEFAULT_HTTP_PROXY_HOST = "NONE";
30 constexpr const char *DEFAULT_HTTP_PROXY_PORT = "0";
31 constexpr const char *DEFAULT_HTTP_PROXY_EXCLUSION_LIST = "NONE";
32 } // namespace
33 
ReadFromSettingsData(HttpProxy & httpProxy)34 void NetHttpProxyTracker::ReadFromSettingsData(HttpProxy &httpProxy)
35 {
36     Uri hostUri(GLOBAL_PROXY_HOST_URI);
37     Uri portUri(GLOBAL_PROXY_PORT_URI);
38     Uri exclusionsUri(GLOBAL_PROXY_EXCLUSIONS_URI);
39     KeyUri keyUri = {hostUri, portUri, exclusionsUri};
40     ReadFromSettingsData(httpProxy, keyUri);
41 }
42 
WriteToSettingsData(HttpProxy & httpProxy)43 bool NetHttpProxyTracker::WriteToSettingsData(HttpProxy &httpProxy)
44 {
45     Uri hostUri(GLOBAL_PROXY_HOST_URI);
46     Uri portUri(GLOBAL_PROXY_PORT_URI);
47     Uri exclusionsUri(GLOBAL_PROXY_EXCLUSIONS_URI);
48     KeyUri keyUri = {hostUri, portUri, exclusionsUri};
49     return WriteToSettingsData(httpProxy, keyUri);
50 }
51 
ReadFromSettingsDataUser(HttpProxy & httpProxy,int32_t userId)52 void NetHttpProxyTracker::ReadFromSettingsDataUser(HttpProxy &httpProxy, int32_t userId)
53 {
54     Uri hostUri(ReplaceUserIdForUri(USER_PROXY_HOST_URI, userId));
55     Uri portUri(ReplaceUserIdForUri(USER_PROXY_PORT_URI, userId));
56     Uri exclusionsUri(ReplaceUserIdForUri(USER_PROXY_EXCLUSIONS_URI, userId));
57     KeyUri keyUri = {hostUri, portUri, exclusionsUri};
58     ReadFromSettingsData(httpProxy, keyUri);
59 }
60 
WriteToSettingsDataUser(HttpProxy & httpProxy,int32_t userId)61 bool NetHttpProxyTracker::WriteToSettingsDataUser(HttpProxy &httpProxy, int32_t userId)
62 {
63     Uri hostUri(ReplaceUserIdForUri(USER_PROXY_HOST_URI, userId));
64     Uri portUri(ReplaceUserIdForUri(USER_PROXY_PORT_URI, userId));
65     Uri exclusionsUri(ReplaceUserIdForUri(USER_PROXY_EXCLUSIONS_URI, userId));
66     KeyUri keyUri = {hostUri, portUri, exclusionsUri};
67     return WriteToSettingsData(httpProxy, keyUri);
68 }
69 
ReadFromSettingsData(HttpProxy & httpProxy,KeyUri keyUri)70 void NetHttpProxyTracker::ReadFromSettingsData(HttpProxy &httpProxy, KeyUri keyUri)
71 {
72     auto dataShareHelperUtils = std::make_unique<NetDataShareHelperUtils>();
73     std::string proxyHost;
74     std::string proxyPort;
75     std::string proxyExclusions;
76     int32_t ret = dataShareHelperUtils->Query(keyUri.hostUri_, KEY_GLOBAL_PROXY_HOST, proxyHost);
77     if (ret != NETMANAGER_SUCCESS) {
78         NETMGR_LOG_D("Query global proxy host failed.");
79     }
80     std::string host = Base64::Decode(proxyHost);
81     host = (host == DEFAULT_HTTP_PROXY_HOST ? "" : host);
82 
83     ret = dataShareHelperUtils->Query(keyUri.portUri_, KEY_GLOBAL_PROXY_PORT, proxyPort);
84     if (ret != NETMANAGER_SUCCESS) {
85         NETMGR_LOG_D("Query global proxy port failed.");
86     }
87     uint16_t port = (proxyPort.empty() || host.empty()) ? 0 : static_cast<uint16_t>(CommonUtils::StrToUint(proxyPort));
88 
89     ret = dataShareHelperUtils->Query(keyUri.exclusionsUri_, KEY_GLOBAL_PROXY_EXCLUSIONS, proxyExclusions);
90     if (ret != NETMANAGER_SUCCESS) {
91         NETMGR_LOG_D("Query global proxy exclusions failed.");
92     }
93     std::list<std::string> exclusionList =
94         host.empty() ? std::list<std::string>() : ParseExclusionList(proxyExclusions);
95     httpProxy = {host, port, exclusionList};
96 }
97 
WriteToSettingsData(HttpProxy & httpProxy,KeyUri keyUri)98 bool NetHttpProxyTracker::WriteToSettingsData(HttpProxy &httpProxy, KeyUri keyUri)
99 {
100     std::string host =
101         httpProxy.GetHost().empty() ? Base64::Encode(DEFAULT_HTTP_PROXY_HOST) : Base64::Encode(httpProxy.GetHost());
102     auto dataShareHelperUtils = std::make_unique<NetDataShareHelperUtils>();
103     int32_t ret = dataShareHelperUtils->Update(keyUri.hostUri_, KEY_GLOBAL_PROXY_HOST, host);
104     if (ret != NETMANAGER_SUCCESS) {
105         NETMGR_LOG_E("Set host:%{public}s to datashare failed", host.c_str());
106         return false;
107     }
108 
109     std::string port = httpProxy.GetHost().empty() ? DEFAULT_HTTP_PROXY_PORT : std::to_string(httpProxy.GetPort());
110     ret = dataShareHelperUtils->Update(keyUri.portUri_, KEY_GLOBAL_PROXY_PORT, port);
111     if (ret != NETMANAGER_SUCCESS) {
112         NETMGR_LOG_E("Set port:%{public}s to datashare failed", port.c_str());
113         return false;
114     }
115 
116     std::string exclusions = GetExclusionsAsString(httpProxy.GetExclusionList());
117     exclusions = (httpProxy.GetHost().empty() || exclusions.empty()) ? DEFAULT_HTTP_PROXY_EXCLUSION_LIST : exclusions;
118     ret = dataShareHelperUtils->Update(keyUri.exclusionsUri_, KEY_GLOBAL_PROXY_EXCLUSIONS, exclusions);
119     if (ret != NETMANAGER_SUCCESS) {
120         NETMGR_LOG_E("Set exclusions:%{public}s to datashare", exclusions.c_str());
121         return false;
122     }
123     httpProxy.SetExclusionList(ParseExclusionList(exclusions));
124     if (!httpProxy.GetUsername().empty()) {
125         auto userInfoHelp = NetProxyUserinfo::GetInstance();
126         userInfoHelp.SaveHttpProxyHostPass(httpProxy);
127     }
128     return true;
129 }
130 
ParseExclusionList(const std::string & exclusions) const131 std::list<std::string> NetHttpProxyTracker::ParseExclusionList(const std::string &exclusions) const
132 {
133     std::list<std::string> exclusionList;
134     if (exclusions.empty() || exclusions == DEFAULT_HTTP_PROXY_EXCLUSION_LIST) {
135         return exclusionList;
136     }
137     size_t startPos = 0;
138     size_t searchPos = exclusions.find(EXCLUSIONS_SPLIT_SYMBOL);
139     std::string exclusion;
140     while (searchPos != std::string::npos) {
141         exclusion = exclusions.substr(startPos, (searchPos - startPos));
142         exclusionList.push_back(exclusion);
143         startPos = searchPos + 1;
144         searchPos = exclusions.find(EXCLUSIONS_SPLIT_SYMBOL, startPos);
145     }
146     exclusion = exclusions.substr(startPos, (exclusions.size() - startPos));
147     exclusionList.push_back(exclusion);
148     return exclusionList;
149 }
150 
GetExclusionsAsString(const std::list<std::string> & exclusionList) const151 std::string NetHttpProxyTracker::GetExclusionsAsString(const std::list<std::string> &exclusionList) const
152 {
153     std::string exclusions;
154     int32_t index = 0;
155     for (const auto &exclusion : exclusionList) {
156         if (exclusion.empty()) {
157             continue;
158         }
159         if (index > 0) {
160             exclusions = exclusions + EXCLUSIONS_SPLIT_SYMBOL;
161         }
162         exclusions = exclusions + exclusion;
163         index++;
164     }
165     return exclusions;
166 }
167 
ReplaceUserIdForUri(const char * uri,int32_t userId)168 std::string NetHttpProxyTracker::ReplaceUserIdForUri(const char *uri, int32_t userId)
169 {
170     if (strlen(uri) <= 0) {
171         return "";
172     }
173     std::regex pattern(USER_URI_PATTERN);
174     return std::regex_replace(uri, pattern, std::to_string(userId));
175 }
176 } // namespace NetManagerStandard
177 } // namespace OHOS