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