diff options
| -rw-r--r-- | services/core/java/com/android/server/accounts/AccountManagerService.java | 88 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java | 62 |
2 files changed, 20 insertions, 130 deletions
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 765afef4857d..2af5316fb352 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -1773,8 +1773,7 @@ public class AccountManagerService // Create a Session for the target user and pass in the bundle completeCloningAccount(response, result, account, toAccounts, userFrom); } else { - // Bundle format is not defined. - super.onResultSkipSanitization(result); + super.onResult(result); } } }.bind(); @@ -1861,8 +1860,7 @@ public class AccountManagerService // account to avoid retries? // TODO: what we do with the visibility? - // Bundle format is not defined. - super.onResultSkipSanitization(result); + super.onResult(result); } @Override @@ -2108,7 +2106,6 @@ public class AccountManagerService @Override public void onResult(Bundle result) { Bundle.setDefusable(result, true); - result = sanitizeBundle(result); IAccountManagerResponse response = getResponseAndClose(); if (response != null) { try { @@ -2459,7 +2456,6 @@ public class AccountManagerService @Override public void onResult(Bundle result) { Bundle.setDefusable(result, true); - result = sanitizeBundle(result); if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) && !result.containsKey(AccountManager.KEY_INTENT)) { final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); @@ -2974,7 +2970,6 @@ public class AccountManagerService @Override public void onResult(Bundle result) { Bundle.setDefusable(result, true); - result = sanitizeBundle(result); if (result != null) { String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL); Bundle bundle = new Bundle(); @@ -3152,7 +3147,6 @@ public class AccountManagerService @Override public void onResult(Bundle result) { Bundle.setDefusable(result, true); - result = sanitizeBundle(result); if (result != null) { if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) { Intent intent = newGrantCredentialsPermissionIntent( @@ -3624,12 +3618,6 @@ public class AccountManagerService @Override public void onResult(Bundle result) { Bundle.setDefusable(result, true); - Bundle sessionBundle = null; - if (result != null) { - // Session bundle will be removed from result. - sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE); - } - result = sanitizeBundle(result); mNumResults++; Intent intent = null; if (result != null) { @@ -3691,6 +3679,7 @@ public class AccountManagerService // bundle contains data necessary for finishing the session // later. The session bundle will be encrypted here and // decrypted later when trying to finish the session. + Bundle sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE); if (sessionBundle != null) { String accountType = sessionBundle.getString(AccountManager.KEY_ACCOUNT_TYPE); if (TextUtils.isEmpty(accountType) @@ -4078,7 +4067,6 @@ public class AccountManagerService @Override public void onResult(Bundle result) { Bundle.setDefusable(result, true); - result = sanitizeBundle(result); IAccountManagerResponse response = getResponseAndClose(); if (response == null) { return; @@ -4392,7 +4380,6 @@ public class AccountManagerService @Override public void onResult(Bundle result) { Bundle.setDefusable(result, true); - result = sanitizeBundle(result); mNumResults++; if (result == null) { onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); @@ -4949,68 +4936,6 @@ public class AccountManagerService callback, resultReceiver); } - - // All keys for Strings passed from AbstractAccountAuthenticator using Bundle. - private static final String[] sStringBundleKeys = new String[] { - AccountManager.KEY_ACCOUNT_NAME, - AccountManager.KEY_ACCOUNT_TYPE, - AccountManager.KEY_AUTHTOKEN, - AccountManager.KEY_AUTH_TOKEN_LABEL, - AccountManager.KEY_ERROR_MESSAGE, - AccountManager.KEY_PASSWORD, - AccountManager.KEY_ACCOUNT_STATUS_TOKEN}; - - /** - * Keep only documented fields in a Bundle received from AbstractAccountAuthenticator. - */ - protected static Bundle sanitizeBundle(Bundle bundle) { - if (bundle == null) { - return null; - } - Bundle sanitizedBundle = new Bundle(); - Bundle.setDefusable(sanitizedBundle, true); - int updatedKeysCount = 0; - for (String stringKey : sStringBundleKeys) { - if (bundle.containsKey(stringKey)) { - String value = bundle.getString(stringKey); - sanitizedBundle.putString(stringKey, value); - updatedKeysCount++; - } - } - String key = AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY; - if (bundle.containsKey(key)) { - long expiryMillis = bundle.getLong(key, 0L); - sanitizedBundle.putLong(key, expiryMillis); - updatedKeysCount++; - } - key = AccountManager.KEY_BOOLEAN_RESULT; - if (bundle.containsKey(key)) { - boolean booleanResult = bundle.getBoolean(key, false); - sanitizedBundle.putBoolean(key, booleanResult); - updatedKeysCount++; - } - key = AccountManager.KEY_ERROR_CODE; - if (bundle.containsKey(key)) { - int errorCode = bundle.getInt(key, 0); - sanitizedBundle.putInt(key, errorCode); - updatedKeysCount++; - } - key = AccountManager.KEY_INTENT; - if (bundle.containsKey(key)) { - Intent intent = bundle.getParcelable(key, Intent.class); - sanitizedBundle.putParcelable(key, intent); - updatedKeysCount++; - } - if (bundle.containsKey(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE)) { - // The field is not copied in sanitized bundle. - updatedKeysCount++; - } - if (updatedKeysCount != bundle.size()) { - Log.w(TAG, "Size mismatch after sanitizeBundle call."); - } - return sanitizedBundle; - } - private abstract class Session extends IAccountAuthenticatorResponse.Stub implements IBinder.DeathRecipient, ServiceConnection { private final Object mSessionLock = new Object(); @@ -5301,15 +5226,10 @@ public class AccountManagerService } } } + @Override public void onResult(Bundle result) { Bundle.setDefusable(result, true); - result = sanitizeBundle(result); - onResultSkipSanitization(result); - } - - public void onResultSkipSanitization(Bundle result) { - Bundle.setDefusable(result, true); mNumResults++; Intent intent = null; if (result != null) { diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index b9ce8ad0b018..0c92abce7254 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -1163,6 +1163,16 @@ public class AccountManagerServiceTest extends AndroidTestCase { verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture()); Bundle result = mBundleCaptor.getValue(); + Bundle sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE); + assertNotNull(sessionBundle); + // Assert that session bundle is decrypted and hence data is visible. + assertEquals(AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1, + sessionBundle.getString(AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1)); + // Assert finishSessionAsUser added calling uid and pid into the sessionBundle + assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_UID)); + assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_PID)); + assertEquals(sessionBundle.getString( + AccountManager.KEY_ANDROID_PACKAGE_NAME), "APCT.package"); // Verify response data assertNull(result.getString(AccountManager.KEY_AUTHTOKEN, null)); @@ -2111,6 +2121,12 @@ public class AccountManagerServiceTest extends AndroidTestCase { result.getString(AccountManager.KEY_ACCOUNT_NAME)); assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, result.getString(AccountManager.KEY_ACCOUNT_TYPE)); + + Bundle optionBundle = result.getParcelable( + AccountManagerServiceTestFixtures.KEY_OPTIONS_BUNDLE); + // Assert addAccountAsUser added calling uid and pid into the option bundle + assertTrue(optionBundle.containsKey(AccountManager.KEY_CALLER_UID)); + assertTrue(optionBundle.containsKey(AccountManager.KEY_CALLER_PID)); } @SmallTest @@ -3441,52 +3457,6 @@ public class AccountManagerServiceTest extends AndroidTestCase { + (readTotalTime.doubleValue() / readerCount / loopSize)); } - @SmallTest - public void testSanitizeBundle_expectedFields() throws Exception { - Bundle bundle = new Bundle(); - bundle.putString(AccountManager.KEY_ACCOUNT_NAME, "name"); - bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, "type"); - bundle.putString(AccountManager.KEY_AUTHTOKEN, "token"); - bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, "label"); - bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "error message"); - bundle.putString(AccountManager.KEY_PASSWORD, "password"); - bundle.putString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN, "status"); - - bundle.putLong(AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY, 123L); - bundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); - bundle.putInt(AccountManager.KEY_ERROR_CODE, 456); - - Bundle sanitizedBundle = AccountManagerService.sanitizeBundle(bundle); - assertEquals(sanitizedBundle.getString(AccountManager.KEY_ACCOUNT_NAME), "name"); - assertEquals(sanitizedBundle.getString(AccountManager.KEY_ACCOUNT_TYPE), "type"); - assertEquals(sanitizedBundle.getString(AccountManager.KEY_AUTHTOKEN), "token"); - assertEquals(sanitizedBundle.getString(AccountManager.KEY_AUTH_TOKEN_LABEL), "label"); - assertEquals(sanitizedBundle.getString(AccountManager.KEY_ERROR_MESSAGE), "error message"); - assertEquals(sanitizedBundle.getString(AccountManager.KEY_PASSWORD), "password"); - assertEquals(sanitizedBundle.getString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN), "status"); - - assertEquals(sanitizedBundle.getLong( - AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY, 0), 123L); - assertEquals(sanitizedBundle.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false), true); - assertEquals(sanitizedBundle.getInt(AccountManager.KEY_ERROR_CODE, 0), 456); - } - - @SmallTest - public void testSanitizeBundle_filtersUnexpectedFields() throws Exception { - Bundle bundle = new Bundle(); - bundle.putString(AccountManager.KEY_ACCOUNT_NAME, "name"); - bundle.putString("unknown_key", "value"); - Bundle sessionBundle = new Bundle(); - bundle.putBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE, sessionBundle); - - Bundle sanitizedBundle = AccountManagerService.sanitizeBundle(bundle); - - assertEquals(sanitizedBundle.getString(AccountManager.KEY_ACCOUNT_NAME), "name"); - assertFalse(sanitizedBundle.containsKey("unknown_key")); - // It is a valid response from Authenticator which will be accessed using original Bundle - assertFalse(sanitizedBundle.containsKey(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE)); - } - private void waitForCyclicBarrier(CyclicBarrier cyclicBarrier) { try { cyclicBarrier.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS); |