summaryrefslogtreecommitdiff
path: root/core/java/com/android/internal/net/VpnConfig.java
blob: 65b974ba8b420e71308c27c62f93e20bc9829f11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.net;

import android.annotation.UnsupportedAppUsage;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.Network;
import android.net.ProxyInfo;
import android.net.RouteInfo;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * A simple container used to carry information in VpnBuilder, VpnDialogs,
 * and com.android.server.connectivity.Vpn. Internal use only.
 *
 * @hide
 */
public class VpnConfig implements Parcelable {

    public static final String SERVICE_INTERFACE = "android.net.VpnService";

    public static final String DIALOGS_PACKAGE = "com.android.vpndialogs";

    public static final String LEGACY_VPN = "[Legacy VPN]";

    public static Intent getIntentForConfirmation() {
        Intent intent = new Intent();
        ComponentName componentName = ComponentName.unflattenFromString(
                Resources.getSystem().getString(
                        com.android.internal.R.string.config_customVpnConfirmDialogComponent));
        intent.setClassName(componentName.getPackageName(), componentName.getClassName());
        return intent;
    }

    /** NOTE: This should only be used for legacy VPN. */
    public static PendingIntent getIntentForStatusPanel(Context context) {
        Intent intent = new Intent();
        intent.setClassName(DIALOGS_PACKAGE, DIALOGS_PACKAGE + ".ManageDialog");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY |
                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        return PendingIntent.getActivityAsUser(context, 0, intent, 0, null, UserHandle.CURRENT);
    }

    public static CharSequence getVpnLabel(Context context, String packageName)
            throws NameNotFoundException {
        PackageManager pm = context.getPackageManager();
        Intent intent = new Intent(SERVICE_INTERFACE);
        intent.setPackage(packageName);
        List<ResolveInfo> services = pm.queryIntentServices(intent, 0 /* flags */);
        if (services != null && services.size() == 1) {
            // This app contains exactly one VPN service. Call loadLabel, which will attempt to
            // load the service's label, and fall back to the app label if none is present.
            return services.get(0).loadLabel(pm);
        } else {
            return pm.getApplicationInfo(packageName, 0).loadLabel(pm);
        }
    }

    public String user;
    public String interfaze;
    public String session;
    public int mtu = -1;
    public List<LinkAddress> addresses = new ArrayList<LinkAddress>();
    public List<RouteInfo> routes = new ArrayList<RouteInfo>();
    public List<String> dnsServers;
    public List<String> searchDomains;
    public List<String> allowedApplications;
    public List<String> disallowedApplications;
    public PendingIntent configureIntent;
    public long startTime = -1;
    public boolean legacy;
    public boolean blocking;
    public boolean allowBypass;
    public boolean allowIPv4;
    public boolean allowIPv6;
    public boolean isMetered = true;
    public Network[] underlyingNetworks;
    public ProxyInfo proxyInfo;

    public void updateAllowedFamilies(InetAddress address) {
        if (address instanceof Inet4Address) {
            allowIPv4 = true;
        } else {
            allowIPv6 = true;
        }
    }

    public void addLegacyRoutes(String routesStr) {
        if (routesStr.trim().equals("")) {
            return;
        }
        String[] routes = routesStr.trim().split(" ");
        for (String route : routes) {
            //each route is ip/prefix
            RouteInfo info = new RouteInfo(new IpPrefix(route), null);
            this.routes.add(info);
            updateAllowedFamilies(info.getDestination().getAddress());
        }
    }

    public void addLegacyAddresses(String addressesStr) {
        if (addressesStr.trim().equals("")) {
            return;
        }
        String[] addresses = addressesStr.trim().split(" ");
        for (String address : addresses) {
            //each address is ip/prefix
            LinkAddress addr = new LinkAddress(address);
            this.addresses.add(addr);
            updateAllowedFamilies(addr.getAddress());
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(user);
        out.writeString(interfaze);
        out.writeString(session);
        out.writeInt(mtu);
        out.writeTypedList(addresses);
        out.writeTypedList(routes);
        out.writeStringList(dnsServers);
        out.writeStringList(searchDomains);
        out.writeStringList(allowedApplications);
        out.writeStringList(disallowedApplications);
        out.writeParcelable(configureIntent, flags);
        out.writeLong(startTime);
        out.writeInt(legacy ? 1 : 0);
        out.writeInt(blocking ? 1 : 0);
        out.writeInt(allowBypass ? 1 : 0);
        out.writeInt(allowIPv4 ? 1 : 0);
        out.writeInt(allowIPv6 ? 1 : 0);
        out.writeInt(isMetered ? 1 : 0);
        out.writeTypedArray(underlyingNetworks, flags);
        out.writeParcelable(proxyInfo, flags);
    }

    public static final Parcelable.Creator<VpnConfig> CREATOR =
            new Parcelable.Creator<VpnConfig>() {
        @Override
        public VpnConfig createFromParcel(Parcel in) {
            VpnConfig config = new VpnConfig();
            config.user = in.readString();
            config.interfaze = in.readString();
            config.session = in.readString();
            config.mtu = in.readInt();
            in.readTypedList(config.addresses, LinkAddress.CREATOR);
            in.readTypedList(config.routes, RouteInfo.CREATOR);
            config.dnsServers = in.createStringArrayList();
            config.searchDomains = in.createStringArrayList();
            config.allowedApplications = in.createStringArrayList();
            config.disallowedApplications = in.createStringArrayList();
            config.configureIntent = in.readParcelable(null);
            config.startTime = in.readLong();
            config.legacy = in.readInt() != 0;
            config.blocking = in.readInt() != 0;
            config.allowBypass = in.readInt() != 0;
            config.allowIPv4 = in.readInt() != 0;
            config.allowIPv6 = in.readInt() != 0;
            config.isMetered = in.readInt() != 0;
            config.underlyingNetworks = in.createTypedArray(Network.CREATOR);
            config.proxyInfo = in.readParcelable(null);
            return config;
        }

        @Override
        public VpnConfig[] newArray(int size) {
            return new VpnConfig[size];
        }
    };

    @Override
    public String toString() {
        return new StringBuilder()
                .append("VpnConfig")
                .append("{ user=").append(user)
                .append(", interface=").append(interfaze)
                .append(", session=").append(session)
                .append(", mtu=").append(mtu)
                .append(", addresses=").append(toString(addresses))
                .append(", routes=").append(toString(routes))
                .append(", dns=").append(toString(dnsServers))
                .append(", searchDomains=").append(toString(searchDomains))
                .append(", allowedApps=").append(toString(allowedApplications))
                .append(", disallowedApps=").append(toString(disallowedApplications))
                .append(", configureIntent=").append(configureIntent)
                .append(", startTime=").append(startTime)
                .append(", legacy=").append(legacy)
                .append(", blocking=").append(blocking)
                .append(", allowBypass=").append(allowBypass)
                .append(", allowIPv4=").append(allowIPv4)
                .append(", allowIPv6=").append(allowIPv6)
                .append(", underlyingNetworks=").append(Arrays.toString(underlyingNetworks))
                .append(", proxyInfo=").append(proxyInfo.toString())
                .append("}")
                .toString();
    }

    static <T> String toString(List<T> ls) {
        if (ls == null) {
            return "null";
        }
        return Arrays.toString(ls.toArray());
    }
}