• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "setup_context.h"
17 
18 #include <new>
19 #include <string>
20 #include <vector>
21 
22 #include "inet_addr.h"
23 #include "napi_utils.h"
24 #include "net_manager_constants.h"
25 #include "netmanager_base_common_utils.h"
26 #include "netmgr_ext_log_wrapper.h"
27 #include "route.h"
28 
29 namespace OHOS {
30 namespace NetManagerStandard {
31 namespace {
32 constexpr int32_t NET_MASK_MAX_LENGTH = 32;
33 constexpr int32_t PARAM_JUST_OPTIONS = 1;
34 constexpr int32_t PARAM_OPTIONS_AND_CALLBACK = 2;
35 constexpr const char *CONFIG_ADDRESSES = "addresses";
36 constexpr const char *CONFIG_ROUTES = "routes";
37 constexpr const char *NET_ADDRESS = "address";
38 constexpr const char *NET_FAMILY = "family";
39 constexpr const char *NET_PORT = "port";
40 constexpr const char *NET_PREFIXLENGTH = "prefixLength";
41 constexpr const char *NET_INTERFACE = "interface";
42 constexpr const char *NET_DESTINATION = "destination";
43 constexpr const char *NET_GATEWAY = "gateway";
44 constexpr const char *NET_HAS_GATEWAY = "hasGateway";
45 constexpr const char *NET_ISDEFAULTROUTE = "isDefaultRoute";
46 constexpr const char *CONFIG_DNSADDRESSES = "dnsAddresses";
47 constexpr const char *CONFIG_SEARCHDOMAINS = "searchDomains";
48 constexpr const char *CONFIG_MTU = "mtu";
49 constexpr const char *CONFIG_ISIPV4ACCEPTED = "isIPv4Accepted";
50 constexpr const char *CONFIG_ISIPV6ACCEPTED = "isIPv6Accepted";
51 constexpr const char *CONFIG_ISLEGACY = "isLegacy";
52 constexpr const char *CONFIG_ISMETERED = "isMetered";
53 constexpr const char *CONFIG_ISBLOCKING = "isBlocking";
54 constexpr const char *CONFIG_TRUSTEDAPPLICATIONS = "trustedApplications";
55 constexpr const char *CONFIG_BLOCKEDAPPLICATIONS = "blockedApplications";
CheckParamsType(napi_env env,napi_value * params,size_t paramsCount)56 bool CheckParamsType(napi_env env, napi_value *params, size_t paramsCount)
57 {
58     switch (paramsCount) {
59         case PARAM_JUST_OPTIONS:
60             return (NapiUtils::GetValueType(env, params[0]) == napi_object);
61         case PARAM_OPTIONS_AND_CALLBACK:
62             return ((NapiUtils::GetValueType(env, params[0]) == napi_object) &&
63                     (NapiUtils::GetValueType(env, params[1]) == napi_function));
64         default:
65             return false;
66     }
67 }
68 
GetStringFromJsMandatoryItem(napi_env env,napi_value object,const std::string & key,std::string & value)69 bool GetStringFromJsMandatoryItem(napi_env env, napi_value object, const std::string &key, std::string &value)
70 {
71     if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, key)) != napi_string) {
72         NETMGR_EXT_LOG_E("param [%{public}s] type is mismatch", key.c_str());
73         return false;
74     }
75     value = NapiUtils::GetStringPropertyUtf8(env, object, key);
76     NETMGR_EXT_LOG_I("%{public}s: %{public}s", key.c_str(), value.c_str());
77     return (value.empty()) ? false : true;
78 }
79 
GetStringFromJsOptionItem(napi_env env,napi_value object,const std::string & key,std::string & value)80 void GetStringFromJsOptionItem(napi_env env, napi_value object, const std::string &key, std::string &value)
81 {
82     if (NapiUtils::HasNamedProperty(env, object, key)) {
83         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, key)) == napi_string) {
84             value = NapiUtils::GetStringPropertyUtf8(env, object, key);
85             NETMGR_EXT_LOG_I("%{public}s: %{public}s", key.c_str(), value.c_str());
86         } else {
87             NETMGR_EXT_LOG_E("param [%{public}s] type is mismatch", key.c_str());
88         }
89     }
90 }
91 
GetUint8FromJsOptionItem(napi_env env,napi_value object,const std::string & key,uint8_t & value)92 void GetUint8FromJsOptionItem(napi_env env, napi_value object, const std::string &key, uint8_t &value)
93 {
94     if (NapiUtils::HasNamedProperty(env, object, key)) {
95         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, key)) == napi_number) {
96             value = static_cast<uint8_t>(NapiUtils::GetUint32Property(env, object, key));
97             NETMGR_EXT_LOG_I("%{public}s: %{public}d", key.c_str(), value);
98         } else {
99             NETMGR_EXT_LOG_E("param [%{public}s] type is mismatch", key.c_str());
100         }
101     }
102 }
103 
GetBoolFromJsOptionItem(napi_env env,napi_value object,const std::string & key,bool & value)104 void GetBoolFromJsOptionItem(napi_env env, napi_value object, const std::string &key, bool &value)
105 {
106     if (NapiUtils::HasNamedProperty(env, object, key)) {
107         if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, object, key)) == napi_boolean) {
108             value = NapiUtils::GetBooleanProperty(env, object, key);
109             NETMGR_EXT_LOG_I("%{public}s: %{public}d", key.c_str(), value);
110         } else {
111             NETMGR_EXT_LOG_E("param [%{public}s] type is mismatch", key.c_str());
112         }
113     }
114 }
115 } // namespace
116 
SetUpContext(napi_env env,EventManager * manager)117 SetUpContext::SetUpContext(napi_env env, EventManager *manager) : BaseContext(env, manager) {}
118 
ParseParams(napi_value * params,size_t paramsCount)119 void SetUpContext::ParseParams(napi_value *params, size_t paramsCount)
120 {
121     if (!CheckParamsType(GetEnv(), params, paramsCount)) {
122         NETMGR_EXT_LOG_E("params type is mismatch");
123         SetNeedThrowException(true);
124         SetErrorCode(NETMANAGER_EXT_ERR_PARAMETER_ERROR);
125         return;
126     }
127     if (!ParseVpnConfig(params)) {
128         NETMGR_EXT_LOG_E("parse vpn config from js failed");
129         SetNeedThrowException(true);
130         SetErrorCode(NETMANAGER_EXT_ERR_PARAMETER_ERROR);
131         return;
132     }
133     if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
134         SetParseOK(SetCallback(params[1]) == napi_ok);
135         return;
136     }
137     SetParseOK(true);
138 }
139 
ParseVpnConfig(napi_value * params)140 bool SetUpContext::ParseVpnConfig(napi_value *params)
141 {
142     vpnConfig_ = new (std::nothrow) VpnConfig();
143     if (vpnConfig_ == nullptr) {
144         NETMGR_EXT_LOG_E("vpnConfig is nullptr");
145         return false;
146     }
147     if (!ParseAddrRouteParams(params[0]) || !ParseChoiceableParams(params[0])) {
148         return false;
149     }
150     return true;
151 }
152 
ParseAddress(napi_env env,napi_value address,struct INetAddr & iNetAddr)153 static bool ParseAddress(napi_env env, napi_value address, struct INetAddr &iNetAddr)
154 {
155     napi_value netAddress = NapiUtils::GetNamedProperty(env, address, NET_ADDRESS);
156     if (NapiUtils::GetValueType(env, netAddress) != napi_object) {
157         NETMGR_EXT_LOG_E("param address type is mismatch");
158         return false;
159     }
160 
161     if (!GetStringFromJsMandatoryItem(env, netAddress, NET_ADDRESS, iNetAddr.address_)) {
162         NETMGR_EXT_LOG_E("get address-address failed");
163         return false;
164     }
165 
166     if (!CommonUtils::IsValidIPV4(iNetAddr.address_)) {
167         NETMGR_EXT_LOG_E("invalid ip address [%{public}s]", iNetAddr.address_.c_str());
168         return false;
169     }
170 
171     GetUint8FromJsOptionItem(env, netAddress, NET_FAMILY, iNetAddr.family_);
172     GetUint8FromJsOptionItem(env, netAddress, NET_PORT, iNetAddr.port_);
173 
174     if (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, address, NET_PREFIXLENGTH)) != napi_number) {
175         NETMGR_EXT_LOG_E("param [%{public}s] type is mismatch", NET_PREFIXLENGTH);
176         return false;
177     }
178     iNetAddr.prefixlen_ = static_cast<uint8_t>(NapiUtils::GetUint32Property(env, address, NET_PREFIXLENGTH));
179     NETMGR_EXT_LOG_I("%{public}s: %{public}d", NET_PREFIXLENGTH, iNetAddr.prefixlen_);
180 
181     uint32_t prefix = iNetAddr.prefixlen_;
182     if (prefix == 0 || prefix >= NET_MASK_MAX_LENGTH) {
183         NETMGR_EXT_LOG_E("prefix: %{public}d error", prefix);
184         return false;
185     }
186 
187     uint32_t maskUint = (0xFFFFFFFF << (NET_MASK_MAX_LENGTH - prefix));
188     uint32_t ipAddrUint = CommonUtils::ConvertIpv4Address(iNetAddr.address_);
189     uint32_t subNetAddress = ipAddrUint & maskUint;
190     uint32_t boardcastAddress = subNetAddress | (~maskUint);
191     if ((ipAddrUint == subNetAddress) || (ipAddrUint == boardcastAddress)) {
192         NETMGR_EXT_LOG_E("invalid ip address [%{public}s]", iNetAddr.address_.c_str());
193         return false;
194     }
195     return true;
196 }
197 
ParseDestination(napi_env env,napi_value jsRoute,struct INetAddr & iNetAddr)198 static bool ParseDestination(napi_env env, napi_value jsRoute, struct INetAddr &iNetAddr)
199 {
200     napi_value destination = NapiUtils::GetNamedProperty(env, jsRoute, NET_DESTINATION);
201     if (NapiUtils::GetValueType(env, destination) != napi_object) {
202         NETMGR_EXT_LOG_E("param destination type is mismatch");
203         return false;
204     }
205 
206     napi_value netAddress = NapiUtils::GetNamedProperty(env, destination, NET_ADDRESS);
207     if (NapiUtils::GetValueType(env, netAddress) != napi_object) {
208         NETMGR_EXT_LOG_E("param address type is mismatch");
209         return false;
210     }
211 
212     if (!GetStringFromJsMandatoryItem(env, netAddress, NET_ADDRESS, iNetAddr.address_)) {
213         NETMGR_EXT_LOG_E("get destination-address failed");
214         return false;
215     }
216 
217     if (!CommonUtils::IsValidIPV4(iNetAddr.address_)) {
218         NETMGR_EXT_LOG_E("invalid ip address [%{public}s]", iNetAddr.address_.c_str());
219         return false;
220     }
221 
222     GetUint8FromJsOptionItem(env, netAddress, NET_FAMILY, iNetAddr.family_);
223     GetUint8FromJsOptionItem(env, netAddress, NET_PORT, iNetAddr.port_);
224     GetUint8FromJsOptionItem(env, destination, NET_PREFIXLENGTH, iNetAddr.prefixlen_);
225     return true;
226 }
227 
ParseGateway(napi_env env,napi_value jsRoute,struct INetAddr & iNetAddr)228 static bool ParseGateway(napi_env env, napi_value jsRoute, struct INetAddr &iNetAddr)
229 {
230     napi_value gateway = NapiUtils::GetNamedProperty(env, jsRoute, NET_GATEWAY);
231     if (NapiUtils::GetValueType(env, gateway) != napi_object) {
232         NETMGR_EXT_LOG_E("param gateway type is mismatch");
233         return false;
234     }
235 
236     if (!GetStringFromJsMandatoryItem(env, gateway, NET_ADDRESS, iNetAddr.address_)) {
237         NETMGR_EXT_LOG_E("get gateway-address failed");
238         return false;
239     }
240 
241     GetUint8FromJsOptionItem(env, gateway, NET_FAMILY, iNetAddr.family_);
242     GetUint8FromJsOptionItem(env, gateway, NET_PORT, iNetAddr.port_);
243     return true;
244 }
245 
ParseRoute(napi_env env,napi_value jsRoute,Route & route)246 static bool ParseRoute(napi_env env, napi_value jsRoute, Route &route)
247 {
248     GetStringFromJsOptionItem(env, jsRoute, NET_INTERFACE, route.iface_);
249 
250     if (!ParseDestination(env, jsRoute, route.destination_)) {
251         NETMGR_EXT_LOG_E("ParseDestination failed");
252         return false;
253     }
254     if (!ParseGateway(env, jsRoute, route.gateway_)) {
255         NETMGR_EXT_LOG_E("ParseGateway failed");
256         return false;
257     }
258 
259     GetBoolFromJsOptionItem(env, jsRoute, NET_HAS_GATEWAY, route.hasGateway_);
260     GetBoolFromJsOptionItem(env, jsRoute, NET_ISDEFAULTROUTE, route.isDefaultRoute_);
261     return true;
262 }
263 
ParseAddrRouteParams(napi_value config)264 bool SetUpContext::ParseAddrRouteParams(napi_value config)
265 {
266     // parse addresses.
267     if (NapiUtils::HasNamedProperty(GetEnv(), config, CONFIG_ADDRESSES)) {
268         napi_value addrArray = NapiUtils::GetNamedProperty(GetEnv(), config, CONFIG_ADDRESSES);
269         if (!NapiUtils::IsArray(GetEnv(), addrArray)) {
270             NETMGR_EXT_LOG_E("addresses is not array");
271             return false;
272         }
273         uint32_t addrLength = NapiUtils::GetArrayLength(GetEnv(), addrArray);
274         for (uint32_t i = 0; i < addrLength; ++i) { // set length limit.
275             INetAddr iNetAddr;
276             if (!ParseAddress(GetEnv(), NapiUtils::GetArrayElement(GetEnv(), addrArray, i), iNetAddr)) {
277                 NETMGR_EXT_LOG_E("ParseAddress failed");
278                 return false;
279             }
280             vpnConfig_->addresses_.emplace_back(iNetAddr);
281         }
282     }
283 
284     // parse routes.
285     if (NapiUtils::HasNamedProperty(GetEnv(), config, CONFIG_ROUTES)) {
286         napi_value routes = NapiUtils::GetNamedProperty(GetEnv(), config, CONFIG_ROUTES);
287         if (!NapiUtils::IsArray(GetEnv(), routes)) {
288             NETMGR_EXT_LOG_E("routes is not array");
289             return false;
290         }
291         uint32_t routesLength = NapiUtils::GetArrayLength(GetEnv(), routes);
292         for (uint32_t idx = 0; idx < routesLength; ++idx) { // set length limit.
293             struct Route routeInfo;
294             if (!ParseRoute(GetEnv(), NapiUtils::GetArrayElement(GetEnv(), routes, idx), routeInfo)) {
295                 NETMGR_EXT_LOG_E("ParseRoute failed");
296                 return false;
297             }
298             vpnConfig_->routes_.emplace_back(routeInfo);
299         }
300     }
301     return true;
302 }
303 
ParseOptionArrayString(napi_env env,napi_value config,const std::string & key,std::vector<std::string> & vector)304 static bool ParseOptionArrayString(napi_env env, napi_value config, const std::string &key,
305                                    std::vector<std::string> &vector)
306 {
307     if (NapiUtils::HasNamedProperty(env, config, key)) {
308         napi_value array = NapiUtils::GetNamedProperty(env, config, key);
309         if (!NapiUtils::IsArray(env, array)) {
310             NETMGR_EXT_LOG_E("param [%{public}s] is not array", key.c_str());
311             return false;
312         }
313         uint32_t arrayLength = NapiUtils::GetArrayLength(env, array);
314         for (uint32_t i = 0; i < arrayLength; ++i) {
315             std::string item = NapiUtils::GetStringFromValueUtf8(env, NapiUtils::GetArrayElement(env, array, i));
316             NETMGR_EXT_LOG_D("%{public}s: %{public}s", key.c_str(), item.c_str());
317             vector.push_back(item);
318         }
319     }
320     return true;
321 }
322 
ParseChoiceableParams(napi_value config)323 bool SetUpContext::ParseChoiceableParams(napi_value config)
324 {
325     ParseOptionArrayString(GetEnv(), config, CONFIG_DNSADDRESSES, vpnConfig_->dnsAddresses_);
326     ParseOptionArrayString(GetEnv(), config, CONFIG_SEARCHDOMAINS, vpnConfig_->searchDomains_);
327 
328     if (NapiUtils::HasNamedProperty(GetEnv(), config, CONFIG_MTU)) {
329         if (NapiUtils::GetValueType(GetEnv(), NapiUtils::GetNamedProperty(GetEnv(), config, CONFIG_MTU)) ==
330             napi_number) {
331             vpnConfig_->mtu_ = NapiUtils::GetInt32Property(GetEnv(), config, CONFIG_MTU);
332             NETMGR_EXT_LOG_I("%{public}s: %{public}d", CONFIG_MTU, vpnConfig_->mtu_);
333         } else {
334             NETMGR_EXT_LOG_E("param [%{public}s] type is mismatch", CONFIG_MTU);
335         }
336     }
337 
338     GetBoolFromJsOptionItem(GetEnv(), config, CONFIG_ISIPV4ACCEPTED, vpnConfig_->isAcceptIPv4_);
339     GetBoolFromJsOptionItem(GetEnv(), config, CONFIG_ISIPV6ACCEPTED, vpnConfig_->isAcceptIPv6_);
340     GetBoolFromJsOptionItem(GetEnv(), config, CONFIG_ISLEGACY, vpnConfig_->isLegacy_);
341     GetBoolFromJsOptionItem(GetEnv(), config, CONFIG_ISMETERED, vpnConfig_->isMetered_);
342     GetBoolFromJsOptionItem(GetEnv(), config, CONFIG_ISBLOCKING, vpnConfig_->isBlocking_);
343 
344     ParseOptionArrayString(GetEnv(), config, CONFIG_TRUSTEDAPPLICATIONS, vpnConfig_->acceptedApplications_);
345     ParseOptionArrayString(GetEnv(), config, CONFIG_BLOCKEDAPPLICATIONS, vpnConfig_->refusedApplications_);
346     return true;
347 }
348 } // namespace NetManagerStandard
349 } // namespace OHOS