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

Commit b3ae2646 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Clear caller Identity in PhoneSubInfoController"

parents e5450a62 f012baa6
Loading
Loading
Loading
Loading
+214 −262
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.ImsiEncryptionInfo;
@@ -60,80 +61,35 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getDeviceIdForPhone(int phoneId, String callingPackage) {
        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
            phoneId = 0;
        }
        final Phone phone = mPhone[phoneId];
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, phone.getSubId(), callingPackage, "getDeviceId")) {
                return null;
            }
            return phone.getDeviceId();
        } else {
            loge("getDeviceIdForPhone phone " + phoneId + " is null");
            return null;
        }
        return callPhoneMethodForPhoneIdWithReadCheck(phoneId, callingPackage,
                "getDeviceId", (phone)-> phone.getDeviceId());
    }

    public String getNaiForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getNai")) {
                return null;
            }
            return phone.getNai();
        } else {
            loge("getNai phone is null for Subscription:" + subId);
            return null;
        }
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getNai",
                (phone)-> phone.getNai());
    }

    public String getImeiForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getImei")) {
                return null;
            }
            return phone.getImei();
        } else {
            loge("getDeviceId phone is null for Subscription:" + subId);
            return null;
        }
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getImei",
                (phone)-> phone.getImei());
    }

    public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType,
                                                              String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage,
                    "getCarrierInfoForImsiEncryption")) {
                return null;
            }
            return phone.getCarrierInfoForImsiEncryption(keyType);
        } else {
            loge("getCarrierInfoForImsiEncryption phone is null for Subscription:" + subId);
            return null;
        }
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
                "getCarrierInfoForImsiEncryption",
                (phone)-> phone.getCarrierInfoForImsiEncryption(keyType));
    }

    public void setCarrierInfoForImsiEncryption(int subId, String callingPackage,
                                                ImsiEncryptionInfo imsiEncryptionInfo) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "setCarrierInfoForImsiEncryption")) {
                return;
            }
            enforceModifyPermission();
        callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage,
                "setCarrierInfoForImsiEncryption",
                (phone)-> {
                    phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo);
        } else {
            loge("setCarrierInfoForImsiEncryption phone is null for Subscription:" + subId);
            return;
        }
                    return null;
                });
    }

    /**
@@ -144,15 +100,12 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
     *  @param callingPackage
     */
    public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            enforceModifyPermission();
        callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage,
                "setCarrierInfoForImsiEncryption",
                (phone)-> {
                    phone.resetCarrierKeysForImsiEncryption();
            return;
        } else {
            loge("resetCarrierKeysForImsiEncryption phone is null for Subscription:" + subId);
            return;
        }
                    return null;
                });
    }


