summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2017-10-05 01:05:56 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-10-05 01:05:56 +0000
commitdb68688e4eeeeceb9ab1b3bc422f77458fba2f24 (patch)
tree43e4f1ce6bba8bacee47227c0cbc0fdba9ff125a /service
parent70954f46ffb95cbf3d6c9d12495be20edf2b3530 (diff)
parent1982ffd9f5a9434623e1e6229df9d23c506e7491 (diff)
Merge "DO NOT MERGE Allow the USE_OPEN_WIFI_PACKAGE to access WifiInfo unfiltered." into oc-mr1-dev
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java4
-rw-r--r--service/java/com/android/server/wifi/util/WifiPermissionsUtil.java118
2 files changed, 120 insertions, 2 deletions
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 9e124463d..e04d33e5b 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -1770,7 +1770,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
uid) == PackageManager.PERMISSION_GRANTED) {
result.setMacAddress(mWifiInfo.getMacAddress());
}
- if (mWifiPermissionsUtil.canAccessScanResults(
+ final WifiConfiguration currentWifiConfiguration = getCurrentWifiConfiguration();
+ if (mWifiPermissionsUtil.canAccessFullConnectionInfo(
+ currentWifiConfiguration,
callingPackage,
uid,
Build.VERSION_CODES.O)) {
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
index 069e5a823..52c96183e 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
@@ -17,17 +17,23 @@
package com.android.server.wifi.util;
import android.Manifest;
+import android.annotation.Nullable;
import android.app.AppOpsManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.net.ConnectivityManager;
import android.net.NetworkScoreManager;
+import android.net.NetworkScorerAppData;
+import android.net.wifi.WifiConfiguration;
import android.os.Binder;
import android.os.RemoteException;
import android.os.UserManager;
import android.provider.Settings;
+import android.text.TextUtils;
+import com.android.server.wifi.FrameworkFacade;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiLog;
import com.android.server.wifi.WifiSettingsStore;
@@ -46,6 +52,7 @@ public class WifiPermissionsUtil {
private final UserManager mUserManager;
private final WifiSettingsStore mSettingsStore;
private final NetworkScoreManager mNetworkScoreManager;
+ private final FrameworkFacade mFrameworkFacade;
private WifiLog mLog;
public WifiPermissionsUtil(WifiPermissionsWrapper wifiPermissionsWrapper,
@@ -58,6 +65,7 @@ public class WifiPermissionsUtil {
mSettingsStore = settingsStore;
mLog = wifiInjector.makeLog(TAG);
mNetworkScoreManager = networkScoreManager;
+ mFrameworkFacade = wifiInjector.getFrameworkFacade();
}
/**
@@ -168,10 +176,81 @@ public class WifiPermissionsUtil {
}
// If the User or profile is current, permission is granted
// Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission.
- if (!isCurrentProfile(uid) && !checkInteractAcrossUsersFull(uid)) {
+ if (!canAccessUserProfile(uid)) {
+ mLog.tC("Denied: Profile not permitted");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * API to determine if the caller has permissions to get a {@link android.net.wifi.WifiInfo}
+ * instance containing the SSID and BSSID.
+ *
+ *
+ * @param currentConfig the currently connected WiFi config
+ * @param pkgName package name of the application requesting access
+ * @param uid The uid of the package
+ * @param minVersion Minimum app API Version number to enforce location permission
+ * @return boolean true if the SSID/BSSID can be sent to the user, false if they
+ * should be hidden/removed.
+ */
+ public boolean canAccessFullConnectionInfo(@Nullable WifiConfiguration currentConfig,
+ String pkgName, int uid, int minVersion) throws SecurityException {
+ mAppOps.checkPackage(uid, pkgName);
+
+ // The User or profile must be current or the uid must
+ // have INTERACT_ACROSS_USERS_FULL permission.
+ if (!canAccessUserProfile(uid)) {
mLog.tC("Denied: Profile not permitted");
return false;
}
+
+ // If the caller has scan result access then they can also see the full connection info.
+ // Otherwise the caller must be the active use open wifi package and the current config
+ // must be for an open network.
+ return canAccessScanResults(pkgName, uid, minVersion)
+ || isUseOpenWifiPackageWithConnectionInfoAccess(currentConfig, pkgName);
+
+ }
+
+ /**
+ * Returns true if the given WiFi config is for an open network and the package is the active
+ * use open wifi app.
+ */
+ private boolean isUseOpenWifiPackageWithConnectionInfoAccess(
+ @Nullable WifiConfiguration currentConfig, String pkgName) {
+
+ // Access is only granted for open networks.
+ if (currentConfig == null) {
+ mLog.tC("Denied: WifiConfiguration is NULL.");
+ return false;
+ }
+
+ // Access is only granted for open networks.
+ if (!currentConfig.isOpenNetwork()) {
+ mLog.tC("Denied: The current config is not for an open network.");
+ return false;
+ }
+
+ // The USE_OPEN_WIFI_PACKAGE can access the full connection info details without
+ // scan result access.
+ if (!isUseOpenWifiPackage(pkgName)) {
+ mLog.tC("Denied: caller is not the current USE_OPEN_WIFI_PACKAGE");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns true if the User or profile is current or the
+ * uid has the INTERACT_ACROSS_USERS_FULL permission.
+ */
+ private boolean canAccessUserProfile(int uid) {
+ if (!isCurrentProfile(uid) && !checkInteractAcrossUsersFull(uid)) {
+ return false;
+ }
return true;
}
@@ -192,6 +271,43 @@ public class WifiPermissionsUtil {
}
/**
+ * Returns true if the given package is equal to the setting keyed by
+ * {@link Settings.Global#USE_OPEN_WIFI_PACKAGE} and the NetworkScoreManager
+ * has the package name set as the use open wifi package.
+ */
+ private boolean isUseOpenWifiPackage(String packageName) {
+ if (TextUtils.isEmpty(packageName)) {
+ return false;
+ }
+
+ // When the setting is enabled it's set to the package name of the use open wifi app.
+ final String useOpenWifiPkg =
+ mFrameworkFacade.getStringSetting(mContext, Settings.Global.USE_OPEN_WIFI_PACKAGE);
+ if (packageName.equals(useOpenWifiPkg)) {
+ // If the package name matches the setting then also confirm that the scorer is
+ // active and the package matches the expected use open wifi package from the scorer's
+ // perspective. The scorer can be active when the use open wifi feature is off so we
+ // can't rely on this check alone.
+ // TODO(b/67278755): Refactor this into an API similar to isCallerActiveScorer()
+ final NetworkScorerAppData appData;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ appData = mNetworkScoreManager.getActiveScorer();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ if (appData != null) {
+ final ComponentName enableUseOpenWifiActivity =
+ appData.getEnableUseOpenWifiActivity();
+ return enableUseOpenWifiActivity != null
+ && packageName.equals(enableUseOpenWifiActivity.getPackageName());
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Returns true if Wifi scan operation is allowed for this caller
* and package.
*/