/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// THREAD-SAFETY
// -------------
// The methods in this file are called from multiple threads (from CommandListener, FwmarkServer
// and DnsProxyListener). So, all accesses to shared state are guarded by a lock.
//
// In some cases, a single non-const method acquires and releases the lock several times, like so:
//     if (isValidNetwork(...)) {  // isValidNetwork() acquires and releases the lock.
//        setDefaultNetwork(...);  // setDefaultNetwork() also acquires and releases the lock.
//
// It might seem that this allows races where the state changes between the two statements, but in
// fact there are no races because:
//     1. This pattern only occurs in non-const methods (i.e., those that mutate state).
//     2. Only CommandListener calls these non-const methods. The others call only const methods.
//     3. CommandListener only processes one command at a time. I.e., it's serialized.
// Thus, no other mutation can occur in between the two statements above.

#include "NetworkController.h"

#define LOG_TAG "Netd"
#include "log/log.h"

#include "cutils/misc.h"
#include "resolv_netid.h"

#include "Controllers.h"
#include "DummyNetwork.h"
#include "DumpWriter.h"
#include "Fwmark.h"
#include "LocalNetwork.h"
#include "PhysicalNetwork.h"
#include "RouteController.h"
#include "VirtualNetwork.h"

namespace {

// Keep these in sync with ConnectivityService.java.
const unsigned MIN_NET_ID = 100;
const unsigned MAX_NET_ID = 65535;

}  // namespace

const unsigned NetworkController::MIN_OEM_ID   =  1;
const unsigned NetworkController::MAX_OEM_ID   = 50;
const unsigned NetworkController::DUMMY_NET_ID = 51;
// NetIds 52..98 are reserved for future use.
const unsigned NetworkController::LOCAL_NET_ID = 99;

// All calls to methods here are made while holding a write lock on mRWLock.
class NetworkController::DelegateImpl : public PhysicalNetwork::Delegate {
public:
    explicit DelegateImpl(NetworkController* networkController);
    virtual ~DelegateImpl();

    int modifyFallthrough(unsigned vpnNetId, const std::string& physicalInterface,
                          Permission permission, bool add) WARN_UNUSED_RESULT;

private:
    int addFallthrough(const std::string& physicalInterface,
                       Permission permission) override WARN_UNUSED_RESULT;
    int removeFallthrough(const std::string& physicalInterface,
                          Permission permission) override WARN_UNUSED_RESULT;

    int modifyFallthrough(const std::string& physicalInterface, Permission permission,
                          bool add) WARN_UNUSED_RESULT;

    NetworkController* const mNetworkController;
};

NetworkController::DelegateImpl::DelegateImpl(NetworkController* networkController) :
        mNetworkController(networkController) {
}

NetworkController::DelegateImpl::~DelegateImpl() {
}

int NetworkController::DelegateImpl::modifyFallthrough(unsigned vpnNetId,
                                                       const std::string& physicalInterface,
                                                       Permission permission, bool add) {
    if (add) {
        if (int ret = RouteController::addVirtualNetworkFallthrough(vpnNetId,
                                                                    physicalInterface.c_str(),
                                                                    permission)) {
            ALOGE("failed to add fallthrough to %s for VPN netId %u", physicalInterface.c_str(),
                  vpnNetId);
            return ret;
        }
    } else {
        if (int ret = RouteController::removeVirtualNetworkFallthrough(vpnNetId,
                                                                       physicalInterface.c_str(),
                                                                       permission)) {
            ALOGE("failed to remove fallthrough to %s for VPN netId %u", physicalInterface.c_str(),
                  vpnNetId);
            return ret;
        }
    }
    return 0;
}

int NetworkController::DelegateImpl::addFallthrough(const std::string& physicalInterface,
                                                    Permission permission) {
    return modifyFallthrough(physicalInterface, permission, true);
}

int NetworkController::DelegateImpl::removeFallthrough(const std::string& physicalInterface,
                                                       Permission permission) {
    return modifyFallthrough(physicalInterface, permission, false);
}

