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