Loading api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6266,6 +6266,7 @@ package android.app.admin { method public long getMaximumTimeToLock(android.content.ComponentName); method public int getOrganizationColor(android.content.ComponentName); method public java.lang.CharSequence getOrganizationName(android.content.ComponentName); method public java.util.List<java.lang.String> getOwnerInstalledCaCerts(android.os.UserHandle); method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName); method public long getPasswordExpiration(android.content.ComponentName); method public long getPasswordExpirationTimeout(android.content.ComponentName); core/java/android/app/admin/DevicePolicyManager.java +24 −0 Original line number Diff line number Diff line Loading @@ -7958,4 +7958,28 @@ public class DevicePolicyManager { throw re.rethrowFromSystemServer(); } } /** * Called by the system to get a list of CA certificates that were installed by the device or * profile owner. * * <p> The caller must be the target user's Device Owner/Profile owner or hold the * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission. * * @param user The user for whom to retrieve information. * @return list of aliases identifying CA certificates installed by the device or profile owner * @throws SecurityException if the caller does not have permission to retrieve information * about the given user's CA certificates. * * @hide */ @TestApi public List<String> getOwnerInstalledCaCerts(@NonNull UserHandle user) { try { return mService.getOwnerInstalledCaCerts(user).getList(); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } } core/java/android/app/admin/IDevicePolicyManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ParceledListSlice; import android.content.pm.StringParceledListSlice; import android.graphics.Bitmap; import android.net.ProxyInfo; import android.net.Uri; Loading Loading @@ -349,4 +350,5 @@ interface IDevicePolicyManager { boolean resetPasswordWithToken(in ComponentName admin, String password, in byte[] token, int flags); boolean isDefaultInputMethodSetByOwner(in UserHandle user); StringParceledListSlice getOwnerInstalledCaCerts(in UserHandle user); } keystore/java/android/security/IKeyChainService.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -29,8 +29,8 @@ interface IKeyChainService { byte[] getCertificate(String alias); byte[] getCaCertificates(String alias); // APIs used by CertInstaller void installCaCertificate(in byte[] caCertificate); // APIs used by CertInstaller and DevicePolicyManager String installCaCertificate(in byte[] caCertificate); // APIs used by DevicePolicyManager boolean installKeyPair(in byte[] privateKey, in byte[] userCert, in byte[] certChain, String alias); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +105 −21 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.StringParceledListSlice; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; Loading Loading @@ -166,6 +167,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BackgroundThread; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.JournaledFile; Loading Loading @@ -243,10 +245,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String TAG_DEFAULT_INPUT_METHOD_SET = "default-ime-set"; private static final String TAG_OWNER_INSTALLED_CA_CERT = "owner-installed-ca-cert"; private static final String ATTR_ID = "id"; private static final String ATTR_VALUE = "value"; private static final String ATTR_ALIAS = "alias"; private static final String TAG_INITIALIZATION_BUNDLE = "initialization-bundle"; private static final String TAG_PASSWORD_TOKEN_HANDLE = "password-token"; Loading Loading @@ -480,6 +486,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>(); final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<>(); // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead. final ArraySet<String> mAcceptedCaCertificates = new ArraySet<>(); // This is the list of component allowed to start lock task mode. Loading @@ -504,6 +511,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean mDefaultInputMethodSet = false; // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead. Set<String> mOwnerInstalledCaCerts = new ArraySet<>(); // Used for initialization of users created by createAndManageUsers. boolean mAdminBroadcastPending = false; PersistableBundle mInitBundle = null; Loading @@ -518,6 +528,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final SparseArray<DevicePolicyData> mUserData = new SparseArray<>(); final Handler mHandler; final Handler mBackgroundHandler; /** Listens on any device, even when mHasFeature == false. */ final BroadcastReceiver mRootCaReceiver = new BroadcastReceiver() { Loading Loading @@ -619,6 +630,25 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { handlePackagesChanged(intent.getData().getSchemeSpecificPart(), userHandle); } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action)) { clearWipeProfileNotification(); } else if (KeyChain.ACTION_TRUST_STORE_CHANGED.equals(intent.getAction())) { mBackgroundHandler.post(() -> { try (final KeyChainConnection keyChainConnection = mInjector.keyChainBindAsUser( UserHandle.of(userHandle))) { final List<String> caCerts = keyChainConnection.getService().getUserCaAliases().getList(); synchronized (DevicePolicyManagerService.this) { if (getUserData(userHandle).mOwnerInstalledCaCerts .retainAll(caCerts)) { saveSettingsLocked(userHandle); } } } catch (InterruptedException e) { Slog.w(LOG_TAG, "error talking to IKeyChainService", e); Thread.currentThread().interrupt(); } catch (RemoteException e) { Slog.w(LOG_TAG, "error talking to IKeyChainService", e); } }); } } Loading Loading @@ -1786,6 +1816,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { .hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN); mIsWatch = mInjector.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_WATCH); mBackgroundHandler = BackgroundThread.getHandler(); // Broadcast filter for changes to the trusted certificate store. These changes get a // separate intent filter so we can listen to them even when device_admin is off. Loading @@ -1807,6 +1838,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { filter.addAction(Intent.ACTION_USER_ADDED); filter.addAction(Intent.ACTION_USER_REMOVED); filter.addAction(Intent.ACTION_USER_STARTED); filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); filter = new IntentFilter(); Loading Loading @@ -2580,6 +2612,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.endTag(null, TAG_DEFAULT_INPUT_METHOD_SET); } for (final String cert : policy.mOwnerInstalledCaCerts) { out.startTag(null, TAG_OWNER_INSTALLED_CA_CERT); out.attribute(null, ATTR_ALIAS, cert); out.endTag(null, TAG_OWNER_INSTALLED_CA_CERT); } out.endTag(null, "policies"); out.endDocument(); Loading Loading @@ -2696,6 +2734,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mAdminList.clear(); policy.mAdminMap.clear(); policy.mAffiliationIds.clear(); policy.mOwnerInstalledCaCerts.clear(); while ((type=parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { Loading Loading @@ -2791,6 +2830,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { parser.getAttributeValue(null, ATTR_VALUE)); } else if (TAG_DEFAULT_INPUT_METHOD_SET.equals(tag)) { policy.mDefaultInputMethodSet = true; } else if (TAG_OWNER_INSTALLED_CA_CERT.equals(tag)) { policy.mOwnerInstalledCaCerts.add(parser.getAttributeValue(null, ATTR_ALIAS)); } else { Slog.w(LOG_TAG, "Unknown tag: " + tag); XmlUtils.skipCurrentTag(parser); Loading Loading @@ -4691,17 +4732,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return false; } final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); final UserHandle userHandle = UserHandle.of(mInjector.userHandleGetCallingUserId()); final long id = mInjector.binderClearCallingIdentity(); String alias = null; try { final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle); try { keyChainConnection.getService().installCaCertificate(pemCert); return true; try (final KeyChainConnection keyChainConnection = mInjector.keyChainBindAsUser( userHandle)) { alias = keyChainConnection.getService().installCaCertificate(pemCert); } catch (RemoteException e) { Log.e(LOG_TAG, "installCaCertsToKeyChain(): ", e); } finally { keyChainConnection.close(); } } catch (InterruptedException e1) { Log.w(LOG_TAG, "installCaCertsToKeyChain(): ", e1); Loading @@ -4709,6 +4748,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } finally { mInjector.binderRestoreCallingIdentity(id); } if (alias == null) { Log.w(LOG_TAG, "Problem installing cert"); } else { synchronized (this) { final int userId = userHandle.getIdentifier(); getUserData(userId).mOwnerInstalledCaCerts.add(alias); saveSettingsLocked(userId); } return true; } return false; } Loading @@ -4722,25 +4771,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { public void uninstallCaCerts(ComponentName admin, String callerPackage, String[] aliases) { enforceCanManageCaCerts(admin, callerPackage); final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); final int userId = mInjector.userHandleGetCallingUserId(); final UserHandle userHandle = UserHandle.of(userId); final long id = mInjector.binderClearCallingIdentity(); try { final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle); try { try (final KeyChainConnection keyChainConnection = mInjector.keyChainBindAsUser( userHandle)) { for (int i = 0 ; i < aliases.length; i++) { keyChainConnection.getService().deleteCaCertificate(aliases[i]); } } catch (RemoteException e) { Log.e(LOG_TAG, "from CaCertUninstaller: ", e); } finally { keyChainConnection.close(); return; } } catch (InterruptedException ie) { Log.w(LOG_TAG, "CaCertUninstaller: ", ie); Thread.currentThread().interrupt(); return; } finally { mInjector.binderRestoreCallingIdentity(id); } synchronized (this) { if (getUserData(userId).mOwnerInstalledCaCerts.removeAll(Arrays.asList(aliases))) { saveSettingsLocked(userId); } } } @Override Loading Loading @@ -6731,6 +6786,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; policyData.mOwnerInstalledCaCerts.clear(); saveSettingsLocked(userId); clearUserPoliciesLocked(userId); mOwners.removeProfileOwner(userId); Loading Loading @@ -7127,27 +7183,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private void enforceFullCrossUsersPermission(int userHandle) { enforceSystemUserOrPermission(userHandle, enforceSystemUserOrPermissionIfCrossUser(userHandle, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); } private void enforceCrossUsersPermission(int userHandle) { enforceSystemUserOrPermission(userHandle, enforceSystemUserOrPermissionIfCrossUser(userHandle, android.Manifest.permission.INTERACT_ACROSS_USERS); } private void enforceSystemUserOrPermission(int userHandle, String permission) { private void enforceSystemUserOrPermission(String permission) { if (!(isCallerWithSystemUid() || mInjector.binderGetCallingUid() == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission(permission, "Must be system or have " + permission + " permission"); } } private void enforceSystemUserOrPermissionIfCrossUser(int userHandle, String permission) { if (userHandle < 0) { throw new IllegalArgumentException("Invalid userId " + userHandle); } final int callingUid = mInjector.binderGetCallingUid(); if (userHandle == UserHandle.getUserId(callingUid)) { if (userHandle == mInjector.userHandleGetCallingUserId()) { return; } if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission(permission, "Must be system or have " + permission + " permission"); } enforceSystemUserOrPermission(permission); } private void enforceManagedProfile(int userHandle, String message) { Loading Loading @@ -7184,6 +7243,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { "Only profile owner, device owner and system may call this method."); } private void enforceProfileOwnerOrFullCrossUsersPermission(int userId) { if (userId == mInjector.userHandleGetCallingUserId()) { synchronized (this) { if (getActiveAdminWithPolicyForUidLocked(null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid()) != null) { // Device Owner/Profile Owner may access the user it runs on. return; } } } // Otherwise, INTERACT_ACROSS_USERS_FULL permission, system UID or root UID is required. enforceSystemUserOrPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); } private void ensureCallerPackage(@Nullable String packageName) { if (packageName == null) { Preconditions.checkState(isCallerWithSystemUid(), Loading Loading @@ -10897,4 +10971,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } return getUserData(userId).mDefaultInputMethodSet; } @Override public StringParceledListSlice getOwnerInstalledCaCerts(@NonNull UserHandle user) { final int userId = user.getIdentifier(); enforceProfileOwnerOrFullCrossUsersPermission(userId); synchronized (this) { return new StringParceledListSlice( new ArrayList<>(getUserData(userId).mOwnerInstalledCaCerts)); } } } Loading
api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6266,6 +6266,7 @@ package android.app.admin { method public long getMaximumTimeToLock(android.content.ComponentName); method public int getOrganizationColor(android.content.ComponentName); method public java.lang.CharSequence getOrganizationName(android.content.ComponentName); method public java.util.List<java.lang.String> getOwnerInstalledCaCerts(android.os.UserHandle); method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName); method public long getPasswordExpiration(android.content.ComponentName); method public long getPasswordExpirationTimeout(android.content.ComponentName);
core/java/android/app/admin/DevicePolicyManager.java +24 −0 Original line number Diff line number Diff line Loading @@ -7958,4 +7958,28 @@ public class DevicePolicyManager { throw re.rethrowFromSystemServer(); } } /** * Called by the system to get a list of CA certificates that were installed by the device or * profile owner. * * <p> The caller must be the target user's Device Owner/Profile owner or hold the * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission. * * @param user The user for whom to retrieve information. * @return list of aliases identifying CA certificates installed by the device or profile owner * @throws SecurityException if the caller does not have permission to retrieve information * about the given user's CA certificates. * * @hide */ @TestApi public List<String> getOwnerInstalledCaCerts(@NonNull UserHandle user) { try { return mService.getOwnerInstalledCaCerts(user).getList(); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } }
core/java/android/app/admin/IDevicePolicyManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ParceledListSlice; import android.content.pm.StringParceledListSlice; import android.graphics.Bitmap; import android.net.ProxyInfo; import android.net.Uri; Loading Loading @@ -349,4 +350,5 @@ interface IDevicePolicyManager { boolean resetPasswordWithToken(in ComponentName admin, String password, in byte[] token, int flags); boolean isDefaultInputMethodSetByOwner(in UserHandle user); StringParceledListSlice getOwnerInstalledCaCerts(in UserHandle user); }
keystore/java/android/security/IKeyChainService.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -29,8 +29,8 @@ interface IKeyChainService { byte[] getCertificate(String alias); byte[] getCaCertificates(String alias); // APIs used by CertInstaller void installCaCertificate(in byte[] caCertificate); // APIs used by CertInstaller and DevicePolicyManager String installCaCertificate(in byte[] caCertificate); // APIs used by DevicePolicyManager boolean installKeyPair(in byte[] privateKey, in byte[] userCert, in byte[] certChain, String alias); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +105 −21 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.StringParceledListSlice; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; Loading Loading @@ -166,6 +167,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BackgroundThread; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.JournaledFile; Loading Loading @@ -243,10 +245,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String TAG_DEFAULT_INPUT_METHOD_SET = "default-ime-set"; private static final String TAG_OWNER_INSTALLED_CA_CERT = "owner-installed-ca-cert"; private static final String ATTR_ID = "id"; private static final String ATTR_VALUE = "value"; private static final String ATTR_ALIAS = "alias"; private static final String TAG_INITIALIZATION_BUNDLE = "initialization-bundle"; private static final String TAG_PASSWORD_TOKEN_HANDLE = "password-token"; Loading Loading @@ -480,6 +486,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>(); final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<>(); // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead. final ArraySet<String> mAcceptedCaCertificates = new ArraySet<>(); // This is the list of component allowed to start lock task mode. Loading @@ -504,6 +511,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean mDefaultInputMethodSet = false; // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead. Set<String> mOwnerInstalledCaCerts = new ArraySet<>(); // Used for initialization of users created by createAndManageUsers. boolean mAdminBroadcastPending = false; PersistableBundle mInitBundle = null; Loading @@ -518,6 +528,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final SparseArray<DevicePolicyData> mUserData = new SparseArray<>(); final Handler mHandler; final Handler mBackgroundHandler; /** Listens on any device, even when mHasFeature == false. */ final BroadcastReceiver mRootCaReceiver = new BroadcastReceiver() { Loading Loading @@ -619,6 +630,25 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { handlePackagesChanged(intent.getData().getSchemeSpecificPart(), userHandle); } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action)) { clearWipeProfileNotification(); } else if (KeyChain.ACTION_TRUST_STORE_CHANGED.equals(intent.getAction())) { mBackgroundHandler.post(() -> { try (final KeyChainConnection keyChainConnection = mInjector.keyChainBindAsUser( UserHandle.of(userHandle))) { final List<String> caCerts = keyChainConnection.getService().getUserCaAliases().getList(); synchronized (DevicePolicyManagerService.this) { if (getUserData(userHandle).mOwnerInstalledCaCerts .retainAll(caCerts)) { saveSettingsLocked(userHandle); } } } catch (InterruptedException e) { Slog.w(LOG_TAG, "error talking to IKeyChainService", e); Thread.currentThread().interrupt(); } catch (RemoteException e) { Slog.w(LOG_TAG, "error talking to IKeyChainService", e); } }); } } Loading Loading @@ -1786,6 +1816,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { .hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN); mIsWatch = mInjector.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_WATCH); mBackgroundHandler = BackgroundThread.getHandler(); // Broadcast filter for changes to the trusted certificate store. These changes get a // separate intent filter so we can listen to them even when device_admin is off. Loading @@ -1807,6 +1838,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { filter.addAction(Intent.ACTION_USER_ADDED); filter.addAction(Intent.ACTION_USER_REMOVED); filter.addAction(Intent.ACTION_USER_STARTED); filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); filter = new IntentFilter(); Loading Loading @@ -2580,6 +2612,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.endTag(null, TAG_DEFAULT_INPUT_METHOD_SET); } for (final String cert : policy.mOwnerInstalledCaCerts) { out.startTag(null, TAG_OWNER_INSTALLED_CA_CERT); out.attribute(null, ATTR_ALIAS, cert); out.endTag(null, TAG_OWNER_INSTALLED_CA_CERT); } out.endTag(null, "policies"); out.endDocument(); Loading Loading @@ -2696,6 +2734,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mAdminList.clear(); policy.mAdminMap.clear(); policy.mAffiliationIds.clear(); policy.mOwnerInstalledCaCerts.clear(); while ((type=parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { Loading Loading @@ -2791,6 +2830,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { parser.getAttributeValue(null, ATTR_VALUE)); } else if (TAG_DEFAULT_INPUT_METHOD_SET.equals(tag)) { policy.mDefaultInputMethodSet = true; } else if (TAG_OWNER_INSTALLED_CA_CERT.equals(tag)) { policy.mOwnerInstalledCaCerts.add(parser.getAttributeValue(null, ATTR_ALIAS)); } else { Slog.w(LOG_TAG, "Unknown tag: " + tag); XmlUtils.skipCurrentTag(parser); Loading Loading @@ -4691,17 +4732,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return false; } final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); final UserHandle userHandle = UserHandle.of(mInjector.userHandleGetCallingUserId()); final long id = mInjector.binderClearCallingIdentity(); String alias = null; try { final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle); try { keyChainConnection.getService().installCaCertificate(pemCert); return true; try (final KeyChainConnection keyChainConnection = mInjector.keyChainBindAsUser( userHandle)) { alias = keyChainConnection.getService().installCaCertificate(pemCert); } catch (RemoteException e) { Log.e(LOG_TAG, "installCaCertsToKeyChain(): ", e); } finally { keyChainConnection.close(); } } catch (InterruptedException e1) { Log.w(LOG_TAG, "installCaCertsToKeyChain(): ", e1); Loading @@ -4709,6 +4748,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } finally { mInjector.binderRestoreCallingIdentity(id); } if (alias == null) { Log.w(LOG_TAG, "Problem installing cert"); } else { synchronized (this) { final int userId = userHandle.getIdentifier(); getUserData(userId).mOwnerInstalledCaCerts.add(alias); saveSettingsLocked(userId); } return true; } return false; } Loading @@ -4722,25 +4771,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { public void uninstallCaCerts(ComponentName admin, String callerPackage, String[] aliases) { enforceCanManageCaCerts(admin, callerPackage); final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); final int userId = mInjector.userHandleGetCallingUserId(); final UserHandle userHandle = UserHandle.of(userId); final long id = mInjector.binderClearCallingIdentity(); try { final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle); try { try (final KeyChainConnection keyChainConnection = mInjector.keyChainBindAsUser( userHandle)) { for (int i = 0 ; i < aliases.length; i++) { keyChainConnection.getService().deleteCaCertificate(aliases[i]); } } catch (RemoteException e) { Log.e(LOG_TAG, "from CaCertUninstaller: ", e); } finally { keyChainConnection.close(); return; } } catch (InterruptedException ie) { Log.w(LOG_TAG, "CaCertUninstaller: ", ie); Thread.currentThread().interrupt(); return; } finally { mInjector.binderRestoreCallingIdentity(id); } synchronized (this) { if (getUserData(userId).mOwnerInstalledCaCerts.removeAll(Arrays.asList(aliases))) { saveSettingsLocked(userId); } } } @Override Loading Loading @@ -6731,6 +6786,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; policyData.mOwnerInstalledCaCerts.clear(); saveSettingsLocked(userId); clearUserPoliciesLocked(userId); mOwners.removeProfileOwner(userId); Loading Loading @@ -7127,27 +7183,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private void enforceFullCrossUsersPermission(int userHandle) { enforceSystemUserOrPermission(userHandle, enforceSystemUserOrPermissionIfCrossUser(userHandle, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); } private void enforceCrossUsersPermission(int userHandle) { enforceSystemUserOrPermission(userHandle, enforceSystemUserOrPermissionIfCrossUser(userHandle, android.Manifest.permission.INTERACT_ACROSS_USERS); } private void enforceSystemUserOrPermission(int userHandle, String permission) { private void enforceSystemUserOrPermission(String permission) { if (!(isCallerWithSystemUid() || mInjector.binderGetCallingUid() == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission(permission, "Must be system or have " + permission + " permission"); } } private void enforceSystemUserOrPermissionIfCrossUser(int userHandle, String permission) { if (userHandle < 0) { throw new IllegalArgumentException("Invalid userId " + userHandle); } final int callingUid = mInjector.binderGetCallingUid(); if (userHandle == UserHandle.getUserId(callingUid)) { if (userHandle == mInjector.userHandleGetCallingUserId()) { return; } if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission(permission, "Must be system or have " + permission + " permission"); } enforceSystemUserOrPermission(permission); } private void enforceManagedProfile(int userHandle, String message) { Loading Loading @@ -7184,6 +7243,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { "Only profile owner, device owner and system may call this method."); } private void enforceProfileOwnerOrFullCrossUsersPermission(int userId) { if (userId == mInjector.userHandleGetCallingUserId()) { synchronized (this) { if (getActiveAdminWithPolicyForUidLocked(null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid()) != null) { // Device Owner/Profile Owner may access the user it runs on. return; } } } // Otherwise, INTERACT_ACROSS_USERS_FULL permission, system UID or root UID is required. enforceSystemUserOrPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); } private void ensureCallerPackage(@Nullable String packageName) { if (packageName == null) { Preconditions.checkState(isCallerWithSystemUid(), Loading Loading @@ -10897,4 +10971,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } return getUserData(userId).mDefaultInputMethodSet; } @Override public StringParceledListSlice getOwnerInstalledCaCerts(@NonNull UserHandle user) { final int userId = user.getIdentifier(); enforceProfileOwnerOrFullCrossUsersPermission(userId); synchronized (this) { return new StringParceledListSlice( new ArrayList<>(getUserData(userId).mOwnerInstalledCaCerts)); } } }