diff --git a/frameworks/accesstoken/BUILD.gn b/frameworks/accesstoken/BUILD.gn index e7ebdac5b5212b28149b36109375b0c9fd5a5b40..9d70f82d7240270bd42284ce970c0f1e7f1328a7 100644 --- a/frameworks/accesstoken/BUILD.gn +++ b/frameworks/accesstoken/BUILD.gn @@ -43,6 +43,7 @@ ohos_shared_library("accesstoken_communication_adapter_cxx") { "src/hap_token_info_parcel.cpp", "src/native_token_info_parcel.cpp", "src/permission_def_parcel.cpp", + "src/permission_list_state_parcel.cpp", "src/permission_state_full_parcel.cpp", ] diff --git a/frameworks/accesstoken/include/i_accesstoken_manager.h b/frameworks/accesstoken/include/i_accesstoken_manager.h index f620e2f56612dd2db108b3b23a846b3fd1c71937..c110dbf23809d4f3a68f5a4542e6709480ae7009 100644 --- a/frameworks/accesstoken/include/i_accesstoken_manager.h +++ b/frameworks/accesstoken/include/i_accesstoken_manager.h @@ -27,6 +27,7 @@ #include "iremote_broker.h" #include "native_token_info_parcel.h" #include "permission_def_parcel.h" +#include "permission_list_state_parcel.h" #include "permission_state_full_parcel.h" namespace OHOS { @@ -45,6 +46,8 @@ public: virtual int GetReqPermissions( AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) = 0; virtual int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) = 0; + virtual PermissionOper GetSelfPermissionsState( + std::vector& permListParcel) = 0; virtual int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) = 0; virtual int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) = 0; virtual int ClearUserGrantedPermissionState(AccessTokenID tokenID) = 0; @@ -101,6 +104,7 @@ public: GET_NATIVE_REMOTE_TOKEN = 0xff2f, DUMP_TOKENINFO = 0xff30, + GET_PERMISSION_OPER_STATE = 0xff31, }; }; } // namespace AccessToken diff --git a/frameworks/accesstoken/include/permission_list_state_parcel.h b/frameworks/accesstoken/include/permission_list_state_parcel.h new file mode 100644 index 0000000000000000000000000000000000000000..98bdb7ab815bf12781b360368eafd1f697a522c5 --- /dev/null +++ b/frameworks/accesstoken/include/permission_list_state_parcel.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_INNER_KITS_PERMISSION_PERMISSION_LIST_STATE_PARCEL_H +#define INTERFACES_INNER_KITS_PERMISSION_PERMISSION_LIST_STATE_PARCEL_H + +#include "permission_list_state.h" +#include "parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct PermissionListStateParcel final : public Parcelable { + PermissionListStateParcel() = default; + + ~PermissionListStateParcel() override = default; + + bool Marshalling(Parcel &out) const override; + + static PermissionListStateParcel *Unmarshalling(Parcel &in); + + PermissionListState permsState; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // INTERFACES_INNER_KITS_PERMISSION_PERMISSION_LIST_STATE_PARCEL_H \ No newline at end of file diff --git a/frameworks/accesstoken/src/permission_list_state_parcel.cpp b/frameworks/accesstoken/src/permission_list_state_parcel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55d4c25c28412d76a3a45f7541dfca1901c8e6c5 --- /dev/null +++ b/frameworks/accesstoken/src/permission_list_state_parcel.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "permission_list_state_parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +#define RETURN_IF_FALSE(expr) \ + if (!(expr)) { \ + return false; \ + } + +#define RELEASE_IF_FALSE(expr, obj) \ + if (!(expr)) { \ + delete (obj); \ + (obj) = nullptr; \ + return (obj); \ + } + +bool PermissionListStateParcel::Marshalling(Parcel& out) const +{ + RETURN_IF_FALSE(out.WriteString(this->permsState.permissionName)); + RETURN_IF_FALSE(out.WriteInt32(this->permsState.state)); + return true; +} + +PermissionListStateParcel* PermissionListStateParcel::Unmarshalling(Parcel& in) +{ + auto* permissionStateParcel = new (std::nothrow) PermissionListStateParcel(); + RELEASE_IF_FALSE(permissionStateParcel != nullptr, permissionStateParcel); + + RELEASE_IF_FALSE(in.ReadString(permissionStateParcel->permsState.permissionName), permissionStateParcel); + RELEASE_IF_FALSE(in.ReadInt32(permissionStateParcel->permsState.state), permissionStateParcel); + + return permissionStateParcel; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/accesstoken/include/access_token.h b/interfaces/innerkits/accesstoken/include/access_token.h index 601120beabfcaec0a52a41fab56cb542454b8864..c44da6abb227692de45433a0250ec920d1abb03b 100644 --- a/interfaces/innerkits/accesstoken/include/access_token.h +++ b/interfaces/innerkits/accesstoken/include/access_token.h @@ -72,6 +72,13 @@ typedef enum TypePermissionFlag { PERMISSION_USER_FIXED = 1 << 1, PERMISSION_SYSTEM_FIXED = 1 << 2, } PermissionFlag; + +typedef enum TypePermissionOper { + SETTING_OPER = -1, + PASS_OPER = 0, + DYNAMIC_OPER = 1, + INVALID_OPER = 2, +} PermissionOper; } // namespace AccessToken } // namespace Security } // namespace OHOS diff --git a/interfaces/innerkits/accesstoken/include/accesstoken_kit.h b/interfaces/innerkits/accesstoken/include/accesstoken_kit.h index 9f6243cd28d79589546e508c249dfad6bd1dd7f4..c6c5baa6caa5699041d6d3b358edb812de586c00 100644 --- a/interfaces/innerkits/accesstoken/include/accesstoken_kit.h +++ b/interfaces/innerkits/accesstoken/include/accesstoken_kit.h @@ -23,6 +23,7 @@ #include "hap_token_info.h" #include "native_token_info.h" #include "permission_def.h" +#include "permission_list_state.h" #include "permission_state_full.h" namespace OHOS { @@ -51,6 +52,7 @@ public: static int GetReqPermissions( AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant); static int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName); + static PermissionOper GetSelfPermissionsState(std::vector& permList); static int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag); static int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag); static int ClearUserGrantedPermissionState(AccessTokenID tokenID); diff --git a/interfaces/innerkits/accesstoken/include/permission_list_state.h b/interfaces/innerkits/accesstoken/include/permission_list_state.h new file mode 100644 index 0000000000000000000000000000000000000000..7c294df2bd838b77ef512fcd5f1649493377acb9 --- /dev/null +++ b/interfaces/innerkits/accesstoken/include/permission_list_state.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_LIST_STATE_H +#define INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_LIST_STATE_H + +#include +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +class PermissionListState final { +public: + std::string permissionName; + int state; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_LIST_STATE_H \ No newline at end of file diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp index f8ba04b10bc354f484edc93b5b47b301d57361e0..d767ddc5d622a1799aaccae42b08b393ac6e45b9 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp +++ b/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp @@ -146,6 +146,11 @@ int AccessTokenKit::GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& n return AccessTokenManagerClient::GetInstance().GetNativeTokenInfo(tokenID, nativeTokenInfoRes); } +PermissionOper AccessTokenKit::GetSelfPermissionsState(std::vector& permList) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "called"); + return AccessTokenManagerClient::GetInstance().GetSelfPermissionsState(permList); +} int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) { ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp index 51e2d60b51881871a7da75d177b11a6394147e3b..e3670ba5c6232fcdb67eac1d0efea0161f53ddf0 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp @@ -126,6 +126,42 @@ int AccessTokenManagerClient::GetPermissionFlag(AccessTokenID tokenID, const std return proxy->GetPermissionFlag(tokenID, permissionName); } +PermissionOper AccessTokenManagerClient::GetSelfPermissionsState( + std::vector& permList) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "permList.size() : %{public}d.", (int)permList.size()); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null."); + return INVALID_OPER; + } + + size_t len = permList.size(); + if (len == 0) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "len is zero."); + return PASS_OPER; + } + + std::vector parcelList; + + for (auto perm : permList) { + PermissionListStateParcel permParcel; + permParcel.permsState = perm; + parcelList.emplace_back(permParcel); + } + + PermissionOper result = proxy->GetSelfPermissionsState(parcelList); + + if (len != parcelList.size()) { + return INVALID_OPER; + } + for (uint32_t i = 0; i < len; i++) { + PermissionListState perm = parcelList[i].permsState; + permList[i].state = perm.state; + } + return result; +} + int AccessTokenManagerClient::GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h index 74df766ed959bff3d915bbaeb9b84371cf345685..6f97162f9d3b24ca78d1a6c11b7bbb4521277981 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h @@ -47,6 +47,7 @@ public: int GetReqPermissions( AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant); int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName); + PermissionOper GetSelfPermissionsState(std::vector& permList); int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag); int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag); int ClearUserGrantedPermissionState(AccessTokenID tokenID); diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp index 218f1da474a91586075d3b401e2beff8b63b15bb..dd7983709a35236fcce4c96f18de031b2b1aa32f 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp @@ -241,6 +241,57 @@ int AccessTokenManagerProxy::GetPermissionFlag(AccessTokenID tokenID, const std: return result; } +PermissionOper AccessTokenManagerProxy::GetSelfPermissionsState( + std::vector& permListParcel) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(permListParcel.size())) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permListParcel size."); + return INVALID_OPER; + } + for (auto permission : permListParcel) { + if (!data.WriteParcelable(&permission)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permListParcel."); + return INVALID_OPER; + } + } + + MessageParcel reply; + MessageOption option(MessageOption::TF_SYNC); + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return INVALID_OPER; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_PERMISSION_OPER_STATE), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return INVALID_OPER; + } + + PermissionOper result = static_cast(reply.ReadInt32()); + if (result == INVALID_OPER) { + ACCESSTOKEN_LOG_ERROR(LABEL, "result from server is invalid."); + return result; + } + size_t size = reply.ReadUint32(); + if (size != permListParcel.size()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "permListParcel size from server is invalid."); + return INVALID_OPER; + } + for (uint32_t i = 0; i < size; i++) { + sptr permissionReq = reply.ReadParcelable(); + if (permissionReq != nullptr) { + permListParcel[i].permsState.state = permissionReq->permsState.state; + } + } + + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + int AccessTokenManagerProxy::GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) { MessageParcel data; diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h index 5463e216bfd43999769b4aaea6aa1ba9858f0992..2772b3da61fb3f792c79cdb831df961bac150526 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h @@ -28,6 +28,7 @@ #include "iremote_proxy.h" #include "native_token_info_parcel.h" #include "permission_def_parcel.h" +#include "permission_list_state_parcel.h" #include "permission_state_full_parcel.h" namespace OHOS { @@ -47,6 +48,7 @@ public: int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) override; int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) override; int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) override; + PermissionOper GetSelfPermissionsState(std::vector& permList) override; int ClearUserGrantedPermissionState(AccessTokenID tokenID) override; int GetTokenType(AccessTokenID tokenID) override; int CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) override; diff --git a/interfaces/innerkits/accesstoken/test/BUILD.gn b/interfaces/innerkits/accesstoken/test/BUILD.gn index e981ea0ecf5a727ad60cb44cee149ab70e44a03d..cfbe12777964b75a3daae662fde13ad28e488c92 100644 --- a/interfaces/innerkits/accesstoken/test/BUILD.gn +++ b/interfaces/innerkits/accesstoken/test/BUILD.gn @@ -23,6 +23,7 @@ ohos_unittest("libaccesstoken_sdk_test") { "//third_party/googletest/include", "//base/security/access_token/interfaces/innerkits/accesstoken/include", "//base/security/access_token/interfaces/innerkits/nativetoken/include", + "//base/security/access_token/interfaces/innerkits/token_setproc/include", "//base/security/access_token/frameworks/common/include", ] @@ -33,6 +34,7 @@ ohos_unittest("libaccesstoken_sdk_test") { deps = [ "//base/security/access_token/interfaces/innerkits/accesstoken:libaccesstoken_sdk", "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", "//utils/native/base:utils", ] diff --git a/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp b/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp index 3aa4e9dc16860a90ae3bbcaadd5f072f15c8786e..caff4c1c608e28753eec0e41aecbafd0a3dcd71e 100644 --- a/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp +++ b/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -19,6 +19,7 @@ #include "accesstoken_kit.h" #include "nativetoken_kit.h" #include "accesstoken_log.h" +#include "token_setproc.h" using namespace testing::ext; using namespace OHOS::Security::AccessToken; @@ -157,8 +158,46 @@ void AccessTokenKitTest::SetUp() .provisionEnable = false, .distributedSceneEnable = false }; + PermissionDef testPermDef1 = { + .permissionName = "ohos.permission.testPermDef1", + .bundleName = TEST_BUNDLE_NAME, + .grantMode = GrantMode::USER_GRANT, + .availableLevel = APL_NORMAL, + .provisionEnable = false, + .distributedSceneEnable = false + }; + + PermissionDef testPermDef2 = { + .permissionName = "ohos.permission.testPermDef2", + .bundleName = TEST_BUNDLE_NAME, + .grantMode = GrantMode::USER_GRANT, + .availableLevel = APL_NORMAL, + .provisionEnable = false, + .distributedSceneEnable = false + }; + + PermissionDef testPermDef3 = { + .permissionName = "ohos.permission.testPermDef3", + .bundleName = TEST_BUNDLE_NAME, + .grantMode = GrantMode::USER_GRANT, + .availableLevel = APL_NORMAL, + .provisionEnable = false, + .distributedSceneEnable = false + }; + PermissionDef testPermDef4 = { + .permissionName = "ohos.permission.testPermDef4", + .bundleName = TEST_BUNDLE_NAME, + .grantMode = GrantMode::USER_GRANT, + .availableLevel = APL_NORMAL, + .provisionEnable = false, + .distributedSceneEnable = false + }; policy.permList.emplace_back(permissionDefAlpha); policy.permList.emplace_back(permissionDefBeta); + policy.permList.emplace_back(testPermDef1); + policy.permList.emplace_back(testPermDef2); + policy.permList.emplace_back(testPermDef3); + policy.permList.emplace_back(testPermDef4); PermissionStateFull permStatAlpha = { .permissionName = TEST_PERMISSION_NAME_ALPHA, @@ -174,11 +213,47 @@ void AccessTokenKitTest::SetUp() .grantStatus = {PermissionState::PERMISSION_GRANTED}, .grantFlags = {PermissionFlag::PERMISSION_USER_SET} }; + PermissionStateFull permTestState1 = { + .grantFlags = {0}, + .grantStatus = {PermissionState::PERMISSION_DENIED}, + .isGeneral = true, + .permissionName = "ohos.permission.testPermDef1", + .resDeviceID = {"local"} + }; + + PermissionStateFull permTestState2 = { + .grantFlags = {1}, + .grantStatus = {PermissionState::PERMISSION_DENIED}, + .isGeneral = true, + .permissionName = "ohos.permission.testPermDef2", + .resDeviceID = {"local"} + }; + + PermissionStateFull permTestState3 = { + .grantFlags = {2}, + .grantStatus = {PermissionState::PERMISSION_DENIED}, + .isGeneral = true, + .permissionName = "ohos.permission.testPermDef3", + .resDeviceID = {"local"} + }; + + PermissionStateFull permTestState4 = { + .grantFlags = {1}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.testPermDef4", + .resDeviceID = {"local"} + }; + policy.permStateList.emplace_back(permStatAlpha); policy.permStateList.emplace_back(permStatBeta); policy.permStateList.emplace_back(g_grantPermissionReq); policy.permStateList.emplace_back(g_revokePermissionReq); - + policy.permStateList.emplace_back(permTestState1); + policy.permStateList.emplace_back(permTestState1); + policy.permStateList.emplace_back(permTestState2); + policy.permStateList.emplace_back(permTestState3); + policy.permStateList.emplace_back(permTestState4); AccessTokenKit::AllocHapToken(info, policy); AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(g_infoManagerTestInfoParms.userID, g_infoManagerTestInfoParms.bundleName, @@ -285,7 +360,7 @@ HWTEST_F(AccessTokenKitTest, GetDefPermissions001, TestSize.Level1) std::vector permDefList; int ret = AccessTokenKit::GetDefPermissions(tokenID, permDefList); ASSERT_EQ(RET_SUCCESS, ret); - ASSERT_EQ(2, permDefList.size()); + ASSERT_EQ(6, permDefList.size()); } /** @@ -348,9 +423,9 @@ HWTEST_F(AccessTokenKitTest, GetDefPermissions004, TestSize.Level0) int ret = RET_FAILED; for (int i = 0; i < CYCLE_TIMES; i++) { std::vector permDefList; - ret = ret = AccessTokenKit::GetDefPermissions(tokenID, permDefList); + ret = AccessTokenKit::GetDefPermissions(tokenID, permDefList); ASSERT_EQ(RET_SUCCESS, ret); - ASSERT_EQ(2, permDefList.size()); + ASSERT_EQ(6, permDefList.size()); } } @@ -367,7 +442,7 @@ HWTEST_F(AccessTokenKitTest, GetReqPermissions001, TestSize.Level1) std::vector permStatList; int ret = AccessTokenKit::GetReqPermissions(tokenID, permStatList, false); ASSERT_EQ(RET_SUCCESS, ret); - ASSERT_EQ(1, permStatList.size()); + ASSERT_EQ(5, permStatList.size()); ASSERT_EQ(TEST_PERMISSION_NAME_ALPHA, permStatList[0].permissionName); ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); @@ -464,9 +539,9 @@ HWTEST_F(AccessTokenKitTest, GetReqPermissions005, TestSize.Level0) int ret = RET_FAILED; for (int i = 0; i < CYCLE_TIMES; i++) { std::vector permStatList; - ret = ret = AccessTokenKit::GetReqPermissions(tokenID, permStatList, false); + ret = AccessTokenKit::GetReqPermissions(tokenID, permStatList, false); ASSERT_EQ(RET_SUCCESS, ret); - ASSERT_EQ(1, permStatList.size()); + ASSERT_EQ(5, permStatList.size()); ASSERT_EQ(TEST_PERMISSION_NAME_ALPHA, permStatList[0].permissionName); } } @@ -533,7 +608,7 @@ HWTEST_F(AccessTokenKitTest, GetPermissionFlag003, TestSize.Level0) ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); ASSERT_EQ(RET_SUCCESS, ret); - ret = ret = AccessTokenKit::GetPermissionFlag(tokenID, TEST_PERMISSION_NAME_ALPHA); + ret = AccessTokenKit::GetPermissionFlag(tokenID, TEST_PERMISSION_NAME_ALPHA); ASSERT_EQ(PERMISSION_USER_FIXED, ret); } } @@ -2061,6 +2136,71 @@ HWTEST_F(AccessTokenKitTest, GetTokenTypeFlag002, TestSize.Level1) ASSERT_EQ(ret, TOKEN_NATIVE); } +/** + * @tc.name: GetSelfPermissionsState001 + * @tc.desc: get permission list state + * @tc.type: FUNC + * @tc.require:AR000GK6T6 + */ +HWTEST_F(AccessTokenKitTest, GetSelfPermissionsState001, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + ASSERT_EQ(0, SetSelfTokenID(tokenID)); + + PermissionListState perm1 = { + .permissionName = "ohos.permission.testPermDef1", + .state = -1, + }; + PermissionListState perm2 = { + .permissionName = "ohos.permission.testPermDef2", + .state = -1, + }; + PermissionListState perm3 = { + .permissionName = "ohos.permission.testPermDef3", + .state = -1, + }; + PermissionListState perm4 = { + .permissionName = "ohos.permission.testPermDef4", + .state = -1, + }; + + std::vector permsList1; + permsList1.emplace_back(perm1); + permsList1.emplace_back(perm2); + permsList1.emplace_back(perm3); + permsList1.emplace_back(perm4); + + PermissionOper ret = AccessTokenKit::GetSelfPermissionsState(permsList1); + ASSERT_EQ(DYNAMIC_OPER, ret); + ASSERT_EQ(4, permsList1.size()); + ASSERT_EQ(DYNAMIC_OPER, permsList1[0].state); + ASSERT_EQ(DYNAMIC_OPER, permsList1[1].state); + ASSERT_EQ(SETTING_OPER, permsList1[2].state); + ASSERT_EQ(PASS_OPER, permsList1[3].state); + ASSERT_EQ("ohos.permission.testPermDef1", permsList1[0].permissionName); + ASSERT_EQ("ohos.permission.testPermDef2", permsList1[1].permissionName); + ASSERT_EQ("ohos.permission.testPermDef3", permsList1[2].permissionName); + ASSERT_EQ("ohos.permission.testPermDef4", permsList1[3].permissionName); + + PermissionListState perm5 = { + .permissionName = "ohos.permission.testPermDef5", + .state = -1, + }; + permsList1.emplace_back(perm5); + ret = AccessTokenKit::GetSelfPermissionsState(permsList1); + ASSERT_EQ(DYNAMIC_OPER, permsList1[0].state); + ASSERT_EQ(DYNAMIC_OPER, ret); + + std::vector permsList2; + permsList2.emplace_back(perm3); + permsList2.emplace_back(perm4); + ret = AccessTokenKit::GetSelfPermissionsState(permsList2); + ASSERT_EQ(SETTING_OPER, permsList2[0].state); + ASSERT_EQ(PASS_OPER, permsList2[1].state); + ASSERT_EQ(PASS_OPER, ret); +} + /** * @tc.name: GetTokenTypeFlag003 * @tc.desc: Get token type with hap tokenID. diff --git a/interfaces/innerkits/nativetoken/src/nativetoken.c b/interfaces/innerkits/nativetoken/src/nativetoken.c index 4e09e88b15669942b452cb4cb7ac8ca41cd2cbc2..785d717e4f7a160153092ce41979a106b80c4bdc 100644 --- a/interfaces/innerkits/nativetoken/src/nativetoken.c +++ b/interfaces/innerkits/nativetoken/src/nativetoken.c @@ -38,6 +38,11 @@ int32_t GetFileBuff(const char *cfg, char **retBuff) return ATRET_FAILED; } + if (fileStat.st_size == 0) { + *retBuff = NULL; + return ATRET_SUCCESS; + } + if ((fileStat.st_size < 0) || (fileStat.st_size > MAX_JSON_FILE_LEN)) { ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:stat file size is invalid.", __func__); return ATRET_FAILED; diff --git a/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h index 683a8f611e56e41a30cfca5b0bd8b7f448b52c1a..553352a40b551805a19c402225ecd4e56f77778b 100644 --- a/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h +++ b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h @@ -22,6 +22,7 @@ #include "access_token.h" #include "hap_token_info_inner.h" #include "permission_def.h" +#include "permission_list_state.h" #include "permission_state_full.h" #include "rwlock.h" @@ -47,6 +48,8 @@ public: void GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag); void RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag); void ClearUserGrantedPermissionState(AccessTokenID tokenID); + void GetSelfPermissionState( + std::vector permsList, PermissionListState &permState); private: PermissionManager(); void UpdateTokenPermissionState( 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 589b641e4c4c041fbff4f6b1e5af55a2b8dd052d..e60c10adaf91ea60cca5a44644eb010cb7b80467 100644 --- a/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h +++ b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h @@ -46,6 +46,8 @@ public: int GetDefPermissions(AccessTokenID tokenID, std::vector& permList) override; int GetReqPermissions( AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) override; + PermissionOper GetSelfPermissionsState( + std::vector& reqPermList) override; int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) override; int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) override; int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) override; diff --git a/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_stub.h b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_stub.h index e382958009b8b38f089a78c0e9c7e33e55c0d060..ff49c9c8320ff88b7661534fa9d4a1c3199a189b 100644 --- a/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_stub.h +++ b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_stub.h @@ -39,6 +39,7 @@ private: void GetDefPermissionInner(MessageParcel& data, MessageParcel& reply); void GetDefPermissionsInner(MessageParcel& data, MessageParcel& reply); void GetReqPermissionsInner(MessageParcel& data, MessageParcel& reply); + void GetSelfPermissionsStateInner(MessageParcel& data, MessageParcel& reply); void GetPermissionFlagInner(MessageParcel& data, MessageParcel& reply); void GrantPermissionInner(MessageParcel& data, MessageParcel& reply); void RevokePermissionInner(MessageParcel& data, MessageParcel& reply); diff --git a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp index cf795e7b321c88316f82ffd7219dce09ef0b0ae3..cd2c4340f72a88d2bd94a18fdc99591f4dcb1aae 100644 --- a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp @@ -195,6 +195,43 @@ int PermissionManager::GetReqPermissions( return RET_SUCCESS; } +void PermissionManager::GetSelfPermissionState(std::vector permsList, + PermissionListState &permState) +{ + bool foundGoal = false; + int32_t goalGrantStatus; + int32_t goalGrantFlags; + for (auto& perm : permsList) { + if (perm.permissionName == permState.permissionName) { + foundGoal = true; + goalGrantStatus = perm.grantStatus[0]; + goalGrantFlags = perm.grantFlags[0]; + break; + } + } + if (foundGoal == false) { + ACCESSTOKEN_LOG_WARN(LABEL, + "can not find permission: %{public}s define!", permState.permissionName.c_str()); + permState.state = DYNAMIC_OPER; + return; + } + + if (goalGrantStatus == PERMISSION_DENIED) { + if ((goalGrantFlags == DEFAULT_PERMISSION_FLAGS) || + (goalGrantFlags == PERMISSION_USER_SET)) { + permState.state = DYNAMIC_OPER; + return; + } + if (goalGrantFlags == PERMISSION_USER_FIXED) { + permState.state = SETTING_OPER; + return; + } + } + + permState.state = PASS_OPER; + return; +} + int PermissionManager::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) { ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s", 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 997da72d38acd1d0f03043cb875ae405b4ef72c0..087dac7af53d197ab4ea2eb6d906c0dfccc5b368 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp @@ -21,8 +21,10 @@ #include "accesstoken_log.h" #include "hap_token_info.h" #include "hap_token_info_inner.h" +#include "ipc_skeleton.h" #include "native_token_info_inner.h" #include "native_token_receptor.h" +#include "permission_list_state.h" #include "permission_manager.h" namespace OHOS { @@ -129,6 +131,34 @@ int AccessTokenManagerService::GetReqPermissions( return ret; } +PermissionOper AccessTokenManagerService::GetSelfPermissionsState( + std::vector& reqPermList) +{ + AccessTokenID callingTokenID = IPCSkeleton::GetCallingTokenID(); + ACCESSTOKEN_LOG_INFO(LABEL, "callingTokenID: %{public}d", callingTokenID); + + bool needRes = false; + std::vector permsList; + int ret = PermissionManager::GetInstance().GetReqPermissions(callingTokenID, permsList, false); + if (ret != RET_SUCCESS) { + return INVALID_OPER; + } + + int32_t size = reqPermList.size(); + ACCESSTOKEN_LOG_INFO(LABEL, "reqPermList size: 0x%{public}x", size); + for (int32_t i = 0; i < size; i++) { + PermissionManager::GetInstance().GetSelfPermissionState( + permsList, reqPermList[i].permsState); + if (reqPermList[i].permsState.state == DYNAMIC_OPER) { + needRes = true; + } + } + if (needRes) { + return DYNAMIC_OPER; + } + return PASS_OPER; +} + int AccessTokenManagerService::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) { ACCESSTOKEN_LOG_INFO(LABEL, diff --git a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp index fe3f37809cb89040ca44a0b1468ced6f2efc9f2f..be8ac75f751bc73815388c2af7a06403253bdfd3 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp @@ -114,6 +114,33 @@ void AccessTokenManagerStub::GetReqPermissionsInner(MessageParcel& data, Message reply.WriteInt32(result); } +void AccessTokenManagerStub::GetSelfPermissionsStateInner(MessageParcel& data, MessageParcel& reply) +{ + std::vector permList; + uint32_t size = data.ReadUint32(); + ACCESSTOKEN_LOG_INFO(LABEL, "permList size read from client data is %{public}u.", size); + if (size > MAX_PERMISSION_SIZE) { + ACCESSTOKEN_LOG_ERROR(LABEL, "permList size %{public}d is invalid", size); + reply.WriteInt32(INVALID_OPER); + return; + } + for (uint32_t i = 0; i < size; i++) { + sptr permissionParcel = data.ReadParcelable(); + if (permissionParcel != nullptr) { + permList.emplace_back(*permissionParcel); + } + } + + PermissionOper result = this->GetSelfPermissionsState(permList); + + reply.WriteInt32(result); + + reply.WriteUint32(permList.size()); + for (auto perm : permList) { + reply.WriteParcelable(&perm); + } +} + void AccessTokenManagerStub::GetPermissionFlagInner(MessageParcel& data, MessageParcel& reply) { unsigned int callingTokenID = IPCSkeleton::GetCallingTokenID(); @@ -462,6 +489,8 @@ AccessTokenManagerStub::AccessTokenManagerStub() &AccessTokenManagerStub::GetRemoteNativeTokenIDInner; requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::DUMP_TOKENINFO)] = &AccessTokenManagerStub::DumpTokenInfoInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_PERMISSION_OPER_STATE)] = + &AccessTokenManagerStub::GetSelfPermissionsStateInner; } AccessTokenManagerStub::~AccessTokenManagerStub() diff --git a/services/accesstokenmanager/main/cpp/src/token/accesstoken_id_manager.cpp b/services/accesstokenmanager/main/cpp/src/token/accesstoken_id_manager.cpp index 56d491df5380d9c6061b4fda32ef79d2ea9cbfe6..5cee5324844127aaa1b81ab8164044289f37c0c2 100644 --- a/services/accesstokenmanager/main/cpp/src/token/accesstoken_id_manager.cpp +++ b/services/accesstokenmanager/main/cpp/src/token/accesstoken_id_manager.cpp @@ -93,10 +93,11 @@ AccessTokenID AccessTokenIDManager::CreateAndRegisterTokenId(ATokenTypeEnum type int ret = RegisterTokenId(tokenId, type); if (ret == RET_SUCCESS) { break; - } else if (i == MAX_CREATE_TOKEN_ID_RETRY - 1) { + } else if (i < MAX_CREATE_TOKEN_ID_RETRY - 1) { ACCESSTOKEN_LOG_INFO(LABEL, "reigster tokenId failed, maybe repeat, retry"); } else { ACCESSTOKEN_LOG_WARN(LABEL, "reigster tokenId finally failed"); + tokenId = 0; } } return tokenId;