/*
 * Copyright (C) 2016 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.
 */

#define LOG_TAG "Netd"

#include "SockDiag.h"

#include <errno.h>
#include <linux/inet_diag.h>
#include <linux/netlink.h>
#include <linux/sock_diag.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/uio.h>

#include <cinttypes>

#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <log/log.h>
#include <netdutils/InternetAddresses.h>
#include <netdutils/Stopwatch.h>

#include "Permission.h"

#ifndef SOCK_DESTROY
#define SOCK_DESTROY 21
#endif

#define INET_DIAG_BC_MARK_COND 10

namespace android {

using android::base::StringPrintf;
using netdutils::ScopedAddrinfo;
using netdutils::Stopwatch;

namespace net {
namespace {

int getAdbPort() {
    return android::base::GetIntProperty("service.adb.tcp.port", 0);
}

bool isAdbSocket(const inet_diag_msg *msg, int adbPort) {
    return adbPort > 0 && msg->id.idiag_sport == htons(adbPort) &&
        (msg->idiag_uid == AID_ROOT || msg->idiag_uid == AID_SHELL);
}

int checkError(int fd) {
    struct {
        nlmsghdr h;
        nlmsgerr err;
    } __attribute__((__packed__)) ack;
    ssize_t bytesread = recv(fd, &ack, sizeof(ack), MSG_DONTWAIT | MSG_PEEK);
    if (bytesread == -1) {
       // Read failed (error), or nothing to read (good).
       return (errno == EAGAIN) ? 0 : -errno;
    } else if (bytesread == (ssize_t) sizeof(ack) && ack.h.nlmsg_type == NLMSG_ERROR) {
        // We got an error. Consume it.
        recv(fd, &ack, sizeof(ack), 0);
        return ack.err.error;
    } else {
        // The kernel replied with something. Leave it to the caller.
        return 0;
    }
}

}  // namespace

bool SockDiag::open() {
    if (hasSocks()) {
        return false;
    }

    mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_INET_DIAG);
    mWriteSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_INET_DIAG);
    if (!hasSocks()) {
        closeSocks();
        return false;
    }

    sockaddr_nl nl = { .nl_family = AF_NETLINK };
    if ((connect(mSock, reinterpret_cast<sockaddr *>(&nl), sizeof(nl)) == -1) ||
        (connect(mWriteSock, reinterpret_cast<sockaddr *>(&nl), sizeof(nl)) == -1)) {
        closeSocks();
        return false;
    }

    return true;
}

int SockDiag::sendDumpRequest(uint8_t proto, uint8_t family, uint8_t extensions, uint32_t states,
                              iovec *iov, int iovcnt) {
    struct {
        nlmsghdr nlh;
        inet_diag_req_v2 req;
    } __attribute__((__packed__)) request = {
        .nlh = {
            .nlmsg_type = SOCK_DIAG_BY_FAMILY,
            .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
        },
        .req = {
            .sdiag_family = family,
            .sdiag_protocol = proto,
            .idiag_ext = extensions,
            .idiag_states = states,
        },
    };

    size_t len = 0;
    iov[0].iov_base = &request;
    iov[0].iov_len = sizeof(request);
    for (int i = 0; i < iovcnt; i++) {
        len += iov[i].iov_len;
    }
    request.nlh.nlmsg_len = len;

    ssize_t writevRet = writev(mSock, iov, iovcnt);
    // Don't let pointers to the stack escape.
    iov[0] = {nullptr, 0};
    if (writevRet != (ssize_t)len) {
        return -errno;
    }

    return checkError(mSock);
}

int SockDiag::sendDumpRequest(uint8_t proto, uint8_t family, uint32_t states) {
    iovec iov[] = {
        { nullptr, 0 },
    };
    return sendDumpRequest(proto, family, 0, states, iov, ARRAY_SIZE(iov));
}

