14043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran/* 24043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * Copyright (C) 2014 The Android Open Source Project 34043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * 44043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * Licensed under the Apache License, Version 2.0 (the "License"); 54043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * you may not use this file except in compliance with the License. 64043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * You may obtain a copy of the License at 74043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * 84043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * http://www.apache.org/licenses/LICENSE-2.0 94043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * 104043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * Unless required by applicable law or agreed to in writing, software 114043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * distributed under the License is distributed on an "AS IS" BASIS, 124043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * See the License for the specific language governing permissions and 144043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran * limitations under the License. 154043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran */ 164043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran 17fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti#include <set> 184043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran#include "VirtualNetwork.h" 194043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran 20fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti#include "SockDiag.h" 214043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran#include "RouteController.h" 224043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran 234043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran#define LOG_TAG "Netd" 244043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran#include "log/log.h" 254043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran 267035f228d17e925116b1b64a7c917b3196ab8818Lorenzo Colittinamespace android { 277035f228d17e925116b1b64a7c917b3196ab8818Lorenzo Colittinamespace net { 287035f228d17e925116b1b64a7c917b3196ab8818Lorenzo Colitti 2995684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram RamachandranVirtualNetwork::VirtualNetwork(unsigned netId, bool hasDns, bool secure) : 3095684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandran Network(netId), mHasDns(hasDns), mSecure(secure) { 314043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran} 324043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran 334043f01f8e25f24246efadc710ad7440aab75529Sreeram RamachandranVirtualNetwork::~VirtualNetwork() { 344043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran} 354043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran 36e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandranbool VirtualNetwork::getHasDns() const { 37e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return mHasDns; 384043f01f8e25f24246efadc710ad7440aab75529Sreeram Ramachandran} 39b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran 4095684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandranbool VirtualNetwork::isSecure() const { 4195684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandran return mSecure; 4295684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandran} 4395684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandran 44e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandranbool VirtualNetwork::appliesToUser(uid_t uid) const { 45e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return mUidRanges.hasUid(uid); 4636ed53e37b2639681055b2d3d8777241e7dd6982Sreeram Ramachandran} 4736ed53e37b2639681055b2d3d8777241e7dd6982Sreeram Ramachandran 48fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 49fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colittiint VirtualNetwork::maybeCloseSockets(bool add, const UidRanges& uidRanges, 50fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti const std::set<uid_t>& protectableUsers) { 51fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti if (!mSecure) { 52fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return 0; 53fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 54fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 55fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti SockDiag sd; 56fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti if (!sd.open()) { 57fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return -EBADFD; 58fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 59fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 600726fec82842883a2332318aa675f7f04670db51Lorenzo Colitti if (int ret = sd.destroySockets(uidRanges, protectableUsers, true /* excludeLoopback */)) { 61fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti ALOGE("Failed to close sockets while %s %s to network %d: %s", 62fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti add ? "adding" : "removing", uidRanges.toString().c_str(), mNetId, strerror(-ret)); 63fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return ret; 64fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 65fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 66fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return 0; 67fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti} 68fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 69fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colittiint VirtualNetwork::addUsers(const UidRanges& uidRanges, const std::set<uid_t>& protectableUsers) { 70fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti maybeCloseSockets(true, uidRanges, protectableUsers); 71fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 72b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran for (const std::string& interface : mInterfaces) { 7395684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandran if (int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure, 745009d5ef3fbcdc69d772b528fd22184b7d605afaSreeram Ramachandran uidRanges)) { 75b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId); 76b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return ret; 77b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 78b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 79b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran mUidRanges.add(uidRanges); 80b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return 0; 81b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran} 82b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran 83fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colittiint VirtualNetwork::removeUsers(const UidRanges& uidRanges, 84fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti const std::set<uid_t>& protectableUsers) { 85fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti maybeCloseSockets(false, uidRanges, protectableUsers); 86fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 87b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran for (const std::string& interface : mInterfaces) { 885009d5ef3fbcdc69d772b528fd22184b7d605afaSreeram Ramachandran if (int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(), 8995684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandran mSecure, uidRanges)) { 90b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId); 91b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return ret; 92b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 93b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 94b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran mUidRanges.remove(uidRanges); 95b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return 0; 96b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran} 97e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran 98e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram RamachandranNetwork::Type VirtualNetwork::getType() const { 99e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return VIRTUAL; 100e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran} 101e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran 102e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandranint VirtualNetwork::addInterface(const std::string& interface) { 103e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran if (hasInterface(interface)) { 104e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return 0; 105e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran } 10695684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandran if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure, 107e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran mUidRanges)) { 108e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId); 109e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return ret; 110e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran } 111e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran mInterfaces.insert(interface); 112e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return 0; 113e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran} 114e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran 115e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandranint VirtualNetwork::removeInterface(const std::string& interface) { 116e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran if (!hasInterface(interface)) { 117e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return 0; 118e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran } 119e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(), 12095684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandran mSecure, mUidRanges)) { 121e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId); 122e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return ret; 123e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran } 124e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran mInterfaces.erase(interface); 125e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return 0; 126e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran} 1277035f228d17e925116b1b64a7c917b3196ab8818Lorenzo Colitti 1287035f228d17e925116b1b64a7c917b3196ab8818Lorenzo Colitti} // namespace net 1297035f228d17e925116b1b64a7c917b3196ab8818Lorenzo Colitti} // namespace android 130