1 /*
2  * Copyright (C) 2021 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.net.module.util
18 
19 import android.Manifest.permission.NETWORK_STACK
20 import android.content.Context
21 import android.content.pm.PackageManager
22 import android.content.pm.PackageManager.NameNotFoundException
23 import android.content.pm.PackageManager.PERMISSION_DENIED
24 import android.content.pm.PackageManager.PERMISSION_GRANTED
25 import android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
26 import androidx.test.filters.SmallTest
27 import androidx.test.platform.app.InstrumentationRegistry
28 import com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf
29 import com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission
30 import com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr
31 import com.android.net.module.util.PermissionUtils.enforcePackageNameMatchesUid
32 import com.android.net.module.util.PermissionUtils.enforceSystemFeature
33 import com.android.net.module.util.PermissionUtils.hasAnyPermissionOf
34 import com.android.testutils.DevSdkIgnoreRule
35 import com.android.testutils.DevSdkIgnoreRunner
36 import kotlin.test.assertEquals
37 import kotlin.test.assertFailsWith
38 import kotlin.test.assertFalse
39 import kotlin.test.assertTrue
40 import org.junit.Assert
41 import org.junit.Before
42 import org.junit.Rule
43 import org.junit.Test
44 import org.junit.runner.RunWith
45 import org.mockito.ArgumentMatchers
46 import org.mockito.ArgumentMatchers.any
47 import org.mockito.ArgumentMatchers.anyInt
48 import org.mockito.ArgumentMatchers.eq
49 import org.mockito.Mockito.doReturn
50 import org.mockito.Mockito.doThrow
51 import org.mockito.Mockito.mock
52 
53 /** Tests for PermissionUtils */
54 @RunWith(DevSdkIgnoreRunner::class)
55 @SmallTest
56 class PermissionUtilsTest {
57     @get:Rule
58     val ignoreRule = DevSdkIgnoreRule()
59     private val TEST_PERMISSION1 = "android.permission.TEST_PERMISSION1"
60     private val TEST_PERMISSION2 = "android.permission.TEST_PERMISSION2"
61     private val TEST_UID1 = 1234
62     private val TEST_UID2 = 1235
63     private val TEST_PACKAGE_NAME = "test.package"
64     private val mockContext = mock(Context::class.java)
65     private val mockPackageManager = mock(PackageManager::class.java)
66 
<lambda>null67     private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
68 
69     @Before
setupnull70     fun setup() {
71         doReturn(mockPackageManager).`when`(mockContext).packageManager
72         doReturn(mockContext).`when`(mockContext).createContextAsUser(any(), anyInt())
73     }
74 
75     @Test
testEnforceAnyPermissionOfnull76     fun testEnforceAnyPermissionOf() {
77         doReturn(PERMISSION_GRANTED).`when`(mockContext)
78             .checkCallingOrSelfPermission(TEST_PERMISSION1)
79         doReturn(PERMISSION_DENIED).`when`(mockContext)
80             .checkCallingOrSelfPermission(TEST_PERMISSION2)
81         assertTrue(hasAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2))
82         enforceAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2)
83 
84         doReturn(PERMISSION_DENIED).`when`(mockContext)
85             .checkCallingOrSelfPermission(TEST_PERMISSION1)
86         doReturn(PERMISSION_GRANTED).`when`(mockContext)
87             .checkCallingOrSelfPermission(TEST_PERMISSION2)
88         assertTrue(hasAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2))
89         enforceAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2)
90 
91         doReturn(PERMISSION_DENIED).`when`(mockContext).checkCallingOrSelfPermission(any())
92         assertFalse(hasAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2))
93         assertFailsWith<SecurityException>("Expect fail but permission granted.") {
94             enforceAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2)
95         }
96     }
97 
98     @Test
testEnforceNetworkStackPermissionOrnull99     fun testEnforceNetworkStackPermissionOr() {
100         doReturn(PERMISSION_GRANTED).`when`(mockContext).checkCallingOrSelfPermission(NETWORK_STACK)
101         doReturn(PERMISSION_DENIED).`when`(mockContext)
102             .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK)
103         enforceNetworkStackPermission(mockContext)
104         enforceNetworkStackPermissionOr(mockContext, TEST_PERMISSION1)
105 
106         doReturn(PERMISSION_DENIED).`when`(mockContext).checkCallingOrSelfPermission(NETWORK_STACK)
107         doReturn(PERMISSION_GRANTED).`when`(mockContext)
108             .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK)
109         enforceNetworkStackPermission(mockContext)
110         enforceNetworkStackPermissionOr(mockContext, TEST_PERMISSION2)
111 
112         doReturn(PERMISSION_DENIED).`when`(mockContext).checkCallingOrSelfPermission(NETWORK_STACK)
113         doReturn(PERMISSION_DENIED).`when`(mockContext)
114             .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK)
115         doReturn(PERMISSION_GRANTED).`when`(mockContext)
116             .checkCallingOrSelfPermission(TEST_PERMISSION1)
117         assertFailsWith<SecurityException>("Expect fail but permission granted.") {
118             enforceNetworkStackPermission(mockContext)
119         }
120         enforceNetworkStackPermissionOr(mockContext, TEST_PERMISSION1)
121 
122         doReturn(PERMISSION_DENIED).`when`(mockContext).checkCallingOrSelfPermission(any())
123         assertFailsWith<SecurityException>("Expect fail but permission granted.") {
124             enforceNetworkStackPermission(mockContext)
125         }
126         assertFailsWith<SecurityException>("Expect fail but permission granted.") {
127             enforceNetworkStackPermissionOr(mockContext, TEST_PERMISSION2)
128         }
129     }
130 
mockHasSystemFeaturenull131     private fun mockHasSystemFeature(featureName: String, hasFeature: Boolean) {
132         doReturn(hasFeature).`when`(mockPackageManager)
133             .hasSystemFeature(ArgumentMatchers.eq(featureName))
134     }
135 
136     @Test
testEnforceSystemFeaturenull137     fun testEnforceSystemFeature() {
138         val systemFeature = "test.system.feature"
139         val exceptionMessage = "test exception message"
140         mockHasSystemFeature(featureName = systemFeature, hasFeature = false)
141         val e = assertFailsWith<UnsupportedOperationException>("Should fail without feature") {
142             enforceSystemFeature(mockContext, systemFeature, exceptionMessage)
143         }
144         assertEquals(exceptionMessage, e.message)
145 
146         mockHasSystemFeature(featureName = systemFeature, hasFeature = true)
147         try {
148             enforceSystemFeature(mockContext, systemFeature, "")
149         } catch (e: UnsupportedOperationException) {
150             Assert.fail("Exception should have not been thrown with system feature enabled")
151         }
152     }
153 
154     @Test
testEnforcePackageNameMatchesUidnull155     fun testEnforcePackageNameMatchesUid() {
156         // Verify name not found throws.
157         doThrow(NameNotFoundException()).`when`(mockPackageManager)
158             .getPackageUid(eq(TEST_PACKAGE_NAME), anyInt())
159         assertFailsWith<SecurityException> {
160             enforcePackageNameMatchesUid(mockContext, TEST_UID1, TEST_PACKAGE_NAME)
161         }
162 
163         // Verify uid mismatch throws.
164         doReturn(TEST_UID1).`when`(mockPackageManager)
165             .getPackageUid(eq(TEST_PACKAGE_NAME), anyInt())
166         assertFailsWith<SecurityException> {
167             enforcePackageNameMatchesUid(mockContext, TEST_UID2, TEST_PACKAGE_NAME)
168         }
169 
170         // Verify uid match passes.
171         enforcePackageNameMatchesUid(mockContext, TEST_UID1, TEST_PACKAGE_NAME)
172     }
173 }
174