AccessPointParserHelper.java revision a42a1e6b6fb6acc9ca327523ae456e464f8aedc1
1/* 2 * Copyright (C) 2010, 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 17package com.android.connectivitymanagertest; 18 19import javax.xml.parsers.SAXParser; 20import javax.xml.parsers.SAXParserFactory; 21 22import org.xml.sax.Attributes; 23import org.xml.sax.SAXException; 24import org.xml.sax.helpers.DefaultHandler; 25 26import android.net.wifi.WifiConfiguration; 27import android.net.wifi.WifiConfiguration.AuthAlgorithm; 28import android.net.wifi.WifiConfiguration.IpAssignment; 29import android.net.wifi.WifiConfiguration.KeyMgmt; 30import android.net.wifi.WifiConfiguration.ProxySettings; 31import android.net.LinkAddress; 32import android.net.LinkProperties; 33import android.util.Log; 34 35import java.io.InputStream; 36import java.net.InetAddress; 37import java.net.UnknownHostException; 38import java.util.ArrayList; 39import java.util.HashMap; 40import java.util.List; 41 42 43/** 44 * Help class to process configurations of access points saved in an XML file. 45 * The configurations of an access point is included in tag 46 * <accesspoint></accesspoint>. The supported configuration includes: ssid, 47 * security, eap, phase2, identity, password, anonymousidentity, cacert, usercert, 48 * in which each is included in the corresponding tags. Static IP setting is also supported. 49 * Tags that can be used include: ip, gateway, netmask, dns1, dns2. All access points have to be 50 * enclosed in tags of <resources></resources>. 51 * 52 * The following is a sample configuration file for an access point using EAP-PEAP with MSCHAP2. 53 * <resources> 54 * <accesspoint> 55 * <ssid>testnet</ssid> 56 * <security>EAP</security> 57 * <eap>PEAP</eap> 58 * <phase2>MSCHAP2</phase2> 59 * <identity>donut</identity</identity> 60 * <password>abcdefgh</password> 61 * </accesspoint> 62 * </resources> 63 * 64 * Note:ssid and security have to be the first two tags 65 * for static ip setting, tag "ip" should be listed before other fields: dns, gateway, netmask. 66 */ 67public class AccessPointParserHelper { 68 private static final String KEYSTORE_SPACE = "keystore://"; 69 private static final String TAG = "AccessPointParserHelper"; 70 static final int NONE = 0; 71 static final int WEP = 1; 72 static final int PSK = 2; 73 static final int EAP = 3; 74 75 List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>(); 76 77 private int getSecurityType (String security) { 78 if (security.equalsIgnoreCase("NONE")) { 79 return NONE; 80 } else if (security.equalsIgnoreCase("WEP")) { 81 return WEP; 82 } else if (security.equalsIgnoreCase("PSK")) { 83 return PSK; 84 } else if (security.equalsIgnoreCase("EAP")) { 85 return EAP; 86 } else { 87 return -1; 88 } 89 } 90 91 private boolean validateEapValue(String value) { 92 if (value.equalsIgnoreCase("PEAP") || 93 value.equalsIgnoreCase("TLS") || 94 value.equalsIgnoreCase("TTLS")) { 95 return true; 96 } else { 97 return false; 98 } 99 } 100 101 DefaultHandler mHandler = new DefaultHandler() { 102 103 boolean ssid = false; 104 boolean security = false; 105 boolean password = false; 106 boolean ip = false; 107 boolean gateway = false; 108 boolean networkprefix = false; 109 boolean netmask = false; 110 boolean dns1 = false; 111 boolean dns2 = false; 112 boolean eap = false; 113 boolean phase2 = false; 114 boolean identity = false; 115 boolean anonymousidentity = false; 116 boolean cacert = false; 117 boolean usercert = false; 118 WifiConfiguration config = null; 119 int securityType = NONE; 120 LinkProperties mLinkProperties = null; 121 InetAddress mInetAddr = null; 122 123 @Override 124 public void startElement(String uri, String localName, String tagName, 125 Attributes attributes) throws SAXException { 126 if (tagName.equalsIgnoreCase("accesspoint")) { 127 config = new WifiConfiguration(); 128 } 129 if (tagName.equalsIgnoreCase("ssid")) { 130 ssid = true; 131 } 132 if (tagName.equalsIgnoreCase("security")) { 133 security = true; 134 } 135 if (tagName.equalsIgnoreCase("password")) { 136 password = true; 137 } 138 if (tagName.equalsIgnoreCase("eap")) { 139 eap = true; 140 } 141 if (tagName.equalsIgnoreCase("phase2")) { 142 phase2 = true; 143 } 144 if (tagName.equalsIgnoreCase("identity")) { 145 identity = true; 146 } 147 if (tagName.equalsIgnoreCase("anonymousidentity")) { 148 anonymousidentity = true; 149 } 150 if (tagName.equalsIgnoreCase("cacert")) { 151 cacert = true; 152 } 153 if (tagName.equalsIgnoreCase("usercert")) { 154 usercert = true; 155 } 156 if (tagName.equalsIgnoreCase("ip")) { 157 mLinkProperties = new LinkProperties(); 158 ip = true; 159 } 160 if (tagName.equalsIgnoreCase("gateway")) { 161 gateway = true; 162 } 163 if (tagName.equalsIgnoreCase("networkprefixlength")) { 164 networkprefix = true; 165 } 166 if (tagName.equalsIgnoreCase("netmask")) { 167 netmask = true; 168 } 169 if (tagName.equalsIgnoreCase("dns1")) { 170 dns1 = true; 171 } 172 if (tagName.equalsIgnoreCase("dns2")) { 173 dns2 = true; 174 } 175 } 176 177 @Override 178 public void endElement(String uri, String localName, String tagName) throws SAXException { 179 if (tagName.equalsIgnoreCase("accesspoint")) { 180 if (mLinkProperties != null) { 181 config.ipAssignment = IpAssignment.STATIC; 182 config.linkProperties = mLinkProperties; 183 } else { 184 config.ipAssignment = IpAssignment.DHCP; 185 } 186 config.proxySettings = ProxySettings.NONE; 187 networks.add(config); 188 } 189 } 190 191 @Override 192 public void characters(char ch[], int start, int length) throws SAXException { 193 if (ssid) { 194 config.SSID = new String(ch, start, length); 195 ssid = false; 196 } 197 if (security) { 198 String securityStr = (new String(ch, start, length)).toUpperCase(); 199 securityType = getSecurityType(securityStr); 200 switch (securityType) { 201 case NONE: 202 config.allowedKeyManagement.set(KeyMgmt.NONE); 203 break; 204 case WEP: 205 config.allowedKeyManagement.set(KeyMgmt.NONE); 206 config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); 207 config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED); 208 break; 209 case PSK: 210 config.allowedKeyManagement.set(KeyMgmt.WPA_PSK); 211 break; 212 case EAP: 213 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); 214 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 215 // Initialize other fields. 216 config.phase2.setValue(""); 217 config.ca_cert.setValue(""); 218 config.client_cert.setValue(""); 219 config.private_key.setValue(""); 220 config.identity.setValue(""); 221 config.anonymous_identity.setValue(""); 222 break; 223 default: 224 throw new SAXException(); 225 } 226 security = false; 227 } 228 if (password) { 229 String passwordStr = new String(ch, start, length); 230 int len = passwordStr.length(); 231 if (len == 0) { 232 throw new SAXException(); 233 } 234 if (securityType == WEP) { 235 if ((len == 10 || len == 26 || len == 58) && 236 passwordStr.matches("[0-9A-Fa-f]*")) { 237 config.wepKeys[0] = passwordStr; 238 } else { 239 config.wepKeys[0] = '"' + passwordStr + '"'; 240 } 241 } else if (securityType == PSK) { 242 if (passwordStr.matches("[0-9A-Fa-f]{64}")) { 243 config.preSharedKey = passwordStr; 244 } else { 245 config.preSharedKey = '"' + passwordStr + '"'; 246 } 247 } else if (securityType == EAP) { 248 config.password.setValue(passwordStr); 249 } else { 250 throw new SAXException(); 251 } 252 password = false; 253 } 254 if (eap) { 255 String eapValue = new String(ch, start, length); 256 if (!validateEapValue(eapValue)) { 257 throw new SAXException(); 258 } 259 config.eap.setValue(eapValue); 260 eap = false; 261 } 262 if (phase2) { 263 String phase2Value = new String(ch, start, length); 264 config.phase2.setValue("auth=" + phase2Value); 265 phase2 = false; 266 } 267 if (identity) { 268 String identityValue = new String(ch, start, length); 269 config.identity.setValue(identityValue); 270 identity = false; 271 } 272 if (anonymousidentity) { 273 String anonyId = new String(ch, start, length); 274 config.anonymous_identity.setValue(anonyId); 275 anonymousidentity = false; 276 } 277 if (cacert) { 278 String cacertValue = new String(ch, start, length); 279 // need to install the credentail to "keystore://" 280 config.ca_cert.setValue(KEYSTORE_SPACE); 281 cacert = false; 282 } 283 if (usercert) { 284 String usercertValue = new String(ch, start, length); 285 config.client_cert.setValue(KEYSTORE_SPACE); 286 usercert = false; 287 } 288 if (ip) { 289 try { 290 String ipAddr = new String(ch, start, length); 291 if (!InetAddress.isNumeric(ipAddr)) { 292 throw new SAXException(); 293 } 294 mInetAddr = InetAddress.getByName(ipAddr); 295 } catch (UnknownHostException e) { 296 throw new SAXException(); 297 } 298 ip = false; 299 } 300 if (gateway) { 301 try { 302 String gwAddr = new String(ch, start, length); 303 if (!InetAddress.isNumeric(gwAddr)) { 304 throw new SAXException(); 305 } 306 mLinkProperties.setGateway(InetAddress.getByName(gwAddr)); 307 } catch (UnknownHostException e) { 308 throw new SAXException(); 309 } 310 gateway = false; 311 } 312 if (networkprefix) { 313 try { 314 int nwPrefixLength = Integer.parseInt(new String(ch, start, length)); 315 if ((nwPrefixLength < 0) || (nwPrefixLength > 32)) { 316 throw new SAXException(); 317 } 318 mLinkProperties.addLinkAddress(new LinkAddress(mInetAddr, nwPrefixLength)); 319 } catch (NumberFormatException e) { 320 throw new SAXException(); 321 } 322 networkprefix = false; 323 } 324 if (netmask) { 325 try { 326 String netMaskStr = new String(ch, start, length); 327 if (!InetAddress.isNumeric(netMaskStr)) { 328 throw new SAXException(); 329 } 330 InetAddress netMaskAddr = InetAddress.getByName(netMaskStr); 331 mLinkProperties.addLinkAddress(new LinkAddress(mInetAddr, netMaskAddr)); 332 } catch (UnknownHostException e) { 333 throw new SAXException(); 334 } 335 netmask = false; 336 } 337 if (dns1) { 338 try { 339 String dnsAddr = new String(ch, start, length); 340 if (!InetAddress.isNumeric(dnsAddr)) { 341 throw new SAXException(); 342 } 343 mLinkProperties.addDns(InetAddress.getByName(dnsAddr)); 344 } catch (UnknownHostException e) { 345 throw new SAXException(); 346 } 347 dns1 = false; 348 } 349 if (dns2) { 350 try { 351 String dnsAddr = new String(ch, start, length); 352 if (!InetAddress.isNumeric(dnsAddr)) { 353 throw new SAXException(); 354 } 355 mLinkProperties.addDns(InetAddress.getByName(dnsAddr)); 356 } catch (UnknownHostException e) { 357 throw new SAXException(); 358 } 359 dns2 = false; 360 } 361 } 362 }; 363 364 /** 365 * Process the InputStream in 366 * @param in is the InputStream that can be used for XML parsing 367 * @throws Exception 368 */ 369 public AccessPointParserHelper(InputStream in) throws Exception { 370 SAXParserFactory factory = SAXParserFactory.newInstance(); 371 SAXParser saxParser = factory.newSAXParser(); 372 saxParser.parse(in, mHandler); 373 } 374 375 public List<WifiConfiguration> getNetworkConfigurations() throws Exception { 376 return networks; 377 } 378} 379