From 40fa62bfd0bd0e627adabbcf0e7eac67b019844b Mon Sep 17 00:00:00 2001 From: lsq Date: Sat, 14 May 2022 15:45:02 +0800 Subject: [PATCH] =?UTF-8?q?dlp=E6=9D=83=E9=99=90=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E5=8F=8A=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lsq Change-Id: Ia99e3afd66ce8d6079ee31e805afa4cce5e20a97 --- .../accesstoken/include/permission_dlp_mode.h | 33 ++++ services/accesstokenmanager/BUILD.gn | 2 + .../permission/dlp_permission_set_manager.h | 52 +++++++ .../permission/dlp_permission_set_parser.h | 53 +++++++ .../permission/dlp_permission_set_manager.cpp | 100 ++++++++++++ .../permission/dlp_permission_set_parser.cpp | 144 ++++++++++++++++++ .../service/accesstoken_manager_service.cpp | 2 + .../src/token/accesstoken_info_manager.cpp | 14 ++ .../cpp/src/token/native_token_receptor.cpp | 5 + 9 files changed, 405 insertions(+) create mode 100644 interfaces/innerkits/accesstoken/include/permission_dlp_mode.h create mode 100644 services/accesstokenmanager/main/cpp/include/permission/dlp_permission_set_manager.h create mode 100644 services/accesstokenmanager/main/cpp/include/permission/dlp_permission_set_parser.h create mode 100644 services/accesstokenmanager/main/cpp/src/permission/dlp_permission_set_manager.cpp create mode 100644 services/accesstokenmanager/main/cpp/src/permission/dlp_permission_set_parser.cpp diff --git a/interfaces/innerkits/accesstoken/include/permission_dlp_mode.h b/interfaces/innerkits/accesstoken/include/permission_dlp_mode.h new file mode 100644 index 000000000..35933cf0a --- /dev/null +++ b/interfaces/innerkits/accesstoken/include/permission_dlp_mode.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021-2022 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 + * + * 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. + */ + +#ifndef INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_DLP_MODE_H +#define INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_DLP_MODE_H + +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +class PermissionDlpMode final { +public: + std::string permissionName; + int32_t dlpMode; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_DLP_MODE_H diff --git a/services/accesstokenmanager/BUILD.gn b/services/accesstokenmanager/BUILD.gn index 8d620f191..036adb972 100644 --- a/services/accesstokenmanager/BUILD.gn +++ b/services/accesstokenmanager/BUILD.gn @@ -44,6 +44,8 @@ ohos_shared_library("accesstoken_manager_service") { "main/cpp/src/database/sqlite_storage.cpp", "main/cpp/src/database/statement.cpp", "main/cpp/src/database/variant_value.cpp", + "main/cpp/src/permission/dlp_permission_set_manager.cpp", + "main/cpp/src/permission/dlp_permission_set_parser.cpp", "main/cpp/src/permission/permission_definition_cache.cpp", "main/cpp/src/permission/permission_manager.cpp", "main/cpp/src/permission/permission_policy_set.cpp", diff --git a/services/accesstokenmanager/main/cpp/include/permission/dlp_permission_set_manager.h b/services/accesstokenmanager/main/cpp/include/permission/dlp_permission_set_manager.h new file mode 100644 index 000000000..ed931a325 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/permission/dlp_permission_set_manager.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021-2022 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 + * + * 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. + */ + +#ifndef ACCESSTOKEN_DLP_PERMISSION_SET_MANAGER_H +#define ACCESSTOKEN_DLP_PERMISSION_SET_MANAGER_H + +#include +#include + +#include "permission_dlp_mode.h" +#include "permission_state_full.h" + +#include "nocopyable.h" +namespace OHOS { +namespace Security { +namespace AccessToken { +class DlpPermissionSetManager final { +public: + static DlpPermissionSetManager& GetInstance(); + virtual ~DlpPermissionSetManager(); + + int32_t UpdatePermStateWithDlpInfo(int32_t dlpType, std::vector& permStateList); + bool IsPermStateNeedUpdate(int32_t dlpType, int32_t dlpMode); + void ProcessDlpPermInfos(const std::vector& info); + +private: + DlpPermissionSetManager(); + DISALLOW_COPY_AND_MOVE(DlpPermissionSetManager); + void ProcessDlpPermsInfos(std::vector& dlpPerms); + + /** + * key: the permission name. + * value: the mode of permission. + */ + std::map dlpPermissionModeMap_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_DLP_PERMISSION_SET_MANAGER_H diff --git a/services/accesstokenmanager/main/cpp/include/permission/dlp_permission_set_parser.h b/services/accesstokenmanager/main/cpp/include/permission/dlp_permission_set_parser.h new file mode 100644 index 000000000..f1785782e --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/permission/dlp_permission_set_parser.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021-2022 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 + * + * 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. + */ + +#ifndef ACCESSTOKEN_DLP_PERMISSION_SET_PARSER_H +#define ACCESSTOKEN_DLP_PERMISSION_SET_PARSER_H + +#include +#include + +#include "permission_dlp_mode.h" +#include "nlohmann/json.hpp" +#include "nocopyable.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +const std::string CLONE_PERMISSION_CONFIG_FILE = "/data/service/el0/access_token/clonePermission.json"; +constexpr int MAX_CLONE_PERMISSION_CONFIG_FILE_SIZE = 5 * 1024 * 1024; // 5M +constexpr size_t MAX_BUFFER_SIZE = 1024; +class DlpPermissionSetParser final { +public: + static DlpPermissionSetParser& GetInstance(); + virtual ~DlpPermissionSetParser() = default; + int Init(); + +private: + DlpPermissionSetParser() : ready_(false) {} + DISALLOW_COPY_AND_MOVE(DlpPermissionSetParser); + int ReadCfgFile(std::string &dlpPermsRawData); + void FromJson(const nlohmann::json &jsonObject, std::vector& dlpPerms); + int32_t ParserDlpPermsRawData(const std::string& dlpPermsRawData, + std::vector& dlpPerms); + void from_json(const nlohmann::json& j, PermissionDlpMode& p); + void ProcessDlpPermsInfos(std::vector& dlpPerms); + + bool ready_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_DLP_PERMISSION_SET_PARSER_H diff --git a/services/accesstokenmanager/main/cpp/src/permission/dlp_permission_set_manager.cpp b/services/accesstokenmanager/main/cpp/src/permission/dlp_permission_set_manager.cpp new file mode 100644 index 000000000..b9ec7b12b --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/permission/dlp_permission_set_manager.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021-2022 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 + * + * 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. + */ +#include +#include +#include +#include +#include + +#include "access_token.h" +#include "accesstoken_log.h" +#include "data_validator.h" +#include "dlp_permission_set_manager.h" +#include "securec.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "DlpPermissionSetManager"}; +} + +DlpPermissionSetManager& DlpPermissionSetManager::GetInstance() +{ + static DlpPermissionSetManager instance; + return instance; +} + +DlpPermissionSetManager::DlpPermissionSetManager() +{} + +DlpPermissionSetManager::~DlpPermissionSetManager() +{} + +void DlpPermissionSetManager::ProcessDlpPermInfos(const std::vector& dlpPermInfos) +{ + for (auto iter = dlpPermInfos.begin(); iter != dlpPermInfos.end(); iter++) { + auto it = dlpPermissionModeMap_.find(iter->permissionName); + if (it != dlpPermissionModeMap_.end()) { + ACCESSTOKEN_LOG_WARN(LABEL, "info for permission: %{public}s has been insert, please check!", + iter->permissionName.c_str()); + continue; + } + dlpPermissionModeMap_[iter->permissionName] = iter->dlpMode; + continue; + } +} + +int32_t DlpPermissionSetManager::UpdatePermStateWithDlpInfo(int32_t dlpType, + std::vector& permStateList) +{ + for (auto iter = permStateList.begin(); iter != permStateList.end(); iter++) { + if (iter->grantStatus[0] == PERMISSION_DENIED) { + continue; // 如果是未授权,则保持未授权 + } + auto it = dlpPermissionModeMap_.find(iter->permissionName); + if (it == dlpPermissionModeMap_.end()) { + ACCESSTOKEN_LOG_INFO(LABEL, "permission: %{public}s is not in dlp set!", + iter->permissionName.c_str()); + continue; // 如果没找到该权限的配置,则保持原授权状态 + } + int32_t dlpMode = dlpPermissionModeMap_[iter->permissionName]; + bool res = IsPermStateNeedUpdate(dlpType, dlpMode); + if (res) { + iter->grantStatus[0] = PERMISSION_DENIED; + } + } + return RET_SUCCESS; +} + +bool DlpPermissionSetManager::IsPermStateNeedUpdate(int32_t dlpType, int32_t dlpMode) +{ + if (dlpType == DLP_READ) { + if (dlpMode == DLP_READ) { + return false; + } + return true; + } + if (dlpType == DLP_FULL_CONTROL) { + if (dlpMode == DLP_FULL_CONTROL) { + return false; + } + return true; + } + return false; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/permission/dlp_permission_set_parser.cpp b/services/accesstokenmanager/main/cpp/src/permission/dlp_permission_set_parser.cpp new file mode 100644 index 000000000..7eae1d794 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/permission/dlp_permission_set_parser.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021-2022 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 + * + * 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. + */ +#include +#include +#include +#include +#include + +//#include "accesstoken_id_manager.h" +//#include "accesstoken_info_manager.h" +#include "accesstoken_log.h" +#include "data_validator.h" +#include "dlp_permission_set_manager.h" +#include "dlp_permission_set_parser.h" +#include "securec.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "DlpPermissionSetParser"}; +} + +// nlohmann json need the function named from_json to parse +void from_json(const nlohmann::json& j, PermissionDlpMode& p) +{ + if (j.find("permissionName") == j.end()) { + return; + } + p.permissionName = j.at("permissionName").get(); + if (!DataValidator::IsProcessNameValid(p.permissionName)) { + return; + } + + if (j.find("dlpMode") == j.end()) { + return; + } + p.dlpMode = j.at("dlpMode").get(); + //if (!DataValidator::IsDlpModeValid(p.dlpMode)) { + // return; + //} + +} + +int32_t DlpPermissionSetParser::ParserDlpPermsRawData(const std::string& dlpPermsRawData, + std::vector& dlpPerms) +{ + nlohmann::json jsonRes = nlohmann::json::parse(dlpPermsRawData, nullptr, false); + if (jsonRes.is_discarded()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "jsonRes is invalid."); + return RET_FAILED; + } + // std::vector dlpPermParsed; is it OK ? + dlpPerms = jsonRes.get>(); + + return RET_SUCCESS; +} + +int DlpPermissionSetParser::ReadCfgFile(std::string& dlpPermsRawData) +{ + int32_t fd = open(CLONE_PERMISSION_CONFIG_FILE.c_str(), O_RDONLY); + if (fd < 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "open failed errno %{public}d.", errno); + return RET_FAILED; + } + struct stat statBuffer; + + if (fstat(fd, &statBuffer) != 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fstat failed."); + close(fd); + return RET_FAILED; + } + + if (statBuffer.st_size == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "config file size is invalid."); + close(fd); + return RET_FAILED; + } + if (statBuffer.st_size > MAX_CLONE_PERMISSION_CONFIG_FILE_SIZE) { + ACCESSTOKEN_LOG_ERROR(LABEL, "config file size is too large."); + close(fd); + return RET_FAILED; + } + dlpPermsRawData.reserve(statBuffer.st_size); + + char buff[MAX_BUFFER_SIZE] = { 0 }; + ssize_t readLen = 0; + while ((readLen = read(fd, buff, MAX_BUFFER_SIZE)) > 0) { + dlpPermsRawData.append(buff, readLen); + } + close(fd); + + if (readLen == 0) { + return RET_SUCCESS; + } + return RET_FAILED; +} + +int DlpPermissionSetParser::Init() +{ + if (ready_) { + ACCESSTOKEN_LOG_ERROR(LABEL, "dlp permission has been set."); + return RET_SUCCESS; + } + + std::string dlpPermsRawData; + int ret = ReadCfgFile(dlpPermsRawData); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "readCfgFile failed."); + return RET_FAILED; + } + std::vector dlpPerms; + ret = ParserDlpPermsRawData(dlpPermsRawData, dlpPerms); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "ParserDlpPermsRawData failed."); + return RET_FAILED; + } + DlpPermissionSetManager::GetInstance().ProcessDlpPermInfos(dlpPerms); + + ready_ = true; + ACCESSTOKEN_LOG_INFO(LABEL, "init ok."); + return RET_SUCCESS; +} + +DlpPermissionSetParser& DlpPermissionSetParser::GetInstance() +{ + static DlpPermissionSetParser instance; + return instance; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp index b1ebfed38..adc9aae5c 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp @@ -19,6 +19,7 @@ #include "accesstoken_id_manager.h" #include "accesstoken_info_manager.h" #include "accesstoken_log.h" +#include "dlp_permission_set_parser.h" #include "hap_token_info.h" #include "hap_token_info_inner.h" #include "ipc_skeleton.h" @@ -357,6 +358,7 @@ bool AccessTokenManagerService::Initialize() const { AccessTokenInfoManager::GetInstance().Init(); NativeTokenReceptor::GetInstance().Init(); + DlpPermissionSetParser::GetInstance().Init(); return true; } } // namespace AccessToken diff --git a/services/accesstokenmanager/main/cpp/src/token/accesstoken_info_manager.cpp b/services/accesstokenmanager/main/cpp/src/token/accesstoken_info_manager.cpp index 18a62e12c..785b10899 100644 --- a/services/accesstokenmanager/main/cpp/src/token/accesstoken_info_manager.cpp +++ b/services/accesstokenmanager/main/cpp/src/token/accesstoken_info_manager.cpp @@ -21,6 +21,7 @@ #include "data_storage.h" #include "data_translator.h" #include "data_validator.h" +#include "dlp_permission_set_manager.h" #include "field_const.h" #include "generic_values.h" #include "hap_token_info_inner.h" @@ -393,6 +394,19 @@ int AccessTokenInfoManager::CreateHapTokenInfo( return RET_FAILED; } + std::shared_ptr policySet = tokenInfo->GetHapInfoPermissionPolicySet(); + std::vector permStateList; + policySet->GetPermissionStateFulls(permStateList); + if (info.dlpType != DLP_COMMON) { + int32_t res = DlpPermissionSetManager::GetInstance().UpdatePermStateWithDlpInfo( + info.dlpType, permStateList); + if (res != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s update dlp permission failed", info.bundleName.c_str()); + AccessTokenIDManager::GetInstance().ReleaseTokenId(tokenId); + return RET_FAILED; + } + } + int ret = AddHapTokenInfo(tokenInfo); if (ret != RET_SUCCESS) { ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s add token info failed", info.bundleName.c_str()); diff --git a/services/accesstokenmanager/main/cpp/src/token/native_token_receptor.cpp b/services/accesstokenmanager/main/cpp/src/token/native_token_receptor.cpp index 8c7d5f9b3..dac042d2c 100644 --- a/services/accesstokenmanager/main/cpp/src/token/native_token_receptor.cpp +++ b/services/accesstokenmanager/main/cpp/src/token/native_token_receptor.cpp @@ -43,14 +43,19 @@ int32_t NativeReqPermsGet( if (permReqList.size() > MAX_REQ_PERM_NUM) { return RET_FAILED; } + std::set permRes; for (auto permReq : permReqList) { PermissionStateFull permState; + if (permRes.count(permReq) != 0) { + continue; + } permState.permissionName = permReq; permState.isGeneral = true; permState.resDeviceID.push_back(""); permState.grantStatus.push_back(PERMISSION_GRANTED); permState.grantFlags.push_back(PERMISSION_SYSTEM_FIXED); permStateList.push_back(permState); + permRes.insert(permReq); } return RET_SUCCESS; } -- Gitee