DO NOT MERGE Revert "Enable SD card encryption policy when emulated"

This reverts commit 7fd14be804

The introduction of proper SD cards breaks the invariant that "external"
storage can be encrypted. Unfortunately, this means that accounts with
that policy bit set will have to be removed for now.

Accounts with the security policy set will be forced to go through
security provisioning on the next sync, using the regular mechanisms of
showing a notification with "Security update required", and then having
it fail. :(

Bug: 4466311
Change-Id: I68119b14f8d198779c2073296e228bc6772136ee
This commit is contained in:
Ben Komalo 2011-06-01 20:42:07 -07:00
parent ff162ee2c0
commit c379ebe372
3 changed files with 60 additions and 137 deletions

View File

@ -123,13 +123,12 @@ public class PolicySet implements Parcelable {
* @param passwordHistory (0=not enforced)
* @param passwordComplexChars (0=not enforced)
* @param requireEncryption
* @param requireEncryptionExternal
* @throws IllegalArgumentException for illegal arguments.
*/
public PolicySet(int minPasswordLength, int passwordMode, int maxPasswordFails,
int maxScreenLockTime, boolean requireRemoteWipe, int passwordExpirationDays,
int passwordHistory, int passwordComplexChars, boolean requireEncryption,
boolean requireEncryptionExternal) throws IllegalArgumentException {
int passwordHistory, int passwordComplexChars, boolean requireEncryption)
throws IllegalArgumentException {
// If we're not enforcing passwords, make sure we clean up related values, since EAS
// can send non-zero values for any or all of these
if (passwordMode == PASSWORD_MODE_NONE) {
@ -180,7 +179,11 @@ public class PolicySet implements Parcelable {
mPasswordHistory = passwordHistory;
mPasswordComplexChars = passwordComplexChars;
mRequireEncryption = requireEncryption;
mRequireEncryptionExternal = requireEncryptionExternal;
// This can never be supported at this time. It exists only for historic reasons where
// this was able to be supported prior to the introduction of proper removable storage
// support for external storage.
mRequireEncryptionExternal = false;
}
/**

View File

@ -33,7 +33,6 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Environment;
import android.util.Log;
/**
@ -45,11 +44,11 @@ public class SecurityPolicy {
private static SecurityPolicy sInstance = null;
private Context mContext;
private DevicePolicyManager mDPM;
private ComponentName mAdminName;
private final ComponentName mAdminName;
private PolicySet mAggregatePolicy;
/* package */ static final PolicySet NO_POLICY_SET =
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false, false);
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false);
/**
* This projection on Account is for scanning/reading
@ -106,7 +105,6 @@ public class SecurityPolicy {
* password expiration take the min (strongest mode)
* password complex chars take the max (strongest mode)
* encryption take the max (logical or)
* encryption (external) take the max (logical or)
*
* @return a policy representing the strongest aggregate. If no policy sets are defined,
* a lightweight "nothing required" policy will be returned. Never null.
@ -123,7 +121,6 @@ public class SecurityPolicy {
int passwordExpirationDays = Integer.MAX_VALUE;
int passwordComplexChars = Integer.MIN_VALUE;
boolean requireEncryption = false;
boolean requireEncryptionExternal = false;
Cursor c = mContext.getContentResolver().query(Account.CONTENT_URI,
ACCOUNT_SECURITY_PROJECTION, Account.SECURITY_NONZERO_SELECTION, null, null);
@ -153,7 +150,6 @@ public class SecurityPolicy {
}
requireRemoteWipe |= p.mRequireRemoteWipe;
requireEncryption |= p.mRequireEncryption;
requireEncryptionExternal |= p.mRequireEncryptionExternal;
policiesFound = true;
}
}
@ -172,7 +168,7 @@ public class SecurityPolicy {
return new PolicySet(minPasswordLength, passwordMode, maxPasswordFails,
maxScreenLockTime, requireRemoteWipe, passwordExpirationDays, passwordHistory,
passwordComplexChars, requireEncryption, requireEncryptionExternal);
passwordComplexChars, requireEncryption);
} else {
return NO_POLICY_SET;
}
@ -233,13 +229,6 @@ public class SecurityPolicy {
return false;
}
}
if (policies.mRequireEncryptionExternal) {
// At this time, we only support "external encryption" when it is provided by virtue
// of emulating the external storage inside an encrypted device.
if (!policies.mRequireEncryption) return false;
if (Environment.isExternalStorageRemovable()) return false;
if (!Environment.isExternalStorageEmulated()) return false;
}
return true;
}
@ -265,19 +254,7 @@ public class SecurityPolicy {
result = new PolicySet(policies.mMinPasswordLength, policies.mPasswordMode,
policies.mMaxPasswordFails, policies.mMaxScreenLockTime,
policies.mRequireRemoteWipe, policies.mPasswordExpirationDays,
policies.mPasswordHistory, policies.mPasswordComplexChars, false, false);
}
}
// At this time, we only support "external encryption" when it is provided by virtue
// of emulating the external storage inside an encrypted device.
if (policies.mRequireEncryptionExternal) {
if (Environment.isExternalStorageRemovable()
|| !Environment.isExternalStorageEmulated()) {
// Make new PolicySet w/o encryption
result = new PolicySet(policies.mMinPasswordLength, policies.mPasswordMode,
policies.mMaxPasswordFails, policies.mMaxScreenLockTime,
policies.mRequireRemoteWipe, policies.mPasswordExpirationDays,
policies.mPasswordHistory, policies.mPasswordComplexChars, false, false);
policies.mPasswordHistory, policies.mPasswordComplexChars, false);
}
}
return result;
@ -398,11 +375,6 @@ public class SecurityPolicy {
reasons |= INACTIVE_NEED_ENCRYPTION;
}
}
// TODO: If we ever support external storage encryption as a first-class feature,
// it will need to be checked here. For now, if there is a policy request for
// external storage encryption, it's sufficient that we've activated internal
// storage encryption.
// password failures are counted locally - no test required here
// no check required for remote wipe (it's supported, if we're the admin)
@ -449,10 +421,6 @@ public class SecurityPolicy {
dpm.setPasswordMinimumNonLetter(mAdminName, policies.mPasswordComplexChars);
// encryption required
dpm.setStorageEncryption(mAdminName, policies.mRequireEncryption);
// TODO: If we ever support external storage encryption as a first-class feature,
// it will need to be set here. For now, if there is a policy request for
// external storage encryption, it's sufficient that we've activated internal
// storage encryption.
}
}

View File

@ -49,7 +49,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
private Context mMockContext;
private static final PolicySet EMPTY_POLICY_SET =
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false, false);
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false);
public SecurityPolicyTests() {
super(EmailProvider.class, EmailContent.AUTHORITY);
@ -58,7 +58,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
@Override
protected void setUp() throws Exception {
super.setUp();
mMockContext = new MockContext2(getMockContext(), this.mContext);
mMockContext = new MockContext2(getMockContext(), mContext);
// Invalidate all caches, since we reset the database for each test
ContentCache.invalidateAllCachesForTest();
}
@ -114,29 +114,28 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// We know that EMPTY_POLICY_SET doesn't generate an Exception or we wouldn't be here
// Try some illegal parameters
try {
new PolicySet(100, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0, false, false);
new PolicySet(100, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0, false);
fail("Too-long password allowed");
} catch (IllegalArgumentException e) {
}
try {
new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG + 1, 0, 0, false, 0, 0, 0, false,
false);
new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG + 1, 0, 0, false, 0, 0, 0, false);
fail("Illegal password mode allowed");
} catch (IllegalArgumentException e) {
}
PolicySet ps = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0,
PolicySet.SCREEN_LOCK_TIME_MAX + 1, false, 0, 0, 0, false, false);
PolicySet.SCREEN_LOCK_TIME_MAX + 1, false, 0, 0, 0, false);
assertEquals(PolicySet.SCREEN_LOCK_TIME_MAX, ps.getMaxScreenLockTimeForTest());
ps = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE,
PolicySet.PASSWORD_MAX_FAILS_MAX + 1, 0, false, 0, 0, 0, false, false);
PolicySet.PASSWORD_MAX_FAILS_MAX + 1, 0, false, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MAX_FAILS_MAX, ps.getMaxPasswordFailsForTest());
// All password related fields should be zero when password mode is NONE
// Illegal values for these fields should be ignored
ps = new PolicySet(999/*length*/, PolicySet.PASSWORD_MODE_NONE,
999/*fails*/, 9999/*screenlock*/, false, 999/*expir*/, 999/*history*/,
999/*complex*/, false, false);
999/*complex*/, false);
assertEquals(0, ps.mMinPasswordLength);
assertEquals(0, ps.mMaxScreenLockTime);
assertEquals(0, ps.mMaxPasswordFails);
@ -146,7 +145,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// With a simple password, we should set complex chars to zero
ps = new PolicySet(4/*length*/, PolicySet.PASSWORD_MODE_SIMPLE,
0, 0, false, 0, 0, 3/*complex*/, false, false);
0, 0, false, 0, 0, 3/*complex*/, false);
assertEquals(4, ps.mMinPasswordLength);
assertEquals(0, ps.mPasswordComplexChars);
}
@ -173,7 +172,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// first test with partially-populated policies
Account a3 = ProviderTestUtils.setupAccount("sec-3", false, mMockContext);
PolicySet p3ain = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
false, false);
false);
p3ain.writeAccount(a3, null, true, mMockContext);
PolicySet p3aout = sp.computeAggregatePolicy();
assertNotNull(p3aout);
@ -181,7 +180,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// Repeat that test with fully-populated policies
PolicySet p3bin = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 15, 16, false, 6, 2, 3,
false, false);
false);
p3bin.writeAccount(a3, null, true, mMockContext);
PolicySet p3bout = sp.computeAggregatePolicy();
assertNotNull(p3bout);
@ -194,9 +193,8 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// expiration - will not change because 0 (unspecified)
// max complex chars - max logic - will change
// encryption required - OR logic - will *not* change here because false
// encryption external req'd - OR logic - will *not* change here because false
PolicySet p4in = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 0, 5, 7,
false, false);
false);
Account a4 = ProviderTestUtils.setupAccount("sec-4", false, mMockContext);
p4in.writeAccount(a4, null, true, mMockContext);
PolicySet p4out = sp.computeAggregatePolicy();
@ -210,7 +208,6 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(7, p4out.mPasswordComplexChars);
assertFalse(p4out.mRequireRemoteWipe);
assertFalse(p4out.mRequireEncryption);
assertFalse(p4out.mRequireEncryptionExternal);
// add another account which mixes it up (the remaining fields will change)
// pw length and pw mode - max logic - will *not* change because smaller #s here
@ -219,9 +216,8 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// expiration time - min logic - will change because lower here
// history & complex chars - will not change because 0 (unspecified)
// encryption required - OR logic - will change here because true
// encryption external req'd - OR logic - will *not* change here because false
PolicySet p5in = new PolicySet(4, PolicySet.PASSWORD_MODE_SIMPLE, 5, 6, true, 1, 0, 0,
true, false);
true);
Account a5 = ProviderTestUtils.setupAccount("sec-5", false, mMockContext);
p5in.writeAccount(a5, null, true, mMockContext);
PolicySet p5out = sp.computeAggregatePolicy();
@ -234,17 +230,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(5, p5out.mPasswordHistory);
assertEquals(7, p5out.mPasswordComplexChars);
assertTrue(p5out.mRequireRemoteWipe);
assertFalse(p5out.mRequireEncryptionExternal);
// add another account that continues to mutate fields
// encryption external req'd - OR logic - will change here because true
PolicySet p6in = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0,
false, true);
Account a6 = ProviderTestUtils.setupAccount("sec-6", false, mMockContext);
p6in.writeAccount(a6, null, true, mMockContext);
PolicySet p6out = sp.computeAggregatePolicy();
assertNotNull(p6out);
assertTrue(p6out.mRequireEncryptionExternal);
assertTrue(p5out.mRequireEncryption);
}
/**
@ -274,7 +260,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
public void testFieldIsolation() {
// Check PASSWORD_LENGTH
PolicySet p = new PolicySet(PolicySet.PASSWORD_LENGTH_MAX, PolicySet.PASSWORD_MODE_SIMPLE,
0, 0, false, 0, 0 ,0, false, false);
0, 0, false, 0, 0 ,0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(PolicySet.PASSWORD_LENGTH_MAX, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
@ -284,10 +270,9 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
assertFalse(p.mRequireEncryptionExternal);
// Check PASSWORD_MODE
p = new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG, 0, 0, false, 0, 0, 0, false, false);
p = new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG, 0, 0, false, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_STRONG, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
@ -297,11 +282,10 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
assertFalse(p.mRequireEncryptionExternal);
// Check PASSWORD_FAILS (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, PolicySet.PASSWORD_MAX_FAILS_MAX, 0,
false, 0, 0, 0, false, false);
false, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(PolicySet.PASSWORD_MAX_FAILS_MAX, p.mMaxPasswordFails);
@ -311,11 +295,10 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
assertFalse(p.mRequireEncryptionExternal);
// Check SCREEN_LOCK_TIME (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, PolicySet.SCREEN_LOCK_TIME_MAX,
false, 0, 0, 0, false, false);
false, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
@ -325,10 +308,9 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
assertFalse(p.mRequireEncryptionExternal);
// Check REQUIRE_REMOTE_WIPE
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, true, 0, 0, 0, false, false);
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, true, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_NONE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
@ -338,11 +320,10 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordComplexChars);
assertTrue(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
assertFalse(p.mRequireEncryptionExternal);
// Check PASSWORD_EXPIRATION (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false,
PolicySet.PASSWORD_EXPIRATION_MAX, 0, 0, false, false);
PolicySet.PASSWORD_EXPIRATION_MAX, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
@ -352,11 +333,10 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
assertFalse(p.mRequireEncryptionExternal);
// Check PASSWORD_HISTORY (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0,
PolicySet.PASSWORD_HISTORY_MAX, 0, false, false);
PolicySet.PASSWORD_HISTORY_MAX, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
@ -366,11 +346,10 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
assertFalse(p.mRequireEncryptionExternal);
// Check PASSWORD_COMPLEX_CHARS (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG, 0, 0, false, 0, 0,
PolicySet.PASSWORD_COMPLEX_CHARS_MAX, false, false);
PolicySet.PASSWORD_COMPLEX_CHARS_MAX, false);
assertEquals(PolicySet.PASSWORD_MODE_STRONG, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
@ -380,10 +359,9 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(PolicySet.PASSWORD_COMPLEX_CHARS_MAX, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
assertFalse(p.mRequireEncryptionExternal);
// Check REQUIRE_ENCRYPTION
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, true, false);
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, true);
assertEquals(PolicySet.PASSWORD_MODE_NONE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
@ -393,20 +371,6 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertTrue(p.mRequireEncryption);
assertFalse(p.mRequireEncryptionExternal);
// Check REQUIRE_ENCRYPTION_EXTERNAL
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false, true);
assertEquals(PolicySet.PASSWORD_MODE_NONE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
assertEquals(0, p.mMaxScreenLockTime);
assertEquals(0, p.mPasswordExpirationDays);
assertEquals(0, p.mPasswordHistory);
assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
assertTrue(p.mRequireEncryptionExternal);
}
/**
@ -414,8 +378,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
*/
@SmallTest
public void testAccountEncoding() {
PolicySet p1 =
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
PolicySet p1 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false);
Account a = new Account();
final String SYNC_KEY = "test_sync_key";
p1.writeAccount(a, SYNC_KEY, false, null);
@ -429,12 +392,9 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
*/
@SmallTest
public void testEquals() {
PolicySet p1 =
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
PolicySet p2 =
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
PolicySet p3 =
new PolicySet(2, PolicySet.PASSWORD_MODE_SIMPLE, 5, 6, true, 7, 8, 9, false, false);
PolicySet p1 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false);
PolicySet p2 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false);
PolicySet p3 = new PolicySet(2, PolicySet.PASSWORD_MODE_SIMPLE, 5, 6, true, 7, 8, 9, false);
assertTrue(p1.equals(p2));
assertFalse(p2.equals(p3));
}
@ -484,12 +444,12 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
public void testDisableAdmin() {
Account a1 = ProviderTestUtils.setupAccount("disable-1", false, mMockContext);
PolicySet p1 = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
false, false);
false);
p1.writeAccount(a1, "sync-key-1", true, mMockContext);
Account a2 = ProviderTestUtils.setupAccount("disable-2", false, mMockContext);
PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0,
false, false);
false);
p2.writeAccount(a2, "sync-key-2", true, mMockContext);
Account a3 = ProviderTestUtils.setupAccount("disable-3", false, mMockContext);
@ -534,40 +494,42 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
* Test the scanner that finds expiring accounts
*/
public void testFindExpiringAccount() {
SecurityPolicy sp = getSecurityPolicy();
Account a1 = ProviderTestUtils.setupAccount("expiring-1", true, mMockContext);
// With no expiring accounts, this should return null.
long nextExpiringAccountId = SecurityPolicy.findShortestExpiration(mMockContext);
long nextExpiringAccountId = sp.findShortestExpiration(mMockContext);
assertEquals(-1, nextExpiringAccountId);
// Add a single expiring account
Account a2 = ProviderTestUtils.setupAccount("expiring-2", false, mMockContext);
PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0,
false, false);
false);
p2.writeAccount(a2, "sync-key-2", true, mMockContext);
// The expiring account should be returned
nextExpiringAccountId = SecurityPolicy.findShortestExpiration(mMockContext);
nextExpiringAccountId = sp.findShortestExpiration(mMockContext);
assertEquals(a2.mId, nextExpiringAccountId);
// Add an account with a longer expiration
Account a3 = ProviderTestUtils.setupAccount("expiring-3", false, mMockContext);
PolicySet p3 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 60, 0, 0,
false, false);
false);
p3.writeAccount(a3, "sync-key-3", true, mMockContext);
// The original expiring account (a2) should be returned
nextExpiringAccountId = SecurityPolicy.findShortestExpiration(mMockContext);
nextExpiringAccountId = sp.findShortestExpiration(mMockContext);
assertEquals(a2.mId, nextExpiringAccountId);
// Add an account with a shorter expiration
Account a4 = ProviderTestUtils.setupAccount("expiring-4", false, mMockContext);
PolicySet p4 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 15, 0, 0,
false, false);
false);
p4.writeAccount(a4, "sync-key-4", true, mMockContext);
// The new expiring account (a4) should be returned
nextExpiringAccountId = SecurityPolicy.findShortestExpiration(mMockContext);
nextExpiringAccountId = sp.findShortestExpiration(mMockContext);
assertEquals(a4.mId, nextExpiringAccountId);
}
@ -593,7 +555,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
Account a1 = ProviderTestUtils.setupAccount("expired-1", true, mMockContext);
Account a2 = ProviderTestUtils.setupAccount("expired-2", false, mMockContext);
PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0,
false, false);
false);
p2.writeAccount(a2, "sync-key-2", true, mMockContext);
// Add a mailbox & messages to each account
@ -619,7 +581,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// Add 3rd account that really expires
Account a3 = ProviderTestUtils.setupAccount("expired-3", false, mMockContext);
PolicySet p3 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0,
false, false);
false);
p3.writeAccount(a3, "sync-key-3", true, mMockContext);
// Add mailbox & messages to 3rd account
@ -656,12 +618,8 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
* TODO inject a mock DPM so we can directly control & test all cases, no matter what device
*/
public void testClearUnsupportedPolicies() {
PolicySet p1 =
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
PolicySet p2 =
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, true, false);
PolicySet p3 =
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, true);
PolicySet p1 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false);
PolicySet p2 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, true);
SecurityPolicy sp = getSecurityPolicy();
DevicePolicyManager dpm = sp.getDPM();
@ -670,22 +628,16 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
PolicySet p1Result = sp.clearUnsupportedPolicies(p1);
PolicySet p2Result = sp.clearUnsupportedPolicies(p2);
PolicySet p3Result = sp.clearUnsupportedPolicies(p3);
// No changes expected when encryptionRequested bits were false
// No changes expected when encryptionRequested was false
assertEquals(p1, p1Result);
if (hasEncryption) {
// No changes expected
// NOTE: TODO: Modify to check for external encryption cleared on devices that
// won't support it (e.g. having only unencrypted, removable storage.)
assertEquals(p2, p2Result);
assertEquals(p3, p3Result);
} else {
// If encryption is unsupported, encryption policy bits are cleared
PolicySet policyExpect =
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
assertEquals(policyExpect, p2Result);
assertEquals(policyExpect, p3Result);
PolicySet p2Expect =
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false);
assertEquals(p2Expect, p2Result);
}
}
@ -695,25 +647,25 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
public void testGetDPManagerPasswordQuality() {
// PolicySet.PASSWORD_MODE_NONE -> DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
PolicySet p1 = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE,
0, 0, false, 0, 0, 0, false, false);
0, 0, false, 0, 0, 0, false);
assertEquals(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
p1.getDPManagerPasswordQuality());
// PASSWORD_MODE_SIMPLE -> PASSWORD_QUALITY_NUMERIC
PolicySet p2 = new PolicySet(4, PolicySet.PASSWORD_MODE_SIMPLE,
0, 0, false, 0, 0, 0, false, false);
0, 0, false, 0, 0, 0, false);
assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
p2.getDPManagerPasswordQuality());
// PASSWORD_MODE_STRONG -> PASSWORD_QUALITY_ALPHANUMERIC
PolicySet p3 = new PolicySet(4, PolicySet.PASSWORD_MODE_STRONG,
0, 0, false, 0, 0, 0, false, false);
0, 0, false, 0, 0, 0, false);
assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
p3.getDPManagerPasswordQuality());
// PASSWORD_MODE_STRONG + complex chars -> PASSWORD_QUALITY_COMPLEX
PolicySet p4 = new PolicySet(4, PolicySet.PASSWORD_MODE_STRONG,
0, 0, false, 0, 0 , 2, false, false);
0, 0, false, 0, 0 , 2, false);
assertEquals(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX,
p4.getDPManagerPasswordQuality());
}