1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.adservices.service.common; 18 19 import static android.adservices.common.AdServicesStatusUtils.STATUS_CALLER_NOT_ALLOWED_PACKAGE_NOT_IN_ALLOWLIST; 20 21 import static com.android.adservices.service.common.AppManifestConfigCall.API_AD_SELECTION; 22 import static com.android.adservices.service.common.AppManifestConfigCall.API_CUSTOM_AUDIENCES; 23 import static com.android.adservices.service.common.AppManifestConfigCall.API_PROTECTED_SIGNALS; 24 import static com.android.adservices.service.common.FledgeAuthorizationFilter.INVALID_API_TYPE; 25 26 import android.adservices.common.AdServicesStatusUtils; 27 import android.annotation.NonNull; 28 29 import com.android.adservices.LoggerFactory; 30 import com.android.adservices.service.Flags; 31 import com.android.adservices.service.stats.AdServicesLogger; 32 33 import java.util.Locale; 34 import java.util.Objects; 35 36 /** FLEDGE Security filter for {@link AllowLists}. */ 37 public class FledgeAllowListsFilter { 38 private static final LoggerFactory.Logger sLogger = LoggerFactory.getFledgeLogger(); 39 @NonNull private final Flags mFlags; 40 @NonNull private final AdServicesLogger mAdServicesLogger; 41 FledgeAllowListsFilter( @onNull Flags flags, @NonNull AdServicesLogger adServicesLogger)42 public FledgeAllowListsFilter( 43 @NonNull Flags flags, @NonNull AdServicesLogger adServicesLogger) { 44 Objects.requireNonNull(flags); 45 Objects.requireNonNull(adServicesLogger); 46 47 mFlags = flags; 48 mAdServicesLogger = adServicesLogger; 49 } 50 51 /** 52 * Asserts the package is allowed to call PPAPI. 53 * 54 * <p>Do not use this method in the Binder thread; flags must not be called there. 55 * 56 * @param appPackageName the package name to be validated. 57 * @param apiNameLoggingId the id of the api being called 58 * @param apiType the type of the api being called 59 * @throws AppNotAllowedException if the package is not authorized. 60 */ assertAppInAllowlist( @onNull String appPackageName, int apiNameLoggingId, @AppManifestConfigCall.ApiType int apiType)61 public void assertAppInAllowlist( 62 @NonNull String appPackageName, 63 int apiNameLoggingId, 64 @AppManifestConfigCall.ApiType int apiType) 65 throws AppNotAllowedException { 66 Objects.requireNonNull(appPackageName); 67 if (!isInAllowList(appPackageName, apiType)) { 68 sLogger.v( 69 "App package name \"%s\" not authorized to call API %d", 70 appPackageName, apiNameLoggingId); 71 mAdServicesLogger.logFledgeApiCallStats( 72 apiNameLoggingId, 73 appPackageName, 74 STATUS_CALLER_NOT_ALLOWED_PACKAGE_NOT_IN_ALLOWLIST, 75 /*latencyMs=*/ 0); 76 throw new AppNotAllowedException(); 77 } 78 } 79 80 /** 81 * Internal exception for easy assertion catches specific to checking that an app is allowed to 82 * use the PP APIs. 83 * 84 * <p>This exception is not meant to be exposed externally and should not be passed outside of 85 * the service. 86 */ 87 public static class AppNotAllowedException extends SecurityException { 88 /** 89 * Creates a {@link AppNotAllowedException}, used in cases where an app should have been 90 * allowed to use the PP APIs. 91 */ AppNotAllowedException()92 public AppNotAllowedException() { 93 super(AdServicesStatusUtils.SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ERROR_MESSAGE); 94 } 95 } 96 isInAllowList( String appPackageName, @AppManifestConfigCall.ApiType int apiType)97 private boolean isInAllowList( 98 String appPackageName, @AppManifestConfigCall.ApiType int apiType) { 99 if (apiType == API_CUSTOM_AUDIENCES) { 100 return AllowLists.isPackageAllowListed(mFlags.getPpapiAppAllowList(), appPackageName); 101 } else if (apiType == API_PROTECTED_SIGNALS) { 102 return AllowLists.isPackageAllowListed(mFlags.getPasAppAllowList(), appPackageName); 103 } else if (apiType == API_AD_SELECTION) { 104 return AllowLists.isPackageAllowListed(mFlags.getPpapiAppAllowList(), appPackageName) 105 || AllowLists.isPackageAllowListed(mFlags.getPasAppAllowList(), appPackageName); 106 } else { 107 throw new IllegalStateException( 108 String.format(Locale.ENGLISH, INVALID_API_TYPE, apiType)); 109 } 110 } 111 } 112