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