int NetworkController::DelegateImpl::modifyFallthrough(const std::string& physicalInterface,
                                                       Permission permission, bool add) {
    for (const auto& entry : mNetworkController->mNetworks) {
        if (entry.second->getType() == Network::VIRTUAL) {
            if (int ret = modifyFallthrough(entry.first, physicalInterface, permission, add)) {
                return ret;
            }
        }
    }
    return 0;
}

NetworkController::NetworkController() :
        mDelegateImpl(new NetworkController::DelegateImpl(this)), mDefaultNetId(NETID_UNSET),
        mProtectableUsers({AID_VPN}) {
    mNetworks[LOCAL_NET_ID] = new LocalNetwork(LOCAL_NET_ID);
    mNetworks[DUMMY_NET_ID] = new DummyNetwork(DUMMY_NET_ID);
}

unsigned NetworkController::getDefaultNetwork() const {
    android::RWLock::AutoRLock lock(mRWLock);
    return mDefaultNetId;
}

int NetworkController::setDefaultNetwork(unsigned netId) {
    android::RWLock::AutoWLock lock(mRWLock);

    if (netId == mDefaultNetId) {
        return 0;
    }

    if (netId != NETID_UNSET) {
        Network* network = getNetworkLocked(netId);
        if (!network) {
            ALOGE("no such netId %u", netId);
            return -ENONET;
        }
        if (network->getType() != Network::PHYSICAL) {
            ALOGE("cannot set default to non-physical network with netId %u", netId);
            return -EINVAL;
        }
        if (int ret = static_cast<PhysicalNetwork*>(network)->addAsDefault()) {
            return ret;
        }
    }

    if (mDefaultNetId != NETID_UNSET) {
        Network* network = getNetworkLocked(mDefaultNetId);
        if (!network || network->getType() != Network::PHYSICAL) {
            ALOGE("cannot find previously set default network with netId %u", mDefaultNetId);
            return -ESRCH;
        }
        if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
            return ret;
        }
    }

    mDefaultNetId = netId;
    return 0;
}

uint32_t NetworkController::getNetworkForDns(unsigned* netId, uid_t uid) const {
    android::RWLock::AutoRLock lock(mRWLock);
    Fwmark fwmark;
    fwmark.protectedFromVpn = true;
    fwmark.permission = PERMISSION_SYSTEM;
    if (checkUserNetworkAccessLocked(uid, *netId) == 0) {
        // If a non-zero NetId was explicitly specified, and the user has permission for that
        // network, use that network's DNS servers. Do not fall through to the default network even
        // if the explicitly selected network is a split tunnel VPN: the explicitlySelected bit
        // ensures that the VPN fallthrough rule does not match.
        fwmark.explicitlySelected = true;

        // If the network is a VPN and it doesn't have DNS servers, use the default network's DNS
        // servers (through the default network). Otherwise, the query is guaranteed to fail.
        // http://b/29498052
        Network *network = getNetworkLocked(*netId);
        if (network && network->getType() == Network::VIRTUAL &&
                !static_cast<VirtualNetwork *>(network)->getHasDns()) {
            *netId = mDefaultNetId;
        }
    } else {
        // If the user is subject to a VPN and the VPN provides DNS servers, use those servers
        // (possibly falling through to the default network if the VPN doesn't provide a route to
        // them). Otherwise, use the default network's DNS servers.
        VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
        if (virtualNetwork && virtualNetwork->getHasDns()) {
            *netId = virtualNetwork->getNetId();
        } else {
            // TODO: return an error instead of silently doing the DNS lookup on the wrong network.
            // http://b/27560555
            *netId = mDefaultNetId;
        }
    }
    fwmark.netId = *netId;
    return fwmark.intValue;
}

