Merge "DPM API to set Wi-Fi minimum security level required"

This commit is contained in:
Stephanie Bak
2022-01-23 02:37:01 +00:00
committed by Android (Google) Code Review
6 changed files with 204 additions and 0 deletions

View File

@@ -7315,6 +7315,7 @@ package android.app.admin {
method public int getMaximumFailedPasswordsForWipe(@Nullable android.content.ComponentName);
method public long getMaximumTimeToLock(@Nullable android.content.ComponentName);
method @NonNull public java.util.List<java.lang.String> getMeteredDataDisabledPackages(@NonNull android.content.ComponentName);
method public int getMinimumRequiredWifiSecurityLevel();
method @RequiresPermission(value=android.Manifest.permission.READ_NEARBY_STREAMING_POLICY, conditional=true) public int getNearbyAppStreamingPolicy();
method @RequiresPermission(value=android.Manifest.permission.READ_NEARBY_STREAMING_POLICY, conditional=true) public int getNearbyNotificationStreamingPolicy();
method @Deprecated @ColorInt public int getOrganizationColor(@NonNull android.content.ComponentName);
@@ -7459,6 +7460,7 @@ package android.app.admin {
method public void setMaximumFailedPasswordsForWipe(@NonNull android.content.ComponentName, int);
method public void setMaximumTimeToLock(@NonNull android.content.ComponentName, long);
method @NonNull public java.util.List<java.lang.String> setMeteredDataDisabledPackages(@NonNull android.content.ComponentName, @NonNull java.util.List<java.lang.String>);
method public void setMinimumRequiredWifiSecurityLevel(int);
method public void setNearbyAppStreamingPolicy(int);
method public void setNearbyNotificationStreamingPolicy(int);
method public void setNetworkLoggingEnabled(@Nullable android.content.ComponentName, boolean);
@@ -7677,6 +7679,10 @@ package android.app.admin {
field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
field public static final int SKIP_SETUP_WIZARD = 1; // 0x1
field public static final int WIFI_SECURITY_ENTERPRISE_192 = 3; // 0x3
field public static final int WIFI_SECURITY_ENTERPRISE_EAP = 2; // 0x2
field public static final int WIFI_SECURITY_OPEN = 0; // 0x0
field public static final int WIFI_SECURITY_PERSONAL = 1; // 0x1
field public static final int WIPE_EUICC = 4; // 0x4
field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2

View File

@@ -1577,6 +1577,78 @@ public class DevicePolicyManager {
@SystemApi
public static final int FLAG_SUPPORTED_MODES_DEVICE_OWNER = 1 << 2;
/**
* Constant for {@link #getMinimumRequiredWifiSecurityLevel()} and
* {@link #setMinimumRequiredWifiSecurityLevel(int)}: no minimum security level.
*
* <p> When returned from {@link #getMinimumRequiredWifiSecurityLevel()}, the constant
* represents the current minimum security level required.
* When passed to {@link #setMinimumRequiredWifiSecurityLevel(int)}, it sets the
* minimum security level a Wi-Fi network must meet.
*
* @see #WIFI_SECURITY_PERSONAL
* @see #WIFI_SECURITY_ENTERPRISE_EAP
* @see #WIFI_SECURITY_ENTERPRISE_192
*/
public static final int WIFI_SECURITY_OPEN = 0;
/**
* Constant for {@link #getMinimumRequiredWifiSecurityLevel()} and
* {@link #setMinimumRequiredWifiSecurityLevel(int)}: personal network such as WEP, WPA2-PSK.
*
* <p> When returned from {@link #getMinimumRequiredWifiSecurityLevel()}, the constant
* represents the current minimum security level required.
* When passed to {@link #setMinimumRequiredWifiSecurityLevel(int)}, it sets the
* minimum security level a Wi-Fi network must meet.
*
* @see #WIFI_SECURITY_OPEN
* @see #WIFI_SECURITY_ENTERPRISE_EAP
* @see #WIFI_SECURITY_ENTERPRISE_192
*/
public static final int WIFI_SECURITY_PERSONAL = 1;
/**
* Constant for {@link #getMinimumRequiredWifiSecurityLevel()} and
* {@link #setMinimumRequiredWifiSecurityLevel(int)}: enterprise EAP network.
*
* <p> When returned from {@link #getMinimumRequiredWifiSecurityLevel()}, the constant
* represents the current minimum security level required.
* When passed to {@link #setMinimumRequiredWifiSecurityLevel(int)}, it sets the
* minimum security level a Wi-Fi network must meet.
*
* @see #WIFI_SECURITY_OPEN
* @see #WIFI_SECURITY_PERSONAL
* @see #WIFI_SECURITY_ENTERPRISE_192
*/
public static final int WIFI_SECURITY_ENTERPRISE_EAP = 2;
/**
* Constant for {@link #getMinimumRequiredWifiSecurityLevel()} and
* {@link #setMinimumRequiredWifiSecurityLevel(int)}: enterprise 192 bit network.
*
* <p> When returned from {@link #getMinimumRequiredWifiSecurityLevel()}, the constant
* represents the current minimum security level required.
* When passed to {@link #setMinimumRequiredWifiSecurityLevel(int)}, it sets the
* minimum security level a Wi-Fi network must meet.
*
* @see #WIFI_SECURITY_OPEN
* @see #WIFI_SECURITY_PERSONAL
* @see #WIFI_SECURITY_ENTERPRISE_EAP
*/
public static final int WIFI_SECURITY_ENTERPRISE_192 = 3;
/**
* Possible Wi-Fi minimum security levels
*
* @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"WIFI_SECURITY_"}, value = {
WIFI_SECURITY_OPEN,
WIFI_SECURITY_PERSONAL,
WIFI_SECURITY_ENTERPRISE_EAP,
WIFI_SECURITY_ENTERPRISE_192})
public @interface WifiSecurity {}
/**
* This MIME type is used for starting the device owner provisioning.
*
@@ -14559,6 +14631,45 @@ public class DevicePolicyManager {
return ProvisioningIntentHelper.createProvisioningIntentFromNfcIntent(nfcIntent);
}
/**
* Called by device owner or profile owner of an organization-owned managed profile to
* specify the minimum security level required for Wi-Fi networks.
* The device may not connect to networks that do not meet the minimum security level.
* If the current network does not meet the minimum security level set, it will be disconnected.
*
*
* @param level minimum security level
* @throws SecurityException if the caller is not a device owner or a profile owner on
* an organization-owned managed profile.
*/
public void setMinimumRequiredWifiSecurityLevel(@WifiSecurity int level) {
throwIfParentInstance("setMinimumRequiredWifiSecurityLevel");
if (mService != null) {
try {
mService.setMinimumRequiredWifiSecurityLevel(level);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
/**
* Returns the current Wi-Fi minimum security level.
*
* @see #setMinimumRequiredWifiSecurityLevel(int)
*/
public @WifiSecurity int getMinimumRequiredWifiSecurityLevel() {
throwIfParentInstance("getMinimumRequiredWifiSecurityLevel");
if (mService == null) {
return WIFI_SECURITY_OPEN;
}
try {
return mService.getMinimumRequiredWifiSecurityLevel();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* For each {@link DevicePolicyDrawableResource} item in {@code drawables}, if
* {@link DevicePolicyDrawableResource#getDrawableSource()} is not set or is set to

View File

@@ -533,6 +533,9 @@ interface IDevicePolicyManager {
boolean isUsbDataSignalingEnabledForUser(int userId);
boolean canUsbDataSignalingBeDisabled();
void setMinimumRequiredWifiSecurityLevel(int level);
int getMinimumRequiredWifiSecurityLevel();
List<UserHandle> listForegroundAffiliatedUsers();
void setDrawables(in List<DevicePolicyDrawableResource> drawables);
void resetDrawables(in int[] drawableIds);

View File

@@ -145,6 +145,7 @@ class ActiveAdmin {
private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED =
"preferential-network-service-enabled";
private static final String TAG_USB_DATA_SIGNALING = "usb-data-signaling";
private static final String TAG_WIFI_MIN_SECURITY = "wifi-min-security";
private static final String ATTR_VALUE = "value";
private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification";
private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications";
@@ -298,6 +299,8 @@ class ActiveAdmin {
private static final boolean USB_DATA_SIGNALING_ENABLED_DEFAULT = true;
boolean mUsbDataSignalingEnabled = USB_DATA_SIGNALING_ENABLED_DEFAULT;
int mWifiMinimumSecurityLevel = DevicePolicyManager.WIFI_SECURITY_OPEN;
ActiveAdmin(DeviceAdminInfo info, boolean isParent) {
this.info = info;
this.isParent = isParent;
@@ -574,6 +577,9 @@ class ActiveAdmin {
if (mUsbDataSignalingEnabled != USB_DATA_SIGNALING_ENABLED_DEFAULT) {
writeAttributeValueToXml(out, TAG_USB_DATA_SIGNALING, mUsbDataSignalingEnabled);
}
if (mWifiMinimumSecurityLevel != DevicePolicyManager.WIFI_SECURITY_OPEN) {
writeAttributeValueToXml(out, TAG_WIFI_MIN_SECURITY, mWifiMinimumSecurityLevel);
}
}
void writeTextToXml(TypedXmlSerializer out, String tag, String text) throws IOException {
@@ -826,6 +832,8 @@ class ActiveAdmin {
} else if (TAG_USB_DATA_SIGNALING.equals(tag)) {
mUsbDataSignalingEnabled = parser.getAttributeBoolean(null, ATTR_VALUE,
USB_DATA_SIGNALING_ENABLED_DEFAULT);
} else if (TAG_WIFI_MIN_SECURITY.equals(tag)) {
mWifiMinimumSecurityLevel = parser.getAttributeInt(null, ATTR_VALUE);
} else {
Slogf.w(LOG_TAG, "Unknown admin tag: %s", tag);
XmlUtils.skipCurrentTag(parser);
@@ -1184,5 +1192,8 @@ class ActiveAdmin {
pw.print("mUsbDataSignaling=");
pw.println(mUsbDataSignalingEnabled);
pw.print("mWifiMinimumSecurityLevel=");
pw.println(mWifiMinimumSecurityLevel);
}
}

View File

@@ -17979,6 +17979,41 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
);
}
private void validateCurrentWifiMeetsAdminRequirements() {
mInjector.binderWithCleanCallingIdentity(
() -> mInjector.getWifiManager().validateCurrentWifiMeetsAdminRequirements());
}
@Override
public void setMinimumRequiredWifiSecurityLevel(int level) {
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(
isDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
"Wi-Fi minimum security level can only be controlled by a device owner or "
+ "a profile owner on an organization-owned device.");
boolean valueChanged = false;
synchronized (getLockObject()) {
final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
if (admin.mWifiMinimumSecurityLevel != level) {
admin.mWifiMinimumSecurityLevel = level;
saveSettingsLocked(caller.getUserId());
valueChanged = true;
}
}
if (valueChanged) validateCurrentWifiMeetsAdminRequirements();
}
@Override
public int getMinimumRequiredWifiSecurityLevel() {
synchronized (getLockObject()) {
final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
UserHandle.USER_SYSTEM);
return (admin == null) ? DevicePolicyManager.WIFI_SECURITY_OPEN
: admin.mWifiMinimumSecurityLevel;
}
}
@Override
public void setDrawables(@NonNull List<DevicePolicyDrawableResource> drawables) {
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(

View File

@@ -34,6 +34,10 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_NO_ERROR;
import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_192;
import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP;
import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_OPEN;
import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_PERSONAL;
import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
import static android.app.admin.PasswordMetrics.computeForPasswordOrPin;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
@@ -7828,6 +7832,40 @@ public class DevicePolicyManagerTest extends DpmTestBase {
() -> dpm.getOrganizationNameForUser(UserHandle.USER_SYSTEM));
}
@Test
public void testSetWifiMinimumSecurity_noDeviceOwnerOrPoOfOrgOwnedDevice() {
assertThrows(SecurityException.class, () -> dpm.setMinimumRequiredWifiSecurityLevel(
DevicePolicyManager.WIFI_SECURITY_PERSONAL));
}
@Test
public void testSetWifiMinimumSecurity_asDeviceOwner() throws Exception {
setDeviceOwner();
final Set<Integer> allowedLevels = Set.of(WIFI_SECURITY_OPEN, WIFI_SECURITY_PERSONAL,
WIFI_SECURITY_ENTERPRISE_EAP, WIFI_SECURITY_ENTERPRISE_192);
for (int level : allowedLevels) {
dpm.setMinimumRequiredWifiSecurityLevel(level);
assertThat(dpm.getMinimumRequiredWifiSecurityLevel()).isEqualTo(level);
}
}
@Test
public void testSetWifiMinimumSecurity_asPoOfOrgOwnedDevice() throws Exception {
final int managedProfileUserId = 15;
final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
addManagedProfile(admin1, managedProfileAdminUid, admin1);
configureProfileOwnerOfOrgOwnedDevice(admin1, managedProfileUserId);
mContext.binder.callingUid = managedProfileAdminUid;
final Set<Integer> allowedLevels = Set.of(WIFI_SECURITY_OPEN, WIFI_SECURITY_PERSONAL,
WIFI_SECURITY_ENTERPRISE_EAP, WIFI_SECURITY_ENTERPRISE_192);
for (int level : allowedLevels) {
dpm.setMinimumRequiredWifiSecurityLevel(level);
assertThat(dpm.getMinimumRequiredWifiSecurityLevel()).isEqualTo(level);
}
}
private void setupVpnAuthorization(String userVpnPackage, int userVpnUid) {
final AppOpsManager.PackageOps vpnOp = new AppOpsManager.PackageOps(userVpnPackage,
userVpnUid, List.of(new AppOpsManager.OpEntry(