/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.pm.verify.domain;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Process;

import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy;

public class DomainVerificationEnforcer {

    @NonNull
    private final Context mContext;

    @NonNull
    private Callback mCallback;

    public DomainVerificationEnforcer(@NonNull Context context) {
        mContext = context;
    }

    public void setCallback(@NonNull Callback callback) {
        mCallback = callback;
    }

    /**
     * Enforced when mutating any state from shell or internally in the system process.
     */
    public void assertInternal(int callingUid) {
        switch (callingUid) {
            case Process.ROOT_UID:
            case Process.SHELL_UID:
            case Process.SYSTEM_UID:
                break;
            default:
                throw new SecurityException(
                        "Caller " + callingUid + " is not allowed to change internal state");
        }
    }

    /**
     * Enforced when retrieving state for a package. The system, the verifier, and anyone approved
     * to mutate user selections are allowed through.
     */
    public void assertApprovedQuerent(int callingUid, @NonNull DomainVerificationProxy proxy) {
        switch (callingUid) {
            case Process.ROOT_UID:
            case Process.SHELL_UID:
            case Process.SYSTEM_UID:
                break;
            default:
                if (!proxy.isCallerVerifier(callingUid)) {
                    throw new SecurityException(
                            "Caller is not allowed to query domain verification state");
                }

                mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES,
                        Binder.getCallingPid(), callingUid,
                        "Caller " + callingUid + " does not hold "
                                + android.Manifest.permission.QUERY_ALL_PACKAGES);
                break;
        }
    }

    /**
     * Enforced when mutating domain verification state inside an exposed API method.
     */
    public void assertApprovedVerifier(int callingUid, @NonNull DomainVerificationProxy proxy)
            throws SecurityException {
        boolean isAllowed;
        switch (callingUid) {
            case Process.ROOT_UID:
            case Process.SHELL_UID:
            case Process.SYSTEM_UID:
                isAllowed = true;
                break;
            default:
                final int callingPid = Binder.getCallingPid();
                boolean isLegacyVerificationAgent = false;
                if (mContext.checkPermission(
                        android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, callingPid,
                        callingUid) != PackageManager.PERMISSION_GRANTED) {
                    isLegacyVerificationAgent = mContext.checkPermission(
                            android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
                            callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
                    if (!isLegacyVerificationAgent) {
                        throw new SecurityException("Caller " + callingUid + " does not hold "
                                + android.Manifest.permission.DOMAIN_VERIFICATION_AGENT);
                    }
                }

                // If the caller isn't a legacy verifier, it needs the QUERY_ALL permission
                if (!isLegacyVerificationAgent) {
                    mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES,
                            callingPid, callingUid, "Caller " + callingUid + " does not hold "
                                    + android.Manifest.permission.QUERY_ALL_PACKAGES);
                }

                isAllowed = proxy.isCallerVerifier(callingUid);
                break;
        }

        if (!isAllowed) {
            throw new SecurityException("Caller " + callingUid
                    + " is not the approved domain verification agent");
        }
    }

    /**
     * Enforced when mutating user selection state inside an exposed API method.
     */
    public boolean assertApprovedUserStateQuerent(int callingUid, @UserIdInt int callingUserId,
            @NonNull String packageName, @UserIdInt int targetUserId) throws SecurityException {
        if (callingUserId != targetUserId) {
            mContext.enforcePermission(
                    Manifest.permission.INTERACT_ACROSS_USERS,
                    Binder.getCallingPid(), callingUid,
                    "Caller is not allowed to edit other users");
        }

        if (!mCallback.doesUserExist(callingUserId)) {
            throw new SecurityException("User " + callingUserId + " does not exist");
        } else if (!mCallback.doesUserExist(targetUserId)) {
            throw new SecurityException("User " + targetUserId + " does not exist");
        }

        return !mCallback.filterAppAccess(packageName, callingUid, targetUserId);
    }

    /**
     * Enforced when mutating user selection state inside an exposed API method.
     */
    public boolean assertApprovedUserSelector(int callingUid, @UserIdInt int callingUserId,
            @Nullable String packageName, @UserIdInt int targetUserId) throws SecurityException {
        if (callingUserId != targetUserId) {
            mContext.enforcePermission(
                    Manifest.permission.INTERACT_ACROSS_USERS,
                    Binder.getCallingPid(), callingUid,
                    "Caller is not allowed to edit other users");
        }

        mContext.enforcePermission(
                android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION,
                Binder.getCallingPid(), callingUid,
                "Caller is not allowed to edit user selections");

        if (!mCallback.doesUserExist(callingUserId)) {
            throw new SecurityException("User " + callingUserId + " does not exist");
        } else if (!mCallback.doesUserExist(targetUserId)) {
            throw new SecurityException("User " + targetUserId + " does not exist");
        }

        if (packageName == null) {
            return true;
        }

        return !mCallback.filterAppAccess(packageName, callingUid, targetUserId);
    }

    public boolean callerIsLegacyUserSelector(int callingUid, @UserIdInt int callingUserId,
            @NonNull String packageName, @UserIdInt int targetUserId) {
        mContext.enforcePermission(
                android.Manifest.permission.SET_PREFERRED_APPLICATIONS,
                Binder.getCallingPid(), callingUid,
                "Caller is not allowed to edit user state");

        if (callingUserId != targetUserId) {
            if (mContext.checkPermission(
                    Manifest.permission.INTERACT_ACROSS_USERS,
                    Binder.getCallingPid(), callingUid) != PackageManager.PERMISSION_GRANTED) {
                // Legacy API did not enforce this, so for backwards compatibility, fail silently
                return false;
            }
        }

        if (!mCallback.doesUserExist(callingUserId)) {
            throw new SecurityException("User " + callingUserId + " does not exist");
        } else if (!mCallback.doesUserExist(targetUserId)) {
            throw new SecurityException("User " + targetUserId + " does not exist");
        }

        return !mCallback.filterAppAccess(packageName, callingUid, targetUserId);
    }

    public boolean callerIsLegacyUserQuerent(int callingUid, @UserIdInt int callingUserId,
            @NonNull String packageName, @UserIdInt int targetUserId) {
        if (callingUserId != targetUserId) {
            // The legacy API enforces the _FULL variant, so maintain that here
            mContext.enforcePermission(
                    Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    Binder.getCallingPid(), callingUid,
                    "Caller is not allowed to edit other users");
        }

        if (!mCallback.doesUserExist(callingUserId)) {
            throw new SecurityException("User " + callingUserId + " does not exist");
        } else if (!mCallback.doesUserExist(targetUserId)) {
            throw new SecurityException("User " + targetUserId + " does not exist");
        }

        return !mCallback.filterAppAccess(packageName, callingUid, targetUserId);
    }

    /**
     * Querying for the owners of a domain. Because this API cannot filter the returned list of
     * packages, enforces {@link android.Manifest.permission.QUERY_ALL_PACKAGES}, but also enforces
     * {@link android.Manifest.permission.INTERACT_ACROSS_USERS} because each user has a different
     * state.
     */
    public void assertOwnerQuerent(int callingUid, @UserIdInt int callingUserId,
            @UserIdInt int targetUserId) {
        final int callingPid = Binder.getCallingPid();
        if (callingUserId != targetUserId) {
            mContext.enforcePermission(android.Manifest.permission.INTERACT_ACROSS_USERS,
                    callingPid, callingUid, "Caller is not allowed to query other users");
        }

        mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES,
                callingPid, callingUid, "Caller " + callingUid + " does not hold "
                        + android.Manifest.permission.QUERY_ALL_PACKAGES);

        mContext.enforcePermission(
                android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION,
                callingPid, callingUid, "Caller is not allowed to query user selections");

        if (!mCallback.doesUserExist(callingUserId)) {
            throw new SecurityException("User " + callingUserId + " does not exist");
        } else if (!mCallback.doesUserExist(targetUserId)) {
            throw new SecurityException("User " + targetUserId + " does not exist");
        }
    }

    public interface Callback {
        /**
         * @return true if access to the given package should be filtered and the method failed as
         * if the package was not installed
         */
        boolean filterAppAccess(@NonNull String packageName, int callingUid, @UserIdInt int userId);

        boolean doesUserExist(@UserIdInt int userId);
    }
}
