1 /*
2  * Copyright 2014, 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.managedprovisioning;
18 
19 import android.net.ProxyInfo;
20 import android.net.IpConfiguration.ProxySettings;
21 import android.net.wifi.WifiConfiguration;
22 import android.net.wifi.WifiManager;
23 import android.text.TextUtils;
24 
25 import java.util.Locale;
26 
27 /**
28  * Utility class for configuring a new WiFi network.
29  */
30 public class WifiConfig {
31 
32     private final WifiManager mWifiManager;
33 
34     enum SecurityType {
35         NONE,
36         WPA,
37         WEP;
38     }
39 
WifiConfig(WifiManager manager)40     public WifiConfig(WifiManager manager) {
41         mWifiManager = manager;
42     }
43 
44     /**
45      * Adds a new WiFi network.
46      *
47      * @return the ID of the newly created network description. Returns -1 on failure.
48      */
addNetwork(String ssid, boolean hidden, String type, String password, String proxyHost, int proxyPort, String proxyBypassHosts, String pacUrl)49     public int addNetwork(String ssid, boolean hidden, String type, String password,
50             String proxyHost, int proxyPort, String proxyBypassHosts, String pacUrl) {
51         if (!mWifiManager.isWifiEnabled()) {
52             mWifiManager.setWifiEnabled(true);
53         }
54 
55         WifiConfiguration wifiConf = new WifiConfiguration();
56         SecurityType securityType;
57         if (type == null || TextUtils.isEmpty(type)) {
58             securityType = SecurityType.NONE;
59         } else {
60             try {
61                 securityType = Enum.valueOf(SecurityType.class, type.toUpperCase(Locale.US));
62             } catch (IllegalArgumentException e) {
63                 ProvisionLogger.loge("Invalid Wifi security type: " + type);
64                 return -1;
65             }
66         }
67         // If we have a password, and no security type, assume WPA.
68         // TODO: Remove this when the programmer supports it.
69         if (securityType.equals(SecurityType.NONE) && !TextUtils.isEmpty(password)) {
70             securityType = SecurityType.WPA;
71         }
72 
73         wifiConf.SSID = ssid;
74         wifiConf.status = WifiConfiguration.Status.ENABLED;
75         wifiConf.hiddenSSID = hidden;
76         wifiConf.userApproved = WifiConfiguration.USER_APPROVED;
77         switch (securityType) {
78             case NONE:
79                 wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
80                 wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
81                 break;
82             case WPA:
83                 updateForWPAConfiguration(wifiConf, password);
84                 break;
85             case WEP:
86                 updateForWEPConfiguration(wifiConf, password);
87                 break;
88         }
89 
90         updateForProxy(wifiConf, proxyHost, proxyPort, proxyBypassHosts, pacUrl);
91 
92         int netId = mWifiManager.addNetwork(wifiConf);
93 
94         if (netId != -1) {
95             // Setting disableOthers to 'true' should trigger a connection attempt.
96             mWifiManager.enableNetwork(netId, true);
97             mWifiManager.saveConfiguration();
98         }
99 
100         return netId;
101     }
102 
updateForWPAConfiguration(WifiConfiguration wifiConf, String wifiPassword)103     protected void updateForWPAConfiguration(WifiConfiguration wifiConf, String wifiPassword) {
104         wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
105         wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
106         wifiConf.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA
107         wifiConf.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
108         wifiConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
109         wifiConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
110         wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
111         wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
112         if (!TextUtils.isEmpty(wifiPassword)) {
113             wifiConf.preSharedKey = "\"" + wifiPassword + "\"";
114         }
115     }
116 
updateForWEPConfiguration(WifiConfiguration wifiConf, String password)117     protected void updateForWEPConfiguration(WifiConfiguration wifiConf, String password) {
118         wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
119         wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
120         wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
121         wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
122         wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
123         wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
124         wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
125         int length = password.length();
126         if ((length == 10 || length == 26 || length == 58) && password.matches("[0-9A-Fa-f]*")) {
127             wifiConf.wepKeys[0] = password;
128         } else {
129             wifiConf.wepKeys[0] = '"' + password + '"';
130         }
131         wifiConf.wepTxKeyIndex = 0;
132     }
133 
updateForProxy(WifiConfiguration wifiConf, String proxyHost, int proxyPort, String proxyBypassHosts, String pacUrl)134     private void updateForProxy(WifiConfiguration wifiConf, String proxyHost, int proxyPort,
135             String proxyBypassHosts, String pacUrl) {
136         if (TextUtils.isEmpty(proxyHost) && TextUtils.isEmpty(pacUrl)) {
137             return;
138         }
139         if (!TextUtils.isEmpty(proxyHost)) {
140             ProxyInfo proxy = new ProxyInfo(proxyHost, proxyPort, proxyBypassHosts);
141             wifiConf.setProxy(ProxySettings.STATIC, proxy);
142         } else {
143             ProxyInfo proxy = new ProxyInfo(pacUrl);
144             wifiConf.setProxy(ProxySettings.PAC, proxy);
145         }
146     }
147 }
148