diff --git a/frameworks/accesstoken/BUILD.gn b/frameworks/accesstoken/BUILD.gn index 6c3e6db17cf3b55323a5c8cf5d7e2ffd381464d4..3471db521a3fba1945752e34c4bd152bd158beaa 100644 --- a/frameworks/accesstoken/BUILD.gn +++ b/frameworks/accesstoken/BUILD.gn @@ -40,6 +40,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 c593a4c27b79fba0da0e737f594e5c1943206887..b9c78cbeac08374ebad7ef7351328ed911bc4274 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; @@ -103,6 +106,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 b2d3243291840480c2240ed00bccaf32637d8643..b6d8e614f6bfb18faf0907693d149c16f04181ae 100644 --- a/interfaces/innerkits/accesstoken/include/access_token.h +++ b/interfaces/innerkits/accesstoken/include/access_token.h @@ -74,6 +74,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 2904763cc8b36872d718f438e1dfa658e3e2c9ee..0c9740761b20df5dac28eff2e6f3c57e9d2daacc 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 182783c89f5cce2059a6dc5e5b1088de098eb0de..ec9dfe189f71360244992ff4a612f85def72f095 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 a10c7114ba7e0e9b5b7eee454c0fc7c30721b3a4..0781fd82976b06b86903dde1d2cb36986faa4d69 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 37b3fc61c472e7d4d1b342d8d1947333e7780e38..e55311aeb3e49bad7959aeabb531f39e43b96d97 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 4f371c6f691e6f87aa08d9c379dc53698f33116c..18950a2ace53eb8c3404c892db62e901d23e6fe7 100644 --- a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp @@ -249,6 +249,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 90c65cee8b4c2741ffb549301d86d4eee0b6d363..07324eefa7bde73803fcf066a3c43f0bceafe1b5 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 c9a97a081289fe52cbff9a79bf056646fb123587..a64bae599dd1cfdbe182e2800b1ddbb02313b158 100644 --- a/interfaces/innerkits/accesstoken/test/BUILD.gn +++ b/interfaces/innerkits/accesstoken/test/BUILD.gn @@ -24,6 +24,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", ] @@ -34,6 +35,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 56a4ada183414994e980c6fb6d840e1fa6c09999..7b0f4bdcf5f3b0ad2cdbb20501aa01a98d3717e6 100644 --- a/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp +++ b/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp @@ -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, @@ -287,7 +362,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()); } /** @@ -352,7 +427,7 @@ HWTEST_F(AccessTokenKitTest, GetDefPermissions004, TestSize.Level0) std::vector permDefList; ret = AccessTokenKit::GetDefPermissions(tokenID, permDefList); ASSERT_EQ(RET_SUCCESS, ret); - ASSERT_EQ(2, permDefList.size()); + ASSERT_EQ(6, permDefList.size()); } } @@ -369,7 +444,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); @@ -468,7 +543,7 @@ HWTEST_F(AccessTokenKitTest, GetReqPermissions005, TestSize.Level0) std::vector permStatList; 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); } } @@ -2063,6 +2138,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 662ba98c19808949ae936c47cb9fe7b68e8f13cd..22d4b5bf7e218a208b499b5dc5b0885281d52263 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 cdc0881273febe641aae0d8df460731e9c24c1fb..64fa632f5e9262231b1b9cbdc8c049ecb3d1c253 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 e8ac7f2f8fe02e380581ccf2eb7f7c94708e46ee..b35579d1bb0b46554e5b3c2b0534b7c841da42b6 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 7b34cc3a7f9cd9a8bd89c94c796948ea54539391..30cfd3f7d4071b0da39c8ee6335ecd1e1ad8f244 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 eaf67ae7af4bc46d421a96db3b4d94ed62f2af32..ac368030f100235a607434c9af2b1d5f46818219 100644 --- a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp @@ -197,6 +197,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 6eb08a9bdf07e2a39f2ad5dfe7c7f3158c8c2691..b222a9dcac74d471810246fd52a3aa6ce91e6a15 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 0d5c8916a84de923121a3a7b09c64f4b48e97dd5..c5e2af9313a2eb27d8d65c7b3415349b8bb3acd6 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(); @@ -492,6 +519,8 @@ AccessTokenManagerStub::AccessTokenManagerStub() 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 aacac14169da3811dd243acf65fcdcfde3c943dc..19d7f272245ec23f99be8f6c808a981a9c2adead 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;