diff options
author | Chad Brubaker <cbrubaker@google.com> | 2015-05-12 10:43:10 -0700 |
---|---|---|
committer | Chad Brubaker <cbrubaker@google.com> | 2015-05-13 10:32:40 -0700 |
commit | c0f031a867a6c3fa05732fcd72bd284d56073cf8 (patch) | |
tree | bb45743eae8c8e81a718f9e39e576547702557ff | |
parent | 72593ee807e89239d98ae08d32c733ecc08203ba (diff) | |
download | android_system_security-c0f031a867a6c3fa05732fcd72bd284d56073cf8.tar.gz android_system_security-c0f031a867a6c3fa05732fcd72bd284d56073cf8.tar.bz2 android_system_security-c0f031a867a6c3fa05732fcd72bd284d56073cf8.zip |
Add onUserAdded/Removed methods
These will handle the logic of Android users being added/removed from
the device instead of the system calling the various reset/sync methods.
(cherry-picked from commit fd777e7111ce01c672706867302db08371e5afce)
Change-Id: Ic6be0de63cc1b0579a46e7101dcfeb1a9ffa4738
-rw-r--r-- | keystore/IKeystoreService.cpp | 59 | ||||
-rw-r--r-- | keystore/include/keystore/IKeystoreService.h | 6 | ||||
-rw-r--r-- | keystore/keystore.cpp | 32 |
3 files changed, 97 insertions, 0 deletions
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp index 64530f5..ab31418 100644 --- a/keystore/IKeystoreService.cpp +++ b/keystore/IKeystoreService.cpp @@ -1291,6 +1291,46 @@ public: } return ret; }; + + virtual int32_t onUserAdded(int32_t userId, int32_t parentId) + { + Parcel data, reply; + data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); + data.writeInt32(userId); + data.writeInt32(parentId); + status_t status = remote()->transact(BnKeystoreService::ON_USER_ADDED, data, &reply); + if (status != NO_ERROR) { + ALOGD("onUserAdded() could not contact remote: %d\n", status); + return -1; + } + int32_t err = reply.readExceptionCode(); + int32_t ret = reply.readInt32(); + if (err < 0) { + ALOGD("onUserAdded() caught exception %d\n", err); + return -1; + } + return ret; + } + + virtual int32_t onUserRemoved(int32_t userId) + { + Parcel data, reply; + data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); + data.writeInt32(userId); + status_t status = remote()->transact(BnKeystoreService::ON_USER_REMOVED, data, &reply); + if (status != NO_ERROR) { + ALOGD("onUserRemoved() could not contact remote: %d\n", status); + return -1; + } + int32_t err = reply.readExceptionCode(); + int32_t ret = reply.readInt32(); + if (err < 0) { + ALOGD("onUserRemoved() caught exception %d\n", err); + return -1; + } + return ret; + } + }; IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService"); @@ -1794,6 +1834,25 @@ status_t BnKeystoreService::onTransact( return NO_ERROR; } + case ON_USER_ADDED: { + CHECK_INTERFACE(IKeystoreService, data, reply); + int32_t userId = data.readInt32(); + int32_t parentId = data.readInt32(); + int32_t result = onUserAdded(userId, parentId); + reply->writeNoException(); + reply->writeInt32(result); + + return NO_ERROR; + } + case ON_USER_REMOVED: { + CHECK_INTERFACE(IKeystoreService, data, reply); + int32_t userId = data.readInt32(); + int32_t result = onUserRemoved(userId); + reply->writeNoException(); + reply->writeInt32(result); + + return NO_ERROR; + } default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h index d0cf6f5..7fdfe38 100644 --- a/keystore/include/keystore/IKeystoreService.h +++ b/keystore/include/keystore/IKeystoreService.h @@ -135,6 +135,8 @@ public: ABORT = IBinder::FIRST_CALL_TRANSACTION + 34, IS_OPERATION_AUTHORIZED = IBinder::FIRST_CALL_TRANSACTION + 35, ADD_AUTH_TOKEN = IBinder::FIRST_CALL_TRANSACTION + 36, + ON_USER_ADDED = IBinder::FIRST_CALL_TRANSACTION + 37, + ON_USER_REMOVED = IBinder::FIRST_CALL_TRANSACTION + 38, }; DECLARE_META_INTERFACE(KeystoreService); @@ -236,6 +238,10 @@ public: virtual int32_t addAuthToken(const uint8_t* token, size_t length) = 0; + virtual int32_t onUserAdded(int32_t userId, int32_t parentId) = 0; + + virtual int32_t onUserRemoved(int32_t userId) = 0; + }; // ---------------------------------------------------------------------------- diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp index c321c45..3068756 100644 --- a/keystore/keystore.cpp +++ b/keystore/keystore.cpp @@ -172,6 +172,7 @@ typedef enum { P_SYNC_UID = 1 << 17, P_PASSWORD_UID = 1 << 18, P_ADD_AUTH = 1 << 19, + P_USER_CHANGED = 1 << 20, } perm_t; static struct user_euid { @@ -205,6 +206,7 @@ const char *perm_labels[] = { "sync_uid", "password_uid", "add_auth", + "user_changed", }; static struct user_perm { @@ -1813,6 +1815,36 @@ public: } } + int32_t onUserAdded(int32_t userId, int32_t parentId) { + if (!checkBinderPermission(P_USER_CHANGED)) { + return ::PERMISSION_DENIED; + } + + // Sanity check that the new user has an empty keystore. + if (!mKeyStore->isEmpty(userId)) { + ALOGW("New user %d's keystore not empty. Clearing old entries.", userId); + } + // Unconditionally clear the keystore, just to be safe. + mKeyStore->resetUser(userId, false); + + // If the user has a parent user then use the parent's + // masterkey/password, otherwise there's nothing to do. + if (parentId != -1) { + return mKeyStore->copyMasterKey(parentId, userId); + } else { + return ::NO_ERROR; + } + } + + int32_t onUserRemoved(int32_t userId) { + if (!checkBinderPermission(P_USER_CHANGED)) { + return ::PERMISSION_DENIED; + } + + mKeyStore->resetUser(userId, false); + return ::NO_ERROR; + } + int32_t lock() { if (!checkBinderPermission(P_LOCK)) { return ::PERMISSION_DENIED; |