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.app.AppOpsManager;
21 import android.compat.annotation.UnsupportedAppUsage;
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.util.Log;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 import com.android.telephony.Rlog;
31 
32 /**
33  * Permissions checks for SMS functionality
34  */
35 public class SmsPermissions {
36     static final String LOG_TAG = "SmsPermissions";
37 
38     @UnsupportedAppUsage
39     private final Phone mPhone;
40     @UnsupportedAppUsage
41     private final Context mContext;
42     @UnsupportedAppUsage
43     private final AppOpsManager mAppOps;
44 
SmsPermissions(Phone phone, Context context, AppOpsManager appOps)45     public SmsPermissions(Phone phone, Context context, AppOpsManager appOps) {
46         mPhone = phone;
47         mContext = context;
48         mAppOps = appOps;
49     }
50 
51     /**
52      * Check that the caller can send text messages.
53      *
54      * For persisted messages, the caller just needs the SEND_SMS permission. For unpersisted
55      * messages, the caller must either be the IMS app or a carrier-privileged app, or they must
56      * have both the MODIFY_PHONE_STATE and SEND_SMS permissions.
57      *
58      * @throws SecurityException if the caller is missing all necessary permission declaration or
59      *                           has had a necessary runtime permission revoked.
60      * @return true unless the caller has all necessary permissions but has a revoked AppOps bit.
61      */
checkCallingCanSendText( boolean persistMessageForNonDefaultSmsApp, String callingPackage, String callingAttributionTag, String message)62     public boolean checkCallingCanSendText(
63             boolean persistMessageForNonDefaultSmsApp, String callingPackage,
64             String callingAttributionTag, String message) {
65         // TODO(b/75978989): Should we allow IMS/carrier apps for persisted messages as well?
66         if (!persistMessageForNonDefaultSmsApp) {
67             try {
68                 enforceCallerIsImsAppOrCarrierApp(message);
69                 // No need to also check SEND_SMS.
70                 return true;
71             } catch (SecurityException e) {
72                 mContext.enforceCallingPermission(
73                         android.Manifest.permission.MODIFY_PHONE_STATE, message);
74             }
75         }
76         return checkCallingCanSendSms(callingPackage, callingAttributionTag, message);
77     }
78 
79     /**
80      * Enforces that the caller is one of the following apps:
81      * <ul>
82      *     <li> IMS App
83      *     <li> Carrier App
84      * </ul>
85      */
enforceCallerIsImsAppOrCarrierApp(String message)86     public void enforceCallerIsImsAppOrCarrierApp(String message) {
87         int callingUid = Binder.getCallingUid();
88         String carrierImsPackage = CarrierSmsUtils.getCarrierImsPackageForIntent(mContext, mPhone,
89                 new Intent(CarrierMessagingService.SERVICE_INTERFACE));
90         try {
91             if (carrierImsPackage != null
92                     && callingUid == mContext.getPackageManager().getPackageUid(
93                     carrierImsPackage, 0)) {
94                 return;
95             }
96         } catch (PackageManager.NameNotFoundException e) {
97             if (Rlog.isLoggable("SMS", Log.DEBUG)) {
98                 loge("Cannot find configured carrier ims package");
99             }
100         }
101 
102         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
103                 mContext, mPhone.getSubId(), message);
104     }
105 
106     /**
107      * Check that the caller has SEND_SMS permissions. Can only be called during an IPC.
108      *
109      * @throws SecurityException if the caller is missing the permission declaration or has had the
110      *                           permission revoked at runtime.
111      * @return whether the caller has the OP_SEND_SMS AppOps bit.
112      */
checkCallingCanSendSms(String callingPackage, String callingAttributionTag, String message)113     public boolean checkCallingCanSendSms(String callingPackage, String callingAttributionTag,
114             String message) {
115         mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, message);
116         return mAppOps.noteOp(AppOpsManager.OPSTR_SEND_SMS, Binder.getCallingUid(), callingPackage)
117                 == AppOpsManager.MODE_ALLOWED;
118     }
119 
120     /**
121      * Check that the caller (or self, if this is not an IPC) has SEND_SMS permissions.
122      *
123      * @throws SecurityException if the caller is missing the permission declaration or has had the
124      *                           permission revoked at runtime.
125      * @return whether the caller has the OP_SEND_SMS AppOps bit.
126      */
checkCallingOrSelfCanSendSms(String callingPackage, String callingAttributionTag, String message)127     public boolean checkCallingOrSelfCanSendSms(String callingPackage, String callingAttributionTag,
128             String message) {
129         mContext.enforceCallingOrSelfPermission(Manifest.permission.SEND_SMS, message);
130         return mAppOps.noteOp(AppOpsManager.OPSTR_SEND_SMS, Binder.getCallingUid(), callingPackage)
131                 == AppOpsManager.MODE_ALLOWED;
132     }
133 
134     /**
135      * Check that the caller (or self, if this is not an IPC) can get SMSC address from (U)SIM.
136      *
137      * The default SMS application can get SMSC address, otherwise the caller must have
138      * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or carrier privileges.
139      *
140      * @return true if the caller is default SMS app or has the required permission and privileges.
141      *              Otherwise, false;
142      */
checkCallingOrSelfCanGetSmscAddress(String callingPackage, String message)143     public boolean checkCallingOrSelfCanGetSmscAddress(String callingPackage, String message) {
144         // Allow it to the default SMS app always.
145         if (!isCallerDefaultSmsPackage(callingPackage)) {
146             TelephonyPermissions
147                         .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
148                                 mContext, mPhone.getSubId(), message);
149         }
150         return true;
151     }
152 
153     /**
154      * Check that the caller (or self, if this is not an IPC) can set SMSC address on (U)SIM.
155      *
156      * The default SMS application can set SMSC address, otherwise the caller must have
157      * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier privileges.
158      *
159      * @return true if the caller is default SMS app or has the required permission and privileges.
160      *              Otherwise, false.
161      */
checkCallingOrSelfCanSetSmscAddress(String callingPackage, String message)162     public boolean checkCallingOrSelfCanSetSmscAddress(String callingPackage, String message) {
163         // Allow it to the default SMS app always.
164         if (!isCallerDefaultSmsPackage(callingPackage)) {
165             // Allow it with MODIFY_PHONE_STATE or Carrier Privileges
166             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
167                     mContext, mPhone.getSubId(), message);
168         }
169         return true;
170     }
171 
172     /** Check if a package is default SMS app. */
173     @VisibleForTesting
isCallerDefaultSmsPackage(String packageName)174     public boolean isCallerDefaultSmsPackage(String packageName) {
175         if (packageNameMatchesCallingUid(packageName)) {
176             return SmsApplication.isDefaultSmsApplication(mContext, packageName);
177         }
178         return false;
179     }
180 
181     /**
182      * Check if the passed in packageName belongs to the calling uid.
183      * @param packageName name of the package to check
184      * @return true if package belongs to calling uid, false otherwise
185      */
186     @VisibleForTesting
packageNameMatchesCallingUid(String packageName)187     public boolean packageNameMatchesCallingUid(String packageName) {
188         try {
189             if (Binder.getCallingUid()
190                     != mContext.getPackageManager().getPackageUid(packageName, 0)) {
191                 Log.e(LOG_TAG, "packageNameMatchesCallingUid: " + packageName + " uid "
192                         + mContext.getPackageManager().getPackageUid(packageName, 0)
193                         + " does not match calling uid " + Binder.getCallingUid());
194                 return false;
195             }
196         } catch (PackageManager.NameNotFoundException ex) {
197             Log.e(LOG_TAG, "packageNameMatchesCallingUid: packageName " + packageName
198                     + " not found");
199             return false;
200         }
201         return true;
202     }
203 
204     @UnsupportedAppUsage
log(String msg)205     protected void log(String msg) {
206         Rlog.d(LOG_TAG, msg);
207     }
208 
loge(String msg)209     protected void loge(String msg) {
210         Rlog.e(LOG_TAG, msg);
211     }
212 
loge(String msg, Throwable e)213     protected void loge(String msg, Throwable e) {
214         Rlog.e(LOG_TAG, msg, e);
215     }
216 }
217