summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChad Brubaker <cbrubaker@google.com>2015-05-12 10:43:10 -0700
committerChad Brubaker <cbrubaker@google.com>2015-05-13 10:32:40 -0700
commitc0f031a867a6c3fa05732fcd72bd284d56073cf8 (patch)
treebb45743eae8c8e81a718f9e39e576547702557ff
parent72593ee807e89239d98ae08d32c733ecc08203ba (diff)
downloadandroid_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.cpp59
-rw-r--r--keystore/include/keystore/IKeystoreService.h6
-rw-r--r--keystore/keystore.cpp32
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;