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 package com.android.cts.deviceadmin;
17 
18 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
19 
20 import android.app.admin.DevicePolicyManager;
21 
22 /**
23  * Tests for {@link DevicePolicyManager#resetPassword} for complex cases.
24  *
25  * This needs to be run as device owner, because in NYC DA can't clear or change the password.
26  */
27 public class DeviceOwnerPasswordTest extends BaseDeviceAdminTest {
28 
29     @Override
setUp()30     protected void setUp() throws Exception {
31         super.setUp();
32 
33         assertDeviceOwner();
34         clearPassword();
35     }
36 
37     @Override
tearDown()38     protected void tearDown() throws Exception {
39         clearPassword();
40 
41         super.tearDown();
42     }
43 
testPasswordQuality_something()44     public void testPasswordQuality_something() {
45         dpm.setPasswordQuality(mAdminComponent,
46                 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
47         assertEquals(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
48                 dpm.getPasswordQuality(mAdminComponent));
49         assertPasswordSufficiency(false);
50 
51         String caseDescription = "initial";
52         assertPasswordSucceeds("1234", caseDescription);
53         assertPasswordSucceeds("abcd", caseDescription); // can't change.
54         assertPasswordSucceeds("abcd1234", caseDescription);
55 
56         dpm.setPasswordMinimumLength(mAdminComponent, 10);
57         caseDescription = "minimum password length = 10";
58         assertEquals(10, dpm.getPasswordMinimumLength(mAdminComponent));
59         assertPasswordSufficiency(true); // length not checked for this quality
60 
61         // TODO(ascull): fix resetPassword() logic so these succeed
62         assertPasswordFails("1234", caseDescription);
63         assertPasswordFails("abcd", caseDescription);
64         assertPasswordFails("abcd1234", caseDescription);
65 
66         dpm.setPasswordMinimumLength(mAdminComponent, 4);
67         caseDescription = "minimum password length = 4";
68         assertEquals(4, dpm.getPasswordMinimumLength(
69                 mAdminComponent));
70         assertPasswordSufficiency(true);
71 
72         assertPasswordSucceeds("1234", caseDescription);
73         assertPasswordSucceeds("abcd", caseDescription);
74         assertPasswordSucceeds("abcd1234", caseDescription);
75     }
76 
testPasswordQuality_numeric()77     public void testPasswordQuality_numeric() {
78         dpm.setPasswordQuality(mAdminComponent,
79                 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
80         assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
81                 dpm.getPasswordQuality(mAdminComponent));
82         assertPasswordSufficiency(false);            // failure
83 
84         String caseDescription = "initial";
85         assertPasswordSucceeds("1234", caseDescription);
86         assertPasswordSucceeds("abcd", caseDescription);
87         assertPasswordSucceeds("abcd1234", caseDescription);
88 
89         dpm.setPasswordMinimumLength(mAdminComponent, 10);
90         caseDescription = "minimum password length = 10";
91         assertEquals(10, dpm.getPasswordMinimumLength(mAdminComponent));
92         assertPasswordSufficiency(false);
93 
94         assertPasswordFails("1234", caseDescription);
95         assertPasswordFails("abcd", caseDescription);
96         assertPasswordFails("abcd1234", caseDescription);
97 
98         dpm.setPasswordMinimumLength(mAdminComponent, 4);
99         caseDescription = "minimum password length = 4";
100         assertEquals(4, dpm.getPasswordMinimumLength(
101                 mAdminComponent));
102         assertPasswordSufficiency(true);
103 
104         assertPasswordSucceeds("1234", caseDescription);
105         assertPasswordSucceeds("abcd", caseDescription);
106         assertPasswordSucceeds("abcd1234", caseDescription);
107     }
108 
testPasswordQuality_alphabetic()109     public void testPasswordQuality_alphabetic() {
110         dpm.setPasswordQuality(mAdminComponent,
111                 DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
112         assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
113                 dpm.getPasswordQuality(mAdminComponent));
114         assertPasswordSufficiency(false);
115 
116         String caseDescription = "initial";
117         assertPasswordFails("1234", caseDescription);      // can't change
118         assertPasswordSucceeds("abcd", caseDescription);
119         assertPasswordSucceeds("abcd1234", caseDescription);
120 
121         dpm.setPasswordMinimumLength(mAdminComponent, 10);
122         caseDescription = "minimum password length = 10";
123         assertEquals(10, dpm.getPasswordMinimumLength(mAdminComponent));
124         assertPasswordSufficiency(false);
125 
126         assertPasswordFails("1234", caseDescription);
127         assertPasswordFails("abcd", caseDescription);
128         assertPasswordFails("abcd1234", caseDescription);
129 
130         dpm.setPasswordMinimumLength(mAdminComponent, 4);
131         caseDescription = "minimum password length = 4";
132         assertEquals(4, dpm.getPasswordMinimumLength(
133                 mAdminComponent));
134         assertPasswordSufficiency(true);
135 
136         assertPasswordFails("1234", caseDescription);
137         assertPasswordSucceeds("abcd", caseDescription);
138         assertPasswordSucceeds("abcd1234", caseDescription);
139     }
140 
testPasswordQuality_alphanumeric()141     public void testPasswordQuality_alphanumeric() {
142         dpm.setPasswordQuality(mAdminComponent,
143                 DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
144         assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
145                 dpm.getPasswordQuality(mAdminComponent));
146         assertPasswordSufficiency(false);
147 
148         String caseDescription = "initial";
149         assertPasswordFails("1234", caseDescription);
150         assertPasswordFails("abcd", caseDescription);
151         assertPasswordSucceeds("abcd1234", caseDescription);
152 
153         dpm.setPasswordMinimumLength(mAdminComponent, 10);
154         caseDescription = "minimum password length = 10";
155         assertEquals(10, dpm.getPasswordMinimumLength(mAdminComponent));
156         assertPasswordSufficiency(false);
157 
158         assertPasswordFails("1234", caseDescription);
159         assertPasswordFails("abcd", caseDescription);
160         assertPasswordFails("abcd1234", caseDescription);
161 
162         dpm.setPasswordMinimumLength(mAdminComponent, 4);
163         caseDescription = "minimum password length = 4";
164         assertEquals(4, dpm.getPasswordMinimumLength(
165                 mAdminComponent));
166         assertPasswordSufficiency(true);
167 
168         assertPasswordFails("1234", caseDescription);
169         assertPasswordFails("abcd", caseDescription);
170         assertPasswordSucceeds("abcd1234", caseDescription);
171     }
172 
testPasswordQuality_complexUpperCase()173     public void testPasswordQuality_complexUpperCase() {
174         dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
175         assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
176         resetComplexPasswordRestrictions();
177 
178         String caseDescription = "minimum UpperCase=0";
179         assertPasswordSucceeds("abc1", caseDescription);
180         assertPasswordSucceeds("aBc1", caseDescription);
181         assertPasswordSucceeds("ABC1", caseDescription);
182         assertPasswordSucceeds("ABCD", caseDescription);
183         assertPasswordFails("123", caseDescription); // too short
184 
185         dpm.setPasswordMinimumUpperCase(mAdminComponent, 1);
186         assertEquals(1, dpm.getPasswordMinimumUpperCase(mAdminComponent));
187         caseDescription = "minimum UpperCase=1";
188         assertPasswordFails("abc1", caseDescription);
189         assertPasswordSucceeds("aBc1", caseDescription);
190         assertPasswordSucceeds("ABC1", caseDescription);
191         assertPasswordSucceeds("ABCD", caseDescription);
192         assertPasswordFails("123", caseDescription); // too short
193 
194         dpm.setPasswordMinimumUpperCase(mAdminComponent, 3);
195         assertEquals(3, dpm.getPasswordMinimumUpperCase(mAdminComponent));
196         caseDescription = "minimum UpperCase=3";
197         assertPasswordFails("abc1", caseDescription);
198         assertPasswordFails("aBC1", caseDescription);
199         assertPasswordSucceeds("ABC1", caseDescription);
200         assertPasswordSucceeds("ABCD", caseDescription);
201         assertPasswordFails("123", caseDescription); // too short
202     }
203 
testPasswordQuality_complexLowerCase()204     public void testPasswordQuality_complexLowerCase() {
205         dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
206         assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
207         resetComplexPasswordRestrictions();
208 
209         String caseDescription = "minimum LowerCase=0";
210         assertPasswordSucceeds("ABCD", caseDescription);
211         assertPasswordSucceeds("aBC1", caseDescription);
212         assertPasswordSucceeds("abc1", caseDescription);
213         assertPasswordSucceeds("abcd", caseDescription);
214         assertPasswordFails("123", caseDescription); // too short
215 
216         dpm.setPasswordMinimumLowerCase(mAdminComponent, 1);
217         assertEquals(1, dpm.getPasswordMinimumLowerCase(mAdminComponent));
218         caseDescription = "minimum LowerCase=1";
219         assertPasswordFails("ABCD", caseDescription);
220         assertPasswordSucceeds("aBC1", caseDescription);
221         assertPasswordSucceeds("abc1", caseDescription);
222         assertPasswordSucceeds("abcd", caseDescription);
223         assertPasswordFails("123", caseDescription); // too short
224 
225         dpm.setPasswordMinimumLowerCase(mAdminComponent, 3);
226         assertEquals(3, dpm.getPasswordMinimumLowerCase(mAdminComponent));
227         caseDescription = "minimum LowerCase=3";
228         assertPasswordFails("ABCD", caseDescription);
229         assertPasswordFails("aBC1", caseDescription);
230         assertPasswordSucceeds("abc1", caseDescription);
231         assertPasswordSucceeds("abcd", caseDescription);
232         assertPasswordFails("123", caseDescription); // too short
233     }
234 
testPasswordQuality_complexLetters()235     public void testPasswordQuality_complexLetters() {
236         dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
237         assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
238         resetComplexPasswordRestrictions();
239 
240         String caseDescription = "minimum Letters=0";
241         assertPasswordSucceeds("1234", caseDescription);
242         assertPasswordSucceeds("a123", caseDescription);
243         assertPasswordSucceeds("abc1", caseDescription);
244         assertPasswordSucceeds("abcd", caseDescription);
245         assertPasswordFails("123", caseDescription); // too short
246 
247         dpm.setPasswordMinimumLetters(mAdminComponent, 1);
248         assertEquals(1, dpm.getPasswordMinimumLetters(mAdminComponent));
249         caseDescription = "minimum Letters=1";
250         assertPasswordFails("1234", caseDescription);
251         assertPasswordSucceeds("a123", caseDescription);
252         assertPasswordSucceeds("abc1", caseDescription);
253         assertPasswordSucceeds("abcd", caseDescription);
254         assertPasswordFails("123", caseDescription); // too short
255 
256         dpm.setPasswordMinimumLetters(mAdminComponent, 3);
257         assertEquals(3, dpm.getPasswordMinimumLetters(mAdminComponent));
258         caseDescription = "minimum Letters=3";
259         assertPasswordFails("1234", caseDescription);
260         assertPasswordFails("a123", caseDescription);
261         assertPasswordSucceeds("abc1", caseDescription);
262         assertPasswordSucceeds("abcd", caseDescription);
263         assertPasswordFails("123", caseDescription); // too short
264     }
265 
testPasswordQuality_complexNumeric()266     public void testPasswordQuality_complexNumeric() {
267         dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
268         assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
269         resetComplexPasswordRestrictions();
270 
271         String caseDescription = "minimum Numeric=0";
272         assertPasswordSucceeds("abcd", caseDescription);
273         assertPasswordSucceeds("1abc", caseDescription);
274         assertPasswordSucceeds("123a", caseDescription);
275         assertPasswordSucceeds("1234", caseDescription);
276         assertPasswordFails("123", caseDescription); // too short
277 
278         dpm.setPasswordMinimumNumeric(mAdminComponent, 1);
279         assertEquals(1, dpm.getPasswordMinimumNumeric(mAdminComponent));
280         caseDescription = "minimum Numeric=1";
281         assertPasswordFails("abcd", caseDescription);
282         assertPasswordSucceeds("1abc", caseDescription);
283         assertPasswordSucceeds("123a", caseDescription);
284         assertPasswordSucceeds("1234", caseDescription);
285         assertPasswordFails("123", caseDescription); // too short
286 
287         dpm.setPasswordMinimumNumeric(mAdminComponent, 3);
288         assertEquals(3, dpm.getPasswordMinimumNumeric(mAdminComponent));
289         caseDescription = "minimum Numeric=3";
290         assertPasswordFails("abcd", caseDescription);
291         assertPasswordFails("1abc", caseDescription);
292         assertPasswordSucceeds("123a", caseDescription);
293         assertPasswordSucceeds("1234", caseDescription);
294         assertPasswordFails("123", caseDescription); // too short
295     }
296 
testPasswordQuality_complexSymbols()297     public void testPasswordQuality_complexSymbols() {
298         dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
299         assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
300         resetComplexPasswordRestrictions();
301 
302         String caseDescription = "minimum Symbols=0";
303         assertPasswordSucceeds("abcd", caseDescription);
304         assertPasswordSucceeds("_bc1", caseDescription);
305         assertPasswordSucceeds("@#!1", caseDescription);
306         assertPasswordSucceeds("_@#!", caseDescription);
307         assertPasswordFails("123", caseDescription); // too short
308 
309         dpm.setPasswordMinimumSymbols(mAdminComponent, 1);
310         assertEquals(1, dpm.getPasswordMinimumSymbols(mAdminComponent));
311         caseDescription = "minimum Symbols=1";
312         assertPasswordFails("abcd", caseDescription);
313         assertPasswordSucceeds("_bc1", caseDescription);
314         assertPasswordSucceeds("@#!1", caseDescription);
315         assertPasswordSucceeds("_@#!", caseDescription);
316         assertPasswordFails("123", caseDescription); // too short
317 
318         dpm.setPasswordMinimumSymbols(mAdminComponent, 3);
319         assertEquals(3, dpm.getPasswordMinimumSymbols(mAdminComponent));
320         caseDescription = "minimum Symbols=3";
321         assertPasswordFails("abcd", caseDescription);
322         assertPasswordFails("_bc1", caseDescription);
323         assertPasswordSucceeds("@#!1", caseDescription);
324         assertPasswordSucceeds("_@#!", caseDescription);
325         assertPasswordFails("123", caseDescription); // too short
326     }
327 
testPasswordQuality_complexNonLetter()328     public void testPasswordQuality_complexNonLetter() {
329         dpm.setPasswordQuality(mAdminComponent, PASSWORD_QUALITY_COMPLEX);
330         assertEquals(PASSWORD_QUALITY_COMPLEX, dpm.getPasswordQuality(mAdminComponent));
331         resetComplexPasswordRestrictions();
332 
333         String caseDescription = "minimum NonLetter=0";
334         assertPasswordSucceeds("Abcd", caseDescription);
335         assertPasswordSucceeds("_bcd", caseDescription);
336         assertPasswordSucceeds("3bcd", caseDescription);
337         assertPasswordSucceeds("_@3c", caseDescription);
338         assertPasswordSucceeds("_25!", caseDescription);
339         assertPasswordFails("123", caseDescription); // too short
340 
341         dpm.setPasswordMinimumNonLetter(mAdminComponent, 1);
342         assertEquals(1, dpm.getPasswordMinimumNonLetter(mAdminComponent));
343         caseDescription = "minimum NonLetter=1";
344         assertPasswordFails("Abcd", caseDescription);
345         assertPasswordSucceeds("_bcd", caseDescription);
346         assertPasswordSucceeds("3bcd", caseDescription);
347         assertPasswordSucceeds("_@3c", caseDescription);
348         assertPasswordSucceeds("_25!", caseDescription);
349         assertPasswordFails("123", caseDescription); // too short
350 
351         dpm.setPasswordMinimumNonLetter(mAdminComponent, 3);
352         assertEquals(3, dpm.getPasswordMinimumNonLetter(mAdminComponent));
353         caseDescription = "minimum NonLetter=3";
354         assertPasswordFails("Abcd", caseDescription);
355         assertPasswordFails("_bcd", caseDescription);
356         assertPasswordFails("3bcd", caseDescription);
357         assertPasswordSucceeds("_@3c", caseDescription);
358         assertPasswordSucceeds("_25!", caseDescription);
359         assertPasswordFails("123", caseDescription); // too short
360     }
361 
assertPasswordFails(String password, String restriction)362     private void assertPasswordFails(String password, String restriction) {
363         try {
364             boolean passwordResetResult = dpm.resetPassword(password, /* flags= */0);
365             assertFalse("Password '" + password + "' should have failed on " + restriction,
366                     passwordResetResult);
367         } catch (IllegalArgumentException e) {
368             // yesss, we have failed!
369         }
370     }
371 
assertPasswordSucceeds(String password, String restriction)372     private void assertPasswordSucceeds(String password, String restriction) {
373         boolean passwordResetResult = dpm.resetPassword(password, /* flags= */0);
374         assertTrue("Password '" + password + "' failed on " + restriction, passwordResetResult);
375         assertPasswordSufficiency(true);
376     }
377 
assertPasswordSufficiency(boolean expectPasswordSufficient)378     private void assertPasswordSufficiency(boolean expectPasswordSufficient) {
379         int retries = 15;
380         // isActivePasswordSufficient() gets the result asynchronously so let's retry a few times
381         while (retries >= 0 && dpm.isActivePasswordSufficient() != expectPasswordSufficient) {
382             retries--;
383             try {
384                 Thread.sleep(200);
385             } catch (InterruptedException e) {
386                 break;
387             }
388         }
389         assertEquals(expectPasswordSufficient, dpm.isActivePasswordSufficient());
390 
391     }
392 }
393