int SockDiag::sendDumpRequest(uint8_t proto, uint8_t family, const char *addrstr) {
    addrinfo hints = { .ai_flags = AI_NUMERICHOST };
    addrinfo *res;
    in6_addr mapped = { .s6_addr32 = { 0, 0, htonl(0xffff), 0 } };

    // TODO: refactor the netlink parsing code out of system/core, bring it into netd, and stop
    // doing string conversions when they're not necessary.
    int ret = getaddrinfo(addrstr, nullptr, &hints, &res);
    if (ret != 0) return -EINVAL;

    // So we don't have to call freeaddrinfo on every failure path.
    ScopedAddrinfo resP(res);

    void *addr;
    uint8_t addrlen;
    if (res->ai_family == AF_INET && family == AF_INET) {
        in_addr& ina = reinterpret_cast<sockaddr_in*>(res->ai_addr)->sin_addr;
        addr = &ina;
        addrlen = sizeof(ina);
    } else if (res->ai_family == AF_INET && family == AF_INET6) {
        in_addr& ina = reinterpret_cast<sockaddr_in*>(res->ai_addr)->sin_addr;
        mapped.s6_addr32[3] = ina.s_addr;
        addr = &mapped;
        addrlen = sizeof(mapped);
    } else if (res->ai_family == AF_INET6 && family == AF_INET6) {
        in6_addr& in6a = reinterpret_cast<sockaddr_in6*>(res->ai_addr)->sin6_addr;
        addr = &in6a;
        addrlen = sizeof(in6a);
    } else {
        return -EAFNOSUPPORT;
    }

    uint8_t prefixlen = addrlen * 8;
    uint8_t yesjump = sizeof(inet_diag_bc_op) + sizeof(inet_diag_hostcond) + addrlen;
    uint8_t nojump = yesjump + 4;

    struct {
        nlattr nla;
        inet_diag_bc_op op;
        inet_diag_hostcond cond;
    } __attribute__((__packed__)) attrs = {
        .nla = {
            .nla_type = INET_DIAG_REQ_BYTECODE,
        },
        .op = {
            INET_DIAG_BC_S_COND,
            yesjump,
            nojump,
        },
        .cond = {
            family,
            prefixlen,
            -1,
            {}
        },
    };

    attrs.nla.nla_len = sizeof(attrs) + addrlen;

    iovec iov[] = {
        { nullptr,           0 },
        { &attrs,            sizeof(attrs) },
        { addr,              addrlen },
    };

    uint32_t states = ~(1 << TCP_TIME_WAIT);
    return sendDumpRequest(proto, family, 0, states, iov, ARRAY_SIZE(iov));
}

int SockDiag::readDiagMsg(uint8_t proto, const SockDiag::DestroyFilter& shouldDestroy) {
    NetlinkDumpCallback callback = [this, proto, shouldDestroy] (nlmsghdr *nlh) {
        const inet_diag_msg *msg = reinterpret_cast<inet_diag_msg *>(NLMSG_DATA(nlh));
        if (shouldDestroy(proto, msg)) {
            sockDestroy(proto, msg);
        }
    };

    return processNetlinkDump(mSock, callback);
}

int SockDiag::readDiagMsgWithTcpInfo(const TcpInfoReader& tcpInfoReader) {
    NetlinkDumpCallback callback = [tcpInfoReader] (nlmsghdr *nlh) {
        if (nlh->nlmsg_type != SOCK_DIAG_BY_FAMILY) {
            ALOGE("expected nlmsg_type=SOCK_DIAG_BY_FAMILY, got nlmsg_type=%d", nlh->nlmsg_type);
            return;
        }
        Fwmark mark;
        struct tcp_info *tcpinfo = nullptr;
        uint32_t tcpinfoLength = 0;
        inet_diag_msg *msg = reinterpret_cast<inet_diag_msg *>(NLMSG_DATA(nlh));
        uint32_t attr_len = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*msg));
        struct rtattr *attr = reinterpret_cast<struct rtattr*>(msg+1);
        while (RTA_OK(attr, attr_len)) {
            if (attr->rta_type == INET_DIAG_INFO) {
                tcpinfo = reinterpret_cast<struct tcp_info*>(RTA_DATA(attr));
                tcpinfoLength = RTA_PAYLOAD(attr);
            }
            if (attr->rta_type == INET_DIAG_MARK) {
                mark.intValue = *reinterpret_cast<uint32_t*>(RTA_DATA(attr));
            }
            attr = RTA_NEXT(attr, attr_len);
        }

        tcpInfoReader(mark, msg, tcpinfo, tcpinfoLength);
    };

    return processNetlinkDump(mSock, callback);
}

