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