am cf5d78fb: Merge "Keep managed profile keystores in sync with owner" into lmp-dev

* commit 'cf5d78fb25a6c1d623ea8d8f5eddab8d6cd3e556':
  Keep managed profile keystores in sync with owner
This commit is contained in:
Robin Lee
2014-08-29 23:35:49 +00:00
committed by Android Git Automerger
3 changed files with 155 additions and 10 deletions

View File

@@ -478,6 +478,59 @@ public interface IKeystoreService extends IInterface {
}
return _result;
}
public int reset_uid(int uid) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(uid);
mRemote.transact(Stub.TRANSACTION_reset_uid, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public int sync_uid(int srcUid, int dstUid) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(srcUid);
_data.writeInt(dstUid);
mRemote.transact(Stub.TRANSACTION_sync_uid, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public int password_uid(String password, int uid) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(password);
_data.writeInt(uid);
mRemote.transact(Stub.TRANSACTION_password_uid, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
private static final String DESCRIPTOR = "android.security.keystore";
@@ -505,6 +558,9 @@ public interface IKeystoreService extends IInterface {
static final int TRANSACTION_duplicate = IBinder.FIRST_CALL_TRANSACTION + 20;
static final int TRANSACTION_is_hardware_backed = IBinder.FIRST_CALL_TRANSACTION + 21;
static final int TRANSACTION_clear_uid = IBinder.FIRST_CALL_TRANSACTION + 22;
static final int TRANSACTION_reset_uid = IBinder.FIRST_CALL_TRANSACTION + 23;
static final int TRANSACTION_sync_uid = IBinder.FIRST_CALL_TRANSACTION + 24;
static final int TRANSACTION_password_uid = IBinder.FIRST_CALL_TRANSACTION + 25;
/**
* Cast an IBinder object into an IKeystoreService interface, generating
@@ -597,4 +653,10 @@ public interface IKeystoreService extends IInterface {
public int is_hardware_backed(String string) throws RemoteException;
public int clear_uid(long uid) throws RemoteException;
public int reset_uid(int uid) throws RemoteException;
public int sync_uid(int sourceUid, int targetUid) throws RemoteException;
public int password_uid(String password, int uid) throws RemoteException;
}

View File

@@ -331,6 +331,36 @@ public class KeyStore {
}
}
public boolean resetUid(int uid) {
try {
mError = mBinder.reset_uid(uid);
return mError == NO_ERROR;
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return false;
}
}
public boolean syncUid(int sourceUid, int targetUid) {
try {
mError = mBinder.sync_uid(sourceUid, targetUid);
return mError == NO_ERROR;
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return false;
}
}
public boolean passwordUid(String password, int uid) {
try {
mError = mBinder.password_uid(password, uid);
return mError == NO_ERROR;
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return false;
}
}
public int getLastError() {
return mError;
}

View File

@@ -16,9 +16,12 @@
package com.android.server;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
@@ -31,6 +34,7 @@ import android.database.sqlite.SQLiteStatement;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.storage.IMountService;
import android.os.ServiceManager;
@@ -41,11 +45,14 @@ import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.provider.Settings.SettingNotFoundException;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
import android.security.KeyStore;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import com.android.internal.os.BackgroundThread;
import com.android.internal.widget.ILockSettings;
import com.android.internal.widget.ILockSettingsObserver;
import com.android.internal.widget.LockPatternUtils;
@@ -99,8 +106,30 @@ public class LockSettingsService extends ILockSettings.Stub {
mLockPatternUtils = new LockPatternUtils(context);
mFirstCallToVold = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_ADDED);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Update keystore settings for profiles which use the same password as their parent
if (Intent.ACTION_USER_STARTED.equals(intent.getAction())) {
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
final UserInfo parentInfo = um.getProfileParent(userHandle);
if (parentInfo != null) {
final KeyStore ks = KeyStore.getInstance();
final int profileUid = UserHandle.getUid(userHandle, Process.SYSTEM_UID);
final int parentUid = UserHandle.getUid(parentInfo.id, Process.SYSTEM_UID);
ks.syncUid(parentUid, profileUid);
}
}
}
};
public void systemReady() {
migrateOldData();
}
@@ -275,6 +304,17 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
private int getUserParentOrSelfId(int userId) {
if (userId != 0) {
final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
final UserInfo pi = um.getProfileParent(userId);
if (pi != null) {
return pi.id;
}
}
return userId;
}
private String getLockPatternFilename(int userId) {
String dataSystemDirectory =
android.os.Environment.getDataDirectory().getAbsolutePath() +
@@ -283,6 +323,7 @@ public class LockSettingsService extends ILockSettings.Stub {
// Leave it in the same place for user 0
return dataSystemDirectory + LOCK_PATTERN_FILE;
} else {
userId = getUserParentOrSelfId(userId);
return new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE)
.getAbsolutePath();
}
@@ -296,7 +337,8 @@ public class LockSettingsService extends ILockSettings.Stub {
// Leave it in the same place for user 0
return dataSystemDirectory + LOCK_PASSWORD_FILE;
} else {
return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE)
userId = getUserParentOrSelfId(userId);
return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE)
.getAbsolutePath();
}
}
@@ -315,16 +357,27 @@ public class LockSettingsService extends ILockSettings.Stub {
return new File(getLockPatternFilename(userId)).length() > 0;
}
private void maybeUpdateKeystore(String password, int userId) {
if (userId == UserHandle.USER_OWNER) {
final KeyStore keyStore = KeyStore.getInstance();
// Conditionally reset the keystore if empty. If non-empty, we are just
// switching key guard type
if (TextUtils.isEmpty(password) && keyStore.isEmpty()) {
keyStore.reset();
private void maybeUpdateKeystore(String password, int userHandle) {
final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
final KeyStore ks = KeyStore.getInstance();
final List<UserInfo> profiles = um.getProfiles(userHandle);
boolean shouldReset = TextUtils.isEmpty(password);
// For historical reasons, don't wipe a non-empty keystore if we have a single user with a
// single profile.
if (userHandle == UserHandle.USER_OWNER && profiles.size() == 1) {
if (!ks.isEmpty()) {
shouldReset = false;
}
}
for (UserInfo pi : profiles) {
final int profileUid = UserHandle.getUid(pi.id, Process.SYSTEM_UID);
if (shouldReset) {
ks.resetUid(profileUid);
} else {
// Update the keystore password
keyStore.password(password);
ks.passwordUid(password, profileUid);
}
}
}