// Returns the NetId that a given UID would use if no network is explicitly selected. Specifically,
// the VPN that applies to the UID if any; otherwise, the default network.
unsigned NetworkController::getNetworkForUser(uid_t uid) const {
    android::RWLock::AutoRLock lock(mRWLock);
    if (VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid)) {
        return virtualNetwork->getNetId();
    }
    return mDefaultNetId;
}

// Returns the NetId that will be set when a socket connect()s. This is the bypassable VPN that
// applies to the user if any; otherwise, the default network.
//
// In general, we prefer to always set the default network's NetId in connect(), so that if the VPN
// is a split-tunnel and disappears later, the socket continues working (since the default network's
// NetId is still valid). Secure VPNs will correctly grab the socket's traffic since they have a
// high-priority routing rule that doesn't care what NetId the socket has.
//
// But bypassable VPNs have a very low priority rule, so we need to mark the socket with the
// bypassable VPN's NetId if we expect it to get any traffic at all. If the bypassable VPN is a
// split-tunnel, that's okay, because we have fallthrough rules that will direct the fallthrough
// traffic to the default network. But it does mean that if the bypassable VPN goes away (and thus
// the fallthrough rules also go away), the socket that used to fallthrough to the default network
// will stop working.
unsigned NetworkController::getNetworkForConnect(uid_t uid) const {
    android::RWLock::AutoRLock lock(mRWLock);
    VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
    if (virtualNetwork && !virtualNetwork->isSecure()) {
        return virtualNetwork->getNetId();
    }
    return mDefaultNetId;
}

void NetworkController::getNetworkContext(
        unsigned netId, uid_t uid, struct android_net_context* netcontext) const {
    struct android_net_context nc = {
            .app_netid = netId,
            .app_mark = MARK_UNSET,
            .dns_netid = netId,
            .dns_mark = MARK_UNSET,
            .uid = uid,
    };

    // |netId| comes directly (via dnsproxyd) from the value returned by netIdForResolv() in the
    // client process. This value is nonzero iff.:
    //
    // 1. The app specified a netid/nethandle to a DNS resolution method such as:
    //        - [Java] android.net.Network#getAllByName()
    //        - [C/++] android_getaddrinfofornetwork()
    // 2. The app specified a netid/nethandle to be used as a process default via:
    //        - [Java] android.net.ConnectivityManager#bindProcessToNetwork()
    //        - [C/++] android_setprocnetwork()
    // 3. The app called android.net.ConnectivityManager#startUsingNetworkFeature().
    //
    // In all these cases (with the possible exception of #3), the right thing to do is to treat
    // such cases as explicitlySelected.
    const bool explicitlySelected = (nc.app_netid != NETID_UNSET);
    if (!explicitlySelected) {
        nc.app_netid = getNetworkForConnect(uid);
    }

    Fwmark fwmark;
    fwmark.netId = nc.app_netid;
    fwmark.explicitlySelected = explicitlySelected;
    fwmark.protectedFromVpn = canProtect(uid);
    fwmark.permission = getPermissionForUser(uid);
    nc.app_mark = fwmark.intValue;

    nc.dns_mark = getNetworkForDns(&(nc.dns_netid), uid);

    if (netcontext) {
        *netcontext = nc;
    }
}

unsigned NetworkController::getNetworkForInterface(const char* interface) const {
    android::RWLock::AutoRLock lock(mRWLock);
    for (const auto& entry : mNetworks) {
        if (entry.second->hasInterface(interface)) {
            return entry.first;
        }
    }
    return NETID_UNSET;
}

bool NetworkController::isVirtualNetwork(unsigned netId) const {
    android::RWLock::AutoRLock lock(mRWLock);
    Network* network = getNetworkLocked(netId);
    return network && network->getType() == Network::VIRTUAL;
}

