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 36 import java.io.InputStream; 37 import java.net.InetAddress; 38 import java.net.UnknownHostException; 39 import java.util.ArrayList; 40 import 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, networkprefixlength, dns1, dns2. All access points 50 * have to be 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, 66 * networkprefixlength. 67 */ 68 public class AccessPointParserHelper { 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 dns1 = false; 110 boolean dns2 = false; 111 boolean eap = false; 112 boolean phase2 = false; 113 boolean identity = false; 114 boolean anonymousidentity = false; 115 boolean cacert = false; 116 boolean usercert = false; 117 WifiConfiguration config = null; 118 int securityType = NONE; 119 LinkProperties mLinkProperties = null; 120 InetAddress mInetAddr = null; 121 122 @Override 123 public void startElement(String uri, String localName, String tagName, 124 Attributes attributes) throws SAXException { 125 if (tagName.equalsIgnoreCase("accesspoint")) { 126 config = new WifiConfiguration(); 127 } 128 if (tagName.equalsIgnoreCase("ssid")) { 129 ssid = true; 130 } 131 if (tagName.equalsIgnoreCase("security")) { 132 security = true; 133 } 134 if (tagName.equalsIgnoreCase("password")) { 135 password = true; 136 } 137 if (tagName.equalsIgnoreCase("eap")) { 138 eap = true; 139 } 140 if (tagName.equalsIgnoreCase("phase2")) { 141 phase2 = true; 142 } 143 if (tagName.equalsIgnoreCase("identity")) { 144 identity = true; 145 } 146 if (tagName.equalsIgnoreCase("anonymousidentity")) { 147 anonymousidentity = true; 148 } 149 if (tagName.equalsIgnoreCase("cacert")) { 150 cacert = true; 151 } 152 if (tagName.equalsIgnoreCase("usercert")) { 153 usercert = true; 154 } 155 if (tagName.equalsIgnoreCase("ip")) { 156 mLinkProperties = new LinkProperties(); 157 ip = true; 158 } 159 if (tagName.equalsIgnoreCase("gateway")) { 160 gateway = true; 161 } 162 if (tagName.equalsIgnoreCase("networkprefixlength")) { 163 networkprefix = true; 164 } 165 if (tagName.equalsIgnoreCase("dns1")) { 166 dns1 = true; 167 } 168 if (tagName.equalsIgnoreCase("dns2")) { 169 dns2 = true; 170 } 171 } 172 173 @Override 174 public void endElement(String uri, String localName, String tagName) throws SAXException { 175 if (tagName.equalsIgnoreCase("accesspoint")) { 176 if (mLinkProperties != null) { 177 config.ipAssignment = IpAssignment.STATIC; 178 config.linkProperties = mLinkProperties; 179 } else { 180 config.ipAssignment = IpAssignment.DHCP; 181 } 182 config.proxySettings = ProxySettings.NONE; 183 networks.add(config); 184 mLinkProperties = null; 185 } 186 } 187 188 @Override 189 public void characters(char ch[], int start, int length) throws SAXException { 190 if (ssid) { 191 config.SSID = new String(ch, start, length); 192 ssid = false; 193 } 194 if (security) { 195 String securityStr = (new String(ch, start, length)).toUpperCase(); 196 securityType = getSecurityType(securityStr); 197 switch (securityType) { 198 case NONE: 199 config.allowedKeyManagement.set(KeyMgmt.NONE); 200 break; 201 case WEP: 202 config.allowedKeyManagement.set(KeyMgmt.NONE); 203 config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); 204 config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED); 205 break; 206 case PSK: 207 config.allowedKeyManagement.set(KeyMgmt.WPA_PSK); 208 break; 209 case EAP: 210 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); 211 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 212 // Initialize other fields. 213 config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE); 214 config.enterpriseConfig.setCaCertificateAlias(""); 215 config.enterpriseConfig.setClientCertificateAlias(""); 216 config.enterpriseConfig.setIdentity(""); 217 config.enterpriseConfig.setAnonymousIdentity(""); 218 break; 219 default: 220 throw new SAXException(); 221 } 222 security = false; 223 } 224 if (password) { 225 String passwordStr = new String(ch, start, length); 226 int len = passwordStr.length(); 227 if (len == 0) { 228 throw new SAXException(); 229 } 230 if (securityType == WEP) { 231 if ((len == 10 || len == 26 || len == 58) && 232 passwordStr.matches("[0-9A-Fa-f]*")) { 233 config.wepKeys[0] = passwordStr; 234 } else { 235 config.wepKeys[0] = '"' + passwordStr + '"'; 236 } 237 } else if (securityType == PSK) { 238 if (passwordStr.matches("[0-9A-Fa-f]{64}")) { 239 config.preSharedKey = passwordStr; 240 } else { 241 config.preSharedKey = '"' + passwordStr + '"'; 242 } 243 } else if (securityType == EAP) { 244 config.enterpriseConfig.setPassword(passwordStr); 245 } else { 246 throw new SAXException(); 247 } 248 password = false; 249 } 250 if (eap) { 251 String eapValue = new String(ch, start, length); 252 if (!validateEapValue(eapValue)) { 253 throw new SAXException(); 254 } 255 if (eapValue.equals("TLS")) { 256 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); 257 } else if (eapValue.equals("TTLS")) { 258 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS); 259 } else if (eapValue.equals("PEAP")) { 260 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP); 261 } 262 eap = false; 263 } 264 if (phase2) { 265 String phase2Value = new String(ch, start, length); 266 if (phase2Value.equals("PAP")) { 267 config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP); 268 } else if (phase2Value.equals("MSCHAP")) { 269 config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAP); 270 } else if (phase2Value.equals("MSCHAPV2")) { 271 config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2); 272 } else if (phase2Value.equals("GTC")) { 273 config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); 274 } 275 phase2 = false; 276 } 277 if (identity) { 278 String identityValue = new String(ch, start, length); 279 config.enterpriseConfig.setIdentity(identityValue); 280 identity = false; 281 } 282 if (anonymousidentity) { 283 String anonyId = new String(ch, start, length); 284 config.enterpriseConfig.setAnonymousIdentity(anonyId); 285 anonymousidentity = false; 286 } 287 if (cacert) { 288 String cacertValue = new String(ch, start, length); 289 config.enterpriseConfig.setCaCertificateAlias(cacertValue); 290 cacert = false; 291 } 292 if (usercert) { 293 String usercertValue = new String(ch, start, length); 294 config.enterpriseConfig.setClientCertificateAlias(usercertValue); 295 usercert = false; 296 } 297 if (ip) { 298 try { 299 String ipAddr = new String(ch, start, length); 300 if (!InetAddress.isNumeric(ipAddr)) { 301 throw new SAXException(); 302 } 303 mInetAddr = InetAddress.getByName(ipAddr); 304 } catch (UnknownHostException e) { 305 throw new SAXException(); 306 } 307 ip = false; 308 } 309 if (gateway) { 310 try { 311 String gwAddr = new String(ch, start, length); 312 if (!InetAddress.isNumeric(gwAddr)) { 313 throw new SAXException(); 314 } 315 mLinkProperties.addRoute(new RouteInfo(InetAddress.getByName(gwAddr))); 316 } catch (UnknownHostException e) { 317 throw new SAXException(); 318 } 319 gateway = false; 320 } 321 if (networkprefix) { 322 try { 323 int nwPrefixLength = Integer.parseInt(new String(ch, start, length)); 324 if ((nwPrefixLength < 0) || (nwPrefixLength > 32)) { 325 throw new SAXException(); 326 } 327 mLinkProperties.addLinkAddress(new LinkAddress(mInetAddr, nwPrefixLength)); 328 } catch (NumberFormatException e) { 329 throw new SAXException(); 330 } 331 networkprefix = false; 332 } 333 if (dns1) { 334 try { 335 String dnsAddr = new String(ch, start, length); 336 if (!InetAddress.isNumeric(dnsAddr)) { 337 throw new SAXException(); 338 } 339 mLinkProperties.addDns(InetAddress.getByName(dnsAddr)); 340 } catch (UnknownHostException e) { 341 throw new SAXException(); 342 } 343 dns1 = false; 344 } 345 if (dns2) { 346 try { 347 String dnsAddr = new String(ch, start, length); 348 if (!InetAddress.isNumeric(dnsAddr)) { 349 throw new SAXException(); 350 } 351 mLinkProperties.addDns(InetAddress.getByName(dnsAddr)); 352 } catch (UnknownHostException e) { 353 throw new SAXException(); 354 } 355 dns2 = false; 356 } 357 } 358 }; 359 360 /** 361 * Process the InputStream in 362 * @param in is the InputStream that can be used for XML parsing 363 * @throws Exception 364 */ 365 public AccessPointParserHelper(InputStream in) throws Exception { 366 SAXParserFactory factory = SAXParserFactory.newInstance(); 367 SAXParser saxParser = factory.newSAXParser(); 368 saxParser.parse(in, mHandler); 369 } 370 371 public List<WifiConfiguration> getNetworkConfigurations() throws Exception { 372 return networks; 373 } 374 } 375