1971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey/*
2971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * Copyright (C) 2011 The Android Open Source Project
3971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *
4971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * you may not use this file except in compliance with the License.
6971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * You may obtain a copy of the License at
7971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *
8971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *
10971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
11971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * See the License for the specific language governing permissions and
14971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * limitations under the License.
15971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey */
16971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
17971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkeypackage com.android.internal.net;
18971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
1982f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkeyimport android.os.Parcel;
2082f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkeyimport android.os.Parcelable;
2169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport android.text.TextUtils;
2282f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey
2369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport java.net.InetAddress;
24d396a448b2e36e29598c954b64bfddef73f3fae0Elliott Hughesimport java.nio.charset.StandardCharsets;
25971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
26971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey/**
27971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * Parcel-like entity class for VPN profiles. To keep things simple, all
28971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * fields are package private. Methods are provided for serialization, so
29971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * storage can be implemented easily. Two rules are set for this class.
30971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * First, all fields must be kept non-null. Second, always make a copy
31971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * using clone() before modifying.
32971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey *
33971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey * @hide
34971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey */
3582f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkeypublic class VpnProfile implements Cloneable, Parcelable {
3669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    private static final String TAG = "VpnProfile";
3769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
38971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    // Match these constants with R.array.vpn_types.
39971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_PPTP = 0;
40971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_L2TP_IPSEC_PSK = 1;
41971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_L2TP_IPSEC_RSA = 2;
42971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_IPSEC_XAUTH_PSK = 3;
43971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_IPSEC_XAUTH_RSA = 4;
44971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_IPSEC_HYBRID_RSA = 5;
45971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static final int TYPE_MAX = 5;
46971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
47971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    // Entity fields.
48971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public final String key;           // -1
49971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String name = "";           // 0
50971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public int type = TYPE_PPTP;       // 1
51971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String server = "";         // 2
52971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String username = "";       // 3
53971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String password = "";       // 4
54971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String dnsServers = "";     // 5
55971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String searchDomains = "";  // 6
56971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String routes = "";         // 7
57971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public boolean mppe = true;        // 8
58971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String l2tpSecret = "";     // 9
59971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecIdentifier = "";// 10
60971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecSecret = "";    // 11
61971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecUserCert = "";  // 12
62971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecCaCert = "";    // 13
63971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public String ipsecServerCert = "";// 14
64971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
65971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    // Helper fields.
66971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public boolean saveLogin = false;
67971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
68971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public VpnProfile(String key) {
69971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        this.key = key;
70971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    }
71971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
726e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    public VpnProfile(Parcel in) {
736e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        key = in.readString();
746e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        name = in.readString();
756e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        type = in.readInt();
766e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        server = in.readString();
776e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        username = in.readString();
786e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        password = in.readString();
796e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        dnsServers = in.readString();
806e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        searchDomains = in.readString();
816e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        routes = in.readString();
826e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        mppe = in.readInt() != 0;
836e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        l2tpSecret = in.readString();
846e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecIdentifier = in.readString();
856e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecSecret = in.readString();
866e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecUserCert = in.readString();
876e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecCaCert = in.readString();
886e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        ipsecServerCert = in.readString();
896e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        saveLogin = in.readInt() != 0;
906e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    }
916e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey
926e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    @Override
936e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    public void writeToParcel(Parcel out, int flags) {
946e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(key);
956e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(name);
966e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeInt(type);
976e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(server);
986e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(username);
996e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(password);
1006e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(dnsServers);
1016e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(searchDomains);
1026e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(routes);
1036e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeInt(mppe ? 1 : 0);
1046e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(l2tpSecret);
1056e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecIdentifier);
1066e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecSecret);
1076e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecUserCert);
1086e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecCaCert);
1096e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeString(ipsecServerCert);
1106e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey        out.writeInt(saveLogin ? 1 : 0);
1116e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey    }
1126e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey
113971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public static VpnProfile decode(String key, byte[] value) {
114971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        try {
115971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            if (key == null) {
116971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey                return null;
117971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            }
118971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
119d396a448b2e36e29598c954b64bfddef73f3fae0Elliott Hughes            String[] values = new String(value, StandardCharsets.UTF_8).split("\0", -1);
120971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            // There can be 14 or 15 values in ICS MR1.
121971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            if (values.length < 14 || values.length > 15) {
122971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey                return null;
123971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            }
124971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
125971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            VpnProfile profile = new VpnProfile(key);
126971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.name = values[0];
127a09b4d2a611a7606e8fc8c73a24bd941b6fc173fNarayan Kamath            profile.type = Integer.parseInt(values[1]);
128971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            if (profile.type < 0 || profile.type > TYPE_MAX) {
129971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey                return null;
130971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            }
131971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.server = values[2];
132971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.username = values[3];
133971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.password = values[4];
134971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.dnsServers = values[5];
135971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.searchDomains = values[6];
136971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.routes = values[7];
137b0800dce4abdca9aeef1cf72018906c2476c4c6bTobias Thierer            profile.mppe = Boolean.parseBoolean(values[8]);
138971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.l2tpSecret = values[9];
139971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecIdentifier = values[10];
140971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecSecret = values[11];
141971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecUserCert = values[12];
142971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecCaCert = values[13];
143971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.ipsecServerCert = (values.length > 14) ? values[14] : "";
144971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
145971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            profile.saveLogin = !profile.username.isEmpty() || !profile.password.isEmpty();
146971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            return profile;
147971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        } catch (Exception e) {
148971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey            // ignore
149971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        }
150971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        return null;
151971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    }
152971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey
153971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    public byte[] encode() {
154971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        StringBuilder builder = new StringBuilder(name);
155971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(type);
156971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(server);
157971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(saveLogin ? username : "");
158971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(saveLogin ? password : "");
159971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(dnsServers);
160971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(searchDomains);
161971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(routes);
162971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(mppe);
163971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(l2tpSecret);
164971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecIdentifier);
165971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecSecret);
166971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecUserCert);
167971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecCaCert);
168971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey        builder.append('\0').append(ipsecServerCert);
169d396a448b2e36e29598c954b64bfddef73f3fae0Elliott Hughes        return builder.toString().getBytes(StandardCharsets.UTF_8);
170971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey    }
17182f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey
17269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    /**
17316dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He     * Tests if profile is valid for lockdown, which requires IPv4 address for
17469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     * both server and DNS. Server hostnames would require using DNS before
17569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     * connection.
17669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     */
17769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    public boolean isValidLockdownProfile() {
17816dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He        return isTypeValidForLockdown()
17916dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He                && isServerAddressNumeric()
18016dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He                && hasDns()
18116dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He                && areDnsAddressesNumeric();
18216dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    }
18316dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He
18416dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    /** Returns {@code true} if the VPN type is valid for lockdown. */
18516dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    public boolean isTypeValidForLockdown() {
18616dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He        // b/7064069: lockdown firewall blocks ports used for PPTP
18716dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He        return type != TYPE_PPTP;
18816dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    }
189bae6d820d2227754bcaa341621d270ba39b59820Robin Lee
19016dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    /** Returns {@code true} if the server address is numeric, e.g. 8.8.8.8 */
19116dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    public boolean isServerAddressNumeric() {
19269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        try {
19369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            InetAddress.parseNumericAddress(server);
19416dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He        } catch (IllegalArgumentException e) {
19516dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He            return false;
19616dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He        }
19716dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He        return true;
19816dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    }
19969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
20016dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    /** Returns {@code true} if one or more DNS servers are specified. */
20116dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    public boolean hasDns() {
20216dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He        return !TextUtils.isEmpty(dnsServers);
20316dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    }
20416dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He
20516dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    /**
20616dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He     * Returns {@code true} if all DNS servers have numeric addresses,
20716dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He     * e.g. 8.8.8.8
20816dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He     */
20916dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He    public boolean areDnsAddressesNumeric() {
21016dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He        try {
21169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            for (String dnsServer : dnsServers.split(" +")) {
21216dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He                InetAddress.parseNumericAddress(dnsServer);
21369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            }
21469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        } catch (IllegalArgumentException e) {
21569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            return false;
21669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
21716dd8500b6d9e8dd64af1879d1fd8a4c1360d34bCharles He        return true;
21869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    }
21969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
22082f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    public static final Creator<VpnProfile> CREATOR = new Creator<VpnProfile>() {
22182f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        @Override
22282f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        public VpnProfile createFromParcel(Parcel in) {
2236e7aa77565553e487a1e14478d9c30f512156232Jeff Sharkey            return new VpnProfile(in);
22482f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        }
22582f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey
22682f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        @Override
22782f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        public VpnProfile[] newArray(int size) {
22882f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey            return new VpnProfile[size];
22982f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        }
23082f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    };
23182f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey
23282f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    @Override
23382f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    public int describeContents() {
23482f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        return 0;
23582f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    }
236971a3cfa51b89aa0f3ab47ee082f05586a1f16f0Jeff Sharkey}
237