• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * &lt;service android:name=".ExampleVpnService"
116  *         android:permission="android.permission.BIND_VPN_SERVICE"&gt;
117  *     &lt;intent-filter&gt;
118  *         &lt;action android:name="android.net.VpnService"/&gt;
119  *     &lt;/intent-filter&gt;
120  * &lt;/service&gt;</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 &mdash; such as the socket(s) passed to {@link #protect(int)} &mdash;
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