@@ -161,17 +114,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getDeviceSvnUsingSubId(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getDeviceSvn")) {
                return null;
            }
            return phone.getDeviceSvn();
        } else {
            loge("getDeviceSvn phone is null");
            return null;
        }
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getDeviceSvn",
                (phone)-> phone.getDeviceSvn());
    }

    public String getSubscriberId(String callingPackage) {
@@ -179,17 +123,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getSubscriberIdForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getSubscriberId")) {
                return null;
            }
            return phone.getSubscriberId();
        } else {
            loge("getSubscriberId phone is null for Subscription:" + subId);
            return null;
        }
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getSubscriberId",
                (phone)-> phone.getSubscriberId());
    }

    /**
@@ -200,17 +135,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getIccSerialNumberForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getIccSerialNumber")) {
                return null;
            }
            return phone.getIccSerialNumber();
        } else {
            loge("getIccSerialNumber phone is null for Subscription:" + subId);
            return null;
        }
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getIccSerialNumber",
                (phone)-> phone.getIccSerialNumber());
    }

    public String getLine1Number(String callingPackage) {
@@ -218,18 +144,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getLine1NumberForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            // This is open to apps with WRITE_SMS.
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
                    mContext, subId, callingPackage, "getLine1Number")) {
                return null;
            }
            return phone.getLine1Number();
        } else {
            loge("getLine1Number phone is null for Subscription:" + subId);
            return null;
        }
        return callPhoneMethodForSubIdWithReadPhoneNumberCheck(
                subId, callingPackage, "getLine1Number",
                (phone)-> phone.getLine1Number());
    }

    public String getLine1AlphaTag(String callingPackage) {
@@ -237,17 +154,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getLine1AlphaTag")) {
                return null;
            }
            return phone.getLine1AlphaTag();
        } else {
            loge("getLine1AlphaTag phone is null for Subscription:" + subId);
            return null;
        }
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getLine1AlphaTag",
                (phone)-> phone.getLine1AlphaTag());
    }

    public String getMsisdn(String callingPackage) {
@@ -255,17 +163,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getMsisdnForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getMsisdn")) {
                return null;
            }
            return phone.getMsisdn();
        } else {
            loge("getMsisdn phone is null for Subscription:" + subId);
            return null;
        }
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getMsisdn",
                (phone)-> phone.getMsisdn());
    }

    public String getVoiceMailNumber(String callingPackage) {
@@ -273,19 +172,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getVoiceMailNumber")) {
                return null;
            }
            String number = PhoneNumberUtils.extractNetworkPortion(phone.getVoiceMailNumber());
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
                "getVoiceMailNumber", (phone)-> {
                    String number = PhoneNumberUtils.extractNetworkPortion(
                            phone.getVoiceMailNumber());
                    if (VDBG) log("VM: getVoiceMailNUmber: " + number);
                    return number;
        } else {
            loge("getVoiceMailNumber phone is null for Subscription:" + subId);
            return null;
        }
                });
    }

    // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE
@@ -311,17 +204,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getVoiceMailAlphaTag")) {
                return null;
            }
            return phone.getVoiceMailAlphaTag();
        } else {
            loge("getVoiceMailAlphaTag phone is null for Subscription:" + subId);
            return null;
        }
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
                "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag());
    }

    /**
@@ -341,6 +225,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
     * @throws SecurityException if the caller does not have the required permission/privilege
     */
    private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) {
        // TODO(b/73660190): Migrate to
        // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete
        // this helper method.
        int permissionResult = mContext.checkCallingOrSelfPermission(
                READ_PRIVILEGED_PHONE_STATE);
        if (permissionResult == PackageManager.PERMISSION_GRANTED) {
@@ -362,114 +249,84 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
        return  PhoneFactory.getDefaultSubscription();
    }


    /**
    * get the Isim Impi based on subId
    */
    public String getIsimImpi(int subId) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
                    "Requires READ_PRIVILEGED_PHONE_STATE");
        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpi",
                (phone) -> {
                    IsimRecords isim = phone.getIsimRecords();
                    if (isim != null) {
                        return isim.getIsimImpi();
                    } else {
                        return null;
                    }
        } else {
            loge("getIsimImpi phone is null for Subscription:" + subId);
            return null;
        }
                });
    }

    /**
    * get the Isim Domain based on subId
    */
    public String getIsimDomain(int subId) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
                    "Requires READ_PRIVILEGED_PHONE_STATE");
        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimDomain",
                (phone) -> {
                    IsimRecords isim = phone.getIsimRecords();
                    if (isim != null) {
                        return isim.getIsimDomain();
                    } else {
                        return null;
                    }
        } else {
            loge("getIsimDomain phone is null for Subscription:" + subId);
            return null;
        }
                });
    }

    /**
    * get the Isim Impu based on subId
    */
    public String[] getIsimImpu(int subId) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
                    "Requires READ_PRIVILEGED_PHONE_STATE");
        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpu",
                (phone) -> {
                    IsimRecords isim = phone.getIsimRecords();
                    if (isim != null) {
                        return isim.getIsimImpu();
                    } else {
                        return null;
                    }
        } else {
            loge("getIsimImpu phone is null for Subscription:" + subId);
            return null;
        }
                });
    }

    /**
    * get the Isim Ist based on subId
    */
    public String getIsimIst(int subId) throws RemoteException {
        Phone phone = getPhone(subId);
        if (phone != null) {
            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
                    "Requires READ_PRIVILEGED_PHONE_STATE");
        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimIst",
                (phone) -> {
                    IsimRecords isim = phone.getIsimRecords();
                    if (isim != null) {
                        return isim.getIsimIst();
                    } else {
                        return null;
                    }
        } else {
            loge("getIsimIst phone is null for Subscription:" + subId);
            return null;
        }
                });
    }

    /**
    * get the Isim Pcscf based on subId
    */
    public String[] getIsimPcscf(int subId) throws RemoteException {
        Phone phone = getPhone(subId);
        if (phone != null) {
            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
                    "Requires READ_PRIVILEGED_PHONE_STATE");
        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimPcscf",
                (phone) -> {
                    IsimRecords isim = phone.getIsimRecords();
                    if (isim != null) {
                        return isim.getIsimPcscf();
                    } else {
                        return null;
                    }
        } else {
            loge("getIsimPcscf phone is null for Subscription:" + subId);
            return null;
        }
                });
    }

    public String getIccSimChallengeResponse(int subId, int appType, int authType, String data)
            throws RemoteException {
        // TODO(b/73660190): Migrate to
        // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete
        // this helper method.
        enforcePrivilegedPermissionOrCarrierPrivilege(subId, "getIccSimChallengeResponse");
        Phone phone = getPhone(subId);
        CallPhoneMethodHelper<String> toExecute = (phone)-> {
            UiccCard uiccCard = phone.getUiccCard();
            if (uiccCard == null) {
                loge("getIccSimChallengeResponse() UiccCard is null");
@@ -478,35 +335,130 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {

            UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
            if (uiccApp == null) {
            loge("getIccSimChallengeResponse() no app with specified type -- " +
                    appType);
                loge("getIccSimChallengeResponse() no app with specified type -- " + appType);
                return null;
            } else {
                loge("getIccSimChallengeResponse() found app " + uiccApp.getAid()
                        + " specified type -- " + appType);
            }

        if(authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM &&
                authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) {
            if (authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM
                    && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) {
                loge("getIccSimChallengeResponse() unsupported authType: " + authType);
                return null;
            }

            return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data);
        };

        return callPhoneMethodWithPermissionCheck(
                subId, null, "getIccSimChallengeResponse", toExecute,
                (aContext, aSubId, aCallingPackage, aMessage)-> {
                    enforcePrivilegedPermissionOrCarrierPrivilege(aSubId, aMessage);
                    return true;
                });
    }

    public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage) {
        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
                "getGroupIdLevel1", (phone)-> phone.getGroupIdLevel1());
    }

    /** Below are utility methods that abstracts the flow that many public methods use:
     *  1. Check permission: pass, throw exception, or fails (returns false).
     *  2. clearCallingIdentity.
     *  3. Call a specified phone method and get return value.
     *  4. restoreCallingIdentity and return.
     */
    private interface CallPhoneMethodHelper<T> {
        T callMethod(Phone phone);
    }

    private interface PermissionCheckHelper {
        // Implemented to do whatever permission check it wants.
        // If passes, it should return true.
        // If permission is not granted, throws SecurityException.
        // If permission is revoked by AppOps, return false.
        boolean checkPermission(Context context, int subId, String callingPackage, String message);
    }

    // Base utility method that others use.
    private <T> T callPhoneMethodWithPermissionCheck(int subId, String callingPackage,
            String message, CallPhoneMethodHelper<T> callMethodHelper,
            PermissionCheckHelper permissionCheckHelper) {
        if (!permissionCheckHelper.checkPermission(mContext, subId, callingPackage, message)) {
            return null;
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            Phone phone = getPhone(subId);
            if (phone != null) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, subId, callingPackage, "getGroupIdLevel1")) {
                return callMethodHelper.callMethod(phone);
            } else {
                loge(message + " phone is null for Subscription:" + subId);
                return null;
            }
            return phone.getGroupIdLevel1();
        } else {
            loge("getGroupIdLevel1 phone is null for Subscription:" + subId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private <T> T callPhoneMethodForSubIdWithReadCheck(int subId, String callingPackage,
            String message, CallPhoneMethodHelper<T> callMethodHelper) {
        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
                (aContext, aSubId, aCallingPackage, aMessage)->
                        TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                                aContext, aSubId, aCallingPackage, aMessage));
    }

    private <T> T callPhoneMethodForSubIdWithPrivilegedCheck(
            int subId, String message, CallPhoneMethodHelper<T> callMethodHelper) {
        return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper,
                (aContext, aSubId, aCallingPackage, aMessage)-> {
                    mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message);
                    return true;
                });
    }

    private <T> T callPhoneMethodForSubIdWithModifyCheck(int subId, String callingPackage,
            String message, CallPhoneMethodHelper<T> callMethodHelper) {
        return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper,
                (aContext, aSubId, aCallingPackage, aMessage)-> {
                    enforceModifyPermission();
                    return true;
                });
    }

    private <T> T callPhoneMethodForSubIdWithReadPhoneNumberCheck(int subId, String callingPackage,
            String message, CallPhoneMethodHelper<T> callMethodHelper) {
        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
                (aContext, aSubId, aCallingPackage, aMessage)->
                        TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
                                aContext, aSubId, aCallingPackage, aMessage));
    }

    private <T> T callPhoneMethodForPhoneIdWithReadCheck(int phoneId, String callingPackage,
            String message, CallPhoneMethodHelper<T> callMethodHelper) {
        // Getting subId before doing permission check.
        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
            phoneId = 0;
        }
        final Phone phone = mPhone[phoneId];
        if (phone == null) {
            return null;
        }

        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, phone.getSubId(), callingPackage, message)) {
            return null;
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            return callMethodHelper.callMethod(phone);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private void log(String s) {