From f283f488eca76c3c702c623ba96cbaf8b82e46d5 Mon Sep 17 00:00:00 2001 From: chennian Date: Mon, 13 Apr 2026 17:33:53 +0800 Subject: [PATCH] add whitelist of userpolicy Co-Authored-By: Agent Signed-off-by: chennian Change-Id: I3bd50c060cafd67920e40f554529bc387b04b28b --- CODEOWNERS | 4 +- .../accesstoken_service_ipc_interface_code.h | 85 - frameworks/common/include/data_validator.h | 1 + frameworks/common/src/data_validator.cpp | 9 + .../ets/@ohos.abilityAccessCtrl.ets | 28 +- .../src/ani_ability_access_ctrl.cpp | 4 +- frameworks/ets/ani/common/include/ani_utils.h | 2 + frameworks/ets/ani/common/src/ani_utils.cpp | 44 + .../accesstoken/include/access_token.h | 8 + .../accesstoken/include/access_token_error.h | 5 +- .../accesstoken/include/accesstoken_kit.h | 41 +- .../accesstoken/libaccesstoken_sdk.map | 2 + .../accesstoken/src/accesstoken_kit.cpp | 1917 +++++++++-------- .../src/accesstoken_manager_client.cpp | 31 + .../src/accesstoken_manager_client.h | 2 + .../innerkits/accesstoken/test/tool/BUILD.gn | 40 +- .../test/tool/create_hap_token.cpp | 122 +- .../test/tool/query_permission_status.cpp | 7 +- .../accesstoken/test/tool/test_common.cpp | 85 +- .../accesstoken/test/tool/test_common.h | 6 +- .../test/tool/update_hap_token.cpp | 150 ++ .../EdmPolicyTest/edm_policy_set_test.cpp | 559 ++++- .../PermDenyTest/accesstoken_deny_test.cpp | 42 +- .../ProxyMockTest/accesstoken_mock_test.cpp | 25 + .../idl/IAccessTokenManager.idl | 8 +- .../permission/accesstoken_info_manager.h | 9 +- .../service/accesstoken_manager_service.h | 2 + .../permission/accesstoken_info_manager.cpp | 106 +- .../service/accesstoken_manager_service.cpp | 64 +- .../permission/token_info_manager_test.cpp | 129 ++ .../accesstoken_manager_service_test.cpp | 56 + 31 files changed, 2453 insertions(+), 1140 deletions(-) delete mode 100644 frameworks/accesstoken/include/accesstoken_service_ipc_interface_code.h create mode 100644 interfaces/innerkits/accesstoken/test/tool/update_hap_token.cpp diff --git a/CODEOWNERS b/CODEOWNERS index f3ec2904f..277b9378a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2026 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 @@ -14,11 +14,9 @@ */ # any change to behind files needs to be reviewed by @leonchan5 -frameworks/accesstoken/include/accesstoken_service_ipc_interface_code.h @leonchan5 frameworks/accesstoken/include/tokensync_callback_ipc_interface_code.h @leonchan5 frameworks/privacy/include/privacy_active_change_ipc_interface_code.h @leonchan5 frameworks/privacy/include/privacy_am_service_ipc_interface_code.h @leonchan5 -frameworks/privacy/include/privacy_service_ipc_interface_code.h @leonchan5 frameworks/privacy/include/privacy_state_change_ipc_interface_code.h @leonchan5 frameworks/tokensync/include/token_sync_service_ipc_interface_code.h @leonchan5 interfaces/inner_api/privacy/include/privacy_permission_record_ipc_interface_code.h @leonchan5 diff --git a/frameworks/accesstoken/include/accesstoken_service_ipc_interface_code.h b/frameworks/accesstoken/include/accesstoken_service_ipc_interface_code.h deleted file mode 100644 index 1faa90993..000000000 --- a/frameworks/accesstoken/include/accesstoken_service_ipc_interface_code.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2023-2024 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_SERVICE_IPC_INTERFACE_CODE_H -#define ACCESSTOKEN_SERVICE_IPC_INTERFACE_CODE_H - -namespace OHOS { -namespace Security { -namespace AccessToken { -/* SAID:3503 */ -enum class AccessTokenInterfaceCode { - VERIFY_ACCESSTOKEN = 0x0000, - GET_DEF_PERMISSION, - GET_REQ_PERMISSIONS, - GET_PERMISSION_FLAG, - GRANT_PERMISSION, - REVOKE_PERMISSION, - CLEAR_USER_GRANT_PERMISSION, - ALLOC_TOKEN_HAP, - TOKEN_DELETE, - INIT_TOKEN_HAP, - SET_PERMISSION_REQUEST_TOGGLE_STATUS, - GET_PERMISSION_REQUEST_TOGGLE_STATUS, - GRANT_PERMISSION_FOR_SPECIFIEDTIME, - REQUEST_APP_PERM_ON_SETTING, - - GET_TOKEN_TYPE = 0x0010, - CHECK_NATIVE_DCAP, - GET_HAP_TOKEN_ID, - ALLOC_LOCAL_TOKEN_ID, - GET_NATIVE_TOKENINFO, - GET_HAP_TOKENINFO, - UPDATE_HAP_TOKEN, - GET_TOKEN_ID_BY_USER_ID, - - GET_HAP_TOKEN_FROM_REMOTE = 0x0020, - GET_ALL_NATIVE_TOKEN_FROM_REMOTE, - SET_REMOTE_HAP_TOKEN_INFO, - SET_REMOTE_NATIVE_TOKEN_INFO, - DELETE_REMOTE_TOKEN_INFO, - DELETE_REMOTE_DEVICE_TOKEN, - GET_NATIVE_REMOTE_TOKEN, - REGISTER_TOKEN_SYNC_CALLBACK, - UNREGISTER_TOKEN_SYNC_CALLBACK, - - DUMP_TOKENINFO = 0x0030, - GET_PERMISSION_OPER_STATE, - GET_PERMISSIONS_STATUS, - REGISTER_PERM_STATE_CHANGE_CALLBACK, - UNREGISTER_PERM_STATE_CHANGE_CALLBACK, - RELOAD_NATIVE_TOKEN_INFO, - GET_NATIVE_TOKEN_ID, - SET_PERM_DIALOG_CAPABILITY, - GET_USER_GRANTED_PERMISSION_USED_TYPE, - DUMP_PERM_DEFINITION_INFO, - GET_VERSION, - GET_PERMISSION_MANAGER_INFO, - INIT_USER_POLICY, - UPDATE_USER_POLICY, - CLEAR_USER_POLICY, - GET_HAP_TOKENINFO_EXT, - REGISTER_SELF_PERM_STATE_CHANGE_CALLBACK, - UNREGISTER_SELF_PERM_STATE_CHANGE_CALLBACK, - GET_KERNEL_PERMISSIONS, - GET_PERMISSION_BY_NAME, - - VERIFY_ACCESSTOKEN_WITH_LIST = 0x0050, -}; -} // namespace AccessToken -} // namespace Security -} // namespace OHOS - -#endif // ACCESSTOKEN_SERVICE_IPC_INTERFACE_CODE_H diff --git a/frameworks/common/include/data_validator.h b/frameworks/common/include/data_validator.h index af92dc7ce..05d52f095 100644 --- a/frameworks/common/include/data_validator.h +++ b/frameworks/common/include/data_validator.h @@ -59,6 +59,7 @@ public: static bool IsPermissionUsedFlagValid(uint32_t flag); static bool IsPermissionUsedTypeValid(uint32_t type); static bool IsEnhancedIdentityValid(const std::string& enhancedIdentity); + static bool IsUpdateWhiteListTypeValid(UpdateWhiteListType type); static bool IsRemotePermissionUsedFlagValid(uint32_t flag); static bool IsPolicyTypeValid(uint32_t type); static bool IsCallerTypeValid(uint32_t type); diff --git a/frameworks/common/src/data_validator.cpp b/frameworks/common/src/data_validator.cpp index 946f24570..bb77f0325 100644 --- a/frameworks/common/src/data_validator.cpp +++ b/frameworks/common/src/data_validator.cpp @@ -219,6 +219,15 @@ bool DataValidator::IsEnhancedIdentityValid(const std::string& enhancedIdentity) return true; } +bool DataValidator::IsUpdateWhiteListTypeValid(UpdateWhiteListType type) +{ + if ((type != ADD) && (type != DELETE)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Invalid type(%{public}d).", static_cast(type)); + return false; + } + return true; +} + bool DataValidator::IsRemotePermissionUsedFlagValid(uint32_t flag) { return ((flag == FLAG_PERMISSION_USAGE_SUMMARY) || (flag == FLAG_PERMISSION_USAGE_DETAIL)); diff --git a/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets b/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets index 2d466cf5b..8e963688c 100644 --- a/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets +++ b/frameworks/ets/ani/accesstoken/ets/@ohos.abilityAccessCtrl.ets @@ -69,13 +69,13 @@ export default namespace abilityAccessCtrl { permissionName: Permissions; } - interface PermissionStatusInfo { - tokenID: int; - permissionName: Permissions; - grantStatus: GrantStatus; - grantFlags: int; - grantTimestamp: long; - } + interface PermissionStatusInfo { + tokenID: int; + permissionName: Permissions; + grantStatus: GrantStatus; + grantFlags: int; + grantTimestamp?: long; + } export enum PermissionStateChangeType { PERMISSION_REVOKED_OPER = 0, @@ -101,13 +101,13 @@ export default namespace abilityAccessCtrl { tokenID: int; permissionName: Permissions; } - class PermissionStatusInfoInner implements PermissionStatusInfo { - tokenID: int; - permissionName: Permissions; - grantStatus: GrantStatus; - grantFlags: int; - grantTimestamp: long; - } + class PermissionStatusInfoInner implements PermissionStatusInfo { + tokenID: int; + permissionName: Permissions; + grantStatus: GrantStatus; + grantFlags: int; + grantTimestamp?: long; + } function validateRequestParams(context: Context, permissionList: Array): void { if ((typeof context === "undefined") || (context == null)) { let err = new BusinessError(); diff --git a/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp b/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp index 1c9e0bd78..54712110a 100644 --- a/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp +++ b/frameworks/ets/ani/accesstoken/src/ani_ability_access_ctrl.cpp @@ -1006,8 +1006,8 @@ static ani_ref CreatePermissionStatusInfoArray(ani_env* env, // Set grantFlags property SetIntProperty(env, aniObject, "grantFlags", static_cast(permStatus.grantFlag)); - // Set grantTimestamp property - SetLongProperty(env, aniObject, "grantTimestamp", static_cast(permStatus.timestamp)); + // Set optional grantTimestamp property + SetOptionalLongProperty(env, aniObject, "grantTimestamp", static_cast(permStatus.timestamp)); // Set array element ani_size index = static_cast(i); diff --git a/frameworks/ets/ani/common/include/ani_utils.h b/frameworks/ets/ani/common/include/ani_utils.h index e4e6f6698..d1f1091c9 100644 --- a/frameworks/ets/ani/common/include/ani_utils.h +++ b/frameworks/ets/ani/common/include/ani_utils.h @@ -54,6 +54,7 @@ bool SetEnumProperty( ani_env* env, ani_object& aniObject, const std::string& enumDescription, const std::string& property, uint32_t value); bool SetOptionalIntProperty(ani_env* env, ani_object& aniObject, const std::string& property, int32_t in); +bool SetOptionalLongProperty(ani_env* env, ani_object& aniObject, const std::string& property, int64_t in); bool IsCurrentThread(std::thread::id threadId); bool AniIsCallbackRefEqual(ani_env* env, const ani_ref& compareRef, const ani_ref& targetRref, std::thread::id threadId, @@ -67,6 +68,7 @@ std::vector ParseAniStringVector(ani_env* env, const ani_array& ani // native to ani ani_string CreateAniString(ani_env *env, const std::string& str); ani_object CreateIntObject(ani_env *env, int32_t value); +ani_object CreateLongObject(ani_env *env, int64_t value); ani_object CreateBooleanObject(ani_env *env, bool value); ani_object CreateClassObject(ani_env* env, const std::string& classDescriptor); ani_object CreateArrayObject(ani_env* env, uint32_t length); diff --git a/frameworks/ets/ani/common/src/ani_utils.cpp b/frameworks/ets/ani/common/src/ani_utils.cpp index 560b2f264..4f1ff7a23 100644 --- a/frameworks/ets/ani/common/src/ani_utils.cpp +++ b/frameworks/ets/ani/common/src/ani_utils.cpp @@ -483,6 +483,32 @@ ani_object CreateIntObject(ani_env* env, int32_t value) return aniObject; } +ani_object CreateLongObject(ani_env* env, int64_t value) +{ + if (env == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Env is null."); + return nullptr; + } + + ani_class longCls; + ani_status status = ANI_ERROR; + if ((status = env->FindClass("std.core.Long", &longCls)) != ANI_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to FindClass, status : %{public}u.", status); + return nullptr; + } + ani_method aniMethod; + if ((status = env->Class_FindMethod(longCls, "", "l:", &aniMethod)) != ANI_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to FindMethod, status : %{public}u.", status); + return nullptr; + } + ani_object aniObject; + if ((status = env->Object_New(longCls, aniMethod, &aniObject, value)) != ANI_OK) { + LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Object_New, status : %{public}u.", status); + return nullptr; + } + return aniObject; +} + ani_object CreateClassObject(ani_env* env, const std::string& classDescriptor) { if (env == nullptr) { @@ -767,6 +793,24 @@ bool SetOptionalIntProperty(ani_env* env, ani_object& aniObject, const std::stri return true; } +bool SetOptionalLongProperty(ani_env* env, ani_object& aniObject, const std::string& property, int64_t in) +{ + if ((env == nullptr) || (aniObject == nullptr)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Input param is nullptr, property(%{public}s).", property.c_str()); + return false; + } + ani_object longObject = CreateLongObject(env, in); + if (longObject == nullptr) { + return false; + } + + if (!SetRefProperty(env, aniObject, property.c_str(), longObject)) { + return false; + } + + return true; +} + bool SetStringProperty(ani_env* env, ani_object& aniObject, const std::string& property, const std::string& in) { if ((env == nullptr) || (aniObject == nullptr)) { diff --git a/interfaces/innerkits/accesstoken/include/access_token.h b/interfaces/innerkits/accesstoken/include/access_token.h index f2e97c1fc..db35e3182 100644 --- a/interfaces/innerkits/accesstoken/include/access_token.h +++ b/interfaces/innerkits/accesstoken/include/access_token.h @@ -310,6 +310,14 @@ typedef struct { std::vector userPolicyList; } UserPermissionPolicy; +/** + * @brief User policy whitelist update type. + */ +typedef enum UpdateWhiteListType { + ADD = 0, + DELETE, +} UpdateWhiteListType; + /** * @brief PermssionRule */ diff --git a/interfaces/innerkits/accesstoken/include/access_token_error.h b/interfaces/innerkits/accesstoken/include/access_token_error.h index 78eb5c6ba..2ebf92185 100644 --- a/interfaces/innerkits/accesstoken/include/access_token_error.h +++ b/interfaces/innerkits/accesstoken/include/access_token_error.h @@ -87,10 +87,13 @@ enum AccessTokenError { ERR_CREATE_KEY_FAILED, ERR_PERM_POLICY_ALREADY_SET_BY_OTHER, ERR_PERM_POLICY_NOT_SET, + ERR_TOKENID_ALREADY_IN_POLICY_WHITELIST, + ERR_TOKENID_NOT_IN_POLICY_WHITELIST, + ERR_TOKENID_NOT_IN_POLICY_USERLIST, ERR_CAPABILITY_NOT_SUPPORT }; } // namespace AccessToken } // namespace Security } // namespace OHOS -#endif // ACCESS_TOKEN_ERROR_H \ No newline at end of file +#endif // ACCESS_TOKEN_ERROR_H diff --git a/interfaces/innerkits/accesstoken/include/accesstoken_kit.h b/interfaces/innerkits/accesstoken/include/accesstoken_kit.h index 67c0bdf7a..25da798b7 100644 --- a/interfaces/innerkits/accesstoken/include/accesstoken_kit.h +++ b/interfaces/innerkits/accesstoken/include/accesstoken_kit.h @@ -491,17 +491,36 @@ public: */ static int32_t SetUserPolicy(const std::vector& userPermissionList); - /** - * @brief Clear user permission policy - * @param permissionList list of permission. - * @return error code, see access_token_error.h - */ - static int32_t ClearUserPolicy(const std::vector& permissionList); - - /** - * @brief Whether it is a system application - * @param tokenId token id. - * @return bool + /** + * @brief Clear user permission policy + * @param permissionList list of permission. + * @return error code, see access_token_error.h + */ + static int32_t ClearUserPolicy(const std::vector& permissionList); + + /** + * @brief Update user policy whitelist. + * @param tokenId target token id. + * @param permission permission name. + * @param type whitelist update type. + * @return error code, see access_token_error.h + */ + static int32_t UpdatePolicyWhiteList( + AccessTokenID tokenId, const std::string& permission, UpdateWhiteListType type); + + /** + * @brief Get user policy whitelist. + * @param permission permission name. + * @param tokenIdList whitelist token id list. + * @return error code, see access_token_error.h + */ + static int32_t GetPolicyWhiteList( + const std::string& permission, std::vector& tokenIdList); + + /** + * @brief Whether it is a system application + * @param tokenId token id. + * @return bool */ static bool IsSystemAppByFullTokenID(uint64_t tokenId); diff --git a/interfaces/innerkits/accesstoken/libaccesstoken_sdk.map b/interfaces/innerkits/accesstoken/libaccesstoken_sdk.map index 3b5992084..fb3c5b76e 100644 --- a/interfaces/innerkits/accesstoken/libaccesstoken_sdk.map +++ b/interfaces/innerkits/accesstoken/libaccesstoken_sdk.map @@ -57,6 +57,8 @@ "OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(unsigned int)"; "OHOS::Security::AccessToken::AccessTokenKit::SetUserPolicy(std::__h::vector> const&)"; "OHOS::Security::AccessToken::AccessTokenKit::ClearUserPolicy(std::__h::vector, std::__h::allocator>, std::__h::allocator, std::__h::allocator>>> const&)"; + "OHOS::Security::AccessToken::AccessTokenKit::UpdatePolicyWhiteList(unsigned int, std::__h::basic_string, std::__h::allocator> const&, OHOS::Security::AccessToken::UpdateWhiteListType)"; + "OHOS::Security::AccessToken::AccessTokenKit::GetPolicyWhiteList(std::__h::basic_string, std::__h::allocator> const&, std::__h::vector>&)"; "OHOS::Security::AccessToken::AccessTokenKit::GetSelfPermissionsState(std::__h::vector>&, OHOS::Security::AccessToken::PermissionGrantInfo&)"; "OHOS::Security::AccessToken::AccessTokenKit::GetPermissionsStatus(unsigned int, std::__h::vector>&)"; "OHOS::Security::AccessToken::AccessTokenKit::GetVersion(unsigned int&)"; diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp index ab4cb0f96..fcd0ebc50 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp +++ b/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp @@ -1,938 +1,979 @@ -/* - * Copyright (c) 2021-2026 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 "accesstoken_kit.h" -#include -#include -#include -#include "accesstoken_common_log.h" -#include "access_token_error.h" -#include "accesstoken_manager_client.h" -#include "constant_common.h" -#include "data_validator.h" -#include "hap_token_info.h" -#include "permission_def.h" -#include "permission_map.h" -#include "perm_setproc.h" -#include "perm_state_change_callback_customize.h" -#include "tokenid_kit.h" -#include "token_setproc.h" - -namespace OHOS { -namespace Security { -namespace AccessToken { -namespace { -static const uint64_t SYSTEM_APP_MASK = (static_cast(1) << 32); -static const uint64_t ATOMIC_SERVICE_MASK = (static_cast(1) << 33); -static const uint64_t TOKEN_ID_LOWMASK = 0xffffffff; -static const int INVALID_DLP_TOKEN_FLAG = -1; -static const int FIRSTCALLER_TOKENID_DEFAULT = 0; -static const int MAX_LENGTH = 256; -} // namespace - -PermUsedTypeEnum AccessTokenKit::GetPermissionUsedType( - AccessTokenID tokenID, const std::string& permissionName) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s.", - tokenID, permissionName.c_str()); - if ((tokenID == INVALID_TOKENID) || (!DataValidator::IsPermissionNameValid(permissionName))) { - LOGE(ATM_DOMAIN, ATM_TAG, "Input param failed."); - return PermUsedTypeEnum::INVALID_USED_TYPE; - } - return AccessTokenManagerClient::GetInstance().GetPermissionUsedType(tokenID, permissionName); -} - -int AccessTokenKit::GrantPermissionForSpecifiedTime( - AccessTokenID tokenID, const std::string& permissionName, uint32_t onceTime) -{ - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s, onceTime=%{public}d.", - tokenID, permissionName.c_str(), onceTime); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "Invalid tokenID"); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (!DataValidator::IsPermissionNameValid(permissionName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Invalid permissionName"); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().GrantPermissionForSpecifiedTime(tokenID, permissionName, onceTime); -} - -static bool IsRenderToken(AccessTokenID tokenID) -{ - AccessTokenIDInner* idInner = reinterpret_cast(&tokenID); - return idInner->renderFlag; -} - -static bool IsNeedCrossIpc(AccessTokenID verifyingTokenID) -{ - uint64_t selfTokenId = GetSelfTokenID(); - bool isSelfNormalApp = (AccessTokenKit::GetTokenTypeFlag(selfTokenId) == TOKEN_HAP) && - (!AccessTokenKit::IsSystemAppByFullTokenID(selfTokenId)); - - return isSelfNormalApp && ((selfTokenId & TOKEN_ID_LOWMASK) != verifyingTokenID); -} - -static void TransferHapPolicyParams(const HapPolicyParams& policyIn, HapPolicy& policyOut) -{ - policyOut.apl = policyIn.apl; - policyOut.domain = policyIn.domain; - policyOut.permList.assign(policyIn.permList.begin(), policyIn.permList.end()); - policyOut.aclRequestedList.assign(policyIn.aclRequestedList.begin(), policyIn.aclRequestedList.end()); - policyOut.preAuthorizationInfo.assign(policyIn.preAuthorizationInfo.begin(), policyIn.preAuthorizationInfo.end()); - for (const auto& perm : policyIn.permStateList) { - PermissionStatus tmp; - tmp.permissionName = perm.permissionName; - tmp.grantStatus = perm.grantStatus.empty() ? PERMISSION_DENIED : perm.grantStatus[0]; - tmp.grantFlag = perm.grantFlags.empty() ? PERMISSION_DEFAULT_FLAG : perm.grantFlags[0]; - tmp.feature = perm.feature; - policyOut.permStateList.emplace_back(tmp); - } - policyOut.checkIgnore = policyIn.checkIgnore; - policyOut.aclExtendedMap = policyIn.aclExtendedMap; - policyOut.isDebugGrant = policyIn.isDebugGrant; -} - -AccessTokenIDEx AccessTokenKit::AllocHapToken(const HapInfoParams& info, const HapPolicyParams& policy) -{ - AccessTokenIDEx res = {0}; - LOGI(ATM_DOMAIN, ATM_TAG, "UserID: %{public}d, bundleName :%{public}s, \ -permList: %{public}zu, stateList: %{public}zu, checkIgnore: %{public}d, isAtomicService: %{public}d", - info.userID, info.bundleName.c_str(), policy.permList.size(), policy.permStateList.size(), policy.checkIgnore, - info.isAtomicService); - if ((!DataValidator::IsUserIdValid(info.userID)) || !DataValidator::IsAppIDDescValid(info.appIDDesc) || - !DataValidator::IsBundleNameValid(info.bundleName) || !DataValidator::IsAplNumValid(policy.apl) || - !DataValidator::IsDomainValid(policy.domain) || !DataValidator::IsDlpTypeValid(info.dlpType)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Input param failed"); - return res; - } - HapPolicy newPolicy; - TransferHapPolicyParams(policy, newPolicy); - return AccessTokenManagerClient::GetInstance().AllocHapToken(info, newPolicy); -} - -int32_t AccessTokenKit::InitHapToken(const HapInfoParams& info, HapPolicyParams& policy, - AccessTokenIDEx& fullTokenId) -{ - HapInfoCheckResult result; - return InitHapToken(info, policy, fullTokenId, result); -} - -int32_t AccessTokenKit::InitHapToken(const HapInfoParams& info, HapPolicyParams& policy, - AccessTokenIDEx& fullTokenId, HapInfoCheckResult& result) -{ - LOGI(ATM_DOMAIN, ATM_TAG, "UserID: %{public}d, bundleName :%{public}s, permList: %{public}zu, " - "stateList: %{public}zu, aclExtendedMap: %{public}zu, checkIgnore: %{public}d, isAtomicService: %{public}d", - info.userID, info.bundleName.c_str(), policy.permList.size(), policy.permStateList.size(), - policy.aclExtendedMap.size(), policy.checkIgnore, info.isAtomicService); - if ((!DataValidator::IsUserIdValid(info.userID)) || !DataValidator::IsAppIDDescValid(info.appIDDesc) || - !DataValidator::IsBundleNameValid(info.bundleName) || !DataValidator::IsAplNumValid(policy.apl) || - !DataValidator::IsDomainValid(policy.domain) || !DataValidator::IsDlpTypeValid(info.dlpType) || - !DataValidator::IsAclExtendedMapSizeValid(policy.aclExtendedMap)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Input param failed"); - return AccessTokenError::ERR_PARAM_INVALID; - } - HapPolicy newPolicy; - TransferHapPolicyParams(policy, newPolicy); - return AccessTokenManagerClient::GetInstance().InitHapToken(info, newPolicy, fullTokenId, result); -} - -FullTokenID AccessTokenKit::AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID) -{ - LOGI(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s, tokenID=%{public}d", - ConstantCommon::EncryptDevId(remoteDeviceID).c_str(), remoteTokenID); -#ifdef DEBUG_API_PERFORMANCE - LOGD(ATM_DOMAIN, ATM_TAG, "Api_performance:start call"); - FullTokenID resID = AccessTokenManagerClient::GetInstance().AllocLocalTokenID(remoteDeviceID, remoteTokenID); - LOGD(ATM_DOMAIN, ATM_TAG, "Api_performance:end call"); - return resID; -#else - return AccessTokenManagerClient::GetInstance().AllocLocalTokenID(remoteDeviceID, remoteTokenID); -#endif -} - -int32_t AccessTokenKit::UpdateHapToken( - AccessTokenIDEx& tokenIdEx, const UpdateHapInfoParams& info, const HapPolicyParams& policy) -{ - HapInfoCheckResult result; - return UpdateHapToken(tokenIdEx, info, policy, result); -} - -int32_t AccessTokenKit::UpdateHapToken(AccessTokenIDEx& tokenIdEx, const UpdateHapInfoParams& info, - const HapPolicyParams& policy, HapInfoCheckResult& result) -{ - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID: %{public}d, isSystemApp: %{public}d, \ -permList: %{public}zu, stateList: %{public}zu, aclExtendedMap: %{public}zu, checkIgnore: %{public}d, \ -isAtomicService: %{public}d", - tokenIdEx.tokenIdExStruct.tokenID, info.isSystemApp, policy.permList.size(), policy.permStateList.size(), - policy.aclExtendedMap.size(), policy.checkIgnore, info.isAtomicService); - if ((tokenIdEx.tokenIdExStruct.tokenID == INVALID_TOKENID) || (!DataValidator::IsAppIDDescValid(info.appIDDesc)) || - (!DataValidator::IsAplNumValid(policy.apl)) || - !DataValidator::IsAclExtendedMapSizeValid(policy.aclExtendedMap)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Input param failed"); - return AccessTokenError::ERR_PARAM_INVALID; - } - HapPolicy newPolicy; - TransferHapPolicyParams(policy, newPolicy); - return AccessTokenManagerClient::GetInstance().UpdateHapToken(tokenIdEx, info, newPolicy, result); -} - -int AccessTokenKit::DeleteToken(AccessTokenID tokenID) -{ - return DeleteToken(tokenID, false); -} - -int AccessTokenKit::DeleteToken(AccessTokenID tokenID, bool isTokenReserved) -{ - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, isTokenReserved=%{public}d.", tokenID, isTokenReserved); - if (tokenID == INVALID_TOKENID) { - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().DeleteToken(tokenID, isTokenReserved); -} - -ATokenTypeEnum AccessTokenKit::GetTokenType(AccessTokenID tokenID) __attribute__((no_sanitize("cfi"))) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid."); - return TOKEN_INVALID; - } - return AccessTokenManagerClient::GetInstance().GetTokenType(tokenID); -} - -ATokenTypeEnum AccessTokenKit::GetTokenTypeFlag(AccessTokenID tokenID) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return TOKEN_INVALID; - } - AccessTokenIDInner* idInner = reinterpret_cast(&tokenID); - return static_cast(idInner->type); -} - -ATokenTypeEnum AccessTokenKit::GetTokenType(FullTokenID tokenID) -{ - AccessTokenID id = tokenID & TOKEN_ID_LOWMASK; - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", id); - if (id == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return TOKEN_INVALID; - } - return AccessTokenManagerClient::GetInstance().GetTokenType(id); -} - -ATokenTypeEnum AccessTokenKit::GetTokenTypeFlag(FullTokenID tokenID) -{ - AccessTokenID id = tokenID & TOKEN_ID_LOWMASK; - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", id); - if (id == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return TOKEN_INVALID; - } - AccessTokenIDInner* idInner = reinterpret_cast(&id); - return static_cast(idInner->type); -} - -AccessTokenID AccessTokenKit::GetHapTokenID( - int32_t userID, const std::string& bundleName, int32_t instIndex) __attribute__((no_sanitize("cfi"))) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "UserID=%{public}d, bundleName=%{public}s, instIndex=%{public}d.", - userID, bundleName.c_str(), instIndex); - if ((!DataValidator::IsUserIdValid(userID)) || (!DataValidator::IsBundleNameValid(bundleName))) { - LOGE(ATM_DOMAIN, ATM_TAG, "Hap token param check failed"); - return INVALID_TOKENID; - } - AccessTokenIDEx tokenIdEx = - AccessTokenManagerClient::GetInstance().GetHapTokenID(userID, bundleName, instIndex); - return tokenIdEx.tokenIdExStruct.tokenID; -} - -AccessTokenIDEx AccessTokenKit::GetHapTokenIDEx(int32_t userID, const std::string& bundleName, int32_t instIndex) -{ - AccessTokenIDEx tokenIdEx = {0}; - LOGD(ATM_DOMAIN, ATM_TAG, "UserID=%{public}d, bundleName=%{public}s, instIndex=%{public}d.", - userID, bundleName.c_str(), instIndex); - if ((!DataValidator::IsUserIdValid(userID)) || (!DataValidator::IsBundleNameValid(bundleName))) { - LOGE(ATM_DOMAIN, ATM_TAG, "Hap token param check failed"); - return tokenIdEx; - } - return AccessTokenManagerClient::GetInstance().GetHapTokenID(userID, bundleName, instIndex); -} - -int32_t AccessTokenKit::GetTokenIDByUserID(int32_t userID, std::unordered_set& tokenIdList) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "UserID=%{public}d.", userID); - if (!DataValidator::IsUserIdValid(userID)) { - LOGE(ATM_DOMAIN, ATM_TAG, "UserID=%{public}d is invalid", userID); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().GetTokenIDByUserID(userID, tokenIdList); -} - -int AccessTokenKit::GetHapTokenInfo( - AccessTokenID tokenID, HapTokenInfo& hapTokenInfoRes) __attribute__((no_sanitize("cfi"))) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); - if (GetTokenTypeFlag(tokenID) != TOKEN_HAP) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID =%{public}d is invalid", tokenID); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (IsRenderToken(tokenID)) { - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process.", tokenID); - return ERR_TOKENID_NOT_EXIST; - } - - return AccessTokenManagerClient::GetInstance().GetHapTokenInfo(tokenID, hapTokenInfoRes); -} - -int AccessTokenKit::GetNativeTokenInfo( - AccessTokenID tokenID, NativeTokenInfo& nativeTokenInfoRes) __attribute__((no_sanitize("cfi"))) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); - if (GetTokenTypeFlag(tokenID) != TOKEN_NATIVE && GetTokenTypeFlag(tokenID) != TOKEN_SHELL) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID =%{public}d is invalid", tokenID); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().GetNativeTokenInfo(tokenID, nativeTokenInfoRes); -} - -int32_t AccessTokenKit::GetSelfPermissionStatus(const std::string& permissionName, PermissionOper& status) -{ - if (permissionName.empty() || permissionName.size() > MAX_LENGTH) { - return ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().GetSelfPermissionStatus(permissionName, status); -} - -PermissionOper AccessTokenKit::GetSelfPermissionsState(std::vector& permList, - PermissionGrantInfo& info) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "PermList.size=%{public}zu.", permList.size()); - return AccessTokenManagerClient::GetInstance().GetSelfPermissionsState(permList, info); -} - -int32_t AccessTokenKit::GetPermissionsStatus(AccessTokenID tokenID, std::vector& permList) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permList.size=%{public}zu.", tokenID, permList.size()); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().GetPermissionsStatus(tokenID, permList); -} - -int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName, bool crossIpc) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s, crossIpc=%{public}d.", - tokenID, permissionName.c_str(), crossIpc); - if (IsRenderToken(tokenID)) { - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process, perm denied.", tokenID); - return PERMISSION_DENIED; - } - uint32_t code; - if (!TransferPermissionToOpcode(permissionName, code)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName(%{public}s) is not exist.", permissionName.c_str()); - return PERMISSION_DENIED; - } - if (crossIpc || IsNeedCrossIpc(tokenID)) { - return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionName); - } - bool isGranted = false; - int32_t ret = GetPermissionFromKernel(tokenID, code, isGranted); - if (ret != 0) { - return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionName); - } - return isGranted ? PERMISSION_GRANTED : PERMISSION_DENIED; -} - -int AccessTokenKit::VerifyAccessToken( - AccessTokenID callerTokenID, AccessTokenID firstTokenID, const std::string& permissionName, bool crossIpc) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "CallerToken=%{public}d, firstToken=%{public}d, permissionName=%{public}s.", - callerTokenID, firstTokenID, permissionName.c_str()); - int ret = AccessTokenKit::VerifyAccessToken(callerTokenID, permissionName, crossIpc); - if (ret != PERMISSION_GRANTED) { - return ret; - } - if (firstTokenID == FIRSTCALLER_TOKENID_DEFAULT) { - return ret; - } - return AccessTokenKit::VerifyAccessToken(firstTokenID, permissionName, crossIpc); -} - -int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s.", - tokenID, permissionName.c_str()); - if (IsRenderToken(tokenID)) { - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process, perm denied.", tokenID); - return PERMISSION_DENIED; - } - if (IsNeedCrossIpc(tokenID)) { - return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionName); - } - uint32_t code; - if (!TransferPermissionToOpcode(permissionName, code)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName(%{public}s) is not exist.", permissionName.c_str()); - return PERMISSION_DENIED; - } - bool isGranted = false; - int32_t ret = GetPermissionFromKernel(tokenID, code, isGranted); - if (ret != 0) { - return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionName); - } - return isGranted ? PERMISSION_GRANTED : PERMISSION_DENIED; -} - -int AccessTokenKit::VerifyAccessToken( - AccessTokenID callerTokenID, AccessTokenID firstTokenID, const std::string& permissionName) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "CallerToken=%{public}d, firstToken=%{public}d, permissionName=%{public}s.", - callerTokenID, firstTokenID, permissionName.c_str()); - int ret = AccessTokenKit::VerifyAccessToken(callerTokenID, permissionName); - if (ret != PERMISSION_GRANTED) { - return ret; - } - if (firstTokenID == FIRSTCALLER_TOKENID_DEFAULT) { - return ret; - } - return AccessTokenKit::VerifyAccessToken(firstTokenID, permissionName); -} - -int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::vector& permissionList, - std::vector& permStateList, bool crossIpc) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionlist.size=%{public}zu, crossIpc=%{public}d.", - tokenID, permissionList.size(), crossIpc); - permStateList.clear(); - if (IsRenderToken(tokenID)) { - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process, perm denied.", tokenID); - permStateList.resize(permissionList.size(), PERMISSION_DENIED); - return RET_SUCCESS; - } - if (crossIpc || IsNeedCrossIpc(tokenID)) { - return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionList, permStateList); - } - - permStateList.resize(permissionList.size(), PERMISSION_DENIED); - std::vector permListCrossIpc; - std::unordered_map permToState; - for (size_t i = 0; i < permissionList.size(); i++) { - bool isGranted = false; - uint32_t code; - if (!TransferPermissionToOpcode(permissionList[i], code)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName(%{public}s) is not exist.", permissionList[i].c_str()); - permStateList[i] = PERMISSION_DENIED; - continue; - } - int32_t ret = GetPermissionFromKernel(tokenID, code, isGranted); - if (ret != 0) { - permToState[permListCrossIpc.size()] = i; - permListCrossIpc.emplace_back(permissionList[i]); - continue; - } - permStateList[i] = isGranted ? PERMISSION_GRANTED : PERMISSION_DENIED; - } - if (!permListCrossIpc.empty()) { - std::vector permStateCrossIpc; - int ret = AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, - permListCrossIpc, permStateCrossIpc); - if (ret != ERR_OK) { - return ret; - } - for (size_t i = 0; i < permStateCrossIpc.size(); i++) { - if (permToState.find(i) != permToState.end()) { - permStateList[permToState[i]] = permStateCrossIpc[i]; - } - } - } - return ERR_OK; -} - -int AccessTokenKit::GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "PermissionName=%{public}s.", permissionName.c_str()); - if (!DataValidator::IsPermissionNameValid(permissionName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - - PermissionBriefDef briefDef; - if (!GetPermissionBriefDef(permissionName, briefDef)) { - return AccessTokenError::ERR_PERMISSION_NOT_EXIST; - } - - if (briefDef.grantMode == GrantMode::SYSTEM_GRANT) { - ConvertPermissionBriefToDef(briefDef, permissionDefResult); - return 0; - } - - return AccessTokenManagerClient::GetInstance().GetDefPermission(permissionName, permissionDefResult); -} - -int AccessTokenKit::GetReqPermissions( - AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, isSystemGrant=%{public}d.", tokenID, isSystemGrant); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - - return AccessTokenManagerClient::GetInstance().GetReqPermissions(tokenID, reqPermList, isSystemGrant); -} - -int AccessTokenKit::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName, uint32_t& flag) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s.", - tokenID, permissionName.c_str()); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (!DataValidator::IsPermissionNameValid(permissionName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().GetPermissionFlag(tokenID, permissionName, flag); -} - -int AccessTokenKit::GrantPermission( - AccessTokenID tokenID, const std::string& permissionName, uint32_t flag, UpdatePermissionFlag updateFlag) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s, flag=%{public}u.", - tokenID, permissionName.c_str(), flag); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (IsRenderToken(tokenID)) { - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process.", tokenID); - return ERR_TOKENID_NOT_EXIST; - } - if (!DataValidator::IsPermissionNameValid(permissionName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (!DataValidator::IsPermissionFlagValid(flag) || DataValidator::IsPermissionFlagValidForAdmin(flag)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Flag is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().GrantPermission(tokenID, permissionName, flag, updateFlag); -} - -int AccessTokenKit::RevokePermission( - AccessTokenID tokenID, const std::string& permissionName, uint32_t flag, - UpdatePermissionFlag updateFlag, bool killProcess) -{ - LOGD(ATM_DOMAIN, ATM_TAG, - "TokenID=%{public}d, permissionName=%{public}s, flag=%{public}u, killProcess=%{public}d.", - tokenID, permissionName.c_str(), flag, killProcess); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "Invalid tokenID"); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (IsRenderToken(tokenID)) { - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process.", tokenID); - return ERR_TOKENID_NOT_EXIST; - } - if (!DataValidator::IsPermissionNameValid(permissionName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Invalid permissionName"); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (!DataValidator::IsPermissionFlagValid(flag) || DataValidator::IsPermissionFlagValidForAdmin(flag)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Invalid flag"); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().RevokePermission( - tokenID, permissionName, flag, updateFlag, killProcess); -} - -int AccessTokenKit::ClearUserGrantedPermissionState(AccessTokenID tokenID) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().ClearUserGrantedPermissionState(tokenID); -} - -int32_t AccessTokenKit::SetPermissionRequestToggleStatus(const std::string& permissionName, uint32_t status, - int32_t userID = 0) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "PermissionName=%{public}s, status=%{public}d, userID=%{public}d.", - permissionName.c_str(), status, userID); - if (!DataValidator::IsPermissionNameValid(permissionName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid."); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (!DataValidator::IsToggleStatusValid(status)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Toggle status is invalid."); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (!DataValidator::IsUserIdValid(userID)) { - LOGE(ATM_DOMAIN, ATM_TAG, "UserID is invalid."); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().SetPermissionRequestToggleStatus(permissionName, status, userID); -} - -int32_t AccessTokenKit::GetPermissionRequestToggleStatus(const std::string& permissionName, uint32_t& status, - int32_t userID = 0) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "PermissionName=%{public}s, userID=%{public}d.", - permissionName.c_str(), userID); - if (!DataValidator::IsPermissionNameValid(permissionName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid."); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (!DataValidator::IsUserIdValid(userID)) { - LOGE(ATM_DOMAIN, ATM_TAG, "UserID is invalid."); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().GetPermissionRequestToggleStatus(permissionName, status, userID); -} - -int32_t AccessTokenKit::RequestAppPermOnSetting(AccessTokenID tokenID) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "tokenID=%{public}d.", tokenID); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().RequestAppPermOnSetting(tokenID); -} - -int32_t AccessTokenKit::RegisterPermStateChangeCallback( - const std::shared_ptr& callback) -{ - return AccessTokenManagerClient::GetInstance().RegisterPermStateChangeCallback(callback, SYSTEM_REGISTER_TYPE); -} - -int32_t AccessTokenKit::UnRegisterPermStateChangeCallback( - const std::shared_ptr& callback) -{ - return AccessTokenManagerClient::GetInstance().UnRegisterPermStateChangeCallback(callback, SYSTEM_REGISTER_TYPE); -} - -int32_t AccessTokenKit::RegisterSelfPermStateChangeCallback( - const std::shared_ptr& callback) -{ - return AccessTokenManagerClient::GetInstance().RegisterPermStateChangeCallback(callback, SELF_REGISTER_TYPE); -} - -int32_t AccessTokenKit::UnRegisterSelfPermStateChangeCallback( - const std::shared_ptr& callback) -{ - return AccessTokenManagerClient::GetInstance().UnRegisterPermStateChangeCallback(callback, SELF_REGISTER_TYPE); -} - -int32_t AccessTokenKit::GetHapDlpFlag(AccessTokenID tokenID) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return INVALID_DLP_TOKEN_FLAG; - } - AccessTokenIDInner* idInner = reinterpret_cast(&tokenID); - return static_cast(idInner->dlpFlag); -} - -int32_t AccessTokenKit::ReloadNativeTokenInfo() -{ -#ifndef ATM_BUILD_VARIANT_USER_ENABLE - return AccessTokenManagerClient::GetInstance().ReloadNativeTokenInfo(); -#else - return 0; -#endif -} - -int AccessTokenKit::GetHapTokenInfoExtension(AccessTokenID tokenID, HapTokenInfoExt& info) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); - if (GetTokenTypeFlag(tokenID) != TOKEN_HAP) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID =%{public}d is invalid.", tokenID); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (IsRenderToken(tokenID)) { - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process.", tokenID); - return ERR_TOKENID_NOT_EXIST; - } - - return AccessTokenManagerClient::GetInstance().GetHapTokenInfoExtension(tokenID, info); -} - -AccessTokenID AccessTokenKit::GetNativeTokenId(const std::string& processName) -{ - if (!DataValidator::IsProcessNameValid(processName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "ProcessName is invalid, processName=%{public}s", processName.c_str()); - return INVALID_TOKENID; - } - return AccessTokenManagerClient::GetInstance().GetNativeTokenId(processName); -} - -#ifdef TOKEN_SYNC_ENABLE -int AccessTokenKit::GetHapTokenInfoFromRemote(AccessTokenID tokenID, HapTokenInfoForSync& hapSync) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return AccessTokenError::ERR_PARAM_INVALID; - } - - return AccessTokenManagerClient::GetInstance().GetHapTokenInfoFromRemote(tokenID, hapSync); -} - -int AccessTokenKit::SetRemoteHapTokenInfo(const std::string& deviceID, - const HapTokenInfoForSync& hapSync) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s, tokenID=%{public}d.", - ConstantCommon::EncryptDevId(deviceID).c_str(), hapSync.baseInfo.tokenID); - return AccessTokenManagerClient::GetInstance().SetRemoteHapTokenInfo(deviceID, hapSync); -} - -int AccessTokenKit::DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s, tokenID=%{public}d.", - ConstantCommon::EncryptDevId(deviceID).c_str(), tokenID); - return AccessTokenManagerClient::GetInstance().DeleteRemoteToken(deviceID, tokenID); -} - -int AccessTokenKit::DeleteRemoteDeviceTokens(const std::string& deviceID) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s.", ConstantCommon::EncryptDevId(deviceID).c_str()); - return AccessTokenManagerClient::GetInstance().DeleteRemoteDeviceTokens(deviceID); -} - -AccessTokenID AccessTokenKit::GetRemoteNativeTokenID(const std::string& deviceID, AccessTokenID tokenID) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s., tokenID=%{public}d", - ConstantCommon::EncryptDevId(deviceID).c_str(), tokenID); - return AccessTokenManagerClient::GetInstance().GetRemoteNativeTokenID(deviceID, tokenID); -} - -int32_t AccessTokenKit::RegisterTokenSyncCallback(const std::shared_ptr& syncCallback) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "Call RegisterTokenSyncCallback."); - return AccessTokenManagerClient::GetInstance().RegisterTokenSyncCallback(syncCallback); -} - -int32_t AccessTokenKit::UnRegisterTokenSyncCallback() -{ - LOGD(ATM_DOMAIN, ATM_TAG, "Call UnRegisterTokenSyncCallback."); - return AccessTokenManagerClient::GetInstance().UnRegisterTokenSyncCallback(); -} -#endif - -void AccessTokenKit::DumpTokenInfo(const AtmToolsParamInfo& info, std::string& dumpInfo) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, bundleName=%{public}s, processName=%{public}s.", - info.tokenId, info.bundleName.c_str(), info.processName.c_str()); - - AccessTokenManagerClient::GetInstance().DumpTokenInfo(info, dumpInfo); -} - -int32_t AccessTokenKit::GetVersion(uint32_t& version) -{ - return AccessTokenManagerClient::GetInstance().GetVersion(version); -} - -int32_t AccessTokenKit::SetPermDialogCap(const HapBaseInfo& hapBaseInfo, bool enable) -{ - return AccessTokenManagerClient::GetInstance().SetPermDialogCap(hapBaseInfo, enable); -} - -void AccessTokenKit::GetPermissionManagerInfo(PermissionGrantInfo& info) -{ - AccessTokenManagerClient::GetInstance().GetPermissionManagerInfo(info); -} - -int32_t AccessTokenKit::SetUserPolicy(const std::vector& userPermissionList) -{ -#ifdef SUPPORT_MANAGE_USER_POLICY - LOGI(ATM_DOMAIN, ATM_TAG, "Enter."); - return AccessTokenManagerClient::GetInstance().SetUserPolicy(userPermissionList); -#else - LOGE(ATM_DOMAIN, ATM_TAG, "Not support."); - return ERR_CAPABILITY_NOT_SUPPORT; -#endif -} - -int32_t AccessTokenKit::ClearUserPolicy(const std::vector& permissionList) -{ -#ifdef SUPPORT_MANAGE_USER_POLICY - LOGI(ATM_DOMAIN, ATM_TAG, "Enter."); - return AccessTokenManagerClient::GetInstance().ClearUserPolicy(permissionList); -#else - LOGE(ATM_DOMAIN, ATM_TAG, "Not support."); - return ERR_CAPABILITY_NOT_SUPPORT; -#endif -} - -bool AccessTokenKit::IsSystemAppByFullTokenID(uint64_t tokenId) -{ - return (tokenId & SYSTEM_APP_MASK) == SYSTEM_APP_MASK; -} - -uint64_t AccessTokenKit::GetRenderTokenID(uint64_t tokenId) -{ - AccessTokenID id = tokenId & TOKEN_ID_LOWMASK; - if (id == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); - return tokenId; - } - AccessTokenIDInner* idInner = reinterpret_cast(&id); - idInner->renderFlag = 1; - - id = *reinterpret_cast(idInner); - return static_cast(id); -} - -int32_t AccessTokenKit::GetKernelPermissions( - AccessTokenID tokenID, std::vector& kernelPermList) -{ - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); - return AccessTokenManagerClient::GetInstance().GetKernelPermissions(tokenID, kernelPermList); -} - -int32_t AccessTokenKit::GetReqPermissionByName( - AccessTokenID tokenID, const std::string& permissionName, std::string& value) -{ - LOGI(ATM_DOMAIN, ATM_TAG, - "TokenID=%{public}d permissionName=%{public}s.", tokenID, permissionName.c_str()); - if (!DataValidator::IsPermissionNameValid(permissionName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid."); - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().GetReqPermissionByName(tokenID, permissionName, value); -} - -#ifdef SECURITY_COMPONENT_ENHANCE_ENABLE -int32_t AccessTokenKit::RegisterSecCompEnhance(const SecCompEnhanceData& enhance) -{ - return AccessTokenManagerClient::GetInstance().RegisterSecCompEnhance(enhance); -} - -int32_t AccessTokenKit::UpdateSecCompEnhance(int32_t pid, uint32_t seqNum) -{ - return AccessTokenManagerClient::GetInstance().UpdateSecCompEnhance(pid, seqNum); -} - -int32_t AccessTokenKit::GetSecCompEnhance(int32_t pid, SecCompEnhanceData& enhance) -{ - return AccessTokenManagerClient::GetInstance().GetSecCompEnhance(pid, enhance); -} -#endif - -bool AccessTokenKit::IsAtomicServiceByFullTokenID(uint64_t tokenId) -{ - LOGD(ATM_DOMAIN, ATM_TAG, "Called, tokenId=%{public}" PRId64, tokenId); - return (tokenId & ATOMIC_SERVICE_MASK) == ATOMIC_SERVICE_MASK; -} - -int32_t AccessTokenKit::SetPermissionStatusWithPolicy( - uint32_t tokenID, const std::vector& permissionList, int32_t status, uint32_t flag) -{ - LOGI(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permList.size=%{public}zu, status=%{public}d, flag=%{public}u.", - tokenID, permissionList.size(), status, flag); - if (tokenID == INVALID_TOKENID) { - LOGE(ATM_DOMAIN, ATM_TAG, "tokenID: %{public}d, TokenID is invalid.", tokenID); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (permissionList.empty()) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionList is empty."); - return AccessTokenError::ERR_PARAM_INVALID; - } - for (const auto& perm : permissionList) { - if (!DataValidator::IsPermissionNameValid(perm)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid: %{public}s.", perm.c_str()); - return AccessTokenError::ERR_PARAM_INVALID; - } - } - if (!DataValidator::IsPermissionStatusValid(status)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Status: %{public}d, status is invalid.", status); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (!DataValidator::IsPermissionFlagValidForAdmin(flag)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Flag: %{public}u, flag is invalid.", flag); - return AccessTokenError::ERR_PARAM_INVALID; - } - if (!DataValidator::IsListSizeValid(permissionList.size())) { - return AccessTokenError::ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().SetPermissionStatusWithPolicy(tokenID, permissionList, status, flag); -} - -bool AccessTokenKit::TransferPermissionToOpcode(const std::string& permissionName, uint32_t& permCode) -{ - return AccessToken::TransferPermissionToOpcode(permissionName, permCode); -} - -bool AccessTokenKit::TransferOpcodeToPermission(uint32_t permCode, std::string& permissionName) -{ - permissionName = AccessToken::TransferOpcodeToPermission(permCode); - if (permissionName.empty()) { - LOGE(ATM_DOMAIN, ATM_TAG, "Perm(%{public}u) is not exist.", permCode); - return false; - } - return true; -} - -int32_t AccessTokenKit::QueryStatusByPermission(const std::vector& permissionList, - std::vector& permissionInfoList, bool onlyHap) -{ - // Validate permission list size - if (!DataValidator::IsListSizeValid(permissionList.size())) { - return AccessTokenError::ERR_PARAM_INVALID; - } - - // Convert permissionList to permCodeList for IPC - std::vector permCodeList; - permCodeList.reserve(permissionList.size()); - for (const auto& permissionName : permissionList) { - // Validate permission name format - if (!DataValidator::IsPermissionNameValid(permissionName)) { - LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName format is invalid: %{public}s.", permissionName.c_str()); - return AccessTokenError::ERR_PARAM_INVALID; - } - - // Validate permission exists and convert to permCode - uint32_t permCode = 0; - if (!AccessToken::TransferPermissionToOpcode(permissionName, permCode)) { - LOGE(ATM_DOMAIN, ATM_TAG, "Permission %{public}s does not exist.", permissionName.c_str()); - return AccessTokenError::ERR_PERMISSION_NOT_EXIST; - } - permCodeList.emplace_back(permCode); - } - - return AccessTokenManagerClient::GetInstance().QueryStatusByPermission( - permCodeList, permissionInfoList, onlyHap); -} - -int32_t AccessTokenKit::QueryStatusByTokenID(const std::vector& tokenIDList, - std::vector& permissionInfoList) -{ - if (!DataValidator::IsListSizeValid(tokenIDList.size())) { - LOGE(ATM_DOMAIN, ATM_TAG, "TokenIDList size is invalid: %{public}zu", tokenIDList.size()); - return ERR_PARAM_INVALID; - } - return AccessTokenManagerClient::GetInstance().QueryStatusByTokenID(tokenIDList, permissionInfoList); -} -} // namespace AccessToken -} // namespace Security -} // namespace OHOS +/* + * Copyright (c) 2021-2026 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 "accesstoken_kit.h" +#include +#include +#include +#include "accesstoken_common_log.h" +#include "access_token_error.h" +#include "accesstoken_manager_client.h" +#include "constant_common.h" +#include "data_validator.h" +#include "hap_token_info.h" +#include "permission_def.h" +#include "permission_map.h" +#include "perm_setproc.h" +#include "perm_state_change_callback_customize.h" +#include "tokenid_kit.h" +#include "token_setproc.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static const uint64_t SYSTEM_APP_MASK = (static_cast(1) << 32); +static const uint64_t ATOMIC_SERVICE_MASK = (static_cast(1) << 33); +static const uint64_t TOKEN_ID_LOWMASK = 0xffffffff; +static const int INVALID_DLP_TOKEN_FLAG = -1; +static const int FIRSTCALLER_TOKENID_DEFAULT = 0; +static const int MAX_LENGTH = 256; +} // namespace + +PermUsedTypeEnum AccessTokenKit::GetPermissionUsedType( + AccessTokenID tokenID, const std::string& permissionName) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s.", + tokenID, permissionName.c_str()); + if ((tokenID == INVALID_TOKENID) || (!DataValidator::IsPermissionNameValid(permissionName))) { + LOGE(ATM_DOMAIN, ATM_TAG, "Input param failed."); + return PermUsedTypeEnum::INVALID_USED_TYPE; + } + return AccessTokenManagerClient::GetInstance().GetPermissionUsedType(tokenID, permissionName); +} + +int AccessTokenKit::GrantPermissionForSpecifiedTime( + AccessTokenID tokenID, const std::string& permissionName, uint32_t onceTime) +{ + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s, onceTime=%{public}d.", + tokenID, permissionName.c_str(), onceTime); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "Invalid tokenID"); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (!DataValidator::IsPermissionNameValid(permissionName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Invalid permissionName"); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GrantPermissionForSpecifiedTime(tokenID, permissionName, onceTime); +} + +static bool IsRenderToken(AccessTokenID tokenID) +{ + AccessTokenIDInner* idInner = reinterpret_cast(&tokenID); + return idInner->renderFlag; +} + +static bool IsNeedCrossIpc(AccessTokenID verifyingTokenID) +{ + uint64_t selfTokenId = GetSelfTokenID(); + bool isSelfNormalApp = (AccessTokenKit::GetTokenTypeFlag(selfTokenId) == TOKEN_HAP) && + (!AccessTokenKit::IsSystemAppByFullTokenID(selfTokenId)); + + return isSelfNormalApp && ((selfTokenId & TOKEN_ID_LOWMASK) != verifyingTokenID); +} + +static void TransferHapPolicyParams(const HapPolicyParams& policyIn, HapPolicy& policyOut) +{ + policyOut.apl = policyIn.apl; + policyOut.domain = policyIn.domain; + policyOut.permList.assign(policyIn.permList.begin(), policyIn.permList.end()); + policyOut.aclRequestedList.assign(policyIn.aclRequestedList.begin(), policyIn.aclRequestedList.end()); + policyOut.preAuthorizationInfo.assign(policyIn.preAuthorizationInfo.begin(), policyIn.preAuthorizationInfo.end()); + for (const auto& perm : policyIn.permStateList) { + PermissionStatus tmp; + tmp.permissionName = perm.permissionName; + tmp.grantStatus = perm.grantStatus.empty() ? PERMISSION_DENIED : perm.grantStatus[0]; + tmp.grantFlag = perm.grantFlags.empty() ? PERMISSION_DEFAULT_FLAG : perm.grantFlags[0]; + tmp.feature = perm.feature; + policyOut.permStateList.emplace_back(tmp); + } + policyOut.checkIgnore = policyIn.checkIgnore; + policyOut.aclExtendedMap = policyIn.aclExtendedMap; + policyOut.isDebugGrant = policyIn.isDebugGrant; +} + +AccessTokenIDEx AccessTokenKit::AllocHapToken(const HapInfoParams& info, const HapPolicyParams& policy) +{ + AccessTokenIDEx res = {0}; + LOGI(ATM_DOMAIN, ATM_TAG, "UserID: %{public}d, bundleName :%{public}s, \ +permList: %{public}zu, stateList: %{public}zu, checkIgnore: %{public}d, isAtomicService: %{public}d", + info.userID, info.bundleName.c_str(), policy.permList.size(), policy.permStateList.size(), policy.checkIgnore, + info.isAtomicService); + if ((!DataValidator::IsUserIdValid(info.userID)) || !DataValidator::IsAppIDDescValid(info.appIDDesc) || + !DataValidator::IsBundleNameValid(info.bundleName) || !DataValidator::IsAplNumValid(policy.apl) || + !DataValidator::IsDomainValid(policy.domain) || !DataValidator::IsDlpTypeValid(info.dlpType)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Input param failed"); + return res; + } + HapPolicy newPolicy; + TransferHapPolicyParams(policy, newPolicy); + return AccessTokenManagerClient::GetInstance().AllocHapToken(info, newPolicy); +} + +int32_t AccessTokenKit::InitHapToken(const HapInfoParams& info, HapPolicyParams& policy, + AccessTokenIDEx& fullTokenId) +{ + HapInfoCheckResult result; + return InitHapToken(info, policy, fullTokenId, result); +} + +int32_t AccessTokenKit::InitHapToken(const HapInfoParams& info, HapPolicyParams& policy, + AccessTokenIDEx& fullTokenId, HapInfoCheckResult& result) +{ + LOGI(ATM_DOMAIN, ATM_TAG, "UserID: %{public}d, bundleName :%{public}s, permList: %{public}zu, " + "stateList: %{public}zu, aclExtendedMap: %{public}zu, checkIgnore: %{public}d, isAtomicService: %{public}d", + info.userID, info.bundleName.c_str(), policy.permList.size(), policy.permStateList.size(), + policy.aclExtendedMap.size(), policy.checkIgnore, info.isAtomicService); + if ((!DataValidator::IsUserIdValid(info.userID)) || !DataValidator::IsAppIDDescValid(info.appIDDesc) || + !DataValidator::IsBundleNameValid(info.bundleName) || !DataValidator::IsAplNumValid(policy.apl) || + !DataValidator::IsDomainValid(policy.domain) || !DataValidator::IsDlpTypeValid(info.dlpType) || + !DataValidator::IsAclExtendedMapSizeValid(policy.aclExtendedMap)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Input param failed"); + return AccessTokenError::ERR_PARAM_INVALID; + } + HapPolicy newPolicy; + TransferHapPolicyParams(policy, newPolicy); + return AccessTokenManagerClient::GetInstance().InitHapToken(info, newPolicy, fullTokenId, result); +} + +FullTokenID AccessTokenKit::AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID) +{ + LOGI(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s, tokenID=%{public}d", + ConstantCommon::EncryptDevId(remoteDeviceID).c_str(), remoteTokenID); +#ifdef DEBUG_API_PERFORMANCE + LOGD(ATM_DOMAIN, ATM_TAG, "Api_performance:start call"); + FullTokenID resID = AccessTokenManagerClient::GetInstance().AllocLocalTokenID(remoteDeviceID, remoteTokenID); + LOGD(ATM_DOMAIN, ATM_TAG, "Api_performance:end call"); + return resID; +#else + return AccessTokenManagerClient::GetInstance().AllocLocalTokenID(remoteDeviceID, remoteTokenID); +#endif +} + +int32_t AccessTokenKit::UpdateHapToken( + AccessTokenIDEx& tokenIdEx, const UpdateHapInfoParams& info, const HapPolicyParams& policy) +{ + HapInfoCheckResult result; + return UpdateHapToken(tokenIdEx, info, policy, result); +} + +int32_t AccessTokenKit::UpdateHapToken(AccessTokenIDEx& tokenIdEx, const UpdateHapInfoParams& info, + const HapPolicyParams& policy, HapInfoCheckResult& result) +{ + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID: %{public}d, isSystemApp: %{public}d, \ +permList: %{public}zu, stateList: %{public}zu, aclExtendedMap: %{public}zu, checkIgnore: %{public}d, \ +isAtomicService: %{public}d", + tokenIdEx.tokenIdExStruct.tokenID, info.isSystemApp, policy.permList.size(), policy.permStateList.size(), + policy.aclExtendedMap.size(), policy.checkIgnore, info.isAtomicService); + if ((tokenIdEx.tokenIdExStruct.tokenID == INVALID_TOKENID) || (!DataValidator::IsAppIDDescValid(info.appIDDesc)) || + (!DataValidator::IsAplNumValid(policy.apl)) || + !DataValidator::IsAclExtendedMapSizeValid(policy.aclExtendedMap)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Input param failed"); + return AccessTokenError::ERR_PARAM_INVALID; + } + HapPolicy newPolicy; + TransferHapPolicyParams(policy, newPolicy); + return AccessTokenManagerClient::GetInstance().UpdateHapToken(tokenIdEx, info, newPolicy, result); +} + +int AccessTokenKit::DeleteToken(AccessTokenID tokenID) +{ + return DeleteToken(tokenID, false); +} + +int AccessTokenKit::DeleteToken(AccessTokenID tokenID, bool isTokenReserved) +{ + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, isTokenReserved=%{public}d.", tokenID, isTokenReserved); + if (tokenID == INVALID_TOKENID) { + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().DeleteToken(tokenID, isTokenReserved); +} + +ATokenTypeEnum AccessTokenKit::GetTokenType(AccessTokenID tokenID) __attribute__((no_sanitize("cfi"))) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid."); + return TOKEN_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetTokenType(tokenID); +} + +ATokenTypeEnum AccessTokenKit::GetTokenTypeFlag(AccessTokenID tokenID) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return TOKEN_INVALID; + } + AccessTokenIDInner* idInner = reinterpret_cast(&tokenID); + return static_cast(idInner->type); +} + +ATokenTypeEnum AccessTokenKit::GetTokenType(FullTokenID tokenID) +{ + AccessTokenID id = tokenID & TOKEN_ID_LOWMASK; + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", id); + if (id == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return TOKEN_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetTokenType(id); +} + +ATokenTypeEnum AccessTokenKit::GetTokenTypeFlag(FullTokenID tokenID) +{ + AccessTokenID id = tokenID & TOKEN_ID_LOWMASK; + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", id); + if (id == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return TOKEN_INVALID; + } + AccessTokenIDInner* idInner = reinterpret_cast(&id); + return static_cast(idInner->type); +} + +AccessTokenID AccessTokenKit::GetHapTokenID( + int32_t userID, const std::string& bundleName, int32_t instIndex) __attribute__((no_sanitize("cfi"))) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "UserID=%{public}d, bundleName=%{public}s, instIndex=%{public}d.", + userID, bundleName.c_str(), instIndex); + if ((!DataValidator::IsUserIdValid(userID)) || (!DataValidator::IsBundleNameValid(bundleName))) { + LOGE(ATM_DOMAIN, ATM_TAG, "Hap token param check failed"); + return INVALID_TOKENID; + } + AccessTokenIDEx tokenIdEx = + AccessTokenManagerClient::GetInstance().GetHapTokenID(userID, bundleName, instIndex); + return tokenIdEx.tokenIdExStruct.tokenID; +} + +AccessTokenIDEx AccessTokenKit::GetHapTokenIDEx(int32_t userID, const std::string& bundleName, int32_t instIndex) +{ + AccessTokenIDEx tokenIdEx = {0}; + LOGD(ATM_DOMAIN, ATM_TAG, "UserID=%{public}d, bundleName=%{public}s, instIndex=%{public}d.", + userID, bundleName.c_str(), instIndex); + if ((!DataValidator::IsUserIdValid(userID)) || (!DataValidator::IsBundleNameValid(bundleName))) { + LOGE(ATM_DOMAIN, ATM_TAG, "Hap token param check failed"); + return tokenIdEx; + } + return AccessTokenManagerClient::GetInstance().GetHapTokenID(userID, bundleName, instIndex); +} + +int32_t AccessTokenKit::GetTokenIDByUserID(int32_t userID, std::unordered_set& tokenIdList) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "UserID=%{public}d.", userID); + if (!DataValidator::IsUserIdValid(userID)) { + LOGE(ATM_DOMAIN, ATM_TAG, "UserID=%{public}d is invalid", userID); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetTokenIDByUserID(userID, tokenIdList); +} + +int AccessTokenKit::GetHapTokenInfo( + AccessTokenID tokenID, HapTokenInfo& hapTokenInfoRes) __attribute__((no_sanitize("cfi"))) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); + if (GetTokenTypeFlag(tokenID) != TOKEN_HAP) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID =%{public}d is invalid", tokenID); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (IsRenderToken(tokenID)) { + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process.", tokenID); + return ERR_TOKENID_NOT_EXIST; + } + + return AccessTokenManagerClient::GetInstance().GetHapTokenInfo(tokenID, hapTokenInfoRes); +} + +int AccessTokenKit::GetNativeTokenInfo( + AccessTokenID tokenID, NativeTokenInfo& nativeTokenInfoRes) __attribute__((no_sanitize("cfi"))) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); + if (GetTokenTypeFlag(tokenID) != TOKEN_NATIVE && GetTokenTypeFlag(tokenID) != TOKEN_SHELL) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID =%{public}d is invalid", tokenID); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetNativeTokenInfo(tokenID, nativeTokenInfoRes); +} + +int32_t AccessTokenKit::GetSelfPermissionStatus(const std::string& permissionName, PermissionOper& status) +{ + if (permissionName.empty() || permissionName.size() > MAX_LENGTH) { + return ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetSelfPermissionStatus(permissionName, status); +} + +PermissionOper AccessTokenKit::GetSelfPermissionsState(std::vector& permList, + PermissionGrantInfo& info) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "PermList.size=%{public}zu.", permList.size()); + return AccessTokenManagerClient::GetInstance().GetSelfPermissionsState(permList, info); +} + +int32_t AccessTokenKit::GetPermissionsStatus(AccessTokenID tokenID, std::vector& permList) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permList.size=%{public}zu.", tokenID, permList.size()); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetPermissionsStatus(tokenID, permList); +} + +int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName, bool crossIpc) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s, crossIpc=%{public}d.", + tokenID, permissionName.c_str(), crossIpc); + if (IsRenderToken(tokenID)) { + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process, perm denied.", tokenID); + return PERMISSION_DENIED; + } + uint32_t code; + if (!TransferPermissionToOpcode(permissionName, code)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName(%{public}s) is not exist.", permissionName.c_str()); + return PERMISSION_DENIED; + } + if (crossIpc || IsNeedCrossIpc(tokenID)) { + return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionName); + } + bool isGranted = false; + int32_t ret = GetPermissionFromKernel(tokenID, code, isGranted); + if (ret != 0) { + return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionName); + } + return isGranted ? PERMISSION_GRANTED : PERMISSION_DENIED; +} + +int AccessTokenKit::VerifyAccessToken( + AccessTokenID callerTokenID, AccessTokenID firstTokenID, const std::string& permissionName, bool crossIpc) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "CallerToken=%{public}d, firstToken=%{public}d, permissionName=%{public}s.", + callerTokenID, firstTokenID, permissionName.c_str()); + int ret = AccessTokenKit::VerifyAccessToken(callerTokenID, permissionName, crossIpc); + if (ret != PERMISSION_GRANTED) { + return ret; + } + if (firstTokenID == FIRSTCALLER_TOKENID_DEFAULT) { + return ret; + } + return AccessTokenKit::VerifyAccessToken(firstTokenID, permissionName, crossIpc); +} + +int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s.", + tokenID, permissionName.c_str()); + if (IsRenderToken(tokenID)) { + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process, perm denied.", tokenID); + return PERMISSION_DENIED; + } + if (IsNeedCrossIpc(tokenID)) { + return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionName); + } + uint32_t code; + if (!TransferPermissionToOpcode(permissionName, code)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName(%{public}s) is not exist.", permissionName.c_str()); + return PERMISSION_DENIED; + } + bool isGranted = false; + int32_t ret = GetPermissionFromKernel(tokenID, code, isGranted); + if (ret != 0) { + return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionName); + } + return isGranted ? PERMISSION_GRANTED : PERMISSION_DENIED; +} + +int AccessTokenKit::VerifyAccessToken( + AccessTokenID callerTokenID, AccessTokenID firstTokenID, const std::string& permissionName) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "CallerToken=%{public}d, firstToken=%{public}d, permissionName=%{public}s.", + callerTokenID, firstTokenID, permissionName.c_str()); + int ret = AccessTokenKit::VerifyAccessToken(callerTokenID, permissionName); + if (ret != PERMISSION_GRANTED) { + return ret; + } + if (firstTokenID == FIRSTCALLER_TOKENID_DEFAULT) { + return ret; + } + return AccessTokenKit::VerifyAccessToken(firstTokenID, permissionName); +} + +int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::vector& permissionList, + std::vector& permStateList, bool crossIpc) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionlist.size=%{public}zu, crossIpc=%{public}d.", + tokenID, permissionList.size(), crossIpc); + permStateList.clear(); + if (IsRenderToken(tokenID)) { + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process, perm denied.", tokenID); + permStateList.resize(permissionList.size(), PERMISSION_DENIED); + return RET_SUCCESS; + } + if (crossIpc || IsNeedCrossIpc(tokenID)) { + return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionList, permStateList); + } + + permStateList.resize(permissionList.size(), PERMISSION_DENIED); + std::vector permListCrossIpc; + std::unordered_map permToState; + for (size_t i = 0; i < permissionList.size(); i++) { + bool isGranted = false; + uint32_t code; + if (!TransferPermissionToOpcode(permissionList[i], code)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName(%{public}s) is not exist.", permissionList[i].c_str()); + permStateList[i] = PERMISSION_DENIED; + continue; + } + int32_t ret = GetPermissionFromKernel(tokenID, code, isGranted); + if (ret != 0) { + permToState[permListCrossIpc.size()] = i; + permListCrossIpc.emplace_back(permissionList[i]); + continue; + } + permStateList[i] = isGranted ? PERMISSION_GRANTED : PERMISSION_DENIED; + } + if (!permListCrossIpc.empty()) { + std::vector permStateCrossIpc; + int ret = AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, + permListCrossIpc, permStateCrossIpc); + if (ret != ERR_OK) { + return ret; + } + for (size_t i = 0; i < permStateCrossIpc.size(); i++) { + if (permToState.find(i) != permToState.end()) { + permStateList[permToState[i]] = permStateCrossIpc[i]; + } + } + } + return ERR_OK; +} + +int AccessTokenKit::GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "PermissionName=%{public}s.", permissionName.c_str()); + if (!DataValidator::IsPermissionNameValid(permissionName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + + PermissionBriefDef briefDef; + if (!GetPermissionBriefDef(permissionName, briefDef)) { + return AccessTokenError::ERR_PERMISSION_NOT_EXIST; + } + + if (briefDef.grantMode == GrantMode::SYSTEM_GRANT) { + ConvertPermissionBriefToDef(briefDef, permissionDefResult); + return 0; + } + + return AccessTokenManagerClient::GetInstance().GetDefPermission(permissionName, permissionDefResult); +} + +int AccessTokenKit::GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, isSystemGrant=%{public}d.", tokenID, isSystemGrant); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + + return AccessTokenManagerClient::GetInstance().GetReqPermissions(tokenID, reqPermList, isSystemGrant); +} + +int AccessTokenKit::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName, uint32_t& flag) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s.", + tokenID, permissionName.c_str()); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (!DataValidator::IsPermissionNameValid(permissionName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetPermissionFlag(tokenID, permissionName, flag); +} + +int AccessTokenKit::GrantPermission( + AccessTokenID tokenID, const std::string& permissionName, uint32_t flag, UpdatePermissionFlag updateFlag) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permissionName=%{public}s, flag=%{public}u.", + tokenID, permissionName.c_str(), flag); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (IsRenderToken(tokenID)) { + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process.", tokenID); + return ERR_TOKENID_NOT_EXIST; + } + if (!DataValidator::IsPermissionNameValid(permissionName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (!DataValidator::IsPermissionFlagValid(flag) || DataValidator::IsPermissionFlagValidForAdmin(flag)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Flag is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GrantPermission(tokenID, permissionName, flag, updateFlag); +} + +int AccessTokenKit::RevokePermission( + AccessTokenID tokenID, const std::string& permissionName, uint32_t flag, + UpdatePermissionFlag updateFlag, bool killProcess) +{ + LOGD(ATM_DOMAIN, ATM_TAG, + "TokenID=%{public}d, permissionName=%{public}s, flag=%{public}u, killProcess=%{public}d.", + tokenID, permissionName.c_str(), flag, killProcess); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "Invalid tokenID"); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (IsRenderToken(tokenID)) { + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process.", tokenID); + return ERR_TOKENID_NOT_EXIST; + } + if (!DataValidator::IsPermissionNameValid(permissionName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Invalid permissionName"); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (!DataValidator::IsPermissionFlagValid(flag) || DataValidator::IsPermissionFlagValidForAdmin(flag)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Invalid flag"); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().RevokePermission( + tokenID, permissionName, flag, updateFlag, killProcess); +} + +int AccessTokenKit::ClearUserGrantedPermissionState(AccessTokenID tokenID) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().ClearUserGrantedPermissionState(tokenID); +} + +int32_t AccessTokenKit::SetPermissionRequestToggleStatus(const std::string& permissionName, uint32_t status, + int32_t userID = 0) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "PermissionName=%{public}s, status=%{public}d, userID=%{public}d.", + permissionName.c_str(), status, userID); + if (!DataValidator::IsPermissionNameValid(permissionName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid."); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (!DataValidator::IsToggleStatusValid(status)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Toggle status is invalid."); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (!DataValidator::IsUserIdValid(userID)) { + LOGE(ATM_DOMAIN, ATM_TAG, "UserID is invalid."); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().SetPermissionRequestToggleStatus(permissionName, status, userID); +} + +int32_t AccessTokenKit::GetPermissionRequestToggleStatus(const std::string& permissionName, uint32_t& status, + int32_t userID = 0) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "PermissionName=%{public}s, userID=%{public}d.", + permissionName.c_str(), userID); + if (!DataValidator::IsPermissionNameValid(permissionName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid."); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (!DataValidator::IsUserIdValid(userID)) { + LOGE(ATM_DOMAIN, ATM_TAG, "UserID is invalid."); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetPermissionRequestToggleStatus(permissionName, status, userID); +} + +int32_t AccessTokenKit::RequestAppPermOnSetting(AccessTokenID tokenID) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "tokenID=%{public}d.", tokenID); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().RequestAppPermOnSetting(tokenID); +} + +int32_t AccessTokenKit::RegisterPermStateChangeCallback( + const std::shared_ptr& callback) +{ + return AccessTokenManagerClient::GetInstance().RegisterPermStateChangeCallback(callback, SYSTEM_REGISTER_TYPE); +} + +int32_t AccessTokenKit::UnRegisterPermStateChangeCallback( + const std::shared_ptr& callback) +{ + return AccessTokenManagerClient::GetInstance().UnRegisterPermStateChangeCallback(callback, SYSTEM_REGISTER_TYPE); +} + +int32_t AccessTokenKit::RegisterSelfPermStateChangeCallback( + const std::shared_ptr& callback) +{ + return AccessTokenManagerClient::GetInstance().RegisterPermStateChangeCallback(callback, SELF_REGISTER_TYPE); +} + +int32_t AccessTokenKit::UnRegisterSelfPermStateChangeCallback( + const std::shared_ptr& callback) +{ + return AccessTokenManagerClient::GetInstance().UnRegisterPermStateChangeCallback(callback, SELF_REGISTER_TYPE); +} + +int32_t AccessTokenKit::GetHapDlpFlag(AccessTokenID tokenID) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return INVALID_DLP_TOKEN_FLAG; + } + AccessTokenIDInner* idInner = reinterpret_cast(&tokenID); + return static_cast(idInner->dlpFlag); +} + +int32_t AccessTokenKit::ReloadNativeTokenInfo() +{ +#ifndef ATM_BUILD_VARIANT_USER_ENABLE + return AccessTokenManagerClient::GetInstance().ReloadNativeTokenInfo(); +#else + return 0; +#endif +} + +int AccessTokenKit::GetHapTokenInfoExtension(AccessTokenID tokenID, HapTokenInfoExt& info) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); + if (GetTokenTypeFlag(tokenID) != TOKEN_HAP) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID =%{public}d is invalid.", tokenID); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (IsRenderToken(tokenID)) { + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID %{public}d is render process.", tokenID); + return ERR_TOKENID_NOT_EXIST; + } + + return AccessTokenManagerClient::GetInstance().GetHapTokenInfoExtension(tokenID, info); +} + +AccessTokenID AccessTokenKit::GetNativeTokenId(const std::string& processName) +{ + if (!DataValidator::IsProcessNameValid(processName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "ProcessName is invalid, processName=%{public}s", processName.c_str()); + return INVALID_TOKENID; + } + return AccessTokenManagerClient::GetInstance().GetNativeTokenId(processName); +} + +#ifdef TOKEN_SYNC_ENABLE +int AccessTokenKit::GetHapTokenInfoFromRemote(AccessTokenID tokenID, HapTokenInfoForSync& hapSync) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return AccessTokenError::ERR_PARAM_INVALID; + } + + return AccessTokenManagerClient::GetInstance().GetHapTokenInfoFromRemote(tokenID, hapSync); +} + +int AccessTokenKit::SetRemoteHapTokenInfo(const std::string& deviceID, + const HapTokenInfoForSync& hapSync) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s, tokenID=%{public}d.", + ConstantCommon::EncryptDevId(deviceID).c_str(), hapSync.baseInfo.tokenID); + return AccessTokenManagerClient::GetInstance().SetRemoteHapTokenInfo(deviceID, hapSync); +} + +int AccessTokenKit::DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s, tokenID=%{public}d.", + ConstantCommon::EncryptDevId(deviceID).c_str(), tokenID); + return AccessTokenManagerClient::GetInstance().DeleteRemoteToken(deviceID, tokenID); +} + +int AccessTokenKit::DeleteRemoteDeviceTokens(const std::string& deviceID) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s.", ConstantCommon::EncryptDevId(deviceID).c_str()); + return AccessTokenManagerClient::GetInstance().DeleteRemoteDeviceTokens(deviceID); +} + +AccessTokenID AccessTokenKit::GetRemoteNativeTokenID(const std::string& deviceID, AccessTokenID tokenID) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "DeviceID=%{public}s., tokenID=%{public}d", + ConstantCommon::EncryptDevId(deviceID).c_str(), tokenID); + return AccessTokenManagerClient::GetInstance().GetRemoteNativeTokenID(deviceID, tokenID); +} + +int32_t AccessTokenKit::RegisterTokenSyncCallback(const std::shared_ptr& syncCallback) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "Call RegisterTokenSyncCallback."); + return AccessTokenManagerClient::GetInstance().RegisterTokenSyncCallback(syncCallback); +} + +int32_t AccessTokenKit::UnRegisterTokenSyncCallback() +{ + LOGD(ATM_DOMAIN, ATM_TAG, "Call UnRegisterTokenSyncCallback."); + return AccessTokenManagerClient::GetInstance().UnRegisterTokenSyncCallback(); +} +#endif + +void AccessTokenKit::DumpTokenInfo(const AtmToolsParamInfo& info, std::string& dumpInfo) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, bundleName=%{public}s, processName=%{public}s.", + info.tokenId, info.bundleName.c_str(), info.processName.c_str()); + + AccessTokenManagerClient::GetInstance().DumpTokenInfo(info, dumpInfo); +} + +int32_t AccessTokenKit::GetVersion(uint32_t& version) +{ + return AccessTokenManagerClient::GetInstance().GetVersion(version); +} + +int32_t AccessTokenKit::SetPermDialogCap(const HapBaseInfo& hapBaseInfo, bool enable) +{ + return AccessTokenManagerClient::GetInstance().SetPermDialogCap(hapBaseInfo, enable); +} + +void AccessTokenKit::GetPermissionManagerInfo(PermissionGrantInfo& info) +{ + AccessTokenManagerClient::GetInstance().GetPermissionManagerInfo(info); +} + +int32_t AccessTokenKit::SetUserPolicy(const std::vector& userPermissionList) +{ +#ifdef SUPPORT_MANAGE_USER_POLICY + LOGI(ATM_DOMAIN, ATM_TAG, "Enter."); + return AccessTokenManagerClient::GetInstance().SetUserPolicy(userPermissionList); +#else + LOGW(ATM_DOMAIN, ATM_TAG, "Not support."); + return ERR_CAPABILITY_NOT_SUPPORT; +#endif +} + +int32_t AccessTokenKit::ClearUserPolicy(const std::vector& permissionList) +{ +#ifdef SUPPORT_MANAGE_USER_POLICY + LOGI(ATM_DOMAIN, ATM_TAG, "Enter."); + return AccessTokenManagerClient::GetInstance().ClearUserPolicy(permissionList); +#else + LOGW(ATM_DOMAIN, ATM_TAG, "Not support."); + return ERR_CAPABILITY_NOT_SUPPORT; +#endif +} + +int32_t AccessTokenKit::UpdatePolicyWhiteList( + AccessTokenID tokenId, const std::string& permission, UpdateWhiteListType type) +{ +#ifdef SUPPORT_MANAGE_USER_POLICY + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}u, permissionName=%{public}s, type=%{public}d.", + tokenId, permission.c_str(), static_cast(type)); + if (!DataValidator::IsTokenIDValid(tokenId) || !DataValidator::IsUpdateWhiteListTypeValid(type)) { + return AccessTokenError::ERR_PARAM_INVALID; + } + if (GetTokenTypeFlag(tokenId) != TOKEN_HAP) { + LOGE(ATM_DOMAIN, ATM_TAG, "Id=%{public}u is not hap.", tokenId); + return AccessTokenError::ERR_PARAM_INVALID; + } + uint32_t permCode = 0; + if (!TransferPermissionToOpcode(permission, permCode)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName=%{public}s is invalid.", permission.c_str()); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().UpdatePolicyWhiteList(tokenId, permCode, type); +#else + LOGW(ATM_DOMAIN, ATM_TAG, "Not support."); + return ERR_CAPABILITY_NOT_SUPPORT; +#endif +} + +int32_t AccessTokenKit::GetPolicyWhiteList(const std::string& permission, std::vector& tokenIdList) +{ +#ifdef SUPPORT_MANAGE_USER_POLICY + tokenIdList.clear(); + uint32_t permCode = 0; + if (!TransferPermissionToOpcode(permission, permCode)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName=%{public}s is invalid.", permission.c_str()); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetPolicyWhiteList(permCode, tokenIdList); +#else + LOGE(ATM_DOMAIN, ATM_TAG, "Not support."); + return ERR_CAPABILITY_NOT_SUPPORT; +#endif +} + +bool AccessTokenKit::IsSystemAppByFullTokenID(uint64_t tokenId) +{ + return (tokenId & SYSTEM_APP_MASK) == SYSTEM_APP_MASK; +} + +uint64_t AccessTokenKit::GetRenderTokenID(uint64_t tokenId) +{ + AccessTokenID id = tokenId & TOKEN_ID_LOWMASK; + if (id == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenID is invalid"); + return tokenId; + } + AccessTokenIDInner* idInner = reinterpret_cast(&id); + idInner->renderFlag = 1; + + id = *reinterpret_cast(idInner); + return static_cast(id); +} + +int32_t AccessTokenKit::GetKernelPermissions( + AccessTokenID tokenID, std::vector& kernelPermList) +{ + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d.", tokenID); + return AccessTokenManagerClient::GetInstance().GetKernelPermissions(tokenID, kernelPermList); +} + +int32_t AccessTokenKit::GetReqPermissionByName( + AccessTokenID tokenID, const std::string& permissionName, std::string& value) +{ + LOGI(ATM_DOMAIN, ATM_TAG, + "TokenID=%{public}d permissionName=%{public}s.", tokenID, permissionName.c_str()); + if (!DataValidator::IsPermissionNameValid(permissionName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid."); + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().GetReqPermissionByName(tokenID, permissionName, value); +} + +#ifdef SECURITY_COMPONENT_ENHANCE_ENABLE +int32_t AccessTokenKit::RegisterSecCompEnhance(const SecCompEnhanceData& enhance) +{ + return AccessTokenManagerClient::GetInstance().RegisterSecCompEnhance(enhance); +} + +int32_t AccessTokenKit::UpdateSecCompEnhance(int32_t pid, uint32_t seqNum) +{ + return AccessTokenManagerClient::GetInstance().UpdateSecCompEnhance(pid, seqNum); +} + +int32_t AccessTokenKit::GetSecCompEnhance(int32_t pid, SecCompEnhanceData& enhance) +{ + return AccessTokenManagerClient::GetInstance().GetSecCompEnhance(pid, enhance); +} +#endif + +bool AccessTokenKit::IsAtomicServiceByFullTokenID(uint64_t tokenId) +{ + LOGD(ATM_DOMAIN, ATM_TAG, "Called, tokenId=%{public}" PRId64, tokenId); + return (tokenId & ATOMIC_SERVICE_MASK) == ATOMIC_SERVICE_MASK; +} + +int32_t AccessTokenKit::SetPermissionStatusWithPolicy( + uint32_t tokenID, const std::vector& permissionList, int32_t status, uint32_t flag) +{ + LOGI(ATM_DOMAIN, ATM_TAG, "TokenID=%{public}d, permList.size=%{public}zu, status=%{public}d, flag=%{public}u.", + tokenID, permissionList.size(), status, flag); + if (tokenID == INVALID_TOKENID) { + LOGE(ATM_DOMAIN, ATM_TAG, "tokenID: %{public}d, TokenID is invalid.", tokenID); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (permissionList.empty()) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionList is empty."); + return AccessTokenError::ERR_PARAM_INVALID; + } + for (const auto& perm : permissionList) { + if (!DataValidator::IsPermissionNameValid(perm)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName is invalid: %{public}s.", perm.c_str()); + return AccessTokenError::ERR_PARAM_INVALID; + } + } + if (!DataValidator::IsPermissionStatusValid(status)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Status: %{public}d, status is invalid.", status); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (!DataValidator::IsPermissionFlagValidForAdmin(flag)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Flag: %{public}u, flag is invalid.", flag); + return AccessTokenError::ERR_PARAM_INVALID; + } + if (!DataValidator::IsListSizeValid(permissionList.size())) { + return AccessTokenError::ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().SetPermissionStatusWithPolicy(tokenID, permissionList, status, flag); +} + +bool AccessTokenKit::TransferPermissionToOpcode(const std::string& permissionName, uint32_t& permCode) +{ + return AccessToken::TransferPermissionToOpcode(permissionName, permCode); +} + +bool AccessTokenKit::TransferOpcodeToPermission(uint32_t permCode, std::string& permissionName) +{ + permissionName = AccessToken::TransferOpcodeToPermission(permCode); + if (permissionName.empty()) { + LOGE(ATM_DOMAIN, ATM_TAG, "Perm(%{public}u) is not exist.", permCode); + return false; + } + return true; +} + +int32_t AccessTokenKit::QueryStatusByPermission(const std::vector& permissionList, + std::vector& permissionInfoList, bool onlyHap) +{ + // Validate permission list size + if (!DataValidator::IsListSizeValid(permissionList.size())) { + return AccessTokenError::ERR_PARAM_INVALID; + } + + // Convert permissionList to permCodeList for IPC + std::vector permCodeList; + permCodeList.reserve(permissionList.size()); + for (const auto& permissionName : permissionList) { + // Validate permission name format + if (!DataValidator::IsPermissionNameValid(permissionName)) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermissionName format is invalid: %{public}s.", permissionName.c_str()); + return AccessTokenError::ERR_PARAM_INVALID; + } + + // Validate permission exists and convert to permCode + uint32_t permCode = 0; + if (!AccessToken::TransferPermissionToOpcode(permissionName, permCode)) { + LOGE(ATM_DOMAIN, ATM_TAG, "Permission %{public}s does not exist.", permissionName.c_str()); + return AccessTokenError::ERR_PERMISSION_NOT_EXIST; + } + permCodeList.emplace_back(permCode); + } + + return AccessTokenManagerClient::GetInstance().QueryStatusByPermission( + permCodeList, permissionInfoList, onlyHap); +} + +int32_t AccessTokenKit::QueryStatusByTokenID(const std::vector& tokenIDList, + std::vector& permissionInfoList) +{ + if (!DataValidator::IsListSizeValid(tokenIDList.size())) { + LOGE(ATM_DOMAIN, ATM_TAG, "TokenIDList size is invalid: %{public}zu", tokenIDList.size()); + return ERR_PARAM_INVALID; + } + return AccessTokenManagerClient::GetInstance().QueryStatusByTokenID(tokenIDList, permissionInfoList); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp index 7c65c00c0..cdf97c09e 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp @@ -1182,6 +1182,37 @@ int32_t AccessTokenManagerClient::ClearUserPolicy(const std::vector } return errCode; } + +int32_t AccessTokenManagerClient::UpdatePolicyWhiteList( + AccessTokenID tokenId, uint32_t permCode, UpdateWhiteListType type) +{ + auto proxy = GetProxy(); + if (proxy == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Proxy is null."); + return AccessTokenError::ERR_SERVICE_ABNORMAL; + } + int32_t errCode = proxy->UpdatePolicyWhiteList(tokenId, permCode, static_cast(type)); + if (errCode != RET_SUCCESS) { + errCode = ConvertResult(errCode); + LOGE(ATM_DOMAIN, ATM_TAG, "Request fail, result: %{public}d.", errCode); + } + return errCode; +} + +int32_t AccessTokenManagerClient::GetPolicyWhiteList(uint32_t permCode, std::vector& tokenIdList) +{ + auto proxy = GetProxy(); + if (proxy == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Proxy is null."); + return AccessTokenError::ERR_SERVICE_ABNORMAL; + } + int32_t errCode = proxy->GetPolicyWhiteList(permCode, tokenIdList); + if (errCode != RET_SUCCESS) { + errCode = ConvertResult(errCode); + LOGE(ATM_DOMAIN, ATM_TAG, "Request fail, result: %{public}d.", errCode); + } + return errCode; +} #endif void AccessTokenManagerClient::ReleaseProxy() diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h index 31521d72d..df6a1e309 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h @@ -115,6 +115,8 @@ public: #ifdef SUPPORT_MANAGE_USER_POLICY int32_t SetUserPolicy(const std::vector& userPermissionList); int32_t ClearUserPolicy(const std::vector& permissionList); + int32_t UpdatePolicyWhiteList(AccessTokenID tokenId, uint32_t permCode, UpdateWhiteListType type); + int32_t GetPolicyWhiteList(uint32_t permCode, std::vector& tokenIdList); #endif #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE int32_t RegisterSecCompEnhance(const SecCompEnhanceData& enhance); diff --git a/interfaces/innerkits/accesstoken/test/tool/BUILD.gn b/interfaces/innerkits/accesstoken/test/tool/BUILD.gn index 113487c12..bf3f74f97 100644 --- a/interfaces/innerkits/accesstoken/test/tool/BUILD.gn +++ b/interfaces/innerkits/accesstoken/test/tool/BUILD.gn @@ -110,10 +110,17 @@ ohos_executable("QueryPermissionStatus") { debug = false } branch_protector_ret = "pac_ret" - sources = [ "query_permission_status.cpp" ] + sources = [ + "query_permission_status.cpp", + "test_common.cpp", + ] + include_dirs = [ + "${access_token_path}/interfaces/innerkits/token_setproc/include", + ] deps = [ "${access_token_path}/interfaces/innerkits/accesstoken:libaccesstoken_sdk", + "${access_token_path}/interfaces/innerkits/token_setproc:libtoken_setproc", ] subsystem_name = "security" @@ -167,6 +174,7 @@ ohos_executable("VerifyAccessToken") { subsystem_name = "security" part_name = "access_token" } + ohos_executable("Relabel") { subsystem_name = "security" part_name = "access_token" @@ -295,6 +303,35 @@ ohos_executable("DeleteHapToken") { part_name = "access_token" } +ohos_executable("UpdateHapToken") { + subsystem_name = "security" + part_name = "access_token" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + branch_protector_ret = "pac_ret" + sources = [ + "update_hap_token.cpp", + "test_common.cpp", + ] + + include_dirs = [ + "${access_token_path}/interfaces/innerkits/nativetoken/include", + "${access_token_path}/interfaces/innerkits/token_setproc/include", + ] + + deps = [ + "${access_token_path}/interfaces/innerkits/accesstoken:libaccesstoken_sdk", + "${access_token_path}/interfaces/innerkits/nativetoken:libnativetoken", + "${access_token_path}/interfaces/innerkits/token_setproc:libtoken_setproc", + ] + + subsystem_name = "security" + part_name = "access_token" +} + group("accesstoken_tool") { deps = [ ":CreateHapToken", @@ -306,6 +343,7 @@ group("accesstoken_tool") { ":Relabel", ":RevokePermission", ":SetPermDialogCap", + ":UpdateHapToken", ":VerifyAccessToken", ] } diff --git a/interfaces/innerkits/accesstoken/test/tool/create_hap_token.cpp b/interfaces/innerkits/accesstoken/test/tool/create_hap_token.cpp index db77abaf3..8ba1835a7 100644 --- a/interfaces/innerkits/accesstoken/test/tool/create_hap_token.cpp +++ b/interfaces/innerkits/accesstoken/test/tool/create_hap_token.cpp @@ -16,25 +16,127 @@ #include #include #include +#include +#include #include "test_common.h" using namespace std; using namespace OHOS::Security::AccessToken; +namespace { +struct CreateHapTokenOptions final { + std::string bundleName; + std::vector reqPerm; + std::vector preAuthPerm; + bool isSystemApp = true; +}; + +void PrintCreateHapTokenHelp() +{ + std::cout << "Help: ./CreateHapToken bundleName [reqPermission ...] [--preauth permission ...]\n" + << "--preauth: switch subsequent arguments to pre-authorized permissions.\n" + << "--system-app : set HapInfoParams.isSystemApp, default true.\n" + << "Note: every --preauth permission must also appear in the req permission list.\n" + << "Example1: ./CreateHapToken com.example.demo ohos.permission.CAMERA " + << "--preauth ohos.permission.CAMERA\n" + << "Example2: ./CreateHapToken com.example.demo --system-app false " + << "ohos.permission.CAMERA\n" + << "Example3: ./CreateHapToken com.example.demo --system-app true " + << "ohos.permission.CAMERA ohos.permission.MICROPHONE " + << "--preauth ohos.permission.MICROPHONE\n" + << std::endl; +} + +bool ValidatePreAuthorizedPermissions(const std::vector& reqPerm, + const std::vector& preAuthPerm) +{ + std::unordered_set reqPermSet(reqPerm.begin(), reqPerm.end()); + for (const auto& permission : preAuthPerm) { + if (reqPermSet.count(permission) == 0) { + std::cout << "CreateHapToken failed, pre-authorized permission must be declared in req permissions: " + << permission << std::endl << std::endl; + return false; + } + } + return true; +} + +bool ParseBoolArg(const std::string& value, bool& result) +{ + if ((value == "true") || (value == "1")) { + result = true; + return true; + } + if ((value == "false") || (value == "0")) { + result = false; + return true; + } + return false; +} + +bool ParseCreateHapTokenArgs(int argc, char* argv[], CreateHapTokenOptions& options) +{ + options.bundleName = argv[1]; // 1: index + bool isPreAuthMode = false; + for (int32_t i = 2; i < argc; ++i) { // 2: start index + std::string arg = argv[i]; + if (arg == "--preauth") { + isPreAuthMode = true; + continue; + } + if (arg == "--system-app") { + if ((i + 1) >= argc) { + std::cout << "CreateHapToken failed, missing value for --system-app" << std::endl << std::endl; + return false; + } + if (!ParseBoolArg(argv[i + 1], options.isSystemApp)) { + std::cout << "CreateHapToken failed, invalid --system-app value: " << argv[i + 1] + << std::endl << std::endl; + return false; + } + ++i; + continue; + } + if (!arg.empty() && arg[0] == '-') { + std::cout << "CreateHapToken failed, unsupported option: " << arg << std::endl << std::endl; + return false; + } + if (isPreAuthMode) { + options.preAuthPerm.emplace_back(arg); + continue; + } + options.reqPerm.emplace_back(arg); + } + return ValidatePreAuthorizedPermissions(options.reqPerm, options.preAuthPerm); +} + +int32_t RunCreateHapToken(const CreateHapTokenOptions& options) +{ + FullTokenID tokenId = GetHapTokenId( + options.bundleName, options.reqPerm, options.preAuthPerm, options.isSystemApp); + if (tokenId == INVALID_TOKENID) { + std::cout << "CreateHapToken failed, bundleName=" << options.bundleName << std::endl << std::endl; + return RET_FAILED; + } + std::cout << "CreateHapToken success, bundleName=" << options.bundleName + << ", isSystemApp=" << options.isSystemApp + << ", permissionCount=" << options.reqPerm.size() + << ", preAuthPermissionCount=" << options.preAuthPerm.size() + << ", tokenId=" << tokenId << std::endl << std::endl; + return RET_SUCCESS; +} +} + int32_t main(int argc, char *argv[]) { if (argc < 2) { // 2: size - std::cout << "Help: ./CreateHapToken bundleName [optional]permission1 permission2 ...\n" << std::endl; + PrintCreateHapTokenHelp(); return 0; } - std::string bundleName = argv[1]; // 1: index - std::vector reqPerm; - for (int32_t i = 2; i < argc; ++i) { // 2: start index - reqPerm.emplace_back(argv[i]); + + CreateHapTokenOptions options; + if (!ParseCreateHapTokenArgs(argc, argv, options)) { + return RET_FAILED; } - FullTokenID tokenId = GetHapTokenId(bundleName, reqPerm); - std::cout << "CreateHapToken success, bundleName=" << bundleName - << ", permissionCount=" << reqPerm.size() - << ", tokenId=" << tokenId << std::endl << std::endl; - return 0; + return RunCreateHapToken(options); } diff --git a/interfaces/innerkits/accesstoken/test/tool/query_permission_status.cpp b/interfaces/innerkits/accesstoken/test/tool/query_permission_status.cpp index c4f783461..955ba07b7 100644 --- a/interfaces/innerkits/accesstoken/test/tool/query_permission_status.cpp +++ b/interfaces/innerkits/accesstoken/test/tool/query_permission_status.cpp @@ -22,6 +22,8 @@ #include #include "accesstoken_kit.h" +#include "test_common.h" +#include "token_setproc.h" using namespace OHOS::Security::AccessToken; @@ -35,7 +37,7 @@ constexpr int32_t MILLISECONDS_PER_SECOND = 1000; constexpr int32_t TM_YEAR_BASE = 1900; constexpr uint64_t INVALID_TIMESTAMP = 0; constexpr int32_t SUCCESS_EXIT_CODE = 0; -constexpr bool QUERY_ONLY_HAP = true; +constexpr bool QUERY_ONLY_HAP = false; constexpr const char* OPTION_PREFIX = "--"; void PrintHelp() @@ -117,6 +119,9 @@ int32_t main(int argc, char* argv[]) return SUCCESS_EXIT_CODE; } + AccessTokenID nativeTokenId = AccessTokenKit::GetNativeTokenId("privacy_service"); + SetSelfTokenID(nativeTokenId); + std::vector permissionInfoList; int32_t ret = RET_SUCCESS; if (tokenID != INVALID_TOKENID) { diff --git a/interfaces/innerkits/accesstoken/test/tool/test_common.cpp b/interfaces/innerkits/accesstoken/test/tool/test_common.cpp index bc12125b2..89c4e94c3 100644 --- a/interfaces/innerkits/accesstoken/test/tool/test_common.cpp +++ b/interfaces/innerkits/accesstoken/test/tool/test_common.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,17 @@ #include "token_setproc.h" using namespace OHOS::Security::AccessToken; +static void AppendUniquePermission(const std::string& permission, std::vector& permissions, + std::unordered_set& uniquePermissions) +{ + if (permission.empty()) { + return; + } + if (uniquePermissions.insert(permission).second) { + permissions.emplace_back(permission); + } +} + void PrintCurrentTime() { std::chrono::milliseconds ms = std::chrono::duration_cast( @@ -62,7 +74,49 @@ AccessTokenID GetNativeTokenId(const std::string& process) return tokenID; } -FullTokenID GetHapTokenId(const std::string& bundle, const std::vector& reqPerm) +void BuildHapPolicyParams(const std::vector& reqPerm, const std::vector& preAuthPerm, + HapPolicyParams& policyParams) +{ + policyParams = { + .apl = APL_NORMAL, + .domain = "accesstoken_test_tool", + }; + + std::vector permissions; + std::unordered_set uniquePermissions; + for (const auto& permission : reqPerm) { + AppendUniquePermission(permission, permissions, uniquePermissions); + } + std::unordered_set uniquePreAuthPerm(preAuthPerm.begin(), preAuthPerm.end()); + + for (const auto& permission : permissions) { + PermissionDef permDefResult; + if (AccessTokenKit::GetDefPermission(permission, permDefResult) != RET_SUCCESS) { + continue; + } + PermissionStateFull permState = { + .permissionName = permission, + .isGeneral = true, + .resDeviceID = {"local3"}, + .grantStatus = {PermissionState::PERMISSION_DENIED}, + .grantFlags = {PermissionFlag::PERMISSION_DEFAULT_FLAG} + }; + policyParams.permStateList.emplace_back(permState); + if (uniquePreAuthPerm.count(permission) != 0) { + PreAuthorizationInfo preAuthInfo = { + .permissionName = permission, + .userCancelable = false, + }; + policyParams.preAuthorizationInfo.emplace_back(preAuthInfo); + } + if (permDefResult.availableLevel > policyParams.apl) { + policyParams.aclRequestedList.emplace_back(permission); + } + } +} + +FullTokenID GetHapTokenId(const std::string& bundle, const std::vector& reqPerm, + const std::vector& preAuthPerm, bool isSystemApp) { uint64_t selfTokenId = GetSelfTokenID(); HapInfoParams infoParams = { @@ -71,31 +125,12 @@ FullTokenID GetHapTokenId(const std::string& bundle, const std::vector policyParams.apl) { - policyParams.aclRequestedList.emplace_back(reqPerm[i]); - } - } + HapPolicyParams policyParams; + BuildHapPolicyParams(reqPerm, preAuthPerm, policyParams); AccessTokenIDEx tokenIdEx = {0}; AccessTokenID mockToken = GetNativeTokenId("foundation"); @@ -104,7 +139,9 @@ FullTokenID GetHapTokenId(const std::string& bundle, const std::vector #include #include "access_token.h" +#include "hap_token_info.h" void PrintCurrentTime(); OHOS::Security::AccessToken::AccessTokenID GetNativeTokenId(const std::string& process); +void BuildHapPolicyParams(const std::vector& reqPerm, + const std::vector& preAuthPerm, OHOS::Security::AccessToken::HapPolicyParams& policyParams); OHOS::Security::AccessToken::FullTokenID GetHapTokenId( - const std::string& bundle, const std::vector& reqPerm); + const std::string& bundle, const std::vector& reqPerm, + const std::vector& preAuthPerm = {}, bool isSystemApp = true); int32_t DeleteHapTokenID(const std::string& bundleName, bool isReservedTokenId); #endif // TEST_TOOL_COMMON_H diff --git a/interfaces/innerkits/accesstoken/test/tool/update_hap_token.cpp b/interfaces/innerkits/accesstoken/test/tool/update_hap_token.cpp new file mode 100644 index 000000000..6e04606e5 --- /dev/null +++ b/interfaces/innerkits/accesstoken/test/tool/update_hap_token.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2026 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 +#include "accesstoken_kit.h" +#include "test_common.h" +#include "token_setproc.h" + +using namespace std; +using namespace OHOS::Security::AccessToken; + +namespace { +struct UpdateHapTokenOptions final { + uint64_t tokenId = 0; + std::vector reqPerm; +}; + +void PrintUpdateHapTokenHelp() +{ + std::cout << "Help: ./UpdateHapToken tokenId [requestPermission ...]\n" + << "Example1: ./UpdateHapToken 281475008495616 ohos.permission.CAMERA\n" + << "Example2: ./UpdateHapToken 281475008495616 " + << "ohos.permission.CAMERA ohos.permission.MICROPHONE\n" + << std::endl; +} + +bool ParseUint64Arg(const std::string& value, uint64_t& result) +{ + if (value.empty()) { + return false; + } + char* end = nullptr; + unsigned long long parsed = std::strtoull(value.c_str(), &end, 10); + if ((end == nullptr) || (*end != '\0')) { + return false; + } + result = static_cast(parsed); + return true; +} + +bool ParseUpdateHapTokenArgs(int argc, char* argv[], UpdateHapTokenOptions& options) +{ + if (!ParseUint64Arg(argv[1], options.tokenId)) { + std::cout << "UpdateHapToken failed, invalid token id: " << argv[1] << std::endl << std::endl; + return false; + } + for (int32_t i = 2; i < argc; ++i) { // 2: start index + std::string arg = argv[i]; + if (!arg.empty() && arg[0] == '-') { + std::cout << "UpdateHapToken failed, unsupported option: " << arg << std::endl << std::endl; + return false; + } + options.reqPerm.emplace_back(arg); + } + return true; +} + +bool LoadUpdateContext(AccessTokenIDEx& tokenIdEx, std::string& bundleName, UpdateHapInfoParams& updateInfoParams) +{ + if (tokenIdEx.tokenIdExStruct.tokenID == INVALID_TOKENID) { + std::cout << "UpdateHapToken failed, tokenId=" << tokenIdEx.tokenIDEx + << ", token not found" << std::endl << std::endl; + return false; + } + + HapTokenInfo hapInfo; + if (AccessTokenKit::GetHapTokenInfo(tokenIdEx.tokenIdExStruct.tokenID, hapInfo) != RET_SUCCESS) { + std::cout << "UpdateHapToken failed, unable to query hap info for tokenId=" << tokenIdEx.tokenIDEx + << std::endl << std::endl; + return false; + } + tokenIdEx.tokenIdExStruct.tokenAttr = hapInfo.tokenAttr; + bundleName = hapInfo.bundleName; + + HapTokenInfoExt hapInfoExt; + if (AccessTokenKit::GetHapTokenInfoExtension(tokenIdEx.tokenIdExStruct.tokenID, hapInfoExt) != RET_SUCCESS) { + std::cout << "UpdateHapToken failed, unable to query hap extension info for bundleName=" << bundleName + << std::endl << std::endl; + return false; + } + + updateInfoParams = { + .appIDDesc = hapInfoExt.appID, + .apiVersion = hapInfo.apiVersion, + .isSystemApp = AccessTokenKit::IsSystemAppByFullTokenID(tokenIdEx.tokenIDEx), + .appDistributionType = "", + }; + return true; +} + +int32_t RunUpdateHapToken(const UpdateHapTokenOptions& options) +{ + uint64_t selfTokenId = GetSelfTokenID(); + AccessTokenID mockToken = GetNativeTokenId("foundation"); + if (mockToken != selfTokenId) { + SetSelfTokenID(mockToken); + } + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx.tokenIDEx = options.tokenId; + + std::string bundleName; + UpdateHapInfoParams updateInfoParams; + if (!LoadUpdateContext(tokenIdEx, bundleName, updateInfoParams)) { + return RET_FAILED; + } + + HapPolicyParams policyParams; + BuildHapPolicyParams(options.reqPerm, {}, policyParams); + + int32_t ret = AccessTokenKit::UpdateHapToken(tokenIdEx, updateInfoParams, policyParams); + SetSelfTokenID(selfTokenId); + + std::cout << "UpdateHapToken end, bundleName=" << bundleName + << ", apiVersion=" << updateInfoParams.apiVersion + << ", permissionCount=" << options.reqPerm.size() + << ", tokenId=" << tokenIdEx.tokenIDEx + << ", ret=" << ret << std::endl << std::endl; + return (ret == RET_SUCCESS) ? RET_SUCCESS : RET_FAILED; +} +} + +int32_t main(int argc, char *argv[]) +{ + if (argc < 2) { // 2: size + PrintUpdateHapTokenHelp(); + return 0; + } + + UpdateHapTokenOptions options; + if (!ParseUpdateHapTokenArgs(argc, argv, options)) { + return RET_FAILED; + } + return RunUpdateHapToken(options); +} diff --git a/interfaces/innerkits/accesstoken/test/unittest/EdmPolicyTest/edm_policy_set_test.cpp b/interfaces/innerkits/accesstoken/test/unittest/EdmPolicyTest/edm_policy_set_test.cpp index 898615e16..486311ee3 100644 --- a/interfaces/innerkits/accesstoken/test/unittest/EdmPolicyTest/edm_policy_set_test.cpp +++ b/interfaces/innerkits/accesstoken/test/unittest/EdmPolicyTest/edm_policy_set_test.cpp @@ -14,6 +14,7 @@ */ #include "edm_policy_set_test.h" +#include #include #include "accesstoken_kit.h" @@ -312,6 +313,9 @@ static void InitUserPolicyTestEnviroment() g_mockUserPolicy1 = MocNativeTokenID("MockUserPolicy1"); g_mockUserPolicy2 = MocNativeTokenID("MockUserPolicy2"); + GTEST_LOG_(INFO) << "Before stop service, pidof accesstoken_service:"; + std::system("pidof accesstoken_service"); + std::system("service_control stop accesstoken_service"); usleep(TIME_500_MS); GTEST_LOG_(INFO) << "stop service, pidof accesstoken_service:"; @@ -380,7 +384,7 @@ HWTEST_F(EdmPolicySetTest, SetUserPolicy002, TestSize.Level1) /** * @tc.name: SetUserPolicy003 - * @tc.desc: SetUserPolicy failed: 1. invalid userId of userList; 2. invalid permission. + * @tc.desc: SetUserPolicy failed with invalid permission or invalid userId. * @tc.type: FUNC * @tc.require:Issue Number */ @@ -405,10 +409,6 @@ HWTEST_F(EdmPolicySetTest, SetUserPolicy003, TestSize.Level1) policy.permissionName = "test"; EXPECT_EQ(AccessTokenError::ERR_PARAM_INVALID, AccessTokenKit::SetUserPolicy({ policy })); - // permission is user_grant - policy.permissionName = "ohos.permission.CAMERA"; - EXPECT_EQ(AccessTokenError::ERR_PARAM_INVALID, AccessTokenKit::SetUserPolicy({ policy })); - // invalid userId policy.permissionName = "ohos.permission.INTERNET"; policy.userPolicyList[0].userId = -1; // -1: invalid userId @@ -1037,6 +1037,516 @@ HWTEST_F(EdmPolicySetTest, ClearUserPolicy004, TestSize.Level1) EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); } +/** + * @tc.name: PolicyWhiteListTest001 + * @tc.desc: UpdatePolicyWhiteList/GetPolicyWhiteList basic function test. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest001, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, + .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID; + + EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId, INTERNET)); + + std::vector tokenIdList; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList)); + EXPECT_TRUE(tokenIdList.empty()); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD)); + EXPECT_EQ(PERMISSION_GRANTED, AccessTokenKit::VerifyAccessToken(tokenId, INTERNET)); + + tokenIdList.clear(); + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList)); + ASSERT_EQ(1u, tokenIdList.size()); + EXPECT_EQ(tokenId, tokenIdList[0]); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE)); + EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId, INTERNET)); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); +} + +/** + * @tc.name: PolicyWhiteListTest002 + * @tc.desc: UpdatePolicyWhiteList failed when caller is not controller. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest002, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, + .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID; + + { + MockNativeToken otherPolicyMock("MockUserPolicy2"); + EXPECT_EQ(ERR_PERM_POLICY_ALREADY_SET_BY_OTHER, + AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD)); + } + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); +} + +/** + * @tc.name: PolicyWhiteListTest003 + * @tc.desc: UpdatePolicyWhiteList returns error when adding duplicated token or deleting absent token. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest003, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, + .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID; + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD)); + EXPECT_EQ(ERR_TOKENID_ALREADY_IN_POLICY_WHITELIST, + AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD)); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE)); + EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_WHITELIST, + AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE)); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); +} + +/** + * @tc.name: PolicyWhiteListTest004 + * @tc.desc: UpdatePolicyWhiteList returns error when user policy is not set. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest004, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID; + + EXPECT_EQ(ERR_PERM_POLICY_NOT_SET, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD)); + + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); +} + +/** + * @tc.name: PolicyWhiteListTest005 + * @tc.desc: UpdatePolicyWhiteList/GetPolicyWhiteList invalid parameter test. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest005, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, + .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID; + + EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::UpdatePolicyWhiteList(INVALID_TOKENID, INTERNET, ADD)); + EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::UpdatePolicyWhiteList(tokenId, "", ADD)); + + std::string invalidPermName(MAX_LENGTH + 1, 'A'); + EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::UpdatePolicyWhiteList(tokenId, invalidPermName, ADD)); + EXPECT_EQ(ERR_PARAM_INVALID, + AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, static_cast(2))); + + std::vector tokenIdList = {tokenId}; + EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::GetPolicyWhiteList("", tokenIdList)); + EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::GetPolicyWhiteList(invalidPermName, tokenIdList)); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); +} + +/** + * @tc.name: PolicyWhiteListTest006 + * @tc.desc: UpdatePolicyWhiteList/GetPolicyWhiteList with multiple tokens. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest006, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, + .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + AccessTokenIDEx fullIdUser2; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + testHapInfo.instIndex = 1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser2)); + AccessTokenID tokenId1 = fullIdUser1.tokenIdExStruct.tokenID; + AccessTokenID tokenId2 = fullIdUser2.tokenIdExStruct.tokenID; + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId1, INTERNET, ADD)); + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId2, INTERNET, ADD)); + + std::vector tokenIdList; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList)); + EXPECT_EQ(2u, tokenIdList.size()); + EXPECT_NE(tokenIdList.end(), std::find(tokenIdList.begin(), tokenIdList.end(), tokenId1)); + EXPECT_NE(tokenIdList.end(), std::find(tokenIdList.begin(), tokenIdList.end(), tokenId2)); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId1, INTERNET, DELETE)); + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList)); + ASSERT_EQ(1u, tokenIdList.size()); + EXPECT_EQ(tokenId2, tokenIdList[0]); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); + testHapInfo.instIndex = 0; + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId1)); + testHapInfo.instIndex = 1; + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId2)); +} + +/** + * @tc.name: PolicyWhiteListTest007 + * @tc.desc: White list only works for target token and is cleared with user policy. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest007, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, + .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + AccessTokenIDEx fullIdUser2; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + testHapInfo.instIndex = 1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser2)); + AccessTokenID tokenId1 = fullIdUser1.tokenIdExStruct.tokenID; + AccessTokenID tokenId2 = fullIdUser2.tokenIdExStruct.tokenID; + + EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId1, INTERNET)); + EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId2, INTERNET)); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId1, INTERNET, ADD)); + EXPECT_EQ(PERMISSION_GRANTED, AccessTokenKit::VerifyAccessToken(tokenId1, INTERNET)); + EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId2, INTERNET)); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); + + std::vector tokenIdList = {tokenId1, tokenId2}; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList)); + EXPECT_TRUE(tokenIdList.empty()); + EXPECT_EQ(PERMISSION_GRANTED, AccessTokenKit::VerifyAccessToken(tokenId1, INTERNET)); + EXPECT_EQ(PERMISSION_GRANTED, AccessTokenKit::VerifyAccessToken(tokenId2, INTERNET)); + + testHapInfo.instIndex = 0; + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId1)); + testHapInfo.instIndex = 1; + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId2)); +} + +/** + * @tc.name: PolicyWhiteListTest008 + * @tc.desc: UpdatePolicyWhiteList returns error when token user is outside controlled userIds. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest008, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, + .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10002; + AccessTokenIDEx fullIdUser2; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser2)); + AccessTokenID tokenId = fullIdUser2.tokenIdExStruct.tokenID; + + EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_USERLIST, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD)); + EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_USERLIST, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE)); + + std::vector tokenIdList; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList)); + EXPECT_TRUE(tokenIdList.empty()); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); +} + +/** + * @tc.name: PolicyWhiteListTest009 + * @tc.desc: GetPolicyWhiteList clears output list when parameter is invalid. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest009, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + std::vector tokenIdList = {INVALID_TOKENID}; + + EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::GetPolicyWhiteList("", tokenIdList)); + EXPECT_TRUE(tokenIdList.empty()); + + tokenIdList = {INVALID_TOKENID}; + std::string invalidPermName(MAX_LENGTH + 1, 'A'); + EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::GetPolicyWhiteList(invalidPermName, tokenIdList)); + EXPECT_TRUE(tokenIdList.empty()); +} + +/** + * @tc.name: PolicyWhiteListTest010 + * @tc.desc: GetPolicyWhiteList returns empty list when whitelist does not exist. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest010, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + std::vector tokenIdList; + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList)); + EXPECT_TRUE(tokenIdList.empty()); +} + +/** + * @tc.name: PolicyWhiteListTest011 + * @tc.desc: UpdatePolicyWhiteList returns error when tokenId is not hap. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest011, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, + .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + AccessTokenID nativeTokenId = AccessTokenKit::GetNativeTokenId("foundation"); + EXPECT_EQ(ERR_PARAM_INVALID, AccessTokenKit::UpdatePolicyWhiteList(nativeTokenId, INTERNET, ADD)); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); +} + +/** + * @tc.name: PolicyWhiteListTest012 + * @tc.desc: GetPolicyWhiteList clears prefilled output list before valid query. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest012, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + std::vector tokenIdList = {INVALID_TOKENID}; + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList)); + EXPECT_TRUE(tokenIdList.empty()); +} + +/** + * @tc.name: PolicyWhiteListTest013 + * @tc.desc: UpdatePolicyWhiteList returns invalid when permission does not exist. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest013, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID; + + EXPECT_EQ(ERR_PARAM_INVALID, + AccessTokenKit::UpdatePolicyWhiteList(tokenId, "ohos.permission.TEST_123", ADD)); + + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); +} + +/** + * @tc.name: PolicyWhiteListTest014 + * @tc.desc: QueryStatusByPermission and QueryStatusByTokenID reflect whitelist final state. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest014, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID; + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD)); + { + MockNativeToken mockNative("privacy_service"); + std::vector permissionInfoList1; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::QueryStatusByPermission({INTERNET}, permissionInfoList1)); + for (const auto& info : permissionInfoList1) { + if (info.tokenID == tokenId) { + EXPECT_EQ(PERMISSION_GRANTED, info.grantStatus); + } + } + + std::vector permissionInfoList2; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::QueryStatusByTokenID({tokenId}, permissionInfoList2)); + for (const auto& info : permissionInfoList2) { + if (info.permissionName == INTERNET) { + EXPECT_EQ(PERMISSION_GRANTED, info.grantStatus); + } + } + } + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE)); + { + MockNativeToken mockNative("privacy_service"); + std::vector permissionInfoList1; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::QueryStatusByPermission({INTERNET}, permissionInfoList1)); + for (const auto& info : permissionInfoList1) { + if (info.tokenID == tokenId) { + EXPECT_EQ(PERMISSION_DENIED, info.grantStatus); + } + } + + std::vector permissionInfoList2; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::QueryStatusByTokenID({tokenId}, permissionInfoList2)); + for (const auto& info : permissionInfoList2) { + if (info.permissionName == INTERNET) { + EXPECT_EQ(PERMISSION_DENIED, info.grantStatus); + } + } + } + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); +} + +class CbCustomizeTestForEdm : public PermStateChangeCallbackCustomize { +public: + explicit CbCustomizeTestForEdm(const PermStateChangeScope &scopeInfo) + : PermStateChangeCallbackCustomize(scopeInfo) + { + } + + ~CbCustomizeTestForEdm() + {} + + virtual void PermStateChangeCallback(PermStateChangeInfo& result) + { + GTEST_LOG_(INFO) << "PermStateChangeCallback permissionName: " << result.permissionName; + GTEST_LOG_(INFO) << "PermStateChangeCallback permStateChangeType: " << result.permStateChangeType; + ready_ = true; + changeCnt_++; + } + + bool ready_ = false; + uint32_t changeCnt_ = 0; +}; + +/** + * @tc.name: PolicyWhiteListTest015 + * @tc.desc: UpdatePolicyWhiteList triggers permission state change callback on add and delete. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListTest015, TestSize.Level1) +{ + MockNativeToken userPolicyMock("MockUserPolicy1"); + UserPermissionPolicy policy = { + .permissionName = INTERNET, + .userPolicyList = {{ .userId = MOCK_USER_ID_10001, .isRestricted = true }} + }; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::SetUserPolicy({ policy })); + + HapInfoParams testHapInfo = g_testHapInfoParams; + testHapInfo.userID = MOCK_USER_ID_10001; + AccessTokenIDEx fullIdUser1; + EXPECT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(testHapInfo, g_testPolicyParams, fullIdUser1)); + AccessTokenID tokenId = fullIdUser1.tokenIdExStruct.tokenID; + EXPECT_EQ(PERMISSION_DENIED, AccessTokenKit::VerifyAccessToken(tokenId, INTERNET)); + + PermStateChangeScope scopeInfo; + scopeInfo.permList = { INTERNET }; + scopeInfo.tokenIDs = { tokenId }; + auto callbackPtr = std::make_shared(scopeInfo); + ASSERT_EQ(RET_SUCCESS, AccessTokenKit::RegisterPermStateChangeCallback(callbackPtr)); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, ADD)); + usleep(500000); // 500000us = 0.5s + EXPECT_TRUE(callbackPtr->ready_); + EXPECT_EQ(1u, callbackPtr->changeCnt_); + + callbackPtr->ready_ = false; + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UpdatePolicyWhiteList(tokenId, INTERNET, DELETE)); + usleep(500000); // 500000us = 0.5s + EXPECT_TRUE(callbackPtr->ready_); + EXPECT_EQ(2u, callbackPtr->changeCnt_); + + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::UnRegisterPermStateChangeCallback(callbackPtr)); + EXPECT_EQ(RET_SUCCESS, AccessTokenKit::ClearUserPolicy({ INTERNET })); + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); +} + /** * @tc.name: UserPolicyTestForInitHap * @tc.desc: Set the authorization status based on the user policy during new hap installation @@ -1135,28 +1645,6 @@ HWTEST_F(EdmPolicySetTest, UserPolicyTestForUpdateHap, TestSize.Level1) EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenId)); } -class CbCustomizeTestForEdm : public PermStateChangeCallbackCustomize { -public: - explicit CbCustomizeTestForEdm(const PermStateChangeScope &scopeInfo) - : PermStateChangeCallbackCustomize(scopeInfo) - { - } - - ~CbCustomizeTestForEdm() - {} - - virtual void PermStateChangeCallback(PermStateChangeInfo& result) - { - GTEST_LOG_(INFO) << "PermStateChangeCallback permissionName: " << result.permissionName; - GTEST_LOG_(INFO) << "PermStateChangeCallback permStateChangeType: " << result.permStateChangeType; - ready_ = true; - changeCnt_++; - } - - bool ready_ = false; - uint32_t changeCnt_ = 0; -}; - /** * @tc.name: UserPolicyTestForRemove * @tc.desc: UpdateHapToken and check permission status with user policy. @@ -1266,6 +1754,21 @@ HWTEST_F(EdmPolicySetTest, SetUserPolicy001, TestSize.Level0) EXPECT_EQ(AccessTokenError::ERR_CAPABILITY_NOT_SUPPORT, AccessTokenKit::SetUserPolicy(permPolicyListEmpty)); EXPECT_EQ(AccessTokenError::ERR_CAPABILITY_NOT_SUPPORT, AccessTokenKit::ClearUserPolicy({ INTERNET })); } + +/** + * @tc.name: PolicyWhiteListNotSupport001 + * @tc.desc: Not support to UpdatePolicyWhiteList/GetPolicyWhiteList. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(EdmPolicySetTest, PolicyWhiteListNotSupport001, TestSize.Level0) +{ + std::vector tokenIdList; + EXPECT_EQ(AccessTokenError::ERR_CAPABILITY_NOT_SUPPORT, + AccessTokenKit::UpdatePolicyWhiteList(INVALID_TOKENID, INTERNET, ADD)); + EXPECT_EQ(AccessTokenError::ERR_CAPABILITY_NOT_SUPPORT, + AccessTokenKit::GetPolicyWhiteList(INTERNET, tokenIdList)); +} #endif /** @@ -2218,4 +2721,4 @@ HWTEST_F(EdmPolicySetTest, EdmTestUpdateHapToken003, TestSize.Level0) } } } -} \ No newline at end of file +} diff --git a/interfaces/innerkits/accesstoken/test/unittest/PermDenyTest/accesstoken_deny_test.cpp b/interfaces/innerkits/accesstoken/test/unittest/PermDenyTest/accesstoken_deny_test.cpp index b2d453038..39ff8b6d8 100644 --- a/interfaces/innerkits/accesstoken/test/unittest/PermDenyTest/accesstoken_deny_test.cpp +++ b/interfaces/innerkits/accesstoken/test/unittest/PermDenyTest/accesstoken_deny_test.cpp @@ -115,6 +115,47 @@ HWTEST_F(AccessTokenDenyTest, SetUserPolicy001, TestSize.Level0) int32_t ret = AccessTokenKit::SetUserPolicy(permPolicyList); EXPECT_EQ(ret, AccessTokenError::ERR_PERMISSION_DENIED); } + +/** + * @tc.name: UpdatePolicyWhiteList001 + * @tc.desc: UpdatePolicyWhiteList without authorized. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(AccessTokenDenyTest, UpdatePolicyWhiteList001, TestSize.Level0) +{ + setuid(g_selfUid); + HapPolicyParams policyPrams = { + .apl = APL_NORMAL, + .domain = "test.domain", + }; + AccessTokenIDEx tokenIdEx = {0}; + ASSERT_EQ(RET_SUCCESS, TestCommon::AllocTestHapToken(g_InfoParms, policyPrams, tokenIdEx)); + ASSERT_NE(INVALID_TOKENID, tokenIdEx.tokenIdExStruct.tokenID); + EXPECT_EQ(RET_SUCCESS, SetSelfTokenID(g_testTokenIDEx.tokenIDEx)); + setuid(1234); // 1234: UID + + int32_t ret = AccessTokenKit::UpdatePolicyWhiteList( + tokenIdEx.tokenIdExStruct.tokenID, "ohos.permission.INTERNET", ADD); + EXPECT_EQ(ret, AccessTokenError::ERR_PERMISSION_DENIED); + + setuid(g_selfUid); + EXPECT_EQ(RET_SUCCESS, SetSelfTokenID(g_selfTokenId)); + EXPECT_EQ(RET_SUCCESS, TestCommon::DeleteTestHapToken(tokenIdEx.tokenIdExStruct.tokenID)); +} + +/** + * @tc.name: GetPolicyWhiteList001 + * @tc.desc: GetPolicyWhiteList without authorized. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(AccessTokenDenyTest, GetPolicyWhiteList001, TestSize.Level0) +{ + std::vector tokenIdList; + int32_t ret = AccessTokenKit::GetPolicyWhiteList("ohos.permission.INTERNET", tokenIdList); + EXPECT_EQ(ret, AccessTokenError::ERR_PERMISSION_DENIED); +} #endif /** @@ -548,4 +589,3 @@ HWTEST_F(AccessTokenDenyTest, GetKernelPermissions001, TestSize.Level0) } // namespace AccessToken } // namespace Security } // namespace OHOS - diff --git a/interfaces/innerkits/accesstoken/test/unittest/ProxyMockTest/accesstoken_mock_test.cpp b/interfaces/innerkits/accesstoken/test/unittest/ProxyMockTest/accesstoken_mock_test.cpp index 3741d15b9..0e58faff0 100644 --- a/interfaces/innerkits/accesstoken/test/unittest/ProxyMockTest/accesstoken_mock_test.cpp +++ b/interfaces/innerkits/accesstoken/test/unittest/ProxyMockTest/accesstoken_mock_test.cpp @@ -734,6 +734,31 @@ HWTEST_F(AccessTokenMockTest, ClearUserPolicy001, TestSize.Level4) permissionList.emplace_back("ohos.permission.INTERNET"); ASSERT_EQ(AccessTokenError::ERR_SERVICE_ABNORMAL, AccessTokenKit::ClearUserPolicy(permissionList)); } + +/** + * @tc.name: UpdatePolicyWhiteList001 + * @tc.desc: UpdatePolicyWhiteList with proxy is null + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(AccessTokenMockTest, UpdatePolicyWhiteList001, TestSize.Level4) +{ + ASSERT_EQ(AccessTokenError::ERR_SERVICE_ABNORMAL, + AccessTokenKit::UpdatePolicyWhiteList(g_testTokenId, "ohos.permission.INTERNET", ADD)); +} + +/** + * @tc.name: GetPolicyWhiteList001 + * @tc.desc: GetPolicyWhiteList with proxy is null + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(AccessTokenMockTest, GetPolicyWhiteList001, TestSize.Level4) +{ + std::vector tokenIdList; + ASSERT_EQ(AccessTokenError::ERR_SERVICE_ABNORMAL, + AccessTokenKit::GetPolicyWhiteList("ohos.permission.INTERNET", tokenIdList)); +} #endif /** diff --git a/services/accesstokenmanager/idl/IAccessTokenManager.idl b/services/accesstokenmanager/idl/IAccessTokenManager.idl index d048e734d..a13885468 100644 --- a/services/accesstokenmanager/idl/IAccessTokenManager.idl +++ b/services/accesstokenmanager/idl/IAccessTokenManager.idl @@ -79,8 +79,12 @@ interface OHOS.Security.AccessToken.IAccessTokenManager{ [ipccode 58] void GetVersion([out] unsigned int version); [ipccode 59] void GetPermissionManagerInfo([out] PermissionGrantInfoParcel infoParcel); - [ipccode 61, macrodef SUPPORT_MANAGE_USER_POLICY] void SetUserPolicy([in] List userPermissionList); - [ipccode 63, macrodef SUPPORT_MANAGE_USER_POLICY] void ClearUserPolicy([in] List permissionList); + [ipccode 60, macrodef SUPPORT_MANAGE_USER_POLICY] void SetUserPolicy([in] List userPermissionList); + [ipccode 61, macrodef SUPPORT_MANAGE_USER_POLICY] void ClearUserPolicy([in] List permissionList); + [ipccode 62, macrodef SUPPORT_MANAGE_USER_POLICY] void UpdatePolicyWhiteList( + [in] unsigned int tokenId, [in] unsigned int permCode, [in] int type); + [ipccode 63, macrodef SUPPORT_MANAGE_USER_POLICY] void GetPolicyWhiteList( + [in] unsigned int permCode, [out] List tokenIdList); [ipccode 64] void GetHapTokenInfoExtension([in] unsigned int tokenID, [out] HapTokenInfoParcel hapTokenInfoRes, [out] String appID); [ipccode 65] void RegisterSelfPermStateChangeCallback([in] PermStateChangeScopeParcel scope, [in] IRemoteObject cb); [ipccode 66] void UnRegisterSelfPermStateChangeCallback([in] IRemoteObject cb); diff --git a/services/accesstokenmanager/main/cpp/include/permission/accesstoken_info_manager.h b/services/accesstokenmanager/main/cpp/include/permission/accesstoken_info_manager.h index 66ea405c2..6487b29ff 100644 --- a/services/accesstokenmanager/main/cpp/include/permission/accesstoken_info_manager.h +++ b/services/accesstokenmanager/main/cpp/include/permission/accesstoken_info_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2025 Huawei Device Co., Ltd. + * Copyright (c) 2021-2026 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 @@ -96,6 +96,8 @@ public: #ifdef SUPPORT_MANAGE_USER_POLICY int32_t SetUserPolicy(const std::vector& userPermissionList); int32_t ClearUserPolicy(const std::vector& permissionList); + int32_t UpdatePolicyWhiteList(AccessTokenID tokenId, uint32_t permCode, UpdateWhiteListType type); + int32_t GetPolicyWhiteList(uint32_t permCode, std::vector& tokenIdList); #endif bool GetPermDialogCap(AccessTokenID tokenID); void ClearUserGrantedPermissionState(AccessTokenID tokenID); @@ -181,8 +183,10 @@ private: void DumpAllNativeTokenName(std::string& dumpInfo); #ifdef SUPPORT_MANAGE_USER_POLICY void UpdatePermissionStateToKernel(uint32_t permCode, const std::map& changedUserList); + void UpdatePermissionStateToKernel(AccessTokenID tokenId, uint32_t permCode, bool isActive); void GetHapTokenInfoListByUserId( const std::map& changedUserList, std::map& tokenIdList); + bool IsInPolicyWhiteList(AccessTokenID tokenId, uint32_t permCode) const; #endif int32_t AddPermRequestToggleStatusToDb(int32_t userID, const std::string& permissionName, int32_t status); int32_t FindPermRequestToggleStatusFromDb(int32_t userID, const std::string& permissionName); @@ -217,8 +221,9 @@ private: #ifdef SUPPORT_MANAGE_USER_POLICY std::shared_mutex userPolicyLock_; - std::map> userPermPolicyList_; // key-permCode + std::map> userPermPolicyList_; // key-permCode, value-userid std::map policyController_; // key-permCode, value-callerToken + std::map> policyWhiteList_; // key-permCode, value-tokenId #endif std::shared_ptr tokenMonitor_; diff --git a/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h index b6865c96d..ba8517310 100644 --- a/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h +++ b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h @@ -133,6 +133,8 @@ public: #ifdef SUPPORT_MANAGE_USER_POLICY int32_t SetUserPolicy(const std::vector& userPermissionList) override; int32_t ClearUserPolicy(const std::vector& permissionList) override; + int32_t UpdatePolicyWhiteList(AccessTokenID tokenId, uint32_t permCode, int32_t type) override; + int32_t GetPolicyWhiteList(uint32_t permCode, std::vector& tokenIdList) override; #endif int32_t DumpTokenInfo(const AtmToolsParamInfoParcel& infoParcel, std::string& dumpInfo) override; int32_t GetVersion(uint32_t& version) override; diff --git a/services/accesstokenmanager/main/cpp/src/permission/accesstoken_info_manager.cpp b/services/accesstokenmanager/main/cpp/src/permission/accesstoken_info_manager.cpp index e7670f391..62af74b87 100644 --- a/services/accesstokenmanager/main/cpp/src/permission/accesstoken_info_manager.cpp +++ b/services/accesstokenmanager/main/cpp/src/permission/accesstoken_info_manager.cpp @@ -1593,8 +1593,13 @@ bool AccessTokenInfoManager::IsPermissionRestrictedByUserPolicy(AccessTokenID id } std::shared_lock infoGuard(this->userPolicyLock_); auto iter = userPermPolicyList_.find(permCode); - if (iter != userPermPolicyList_.end() && - std::find(iter->second.begin(), iter->second.end(), infoPtr->GetUserID()) != iter->second.end()) { + if (iter == userPermPolicyList_.end()) { + return false; + } + if (IsInPolicyWhiteList(id, permCode)) { + return false; + } + if (std::find(iter->second.begin(), iter->second.end(), infoPtr->GetUserID()) != iter->second.end()) { std::string permissionName = TransferOpcodeToPermission(permCode); LOGW(ATM_DOMAIN, ATM_TAG, "Perm %{public}s of %{public}u is restricted.", permissionName.c_str(), id); return true; @@ -1725,15 +1730,36 @@ void AccessTokenInfoManager::UpdatePermissionStateToKernel( return; } +void AccessTokenInfoManager::UpdatePermissionStateToKernel(AccessTokenID tokenId, uint32_t permCode, bool isActive) +{ + std::map refreshedPermList; + HapTokenInfoInner::RefreshPermStateToKernel(tokenId, permCode, isActive, refreshedPermList); + if (!refreshedPermList.empty()) { + PermissionManager::GetInstance().ParamUpdate(std::string(), 0, true); + } + for (const auto& perm : refreshedPermList) { + LOGI(ATM_DOMAIN, ATM_TAG, "Perm %{public}s refreshed by whitelist, isActive %{public}d.", + perm.first.c_str(), perm.second); + PermStateChangeType change = perm.second ? + PermStateChangeType::STATE_CHANGE_GRANTED : PermStateChangeType::STATE_CHANGE_REVOKED; + CallbackManager::GetInstance().ExecuteCallbackAsync(tokenId, perm.first, change); + } +} + +bool AccessTokenInfoManager::IsInPolicyWhiteList(AccessTokenID tokenId, uint32_t permCode) const +{ + auto iter = policyWhiteList_.find(permCode); + return (iter != policyWhiteList_.end()) && (iter->second.find(tokenId) != iter->second.end()); +} + int32_t AccessTokenInfoManager::SetUserPolicy(const std::vector& userPermissionList) { AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID(); std::vector userPolist; std::unique_lock infoGuard(this->userPolicyLock_); for (const auto& policy : userPermissionList) { - PermissionBriefDef briefDef; uint32_t code; - if (!GetPermissionBriefDef(policy.permissionName, briefDef, code) || (briefDef.grantMode != SYSTEM_GRANT)) { + if (!TransferPermissionToOpcode(policy.permissionName, code)) { LOGE(ATM_DOMAIN, ATM_TAG, "Permission(%{public}s) is invalid.", policy.permissionName.c_str()); return AccessTokenError::ERR_PARAM_INVALID; } @@ -1806,11 +1832,83 @@ int32_t AccessTokenInfoManager::ClearUserPolicy(const std::vector& changedUserList[userId] = false; } UpdatePermissionStateToKernel(code, changedUserList); + policyWhiteList_.erase(code); userPermPolicyList_.erase(code); policyController_.erase(code); } return RET_SUCCESS; } + +int32_t AccessTokenInfoManager::UpdatePolicyWhiteList( + AccessTokenID tokenId, uint32_t permCode, UpdateWhiteListType type) +{ + std::shared_ptr infoPtr = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenId); + if (infoPtr == nullptr) { + LOGE(ATM_DOMAIN, ATM_TAG, "Token %{public}u is invalid.", tokenId); + return AccessTokenError::ERR_PARAM_INVALID; + } + + std::string permission = TransferOpcodeToPermission(permCode); + AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID(); + bool isActive = true; + { + std::unique_lock infoGuard(this->userPolicyLock_); + if (userPermPolicyList_.find(permCode) == userPermPolicyList_.end()) { + LOGE(ATM_DOMAIN, ATM_TAG, "Permission(%{public}s) policy is not set.", permission.c_str()); + return AccessTokenError::ERR_PERM_POLICY_NOT_SET; + } + if (policyController_.find(permCode) != policyController_.end() && policyController_[permCode] != callerToken) { + LOGE(ATM_DOMAIN, ATM_TAG, "Permission(%{public}s) is already set by %{public}u, currCaller(%{public}u).", + permission.c_str(), policyController_[permCode], callerToken); + return AccessTokenError::ERR_PERM_POLICY_ALREADY_SET_BY_OTHER; + } + bool isRestricted = std::find(userPermPolicyList_[permCode].begin(), userPermPolicyList_[permCode].end(), + infoPtr->GetUserID()) != userPermPolicyList_[permCode].end(); + if (!isRestricted) { + LOGE(ATM_DOMAIN, ATM_TAG, "Token %{public}u userId %{public}d is not controlled by perm %{public}s.", + tokenId, infoPtr->GetUserID(), permission.c_str()); + return AccessTokenError::ERR_TOKENID_NOT_IN_POLICY_USERLIST; + } + + auto& whiteList = policyWhiteList_[permCode]; + if (type == ADD) { + if (whiteList.find(tokenId) != whiteList.end()) { + LOGE(ATM_DOMAIN, ATM_TAG, "Token %{public}u is already in whitelist.", tokenId); + return AccessTokenError::ERR_TOKENID_ALREADY_IN_POLICY_WHITELIST; + } + whiteList.insert(tokenId); + } else { + if (whiteList.find(tokenId) == whiteList.end()) { + LOGE(ATM_DOMAIN, ATM_TAG, "Token %{public}u is not in whitelist.", tokenId); + return AccessTokenError::ERR_TOKENID_NOT_IN_POLICY_WHITELIST; + } + whiteList.erase(tokenId); + if (whiteList.empty()) { + policyWhiteList_.erase(permCode); + } + } + isActive = !isRestricted || IsInPolicyWhiteList(tokenId, permCode); + } + UpdatePermissionStateToKernel(tokenId, permCode, isActive); + return RET_SUCCESS; +} + +int32_t AccessTokenInfoManager::GetPolicyWhiteList(uint32_t permCode, std::vector& tokenIdList) +{ + tokenIdList.clear(); + std::string permission = TransferOpcodeToPermission(permCode); + if (permission.empty()) { + LOGE(ATM_DOMAIN, ATM_TAG, "PermCode %{public}u does not exist.", permCode); + return AccessTokenError::ERR_PERMISSION_NOT_EXIST; + } + + std::shared_lock infoGuard(this->userPolicyLock_); + auto iter = policyWhiteList_.find(permCode); + if (iter != policyWhiteList_.end()) { + tokenIdList.assign(iter->second.begin(), iter->second.end()); + } + return RET_SUCCESS; +} #endif bool AccessTokenInfoManager::GetPermDialogCap(AccessTokenID 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 c2f21f66e..ea12fd8e9 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp @@ -24,7 +24,6 @@ #include "accesstoken_common_log.h" #include "accesstoken_dfx_define.h" #include "accesstoken_id_manager.h" -#include "accesstoken_service_ipc_interface_code.h" #include "constant_common.h" #include "data_usage_dfx.h" #include "data_validator.h" @@ -1285,18 +1284,18 @@ int32_t AccessTokenManagerService::GetPermissionManagerInfo(PermissionGrantInfoP int32_t AccessTokenManagerService::SetUserPolicy(const std::vector& userPermissionList) { LOGI(ATM_DOMAIN, ATM_TAG, "CallerPid %{public}d.", IPCSkeleton::GetCallingPid()); - uint32_t callingToken = IPCSkeleton::GetCallingTokenID(); - if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) { - LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken); - return AccessTokenError::ERR_PERMISSION_DENIED; - } - size_t policySize = userPermissionList.size(); if ((policySize == 0) || (policySize > MAX_USER_POLICY_SIZE)) { LOGE(ATM_DOMAIN, ATM_TAG, "PolicySize %{public}zu is invalid.", policySize); return AccessTokenError::ERR_PARAM_INVALID; } + uint32_t callingToken = IPCSkeleton::GetCallingTokenID(); + if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) { + LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken); + return AccessTokenError::ERR_PERMISSION_DENIED; + } + std::vector policyList; for (const auto& permPolicyIdl : userPermissionList) { UserPermissionPolicy permPolicy; @@ -1315,19 +1314,60 @@ int32_t AccessTokenManagerService::SetUserPolicy(const std::vector& permissionList) { LOGI(ATM_DOMAIN, ATM_TAG, "CallerPid %{public}d.", IPCSkeleton::GetCallingPid()); - uint32_t callingToken = IPCSkeleton::GetCallingTokenID(); - if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) { - LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken); - return AccessTokenError::ERR_PERMISSION_DENIED; - } size_t permSize = permissionList.size(); if ((permSize == 0) || (permSize > MAX_USER_POLICY_SIZE)) { LOGE(ATM_DOMAIN, ATM_TAG, "PermSize %{public}zu is invalid.", permSize); return AccessTokenError::ERR_PARAM_INVALID; } + uint32_t callingToken = IPCSkeleton::GetCallingTokenID(); + if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) { + LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken); + return AccessTokenError::ERR_PERMISSION_DENIED; + } + return AccessTokenInfoManager::GetInstance().ClearUserPolicy(permissionList); } + +int32_t AccessTokenManagerService::UpdatePolicyWhiteList(AccessTokenID tokenId, uint32_t permCode, int32_t type) +{ + LOGI(ATM_DOMAIN, ATM_TAG, "CallerPid %{public}d.", IPCSkeleton::GetCallingPid()); + auto updateType = static_cast(type); + if (!DataValidator::IsTokenIDValid(tokenId) || !DataValidator::IsUpdateWhiteListTypeValid(updateType)) { + return AccessTokenError::ERR_PARAM_INVALID; + } + if (this->GetTokenType(tokenId) != TOKEN_HAP) { + LOGE(ATM_DOMAIN, ATM_TAG, "Id=%{public}u is not hap.", tokenId); + return AccessTokenError::ERR_PARAM_INVALID; + } + std::string permission = TransferOpcodeToPermission(permCode); + if (permission.empty()) { + LOGE(ATM_DOMAIN, ATM_TAG, "Invalid permCode: %{public}u.", permCode); + return AccessTokenError::ERR_PARAM_INVALID; + } + uint32_t callingToken = IPCSkeleton::GetCallingTokenID(); + if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) { + LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken); + return AccessTokenError::ERR_PERMISSION_DENIED; + } + return AccessTokenInfoManager::GetInstance().UpdatePolicyWhiteList(tokenId, permCode, updateType); +} + +int32_t AccessTokenManagerService::GetPolicyWhiteList(uint32_t permCode, std::vector& tokenIdList) +{ + LOGI(ATM_DOMAIN, ATM_TAG, "CallerPid %{public}d.", IPCSkeleton::GetCallingPid()); + std::string permission = TransferOpcodeToPermission(permCode); + if (permission.empty()) { + LOGE(ATM_DOMAIN, ATM_TAG, "Invalid permCode: %{public}u.", permCode); + return AccessTokenError::ERR_PARAM_INVALID; + } + uint32_t callingToken = IPCSkeleton::GetCallingTokenID(); + if (VerifyAccessToken(callingToken, MANAGE_USER_POLICY) == PERMISSION_DENIED) { + LOGE(ATM_DOMAIN, ATM_TAG, "Perm denied(tokenID %{public}d).", callingToken); + return AccessTokenError::ERR_PERMISSION_DENIED; + } + return AccessTokenInfoManager::GetInstance().GetPolicyWhiteList(permCode, tokenIdList); +} #endif void AccessTokenManagerService::AccessTokenServiceParamSet() const diff --git a/services/accesstokenmanager/test/unittest/permission/token_info_manager_test.cpp b/services/accesstokenmanager/test/unittest/permission/token_info_manager_test.cpp index c0eb13c55..21a8891a9 100644 --- a/services/accesstokenmanager/test/unittest/permission/token_info_manager_test.cpp +++ b/services/accesstokenmanager/test/unittest/permission/token_info_manager_test.cpp @@ -121,6 +121,70 @@ static PermissionStatus g_permState = { .grantFlag = PermissionFlag::PERMISSION_DEFAULT_FLAG }; +#ifdef SUPPORT_MANAGE_USER_POLICY +class PolicyWhiteListStateGuard { +public: + PolicyWhiteListStateGuard(AccessTokenInfoManager& manager, uint32_t permCode) + : manager_(manager), permCode_(permCode) + { + std::unique_lock lock(manager_.userPolicyLock_); + auto userIter = manager_.userPermPolicyList_.find(permCode_); + if (userIter != manager_.userPermPolicyList_.end()) { + hasUserList_ = true; + oldUserList_ = userIter->second; + } + auto whiteIter = manager_.policyWhiteList_.find(permCode_); + if (whiteIter != manager_.policyWhiteList_.end()) { + hasWhiteList_ = true; + oldWhiteList_ = whiteIter->second; + } + auto controllerIter = manager_.policyController_.find(permCode_); + if (controllerIter != manager_.policyController_.end()) { + hasController_ = true; + oldController_ = controllerIter->second; + } + } + + ~PolicyWhiteListStateGuard() + { + std::unique_lock lock(manager_.userPolicyLock_); + if (hasUserList_) { + manager_.userPermPolicyList_[permCode_] = oldUserList_; + } else { + manager_.userPermPolicyList_.erase(permCode_); + } + if (hasWhiteList_) { + manager_.policyWhiteList_[permCode_] = oldWhiteList_; + } else { + manager_.policyWhiteList_.erase(permCode_); + } + if (hasController_) { + manager_.policyController_[permCode_] = oldController_; + } else { + manager_.policyController_.erase(permCode_); + } + } + + void SetControlledUser(int32_t userId, AccessTokenID controller) + { + std::unique_lock lock(manager_.userPolicyLock_); + manager_.userPermPolicyList_[permCode_] = { userId }; + manager_.policyController_[permCode_] = controller; + manager_.policyWhiteList_.erase(permCode_); + } + +private: + AccessTokenInfoManager& manager_; + uint32_t permCode_; + std::vector oldUserList_; + std::unordered_set oldWhiteList_; + AccessTokenID oldController_ = INVALID_TOKENID; + bool hasUserList_ = false; + bool hasWhiteList_ = false; + bool hasController_ = false; +}; +#endif + #ifdef TOKEN_SYNC_ENABLE static uint32_t tokenSyncId_ = 0; static const int32_t FAKE_SYNC_RET = 0xabcdef; @@ -2477,6 +2541,71 @@ HWTEST_F(TokenInfoManagerTest, IsPermissionRestrictedByUserPolicy001, TestSize.L #endif } +#ifdef SUPPORT_MANAGE_USER_POLICY +/** + * @tc.name: UpdatePolicyWhiteList001 + * @tc.desc: UpdatePolicyWhiteList returns error when token user is outside controlled user list. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TokenInfoManagerTest, UpdatePolicyWhiteList001, TestSize.Level0) +{ + AccessTokenIDEx tokenIdEx = {0}; + std::vector undefValues; + ASSERT_EQ(RET_SUCCESS, AccessTokenInfoManager::GetInstance().CreateHapTokenInfo( + g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams1, tokenIdEx, undefValues)); + AccessTokenID tokenId = tokenIdEx.tokenIdExStruct.tokenID; + + uint32_t permCode; + ASSERT_TRUE(TransferPermissionToOpcode("ohos.permission.CAMERA", permCode)); + + auto& manager = AccessTokenInfoManager::GetInstance(); + PolicyWhiteListStateGuard stateGuard(manager, permCode); + stateGuard.SetControlledUser(USER_ID, GetSelfTokenID()); + + EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_USERLIST, + manager.UpdatePolicyWhiteList(tokenId, permCode, UpdateWhiteListType::ADD)); + EXPECT_EQ(ERR_TOKENID_NOT_IN_POLICY_USERLIST, + manager.UpdatePolicyWhiteList(tokenId, permCode, UpdateWhiteListType::DELETE)); + + std::vector tokenIdList; + EXPECT_EQ(RET_SUCCESS, manager.GetPolicyWhiteList(permCode, tokenIdList)); + EXPECT_TRUE(tokenIdList.empty()); + + EXPECT_EQ(RET_SUCCESS, manager.RemoveHapTokenInfo(tokenId)); +} + +/** + * @tc.name: UpdatePolicyWhiteList002 + * @tc.desc: UpdatePolicyWhiteList returns error for invalid tokenId. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TokenInfoManagerTest, UpdatePolicyWhiteList002, TestSize.Level0) +{ + uint32_t permCode; + ASSERT_TRUE(TransferPermissionToOpcode("ohos.permission.CAMERA", permCode)); + + auto& manager = AccessTokenInfoManager::GetInstance(); + EXPECT_EQ(ERR_PARAM_INVALID, manager.UpdatePolicyWhiteList(INVALID_TOKENID, permCode, UpdateWhiteListType::ADD)); +} + +/** + * @tc.name: GetPolicyWhiteList001 + * @tc.desc: GetPolicyWhiteList clears output list and returns error for invalid permCode. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TokenInfoManagerTest, GetPolicyWhiteList001, TestSize.Level0) +{ + auto& manager = AccessTokenInfoManager::GetInstance(); + std::vector tokenIdList = {RANDOM_TOKENID}; + + EXPECT_EQ(ERR_PERMISSION_NOT_EXIST, manager.GetPolicyWhiteList(UINT32_MAX, tokenIdList)); + EXPECT_TRUE(tokenIdList.empty()); +} +#endif + /** * @tc.name: ReservedHapInfo001 * @tc.desc: RemoveReservedHapInfo diff --git a/services/accesstokenmanager/test/unittest/service/accesstoken_manager_service_test.cpp b/services/accesstokenmanager/test/unittest/service/accesstoken_manager_service_test.cpp index c2d9dab27..ea7408f85 100644 --- a/services/accesstokenmanager/test/unittest/service/accesstoken_manager_service_test.cpp +++ b/services/accesstokenmanager/test/unittest/service/accesstoken_manager_service_test.cpp @@ -18,6 +18,7 @@ #include #include "accesstoken_callbacks.h" +#include "accesstoken_kit.h" #include "access_token_db_operator.h" #include "access_token_db.h" #include "access_token_error.h" @@ -2216,6 +2217,61 @@ HWTEST_F(AccessTokenManagerServiceTest, AccessTokenServiceCoverageTest001, TestS ret = atManagerService_->GetPermissionsStatus(RANDOM_TOKENID, reqPermList); EXPECT_NE(RET_SUCCESS, ret); } + +#ifdef SUPPORT_MANAGE_USER_POLICY +/** + * @tc.name: PolicyWhiteListServiceTest001 + * @tc.desc: Test UpdatePolicyWhiteList service param validation. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(AccessTokenManagerServiceTest, PolicyWhiteListServiceTest001, TestSize.Level1) +{ + HapInfoParcel infoParcel; + infoParcel.hapInfoParameter = g_info; + HapPolicyParcel policyParcel; + policyParcel.hapPolicy.apl = APL_SYSTEM_BASIC; + policyParcel.hapPolicy.domain = "test.domain"; + PermissionStatus internetState = { + .permissionName = "ohos.permission.INTERNET", + .grantStatus = static_cast(PermissionState::PERMISSION_GRANTED), + .grantFlag = static_cast(PermissionFlag::PERMISSION_DEFAULT_FLAG) + }; + policyParcel.hapPolicy.permStateList = {internetState}; + + AccessTokenID tokenId; + std::map tokenIdAplMap; + CreateHapToken(infoParcel, policyParcel, tokenId, tokenIdAplMap); + + uint32_t permCode = 0; + ASSERT_TRUE(TransferPermissionToOpcode("ohos.permission.INTERNET", permCode)); + + EXPECT_EQ(ERR_PARAM_INVALID, + atManagerService_->UpdatePolicyWhiteList(INVALID_TOKENID, permCode, static_cast(ADD))); + EXPECT_EQ(ERR_PARAM_INVALID, + atManagerService_->UpdatePolicyWhiteList(tokenId, permCode, 2)); // 2: invalid enum value + EXPECT_EQ(ERR_PARAM_INVALID, + atManagerService_->UpdatePolicyWhiteList(tokenId, UINT32_MAX, static_cast(ADD))); + + AccessTokenID nativeTokenId = AccessTokenKit::GetNativeTokenId("foundation"); + EXPECT_EQ(ERR_PARAM_INVALID, + atManagerService_->UpdatePolicyWhiteList(nativeTokenId, permCode, static_cast(ADD))); + + DelTestDataAndRestoreOri(tokenId, {}); +} + +/** + * @tc.name: PolicyWhiteListServiceTest002 + * @tc.desc: Test GetPolicyWhiteList service param validation. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(AccessTokenManagerServiceTest, PolicyWhiteListServiceTest002, TestSize.Level1) +{ + std::vector tokenIdList = {RANDOM_TOKENID}; + EXPECT_EQ(ERR_PARAM_INVALID, atManagerService_->GetPolicyWhiteList(UINT32_MAX, tokenIdList)); +} +#endif } // namespace AccessToken } // namespace Security } // namespace OHOS