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