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