int NetworkController::createPhysicalNetwork(unsigned netId, Permission permission) {
    if (!((MIN_NET_ID <= netId && netId <= MAX_NET_ID) ||
          (MIN_OEM_ID <= netId && netId <= MAX_OEM_ID))) {
        ALOGE("invalid netId %u", netId);
        return -EINVAL;
    }

    if (isValidNetwork(netId)) {
        ALOGE("duplicate netId %u", netId);
        return -EEXIST;
    }

    PhysicalNetwork* physicalNetwork = new PhysicalNetwork(netId, mDelegateImpl);
    if (int ret = physicalNetwork->setPermission(permission)) {
        ALOGE("inconceivable! setPermission cannot fail on an empty network");
        delete physicalNetwork;
        return ret;
    }

    android::RWLock::AutoWLock lock(mRWLock);
    mNetworks[netId] = physicalNetwork;
    return 0;
}

int NetworkController::createVirtualNetwork(unsigned netId, bool hasDns, bool secure) {
    if (!(MIN_NET_ID <= netId && netId <= MAX_NET_ID)) {
        ALOGE("invalid netId %u", netId);
        return -EINVAL;
    }

    if (isValidNetwork(netId)) {
        ALOGE("duplicate netId %u", netId);
        return -EEXIST;
    }

    android::RWLock::AutoWLock lock(mRWLock);
    if (int ret = modifyFallthroughLocked(netId, true)) {
        return ret;
    }
    mNetworks[netId] = new VirtualNetwork(netId, hasDns, secure);
    return 0;
}

int NetworkController::destroyNetwork(unsigned netId) {
    if (netId == LOCAL_NET_ID) {
        ALOGE("cannot destroy local network");
        return -EINVAL;
    }
    if (!isValidNetwork(netId)) {
        ALOGE("no such netId %u", netId);
        return -ENONET;
    }

    // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network.

    android::RWLock::AutoWLock lock(mRWLock);
    Network* network = getNetworkLocked(netId);

    // If we fail to destroy a network, things will get stuck badly. Therefore, unlike most of the
    // other network code, ignore failures and attempt to clear out as much state as possible, even
    // if we hit an error on the way. Return the first error that we see.
    int ret = network->clearInterfaces();

    if (mDefaultNetId == netId) {
        if (int err = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
            ALOGE("inconceivable! removeAsDefault cannot fail on an empty network");
            if (!ret) {
                ret = err;
            }
        }
        mDefaultNetId = NETID_UNSET;
    } else if (network->getType() == Network::VIRTUAL) {
        if (int err = modifyFallthroughLocked(netId, false)) {
            if (!ret) {
                ret = err;
            }
        }
    }
    mNetworks.erase(netId);
    delete network;
    _resolv_delete_cache_for_net(netId);
    return ret;
}

int NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) {
    if (!isValidNetwork(netId)) {
        ALOGE("no such netId %u", netId);
        return -ENONET;
    }

    unsigned existingNetId = getNetworkForInterface(interface);
    if (existingNetId != NETID_UNSET && existingNetId != netId) {
        ALOGE("interface %s already assigned to netId %u", interface, existingNetId);
        return -EBUSY;
    }

    android::RWLock::AutoWLock lock(mRWLock);
    return getNetworkLocked(netId)->addInterface(interface);
}

int NetworkController::removeInterfaceFromNetwork(unsigned netId, const char* interface) {
    if (!isValidNetwork(netId)) {
        ALOGE("no such netId %u", netId);
        return -ENONET;
    }

    android::RWLock::AutoWLock lock(mRWLock);
    return getNetworkLocked(netId)->removeInterface(interface);
}

Permission NetworkController::getPermissionForUser(uid_t uid) const {
    android::RWLock::AutoRLock lock(mRWLock);
    return getPermissionForUserLocked(uid);
}

void NetworkController::setPermissionForUsers(Permission permission,
                                              const std::vector<uid_t>& uids) {
    android::RWLock::AutoWLock lock(mRWLock);
    for (uid_t uid : uids) {
        mUsers[uid] = permission;
    }
}

int NetworkController::checkUserNetworkAccess(uid_t uid, unsigned netId) const {
    android::RWLock::AutoRLock lock(mRWLock);
    return checkUserNetworkAccessLocked(uid, netId);
}

