1 /* 2 * Copyright (C) 2019 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.internal.telephony; 18 19 import android.Manifest; 20 import android.annotation.UnsupportedAppUsage; 21 import android.app.AppOpsManager; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.pm.PackageManager; 25 import android.os.Binder; 26 import android.service.carrier.CarrierMessagingService; 27 import android.telephony.Rlog; 28 import android.util.Log; 29 30 /** 31 * Permissions checks for SMS functionality 32 */ 33 public class SmsPermissions { 34 static final String LOG_TAG = "SmsPermissions"; 35 36 @UnsupportedAppUsage 37 private final Phone mPhone; 38 @UnsupportedAppUsage 39 private final Context mContext; 40 @UnsupportedAppUsage 41 private final AppOpsManager mAppOps; 42 SmsPermissions(Phone phone, Context context, AppOpsManager appOps)43 public SmsPermissions(Phone phone, Context context, AppOpsManager appOps) { 44 mPhone = phone; 45 mContext = context; 46 mAppOps = appOps; 47 } 48 49 /** 50 * Check that the caller can send text messages. 51 * 52 * For persisted messages, the caller just needs the SEND_SMS permission. For unpersisted 53 * For persisted messages, the caller just needs the SEND_SMS permission. For unpersisted 54 * messages, the caller must either be the IMS app or a carrier-privileged app, or they must 55 * have both the MODIFY_PHONE_STATE and SEND_SMS permissions. 56 * 57 * @throws SecurityException if the caller is missing all necessary permission declaration or 58 * has had a necessary runtime permission revoked. 59 * @return true unless the caller has all necessary permissions but has a revoked AppOps bit. 60 */ checkCallingCanSendText( boolean persistMessageForNonDefaultSmsApp, String callingPackage, String message)61 public boolean checkCallingCanSendText( 62 boolean persistMessageForNonDefaultSmsApp, String callingPackage, String message) { 63 // TODO(b/75978989): Should we allow IMS/carrier apps for persisted messages as well? 64 if (!persistMessageForNonDefaultSmsApp) { 65 try { 66 enforceCallerIsImsAppOrCarrierApp(message); 67 // No need to also check SEND_SMS. 68 return true; 69 } catch (SecurityException e) { 70 mContext.enforceCallingPermission( 71 android.Manifest.permission.MODIFY_PHONE_STATE, message); 72 } 73 } 74 return checkCallingCanSendSms(callingPackage, message); 75 } 76 77 78 /** 79 * Enforces that the caller is one of the following apps: 80 * <ul> 81 * <li> IMS App 82 * <li> Carrier App 83 * </ul> 84 */ enforceCallerIsImsAppOrCarrierApp(String message)85 public void enforceCallerIsImsAppOrCarrierApp(String message) { 86 int callingUid = Binder.getCallingUid(); 87 String carrierImsPackage = CarrierSmsUtils.getCarrierImsPackageForIntent(mContext, mPhone, 88 new Intent(CarrierMessagingService.SERVICE_INTERFACE)); 89 try { 90 if (carrierImsPackage != null 91 && callingUid == mContext.getPackageManager().getPackageUid( 92 carrierImsPackage, 0)) { 93 return; 94 } 95 } catch (PackageManager.NameNotFoundException e) { 96 if (Rlog.isLoggable("SMS", Log.DEBUG)) { 97 log("Cannot find configured carrier ims package"); 98 } 99 } 100 101 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mPhone.getSubId(), message); 102 } 103 104 105 /** 106 * Check that the caller has SEND_SMS permissions. Can only be called during an IPC. 107 * 108 * @throws SecurityException if the caller is missing the permission declaration or has had the 109 * permission revoked at runtime. 110 * @return whether the caller has the OP_SEND_SMS AppOps bit. 111 */ checkCallingCanSendSms(String callingPackage, String message)112 public boolean checkCallingCanSendSms(String callingPackage, String message) { 113 mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, message); 114 return mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(), callingPackage) 115 == AppOpsManager.MODE_ALLOWED; 116 } 117 118 /** 119 * Check that the caller (or self, if this is not an IPC) has SEND_SMS permissions. 120 * 121 * @throws SecurityException if the caller is missing the permission declaration or has had the 122 * permission revoked at runtime. 123 * @return whether the caller has the OP_SEND_SMS AppOps bit. 124 */ checkCallingOrSelfCanSendSms(String callingPackage, String message)125 public boolean checkCallingOrSelfCanSendSms(String callingPackage, String message) { 126 mContext.enforceCallingOrSelfPermission(Manifest.permission.SEND_SMS, message); 127 return mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(), callingPackage) 128 == AppOpsManager.MODE_ALLOWED; 129 } 130 131 @UnsupportedAppUsage log(String msg)132 protected void log(String msg) { 133 Log.d(LOG_TAG, "[IccSmsInterfaceManager] " + msg); 134 } 135 } 136