Merge "Enable SD card encryption policy when emulated"
This commit is contained in:
commit
45e161bb5e
|
@ -63,8 +63,10 @@ public class PolicySet implements Parcelable {
|
|||
private static final int PASSWORD_COMPLEX_CHARS_SHIFT = 44;
|
||||
private static final long PASSWORD_COMPLEX_CHARS_MASK = 31L << PASSWORD_COMPLEX_CHARS_SHIFT;
|
||||
public static final int PASSWORD_COMPLEX_CHARS_MAX = 31;
|
||||
// bit 49: requires device encryption
|
||||
// bit 49: requires device encryption (internal)
|
||||
private static final long REQUIRE_ENCRYPTION = 1L << 49;
|
||||
// bit 50: requires external storage encryption
|
||||
private static final long REQUIRE_ENCRYPTION_EXTERNAL = 1L << 50;
|
||||
|
||||
/* Convert days to mSec (used for password expiration) */
|
||||
private static final long DAYS_TO_MSEC = 24 * 60 * 60 * 1000;
|
||||
|
@ -80,6 +82,7 @@ public class PolicySet implements Parcelable {
|
|||
public final int mPasswordHistory;
|
||||
public final int mPasswordComplexChars;
|
||||
public final boolean mRequireEncryption;
|
||||
public final boolean mRequireEncryptionExternal;
|
||||
|
||||
public int getMinPasswordLengthForTest() {
|
||||
return mMinPasswordLength;
|
||||
|
@ -105,6 +108,10 @@ public class PolicySet implements Parcelable {
|
|||
return mRequireEncryption;
|
||||
}
|
||||
|
||||
public boolean isRequireEncryptionExternalForTest() {
|
||||
return mRequireEncryptionExternal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from raw values.
|
||||
* @param minPasswordLength (0=not enforced)
|
||||
|
@ -115,12 +122,14 @@ public class PolicySet implements Parcelable {
|
|||
* @param passwordExpirationDays in days (0=not enforced)
|
||||
* @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)
|
||||
throws IllegalArgumentException {
|
||||
int passwordHistory, int passwordComplexChars, boolean requireEncryption,
|
||||
boolean requireEncryptionExternal) 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) {
|
||||
|
@ -171,6 +180,7 @@ public class PolicySet implements Parcelable {
|
|||
mPasswordHistory = passwordHistory;
|
||||
mPasswordComplexChars = passwordComplexChars;
|
||||
mRequireEncryption = requireEncryption;
|
||||
mRequireEncryptionExternal = requireEncryptionExternal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,6 +211,7 @@ public class PolicySet implements Parcelable {
|
|||
mPasswordComplexChars =
|
||||
(int) ((flags & PASSWORD_COMPLEX_CHARS_MASK) >> PASSWORD_COMPLEX_CHARS_SHIFT);
|
||||
mRequireEncryption = 0 != (flags & REQUIRE_ENCRYPTION);
|
||||
mRequireEncryptionExternal = 0 != (flags & REQUIRE_ENCRYPTION_EXTERNAL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,6 +316,7 @@ public class PolicySet implements Parcelable {
|
|||
dest.writeInt(mPasswordHistory);
|
||||
dest.writeInt(mPasswordComplexChars);
|
||||
dest.writeInt(mRequireEncryption ? 1 : 0);
|
||||
dest.writeInt(mRequireEncryptionExternal ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -320,6 +332,7 @@ public class PolicySet implements Parcelable {
|
|||
mPasswordHistory = in.readInt();
|
||||
mPasswordComplexChars = in.readInt();
|
||||
mRequireEncryption = in.readInt() == 1;
|
||||
mRequireEncryptionExternal = in.readInt() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -339,6 +352,7 @@ public class PolicySet implements Parcelable {
|
|||
flags |= (long)mPasswordExpirationDays << PASSWORD_EXPIRATION_SHIFT;
|
||||
flags |= (long)mPasswordComplexChars << PASSWORD_COMPLEX_CHARS_SHIFT;
|
||||
if (mRequireEncryption) flags |= REQUIRE_ENCRYPTION;
|
||||
if (mRequireEncryptionExternal) flags |= REQUIRE_ENCRYPTION_EXTERNAL;
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
@ -350,7 +364,8 @@ public class PolicySet implements Parcelable {
|
|||
+ " pw-expiration=" + mPasswordExpirationDays
|
||||
+ " pw-history=" + mPasswordHistory
|
||||
+ " pw-complex-chars=" + mPasswordComplexChars
|
||||
+ " require-encryption=" + mRequireEncryption + "}";
|
||||
+ " require-encryption=" + mRequireEncryption
|
||||
+ " require-encryptionExternal=" + mRequireEncryptionExternal + "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import android.content.ContentValues;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
|
@ -48,7 +49,7 @@ public class SecurityPolicy {
|
|||
private PolicySet mAggregatePolicy;
|
||||
|
||||
/* package */ static final PolicySet NO_POLICY_SET =
|
||||
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false);
|
||||
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false, false);
|
||||
|
||||
/**
|
||||
* This projection on Account is for scanning/reading
|
||||
|
@ -105,6 +106,7 @@ 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.
|
||||
|
@ -121,6 +123,7 @@ 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);
|
||||
|
@ -150,6 +153,7 @@ public class SecurityPolicy {
|
|||
}
|
||||
requireRemoteWipe |= p.mRequireRemoteWipe;
|
||||
requireEncryption |= p.mRequireEncryption;
|
||||
requireEncryptionExternal |= p.mRequireEncryptionExternal;
|
||||
policiesFound = true;
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +172,7 @@ public class SecurityPolicy {
|
|||
|
||||
return new PolicySet(minPasswordLength, passwordMode, maxPasswordFails,
|
||||
maxScreenLockTime, requireRemoteWipe, passwordExpirationDays, passwordHistory,
|
||||
passwordComplexChars, requireEncryption);
|
||||
passwordComplexChars, requireEncryption, requireEncryptionExternal);
|
||||
} else {
|
||||
return NO_POLICY_SET;
|
||||
}
|
||||
|
@ -229,6 +233,13 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -254,7 +265,19 @@ public class SecurityPolicy {
|
|||
result = new PolicySet(policies.mMinPasswordLength, policies.mPasswordMode,
|
||||
policies.mMaxPasswordFails, policies.mMaxScreenLockTime,
|
||||
policies.mRequireRemoteWipe, policies.mPasswordExpirationDays,
|
||||
policies.mPasswordHistory, policies.mPasswordComplexChars, false);
|
||||
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);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -375,6 +398,11 @@ 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)
|
||||
|
||||
|
@ -415,6 +443,10 @@ 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.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false, false);
|
||||
|
||||
public SecurityPolicyTests() {
|
||||
super(EmailProvider.class, EmailContent.AUTHORITY);
|
||||
|
@ -114,28 +114,29 @@ 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);
|
||||
new PolicySet(100, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0, false, 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);
|
||||
new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG + 1, 0, 0, false, 0, 0, 0, false,
|
||||
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);
|
||||
PolicySet.SCREEN_LOCK_TIME_MAX + 1, false, 0, 0, 0, false, 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);
|
||||
PolicySet.PASSWORD_MAX_FAILS_MAX + 1, 0, false, 0, 0, 0, false, 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);
|
||||
999/*complex*/, false, false);
|
||||
assertEquals(0, ps.mMinPasswordLength);
|
||||
assertEquals(0, ps.mMaxScreenLockTime);
|
||||
assertEquals(0, ps.mMaxPasswordFails);
|
||||
|
@ -145,7 +146,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);
|
||||
0, 0, false, 0, 0, 3/*complex*/, false, false);
|
||||
assertEquals(4, ps.mMinPasswordLength);
|
||||
assertEquals(0, ps.mPasswordComplexChars);
|
||||
}
|
||||
|
@ -172,7 +173,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);
|
||||
|
@ -180,7 +181,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);
|
||||
|
@ -193,8 +194,9 @@ 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();
|
||||
|
@ -208,6 +210,7 @@ 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
|
||||
|
@ -216,8 +219,9 @@ 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);
|
||||
true, false);
|
||||
Account a5 = ProviderTestUtils.setupAccount("sec-5", false, mMockContext);
|
||||
p5in.writeAccount(a5, null, true, mMockContext);
|
||||
PolicySet p5out = sp.computeAggregatePolicy();
|
||||
|
@ -230,7 +234,17 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
assertEquals(5, p5out.mPasswordHistory);
|
||||
assertEquals(7, p5out.mPasswordComplexChars);
|
||||
assertTrue(p5out.mRequireRemoteWipe);
|
||||
assertTrue(p5out.mRequireEncryption);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -260,7 +274,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);
|
||||
0, 0, false, 0, 0 ,0, false, false);
|
||||
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
|
||||
assertEquals(PolicySet.PASSWORD_LENGTH_MAX, p.mMinPasswordLength);
|
||||
assertEquals(0, p.mMaxPasswordFails);
|
||||
|
@ -270,9 +284,10 @@ 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);
|
||||
p = new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG, 0, 0, false, 0, 0, 0, false, false);
|
||||
assertEquals(PolicySet.PASSWORD_MODE_STRONG, p.mPasswordMode);
|
||||
assertEquals(0, p.mMinPasswordLength);
|
||||
assertEquals(0, p.mMaxPasswordFails);
|
||||
|
@ -282,10 +297,11 @@ 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, 0, 0, 0, false, false);
|
||||
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
|
||||
assertEquals(0, p.mMinPasswordLength);
|
||||
assertEquals(PolicySet.PASSWORD_MAX_FAILS_MAX, p.mMaxPasswordFails);
|
||||
|
@ -295,10 +311,11 @@ 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, 0, 0, 0, false, false);
|
||||
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
|
||||
assertEquals(0, p.mMinPasswordLength);
|
||||
assertEquals(0, p.mMaxPasswordFails);
|
||||
|
@ -308,9 +325,10 @@ 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);
|
||||
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, true, 0, 0, 0, false, false);
|
||||
assertEquals(PolicySet.PASSWORD_MODE_NONE, p.mPasswordMode);
|
||||
assertEquals(0, p.mMinPasswordLength);
|
||||
assertEquals(0, p.mMaxPasswordFails);
|
||||
|
@ -320,10 +338,11 @@ 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);
|
||||
PolicySet.PASSWORD_EXPIRATION_MAX, 0, 0, false, false);
|
||||
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
|
||||
assertEquals(0, p.mMinPasswordLength);
|
||||
assertEquals(0, p.mMaxPasswordFails);
|
||||
|
@ -333,10 +352,11 @@ 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);
|
||||
PolicySet.PASSWORD_HISTORY_MAX, 0, false, false);
|
||||
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
|
||||
assertEquals(0, p.mMinPasswordLength);
|
||||
assertEquals(0, p.mMaxPasswordFails);
|
||||
|
@ -346,10 +366,11 @@ 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);
|
||||
PolicySet.PASSWORD_COMPLEX_CHARS_MAX, false, false);
|
||||
assertEquals(PolicySet.PASSWORD_MODE_STRONG, p.mPasswordMode);
|
||||
assertEquals(0, p.mMinPasswordLength);
|
||||
assertEquals(0, p.mMaxPasswordFails);
|
||||
|
@ -359,9 +380,10 @@ 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);
|
||||
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, true, false);
|
||||
assertEquals(PolicySet.PASSWORD_MODE_NONE, p.mPasswordMode);
|
||||
assertEquals(0, p.mMinPasswordLength);
|
||||
assertEquals(0, p.mMaxPasswordFails);
|
||||
|
@ -371,6 +393,20 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -378,7 +414,8 @@ 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);
|
||||
PolicySet p1 =
|
||||
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
|
||||
Account a = new Account();
|
||||
final String SYNC_KEY = "test_sync_key";
|
||||
p1.writeAccount(a, SYNC_KEY, false, null);
|
||||
|
@ -392,9 +429,12 @@ 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);
|
||||
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);
|
||||
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);
|
||||
assertTrue(p1.equals(p2));
|
||||
assertFalse(p2.equals(p3));
|
||||
}
|
||||
|
@ -444,12 +484,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);
|
||||
|
@ -494,42 +534,40 @@ 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 = sp.findShortestExpiration(mMockContext);
|
||||
long nextExpiringAccountId = SecurityPolicy.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 = sp.findShortestExpiration(mMockContext);
|
||||
nextExpiringAccountId = SecurityPolicy.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 = sp.findShortestExpiration(mMockContext);
|
||||
nextExpiringAccountId = SecurityPolicy.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 = sp.findShortestExpiration(mMockContext);
|
||||
nextExpiringAccountId = SecurityPolicy.findShortestExpiration(mMockContext);
|
||||
assertEquals(a4.mId, nextExpiringAccountId);
|
||||
}
|
||||
|
||||
|
@ -555,7 +593,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
|
||||
|
@ -581,7 +619,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
|
||||
|
@ -618,8 +656,12 @@ 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);
|
||||
PolicySet p2 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, true);
|
||||
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);
|
||||
|
||||
SecurityPolicy sp = getSecurityPolicy();
|
||||
DevicePolicyManager dpm = sp.getDPM();
|
||||
|
@ -628,16 +670,22 @@ 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 was false
|
||||
// No changes expected when encryptionRequested bits were 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 {
|
||||
PolicySet p2Expect =
|
||||
new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false);
|
||||
assertEquals(p2Expect, p2Result);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue