1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <set>
18 
19 #define LOG_TAG "Netd"
20 
21 #include "VirtualNetwork.h"
22 
23 #include "SockDiag.h"
24 #include "RouteController.h"
25 
26 #include "log/log.h"
27 
28 namespace android {
29 namespace net {
30 
VirtualNetwork(unsigned netId,bool secure)31 VirtualNetwork::VirtualNetwork(unsigned netId, bool secure) : Network(netId), mSecure(secure) {}
32 
~VirtualNetwork()33 VirtualNetwork::~VirtualNetwork() {}
34 
isSecure() const35 bool VirtualNetwork::isSecure() const {
36     return mSecure;
37 }
38 
appliesToUser(uid_t uid) const39 bool VirtualNetwork::appliesToUser(uid_t uid) const {
40     return mUidRanges.hasUid(uid);
41 }
42 
43 
maybeCloseSockets(bool add,const UidRanges & uidRanges,const std::set<uid_t> & protectableUsers)44 int VirtualNetwork::maybeCloseSockets(bool add, const UidRanges& uidRanges,
45                                       const std::set<uid_t>& protectableUsers) {
46     if (!mSecure) {
47         return 0;
48     }
49 
50     SockDiag sd;
51     if (!sd.open()) {
52         return -EBADFD;
53     }
54 
55     if (int ret = sd.destroySockets(uidRanges, protectableUsers, true /* excludeLoopback */)) {
56         ALOGE("Failed to close sockets while %s %s to network %d: %s",
57               add ? "adding" : "removing", uidRanges.toString().c_str(), mNetId, strerror(-ret));
58         return ret;
59     }
60 
61     return 0;
62 }
63 
addUsers(const UidRanges & uidRanges,const std::set<uid_t> & protectableUsers)64 int VirtualNetwork::addUsers(const UidRanges& uidRanges, const std::set<uid_t>& protectableUsers) {
65     maybeCloseSockets(true, uidRanges, protectableUsers);
66 
67     for (const std::string& interface : mInterfaces) {
68         if (int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure,
69                                                                 uidRanges)) {
70             ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
71             return ret;
72         }
73     }
74     mUidRanges.add(uidRanges);
75     return 0;
76 }
77 
removeUsers(const UidRanges & uidRanges,const std::set<uid_t> & protectableUsers)78 int VirtualNetwork::removeUsers(const UidRanges& uidRanges,
79                                 const std::set<uid_t>& protectableUsers) {
80     maybeCloseSockets(false, uidRanges, protectableUsers);
81 
82     for (const std::string& interface : mInterfaces) {
83         if (int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(),
84                                                                      mSecure, uidRanges)) {
85             ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
86             return ret;
87         }
88     }
89     mUidRanges.remove(uidRanges);
90     return 0;
91 }
92 
getType() const93 Network::Type VirtualNetwork::getType() const {
94     return VIRTUAL;
95 }
96 
addInterface(const std::string & interface)97 int VirtualNetwork::addInterface(const std::string& interface) {
98     if (hasInterface(interface)) {
99         return 0;
100     }
101     if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure,
102                                                                 mUidRanges)) {
103         ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId);
104         return ret;
105     }
106     mInterfaces.insert(interface);
107     return 0;
108 }
109 
removeInterface(const std::string & interface)110 int VirtualNetwork::removeInterface(const std::string& interface) {
111     if (!hasInterface(interface)) {
112         return 0;
113     }
114     if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(),
115                                                                      mSecure, mUidRanges)) {
116         ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId);
117         return ret;
118     }
119     mInterfaces.erase(interface);
120     return 0;
121 }
122 
123 }  // namespace net
124 }  // namespace android
125