int NetworkController::setPermissionForNetworks(Permission permission,
                                                const std::vector<unsigned>& netIds) {
    android::RWLock::AutoWLock lock(mRWLock);
    for (unsigned netId : netIds) {
        Network* network = getNetworkLocked(netId);
        if (!network) {
            ALOGE("no such netId %u", netId);
            return -ENONET;
        }
        if (network->getType() != Network::PHYSICAL) {
            ALOGE("cannot set permissions on non-physical network with netId %u", netId);
            return -EINVAL;
        }

        // TODO: ioctl(SIOCKILLADDR, ...) to kill socets on the network that don't have permission.

        if (int ret = static_cast<PhysicalNetwork*>(network)->setPermission(permission)) {
            return ret;
        }
    }
    return 0;
}

int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) {
    android::RWLock::AutoWLock lock(mRWLock);
    Network* network = getNetworkLocked(netId);
    if (!network) {
        ALOGE("no such netId %u", netId);
        return -ENONET;
    }
    if (network->getType() != Network::VIRTUAL) {
        ALOGE("cannot add users to non-virtual network with netId %u", netId);
        return -EINVAL;
    }
    if (int ret = static_cast<VirtualNetwork*>(network)->addUsers(uidRanges, mProtectableUsers)) {
        return ret;
    }
    return 0;
}

int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) {
    android::RWLock::AutoWLock lock(mRWLock);
    Network* network = getNetworkLocked(netId);
    if (!network) {
        ALOGE("no such netId %u", netId);
        return -ENONET;
    }
    if (network->getType() != Network::VIRTUAL) {
        ALOGE("cannot remove users from non-virtual network with netId %u", netId);
        return -EINVAL;
    }
    if (int ret = static_cast<VirtualNetwork*>(network)->removeUsers(uidRanges,
                                                                     mProtectableUsers)) {
        return ret;
    }
    return 0;
}

int NetworkController::addRoute(unsigned netId, const char* interface, const char* destination,
                                const char* nexthop, bool legacy, uid_t uid) {
    return modifyRoute(netId, interface, destination, nexthop, true, legacy, uid);
}

int NetworkController::removeRoute(unsigned netId, const char* interface, const char* destination,
                                   const char* nexthop, bool legacy, uid_t uid) {
    return modifyRoute(netId, interface, destination, nexthop, false, legacy, uid);
}

