Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f24d22c1 authored by Rubin Xu's avatar Rubin Xu Committed by android-build-merger
Browse files

Merge "Remove password blacklist API" into pi-dev am: 69196f6f

am: 73ebccac

Change-Id: I785df4a0158c62a358c0f1d1cff95eb2e75d91fc
parents 6bcab1a3 73ebccac
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -6468,7 +6468,6 @@ package android.app.admin {
    method public java.lang.CharSequence getOrganizationName(android.content.ComponentName);
    method public java.util.List<android.telephony.data.ApnSetting> getOverrideApns(android.content.ComponentName);
    method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName);
    method public java.lang.String getPasswordBlacklistName(android.content.ComponentName);
    method public long getPasswordExpiration(android.content.ComponentName);
    method public long getPasswordExpirationTimeout(android.content.ComponentName);
    method public int getPasswordHistoryLength(android.content.ComponentName);
@@ -6577,7 +6576,6 @@ package android.app.admin {
    method public void setOrganizationName(android.content.ComponentName, java.lang.CharSequence);
    method public void setOverrideApnsEnabled(android.content.ComponentName, boolean);
    method public java.lang.String[] setPackagesSuspended(android.content.ComponentName, java.lang.String[], boolean);
    method public boolean setPasswordBlacklist(android.content.ComponentName, java.lang.String, java.util.List<java.lang.String>);
    method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
    method public void setPasswordHistoryLength(android.content.ComponentName, int);
    method public void setPasswordMinimumLength(android.content.ComponentName, int);
+0 −104
Original line number Diff line number Diff line
@@ -2746,110 +2746,6 @@ public class DevicePolicyManager {
        return 16;
    }

    /**
     * The maximum number of characters allowed in the password blacklist.
     */
    private static final int PASSWORD_BLACKLIST_CHARACTER_LIMIT = 128 * 1000;

    /**
     * Throws an exception if the password blacklist is too large.
     *
     * @hide
     */
    public static void enforcePasswordBlacklistSize(List<String> blacklist) {
        if (blacklist == null) {
            return;
        }
        long characterCount = 0;
        for (final String item : blacklist) {
            characterCount += item.length();
        }
        if (characterCount > PASSWORD_BLACKLIST_CHARACTER_LIMIT) {
            throw new IllegalArgumentException("128 thousand blacklist character limit exceeded by "
                      + (characterCount - PASSWORD_BLACKLIST_CHARACTER_LIMIT) + " characters");
        }
    }

    /**
     * Called by an application that is administering the device to blacklist passwords.
     * <p>
     * Any blacklisted password or PIN is prevented from being enrolled by the user or the admin.
     * Note that the match against the blacklist is case insensitive. The blacklist applies for all
     * password qualities requested by {@link #setPasswordQuality} however it is not taken into
     * consideration by {@link #isActivePasswordSufficient}.
     * <p>
     * The blacklist can be cleared by passing {@code null} or an empty list. The blacklist is
     * given a name that is used to track which blacklist is currently set by calling {@link
     * #getPasswordBlacklistName}. If the blacklist is being cleared, the name is ignored and {@link
     * #getPasswordBlacklistName} will return {@code null}. The name can only be {@code null} when
     * the blacklist is being cleared.
     * <p>
     * The blacklist is limited to a total of 128 thousand characters rather than limiting to a
     * number of entries.
     * <p>
     * This method can be called on the {@link DevicePolicyManager} instance returned by
     * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
     * profile.
     *
     * @param admin the {@link DeviceAdminReceiver} this request is associated with
     * @param name name to associate with the blacklist
     * @param blacklist list of passwords to blacklist or {@code null} to clear the blacklist
     * @return whether the new blacklist was successfully installed
     * @throws SecurityException if {@code admin} is not a device or profile owner
     * @throws IllegalArgumentException if the blacklist surpasses the character limit
     * @throws NullPointerException if {@code name} is {@code null} when setting a non-empty list
     *
     * @see #getPasswordBlacklistName
     * @see #isActivePasswordSufficient
     * @see #resetPasswordWithToken
     */
    public boolean setPasswordBlacklist(@NonNull ComponentName admin, @Nullable String name,
            @Nullable List<String> blacklist) {
        enforcePasswordBlacklistSize(blacklist);

        try {
            return mService.setPasswordBlacklist(admin, name, blacklist, mParentInstance);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Get the name of the password blacklist set by the given admin.
     *
     * @param admin the {@link DeviceAdminReceiver} this request is associated with
     * @return the name of the blacklist or {@code null} if no blacklist is set
     *
     * @see #setPasswordBlacklist
     */
    public @Nullable String getPasswordBlacklistName(@NonNull ComponentName admin) {
        try {
            return mService.getPasswordBlacklistName(admin, myUserId(), mParentInstance);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Test if a given password is blacklisted.
     *
     * @param userId the user to valiate for
     * @param password the password to check against the blacklist
     * @return whether the password is blacklisted
     *
     * @see #setPasswordBlacklist
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.TEST_BLACKLISTED_PASSWORD)
    public boolean isPasswordBlacklisted(@UserIdInt int userId, @NonNull String password) {
        try {
            return mService.isPasswordBlacklisted(userId, password);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Determine whether the current password the user has set is sufficient to meet the policy
     * requirements (e.g. quality, minimum length) that have been requested by the admins of this
+0 −4
Original line number Diff line number Diff line
@@ -79,10 +79,6 @@ interface IDevicePolicyManager {

    long getPasswordExpiration(in ComponentName who, int userHandle, boolean parent);

    boolean setPasswordBlacklist(in ComponentName who, String name, in List<String> blacklist, boolean parent);
    String getPasswordBlacklistName(in ComponentName who, int userId, boolean parent);
    boolean isPasswordBlacklisted(int userId, String password);

    boolean isActivePasswordSufficient(int userHandle, boolean parent);
    boolean isProfileActivePasswordSufficientForParent(int userHandle);
    boolean isUsingUnifiedPassword(in ComponentName admin);
+0 −17
Original line number Diff line number Diff line
@@ -78,23 +78,6 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
        return false;
    }

    @Override
    public boolean setPasswordBlacklist(ComponentName who, String name, List<String> blacklist,
            boolean parent) {
        return false;
    }

    @Override
    public String getPasswordBlacklistName(ComponentName who, @UserIdInt int userId,
            boolean parent) {
        return null;
    }

    @Override
    public boolean isPasswordBlacklisted(@UserIdInt int userId, String password) {
        return false;
    }

    public boolean isUsingUnifiedPassword(ComponentName who) {
        return true;
    }
+0 −152
Original line number Diff line number Diff line
@@ -820,7 +820,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        private static final String TAG_PASSWORD_HISTORY_LENGTH = "password-history-length";
        private static final String TAG_MIN_PASSWORD_LENGTH = "min-password-length";
        private static final String ATTR_VALUE = "value";
        private static final String TAG_PASSWORD_BLACKLIST = "password-blacklist";
        private static final String TAG_PASSWORD_QUALITY = "password-quality";
        private static final String TAG_POLICIES = "policies";
        private static final String TAG_CROSS_PROFILE_WIDGET_PROVIDERS =
@@ -961,9 +960,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        // Default title of confirm credentials screen
        String organizationName = null;
        // The blacklist data is stored in a file whose name is stored in the XML
        String passwordBlacklistFile = null;
        // The component name of the backup transport which has to be used if backups are mandatory
        // or null if backups are not mandatory.
        ComponentName mandatoryBackupTransport = null;
@@ -1053,11 +1049,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                    out.endTag(null, TAG_MIN_PASSWORD_NONLETTER);
                }
            }
            if (passwordBlacklistFile != null) {
                out.startTag(null, TAG_PASSWORD_BLACKLIST);
                out.attribute(null, ATTR_VALUE, passwordBlacklistFile);
                out.endTag(null, TAG_PASSWORD_BLACKLIST);
            }
            if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) {
                out.startTag(null, TAG_MAX_TIME_TO_UNLOCK);
                out.attribute(null, ATTR_VALUE, Long.toString(maximumTimeToUnlock));
@@ -1313,8 +1304,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                } else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) {
                    minimumPasswordMetrics.nonLetter = Integer.parseInt(
                            parser.getAttributeValue(null, ATTR_VALUE));
                } else if (TAG_PASSWORD_BLACKLIST.equals(tag)) {
                    passwordBlacklistFile = parser.getAttributeValue(null, ATTR_VALUE);
                }else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
                    maximumTimeToUnlock = Long.parseLong(
                            parser.getAttributeValue(null, ATTR_VALUE));
@@ -1589,8 +1578,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                    pw.println(minimumPasswordMetrics.symbols);
            pw.print(prefix); pw.print("minimumPasswordNonLetter=");
                    pw.println(minimumPasswordMetrics.nonLetter);
            pw.print(prefix); pw.print("passwordBlacklist=");
                    pw.println(passwordBlacklistFile != null);
            pw.print(prefix); pw.print("maximumTimeToUnlock=");
                    pw.println(maximumTimeToUnlock);
            pw.print(prefix); pw.print("strongAuthUnlockTimeout=");
@@ -1857,10 +1844,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            return new LockPatternUtils(mContext);
        }
        PasswordBlacklist newPasswordBlacklist(File file) {
            return new PasswordBlacklist(file);
        }
        boolean storageManagerIsFileBasedEncryptionEnabled() {
            return StorageManager.isFileEncryptedNativeOnly();
        }
@@ -4413,136 +4396,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
    }
    /* @return the password blacklist set by the admin or {@code null} if none. */
    PasswordBlacklist getAdminPasswordBlacklistLocked(@NonNull ActiveAdmin admin) {
        final int userId = UserHandle.getUserId(admin.getUid());
        return admin.passwordBlacklistFile == null ? null : new PasswordBlacklist(
                new File(getPolicyFileDirectory(userId), admin.passwordBlacklistFile));
    }
    private static final String PASSWORD_BLACKLIST_FILE_PREFIX = "password-blacklist-";
    private static final String PASSWORD_BLACKLIST_FILE_SUFFIX = "";
    @Override
    public boolean setPasswordBlacklist(ComponentName who, String name, List<String> blacklist,
            boolean parent) {
        if (!mHasFeature) {
            return false;
        }
        Preconditions.checkNotNull(who, "who is null");
        synchronized (this) {
            final ActiveAdmin admin = getActiveAdminForCallerLocked(
                    who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
            final int userId = mInjector.userHandleGetCallingUserId();
            PasswordBlacklist adminBlacklist = getAdminPasswordBlacklistLocked(admin);
            if (blacklist == null || blacklist.isEmpty()) {
                // Remove the adminBlacklist
                admin.passwordBlacklistFile = null;
                saveSettingsLocked(userId);
                if (adminBlacklist != null) {
                    adminBlacklist.delete();
                }
                return true;
            }
            // Validate server side
            Preconditions.checkNotNull(name, "name is null");
            DevicePolicyManager.enforcePasswordBlacklistSize(blacklist);
            // Blacklist is case insensitive so normalize to lower case
            final int blacklistSize = blacklist.size();
            for (int i = 0; i < blacklistSize; ++i) {
                blacklist.set(i, blacklist.get(i).toLowerCase());
            }
            final boolean isNewBlacklist = adminBlacklist == null;
            if (isNewBlacklist) {
                // Create a new file for the blacklist. There could be multiple admins, each setting
                // different blacklists, to restrict a user's credential, for example a managed
                // profile can impose restrictions on its parent while the parent is already
                // restricted by its own admin. A deterministic naming scheme would be fragile if
                // new types of admin are introduced so we generate and save the file name instead.
                // This isn't a temporary file but it reuses the name generation logic
                final File file;
                try {
                    file = File.createTempFile(PASSWORD_BLACKLIST_FILE_PREFIX,
                            PASSWORD_BLACKLIST_FILE_SUFFIX, getPolicyFileDirectory(userId));
                } catch (IOException e) {
                    Slog.e(LOG_TAG, "Failed to make a file for the blacklist", e);
                    return false;
                }
                adminBlacklist = mInjector.newPasswordBlacklist(file);
            }
            if (adminBlacklist.savePasswordBlacklist(name, blacklist)) {
                if (isNewBlacklist) {
                    // The blacklist was saved so point the admin to the file
                    admin.passwordBlacklistFile = adminBlacklist.getFile().getName();
                    saveSettingsLocked(userId);
                }
                return true;
            }
        }
        return false;
    }
    @Override
    public String getPasswordBlacklistName(ComponentName who, @UserIdInt int userId,
            boolean parent) {
        if (!mHasFeature) {
            return null;
        }
        Preconditions.checkNotNull(who, "who is null");
        enforceFullCrossUsersPermission(userId);
        synchronized (this) {
            final ActiveAdmin admin = getActiveAdminForCallerLocked(
                    who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
            final PasswordBlacklist blacklist = getAdminPasswordBlacklistLocked(admin);
            if (blacklist == null) {
                return null;
            }
            return blacklist.getName();
        }
    }
    @Override
    public boolean isPasswordBlacklisted(@UserIdInt int userId, String password) {
        if (!mHasFeature) {
            return false;
        }
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.TEST_BLACKLISTED_PASSWORD, null);
        return isPasswordBlacklistedInternal(userId, password);
    }
    private boolean isPasswordBlacklistedInternal(@UserIdInt int userId, String password) {
        Preconditions.checkNotNull(password, "Password is null");
        enforceFullCrossUsersPermission(userId);
        // Normalize to lower case for case insensitive blacklist match
        final String lowerCasePassword = password.toLowerCase();
        synchronized (this) {
            final List<ActiveAdmin> admins =
                    getActiveAdminsForLockscreenPoliciesLocked(userId, /* parent */ false);
            final int N = admins.size();
            for (int i = 0; i < N; i++) {
                final PasswordBlacklist blacklist
                        = getAdminPasswordBlacklistLocked(admins.get(i));
                if (blacklist != null) {
                    if (blacklist.isPasswordBlacklisted(lowerCasePassword)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    @Override
    public boolean isActivePasswordSufficient(int userHandle, boolean parent) {
        if (!mHasFeature) {
@@ -4938,11 +4791,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                    return false;
                }
            }
            if (isPasswordBlacklistedInternal(userHandle, password)) {
                Slog.w(LOG_TAG, "resetPassword: the password is blacklisted");
                return false;
            }
        }
        DevicePolicyData policy = getUserData(userHandle);
Loading