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.KeyMgmt; 29 30 import android.util.Log; 31 import java.io.InputStream; 32 import java.util.ArrayList; 33 import java.util.List; 34 35 36 /** 37 * Help class to process configurations of access points saved in an XML file. 38 * The configurations of an access point is included in tag 39 * <accesspoint></accesspoint>. The supported configuration includes: ssid, 40 * security, eap, phase2, identity, password, anonymousidentity, cacert, usercert, 41 * in which each is included in the corresponding tags. All access points have to be 42 * enclosed in tags of <resources></resources>. 43 * 44 * The following is a sample configuration file for an access point using EAP-PEAP with MSCHAP2. 45 * <resources> 46 * <accesspoint> 47 * <ssid>testnet</ssid> 48 * <security>EAP</security> 49 * <eap>PEAP</eap> 50 * <phase2>MSCHAP2</phase2> 51 * <identity>donut</identity</identity> 52 * <password>abcdefgh</password> 53 * </accesspoint> 54 * </resources> 55 */ 56 public class AccessPointParserHelper { 57 private static final String KEYSTORE_SPACE = "keystore://"; 58 private static final String TAG = "AccessPointParserHelper"; 59 static final int NONE = 0; 60 static final int WEP = 1; 61 static final int PSK = 2; 62 static final int EAP = 3; 63 64 List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>(); 65 66 private int getSecurityType (String security) { 67 if (security.equalsIgnoreCase("NONE")) { 68 return NONE; 69 } else if (security.equalsIgnoreCase("WEP")) { 70 return WEP; 71 } else if (security.equalsIgnoreCase("PSK")) { 72 return PSK; 73 } else if (security.equalsIgnoreCase("EAP")) { 74 return EAP; 75 } else { 76 return -1; 77 } 78 } 79 80 private boolean validateEapValue(String value) { 81 if (value.equalsIgnoreCase("PEAP") || 82 value.equalsIgnoreCase("TLS") || 83 value.equalsIgnoreCase("TTLS")) { 84 return true; 85 } else { 86 return false; 87 } 88 } 89 90 DefaultHandler mHandler = new DefaultHandler() { 91 92 boolean ssid = false; 93 boolean security = false; 94 boolean password = false; 95 boolean ip = false; 96 boolean subnetmask = false; 97 boolean gateway = false; 98 boolean dns = false; 99 boolean eap = false; 100 boolean phase2 = false; 101 boolean identity = false; 102 boolean anonymousidentity = false; 103 boolean cacert = false; 104 boolean usercert = false; 105 WifiConfiguration config = null; 106 int securityType = NONE; 107 108 @Override 109 public void startElement(String uri, String localName, String tagName, 110 Attributes attributes) throws SAXException { 111 if (tagName.equalsIgnoreCase("accesspoint")) { 112 config = new WifiConfiguration(); 113 } 114 if (tagName.equalsIgnoreCase("ssid")) { 115 ssid = true; 116 } 117 if (tagName.equalsIgnoreCase("security")) { 118 security = true; 119 } 120 if (tagName.equalsIgnoreCase("password")) { 121 password = true; 122 } 123 if (tagName.equalsIgnoreCase("eap")) { 124 eap = true; 125 } 126 if (tagName.equalsIgnoreCase("phase2")) { 127 phase2 = true; 128 } 129 if (tagName.equalsIgnoreCase("identity")) { 130 identity = true; 131 } 132 if (tagName.equalsIgnoreCase("anonymousidentity")) { 133 anonymousidentity = true; 134 } 135 if (tagName.equalsIgnoreCase("cacert")) { 136 cacert = true; 137 } 138 if (tagName.equalsIgnoreCase("usercert")) { 139 usercert = true; 140 } 141 } 142 143 @Override 144 public void endElement(String uri, String localName, String tagName) throws SAXException { 145 Log.v(TAG, "endElement: " + tagName); 146 if (tagName.equalsIgnoreCase("accesspoint")) { 147 networks.add(config); 148 } 149 } 150 151 @Override 152 public void characters(char ch[], int start, int length) throws SAXException { 153 if (ssid) { 154 config.SSID = new String(ch, start, length); 155 Log.v(TAG, "ssid: " + config.SSID); 156 ssid = false; 157 } 158 if (security) { 159 String securityStr = (new String(ch, start, length)).toUpperCase(); 160 Log.v(TAG, "security: " + securityStr); 161 securityType = getSecurityType(securityStr); 162 Log.v(TAG, "securityType = " + securityType); 163 switch (securityType) { 164 case NONE: 165 config.allowedKeyManagement.set(KeyMgmt.NONE); 166 break; 167 case WEP: 168 config.allowedKeyManagement.set(KeyMgmt.NONE); 169 config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); 170 config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED); 171 break; 172 case PSK: 173 config.allowedKeyManagement.set(KeyMgmt.WPA_PSK); 174 break; 175 case EAP: 176 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); 177 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); 178 break; 179 default: 180 throw new SAXException(); 181 } 182 security = false; 183 } 184 if (password) { 185 String passwordStr = new String(ch, start, length); 186 int len = passwordStr.length(); 187 if (len == 0) { 188 throw new SAXException(); 189 } 190 Log.v(TAG, "passwordStr:" + passwordStr); 191 if (securityType == WEP) { 192 if ((len == 10 || len == 26 || len == 58) && 193 passwordStr.matches("[0-9A-Fa-f]*")) { 194 config.wepKeys[0] = passwordStr; 195 } else { 196 config.wepKeys[0] = '"' + passwordStr + '"'; 197 } 198 } else if (securityType == PSK) { 199 if (passwordStr.matches("[0-9A-Fa-f]{64}")) { 200 config.preSharedKey = passwordStr; 201 } else { 202 config.preSharedKey = '"' + passwordStr + '"'; 203 } 204 } else if (securityType == EAP) { 205 config.password.setValue(passwordStr); 206 } else { 207 throw new SAXException(); 208 } 209 password = false; 210 } 211 if (eap) { 212 String eapValue = new String(ch, start, length); 213 if (!validateEapValue(eapValue)) { 214 throw new SAXException(); 215 } 216 config.eap.setValue(eapValue); 217 eap = false; 218 } 219 if (phase2) { 220 String phase2Value = new String(ch, start, length); 221 config.phase2.setValue("auth=" + phase2Value); 222 phase2 = false; 223 } 224 if (identity) { 225 String identityValue = new String(ch, start, length); 226 config.identity.setValue(identityValue); 227 identity = false; 228 } 229 if (anonymousidentity) { 230 String anonyId = new String(ch, start, length); 231 config.anonymous_identity.setValue(anonyId); 232 anonymousidentity = false; 233 } 234 if (cacert) { 235 String cacertValue = new String(ch, start, length); 236 // need to install the credentail to "keystore://" 237 config.ca_cert.setValue(KEYSTORE_SPACE); 238 cacert = false; 239 } 240 if (usercert) { 241 String usercertValue = new String(ch, start, length); 242 config.client_cert.setValue(KEYSTORE_SPACE); 243 usercert = false; 244 } 245 } 246 }; 247 248 public AccessPointParserHelper() { 249 } 250 251 /** 252 * Process the accesspoint.xml file 253 * @return List of WifiConfiguration 254 * @throws Exception when parsing the XML file 255 */ 256 public List<WifiConfiguration> processAccessPoint(InputStream in) throws Exception { 257 SAXParserFactory factory = SAXParserFactory.newInstance(); 258 SAXParser saxParser = factory.newSAXParser(); 259 saxParser.parse(in, mHandler); 260 return networks; 261 } 262 } 263