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