// Determines whether a socket is a loopback socket. Does not check socket state.
bool SockDiag::isLoopbackSocket(const inet_diag_msg *msg) {
    switch (msg->idiag_family) {
        case AF_INET:
            // Old kernels only copy the IPv4 address and leave the other 12 bytes uninitialized.
            return IN_LOOPBACK(htonl(msg->id.idiag_src[0])) ||
                   IN_LOOPBACK(htonl(msg->id.idiag_dst[0])) ||
                   msg->id.idiag_src[0] == msg->id.idiag_dst[0];

        case AF_INET6: {
            const struct in6_addr *src = (const struct in6_addr *) &msg->id.idiag_src;
            const struct in6_addr *dst = (const struct in6_addr *) &msg->id.idiag_dst;
            return (IN6_IS_ADDR_V4MAPPED(src) && IN_LOOPBACK(src->s6_addr32[3])) ||
                   (IN6_IS_ADDR_V4MAPPED(dst) && IN_LOOPBACK(dst->s6_addr32[3])) ||
                   IN6_IS_ADDR_LOOPBACK(src) || IN6_IS_ADDR_LOOPBACK(dst) ||
                   !memcmp(src, dst, sizeof(*src));
        }
        default:
            return false;
    }
}

int SockDiag::sockDestroy(uint8_t proto, const inet_diag_msg *msg) {
    if (msg == nullptr) {
       return 0;
    }

    DestroyRequest request = {
        .nlh = {
            .nlmsg_type = SOCK_DESTROY,
            .nlmsg_flags = NLM_F_REQUEST,
        },
        .req = {
            .sdiag_family = msg->idiag_family,
            .sdiag_protocol = proto,
            .idiag_states = (uint32_t) (1 << msg->idiag_state),
            .id = msg->id,
        },
    };
    request.nlh.nlmsg_len = sizeof(request);

    if (write(mWriteSock, &request, sizeof(request)) < (ssize_t) sizeof(request)) {
        return -errno;
    }

    int ret = checkError(mWriteSock);
    if (!ret) mSocketsDestroyed++;
    return ret;
}

int SockDiag::destroySockets(uint8_t proto, int family, const char* addrstr, int ifindex) {
    if (!hasSocks()) {
        return -EBADFD;
    }

    if (int ret = sendDumpRequest(proto, family, addrstr)) {
        return ret;
    }

    // Destroy all sockets on the address, except link-local sockets where ifindex doesn't match.
    auto shouldDestroy = [ifindex](uint8_t, const inet_diag_msg* msg) {
        return ifindex == 0 || ifindex == (int)msg->id.idiag_if;
    };

    return readDiagMsg(proto, shouldDestroy);
}

int SockDiag::destroySockets(const char* addrstr, int ifindex) {
    Stopwatch s;
    mSocketsDestroyed = 0;

    std::string where = addrstr;
    if (ifindex) where += StringPrintf(" ifindex %d", ifindex);

    if (!strchr(addrstr, ':')) {  // inet_ntop never returns something like ::ffff:192.0.2.1
        if (int ret = destroySockets(IPPROTO_TCP, AF_INET, addrstr, ifindex)) {
            ALOGE("Failed to destroy IPv4 sockets on %s: %s", where.c_str(), strerror(-ret));
            return ret;
        }
    }
    if (int ret = destroySockets(IPPROTO_TCP, AF_INET6, addrstr, ifindex)) {
        ALOGE("Failed to destroy IPv6 sockets on %s: %s", where.c_str(), strerror(-ret));
        return ret;
    }

    if (mSocketsDestroyed > 0) {
        ALOGI("Destroyed %d sockets on %s in %" PRId64 "us", mSocketsDestroyed, where.c_str(),
              s.timeTakenUs());
    }

    return mSocketsDestroyed;
}

