Vpn.java revision 323f29df583e9338e3b2bf90fc8c0785a934a61b
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.setDetailedState(DetailedState.CONNECTING, null, null); 453 454 NetworkMisc networkMisc = new NetworkMisc(); 455 networkMisc.allowBypass = mConfig.allowBypass; 456 457 long token = Binder.clearCallingIdentity(); 458 try { 459 mNetworkAgent = new NetworkAgent(mLooper, mContext, NETWORKTYPE, 460 mNetworkInfo, mNetworkCapabilities, lp, 0, networkMisc) { 461 @Override 462 public void unwanted() { 463 // We are user controlled, not driven by NetworkRequest. 464 } 465 }; 466 } finally { 467 Binder.restoreCallingIdentity(token); 468 } 469 470 addVpnUserLocked(mUserHandle); 471 // If the user can have restricted profiles, assign all its restricted profiles to this VPN 472 if (canHaveRestrictedProfile(mUserHandle)) { 473 token = Binder.clearCallingIdentity(); 474 List<UserInfo> users; 475 try { 476 users = UserManager.get(mContext).getUsers(); 477 } finally { 478 Binder.restoreCallingIdentity(token); 479 } 480 for (UserInfo user : users) { 481 if (user.isRestricted() && (user.restrictedProfileParentId == mUserHandle)) { 482 addVpnUserLocked(user.id); 483 } 484 } 485 } 486 mNetworkAgent.addUidRanges(mVpnUsers.toArray(new UidRange[mVpnUsers.size()])); 487 488 mNetworkInfo.setIsAvailable(true); 489 updateState(DetailedState.CONNECTED, "agentConnect"); 490 } 491 492 private boolean canHaveRestrictedProfile(int userId) { 493 long token = Binder.clearCallingIdentity(); 494 try { 495 return UserManager.get(mContext).canHaveRestrictedProfile(userId); 496 } finally { 497 Binder.restoreCallingIdentity(token); 498 } 499 } 500 501 private void agentDisconnect(NetworkInfo networkInfo, NetworkAgent networkAgent) { 502 networkInfo.setIsAvailable(false); 503 networkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null); 504 if (networkAgent != null) { 505 networkAgent.sendNetworkInfo(networkInfo); 506 } 507 } 508 509 private void agentDisconnect(NetworkAgent networkAgent) { 510 NetworkInfo networkInfo = new NetworkInfo(mNetworkInfo); 511 agentDisconnect(networkInfo, networkAgent); 512 } 513 514 private void agentDisconnect() { 515 if (mNetworkInfo.isConnected()) { 516 agentDisconnect(mNetworkInfo, mNetworkAgent); 517 mNetworkAgent = null; 518 } 519 } 520 521 /** 522 * Establish a VPN network and return the file descriptor of the VPN 523 * interface. This methods returns {@code null} if the application is 524 * revoked or not prepared. 525 * 526 * @param config The parameters to configure the network. 527 * @return The file descriptor of the VPN interface. 528 */ 529 public synchronized ParcelFileDescriptor establish(VpnConfig config) { 530 // Check if the caller is already prepared. 531 UserManager mgr = UserManager.get(mContext); 532 if (Binder.getCallingUid() != mOwnerUID) { 533 return null; 534 } 535 // Check to ensure consent hasn't been revoked since we were prepared. 536 if (!isVpnUserPreConsented(mPackage)) { 537 return null; 538 } 539 // Check if the service is properly declared. 540 Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE); 541 intent.setClassName(mPackage, config.user); 542 long token = Binder.clearCallingIdentity(); 543 try { 544 // Restricted users are not allowed to create VPNs, they are tied to Owner 545 UserInfo user = mgr.getUserInfo(mUserHandle); 546 if (user.isRestricted() || mgr.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, 547 new UserHandle(mUserHandle))) { 548 throw new SecurityException("Restricted users cannot establish VPNs"); 549 } 550 551 ResolveInfo info = AppGlobals.getPackageManager().resolveService(intent, 552 null, 0, mUserHandle); 553 if (info == null) { 554 throw new SecurityException("Cannot find " + config.user); 555 } 556 if (!BIND_VPN_SERVICE.equals(info.serviceInfo.permission)) { 557 throw new SecurityException(config.user + " does not require " + BIND_VPN_SERVICE); 558 } 559 } catch (RemoteException e) { 560 throw new SecurityException("Cannot find " + config.user); 561 } finally { 562 Binder.restoreCallingIdentity(token); 563 } 564 565 // Save the old config in case we need to go back. 566 VpnConfig oldConfig = mConfig; 567 String oldInterface = mInterface; 568 Connection oldConnection = mConnection; 569 NetworkAgent oldNetworkAgent = mNetworkAgent; 570 mNetworkAgent = null; 571 List<UidRange> oldUsers = mVpnUsers; 572 573 // Configure the interface. Abort if any of these steps fails. 574 ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu)); 575 try { 576 updateState(DetailedState.CONNECTING, "establish"); 577 String interfaze = jniGetName(tun.getFd()); 578 579 // TEMP use the old jni calls until there is support for netd address setting 580 StringBuilder builder = new StringBuilder(); 581 for (LinkAddress address : config.addresses) { 582 builder.append(" " + address); 583 } 584 if (jniSetAddresses(interfaze, builder.toString()) < 1) { 585 throw new IllegalArgumentException("At least one address must be specified"); 586 } 587 Connection connection = new Connection(); 588 if (!mContext.bindServiceAsUser(intent, connection, 589 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, 590 new UserHandle(mUserHandle))) { 591 throw new IllegalStateException("Cannot bind " + config.user); 592 } 593 594 mConnection = connection; 595 mInterface = interfaze; 596 597 // Fill more values. 598 config.user = mPackage; 599 config.interfaze = mInterface; 600 config.startTime = SystemClock.elapsedRealtime(); 601 mConfig = config; 602 603 // Set up forwarding and DNS rules. 604 mVpnUsers = new ArrayList<UidRange>(); 605 606 agentConnect(); 607 608 if (oldConnection != null) { 609 mContext.unbindService(oldConnection); 610 } 611 // Remove the old tun's user forwarding rules 612 // The new tun's user rules have already been added so they will take over 613 // as rules are deleted. This prevents data leakage as the rules are moved over. 614 agentDisconnect(oldNetworkAgent); 615 if (oldInterface != null && !oldInterface.equals(interfaze)) { 616 jniReset(oldInterface); 617 } 618 619 try { 620 IoUtils.setBlocking(tun.getFileDescriptor(), config.blocking); 621 } catch (IOException e) { 622 throw new IllegalStateException( 623 "Cannot set tunnel's fd as blocking=" + config.blocking, e); 624 } 625 } catch (RuntimeException e) { 626 IoUtils.closeQuietly(tun); 627 agentDisconnect(); 628 // restore old state 629 mConfig = oldConfig; 630 mConnection = oldConnection; 631 mVpnUsers = oldUsers; 632 mNetworkAgent = oldNetworkAgent; 633 mInterface = oldInterface; 634 throw e; 635 } 636 Log.i(TAG, "Established by " + config.user + " on " + mInterface); 637 return tun; 638 } 639 640 private boolean isRunningLocked() { 641 return mNetworkAgent != null && mInterface != null; 642 } 643 644 // Returns true if the VPN has been established and the calling UID is its owner. Used to check 645 // that a call to mutate VPN state is admissible. 646 private boolean isCallerEstablishedOwnerLocked() { 647 return isRunningLocked() && Binder.getCallingUid() == mOwnerUID; 648 } 649 650 // Note: Return type guarantees results are deduped and sorted, which callers require. 651 private SortedSet<Integer> getAppsUids(List<String> packageNames, int userHandle) { 652 SortedSet<Integer> uids = new TreeSet<Integer>(); 653 for (String app : packageNames) { 654 int uid = getAppUid(app, userHandle); 655 if (uid != -1) uids.add(uid); 656 } 657 return uids; 658 } 659 660 // Note: This function adds to mVpnUsers but does not publish list to NetworkAgent. 661 private void addVpnUserLocked(int userHandle) { 662 if (mVpnUsers == null) { 663 throw new IllegalStateException("VPN is not active"); 664 } 665 666 if (mConfig.allowedApplications != null) { 667 // Add ranges covering all UIDs for allowedApplications. 668 int start = -1, stop = -1; 669 for (int uid : getAppsUids(mConfig.allowedApplications, userHandle)) { 670 if (start == -1) { 671 start = uid; 672 } else if (uid != stop + 1) { 673 mVpnUsers.add(new UidRange(start, stop)); 674 start = uid; 675 } 676 stop = uid; 677 } 678 if (start != -1) mVpnUsers.add(new UidRange(start, stop)); 679 } else if (mConfig.disallowedApplications != null) { 680 // Add all ranges for user skipping UIDs for disallowedApplications. 681 final UidRange userRange = UidRange.createForUser(userHandle); 682 int start = userRange.start; 683 for (int uid : getAppsUids(mConfig.disallowedApplications, userHandle)) { 684 if (uid == start) { 685 start++; 686 } else { 687 mVpnUsers.add(new UidRange(start, uid - 1)); 688 start = uid + 1; 689 } 690 } 691 if (start <= userRange.stop) mVpnUsers.add(new UidRange(start, userRange.stop)); 692 } else { 693 // Add all UIDs for the user. 694 mVpnUsers.add(UidRange.createForUser(userHandle)); 695 } 696 697 prepareStatusIntent(); 698 } 699 700 // Returns the subset of the full list of active UID ranges the VPN applies to (mVpnUsers) that 701 // apply to userHandle. 702 private List<UidRange> uidRangesForUser(int userHandle) { 703 final UidRange userRange = UidRange.createForUser(userHandle); 704 final List<UidRange> ranges = new ArrayList<UidRange>(); 705 for (UidRange range : mVpnUsers) { 706 if (range.start >= userRange.start && range.stop <= userRange.stop) { 707 ranges.add(range); 708 } 709 } 710 return ranges; 711 } 712 713 private void removeVpnUserLocked(int userHandle) { 714 if (mVpnUsers == null) { 715 throw new IllegalStateException("VPN is not active"); 716 } 717 final List<UidRange> ranges = uidRangesForUser(userHandle); 718 if (mNetworkAgent != null) { 719 mNetworkAgent.removeUidRanges(ranges.toArray(new UidRange[ranges.size()])); 720 } 721 mVpnUsers.removeAll(ranges); 722 mStatusIntent = null; 723 } 724 725 public void onUserAdded(int userHandle) { 726 // If the user is restricted tie them to the parent user's VPN 727 UserInfo user = UserManager.get(mContext).getUserInfo(userHandle); 728 if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle 729 && mVpnUsers != null) { 730 synchronized(Vpn.this) { 731 try { 732 addVpnUserLocked(userHandle); 733 if (mNetworkAgent != null) { 734 final List<UidRange> ranges = uidRangesForUser(userHandle); 735 mNetworkAgent.addUidRanges(ranges.toArray(new UidRange[ranges.size()])); 736 } 737 } catch (Exception e) { 738 Log.wtf(TAG, "Failed to add restricted user to owner", e); 739 } 740 } 741 } 742 } 743 744 public void onUserRemoved(int userHandle) { 745 // clean up if restricted 746 UserInfo user = UserManager.get(mContext).getUserInfo(userHandle); 747 if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle 748 && mVpnUsers != null) { 749 synchronized(Vpn.this) { 750 try { 751 removeVpnUserLocked(userHandle); 752 } catch (Exception e) { 753 Log.wtf(TAG, "Failed to remove restricted user to owner", e); 754 } 755 } 756 } 757 } 758 759 /** 760 * Return the configuration of the currently running VPN. 761 */ 762 public VpnConfig getVpnConfig() { 763 enforceControlPermission(); 764 return mConfig; 765 } 766 767 @Deprecated 768 public synchronized void interfaceStatusChanged(String iface, boolean up) { 769 try { 770 mObserver.interfaceStatusChanged(iface, up); 771 } catch (RemoteException e) { 772 // ignored; target is local 773 } 774 } 775 776 private INetworkManagementEventObserver mObserver = new BaseNetworkObserver() { 777 @Override 778 public void interfaceStatusChanged(String interfaze, boolean up) { 779 synchronized (Vpn.this) { 780 if (!up && mLegacyVpnRunner != null) { 781 mLegacyVpnRunner.check(interfaze); 782 } 783 } 784 } 785 786 @Override 787 public void interfaceRemoved(String interfaze) { 788 synchronized (Vpn.this) { 789 if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) { 790 mStatusIntent = null; 791 mVpnUsers = null; 792 mConfig = null; 793 mInterface = null; 794 if (mConnection != null) { 795 mContext.unbindService(mConnection); 796 mConnection = null; 797 agentDisconnect(); 798 } else if (mLegacyVpnRunner != null) { 799 mLegacyVpnRunner.exit(); 800 mLegacyVpnRunner = null; 801 } 802 } 803 } 804 } 805 }; 806 807 private void enforceControlPermission() { 808 mContext.enforceCallingPermission(Manifest.permission.CONTROL_VPN, "Unauthorized Caller"); 809 } 810 811 private void enforceControlPermissionOrInternalCaller() { 812 // Require caller to be either an application with CONTROL_VPN permission or a process 813 // in the system server. 814 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONTROL_VPN, 815 "Unauthorized Caller"); 816 } 817 818 private class Connection implements ServiceConnection { 819 private IBinder mService; 820 821 @Override 822 public void onServiceConnected(ComponentName name, IBinder service) { 823 mService = service; 824 } 825 826 @Override 827 public void onServiceDisconnected(ComponentName name) { 828 mService = null; 829 } 830 } 831 832 private void prepareStatusIntent() { 833 final long token = Binder.clearCallingIdentity(); 834 try { 835 mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext); 836 } finally { 837 Binder.restoreCallingIdentity(token); 838 } 839 } 840 841 public synchronized boolean addAddress(String address, int prefixLength) { 842 if (!isCallerEstablishedOwnerLocked()) { 843 return false; 844 } 845 boolean success = jniAddAddress(mInterface, address, prefixLength); 846 mNetworkAgent.sendLinkProperties(makeLinkProperties()); 847 return success; 848 } 849 850 public synchronized boolean removeAddress(String address, int prefixLength) { 851 if (!isCallerEstablishedOwnerLocked()) { 852 return false; 853 } 854 boolean success = jniDelAddress(mInterface, address, prefixLength); 855 mNetworkAgent.sendLinkProperties(makeLinkProperties()); 856 return success; 857 } 858 859 public synchronized boolean setUnderlyingNetworks(Network[] networks) { 860 if (!isCallerEstablishedOwnerLocked()) { 861 return false; 862 } 863 if (networks == null) { 864 mConfig.underlyingNetworks = null; 865 } else { 866 mConfig.underlyingNetworks = new Network[networks.length]; 867 for (int i = 0; i < networks.length; ++i) { 868 if (networks[i] == null) { 869 mConfig.underlyingNetworks[i] = null; 870 } else { 871 mConfig.underlyingNetworks[i] = new Network(networks[i].netId); 872 } 873 } 874 } 875 return true; 876 } 877 878 public synchronized Network[] getUnderlyingNetworks() { 879 if (!isRunningLocked()) { 880 return null; 881 } 882 return mConfig.underlyingNetworks; 883 } 884 885 /** 886 * This method should only be called by ConnectivityService. Because it doesn't 887 * have enough data to fill VpnInfo.primaryUnderlyingIface field. 888 */ 889 public synchronized VpnInfo getVpnInfo() { 890 if (!isRunningLocked()) { 891 return null; 892 } 893 894 VpnInfo info = new VpnInfo(); 895 info.ownerUid = mOwnerUID; 896 info.vpnIface = mInterface; 897 return info; 898 } 899 900 public synchronized boolean appliesToUid(int uid) { 901 if (!isRunningLocked()) { 902 return false; 903 } 904 for (UidRange uidRange : mVpnUsers) { 905 if (uidRange.start <= uid && uid <= uidRange.stop) { 906 return true; 907 } 908 } 909 return false; 910 } 911 912 private native int jniCreate(int mtu); 913 private native String jniGetName(int tun); 914 private native int jniSetAddresses(String interfaze, String addresses); 915 private native void jniReset(String interfaze); 916 private native int jniCheck(String interfaze); 917 private native boolean jniAddAddress(String interfaze, String address, int prefixLen); 918 private native boolean jniDelAddress(String interfaze, String address, int prefixLen); 919 920 private static RouteInfo findIPv4DefaultRoute(LinkProperties prop) { 921 for (RouteInfo route : prop.getAllRoutes()) { 922 // Currently legacy VPN only works on IPv4. 923 if (route.isDefaultRoute() && route.getGateway() instanceof Inet4Address) { 924 return route; 925 } 926 } 927 928 throw new IllegalStateException("Unable to find IPv4 default gateway"); 929 } 930 931 /** 932 * Start legacy VPN, controlling native daemons as needed. Creates a 933 * secondary thread to perform connection work, returning quickly. 934 * 935 * Should only be called to respond to Binder requests as this enforces caller permission. Use 936 * {@link #startLegacyVpnPrivileged(VpnProfile, KeyStore, LinkProperties)} to skip the 937 * permission check only when the caller is trusted (or the call is initiated by the system). 938 */ 939 public void startLegacyVpn(VpnProfile profile, KeyStore keyStore, LinkProperties egress) { 940 enforceControlPermission(); 941 long token = Binder.clearCallingIdentity(); 942 try { 943 startLegacyVpnPrivileged(profile, keyStore, egress); 944 } finally { 945 Binder.restoreCallingIdentity(token); 946 } 947 } 948 949 /** 950 * Like {@link #startLegacyVpn(VpnProfile, KeyStore, LinkProperties)}, but does not check 951 * permissions under the assumption that the caller is the system. 952 * 953 * Callers are responsible for checking permissions if needed. 954 */ 955 public void startLegacyVpnPrivileged(VpnProfile profile, KeyStore keyStore, 956 LinkProperties egress) { 957 UserManager mgr = UserManager.get(mContext); 958 UserInfo user = mgr.getUserInfo(mUserHandle); 959 if (user.isRestricted() || mgr.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, 960 new UserHandle(mUserHandle))) { 961 throw new SecurityException("Restricted users cannot establish VPNs"); 962 } 963 964 final RouteInfo ipv4DefaultRoute = findIPv4DefaultRoute(egress); 965 final String gateway = ipv4DefaultRoute.getGateway().getHostAddress(); 966 final String iface = ipv4DefaultRoute.getInterface(); 967 968 // Load certificates. 969 String privateKey = ""; 970 String userCert = ""; 971 String caCert = ""; 972 String serverCert = ""; 973 if (!profile.ipsecUserCert.isEmpty()) { 974 privateKey = Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert; 975 byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecUserCert); 976 userCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8); 977 } 978 if (!profile.ipsecCaCert.isEmpty()) { 979 byte[] value = keyStore.get(Credentials.CA_CERTIFICATE + profile.ipsecCaCert); 980 caCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8); 981 } 982 if (!profile.ipsecServerCert.isEmpty()) { 983 byte[] value = keyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecServerCert); 984 serverCert = (value == null) ? null : new String(value, StandardCharsets.UTF_8); 985 } 986 if (privateKey == null || userCert == null || caCert == null || serverCert == null) { 987 throw new IllegalStateException("Cannot load credentials"); 988 } 989 990 // Prepare arguments for racoon. 991 String[] racoon = null; 992 switch (profile.type) { 993 case VpnProfile.TYPE_L2TP_IPSEC_PSK: 994 racoon = new String[] { 995 iface, profile.server, "udppsk", profile.ipsecIdentifier, 996 profile.ipsecSecret, "1701", 997 }; 998 break; 999 case VpnProfile.TYPE_L2TP_IPSEC_RSA: 1000 racoon = new String[] { 1001 iface, profile.server, "udprsa", privateKey, userCert, 1002 caCert, serverCert, "1701", 1003 }; 1004 break; 1005 case VpnProfile.TYPE_IPSEC_XAUTH_PSK: 1006 racoon = new String[] { 1007 iface, profile.server, "xauthpsk", profile.ipsecIdentifier, 1008 profile.ipsecSecret, profile.username, profile.password, "", gateway, 1009 }; 1010 break; 1011 case VpnProfile.TYPE_IPSEC_XAUTH_RSA: 1012 racoon = new String[] { 1013 iface, profile.server, "xauthrsa", privateKey, userCert, 1014 caCert, serverCert, profile.username, profile.password, "", gateway, 1015 }; 1016 break; 1017 case VpnProfile.TYPE_IPSEC_HYBRID_RSA: 1018 racoon = new String[] { 1019 iface, profile.server, "hybridrsa", 1020 caCert, serverCert, profile.username, profile.password, "", gateway, 1021 }; 1022 break; 1023 } 1024 1025 // Prepare arguments for mtpd. 1026 String[] mtpd = null; 1027 switch (profile.type) { 1028 case VpnProfile.TYPE_PPTP: 1029 mtpd = new String[] { 1030 iface, "pptp", profile.server, "1723", 1031 "name", profile.username, "password", profile.password, 1032 "linkname", "vpn", "refuse-eap", "nodefaultroute", 1033 "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400", 1034 (profile.mppe ? "+mppe" : "nomppe"), 1035 }; 1036 break; 1037 case VpnProfile.TYPE_L2TP_IPSEC_PSK: 1038 case VpnProfile.TYPE_L2TP_IPSEC_RSA: 1039 mtpd = new String[] { 1040 iface, "l2tp", profile.server, "1701", profile.l2tpSecret, 1041 "name", profile.username, "password", profile.password, 1042 "linkname", "vpn", "refuse-eap", "nodefaultroute", 1043 "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400", 1044 }; 1045 break; 1046 } 1047 1048 VpnConfig config = new VpnConfig(); 1049 config.legacy = true; 1050 config.user = profile.key; 1051 config.interfaze = iface; 1052 config.session = profile.name; 1053 1054 config.addLegacyRoutes(profile.routes); 1055 if (!profile.dnsServers.isEmpty()) { 1056 config.dnsServers = Arrays.asList(profile.dnsServers.split(" +")); 1057 } 1058 if (!profile.searchDomains.isEmpty()) { 1059 config.searchDomains = Arrays.asList(profile.searchDomains.split(" +")); 1060 } 1061 startLegacyVpn(config, racoon, mtpd); 1062 } 1063 1064 private synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) { 1065 stopLegacyVpnPrivileged(); 1066 1067 // Prepare for the new request. 1068 prepareInternal(VpnConfig.LEGACY_VPN); 1069 updateState(DetailedState.CONNECTING, "startLegacyVpn"); 1070 1071 // Start a new LegacyVpnRunner and we are done! 1072 mLegacyVpnRunner = new LegacyVpnRunner(config, racoon, mtpd); 1073 mLegacyVpnRunner.start(); 1074 } 1075 1076 /** Stop legacy VPN. Permissions must be checked by callers. */ 1077 public synchronized void stopLegacyVpnPrivileged() { 1078 if (mLegacyVpnRunner != null) { 1079 mLegacyVpnRunner.exit(); 1080 mLegacyVpnRunner = null; 1081 1082 synchronized (LegacyVpnRunner.TAG) { 1083 // wait for old thread to completely finish before spinning up 1084 // new instance, otherwise state updates can be out of order. 1085 } 1086 } 1087 } 1088 1089 /** 1090 * Return the information of the current ongoing legacy VPN. 1091 */ 1092 public synchronized LegacyVpnInfo getLegacyVpnInfo() { 1093 // Check if the caller is authorized. 1094 enforceControlPermission(); 1095 return getLegacyVpnInfoPrivileged(); 1096 } 1097 1098 /** 1099 * Return the information of the current ongoing legacy VPN. 1100 * Callers are responsible for checking permissions if needed. 1101 */ 1102 public synchronized LegacyVpnInfo getLegacyVpnInfoPrivileged() { 1103 if (mLegacyVpnRunner == null) return null; 1104 1105 final LegacyVpnInfo info = new LegacyVpnInfo(); 1106 info.key = mConfig.user; 1107 info.state = LegacyVpnInfo.stateFromNetworkInfo(mNetworkInfo); 1108 if (mNetworkInfo.isConnected()) { 1109 info.intent = mStatusIntent; 1110 } 1111 return info; 1112 } 1113 1114 public VpnConfig getLegacyVpnConfig() { 1115 if (mLegacyVpnRunner != null) { 1116 return mConfig; 1117 } else { 1118 return null; 1119 } 1120 } 1121 1122 /** 1123 * Bringing up a VPN connection takes time, and that is all this thread 1124 * does. Here we have plenty of time. The only thing we need to take 1125 * care of is responding to interruptions as soon as possible. Otherwise 1126 * requests will be piled up. This can be done in a Handler as a state 1127 * machine, but it is much easier to read in the current form. 1128 */ 1129 private class LegacyVpnRunner extends Thread { 1130 private static final String TAG = "LegacyVpnRunner"; 1131 1132 private final String[] mDaemons; 1133 private final String[][] mArguments; 1134 private final LocalSocket[] mSockets; 1135 private final String mOuterInterface; 1136 private final AtomicInteger mOuterConnection = 1137 new AtomicInteger(ConnectivityManager.TYPE_NONE); 1138 1139 private long mTimer = -1; 1140 1141 /** 1142 * Watch for the outer connection (passing in the constructor) going away. 1143 */ 1144 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 1145 @Override 1146 public void onReceive(Context context, Intent intent) { 1147 if (!mEnableTeardown) return; 1148 1149 if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 1150 if (intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 1151 ConnectivityManager.TYPE_NONE) == mOuterConnection.get()) { 1152 NetworkInfo info = (NetworkInfo)intent.getExtra( 1153 ConnectivityManager.EXTRA_NETWORK_INFO); 1154 if (info != null && !info.isConnectedOrConnecting()) { 1155 try { 1156 mObserver.interfaceStatusChanged(mOuterInterface, false); 1157 } catch (RemoteException e) {} 1158 } 1159 } 1160 } 1161 } 1162 }; 1163 1164 public LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd) { 1165 super(TAG); 1166 mConfig = config; 1167 mDaemons = new String[] {"racoon", "mtpd"}; 1168 // TODO: clear arguments from memory once launched 1169 mArguments = new String[][] {racoon, mtpd}; 1170 mSockets = new LocalSocket[mDaemons.length]; 1171 1172 // This is the interface which VPN is running on, 1173 // mConfig.interfaze will change to point to OUR 1174 // internal interface soon. TODO - add inner/outer to mconfig 1175 // TODO - we have a race - if the outer iface goes away/disconnects before we hit this 1176 // we will leave the VPN up. We should check that it's still there/connected after 1177 // registering 1178 mOuterInterface = mConfig.interfaze; 1179 1180 if (!TextUtils.isEmpty(mOuterInterface)) { 1181 final ConnectivityManager cm = ConnectivityManager.from(mContext); 1182 for (Network network : cm.getAllNetworks()) { 1183 final LinkProperties lp = cm.getLinkProperties(network); 1184 if (lp != null && lp.getAllInterfaceNames().contains(mOuterInterface)) { 1185 final NetworkInfo networkInfo = cm.getNetworkInfo(network); 1186 if (networkInfo != null) mOuterConnection.set(networkInfo.getType()); 1187 } 1188 } 1189 } 1190 1191 IntentFilter filter = new IntentFilter(); 1192 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 1193 mContext.registerReceiver(mBroadcastReceiver, filter); 1194 } 1195 1196 public void check(String interfaze) { 1197 if (interfaze.equals(mOuterInterface)) { 1198 Log.i(TAG, "Legacy VPN is going down with " + interfaze); 1199 exit(); 1200 } 1201 } 1202 1203 public void exit() { 1204 // We assume that everything is reset after stopping the daemons. 1205 interrupt(); 1206 for (LocalSocket socket : mSockets) { 1207 IoUtils.closeQuietly(socket); 1208 } 1209 agentDisconnect(); 1210 try { 1211 mContext.unregisterReceiver(mBroadcastReceiver); 1212 } catch (IllegalArgumentException e) {} 1213 } 1214 1215 @Override 1216 public void run() { 1217 // Wait for the previous thread since it has been interrupted. 1218 Log.v(TAG, "Waiting"); 1219 synchronized (TAG) { 1220 Log.v(TAG, "Executing"); 1221 execute(); 1222 monitorDaemons(); 1223 } 1224 } 1225 1226 private void checkpoint(boolean yield) throws InterruptedException { 1227 long now = SystemClock.elapsedRealtime(); 1228 if (mTimer == -1) { 1229 mTimer = now; 1230 Thread.sleep(1); 1231 } else if (now - mTimer <= 60000) { 1232 Thread.sleep(yield ? 200 : 1); 1233 } else { 1234 updateState(DetailedState.FAILED, "checkpoint"); 1235 throw new IllegalStateException("Time is up"); 1236 } 1237 } 1238 1239 private void execute() { 1240 // Catch all exceptions so we can clean up few things. 1241 boolean initFinished = false; 1242 try { 1243 // Initialize the timer. 1244 checkpoint(false); 1245 1246 // Wait for the daemons to stop. 1247 for (String daemon : mDaemons) { 1248 while (!SystemService.isStopped(daemon)) { 1249 checkpoint(true); 1250 } 1251 } 1252 1253 // Clear the previous state. 1254 File state = new File("/data/misc/vpn/state"); 1255 state.delete(); 1256 if (state.exists()) { 1257 throw new IllegalStateException("Cannot delete the state"); 1258 } 1259 new File("/data/misc/vpn/abort").delete(); 1260 initFinished = true; 1261 1262 // Check if we need to restart any of the daemons. 1263 boolean restart = false; 1264 for (String[] arguments : mArguments) { 1265 restart = restart || (arguments != null); 1266 } 1267 if (!restart) { 1268 agentDisconnect(); 1269 return; 1270 } 1271 updateState(DetailedState.CONNECTING, "execute"); 1272 1273 // Start the daemon with arguments. 1274 for (int i = 0; i < mDaemons.length; ++i) { 1275 String[] arguments = mArguments[i]; 1276 if (arguments == null) { 1277 continue; 1278 } 1279 1280 // Start the daemon. 1281 String daemon = mDaemons[i]; 1282 SystemService.start(daemon); 1283 1284 // Wait for the daemon to start. 1285 while (!SystemService.isRunning(daemon)) { 1286 checkpoint(true); 1287 } 1288 1289 // Create the control socket. 1290 mSockets[i] = new LocalSocket(); 1291 LocalSocketAddress address = new LocalSocketAddress( 1292 daemon, LocalSocketAddress.Namespace.RESERVED); 1293 1294 // Wait for the socket to connect. 1295 while (true) { 1296 try { 1297 mSockets[i].connect(address); 1298 break; 1299 } catch (Exception e) { 1300 // ignore 1301 } 1302 checkpoint(true); 1303 } 1304 mSockets[i].setSoTimeout(500); 1305 1306 // Send over the arguments. 1307 OutputStream out = mSockets[i].getOutputStream(); 1308 for (String argument : arguments) { 1309 byte[] bytes = argument.getBytes(StandardCharsets.UTF_8); 1310 if (bytes.length >= 0xFFFF) { 1311 throw new IllegalArgumentException("Argument is too large"); 1312 } 1313 out.write(bytes.length >> 8); 1314 out.write(bytes.length); 1315 out.write(bytes); 1316 checkpoint(false); 1317 } 1318 out.write(0xFF); 1319 out.write(0xFF); 1320 out.flush(); 1321 1322 // Wait for End-of-File. 1323 InputStream in = mSockets[i].getInputStream(); 1324 while (true) { 1325 try { 1326 if (in.read() == -1) { 1327 break; 1328 } 1329 } catch (Exception e) { 1330 // ignore 1331 } 1332 checkpoint(true); 1333 } 1334 } 1335 1336 // Wait for the daemons to create the new state. 1337 while (!state.exists()) { 1338 // Check if a running daemon is dead. 1339 for (int i = 0; i < mDaemons.length; ++i) { 1340 String daemon = mDaemons[i]; 1341 if (mArguments[i] != null && !SystemService.isRunning(daemon)) { 1342 throw new IllegalStateException(daemon + " is dead"); 1343 } 1344 } 1345 checkpoint(true); 1346 } 1347 1348 // Now we are connected. Read and parse the new state. 1349 String[] parameters = FileUtils.readTextFile(state, 0, null).split("\n", -1); 1350 if (parameters.length != 7) { 1351 throw new IllegalStateException("Cannot parse the state"); 1352 } 1353 1354 // Set the interface and the addresses in the config. 1355 mConfig.interfaze = parameters[0].trim(); 1356 1357 mConfig.addLegacyAddresses(parameters[1]); 1358 // Set the routes if they are not set in the config. 1359 if (mConfig.routes == null || mConfig.routes.isEmpty()) { 1360 mConfig.addLegacyRoutes(parameters[2]); 1361 } 1362 1363 // Set the DNS servers if they are not set in the config. 1364 if (mConfig.dnsServers == null || mConfig.dnsServers.size() == 0) { 1365 String dnsServers = parameters[3].trim(); 1366 if (!dnsServers.isEmpty()) { 1367 mConfig.dnsServers = Arrays.asList(dnsServers.split(" ")); 1368 } 1369 } 1370 1371 // Set the search domains if they are not set in the config. 1372 if (mConfig.searchDomains == null || mConfig.searchDomains.size() == 0) { 1373 String searchDomains = parameters[4].trim(); 1374 if (!searchDomains.isEmpty()) { 1375 mConfig.searchDomains = Arrays.asList(searchDomains.split(" ")); 1376 } 1377 } 1378 1379 // Add a throw route for the VPN server endpoint, if one was specified. 1380 String endpoint = parameters[5]; 1381 if (!endpoint.isEmpty()) { 1382 try { 1383 InetAddress addr = InetAddress.parseNumericAddress(endpoint); 1384 if (addr instanceof Inet4Address) { 1385 mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 32), RTN_THROW)); 1386 } else if (addr instanceof Inet6Address) { 1387 mConfig.routes.add(new RouteInfo(new IpPrefix(addr, 128), RTN_THROW)); 1388 } else { 1389 Log.e(TAG, "Unknown IP address family for VPN endpoint: " + endpoint); 1390 } 1391 } catch (IllegalArgumentException e) { 1392 Log.e(TAG, "Exception constructing throw route to " + endpoint + ": " + e); 1393 } 1394 } 1395 1396 // Here is the last step and it must be done synchronously. 1397 synchronized (Vpn.this) { 1398 // Set the start time 1399 mConfig.startTime = SystemClock.elapsedRealtime(); 1400 1401 // Check if the thread is interrupted while we are waiting. 1402 checkpoint(false); 1403 1404 // Check if the interface is gone while we are waiting. 1405 if (jniCheck(mConfig.interfaze) == 0) { 1406 throw new IllegalStateException(mConfig.interfaze + " is gone"); 1407 } 1408 1409 // Now INetworkManagementEventObserver is watching our back. 1410 mInterface = mConfig.interfaze; 1411 mVpnUsers = new ArrayList<UidRange>(); 1412 1413 agentConnect(); 1414 1415 Log.i(TAG, "Connected!"); 1416 } 1417 } catch (Exception e) { 1418 Log.i(TAG, "Aborting", e); 1419 updateState(DetailedState.FAILED, e.getMessage()); 1420 exit(); 1421 } finally { 1422 // Kill the daemons if they fail to stop. 1423 if (!initFinished) { 1424 for (String daemon : mDaemons) { 1425 SystemService.stop(daemon); 1426 } 1427 } 1428 1429 // Do not leave an unstable state. 1430 if (!initFinished || mNetworkInfo.getDetailedState() == DetailedState.CONNECTING) { 1431 agentDisconnect(); 1432 } 1433 } 1434 } 1435 1436 /** 1437 * Monitor the daemons we started, moving to disconnected state if the 1438 * underlying services fail. 1439 */ 1440 private void monitorDaemons() { 1441 if (!mNetworkInfo.isConnected()) { 1442 return; 1443 } 1444 1445 try { 1446 while (true) { 1447 Thread.sleep(2000); 1448 for (int i = 0; i < mDaemons.length; i++) { 1449 if (mArguments[i] != null && SystemService.isStopped(mDaemons[i])) { 1450 return; 1451 } 1452 } 1453 } 1454 } catch (InterruptedException e) { 1455 Log.d(TAG, "interrupted during monitorDaemons(); stopping services"); 1456 } finally { 1457 for (String daemon : mDaemons) { 1458 SystemService.stop(daemon); 1459 } 1460 1461 agentDisconnect(); 1462 } 1463 } 1464 } 1465} 1466