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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user