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