1a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak/*
2a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * Copyright (C) 2014 The Android Open Source Project
3a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak *
4a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * Licensed under the Apache License, Version 2.0 (the "License");
5a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * you may not use this file except in compliance with the License.
6a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * You may obtain a copy of the License at
7a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak *
8a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak *      http://www.apache.org/licenses/LICENSE-2.0
9a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak *
10a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * Unless required by applicable law or agreed to in writing, software
11a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * distributed under the License is distributed on an "AS IS" BASIS,
12a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * See the License for the specific language governing permissions and
14a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * limitations under the License.
15a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak */
16a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak
1772604075e74af459fb4637404fbf030422c6b6b6Sreeram Ramachandran#ifndef NETD_SERVER_NETWORK_CONTROLLER_H
1872604075e74af459fb4637404fbf030422c6b6b6Sreeram Ramachandran#define NETD_SERVER_NETWORK_CONTROLLER_H
19a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak
20f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran#include "NetdConstants.h"
215c181bf8ca0c89bd9e3e6d8e40bac53d0ee7082fSreeram Ramachandran#include "Permission.h"
22f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran
2372604075e74af459fb4637404fbf030422c6b6b6Sreeram Ramachandran#include "utils/RWLock.h"
245c181bf8ca0c89bd9e3e6d8e40bac53d0ee7082fSreeram Ramachandran
25a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak#include <list>
26a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak#include <map>
2789dad013e4dd98434b0409a84567f38782894029Sreeram Ramachandran#include <set>
28f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran#include <sys/types.h>
2972604075e74af459fb4637404fbf030422c6b6b6Sreeram Ramachandran#include <vector>
30a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak
31f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandranclass Network;
32b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandranclass UidRanges;
33e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandranclass VirtualNetwork;
345c181bf8ca0c89bd9e3e6d8e40bac53d0ee7082fSreeram Ramachandran
35a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak/*
36a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * Keeps track of default, per-pid, and per-uid-range network selection, as
37a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * well as the mark associated with each network. Networks are identified
38a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * by netid. In all set* commands netid == 0 means "unspecified" and is
39a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak * equivalent to clearing the mapping.
40a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak */
41a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczakclass NetworkController {
42a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczakpublic:
43bbdde9909b7b4fd31c5857156ceb00049bf4992dSreeram Ramachandran    static const unsigned MIN_OEM_ID;
44bbdde9909b7b4fd31c5857156ceb00049bf4992dSreeram Ramachandran    static const unsigned MAX_OEM_ID;
45bbdde9909b7b4fd31c5857156ceb00049bf4992dSreeram Ramachandran    static const unsigned LOCAL_NET_ID;
4687475a1471373b72ffc9f81f17dfd7884723fa86Sreeram Ramachandran
47f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    NetworkController();
48a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak
49a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak    unsigned getDefaultNetwork() const;
50f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    int setDefaultNetwork(unsigned netId) WARN_UNUSED_RESULT;
51a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak
521011b4941d96d9fd90bc7243be387b63ec775936Sreeram Ramachandran    // Sets |*netId| to an appropriate NetId to use for DNS for the given user. Call with |*netId|
531011b4941d96d9fd90bc7243be387b63ec775936Sreeram Ramachandran    // set to a non-NETID_UNSET value if the user already has indicated a preference. Returns the
541011b4941d96d9fd90bc7243be387b63ec775936Sreeram Ramachandran    // fwmark value to set on the socket when performing the DNS request.
551011b4941d96d9fd90bc7243be387b63ec775936Sreeram Ramachandran    uint32_t getNetworkForDns(unsigned* netId, uid_t uid) const;
561011b4941d96d9fd90bc7243be387b63ec775936Sreeram Ramachandran    unsigned getNetworkForUser(uid_t uid) const;
571011b4941d96d9fd90bc7243be387b63ec775936Sreeram Ramachandran    unsigned getNetworkForConnect(uid_t uid) const;
58e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran    unsigned getNetworkForInterface(const char* interface) const;
59070b2d296de30e3dbc68c21f542acb1f2914d870Sreeram Ramachandran    bool isVirtualNetwork(unsigned netId) const;
60a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak
61e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran    int createPhysicalNetwork(unsigned netId, Permission permission) WARN_UNUSED_RESULT;
6295684ba176a9fe5ea59207d7202e47fa12bbfdbeSreeram Ramachandran    int createVirtualNetwork(unsigned netId, bool hasDns, bool secure) WARN_UNUSED_RESULT;
63f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    int destroyNetwork(unsigned netId) WARN_UNUSED_RESULT;
645c181bf8ca0c89bd9e3e6d8e40bac53d0ee7082fSreeram Ramachandran
65f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    int addInterfaceToNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT;
66f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    int removeInterfaceFromNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT;
67f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran
68f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    Permission getPermissionForUser(uid_t uid) const;
69f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    void setPermissionForUsers(Permission permission, const std::vector<uid_t>& uids);
70a1067c8d2b2165f1058a3a8216bed4efacfa1c80Lorenzo Colitti    int checkUserNetworkAccess(uid_t uid, unsigned netId) const;
71f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    int setPermissionForNetworks(Permission permission,
72f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran                                 const std::vector<unsigned>& netIds) WARN_UNUSED_RESULT;
73379bd33f7640e2c4bef902be0ed6cb96378c8c2eSreeram Ramachandran
74b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran    int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT;
75b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran    int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT;
76b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran
77de5d5df753dd35d852ac47a6174b06eacd0d5523Sreeram Ramachandran    // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
784c95a125e0930c112555437589f7620575482095Lorenzo Colitti    // route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
79de5d5df753dd35d852ac47a6174b06eacd0d5523Sreeram Ramachandran    //
807619e1bbebdfe643c35ee6be4ac054f5255f0706Sreeram Ramachandran    // Routes are added to tables determined by the interface, so only |interface| is actually used.
817619e1bbebdfe643c35ee6be4ac054f5255f0706Sreeram Ramachandran    // |netId| is given only to sanity check that the interface has the correct netId.
82f7fc8eccb0a6a4fbca4cafdf53f5c167c8f1d755Lorenzo Colitti    int addRoute(unsigned netId, const char* interface, const char* destination,
83f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran                 const char* nexthop, bool legacy, uid_t uid) WARN_UNUSED_RESULT;
84f7fc8eccb0a6a4fbca4cafdf53f5c167c8f1d755Lorenzo Colitti    int removeRoute(unsigned netId, const char* interface, const char* destination,
85f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran                    const char* nexthop, bool legacy, uid_t uid) WARN_UNUSED_RESULT;
8672604075e74af459fb4637404fbf030422c6b6b6Sreeram Ramachandran
87e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran    bool canProtect(uid_t uid) const;
8889dad013e4dd98434b0409a84567f38782894029Sreeram Ramachandran    void allowProtect(const std::vector<uid_t>& uids);
8989dad013e4dd98434b0409a84567f38782894029Sreeram Ramachandran    void denyProtect(const std::vector<uid_t>& uids);
9089dad013e4dd98434b0409a84567f38782894029Sreeram Ramachandran
91a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczakprivate:
92e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran    bool isValidNetwork(unsigned netId) const;
93f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    Network* getNetworkLocked(unsigned netId) const;
94e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran    VirtualNetwork* getVirtualNetworkForUserLocked(uid_t uid) const;
95ed4bd1f7d219f9f5f56763ea02cf4947e78397f6Sreeram Ramachandran    Permission getPermissionForUserLocked(uid_t uid) const;
96a1067c8d2b2165f1058a3a8216bed4efacfa1c80Lorenzo Colitti    int checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const;
977619e1bbebdfe643c35ee6be4ac054f5255f0706Sreeram Ramachandran
98f7fc8eccb0a6a4fbca4cafdf53f5c167c8f1d755Lorenzo Colitti    int modifyRoute(unsigned netId, const char* interface, const char* destination,
99f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran                    const char* nexthop, bool add, bool legacy, uid_t uid) WARN_UNUSED_RESULT;
10048e19b037e7e20674048ef76bf31ce65c741347cSreeram Ramachandran    int modifyFallthroughLocked(unsigned vpnNetId, bool add) WARN_UNUSED_RESULT;
10148e19b037e7e20674048ef76bf31ce65c741347cSreeram Ramachandran
10248e19b037e7e20674048ef76bf31ce65c741347cSreeram Ramachandran    class DelegateImpl;
10348e19b037e7e20674048ef76bf31ce65c741347cSreeram Ramachandran    DelegateImpl* const mDelegateImpl;
1047619e1bbebdfe643c35ee6be4ac054f5255f0706Sreeram Ramachandran
105e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran    // mRWLock guards all accesses to mDefaultNetId, mNetworks, mUsers and mProtectableUsers.
106a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak    mutable android::RWLock mRWLock;
107a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak    unsigned mDefaultNetId;
10836ed53e37b2639681055b2d3d8777241e7dd6982Sreeram Ramachandran    std::map<unsigned, Network*> mNetworks;  // Map keys are NetIds.
109f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran    std::map<uid_t, Permission> mUsers;
11089dad013e4dd98434b0409a84567f38782894029Sreeram Ramachandran    std::set<uid_t> mProtectableUsers;
111a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak};
112a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak
11372604075e74af459fb4637404fbf030422c6b6b6Sreeram Ramachandran#endif  // NETD_SERVER_NETWORK_CONTROLLER_H
114