Home | History | Annotate | Download | only in connectivity
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.connectivity;
     18 
     19 import static android.Manifest.permission.BIND_VPN_SERVICE;
     20 import static android.net.ConnectivityManager.NETID_UNSET;
     21 import static android.net.RouteInfo.RTN_THROW;
     22 import static android.net.RouteInfo.RTN_UNREACHABLE;
     23 
     24 import android.Manifest;
     25 import android.annotation.NonNull;
     26 import android.annotation.Nullable;
     27 import android.annotation.UserIdInt;
     28 import android.app.AppGlobals;
     29 import android.app.AppOpsManager;
     30 import android.app.Notification;
     31 import android.app.NotificationManager;
     32 import android.app.PendingIntent;
     33 import android.content.BroadcastReceiver;
     34 import android.content.ComponentName;
     35 import android.content.Context;
     36 import android.content.Intent;
     37 import android.content.IntentFilter;
     38 import android.content.ServiceConnection;
     39 import android.content.pm.ApplicationInfo;
     40 import android.content.pm.PackageManager;
     41 import android.content.pm.PackageManager.NameNotFoundException;
     42 import android.content.pm.ResolveInfo;
     43 import android.content.pm.UserInfo;
     44 import android.net.ConnectivityManager;
     45 import android.net.INetworkManagementEventObserver;
     46 import android.net.IpPrefix;
     47 import android.net.LinkAddress;
     48 import android.net.LinkProperties;
     49 import android.net.LocalSocket;
     50 import android.net.LocalSocketAddress;
     51 import android.net.Network;
     52 import android.net.NetworkAgent;
     53 import android.net.NetworkCapabilities;
     54 import android.net.NetworkInfo;
     55 import android.net.NetworkInfo.DetailedState;
     56 import android.net.NetworkMisc;
     57 import android.net.RouteInfo;
     58 import android.net.UidRange;
     59 import android.net.Uri;
     60 import android.net.VpnService;
     61 import android.os.Binder;
     62 import android.os.Build.VERSION_CODES;
     63 import android.os.Bundle;
     64 import android.os.FileUtils;
     65 import android.os.IBinder;
     66 import android.os.INetworkManagementService;
     67 import android.os.Looper;
     68 import android.os.Parcel;
     69 import android.os.ParcelFileDescriptor;
     70 import android.os.PatternMatcher;
     71 import android.os.Process;
     72 import android.os.RemoteException;
     73 import android.os.SystemClock;
     74 import android.os.SystemService;
     75 import android.os.UserHandle;
     76 import android.os.UserManager;
     77 import android.provider.Settings;
     78 import android.security.Credentials;
     79 import android.security.KeyStore;
     80 import android.text.TextUtils;
     81 import android.util.ArraySet;
     82 import android.util.Log;
     83 
     84 import com.android.internal.R;
     85 import com.android.internal.annotations.GuardedBy;
     86 import com.android.internal.annotations.VisibleForTesting;
     87 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
     88 import com.android.internal.net.LegacyVpnInfo;
     89 import com.android.internal.net.VpnConfig;
     90 import com.android.internal.net.VpnInfo;
     91 import com.android.internal.net.VpnProfile;
     92 import com.android.internal.notification.SystemNotificationChannels;
     93 import com.android.server.DeviceIdleController;
     94 import com.android.server.LocalServices;
     95 import com.android.server.net.BaseNetworkObserver;
     96 
     97 import libcore.io.IoUtils;
     98 
     99 import java.io.File;
    100 import java.io.IOException;
    101 import java.io.InputStream;
    102 import java.io.OutputStream;
    103 import java.net.Inet4Address;
    104 import java.net.Inet6Address;
    105 import java.net.InetAddress;
    106 import java.nio.charset.StandardCharsets;
    107 import java.util.ArrayList;
    108 import java.util.Arrays;
    109 import java.util.Collection;
    110 import java.util.Collections;
    111 import java.util.List;
    112 import java.util.Set;
    113 import java.util.SortedSet;
    114 import java.util.TreeSet;
    115 import java.util.concurrent.atomic.AtomicInteger;
    116 
    117 /**
    118  * @hide
    119  */
    120 public class Vpn {
    121     private static final String NETWORKTYPE = "VPN";
    122     private static final String TAG = "Vpn";
    123     private static final boolean LOGD = true;
    124 
    125     // Length of time (in milliseconds) that an app hosting an always-on VPN is placed on
    126     // the device idle whitelist during service launch and VPN bootstrap.
    127     private static final long VPN_LAUNCH_IDLE_WHITELIST_DURATION = 60 * 1000;
    128 
    129     // TODO: create separate trackers for each unique VPN to support
    130     // automated reconnection
    131 
    132     private Context mContext;
    133     private NetworkInfo mNetworkInfo;
    134     private String mPackage;
    135     private int mOwnerUID;
    136     private String mInterface;
    137     private Connection mConnection;
    138     private LegacyVpnRunner mLegacyVpnRunner;
    139     private PendingIntent mStatusIntent;
    140     private volatile boolean mEnableTeardown = true;
    141     private final INetworkManagementService mNetd;
    142     private VpnConfig mConfig;
    143     private NetworkAgent mNetworkAgent;
    144     private final Looper mLooper;
    145     private final NetworkCapabilities mNetworkCapabilities;
    146     private final SystemServices mSystemServices;
    147 
    148     /**
    149      * Whether to keep the connection active after rebooting, or upgrading or reinstalling. This
    150      * only applies to {@link VpnService} connections.
    151      */
    152     private boolean mAlwaysOn = false;
    153 
    154     /**
    155      * Whether to disable traffic outside of this VPN even when the VPN is not connected. System
    156      * apps can still bypass by choosing explicit networks. Has no effect if {@link mAlwaysOn} is
    157      * not set.
    158      */
    159     private boolean mLockdown = false;
    160 
    161     /**
    162      * List of UIDs that are set to use this VPN by default. Normally, every UID in the user is
    163      * added to this set but that can be changed by adding allowed or disallowed applications. It
    164      * is non-null iff the VPN is connected.
    165      *
    166      * Unless the VPN has set allowBypass=true, these UIDs are forced into the VPN.
    167      *
    168      * @see VpnService.Builder#addAllowedApplication(String)
    169      * @see VpnService.Builder#addDisallowedApplication(String)
    170      */
    171     @GuardedBy("this")
    172     private Set<UidRange> mVpnUsers = null;
    173 
    174     /**
    175      * List of UIDs for which networking should be blocked until VPN is ready, during brief periods
    176      * when VPN is not running. For example, during system startup or after a crash.
    177      * @see mLockdown
    178      */
    179     @GuardedBy("this")
    180     private Set<UidRange> mBlockedUsers = new ArraySet<>();
    181 
    182     // Handle of user initiating VPN.
    183     private final int mUserHandle;
    184 
    185     // Listen to package remove and change event in this user
    186     private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
    187         @Override
    188         public void onReceive(Context context, Intent intent) {
    189             final Uri data = intent.getData();
    190             final String packageName = data == null ? null : data.getSchemeSpecificPart();
    191             if (packageName == null) {
    192                 return;
    193             }
    194 
    195             synchronized (Vpn.this) {
    196                 // Avoid race that always-on package has been unset
    197                 if (!packageName.equals(getAlwaysOnPackage())) {
    198                     return;
    199                 }
    200 
    201                 final String action = intent.getAction();
    202                 Log.i(TAG, "Received broadcast " + action + " for always-on package " + packageName
    203                         + " in user " + mUserHandle);
    204 
    205                 switch(action) {
    206                     case Intent.ACTION_PACKAGE_REPLACED:
    207                         // Start vpn after app upgrade
    208                         startAlwaysOnVpn();
    209                         break;
    210                     case Intent.ACTION_PACKAGE_REMOVED:
    211                         final boolean isPackageRemoved = !intent.getBooleanExtra(
    212                                 Intent.EXTRA_REPLACING, false);
    213                         if (isPackageRemoved) {
    214                             setAlwaysOnPackage(null, false);
    215                         }
    216                         break;
    217                 }
    218             }
    219         }
    220     };
    221 
    222     private boolean mIsPackageIntentReceiverRegistered = false;
    223 
    224     public Vpn(Looper looper, Context context, INetworkManagementService netService,
    225             @UserIdInt int userHandle) {
    226         this(looper, context, netService, userHandle, new SystemServices(context));
    227     }
    228 
    229     @VisibleForTesting
    230     protected Vpn(Looper looper, Context context, INetworkManagementService netService,
    231             int userHandle, SystemServices systemServices) {
    232         mContext = context;
    233         mNetd = netService;
    234         mUserHandle = userHandle;
    235         mLooper = looper;
    236         mSystemServices = systemServices;
    237 
    238         mPackage = VpnConfig.LEGACY_VPN;
    239         mOwnerUID = getAppUid(mPackage, mUserHandle);
    240 
    241         try {
    242             netService.registerObserver(mObserver);
    243         } catch (RemoteException e) {
    244             Log.wtf(TAG, "Problem registering observer", e);
    245         }
    246 
    247         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_VPN, 0, NETWORKTYPE, "");
    248         // TODO: Copy metered attribute and bandwidths from physical transport, b/16207332
    249         mNetworkCapabilities = new NetworkCapabilities();
    250         mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_VPN);
    251         mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
    252 
    253         loadAlwaysOnPackage();
    254     }
    255 
    256     /**
    257      * Set if this object is responsible for watching for {@link NetworkInfo}
    258      * teardown. When {@code false}, teardown is handled externally by someone
    259      * else.
    260      */
    261     public void setEnableTeardown(boolean enableTeardown) {
    262         mEnableTeardown = enableTeardown;
    263     }
    264 
    265     /**
    266      * Update current state, dispaching event to listeners.
    267      */
    268     @VisibleForTesting
    269     protected void updateState(DetailedState detailedState, String reason) {
    270         if (LOGD) Log.d(TAG, "setting state=" + detailedState + ", reason=" + reason);
    271         mNetworkInfo.setDetailedState(detailedState, reason, null);
    272         if (mNetworkAgent != null) {
    273             mNetworkAgent.sendNetworkInfo(mNetworkInfo);
    274         }
    275         updateAlwaysOnNotification(detailedState);
    276     }
    277 
    278     /**
    279      * Chooses whether to force all connections to go though VPN.
    280      *
    281      * Used to enable/disable legacy VPN lockdown.
    282      *
    283      * This uses the same ip rule mechanism as {@link #setAlwaysOnPackage(String, boolean)};
    284      * previous settings from calling that function will be replaced and saved with the
    285      * always-on state.
    286      *
    287      * @param lockdown whether to prevent all traffic outside of a VPN.
    288      */
    289     public synchronized void setLockdown(boolean lockdown) {
    290         enforceControlPermissionOrInternalCaller();
    291 
    292         setVpnForcedLocked(lockdown);
    293         mLockdown = lockdown;
    294 
    295         // Update app lockdown setting if it changed. Legacy VPN lockdown status is controlled by
    296         // LockdownVpnTracker.isEnabled() which keeps track of its own state.
    297         if (mAlwaysOn) {
    298             saveAlwaysOnPackage();
    299         }
    300     }
    301 
    302     /**
    303      * Checks if a VPN app supports always-on mode.
    304      *
    305      * In order to support the always-on feature, an app has to
    306      * <ul>
    307      *     <li>target {@link VERSION_CODES#N API 24} or above, and
    308      *     <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}
    309      *         meta-data field.
    310      * </ul>
    311      *
    312      * @param packageName the canonical package name of the VPN app
    313      * @return {@code true} if and only if the VPN app exists and supports always-on mode
    314      */
    315     public boolean isAlwaysOnPackageSupported(String packageName) {
    316         enforceSettingsPermission();
    317 
    318         if (packageName == null) {
    319             return false;
    320         }
    321 
    322         PackageManager pm = mContext.getPackageManager();
    323         ApplicationInfo appInfo = null;
    324         try {
    325             appInfo = pm.getApplicationInfoAsUser(packageName, 0 /*flags*/, mUserHandle);
    326         } catch (NameNotFoundException unused) {
    327             Log.w(TAG, "Can't find \"" + packageName + "\" when checking always-on support");
    328         }
    329         if (appInfo == null || appInfo.targetSdkVersion < VERSION_CODES.N) {
    330             return false;
    331         }
    332 
    333         final Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE);
    334         intent.setPackage(packageName);
    335         List<ResolveInfo> services =
    336                 pm.queryIntentServicesAsUser(intent, PackageManager.GET_META_DATA, mUserHandle);
    337         if (services == null || services.size() == 0) {
    338             return false;
    339         }
    340 
    341         for (ResolveInfo rInfo : services) {
    342             final Bundle metaData = rInfo.serviceInfo.metaData;
    343             if (metaData != null &&
    344                     !metaData.getBoolean(VpnService.SERVICE_META_DATA_SUPPORTS_ALWAYS_ON, true)) {
    345                 return false;
    346             }
    347         }
    348 
    349         return true;
    350     }
    351 
    352     /**
    353      * Configures an always-on VPN connection through a specific application.
    354      * This connection is automatically granted and persisted after a reboot.
    355      *
    356      * <p>The designated package should exist and declare a {@link VpnService} in its
    357      *    manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
    358      *    otherwise the call will fail.
    359      *
    360      * <p>Note that this method does not check if the VPN app supports always-on mode. The check is
    361      *    delayed to {@link #startAlwaysOnVpn()}, which is always called immediately after this
    362      *    method in {@link android.net.IConnectivityManager#setAlwaysOnVpnPackage}.
    363      *
    364      * @param packageName the package to designate as always-on VPN supplier.
    365      * @param lockdown whether to prevent traffic outside of a VPN, for example while connecting.
    366      * @return {@code true} if the package has been set as always-on, {@code false} otherwise.
    367      */
    368     public synchronized boolean setAlwaysOnPackage(String packageName, boolean lockdown) {
    369         enforceControlPermissionOrInternalCaller();
    370 
    371         if (setAlwaysOnPackageInternal(packageName, lockdown)) {
    372             saveAlwaysOnPackage();
    373             return true;
    374         }
    375         return false;
    376     }
    377 
    378     /**
    379      * Configures an always-on VPN connection through a specific application, the same as
    380      * {@link #setAlwaysOnPackage}.
    381      *
    382      * Does not perform permission checks. Does not persist any of the changes to storage.
    383      *
    384      * @param packageName the package to designate as always-on VPN supplier.
    385      * @param lockdown whether to prevent traffic outside of a VPN, for example while connecting.
    386      * @return {@code true} if the package has been set as always-on, {@code false} otherwise.
    387      */
    388     @GuardedBy("this")
    389     private boolean setAlwaysOnPackageInternal(String packageName, boolean lockdown) {
    390         if (VpnConfig.LEGACY_VPN.equals(packageName)) {
    391             Log.w(TAG, "Not setting legacy VPN \"" + packageName + "\" as always-on.");
    392             return false;
    393         }
    394 
    395         if (packageName != null) {
    396             // Pre-authorize new always-on VPN package.
    397             if (!setPackageAuthorization(packageName, true)) {
    398                 return false;
    399             }
    400             mAlwaysOn = true;
    401         } else {
    402             packageName = VpnConfig.LEGACY_VPN;
    403             mAlwaysOn = false;
    404         }
    405 
    406         mLockdown = (mAlwaysOn && lockdown);
    407         if (isCurrentPreparedPackage(packageName)) {
    408             updateAlwaysOnNotification(mNetworkInfo.getDetailedState());
    409         } else {
    410             // Prepare this app. The notification will update as a side-effect of updateState().
    411             prepareInternal(packageName);
    412         }
    413         maybeRegisterPackageChangeReceiverLocked(packageName);
    414         setVpnForcedLocked(mLockdown);
    415         return true;
    416     }
    417 
    418     private static boolean isNullOrLegacyVpn(String packageName) {
    419         return packageName == null || VpnConfig.LEGACY_VPN.equals(packageName);
    420     }
    421 
    422     private void unregisterPackageChangeReceiverLocked() {
    423         // register previous intent filter
    424         if (mIsPackageIntentReceiverRegistered) {
    425             mContext.unregisterReceiver(mPackageIntentReceiver);
    426             mIsPackageIntentReceiverRegistered = false;
    427         }
    428     }
    429 
    430     private void maybeRegisterPackageChangeReceiverLocked(String packageName) {
    431         // Unregister IntentFilter listening for previous always-on package change
    432         unregisterPackageChangeReceiverLocked();
    433 
    434         if (!isNullOrLegacyVpn(packageName)) {
    435             mIsPackageIntentReceiverRegistered = true;
    436 
    437             IntentFilter intentFilter = new IntentFilter();
    438             // Protected intent can only be sent by system. No permission required in register.
    439             intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
    440             intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
    441             intentFilter.addDataScheme("package");
    442             intentFilter.addDataSchemeSpecificPart(packageName, PatternMatcher.PATTERN_LITERAL);
    443             mContext.registerReceiverAsUser(
    444                     mPackageIntentReceiver, UserHandle.of(mUserHandle), intentFilter, null, null);
    445         }
    446     }
    447 
    448     /**
    449      * @return the package name of the VPN controller responsible for always-on VPN,
    450      *         or {@code null} if none is set or always-on VPN is controlled through
    451      *         lockdown instead.
    452      * @hide
    453      */
    454     public synchronized String getAlwaysOnPackage() {
    455         enforceControlPermissionOrInternalCaller();
    456         return (mAlwaysOn ? mPackage : null);
    457     }
    458 
    459     /**
    460      * Save the always-on package and lockdown config into Settings.Secure
    461      */
    462     @GuardedBy("this")
    463     private void saveAlwaysOnPackage() {
    464         final long token = Binder.clearCallingIdentity();
    465         try {
    466             mSystemServices.settingsSecurePutStringForUser(Settings.Secure.ALWAYS_ON_VPN_APP,
    467                     getAlwaysOnPackage(), mUserHandle);
    468             mSystemServices.settingsSecurePutIntForUser(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN,
    469                     (mAlwaysOn && mLockdown ? 1 : 0), mUserHandle);
    470         } finally {
    471             Binder.restoreCallingIdentity(token);
    472         }
    473     }
    474 
    475     /**
    476      * Load the always-on package and lockdown config from Settings.Secure
    477      */
    478     @GuardedBy("this")
    479     private void loadAlwaysOnPackage() {
    480         final long token = Binder.clearCallingIdentity();
    481         try {
    482             final String alwaysOnPackage = mSystemServices.settingsSecureGetStringForUser(
    483                     Settings.Secure.ALWAYS_ON_VPN_APP, mUserHandle);
    484             final boolean alwaysOnLockdown = mSystemServices.settingsSecureGetIntForUser(
    485                     Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, 0 /*default*/, mUserHandle) != 0;
    486             setAlwaysOnPackageInternal(alwaysOnPackage, alwaysOnLockdown);
    487         } finally {
    488             Binder.restoreCallingIdentity(token);
    489         }
    490     }
    491 
    492     /**
    493      * @return {@code true} if the service was started, the service was already connected, or there
    494      *         was no always-on VPN to start. {@code false} otherwise.
    495      */
    496     public boolean startAlwaysOnVpn() {
    497         final String alwaysOnPackage;
    498         synchronized (this) {
    499             alwaysOnPackage = getAlwaysOnPackage();
    500             // Skip if there is no service to start.
    501             if (alwaysOnPackage == null) {
    502                 return true;
    503             }
    504             // Remove always-on VPN if it's not supported.
    505             if (!isAlwaysOnPackageSupported(alwaysOnPackage)) {
    506                 setAlwaysOnPackage(null, false);
    507                 return false;
    508             }
    509             // Skip if the service is already established. This isn't bulletproof: it's not bound
    510             // until after establish(), so if it's mid-setup onStartCommand will be sent twice,
    511             // which may restart the connection.
    512             if (getNetworkInfo().isConnected()) {
    513                 return true;
    514             }
    515         }
    516 
    517         // Tell the OS that background services in this app need to be allowed for
    518         // a short time, so we can bootstrap the VPN service.
    519         final long oldId = Binder.clearCallingIdentity();
    520         try {
    521             DeviceIdleController.LocalService idleController =
    522                     LocalServices.getService(DeviceIdleController.LocalService.class);
    523             idleController.addPowerSaveTempWhitelistApp(Process.myUid(), alwaysOnPackage,
    524                     VPN_LAUNCH_IDLE_WHITELIST_DURATION, mUserHandle, false, "vpn");
    525 
    526             // Start the VPN service declared in the app's manifest.
    527             Intent serviceIntent = new Intent(VpnConfig.SERVICE_INTERFACE);
    528             serviceIntent.setPackage(alwaysOnPackage);
    529             try {
    530                 return mContext.startServiceAsUser(serviceIntent, UserHandle.of(mUserHandle)) != null;
    531             } catch (RuntimeException e) {
    532                 Log.e(TAG, "VpnService " + serviceIntent + " failed to start", e);
    533                 return false;
    534             }
    535         } finally {
    536             Binder.restoreCallingIdentity(oldId);
    537         }
    538     }
    539 
    540     /**
    541      * Prepare for a VPN application. This method is designed to solve
    542      * race conditions. It first compares the current prepared package
    543      * with {@code oldPackage}. If they are the same, the prepared
    544      * package is revoked and replaced with {@code newPackage}. If
    545      * {@code oldPackage} is {@code null}, the comparison is omitted.
    546      * If {@code newPackage} is the same package or {@code null}, the
    547      * revocation is omitted. This method returns {@code true} if the
    548      * operation is succeeded.
    549      *
    550      * Legacy VPN is handled specially since it is not a real package.
    551      * It uses {@link VpnConfig#LEGACY_VPN} as its package name, and
    552      * it can be revoked by itself.
    553      *
    554      * Note: when we added VPN pre-consent in http://ag/522961 the names oldPackage
    555      * and newPackage become misleading, because when an app is pre-consented, we
    556      * actually prepare oldPackage, not newPackage.
    557      *
    558      * Their meanings actually are:
    559      *
    560      * - oldPackage non-null, newPackage null: App calling VpnService#prepare().
    561      * - oldPackage null, newPackage non-null: ConfirmDialog calling prepareVpn().
    562      * - oldPackage null, newPackage=LEGACY_VPN: Used internally to disconnect
    563      *   and revoke any current app VPN and re-prepare legacy vpn.
    564      *
    565      * TODO: Rename the variables - or split this method into two - and end this confusion.
    566      * TODO: b/29032008 Migrate code from prepare(oldPackage=non-null, newPackage=LEGACY_VPN)
    567      * to prepare(oldPackage=null, newPackage=LEGACY_VPN)
    568      *
    569      * @param oldPackage The package name of the old VPN application
    570      * @param newPackage The package name of the new VPN application
    571      *
    572      * @return true if the operation is succeeded.
    573      */
    574     public synchronized boolean prepare(String oldPackage, String newPackage) {
    575         if (oldPackage != null) {
    576             // Stop an existing always-on VPN from being dethroned by other apps.
    577             if (mAlwaysOn && !isCurrentPreparedPackage(oldPackage)) {
    578                 return false;
    579             }
    580 
    581             // Package is not same or old package was reinstalled.
    582             if (!isCurrentPreparedPackage(oldPackage)) {
    583                 // The package doesn't match. We return false (to obtain user consent) unless the
    584                 // user has already consented to that VPN package.
    585                 if (!oldPackage.equals(VpnConfig.LEGACY_VPN) && isVpnUserPreConsented(oldPackage)) {
    586                     prepareInternal(oldPackage);
    587                     return true;
    588                 }
    589                 return false;
    590             } else if (!oldPackage.equals(VpnConfig.LEGACY_VPN)
    591                     && !isVpnUserPreConsented(oldPackage)) {
    592                 // Currently prepared VPN is revoked, so unprepare it and return false.
    593                 prepareInternal(VpnConfig.LEGACY_VPN);
    594                 return false;
    595             }
    596         }
    597 
    598         // Return true if we do not need to revoke.
    599         if (newPackage == null || (!newPackage.equals(VpnConfig.LEGACY_VPN) &&
    600                 isCurrentPreparedPackage(newPackage))) {
    601             return true;
    602         }
    603 
    604         // Check that the caller is authorized.
    605         enforceControlPermission();
    606 
    607         // Stop an existing always-on VPN from being dethroned by other apps.
    608         if (mAlwaysOn && !isCurrentPreparedPackage(newPackage)) {
    609             return false;
    610         }
    611 
    612         prepareInternal(newPackage);
    613         return true;
    614     }
    615 
    616     private boolean isCurrentPreparedPackage(String packageName) {
    617         // We can't just check that packageName matches mPackage, because if the app was uninstalled
    618         // and reinstalled it will no longer be prepared. Instead check the UID.
    619         return getAppUid(packageName, mUserHandle) == mOwnerUID;
    620     }
    621 
    622     /** Prepare the VPN for the given package. Does not perform permission checks. */
    623     private void prepareInternal(String newPackage) {
    624         long token = Binder.clearCallingIdentity();
    625         try {
    626             // Reset the interface.
    627             if (mInterface != null) {
    628                 mStatusIntent = null;
    629                 agentDisconnect();
    630                 jniReset(mInterface);
    631                 mInterface = null;
    632                 mVpnUsers = null;
    633             }
    634 
    635             // Revoke the connection or stop LegacyVpnRunner.
    636             if (mConnection != null) {
    637                 try {
    638                     mConnection.mService.transact(IBinder.LAST_CALL_TRANSACTION,
    639                             Parcel.obtain(), null, IBinder.FLAG_ONEWAY);
    640                 } catch (Exception e) {
    641                     // ignore
    642                 }
    643                 mContext.unbindService(mConnection);
    644                 mConnection = null;
    645             } else if (mLegacyVpnRunner != null) {
    646                 mLegacyVpnRunner.exit();
    647                 mLegacyVpnRunner = null;
    648             }
    649 
    650             try {
    651                 mNetd.denyProtect(mOwnerUID);
    652             } catch (Exception e) {
    653                 Log.wtf(TAG, "Failed to disallow UID " + mOwnerUID + " to call protect() " + e);
    654             }
    655 
    656             Log.i(TAG, "Switched from " + mPackage + " to " + newPackage);
    657             mPackage = newPackage;
    658             mOwnerUID = getAppUid(newPackage, mUserHandle);
    659             try {
    660                 mNetd.allowProtect(mOwnerUID);
    661             } catch (Exception e) {
    662                 Log.wtf(TAG, "Failed to allow UID " + mOwnerUID + " to call protect() " + e);
    663             }
    664             mConfig = null;
    665 
    666             updateState(DetailedState.IDLE, "prepare");
    667             setVpnForcedLocked(mLockdown);
    668         } finally {
    669             Binder.restoreCallingIdentity(token);
    670         }
    671     }
    672 
    673     /**
    674      * Set whether a package has the ability to launch VPNs without user intervention.
    675      */
    676     public boolean setPackageAuthorization(String packageName, boolean authorized) {
    677         // Check if the caller is authorized.
    678         enforceControlPermissionOrInternalCaller();
    679 
    680         int uid = getAppUid(packageName, mUserHandle);
    681         if (uid == -1 || VpnConfig.LEGACY_VPN.equals(packageName)) {
    682             // Authorization for nonexistent packages (or fake ones) can't be updated.
    683             return false;
    684         }
    685 
    686         long token = Binder.clearCallingIdentity();
    687         try {
    688             AppOpsManager appOps =
    689                     (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
    690             appOps.setMode(AppOpsManager.OP_ACTIVATE_VPN, uid, packageName,
    691                     authorized ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
    692             return true;
    693         } catch (Exception e) {
    694             Log.wtf(TAG, "Failed to set app ops for package " + packageName + ", uid " + uid, e);
    695         } finally {
    696             Binder.restoreCallingIdentity(token);
    697         }
    698         return false;
    699     }
    700 
    701     private boolean isVpnUserPreConsented(String packageName) {
    702         AppOpsManager appOps =
    703                 (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
    704 
    705         // Verify that the caller matches the given package and has permission to activate VPNs.
    706         return appOps.noteOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN, Binder.getCallingUid(),
    707                 packageName) == AppOpsManager.MODE_ALLOWED;
    708     }
    709 
    710     private int getAppUid(String app, int userHandle) {
    711         if (VpnConfig.LEGACY_VPN.equals(app)) {
    712             return Process.myUid();
    713         }
    714         PackageManager pm = mContext.getPackageManager();
    715         int result;
    716         try {
    717             result = pm.getPackageUidAsUser(app, userHandle);
    718         } catch (NameNotFoundException e) {
    719             result = -1;
    720         }
    721         return result;
    722     }
    723 
    724     public NetworkInfo getNetworkInfo() {
    725         return mNetworkInfo;
    726     }
    727 
    728     public int getNetId() {
    729         return mNetworkAgent != null ? mNetworkAgent.netId : NETID_UNSET;
    730     }
    731 
    732     private LinkProperties makeLinkProperties() {
    733         boolean allowIPv4 = mConfig.allowIPv4;
    734         boolean allowIPv6 = mConfig.allowIPv6;
    735 
    736         LinkProperties lp = new LinkProperties();
    737 
    738         lp.setInterfaceName(mInterface);
    739 
    740         if (mConfig.addresses != null) {
    741             for (LinkAddress address : mConfig.addresses) {
    742                 lp.addLinkAddress(address);
    743                 allowIPv4 |= address.getAddress() instanceof Inet4Address;
    744                 allowIPv6 |= address.getAddress() instanceof Inet6Address;
    745             }
    746         }
    747 
    748         if (mConfig.routes != null) {
    749             for (RouteInfo route : mConfig.routes) {
    750                 lp.addRoute(route);
    751                 InetAddress address = route.getDestination().getAddress();
    752                 allowIPv4 |= address instanceof Inet4Address;
    753                 allowIPv6 |= address instanceof Inet6Address;
    754             }
    755         }
    756 
    757         if (mConfig.dnsServers != null) {
    758             for (String dnsServer : mConfig.dnsServers) {
    759                 InetAddress address = InetAddress.parseNumericAddress(dnsServer);
    760                 lp.addDnsServer(address);
    761                 allowIPv4 |= address instanceof Inet4Address;
    762                 allowIPv6 |= address instanceof Inet6Address;
    763             }
    764         }
    765 
    766         if (!allowIPv4) {
    767             lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
    768         }
    769         if (!allowIPv6) {
    770             lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
    771         }
    772 
    773         // Concatenate search domains into a string.
    774         StringBuilder buffer = new StringBuilder();
    775         if (mConfig.searchDomains != null) {
    776             for (String domain : mConfig.searchDomains) {
    777                 buffer.append(domain).append(' ');
    778             }
    779         }
    780         lp.setDomains(buffer.toString().trim());
    781 
    782         // TODO: Stop setting the MTU in jniCreate and set it here.
    783 
    784         return lp;
    785     }
    786 
    787     private void agentConnect() {
    788         LinkProperties lp = makeLinkProperties();
    789 
    790         if (lp.hasIPv4DefaultRoute() || lp.hasIPv6DefaultRoute()) {
    791             mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
    792         } else {
    793             mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
    794         }
    795 
    796         mNetworkInfo.setDetailedState(DetailedState.CONNECTING, null, null);
    797 
    798         NetworkMisc networkMisc = new NetworkMisc();
    799         networkMisc.allowBypass = mConfig.allowBypass && !mLockdown;
    800 
    801         long token = Binder.clearCallingIdentity();
    802         try {
    803             mNetworkAgent = new NetworkAgent(mLooper, mContext, NETWORKTYPE,
    804                     mNetworkInfo, mNetworkCapabilities, lp, 0, networkMisc) {
    805                             @Override
    806                             public void unwanted() {
    807                                 // We are user controlled, not driven by NetworkRequest.
    808                             }
    809                         };
    810         } finally {
    811             Binder.restoreCallingIdentity(token);
    812         }
    813 
    814         mVpnUsers = createUserAndRestrictedProfilesRanges(mUserHandle,
    815                 mConfig.allowedApplications, mConfig.disallowedApplications);
    816         mNetworkAgent.addUidRanges(mVpnUsers.toArray(new UidRange[mVpnUsers.size()]));
    817 
    818         mNetworkInfo.setIsAvailable(true);
    819         updateState(DetailedState.CONNECTED, "agentConnect");
    820     }
    821 
    822     private boolean canHaveRestrictedProfile(int userId) {
    823         long token = Binder.clearCallingIdentity();
    824         try {
    825             return UserManager.get(mContext).canHaveRestrictedProfile(userId);
    826         } finally {
    827             Binder.restoreCallingIdentity(token);
    828         }
    829     }
    830 
    831     private void agentDisconnect(NetworkAgent networkAgent) {
    832         if (networkAgent != null) {
    833             NetworkInfo networkInfo = new NetworkInfo(mNetworkInfo);
    834             networkInfo.setIsAvailable(false);
    835             networkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
    836             networkAgent.sendNetworkInfo(networkInfo);
    837         }
    838     }
    839 
    840     private void agentDisconnect() {
    841         if (mNetworkInfo.isConnected()) {
    842             mNetworkInfo.setIsAvailable(false);
    843             updateState(DetailedState.DISCONNECTED, "agentDisconnect");
    844             mNetworkAgent = null;
    845         }
    846     }
    847 
    848     /**
    849      * Establish a VPN network and return the file descriptor of the VPN
    850      * interface. This methods returns {@code null} if the application is
    851      * revoked or not prepared.
    852      *
    853      * @param config The parameters to configure the network.
    854      * @return The file descriptor of the VPN interface.
    855      */
    856     public synchronized ParcelFileDescriptor establish(VpnConfig config) {
    857         // Check if the caller is already prepared.
    858         UserManager mgr = UserManager.get(mContext);
    859         if (Binder.getCallingUid() != mOwnerUID) {
    860             return null;
    861         }
    862         // Check to ensure consent hasn't been revoked since we were prepared.
    863         if (!isVpnUserPreConsented(mPackage)) {
    864             return null;
    865         }
    866         // Check if the service is properly declared.
    867         Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE);
    868         intent.setClassName(mPackage, config.user);
    869         long token = Binder.clearCallingIdentity();
    870         try {
    871             // Restricted users are not allowed to create VPNs, they are tied to Owner
    872             UserInfo user = mgr.getUserInfo(mUserHandle);
    873             if (user.isRestricted()) {
    874                 throw new SecurityException("Restricted users cannot establish VPNs");
    875             }
    876 
    877             ResolveInfo info = AppGlobals.getPackageManager().resolveService(intent,
    878                                                                         null, 0, mUserHandle);
    879             if (info == null) {
    880                 throw new SecurityException("Cannot find " + config.user);
    881             }
    882             if (!BIND_VPN_SERVICE.equals(info.serviceInfo.permission)) {
    883                 throw new SecurityException(config.user + " does not require " + BIND_VPN_SERVICE);
    884             }
    885         } catch (RemoteException e) {
    886                 throw new SecurityException("Cannot find " + config.user);
    887         } finally {
    888             Binder.restoreCallingIdentity(token);
    889         }
    890 
    891         // Save the old config in case we need to go back.
    892         VpnConfig oldConfig = mConfig;
    893         String oldInterface = mInterface;
    894         Connection oldConnection = mConnection;
    895         NetworkAgent oldNetworkAgent = mNetworkAgent;
    896         mNetworkAgent = null;
    897         Set<UidRange> oldUsers = mVpnUsers;
    898 
    899         // Configure the interface. Abort if any of these steps fails.
    900         ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
    901         try {
    902             updateState(DetailedState.CONNECTING, "establish");
    903             String interfaze = jniGetName(tun.getFd());
    904 
    905             // TEMP use the old jni calls until there is support for netd address setting
    906             StringBuilder builder = new StringBuilder();
    907             for (LinkAddress address : config.addresses) {
    908                 builder.append(" " + address);
    909             }
    910             if (jniSetAddresses(interfaze, builder.toString()) < 1) {
    911                 throw new IllegalArgumentException("At least one address must be specified");
    912             }
    913             Connection connection = new Connection();
    914             if (!mContext.bindServiceAsUser(intent, connection,
    915                     Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
    916                     new UserHandle(mUserHandle))) {
    917                 throw new IllegalStateException("Cannot bind " + config.user);
    918             }
    919 
    920             mConnection = connection;
    921             mInterface = interfaze;
    922 
    923             // Fill more values.
    924             config.user = mPackage;
    925             config.interfaze = mInterface;
    926             config.startTime = SystemClock.elapsedRealtime();
    927             mConfig = config;
    928 
    929             // Set up forwarding and DNS rules.
    930             agentConnect();
    931 
    932             if (oldConnection != null) {
    933                 mContext.unbindService(oldConnection);
    934             }
    935             // Remove the old tun's user forwarding rules
    936             // The new tun's user rules have already been added so they will take over
    937             // as rules are deleted. This prevents data leakage as the rules are moved over.
    938             agentDisconnect(oldNetworkAgent);
    939             if (oldInterface != null && !oldInterface.equals(interfaze)) {
    940                 jniReset(oldInterface);
    941             }
    942 
    943             try {
    944                 IoUtils.setBlocking(tun.getFileDescriptor(), config.blocking);
    945             } catch (IOException e) {
    946                 throw new IllegalStateException(
    947                         "Cannot set tunnel's fd as blocking=" + config.blocking, e);
    948             }
    949         } catch (RuntimeException e) {
    950             IoUtils.closeQuietly(tun);
    951             agentDisconnect();
    952             // restore old state
    953             mConfig = oldConfig;
    954             mConnection = oldConnection;
    955             mVpnUsers = oldUsers;
    956             mNetworkAgent = oldNetworkAgent;
    957             mInterface = oldInterface;
    958             throw e;
    959         }
    960         Log.i(TAG, "Established by " + config.user + " on " + mInterface);
    961         return tun;
    962     }
    963 
    964     private boolean isRunningLocked() {
    965         return mNetworkAgent != null && mInterface != null;
    966     }
    967 
    968     // Returns true if the VPN has been established and the calling UID is its owner. Used to check
    969     // that a call to mutate VPN state is admissible.
    970     private boolean isCallerEstablishedOwnerLocked() {
    971         return isRunningLocked() && Binder.getCallingUid() == mOwnerUID;
    972     }
    973 
    974     // Note: Return type guarantees results are deduped and sorted, which callers require.
    975     private SortedSet<Integer> getAppsUids(List<String> packageNames, int userHandle) {
    976         SortedSet<Integer> uids = new TreeSet<Integer>();
    977         for (String app : packageNames) {
    978             int uid = getAppUid(app, userHandle);
    979             if (uid != -1) uids.add(uid);
    980         }
    981         return uids;
    982     }
    983 
    984     /**
    985      * Creates a {@link Set} of non-intersecting {@link UidRange} objects including all UIDs
    986      * associated with one user, and any restricted profiles attached to that user.
    987      *
    988      * <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided,
    989      * the UID ranges will match the app whitelist or blacklist specified there. Otherwise, all UIDs
    990      * in each user and profile will be included.
    991      *
    992      * @param userHandle The userId to create UID ranges for along with any of its restricted
    993      *                   profiles.
    994      * @param allowedApplications (optional) whitelist of applications to include.
    995      * @param disallowedApplications (optional) blacklist of applications to exclude.
    996      */
    997     @VisibleForTesting
    998     Set<UidRange> createUserAndRestrictedProfilesRanges(@UserIdInt int userHandle,
    999             @Nullable List<String> allowedApplications,
   1000             @Nullable List<String> disallowedApplications) {
   1001         final Set<UidRange> ranges = new ArraySet<>();
   1002 
   1003         // Assign the top-level user to the set of ranges
   1004         addUserToRanges(ranges, userHandle, allowedApplications, disallowedApplications);
   1005 
   1006         // If the user can have restricted profiles, assign all its restricted profiles too
   1007         if (canHaveRestrictedProfile(userHandle)) {
   1008             final long token = Binder.clearCallingIdentity();
   1009             List<UserInfo> users;
   1010             try {
   1011                 users = UserManager.get(mContext).getUsers(true);
   1012             } finally {
   1013                 Binder.restoreCallingIdentity(token);
   1014             }
   1015             for (UserInfo user : users) {
   1016                 if (user.isRestricted() && (user.restrictedProfileParentId == userHandle)) {
   1017                     addUserToRanges(ranges, user.id, allowedApplications, disallowedApplications);
   1018                 }
   1019             }
   1020         }
   1021         return ranges;
   1022     }
   1023 
   1024     /**
   1025      * Updates a {@link Set} of non-intersecting {@link UidRange} objects to include all UIDs
   1026      * associated with one user.
   1027      *
   1028      * <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided,
   1029      * the UID ranges will match the app whitelist or blacklist specified there. Otherwise, all UIDs
   1030      * in the user will be included.
   1031      *
   1032      * @param ranges {@link Set} of {@link UidRange}s to which to add.
   1033      * @param userHandle The userId to add to {@param ranges}.
   1034      * @param allowedApplications (optional) whitelist of applications to include.
   1035      * @param disallowedApplications (optional) blacklist of applications to exclude.
   1036      */
   1037     @VisibleForTesting
   1038     void addUserToRanges(@NonNull Set<UidRange> ranges, @UserIdInt int userHandle,
   1039             @Nullable List<String> allowedApplications,
   1040             @Nullable List<String> disallowedApplications) {
   1041         if (allowedApplications != null) {
   1042             // Add ranges covering all UIDs for allowedApplications.
   1043             int start = -1, stop = -1;
   1044             for (int uid : getAppsUids(allowedApplications, userHandle)) {
   1045                 if (start == -1) {
   1046                     start = uid;
   1047                 } else if (uid != stop + 1) {
   1048                     ranges.add(new UidRange(start, stop));
   1049                     start = uid;
   1050                 }
   1051                 stop = uid;
   1052             }
   1053             if (start != -1) ranges.add(new UidRange(start, stop));
   1054         } else if (disallowedApplications != null) {
   1055             // Add all ranges for user skipping UIDs for disallowedApplications.
   1056             final UidRange userRange = UidRange.createForUser(userHandle);
   1057             int start = userRange.start;
   1058             for (int uid : getAppsUids(disallowedApplications, userHandle)) {
   1059                 if (uid == start) {
   1060                     start++;
   1061                 } else {
   1062                     ranges.add(new UidRange(start, uid - 1));
   1063                     start = uid + 1;
   1064                 }
   1065             }
   1066             if (start <= userRange.stop) ranges.add(new UidRange(start, userRange.stop));
   1067         } else {
   1068             // Add all UIDs for the user.
   1069             ranges.add(UidRange.createForUser(userHandle));
   1070         }
   1071     }
   1072 
   1073     // Returns the subset of the full list of active UID ranges the VPN applies to (mVpnUsers) that
   1074     // apply to userHandle.
   1075     private List<UidRange> uidRangesForUser(int userHandle) {
   1076         final UidRange userRange = UidRange.createForUser(userHandle);
   1077         final List<UidRange> ranges = new ArrayList<UidRange>();
   1078         for (UidRange range : mVpnUsers) {
   1079             if (userRange.containsRange(range)) {
   1080                 ranges.add(range);
   1081             }
   1082         }
   1083         return ranges;
   1084     }
   1085 
   1086     private void removeVpnUserLocked(int userHandle) {
   1087         if (mVpnUsers == null) {
   1088             throw new IllegalStateException("VPN is not active");
   1089         }
   1090         final List<UidRange> ranges = uidRangesForUser(userHandle);
   1091         if (mNetworkAgent != null) {
   1092             mNetworkAgent.removeUidRanges(ranges.toArray(new UidRange[ranges.size()]));
   1093         }
   1094         mVpnUsers.removeAll(ranges);
   1095     }
   1096 
   1097     public void onUserAdded(int userHandle) {
   1098         // If the user is restricted tie them to the parent user's VPN
   1099         UserInfo user = UserManager.get(mContext).getUserInfo(userHandle);
   1100         if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle) {
   1101             synchronized(Vpn.this) {
   1102                 if (mVpnUsers != null) {
   1103                     try {
   1104                         addUserToRanges(mVpnUsers, userHandle, mConfig.allowedApplications,
   1105                                 mConfig.disallowedApplications);
   1106                         if (mNetworkAgent != null) {
   1107                             final List<UidRange> ranges = uidRangesForUser(userHandle);
   1108                             mNetworkAgent.addUidRanges(ranges.toArray(new UidRange[ranges.size()]));
   1109                         }
   1110                     } catch (Exception e) {
   1111                         Log.wtf(TAG, "Failed to add restricted user to owner", e);
   1112                     }
   1113                 }
   1114                 setVpnForcedLocked(mLockdown);
   1115             }
   1116         }
   1117     }
   1118 
   1119     public void onUserRemoved(int userHandle) {
   1120         // clean up if restricted
   1121         UserInfo user = UserManager.get(mContext).getUserInfo(userHandle);
   1122         if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle) {
   1123             synchronized(Vpn.this) {
   1124                 if (mVpnUsers != null) {
   1125                     try {
   1126                         removeVpnUserLocked(userHandle);
   1127                     } catch (Exception e) {
   1128                         Log.wtf(TAG, "Failed to remove restricted user to owner", e);
   1129                     }
   1130                 }
   1131                 setVpnForcedLocked(mLockdown);
   1132             }
   1133         }
   1134     }
   1135 
   1136     /**
   1137      * Called when the user associated with this VPN has just been stopped.
   1138      */
   1139     public synchronized void onUserStopped() {
   1140         // Switch off networking lockdown (if it was enabled)
   1141         setLockdown(false);
   1142         mAlwaysOn = false;
   1143 
   1144         unregisterPackageChangeReceiverLocked();
   1145         // Quit any active connections
   1146         agentDisconnect();
   1147     }
   1148 
   1149     /**
   1150      * Restrict network access from all UIDs affected by this {@link Vpn}, apart from the VPN
   1151      * service app itself, to only sockets that have had {@code protect()} called on them. All
   1152      * non-VPN traffic is blocked via a {@code PROHIBIT} response from the kernel.
   1153      *
   1154      * The exception for the VPN UID isn't technically necessary -- setup should use protected
   1155      * sockets -- but in practice it saves apps that don't protect their sockets from breaking.
   1156      *
   1157      * Calling multiple times with {@param enforce} = {@code true} will recreate the set of UIDs to
   1158      * block every time, and if anything has changed update using {@link #setAllowOnlyVpnForUids}.
   1159      *
   1160      * @param enforce {@code true} to require that all traffic under the jurisdiction of this
   1161      *                {@link Vpn} goes through a VPN connection or is blocked until one is
   1162      *                available, {@code false} to lift the requirement.
   1163      *
   1164      * @see #mBlockedUsers
   1165      */
   1166     @GuardedBy("this")
   1167     private void setVpnForcedLocked(boolean enforce) {
   1168         final List<String> exemptedPackages =
   1169                 isNullOrLegacyVpn(mPackage) ? null : Collections.singletonList(mPackage);
   1170         setVpnForcedWithExemptionsLocked(enforce, exemptedPackages);
   1171     }
   1172 
   1173     /**
   1174      * @see #setVpnForcedLocked
   1175      */
   1176     @GuardedBy("this")
   1177     private void setVpnForcedWithExemptionsLocked(boolean enforce,
   1178             @Nullable List<String> exemptedPackages) {
   1179         final Set<UidRange> removedRanges = new ArraySet<>(mBlockedUsers);
   1180 
   1181         Set<UidRange> addedRanges = Collections.emptySet();
   1182         if (enforce) {
   1183             addedRanges = createUserAndRestrictedProfilesRanges(mUserHandle,
   1184                     /* allowedApplications */ null,
   1185                     /* disallowedApplications */ exemptedPackages);
   1186 
   1187             removedRanges.removeAll(addedRanges);
   1188             addedRanges.removeAll(mBlockedUsers);
   1189         }
   1190 
   1191         setAllowOnlyVpnForUids(false, removedRanges);
   1192         setAllowOnlyVpnForUids(true, addedRanges);
   1193     }
   1194 
   1195     /**
   1196      * Either add or remove a list of {@link UidRange}s to the list of UIDs that are only allowed
   1197      * to make connections through sockets that have had {@code protect()} called on them.
   1198      *
   1199      * @param enforce {@code true} to add to the blacklist, {@code false} to remove.
   1200      * @param ranges {@link Collection} of {@link UidRange}s to add (if {@param enforce} is
   1201      *               {@code true}) or to remove.
   1202      * @return {@code true} if all of the UIDs were added/removed. {@code false} otherwise,
   1203      *         including added ranges that already existed or removed ones that didn't.
   1204      */
   1205     @GuardedBy("this")
   1206     private boolean setAllowOnlyVpnForUids(boolean enforce, Collection<UidRange> ranges) {
   1207         if (ranges.size() == 0) {
   1208             return true;
   1209         }
   1210         final UidRange[] rangesArray = ranges.toArray(new UidRange[ranges.size()]);
   1211         try {
   1212             mNetd.setAllowOnlyVpnForUids(enforce, rangesArray);
   1213         } catch (RemoteException | RuntimeException e) {
   1214             Log.e(TAG, "Updating blocked=" + enforce
   1215                     + " for UIDs " + Arrays.toString(ranges.toArray()) + " failed", e);
   1216             return false;
   1217         }
   1218         if (enforce) {
   1219             mBlockedUsers.addAll(ranges);
   1220         } else {
   1221             mBlockedUsers.removeAll(ranges);
   1222         }
   1223         return true;
   1224     }
   1225 
   1226     /**
   1227      * Return the configuration of the currently running VPN.
   1228      */
   1229     public VpnConfig getVpnConfig() {
   1230         enforceControlPermission();
   1231         return mConfig;
   1232     }
   1233 
   1234     @Deprecated
   1235     public synchronized void interfaceStatusChanged(String iface, boolean up) {
   1236         try {
   1237             mObserver.interfaceStatusChanged(iface, up);
   1238         } catch (RemoteException e) {
   1239             // ignored; target is local
   1240         }
   1241     }
   1242 
   1243     private INetworkManagementEventObserver mObserver = new BaseNetworkObserver() {
   1244         @Override
   1245         public void interfaceStatusChanged(String interfaze, boolean up) {
   1246             synchronized (Vpn.this) {
   1247                 if (!up && mLegacyVpnRunner != null) {
   1248                     mLegacyVpnRunner.check(interfaze);
   1249                 }
   1250             }
   1251         }
   1252 
   1253         @Override
   1254         public void interfaceRemoved(String interfaze) {
   1255             synchronized (Vpn.this) {
   1256                 if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
   1257                     mStatusIntent = null;
   1258                     mVpnUsers = null;
   1259                     mConfig = null;
   1260                     mInterface = null;
   1261                     if (mConnection != null) {
   1262                         mContext.unbindService(mConnection);
   1263                         mConnection = null;
   1264                         agentDisconnect();
   1265                     } else if (mLegacyVpnRunner != null) {
   1266                         mLegacyVpnRunner.exit();
   1267                         mLegacyVpnRunner = null;
   1268                     }
   1269                 }
   1270             }
   1271         }
   1272     };
   1273 
   1274     private void enforceControlPermission() {
   1275         mContext.enforceCallingPermission(Manifest.permission.CONTROL_VPN, "Unauthorized Caller");
   1276     }
   1277 
   1278     private void enforceControlPermissionOrInternalCaller() {
   1279         // Require caller to be either an application with CONTROL_VPN permission or a process
   1280         // in the system server.
   1281         mContext.enforceCallingOrSelfPermission(Manifest.permission.CONTROL_VPN,
   1282                 "Unauthorized Caller");
   1283     }
   1284 
   1285     private void enforceSettingsPermission() {
   1286         mContext.enforceCallingOrSelfPermission(Manifest.permission.NETWORK_SETTINGS,
   1287                 "Unauthorized Caller");
   1288     }
   1289 
   1290     private class Connection implements ServiceConnection {
   1291         private IBinder mService;
   1292 
   1293         @Override
   1294         public void onServiceConnected(ComponentName name, IBinder service) {
   1295             mService = service;
   1296         }
   1297 
   1298         @Override
   1299         public void onServiceDisconnected(ComponentName name) {
   1300             mService = null;
   1301         }
   1302     }
   1303 
   1304     private void prepareStatusIntent() {
   1305         final long token = Binder.clearCallingIdentity();
   1306         try {
   1307             mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext);
   1308         } finally {
   1309             Binder.restoreCallingIdentity(token);
   1310         }
   1311     }
   1312 
   1313     public synchronized boolean addAddress(String address, int prefixLength) {
   1314         if (!isCallerEstablishedOwnerLocked()) {
   1315             return false;
   1316         }
   1317         boolean success = jniAddAddress(mInterface, address, prefixLength);
   1318         mNetworkAgent.sendLinkProperties(makeLinkProperties());
   1319         return success;
   1320     }
   1321 
   1322     public synchronized boolean removeAddress(String address, int prefixLength) {
   1323         if (!isCallerEstablishedOwnerLocked()) {
   1324             return false;
   1325         }
   1326         boolean success = jniDelAddress(mInterface, address, prefixLength);
   1327         mNetworkAgent.sendLinkProperties(makeLinkProperties());
   1328         return success;
   1329     }
   1330 
   1331     public synchronized boolean setUnderlyingNetworks(Network[] networks) {
   1332         if (!isCallerEstablishedOwnerLocked()) {
   1333             return false;
   1334         }
   1335         if (networks == null) {
   1336             mConfig.underlyingNetworks = null;
   1337         } else {
   1338             mConfig.underlyingNetworks = new Network[networks.length];
   1339             for (int i = 0; i < networks.length; ++i) {
   1340                 if (networks[i] == null) {
   1341                     mConfig.underlyingNetworks[i] = null;
   1342                 } else {
   1343                     mConfig.underlyingNetworks[i] = new Network(networks[i].netId);
   1344                 }
   1345             }
   1346         }
   1347         return true;
   1348     }
   1349 
   1350     public synchronized Network[] getUnderlyingNetworks() {
   1351         if (!isRunningLocked()) {
   1352             return null;
   1353         }
   1354         return mConfig.underlyingNetworks;
   1355     }
   1356 
   1357     /**
   1358      * This method should only be called by ConnectivityService. Because it doesn't
   1359      * have enough data to fill VpnInfo.primaryUnderlyingIface field.
   1360      */
   1361     public synchronized VpnInfo getVpnInfo() {
   1362         if (!isRunningLocked()) {
   1363             return null;
   1364         }
   1365 
   1366         VpnInfo info = new VpnInfo();
   1367         info.ownerUid = mOwnerUID;
   1368         info.vpnIface = mInterface;
   1369         return info;
   1370     }
   1371 
   1372     public synchronized boolean appliesToUid(int uid) {
   1373         if (!isRunningLocked()) {
   1374             return false;
   1375         }
   1376         for (UidRange uidRange : mVpnUsers) {
   1377             if (uidRange.contains(uid)) {
   1378                 return true;
   1379             }
   1380         }
   1381         return false;
   1382     }
   1383 
   1384     /**
   1385      * @return {@code true} if {@param uid} is blocked by an always-on VPN.
   1386      *         A UID is blocked if it's included in one of the mBlockedUsers ranges and the VPN is
   1387      *         not connected, or if the VPN is connected but does not apply to the UID.
   1388      *
   1389      * @see #mBlockedUsers
   1390      */
   1391     public synchronized boolean isBlockingUid(int uid) {
   1392         if (!mLockdown) {
   1393             return false;
   1394         }
   1395 
   1396         if (mNetworkInfo.isConnected()) {
   1397             return !appliesToUid(uid);
   1398         } else {
   1399             for (UidRange uidRange : mBlockedUsers) {
   1400                 if (uidRange.contains(uid)) {
   1401                     return true;
   1402                 }
   1403             }
   1404             return false;
   1405         }
   1406     }
   1407 
   1408     private void updateAlwaysOnNotification(DetailedState networkState) {
   1409         final boolean visible = (mAlwaysOn && networkState != DetailedState.CONNECTED);
   1410 
   1411         final UserHandle user = UserHandle.of(mUserHandle);
   1412         final long token = Binder.clearCallingIdentity();
   1413         try {
   1414             final NotificationManager notificationManager = NotificationManager.from(mContext);
   1415             if (!visible) {
   1416                 notificationManager.cancelAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, user);
   1417                 return;
   1418             }
   1419             final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
   1420             final PendingIntent configIntent = mSystemServices.pendingIntentGetActivityAsUser(
   1421                     intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT, user);
   1422             final Notification.Builder builder =
   1423                     new Notification.Builder(mContext, SystemNotificationChannels.VPN)
   1424                             .setSmallIcon(R.drawable.vpn_connected)
   1425                             .setContentTitle(mContext.getString(R.string.vpn_lockdown_disconnected))
   1426                             .setContentText(mContext.getString(R.string.vpn_lockdown_config))
   1427                             .setContentIntent(configIntent)
   1428                             .setCategory(Notification.CATEGORY_SYSTEM)
   1429                             .setVisibility(Notification.VISIBILITY_PUBLIC)
   1430                             .setOngoing(true)
   1431                             .setColor(mContext.getColor(R.color.system_notification_accent_color));
   1432             notificationManager.notifyAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED,
   1433                     builder.build(), user);
   1434         } finally {
   1435             Binder.restoreCallingIdentity(token);
   1436         }
   1437     }
   1438 
   1439     /**
   1440      * Facade for system service calls that change, or depend on, state outside of
   1441      * {@link ConnectivityService} and have hard-to-mock interfaces.
   1442      *
   1443      * @see com.android.server.connectivity.VpnTest
   1444      */
   1445     @VisibleForTesting
   1446     public static class SystemServices {
   1447         private final Context mContext;
   1448 
   1449         public SystemServices(@NonNull Context context) {
   1450             mContext = context;
   1451         }
   1452 
   1453         /**
   1454          * @see PendingIntent#getActivityAsUser()
   1455          */
   1456         public PendingIntent pendingIntentGetActivityAsUser(
   1457                 Intent intent, int flags, UserHandle user) {
   1458             return PendingIntent.getActivityAsUser(mContext, 0 /*request*/, intent, flags,
   1459                     null /*options*/, user);
   1460         }
   1461 
   1462         /**
   1463          * @see Settings.Secure#putStringForUser
   1464          */
   1465         public void settingsSecurePutStringForUser(String key, String value, int userId) {
   1466             Settings.Secure.putStringForUser(mContext.getContentResolver(), key, value, userId);
   1467         }
   1468 
   1469         /**
   1470          * @see Settings.Secure#putIntForUser
   1471          */
   1472         public void settingsSecurePutIntForUser(String key, int value, int userId) {
   1473             Settings.Secure.putIntForUser(mContext.getContentResolver(), key, value, userId);
   1474         }
   1475 
   1476         /**
   1477          * @see Settings.Secure#getStringForUser
   1478          */
   1479         public String settingsSecureGetStringForUser(String key, int userId) {
   1480             return Settings.Secure.getStringForUser(mContext.getContentResolver(), key, userId);
   1481         }
   1482 
   1483         /**
   1484          * @see Settings.Secure#getIntForUser
   1485          */
   1486         public int settingsSecureGetIntForUser(String key, int def, int userId) {
   1487             return Settings.Secure.getIntForUser(mContext.getContentResolver(), key, def, userId);
   1488         }
   1489     }
   1490 
   1491     private native int jniCreate(int mtu);
   1492     private native String jniGetName(int tun);
   1493     private native int jniSetAddresses(String interfaze, String addresses);
   1494     private native void jniReset(String interfaze);
   1495     private native int jniCheck(String interfaze);
   1496     private native boolean jniAddAddress(String interfaze, String address, int prefixLen);
   1497     private native boolean jniDelAddress(String interfaze, String address, int prefixLen);
   1498 
   1499     private static RouteInfo findIPv4DefaultRoute(LinkProperties prop) {
   1500         for (RouteInfo route : prop.getAllRoutes()) {
   1501             // Currently legacy VPN only works on IPv4.
   1502             if (route.isDefaultRoute() && route.getGateway() instanceof Inet4Address) {
   1503                 return route;
   1504             }
   1505         }
   1506 
   1507         throw new IllegalStateException("Unable to find IPv4 default gateway");
   1508     }
   1509 
   1510     /**
   1511      * Start legacy VPN, controlling native daemons as needed. Creates a
   1512      * secondary thread to perform connection work, returning quickly.
   1513      *
   1514      * Should only be called to respond to Binder requests as this enforces caller permission. Use
   1515      * {@link #startLegacyVpnPrivileged(VpnProfile, KeyStore, LinkProperties)} to skip the
   1516      * permission check only when the caller is trusted (or the call is initiated by the system).
   1517      */
   1518     public void startLegacyVpn(VpnProfile profile, KeyStore keyStore, LinkProperties egress) {
   1519         enforceControlPermission();
   1520         long token = Binder.clearCallingIdentity();
   1521         try {
   1522             startLegacyVpnPrivileged(profile, keyStore, egress);
   1523         } finally {
   1524             Binder.restoreCallingIdentity(token);
   1525         }
   1526     }
   1527 
   1528     /**
   1529      * Like {@link #startLegacyVpn(VpnProfile, KeyStore, LinkProperties)}, but does not check
   1530      * permissions under the assumption that the caller is the system.
   1531      *
   1532      * Callers are responsible for checking permissions if needed.
   1533      */
   1534     public void startLegacyVpnPrivileged(VpnProfile profile, KeyStore keyStore,
   1535             LinkProperties egress) {
   1536         UserManager mgr = UserManager.get(mContext);
   1537         UserInfo user = mgr.getUserInfo(mUserHandle);
   1538         if (user.isRestricted() || mgr.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN,
   1539                     new UserHandle(mUserHandle))) {
   1540             throw new SecurityException("Restricted users cannot establish VPNs");
   1541         }
   1542 
   1543         final RouteInfo ipv4DefaultRoute = findIPv4DefaultRoute(egress);
   1544         final String gateway = ipv4DefaultRoute.getGateway().getHostAddress();
   1545         final String iface = ipv4DefaultRoute.getInterface();
   1546 
   1547         // Load certificates.
   1548         String privateKey = "";
   1549         String userCert = "";
   1550         String caCert = "";
   1551         String serverCert = "";
   1552         if (!profile.ipsecUserCert.isEmpty()) {
   1553             privateKey = Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert;
   1554             byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecUserCert);
   1555             userCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
   1556         }
   1557         if (!profile.ipsecCaCert.isEmpty()) {
   1558             byte[] value = keyStore.get(Credentials.CA_CERTIFICATE + profile.ipsecCaCert);
   1559             caCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
   1560         }
   1561         if (!profile.ipsecServerCert.isEmpty()) {
   1562             byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecServerCert);
   1563             serverCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
   1564         }
   1565         if (privateKey == null || userCert == null || caCert == null || serverCert == null) {
   1566             throw new IllegalStateException("Cannot load credentials");
   1567         }
   1568 
   1569         // Prepare arguments for racoon.
   1570         String[] racoon = null;
   1571         switch (profile.type) {
   1572             case VpnProfile.TYPE_L2TP_IPSEC_PSK:
   1573                 racoon = new String[] {
   1574                     iface, profile.server, "udppsk", profile.ipsecIdentifier,
   1575                     profile.ipsecSecret, "1701",
   1576                 };
   1577                 break;
   1578             case VpnProfile.TYPE_L2TP_IPSEC_RSA:
   1579                 racoon = new String[] {
   1580                     iface, profile.server, "udprsa", privateKey, userCert,
   1581                     caCert, serverCert, "1701",
   1582                 };
   1583                 break;
   1584             case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
   1585                 racoon = new String[] {
   1586                     iface, profile.server, "xauthpsk", profile.ipsecIdentifier,
   1587                     profile.ipsecSecret, profile.username, profile.password, "", gateway,
   1588                 };
   1589                 break;
   1590             case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
   1591                 racoon = new String[] {
   1592                     iface, profile.server, "xauthrsa", privateKey, userCert,
   1593                     caCert, serverCert, profile.username, profile.password, "", gateway,
   1594                 };
   1595                 break;
   1596             case VpnProfile.TYPE_IPSEC_HYBRID_RSA:
   1597                 racoon = new String[] {
   1598                     iface, profile.server, "hybridrsa",
   1599                     caCert, serverCert, profile.username, profile.password, "", gateway,
   1600                 };
   1601                 break;
   1602         }
   1603 
   1604         // Prepare arguments for mtpd.
   1605         String[] mtpd = null;
   1606         switch (profile.type) {
   1607             case VpnProfile.TYPE_PPTP:
   1608                 mtpd = new String[] {
   1609                     iface, "pptp", profile.server, "1723",
   1610                     "name", profile.username, "password", profile.password,
   1611                     "linkname", "vpn", "refuse-eap", "nodefaultroute",
   1612                     "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
   1613                     (profile.mppe ? "+mppe" : "nomppe"),
   1614                 };
   1615                 break;
   1616             case VpnProfile.TYPE_L2TP_IPSEC_PSK:
   1617             case VpnProfile.TYPE_L2TP_IPSEC_RSA:
   1618                 mtpd = new String[] {
   1619                     iface, "l2tp", profile.server, "1701", profile.l2tpSecret,
   1620                     "name", profile.username, "password", profile.password,
   1621                     "linkname", "vpn", "refuse-eap", "nodefaultroute",
   1622                     "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
   1623                 };
   1624                 break;
   1625         }
   1626 
   1627         VpnConfig config = new VpnConfig();
   1628         config.legacy = true;
   1629         config.user = profile.key;
   1630         config.interfaze = iface;
   1631         config.session = profile.name;
   1632 
   1633         config.addLegacyRoutes(profile.routes);
   1634         if (!profile.dnsServers.isEmpty()) {
   1635             config.dnsServers = Arrays.asList(profile.dnsServers.split(" +"));
   1636         }
   1637         if (!profile.searchDomains.isEmpty()) {
   1638             config.searchDomains = Arrays.asList(profile.searchDomains.split(" +"));
   1639         }
   1640         startLegacyVpn(config, racoon, mtpd);
   1641     }
   1642 
   1643     private synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
   1644         stopLegacyVpnPrivileged();
   1645 
   1646         // Prepare for the new request.
   1647         prepareInternal(VpnConfig.LEGACY_VPN);
   1648         updateState(DetailedState.CONNECTING, "startLegacyVpn");
   1649 
   1650         // Start a new LegacyVpnRunner and we are done!
   1651         mLegacyVpnRunner = new LegacyVpnRunner(config, racoon, mtpd);
   1652         mLegacyVpnRunner.start();
   1653     }
   1654 
   1655     /** Stop legacy VPN. Permissions must be checked by callers. */
   1656     public synchronized void stopLegacyVpnPrivileged() {
   1657         if (mLegacyVpnRunner != null) {
   1658             mLegacyVpnRunner.exit();
   1659             mLegacyVpnRunner = null;
   1660 
   1661             synchronized (LegacyVpnRunner.TAG) {
   1662                 // wait for old thread to completely finish before spinning up
   1663                 // new instance, otherwise state updates can be out of order.
   1664             }
   1665         }
   1666     }
   1667 
   1668     /**
   1669      * Return the information of the current ongoing legacy VPN.
   1670      */
   1671     public synchronized LegacyVpnInfo getLegacyVpnInfo() {
   1672         // Check if the caller is authorized.
   1673         enforceControlPermission();
   1674         return getLegacyVpnInfoPrivileged();
   1675     }
   1676 
   1677     /**
   1678      * Return the information of the current ongoing legacy VPN.
   1679      * Callers are responsible for checking permissions if needed.
   1680      */
   1681     public synchronized LegacyVpnInfo getLegacyVpnInfoPrivileged() {
   1682         if (mLegacyVpnRunner == null) return null;
   1683 
   1684         final LegacyVpnInfo info = new LegacyVpnInfo();
   1685         info.key = mConfig.user;
   1686         info.state = LegacyVpnInfo.stateFromNetworkInfo(mNetworkInfo);
   1687         if (mNetworkInfo.isConnected()) {
   1688             info.intent = mStatusIntent;
   1689         }
   1690         return info;
   1691     }
   1692 
   1693     public VpnConfig getLegacyVpnConfig() {
   1694         if (mLegacyVpnRunner != null) {
   1695             return mConfig;
   1696         } else {
   1697             return null;
   1698         }
   1699     }
   1700 
   1701     /**
   1702      * Bringing up a VPN connection takes time, and that is all this thread
   1703      * does. Here we have plenty of time. The only thing we need to take
   1704      * care of is responding to interruptions as soon as possible. Otherwise
   1705      * requests will be piled up. This can be done in a Handler as a state
   1706      * machine, but it is much easier to read in the current form.
   1707      */
   1708     private class LegacyVpnRunner extends Thread {
   1709         private static final String TAG = "LegacyVpnRunner";
   1710 
   1711         private final String[] mDaemons;
   1712         private final String[][] mArguments;
   1713         private final LocalSocket[] mSockets;
   1714         private final String mOuterInterface;
   1715         private final AtomicInteger mOuterConnection =
   1716                 new AtomicInteger(ConnectivityManager.TYPE_NONE);
   1717 
   1718         private long mTimer = -1;
   1719 
   1720         /**
   1721          * Watch for the outer connection (passing in the constructor) going away.
   1722          */
   1723         private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
   1724             @Override
   1725             public void onReceive(Context context, Intent intent) {
   1726                 if (!mEnableTeardown) return;
   1727 
   1728                 if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
   1729                     if (intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE,
   1730                             ConnectivityManager.TYPE_NONE) == mOuterConnection.get()) {
   1731                         NetworkInfo info = (NetworkInfo)intent.getExtra(
   1732                                 ConnectivityManager.EXTRA_NETWORK_INFO);
   1733                         if (info != null && !info.isConnectedOrConnecting()) {
   1734                             try {
   1735                                 mObserver.interfaceStatusChanged(mOuterInterface, false);
   1736                             } catch (RemoteException e) {}
   1737                         }
   1738                     }
   1739                 }
   1740             }
   1741         };
   1742 
   1743         public LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd) {
   1744             super(TAG);
   1745             mConfig = config;
   1746             mDaemons = new String[] {"racoon", "mtpd"};
   1747             // TODO: clear arguments from memory once launched
   1748             mArguments = new String[][] {racoon, mtpd};
   1749             mSockets = new LocalSocket[mDaemons.length];
   1750 
   1751             // This is the interface which VPN is running on,
   1752             // mConfig.interfaze will change to point to OUR
   1753             // internal interface soon. TODO - add inner/outer to mconfig
   1754             // TODO - we have a race - if the outer iface goes away/disconnects before we hit this
   1755             // we will leave the VPN up.  We should check that it's still there/connected after
   1756             // registering
   1757             mOuterInterface = mConfig.interfaze;
   1758 
   1759             if (!TextUtils.isEmpty(mOuterInterface)) {
   1760                 final ConnectivityManager cm = ConnectivityManager.from(mContext);
   1761                 for (Network network : cm.getAllNetworks()) {
   1762                     final LinkProperties lp = cm.getLinkProperties(network);
   1763                     if (lp != null && lp.getAllInterfaceNames().contains(mOuterInterface)) {
   1764                         final NetworkInfo networkInfo = cm.getNetworkInfo(network);
   1765                         if (networkInfo != null) mOuterConnection.set(networkInfo.getType());
   1766                     }
   1767                 }
   1768             }
   1769 
   1770             IntentFilter filter = new IntentFilter();
   1771             filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
   1772             mContext.registerReceiver(mBroadcastReceiver, filter);
   1773         }
   1774 
   1775         public void check(String interfaze) {
   1776             if (interfaze.equals(mOuterInterface)) {
   1777                 Log.i(TAG, "Legacy VPN is going down with " + interfaze);
   1778                 exit();
   1779             }
   1780         }
   1781 
   1782         public void exit() {
   1783             // We assume that everything is reset after stopping the daemons.
   1784             interrupt();
   1785             agentDisconnect();
   1786             try {
   1787                 mContext.unregisterReceiver(mBroadcastReceiver);
   1788             } catch (IllegalArgumentException e) {}
   1789         }
   1790 
   1791         @Override
   1792         public void run() {
   1793             // Wait for the previous thread since it has been interrupted.
   1794             Log.v(TAG, "Waiting");
   1795             synchronized (TAG) {
   1796                 Log.v(TAG, "Executing");
   1797                 try {
   1798                     execute();
   1799                     monitorDaemons();
   1800                     interrupted(); // Clear interrupt flag if execute called exit.
   1801                 } catch (InterruptedException e) {
   1802                 } finally {
   1803                     for (LocalSocket socket : mSockets) {
   1804                         IoUtils.closeQuietly(socket);
   1805                     }
   1806                     // This sleep is necessary for racoon to successfully complete sending delete
   1807                     // message to server.
   1808                     try {
   1809                         Thread.sleep(50);
   1810                     } catch (InterruptedException e) {
   1811                     }
   1812                     for (String daemon : mDaemons) {
   1813                         SystemService.stop(daemon);
   1814                     }
   1815                 }
   1816                 agentDisconnect();
   1817             }
   1818         }
   1819 
   1820         private void checkpoint(boolean yield) throws InterruptedException {
   1821             long now = SystemClock.elapsedRealtime();
   1822             if (mTimer == -1) {
   1823                 mTimer = now;
   1824                 Thread.sleep(1);
   1825             } else if (now - mTimer <= 60000) {
   1826                 Thread.sleep(yield ? 200 : 1);
   1827             } else {
   1828                 updateState(DetailedState.FAILED, "checkpoint");
   1829                 throw new IllegalStateException("Time is up");
   1830             }
   1831         }
   1832 
   1833         private void execute() {
   1834             // Catch all exceptions so we can clean up few things.
   1835             boolean initFinished = false;
   1836             try {
   1837                 // Initialize the timer.
   1838                 checkpoint(false);
   1839 
   1840                 // Wait for the daemons to stop.
   1841                 for (String daemon : mDaemons) {
   1842                     while (!SystemService.isStopped(daemon)) {
   1843                         checkpoint(true);
   1844                     }
   1845                 }
   1846 
   1847                 // Clear the previous state.
   1848                 File state = new File("/data/misc/vpn/state");
   1849                 state.delete();
   1850                 if (state.exists()) {
   1851                     throw new IllegalStateException("Cannot delete the state");
   1852                 }
   1853                 new File("/data/misc/vpn/abort").delete();
   1854                 initFinished = true;
   1855 
   1856                 // Check if we need to restart any of the daemons.
   1857                 boolean restart = false;
   1858                 for (String[] arguments : mArguments) {
   1859                     restart = restart || (arguments != null);
   1860                 }
   1861                 if (!restart) {
   1862                     agentDisconnect();
   1863                     return;
   1864                 }
   1865                 updateState(DetailedState.CONNECTING, "execute");
   1866 
   1867                 // Start the daemon with arguments.
   1868                 for (int i = 0; i < mDaemons.length; ++i) {
   1869                     String[] arguments = mArguments[i];
   1870                     if (arguments == null) {
   1871                         continue;
   1872                     }
   1873 
   1874                     // Start the daemon.
   1875                     String daemon = mDaemons[i];
   1876                     SystemService.start(daemon);
   1877 
   1878                     // Wait for the daemon to start.
   1879                     while (!SystemService.isRunning(daemon)) {
   1880                         checkpoint(true);
   1881                     }
   1882 
   1883                     // Create the control socket.
   1884                     mSockets[i] = new LocalSocket();
   1885                     LocalSocketAddress address = new LocalSocketAddress(
   1886                             daemon, LocalSocketAddress.Namespace.RESERVED);
   1887 
   1888                     // Wait for the socket to connect.
   1889                     while (true) {
   1890                         try {
   1891                             mSockets[i].connect(address);
   1892                             break;
   1893                         } catch (Exception e) {
   1894                             // ignore
   1895                         }
   1896                         checkpoint(true);
   1897                     }
   1898                     mSockets[i].setSoTimeout(500);
   1899 
   1900                     // Send over the arguments.
   1901                     OutputStream out = mSockets[i].getOutputStream();
   1902                     for (String argument : arguments) {
   1903                         byte[] bytes = argument.getBytes(StandardCharsets.UTF_8);
   1904                         if (bytes.length >= 0xFFFF) {
   1905                             throw new IllegalArgumentException("Argument is too large");
   1906                         }
   1907                         out.write(bytes.length >> 8);
   1908                         out.write(bytes.length);
   1909                         out.write(bytes);
   1910                         checkpoint(false);
   1911                     }
   1912                     out.write(0xFF);
   1913                     out.write(0xFF);
   1914                     out.flush();
   1915 
   1916                     // Wait for End-of-File.
   1917                     InputStream in = mSockets[i].getInputStream();
   1918                     while (true) {
   1919                         try {
   1920                             if (in.read() == -1) {
   1921                                 break;
   1922                             }
   1923                         } catch (Exception e) {
   1924                             // ignore
   1925                         }
   1926                         checkpoint(true);
   1927                     }
   1928                 }
   1929 
   1930                 // Wait for the daemons to create the new state.
   1931                 while (!state.exists()) {
   1932                     // Check if a running daemon is dead.
   1933                     for (int i = 0; i < mDaemons.length; ++i) {
   1934                         String daemon = mDaemons[i];
   1935                         if (mArguments[i] != null && !SystemService.isRunning(daemon)) {
   1936                             throw new IllegalStateException(daemon + " is dead");
   1937                         }
   1938                     }
   1939                     checkpoint(true);
   1940                 }
   1941 
   1942                 // Now we are connected. Read and parse the new state.
   1943                 String[] parameters = FileUtils.readTextFile(state, 0, null).split("\n", -1);
   1944                 if (parameters.length != 7) {
   1945                     throw new IllegalStateException("Cannot parse the state");
   1946                 }
   1947 
   1948                 // Set the interface and the addresses in the config.
   1949                 mConfig.interfaze = parameters[0].trim();
   1950 
   1951                 mConfig.addLegacyAddresses(parameters[1]);
   1952                 // Set the routes if they are not set in the config.
   1953                 if (mConfig.routes == null || mConfig.routes.isEmpty()) {
   1954                     mConfig.addLegacyRoutes(parameters[2]);
   1955                 }
   1956 
   1957                 // Set the DNS servers if they are not set in the config.
   1958                 if (mConfig.dnsServers == null || mConfig.dnsServers.size() == 0) {
   1959                     String dnsServers = parameters[3].trim();
   1960                     if (!dnsServers.isEmpty()) {
   1961                         mConfig.dnsServers = Arrays.asList(dnsServers.split(" "));
   1962                     }
   1963                 }
   1964 
   1965                 // Set the search domains if they are not set in the config.
   1966                 if (mConfig.searchDomains == null || mConfig.searchDomains.size() == 0) {
   1967                     String searchDomains = parameters[4].trim();
   1968                     if (!searchDomains.isEmpty()) {
   1969                         mConfig.searchDomains = Arrays.asList(searchDomains.split(" "));
   1970                     }
   1971                 }
   1972 
   1973                 // Add a throw route for the VPN server endpoint, if one was specified.
   1974                 String endpoint = parameters[5];
   1975                 if (!endpoint.isEmpty()) {
   1976                     try {
   1977                         InetAddress addr = InetAddress.parseNumericAddress(endpoint);
   1978                         if (addr instanceof Inet4Address) {
   1979                             mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 32), RTN_THROW));
   1980                         } else if (addr instanceof Inet6Address) {
   1981                             mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 128), RTN_THROW));
   1982                         } else {
   1983                             Log.e(TAG, "Unknown IP address family for VPN endpoint: " + endpoint);
   1984                         }
   1985                     } catch (IllegalArgumentException e) {
   1986                         Log.e(TAG, "Exception constructing throw route to " + endpoint + ": " + e);
   1987                     }
   1988                 }
   1989 
   1990                 // Here is the last step and it must be done synchronously.
   1991                 synchronized (Vpn.this) {
   1992                     // Set the start time
   1993                     mConfig.startTime = SystemClock.elapsedRealtime();
   1994 
   1995                     // Check if the thread is interrupted while we are waiting.
   1996                     checkpoint(false);
   1997 
   1998                     // Check if the interface is gone while we are waiting.
   1999                     if (jniCheck(mConfig.interfaze) == 0) {
   2000                         throw new IllegalStateException(mConfig.interfaze + " is gone");
   2001                     }
   2002 
   2003                     // Now INetworkManagementEventObserver is watching our back.
   2004                     mInterface = mConfig.interfaze;
   2005                     prepareStatusIntent();
   2006 
   2007                     agentConnect();
   2008 
   2009                     Log.i(TAG, "Connected!");
   2010                 }
   2011             } catch (Exception e) {
   2012                 Log.i(TAG, "Aborting", e);
   2013                 updateState(DetailedState.FAILED, e.getMessage());
   2014                 exit();
   2015             }
   2016         }
   2017 
   2018         /**
   2019          * Monitor the daemons we started, moving to disconnected state if the
   2020          * underlying services fail.
   2021          */
   2022         private void monitorDaemons() throws InterruptedException{
   2023             if (!mNetworkInfo.isConnected()) {
   2024                 return;
   2025             }
   2026             while (true) {
   2027                 Thread.sleep(2000);
   2028                 for (int i = 0; i < mDaemons.length; i++) {
   2029                     if (mArguments[i] != null && SystemService.isStopped(mDaemons[i])) {
   2030                         return;
   2031                     }
   2032                 }
   2033             }
   2034         }
   2035     }
   2036 }
   2037