1 /*
2  * Copyright (C) 2024 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 android.security.cts.CVE_2024_31332;
18 
19 import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
20 
21 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
22 
23 import static com.android.sts.common.DumpsysUtils.isActivityVisible;
24 import static com.android.sts.common.SystemUtil.poll;
25 
26 import static com.google.common.truth.Truth.assertWithMessage;
27 import static com.google.common.truth.TruthJUnit.assume;
28 
29 import android.app.admin.DevicePolicyManager;
30 import android.content.ComponentName;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.net.Uri;
34 import android.net.wifi.WifiManager;
35 import android.provider.Settings;
36 
37 import androidx.test.runner.AndroidJUnit4;
38 
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 
42 import java.util.function.BooleanSupplier;
43 
44 @RunWith(AndroidJUnit4.class)
45 public class DeviceTest {
46 
47     @Test
testCVE_2024_31332()48     public void testCVE_2024_31332() {
49         try {
50             // Check for easy connect support
51             final Context context = getApplicationContext();
52             final WifiManager wifiManager = context.getSystemService(WifiManager.class);
53             assume().withMessage(
54                             "Current device does not support easy connect."
55                                     + " Hence, CTS for CVE-2024-31332 cannot be validated.")
56                     .that(wifiManager.isEasyConnectSupported())
57                     .isTrue();
58 
59             // Fetch 'DeviceOwnerComponentName' from 'DevicePolicyManager'
60             final DevicePolicyManager devicePolicyManager =
61                     context.getSystemService(DevicePolicyManager.class);
62             final ComponentName deviceOwnerComponentName =
63                     devicePolicyManager.getDeviceOwnerComponentOnCallingUser();
64             assume().withMessage(
65                             "Unable to get 'DeviceOwnerComponentName' from DevicePolicyManager")
66                     .that(deviceOwnerComponentName)
67                     .isNotNull();
68 
69             // Check whether 'PocDeviceAdminReceiver' is set as device owner
70             final ComponentName pocDeviceAdminReceiverComponentName =
71                     new ComponentName(context, PocDeviceAdminReceiver.class);
72             assume().withMessage("Unable to set 'PocDeviceAdminReceiver' as device owner")
73                     .that(deviceOwnerComponentName.flattenToString())
74                     .isEqualTo(pocDeviceAdminReceiverComponentName.flattenToString());
75 
76             try (AutoCloseable withDisallowAddWifiConfigRestriction =
77                     withDisallowAddWifiConfigRestriction(
78                             devicePolicyManager, pocDeviceAdminReceiverComponentName)) {
79                 // Launch activity to reproduce the vulnerability
80                 final int cveBugId = 299931076;
81                 final String mockQrCode = String.format("DPP:I:%d;K:%d;", cveBugId, cveBugId);
82                 final Intent intent = new Intent(Settings.ACTION_PROCESS_WIFI_EASY_CONNECT_URI);
83                 context.startActivity(
84                         intent.setData(Uri.parse(mockQrCode))
85                                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
86 
87                 // Without fix 'WifiDppConfiguratorActivity' launches and test fails
88                 final String activityName =
89                         intent.resolveActivity(context.getPackageManager()).flattenToString();
90                 assertWithMessage(
91                                 "Device is vulnerable to b/299931076 !! Connect to an untrusted"
92                                         + " Wi-Fi network through WifiDppConfiguratorActivity.")
93                         .that(poll(() -> isActivityVisible(activityName)))
94                         .isFalse();
95             }
96         } catch (Exception e) {
97             assume().that(e).isNull();
98         }
99     }
100 
withDisallowAddWifiConfigRestriction( DevicePolicyManager devicePolicyManager, ComponentName componentName)101     private AutoCloseable withDisallowAddWifiConfigRestriction(
102             DevicePolicyManager devicePolicyManager, ComponentName componentName) throws Exception {
103         // Return if 'DISALLOW_ADD_WIFI_CONFIG' restriction is already set
104         final BooleanSupplier userRestriction =
105                 () ->
106                         devicePolicyManager
107                                 .getUserRestrictions(componentName)
108                                 .getBoolean(DISALLOW_ADD_WIFI_CONFIG);
109         if (userRestriction.getAsBoolean()) {
110             return () -> {};
111         }
112 
113         // Set 'DISALLOW_ADD_WIFI_CONFIG' restriction
114         devicePolicyManager.addUserRestriction(componentName, DISALLOW_ADD_WIFI_CONFIG);
115         assume().withMessage("Failed to set 'DISALLOW_ADD_WIFI_CONFIG' restriction")
116                 .that(userRestriction.getAsBoolean())
117                 .isTrue();
118 
119         // Remove 'DISALLOW_ADD_WIFI_CONFIG' restriction
120         return () ->
121                 devicePolicyManager.clearUserRestriction(componentName, DISALLOW_ADD_WIFI_CONFIG);
122     }
123 }
124