Add DPM.getKeyPairGrants()
The method returns names of the packages that have access to the key grouped by UID since grants are stored on per-uid basis. This is expressed as Set<Set<String>> Since Binder currently doesn't support sets or lists of lists, this data structure is flattened into a list of strings, with null values used as a delimiter. Bug: 160457441 Test: atest com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testKeyManagement Test: atest com.android.cts.devicepolicy.MixedDeviceOwnerTest#testDelegatedCertInstallerDirectly Test: atest android.admin.cts.DevicePolicyManagerTest Change-Id: Ieee1048b145fb8400eccbf32c054afc64b5d90c0
This commit is contained in:
@@ -6919,6 +6919,7 @@ package android.app.admin {
|
|||||||
method public int getGlobalPrivateDnsMode(@NonNull android.content.ComponentName);
|
method public int getGlobalPrivateDnsMode(@NonNull android.content.ComponentName);
|
||||||
method @NonNull public java.util.List<byte[]> getInstalledCaCerts(@Nullable android.content.ComponentName);
|
method @NonNull public java.util.List<byte[]> getInstalledCaCerts(@Nullable android.content.ComponentName);
|
||||||
method @Nullable public java.util.List<java.lang.String> getKeepUninstalledPackages(@Nullable android.content.ComponentName);
|
method @Nullable public java.util.List<java.lang.String> getKeepUninstalledPackages(@Nullable android.content.ComponentName);
|
||||||
|
method @NonNull public java.util.Set<java.util.Set<java.lang.String>> getKeyPairGrants(@NonNull String);
|
||||||
method public int getKeyguardDisabledFeatures(@Nullable android.content.ComponentName);
|
method public int getKeyguardDisabledFeatures(@Nullable android.content.ComponentName);
|
||||||
method public int getLockTaskFeatures(@NonNull android.content.ComponentName);
|
method public int getLockTaskFeatures(@NonNull android.content.ComponentName);
|
||||||
method @NonNull public String[] getLockTaskPackages(@NonNull android.content.ComponentName);
|
method @NonNull public String[] getLockTaskPackages(@NonNull android.content.ComponentName);
|
||||||
|
|||||||
@@ -5618,7 +5618,6 @@ public class DevicePolicyManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by a device or profile owner, or delegated certificate chooser (an app that has been
|
* Called by a device or profile owner, or delegated certificate chooser (an app that has been
|
||||||
* delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to grant an application access
|
* delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to grant an application access
|
||||||
@@ -5654,6 +5653,51 @@ public class DevicePolicyManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by a device or profile owner, or delegated certificate chooser (an app that has been
|
||||||
|
* delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to query which apps have access
|
||||||
|
* to a given KeyChain key.
|
||||||
|
*
|
||||||
|
* Key are granted on a per-UID basis, so if several apps share the same UID, granting access to
|
||||||
|
* one of them automatically grants it to others. This method returns a set of sets of package
|
||||||
|
* names, where each internal set contains all packages sharing the same UID. Grantee packages
|
||||||
|
* that don't share UID with other packages are represented by singleton sets.
|
||||||
|
*
|
||||||
|
* @param alias The alias of the key to grant access to.
|
||||||
|
* @return package names of apps that have access to a given key, grouped by UIDs
|
||||||
|
*
|
||||||
|
* @throws SecurityException if the caller is not a device owner, a profile owner or
|
||||||
|
* delegated certificate chooser.
|
||||||
|
* @throws IllegalArgumentException if {@code alias} doesn't correspond to an existing key.
|
||||||
|
*
|
||||||
|
* @see #grantKeyPairToApp(ComponentName, String, String)
|
||||||
|
*/
|
||||||
|
public @NonNull Set<Set<String>> getKeyPairGrants(@NonNull String alias) {
|
||||||
|
throwIfParentInstance("getKeyPairGrants");
|
||||||
|
try {
|
||||||
|
// Set of sets is flattened into a null-separated list.
|
||||||
|
final List<String> flattened =
|
||||||
|
mService.getKeyPairGrants(mContext.getPackageName(), alias);
|
||||||
|
final Set<Set<String>> result = new HashSet<>();
|
||||||
|
Set<String> pkgsForOneUid = new HashSet<>();
|
||||||
|
for (final String pkg : flattened) {
|
||||||
|
if (pkg == null) {
|
||||||
|
result.add(pkgsForOneUid);
|
||||||
|
pkgsForOneUid = new HashSet<>();
|
||||||
|
} else {
|
||||||
|
pkgsForOneUid.add(pkg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pkgsForOneUid.isEmpty()) {
|
||||||
|
result.add(pkgsForOneUid);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by a device or profile owner, or delegated certificate chooser (an app that has been
|
* Called by a device or profile owner, or delegated certificate chooser (an app that has been
|
||||||
* delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to revoke an application's
|
* delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to revoke an application's
|
||||||
|
|||||||
@@ -471,6 +471,7 @@ interface IDevicePolicyManager {
|
|||||||
boolean startViewCalendarEventInManagedProfile(String packageName, long eventId, long start, long end, boolean allDay, int flags);
|
boolean startViewCalendarEventInManagedProfile(String packageName, long eventId, long start, long end, boolean allDay, int flags);
|
||||||
|
|
||||||
boolean setKeyGrantForApp(in ComponentName admin, String callerPackage, String alias, String packageName, boolean hasGrant);
|
boolean setKeyGrantForApp(in ComponentName admin, String callerPackage, String alias, String packageName, boolean hasGrant);
|
||||||
|
List<String> getKeyPairGrants(in String callerPackage, in String alias);
|
||||||
|
|
||||||
void setUserControlDisabledPackages(in ComponentName admin, in List<String> packages);
|
void setUserControlDisabledPackages(in ComponentName admin, in List<String> packages);
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ interface IKeyChainService {
|
|||||||
in byte[] privateKey, in byte[] userCert, in byte[] certChain, String alias, int uid);
|
in byte[] privateKey, in byte[] userCert, in byte[] certChain, String alias, int uid);
|
||||||
boolean removeKeyPair(String alias);
|
boolean removeKeyPair(String alias);
|
||||||
boolean containsKeyPair(String alias);
|
boolean containsKeyPair(String alias);
|
||||||
|
int[] getGrants(String alias);
|
||||||
|
|
||||||
// APIs used by Settings
|
// APIs used by Settings
|
||||||
boolean deleteCaCertificate(String alias);
|
boolean deleteCaCertificate(String alias);
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import android.util.Slog;
|
|||||||
|
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the required interface for IDevicePolicyManager implemenation.
|
* Defines the required interface for IDevicePolicyManager implemenation.
|
||||||
*
|
*
|
||||||
@@ -101,4 +103,9 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
|
|||||||
public boolean canProfileOwnerResetPasswordWhenLocked(int userId) {
|
public boolean canProfileOwnerResetPasswordWhenLocked(int userId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getKeyPairGrants(String callerPackage, String alias) {
|
||||||
|
// STOPSHIP: implement delegation code in ArcDevicePolicyManagerWrapperService & nuke this.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5169,6 +5169,44 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getKeyPairGrants(String callerPackage, String alias) {
|
||||||
|
final CallerIdentity caller = getCallerIdentity(callerPackage);
|
||||||
|
Preconditions.checkCallAuthorization(canManageCertificates(caller));
|
||||||
|
|
||||||
|
return mInjector.binderWithCleanCallingIdentity(() -> {
|
||||||
|
try (KeyChainConnection keyChainConnection =
|
||||||
|
KeyChain.bindAsUser(mContext, caller.getUserHandle())) {
|
||||||
|
final List<String> result = new ArrayList<>();
|
||||||
|
final int[] granteeUids = keyChainConnection.getService().getGrants(alias);
|
||||||
|
final PackageManager pm = mInjector.getPackageManager(caller.getUserId());
|
||||||
|
|
||||||
|
// TODO: Return Set<Set<String>> when AIDL supports it: b/136048684
|
||||||
|
// Public API returns a set of sets, where each internal set contains all package
|
||||||
|
// names corresponding to the same UID. For now a set of sets is marshalled as a
|
||||||
|
// null-separated list.
|
||||||
|
for (final int uid : granteeUids) {
|
||||||
|
final String[] packages = pm.getPackagesForUid(uid);
|
||||||
|
if (packages == null) {
|
||||||
|
Slog.wtf(LOG_TAG, "No packages found for uid " + uid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!result.isEmpty()) {
|
||||||
|
result.add(null);
|
||||||
|
}
|
||||||
|
result.addAll(Arrays.asList(packages));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(LOG_TAG, "Querying keypair grants", e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.w(LOG_TAG, "Interrupted while querying keypair grants", e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enforce one the following conditions are met:
|
* Enforce one the following conditions are met:
|
||||||
* (1) The device has a Device Owner, and one of the following holds:
|
* (1) The device has a Device Owner, and one of the following holds:
|
||||||
|
|||||||
Reference in New Issue
Block a user