diff options
author | Yuyang Huang <yuyanghuang@google.com> | 2023-08-08 11:42:18 +0900 |
---|---|---|
committer | Yuyang Huang <yuyanghuang@google.com> | 2023-08-24 16:48:48 +0900 |
commit | 3f6adaa0a5e458574b49c51ce6df04b7885e4079 (patch) | |
tree | a96fe3b61bb89149225505486168c58ae40acde2 | |
parent | 027be158fc418d7838d47ff4f8541918822da6f6 (diff) | |
download | net-3f6adaa0a5e458574b49c51ce6df04b7885e4079.tar.gz |
Add util to check if permission has system signature
Bug: 294777050
Test: m
Change-Id: I66e94595ce5f4ab3b4f372e4e5e6cb06dc686c21
-rw-r--r-- | common/framework/com/android/net/module/util/PermissionUtils.java | 22 | ||||
-rw-r--r-- | common/tests/unit/src/com/android/net/module/util/PermissionUtilsTest.kt | 137 |
2 files changed, 112 insertions, 47 deletions
diff --git a/common/framework/com/android/net/module/util/PermissionUtils.java b/common/framework/com/android/net/module/util/PermissionUtils.java index 8315b8f6..d5b4c90a 100644 --- a/common/framework/com/android/net/module/util/PermissionUtils.java +++ b/common/framework/com/android/net/module/util/PermissionUtils.java @@ -21,12 +21,15 @@ import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.NETWORK_STACK; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.content.pm.PermissionInfo.PROTECTION_SIGNATURE; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PermissionInfo; import android.os.Binder; import java.io.PrintWriter; @@ -54,6 +57,25 @@ public final class PermissionUtils { } /** + * Return true if the permission has system signature. + */ + public static boolean isSystemSignaturePermission(@NonNull Context context, + @NonNull String permission) { + try { + PermissionInfo permissionInfo = context.getPackageManager().getPermissionInfo( + permission, 0 /* flags */); + if (permissionInfo == null) { + return false; + } + return "android".equals(permissionInfo.packageName) + && permissionInfo.getProtection() == PROTECTION_SIGNATURE; + } catch (PackageManager.NameNotFoundException ignored) { + // Ignored the NameNotFoundException and return false + } + return false; + } + + /** * Return true if the context has one of give permission that is allowed * for a particular process and user ID running in the system. */ diff --git a/common/tests/unit/src/com/android/net/module/util/PermissionUtilsTest.kt b/common/tests/unit/src/com/android/net/module/util/PermissionUtilsTest.kt index 1b6cbcb0..028308b3 100644 --- a/common/tests/unit/src/com/android/net/module/util/PermissionUtilsTest.kt +++ b/common/tests/unit/src/com/android/net/module/util/PermissionUtilsTest.kt @@ -16,96 +16,115 @@ package com.android.net.module.util +import android.Manifest.permission.INTERNET +import android.Manifest.permission.NETWORK_SETTINGS import android.Manifest.permission.NETWORK_STACK import android.content.Context import android.content.pm.PackageManager import android.content.pm.PackageManager.PERMISSION_DENIED import android.content.pm.PackageManager.PERMISSION_GRANTED import android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK +import android.os.Build import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry import com.android.net.module.util.PermissionUtils.checkAnyPermissionOf import com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf import com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission import com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr import com.android.net.module.util.PermissionUtils.enforceSystemFeature +import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.DevSdkIgnoreRunner +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertFalse +import kotlin.test.assertTrue import org.junit.Assert -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers import org.mockito.ArgumentMatchers.any import org.mockito.Mockito.doReturn import org.mockito.Mockito.mock -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith /** Tests for PermissionUtils */ -@RunWith(AndroidJUnit4::class) +@RunWith(DevSdkIgnoreRunner::class) @SmallTest class PermissionUtilsTest { + @get:Rule + val ignoreRule = DevSdkIgnoreRule() private val TEST_PERMISSION1 = "android.permission.TEST_PERMISSION1" private val TEST_PERMISSION2 = "android.permission.TEST_PERMISSION2" - private val context = mock(Context::class.java) - private val packageManager = mock(PackageManager::class.java) + private val mockContext = mock(Context::class.java) + private val mockPackageManager = mock(PackageManager::class.java) + + private val context by lazy { InstrumentationRegistry.getInstrumentation().context } @Before fun setup() { - doReturn(packageManager).`when`(context).packageManager + doReturn(mockPackageManager).`when`(mockContext).packageManager } @Test fun testEnforceAnyPermissionOf() { - doReturn(PERMISSION_GRANTED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION1) - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION2) - assertTrue(checkAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2)) - enforceAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2) - - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION1) - doReturn(PERMISSION_GRANTED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION2) - assertTrue(checkAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2)) - enforceAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2) - - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(any()) - assertFalse(checkAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2)) + doReturn(PERMISSION_GRANTED).`when`(mockContext) + .checkCallingOrSelfPermission(TEST_PERMISSION1) + doReturn(PERMISSION_DENIED).`when`(mockContext) + .checkCallingOrSelfPermission(TEST_PERMISSION2) + assertTrue(checkAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2)) + enforceAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2) + + doReturn(PERMISSION_DENIED).`when`(mockContext) + .checkCallingOrSelfPermission(TEST_PERMISSION1) + doReturn(PERMISSION_GRANTED).`when`(mockContext) + .checkCallingOrSelfPermission(TEST_PERMISSION2) + assertTrue(checkAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2)) + enforceAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2) + + doReturn(PERMISSION_DENIED).`when`(mockContext).checkCallingOrSelfPermission(any()) + assertFalse(checkAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2)) assertFailsWith<SecurityException>("Expect fail but permission granted.") { - enforceAnyPermissionOf(context, TEST_PERMISSION1, TEST_PERMISSION2) } + enforceAnyPermissionOf(mockContext, TEST_PERMISSION1, TEST_PERMISSION2) + } } @Test fun testEnforceNetworkStackPermissionOr() { - doReturn(PERMISSION_GRANTED).`when`(context).checkCallingOrSelfPermission(NETWORK_STACK) - doReturn(PERMISSION_DENIED).`when`(context) - .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK) - enforceNetworkStackPermission(context) - enforceNetworkStackPermissionOr(context, TEST_PERMISSION1) - - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(NETWORK_STACK) - doReturn(PERMISSION_GRANTED).`when`(context) - .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK) - enforceNetworkStackPermission(context) - enforceNetworkStackPermissionOr(context, TEST_PERMISSION2) - - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(NETWORK_STACK) - doReturn(PERMISSION_DENIED).`when`(context) - .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK) - doReturn(PERMISSION_GRANTED).`when`(context).checkCallingOrSelfPermission(TEST_PERMISSION1) + doReturn(PERMISSION_GRANTED).`when`(mockContext).checkCallingOrSelfPermission(NETWORK_STACK) + doReturn(PERMISSION_DENIED).`when`(mockContext) + .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK) + enforceNetworkStackPermission(mockContext) + enforceNetworkStackPermissionOr(mockContext, TEST_PERMISSION1) + + doReturn(PERMISSION_DENIED).`when`(mockContext).checkCallingOrSelfPermission(NETWORK_STACK) + doReturn(PERMISSION_GRANTED).`when`(mockContext) + .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK) + enforceNetworkStackPermission(mockContext) + enforceNetworkStackPermissionOr(mockContext, TEST_PERMISSION2) + + doReturn(PERMISSION_DENIED).`when`(mockContext).checkCallingOrSelfPermission(NETWORK_STACK) + doReturn(PERMISSION_DENIED).`when`(mockContext) + .checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK) + doReturn(PERMISSION_GRANTED).`when`(mockContext) + .checkCallingOrSelfPermission(TEST_PERMISSION1) assertFailsWith<SecurityException>("Expect fail but permission granted.") { - enforceNetworkStackPermission(context) } - enforceNetworkStackPermissionOr(context, TEST_PERMISSION1) + enforceNetworkStackPermission(mockContext) + } + enforceNetworkStackPermissionOr(mockContext, TEST_PERMISSION1) - doReturn(PERMISSION_DENIED).`when`(context).checkCallingOrSelfPermission(any()) + doReturn(PERMISSION_DENIED).`when`(mockContext).checkCallingOrSelfPermission(any()) assertFailsWith<SecurityException>("Expect fail but permission granted.") { - enforceNetworkStackPermission(context) } + enforceNetworkStackPermission(mockContext) + } assertFailsWith<SecurityException>("Expect fail but permission granted.") { - enforceNetworkStackPermissionOr(context, TEST_PERMISSION2) } + enforceNetworkStackPermissionOr(mockContext, TEST_PERMISSION2) + } } private fun mockHasSystemFeature(featureName: String, hasFeature: Boolean) { - doReturn(hasFeature).`when`(packageManager) - .hasSystemFeature(ArgumentMatchers.eq(featureName)) + doReturn(hasFeature).`when`(mockPackageManager) + .hasSystemFeature(ArgumentMatchers.eq(featureName)) } @Test @@ -114,14 +133,38 @@ class PermissionUtilsTest { val exceptionMessage = "test exception message" mockHasSystemFeature(featureName = systemFeature, hasFeature = false) val e = assertFailsWith<UnsupportedOperationException>("Should fail without feature") { - enforceSystemFeature(context, systemFeature, exceptionMessage) } + enforceSystemFeature(mockContext, systemFeature, exceptionMessage) + } assertEquals(exceptionMessage, e.message) mockHasSystemFeature(featureName = systemFeature, hasFeature = true) try { - enforceSystemFeature(context, systemFeature, "") + enforceSystemFeature(mockContext, systemFeature, "") } catch (e: UnsupportedOperationException) { Assert.fail("Exception should have not been thrown with system feature enabled") } } + + @Test + @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2) + fun testIsSystemSignaturePermission() { + assertTrue( + PermissionUtils.isSystemSignaturePermission( + context, + NETWORK_SETTINGS + ) + ) + assertFalse( + PermissionUtils + .isSystemSignaturePermission(context, PERMISSION_MAINLINE_NETWORK_STACK) + ) + assertFalse( + PermissionUtils + .isSystemSignaturePermission(context, "test_permission") + ) + assertFalse( + PermissionUtils + .isSystemSignaturePermission(context, INTERNET) + ) + } } |