diff options
author | Etan Cohen <etancohen@google.com> | 2016-08-02 11:14:12 -0700 |
---|---|---|
committer | Etan Cohen <etancohen@google.com> | 2016-08-11 16:09:35 -0700 |
commit | ae719e944792a5bc36ec26230bee16f1415ce141 (patch) | |
tree | 36a4bccdedcf1189526271ac1e0e2fab302e1100 /service | |
parent | 4ab83906ab146d871434e2ae95c17d4b7f28606a (diff) |
[NAN] Gate local identity information (MAC) based on LOCATIONING permission
Gate providing MAC address of NAN discovery interface to app by LOCATIONING
permission.
Bug: 30000323
Change-Id: I2cfb224413a900a88f4e6504d2bf9edfa96f6a4c
Diffstat (limited to 'service')
3 files changed, 78 insertions, 23 deletions
diff --git a/service/java/com/android/server/wifi/nan/WifiNanClientState.java b/service/java/com/android/server/wifi/nan/WifiNanClientState.java index 74fa71dc3..1a95f2986 100644 --- a/service/java/com/android/server/wifi/nan/WifiNanClientState.java +++ b/service/java/com/android/server/wifi/nan/WifiNanClientState.java @@ -16,6 +16,10 @@ package com.android.server.wifi.nan; +import android.Manifest; +import android.app.AppOpsManager; +import android.content.Context; +import android.content.pm.PackageManager; import android.net.wifi.RttManager; import android.net.wifi.nan.ConfigRequest; import android.net.wifi.nan.IWifiNanEventCallback; @@ -23,6 +27,8 @@ import android.os.RemoteException; import android.util.Log; import android.util.SparseArray; +import libcore.util.HexEncoding; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Arrays; @@ -44,22 +50,32 @@ public class WifiNanClientState { /* package */ static final int CLUSTER_CHANGE_EVENT_STARTED = 0; /* package */ static final int CLUSTER_CHANGE_EVENT_JOINED = 1; - private IWifiNanEventCallback mCallback; + private final Context mContext; + private final IWifiNanEventCallback mCallback; private final SparseArray<WifiNanSessionState> mSessions = new SparseArray<>(); - private int mClientId; + private final int mClientId; private ConfigRequest mConfigRequest; - private int mUid; + private final int mUid; + private final int mPid; + private final String mCallingPackage; + + private AppOpsManager mAppOps; private static final byte[] ALL_ZERO_MAC = new byte[] {0, 0, 0, 0, 0, 0}; private byte[] mLastDiscoveryInterfaceMac = ALL_ZERO_MAC; - public WifiNanClientState(int clientId, int uid, IWifiNanEventCallback callback, - ConfigRequest configRequest) { + public WifiNanClientState(Context context, int clientId, int uid, int pid, + String callingPackage, IWifiNanEventCallback callback, ConfigRequest configRequest) { + mContext = context; mClientId = clientId; mUid = uid; + mPid = pid; + mCallingPackage = callingPackage; mCallback = callback; mConfigRequest = configRequest; + + mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); } /** @@ -172,11 +188,21 @@ public class WifiNanClientState { * client. */ public void onInterfaceAddressChange(byte[] mac) { + if (VDBG) { + Log.v(TAG, + "onInterfaceAddressChange: mClientId=" + mClientId + + ", mEnableIdentityChangeCallback=" + + mConfigRequest.mEnableIdentityChangeCallback + ", mac=" + + String.valueOf(HexEncoding.encode(mac)) + + ", mLastDiscoveryInterfaceMac=" + String.valueOf( + HexEncoding.encode(mLastDiscoveryInterfaceMac))); + } if (mConfigRequest.mEnableIdentityChangeCallback && !Arrays.equals(mac, mLastDiscoveryInterfaceMac)) { try { - // TODO: b/30000323 - resolve privacy concerns - mCallback.onIdentityChanged(mac); + boolean hasPermission = hasLocationingPermission(); + if (VDBG) Log.v(TAG, "hasPermission=" + hasPermission); + mCallback.onIdentityChanged(hasPermission ? mac : ALL_ZERO_MAC); } catch (RemoteException e) { Log.w(TAG, "onIdentityChanged: RemoteException - ignored: " + e); } @@ -196,11 +222,22 @@ public class WifiNanClientState { * @param currentDiscoveryInterfaceMac The MAC address of the discovery interface. */ public void onClusterChange(int flag, byte[] mac, byte[] currentDiscoveryInterfaceMac) { + if (VDBG) { + Log.v(TAG, + "onClusterChange: mClientId=" + mClientId + ", mEnableIdentityChangeCallback=" + + mConfigRequest.mEnableIdentityChangeCallback + ", mac=" + + String.valueOf(HexEncoding.encode(mac)) + + ", currentDiscoveryInterfaceMac=" + String.valueOf( + HexEncoding.encode(currentDiscoveryInterfaceMac)) + + ", mLastDiscoveryInterfaceMac=" + String.valueOf( + HexEncoding.encode(mLastDiscoveryInterfaceMac))); + } if (mConfigRequest.mEnableIdentityChangeCallback && !Arrays.equals( currentDiscoveryInterfaceMac, mLastDiscoveryInterfaceMac)) { try { - // TODO: b/30000323 - resolve privacy concerns - mCallback.onIdentityChanged(currentDiscoveryInterfaceMac); + boolean hasPermission = hasLocationingPermission(); + if (VDBG) Log.v(TAG, "hasPermission=" + hasPermission); + mCallback.onIdentityChanged(hasPermission ? mac : ALL_ZERO_MAC); } catch (RemoteException e) { Log.w(TAG, "onIdentityChanged: RemoteException - ignored: " + e); } @@ -209,6 +246,14 @@ public class WifiNanClientState { mLastDiscoveryInterfaceMac = currentDiscoveryInterfaceMac; } + private boolean hasLocationingPermission() { + // FINE provides COARSE, so only have to check for the latter + return mContext.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, mPid, mUid) + == PackageManager.PERMISSION_GRANTED && mAppOps.noteOp( + AppOpsManager.OP_COARSE_LOCATION, mUid, mCallingPackage) + == AppOpsManager.MODE_ALLOWED; + } + /** * Called on RTT success - forwards call to client. */ diff --git a/service/java/com/android/server/wifi/nan/WifiNanServiceImpl.java b/service/java/com/android/server/wifi/nan/WifiNanServiceImpl.java index a83b80f34..ec5df3b0c 100644 --- a/service/java/com/android/server/wifi/nan/WifiNanServiceImpl.java +++ b/service/java/com/android/server/wifi/nan/WifiNanServiceImpl.java @@ -134,7 +134,7 @@ public class WifiNanServiceImpl extends IWifiNanManager.Stub { } @Override - public int connect(final IBinder binder, IWifiNanEventCallback callback, + public int connect(final IBinder binder, String callingPackage, IWifiNanEventCallback callback, ConfigRequest configRequest) { enforceAccessPermission(); enforceChangePermission(); @@ -156,6 +156,7 @@ public class WifiNanServiceImpl extends IWifiNanManager.Stub { configRequest.validate(); final int uid = getMockableCallingUid(); + int pid = getCallingPid(); final int clientId; synchronized (mLock) { @@ -199,7 +200,7 @@ public class WifiNanServiceImpl extends IWifiNanManager.Stub { mUidByClientId.put(clientId, uid); } - mStateManager.connect(clientId, uid, callback, configRequest); + mStateManager.connect(clientId, uid, pid, callingPackage, callback, configRequest); return clientId; } diff --git a/service/java/com/android/server/wifi/nan/WifiNanStateManager.java b/service/java/com/android/server/wifi/nan/WifiNanStateManager.java index 8db4193e0..c807b4187 100644 --- a/service/java/com/android/server/wifi/nan/WifiNanStateManager.java +++ b/service/java/com/android/server/wifi/nan/WifiNanStateManager.java @@ -165,6 +165,8 @@ public class WifiNanStateManager { private static final String MESSAGE_BUNDLE_KEY_CHANNEL = "channel"; private static final String MESSAGE_BUNDLE_KEY_PEER_ID = "peer_id"; private static final String MESSAGE_BUNDLE_KEY_UID = "uid"; + private static final String MESSAGE_BUNDLE_KEY_PID = "pid"; + private static final String MESSAGE_BUNDLE_KEY_CALLING_PACKAGE = "calling_package"; private static final String MESSAGE_BUNDLE_KEY_SENT_MESSAGE = "send_message"; private static final String MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ = "message_arrival_seq"; @@ -247,14 +249,16 @@ public class WifiNanStateManager { /** * Place a request for a new client connection on the state machine queue. */ - public void connect(int clientId, int uid, IWifiNanEventCallback callback, - ConfigRequest configRequest) { + public void connect(int clientId, int uid, int pid, String callingPackage, + IWifiNanEventCallback callback, ConfigRequest configRequest) { Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); msg.arg1 = COMMAND_TYPE_CONNECT; msg.arg2 = clientId; msg.obj = callback; msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_CONFIG, configRequest); msg.getData().putInt(MESSAGE_BUNDLE_KEY_UID, uid); + msg.getData().putInt(MESSAGE_BUNDLE_KEY_PID, pid); + msg.getData().putString(MESSAGE_BUNDLE_KEY_CALLING_PACKAGE, callingPackage); mSm.sendMessage(msg); } @@ -1178,9 +1182,12 @@ public class WifiNanStateManager { ConfigRequest configRequest = (ConfigRequest) msg.getData() .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG); int uid = msg.getData().getInt(MESSAGE_BUNDLE_KEY_UID); + int pid = msg.getData().getInt(MESSAGE_BUNDLE_KEY_PID); + String callingPackage = msg.getData().getString( + MESSAGE_BUNDLE_KEY_CALLING_PACKAGE); - waitForResponse = connectLocal(mCurrentTransactionId, clientId, uid, callback, - configRequest); + waitForResponse = connectLocal(mCurrentTransactionId, clientId, uid, pid, + callingPackage, callback, configRequest); break; } case COMMAND_TYPE_DISCONNECT: { @@ -1730,12 +1737,12 @@ public class WifiNanStateManager { * COMMANDS */ - private boolean connectLocal(short transactionId, int clientId, int uid, - IWifiNanEventCallback callback, ConfigRequest configRequest) { + private boolean connectLocal(short transactionId, int clientId, int uid, int pid, + String callingPackage, IWifiNanEventCallback callback, ConfigRequest configRequest) { if (VDBG) { Log.v(TAG, "connectLocal(): transactionId=" + transactionId + ", clientId=" + clientId - + ", uid=" + uid + ", callback=" + callback + ", configRequest=" - + configRequest); + + ", uid=" + uid + ", pid=" + pid + ", callingPackage=" + callingPackage + + ", callback=" + callback + ", configRequest=" + configRequest); } if (!mUsageEnabled) { @@ -1765,8 +1772,8 @@ public class WifiNanStateManager { } catch (RemoteException e) { Log.w(TAG, "connectLocal onConnectSuccess(): RemoteException (FYI): " + e); } - WifiNanClientState client = new WifiNanClientState(clientId, uid, callback, - configRequest); + WifiNanClientState client = new WifiNanClientState(mContext, clientId, uid, pid, + callingPackage, callback, configRequest); client.onInterfaceAddressChange(mCurrentDiscoveryInterfaceMac); mClients.append(clientId, client); return false; @@ -2051,9 +2058,11 @@ public class WifiNanStateManager { ConfigRequest configRequest = (ConfigRequest) data .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG); int uid = data.getInt(MESSAGE_BUNDLE_KEY_UID); + int pid = data.getInt(MESSAGE_BUNDLE_KEY_PID); + String callingPackage = data.getString(MESSAGE_BUNDLE_KEY_CALLING_PACKAGE); - WifiNanClientState client = new WifiNanClientState(clientId, uid, callback, - configRequest); + WifiNanClientState client = new WifiNanClientState(mContext, clientId, uid, pid, + callingPackage, callback, configRequest); mClients.put(clientId, client); try { callback.onConnectSuccess(); |