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 android.net; 18 19 import static android.system.OsConstants.AF_INET; 20 import static android.system.OsConstants.AF_INET6; 21 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.RequiresPermission; 25 import android.annotation.SystemApi; 26 import android.app.Activity; 27 import android.app.PendingIntent; 28 import android.app.Service; 29 import android.app.admin.DevicePolicyManager; 30 import android.compat.annotation.UnsupportedAppUsage; 31 import android.content.ComponentName; 32 import android.content.Context; 33 import android.content.Intent; 34 import android.content.pm.IPackageManager; 35 import android.content.pm.PackageManager; 36 import android.os.Binder; 37 import android.os.IBinder; 38 import android.os.Parcel; 39 import android.os.ParcelFileDescriptor; 40 import android.os.RemoteException; 41 import android.os.ServiceManager; 42 import android.os.UserHandle; 43 44 import com.android.internal.annotations.VisibleForTesting; 45 import com.android.internal.net.NetworkUtilsInternal; 46 import com.android.internal.net.VpnConfig; 47 48 import java.net.DatagramSocket; 49 import java.net.Inet4Address; 50 import java.net.Inet6Address; 51 import java.net.InetAddress; 52 import java.net.Socket; 53 import java.util.ArrayList; 54 import java.util.Collections; 55 import java.util.List; 56 import java.util.Set; 57 58 /** 59 * VpnService is a base class for applications to extend and build their 60 * own VPN solutions. In general, it creates a virtual network interface, 61 * configures addresses and routing rules, and returns a file descriptor 62 * to the application. Each read from the descriptor retrieves an outgoing 63 * packet which was routed to the interface. Each write to the descriptor 64 * injects an incoming packet just like it was received from the interface. 65 * The interface is running on Internet Protocol (IP), so packets are 66 * always started with IP headers. The application then completes a VPN 67 * connection by processing and exchanging packets with the remote server 68 * over a tunnel. 69 * 70 * <p>Letting applications intercept packets raises huge security concerns. 71 * A VPN application can easily break the network. Besides, two of them may 72 * conflict with each other. The system takes several actions to address 73 * these issues. Here are some key points: 74 * <ul> 75 * <li>User action is required the first time an application creates a VPN 76 * connection.</li> 77 * <li>There can be only one VPN connection running at the same time. The 78 * existing interface is deactivated when a new one is created.</li> 79 * <li>A system-managed notification is shown during the lifetime of a 80 * VPN connection.</li> 81 * <li>A system-managed dialog gives the information of the current VPN 82 * connection. It also provides a button to disconnect.</li> 83 * <li>The network is restored automatically when the file descriptor is 84 * closed. It also covers the cases when a VPN application is crashed 85 * or killed by the system.</li> 86 * </ul> 87 * 88 * <p>There are two primary methods in this class: {@link #prepare} and 89 * {@link Builder#establish}. The former deals with user action and stops 90 * the VPN connection created by another application. The latter creates 91 * a VPN interface using the parameters supplied to the {@link Builder}. 92 * An application must call {@link #prepare} to grant the right to use 93 * other methods in this class, and the right can be revoked at any time. 94 * Here are the general steps to create a VPN connection: 95 * <ol> 96 * <li>When the user presses the button to connect, call {@link #prepare} 97 * and launch the returned intent, if non-null.</li> 98 * <li>When the application becomes prepared, start the service.</li> 99 * <li>Create a tunnel to the remote server and negotiate the network 100 * parameters for the VPN connection.</li> 101 * <li>Supply those parameters to a {@link Builder} and create a VPN 102 * interface by calling {@link Builder#establish}.</li> 103 * <li>Process and exchange packets between the tunnel and the returned 104 * file descriptor.</li> 105 * <li>When {@link #onRevoke} is invoked, close the file descriptor and 106 * shut down the tunnel gracefully.</li> 107 * </ol> 108 * 109 * <p>Services extending this class need to be declared with an appropriate 110 * permission and intent filter. Their access must be secured by 111 * {@link android.Manifest.permission#BIND_VPN_SERVICE} permission, and 112 * their intent filter must match {@link #SERVICE_INTERFACE} action. Here 113 * is an example of declaring a VPN service in {@code AndroidManifest.xml}: 114 * <pre> 115 * <service android:name=".ExampleVpnService" 116 * android:permission="android.permission.BIND_VPN_SERVICE"> 117 * <intent-filter> 118 * <action android:name="android.net.VpnService"/> 119 * </intent-filter> 120 * </service></pre> 121 * 122 * <p> The Android system starts a VPN in the background by calling 123 * {@link android.content.Context#startService startService()}. In Android 8.0 124 * (API level 26) and higher, the system places VPN apps on the temporary 125 * allowlist for a short period so the app can start in the background. The VPN 126 * app must promote itself to the foreground after it's launched or the system 127 * will shut down the app. 128 * 129 * <h3>Developer's guide</h3> 130 * 131 * <p>To learn more about developing VPN apps, read the 132 * <a href="{@docRoot}guide/topics/connectivity/vpn">VPN developer's guide</a>. 133 * 134 * @see Builder 135 */ 136 public class VpnService extends Service { 137 138 /** 139 * The action must be matched by the intent filter of this service. It also 140 * needs to require {@link android.Manifest.permission#BIND_VPN_SERVICE} 141 * permission so that other applications cannot abuse it. 142 */ 143 public static final String SERVICE_INTERFACE = VpnConfig.SERVICE_INTERFACE; 144 145 /** 146 * Key for boolean meta-data field indicating whether this VpnService supports always-on mode. 147 * 148 * <p>For a VPN app targeting {@link android.os.Build.VERSION_CODES#N API 24} or above, Android 149 * provides users with the ability to set it as always-on, so that VPN connection is 150 * persisted after device reboot and app upgrade. Always-on VPN can also be enabled by device 151 * owner and profile owner apps through 152 * {@link DevicePolicyManager#setAlwaysOnVpnPackage}. 153 * 154 * <p>VPN apps not supporting this feature should opt out by adding this meta-data field to the 155 * {@code VpnService} component of {@code AndroidManifest.xml}. In case there is more than one 156 * {@code VpnService} component defined in {@code AndroidManifest.xml}, opting out any one of 157 * them will opt out the entire app. For example, 158 * <pre> {@code 159 * <service android:name=".ExampleVpnService" 160 * android:permission="android.permission.BIND_VPN_SERVICE"> 161 * <intent-filter> 162 * <action android:name="android.net.VpnService"/> 163 * </intent-filter> 164 * <meta-data android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON" 165 * android:value=false/> 166 * </service> 167 * } </pre> 168 * 169 * <p>This meta-data field defaults to {@code true} if absent. It will only have effect on 170 * {@link android.os.Build.VERSION_CODES#O_MR1} or higher. 171 */ 172 public static final String SERVICE_META_DATA_SUPPORTS_ALWAYS_ON = 173 "android.net.VpnService.SUPPORTS_ALWAYS_ON"; 174 175 /** 176 * Use IVpnManager since those methods are hidden and not available in VpnManager. 177 */ getService()178 private static IVpnManager getService() { 179 return IVpnManager.Stub.asInterface( 180 ServiceManager.getService(Context.VPN_MANAGEMENT_SERVICE)); 181 } 182 183 /** 184 * Prepare to establish a VPN connection. This method returns {@code null} 185 * if the VPN application is already prepared or if the user has previously 186 * consented to the VPN application. Otherwise, it returns an 187 * {@link Intent} to a system activity. The application should launch the 188 * activity using {@link Activity#startActivityForResult} to get itself 189 * prepared. The activity may pop up a dialog to require user action, and 190 * the result will come back via its {@link Activity#onActivityResult}. 191 * If the result is {@link Activity#RESULT_OK}, the application becomes 192 * prepared and is granted to use other methods in this class. 193 * 194 * <p>Only one application can be granted at the same time. The right 195 * is revoked when another application is granted. The application 196 * losing the right will be notified via its {@link #onRevoke}. Unless 197 * it becomes prepared again, subsequent calls to other methods in this 198 * class will fail. 199 * 200 * <p>The user may disable the VPN at any time while it is activated, in 201 * which case this method will return an intent the next time it is 202 * executed to obtain the user's consent again. 203 * 204 * @see #onRevoke 205 */ prepare(Context context)206 public static Intent prepare(Context context) { 207 try { 208 if (getService().prepareVpn(context.getPackageName(), null, context.getUserId())) { 209 return null; 210 } 211 } catch (RemoteException e) { 212 // ignore 213 } 214 return VpnConfig.getIntentForConfirmation(); 215 } 216 217 /** 218 * Version of {@link #prepare(Context)} which does not require user consent. 219 * 220 * <p>Requires {@link android.Manifest.permission#CONTROL_VPN} and should generally not be 221 * used. Only acceptable in situations where user consent has been obtained through other means. 222 * 223 * <p>Once this is run, future preparations may be done with the standard prepare method as this 224 * will authorize the package to prepare the VPN without consent in the future. 225 * 226 * @hide 227 */ 228 @SystemApi 229 @RequiresPermission(android.Manifest.permission.CONTROL_VPN) prepareAndAuthorize(Context context)230 public static void prepareAndAuthorize(Context context) { 231 IVpnManager vm = getService(); 232 String packageName = context.getPackageName(); 233 try { 234 // Only prepare if we're not already prepared. 235 int userId = context.getUserId(); 236 if (!vm.prepareVpn(packageName, null, userId)) { 237 vm.prepareVpn(null, packageName, userId); 238 } 239 vm.setVpnPackageAuthorization(packageName, userId, VpnManager.TYPE_VPN_SERVICE); 240 } catch (RemoteException e) { 241 // ignore 242 } 243 } 244 245 /** 246 * Protect a socket from VPN connections. After protecting, data sent 247 * through this socket will go directly to the underlying network, 248 * so its traffic will not be forwarded through the VPN. 249 * This method is useful if some connections need to be kept 250 * outside of VPN. For example, a VPN tunnel should protect itself if its 251 * destination is covered by VPN routes. Otherwise its outgoing packets 252 * will be sent back to the VPN interface and cause an infinite loop. This 253 * method will fail if the application is not prepared or is revoked. 254 * 255 * <p class="note">The socket is NOT closed by this method. 256 * 257 * @return {@code true} on success. 258 */ protect(int socket)259 public boolean protect(int socket) { 260 return NetworkUtilsInternal.protectFromVpn(socket); 261 } 262 263 /** 264 * Convenience method to protect a {@link Socket} from VPN connections. 265 * 266 * @return {@code true} on success. 267 * @see #protect(int) 268 */ protect(Socket socket)269 public boolean protect(Socket socket) { 270 return protect(socket.getFileDescriptor$().getInt$()); 271 } 272 273 /** 274 * Convenience method to protect a {@link DatagramSocket} from VPN 275 * connections. 276 * 277 * @return {@code true} on success. 278 * @see #protect(int) 279 */ protect(DatagramSocket socket)280 public boolean protect(DatagramSocket socket) { 281 return protect(socket.getFileDescriptor$().getInt$()); 282 } 283 284 /** 285 * Adds a network address to the VPN interface. 286 * 287 * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the 288 * address is already in use or cannot be assigned to the interface for any other reason. 289 * 290 * Adding an address implicitly allows traffic from that address family (i.e., IPv4 or IPv6) to 291 * be routed over the VPN. @see Builder#allowFamily 292 * 293 * @throws IllegalArgumentException if the address is invalid. 294 * 295 * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface. 296 * @param prefixLength The prefix length of the address. 297 * 298 * @return {@code true} on success. 299 * @see Builder#addAddress 300 * 301 * @hide 302 */ addAddress(InetAddress address, int prefixLength)303 public boolean addAddress(InetAddress address, int prefixLength) { 304 check(address, prefixLength); 305 try { 306 return getService().addVpnAddress(address.getHostAddress(), prefixLength); 307 } catch (RemoteException e) { 308 throw new IllegalStateException(e); 309 } 310 } 311 312 /** 313 * Removes a network address from the VPN interface. 314 * 315 * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the 316 * address is not assigned to the VPN interface, or if it is the only address assigned (thus 317 * cannot be removed), or if the address cannot be removed for any other reason. 318 * 319 * After removing an address, if there are no addresses, routes or DNS servers of a particular 320 * address family (i.e., IPv4 or IPv6) configured on the VPN, that <b>DOES NOT</b> block that 321 * family from being routed. In other words, once an address family has been allowed, it stays 322 * allowed for the rest of the VPN's session. @see Builder#allowFamily 323 * 324 * @throws IllegalArgumentException if the address is invalid. 325 * 326 * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface. 327 * @param prefixLength The prefix length of the address. 328 * 329 * @return {@code true} on success. 330 * 331 * @hide 332 */ removeAddress(InetAddress address, int prefixLength)333 public boolean removeAddress(InetAddress address, int prefixLength) { 334 check(address, prefixLength); 335 try { 336 return getService().removeVpnAddress(address.getHostAddress(), prefixLength); 337 } catch (RemoteException e) { 338 throw new IllegalStateException(e); 339 } 340 } 341 342 /** 343 * Sets the underlying networks used by the VPN for its upstream connections. 344 * 345 * <p>Used by the system to know the actual networks that carry traffic for apps affected by 346 * this VPN in order to present this information to the user (e.g., via status bar icons). 347 * 348 * <p>This method only needs to be called if the VPN has explicitly bound its underlying 349 * communications channels — such as the socket(s) passed to {@link #protect(int)} — 350 * to a {@code Network} using APIs such as {@link Network#bindSocket(Socket)} or 351 * {@link Network#bindSocket(DatagramSocket)}. The VPN should call this method every time 352 * the set of {@code Network}s it is using changes. 353 * 354 * <p>{@code networks} is one of the following: 355 * <ul> 356 * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in 357 * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular) 358 * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear 359 * first in the array.</li> 360 * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no 361 * underlying network connection, and thus, app traffic will not be sent or received.</li> 362 * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's 363 * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket} 364 * APIs mentioned above to send traffic over specific channels.</li> 365 * </ul> 366 * 367 * <p>This call will succeed only if the VPN is currently established. For setting this value 368 * when the VPN has not yet been established, see {@link Builder#setUnderlyingNetworks}. 369 * 370 * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers. 371 * 372 * @return {@code true} on success. 373 */ setUnderlyingNetworks(Network[] networks)374 public boolean setUnderlyingNetworks(Network[] networks) { 375 try { 376 return getService().setUnderlyingNetworksForVpn(networks); 377 } catch (RemoteException e) { 378 throw new IllegalStateException(e); 379 } 380 } 381 382 /** 383 * Returns whether the service is running in always-on VPN mode. In this mode the system ensures 384 * that the service is always running by restarting it when necessary, e.g. after reboot. 385 * 386 * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set) 387 */ isAlwaysOn()388 public final boolean isAlwaysOn() { 389 try { 390 return getService().isCallerCurrentAlwaysOnVpnApp(); 391 } catch (RemoteException e) { 392 throw e.rethrowFromSystemServer(); 393 } 394 } 395 396 /** 397 * Returns whether the service is running in always-on VPN lockdown mode. In this mode the 398 * system ensures that the service is always running and that the apps aren't allowed to bypass 399 * the VPN. 400 * 401 * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set) 402 */ isLockdownEnabled()403 public final boolean isLockdownEnabled() { 404 try { 405 return getService().isCallerCurrentAlwaysOnVpnLockdownApp(); 406 } catch (RemoteException e) { 407 throw e.rethrowFromSystemServer(); 408 } 409 } 410 411 /** 412 * Return the communication interface to the service. This method returns 413 * {@code null} on {@link Intent}s other than {@link #SERVICE_INTERFACE} 414 * action. Applications overriding this method must identify the intent 415 * and return the corresponding interface accordingly. 416 * 417 * @see Service#onBind 418 */ 419 @Override onBind(Intent intent)420 public IBinder onBind(Intent intent) { 421 if (intent != null && SERVICE_INTERFACE.equals(intent.getAction())) { 422 return new Callback(); 423 } 424 return null; 425 } 426 427 /** 428 * Invoked when the application is revoked. At this moment, the VPN 429 * interface is already deactivated by the system. The application should 430 * close the file descriptor and shut down gracefully. The default 431 * implementation of this method is calling {@link Service#stopSelf()}. 432 * 433 * <p class="note">Calls to this method may not happen on the main thread 434 * of the process. 435 * 436 * @see #prepare 437 */ onRevoke()438 public void onRevoke() { 439 stopSelf(); 440 } 441 442 /** 443 * Use raw Binder instead of AIDL since now there is only one usage. 444 */ 445 private class Callback extends Binder { 446 @Override onTransact(int code, Parcel data, Parcel reply, int flags)447 protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) { 448 if (code == IBinder.LAST_CALL_TRANSACTION) { 449 onRevoke(); 450 return true; 451 } 452 return false; 453 } 454 } 455 456 /** 457 * Private method to validate address and prefixLength. 458 */ check(InetAddress address, int prefixLength)459 private static void check(InetAddress address, int prefixLength) { 460 if (address.isLoopbackAddress()) { 461 throw new IllegalArgumentException("Bad address"); 462 } 463 if (address instanceof Inet4Address) { 464 if (prefixLength < 0 || prefixLength > 32) { 465 throw new IllegalArgumentException("Bad prefixLength"); 466 } 467 } else if (address instanceof Inet6Address) { 468 if (prefixLength < 0 || prefixLength > 128) { 469 throw new IllegalArgumentException("Bad prefixLength"); 470 } 471 } else { 472 throw new IllegalArgumentException("Unsupported family"); 473 } 474 } 475 checkNonPrefixBytes(@onNull InetAddress address, int prefixLength)476 private static void checkNonPrefixBytes(@NonNull InetAddress address, int prefixLength) { 477 final IpPrefix prefix = new IpPrefix(address, prefixLength); 478 if (!prefix.getAddress().equals(address)) { 479 throw new IllegalArgumentException("Bad address"); 480 } 481 } 482 483 /** 484 * Helper class to create a VPN interface. This class should be always 485 * used within the scope of the outer {@link VpnService}. 486 * 487 * @see VpnService 488 */ 489 public class Builder { 490 491 private final VpnConfig mConfig = new VpnConfig(); 492 @UnsupportedAppUsage 493 private final List<LinkAddress> mAddresses = new ArrayList<>(); 494 @UnsupportedAppUsage 495 private final List<RouteInfo> mRoutes = new ArrayList<>(); 496 Builder()497 public Builder() { 498 mConfig.user = VpnService.this.getClass().getName(); 499 } 500 501 /** 502 * Set the name of this session. It will be displayed in 503 * system-managed dialogs and notifications. This is recommended 504 * not required. 505 */ 506 @NonNull setSession(@onNull String session)507 public Builder setSession(@NonNull String session) { 508 mConfig.session = session; 509 return this; 510 } 511 512 /** 513 * Set the {@link PendingIntent} to an activity for users to 514 * configure the VPN connection. If it is not set, the button 515 * to configure will not be shown in system-managed dialogs. 516 */ 517 @NonNull setConfigureIntent(@onNull PendingIntent intent)518 public Builder setConfigureIntent(@NonNull PendingIntent intent) { 519 mConfig.configureIntent = intent; 520 return this; 521 } 522 523 /** 524 * Set the maximum transmission unit (MTU) of the VPN interface. If 525 * it is not set, the default value in the operating system will be 526 * used. 527 * 528 * @throws IllegalArgumentException if the value is not positive. 529 */ 530 @NonNull setMtu(int mtu)531 public Builder setMtu(int mtu) { 532 if (mtu <= 0) { 533 throw new IllegalArgumentException("Bad mtu"); 534 } 535 mConfig.mtu = mtu; 536 return this; 537 } 538 539 /** 540 * Sets an HTTP proxy for the VPN network. This proxy is only a recommendation 541 * and it is possible that some apps will ignore it. PAC proxies are not supported. 542 */ 543 @NonNull setHttpProxy(@onNull ProxyInfo proxyInfo)544 public Builder setHttpProxy(@NonNull ProxyInfo proxyInfo) { 545 mConfig.proxyInfo = proxyInfo; 546 return this; 547 } 548 549 /** 550 * Add a network address to the VPN interface. Both IPv4 and IPv6 551 * addresses are supported. At least one address must be set before 552 * calling {@link #establish}. 553 * 554 * Adding an address implicitly allows traffic from that address family 555 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily 556 * 557 * @throws IllegalArgumentException if the address is invalid. 558 */ 559 @NonNull addAddress(@onNull InetAddress address, int prefixLength)560 public Builder addAddress(@NonNull InetAddress address, int prefixLength) { 561 check(address, prefixLength); 562 563 if (address.isAnyLocalAddress()) { 564 throw new IllegalArgumentException("Bad address"); 565 } 566 mAddresses.add(new LinkAddress(address, prefixLength)); 567 return this; 568 } 569 570 /** 571 * Convenience method to add a network address to the VPN interface 572 * using a numeric address string. See {@link InetAddress} for the 573 * definitions of numeric address formats. 574 * 575 * Adding an address implicitly allows traffic from that address family 576 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily 577 * 578 * @throws IllegalArgumentException if the address is invalid. 579 * @see #addAddress(InetAddress, int) 580 */ 581 @NonNull addAddress(@onNull String address, int prefixLength)582 public Builder addAddress(@NonNull String address, int prefixLength) { 583 return addAddress(InetAddress.parseNumericAddress(address), prefixLength); 584 } 585 586 /** 587 * Add a network route to the VPN interface. Both IPv4 and IPv6 588 * routes are supported. 589 * 590 * If a route with the same destination is already present, its type will be updated. 591 * 592 * @throws IllegalArgumentException if the route is invalid. 593 */ 594 @NonNull addRoute(@onNull IpPrefix prefix, int type)595 private Builder addRoute(@NonNull IpPrefix prefix, int type) { 596 check(prefix.getAddress(), prefix.getPrefixLength()); 597 598 final RouteInfo newRoute = new RouteInfo(prefix, /* gateway */ 599 null, /* interface */ null, type); 600 601 final int index = findRouteIndexByDestination(newRoute); 602 603 if (index == -1) { 604 mRoutes.add(newRoute); 605 } else { 606 mRoutes.set(index, newRoute); 607 } 608 609 return this; 610 } 611 612 /** 613 * Add a network route to the VPN interface. Both IPv4 and IPv6 614 * routes are supported. 615 * 616 * Adding a route implicitly allows traffic from that address family 617 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily 618 * 619 * Calling this method overrides previous calls to {@link #excludeRoute} for the same 620 * destination. 621 * 622 * If multiple routes match the packet destination, route with the longest prefix takes 623 * precedence. 624 * 625 * @throws IllegalArgumentException if the route is invalid. 626 */ 627 @NonNull addRoute(@onNull InetAddress address, int prefixLength)628 public Builder addRoute(@NonNull InetAddress address, int prefixLength) { 629 checkNonPrefixBytes(address, prefixLength); 630 631 return addRoute(new IpPrefix(address, prefixLength), RouteInfo.RTN_UNICAST); 632 } 633 634 /** 635 * Add a network route to the VPN interface. Both IPv4 and IPv6 636 * routes are supported. 637 * 638 * Adding a route implicitly allows traffic from that address family 639 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily 640 * 641 * Calling this method overrides previous calls to {@link #excludeRoute} for the same 642 * destination. 643 * 644 * If multiple routes match the packet destination, route with the longest prefix takes 645 * precedence. 646 * 647 * @throws IllegalArgumentException if the route is invalid. 648 */ 649 @NonNull addRoute(@onNull IpPrefix prefix)650 public Builder addRoute(@NonNull IpPrefix prefix) { 651 return addRoute(prefix, RouteInfo.RTN_UNICAST); 652 } 653 654 /** 655 * Convenience method to add a network route to the VPN interface 656 * using a numeric address string. See {@link InetAddress} for the 657 * definitions of numeric address formats. 658 * 659 * Adding a route implicitly allows traffic from that address family 660 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily 661 * 662 * Calling this method overrides previous calls to {@link #excludeRoute} for the same 663 * destination. 664 * 665 * If multiple routes match the packet destination, route with the longest prefix takes 666 * precedence. 667 * 668 * @throws IllegalArgumentException if the route is invalid. 669 * @see #addRoute(InetAddress, int) 670 */ 671 @NonNull addRoute(@onNull String address, int prefixLength)672 public Builder addRoute(@NonNull String address, int prefixLength) { 673 return addRoute(InetAddress.parseNumericAddress(address), prefixLength); 674 } 675 676 /** 677 * Exclude a network route from the VPN interface. Both IPv4 and IPv6 678 * routes are supported. 679 * 680 * Calling this method overrides previous calls to {@link #addRoute} for the same 681 * destination. 682 * 683 * If multiple routes match the packet destination, route with the longest prefix takes 684 * precedence. 685 * 686 * @throws IllegalArgumentException if the route is invalid. 687 */ 688 @NonNull excludeRoute(@onNull IpPrefix prefix)689 public Builder excludeRoute(@NonNull IpPrefix prefix) { 690 return addRoute(prefix, RouteInfo.RTN_THROW); 691 } 692 693 /** 694 * Add a DNS server to the VPN connection. Both IPv4 and IPv6 695 * addresses are supported. If none is set, the DNS servers of 696 * the default network will be used. 697 * 698 * Adding a server implicitly allows traffic from that address family 699 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily 700 * 701 * @throws IllegalArgumentException if the address is invalid. 702 */ 703 @NonNull addDnsServer(@onNull InetAddress address)704 public Builder addDnsServer(@NonNull InetAddress address) { 705 if (address.isLoopbackAddress() || address.isAnyLocalAddress()) { 706 throw new IllegalArgumentException("Bad address"); 707 } 708 if (mConfig.dnsServers == null) { 709 mConfig.dnsServers = new ArrayList<String>(); 710 } 711 mConfig.dnsServers.add(address.getHostAddress()); 712 return this; 713 } 714 715 /** 716 * Convenience method to add a DNS server to the VPN connection 717 * using a numeric address string. See {@link InetAddress} for the 718 * definitions of numeric address formats. 719 * 720 * Adding a server implicitly allows traffic from that address family 721 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily 722 * 723 * @throws IllegalArgumentException if the address is invalid. 724 * @see #addDnsServer(InetAddress) 725 */ 726 @NonNull addDnsServer(@onNull String address)727 public Builder addDnsServer(@NonNull String address) { 728 return addDnsServer(InetAddress.parseNumericAddress(address)); 729 } 730 731 /** 732 * Add a search domain to the DNS resolver. 733 */ 734 @NonNull addSearchDomain(@onNull String domain)735 public Builder addSearchDomain(@NonNull String domain) { 736 if (mConfig.searchDomains == null) { 737 mConfig.searchDomains = new ArrayList<String>(); 738 } 739 mConfig.searchDomains.add(domain); 740 return this; 741 } 742 743 /** 744 * Allows traffic from the specified address family. 745 * 746 * By default, if no address, route or DNS server of a specific family (IPv4 or IPv6) is 747 * added to this VPN, then all outgoing traffic of that family is blocked. If any address, 748 * route or DNS server is added, that family is allowed. 749 * 750 * This method allows an address family to be unblocked even without adding an address, 751 * route or DNS server of that family. Traffic of that family will then typically 752 * fall-through to the underlying network if it's supported. 753 * 754 * {@code family} must be either {@code AF_INET} (for IPv4) or {@code AF_INET6} (for IPv6). 755 * {@link IllegalArgumentException} is thrown if it's neither. 756 * 757 * @param family The address family ({@code AF_INET} or {@code AF_INET6}) to allow. 758 * 759 * @return this {@link Builder} object to facilitate chaining of method calls. 760 */ 761 @NonNull allowFamily(int family)762 public Builder allowFamily(int family) { 763 if (family == AF_INET) { 764 mConfig.allowIPv4 = true; 765 } else if (family == AF_INET6) { 766 mConfig.allowIPv6 = true; 767 } else { 768 throw new IllegalArgumentException(family + " is neither " + AF_INET + " nor " + 769 AF_INET6); 770 } 771 return this; 772 } 773 verifyApp(String packageName)774 private void verifyApp(String packageName) throws PackageManager.NameNotFoundException { 775 IPackageManager pm = IPackageManager.Stub.asInterface( 776 ServiceManager.getService("package")); 777 try { 778 pm.getApplicationInfo(packageName, 0, UserHandle.getCallingUserId()); 779 } catch (RemoteException e) { 780 throw new IllegalStateException(e); 781 } 782 } 783 784 /** 785 * Adds an application that's allowed to access the VPN connection. 786 * 787 * If this method is called at least once, only applications added through this method (and 788 * no others) are allowed access. Else (if this method is never called), all applications 789 * are allowed by default. If some applications are added, other, un-added applications 790 * will use networking as if the VPN wasn't running. 791 * 792 * A {@link Builder} may have only a set of allowed applications OR a set of disallowed 793 * ones, but not both. Calling this method after {@link #addDisallowedApplication} has 794 * already been called, or vice versa, will throw an {@link UnsupportedOperationException}. 795 * 796 * {@code packageName} must be the canonical name of a currently installed application. 797 * {@link PackageManager.NameNotFoundException} is thrown if there's no such application. 798 * 799 * @throws PackageManager.NameNotFoundException If the application isn't installed. 800 * 801 * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application. 802 * 803 * @return this {@link Builder} object to facilitate chaining method calls. 804 */ 805 @NonNull addAllowedApplication(@onNull String packageName)806 public Builder addAllowedApplication(@NonNull String packageName) 807 throws PackageManager.NameNotFoundException { 808 if (mConfig.disallowedApplications != null) { 809 throw new UnsupportedOperationException("addDisallowedApplication already called"); 810 } 811 verifyApp(packageName); 812 if (mConfig.allowedApplications == null) { 813 mConfig.allowedApplications = new ArrayList<String>(); 814 } 815 mConfig.allowedApplications.add(packageName); 816 return this; 817 } 818 819 /** 820 * Adds an application that's denied access to the VPN connection. 821 * 822 * By default, all applications are allowed access, except for those denied through this 823 * method. Denied applications will use networking as if the VPN wasn't running. 824 * 825 * A {@link Builder} may have only a set of allowed applications OR a set of disallowed 826 * ones, but not both. Calling this method after {@link #addAllowedApplication} has already 827 * been called, or vice versa, will throw an {@link UnsupportedOperationException}. 828 * 829 * {@code packageName} must be the canonical name of a currently installed application. 830 * {@link PackageManager.NameNotFoundException} is thrown if there's no such application. 831 * 832 * @throws PackageManager.NameNotFoundException If the application isn't installed. 833 * 834 * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application. 835 * 836 * @return this {@link Builder} object to facilitate chaining method calls. 837 */ 838 @NonNull addDisallowedApplication(@onNull String packageName)839 public Builder addDisallowedApplication(@NonNull String packageName) 840 throws PackageManager.NameNotFoundException { 841 if (mConfig.allowedApplications != null) { 842 throw new UnsupportedOperationException("addAllowedApplication already called"); 843 } 844 verifyApp(packageName); 845 if (mConfig.disallowedApplications == null) { 846 mConfig.disallowedApplications = new ArrayList<String>(); 847 } 848 mConfig.disallowedApplications.add(packageName); 849 return this; 850 } 851 852 /** 853 * Allows all apps to bypass this VPN connection. 854 * 855 * By default, all traffic from apps is forwarded through the VPN interface and it is not 856 * possible for apps to side-step the VPN. If this method is called, apps may use methods 857 * such as {@link ConnectivityManager#bindProcessToNetwork} to instead send/receive 858 * directly over the underlying network or any other network they have permissions for. 859 * 860 * @return this {@link Builder} object to facilitate chaining of method calls. 861 */ 862 @NonNull allowBypass()863 public Builder allowBypass() { 864 mConfig.allowBypass = true; 865 return this; 866 } 867 868 /** 869 * Sets the VPN interface's file descriptor to be in blocking/non-blocking mode. 870 * 871 * By default, the file descriptor returned by {@link #establish} is non-blocking. 872 * 873 * @param blocking True to put the descriptor into blocking mode; false for non-blocking. 874 * 875 * @return this {@link Builder} object to facilitate chaining method calls. 876 */ 877 @NonNull setBlocking(boolean blocking)878 public Builder setBlocking(boolean blocking) { 879 mConfig.blocking = blocking; 880 return this; 881 } 882 883 /** 884 * Sets the underlying networks used by the VPN for its upstream connections. 885 * 886 * @see VpnService#setUnderlyingNetworks 887 * 888 * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers. 889 * 890 * @return this {@link Builder} object to facilitate chaining method calls. 891 */ 892 @NonNull setUnderlyingNetworks(@ullable Network[] networks)893 public Builder setUnderlyingNetworks(@Nullable Network[] networks) { 894 mConfig.underlyingNetworks = networks != null ? networks.clone() : null; 895 return this; 896 } 897 898 /** 899 * Marks the VPN network as metered. A VPN network is classified as metered when the user is 900 * sensitive to heavy data usage due to monetary costs and/or data limitations. In such 901 * cases, you should set this to {@code true} so that apps on the system can avoid doing 902 * large data transfers. Otherwise, set this to {@code false}. Doing so would cause VPN 903 * network to inherit its meteredness from its underlying networks. 904 * 905 * <p>VPN apps targeting {@link android.os.Build.VERSION_CODES#Q} or above will be 906 * considered metered by default. 907 * 908 * @param isMetered {@code true} if VPN network should be treated as metered regardless of 909 * underlying network meteredness 910 * @return this {@link Builder} object to facilitate chaining method calls 911 * @see #setUnderlyingNetworks(Network[]) 912 * @see ConnectivityManager#isActiveNetworkMetered() 913 */ 914 @NonNull setMetered(boolean isMetered)915 public Builder setMetered(boolean isMetered) { 916 mConfig.isMetered = isMetered; 917 return this; 918 } 919 920 /** 921 * Create a VPN interface using the parameters supplied to this 922 * builder. The interface works on IP packets, and a file descriptor 923 * is returned for the application to access them. Each read 924 * retrieves an outgoing packet which was routed to the interface. 925 * Each write injects an incoming packet just like it was received 926 * from the interface. The file descriptor is put into non-blocking 927 * mode by default to avoid blocking Java threads. To use the file 928 * descriptor completely in native space, see 929 * {@link ParcelFileDescriptor#detachFd()}. The application MUST 930 * close the file descriptor when the VPN connection is terminated. 931 * The VPN interface will be removed and the network will be 932 * restored by the system automatically. 933 * 934 * <p>To avoid conflicts, there can be only one active VPN interface 935 * at the same time. Usually network parameters are never changed 936 * during the lifetime of a VPN connection. It is also common for an 937 * application to create a new file descriptor after closing the 938 * previous one. However, it is rare but not impossible to have two 939 * interfaces while performing a seamless handover. In this case, the 940 * old interface will be deactivated when the new one is created 941 * successfully. Both file descriptors are valid but now outgoing 942 * packets will be routed to the new interface. Therefore, after 943 * draining the old file descriptor, the application MUST close it 944 * and start using the new file descriptor. If the new interface 945 * cannot be created, the existing interface and its file descriptor 946 * remain untouched. 947 * 948 * <p>An exception will be thrown if the interface cannot be created 949 * for any reason. However, this method returns {@code null} if the 950 * application is not prepared or is revoked. This helps solve 951 * possible race conditions between other VPN applications. 952 * 953 * @return {@link ParcelFileDescriptor} of the VPN interface, or 954 * {@code null} if the application is not prepared. 955 * @throws IllegalArgumentException if a parameter is not accepted 956 * by the operating system. 957 * @throws IllegalStateException if a parameter cannot be applied 958 * by the operating system. 959 * @throws SecurityException if the service is not properly declared 960 * in {@code AndroidManifest.xml}. 961 * @see VpnService 962 */ 963 @Nullable establish()964 public ParcelFileDescriptor establish() { 965 mConfig.addresses = mAddresses; 966 mConfig.routes = mRoutes; 967 968 try { 969 return getService().establishVpn(mConfig); 970 } catch (RemoteException e) { 971 throw new IllegalStateException(e); 972 } 973 } 974 findRouteIndexByDestination(RouteInfo route)975 private int findRouteIndexByDestination(RouteInfo route) { 976 for (int i = 0; i < mRoutes.size(); i++) { 977 if (mRoutes.get(i).getDestination().equals(route.getDestination())) { 978 return i; 979 } 980 } 981 return -1; 982 } 983 984 /** 985 * Method for testing, to observe mRoutes while builder is being used. 986 * @hide 987 */ 988 @VisibleForTesting routes()989 public List<RouteInfo> routes() { 990 return Collections.unmodifiableList(mRoutes); 991 } 992 } 993 } 994