private static final int DEVICE_ADMIN_DEACTIVATE_TIMEOUT = 10000;
+ /**
+ * Minimum timeout in milliseconds after which unlocking with weak auth times out,
+ * i.e. the user has to use a strong authentication method like password, PIN or pattern.
+ */
+ private static final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = 1 * 60 * 60 * 1000; // 1h
+
final Context mContext;
final Injector mInjector;
final IPackageManager mIPackageManager;
new MonitoringCertNotificationTask().execute(userId);
}
if (Intent.ACTION_USER_ADDED.equals(action)) {
- disableSecurityLoggingIfNotCompliant();
+ disableDeviceOwnerManagedSingleUserFeaturesIfNeeded();
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
- disableSecurityLoggingIfNotCompliant();
+ disableDeviceOwnerManagedSingleUserFeaturesIfNeeded();
removeUserData(userHandle);
} else if (Intent.ACTION_USER_STARTED.equals(action)) {
synchronized (DevicePolicyManagerService.this) {
private static final String TAG_PERMITTED_IMES = "permitted-imes";
private static final String TAG_MAX_FAILED_PASSWORD_WIPE = "max-failed-password-wipe";
private static final String TAG_MAX_TIME_TO_UNLOCK = "max-time-to-unlock";
+ private static final String TAG_STRONG_AUTH_UNLOCK_TIMEOUT = "strong-auth-unlock-timeout";
private static final String TAG_MIN_PASSWORD_NONLETTER = "min-password-nonletter";
private static final String TAG_MIN_PASSWORD_SYMBOLS = "min-password-symbols";
private static final String TAG_MIN_PASSWORD_NUMERIC = "min-password-numeric";
static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0;
long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK;
+ long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
+
static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0;
int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE;
out.attribute(null, ATTR_VALUE, Long.toString(maximumTimeToUnlock));
out.endTag(null, TAG_MAX_TIME_TO_UNLOCK);
}
+ if (strongAuthUnlockTimeout != DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) {
+ out.startTag(null, TAG_STRONG_AUTH_UNLOCK_TIMEOUT);
+ out.attribute(null, ATTR_VALUE, Long.toString(strongAuthUnlockTimeout));
+ out.endTag(null, TAG_STRONG_AUTH_UNLOCK_TIMEOUT);
+ }
if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
out.startTag(null, TAG_MAX_FAILED_PASSWORD_WIPE);
out.attribute(null, ATTR_VALUE, Integer.toString(maximumFailedPasswordsForWipe));
} else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
maximumTimeToUnlock = Long.parseLong(
parser.getAttributeValue(null, ATTR_VALUE));
+ } else if (TAG_STRONG_AUTH_UNLOCK_TIMEOUT.equals(tag)) {
+ strongAuthUnlockTimeout = Long.parseLong(
+ parser.getAttributeValue(null, ATTR_VALUE));
} else if (TAG_MAX_FAILED_PASSWORD_WIPE.equals(tag)) {
maximumFailedPasswordsForWipe = Integer.parseInt(
parser.getAttributeValue(null, ATTR_VALUE));
pw.println(minimumPasswordNonLetter);
pw.print(prefix); pw.print("maximumTimeToUnlock=");
pw.println(maximumTimeToUnlock);
+ pw.print(prefix); pw.print("strongAuthUnlockTimeout=");
+ pw.println(strongAuthUnlockTimeout);
pw.print(prefix); pw.print("maximumFailedPasswordsForWipe=");
pw.println(maximumFailedPasswordsForWipe);
pw.print(prefix); pw.print("specifiesGlobalProxy=");
if (mOwners.hasDeviceOwner()) {
mInjector.systemPropertiesSet(PROPERTY_DEVICE_OWNER_PRESENT, "true");
Slog.i(LOG_TAG, "Set ro.device_owner property to true");
- disableSecurityLoggingIfNotCompliant();
+ disableDeviceOwnerManagedSingleUserFeaturesIfNeeded();
if (mInjector.securityLogGetLoggingEnabledProperty()) {
mSecurityLogMonitor.start();
}
}
@Override
+ public void setRequiredStrongAuthTimeout(ComponentName who, long timeoutMs,
+ boolean parent) {
+ if (!mHasFeature) {
+ return;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ Preconditions.checkArgument(timeoutMs >= MINIMUM_STRONG_AUTH_TIMEOUT_MS,
+ "Timeout must not be lower than the minimum strong auth timeout.");
+ Preconditions.checkArgument(timeoutMs <= DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS,
+ "Timeout must not be higher than the default strong auth timeout.");
+
+ final int userHandle = mInjector.userHandleGetCallingUserId();
+ synchronized (this) {
+ ActiveAdmin ap = getActiveAdminForCallerLocked(who,
+ DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
+ if (ap.strongAuthUnlockTimeout != timeoutMs) {
+ ap.strongAuthUnlockTimeout = timeoutMs;
+ saveSettingsLocked(userHandle);
+ }
+ }
+ }
+
+ /**
+ * Return a single admin's strong auth unlock timeout or minimum value (strictest) of all
+ * admins if who is null.
+ * Returns default timeout if not configured.
+ */
+ @Override
+ public long getRequiredStrongAuthTimeout(ComponentName who, int userId, boolean parent) {
+ if (!mHasFeature) {
+ return DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
+ }
+ enforceFullCrossUsersPermission(userId);
+ synchronized (this) {
+ if (who != null) {
+ ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userId, parent);
+ return admin != null ? Math.max(admin.strongAuthUnlockTimeout,
+ MINIMUM_STRONG_AUTH_TIMEOUT_MS)
+ : DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
+ }
+
+ // Return the strictest policy across all participating admins.
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userId, parent);
+
+ long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
+ for (int i = 0; i < admins.size(); i++) {
+ strongAuthUnlockTimeout = Math.min(admins.get(i).strongAuthUnlockTimeout,
+ strongAuthUnlockTimeout);
+ }
+ return Math.max(strongAuthUnlockTimeout, MINIMUM_STRONG_AUTH_TIMEOUT_MS);
+ }
+ }
+
+ @Override
public void lockNow(boolean parent) {
if (!mHasFeature) {
return;
mOwners.clearDeviceOwner();
mOwners.writeDeviceOwner();
updateDeviceOwnerLocked();
- disableSecurityLoggingIfNotCompliant();
+ disableDeviceOwnerManagedSingleUserFeaturesIfNeeded();
try {
// Reactivate backup service.
mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true);
return false;
}
- private synchronized void disableSecurityLoggingIfNotCompliant() {
+ private synchronized void disableDeviceOwnerManagedSingleUserFeaturesIfNeeded() {
if (!isDeviceOwnerManagedSingleUserDevice()) {
mInjector.securityLogSetLoggingEnabledProperty(false);
Slog.w(LOG_TAG, "Security logging turned off as it's no longer a single user device.");
+ setBackupServiceEnabledInternal(false);
+ Slog.w(LOG_TAG, "Backup is off as it's a managed device that has more that one user.");
}
}
return false;
}
}
+
+ @Override
+ public void setBackupServiceEnabled(ComponentName admin, boolean enabled) {
+ Preconditions.checkNotNull(admin);
+ if (!mHasFeature) {
+ return;
+ }
+ ensureDeviceOwnerManagingSingleUser(admin);
+ setBackupServiceEnabledInternal(enabled);
+ }
+
+ private synchronized void setBackupServiceEnabledInternal(boolean enabled) {
+ long ident = mInjector.binderClearCallingIdentity();
+ try {
+ IBackupManager ibm = mInjector.getIBackupManager();
+ if (ibm != null) {
+ ibm.setBackupServiceActive(UserHandle.USER_SYSTEM, enabled);
+ }
+ } catch (RemoteException e) {
+ throw new IllegalStateException(
+ "Failed " + (enabled ? "" : "de") + "activating backup service.", e);
+ } finally {
+ mInjector.binderRestoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public boolean isBackupServiceEnabled(ComponentName admin) {
+ Preconditions.checkNotNull(admin);
+ if (!mHasFeature) {
+ return true;
+ }
+ synchronized (this) {
+ getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ try {
+ IBackupManager ibm = mInjector.getIBackupManager();
+ return ibm != null && ibm.isBackupServiceActive(UserHandle.USER_SYSTEM);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Failed requesting backup service state.", e);
+ }
+ }
+ }
}