• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.devicepolicy.cts;
18 
19 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
20 import static android.content.pm.PackageManager.FEATURE_SECURE_LOCK_SCREEN;
21 
22 import static com.android.bedstead.remotedpc.RemoteDpc.DPC_COMPONENT_NAME;
23 
24 import static com.google.common.truth.Truth.assertThat;
25 
26 import static org.junit.Assert.fail;
27 
28 import android.app.admin.RemoteDevicePolicyManager;
29 import android.content.ComponentName;
30 
31 import com.android.bedstead.harrier.BedsteadJUnit4;
32 import com.android.bedstead.harrier.DeviceState;
33 import com.android.bedstead.harrier.annotations.Postsubmit;
34 import com.android.bedstead.harrier.annotations.RequireDoesNotHaveFeature;
35 import com.android.bedstead.harrier.annotations.RequireFeature;
36 import com.android.bedstead.harrier.annotations.enterprise.CanSetPolicyTest;
37 import com.android.bedstead.harrier.policies.LockscreenPolicyWithUnifiedChallenge;
38 import com.android.bedstead.harrier.policies.ScreenCaptureDisabled;
39 import com.android.bedstead.testapp.TestApp;
40 import com.android.bedstead.testapp.TestAppInstance;
41 
42 import org.junit.ClassRule;
43 import org.junit.Rule;
44 import org.junit.runner.RunWith;
45 
46 import java.util.function.BiConsumer;
47 
48 /**
49  * Test that DevicePolicyManager getters that accept "ComponentName who" argument don't allow a
50  * different app to probe for admins when policy is set: those getters should only allow either
51  * calls where "who" is null or "who" is not null and belongs to caller. SecurityExceptions that are
52  * thrown otherwise shouldn't leak that data either.
53  */
54 // Password policies aren't supported on automotive
55 @RequireDoesNotHaveFeature(FEATURE_AUTOMOTIVE)
56 @RequireFeature(FEATURE_SECURE_LOCK_SCREEN)
57 @RunWith(BedsteadJUnit4.class)
58 public class NoAdminLeakingTest {
59     @ClassRule
60     @Rule
61     public static final DeviceState sDeviceState = new DeviceState();
62 
63     private static final TestApp sTestApp = sDeviceState.testApps().any();
64 
65     @Postsubmit(reason = "new test")
66     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordQuality_adminPolicyNotAvailableToNonAdmin()67     public void passwordQuality_adminPolicyNotAvailableToNonAdmin() {
68         assertOnlyAggregatePolicyAvailableToNonAdmin(
69                 (dpm, who) -> dpm.getPasswordQuality(who));
70     }
71 
72     @Postsubmit(reason = "new test")
73     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordMinimumLength_adminPolicyNotAvailableToNonAdmin()74     public void passwordMinimumLength_adminPolicyNotAvailableToNonAdmin() {
75         assertOnlyAggregatePolicyAvailableToNonAdmin(
76                 (dpm, who) -> dpm.getPasswordMinimumLength(who));
77     }
78 
79     @Postsubmit(reason = "new test")
80     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordMinimumLetters_adminPolicyNotAvailableToNonAdmin()81     public void passwordMinimumLetters_adminPolicyNotAvailableToNonAdmin() {
82         assertOnlyAggregatePolicyAvailableToNonAdmin(
83                 (dpm, who) -> dpm.getPasswordMinimumLetters(who));
84     }
85 
86     @Postsubmit(reason = "new test")
87     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordMinimumNonLetter_adminPolicyNotAvailableToNonAdmin()88     public void passwordMinimumNonLetter_adminPolicyNotAvailableToNonAdmin() {
89         assertOnlyAggregatePolicyAvailableToNonAdmin(
90                 (dpm, who) -> dpm.getPasswordMinimumNonLetter(who));
91     }
92 
93     @Postsubmit(reason = "new test")
94     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordMinimumLowerCase_adminPolicyNotAvailableToNonAdmin()95     public void passwordMinimumLowerCase_adminPolicyNotAvailableToNonAdmin() {
96         assertOnlyAggregatePolicyAvailableToNonAdmin(
97                 (dpm, who) -> dpm.getPasswordMinimumLowerCase(who));
98     }
99 
100     @Postsubmit(reason = "new test")
101     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordMinimumUpperCase_adminPolicyNotAvailableToNonAdmin()102     public void passwordMinimumUpperCase_adminPolicyNotAvailableToNonAdmin() {
103         assertOnlyAggregatePolicyAvailableToNonAdmin(
104                 (dpm, who) -> dpm.getPasswordMinimumUpperCase(who));
105     }
106 
107     @Postsubmit(reason = "new test")
108     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordMinimumNumeric_adminPolicyNotAvailableToNonAdmin()109     public void passwordMinimumNumeric_adminPolicyNotAvailableToNonAdmin() {
110         assertOnlyAggregatePolicyAvailableToNonAdmin(
111                 (dpm, who) -> dpm.getPasswordMinimumNumeric(who));
112     }
113 
114     @Postsubmit(reason = "new test")
115     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordMinimumSymbols_adminPolicyNotAvailableToNonAdmin()116     public void passwordMinimumSymbols_adminPolicyNotAvailableToNonAdmin() {
117         assertOnlyAggregatePolicyAvailableToNonAdmin(
118                 (dpm, who) -> dpm.getPasswordMinimumSymbols(who));
119     }
120 
121     @Postsubmit(reason = "new test")
122     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordHistoryLength_adminPolicyNotAvailableToNonAdmin()123     public void passwordHistoryLength_adminPolicyNotAvailableToNonAdmin() {
124         assertOnlyAggregatePolicyAvailableToNonAdmin(
125                 (dpm, who) -> dpm.getPasswordHistoryLength(who));
126     }
127 
128     @Postsubmit(reason = "new test")
129     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordExpiration_adminPolicyNotAvailableToNonAdmin()130     public void passwordExpiration_adminPolicyNotAvailableToNonAdmin() {
131         assertOnlyAggregatePolicyAvailableToNonAdmin(
132                 (dpm, who) -> dpm.getPasswordExpiration(who));
133     }
134 
135     @Postsubmit(reason = "new test")
136     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
passwordExpirationTimeout_adminPolicyNotAvailableToNonAdmin()137     public void passwordExpirationTimeout_adminPolicyNotAvailableToNonAdmin() {
138         assertOnlyAggregatePolicyAvailableToNonAdmin(
139                 (dpm, who) -> dpm.getPasswordExpirationTimeout(who));
140     }
141 
142     @Postsubmit(reason = "new test")
143     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
maximumFailedPasswordsForWipe_adminPolicyNotAvailableToNonAdmin()144     public void maximumFailedPasswordsForWipe_adminPolicyNotAvailableToNonAdmin() {
145         assertOnlyAggregatePolicyAvailableToNonAdmin(
146                 (dpm, who) -> dpm.getMaximumFailedPasswordsForWipe(who));
147     }
148 
149     @Postsubmit(reason = "new test")
150     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
maximumTimeToLock_adminPolicyNotAvailableToNonAdmin()151     public void maximumTimeToLock_adminPolicyNotAvailableToNonAdmin() {
152         assertOnlyAggregatePolicyAvailableToNonAdmin(
153                 (dpm, who) -> dpm.getMaximumTimeToLock(who));
154     }
155 
156     @Postsubmit(reason = "new test")
157     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
requiredStrongAuthTimeout_adminPolicyNotAvailableToNonAdmin()158     public void requiredStrongAuthTimeout_adminPolicyNotAvailableToNonAdmin() {
159         assertOnlyAggregatePolicyAvailableToNonAdmin(
160                 (dpm, who) -> dpm.getRequiredStrongAuthTimeout(who));
161     }
162 
163     @Postsubmit(reason = "new test")
164     @CanSetPolicyTest(policy = ScreenCaptureDisabled.class)
screenCaptureDisabled_adminPolicyNotAvailableToNonAdmin()165     public void screenCaptureDisabled_adminPolicyNotAvailableToNonAdmin() {
166         assertOnlyAggregatePolicyAvailableToNonAdmin(
167                 (dpm, who) -> dpm.getScreenCaptureDisabled(who));
168     }
169 
170     @Postsubmit(reason = "new test")
171     @CanSetPolicyTest(policy = LockscreenPolicyWithUnifiedChallenge.class)
trustAgentConfiguration_adminPolicyNotAvailableToNonAdmin()172     public void trustAgentConfiguration_adminPolicyNotAvailableToNonAdmin() {
173         assertOnlyAggregatePolicyAvailableToNonAdmin(
174                 (dpm, who) -> dpm.getTrustAgentConfiguration(who,
175                         DPC_COMPONENT_NAME /* agent component, need to be non-null */));
176     }
177 
178     // TODO(b/210996030): replace this with test method parametrization and separate "null" case.
assertOnlyAggregatePolicyAvailableToNonAdmin( BiConsumer<RemoteDevicePolicyManager, ComponentName> accessor)179     private void assertOnlyAggregatePolicyAvailableToNonAdmin(
180             BiConsumer<RemoteDevicePolicyManager, ComponentName> accessor) {
181         try (TestAppInstance testApp = sTestApp.install()) {
182             // Invoking with null admin should not throw.
183             accessor.accept(testApp.devicePolicyManager(), /* who= */ null);
184 
185             SecurityException adminPackageEx = null;
186             try {
187                 // Requesting policy for an admin from a different app should throw.
188                 accessor.accept(testApp.devicePolicyManager(), DPC_COMPONENT_NAME);
189                 fail("Checking particular admin policy shouldn't be allowed for non admin");
190             } catch (SecurityException e) {
191                 adminPackageEx = e;
192             }
193 
194             ComponentName nonexistentComponent = new ComponentName("bad_pkg_123", "bad_clz_456");
195             SecurityException nonexistentPackageEx = null;
196             try {
197                 // Requesting policy for a nonexistent admin should throw.
198                 accessor.accept(testApp.devicePolicyManager(), nonexistentComponent);
199                 fail("Querying policy for non-existent admin should have thrown an exception");
200             } catch (SecurityException e) {
201                 nonexistentPackageEx = e;
202             }
203 
204             // Both exceptions should have the same message (except package name) to avoid revealing
205             // admin existence.
206             String adminMessage = adminPackageEx.getMessage()
207                     .replace(DPC_COMPONENT_NAME.toString(), "");
208             String nonexistentMessage = nonexistentPackageEx.getMessage()
209                     .replace(nonexistentComponent.toString(), "");
210             assertThat(adminMessage).isEqualTo(nonexistentMessage);
211         }
212     }
213 }
214