int SockDiag::destroyLiveSockets(const DestroyFilter& destroyFilter, const char *what,
                                 iovec *iov, int iovcnt) {
    const int proto = IPPROTO_TCP;
    const uint32_t states = (1 << TCP_ESTABLISHED) | (1 << TCP_SYN_SENT) | (1 << TCP_SYN_RECV);

    for (const int family : {AF_INET, AF_INET6}) {
        const char *familyName = (family == AF_INET) ? "IPv4" : "IPv6";
        if (int ret = sendDumpRequest(proto, family, 0, states, iov, iovcnt)) {
            ALOGE("Failed to dump %s sockets for %s: %s", familyName, what, strerror(-ret));
            return ret;
        }
        if (int ret = readDiagMsg(proto, destroyFilter)) {
            ALOGE("Failed to destroy %s sockets for %s: %s", familyName, what, strerror(-ret));
            return ret;
        }
    }

    return 0;
}

int SockDiag::getLiveTcpInfos(const TcpInfoReader& tcpInfoReader) {
    const int proto = IPPROTO_TCP;
    const uint32_t states = (1 << TCP_ESTABLISHED) | (1 << TCP_SYN_SENT) | (1 << TCP_SYN_RECV);
    const uint8_t extensions = (1 << INET_DIAG_MEMINFO); // flag for dumping struct tcp_info.

    iovec iov[] = {
        { nullptr, 0 },
    };

    for (const int family : {AF_INET, AF_INET6}) {
        const char *familyName = (family == AF_INET) ? "IPv4" : "IPv6";
        if (int ret = sendDumpRequest(proto, family, extensions, states, iov, ARRAY_SIZE(iov))) {
            ALOGE("Failed to dump %s sockets struct tcp_info: %s", familyName, strerror(-ret));
            return ret;
        }
        if (int ret = readDiagMsgWithTcpInfo(tcpInfoReader)) {
            ALOGE("Failed to read %s sockets struct tcp_info: %s", familyName, strerror(-ret));
            return ret;
        }
    }

    return 0;
}

int SockDiag::destroySockets(uint8_t proto, const uid_t uid, bool excludeLoopback) {
    mSocketsDestroyed = 0;
    Stopwatch s;

    auto shouldDestroy = [uid, excludeLoopback] (uint8_t, const inet_diag_msg *msg) {
        return msg != nullptr &&
               msg->idiag_uid == uid &&
               !(excludeLoopback && isLoopbackSocket(msg));
    };

    for (const int family : {AF_INET, AF_INET6}) {
        const char *familyName = family == AF_INET ? "IPv4" : "IPv6";
        uint32_t states = (1 << TCP_ESTABLISHED) | (1 << TCP_SYN_SENT) | (1 << TCP_SYN_RECV);
        if (int ret = sendDumpRequest(proto, family, states)) {
            ALOGE("Failed to dump %s sockets for UID: %s", familyName, strerror(-ret));
            return ret;
        }
        if (int ret = readDiagMsg(proto, shouldDestroy)) {
            ALOGE("Failed to destroy %s sockets for UID: %s", familyName, strerror(-ret));
            return ret;
        }
    }

    if (mSocketsDestroyed > 0) {
        ALOGI("Destroyed %d sockets for UID in %" PRId64 "us", mSocketsDestroyed, s.timeTakenUs());
    }

    return 0;
}

int SockDiag::destroySockets(const UidRanges& uidRanges, const std::set<uid_t>& skipUids,
                             bool excludeLoopback) {
    mSocketsDestroyed = 0;
    Stopwatch s;

    auto shouldDestroy = [&] (uint8_t, const inet_diag_msg *msg) {
        return msg != nullptr &&
               uidRanges.hasUid(msg->idiag_uid) &&
               skipUids.find(msg->idiag_uid) == skipUids.end() &&
               !(excludeLoopback && isLoopbackSocket(msg)) &&
               !isAdbSocket(msg, getAdbPort());
    };

    iovec iov[] = {
        { nullptr, 0 },
    };

    if (int ret = destroyLiveSockets(shouldDestroy, "UID", iov, ARRAY_SIZE(iov))) {
        return ret;
    }

    if (mSocketsDestroyed > 0) {
        ALOGI("Destroyed %d sockets for %s skip={%s} in %" PRId64 "us", mSocketsDestroyed,
              uidRanges.toString().c_str(), android::base::Join(skipUids, " ").c_str(),
              s.timeTakenUs());
    }

    return 0;
}

