From 9a99a8a4fcdc64c67f016f5a07ffae0792d5e5cf Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 9 Oct 2019 07:19:30 -0700 Subject: WifiService: Revert get/remove passpoint API deprecation Allow apps to get/remove passpoint profiles installed by them. Privileged apps can continue to get/remove all profiles. Bug: 141639265 Test: atest com.android.server.wifi Change-Id: Id073c25a021dbeb81e87064e93ead966a363390e Merged-In: Id073c25a021dbeb81e87064e93ead966a363390e --- .../com/android/server/wifi/ClientModeImpl.java | 22 +++++++++++----- .../com/android/server/wifi/WifiServiceImpl.java | 27 ++++++++----------- .../server/wifi/hotspot2/PasspointManager.java | 30 ++++++++++++++++------ 3 files changed, 48 insertions(+), 31 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 66f138097..134977a62 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -1780,12 +1780,14 @@ public class ClientModeImpl extends StateMachine { * Remove a Passpoint configuration synchronously. * * @param channel Channel for communicating with the state machine + * @param privileged Whether the caller is a privileged entity * @param fqdn The FQDN of the Passpoint configuration to remove * @return true on success */ - public boolean syncRemovePasspointConfig(AsyncChannel channel, String fqdn) { + public boolean syncRemovePasspointConfig(AsyncChannel channel, boolean privileged, + String fqdn) { Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_PASSPOINT_CONFIG, - fqdn); + privileged ? 1 : 0, 0, fqdn); if (messageIsNull(resultMsg)) return false; boolean result = (resultMsg.arg1 == SUCCESS); resultMsg.recycle(); @@ -1796,10 +1798,13 @@ public class ClientModeImpl extends StateMachine { * Get the list of installed Passpoint configurations synchronously. * * @param channel Channel for communicating with the state machine + * @param privileged Whether the caller is a privileged entity * @return List of {@link PasspointConfiguration} */ - public List syncGetPasspointConfigs(AsyncChannel channel) { - Message resultMsg = channel.sendMessageSynchronously(CMD_GET_PASSPOINT_CONFIGS); + public List syncGetPasspointConfigs(AsyncChannel channel, + boolean privileged) { + Message resultMsg = channel.sendMessageSynchronously(CMD_GET_PASSPOINT_CONFIGS, + privileged ? 1 : 0); if (messageIsNull(resultMsg)) return null; List result = (List) resultMsg.obj; resultMsg.recycle(); @@ -3685,11 +3690,13 @@ public class ClientModeImpl extends StateMachine { break; case CMD_REMOVE_PASSPOINT_CONFIG: int removeResult = mPasspointManager.removeProvider( - (String) message.obj) ? SUCCESS : FAILURE; + message.sendingUid, message.arg1 == 1, (String) message.obj) + ? SUCCESS : FAILURE; replyToMessage(message, message.what, removeResult); break; case CMD_GET_PASSPOINT_CONFIGS: - replyToMessage(message, message.what, mPasspointManager.getProviderConfigs()); + replyToMessage(message, message.what, mPasspointManager.getProviderConfigs( + message.sendingUid, message.arg1 == 1)); break; case CMD_RESET_SIM_NETWORKS: /* Defer this message until supplicant is started. */ @@ -4524,7 +4531,8 @@ public class ClientModeImpl extends StateMachine { break; case CMD_REMOVE_PASSPOINT_CONFIG: String fqdn = (String) message.obj; - if (mPasspointManager.removeProvider(fqdn)) { + if (mPasspointManager.removeProvider( + message.sendingUid, message.arg1 == 1, fqdn)) { if (isProviderOwnedNetwork(mTargetNetworkId, fqdn) || isProviderOwnedNetwork(mLastNetworkId, fqdn)) { logd("Disconnect from current network since its provider is removed"); diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 2d15af53c..650f33d36 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -2309,18 +2309,16 @@ public class WifiServiceImpl extends BaseWifiService { @Override public boolean removePasspointConfiguration(String fqdn, String packageName) { final int uid = Binder.getCallingUid(); - if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid) - && !mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(uid)) { - if (mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q, uid)) { - return false; - } - throw new SecurityException(TAG + ": Permission denied"); + boolean privileged = false; + if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid) + || mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(uid)) { + privileged = true; } mLog.info("removePasspointConfiguration uid=%").c(Binder.getCallingUid()).flush(); if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)) { return false; } - return mClientModeImpl.syncRemovePasspointConfig(mClientModeImplChannel, fqdn); + return mClientModeImpl.syncRemovePasspointConfig(mClientModeImplChannel, privileged, fqdn); } /** @@ -2333,13 +2331,10 @@ public class WifiServiceImpl extends BaseWifiService { @Override public List getPasspointConfigurations(String packageName) { final int uid = Binder.getCallingUid(); - mAppOps.checkPackage(uid, packageName); - if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid) - && !mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)) { - if (mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q, uid)) { - return new ArrayList<>(); - } - throw new SecurityException(TAG + ": Permission denied"); + boolean privileged = false; + if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid) + || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)) { + privileged = true; } if (mVerboseLoggingEnabled) { mLog.info("getPasspointConfigurations uid=%").c(Binder.getCallingUid()).flush(); @@ -2348,7 +2343,7 @@ public class WifiServiceImpl extends BaseWifiService { PackageManager.FEATURE_WIFI_PASSPOINT)) { return new ArrayList<>(); } - return mClientModeImpl.syncGetPasspointConfigs(mClientModeImplChannel); + return mClientModeImpl.syncGetPasspointConfigs(mClientModeImplChannel, privileged); } /** @@ -2975,7 +2970,7 @@ public class WifiServiceImpl extends BaseWifiService { if (mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_WIFI_PASSPOINT)) { List configs = mClientModeImpl.syncGetPasspointConfigs( - mClientModeImplChannel); + mClientModeImplChannel, true); if (configs != null) { for (PasspointConfiguration config : configs) { removePasspointConfiguration(config.getHomeSp().getFqdn(), packageName); diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index e54cee8e9..c46873761 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -288,7 +288,7 @@ public class PasspointManager { for (Map.Entry entry : getPasspointProviderWithPackage( packageName).entrySet()) { String fqdn = entry.getValue().getConfig().getHomeSp().getFqdn(); - removeProvider(fqdn); + removeProvider(Process.WIFI_UID /* ignored */, true, fqdn); disconnectIfPasspointNetwork(fqdn); } } @@ -658,18 +658,26 @@ public class PasspointManager { /** * Remove a Passpoint provider identified by the given FQDN. * + * @param callingUid Calling UID. + * @param privileged Whether the caller is a privileged entity * @param fqdn The FQDN of the provider to remove * @return true if a provider is removed, false otherwise */ - public boolean removeProvider(String fqdn) { + public boolean removeProvider(int callingUid, boolean privileged, String fqdn) { mWifiMetrics.incrementNumPasspointProviderUninstallation(); String packageName; - if (!mProviders.containsKey(fqdn)) { + PasspointProvider provider = mProviders.get(fqdn); + if (provider == null) { Log.e(TAG, "Config doesn't exist"); return false; } - mProviders.get(fqdn).uninstallCertsAndKeys(); - packageName = mProviders.get(fqdn).getPackageName(); + if (!privileged && callingUid != provider.getCreatorUid()) { + Log.e(TAG, "UID " + callingUid + " cannot remove profile created by " + + provider.getCreatorUid()); + return false; + } + provider.uninstallCertsAndKeys(); + packageName = provider.getPackageName(); mProviders.remove(fqdn); mWifiConfigManager.saveToStore(true /* forceWrite */); @@ -702,12 +710,17 @@ public class PasspointManager { * * An empty list will be returned when no provider is installed. * + * @param callingUid Calling UID. + * @param privileged Whether the caller is a privileged entity * @return A list of {@link PasspointConfiguration} */ - public List getProviderConfigs() { + public List getProviderConfigs(int callingUid, boolean privileged) { List configs = new ArrayList<>(); for (Map.Entry entry : mProviders.entrySet()) { - configs.add(entry.getValue().getConfig()); + PasspointProvider provider = entry.getValue(); + if (privileged || callingUid == provider.getCreatorUid()) { + configs.add(provider.getConfig()); + } } return configs; } @@ -1007,7 +1020,8 @@ public class PasspointManager { public Map getMatchingPasspointConfigsForOsuProviders( List osuProviders) { Map matchingPasspointConfigs = new HashMap<>(); - List passpointConfigurations = getProviderConfigs(); + List passpointConfigurations = + getProviderConfigs(Process.WIFI_UID /* ignored */, true); for (OsuProvider osuProvider : osuProviders) { Map friendlyNamesForOsuProvider = osuProvider.getFriendlyNameList(); -- cgit v1.2.3