Home | History | Annotate | Download | only in connectivitymanagertest
      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.LinkAddress;
     32 import android.net.LinkProperties;
     33 import android.net.RouteInfo;
     34 import android.util.Log;
     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.HashMap;
     41 import java.util.List;
     42 
     43 
     44 /**
     45  * Help class to process configurations of access points saved in an XML file.
     46  * The configurations of an access point is included in tag
     47  * <accesspoint></accesspoint>. The supported configuration includes: ssid,
     48  * security, eap, phase2, identity, password, anonymousidentity, cacert, usercert,
     49  * in which each is included in the corresponding tags. Static IP setting is also supported.
     50  * Tags that can be used include: ip, gateway, networkprefixlength, dns1, dns2. All access points
     51  * have to be enclosed in tags of <resources></resources>.
     52  *
     53  * The following is a sample configuration file for an access point using EAP-PEAP with MSCHAP2.
     54  * <resources>
     55  *   <accesspoint>
     56  *   <ssid>testnet</ssid>
     57  *   <security>EAP</security>
     58  *   <eap>PEAP</eap>
     59  *   <phase2>MSCHAP2</phase2>
     60  *   <identity>donut</identity</identity>
     61  *   <password>abcdefgh</password>
     62  *   </accesspoint>
     63  * </resources>
     64  *
     65  * Note:ssid and security have to be the first two tags
     66  *      for static ip setting, tag "ip" should be listed before other fields: dns, gateway,
     67  *      networkprefixlength.
     68  */
     69 public class AccessPointParserHelper {
     70     private static final String KEYSTORE_SPACE = "keystore://";
     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.phase2.setValue("");
    216                         config.ca_cert.setValue("");
    217                         config.client_cert.setValue("");
    218                         config.engine.setValue("");
    219                         config.engine_id.setValue("");
    220                         config.key_id.setValue("");
    221                         config.identity.setValue("");
    222                         config.anonymous_identity.setValue("");
    223                         break;
    224                     default:
    225                         throw new SAXException();
    226                 }
    227                 security = false;
    228             }
    229             if (password) {
    230                 String passwordStr = new String(ch, start, length);
    231                 int len = passwordStr.length();
    232                 if (len == 0) {
    233                     throw new SAXException();
    234                 }
    235                 if (securityType == WEP) {
    236                     if ((len == 10 || len == 26 || len == 58) &&
    237                             passwordStr.matches("[0-9A-Fa-f]*")) {
    238                         config.wepKeys[0] = passwordStr;
    239                     } else {
    240                         config.wepKeys[0] = '"' + passwordStr + '"';
    241                     }
    242                 } else if (securityType == PSK) {
    243                     if (passwordStr.matches("[0-9A-Fa-f]{64}")) {
    244                         config.preSharedKey = passwordStr;
    245                     } else {
    246                         config.preSharedKey = '"' + passwordStr + '"';
    247                     }
    248                 } else if (securityType == EAP) {
    249                     config.password.setValue(passwordStr);
    250                 } else {
    251                     throw new SAXException();
    252                 }
    253                 password = false;
    254             }
    255             if (eap) {
    256                 String eapValue = new String(ch, start, length);
    257                 if (!validateEapValue(eapValue)) {
    258                     throw new SAXException();
    259                 }
    260                 config.eap.setValue(eapValue);
    261                 eap = false;
    262             }
    263             if (phase2) {
    264                 String phase2Value = new String(ch, start, length);
    265                 config.phase2.setValue("auth=" + phase2Value);
    266                 phase2 = false;
    267             }
    268             if (identity) {
    269                 String identityValue = new String(ch, start, length);
    270                 config.identity.setValue(identityValue);
    271                 identity = false;
    272             }
    273             if (anonymousidentity) {
    274                 String anonyId = new String(ch, start, length);
    275                 config.anonymous_identity.setValue(anonyId);
    276                 anonymousidentity = false;
    277             }
    278             if (cacert) {
    279                 String cacertValue = new String(ch, start, length);
    280                 // need to install the credentail to "keystore://"
    281                 config.ca_cert.setValue(KEYSTORE_SPACE);
    282                 cacert = false;
    283             }
    284             if (usercert) {
    285                 String usercertValue = new String(ch, start, length);
    286                 config.client_cert.setValue(KEYSTORE_SPACE);
    287                 usercert = false;
    288             }
    289             if (ip) {
    290                 try {
    291                     String ipAddr = new String(ch, start, length);
    292                     if (!InetAddress.isNumeric(ipAddr)) {
    293                         throw new SAXException();
    294                     }
    295                     mInetAddr = InetAddress.getByName(ipAddr);
    296                 } catch (UnknownHostException e) {
    297                     throw new SAXException();
    298                 }
    299                 ip = false;
    300             }
    301             if (gateway) {
    302                 try {
    303                     String gwAddr = new String(ch, start, length);
    304                     if (!InetAddress.isNumeric(gwAddr)) {
    305                         throw new SAXException();
    306                     }
    307                     mLinkProperties.addRoute(new RouteInfo(InetAddress.getByName(gwAddr)));
    308                 } catch (UnknownHostException e) {
    309                     throw new SAXException();
    310                 }
    311                 gateway = false;
    312             }
    313             if (networkprefix) {
    314                 try {
    315                     int nwPrefixLength = Integer.parseInt(new String(ch, start, length));
    316                     if ((nwPrefixLength < 0) || (nwPrefixLength > 32)) {
    317                         throw new SAXException();
    318                     }
    319                     mLinkProperties.addLinkAddress(new LinkAddress(mInetAddr, nwPrefixLength));
    320                 } catch (NumberFormatException e) {
    321                     throw new SAXException();
    322                 }
    323                 networkprefix = false;
    324             }
    325             if (dns1) {
    326                 try {
    327                     String dnsAddr = new String(ch, start, length);
    328                     if (!InetAddress.isNumeric(dnsAddr)) {
    329                         throw new SAXException();
    330                     }
    331                     mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
    332                 } catch (UnknownHostException e) {
    333                     throw new SAXException();
    334                 }
    335                 dns1 = false;
    336             }
    337             if (dns2) {
    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                 dns2 = false;
    348             }
    349         }
    350     };
    351 
    352     /**
    353      * Process the InputStream in
    354      * @param in is the InputStream that can be used for XML parsing
    355      * @throws Exception
    356      */
    357     public AccessPointParserHelper(InputStream in) throws Exception {
    358         SAXParserFactory factory = SAXParserFactory.newInstance();
    359         SAXParser saxParser = factory.newSAXParser();
    360         saxParser.parse(in, mHandler);
    361     }
    362 
    363     public List<WifiConfiguration> getNetworkConfigurations() throws Exception {
    364         return networks;
    365     }
    366 }
    367