From 91f5907dfdbd824348615f77cb679c03320cc102 Mon Sep 17 00:00:00 2001 From: chen0088 Date: Mon, 28 Apr 2025 17:56:00 +0800 Subject: [PATCH] add ACL check Signed-off-by: chen0088 --- bundle.json | 3 +- .../base/include/dcamera_capture_info_cmd.h | 4 +- .../base/src/dcamera_capture_info_cmd.cpp | 20 ++++-- services/cameraservice/sinkservice/BUILD.gn | 2 + .../dcamera_sink_controller.h | 3 + .../dcamera_sink_controller.cpp | 60 ++++++++++++++++ ..._sink_controller_channel_listener_test.cpp | 16 +++-- services/cameraservice/sourceservice/BUILD.gn | 5 +- .../dcamera_source_controller.h | 13 +++- .../dcamera_source_controller.cpp | 71 ++++++++++++++++++- .../common/distributedcameramgr/BUILD.gn | 1 + .../dcamera_source_controller_test.cpp | 4 +- .../dcamera_source_input_test.cpp | 7 +- 13 files changed, 189 insertions(+), 20 deletions(-) diff --git a/bundle.json b/bundle.json index f594c867..cd065692 100644 --- a/bundle.json +++ b/bundle.json @@ -54,7 +54,8 @@ "safwk", "drivers_interface_camera", "access_token", - "av_codec" + "av_codec", + "os_account" ] }, "build": { diff --git a/services/cameraservice/base/include/dcamera_capture_info_cmd.h b/services/cameraservice/base/include/dcamera_capture_info_cmd.h index 5e79e429..59579449 100644 --- a/services/cameraservice/base/include/dcamera_capture_info_cmd.h +++ b/services/cameraservice/base/include/dcamera_capture_info_cmd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * 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 @@ -42,6 +42,8 @@ public: std::string command_; std::vector> value_; int32_t sceneMode_; + int32_t userId_; + uint64_t tokenId_; public: int32_t Marshal(std::string& jsonStr); diff --git a/services/cameraservice/base/src/dcamera_capture_info_cmd.cpp b/services/cameraservice/base/src/dcamera_capture_info_cmd.cpp index 97206641..2744ceaf 100644 --- a/services/cameraservice/base/src/dcamera_capture_info_cmd.cpp +++ b/services/cameraservice/base/src/dcamera_capture_info_cmd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * 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 @@ -24,9 +24,7 @@ namespace DistributedHardware { int32_t DCameraCaptureInfoCmd::Marshal(std::string& jsonStr) { cJSON *rootValue = cJSON_CreateObject(); - if (rootValue == nullptr) { - return DCAMERA_BAD_VALUE; - } + CHECK_NULL_RETURN((rootValue == nullptr), DCAMERA_BAD_VALUE); cJSON_AddStringToObject(rootValue, "Type", type_.c_str()); cJSON_AddStringToObject(rootValue, "dhId", dhId_.c_str()); cJSON_AddStringToObject(rootValue, "Command", command_.c_str()); @@ -63,6 +61,8 @@ int32_t DCameraCaptureInfoCmd::Marshal(std::string& jsonStr) } } cJSON_AddNumberToObject(rootValue, "mode", sceneMode_); + cJSON_AddNumberToObject(rootValue, "userId", userId_); + cJSON_AddNumberToObject(rootValue, "tokenId", tokenId_); char *data = cJSON_Print(rootValue); if (data == nullptr) { @@ -110,6 +110,18 @@ int32_t DCameraCaptureInfoCmd::Unmarshal(const std::string& jsonStr) } else { sceneMode_ = mode->valueint; } + cJSON *userId = cJSON_GetObjectItemCaseSensitive(rootValue, "userId"); + if (userId == nullptr || !cJSON_IsNumber(userId)) { + userId_ = -1; + } else { + userId_ = userId->valueint; + } + cJSON *tokenId = cJSON_GetObjectItemCaseSensitive(rootValue, "tokenId"); + if (tokenId == nullptr || !cJSON_IsNumber(tokenId)) { + tokenId_ = 0; + } else { + tokenId_ = tokenId->valueint; + } cJSON_Delete(rootValue); return ret; } diff --git a/services/cameraservice/sinkservice/BUILD.gn b/services/cameraservice/sinkservice/BUILD.gn index fd93d2d8..c696bb9e 100644 --- a/services/cameraservice/sinkservice/BUILD.gn +++ b/services/cameraservice/sinkservice/BUILD.gn @@ -124,6 +124,8 @@ ohos_shared_library("distributed_camera_sink") { "hdf_core:libhdf_utils", "hilog:libhilog", "ipc:ipc_core", + "os_account:libaccountkits", + "os_account:os_account_innerkits", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_controller.h b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_controller.h index 3660d51e..01cb498d 100644 --- a/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_controller.h +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_controller.h @@ -85,6 +85,7 @@ private: void ProcessPostAuthorization(const AppExecFwk::InnerEvent::Pointer &event); int32_t CreateCtrlSession(); int32_t CheckSensitive(); + bool CheckAclRight(); bool isInit_; int32_t sessionState_; @@ -105,6 +106,8 @@ private: bool isSameAccount_ = false; bool isCheckSecLevel_ = false; int32_t sceneMode_ = 0; + int32_t userId_ = -1; + uint64_t tokenId_ = 0; const std::string SESSION_FLAG = "control"; const std::string SRC_TYPE = "camera"; diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp index 8462e787..a3ff92f8 100644 --- a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp @@ -42,6 +42,9 @@ #include "idistributed_camera_source.h" #include "ipc_skeleton.h" #include "dcamera_low_latency.h" +#include "ohos_account_kits.h" +#include "os_account_manager.h" +#include "ipc_skeleton.h" #include namespace OHOS { @@ -672,6 +675,12 @@ int32_t DCameraSinkController::HandleReceivedData(std::shared_ptr& d return ret; } sceneMode_ = captureInfoCmd.sceneMode_; + userId_ = captureInfoCmd.userId_; + tokenId_ = captureInfoCmd.tokenId_; + if (!CheckAclRight()) { + DHLOGE("ACL check failed."); + return DCAMERA_BAD_VALUE; + } return StartCapture(captureInfoCmd.value_, sceneMode_); } else if ((!command.empty()) && (command.compare(DCAMERA_PROTOCOL_CMD_UPDATE_METADATA) == 0)) { DCameraMetadataSettingCmd metadataSettingCmd; @@ -688,6 +697,57 @@ int32_t DCameraSinkController::HandleReceivedData(std::shared_ptr& d return DCAMERA_BAD_VALUE; } +bool DCameraSinkController::CheckAclRight() +{ + if (userId_ == -1) { + return true; + } + std::string sinkDevId; + int32_t ret = GetLocalDeviceNetworkId(sinkDevId); + CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, false, "GetLocalDeviceNetworkId failed, ret: %{public}d", ret); + std::vector ids; + ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids); + if (ret != DCAMERA_OK) { + DHLOGE("Get userId from active os accountIds fail, ret: %{public}d", ret); + return false; + } + int32_t userId = -1; + if (ids.empty()) { + userId = 0; + } else { + userId = ids[0]; + } + + AccountSA::OhosAccountInfo osAccountInfo; + ret = AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfo(osAccountInfo); + if (ret != DCAMERA_OK) { + DHLOGE("Get accountId from ohos account info fail, ret: %{public}d", ret); + return false; + } + std::string accountId = osAccountInfo.uid_; + ret = DeviceManager::GetInstance().InitDeviceManager(DCAMERA_PKG_NAME, initCallback_); + if (ret != DCAMERA_OK) { + DHLOGE("InitDeviceManager failed ret = %{public}d", ret); + return false; + } + DmAccessCaller dmSrcCaller = { + .accountId = "", + .pkgName = DCAMERA_PKG_NAME, + .networkId = srcDevId_, + .userId = userId_, + .tokenId = tokenId_, + }; + DmAccessCallee dmDstCallee = { + .networkId = sinkDevId, + .accountId = accountId, + .userId = userId, + .tokenId = IPCSkeleton::GetCallingTokenID(), + }; + DHLOGI("CheckAclRight srcDevId: %{public}s, accountId: %{public}s, sinkDevId: %{public}s", + GetAnonyString(srcDevId_).c_str(), GetAnonyString(accountId).c_str(), GetAnonyString(sinkDevId).c_str()); + return DeviceManager::GetInstance().CheckAccessControl(dmSrcCaller, dmDstCallee); +} + int32_t DCameraSinkController::PauseDistributedHardware(const std::string &networkId) { DHLOGI("Pause distributed hardware dhId: %{public}s", GetAnonyString(dhId_).c_str()); diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_controller_channel_listener_test.cpp b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_controller_channel_listener_test.cpp index 22192d8b..846714ee 100644 --- a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_controller_channel_listener_test.cpp +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_controller_channel_listener_test.cpp @@ -71,7 +71,8 @@ HWTEST_F(DCameraSinkControllerChannelListenerTest, dcamera_sink_controller_chann ASSERT_NE(channelListener_, nullptr); int32_t state = 1; std::string networkId = "networkId"; - EXPECT_NO_FATAL_FAILURE(channelListener_->OnSessionState(state, networkId)); + channelListener_->OnSessionState(state, networkId); + EXPECT_EQ(true, state == 0); } /** @@ -87,7 +88,8 @@ HWTEST_F(DCameraSinkControllerChannelListenerTest, dcamera_sink_controller_chann int32_t eventType = 0; int32_t eventReason = 1; std::string detail = "detail"; - EXPECT_NO_FATAL_FAILURE(channelListener_->OnSessionError(eventType, eventReason, detail)); + channelListener_->OnSessionError(eventType, eventReason, detail); + EXPECT_EQ(true, eventType == 0); } /** @@ -104,7 +106,8 @@ HWTEST_F(DCameraSinkControllerChannelListenerTest, dcamera_sink_controller_chann size_t capacity = 0; std::shared_ptr dataBuffer = std::make_shared(capacity); buffers.push_back(dataBuffer); - EXPECT_NO_FATAL_FAILURE(channelListener_->OnDataReceived(buffers)); + channelListener_->OnDataReceived(buffers); + EXPECT_EQ(true, capacity == 0); } /** @@ -120,16 +123,17 @@ HWTEST_F(DCameraSinkControllerChannelListenerTest, dcamera_sink_controller_chann auto channelListener = std::make_shared(contl); int32_t state = 1; std::string networkId = "networkId"; - EXPECT_NO_FATAL_FAILURE(channelListener->OnSessionState(state, networkId)); + channelListener->OnSessionState(state, networkId); int32_t eventType = 0; int32_t eventReason = 1; std::string detail = "detail"; - EXPECT_NO_FATAL_FAILURE(channelListener->OnSessionError(eventType, eventReason, detail)); + channelListener->OnSessionError(eventType, eventReason, detail); std::vector> buffers; size_t capacity = 0; std::shared_ptr dataBuffer = std::make_shared(capacity); buffers.push_back(dataBuffer); - EXPECT_NO_FATAL_FAILURE(channelListener->OnDataReceived(buffers)); + channelListener->OnDataReceived(buffers); + EXPECT_EQ(true, capacity == 0); } } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sourceservice/BUILD.gn b/services/cameraservice/sourceservice/BUILD.gn index 4b6bc930..183940b4 100644 --- a/services/cameraservice/sourceservice/BUILD.gn +++ b/services/cameraservice/sourceservice/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2024 Huawei Device Co., Ltd. +# Copyright (c) 2021-2025 Huawei Device Co., Ltd. # 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 @@ -130,6 +130,7 @@ ohos_shared_library("distributed_camera_source") { "cJSON:cjson", "c_utils:utils", "camera_framework:camera_framework", + "device_manager:devicemanagersdk", "distributed_hardware_fwk:distributed_av_receiver", "distributed_hardware_fwk:distributedhardwareutils", "distributed_hardware_fwk:libdhfwk_sdk", @@ -147,6 +148,8 @@ ohos_shared_library("distributed_camera_source") { "hitrace:hitrace_meter", "ipc:ipc_core", "media_foundation:media_foundation", + "os_account:libaccountkits", + "os_account:os_account_innerkits", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller.h index e5c4aca0..9c8ea9c1 100644 --- a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller.h +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * 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 @@ -24,6 +24,7 @@ #include "dcamera_source_state_machine.h" #include "icamera_channel.h" #include "iremote_object.h" +#include "device_manager.h" #include "v1_1/id_camera_provider.h" @@ -58,6 +59,8 @@ private: void PostChannelDisconnectedEvent(); int32_t PublishEnableLatencyMsg(const std::string& devId); void HandleReceivedData(std::shared_ptr &dataBuffer); + bool CheckAclRight(); + bool GetOsAccountInfo(); class DCameraHdiRecipient : public IRemoteObject::DeathRecipient { public: void OnRemoteDied(const wptr &remote) override; @@ -84,6 +87,14 @@ private: std::atomic isChannelConnected_ = false; std::mutex channelMtx_; std::condition_variable channelCond_; + std::string accountId_ = ""; + int32_t userId_ = -1; + std::string srcDevId_ = ""; + uint64_t tokenId_ = 0; +}; + +class DeviceInitCallback : public DmInitCallback { + void OnRemoteDied() override; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp index 03a47786..3752721a 100644 --- a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * 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 @@ -38,6 +38,9 @@ #include "distributed_hardware_log.h" #include "idistributed_camera_sink.h" #include "dcamera_low_latency.h" +#include "ohos_account_kits.h" +#include "os_account_manager.h" +#include "ipc_skeleton.h" namespace OHOS { namespace DistributedHardware { @@ -80,6 +83,8 @@ int32_t DCameraSourceController::StartCapture(std::vector& o std::string devId = indexs_.begin()->devId_; DHLOGI("DCameraSourceController OpenChannel Start, devId: %{public}s, dhId: %{public}s", GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + srcDevId_ = openInfo->sourceDevId_; + if (!CheckAclRight()) { + DHLOGE("ACL check failed."); + return DCAMERA_BAD_OPERATE; + } if (!ManageSelectChannel::GetInstance().GetSrcConnect()) { sptr camSinkSrv = DCameraSourceServiceIpc::GetInstance().GetSinkRemoteCamSrv(devId); if (camSinkSrv == nullptr) { @@ -367,6 +377,60 @@ int32_t DCameraSourceController::OpenChannel(std::shared_ptr& o return PublishEnableLatencyMsg(devId); } +bool DCameraSourceController::CheckAclRight() +{ + if (!GetOsAccountInfo()) { + return false; + } + std::shared_ptr initCallback = std::make_shared(); + int32_t ret = DeviceManager::GetInstance().InitDeviceManager(DCAMERA_PKG_NAME, initCallback); + if (ret != DCAMERA_OK) { + DHLOGE("InitDeviceManager failed ret = %{public}d", ret); + return false; + } + tokenId_ = IPCSkeleton::GetCallingTokenID(); + DmAccessCaller dmSrcCaller = { + .accountId = accountId_, + .pkgName = DCAMERA_PKG_NAME, + .networkId = srcDevId_, + .userId = userId_, + .tokenId = tokenId_, + }; + DmAccessCallee dmDstCallee = { + .networkId = devId_, + }; + DHLOGI("CheckAclRight dmSrcCaller networkId: %{public}s, accountId: %{public}s, devId: %{public}s", + GetAnonyString(srcDevId_).c_str(), GetAnonyString(accountId_).c_str(), GetAnonyString(devId_).c_str()); + if (DeviceManager::GetInstance().CheckAccessControl(dmSrcCaller, dmDstCallee)) { + return true; + } + return false; +} + +bool DCameraSourceController::GetOsAccountInfo() +{ + std::vector ids; + int32_t ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids); + if (ret != DCAMERA_OK) { + DHLOGE("Get userId from active os accountIds fail, ret: %{public}d", ret); + return false; + } + if (ids.empty()) { + userId_ = 0; + } else { + userId_ = ids[0]; + } + + AccountSA::OhosAccountInfo osAccountInfo; + ret = AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfo(osAccountInfo); + if (ret != DCAMERA_OK) { + DHLOGE("Get accountId from ohos account info fail, ret: %{public}d", ret); + return false; + } + accountId_ = osAccountInfo.uid_; + return true; +} + int32_t DCameraSourceController::CloseChannel() { if (indexs_.empty() || indexs_.size() > DCAMERA_MAX_NUM) { @@ -593,5 +657,10 @@ void DCameraSourceController::DCameraHdiRecipient::OnRemoteDied(const wptr openInfo = std::make_shared(); int32_t ret = GetLocalDeviceNetworkId(openInfo->sourceDevId_); ret = controller_->OpenChannel(openInfo); - controller_->UnInit(); + ret = controller_->UnInit(); ManageSelectChannel::GetInstance().SetSrcConnect(saved); EXPECT_EQ(ret, DCAMERA_OK); } diff --git a/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_input_test.cpp b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_input_test.cpp index 7e365058..f5b4c3b2 100644 --- a/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_input_test.cpp +++ b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_input_test.cpp @@ -449,16 +449,17 @@ HWTEST_F(DCameraSourceInputTest, dcamera_source_input_test_016, TestSize.Level1) std::make_shared(testInput_, DCStreamType::CONTINUOUS_FRAME); int32_t state = 0; std::string networkId = "networkId"; - EXPECT_NO_FATAL_FAILURE(testInputListener->OnSessionState(state, networkId)); + testInputListener->OnSessionState(state, networkId); int32_t eventType = 0; int32_t eventReason = 1; std::string detail = "detail"; - EXPECT_NO_FATAL_FAILURE(testInputListener->OnSessionError(eventType, eventReason, detail)); + testInputListener->OnSessionError(eventType, eventReason, detail); std::vector> buffers; size_t capacity = 0; std::shared_ptr dataBuffer = std::make_shared(capacity); buffers.push_back(dataBuffer); - EXPECT_NO_FATAL_FAILURE(testInputListener->OnDataReceived(buffers)); + testInputListener->OnDataReceived(buffers); + EXPECT_EQ(true, capacity == 0); } } // namespace DistributedHardware } // namespace OHOS -- Gitee