// Destroys all "live" (CONNECTED, SYN_SENT, SYN_RECV) TCP sockets on the specified netId where:
// 1. The opening app no longer has permission to use this network, or:
// 2. The opening app does have permission, but did not explicitly select this network.
//
// We destroy sockets without the explicit bit because we want to avoid the situation where a
// privileged app uses its privileges without knowing it is doing so. For example, a privileged app
// might have opened a socket on this network just because it was the default network at the
// time. If we don't kill these sockets, those apps could continue to use them without realizing
// that they are now sending and receiving traffic on a network that is now restricted.
int SockDiag::destroySocketsLackingPermission(unsigned netId, Permission permission,
                                              bool excludeLoopback) {
    struct markmatch {
        inet_diag_bc_op op;
        // TODO: switch to inet_diag_markcond
        __u32 mark;
        __u32 mask;
    } __attribute__((packed));
    constexpr uint8_t matchlen = sizeof(markmatch);

    Fwmark netIdMark, netIdMask;
    netIdMark.netId = netId;
    netIdMask.netId = 0xffff;

    Fwmark controlMark;
    controlMark.explicitlySelected = true;
    controlMark.permission = permission;

    // A SOCK_DIAG bytecode program that accepts the sockets we intend to destroy.
    struct bytecode {
        markmatch netIdMatch;
        markmatch controlMatch;
        inet_diag_bc_op controlJump;
    } __attribute__((packed)) bytecode;

    // The length of the INET_DIAG_BC_JMP instruction.
    constexpr uint8_t jmplen = sizeof(inet_diag_bc_op);
    // Jump exactly this far past the end of the program to reject.
    constexpr uint8_t rejectoffset = sizeof(inet_diag_bc_op);
    // Total length of the program.
    constexpr uint8_t bytecodelen = sizeof(bytecode);

    bytecode = (struct bytecode) {
        // If netId matches, continue, otherwise, reject (i.e., leave socket alone).
        { { INET_DIAG_BC_MARK_COND, matchlen, bytecodelen + rejectoffset },
          netIdMark.intValue, netIdMask.intValue },

        // If explicit and permission bits match, go to the JMP below which rejects the socket
        // (i.e., we leave it alone). Otherwise, jump to the end of the program, which accepts the
        // socket (so we destroy it).
        { { INET_DIAG_BC_MARK_COND, matchlen, matchlen + jmplen },
          controlMark.intValue, controlMark.intValue },

        // This JMP unconditionally rejects the packet by jumping to the reject target. It is
        // necessary to keep the kernel bytecode verifier happy. If we don't have a JMP the bytecode
        // is invalid because the target of every no jump must always be reachable by yes jumps.
        // Without this JMP, the accept target is not reachable by yes jumps and the program will
        // be rejected by the validator.
        { INET_DIAG_BC_JMP, jmplen, jmplen + rejectoffset },

        // We have reached the end of the program. Accept the socket, and destroy it below.
    };

    struct nlattr nla = {
            .nla_len = sizeof(struct nlattr) + bytecodelen,
            .nla_type = INET_DIAG_REQ_BYTECODE,
    };

    iovec iov[] = {
        { nullptr,   0 },
        { &nla,      sizeof(nla) },
        { &bytecode, bytecodelen },
    };

    mSocketsDestroyed = 0;
    Stopwatch s;

    auto shouldDestroy = [&] (uint8_t, const inet_diag_msg *msg) {
        return msg != nullptr && !(excludeLoopback && isLoopbackSocket(msg));
    };

    if (int ret = destroyLiveSockets(shouldDestroy, "permission change", iov, ARRAY_SIZE(iov))) {
        return ret;
    }

    if (mSocketsDestroyed > 0) {
        ALOGI("Destroyed %d sockets for netId %d permission=%d in %" PRId64 "us", mSocketsDestroyed,
              netId, permission, s.timeTakenUs());
    }

    return 0;
}

}  // namespace net
}  // namespace android