bool NetworkController::canProtect(uid_t uid) const {
    android::RWLock::AutoRLock lock(mRWLock);
    return ((getPermissionForUserLocked(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) ||
           mProtectableUsers.find(uid) != mProtectableUsers.end();
}

void NetworkController::allowProtect(const std::vector<uid_t>& uids) {
    android::RWLock::AutoWLock lock(mRWLock);
    mProtectableUsers.insert(uids.begin(), uids.end());
}

void NetworkController::denyProtect(const std::vector<uid_t>& uids) {
    android::RWLock::AutoWLock lock(mRWLock);
    for (uid_t uid : uids) {
        mProtectableUsers.erase(uid);
    }
}

void NetworkController::dump(DumpWriter& dw) {
    android::RWLock::AutoRLock lock(mRWLock);

    dw.incIndent();
    dw.println("NetworkController");

    dw.incIndent();
    dw.println("Default network: %u", mDefaultNetId);

    dw.blankline();
    dw.println("Networks:");
    dw.incIndent();
    for (const auto& i : mNetworks) {
        dw.println(i.second->toString().c_str());
        android::net::gCtls->resolverCtrl.dump(dw, i.first);
        dw.blankline();
    }
    dw.decIndent();

    dw.decIndent();

    dw.decIndent();
}

bool NetworkController::isValidNetwork(unsigned netId) const {
    android::RWLock::AutoRLock lock(mRWLock);
    return getNetworkLocked(netId);
}

Network* NetworkController::getNetworkLocked(unsigned netId) const {
    auto iter = mNetworks.find(netId);
    return iter == mNetworks.end() ? NULL : iter->second;
}

VirtualNetwork* NetworkController::getVirtualNetworkForUserLocked(uid_t uid) const {
    for (const auto& entry : mNetworks) {
        if (entry.second->getType() == Network::VIRTUAL) {
            VirtualNetwork* virtualNetwork = static_cast<VirtualNetwork*>(entry.second);
            if (virtualNetwork->appliesToUser(uid)) {
                return virtualNetwork;
            }
        }
    }
    return NULL;
}

Permission NetworkController::getPermissionForUserLocked(uid_t uid) const {
    auto iter = mUsers.find(uid);
    if (iter != mUsers.end()) {
        return iter->second;
    }
    return uid < FIRST_APPLICATION_UID ? PERMISSION_SYSTEM : PERMISSION_NONE;
}

int NetworkController::checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const {
    Network* network = getNetworkLocked(netId);
    if (!network) {
        return -ENONET;
    }

    // If uid is INVALID_UID, this likely means that we were unable to retrieve the UID of the peer
    // (using SO_PEERCRED). Be safe and deny access to the network, even if it's valid.
    if (uid == INVALID_UID) {
        return -EREMOTEIO;
    }
    Permission userPermission = getPermissionForUserLocked(uid);
    if ((userPermission & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
        return 0;
    }
    if (network->getType() == Network::VIRTUAL) {
        return static_cast<VirtualNetwork*>(network)->appliesToUser(uid) ? 0 : -EPERM;
    }
    VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
    if (virtualNetwork && virtualNetwork->isSecure() &&
            mProtectableUsers.find(uid) == mProtectableUsers.end()) {
        return -EPERM;
    }
    Permission networkPermission = static_cast<PhysicalNetwork*>(network)->getPermission();
    return ((userPermission & networkPermission) == networkPermission) ? 0 : -EACCES;
}

int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination,
                                   const char* nexthop, bool add, bool legacy, uid_t uid) {
    if (!isValidNetwork(netId)) {
        ALOGE("no such netId %u", netId);
        return -ENONET;
    }
    unsigned existingNetId = getNetworkForInterface(interface);
    if (existingNetId == NETID_UNSET) {
        ALOGE("interface %s not assigned to any netId", interface);
        return -ENODEV;
    }
    if (existingNetId != netId) {
        ALOGE("interface %s assigned to netId %u, not %u", interface, existingNetId, netId);
        return -ENOENT;
    }

    RouteController::TableType tableType;
    if (netId == LOCAL_NET_ID) {
        tableType = RouteController::LOCAL_NETWORK;
    } else if (legacy) {
        if ((getPermissionForUser(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
            tableType = RouteController::LEGACY_SYSTEM;
        } else {
            tableType = RouteController::LEGACY_NETWORK;
        }
    } else {
        tableType = RouteController::INTERFACE;
    }

    return add ? RouteController::addRoute(interface, destination, nexthop, tableType) :
                 RouteController::removeRoute(interface, destination, nexthop, tableType);
}

int NetworkController::modifyFallthroughLocked(unsigned vpnNetId, bool add) {
    if (mDefaultNetId == NETID_UNSET) {
        return 0;
    }
    Network* network = getNetworkLocked(mDefaultNetId);
    if (!network) {
        ALOGE("cannot find previously set default network with netId %u", mDefaultNetId);
        return -ESRCH;
    }
    if (network->getType() != Network::PHYSICAL) {
        ALOGE("inconceivable! default network must be a physical network");
        return -EINVAL;
    }
    Permission permission = static_cast<PhysicalNetwork*>(network)->getPermission();
    for (const auto& physicalInterface : network->getInterfaces()) {
        if (int ret = mDelegateImpl->modifyFallthrough(vpnNetId, physicalInterface, permission,
                                                       add)) {
            return ret;
        }
    }
    return 0;
}
