1 /*
2  * Copyright (c) 2021-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 "conn_manager.h"
17 
18 #include <linux/if_ether.h>
19 #include <net/if.h>
20 #include <ifaddrs.h>
21 #include <string>
22 
23 #include "bpf_def.h"
24 #include "bpf_mapper.h"
25 #include "bpf_path.h"
26 #include "local_network.h"
27 #include "net_manager_constants.h"
28 #include "netmanager_base_common_utils.h"
29 #include "netnative_log_wrapper.h"
30 #include "physical_network.h"
31 #include "virtual_network.h"
32 #include "securec.h"
33 #include "bpf_ring_buffer.h"
34 
35 namespace OHOS {
36 namespace nmd {
37 using namespace NetManagerStandard;
38 namespace {
39 constexpr int32_t INTERFACE_UNSET = -1;
40 constexpr int32_t LOCAL_NET_ID = 99;
41 } // namespace
42 
ConnManager()43 ConnManager::ConnManager()
44 {
45     networks_.EnsureInsert(LOCAL_NET_ID, std::make_shared<LocalNetwork>(LOCAL_NET_ID));
46     defaultNetId_ = 0;
47     needReinitRouteFlag_ = false;
48 }
49 
~ConnManager()50 ConnManager::~ConnManager()
51 {
52     networks_.Clear();
53 }
54 
SetInternetPermission(uint32_t uid,uint8_t allow,uint8_t isBroker)55 int32_t ConnManager::SetInternetPermission(uint32_t uid, uint8_t allow, uint8_t isBroker)
56 {
57     // 0 means root
58     if (uid == 0) {
59         return NETMANAGER_ERROR;
60     }
61     if (isBroker) {
62         BpfMapper<sock_permission_key, sock_permission_value> permissionMap(BROKER_SOCKET_PERMISSION_MAP_PATH,
63                                                                             BPF_F_WRONLY);
64         if (!permissionMap.IsValid()) {
65             return NETMANAGER_ERROR;
66         }
67         // 0 means no permission
68         if (permissionMap.Write(uid, allow, 0) != 0) {
69             return NETMANAGER_ERROR;
70         }
71 
72         return NETMANAGER_SUCCESS;
73     }
74     BpfMapper<sock_permission_key, sock_permission_value> permissionMap(OH_SOCKET_PERMISSION_MAP_PATH, BPF_F_WRONLY);
75     if (!permissionMap.IsValid()) {
76         return NETMANAGER_ERROR;
77     }
78     // 0 means no permission
79     if (permissionMap.Write(uid, allow, 0) != 0) {
80         return NETMANAGER_ERROR;
81     }
82 
83     return NETMANAGER_SUCCESS;
84 }
85 
CreatePhysicalNetwork(uint16_t netId,NetworkPermission permission)86 int32_t ConnManager::CreatePhysicalNetwork(uint16_t netId, NetworkPermission permission)
87 {
88     if (needReinitRouteFlag_) {
89         std::set<int32_t> netIds;
90         networks_.Iterate([&netIds](int32_t id, std::shared_ptr<NetsysNetwork> &NetsysNetworkPtr) {
91             if (id == LOCAL_NET_ID || NetsysNetworkPtr == nullptr) {
92                 return;
93             }
94             netIds.insert(NetsysNetworkPtr->GetNetId());
95         });
96 
97         for (auto netId : netIds) {
98             std::string interfaceName;
99             {
100                 std::lock_guard<std::mutex> lock(interfaceNameMutex_);
101                 interfaceName = physicalInterfaceName_[netId];
102             }
103             RemoveInterfaceFromNetwork(netId, interfaceName);
104             DestroyNetwork(netId);
105         }
106         needReinitRouteFlag_ = false;
107     }
108     std::shared_ptr<NetsysNetwork> network = std::make_shared<PhysicalNetwork>(netId, permission);
109     networks_.EnsureInsert(netId, network);
110     return NETMANAGER_SUCCESS;
111 }
112 
CreateVirtualNetwork(uint16_t netId,bool hasDns)113 int32_t ConnManager::CreateVirtualNetwork(uint16_t netId, bool hasDns)
114 {
115     networks_.EnsureInsert(netId, std::make_shared<VirtualNetwork>(netId, hasDns));
116     return NETMANAGER_SUCCESS;
117 }
118 
DestroyNetwork(int32_t netId)119 int32_t ConnManager::DestroyNetwork(int32_t netId)
120 {
121     if (netId == LOCAL_NET_ID) {
122         NETNATIVE_LOGE("Cannot destroy local network");
123         return NETMANAGER_ERROR;
124     }
125     const auto &net = FindNetworkById(netId);
126     if (std::get<0>(net)) {
127         std::shared_ptr<NetsysNetwork> nw = std::get<1>(net);
128         if (defaultNetId_ == netId) {
129             if (nw->IsPhysical()) {
130                 static_cast<PhysicalNetwork *>(nw.get())->RemoveDefault();
131             }
132             defaultNetId_ = 0;
133         }
134         nw->ClearInterfaces();
135     }
136     networks_.Erase(netId);
137     return NETMANAGER_SUCCESS;
138 }
139 
SetDefaultNetwork(int32_t netId)140 int32_t ConnManager::SetDefaultNetwork(int32_t netId)
141 {
142     if (defaultNetId_ == netId) {
143         return NETMANAGER_SUCCESS;
144     }
145 
146     // check if this network exists
147     const auto &net = FindNetworkById(netId);
148     if (std::get<0>(net)) {
149         std::shared_ptr<NetsysNetwork> nw = std::get<1>(net);
150         if (!nw->IsPhysical()) {
151             NETNATIVE_LOGE("SetDefaultNetwork fail, network :%{public}d is not physical ", netId);
152             return NETMANAGER_ERROR;
153         }
154         static_cast<PhysicalNetwork *>(nw.get())->AddDefault();
155     }
156 
157     if (defaultNetId_ != 0) {
158         const auto &defaultNet = FindNetworkById(defaultNetId_);
159         if (std::get<0>(defaultNet)) {
160             std::shared_ptr<NetsysNetwork> nw = std::get<1>(defaultNet);
161             if (!nw->IsPhysical()) {
162                 NETNATIVE_LOGE("SetDefaultNetwork fail, defaultNetId_ :%{public}d is not physical", defaultNetId_);
163                 return NETMANAGER_ERROR;
164             }
165             static_cast<PhysicalNetwork *>(nw.get())->RemoveDefault();
166         }
167     }
168     defaultNetId_ = netId;
169     return NETMANAGER_SUCCESS;
170 }
171 
ClearDefaultNetwork()172 int32_t ConnManager::ClearDefaultNetwork()
173 {
174     if (defaultNetId_ != 0) {
175         const auto &net = FindNetworkById(defaultNetId_);
176         if (std::get<0>(net)) {
177             std::shared_ptr<NetsysNetwork> nw = std::get<1>(net);
178             if (!nw->IsPhysical()) {
179                 NETNATIVE_LOGE("ClearDefaultNetwork fail, defaultNetId_ :%{public}d is not physical", defaultNetId_);
180                 return NETMANAGER_ERROR;
181             }
182             static_cast<PhysicalNetwork *>(nw.get())->RemoveDefault();
183         }
184     }
185     defaultNetId_ = 0;
186     return NETMANAGER_SUCCESS;
187 }
188 
FindNetworkById(int32_t netId)189 std::tuple<bool, std::shared_ptr<NetsysNetwork>> ConnManager::FindNetworkById(int32_t netId)
190 {
191     NETNATIVE_LOG_D("Entry ConnManager::FindNetworkById netId:%{public}d", netId);
192     std::shared_ptr<NetsysNetwork> netsysNetworkPtr;
193     bool ret = networks_.Find(netId, netsysNetworkPtr);
194     if (ret) {
195         return std::make_tuple(true, netsysNetworkPtr);
196     }
197     return std::make_tuple<bool, std::shared_ptr<NetsysNetwork>>(false, nullptr);
198 }
199 
GetDefaultNetwork() const200 int32_t ConnManager::GetDefaultNetwork() const
201 {
202     return defaultNetId_;
203 }
204 
GetNetworkForInterface(int32_t netId,std::string & interfaceName)205 int32_t ConnManager::GetNetworkForInterface(int32_t netId, std::string &interfaceName)
206 {
207     NETNATIVE_LOG_D("Entry ConnManager::GetNetworkForInterface interfaceName:%{public}s", interfaceName.c_str());
208     std::map<int32_t, std::shared_ptr<NetsysNetwork>>::iterator it;
209     int32_t InterfaceId = INTERFACE_UNSET;
210     bool isInternalNetId = IsInternalNetId(netId);
211     networks_.Iterate([&InterfaceId, &interfaceName, isInternalNetId]
212         (int32_t id, std::shared_ptr<NetsysNetwork> &NetsysNetworkPtr) {
213         if (IsInternalNetId(id) != isInternalNetId) {
214             return;
215         }
216         if (InterfaceId != INTERFACE_UNSET) {
217             return;
218         }
219         if (NetsysNetworkPtr != nullptr) {
220             if (NetsysNetworkPtr->ExistInterface(interfaceName)) {
221                 InterfaceId = id;
222             }
223         }
224     });
225     return InterfaceId;
226 }
227 
AddInterfaceToNetwork(int32_t netId,std::string & interfaceName,NetManagerStandard::NetBearType netBearerType)228 int32_t ConnManager::AddInterfaceToNetwork(int32_t netId, std::string &interfaceName,
229                                            NetManagerStandard::NetBearType netBearerType)
230 {
231     NETNATIVE_LOG_D(
232         "Entry ConnManager::AddInterfaceToNetwork netId:%{public}d, interfaceName:%{public}s, netBearerType: "
233         "%{public}u",
234         netId, interfaceName.c_str(), netBearerType);
235     int32_t alreadySetNetId = GetNetworkForInterface(netId, interfaceName);
236     if ((alreadySetNetId != netId) && (alreadySetNetId != INTERFACE_UNSET)) {
237         NETNATIVE_LOGE("AddInterfaceToNetwork failed alreadySetNetId:%{public}d", alreadySetNetId);
238         return NETMANAGER_ERROR;
239     }
240 
241     const auto &net = FindNetworkById(netId);
242     if (std::get<0>(net)) {
243         // Create Map Table to establish the relationship betweet netId and the id about interfaceName.
244         BpfMapper<net_index, net_interface_name_id> netIdAndIfaceMap(NET_INDEX_AND_IFACE_MAP_PATH, BPF_ANY);
245         if (netIdAndIfaceMap.IsValid()) {
246             net_interface_name_id v = {0};
247             if (netBearerType == BEARER_WIFI) {
248                 v = NETWORK_BEARER_TYPE_WIFI;
249             } else if (netBearerType == BEARER_CELLULAR) {
250                 v = NETWORK_BEARER_TYPE_CELLULAR;
251             } else {
252                 v = NETWORK_BEARER_TYPE_INITIAL;
253             }
254 
255             if (netIdAndIfaceMap.Write(netId, v, 0) != 0) {
256                 NETNATIVE_LOGE("netIdAndIfaceMap add error: netId:%{public}d, interfaceName:%{public}s", netId,
257                     interfaceName.c_str());
258             }
259         }
260         std::shared_ptr<NetsysNetwork> nw = std::get<1>(net);
261         if (nw->IsPhysical()) {
262             std::lock_guard<std::mutex> lock(interfaceNameMutex_);
263             physicalInterfaceName_[netId] = interfaceName;
264         }
265         return nw->AddInterface(interfaceName);
266     }
267     return NETMANAGER_ERROR;
268 }
269 
RemoveInterfaceFromNetwork(int32_t netId,std::string & interfaceName)270 int32_t ConnManager::RemoveInterfaceFromNetwork(int32_t netId, std::string &interfaceName)
271 {
272     int32_t alreadySetNetId = GetNetworkForInterface(netId, interfaceName);
273     if ((alreadySetNetId != netId) || (alreadySetNetId == INTERFACE_UNSET)) {
274         return NETMANAGER_SUCCESS;
275     } else if (alreadySetNetId == netId) {
276         const auto &net = FindNetworkById(netId);
277         if (std::get<0>(net)) {
278             std::shared_ptr<NetsysNetwork> nw = std::get<1>(net);
279             int32_t ret = nw->RemoveInterface(interfaceName);
280             if (nw->IsPhysical()) {
281                 std::lock_guard<std::mutex> lock(interfaceNameMutex_);
282                 physicalInterfaceName_.erase(netId);
283             }
284 
285             BpfMapper<net_index, net_interface_name_id> netIdAndIfaceMap(NET_INDEX_AND_IFACE_MAP_PATH, BPF_ANY);
286             if (netIdAndIfaceMap.IsValid() && netIdAndIfaceMap.Delete(netId) != 0) {
287                 NETNATIVE_LOGE("netIdAndIfaceMap remove error: netId:%{public}d, interfaceName:%{public}s", netId,
288                                interfaceName.c_str());
289             }
290             return ret;
291         }
292     }
293     return NETMANAGER_SUCCESS;
294 }
295 
ReinitRoute()296 int32_t ConnManager::ReinitRoute()
297 {
298     NETNATIVE_LOG_D("ConnManager::ReInitRoute");
299     needReinitRouteFlag_ = true;
300     return NETMANAGER_SUCCESS;
301 }
302 
AddRoute(int32_t netId,std::string interfaceName,std::string destination,std::string nextHop)303 int32_t ConnManager::AddRoute(int32_t netId, std::string interfaceName, std::string destination, std::string nextHop)
304 {
305     return RouteManager::AddRoute(GetTableType(netId), interfaceName, destination, nextHop);
306 }
307 
RemoveRoute(int32_t netId,std::string interfaceName,std::string destination,std::string nextHop)308 int32_t ConnManager::RemoveRoute(int32_t netId, std::string interfaceName, std::string destination, std::string nextHop)
309 {
310     return RouteManager::RemoveRoute(GetTableType(netId), interfaceName, destination, nextHop);
311 }
312 
UpdateRoute(int32_t netId,std::string interfaceName,std::string destination,std::string nextHop)313 int32_t ConnManager::UpdateRoute(int32_t netId, std::string interfaceName, std::string destination, std::string nextHop)
314 {
315     return RouteManager::UpdateRoute(GetTableType(netId), interfaceName, destination, nextHop);
316 }
317 
GetTableType(int32_t netId)318 RouteManager::TableType ConnManager::GetTableType(int32_t netId)
319 {
320     if (netId == LOCAL_NET_ID) {
321         return RouteManager::LOCAL_NETWORK;
322     } else if (FindVirtualNetwork(netId) != nullptr) {
323         return RouteManager::VPN_NETWORK;
324     } else if (NetManagerStandard::IsInternalNetId(netId)) {
325         return RouteManager::INTERNAL_DEFAULT;
326     } else {
327         return RouteManager::INTERFACE;
328     }
329 }
330 
GetFwmarkForNetwork(int32_t netId)331 int32_t ConnManager::GetFwmarkForNetwork(int32_t netId)
332 {
333     return NETMANAGER_ERROR;
334 }
335 
SetPermissionForNetwork(int32_t netId,NetworkPermission permission)336 int32_t ConnManager::SetPermissionForNetwork(int32_t netId, NetworkPermission permission)
337 {
338     return NETMANAGER_ERROR;
339 }
340 
FindVirtualNetwork(int32_t netId)341 std::shared_ptr<NetsysNetwork> ConnManager::FindVirtualNetwork(int32_t netId)
342 {
343     if (netId == LOCAL_NET_ID) {
344         return nullptr;
345     }
346     std::shared_ptr<NetsysNetwork> netsysNetworkPtr = nullptr;
347     auto ret = networks_.Find(netId, netsysNetworkPtr);
348     if (!ret || netsysNetworkPtr == nullptr) {
349         NETNATIVE_LOGE("invalid netId:%{public}d or nw is null.", netId);
350         return nullptr;
351     }
352     if (netsysNetworkPtr->IsPhysical()) {
353         return nullptr;
354     }
355     return netsysNetworkPtr;
356 }
357 
AddUidsToNetwork(int32_t netId,const std::vector<NetManagerStandard::UidRange> & uidRanges)358 int32_t ConnManager::AddUidsToNetwork(int32_t netId, const std::vector<NetManagerStandard::UidRange> &uidRanges)
359 {
360     auto netsysNetwork = FindVirtualNetwork(netId);
361     if (netsysNetwork == nullptr) {
362         NETNATIVE_LOGE("cannot add uids to non-virtual network with netId:%{public}d", netId);
363         return NETMANAGER_ERROR;
364     }
365     return static_cast<VirtualNetwork *>(netsysNetwork.get())->AddUids(uidRanges);
366 }
367 
RemoveUidsFromNetwork(int32_t netId,const std::vector<NetManagerStandard::UidRange> & uidRanges)368 int32_t ConnManager::RemoveUidsFromNetwork(int32_t netId, const std::vector<NetManagerStandard::UidRange> &uidRanges)
369 {
370     auto netsysNetwork = FindVirtualNetwork(netId);
371     if (netsysNetwork == nullptr) {
372         NETNATIVE_LOGE("cannot remove uids from non-virtual network with netId:%{public}d", netId);
373         return NETMANAGER_ERROR;
374     }
375     return static_cast<VirtualNetwork *>(netsysNetwork.get())->RemoveUids(uidRanges);
376 }
377 
GetDumpInfos(std::string & infos)378 void ConnManager::GetDumpInfos(std::string &infos)
379 {
380     static const std::string TAB = "  ";
381     infos.append("Netsys connect manager :\n");
382     infos.append(TAB + "default NetId: " + std::to_string(defaultNetId_) + "\n");
383     networks_.Iterate([&infos](int32_t id, std::shared_ptr<NetsysNetwork> &NetsysNetworkPtr) {
384         infos.append(TAB + "NetId:" + std::to_string(id));
385         std::string interfaces = TAB + "interfaces: {";
386         for (const auto &interface : NetsysNetworkPtr->GetAllInterface()) {
387             interfaces.append(interface + ", ");
388         }
389         infos.append(interfaces + "}\n");
390     });
391 }
392 
SetNetworkAccessPolicy(uint32_t uid,NetManagerStandard::NetworkAccessPolicy policy,bool reconfirmFlag,bool isBroker)393 int32_t ConnManager::SetNetworkAccessPolicy(uint32_t uid, NetManagerStandard::NetworkAccessPolicy policy,
394                                             bool reconfirmFlag, bool isBroker)
395 {
396     NETNATIVE_LOGI("SetNetworkAccessPolicy isBroker: %{public}d", isBroker);
397 
398     if (isBroker) {
399         BpfMapper<app_uid_key, app_uid_key> brokerUidAccessPolicyMap(BROKER_UID_ACCESS_POLICY_MAP_PATH, BPF_F_WRONLY);
400         if (!brokerUidAccessPolicyMap.IsValid()) {
401             return NETMANAGER_ERROR;
402         }
403         // 0 means no permission
404         app_uid_key v = {0};
405         v = uid;
406         if (brokerUidAccessPolicyMap.Write(DEFAULT_BROKER_UID_KEY, v, 0) != 0) {
407             NETNATIVE_LOGE("SetNetworkAccessPolicy Write brokerUidAccessPolicyMap err");
408             return NETMANAGER_ERROR;
409         }
410 
411         NETNATIVE_LOG_D("SetNetworkAccessPolicy brokerUidAccessPolicyMap: %{public}d", isBroker);
412     }
413 
414     BpfMapper<app_uid_key, uid_access_policy_value> uidAccessPolicyMap(APP_UID_PERMISSION_MAP_PATH, BPF_ANY);
415     if (!uidAccessPolicyMap.IsValid()) {
416         NETNATIVE_LOGE("SetNetworkAccessPolicy uidAccessPolicyMap not exist.");
417         return NETMANAGER_ERROR;
418     }
419 
420     uid_access_policy_value v = {0};
421     uid_access_policy_value v2 = {0};
422     (void)uidAccessPolicyMap.Read(uid, v);
423 
424     v.configSetFromFlag = reconfirmFlag;
425     v.diagAckFlag = 0;
426     v.wifiPolicy = policy.wifiAllow;
427     v.cellularPolicy = policy.cellularAllow;
428 
429     if (uidAccessPolicyMap.Write(uid, v, 0) != 0) {
430         NETNATIVE_LOGE("SetNetworkAccessPolicy Write uidAccessPolicyMap err");
431         return NETMANAGER_ERROR;
432     }
433 
434     (void)uidAccessPolicyMap.Read(uid, v2);
435     NETNATIVE_LOG_D(
436         "SetNetworkAccessPolicy Read uid:%{public}u, wifi:%{public}u, cellular:%{public}u, reconfirmFlag:%{public}u",
437         uid, v2.wifiPolicy, v2.cellularPolicy, v2.configSetFromFlag);
438     return NETMANAGER_SUCCESS;
439 }
440 
DeleteNetworkAccessPolicy(uint32_t uid)441 int32_t ConnManager::DeleteNetworkAccessPolicy(uint32_t uid)
442 {
443     BpfMapper<app_uid_key, uid_access_policy_value> uidAccessPolicyMap(APP_UID_PERMISSION_MAP_PATH, BPF_ANY);
444     if (!uidAccessPolicyMap.IsValid()) {
445         NETNATIVE_LOGE("uidAccessPolicyMap not exist");
446         return NETMANAGER_ERROR;
447     }
448 
449     if (uidAccessPolicyMap.Delete(uid) != 0) {
450         NETNATIVE_LOGE("DeleteNetworkAccessPolicy err");
451         return NETMANAGER_ERROR;
452     }
453 
454     return NETMANAGER_SUCCESS;
455 }
456 
NotifyNetBearerTypeChange(std::set<NetManagerStandard::NetBearType> bearerTypes)457 int32_t ConnManager::NotifyNetBearerTypeChange(std::set<NetManagerStandard::NetBearType> bearerTypes)
458 {
459     NETNATIVE_LOG_D("NotifyNetBearerTypeChange");
460     BpfMapper<net_bear_id_key, net_bear_type_map_value> NetBearerTypeMap(NET_BEAR_TYPE_MAP_PATH, BPF_ANY);
461     if (!NetBearerTypeMap.IsValid()) {
462         NETNATIVE_LOGE("NetBearerTypeMap not exist");
463         return NETMANAGER_ERROR;
464     }
465 
466     // -1 means invalid
467     int32_t netbearerType = -1;
468     for (const auto& bearerType : bearerTypes) {
469         if (bearerType == BEARER_CELLULAR) {
470             netbearerType = NETWORK_BEARER_TYPE_CELLULAR;
471         }
472         if (bearerType == BEARER_WIFI) {
473             netbearerType = NETWORK_BEARER_TYPE_WIFI;
474         }
475     }
476     NETNATIVE_LOGI("NotifyNetBearerTypeChange Type: %{public}d", static_cast<int32_t>(netbearerType));
477 
478     net_bear_type_map_value v = 0;
479     int32_t ret = NetBearerTypeMap.Read(0, v);
480 
481     net_bear_id_key key = DEFAULT_NETWORK_BEARER_MAP_KEY;
482     // -1 means current bearer independent network access.
483     if (netbearerType != -1 &&
484         (((ret == NETSYS_SUCCESS) && (static_cast<int32_t>(v) != netbearerType)) || (ret != NETSYS_SUCCESS))) {
485         v = netbearerType;
486         if (NetBearerTypeMap.Write(key, v, 0) != 0) {
487             NETNATIVE_LOGE("Could not update NetBearerTypeMap");
488             return NETMANAGER_ERROR;
489         }
490     }
491 
492     return NETMANAGER_SUCCESS;
493 }
494 } // namespace nmd
495 } // namespace OHOS
496