diff options
| author | 2021-02-17 14:26:44 +0000 | |
|---|---|---|
| committer | 2021-02-17 18:30:39 +0000 | |
| commit | df40469ffff761d5c25d47e48284e555d0360e41 (patch) | |
| tree | c7230ac7c83ab0a335b5ed75a6b7312e4ffcfd2b | |
| parent | ab42e66b4c27253a6a45c3ce70bd798694d44631 (diff) | |
Support ADB command for denying client auth
To make it easier to verify the permissions authentication logic, add
support for immediately denying a client access to a nanoapp.
Bug: 166846988
Test: adb shell cmd contexthub disable 0 test 0x123412 and verify
the app no longer can talk to the nanoapp
Change-Id: I45e15325e8cd3cc4b216f80292b507cbc675cd10
4 files changed, 121 insertions, 18 deletions
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java b/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java index 3d294de256ff..6249a068f591 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java @@ -425,6 +425,10 @@ public class ContextHubClientBroker extends IContextHubClient.Stub } } + /* package */ String getPackageName() { + return mPackage; + } + /** * Used to override the attribution tag with a newer value if a PendingIntent broker is * retrieved. @@ -645,6 +649,13 @@ public class ContextHubClientBroker extends IContextHubClient.Stub */ private void updateNanoAppAuthState( long nanoAppId, boolean hasPermissions, boolean gracePeriodExpired) { + updateNanoAppAuthState( + nanoAppId, hasPermissions, gracePeriodExpired, false /* forceDenied */); + } + + /* package */ void updateNanoAppAuthState( + long nanoAppId, boolean hasPermissions, boolean gracePeriodExpired, + boolean forceDenied) { int curAuthState; int newAuthState; synchronized (mMessageChannelNanoappIdMap) { @@ -655,7 +666,10 @@ public class ContextHubClientBroker extends IContextHubClient.Stub // GRANTED -> DENIED_GRACE_PERIOD only if permissions have been lost // DENIED_GRACE_PERIOD -> DENIED only if the grace period expires // DENIED/DENIED_GRACE_PERIOD -> GRANTED only if permissions are granted again - if (gracePeriodExpired) { + // any state -> DENIED if "forceDenied" is true + if (forceDenied) { + newAuthState = AUTHORIZATION_DENIED; + } else if (gracePeriodExpired) { if (curAuthState == AUTHORIZATION_DENIED_GRACE_PERIOD) { newAuthState = AUTHORIZATION_DENIED; } @@ -667,13 +681,12 @@ public class ContextHubClientBroker extends IContextHubClient.Stub } } - if (newAuthState == AUTHORIZATION_GRANTED) { + if (newAuthState != AUTHORIZATION_DENIED_GRACE_PERIOD) { AuthStateDenialTimer timer = mNappToAuthTimerMap.remove(nanoAppId); if (timer != null) { timer.cancel(); } - } else if (curAuthState == AUTHORIZATION_GRANTED - && newAuthState == AUTHORIZATION_DENIED_GRACE_PERIOD) { + } else if (curAuthState == AUTHORIZATION_GRANTED) { AuthStateDenialTimer timer = new AuthStateDenialTimer(this, nanoAppId, Looper.getMainLooper()); mNappToAuthTimerMap.put(nanoAppId, timer); diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java index bc3f4b1db46d..e3522f6d487c 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java @@ -319,6 +319,21 @@ import java.util.function.Consumer; } /** + * Runs a command for each client that is attached to a hub with the given ID. + * + * @param contextHubId the ID of the hub + * @param callback the command to invoke for the client + */ + /* package */ void forEachClientOfHub( + int contextHubId, Consumer<ContextHubClientBroker> callback) { + for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) { + if (broker.getAttachedContextHubId() == contextHubId) { + callback.accept(broker); + } + } + } + + /** * Returns an available host endpoint ID. * * @returns an available host endpoint ID @@ -358,20 +373,6 @@ import java.util.function.Consumer; } /** - * Runs a command for each client that is attached to a hub with the given ID. - * - * @param contextHubId the ID of the hub - * @param callback the command to invoke for the client - */ - private void forEachClientOfHub(int contextHubId, Consumer<ContextHubClientBroker> callback) { - for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) { - if (broker.getAttachedContextHubId() == contextHubId) { - callback.accept(broker); - } - } - } - - /** * Retrieves a ContextHubClientBroker object with a matching PendingIntent and Context Hub ID. * * @param pendingIntent the PendingIntent to match diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java index 40986fcf03cb..0737db7b8358 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java @@ -50,6 +50,8 @@ import android.net.wifi.WifiManager; import android.os.Binder; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.os.ResultReceiver; +import android.os.ShellCallback; import android.os.UserHandle; import android.provider.Settings; import android.util.Log; @@ -366,6 +368,12 @@ public class ContextHubService extends IContextHubService.Stub { } @Override + public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, + String[] args, ShellCallback callback, ResultReceiver result) { + new ContextHubShellCommand(mContext, this).exec(this, in, out, err, args, callback, result); + } + + @Override public int registerCallback(IContextHubCallback callback) throws RemoteException { checkPermissions(); mCallbacksList.register(callback); @@ -933,6 +941,16 @@ public class ContextHubService extends IContextHubService.Stub { // dump eventLog } + /* package */ void denyClientAuthState(int contextHubId, String packageName, long nanoAppId) { + mClientManager.forEachClientOfHub(contextHubId, client -> { + if (client.getPackageName().equals(packageName)) { + client.updateNanoAppAuthState( + nanoAppId, false /* hasPermissions */, false /* gracePeriodExpired */, + true /* forceDenied */); + } + }); + } + private void dump(ProtoOutputStream proto) { mContextHubIdToInfoMap.values().forEach(hubInfo -> { long token = proto.start(ContextHubServiceProto.CONTEXT_HUB_INFO); diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubShellCommand.java b/services/core/java/com/android/server/location/contexthub/ContextHubShellCommand.java new file mode 100644 index 000000000000..5ec85e661b98 --- /dev/null +++ b/services/core/java/com/android/server/location/contexthub/ContextHubShellCommand.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.location.contexthub; + +import android.content.Context; +import android.os.ShellCommand; + +import java.io.PrintWriter; + +/** + * ShellCommands for ContextHubService. + * + * Use with {@code adb shell cmd contexthub ...}. + * + * @hide + */ +public class ContextHubShellCommand extends ShellCommand { + + // Internal service impl -- must perform security checks before touching. + private final ContextHubService mInternal; + + public ContextHubShellCommand(Context context, ContextHubService service) { + mInternal = service; + + context.enforceCallingOrSelfPermission( + android.Manifest.permission.ACCESS_CONTEXT_HUB, "ContextHubShellCommand"); + } + + @Override + public int onCommand(String cmd) { + if ("deny".equals(cmd)) { + return runDisableAuth(); + } + + return handleDefaultCommands(cmd); + } + + private int runDisableAuth() { + int contextHubId = Integer.decode(getNextArgRequired()); + String packageName = getNextArgRequired(); + long nanoAppId = Long.decode(getNextArgRequired()); + + mInternal.denyClientAuthState(contextHubId, packageName, nanoAppId); + return 0; + } + + @Override + public void onHelp() { + PrintWriter pw = getOutPrintWriter(); + pw.println("ContextHub commands:"); + pw.println(" help"); + pw.println(" Print this help text."); + pw.println(" deny [contextHubId] [packageName] [nanoAppId]"); + pw.println(" Immediately transitions the package's authentication state to denied so"); + pw.println(" can no longer communciate with the nanoapp."); + } +} |