WifiBackupRestoreTest.java revision e7df893234345aefd8efb25e45aa02c39644fcb2
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 static org.junit.Assert.*;
20import static org.mockito.Mockito.*;
21
22import android.net.IpConfiguration;
23import android.net.wifi.WifiConfiguration;
24import android.os.Process;
25import android.support.test.filters.SmallTest;
26
27import com.android.server.net.IpConfigStore;
28import com.android.server.wifi.util.WifiPermissionsUtil;
29
30import org.junit.After;
31import org.junit.Before;
32import org.junit.Test;
33import org.mockito.Mock;
34import org.mockito.MockitoAnnotations;
35
36import java.io.ByteArrayOutputStream;
37import java.io.DataOutputStream;
38import java.io.FileDescriptor;
39import java.io.IOException;
40import java.io.OutputStreamWriter;
41import java.io.PrintWriter;
42import java.io.StringWriter;
43import java.util.ArrayList;
44import java.util.HashMap;
45import java.util.List;
46import java.util.Map;
47import java.util.Random;
48
49/**
50 * Unit tests for {@link com.android.server.wifi.WifiBackupRestore}.
51 */
52@SmallTest
53public class WifiBackupRestoreTest {
54
55    private static final String WIFI_BACKUP_DATA_WITH_UNSUPPORTED_TAG =
56            "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
57            + "<WifiBackupData>"
58            + "<int name=\"Version\" value=\"1\" />"
59            + "<NetworkList>"
60            + "<Network>"
61            + "<WifiConfiguration>"
62            + "<string name=\"ConfigKey\">&quot;GoogleGuest-Legacy&quot;NONE</string>"
63            + "<string name=\"SSID\">&quot;GoogleGuest-Legacy&quot;</string>"
64            + "<null name=\"BSSID\" />"
65            + "<null name=\"PreSharedKey\" />"
66            + "<null name=\"WEPKeys\" />"
67            + "<int name=\"WEPTxKeyIndex\" value=\"0\" />"
68            + "<boolean name=\"HiddenSSID\" value=\"false\" />"
69            + "<boolean name=\"RequirePMF\" value=\"false\" />"
70            + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>"
71            + "<byte-array name=\"AllowedProtocols\" num=\"1\">03</byte-array>"
72            + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">01</byte-array>"
73            + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>"
74            + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>"
75            + "<boolean name=\"Shared\" value=\"true\" />"
76            + "<null name=\"SimSlot\" />"
77            + "</WifiConfiguration>"
78            + "<IpConfiguration>"
79            + "<string name=\"IpAssignment\">DHCP</string>"
80            + "<string name=\"ProxySettings\">NONE</string>"
81            + "</IpConfiguration>"
82            + "</Network>"
83            + "</NetworkList>"
84            + "</WifiBackupData>";
85
86    // |AllowedKeyMgmt|, |AllowedProtocols|, |AllowedAuthAlgorithms|, |AllowedGroupCiphers| and
87    // |AllowedPairwiseCiphers| fields have invalid values in them.
88    private static final String WIFI_BACKUP_DATA_WITH_UNSUPPORTED_VALUES_IN_BITSETS =
89            "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
90                    + "<WifiBackupData>"
91                    + "<int name=\"Version\" value=\"1\" />"
92                    + "<NetworkList>"
93                    + "<Network>"
94                    + "<WifiConfiguration>"
95                    + "<string name=\"ConfigKey\">&quot;GoogleGuest-Legacy&quot;NONE</string>"
96                    + "<string name=\"SSID\">&quot;GoogleGuest-Legacy&quot;</string>"
97                    + "<null name=\"BSSID\" />"
98                    + "<null name=\"PreSharedKey\" />"
99                    + "<null name=\"WEPKeys\" />"
100                    + "<int name=\"WEPTxKeyIndex\" value=\"0\" />"
101                    + "<boolean name=\"HiddenSSID\" value=\"false\" />"
102                    + "<boolean name=\"RequirePMF\" value=\"false\" />"
103                    // Valid Value: 01
104                    + "<byte-array name=\"AllowedKeyMgmt\" num=\"2\">0101</byte-array>"
105                    // Valid Value: 03
106                    + "<byte-array name=\"AllowedProtocols\" num=\"1\">0b</byte-array>"
107                    // Valid Value: 01
108                    + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">09</byte-array>"
109                    // Valid Value: 0f
110                    + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">2f</byte-array>"
111                    // Valid Value: 06
112                    + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">0e</byte-array>"
113                    + "<boolean name=\"Shared\" value=\"true\" />"
114                    + "<null name=\"SimSlot\" />"
115                    + "</WifiConfiguration>"
116                    + "<IpConfiguration>"
117                    + "<string name=\"IpAssignment\">DHCP</string>"
118                    + "<string name=\"ProxySettings\">NONE</string>"
119                    + "</IpConfiguration>"
120                    + "</Network>"
121                    + "</NetworkList>"
122                    + "</WifiBackupData>";
123
124    @Mock WifiPermissionsUtil mWifiPermissionsUtil;
125    private WifiBackupRestore mWifiBackupRestore;
126    private boolean mCheckDump = true;
127
128    @Before
129    public void setUp() throws Exception {
130        MockitoAnnotations.initMocks(this);
131        when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
132        mWifiBackupRestore = new WifiBackupRestore(mWifiPermissionsUtil);
133        // Enable verbose logging before tests to check the backup data dumps.
134        mWifiBackupRestore.enableVerboseLogging(1);
135    }
136
137    @After
138    public void cleanUp() throws Exception {
139        if (mCheckDump) {
140            StringWriter stringWriter = new StringWriter();
141            mWifiBackupRestore.dump(
142                    new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
143            String dumpString = stringWriter.toString();
144            // Ensure that the SSID was dumped out.
145            assertTrue("Dump: " + dumpString,
146                    dumpString.contains(WifiConfigurationTestUtil.TEST_SSID));
147            // Ensure that the password wasn't dumped out.
148            assertFalse("Dump: " + dumpString,
149                    dumpString.contains(WifiConfigurationTestUtil.TEST_PSK));
150            assertFalse("Dump: " + dumpString,
151                    dumpString.contains(WifiConfigurationTestUtil.TEST_WEP_KEYS[0]));
152            assertFalse("Dump: " + dumpString,
153                    dumpString.contains(WifiConfigurationTestUtil.TEST_WEP_KEYS[1]));
154            assertFalse("Dump: " + dumpString,
155                    dumpString.contains(WifiConfigurationTestUtil.TEST_WEP_KEYS[2]));
156            assertFalse("Dump: " + dumpString,
157                    dumpString.contains(WifiConfigurationTestUtil.TEST_WEP_KEYS[3]));
158        }
159    }
160
161    /**
162     * Verify that a null network list is serialized correctly.
163     */
164    @Test
165    public void testNullNetworkListBackup() {
166        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(null);
167        assertTrue(backupData != null);
168        assertEquals(backupData.length, 0);
169        // No valid data to check in dump.
170        mCheckDump = false;
171    }
172
173    /**
174     * Verify that a single open network configuration is serialized & deserialized correctly.
175     */
176    @Test
177    public void testSingleOpenNetworkBackupRestore() {
178        List<WifiConfiguration> configurations = new ArrayList<>();
179        configurations.add(WifiConfigurationTestUtil.createOpenNetwork());
180
181        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
182        List<WifiConfiguration> retrievedConfigurations =
183                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
184        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
185                configurations, retrievedConfigurations);
186    }
187
188    /**
189     * Verify that a single open hidden network configuration is serialized & deserialized
190     * correctly.
191     */
192    @Test
193    public void testSingleOpenHiddenNetworkBackupRestore() {
194        List<WifiConfiguration> configurations = new ArrayList<>();
195        configurations.add(WifiConfigurationTestUtil.createOpenHiddenNetwork());
196
197        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
198        List<WifiConfiguration> retrievedConfigurations =
199                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
200        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
201                configurations, retrievedConfigurations);
202    }
203
204    /**
205     * Verify that a single PSK network configuration is serialized & deserialized correctly.
206     */
207    @Test
208    public void testSinglePskNetworkBackupRestore() {
209        List<WifiConfiguration> configurations = new ArrayList<>();
210        configurations.add(WifiConfigurationTestUtil.createPskNetwork());
211
212        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
213        List<WifiConfiguration> retrievedConfigurations =
214                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
215        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
216                configurations, retrievedConfigurations);
217    }
218
219    /**
220     * Verify that a single PSK hidden network configuration is serialized & deserialized correctly.
221     */
222    @Test
223    public void testSinglePskHiddenNetworkBackupRestore() {
224        List<WifiConfiguration> configurations = new ArrayList<>();
225        configurations.add(WifiConfigurationTestUtil.createPskHiddenNetwork());
226
227        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
228        List<WifiConfiguration> retrievedConfigurations =
229                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
230        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
231                configurations, retrievedConfigurations);
232    }
233
234    /**
235     * Verify that a single WEP network configuration is serialized & deserialized correctly.
236     */
237    @Test
238    public void testSingleWepNetworkBackupRestore() {
239        List<WifiConfiguration> configurations = new ArrayList<>();
240        configurations.add(WifiConfigurationTestUtil.createWepNetwork());
241
242        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
243        List<WifiConfiguration> retrievedConfigurations =
244                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
245        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
246                configurations, retrievedConfigurations);
247    }
248
249    /**
250     * Verify that restoring of configuration that contains unsupported tags works correctly
251     * (unsupported tags are ignored).
252     */
253    @Test
254    public void testConfigurationWithUnsupportedTagsRestore() {
255        List<WifiConfiguration> configurations = new ArrayList<>();
256        configurations.add(createNetworkForConfigurationWithUnsupportedTag());
257
258        byte[] backupData = WIFI_BACKUP_DATA_WITH_UNSUPPORTED_TAG.getBytes();
259        List<WifiConfiguration> retrievedConfigurations =
260                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
261        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
262                configurations, retrievedConfigurations);
263
264        // No valid data to check in dump.
265        mCheckDump = false;
266    }
267
268    /**
269     * Creates correct WiFiConfiguration that should be parsed out of
270     * {@link #WIFI_BACKUP_DATA_WITH_UNSUPPORTED_TAG} configuration which contains unsupported tag.
271     */
272    private static WifiConfiguration createNetworkForConfigurationWithUnsupportedTag() {
273        final WifiConfiguration config = new WifiConfiguration();
274        config.SSID = "\"GoogleGuest-Legacy\"";
275        config.wepTxKeyIndex = 0;
276        config.hiddenSSID = false;
277        config.requirePMF = false;
278        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
279        config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
280        config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
281        config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
282        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
283        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
284        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
285        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
286        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
287        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
288        config.shared = true;
289
290        IpConfiguration ipConfiguration = new IpConfiguration();
291        ipConfiguration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
292        ipConfiguration.setProxySettings(IpConfiguration.ProxySettings.NONE);
293        config.setIpConfiguration(ipConfiguration);
294
295        return config;
296    }
297
298    /**
299     * Verify that restoring of configuration that contains unsupported values in bitsets works
300     * correctly (unsupported values are ignored).
301     */
302    @Test
303    public void testConfigurationWithUnsupportedValuesInBitsetsRestore() {
304        List<WifiConfiguration> configurations = new ArrayList<>();
305        configurations.add(createNetworkForConfigurationWithUnsupportedValuesInBitsetsInRestore());
306
307        byte[] backupData = WIFI_BACKUP_DATA_WITH_UNSUPPORTED_VALUES_IN_BITSETS.getBytes();
308        List<WifiConfiguration> retrievedConfigurations =
309                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
310        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
311                configurations, retrievedConfigurations);
312
313        // No valid data to check in dump.
314        mCheckDump = false;
315    }
316
317    /**
318     * Creates correct WiFiConfiguration that should be parsed out of
319     * {@link #WIFI_BACKUP_DATA_WITH_UNSUPPORTED_VALUES_IN_BITSETS} configuration which contains
320     * unsupported values.
321     * |AllowedKeyMgmt|, |AllowedProtocols|, |AllowedAuthAlgorithms|, |AllowedGroupCiphers| and
322     * |AllowedPairwiseCiphers| fields have invalid values in them.
323     */
324    private static WifiConfiguration
325            createNetworkForConfigurationWithUnsupportedValuesInBitsetsInRestore() {
326        final WifiConfiguration config = new WifiConfiguration();
327        config.SSID = "\"GoogleGuest-Legacy\"";
328        config.wepTxKeyIndex = 0;
329        config.hiddenSSID = false;
330        config.requirePMF = false;
331        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
332        config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
333        config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
334        config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
335        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
336        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
337        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
338        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
339        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
340        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
341        config.shared = true;
342
343        IpConfiguration ipConfiguration = new IpConfiguration();
344        ipConfiguration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
345        ipConfiguration.setProxySettings(IpConfiguration.ProxySettings.NONE);
346        config.setIpConfiguration(ipConfiguration);
347
348        return config;
349    }
350
351    /**
352     * Verify that a single WEP network configuration with only 1 key is serialized & deserialized
353     * correctly.
354     */
355    @Test
356    public void testSingleWepNetworkWithSingleKeyBackupRestore() {
357        List<WifiConfiguration> configurations = new ArrayList<>();
358        configurations.add(WifiConfigurationTestUtil.createWepNetworkWithSingleKey());
359
360        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
361        List<WifiConfiguration> retrievedConfigurations =
362                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
363        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
364                configurations, retrievedConfigurations);
365    }
366
367    /**
368     * Verify that a single enterprise network configuration is not serialized.
369     */
370    @Test
371    public void testSingleEnterpriseNetworkNotBackupRestore() {
372        List<WifiConfiguration> configurations = new ArrayList<>();
373        configurations.add(WifiConfigurationTestUtil.createEapNetwork());
374
375        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
376        List<WifiConfiguration> retrievedConfigurations =
377                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
378        assertTrue(retrievedConfigurations.isEmpty());
379        // No valid data to check in dump.
380        mCheckDump = false;
381    }
382
383    /**
384     * Verify that a single PSK network configuration with static ip/proxy settings is serialized &
385     * deserialized correctly.
386     */
387    @Test
388    public void testSinglePskNetworkWithStaticIpAndStaticProxyBackupRestore() {
389        List<WifiConfiguration> configurations = new ArrayList<>();
390        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
391        pskNetwork.setIpConfiguration(
392                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
393        configurations.add(pskNetwork);
394
395        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
396        List<WifiConfiguration> retrievedConfigurations =
397                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
398        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
399                configurations, retrievedConfigurations);
400    }
401
402    /**
403     * Verify that a single PSK network configuration with static ip & PAC proxy settings is
404     * serialized & deserialized correctly.
405     */
406    @Test
407    public void testSinglePskNetworkWithStaticIpAndPACProxyBackupRestore() {
408        List<WifiConfiguration> configurations = new ArrayList<>();
409        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
410        pskNetwork.setIpConfiguration(
411                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
412        configurations.add(pskNetwork);
413
414        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
415        List<WifiConfiguration> retrievedConfigurations =
416                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
417        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
418                configurations, retrievedConfigurations);
419    }
420
421    /**
422     * Verify that a single PSK network configuration with DHCP ip & PAC proxy settings is
423     * serialized & deserialized correctly.
424     */
425    @Test
426    public void testSinglePskNetworkWithDHCPIpAndPACProxyBackupRestore() {
427        List<WifiConfiguration> configurations = new ArrayList<>();
428        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
429        pskNetwork.setIpConfiguration(
430                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
431        configurations.add(pskNetwork);
432
433        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
434        List<WifiConfiguration> retrievedConfigurations =
435                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
436        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
437                configurations, retrievedConfigurations);
438    }
439
440    /**
441     * Verify that a single PSK network configuration with partial static ip settings is serialized
442     * & deserialized correctly.
443     */
444    @Test
445    public void testSinglePskNetworkWithPartialStaticIpBackupRestore() {
446        List<WifiConfiguration> configurations = new ArrayList<>();
447        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
448        pskNetwork.setIpConfiguration(
449                WifiConfigurationTestUtil.createPartialStaticIpConfigurationWithPacProxy());
450        configurations.add(pskNetwork);
451
452        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
453        List<WifiConfiguration> retrievedConfigurations =
454                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
455        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
456                configurations, retrievedConfigurations);
457    }
458
459    /**
460     * Verify that multiple networks of different types are serialized and deserialized correctly.
461     */
462    @Test
463    public void testMultipleNetworksAllBackupRestore() {
464        List<WifiConfiguration> configurations = new ArrayList<>();
465        configurations.add(WifiConfigurationTestUtil.createWepNetwork());
466        configurations.add(WifiConfigurationTestUtil.createWepNetwork());
467        configurations.add(WifiConfigurationTestUtil.createPskNetwork());
468        configurations.add(WifiConfigurationTestUtil.createOpenNetwork());
469
470        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
471        List<WifiConfiguration> retrievedConfigurations =
472                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
473        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
474                configurations, retrievedConfigurations);
475    }
476
477    /**
478     * Verify that multiple networks of different types except enterprise ones are serialized and
479     * deserialized correctly
480     */
481    @Test
482    public void testMultipleNetworksNonEnterpriseBackupRestore() {
483        List<WifiConfiguration> configurations = new ArrayList<>();
484        List<WifiConfiguration> expectedConfigurations = new ArrayList<>();
485
486        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
487        configurations.add(wepNetwork);
488        expectedConfigurations.add(wepNetwork);
489
490        configurations.add(WifiConfigurationTestUtil.createEapNetwork());
491
492        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
493        configurations.add(pskNetwork);
494        expectedConfigurations.add(pskNetwork);
495
496        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
497        configurations.add(openNetwork);
498        expectedConfigurations.add(openNetwork);
499
500        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
501        List<WifiConfiguration> retrievedConfigurations =
502                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
503        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
504                expectedConfigurations, retrievedConfigurations);
505    }
506
507    /**
508     * Verify that multiple networks with different credential types and IpConfiguration types are
509     * serialized and deserialized correctly.
510     */
511    @Test
512    public void testMultipleNetworksWithDifferentIpConfigurationsAllBackupRestore() {
513        List<WifiConfiguration> configurations = new ArrayList<>();
514
515        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
516        wepNetwork.setIpConfiguration(
517                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
518        configurations.add(wepNetwork);
519
520        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
521        pskNetwork.setIpConfiguration(
522                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
523        configurations.add(pskNetwork);
524
525        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
526        openNetwork.setIpConfiguration(
527                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
528        configurations.add(openNetwork);
529
530        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
531        List<WifiConfiguration> retrievedConfigurations =
532                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
533        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
534                configurations, retrievedConfigurations);
535    }
536
537    /**
538     * Verify that multiple networks of different types except the non system app created ones are
539     * serialized and deserialized correctly.
540     */
541    @Test
542    public void testMultipleNetworksSystemAppBackupRestore() {
543        int systemAppUid = Process.SYSTEM_UID;
544        int nonSystemAppUid = Process.FIRST_APPLICATION_UID + 556;
545        when(mWifiPermissionsUtil.checkConfigOverridePermission(eq(systemAppUid)))
546                .thenReturn(true);
547        when(mWifiPermissionsUtil.checkConfigOverridePermission(eq(nonSystemAppUid)))
548                .thenReturn(false);
549
550        List<WifiConfiguration> configurations = new ArrayList<>();
551        List<WifiConfiguration> expectedConfigurations = new ArrayList<>();
552
553        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
554        wepNetwork.creatorUid = systemAppUid;
555        configurations.add(wepNetwork);
556        expectedConfigurations.add(wepNetwork);
557
558        // These should not be in |expectedConfigurations|.
559        WifiConfiguration nonSystemAppWepNetwork = WifiConfigurationTestUtil.createWepNetwork();
560        nonSystemAppWepNetwork.creatorUid = nonSystemAppUid;
561        configurations.add(nonSystemAppWepNetwork);
562
563        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
564        pskNetwork.creatorUid = systemAppUid;
565        configurations.add(pskNetwork);
566        expectedConfigurations.add(pskNetwork);
567
568        // These should not be in |expectedConfigurations|.
569        WifiConfiguration nonSystemAppPskNetwork = WifiConfigurationTestUtil.createPskNetwork();
570        nonSystemAppPskNetwork.creatorUid = nonSystemAppUid;
571        configurations.add(nonSystemAppPskNetwork);
572
573        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
574        configurations.add(openNetwork);
575        expectedConfigurations.add(openNetwork);
576
577        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
578        List<WifiConfiguration> retrievedConfigurations =
579                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
580        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
581                expectedConfigurations, retrievedConfigurations);
582    }
583
584    /**
585     * Verify that a single open network configuration is serialized & deserialized correctly from
586     * old backups.
587     */
588    @Test
589    public void testSingleOpenNetworkSupplicantBackupRestore() {
590        List<WifiConfiguration> configurations = new ArrayList<>();
591        configurations.add(WifiConfigurationTestUtil.createOpenNetwork());
592
593        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
594        byte[] ipConfigData = createIpConfBackupData(configurations);
595        List<WifiConfiguration> retrievedConfigurations =
596                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
597                        supplicantData, ipConfigData);
598        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
599                configurations, retrievedConfigurations);
600    }
601
602    /**
603     * Verify that a single open hidden network configuration is serialized & deserialized
604     * correctly from old backups.
605     */
606    @Test
607    public void testSingleOpenHiddenNetworkSupplicantBackupRestore() {
608        List<WifiConfiguration> configurations = new ArrayList<>();
609        configurations.add(WifiConfigurationTestUtil.createOpenHiddenNetwork());
610
611        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
612        byte[] ipConfigData = createIpConfBackupData(configurations);
613        List<WifiConfiguration> retrievedConfigurations =
614                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
615                        supplicantData, ipConfigData);
616        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
617                configurations, retrievedConfigurations);
618    }
619
620    /**
621     * Verify that a single PSK network configuration is serialized & deserialized correctly from
622     * old backups.
623     */
624    @Test
625    public void testSinglePskNetworkSupplicantBackupRestore() {
626        List<WifiConfiguration> configurations = new ArrayList<>();
627        configurations.add(WifiConfigurationTestUtil.createPskNetwork());
628
629        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
630        byte[] ipConfigData = createIpConfBackupData(configurations);
631        List<WifiConfiguration> retrievedConfigurations =
632                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
633                        supplicantData, ipConfigData);
634        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
635                configurations, retrievedConfigurations);
636    }
637
638    /**
639     * Verify that a single PSK hidden network configuration is serialized & deserialized correctly
640     * from old backups.
641     */
642    @Test
643    public void testSinglePskHiddenNetworkSupplicantBackupRestore() {
644        List<WifiConfiguration> configurations = new ArrayList<>();
645        configurations.add(WifiConfigurationTestUtil.createPskHiddenNetwork());
646
647        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
648        byte[] ipConfigData = createIpConfBackupData(configurations);
649        List<WifiConfiguration> retrievedConfigurations =
650                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
651                        supplicantData, ipConfigData);
652        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
653                configurations, retrievedConfigurations);
654    }
655
656    /**
657     * Verify that a single WEP network configuration is serialized & deserialized correctly from
658     * old backups.
659     */
660    @Test
661    public void testSingleWepNetworkSupplicantBackupRestore() {
662        List<WifiConfiguration> configurations = new ArrayList<>();
663        configurations.add(WifiConfigurationTestUtil.createWepNetwork());
664
665        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
666        byte[] ipConfigData = createIpConfBackupData(configurations);
667        List<WifiConfiguration> retrievedConfigurations =
668                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
669                        supplicantData, ipConfigData);
670        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
671                configurations, retrievedConfigurations);
672    }
673
674    /**
675     * Verify that a single WEP network configuration with only 1 key is serialized & deserialized
676     * correctly from old backups.
677     */
678    @Test
679    public void testSingleWepNetworkWithSingleKeySupplicantBackupRestore() {
680        List<WifiConfiguration> configurations = new ArrayList<>();
681        configurations.add(WifiConfigurationTestUtil.createWepNetworkWithSingleKey());
682
683        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
684        byte[] ipConfigData = createIpConfBackupData(configurations);
685        List<WifiConfiguration> retrievedConfigurations =
686                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
687                        supplicantData, ipConfigData);
688        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
689                configurations, retrievedConfigurations);
690    }
691
692    /**
693     * Verify that a single enterprise network configuration is not serialized from old backups.
694     */
695    @Test
696    public void testSingleEnterpriseNetworkNotSupplicantBackupRestore() {
697        List<WifiConfiguration> configurations = new ArrayList<>();
698        configurations.add(WifiConfigurationTestUtil.createEapNetwork());
699
700        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
701        byte[] ipConfigData = createIpConfBackupData(configurations);
702        List<WifiConfiguration> retrievedConfigurations =
703                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
704                        supplicantData, ipConfigData);
705        assertTrue(retrievedConfigurations.isEmpty());
706    }
707
708    /**
709     * Verify that multiple networks with different credential types and IpConfiguration types are
710     * serialized and deserialized correctly from old backups
711     */
712    @Test
713    public void testMultipleNetworksWithDifferentIpConfigurationsAllSupplicantBackupRestore() {
714        List<WifiConfiguration> configurations = new ArrayList<>();
715
716        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
717        wepNetwork.setIpConfiguration(
718                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
719        configurations.add(wepNetwork);
720
721        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
722        pskNetwork.setIpConfiguration(
723                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
724        configurations.add(pskNetwork);
725
726        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
727        openNetwork.setIpConfiguration(
728                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
729        configurations.add(openNetwork);
730
731        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
732        byte[] ipConfigData = createIpConfBackupData(configurations);
733        List<WifiConfiguration> retrievedConfigurations =
734                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
735                        supplicantData, ipConfigData);
736        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
737                configurations, retrievedConfigurations);
738    }
739
740    /**
741     * Verify that a single open network configuration is serialized & deserialized correctly from
742     * old backups with no ipconfig data.
743     */
744    @Test
745    public void testSingleOpenNetworkSupplicantBackupRestoreWithNoIpConfigData() {
746        List<WifiConfiguration> configurations = new ArrayList<>();
747        configurations.add(WifiConfigurationTestUtil.createOpenNetwork());
748
749        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
750        List<WifiConfiguration> retrievedConfigurations =
751                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
752                        supplicantData, null);
753        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
754                configurations, retrievedConfigurations);
755    }
756
757    /**
758     * Verify that multiple networks with different credential types are serialized and
759     * deserialized correctly from old backups with no ipconfig data.
760     */
761    @Test
762    public void testMultipleNetworksAllSupplicantBackupRestoreWithNoIpConfigData() {
763        List<WifiConfiguration> configurations = new ArrayList<>();
764
765        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
766        configurations.add(wepNetwork);
767
768        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
769        configurations.add(pskNetwork);
770
771        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
772        configurations.add(openNetwork);
773
774        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
775        List<WifiConfiguration> retrievedConfigurations =
776                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
777                        supplicantData, null);
778        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
779                configurations, retrievedConfigurations);
780    }
781
782    /**
783     * Verify that multiple networks of different types except the non system app created ones are
784     * serialized and deserialized correctly from old backups.
785     */
786    @Test
787    public void testMultipleNetworksSystemAppSupplicantBackupRestore() {
788        List<WifiConfiguration> configurations = new ArrayList<>();
789        List<WifiConfiguration> expectedConfigurations = new ArrayList<>();
790
791        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
792        configurations.add(wepNetwork);
793        expectedConfigurations.add(wepNetwork);
794
795        // These should not be in |expectedConfigurations|.
796        WifiConfiguration nonSystemAppWepNetwork = WifiConfigurationTestUtil.createWepNetwork();
797        nonSystemAppWepNetwork.creatorUid = Process.FIRST_APPLICATION_UID;
798        configurations.add(nonSystemAppWepNetwork);
799
800        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
801        configurations.add(pskNetwork);
802        expectedConfigurations.add(pskNetwork);
803
804        // These should not be in |expectedConfigurations|.
805        WifiConfiguration nonSystemAppPskNetwork = WifiConfigurationTestUtil.createPskNetwork();
806        nonSystemAppPskNetwork.creatorUid = Process.FIRST_APPLICATION_UID + 1;
807        configurations.add(nonSystemAppPskNetwork);
808
809        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
810        configurations.add(openNetwork);
811        expectedConfigurations.add(openNetwork);
812
813        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
814        byte[] ipConfigData = createIpConfBackupData(configurations);
815        List<WifiConfiguration> retrievedConfigurations =
816                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
817                        supplicantData, ipConfigData);
818        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
819                expectedConfigurations, retrievedConfigurations);
820    }
821
822    /**
823     * Verifying that backup data containing some unknown keys is properly restored.
824     * The backup data used here is a PII masked version of a backup data seen in a reported bug.
825     */
826    @Test
827    public void testSingleNetworkSupplicantBackupRestoreWithUnknownEAPKey() {
828        String backupSupplicantConfNetworkBlock = "network={\n"
829                + "ssid=" + WifiConfigurationTestUtil.TEST_SSID + "\n"
830                + "psk=" + WifiConfigurationTestUtil.TEST_PSK + "\n"
831                + "key_mgmt=WPA-PSK WPA-PSK-SHA256\n"
832                + "priority=18\n"
833                + "id_str=\"%7B%22creatorUid%22%3A%221000%22%2C%22configKey"
834                + "%22%3A%22%5C%22BLAH%5C%22WPA_PSK%22%7D\"\n"
835                + "eapRetryCount=6\n";
836        byte[] supplicantData = backupSupplicantConfNetworkBlock.getBytes();
837        List<WifiConfiguration> retrievedConfigurations =
838                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
839                        supplicantData, null);
840
841        final WifiConfiguration expectedConfiguration = new WifiConfiguration();
842        expectedConfiguration.SSID = WifiConfigurationTestUtil.TEST_SSID;
843        expectedConfiguration.preSharedKey = WifiConfigurationTestUtil.TEST_PSK;
844        expectedConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
845
846        ArrayList<WifiConfiguration> expectedConfigurations = new ArrayList<WifiConfiguration>() {{
847                add(expectedConfiguration);
848            }};
849        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
850                expectedConfigurations, retrievedConfigurations);
851    }
852
853    /**
854     * Verify that any corrupted data provided by Backup/Restore is ignored correctly.
855     */
856    @Test
857    public void testCorruptBackupRestore() {
858        Random random = new Random();
859        byte[] backupData = new byte[100];
860        random.nextBytes(backupData);
861
862        List<WifiConfiguration> retrievedConfigurations =
863                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
864        assertNull(retrievedConfigurations);
865        // No valid data to check in dump.
866        mCheckDump = false;
867    }
868
869    /**
870     * Helper method to write a list of networks in wpa_supplicant.conf format to the output stream.
871     */
872    private byte[] createWpaSupplicantConfBackupData(List<WifiConfiguration> configurations) {
873        ByteArrayOutputStream bos = new ByteArrayOutputStream();
874        OutputStreamWriter out = new OutputStreamWriter(bos);
875        try {
876            for (WifiConfiguration configuration : configurations) {
877                writeConfigurationToWpaSupplicantConf(out, configuration);
878            }
879            out.flush();
880            return bos.toByteArray();
881        } catch (IOException e) {
882            return null;
883        }
884    }
885
886    /**
887     * Helper method to write a network in wpa_supplicant.conf format to the output stream.
888     * This was created using a sample wpa_supplicant.conf file. Using the raw key strings here
889     * (instead of consts in WifiBackupRestore).
890     */
891    private void writeConfigurationToWpaSupplicantConf(
892            OutputStreamWriter out, WifiConfiguration configuration)
893            throws IOException {
894        out.write("network={\n");
895        out.write("        " + "ssid=" + configuration.SSID + "\n");
896        String allowedKeyManagement = "";
897        if (configuration.hiddenSSID) {
898            out.write("        " + "scan_ssid=1" + "\n");
899        }
900        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) {
901            allowedKeyManagement += "NONE";
902        }
903        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
904            allowedKeyManagement += "WPA-PSK ";
905        }
906        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
907            allowedKeyManagement += "WPA-EAP ";
908        }
909        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) {
910            allowedKeyManagement += "IEEE8021X ";
911        }
912        out.write("        " + "key_mgmt=" + allowedKeyManagement + "\n");
913        if (configuration.preSharedKey != null) {
914            out.write("        " + "psk=" + configuration.preSharedKey + "\n");
915        }
916        if (configuration.wepKeys[0] != null) {
917            out.write("        " + "wep_key0=" + configuration.wepKeys[0] + "\n");
918        }
919        if (configuration.wepKeys[1] != null) {
920            out.write("        " + "wep_key1=" + configuration.wepKeys[1] + "\n");
921        }
922        if (configuration.wepKeys[2] != null) {
923            out.write("        " + "wep_key2=" + configuration.wepKeys[2] + "\n");
924        }
925        if (configuration.wepKeys[3] != null) {
926            out.write("        " + "wep_key3=" + configuration.wepKeys[3] + "\n");
927        }
928        if (configuration.wepKeys[0] != null || configuration.wepKeys[1] != null
929                || configuration.wepKeys[2] != null || configuration.wepKeys[3] != null) {
930            out.write("        " + "wep_tx_keyidx=" + configuration.wepTxKeyIndex + "\n");
931        }
932        Map<String, String> extras = new HashMap<>();
933        extras.put(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY, configuration.configKey());
934        extras.put(SupplicantStaNetworkHal.ID_STRING_KEY_CREATOR_UID,
935                Integer.toString(configuration.creatorUid));
936        String idString = "\"" + SupplicantStaNetworkHal.createNetworkExtra(extras) + "\"";
937        if (idString != null) {
938            out.write("        " + "id_str=" + idString + "\n");
939        }
940        out.write("}\n");
941        out.write("\n");
942    }
943
944    /**
945     * Helper method to write a list of networks in ipconfig.txt format to the output stream.
946     */
947    private byte[] createIpConfBackupData(List<WifiConfiguration> configurations) {
948        ByteArrayOutputStream bos = new ByteArrayOutputStream();
949        DataOutputStream out = new DataOutputStream(bos);
950        final int configStoreVersion = 2;
951        try {
952            // write version first.
953            out.writeInt(configStoreVersion);
954            for (WifiConfiguration configuration : configurations) {
955                // TODO: store configKey as a string instead of calculating its hash
956                IpConfigStore.writeConfig(out, String.valueOf(configuration.configKey().hashCode()),
957                        configuration.getIpConfiguration(), configStoreVersion);
958            }
959            out.flush();
960            return bos.toByteArray();
961        } catch (IOException e) {
962            return null;
963        }
964    }
965}
966