Revert "Enable SD card encryption policy when emulated"
This is a manual cherry-pick ofc379ebe372
This reverts commit7fd14be804
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:
parent
0268581de2
commit
e76962b1b9
|
@ -35,7 +35,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;
|
||||
|
||||
/**
|
||||
|
@ -99,7 +98,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.
|
||||
|
@ -117,6 +115,10 @@ public class SecurityPolicy {
|
|||
aggregate.mMaxScreenLockTime = Integer.MAX_VALUE;
|
||||
aggregate.mRequireRemoteWipe = false;
|
||||
aggregate.mRequireEncryption = false;
|
||||
|
||||
// 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.
|
||||
aggregate.mRequireEncryptionExternal = false;
|
||||
|
||||
Cursor c = mContext.getContentResolver().query(Policy.CONTENT_URI,
|
||||
|
@ -153,7 +155,6 @@ public class SecurityPolicy {
|
|||
}
|
||||
aggregate.mRequireRemoteWipe |= policy.mRequireRemoteWipe;
|
||||
aggregate.mRequireEncryption |= policy.mRequireEncryption;
|
||||
aggregate.mRequireEncryptionExternal |= policy.mRequireEncryptionExternal;
|
||||
aggregate.mDontAllowCamera |= policy.mDontAllowCamera;
|
||||
policiesFound = true;
|
||||
}
|
||||
|
@ -240,13 +241,6 @@ public class SecurityPolicy {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (policy.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 (!policy.mRequireEncryption) return false;
|
||||
if (Environment.isExternalStorageRemovable()) return false;
|
||||
if (!Environment.isExternalStorageEmulated()) return false;
|
||||
}
|
||||
|
||||
// If we ever support devices that can't disable cameras for any reason, we should
|
||||
// indicate as such in the mDontAllowCamera policy
|
||||
|
@ -274,14 +268,6 @@ public class SecurityPolicy {
|
|||
policy.mRequireEncryption = 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 (policy.mRequireEncryptionExternal) {
|
||||
if (Environment.isExternalStorageRemovable()
|
||||
|| !Environment.isExternalStorageEmulated()) {
|
||||
policy.mRequireEncryptionExternal = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If we ever support devices that can't disable cameras for any reason, we should
|
||||
// clear the mDontAllowCamera policy
|
||||
|
@ -425,11 +411,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)
|
||||
|
||||
|
@ -485,10 +466,6 @@ public class SecurityPolicy {
|
|||
|
||||
// encryption required
|
||||
dpm.setStorageEncryption(mAdminName, aggregatePolicy.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.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
private Policy setupPolicy(int minPasswordLength, int passwordMode, int maxPasswordFails,
|
||||
int maxScreenLockTime, boolean requireRemoteWipe, int passwordExpirationDays,
|
||||
int passwordHistory, int passwordComplexChars, boolean requireEncryption,
|
||||
boolean requireEncryptionExternal, boolean dontAllowCamera)
|
||||
boolean dontAllowCamera)
|
||||
throws IllegalArgumentException {
|
||||
Policy policy = new Policy();
|
||||
policy.mPasswordMinLength = minPasswordLength;
|
||||
|
@ -117,7 +117,6 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
policy.mPasswordHistory = passwordHistory;
|
||||
policy.mPasswordComplexChars = passwordComplexChars;
|
||||
policy.mRequireEncryption = requireEncryption;
|
||||
policy.mRequireEncryptionExternal = requireEncryptionExternal;
|
||||
policy.mDontAllowCamera = dontAllowCamera;
|
||||
return policy;
|
||||
}
|
||||
|
@ -140,7 +139,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
// first test with partially-populated policies
|
||||
Account a3 = ProviderTestUtils.setupAccount("sec-3", true, mMockContext);
|
||||
Policy p3ain = setupPolicy(10, Policy.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
|
||||
false, false, false);
|
||||
false, false);
|
||||
Policy.setAccountPolicy(mMockContext, a3, p3ain, null);
|
||||
Policy p3aout = mSecurityPolicy.computeAggregatePolicy();
|
||||
assertNotNull(p3aout);
|
||||
|
@ -148,7 +147,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
|
||||
// Repeat that test with fully-populated policies
|
||||
Policy p3bin = setupPolicy(10, Policy.PASSWORD_MODE_SIMPLE, 15, 16, false, 6, 2, 3,
|
||||
false, false, false);
|
||||
false, false);
|
||||
Policy.setAccountPolicy(mMockContext, a3, p3bin, null);
|
||||
Policy p3bout = mSecurityPolicy.computeAggregatePolicy();
|
||||
assertNotNull(p3bout);
|
||||
|
@ -161,10 +160,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
|
||||
// don't allow camera - OR logic - will change here because it's true
|
||||
Policy p4in = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 0, 5, 7,
|
||||
false, false, true);
|
||||
false, true);
|
||||
Account a4 = ProviderTestUtils.setupAccount("sec-4", true, mMockContext);
|
||||
Policy.setAccountPolicy(mMockContext, a4, p4in, null);
|
||||
Policy p4out = mSecurityPolicy.computeAggregatePolicy();
|
||||
|
@ -188,10 +186,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
|
||||
// don't allow camera - OR logic - will *not* change here because it's already true
|
||||
Policy p5in = setupPolicy(4, Policy.PASSWORD_MODE_SIMPLE, 5, 6, true, 1, 0, 0,
|
||||
true, false, false);
|
||||
true, false);
|
||||
Account a5 = ProviderTestUtils.setupAccount("sec-5", true, mMockContext);
|
||||
Policy.setAccountPolicy(mMockContext, a5, p5in, null);
|
||||
Policy p5out = mSecurityPolicy.computeAggregatePolicy();
|
||||
|
@ -210,7 +207,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
// add another account that continues to mutate fields
|
||||
// encryption external req'd - OR logic - will change here because true
|
||||
Policy p6in = setupPolicy(0, Policy.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0,
|
||||
false, true, false);
|
||||
false, false);
|
||||
Account a6 = ProviderTestUtils.setupAccount("sec-6", true, mMockContext);
|
||||
Policy.setAccountPolicy(mMockContext, a6, p6in, null);
|
||||
Policy p6out = mSecurityPolicy.computeAggregatePolicy();
|
||||
|
@ -246,13 +243,13 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
Account account = ProviderTestUtils.setupAccount("testaccount", true, mMockContext);
|
||||
long accountId = account.mId;
|
||||
Policy initial = setupPolicy(10, Policy.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
|
||||
false, false, false);
|
||||
false, false);
|
||||
Policy.setAccountPolicy(mMockContext, accountId, initial, null);
|
||||
|
||||
long oldKey = assertAccountPolicyConsistent(account.mId, 0);
|
||||
|
||||
Policy updated = setupPolicy(10, Policy.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
|
||||
false, false, false);
|
||||
false, false);
|
||||
Policy.setAccountPolicy(mMockContext, accountId, updated, null);
|
||||
oldKey = assertAccountPolicyConsistent(account.mId, oldKey);
|
||||
|
||||
|
@ -270,13 +267,13 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
@SmallTest
|
||||
public void testEquals() {
|
||||
Policy p1 =
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false, false);
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
|
||||
Policy p2 =
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false, false);
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
|
||||
Policy p3 =
|
||||
setupPolicy(2, Policy.PASSWORD_MODE_SIMPLE, 5, 6, true, 7, 8, 9, false, false, false);
|
||||
setupPolicy(2, Policy.PASSWORD_MODE_SIMPLE, 5, 6, true, 7, 8, 9, false, false);
|
||||
Policy p4 =
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false, true);
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, true);
|
||||
assertTrue(p1.equals(p2));
|
||||
assertFalse(p2.equals(p3));
|
||||
assertFalse(p1.equals(p4));
|
||||
|
@ -327,12 +324,12 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
public void testDisableAdmin() {
|
||||
Account a1 = ProviderTestUtils.setupAccount("disable-1", true, mMockContext);
|
||||
Policy p1 = setupPolicy(10, Policy.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
|
||||
false, false, false);
|
||||
false, false);
|
||||
Policy.setAccountPolicy(mMockContext, a1, p1, "security-sync-key-1");
|
||||
|
||||
Account a2 = ProviderTestUtils.setupAccount("disable-2", true, mMockContext);
|
||||
Policy p2 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0,
|
||||
false, false, false);
|
||||
false, false);
|
||||
Policy.setAccountPolicy(mMockContext, a2, p2, "security-sync-key-2");
|
||||
|
||||
Account a3 = ProviderTestUtils.setupAccount("disable-3", true, mMockContext);
|
||||
|
@ -388,7 +385,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
Account a2 =
|
||||
ProviderTestUtils.setupAccount("expiring-2", true, mMockContext);
|
||||
Policy p2 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0,
|
||||
false, false, true);
|
||||
false, true);
|
||||
Policy.setAccountPolicy(mMockContext, a2, p2, null);
|
||||
|
||||
// The expiring account should be returned
|
||||
|
@ -398,7 +395,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
// Add an account with a longer expiration
|
||||
Account a3 = ProviderTestUtils.setupAccount("expiring-3", true, mMockContext);
|
||||
Policy p3 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 60, 0, 0,
|
||||
false, false, true);
|
||||
false, true);
|
||||
Policy.setAccountPolicy(mMockContext, a3, p3, null);
|
||||
|
||||
// The original expiring account (a2) should be returned
|
||||
|
@ -408,7 +405,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
// Add an account with a shorter expiration
|
||||
Account a4 = ProviderTestUtils.setupAccount("expiring-4", true, mMockContext);
|
||||
Policy p4 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 15, 0, 0,
|
||||
false, false, true);
|
||||
false, true);
|
||||
Policy.setAccountPolicy(mMockContext, a4, p4, null);
|
||||
|
||||
// The new expiring account (a4) should be returned
|
||||
|
@ -438,7 +435,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
Account a1 = ProviderTestUtils.setupAccount("expired-1", true, mMockContext);
|
||||
Account a2 = ProviderTestUtils.setupAccount("expired-2", true, mMockContext);
|
||||
Policy p2 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0,
|
||||
false, false, true);
|
||||
false, true);
|
||||
Policy.setAccountPolicy(mMockContext, a2, p2, null);
|
||||
|
||||
// Add a mailbox & messages to each account
|
||||
|
@ -464,7 +461,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
// Add 3rd account that really expires
|
||||
Account a3 = ProviderTestUtils.setupAccount("expired-3", true, mMockContext);
|
||||
Policy p3 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0,
|
||||
false, false, true);
|
||||
false, true);
|
||||
Policy.setAccountPolicy(mMockContext, a3, p3, null);
|
||||
|
||||
// Add mailbox & messages to 3rd account
|
||||
|
@ -502,11 +499,9 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
*/
|
||||
public void testClearUnsupportedPolicies() {
|
||||
Policy p1 =
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false, false);
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
|
||||
Policy p2 =
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, true, false, false);
|
||||
Policy p3 =
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, true, false);
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, true, false);
|
||||
|
||||
mSecurityPolicy = SecurityPolicy.getInstance(mMockContext);
|
||||
DevicePolicyManager dpm = mSecurityPolicy.getDPM();
|
||||
|
@ -515,23 +510,18 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
|
||||
Policy p1Result = mSecurityPolicy.clearUnsupportedPolicies(p1);
|
||||
Policy p2Result = mSecurityPolicy.clearUnsupportedPolicies(p2);
|
||||
Policy p3Result = mSecurityPolicy.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
|
||||
Policy policyExpect =
|
||||
setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false,
|
||||
false, false);
|
||||
false);
|
||||
assertEquals(policyExpect, p2Result);
|
||||
assertEquals(policyExpect, p3Result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -541,25 +531,25 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
|
|||
public void testGetDPManagerPasswordQuality() {
|
||||
// Policy.PASSWORD_MODE_NONE -> DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
|
||||
Policy p1 = setupPolicy(0, Policy.PASSWORD_MODE_NONE,
|
||||
0, 0, false, 0, 0, 0, false, false, false);
|
||||
0, 0, false, 0, 0, 0, false, false);
|
||||
assertEquals(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
|
||||
p1.getDPManagerPasswordQuality());
|
||||
|
||||
// PASSWORD_MODE_SIMPLE -> PASSWORD_QUALITY_NUMERIC
|
||||
Policy p2 = setupPolicy(4, Policy.PASSWORD_MODE_SIMPLE,
|
||||
0, 0, false, 0, 0, 0, false, false, false);
|
||||
0, 0, false, 0, 0, 0, false, false);
|
||||
assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
|
||||
p2.getDPManagerPasswordQuality());
|
||||
|
||||
// PASSWORD_MODE_STRONG -> PASSWORD_QUALITY_ALPHANUMERIC
|
||||
Policy p3 = setupPolicy(4, Policy.PASSWORD_MODE_STRONG,
|
||||
0, 0, false, 0, 0, 0, false, false, false);
|
||||
0, 0, false, 0, 0, 0, false, false);
|
||||
assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
|
||||
p3.getDPManagerPasswordQuality());
|
||||
|
||||
// PASSWORD_MODE_STRONG + complex chars -> PASSWORD_QUALITY_COMPLEX
|
||||
Policy p4 = setupPolicy(4, Policy.PASSWORD_MODE_STRONG,
|
||||
0, 0, false, 0, 0 , 2, false, false, false);
|
||||
0, 0, false, 0, 0 , 2, false, false);
|
||||
assertEquals(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX,
|
||||
p4.getDPManagerPasswordQuality());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue