Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42065ac6 authored by Sreeram Ramachandran's avatar Sreeram Ramachandran
Browse files

Prohibit address families by default unless a VPN explicitly allows them.

Bug: 15972465
Change-Id: I3278d94536fefacc86390c1ba4231680f7be8589
parent 4c4064fa
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -106,6 +106,20 @@ public abstract class NetworkAgent extends Handler {
     */
    public static final int EVENT_UID_RANGES_REMOVED = BASE + 6;

    /**
     * Sent by the NetworkAgent to ConnectivityService to block all routes for a certain address
     * family (AF_INET or AF_INET6) on this Network. For VPNs only.
     * obj = Integer representing the family (AF_INET or AF_INET6)
     */
    public static final int EVENT_BLOCK_ADDRESS_FAMILY = BASE + 7;

    /**
     * Sent by the NetworkAgent to ConnectivityService to unblock routes for a certain address
     * family (AF_INET or AF_INET6) on this Network. For VPNs only.
     * obj = Integer representing the family (AF_INET or AF_INET6)
     */
    public static final int EVENT_UNBLOCK_ADDRESS_FAMILY = BASE + 8;

    public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
            NetworkCapabilities nc, LinkProperties lp, int score) {
        this(looper, context, logTag, ni, nc, lp, score, null);
@@ -228,6 +242,21 @@ public abstract class NetworkAgent extends Handler {
        queueOrSendMessage(EVENT_UID_RANGES_REMOVED, ranges);
    }

    /**
     * Called by the VPN code when it wants to block an address family from being routed, typically
     * because the VPN network doesn't support that family.
     */
    public void blockAddressFamily(int family) {
        queueOrSendMessage(EVENT_BLOCK_ADDRESS_FAMILY, family);
    }

    /**
     * Called by the VPN code when it wants to unblock an address family from being routed.
     */
    public void unblockAddressFamily(int family) {
        queueOrSendMessage(EVENT_UNBLOCK_ADDRESS_FAMILY, family);
    }

    /**
     * Called when ConnectivityService has indicated they no longer want this network.
     * The parent factory should (previously) have received indication of the change
+10 −1
Original line number Diff line number Diff line
@@ -373,6 +373,7 @@ public class VpnService extends Service {
                throw new IllegalArgumentException("Bad address");
            }
            mAddresses.add(new LinkAddress(address, prefixLength));
            mConfig.updateAllowedFamilies(address);
            return this;
        }

@@ -413,6 +414,7 @@ public class VpnService extends Service {
                }
            }
            mRoutes.add(new RouteInfo(new LinkAddress(address, prefixLength), null));
            mConfig.updateAllowedFamilies(address);
            return this;
        }

@@ -497,7 +499,14 @@ public class VpnService extends Service {
         * @return this {@link Builder} object to facilitate chaining of method calls.
         */
        public Builder allowFamily(int family) {
            // TODO
            if (family == AF_INET) {
                mConfig.allowIPv4 = true;
            } else if (family == AF_INET6) {
                mConfig.allowIPv6 = true;
            } else {
                throw new IllegalArgumentException(family + " is neither " + AF_INET + " nor " +
                        AF_INET6);
            }
            return this;
        }

+3 −0
Original line number Diff line number Diff line
@@ -404,4 +404,7 @@ interface INetworkManagementService

    void addInterfaceToLocalNetwork(String iface, in List<RouteInfo> routes);
    void removeInterfaceFromLocalNetwork(String iface);

    void blockAddressFamily(int family, int netId, String iface);
    void unblockAddressFamily(int family, int netId, String iface);
}
+17 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.UserHandle;
import android.net.RouteInfo;
import android.net.LinkAddress;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.List;
import java.util.ArrayList;
@@ -75,6 +76,16 @@ public class VpnConfig implements Parcelable {
    public boolean legacy;
    public boolean blocking;
    public boolean allowBypass;
    public boolean allowIPv4;
    public boolean allowIPv6;

    public void updateAllowedFamilies(InetAddress address) {
        if (address instanceof Inet4Address) {
            allowIPv4 = true;
        } else {
            allowIPv6 = true;
        }
    }

    public void addLegacyRoutes(String routesStr) {
        if (routesStr.trim().equals("")) {
@@ -87,6 +98,7 @@ public class VpnConfig implements Parcelable {
            RouteInfo info = new RouteInfo(new LinkAddress
                    (InetAddress.parseNumericAddress(split[0]), Integer.parseInt(split[1])), null);
            this.routes.add(info);
            updateAllowedFamilies(info.getDestination().getAddress());
        }
    }

@@ -101,6 +113,7 @@ public class VpnConfig implements Parcelable {
            LinkAddress addr = new LinkAddress(InetAddress.parseNumericAddress(split[0]),
                    Integer.parseInt(split[1]));
            this.addresses.add(addr);
            updateAllowedFamilies(addr.getAddress());
        }
    }

@@ -124,6 +137,8 @@ public class VpnConfig implements Parcelable {
        out.writeInt(legacy ? 1 : 0);
        out.writeInt(blocking ? 1 : 0);
        out.writeInt(allowBypass ? 1 : 0);
        out.writeInt(allowIPv4 ? 1 : 0);
        out.writeInt(allowIPv6 ? 1 : 0);
    }

    public static final Parcelable.Creator<VpnConfig> CREATOR =
@@ -144,6 +159,8 @@ public class VpnConfig implements Parcelable {
            config.legacy = in.readInt() != 0;
            config.blocking = in.readInt() != 0;
            config.allowBypass = in.readInt() != 0;
            config.allowIPv4 = in.readInt() != 0;
            config.allowIPv6 = in.readInt() != 0;
            return config;
        }

+36 −2
Original line number Diff line number Diff line
@@ -2940,7 +2940,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
                    }
                    try {
                        mNetd.addVpnUidRanges(nai.network.netId, (UidRange[])msg.obj);
                    } catch (RemoteException e) {
                    } catch (Exception e) {
                        // Never crash!
                        loge("Exception in addVpnUidRanges: " + e);
                    }
                    break;
                }
@@ -2952,7 +2954,39 @@ public class ConnectivityService extends IConnectivityManager.Stub {
                    }
                    try {
                        mNetd.removeVpnUidRanges(nai.network.netId, (UidRange[])msg.obj);
                    } catch (RemoteException e) {
                    } catch (Exception e) {
                        // Never crash!
                        loge("Exception in removeVpnUidRanges: " + e);
                    }
                    break;
                }
                case NetworkAgent.EVENT_BLOCK_ADDRESS_FAMILY: {
                    NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
                    if (nai == null) {
                        loge("EVENT_BLOCK_ADDRESS_FAMILY from unknown NetworkAgent");
                        break;
                    }
                    try {
                        mNetd.blockAddressFamily((Integer) msg.obj, nai.network.netId,
                                nai.linkProperties.getInterfaceName());
                    } catch (Exception e) {
                        // Never crash!
                        loge("Exception in blockAddressFamily: " + e);
                    }
                    break;
                }
                case NetworkAgent.EVENT_UNBLOCK_ADDRESS_FAMILY: {
                    NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
                    if (nai == null) {
                        loge("EVENT_UNBLOCK_ADDRESS_FAMILY from unknown NetworkAgent");
                        break;
                    }
                    try {
                        mNetd.unblockAddressFamily((Integer) msg.obj, nai.network.netId,
                                nai.linkProperties.getInterfaceName());
                    } catch (Exception e) {
                        // Never crash!
                        loge("Exception in blockAddressFamily: " + e);
                    }
                    break;
                }
Loading