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.os.UserHandle.PER_USER_RANGE;
     21 import static android.net.RouteInfo.RTN_THROW;
     22 import static android.net.RouteInfo.RTN_UNREACHABLE;
     23 import static android.system.OsConstants.AF_INET;
     24 import static android.system.OsConstants.AF_INET6;
     25 
     26 import android.app.AppGlobals;
     27 import android.app.AppOpsManager;
     28 import android.app.PendingIntent;
     29 import android.content.BroadcastReceiver;
     30 import android.content.ComponentName;
     31 import android.content.Context;
     32 import android.content.Intent;
     33 import android.content.IntentFilter;
     34 import android.content.ServiceConnection;
     35 import android.content.pm.ApplicationInfo;
     36 import android.content.pm.PackageManager;
     37 import android.content.pm.PackageManager.NameNotFoundException;
     38 import android.content.pm.ResolveInfo;
     39 import android.content.pm.UserInfo;
     40 import android.net.ConnectivityManager;
     41 import android.net.IConnectivityManager;
     42 import android.net.INetworkManagementEventObserver;
     43 import android.net.IpPrefix;
     44 import android.net.LinkAddress;
     45 import android.net.LinkProperties;
     46 import android.net.LocalSocket;
     47 import android.net.LocalSocketAddress;
     48 import android.net.NetworkAgent;
     49 import android.net.NetworkCapabilities;
     50 import android.net.NetworkInfo;
     51 import android.net.NetworkInfo.DetailedState;
     52 import android.net.NetworkMisc;
     53 import android.net.RouteInfo;
     54 import android.net.UidRange;
     55 import android.os.Binder;
     56 import android.os.FileUtils;
     57 import android.os.IBinder;
     58 import android.os.INetworkManagementService;
     59 import android.os.Looper;
     60 import android.os.Parcel;
     61 import android.os.ParcelFileDescriptor;
     62 import android.os.Process;
     63 import android.os.RemoteException;
     64 import android.os.SystemClock;
     65 import android.os.SystemService;
     66 import android.os.UserHandle;
     67 import android.os.UserManager;
     68 import android.security.Credentials;
     69 import android.security.KeyStore;
     70 import android.util.Log;
     71 
     72 import com.android.internal.annotations.GuardedBy;
     73 import com.android.internal.net.LegacyVpnInfo;
     74 import com.android.internal.net.VpnConfig;
     75 import com.android.internal.net.VpnProfile;
     76 import com.android.server.net.BaseNetworkObserver;
     77 
     78 import libcore.io.IoUtils;
     79 
     80 import java.io.File;
     81 import java.io.IOException;
     82 import java.io.InputStream;
     83 import java.io.OutputStream;
     84 import java.net.Inet4Address;
     85 import java.net.Inet6Address;
     86 import java.net.InetAddress;
     87 import java.nio.charset.StandardCharsets;
     88 import java.util.ArrayList;
     89 import java.util.Arrays;
     90 import java.util.List;
     91 import java.util.SortedSet;
     92 import java.util.TreeSet;
     93 import java.util.concurrent.atomic.AtomicInteger;
     94 
     95 /**
     96  * @hide
     97  */
     98 public class Vpn {
     99     private static final String NETWORKTYPE = "VPN";
    100     private static final String TAG = "Vpn";
    101     private static final boolean LOGD = true;
    102 
    103     // TODO: create separate trackers for each unique VPN to support
    104     // automated reconnection
    105 
    106     private Context mContext;
    107     private NetworkInfo mNetworkInfo;
    108     private String mPackage;
    109     private int mOwnerUID;
    110     private String mInterface;
    111     private Connection mConnection;
    112     private LegacyVpnRunner mLegacyVpnRunner;
    113     private PendingIntent mStatusIntent;
    114     private volatile boolean mEnableTeardown = true;
    115     private final IConnectivityManager mConnService;
    116     private final INetworkManagementService mNetd;
    117     private VpnConfig mConfig;
    118     private NetworkAgent mNetworkAgent;
    119     private final Looper mLooper;
    120     private final NetworkCapabilities mNetworkCapabilities;
    121 
    122     /* list of users using this VPN. */
    123     @GuardedBy("this")
    124     private List<UidRange> mVpnUsers = null;
    125     private BroadcastReceiver mUserIntentReceiver = null;
    126 
    127     // Handle of user initiating VPN.
    128     private final int mUserHandle;
    129 
    130     public Vpn(Looper looper, Context context, INetworkManagementService netService,
    131             IConnectivityManager connService, int userHandle) {
    132         mContext = context;
    133         mNetd = netService;
    134         mConnService = connService;
    135         mUserHandle = userHandle;
    136         mLooper = looper;
    137 
    138         mPackage = VpnConfig.LEGACY_VPN;
    139         mOwnerUID = getAppUid(mPackage, mUserHandle);
    140 
    141         try {
    142             netService.registerObserver(mObserver);
    143         } catch (RemoteException e) {
    144             Log.wtf(TAG, "Problem registering observer", e);
    145         }
    146         if (userHandle == UserHandle.USER_OWNER) {
    147             // Owner's VPN also needs to handle restricted users
    148             mUserIntentReceiver = new BroadcastReceiver() {
    149                 @Override
    150                 public void onReceive(Context context, Intent intent) {
    151                     final String action = intent.getAction();
    152                     final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
    153                             UserHandle.USER_NULL);
    154                     if (userHandle == UserHandle.USER_NULL) return;
    155 
    156                     if (Intent.ACTION_USER_ADDED.equals(action)) {
    157                         onUserAdded(userHandle);
    158                     } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
    159                         onUserRemoved(userHandle);
    160                     }
    161                 }
    162             };
    163 
    164             IntentFilter intentFilter = new IntentFilter();
    165             intentFilter.addAction(Intent.ACTION_USER_ADDED);
    166             intentFilter.addAction(Intent.ACTION_USER_REMOVED);
    167             mContext.registerReceiverAsUser(
    168                     mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
    169         }
    170 
    171         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_VPN, 0, NETWORKTYPE, "");
    172         // TODO: Copy metered attribute and bandwidths from physical transport, b/16207332
    173         mNetworkCapabilities = new NetworkCapabilities();
    174         mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_VPN);
    175         mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
    176     }
    177 
    178     /**
    179      * Set if this object is responsible for watching for {@link NetworkInfo}
    180      * teardown. When {@code false}, teardown is handled externally by someone
    181      * else.
    182      */
    183     public void setEnableTeardown(boolean enableTeardown) {
    184         mEnableTeardown = enableTeardown;
    185     }
    186 
    187     /**
    188      * Update current state, dispaching event to listeners.
    189      */
    190     private void updateState(DetailedState detailedState, String reason) {
    191         if (LOGD) Log.d(TAG, "setting state=" + detailedState + ", reason=" + reason);
    192         mNetworkInfo.setDetailedState(detailedState, reason, null);
    193         if (mNetworkAgent != null) {
    194             mNetworkAgent.sendNetworkInfo(mNetworkInfo);
    195         }
    196     }
    197 
    198     /**
    199      * Prepare for a VPN application. This method is designed to solve
    200      * race conditions. It first compares the current prepared package
    201      * with {@code oldPackage}. If they are the same, the prepared
    202      * package is revoked and replaced with {@code newPackage}. If
    203      * {@code oldPackage} is {@code null}, the comparison is omitted.
    204      * If {@code newPackage} is the same package or {@code null}, the
    205      * revocation is omitted. This method returns {@code true} if the
    206      * operation is succeeded.
    207      *
    208      * Legacy VPN is handled specially since it is not a real package.
    209      * It uses {@link VpnConfig#LEGACY_VPN} as its package name, and
    210      * it can be revoked by itself.
    211      *
    212      * @param oldPackage The package name of the old VPN application.
    213      * @param newPackage The package name of the new VPN application.
    214      * @return true if the operation is succeeded.
    215      */
    216     public synchronized boolean prepare(String oldPackage, String newPackage) {
    217         // Return false if the package does not match.
    218         if (oldPackage != null && !oldPackage.equals(mPackage)) {
    219             // The package doesn't match. If this VPN was not previously authorized, return false
    220             // to force user authorization. Otherwise, revoke the VPN anyway.
    221             if (!oldPackage.equals(VpnConfig.LEGACY_VPN) && isVpnUserPreConsented(oldPackage)) {
    222                 long token = Binder.clearCallingIdentity();
    223                 try {
    224                     // This looks bizarre, but it is what ConfirmDialog in VpnDialogs is doing when
    225                     // the user clicks through to allow the VPN to consent. So we are emulating the
    226                     // action of the dialog without actually showing it.
    227                     prepare(null, oldPackage);
    228                 } finally {
    229                     Binder.restoreCallingIdentity(token);
    230                 }
    231                 return true;
    232             }
    233             return false;
    234         }
    235 
    236         // Return true if we do not need to revoke.
    237         if (newPackage == null ||
    238                 (newPackage.equals(mPackage) && !newPackage.equals(VpnConfig.LEGACY_VPN))) {
    239             return true;
    240         }
    241 
    242         // Check if the caller is authorized.
    243         enforceControlPermission();
    244 
    245         // Reset the interface.
    246         if (mInterface != null) {
    247             mStatusIntent = null;
    248             agentDisconnect();
    249             jniReset(mInterface);
    250             mInterface = null;
    251             mVpnUsers = null;
    252         }
    253 
    254         // Revoke the connection or stop LegacyVpnRunner.
    255         if (mConnection != null) {
    256             try {
    257                 mConnection.mService.transact(IBinder.LAST_CALL_TRANSACTION,
    258                         Parcel.obtain(), null, IBinder.FLAG_ONEWAY);
    259             } catch (Exception e) {
    260                 // ignore
    261             }
    262             mContext.unbindService(mConnection);
    263             mConnection = null;
    264         } else if (mLegacyVpnRunner != null) {
    265             mLegacyVpnRunner.exit();
    266             mLegacyVpnRunner = null;
    267         }
    268 
    269         long token = Binder.clearCallingIdentity();
    270         try {
    271             mNetd.denyProtect(mOwnerUID);
    272         } catch (Exception e) {
    273             Log.wtf(TAG, "Failed to disallow UID " + mOwnerUID + " to call protect() " + e);
    274         } finally {
    275             Binder.restoreCallingIdentity(token);
    276         }
    277 
    278         Log.i(TAG, "Switched from " + mPackage + " to " + newPackage);
    279         mPackage = newPackage;
    280         mOwnerUID = getAppUid(newPackage, mUserHandle);
    281         token = Binder.clearCallingIdentity();
    282         try {
    283             mNetd.allowProtect(mOwnerUID);
    284         } catch (Exception e) {
    285             Log.wtf(TAG, "Failed to allow UID " + mOwnerUID + " to call protect() " + e);
    286         } finally {
    287             Binder.restoreCallingIdentity(token);
    288         }
    289         mConfig = null;
    290 
    291         updateState(DetailedState.IDLE, "prepare");
    292         return true;
    293     }
    294 
    295     /**
    296      * Set whether the current package has the ability to launch VPNs without user intervention.
    297      */
    298     public void setPackageAuthorization(boolean authorized) {
    299         // Check if the caller is authorized.
    300         enforceControlPermission();
    301 
    302         if (mPackage == null || VpnConfig.LEGACY_VPN.equals(mPackage)) {
    303             return;
    304         }
    305 
    306         long token = Binder.clearCallingIdentity();
    307         try {
    308             AppOpsManager appOps =
    309                     (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
    310             appOps.setMode(AppOpsManager.OP_ACTIVATE_VPN, mOwnerUID, mPackage,
    311                     authorized ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
    312         } catch (Exception e) {
    313             Log.wtf(TAG, "Failed to set app ops for package " + mPackage, e);
    314         } finally {
    315             Binder.restoreCallingIdentity(token);
    316         }
    317     }
    318 
    319     private boolean isVpnUserPreConsented(String packageName) {
    320         AppOpsManager appOps =
    321                 (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
    322 
    323         // Verify that the caller matches the given package and has permission to activate VPNs.
    324         return appOps.noteOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN, Binder.getCallingUid(),
    325                 packageName) == AppOpsManager.MODE_ALLOWED;
    326     }
    327 
    328     private int getAppUid(String app, int userHandle) {
    329         if (VpnConfig.LEGACY_VPN.equals(app)) {
    330             return Process.myUid();
    331         }
    332         PackageManager pm = mContext.getPackageManager();
    333         int result;
    334         try {
    335             result = pm.getPackageUid(app, userHandle);
    336         } catch (NameNotFoundException e) {
    337             result = -1;
    338         }
    339         return result;
    340     }
    341 
    342     public NetworkInfo getNetworkInfo() {
    343         return mNetworkInfo;
    344     }
    345 
    346     private LinkProperties makeLinkProperties() {
    347         boolean allowIPv4 = mConfig.allowIPv4;
    348         boolean allowIPv6 = mConfig.allowIPv6;
    349 
    350         LinkProperties lp = new LinkProperties();
    351 
    352         lp.setInterfaceName(mInterface);
    353 
    354         if (mConfig.addresses != null) {
    355             for (LinkAddress address : mConfig.addresses) {
    356                 lp.addLinkAddress(address);
    357                 allowIPv4 |= address.getAddress() instanceof Inet4Address;
    358                 allowIPv6 |= address.getAddress() instanceof Inet6Address;
    359             }
    360         }
    361 
    362         if (mConfig.routes != null) {
    363             for (RouteInfo route : mConfig.routes) {
    364                 lp.addRoute(route);
    365                 InetAddress address = route.getDestination().getAddress();
    366                 allowIPv4 |= address instanceof Inet4Address;
    367                 allowIPv6 |= address instanceof Inet6Address;
    368             }
    369         }
    370 
    371         if (mConfig.dnsServers != null) {
    372             for (String dnsServer : mConfig.dnsServers) {
    373                 InetAddress address = InetAddress.parseNumericAddress(dnsServer);
    374                 lp.addDnsServer(address);
    375                 allowIPv4 |= address instanceof Inet4Address;
    376                 allowIPv6 |= address instanceof Inet6Address;
    377             }
    378         }
    379 
    380         if (!allowIPv4) {
    381             lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
    382         }
    383         if (!allowIPv6) {
    384             lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
    385         }
    386 
    387         // Concatenate search domains into a string.
    388         StringBuilder buffer = new StringBuilder();
    389         if (mConfig.searchDomains != null) {
    390             for (String domain : mConfig.searchDomains) {
    391                 buffer.append(domain).append(' ');
    392             }
    393         }
    394         lp.setDomains(buffer.toString().trim());
    395 
    396         // TODO: Stop setting the MTU in jniCreate and set it here.
    397 
    398         return lp;
    399     }
    400 
    401     private void agentConnect() {
    402         LinkProperties lp = makeLinkProperties();
    403 
    404         if (lp.hasIPv4DefaultRoute() || lp.hasIPv6DefaultRoute()) {
    405             mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
    406         } else {
    407             mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
    408         }
    409 
    410         mNetworkInfo.setIsAvailable(true);
    411         mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
    412 
    413         NetworkMisc networkMisc = new NetworkMisc();
    414         networkMisc.allowBypass = mConfig.allowBypass;
    415 
    416         long token = Binder.clearCallingIdentity();
    417         try {
    418             mNetworkAgent = new NetworkAgent(mLooper, mContext, NETWORKTYPE,
    419                     mNetworkInfo, mNetworkCapabilities, lp, 0, networkMisc) {
    420                             @Override
    421                             public void unwanted() {
    422                                 // We are user controlled, not driven by NetworkRequest.
    423                             }
    424                         };
    425         } finally {
    426             Binder.restoreCallingIdentity(token);
    427         }
    428 
    429         addVpnUserLocked(mUserHandle);
    430         // If we are owner assign all Restricted Users to this VPN
    431         if (mUserHandle == UserHandle.USER_OWNER) {
    432             token = Binder.clearCallingIdentity();
    433             List<UserInfo> users;
    434             try {
    435                 users = UserManager.get(mContext).getUsers();
    436             } finally {
    437                 Binder.restoreCallingIdentity(token);
    438             }
    439             for (UserInfo user : users) {
    440                 if (user.isRestricted()) {
    441                     addVpnUserLocked(user.id);
    442                 }
    443             }
    444         }
    445         mNetworkAgent.addUidRanges(mVpnUsers.toArray(new UidRange[mVpnUsers.size()]));
    446     }
    447 
    448     private void agentDisconnect(NetworkInfo networkInfo, NetworkAgent networkAgent) {
    449         networkInfo.setIsAvailable(false);
    450         networkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
    451         if (networkAgent != null) {
    452             networkAgent.sendNetworkInfo(networkInfo);
    453         }
    454     }
    455 
    456     private void agentDisconnect(NetworkAgent networkAgent) {
    457         NetworkInfo networkInfo = new NetworkInfo(mNetworkInfo);
    458         agentDisconnect(networkInfo, networkAgent);
    459     }
    460 
    461     private void agentDisconnect() {
    462         if (mNetworkInfo.isConnected()) {
    463             agentDisconnect(mNetworkInfo, mNetworkAgent);
    464             mNetworkAgent = null;
    465         }
    466     }
    467 
    468     /**
    469      * Establish a VPN network and return the file descriptor of the VPN
    470      * interface. This methods returns {@code null} if the application is
    471      * revoked or not prepared.
    472      *
    473      * @param config The parameters to configure the network.
    474      * @return The file descriptor of the VPN interface.
    475      */
    476     public synchronized ParcelFileDescriptor establish(VpnConfig config) {
    477         // Check if the caller is already prepared.
    478         UserManager mgr = UserManager.get(mContext);
    479         if (Binder.getCallingUid() != mOwnerUID) {
    480             return null;
    481         }
    482         // Check if the service is properly declared.
    483         Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE);
    484         intent.setClassName(mPackage, config.user);
    485         long token = Binder.clearCallingIdentity();
    486         try {
    487             // Restricted users are not allowed to create VPNs, they are tied to Owner
    488             UserInfo user = mgr.getUserInfo(mUserHandle);
    489             if (user.isRestricted() || mgr.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
    490                 throw new SecurityException("Restricted users cannot establish VPNs");
    491             }
    492 
    493             ResolveInfo info = AppGlobals.getPackageManager().resolveService(intent,
    494                                                                         null, 0, mUserHandle);
    495             if (info == null) {
    496                 throw new SecurityException("Cannot find " + config.user);
    497             }
    498             if (!BIND_VPN_SERVICE.equals(info.serviceInfo.permission)) {
    499                 throw new SecurityException(config.user + " does not require " + BIND_VPN_SERVICE);
    500             }
    501         } catch (RemoteException e) {
    502                 throw new SecurityException("Cannot find " + config.user);
    503         } finally {
    504             Binder.restoreCallingIdentity(token);
    505         }
    506 
    507         // Save the old config in case we need to go back.
    508         VpnConfig oldConfig = mConfig;
    509         String oldInterface = mInterface;
    510         Connection oldConnection = mConnection;
    511         NetworkAgent oldNetworkAgent = mNetworkAgent;
    512         mNetworkAgent = null;
    513         List<UidRange> oldUsers = mVpnUsers;
    514 
    515         // Configure the interface. Abort if any of these steps fails.
    516         ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
    517         try {
    518             updateState(DetailedState.CONNECTING, "establish");
    519             String interfaze = jniGetName(tun.getFd());
    520 
    521             // TEMP use the old jni calls until there is support for netd address setting
    522             StringBuilder builder = new StringBuilder();
    523             for (LinkAddress address : config.addresses) {
    524                 builder.append(" " + address);
    525             }
    526             if (jniSetAddresses(interfaze, builder.toString()) < 1) {
    527                 throw new IllegalArgumentException("At least one address must be specified");
    528             }
    529             Connection connection = new Connection();
    530             if (!mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE,
    531                         new UserHandle(mUserHandle))) {
    532                 throw new IllegalStateException("Cannot bind " + config.user);
    533             }
    534 
    535             mConnection = connection;
    536             mInterface = interfaze;
    537 
    538             // Fill more values.
    539             config.user = mPackage;
    540             config.interfaze = mInterface;
    541             config.startTime = SystemClock.elapsedRealtime();
    542             mConfig = config;
    543 
    544             // Set up forwarding and DNS rules.
    545             mVpnUsers = new ArrayList<UidRange>();
    546 
    547             agentConnect();
    548 
    549             if (oldConnection != null) {
    550                 mContext.unbindService(oldConnection);
    551             }
    552             // Remove the old tun's user forwarding rules
    553             // The new tun's user rules have already been added so they will take over
    554             // as rules are deleted. This prevents data leakage as the rules are moved over.
    555             agentDisconnect(oldNetworkAgent);
    556             if (oldInterface != null && !oldInterface.equals(interfaze)) {
    557                 jniReset(oldInterface);
    558             }
    559 
    560             try {
    561                 IoUtils.setBlocking(tun.getFileDescriptor(), config.blocking);
    562             } catch (IOException e) {
    563                 throw new IllegalStateException(
    564                         "Cannot set tunnel's fd as blocking=" + config.blocking, e);
    565             }
    566         } catch (RuntimeException e) {
    567             IoUtils.closeQuietly(tun);
    568             agentDisconnect();
    569             // restore old state
    570             mConfig = oldConfig;
    571             mConnection = oldConnection;
    572             mVpnUsers = oldUsers;
    573             mNetworkAgent = oldNetworkAgent;
    574             mInterface = oldInterface;
    575             throw e;
    576         }
    577         Log.i(TAG, "Established by " + config.user + " on " + mInterface);
    578         return tun;
    579     }
    580 
    581     private boolean isRunningLocked() {
    582         return mVpnUsers != null;
    583     }
    584 
    585     // Note: Return type guarantees results are deduped and sorted, which callers require.
    586     private SortedSet<Integer> getAppsUids(List<String> packageNames, int userHandle) {
    587         SortedSet<Integer> uids = new TreeSet<Integer>();
    588         for (String app : packageNames) {
    589             int uid = getAppUid(app, userHandle);
    590             if (uid != -1) uids.add(uid);
    591         }
    592         return uids;
    593     }
    594 
    595     // Note: This function adds to mVpnUsers but does not publish list to NetworkAgent.
    596     private void addVpnUserLocked(int userHandle) {
    597         if (!isRunningLocked()) {
    598             throw new IllegalStateException("VPN is not active");
    599         }
    600 
    601         if (mConfig.allowedApplications != null) {
    602             // Add ranges covering all UIDs for allowedApplications.
    603             int start = -1, stop = -1;
    604             for (int uid : getAppsUids(mConfig.allowedApplications, userHandle)) {
    605                 if (start == -1) {
    606                     start = uid;
    607                 } else if (uid != stop + 1) {
    608                     mVpnUsers.add(new UidRange(start, stop));
    609                     start = uid;
    610                 }
    611                 stop = uid;
    612             }
    613             if (start != -1) mVpnUsers.add(new UidRange(start, stop));
    614         } else if (mConfig.disallowedApplications != null) {
    615             // Add all ranges for user skipping UIDs for disallowedApplications.
    616             final UidRange userRange = UidRange.createForUser(userHandle);
    617             int start = userRange.start;
    618             for (int uid : getAppsUids(mConfig.disallowedApplications, userHandle)) {
    619                 if (uid == start) {
    620                     start++;
    621                 } else {
    622                     mVpnUsers.add(new UidRange(start, uid - 1));
    623                     start = uid + 1;
    624                 }
    625             }
    626             if (start <= userRange.stop) mVpnUsers.add(new UidRange(start, userRange.stop));
    627         } else {
    628             // Add all UIDs for the user.
    629             mVpnUsers.add(UidRange.createForUser(userHandle));
    630         }
    631 
    632         prepareStatusIntent();
    633     }
    634 
    635     // Returns the subset of the full list of active UID ranges the VPN applies to (mVpnUsers) that
    636     // apply to userHandle.
    637     private List<UidRange> uidRangesForUser(int userHandle) {
    638         final UidRange userRange = UidRange.createForUser(userHandle);
    639         final List<UidRange> ranges = new ArrayList<UidRange>();
    640         for (UidRange range : mVpnUsers) {
    641             if (range.start >= userRange.start && range.stop <= userRange.stop) {
    642                 ranges.add(range);
    643             }
    644         }
    645         return ranges;
    646     }
    647 
    648     private void removeVpnUserLocked(int userHandle) {
    649         if (!isRunningLocked()) {
    650             throw new IllegalStateException("VPN is not active");
    651         }
    652         final List<UidRange> ranges = uidRangesForUser(userHandle);
    653         if (mNetworkAgent != null) {
    654             mNetworkAgent.removeUidRanges(ranges.toArray(new UidRange[ranges.size()]));
    655         }
    656         mVpnUsers.removeAll(ranges);
    657         mStatusIntent = null;
    658     }
    659 
    660     private void onUserAdded(int userHandle) {
    661         // If the user is restricted tie them to the owner's VPN
    662         synchronized(Vpn.this) {
    663             UserManager mgr = UserManager.get(mContext);
    664             UserInfo user = mgr.getUserInfo(userHandle);
    665             if (user.isRestricted()) {
    666                 try {
    667                     addVpnUserLocked(userHandle);
    668                     if (mNetworkAgent != null) {
    669                         final List<UidRange> ranges = uidRangesForUser(userHandle);
    670                         mNetworkAgent.addUidRanges(ranges.toArray(new UidRange[ranges.size()]));
    671                     }
    672                 } catch (Exception e) {
    673                     Log.wtf(TAG, "Failed to add restricted user to owner", e);
    674                 }
    675             }
    676         }
    677     }
    678 
    679     private void onUserRemoved(int userHandle) {
    680         // clean up if restricted
    681         synchronized(Vpn.this) {
    682             UserManager mgr = UserManager.get(mContext);
    683             UserInfo user = mgr.getUserInfo(userHandle);
    684             if (user.isRestricted()) {
    685                 try {
    686                     removeVpnUserLocked(userHandle);
    687                 } catch (Exception e) {
    688                     Log.wtf(TAG, "Failed to remove restricted user to owner", e);
    689                 }
    690             }
    691         }
    692     }
    693 
    694     /**
    695      * Return the configuration of the currently running VPN.
    696      */
    697     public VpnConfig getVpnConfig() {
    698         enforceControlPermission();
    699         return mConfig;
    700     }
    701 
    702     @Deprecated
    703     public synchronized void interfaceStatusChanged(String iface, boolean up) {
    704         try {
    705             mObserver.interfaceStatusChanged(iface, up);
    706         } catch (RemoteException e) {
    707             // ignored; target is local
    708         }
    709     }
    710 
    711     private INetworkManagementEventObserver mObserver = new BaseNetworkObserver() {
    712         @Override
    713         public void interfaceStatusChanged(String interfaze, boolean up) {
    714             synchronized (Vpn.this) {
    715                 if (!up && mLegacyVpnRunner != null) {
    716                     mLegacyVpnRunner.check(interfaze);
    717                 }
    718             }
    719         }
    720 
    721         @Override
    722         public void interfaceRemoved(String interfaze) {
    723             synchronized (Vpn.this) {
    724                 if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
    725                     mStatusIntent = null;
    726                     mVpnUsers = null;
    727                     mInterface = null;
    728                     if (mConnection != null) {
    729                         mContext.unbindService(mConnection);
    730                         mConnection = null;
    731                         agentDisconnect();
    732                     } else if (mLegacyVpnRunner != null) {
    733                         mLegacyVpnRunner.exit();
    734                         mLegacyVpnRunner = null;
    735                     }
    736                 }
    737             }
    738         }
    739     };
    740 
    741     private void enforceControlPermission() {
    742         // System user is allowed to control VPN.
    743         if (Binder.getCallingUid() == Process.SYSTEM_UID) {
    744             return;
    745         }
    746         int appId = UserHandle.getAppId(Binder.getCallingUid());
    747         final long token = Binder.clearCallingIdentity();
    748         try {
    749             // System VPN dialogs are also allowed to control VPN.
    750             PackageManager pm = mContext.getPackageManager();
    751             ApplicationInfo app = pm.getApplicationInfo(VpnConfig.DIALOGS_PACKAGE, 0);
    752             if (((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) && (appId == app.uid)) {
    753                 return;
    754             }
    755             // SystemUI dialogs are also allowed to control VPN.
    756             ApplicationInfo sysUiApp = pm.getApplicationInfo("com.android.systemui", 0);
    757             if (((sysUiApp.flags & ApplicationInfo.FLAG_SYSTEM) != 0) && (appId == sysUiApp.uid)) {
    758                 return;
    759             }
    760         } catch (Exception e) {
    761             // ignore
    762         } finally {
    763             Binder.restoreCallingIdentity(token);
    764         }
    765 
    766         throw new SecurityException("Unauthorized Caller");
    767     }
    768 
    769     private class Connection implements ServiceConnection {
    770         private IBinder mService;
    771 
    772         @Override
    773         public void onServiceConnected(ComponentName name, IBinder service) {
    774             mService = service;
    775         }
    776 
    777         @Override
    778         public void onServiceDisconnected(ComponentName name) {
    779             mService = null;
    780         }
    781     }
    782 
    783     private void prepareStatusIntent() {
    784         final long token = Binder.clearCallingIdentity();
    785         try {
    786             mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext);
    787         } finally {
    788             Binder.restoreCallingIdentity(token);
    789         }
    790     }
    791 
    792     public synchronized boolean addAddress(String address, int prefixLength) {
    793         if (Binder.getCallingUid() != mOwnerUID || mInterface == null || mNetworkAgent == null) {
    794             return false;
    795         }
    796         boolean success = jniAddAddress(mInterface, address, prefixLength);
    797         if (mNetworkAgent != null) {
    798             mNetworkAgent.sendLinkProperties(makeLinkProperties());
    799         }
    800         return success;
    801     }
    802 
    803     public synchronized boolean removeAddress(String address, int prefixLength) {
    804         if (Binder.getCallingUid() != mOwnerUID || mInterface == null || mNetworkAgent == null) {
    805             return false;
    806         }
    807         boolean success = jniDelAddress(mInterface, address, prefixLength);
    808         if (mNetworkAgent != null) {
    809             mNetworkAgent.sendLinkProperties(makeLinkProperties());
    810         }
    811         return success;
    812     }
    813 
    814     private native int jniCreate(int mtu);
    815     private native String jniGetName(int tun);
    816     private native int jniSetAddresses(String interfaze, String addresses);
    817     private native void jniReset(String interfaze);
    818     private native int jniCheck(String interfaze);
    819     private native boolean jniAddAddress(String interfaze, String address, int prefixLen);
    820     private native boolean jniDelAddress(String interfaze, String address, int prefixLen);
    821 
    822     private static RouteInfo findIPv4DefaultRoute(LinkProperties prop) {
    823         for (RouteInfo route : prop.getAllRoutes()) {
    824             // Currently legacy VPN only works on IPv4.
    825             if (route.isDefaultRoute() && route.getGateway() instanceof Inet4Address) {
    826                 return route;
    827             }
    828         }
    829 
    830         throw new IllegalStateException("Unable to find IPv4 default gateway");
    831     }
    832 
    833     /**
    834      * Start legacy VPN, controlling native daemons as needed. Creates a
    835      * secondary thread to perform connection work, returning quickly.
    836      */
    837     public void startLegacyVpn(VpnProfile profile, KeyStore keyStore, LinkProperties egress) {
    838         enforceControlPermission();
    839         if (!keyStore.isUnlocked()) {
    840             throw new IllegalStateException("KeyStore isn't unlocked");
    841         }
    842         UserManager mgr = UserManager.get(mContext);
    843         UserInfo user = mgr.getUserInfo(mUserHandle);
    844         if (user.isRestricted() || mgr.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
    845             throw new SecurityException("Restricted users cannot establish VPNs");
    846         }
    847 
    848         final RouteInfo ipv4DefaultRoute = findIPv4DefaultRoute(egress);
    849         final String gateway = ipv4DefaultRoute.getGateway().getHostAddress();
    850         final String iface = ipv4DefaultRoute.getInterface();
    851 
    852         // Load certificates.
    853         String privateKey = "";
    854         String userCert = "";
    855         String caCert = "";
    856         String serverCert = "";
    857         if (!profile.ipsecUserCert.isEmpty()) {
    858             privateKey = Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert;
    859             byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecUserCert);
    860             userCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
    861         }
    862         if (!profile.ipsecCaCert.isEmpty()) {
    863             byte[] value = keyStore.get(Credentials.CA_CERTIFICATE + profile.ipsecCaCert);
    864             caCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
    865         }
    866         if (!profile.ipsecServerCert.isEmpty()) {
    867             byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecServerCert);
    868             serverCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8);
    869         }
    870         if (privateKey == null || userCert == null || caCert == null || serverCert == null) {
    871             throw new IllegalStateException("Cannot load credentials");
    872         }
    873 
    874         // Prepare arguments for racoon.
    875         String[] racoon = null;
    876         switch (profile.type) {
    877             case VpnProfile.TYPE_L2TP_IPSEC_PSK:
    878                 racoon = new String[] {
    879                     iface, profile.server, "udppsk", profile.ipsecIdentifier,
    880                     profile.ipsecSecret, "1701",
    881                 };
    882                 break;
    883             case VpnProfile.TYPE_L2TP_IPSEC_RSA:
    884                 racoon = new String[] {
    885                     iface, profile.server, "udprsa", privateKey, userCert,
    886                     caCert, serverCert, "1701",
    887                 };
    888                 break;
    889             case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
    890                 racoon = new String[] {
    891                     iface, profile.server, "xauthpsk", profile.ipsecIdentifier,
    892                     profile.ipsecSecret, profile.username, profile.password, "", gateway,
    893                 };
    894                 break;
    895             case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
    896                 racoon = new String[] {
    897                     iface, profile.server, "xauthrsa", privateKey, userCert,
    898                     caCert, serverCert, profile.username, profile.password, "", gateway,
    899                 };
    900                 break;
    901             case VpnProfile.TYPE_IPSEC_HYBRID_RSA:
    902                 racoon = new String[] {
    903                     iface, profile.server, "hybridrsa",
    904                     caCert, serverCert, profile.username, profile.password, "", gateway,
    905                 };
    906                 break;
    907         }
    908 
    909         // Prepare arguments for mtpd.
    910         String[] mtpd = null;
    911         switch (profile.type) {
    912             case VpnProfile.TYPE_PPTP:
    913                 mtpd = new String[] {
    914                     iface, "pptp", profile.server, "1723",
    915                     "name", profile.username, "password", profile.password,
    916                     "linkname", "vpn", "refuse-eap", "nodefaultroute",
    917                     "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
    918                     (profile.mppe ? "+mppe" : "nomppe"),
    919                 };
    920                 break;
    921             case VpnProfile.TYPE_L2TP_IPSEC_PSK:
    922             case VpnProfile.TYPE_L2TP_IPSEC_RSA:
    923                 mtpd = new String[] {
    924                     iface, "l2tp", profile.server, "1701", profile.l2tpSecret,
    925                     "name", profile.username, "password", profile.password,
    926                     "linkname", "vpn", "refuse-eap", "nodefaultroute",
    927                     "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
    928                 };
    929                 break;
    930         }
    931 
    932         VpnConfig config = new VpnConfig();
    933         config.legacy = true;
    934         config.user = profile.key;
    935         config.interfaze = iface;
    936         config.session = profile.name;
    937 
    938         config.addLegacyRoutes(profile.routes);
    939         if (!profile.dnsServers.isEmpty()) {
    940             config.dnsServers = Arrays.asList(profile.dnsServers.split(" +"));
    941         }
    942         if (!profile.searchDomains.isEmpty()) {
    943             config.searchDomains = Arrays.asList(profile.searchDomains.split(" +"));
    944         }
    945         startLegacyVpn(config, racoon, mtpd);
    946     }
    947 
    948     private synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
    949         stopLegacyVpn();
    950 
    951         // Prepare for the new request. This also checks the caller.
    952         prepare(null, VpnConfig.LEGACY_VPN);
    953         updateState(DetailedState.CONNECTING, "startLegacyVpn");
    954 
    955         // Start a new LegacyVpnRunner and we are done!
    956         mLegacyVpnRunner = new LegacyVpnRunner(config, racoon, mtpd);
    957         mLegacyVpnRunner.start();
    958     }
    959 
    960     public synchronized void stopLegacyVpn() {
    961         if (mLegacyVpnRunner != null) {
    962             mLegacyVpnRunner.exit();
    963             mLegacyVpnRunner = null;
    964 
    965             synchronized (LegacyVpnRunner.TAG) {
    966                 // wait for old thread to completely finish before spinning up
    967                 // new instance, otherwise state updates can be out of order.
    968             }
    969         }
    970     }
    971 
    972     /**
    973      * Return the information of the current ongoing legacy VPN.
    974      */
    975     public synchronized LegacyVpnInfo getLegacyVpnInfo() {
    976         // Check if the caller is authorized.
    977         enforceControlPermission();
    978         if (mLegacyVpnRunner == null) return null;
    979 
    980         final LegacyVpnInfo info = new LegacyVpnInfo();
    981         info.key = mConfig.user;
    982         info.state = LegacyVpnInfo.stateFromNetworkInfo(mNetworkInfo);
    983         if (mNetworkInfo.isConnected()) {
    984             info.intent = mStatusIntent;
    985         }
    986         return info;
    987     }
    988 
    989     public VpnConfig getLegacyVpnConfig() {
    990         if (mLegacyVpnRunner != null) {
    991             return mConfig;
    992         } else {
    993             return null;
    994         }
    995     }
    996 
    997     /**
    998      * Bringing up a VPN connection takes time, and that is all this thread
    999      * does. Here we have plenty of time. The only thing we need to take
   1000      * care of is responding to interruptions as soon as possible. Otherwise
   1001      * requests will be piled up. This can be done in a Handler as a state
   1002      * machine, but it is much easier to read in the current form.
   1003      */
   1004     private class LegacyVpnRunner extends Thread {
   1005         private static final String TAG = "LegacyVpnRunner";
   1006 
   1007         private final String[] mDaemons;
   1008         private final String[][] mArguments;
   1009         private final LocalSocket[] mSockets;
   1010         private final String mOuterInterface;
   1011         private final AtomicInteger mOuterConnection =
   1012                 new AtomicInteger(ConnectivityManager.TYPE_NONE);
   1013 
   1014         private long mTimer = -1;
   1015 
   1016         /**
   1017          * Watch for the outer connection (passing in the constructor) going away.
   1018          */
   1019         private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
   1020             @Override
   1021             public void onReceive(Context context, Intent intent) {
   1022                 if (!mEnableTeardown) return;
   1023 
   1024                 if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
   1025                     if (intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE,
   1026                             ConnectivityManager.TYPE_NONE) == mOuterConnection.get()) {
   1027                         NetworkInfo info = (NetworkInfo)intent.getExtra(
   1028                                 ConnectivityManager.EXTRA_NETWORK_INFO);
   1029                         if (info != null && !info.isConnectedOrConnecting()) {
   1030                             try {
   1031                                 mObserver.interfaceStatusChanged(mOuterInterface, false);
   1032                             } catch (RemoteException e) {}
   1033                         }
   1034                     }
   1035                 }
   1036             }
   1037         };
   1038 
   1039         public LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd) {
   1040             super(TAG);
   1041             mConfig = config;
   1042             mDaemons = new String[] {"racoon", "mtpd"};
   1043             // TODO: clear arguments from memory once launched
   1044             mArguments = new String[][] {racoon, mtpd};
   1045             mSockets = new LocalSocket[mDaemons.length];
   1046 
   1047             // This is the interface which VPN is running on,
   1048             // mConfig.interfaze will change to point to OUR
   1049             // internal interface soon. TODO - add inner/outer to mconfig
   1050             // TODO - we have a race - if the outer iface goes away/disconnects before we hit this
   1051             // we will leave the VPN up.  We should check that it's still there/connected after
   1052             // registering
   1053             mOuterInterface = mConfig.interfaze;
   1054 
   1055             try {
   1056                 mOuterConnection.set(
   1057                         mConnService.findConnectionTypeForIface(mOuterInterface));
   1058             } catch (Exception e) {
   1059                 mOuterConnection.set(ConnectivityManager.TYPE_NONE);
   1060             }
   1061 
   1062             IntentFilter filter = new IntentFilter();
   1063             filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
   1064             mContext.registerReceiver(mBroadcastReceiver, filter);
   1065         }
   1066 
   1067         public void check(String interfaze) {
   1068             if (interfaze.equals(mOuterInterface)) {
   1069                 Log.i(TAG, "Legacy VPN is going down with " + interfaze);
   1070                 exit();
   1071             }
   1072         }
   1073 
   1074         public void exit() {
   1075             // We assume that everything is reset after stopping the daemons.
   1076             interrupt();
   1077             for (LocalSocket socket : mSockets) {
   1078                 IoUtils.closeQuietly(socket);
   1079             }
   1080             agentDisconnect();
   1081             try {
   1082                 mContext.unregisterReceiver(mBroadcastReceiver);
   1083             } catch (IllegalArgumentException e) {}
   1084         }
   1085 
   1086         @Override
   1087         public void run() {
   1088             // Wait for the previous thread since it has been interrupted.
   1089             Log.v(TAG, "Waiting");
   1090             synchronized (TAG) {
   1091                 Log.v(TAG, "Executing");
   1092                 execute();
   1093                 monitorDaemons();
   1094             }
   1095         }
   1096 
   1097         private void checkpoint(boolean yield) throws InterruptedException {
   1098             long now = SystemClock.elapsedRealtime();
   1099             if (mTimer == -1) {
   1100                 mTimer = now;
   1101                 Thread.sleep(1);
   1102             } else if (now - mTimer <= 60000) {
   1103                 Thread.sleep(yield ? 200 : 1);
   1104             } else {
   1105                 updateState(DetailedState.FAILED, "checkpoint");
   1106                 throw new IllegalStateException("Time is up");
   1107             }
   1108         }
   1109 
   1110         private void execute() {
   1111             // Catch all exceptions so we can clean up few things.
   1112             boolean initFinished = false;
   1113             try {
   1114                 // Initialize the timer.
   1115                 checkpoint(false);
   1116 
   1117                 // Wait for the daemons to stop.
   1118                 for (String daemon : mDaemons) {
   1119                     while (!SystemService.isStopped(daemon)) {
   1120                         checkpoint(true);
   1121                     }
   1122                 }
   1123 
   1124                 // Clear the previous state.
   1125                 File state = new File("/data/misc/vpn/state");
   1126                 state.delete();
   1127                 if (state.exists()) {
   1128                     throw new IllegalStateException("Cannot delete the state");
   1129                 }
   1130                 new File("/data/misc/vpn/abort").delete();
   1131                 initFinished = true;
   1132 
   1133                 // Check if we need to restart any of the daemons.
   1134                 boolean restart = false;
   1135                 for (String[] arguments : mArguments) {
   1136                     restart = restart || (arguments != null);
   1137                 }
   1138                 if (!restart) {
   1139                     agentDisconnect();
   1140                     return;
   1141                 }
   1142                 updateState(DetailedState.CONNECTING, "execute");
   1143 
   1144                 // Start the daemon with arguments.
   1145                 for (int i = 0; i < mDaemons.length; ++i) {
   1146                     String[] arguments = mArguments[i];
   1147                     if (arguments == null) {
   1148                         continue;
   1149                     }
   1150 
   1151                     // Start the daemon.
   1152                     String daemon = mDaemons[i];
   1153                     SystemService.start(daemon);
   1154 
   1155                     // Wait for the daemon to start.
   1156                     while (!SystemService.isRunning(daemon)) {
   1157                         checkpoint(true);
   1158                     }
   1159 
   1160                     // Create the control socket.
   1161                     mSockets[i] = new LocalSocket();
   1162                     LocalSocketAddress address = new LocalSocketAddress(
   1163                             daemon, LocalSocketAddress.Namespace.RESERVED);
   1164 
   1165                     // Wait for the socket to connect.
   1166                     while (true) {
   1167                         try {
   1168                             mSockets[i].connect(address);
   1169                             break;
   1170                         } catch (Exception e) {
   1171                             // ignore
   1172                         }
   1173                         checkpoint(true);
   1174                     }
   1175                     mSockets[i].setSoTimeout(500);
   1176 
   1177                     // Send over the arguments.
   1178                     OutputStream out = mSockets[i].getOutputStream();
   1179                     for (String argument : arguments) {
   1180                         byte[] bytes = argument.getBytes(StandardCharsets.UTF_8);
   1181                         if (bytes.length >= 0xFFFF) {
   1182                             throw new IllegalArgumentException("Argument is too large");
   1183                         }
   1184                         out.write(bytes.length >> 8);
   1185                         out.write(bytes.length);
   1186                         out.write(bytes);
   1187                         checkpoint(false);
   1188                     }
   1189                     out.write(0xFF);
   1190                     out.write(0xFF);
   1191                     out.flush();
   1192 
   1193                     // Wait for End-of-File.
   1194                     InputStream in = mSockets[i].getInputStream();
   1195                     while (true) {
   1196                         try {
   1197                             if (in.read() == -1) {
   1198                                 break;
   1199                             }
   1200                         } catch (Exception e) {
   1201                             // ignore
   1202                         }
   1203                         checkpoint(true);
   1204                     }
   1205                 }
   1206 
   1207                 // Wait for the daemons to create the new state.
   1208                 while (!state.exists()) {
   1209                     // Check if a running daemon is dead.
   1210                     for (int i = 0; i < mDaemons.length; ++i) {
   1211                         String daemon = mDaemons[i];
   1212                         if (mArguments[i] != null && !SystemService.isRunning(daemon)) {
   1213                             throw new IllegalStateException(daemon + " is dead");
   1214                         }
   1215                     }
   1216                     checkpoint(true);
   1217                 }
   1218 
   1219                 // Now we are connected. Read and parse the new state.
   1220                 String[] parameters = FileUtils.readTextFile(state, 0, null).split("\n", -1);
   1221                 if (parameters.length != 7) {
   1222                     throw new IllegalStateException("Cannot parse the state");
   1223                 }
   1224 
   1225                 // Set the interface and the addresses in the config.
   1226                 mConfig.interfaze = parameters[0].trim();
   1227 
   1228                 mConfig.addLegacyAddresses(parameters[1]);
   1229                 // Set the routes if they are not set in the config.
   1230                 if (mConfig.routes == null || mConfig.routes.isEmpty()) {
   1231                     mConfig.addLegacyRoutes(parameters[2]);
   1232                 }
   1233 
   1234                 // Set the DNS servers if they are not set in the config.
   1235                 if (mConfig.dnsServers == null || mConfig.dnsServers.size() == 0) {
   1236                     String dnsServers = parameters[3].trim();
   1237                     if (!dnsServers.isEmpty()) {
   1238                         mConfig.dnsServers = Arrays.asList(dnsServers.split(" "));
   1239                     }
   1240                 }
   1241 
   1242                 // Set the search domains if they are not set in the config.
   1243                 if (mConfig.searchDomains == null || mConfig.searchDomains.size() == 0) {
   1244                     String searchDomains = parameters[4].trim();
   1245                     if (!searchDomains.isEmpty()) {
   1246                         mConfig.searchDomains = Arrays.asList(searchDomains.split(" "));
   1247                     }
   1248                 }
   1249 
   1250                 // Add a throw route for the VPN server endpoint, if one was specified.
   1251                 String endpoint = parameters[5];
   1252                 if (!endpoint.isEmpty()) {
   1253                     try {
   1254                         InetAddress addr = InetAddress.parseNumericAddress(endpoint);
   1255                         if (addr instanceof Inet4Address) {
   1256                             mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 32), RTN_THROW));
   1257                         } else if (addr instanceof Inet6Address) {
   1258                             mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 128), RTN_THROW));
   1259                         } else {
   1260                             Log.e(TAG, "Unknown IP address family for VPN endpoint: " + endpoint);
   1261                         }
   1262                     } catch (IllegalArgumentException e) {
   1263                         Log.e(TAG, "Exception constructing throw route to " + endpoint + ": " + e);
   1264                     }
   1265                 }
   1266 
   1267                 // Here is the last step and it must be done synchronously.
   1268                 synchronized (Vpn.this) {
   1269                     // Set the start time
   1270                     mConfig.startTime = SystemClock.elapsedRealtime();
   1271 
   1272                     // Check if the thread is interrupted while we are waiting.
   1273                     checkpoint(false);
   1274 
   1275                     // Check if the interface is gone while we are waiting.
   1276                     if (jniCheck(mConfig.interfaze) == 0) {
   1277                         throw new IllegalStateException(mConfig.interfaze + " is gone");
   1278                     }
   1279 
   1280                     // Now INetworkManagementEventObserver is watching our back.
   1281                     mInterface = mConfig.interfaze;
   1282                     mVpnUsers = new ArrayList<UidRange>();
   1283 
   1284                     agentConnect();
   1285 
   1286                     Log.i(TAG, "Connected!");
   1287                 }
   1288             } catch (Exception e) {
   1289                 Log.i(TAG, "Aborting", e);
   1290                 updateState(DetailedState.FAILED, e.getMessage());
   1291                 exit();
   1292             } finally {
   1293                 // Kill the daemons if they fail to stop.
   1294                 if (!initFinished) {
   1295                     for (String daemon : mDaemons) {
   1296                         SystemService.stop(daemon);
   1297                     }
   1298                 }
   1299 
   1300                 // Do not leave an unstable state.
   1301                 if (!initFinished || mNetworkInfo.getDetailedState() == DetailedState.CONNECTING) {
   1302                     agentDisconnect();
   1303                 }
   1304             }
   1305         }
   1306 
   1307         /**
   1308          * Monitor the daemons we started, moving to disconnected state if the
   1309          * underlying services fail.
   1310          */
   1311         private void monitorDaemons() {
   1312             if (!mNetworkInfo.isConnected()) {
   1313                 return;
   1314             }
   1315 
   1316             try {
   1317                 while (true) {
   1318                     Thread.sleep(2000);
   1319                     for (int i = 0; i < mDaemons.length; i++) {
   1320                         if (mArguments[i] != null && SystemService.isStopped(mDaemons[i])) {
   1321                             return;
   1322                         }
   1323                     }
   1324                 }
   1325             } catch (InterruptedException e) {
   1326                 Log.d(TAG, "interrupted during monitorDaemons(); stopping services");
   1327             } finally {
   1328                 for (String daemon : mDaemons) {
   1329                     SystemService.stop(daemon);
   1330                 }
   1331 
   1332                 agentDisconnect();
   1333             }
   1334         }
   1335     }
   1336 }
   1337