1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.net;
18 
19 import android.app.PendingIntent;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.content.pm.PackageManager.NameNotFoundException;
25 import android.content.pm.ResolveInfo;
26 import android.content.res.Resources;
27 import android.net.IpPrefix;
28 import android.net.LinkAddress;
29 import android.net.Network;
30 import android.net.RouteInfo;
31 import android.os.Parcel;
32 import android.os.Parcelable;
33 import android.os.UserHandle;
34 
35 import java.net.Inet4Address;
36 import java.net.InetAddress;
37 import java.util.ArrayList;
38 import java.util.List;
39 
40 /**
41  * A simple container used to carry information in VpnBuilder, VpnDialogs,
42  * and com.android.server.connectivity.Vpn. Internal use only.
43  *
44  * @hide
45  */
46 public class VpnConfig implements Parcelable {
47 
48     public static final String SERVICE_INTERFACE = "android.net.VpnService";
49 
50     public static final String DIALOGS_PACKAGE = "com.android.vpndialogs";
51 
52     public static final String LEGACY_VPN = "[Legacy VPN]";
53 
getIntentForConfirmation()54     public static Intent getIntentForConfirmation() {
55         Intent intent = new Intent();
56         ComponentName componentName = ComponentName.unflattenFromString(
57                 Resources.getSystem().getString(
58                         com.android.internal.R.string.config_customVpnConfirmDialogComponent));
59         intent.setClassName(componentName.getPackageName(), componentName.getClassName());
60         return intent;
61     }
62 
63     /** NOTE: This should only be used for legacy VPN. */
getIntentForStatusPanel(Context context)64     public static PendingIntent getIntentForStatusPanel(Context context) {
65         Intent intent = new Intent();
66         intent.setClassName(DIALOGS_PACKAGE, DIALOGS_PACKAGE + ".ManageDialog");
67         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY |
68                 Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
69         return PendingIntent.getActivityAsUser(context, 0, intent, 0, null, UserHandle.CURRENT);
70     }
71 
getVpnLabel(Context context, String packageName)72     public static CharSequence getVpnLabel(Context context, String packageName)
73             throws NameNotFoundException {
74         PackageManager pm = context.getPackageManager();
75         Intent intent = new Intent(SERVICE_INTERFACE);
76         intent.setPackage(packageName);
77         List<ResolveInfo> services = pm.queryIntentServices(intent, 0 /* flags */);
78         if (services != null && services.size() == 1) {
79             // This app contains exactly one VPN service. Call loadLabel, which will attempt to
80             // load the service's label, and fall back to the app label if none is present.
81             return services.get(0).loadLabel(pm);
82         } else {
83             return pm.getApplicationInfo(packageName, 0).loadLabel(pm);
84         }
85     }
86 
87     public String user;
88     public String interfaze;
89     public String session;
90     public int mtu = -1;
91     public List<LinkAddress> addresses = new ArrayList<LinkAddress>();
92     public List<RouteInfo> routes = new ArrayList<RouteInfo>();
93     public List<String> dnsServers;
94     public List<String> searchDomains;
95     public List<String> allowedApplications;
96     public List<String> disallowedApplications;
97     public PendingIntent configureIntent;
98     public long startTime = -1;
99     public boolean legacy;
100     public boolean blocking;
101     public boolean allowBypass;
102     public boolean allowIPv4;
103     public boolean allowIPv6;
104     public Network[] underlyingNetworks;
105 
updateAllowedFamilies(InetAddress address)106     public void updateAllowedFamilies(InetAddress address) {
107         if (address instanceof Inet4Address) {
108             allowIPv4 = true;
109         } else {
110             allowIPv6 = true;
111         }
112     }
113 
addLegacyRoutes(String routesStr)114     public void addLegacyRoutes(String routesStr) {
115         if (routesStr.trim().equals("")) {
116             return;
117         }
118         String[] routes = routesStr.trim().split(" ");
119         for (String route : routes) {
120             //each route is ip/prefix
121             RouteInfo info = new RouteInfo(new IpPrefix(route), null);
122             this.routes.add(info);
123             updateAllowedFamilies(info.getDestination().getAddress());
124         }
125     }
126 
addLegacyAddresses(String addressesStr)127     public void addLegacyAddresses(String addressesStr) {
128         if (addressesStr.trim().equals("")) {
129             return;
130         }
131         String[] addresses = addressesStr.trim().split(" ");
132         for (String address : addresses) {
133             //each address is ip/prefix
134             LinkAddress addr = new LinkAddress(address);
135             this.addresses.add(addr);
136             updateAllowedFamilies(addr.getAddress());
137         }
138     }
139 
140     @Override
describeContents()141     public int describeContents() {
142         return 0;
143     }
144 
145     @Override
writeToParcel(Parcel out, int flags)146     public void writeToParcel(Parcel out, int flags) {
147         out.writeString(user);
148         out.writeString(interfaze);
149         out.writeString(session);
150         out.writeInt(mtu);
151         out.writeTypedList(addresses);
152         out.writeTypedList(routes);
153         out.writeStringList(dnsServers);
154         out.writeStringList(searchDomains);
155         out.writeStringList(allowedApplications);
156         out.writeStringList(disallowedApplications);
157         out.writeParcelable(configureIntent, flags);
158         out.writeLong(startTime);
159         out.writeInt(legacy ? 1 : 0);
160         out.writeInt(blocking ? 1 : 0);
161         out.writeInt(allowBypass ? 1 : 0);
162         out.writeInt(allowIPv4 ? 1 : 0);
163         out.writeInt(allowIPv6 ? 1 : 0);
164         out.writeTypedArray(underlyingNetworks, flags);
165     }
166 
167     public static final Parcelable.Creator<VpnConfig> CREATOR =
168             new Parcelable.Creator<VpnConfig>() {
169         @Override
170         public VpnConfig createFromParcel(Parcel in) {
171             VpnConfig config = new VpnConfig();
172             config.user = in.readString();
173             config.interfaze = in.readString();
174             config.session = in.readString();
175             config.mtu = in.readInt();
176             in.readTypedList(config.addresses, LinkAddress.CREATOR);
177             in.readTypedList(config.routes, RouteInfo.CREATOR);
178             config.dnsServers = in.createStringArrayList();
179             config.searchDomains = in.createStringArrayList();
180             config.allowedApplications = in.createStringArrayList();
181             config.disallowedApplications = in.createStringArrayList();
182             config.configureIntent = in.readParcelable(null);
183             config.startTime = in.readLong();
184             config.legacy = in.readInt() != 0;
185             config.blocking = in.readInt() != 0;
186             config.allowBypass = in.readInt() != 0;
187             config.allowIPv4 = in.readInt() != 0;
188             config.allowIPv6 = in.readInt() != 0;
189             config.underlyingNetworks = in.createTypedArray(Network.CREATOR);
190             return config;
191         }
192 
193         @Override
194         public VpnConfig[] newArray(int size) {
195             return new VpnConfig[size];
196         }
197     };
198 }
199