1 /* 2 * Copyright (C) 2018 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.server.wifi; 18 19 import android.annotation.Nullable; 20 import android.net.InetAddresses; 21 import android.net.IpConfiguration; 22 import android.net.IpConfiguration.IpAssignment; 23 import android.net.IpConfiguration.ProxySettings; 24 import android.net.LinkAddress; 25 import android.net.ProxyInfo; 26 import android.net.RouteInfo; 27 import android.net.StaticIpConfiguration; 28 import android.net.Uri; 29 import android.net.wifi.WifiConfiguration; 30 import android.util.Log; 31 import android.util.Pair; 32 33 import com.android.server.wifi.util.XmlUtil; 34 import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil; 35 import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil; 36 37 import org.xmlpull.v1.XmlPullParser; 38 import org.xmlpull.v1.XmlPullParserException; 39 40 import java.io.IOException; 41 import java.net.Inet4Address; 42 import java.net.InetAddress; 43 import java.util.ArrayList; 44 import java.util.Arrays; 45 import java.util.BitSet; 46 import java.util.Collections; 47 import java.util.HashSet; 48 import java.util.List; 49 import java.util.Locale; 50 import java.util.Set; 51 52 /** 53 * Parser for major version 1 of WiFi backup data. 54 * Contains whitelists of tags for WifiConfiguration and IpConfiguration sections for each of 55 * the minor versions. 56 * 57 * Overall structure of the major version 1 XML schema: 58 * <?xml version='1.0' encoding='utf-8' standalone='yes' ?> 59 * <WifiConfigStore> 60 * <float name="Version" value="1.0" /> 61 * <NetworkList> 62 * <Network> 63 * <WifiConfiguration> 64 * <string name="ConfigKey">value</string> 65 * <string name="SSID">value</string> 66 * <string name="PreSharedKey" />value</string> 67 * <string-array name="WEPKeys" num="4"> 68 * <item value="WifiConfigStoreWep1" /> 69 * <item value="WifiConfigStoreWep2" /> 70 * <item value="WifiConfigStoreWep3" /> 71 * <item value="WifiConfigStoreWep3" /> 72 * </string-array> 73 * ... (other supported tag names in minor version 1: "WEPTxKeyIndex", "HiddenSSID", 74 * "RequirePMF", "AllowedKeyMgmt", "AllowedProtocols", "AllowedAuthAlgos", 75 * "AllowedGroupCiphers", "AllowedPairwiseCiphers", "Shared") 76 * </WifiConfiguration> 77 * <IpConfiguration> 78 * <string name="IpAssignment">value</string> 79 * <string name="ProxySettings">value</string> 80 * ... (other supported tag names in minor version 1: "LinkAddress", "LinkPrefixLength", 81 * "GatewayAddress", "DNSServers", "ProxyHost", "ProxyPort", "ProxyPac", 82 * "ProxyExclusionList") 83 * </IpConfiguration> 84 * </Network> 85 * <Network> 86 * ... (format as above) 87 * </Network> 88 * </NetworkList> 89 * </WifiConfigStore> 90 */ 91 class WifiBackupDataV1Parser implements WifiBackupDataParser { 92 93 private static final String TAG = "WifiBackupDataV1Parser"; 94 95 private static final int HIGHEST_SUPPORTED_MINOR_VERSION = 2; 96 97 // List of tags supported for <WifiConfiguration> section in minor version 0 98 private static final Set<String> WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS = 99 new HashSet<String>(Arrays.asList(new String[] { 100 WifiConfigurationXmlUtil.XML_TAG_CONFIG_KEY, 101 WifiConfigurationXmlUtil.XML_TAG_SSID, 102 WifiConfigurationXmlUtil.XML_TAG_PRE_SHARED_KEY, 103 WifiConfigurationXmlUtil.XML_TAG_WEP_KEYS, 104 WifiConfigurationXmlUtil.XML_TAG_WEP_TX_KEY_INDEX, 105 WifiConfigurationXmlUtil.XML_TAG_HIDDEN_SSID, 106 WifiConfigurationXmlUtil.XML_TAG_REQUIRE_PMF, 107 WifiConfigurationXmlUtil.XML_TAG_ALLOWED_KEY_MGMT, 108 WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PROTOCOLS, 109 WifiConfigurationXmlUtil.XML_TAG_ALLOWED_AUTH_ALGOS, 110 WifiConfigurationXmlUtil.XML_TAG_ALLOWED_GROUP_CIPHERS, 111 WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PAIRWISE_CIPHERS, 112 WifiConfigurationXmlUtil.XML_TAG_SHARED, 113 })); 114 115 // List of tags supported for <WifiConfiguration> section in minor version 1 116 private static final Set<String> WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS = 117 new HashSet<String>() {{ 118 addAll(WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS); 119 add(WifiConfigurationXmlUtil.XML_TAG_METERED_OVERRIDE); 120 }}; 121 122 // List of tags supported for <WifiConfiguration> section in minor version 2 123 private static final Set<String> WIFI_CONFIGURATION_MINOR_V2_SUPPORTED_TAGS = 124 new HashSet<String>() {{ 125 addAll(WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS); 126 add(WifiConfigurationXmlUtil.XML_TAG_IS_AUTO_JOIN); 127 }}; 128 129 // List of tags supported for <IpConfiguration> section in minor version 0 to 2 130 private static final Set<String> IP_CONFIGURATION_MINOR_V0_V1_V2_SUPPORTED_TAGS = 131 new HashSet<String>(Arrays.asList(new String[] { 132 IpConfigurationXmlUtil.XML_TAG_IP_ASSIGNMENT, 133 IpConfigurationXmlUtil.XML_TAG_LINK_ADDRESS, 134 IpConfigurationXmlUtil.XML_TAG_LINK_PREFIX_LENGTH, 135 IpConfigurationXmlUtil.XML_TAG_GATEWAY_ADDRESS, 136 IpConfigurationXmlUtil.XML_TAG_DNS_SERVER_ADDRESSES, 137 IpConfigurationXmlUtil.XML_TAG_PROXY_SETTINGS, 138 IpConfigurationXmlUtil.XML_TAG_PROXY_HOST, 139 IpConfigurationXmlUtil.XML_TAG_PROXY_PORT, 140 IpConfigurationXmlUtil.XML_TAG_PROXY_EXCLUSION_LIST, 141 IpConfigurationXmlUtil.XML_TAG_PROXY_PAC_FILE, 142 })); 143 144 @Override parseNetworkConfigurationsFromXml(XmlPullParser in, int outerTagDepth, int minorVersion)145 public List<WifiConfiguration> parseNetworkConfigurationsFromXml(XmlPullParser in, 146 int outerTagDepth, int minorVersion) throws XmlPullParserException, IOException { 147 // clamp down the minorVersion to the highest one that this parser version supports 148 if (minorVersion > HIGHEST_SUPPORTED_MINOR_VERSION) { 149 minorVersion = HIGHEST_SUPPORTED_MINOR_VERSION; 150 } 151 // Find the configuration list section. 152 XmlUtil.gotoNextSectionWithName(in, WifiBackupRestore.XML_TAG_SECTION_HEADER_NETWORK_LIST, 153 outerTagDepth); 154 // Find all the configurations within the configuration list section. 155 int networkListTagDepth = outerTagDepth + 1; 156 List<WifiConfiguration> configurations = new ArrayList<>(); 157 while (XmlUtil.gotoNextSectionWithNameOrEnd( 158 in, WifiBackupRestore.XML_TAG_SECTION_HEADER_NETWORK, networkListTagDepth)) { 159 WifiConfiguration configuration = 160 parseNetworkConfigurationFromXml(in, minorVersion, networkListTagDepth); 161 if (configuration != null) { 162 Log.v(TAG, "Parsed Configuration: " + configuration.getKey()); 163 configurations.add(configuration); 164 } 165 } 166 return configurations; 167 } 168 169 @Override getHighestSupportedMinorVersion()170 public int getHighestSupportedMinorVersion() { 171 return HIGHEST_SUPPORTED_MINOR_VERSION; 172 } 173 174 /** 175 * Parses the configuration data elements from the provided XML stream to a Configuration. 176 * 177 * @param in XmlPullParser instance pointing to the XML stream. 178 * @param minorVersion minor version number parsed from incoming data. 179 * @param outerTagDepth depth of the outer tag in the XML document. 180 * @return WifiConfiguration object if parsing is successful, null otherwise. 181 */ parseNetworkConfigurationFromXml(XmlPullParser in, int minorVersion, int outerTagDepth)182 private WifiConfiguration parseNetworkConfigurationFromXml(XmlPullParser in, int minorVersion, 183 int outerTagDepth) throws XmlPullParserException, IOException { 184 WifiConfiguration configuration = null; 185 int networkTagDepth = outerTagDepth + 1; 186 // Retrieve WifiConfiguration object first. 187 XmlUtil.gotoNextSectionWithName( 188 in, WifiBackupRestore.XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION, 189 networkTagDepth); 190 int configTagDepth = networkTagDepth + 1; 191 configuration = parseWifiConfigurationFromXml(in, configTagDepth, minorVersion); 192 if (configuration == null) { 193 return null; 194 } 195 // Now retrieve any IP configuration info. 196 XmlUtil.gotoNextSectionWithName( 197 in, WifiBackupRestore.XML_TAG_SECTION_HEADER_IP_CONFIGURATION, networkTagDepth); 198 IpConfiguration ipConfiguration = parseIpConfigurationFromXml(in, configTagDepth, 199 minorVersion); 200 configuration.setIpConfiguration(ipConfiguration); 201 return configuration; 202 } 203 204 /** 205 * Helper method to parse the WifiConfiguration object. 206 */ parseWifiConfigurationFromXml(XmlPullParser in, int outerTagDepth, int minorVersion)207 private WifiConfiguration parseWifiConfigurationFromXml(XmlPullParser in, 208 int outerTagDepth, int minorVersion) throws XmlPullParserException, IOException { 209 Pair<String, WifiConfiguration> parsedConfig = 210 parseWifiConfigurationFromXmlInternal(in, outerTagDepth, minorVersion); 211 if (parsedConfig == null || parsedConfig.first == null || parsedConfig.second == null) { 212 return null; 213 } 214 String configKeyParsed = parsedConfig.first; 215 WifiConfiguration configuration = parsedConfig.second; 216 String configKeyCalculated = configuration.getKey(); 217 if (!configKeyParsed.equals(configKeyCalculated)) { 218 // configKey is not part of the SDK. So, we can't expect this to be the same 219 // across OEM's. Just log a warning & continue. 220 Log.w(TAG, "Configuration key does not match. Retrieved: " + configKeyParsed 221 + ", Calculated: " + configKeyCalculated); 222 } 223 return configuration; 224 } 225 226 /** 227 * Helper method to mask out any invalid data in parsed WifiConfiguration. 228 * 229 * This is a compatibility layer added to the parsing logic to try and weed out any known 230 * issues in the backup data format from other OEM's. 231 */ clearAnyKnownIssuesInParsedConfiguration(WifiConfiguration config)232 private static void clearAnyKnownIssuesInParsedConfiguration(WifiConfiguration config) { 233 /** 234 * Fix for b/73987207. Clear any invalid bits in the bitsets. 235 */ 236 // |allowedKeyManagement| 237 if (config.allowedKeyManagement.length() 238 > WifiConfiguration.KeyMgmt.strings.length) { 239 config.allowedKeyManagement.clear( 240 WifiConfiguration.KeyMgmt.strings.length, 241 config.allowedKeyManagement.length()); 242 } 243 // |allowedProtocols| 244 if (config.allowedProtocols.length() 245 > WifiConfiguration.Protocol.strings.length) { 246 config.allowedProtocols.clear( 247 WifiConfiguration.Protocol.strings.length, 248 config.allowedProtocols.length()); 249 } 250 // |allowedAuthAlgorithms| 251 if (config.allowedAuthAlgorithms.length() 252 > WifiConfiguration.AuthAlgorithm.strings.length) { 253 config.allowedAuthAlgorithms.clear( 254 WifiConfiguration.AuthAlgorithm.strings.length, 255 config.allowedAuthAlgorithms.length()); 256 } 257 // |allowedGroupCiphers| 258 if (config.allowedGroupCiphers.length() 259 > WifiConfiguration.GroupCipher.strings.length) { 260 config.allowedGroupCiphers.clear( 261 WifiConfiguration.GroupCipher.strings.length, 262 config.allowedGroupCiphers.length()); 263 } 264 // |allowedPairwiseCiphers| 265 if (config.allowedPairwiseCiphers.length() 266 > WifiConfiguration.PairwiseCipher.strings.length) { 267 config.allowedPairwiseCiphers.clear( 268 WifiConfiguration.PairwiseCipher.strings.length, 269 config.allowedPairwiseCiphers.length()); 270 } 271 // Add any other fixable issues discovered from other OEM's here. 272 } 273 274 /** 275 * Parses the configuration data elements from the provided XML stream to a 276 * WifiConfiguration object. 277 * Looping through the tags makes it easy to add elements in the future minor versions if 278 * needed. Unsupported elements will be ignored. 279 * 280 * @param in XmlPullParser instance pointing to the XML stream. 281 * @param outerTagDepth depth of the outer tag in the XML document. 282 * @param minorVersion minor version number parsed from incoming data. 283 * @return Pair<Config key, WifiConfiguration object> if parsing is successful, null otherwise. 284 */ parseWifiConfigurationFromXmlInternal( XmlPullParser in, int outerTagDepth, int minorVersion)285 private static Pair<String, WifiConfiguration> parseWifiConfigurationFromXmlInternal( 286 XmlPullParser in, int outerTagDepth, int minorVersion) 287 throws XmlPullParserException, IOException { 288 WifiConfiguration configuration = new WifiConfiguration(); 289 String configKeyInData = null; 290 Set<String> supportedTags = getSupportedWifiConfigurationTags(minorVersion); 291 292 // Loop through and parse out all the elements from the stream within this section. 293 while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) { 294 String[] valueName = new String[1]; 295 Object value = XmlUtil.readCurrentValue(in, valueName); 296 String tagName = valueName[0]; 297 if (tagName == null) { 298 throw new XmlPullParserException("Missing value name"); 299 } 300 301 // ignore the tags that are not supported up until the current minor version 302 if (!supportedTags.contains(tagName)) { 303 Log.w(TAG, "Unsupported tag + \"" + tagName + "\" found in <WifiConfiguration>" 304 + " section, ignoring."); 305 continue; 306 } 307 308 // note: the below switch case list should contain all tags supported up until the 309 // highest minor version supported by this parser 310 switch (tagName) { 311 case WifiConfigurationXmlUtil.XML_TAG_CONFIG_KEY: 312 configKeyInData = (String) value; 313 break; 314 case WifiConfigurationXmlUtil.XML_TAG_SSID: 315 configuration.SSID = (String) value; 316 break; 317 case WifiConfigurationXmlUtil.XML_TAG_PRE_SHARED_KEY: 318 configuration.preSharedKey = (String) value; 319 break; 320 case WifiConfigurationXmlUtil.XML_TAG_WEP_KEYS: 321 populateWepKeysFromXmlValue(value, configuration.wepKeys); 322 break; 323 case WifiConfigurationXmlUtil.XML_TAG_WEP_TX_KEY_INDEX: 324 configuration.wepTxKeyIndex = (int) value; 325 break; 326 case WifiConfigurationXmlUtil.XML_TAG_HIDDEN_SSID: 327 configuration.hiddenSSID = (boolean) value; 328 break; 329 case WifiConfigurationXmlUtil.XML_TAG_REQUIRE_PMF: 330 configuration.requirePmf = (boolean) value; 331 break; 332 case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_KEY_MGMT: 333 byte[] allowedKeyMgmt = (byte[]) value; 334 configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt); 335 break; 336 case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PROTOCOLS: 337 byte[] allowedProtocols = (byte[]) value; 338 configuration.allowedProtocols = BitSet.valueOf(allowedProtocols); 339 break; 340 case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_AUTH_ALGOS: 341 byte[] allowedAuthAlgorithms = (byte[]) value; 342 configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms); 343 break; 344 case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_GROUP_CIPHERS: 345 byte[] allowedGroupCiphers = (byte[]) value; 346 configuration.allowedGroupCiphers = BitSet.valueOf(allowedGroupCiphers); 347 break; 348 case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PAIRWISE_CIPHERS: 349 byte[] allowedPairwiseCiphers = (byte[]) value; 350 configuration.allowedPairwiseCiphers = 351 BitSet.valueOf(allowedPairwiseCiphers); 352 break; 353 case WifiConfigurationXmlUtil.XML_TAG_SHARED: 354 configuration.shared = (boolean) value; 355 break; 356 case WifiConfigurationXmlUtil.XML_TAG_METERED_OVERRIDE: 357 configuration.meteredOverride = (int) value; 358 break; 359 case WifiConfigurationXmlUtil.XML_TAG_IS_AUTO_JOIN: 360 configuration.allowAutojoin = (boolean) value; 361 break; 362 default: 363 // should never happen, since other tags are filtered out earlier 364 throw new XmlPullParserException( 365 "Unknown value name found: " + valueName[0]); 366 } 367 } 368 clearAnyKnownIssuesInParsedConfiguration(configuration); 369 return Pair.create(configKeyInData, configuration); 370 } 371 372 /** 373 * Returns a set of supported tags of <WifiConfiguration> element for all minor versions of 374 * this major version up to and including the specified minorVersion (only adding tags is 375 * supported in minor versions, removal or changing the meaning of tags requires bumping 376 * the major version and reseting the minor to 0). 377 * 378 * @param minorVersion minor version number parsed from incoming data. 379 */ getSupportedWifiConfigurationTags(int minorVersion)380 private static Set<String> getSupportedWifiConfigurationTags(int minorVersion) { 381 switch (minorVersion) { 382 case 0: 383 return WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS; 384 case 1: 385 return WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS; 386 case 2: 387 return WIFI_CONFIGURATION_MINOR_V2_SUPPORTED_TAGS; 388 default: 389 Log.e(TAG, "Invalid minorVersion: " + minorVersion); 390 return Collections.<String>emptySet(); 391 } 392 } 393 394 /** 395 * Populate wepKeys array elements only if they were non-empty in the backup data. 396 * 397 * @throws XmlPullParserException if parsing errors occur. 398 */ populateWepKeysFromXmlValue(Object value, String[] wepKeys)399 private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys) 400 throws XmlPullParserException, IOException { 401 String[] wepKeysInData = (String[]) value; 402 if (wepKeysInData == null) { 403 return; 404 } 405 if (wepKeysInData.length != wepKeys.length) { 406 throw new XmlPullParserException( 407 "Invalid Wep Keys length: " + wepKeysInData.length); 408 } 409 for (int i = 0; i < wepKeys.length; i++) { 410 if (wepKeysInData[i].isEmpty()) { 411 wepKeys[i] = null; 412 } else { 413 wepKeys[i] = wepKeysInData[i]; 414 } 415 } 416 } 417 parseProxyExclusionListString( @ullable String exclusionListString)418 private static List<String> parseProxyExclusionListString( 419 @Nullable String exclusionListString) { 420 if (exclusionListString == null) { 421 return Collections.emptyList(); 422 } else { 423 return Arrays.asList(exclusionListString.toLowerCase(Locale.ROOT).split(",")); 424 } 425 } 426 427 /** 428 * Parses the IP configuration data elements from the provided XML stream to an 429 * IpConfiguration object. 430 * 431 * @param in XmlPullParser instance pointing to the XML stream. 432 * @param outerTagDepth depth of the outer tag in the XML document. 433 * @param minorVersion minor version number parsed from incoming data. 434 * @return IpConfiguration object if parsing is successful, null otherwise. 435 */ parseIpConfigurationFromXml(XmlPullParser in, int outerTagDepth, int minorVersion)436 private static IpConfiguration parseIpConfigurationFromXml(XmlPullParser in, 437 int outerTagDepth, int minorVersion) throws XmlPullParserException, IOException { 438 // First parse *all* of the tags in <IpConfiguration> section 439 Set<String> supportedTags = getSupportedIpConfigurationTags(minorVersion); 440 441 String ipAssignmentString = null; 442 String linkAddressString = null; 443 Integer linkPrefixLength = null; 444 String gatewayAddressString = null; 445 String[] dnsServerAddressesString = null; 446 String proxySettingsString = null; 447 String proxyHost = null; 448 int proxyPort = -1; 449 String proxyExclusionList = null; 450 String proxyPacFile = null; 451 452 // Loop through and parse out all the elements from the stream within this section. 453 while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) { 454 String[] valueName = new String[1]; 455 Object value = XmlUtil.readCurrentValue(in, valueName); 456 String tagName = valueName[0]; 457 if (tagName == null) { 458 throw new XmlPullParserException("Missing value name"); 459 } 460 461 // ignore the tags that are not supported up until the current minor version 462 if (!supportedTags.contains(tagName)) { 463 Log.w(TAG, "Unsupported tag + \"" + tagName + "\" found in <IpConfiguration>" 464 + " section, ignoring."); 465 continue; 466 } 467 468 // note: the below switch case list should contain all tags supported up until the 469 // highest minor version supported by this parser 470 // should any tags be added in next minor versions, conditional processing of them 471 // also needs to be added in the below code (processing into IpConfiguration object) 472 switch (tagName) { 473 case IpConfigurationXmlUtil.XML_TAG_IP_ASSIGNMENT: 474 ipAssignmentString = (String) value; 475 break; 476 case IpConfigurationXmlUtil.XML_TAG_LINK_ADDRESS: 477 linkAddressString = (String) value; 478 break; 479 case IpConfigurationXmlUtil.XML_TAG_LINK_PREFIX_LENGTH: 480 linkPrefixLength = (Integer) value; 481 break; 482 case IpConfigurationXmlUtil.XML_TAG_GATEWAY_ADDRESS: 483 gatewayAddressString = (String) value; 484 break; 485 case IpConfigurationXmlUtil.XML_TAG_DNS_SERVER_ADDRESSES: 486 dnsServerAddressesString = (String[]) value; 487 break; 488 case IpConfigurationXmlUtil.XML_TAG_PROXY_SETTINGS: 489 proxySettingsString = (String) value; 490 break; 491 case IpConfigurationXmlUtil.XML_TAG_PROXY_HOST: 492 proxyHost = (String) value; 493 break; 494 case IpConfigurationXmlUtil.XML_TAG_PROXY_PORT: 495 proxyPort = (int) value; 496 break; 497 case IpConfigurationXmlUtil.XML_TAG_PROXY_EXCLUSION_LIST: 498 proxyExclusionList = (String) value; 499 break; 500 case IpConfigurationXmlUtil.XML_TAG_PROXY_PAC_FILE: 501 proxyPacFile = (String) value; 502 break; 503 default: 504 // should never happen, since other tags are filtered out earlier 505 throw new XmlPullParserException( 506 "Unknown value name found: " + valueName[0]); 507 } 508 } 509 510 // Now process the values into IpConfiguration object 511 IpConfiguration ipConfiguration = new IpConfiguration(); 512 if (ipAssignmentString == null) { 513 throw new XmlPullParserException("IpAssignment was missing in IpConfiguration section"); 514 } 515 IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString); 516 ipConfiguration.setIpAssignment(ipAssignment); 517 switch (ipAssignment) { 518 case STATIC: 519 StaticIpConfiguration.Builder builder = new StaticIpConfiguration.Builder(); 520 if (linkAddressString != null && linkPrefixLength != null) { 521 LinkAddress linkAddress = new LinkAddress( 522 InetAddresses.parseNumericAddress(linkAddressString), linkPrefixLength); 523 if (linkAddress.getAddress() instanceof Inet4Address) { 524 builder.setIpAddress(linkAddress); 525 } else { 526 Log.w(TAG, "Non-IPv4 address: " + linkAddress); 527 } 528 } 529 if (gatewayAddressString != null) { 530 InetAddress gateway = InetAddresses.parseNumericAddress(gatewayAddressString); 531 RouteInfo route = new RouteInfo(null, gateway, null, RouteInfo.RTN_UNICAST); 532 if (route.isDefaultRoute() 533 && route.getDestination().getAddress() instanceof Inet4Address) { 534 builder.setGateway(gateway); 535 } else { 536 Log.w(TAG, "Non-IPv4 default route: " + route); 537 } 538 } 539 if (dnsServerAddressesString != null) { 540 List<InetAddress> dnsServerAddresses = new ArrayList<>(); 541 for (String dnsServerAddressString : dnsServerAddressesString) { 542 InetAddress dnsServerAddress = 543 InetAddresses.parseNumericAddress(dnsServerAddressString); 544 dnsServerAddresses.add(dnsServerAddress); 545 } 546 builder.setDnsServers(dnsServerAddresses); 547 } 548 ipConfiguration.setStaticIpConfiguration(builder.build()); 549 break; 550 case DHCP: 551 case UNASSIGNED: 552 break; 553 default: 554 throw new XmlPullParserException("Unknown ip assignment type: " + ipAssignment); 555 } 556 557 // Process the proxy settings next 558 if (proxySettingsString == null) { 559 throw new XmlPullParserException("ProxySettings was missing in" 560 + " IpConfiguration section"); 561 } 562 ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString); 563 ipConfiguration.setProxySettings(proxySettings); 564 switch (proxySettings) { 565 case STATIC: 566 if (proxyHost == null) { 567 throw new XmlPullParserException("ProxyHost was missing in" 568 + " IpConfiguration section"); 569 } 570 if (proxyPort == -1) { 571 throw new XmlPullParserException("ProxyPort was missing in" 572 + " IpConfiguration section"); 573 } 574 if (proxyExclusionList == null) { 575 throw new XmlPullParserException("ProxyExclusionList was missing in" 576 + " IpConfiguration section"); 577 } 578 ipConfiguration.setHttpProxy( 579 ProxyInfo.buildDirectProxy( 580 proxyHost, proxyPort, 581 parseProxyExclusionListString(proxyExclusionList))); 582 break; 583 case PAC: 584 if (proxyPacFile == null) { 585 throw new XmlPullParserException("ProxyPac was missing in" 586 + " IpConfiguration section"); 587 } 588 ipConfiguration.setHttpProxy( 589 ProxyInfo.buildPacProxy(Uri.parse(proxyPacFile))); 590 break; 591 case NONE: 592 case UNASSIGNED: 593 break; 594 default: 595 throw new XmlPullParserException( 596 "Unknown proxy settings type: " + proxySettings); 597 } 598 599 return ipConfiguration; 600 } 601 602 /** 603 * Returns a set of supported tags of <IpConfiguration> element for all minor versions of 604 * this major version up to and including the specified minorVersion (only adding tags is 605 * supported in minor versions, removal or changing the meaning of tags requires bumping 606 * the major version and reseting the minor to 0). 607 * 608 * @param minorVersion minor version number parsed from incoming data. 609 */ getSupportedIpConfigurationTags(int minorVersion)610 private static Set<String> getSupportedIpConfigurationTags(int minorVersion) { 611 switch (minorVersion) { 612 case 0: 613 case 1: 614 case 2: 615 return IP_CONFIGURATION_MINOR_V0_V1_V2_SUPPORTED_TAGS; 616 default: 617 Log.e(TAG, "Invalid minorVersion: " + minorVersion); 618 return Collections.<String>emptySet(); 619 } 620 } 621 } 622