WifiConfigurationUtil.java revision 2d327a58a4d39c7b1b700bf06d2fbbe7fb68c7c4
1/*
2 * Copyright (C) 2016 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.server.wifi;
18
19import android.content.pm.UserInfo;
20import android.net.IpConfiguration;
21import android.net.ProxyInfo;
22import android.net.wifi.WifiConfiguration;
23import android.net.wifi.WifiEnterpriseConfig;
24import android.os.UserHandle;
25
26import com.android.internal.annotations.VisibleForTesting;
27
28import java.security.cert.X509Certificate;
29import java.util.Arrays;
30import java.util.List;
31import java.util.Objects;
32
33/**
34 * WifiConfiguration utility for any {@link android.net.wifi.WifiConfiguration} related operations.
35 * Currently contains:
36 *   > Helper method to check if the WifiConfiguration object is visible to the provided users.
37 *   > Helper methods to identify the encryption of a WifiConfiguration object.
38 */
39public class WifiConfigurationUtil {
40    /**
41     * Check whether a network configuration is visible to a user or any of its managed profiles.
42     *
43     * @param config   the network configuration whose visibility should be checked
44     * @param profiles the user IDs of the user itself and all its managed profiles (can be obtained
45     *                 via {@link android.os.UserManager#getProfiles})
46     * @return whether the network configuration is visible to the user or any of its managed
47     * profiles
48     */
49    public static boolean isVisibleToAnyProfile(WifiConfiguration config, List<UserInfo> profiles) {
50        if (config.shared) {
51            return true;
52        }
53        final int creatorUserId = UserHandle.getUserId(config.creatorUid);
54        for (UserInfo profile : profiles) {
55            if (profile.id == creatorUserId) {
56                return true;
57            }
58        }
59        return false;
60    }
61
62    /**
63     * Checks if the provided |wepKeys| array contains any non-null value;
64     */
65    public static boolean hasAnyValidWepKey(String[] wepKeys) {
66        for (int i = 0; i < wepKeys.length; i++) {
67            if (wepKeys[i] != null) {
68                return true;
69            }
70        }
71        return false;
72    }
73
74    /**
75     * Helper method to check if the provided |config| corresponds to a PSK network or not.
76     */
77    public static boolean isConfigForPskNetwork(WifiConfiguration config) {
78        return config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK);
79    }
80
81    /**
82     * Helper method to check if the provided |config| corresponds to a EAP network or not.
83     */
84    public static boolean isConfigForEapNetwork(WifiConfiguration config) {
85        return (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)
86                || config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
87    }
88
89    /**
90     * Helper method to check if the provided |config| corresponds to a WEP network or not.
91     */
92    public static boolean isConfigForWepNetwork(WifiConfiguration config) {
93        return (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)
94                && hasAnyValidWepKey(config.wepKeys));
95    }
96
97    /**
98     * Helper method to check if the provided |config| corresponds to an open network or not.
99     */
100    public static boolean isConfigForOpenNetwork(WifiConfiguration config) {
101        return !(isConfigForWepNetwork(config) || isConfigForPskNetwork(config)
102                || isConfigForEapNetwork(config));
103    }
104
105    /**
106     * Compare existing and new WifiConfiguration objects after a network update and return if
107     * IP parameters have changed or not.
108     *
109     * @param existingConfig Existing WifiConfiguration object corresponding to the network.
110     * @param newConfig      New WifiConfiguration object corresponding to the network.
111     * @return true if IP parameters have changed, false otherwise.
112     */
113    public static boolean hasIpChanged(WifiConfiguration existingConfig,
114            WifiConfiguration newConfig) {
115        if (existingConfig.getIpAssignment() != newConfig.getIpAssignment()) {
116            return true;
117        }
118        if (newConfig.getIpAssignment() == IpConfiguration.IpAssignment.STATIC) {
119            return !Objects.equals(existingConfig.getStaticIpConfiguration(),
120                    newConfig.getStaticIpConfiguration());
121        }
122        return false;
123    }
124
125    /**
126     * Compare existing and new WifiConfiguration objects after a network update and return if
127     * proxy parameters have changed or not.
128     *
129     * @param existingConfig Existing WifiConfiguration object corresponding to the network.
130     * @param newConfig      New WifiConfiguration object corresponding to the network.
131     * @return true if proxy parameters have changed, false otherwise.
132     */
133    public static boolean hasProxyChanged(WifiConfiguration existingConfig,
134            WifiConfiguration newConfig) {
135        if (existingConfig.getProxySettings() != newConfig.getProxySettings()) {
136            return true;
137        }
138        if (newConfig.getProxySettings() == IpConfiguration.ProxySettings.PAC) {
139            ProxyInfo existingHttpProxy = existingConfig.getHttpProxy();
140            ProxyInfo newHttpProxy = newConfig.getHttpProxy();
141            if (existingHttpProxy != null) {
142                return !existingHttpProxy.equals(newHttpProxy);
143            } else {
144                return (newHttpProxy != null);
145            }
146        }
147        return false;
148    }
149
150    /**
151     * Compare existing and new WifiEnterpriseConfig objects after a network update and return if
152     * credential parameters have changed or not.
153     *
154     * @param existingEnterpriseConfig Existing WifiConfiguration object corresponding to the
155     *                                 network.
156     * @param newEnterpriseConfig      New WifiConfiguration object corresponding to the network.
157     * @return true if credentials have changed, false otherwise.
158     */
159    @VisibleForTesting
160    public static boolean hasEnterpriseConfigChanged(WifiEnterpriseConfig existingEnterpriseConfig,
161            WifiEnterpriseConfig newEnterpriseConfig) {
162        if (existingEnterpriseConfig != null && newEnterpriseConfig != null) {
163            if (existingEnterpriseConfig.getEapMethod() != newEnterpriseConfig.getEapMethod()) {
164                return true;
165            }
166            if (existingEnterpriseConfig.getPhase2Method()
167                    != newEnterpriseConfig.getPhase2Method()) {
168                return true;
169            }
170            X509Certificate[] existingCaCerts = existingEnterpriseConfig.getCaCertificates();
171            X509Certificate[] newCaCerts = newEnterpriseConfig.getCaCertificates();
172            if (!Arrays.equals(existingCaCerts, newCaCerts)) {
173                return true;
174            }
175        } else {
176            // One of the configs may have an enterpriseConfig
177            if (existingEnterpriseConfig != null || newEnterpriseConfig != null) {
178                return true;
179            }
180        }
181        return false;
182    }
183
184    /**
185     * Compare existing and new WifiConfiguration objects after a network update and return if
186     * credential parameters have changed or not.
187     *
188     * @param existingConfig Existing WifiConfiguration object corresponding to the network.
189     * @param newConfig      New WifiConfiguration object corresponding to the network.
190     * @return true if credentials have changed, false otherwise.
191     */
192    public static boolean hasCredentialChanged(WifiConfiguration existingConfig,
193            WifiConfiguration newConfig) {
194        if (!Objects.equals(existingConfig.allowedKeyManagement,
195                newConfig.allowedKeyManagement)) {
196            return true;
197        }
198        if (!Objects.equals(existingConfig.allowedProtocols, newConfig.allowedProtocols)) {
199            return true;
200        }
201        if (!Objects.equals(existingConfig.allowedAuthAlgorithms,
202                newConfig.allowedAuthAlgorithms)) {
203            return true;
204        }
205        if (!Objects.equals(existingConfig.allowedPairwiseCiphers,
206                newConfig.allowedPairwiseCiphers)) {
207            return true;
208        }
209        if (!Objects.equals(existingConfig.allowedGroupCiphers,
210                newConfig.allowedGroupCiphers)) {
211            return true;
212        }
213        if (!Objects.equals(existingConfig.preSharedKey, newConfig.preSharedKey)) {
214            return true;
215        }
216        if (!Arrays.equals(existingConfig.wepKeys, newConfig.wepKeys)) {
217            return true;
218        }
219        if (existingConfig.wepTxKeyIndex != newConfig.wepTxKeyIndex) {
220            return true;
221        }
222        if (existingConfig.hiddenSSID != newConfig.hiddenSSID) {
223            return true;
224        }
225        if (hasEnterpriseConfigChanged(existingConfig.enterpriseConfig,
226                newConfig.enterpriseConfig)) {
227            return true;
228        }
229        return false;
230    }
231
232}
233