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.compat.annotation.UnsupportedAppUsage; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.pm.PackageManager; 25 import android.content.pm.PackageManager.NameNotFoundException; 26 import android.content.pm.ResolveInfo; 27 import android.content.res.Resources; 28 import android.net.IpPrefix; 29 import android.net.LinkAddress; 30 import android.net.Network; 31 import android.net.ProxyInfo; 32 import android.net.RouteInfo; 33 import android.os.Parcel; 34 import android.os.Parcelable; 35 import android.os.UserHandle; 36 37 import java.util.ArrayList; 38 import java.util.Arrays; 39 import java.util.List; 40 41 /** 42 * A simple container used to carry information in VpnBuilder, VpnDialogs, 43 * and com.android.server.connectivity.Vpn. Internal use only. 44 * 45 * @hide 46 */ 47 public class VpnConfig implements Parcelable { 48 49 public static final String SERVICE_INTERFACE = "android.net.VpnService"; 50 51 public static final String DIALOGS_PACKAGE = "com.android.vpndialogs"; 52 53 // TODO: Rename this to something that encompasses Settings-based Platform VPNs as well. 54 public static final String LEGACY_VPN = "[Legacy VPN]"; 55 getIntentForConfirmation()56 public static Intent getIntentForConfirmation() { 57 Intent intent = new Intent(); 58 ComponentName componentName = ComponentName.unflattenFromString( 59 Resources.getSystem().getString( 60 com.android.internal.R.string.config_customVpnConfirmDialogComponent)); 61 intent.setClassName(componentName.getPackageName(), componentName.getClassName()); 62 return intent; 63 } 64 65 /** NOTE: This should only be used for legacy VPN. */ getIntentForStatusPanel(Context context)66 public static PendingIntent getIntentForStatusPanel(Context context) { 67 Intent intent = new Intent(); 68 intent.setClassName(DIALOGS_PACKAGE, DIALOGS_PACKAGE + ".ManageDialog"); 69 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY | 70 Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 71 return PendingIntent.getActivityAsUser(context, 0 /* requestCode */, intent, 72 PendingIntent.FLAG_IMMUTABLE, null /* options */, UserHandle.CURRENT); 73 } 74 getVpnLabel(Context context, String packageName)75 public static CharSequence getVpnLabel(Context context, String packageName) 76 throws NameNotFoundException { 77 PackageManager pm = context.getPackageManager(); 78 Intent intent = new Intent(SERVICE_INTERFACE); 79 intent.setPackage(packageName); 80 List<ResolveInfo> services = pm.queryIntentServices(intent, 0 /* flags */); 81 if (services != null && services.size() == 1) { 82 // This app contains exactly one VPN service. Call loadLabel, which will attempt to 83 // load the service's label, and fall back to the app label if none is present. 84 return services.get(0).loadLabel(pm); 85 } else { 86 return pm.getApplicationInfo(packageName, 0).loadLabel(pm); 87 } 88 } 89 90 public String user; 91 public String interfaze; 92 public String session; 93 public int mtu = -1; 94 public List<LinkAddress> addresses = new ArrayList<>(); 95 public List<RouteInfo> routes = new ArrayList<>(); 96 public List<String> dnsServers; 97 public List<String> searchDomains; 98 public List<String> allowedApplications; 99 public List<String> disallowedApplications; 100 public PendingIntent configureIntent; 101 public long startTime = -1; 102 public boolean legacy; 103 public boolean blocking; 104 public boolean allowBypass; 105 public boolean allowIPv4; 106 public boolean allowIPv6; 107 public boolean isMetered = true; 108 public boolean requiresInternetValidation = false; 109 public boolean excludeLocalRoutes = false; 110 public Network[] underlyingNetworks; 111 public ProxyInfo proxyInfo; 112 113 @UnsupportedAppUsage VpnConfig()114 public VpnConfig() { 115 } 116 VpnConfig(VpnConfig other)117 public VpnConfig(VpnConfig other) { 118 user = other.user; 119 interfaze = other.interfaze; 120 session = other.session; 121 mtu = other.mtu; 122 addresses = copyOf(other.addresses); 123 routes = copyOf(other.routes); 124 dnsServers = copyOf(other.dnsServers); 125 searchDomains = copyOf(other.searchDomains); 126 allowedApplications = copyOf(other.allowedApplications); 127 disallowedApplications = copyOf(other.disallowedApplications); 128 configureIntent = other.configureIntent; 129 startTime = other.startTime; 130 legacy = other.legacy; 131 blocking = other.blocking; 132 allowBypass = other.allowBypass; 133 allowIPv4 = other.allowIPv4; 134 allowIPv6 = other.allowIPv6; 135 isMetered = other.isMetered; 136 requiresInternetValidation = other.requiresInternetValidation; 137 excludeLocalRoutes = other.excludeLocalRoutes; 138 underlyingNetworks = other.underlyingNetworks != null ? Arrays.copyOf( 139 other.underlyingNetworks, other.underlyingNetworks.length) : null; 140 proxyInfo = other.proxyInfo; 141 } 142 copyOf(List<T> list)143 private static <T> List<T> copyOf(List<T> list) { 144 return list != null ? new ArrayList<>(list) : null; 145 } 146 addLegacyRoutes(String routesStr)147 public void addLegacyRoutes(String routesStr) { 148 if (routesStr.trim().equals("")) { 149 return; 150 } 151 String[] routes = routesStr.trim().split(" "); 152 for (String route : routes) { 153 //each route is ip/prefix 154 RouteInfo info = new RouteInfo(new IpPrefix(route), null, null, RouteInfo.RTN_UNICAST); 155 this.routes.add(info); 156 } 157 } 158 addLegacyAddresses(String addressesStr)159 public void addLegacyAddresses(String addressesStr) { 160 if (addressesStr.trim().equals("")) { 161 return; 162 } 163 String[] addresses = addressesStr.trim().split(" "); 164 for (String address : addresses) { 165 //each address is ip/prefix 166 LinkAddress addr = new LinkAddress(address); 167 this.addresses.add(addr); 168 } 169 } 170 171 @Override describeContents()172 public int describeContents() { 173 return 0; 174 } 175 176 @Override writeToParcel(Parcel out, int flags)177 public void writeToParcel(Parcel out, int flags) { 178 out.writeString(user); 179 out.writeString(interfaze); 180 out.writeString(session); 181 out.writeInt(mtu); 182 out.writeTypedList(addresses); 183 out.writeTypedList(routes); 184 out.writeStringList(dnsServers); 185 out.writeStringList(searchDomains); 186 out.writeStringList(allowedApplications); 187 out.writeStringList(disallowedApplications); 188 out.writeParcelable(configureIntent, flags); 189 out.writeLong(startTime); 190 out.writeInt(legacy ? 1 : 0); 191 out.writeInt(blocking ? 1 : 0); 192 out.writeInt(allowBypass ? 1 : 0); 193 out.writeInt(allowIPv4 ? 1 : 0); 194 out.writeInt(allowIPv6 ? 1 : 0); 195 out.writeInt(isMetered ? 1 : 0); 196 out.writeInt(requiresInternetValidation ? 1 : 0); 197 out.writeInt(excludeLocalRoutes ? 1 : 0); 198 out.writeTypedArray(underlyingNetworks, flags); 199 out.writeParcelable(proxyInfo, flags); 200 } 201 202 public static final Parcelable.Creator<VpnConfig> CREATOR = 203 new Parcelable.Creator<VpnConfig>() { 204 @Override 205 public VpnConfig createFromParcel(Parcel in) { 206 VpnConfig config = new VpnConfig(); 207 config.user = in.readString(); 208 config.interfaze = in.readString(); 209 config.session = in.readString(); 210 config.mtu = in.readInt(); 211 in.readTypedList(config.addresses, LinkAddress.CREATOR); 212 in.readTypedList(config.routes, RouteInfo.CREATOR); 213 config.dnsServers = in.createStringArrayList(); 214 config.searchDomains = in.createStringArrayList(); 215 config.allowedApplications = in.createStringArrayList(); 216 config.disallowedApplications = in.createStringArrayList(); 217 config.configureIntent = in.readParcelable(null, android.app.PendingIntent.class); 218 config.startTime = in.readLong(); 219 config.legacy = in.readInt() != 0; 220 config.blocking = in.readInt() != 0; 221 config.allowBypass = in.readInt() != 0; 222 config.allowIPv4 = in.readInt() != 0; 223 config.allowIPv6 = in.readInt() != 0; 224 config.isMetered = in.readInt() != 0; 225 config.requiresInternetValidation = in.readInt() != 0; 226 config.excludeLocalRoutes = in.readInt() != 0; 227 config.underlyingNetworks = in.createTypedArray(Network.CREATOR); 228 config.proxyInfo = in.readParcelable(null, android.net.ProxyInfo.class); 229 return config; 230 } 231 232 @Override 233 public VpnConfig[] newArray(int size) { 234 return new VpnConfig[size]; 235 } 236 }; 237 238 @Override toString()239 public String toString() { 240 return new StringBuilder() 241 .append("VpnConfig") 242 .append("{ user=").append(user) 243 .append(", interface=").append(interfaze) 244 .append(", session=").append(session) 245 .append(", mtu=").append(mtu) 246 .append(", addresses=").append(toString(addresses)) 247 .append(", routes=").append(toString(routes)) 248 .append(", dns=").append(toString(dnsServers)) 249 .append(", searchDomains=").append(toString(searchDomains)) 250 .append(", allowedApps=").append(toString(allowedApplications)) 251 .append(", disallowedApps=").append(toString(disallowedApplications)) 252 .append(", configureIntent=").append(configureIntent) 253 .append(", startTime=").append(startTime) 254 .append(", legacy=").append(legacy) 255 .append(", blocking=").append(blocking) 256 .append(", allowBypass=").append(allowBypass) 257 .append(", allowIPv4=").append(allowIPv4) 258 .append(", allowIPv6=").append(allowIPv6) 259 .append(", isMetered=").append(isMetered) 260 .append(", requiresInternetValidation=").append(requiresInternetValidation) 261 .append(", excludeLocalRoutes=").append(excludeLocalRoutes) 262 .append(", underlyingNetworks=").append(Arrays.toString(underlyingNetworks)) 263 .append(", proxyInfo=").append(proxyInfo) 264 .append("}") 265 .toString(); 266 } 267 toString(List<T> ls)268 static <T> String toString(List<T> ls) { 269 if (ls == null) { 270 return "null"; 271 } 272 return Arrays.toString(ls.toArray()); 273 } 274 } 275