diff options
author | Glen Kuhne <kuh@google.com> | 2016-08-31 16:23:22 -0700 |
---|---|---|
committer | Glen Kuhne <kuh@google.com> | 2017-01-17 15:32:35 -0800 |
commit | 0d14dbc1da819e72054b9f168c8e3db767dd34bf (patch) | |
tree | cabf1690352018a70f1a3115e892a4d74d16ebd2 /service | |
parent | e4c4861e078e2e0fb2a6551859f4c44ee2634f2c (diff) |
Http Proxy Profile & Device Owner permission check
Adding permissions checks to ensure callers of
WifiManager.SAVE_NETWORK and addOrUpdateNetwork() have either
Profile Owner policy, Device Owner policy, or the System Uid. if
they're setting the Http Proxy.
While I was here: Fixed a bug where IpManager wasn't notified of an IP
settings change when a WifiConfiguration's STATIC proxy was modified.
Bug: 14669153
Bug: 32584568
Test: extended WifiConfigManagerTest
Change-Id: I5bc3b1bff6628ffeea7bf6ecd0f6f25a671ab682
Merged-In: I5bc3b1bff6628ffeea7bf6ecd0f6f25a671ab682
Diffstat (limited to 'service')
4 files changed, 60 insertions, 19 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index b59a75e1f..55e681ab0 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -50,6 +50,7 @@ import com.android.server.LocalServices; import com.android.server.wifi.WifiConfigStoreLegacy.WifiConfigStoreDataLegacy; import com.android.server.wifi.util.ScanResultUtil; import com.android.server.wifi.util.TelephonyUtil; +import com.android.server.wifi.util.WifiPermissionsWrapper; import org.xmlpull.v1.XmlPullParserException; @@ -216,6 +217,7 @@ public class WifiConfigManager { private final WifiKeyStore mWifiKeyStore; private final WifiConfigStore mWifiConfigStore; private final WifiConfigStoreLegacy mWifiConfigStoreLegacy; + private final WifiPermissionsWrapper mWifiPermissionsWrapper; /** * Local log used for debugging any WifiConfigManager issues. */ @@ -285,7 +287,8 @@ public class WifiConfigManager { WifiConfigManager( Context context, FrameworkFacade facade, Clock clock, UserManager userManager, TelephonyManager telephonyManager, WifiKeyStore wifiKeyStore, - WifiConfigStore wifiConfigStore, WifiConfigStoreLegacy wifiConfigStoreLegacy) { + WifiConfigStore wifiConfigStore, WifiConfigStoreLegacy wifiConfigStoreLegacy, + WifiPermissionsWrapper wifiPermissionsWrapper) { mContext = context; mFacade = facade; mClock = clock; @@ -295,6 +298,7 @@ public class WifiConfigManager { mWifiKeyStore = wifiKeyStore; mWifiConfigStore = wifiConfigStore; mWifiConfigStoreLegacy = wifiConfigStoreLegacy; + mWifiPermissionsWrapper = wifiPermissionsWrapper; mConfiguredNetworks = new ConfigurationMap(userManager); mScanDetailCaches = new HashMap<>(16, 0.75f); @@ -899,6 +903,15 @@ public class WifiConfigManager { existingInternalConfig, config, uid); } + // Only add networks with proxy settings if the user has permission to + if (WifiConfigurationUtil.hasProxyChanged(existingInternalConfig, newInternalConfig) + && !canModifyProxySettings(uid)) { + Log.e(TAG, "UID " + uid + " does not have permission to modify proxy Settings " + + config.configKey() + ". Must have OVERRIDE_WIFI_CONFIG," + + " or be device or profile owner."); + return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + } + // Update the keys for non-Passpoint enterprise networks. For Passpoint, the certificates // and keys are installed at the time the provider is installed. if (config.enterpriseConfig != null @@ -2618,4 +2631,28 @@ public class WifiConfigManager { pw.println("WifiConfigManager - Next network ID to be allocated " + mNextNetworkId); pw.println("WifiConfigManager - Last selected network ID " + mLastSelectedNetworkId); } + + /** + * Returns true if the given uid has permission to add, update or remove proxy settings + */ + private boolean canModifyProxySettings(int uid) { + final DevicePolicyManagerInternal dpmi = + mWifiPermissionsWrapper.getDevicePolicyManagerInternal(); + final boolean isUidProfileOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(uid, + DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + final boolean isUidDeviceOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(uid, + DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); + final boolean hasConfigOverridePermission = checkConfigOverridePermission(uid); + // If |uid| corresponds to the device owner, allow all modifications. + if (isUidDeviceOwner || isUidProfileOwner || hasConfigOverridePermission) { + return true; + } + if (mVerboseLoggingEnabled) { + Log.v(TAG, "UID: " + uid + " cannot modify WifiConfiguration proxy settings." + + " ConfigOverride=" + hasConfigOverridePermission + + " DeviceOwner=" + isUidDeviceOwner + + " ProfileOwner=" + isUidProfileOwner); + } + return false; + } } diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java index 29ff8fb5d..67f1faded 100644 --- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java +++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java @@ -18,7 +18,6 @@ package com.android.server.wifi; import android.content.pm.UserInfo; import android.net.IpConfiguration; -import android.net.ProxyInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiScanner; @@ -139,23 +138,18 @@ public class WifiConfigurationUtil { * * @param existingConfig Existing WifiConfiguration object corresponding to the network. * @param newConfig New WifiConfiguration object corresponding to the network. - * @return true if proxy parameters have changed, false otherwise. + * @return true if proxy parameters have changed, false if no existing config and proxy settings + * are NONE, false otherwise. */ public static boolean hasProxyChanged(WifiConfiguration existingConfig, WifiConfiguration newConfig) { - if (existingConfig.getProxySettings() != newConfig.getProxySettings()) { - return true; + if (existingConfig == null) { + return newConfig.getProxySettings() != IpConfiguration.ProxySettings.NONE; } - if (newConfig.getProxySettings() == IpConfiguration.ProxySettings.PAC) { - ProxyInfo existingHttpProxy = existingConfig.getHttpProxy(); - ProxyInfo newHttpProxy = newConfig.getHttpProxy(); - if (existingHttpProxy != null) { - return !existingHttpProxy.equals(newHttpProxy); - } else { - return (newHttpProxy != null); - } + if (newConfig.getProxySettings() != existingConfig.getProxySettings()) { + return true; } - return false; + return !Objects.equals(existingConfig.getHttpProxy(), newConfig.getHttpProxy()); } /** diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 902cc644a..1aa5ce837 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -121,6 +121,10 @@ public class WifiInjector { mContext = context; mUseRealLogger = mContext.getResources().getBoolean( R.bool.config_wifi_enable_wifi_firmware_debugging); + mSettingsStore = new WifiSettingsStore(mContext); + mWifiPermissionsWrapper = new WifiPermissionsWrapper(mContext); + mWifiPermissionsUtil = new WifiPermissionsUtil(mWifiPermissionsWrapper, mContext, + mSettingsStore, UserManager.get(mContext), new NetworkScorerAppManager(mContext)); // Now create and start handler threads mWifiServiceHandlerThread = new HandlerThread("WifiService"); @@ -156,7 +160,7 @@ public class WifiInjector { // Config Manager mWifiConfigManager = new WifiConfigManager(mContext, mFrameworkFacade, mClock, UserManager.get(mContext), TelephonyManager.from(mContext), - mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy); + mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy, mWifiPermissionsWrapper); mNetworkScoreManager = (NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE); mWifiNetworkScoreCache = new WifiNetworkScoreCache(mContext); @@ -178,7 +182,6 @@ public class WifiInjector { mWifiStateMachine = new WifiStateMachine(mContext, mFrameworkFacade, mWifiStateMachineHandlerThread.getLooper(), UserManager.get(mContext), this, mBackupManagerProxy, mCountryCode, mWifiNative); - mSettingsStore = new WifiSettingsStore(mContext); mCertManager = new WifiCertManager(mContext); mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService()); mWifiController = new WifiController(mContext, mWifiStateMachine, mSettingsStore, @@ -186,9 +189,6 @@ public class WifiInjector { mWifiLastResortWatchdog = new WifiLastResortWatchdog(mWifiController, mWifiMetrics); mWifiMulticastLockManager = new WifiMulticastLockManager(mWifiStateMachine, BatteryStatsService.getService()); - mWifiPermissionsWrapper = new WifiPermissionsWrapper(mContext); - mWifiPermissionsUtil = new WifiPermissionsUtil(mWifiPermissionsWrapper, mContext, - mSettingsStore, UserManager.get(mContext), new NetworkScorerAppManager(mContext)); } /** diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java b/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java index be10aefa4..72c439d47 100644 --- a/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java +++ b/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java @@ -17,9 +17,12 @@ package com.android.server.wifi.util; import android.app.ActivityManager; +import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; import android.os.UserHandle; +import com.android.server.LocalServices; + import java.util.List; /** @@ -71,4 +74,11 @@ public class WifiPermissionsWrapper { public int getUidPermission(String permissionType, int uid) { return ActivityManager.checkUidPermission(permissionType, uid); } + + /** + * Gets the local service {link@ DevicePolicyManagerInternal}, can be null + */ + public DevicePolicyManagerInternal getDevicePolicyManagerInternal() { + return LocalServices.getService(DevicePolicyManagerInternal.class); + } } |