diff --git a/interfaces/innerkits/accesstoken/include/access_token.h b/interfaces/innerkits/accesstoken/include/access_token.h index b5f3e732b9aeae3dae792da3c2bb510f0d3a88bc..adfe189752dbabb75803994e01da243701b64164 100644 --- a/interfaces/innerkits/accesstoken/include/access_token.h +++ b/interfaces/innerkits/accesstoken/include/access_token.h @@ -89,6 +89,13 @@ typedef enum DlpType { DLP_READ = 1, DLP_FULL_CONTROL = 2, } HapDlpType; + +typedef enum TypeDlpPerm { + DLP_PERM_ALL = 0, + DLP_PERM_FULL_CONTROL = 1, + DLP_PERM_NONE = 2, +} DlpPermMode; + } // namespace AccessToken } // namespace Security } // namespace OHOS 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 0000000000000000000000000000000000000000..35933cf0a0321648efe1f7afc76441fe76f62200 --- /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 76c93af482436903b67843e88c29c973a6e942fe..197cfe5a8cbd2ae028cc2a8d370cd5d762f6bf8c 100644 --- a/services/accesstokenmanager/BUILD.gn +++ b/services/accesstokenmanager/BUILD.gn @@ -47,6 +47,8 @@ ohos_shared_library("accesstoken_manager_service") { "main/cpp/src/database/data_storage.cpp", "main/cpp/src/database/data_translator.cpp", "main/cpp/src/database/sqlite_storage.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 0000000000000000000000000000000000000000..ed931a3258ea23569abc9956b7ebbc6bde34abbf --- /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 0000000000000000000000000000000000000000..f1785782e1c6e73058971448fed5bfc8397b4308 --- /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 0000000000000000000000000000000000000000..c800e67d31db589b4522432482e32f03ed53ed28 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/permission/dlp_permission_set_manager.cpp @@ -0,0 +1,98 @@ +/* + * 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) +{ + /* permission is available to all dlp hap */ + if (dlpMode == DLP_PERM_ALL) { + return false; + } + + /* permission is available to full control */ + if (dlpMode == DLP_PERM_FULL_CONTROL && dlpType == DLP_FULL_CONTROL) { + return false; + } + /* permission is available to none */ + return true; +} +} // 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 0000000000000000000000000000000000000000..7eae1d7944538427e7b845fa7eb9c48a332e3c58 --- /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/permission/permission_manager.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp index 04c3947f1795db9b976c4dbf450646c6c5e45ebc..784ea41d380f74712330148772997cbddc12ca3b 100644 --- a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp @@ -319,7 +319,15 @@ void PermissionManager::UpdateTokenPermissionState( ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); return; } - + if (isGranted && infoPtr->tokenInfoBasic_.dlpType != DLP_COMMON) { + int32_t res = DlpPermissionSetManager::GetInstance().UpdatePermStateWithDlpInfo( + infoPtr->tokenInfoBasic_.dlpType, permPolicySet->permStateList_); + if (res != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s update dlp permission failed", + infoPtr->tokenInfoBasic_.bundleName.c_str()); + return; + } + } permPolicySet->UpdatePermissionStatus(permissionName, isGranted, flag); #ifdef TOKEN_SYNC_ENABLE TokenModifyNotifier::GetInstance().NotifyTokenModify(tokenID); 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 24fcdf6aa432a995b1566958777beea992da9a82..a4bbd20bd4af22d43f63f48691a3c6729c2d4872 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp @@ -25,6 +25,7 @@ #include "atm_device_state_callback.h" #include "device_manager.h" #endif +#include "dlp_permission_set_parser.h" #include "hap_token_info.h" #include "hap_token_info_inner.h" #include "ipc_skeleton.h" @@ -437,6 +438,7 @@ bool AccessTokenManagerService::Initialize() #ifdef TOKEN_SYNC_ENABLE CreateDeviceListenner(); // for start tokensync when remote devivce online #endif + 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 e8f8a03668cb866e10dac9c08fbd32e081b4c5e1..33479a25b301bcf94f8a246a032dc51ca70af2ac 100644 --- a/services/accesstokenmanager/main/cpp/src/token/accesstoken_info_manager.cpp +++ b/services/accesstokenmanager/main/cpp/src/token/accesstoken_info_manager.cpp @@ -22,6 +22,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,17 @@ int AccessTokenInfoManager::CreateHapTokenInfo( return RET_FAILED; } + std::shared_ptr policySet = tokenInfo->GetHapInfoPermissionPolicySet(); + if (info.dlpType != DLP_COMMON) { + int32_t res = DlpPermissionSetManager::GetInstance().UpdatePermStateWithDlpInfo( + info.dlpType, policySet->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 8c7d5f9b371c4a98746b43209c9fed2da6f71a5e..dac042d2c05e0c9071071bbc0f8780112202e2ee 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; }