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.private_key.setValue("");
    219                         config.identity.setValue("");
    220                         config.anonymous_identity.setValue("");
    221                         break;
    222                     default:
    223                         throw new SAXException();
    224                 }
    225                 security = false;
    226             }
    227             if (password) {
    228                 String passwordStr = new String(ch, start, length);
    229                 int len = passwordStr.length();
    230                 if (len == 0) {
    231                     throw new SAXException();
    232                 }
    233                 if (securityType == WEP) {
    234                     if ((len == 10 || len == 26 || len == 58) &&
    235                             passwordStr.matches("[0-9A-Fa-f]*")) {
    236                         config.wepKeys[0] = passwordStr;
    237                     } else {
    238                         config.wepKeys[0] = '"' + passwordStr + '"';
    239                     }
    240                 } else if (securityType == PSK) {
    241                     if (passwordStr.matches("[0-9A-Fa-f]{64}")) {
    242                         config.preSharedKey = passwordStr;
    243                     } else {
    244                         config.preSharedKey = '"' + passwordStr + '"';
    245                     }
    246                 } else if (securityType == EAP) {
    247                     config.password.setValue(passwordStr);
    248                 } else {
    249                     throw new SAXException();
    250                 }
    251                 password = false;
    252             }
    253             if (eap) {
    254                 String eapValue = new String(ch, start, length);
    255                 if (!validateEapValue(eapValue)) {
    256                     throw new SAXException();
    257                 }
    258                 config.eap.setValue(eapValue);
    259                 eap = false;
    260             }
    261             if (phase2) {
    262                 String phase2Value = new String(ch, start, length);
    263                 config.phase2.setValue("auth=" + phase2Value);
    264                 phase2 = false;
    265             }
    266             if (identity) {
    267                 String identityValue = new String(ch, start, length);
    268                 config.identity.setValue(identityValue);
    269                 identity = false;
    270             }
    271             if (anonymousidentity) {
    272                 String anonyId = new String(ch, start, length);
    273                 config.anonymous_identity.setValue(anonyId);
    274                 anonymousidentity = false;
    275             }
    276             if (cacert) {
    277                 String cacertValue = new String(ch, start, length);
    278                 // need to install the credentail to "keystore://"
    279                 config.ca_cert.setValue(KEYSTORE_SPACE);
    280                 cacert = false;
    281             }
    282             if (usercert) {
    283                 String usercertValue = new String(ch, start, length);
    284                 config.client_cert.setValue(KEYSTORE_SPACE);
    285                 usercert = false;
    286             }
    287             if (ip) {
    288                 try {
    289                     String ipAddr = new String(ch, start, length);
    290                     if (!InetAddress.isNumeric(ipAddr)) {
    291                         throw new SAXException();
    292                     }
    293                     mInetAddr = InetAddress.getByName(ipAddr);
    294                 } catch (UnknownHostException e) {
    295                     throw new SAXException();
    296                 }
    297                 ip = false;
    298             }
    299             if (gateway) {
    300                 try {
    301                     String gwAddr = new String(ch, start, length);
    302                     if (!InetAddress.isNumeric(gwAddr)) {
    303                         throw new SAXException();
    304                     }
    305                     mLinkProperties.addRoute(new RouteInfo(InetAddress.getByName(gwAddr)));
    306                 } catch (UnknownHostException e) {
    307                     throw new SAXException();
    308                 }
    309                 gateway = false;
    310             }
    311             if (networkprefix) {
    312                 try {
    313                     int nwPrefixLength = Integer.parseInt(new String(ch, start, length));
    314                     if ((nwPrefixLength < 0) || (nwPrefixLength > 32)) {
    315                         throw new SAXException();
    316                     }
    317                     mLinkProperties.addLinkAddress(new LinkAddress(mInetAddr, nwPrefixLength));
    318                 } catch (NumberFormatException e) {
    319                     throw new SAXException();
    320                 }
    321                 networkprefix = false;
    322             }
    323             if (dns1) {
    324                 try {
    325                     String dnsAddr = new String(ch, start, length);
    326                     if (!InetAddress.isNumeric(dnsAddr)) {
    327                         throw new SAXException();
    328                     }
    329                     mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
    330                 } catch (UnknownHostException e) {
    331                     throw new SAXException();
    332                 }
    333                 dns1 = false;
    334             }
    335             if (dns2) {
    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                 dns2 = false;
    346             }
    347         }
    348     };
    349 
    350     /**
    351      * Process the InputStream in
    352      * @param in is the InputStream that can be used for XML parsing
    353      * @throws Exception
    354      */
    355     public AccessPointParserHelper(InputStream in) throws Exception {
    356         SAXParserFactory factory = SAXParserFactory.newInstance();
    357         SAXParser saxParser = factory.newSAXParser();
    358         saxParser.parse(in, mHandler);
    359     }
    360 
    361     public List<WifiConfiguration> getNetworkConfigurations() throws Exception {
    362         return networks;
    363     }
    364 }
    365