diff --git a/BUILD.gn b/BUILD.gn index 4e262743dd640165d7de1ea5031b9743cabd5a46..d57c193e9917a78fda6d7a3ae133a5704c51cc7d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -11,24 +11,51 @@ # See the License for the specific language governing permissions and # limitations under the License. +#import("//base/security/permission/permission.gni") import("//build/ohos.gni") - -group("accesstoken_build_module_standard") { +group("accesstoken_build_module") { if (is_standard_system) { deps = [ "//base/security/access_token/interfaces/innerkits/accesstoken:libaccesstoken_sdk", - "//base/security/access_token/services/accesstoken:accesstoken_manager_service", - "//base/security/access_token/services/accesstoken/main/sa_profile:accesstoken_sa_profile_standard", + "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + "//base/security/access_token/interfaces/kits:napi_packages", + "//base/security/access_token/services/accesstokenmanager:accesstoken_manager_service", + "//base/security/access_token/services/accesstokenmanager/main/sa_profile:accesstoken_sa_profile_standard", + ] + } +} + +group("tokensync_build_module") { + if (is_standard_system) { + deps = [ + "//base/security/access_token/interfaces/innerkits/tokensync:libtokensync_sdk", + "//base/security/access_token/services/tokensyncmanager:token_sync_manager_service", + "//base/security/access_token/services/tokensyncmanager/sa_profile:tokensync_sa_profile_standard", ] } } -group("accesstoken_build_module_standard_test") { +group("accesstoken_build_module_test") { testonly = true deps = [] if (is_standard_system) { deps += [ "//base/security/access_token/interfaces/innerkits/accesstoken/test:unittest", + "//base/security/access_token/interfaces/innerkits/nativetoken/test:unittest", + "//base/security/access_token/interfaces/innerkits/token_setproc/test:unittest", + "//base/security/access_token/interfaces/innerkits/tokensync/test:unittest", + "//base/security/access_token/services/accesstokenmanager/test:unittest", ] } -} \ No newline at end of file +} +#group("distributed_permission") { +# if (is_standard_system) { +# deps = [ +# "${distributed_permission_innerkits_distributed_path}:distributed_permission_innerkits", +# "${distributed_permission_record_database_path}:permission_standard_infrastructure_record_database", +# "${distributed_permission_services_path}:distributed_permission_services", +# "${distributed_permission_services_path}/main/sa_profile:distributed_permission_sa_profile_standard", +# ] +# } +#} diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 0000000000000000000000000000000000000000..b11daf5274a1b8efb7d7851c97861d0d8bf5d059 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 11f465df97e3c0d571a30f2d5ef4f208b0e1aae6..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# security_access_token - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 9d2b06ed3c0a7d5bbad7b383686580f7721cc7c2..9ef56a6a22cfc0cfc4d47ffe9665e77b01937d92 100644 --- a/README.md +++ b/README.md @@ -1,51 +1 @@ -# security_access_token - -- [简介](#section11660541593) -- [缩略词](#section161941989596) -- [目录](#section119744591305) -- [使用](#section137768191623) - - [接口说明](#section1551164914237) - - [使用说明](#section129654513264) - -- [相关仓](#section1371113476307) - -## 简介 - -ATM(AccessTokenManager)是OpenHarmony上基于AccessToken构建的统一的应用权限管理能力,应用的Accesstoken信息主要包括应用身份标识APPID、用户ID,应用分身索引、应用APL等级、应用权限信息等。每个应用的Accestoken信息由一个32bits的设备内唯一标识符tokenID来标识。 -ATM模块主要提供如下功能: -- 提供基于tokenID的应用权限校验机制,应用访问敏感数据或者API时可以检查是否有对应的权限; -- 提供基于tokenID的Accestoken信息查询,应用可以根据tokenID查询自身的APL等级等信息; - -## 缩略词 -- AT:Access Token, 访问凭据 -- AACL:API Access Control List, 权限访问控制列表 -- APL:API Ability Privilege Level, 权限访问控制列表 - -## 目录 - -``` -/base/security/access_token -├── frameworks # 框架层,作为基础功能目录,被interfaces和services使用 -│ ├── accesstoken # Accesstoken管理框架代码实现 -│ ├── tokensync # Accesstoken信息同步框架代码实现 -│ └── common # 框架公共代码实现 -├── interfaces # 接口层 -│ └── innerkits # 内部接口层 -│ ├── accesstoken # Accesstoken内部接口实现代码 -│ └── tokensync # Accesstoken信息同步内部接口实现代码 -└── services # 服务层 - ├── accesstokenmanager # Accesstoken管理服务代码 - └── tokensyncmanager # Accesstoken信息同步服务代码 -``` - -## 使用 -### 接口说明 - -### 使用说明 -1. xxxx -2. xxxx -3. xxxx - -## 相关仓 -安全子系统 -security\_access\_token \ No newline at end of file +An english translation is now being prepared. \ No newline at end of file diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..23be5b3aff107affb9e6cb468b095a4b833101ab --- /dev/null +++ b/README_zh.md @@ -0,0 +1,81 @@ +# 访问控制 + +- [简介](#section11660541593) +- [目录](#section119744591305) +- [使用](#section137768191623) + - [接口说明](#section1551164914237) + - [使用说明](#section129654513264) +- [相关仓](#section1371113476307) + +## 简介 + +ATM(AccessTokenManager)是OpenHarmony上基于AccessToken构建的统一的应用权限管理能力。 + +应用的Accesstoken信息主要包括应用身份标识APPID、用户ID,应用分身索引、应用APL(Ability Privilege Level)等级、应用权限信息等。每个应用的Accestoken信息由一个32bits的设备内唯一标识符TokenID(Token identity)来标识。 + +ATM模块主要提供如下功能: +- 提供基于TokenID的应用权限校验机制,应用访问敏感数据或者API时可以检查是否有对应的权限。 +- 提供基于TokenID的Accestoken信息查询,应用可以根据TokenID查询自身的APL等级等信息。 + +## 目录 + +``` +/base/security/access_token +├── frameworks # 框架层,基础功能代码存放目录 +│ ├── accesstoken # Accesstoken管理框架代码存放目录 +│ ├── tokensync # Accesstoken信息同步框架代码存放目录 +│ └── common # 框架公共代码存放目录 +├── interfaces # 接口层 +│ └── innerkits # 内部接口层 +│ ├── accesstoken # Accesstoken内部接口代码存放目录 +│ ├── nativetoken # nativetoken内部接口代码存放目录 +│ └── tokensync # Accesstoken信息同步内部接口代码存放目录 +└── services # 服务层 + ├── accesstokenmanager # Accesstoken管理服务代码存放目录 + └── tokensyncmanager # Accesstoken信息同步服务代码存放目录 +``` + +## 使用 +### 接口说明 + +| **接口申明** | **接口描述** | +| --- | --- | +| AccessTokenIDEx AllocHapToken(const HapInfoParams& info, const HapPolicyParams& policy); | 为应用进程分配一个tokenID | +| AccessTokenID AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID); | 为远端设备的应用进程分配一个本地tokenID | +| int UpdateHapToken(AccessTokenID tokenID, const std::string& appIDDesc, const HapPolicyParams& policy); | 更新tokenId对应的tokenInfo信息 | +| int DeleteToken(AccessTokenID tokenID); | 删除应用tokenID及其对应的tokenInfo信息 | +| int GetTokenType(AccessTokenID tokenID); | 查询指定tokenID的类型 | +| int CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap); | 检测指定tokenID对应的native进程是否具有指定的分布式能力 | +| AccessTokenID GetHapTokenID(int userID, const std::string& bundleName, int instIndex); | 查询指定应用的tokenId | +| int GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo& hapTokenInfoRes); | 查询指定tokenID对应的hap包的tokenInfo信息 | +| int GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& nativeTokenInfoRes); | 查询指定tokenID对应的native的tokenInfo信息 | +| int VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName); | 检查指定tokenID是否具有指定权限 | +| int GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult); | 查询指定权限的权限定义信息 | +| int GetDefPermissions(AccessTokenID tokenID, std::vector& permList); | 查询指定tokenID对应的hap包的权限定义集合 | +| int GetReqPermissions(AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant); | 查询指定tokenID对应的hap包申请的权限状态集合 | +| int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName); | 查询指定tokenID的应用的指定权限 | +| int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag); | 授予指定tokenID的应用的指定权限 | +| int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag); | 撤销指定tokenID的应用的指定权限 | +| int ClearUserGrantedPermissionState(AccessTokenID tokenID); | 清空指定tokenID的应用的user_grant权限状态 | +| uint64_t GetAccessTokenId(const char *processname, const char **dcap, int32_t dacpNum, const char *aplStr); | 创建获取native进程的tokenId | + +### 使用说明 +ATM提供了统一的应用权限访问控制功能,支持应用程序或者SA查询校验应用权限、APL等信息。从使用者角度,可以分为基于native进程启动的SA和应用Hap两类使用者。 + +#### native进程 +- 在native进程拉起前,需要调用GetAccessTokenId函数,获取该native进程的TokenID;再调用SetSelfTokenID将进程TokenID设置到内核中。 +- 在native进程运行过程中,可以通过调用GetNativeTokenInfo、CheckNativeDCap来查验对应进程所具备的token信息,包括分布式能力、APL等级等信息。 + +#### 应用hap +- 在应用安装时,需要调用AllocHapToken创建获取该应用的TokenID。 +- 在应用运行过程中,需要进行鉴权等操作时,可调用VerifyAccessToken、GetReqPermissions等函数查询校验应用权限、APL等信息。 +- 在应用卸载时,需要调用DeleteToken函数删除系统中管理的对应Accesstoken信息。 + +## 相关仓 +安全子系统 + +[startup\_init\_lite](https://gitee.com/openharmony/startup_init_lite/blob/master/README.md) + +[security\_deviceauth](https://gitee.com/openharmony/security_deviceauth/blob/master/README.md) + +**[security\_access\_token](https://gitee.com/openharmony-sig/security_access_token/blob/master/README.md)** \ No newline at end of file diff --git a/bundle.json b/bundle.json new file mode 100755 index 0000000000000000000000000000000000000000..c6b2039c0eb69034d4da4618fcae1f00c23da2a5 --- /dev/null +++ b/bundle.json @@ -0,0 +1,85 @@ +{ + "name": "@openharmony/access_token", + "description": "access_token", + "version": "3.1.0", + "license": "Apache License 2.0", + "publishAs": "code-segment", + "segment": { + "destPath": "base/security/access_token" + }, + "dirs": {}, + "scripts": {}, + "component": { + "name": "access_token", + "subsystem": "security", + "syscap": [ + "SystemCapability.Security.AccessToken" + ], + "adapted_system_type": [ "standard" ], + "rom": "2048KB", + "ram": "5102KB", + "deps": { + "components": [ + "ability_base", + "hiviewdfx_hilog_native", + "ipc_core", + "ans_standard", + "aafwk_standard", + "system_ability_fwk", + "samgr_proxy", + "appexecfwk_standard", + "eventhandler", + "napi", + "safwk", + "samgr_standard", + "utils_base" + ], + "third_party": [ + "cJSON", + "sqlite", + "mbedtls" + ] + }, + "build": { + "sub_component": [ + "//base/security/access_token:accesstoken_build_module", + "//base/security/access_token:tokensync_build_module" + ], + "inner_kits": [ + { + "name": "//base/security/access_token/interfaces/innerkits/accesstoken:libaccesstoken_sdk", + "header": { + "header_files": [ + "accesstoken_kit.h" + ], + "header_base": "//base/security/access_token/interfaces/innerkits/accesstoken/include" + } + }, + { + "name": "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", + "header": { + "header_files": [ + "nativetoken_kit.h" + ], + "header_base": "//base/security/access_token/interfaces/innerkits/nativetoken/include" + } + }, + { + "name": "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + "header": { + "header_files": [ + "token_setproc.h" + ], + "header_base": "//base/security/access_token/interfaces/innerkits/token_setproc/include" + } + } + ], + "test": [ + "//base/security/access_token:accesstoken_build_module_test", + "//base/security/access_token/interfaces/innerkits/accesstoken/test:unittest", + "//base/security/access_token/interfaces/innerkits/nativetoken/test:unittest", + "//base/security/access_token/interfaces/innerkits/token_setproc/test:unittest" + ] + } + } +} diff --git a/frameworks/accesstoken/BUILD.gn b/frameworks/accesstoken/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..e7ebdac5b5212b28149b36109375b0c9fd5a5b40 --- /dev/null +++ b/frameworks/accesstoken/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (c) 2021 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. + +import("//build/ohos.gni") + +################################################################ +# C++, Main source file here. +################################################################ +config("accesstoken_communication_adapter_cxx_public_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", + ] +} + +ohos_shared_library("accesstoken_communication_adapter_cxx") { + subsystem_name = "security" + part_name = "access_token" + + public_configs = [ ":accesstoken_communication_adapter_cxx_public_config" ] + + include_dirs = [ + "include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", + "//utils/native/base/include", + ] + + sources = [ + "src/hap_info_parcel.cpp", + "src/hap_policy_parcel.cpp", + "src/hap_token_info_for_sync_parcel.cpp", + "src/hap_token_info_parcel.cpp", + "src/native_token_info_parcel.cpp", + "src/permission_def_parcel.cpp", + "src/permission_state_full_parcel.cpp", + ] + + deps = [ "//utils/native/base:utils" ] + + external_deps = [ "ipc:ipc_core" ] +} diff --git a/frameworks/accesstoken/i_accesstoken_manager.h b/frameworks/accesstoken/include/hap_info_parcel.h similarity index 57% rename from frameworks/accesstoken/i_accesstoken_manager.h rename to frameworks/accesstoken/include/hap_info_parcel.h index e3774c8a41ce8f5364bb413ccc7a229bf21a4f5c..8f496175e23d78cc314654838ab443d6dc91fa3c 100644 --- a/frameworks/accesstoken/i_accesstoken_manager.h +++ b/frameworks/accesstoken/include/hap_info_parcel.h @@ -1,44 +1,40 @@ -/* - * Copyright (c) 2021 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 I_ACCESSTOKEN_MANAGER_H -#define I_ACCESSTOKEN_MANAGER_H - -#include -#include "iremote_broker.h" -#include "errors.h" - -#include "accesstoken.h" - -namespace OHOS { -namespace Security { -namespace AccessToken { -class IAccessTokenManager : public IRemoteBroker { -public: - static const int SA_ID_ACCESSTOKEN_MANAGER_SERVICE = 3503; - - DECLARE_INTERFACE_DESCRIPTOR(u"ohos.security.accesstoken.IAccessTokennManager"); - - virtual int VerifyAccesstoken(AccessTokenID tokenID, const std::string &permissionName) = 0; - - enum class InterfaceCode { - VERIFY_ACCESSTOKEN = 0xff01, - }; -}; -} // namespace AccessToken -} // namespace Security -} // namespace OHOS - -#endif // I_ACCESSTOKEN_MANAGER_H +/* + * Copyright (c) 2021 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 HAP_INFO_PARCEL_H +#define HAP_INFO_PARCEL_H + +#include "hap_token_info.h" + +#include "parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct HapInfoParcel final : public Parcelable { + HapInfoParcel() = default; + + ~HapInfoParcel() override = default; + + bool Marshalling(Parcel &out) const override; + + static HapInfoParcel *Unmarshalling(Parcel &in); + + HapInfoParams hapInfoParameter; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // HAP_INFO_PARCEL_H diff --git a/frameworks/accesstoken/include/hap_policy_parcel.h b/frameworks/accesstoken/include/hap_policy_parcel.h new file mode 100644 index 0000000000000000000000000000000000000000..7886bfbeb7fff89c01ecba7eb4a6a7f712221129 --- /dev/null +++ b/frameworks/accesstoken/include/hap_policy_parcel.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 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 HAP_POLICY_PARCEL_H +#define HAP_POLICY_PARCEL_H + +#include "hap_token_info.h" +#include "permission_def_parcel.h" +#include "permission_state_full_parcel.h" + + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct HapPolicyParcel final : public Parcelable { + HapPolicyParcel() = default; + + ~HapPolicyParcel() override = default; + + bool Marshalling(Parcel &out) const override; + + static HapPolicyParcel *Unmarshalling(Parcel &in); + + HapPolicyParams hapPolicyParameter; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // HAP_POLICY_PARCEL_H diff --git a/frameworks/accesstoken/include/hap_token_info_for_sync_parcel.h b/frameworks/accesstoken/include/hap_token_info_for_sync_parcel.h new file mode 100644 index 0000000000000000000000000000000000000000..b0c838402a24fb0c18e96943fc6d451a023cb802 --- /dev/null +++ b/frameworks/accesstoken/include/hap_token_info_for_sync_parcel.h @@ -0,0 +1,40 @@ +/* + * 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 HAP_TOKEN_INFO_FOR_SYNC_PARCEL_H +#define HAP_TOKEN_INFO_FOR_SYNC_PARCEL_H + +#include "hap_token_info.h" +#include "parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct HapTokenInfoForSyncParcel final : public Parcelable { + HapTokenInfoForSyncParcel() = default; + + ~HapTokenInfoForSyncParcel() override = default; + + bool Marshalling(Parcel &out) const override; + + static HapTokenInfoForSyncParcel *Unmarshalling(Parcel &in); + + HapTokenInfoForSync hapTokenInfoForSyncParams; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // HAP_TOKEN_INFO_FOR_SYNC_PARCEL_H + diff --git a/frameworks/accesstoken/include/hap_token_info_parcel.h b/frameworks/accesstoken/include/hap_token_info_parcel.h new file mode 100644 index 0000000000000000000000000000000000000000..d13fda88a2ec7c89c5ab9be86f46f19db3d8841b --- /dev/null +++ b/frameworks/accesstoken/include/hap_token_info_parcel.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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 HAP_TOKEN_INFO_PARCEL_H +#define HAP_TOKEN_INFO_PARCEL_H + +#include "hap_token_info.h" + +#include "parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct HapTokenInfoParcel final : public Parcelable { + HapTokenInfoParcel() = default; + + ~HapTokenInfoParcel() override = default; + + bool Marshalling(Parcel &out) const override; + + static HapTokenInfoParcel *Unmarshalling(Parcel &in); + + HapTokenInfo hapTokenInfoParams; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // HAP_TOKEN_INFO_PARCEL_H diff --git a/frameworks/accesstoken/include/i_accesstoken_manager.h b/frameworks/accesstoken/include/i_accesstoken_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..12b1d3165ad69bd12b4b08c149115da08f444c23 --- /dev/null +++ b/frameworks/accesstoken/include/i_accesstoken_manager.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 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 I_ACCESSTOKEN_MANAGER_H +#define I_ACCESSTOKEN_MANAGER_H + +#include + +#include "access_token.h" +#include "errors.h" +#include "hap_info_parcel.h" +#include "hap_policy_parcel.h" +#include "hap_token_info_for_sync_parcel.h" +#include "hap_token_info_parcel.h" +#include "iremote_broker.h" +#include "native_token_info_parcel.h" +#include "permission_def_parcel.h" +#include "permission_state_full_parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class IAccessTokenManager : public IRemoteBroker { +public: + static const int SA_ID_ACCESSTOKEN_MANAGER_SERVICE = 3503; + + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.security.accesstoken.IAccessTokenManager"); + + virtual int VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) = 0; + virtual int GetDefPermission(const std::string& permissionName, PermissionDefParcel& permissionDefResult) = 0; + virtual int GetDefPermissions(AccessTokenID tokenID, std::vector& permList) = 0; + virtual int GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) = 0; + virtual int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) = 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; + virtual AccessTokenIDEx AllocHapToken(const HapInfoParcel& hapInfo, const HapPolicyParcel& policyParcel) = 0; + virtual int DeleteToken(AccessTokenID tokenID) = 0; + virtual int GetTokenType(AccessTokenID tokenID) = 0; + virtual int CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) = 0; + virtual AccessTokenID GetHapTokenID(int userID, const std::string& bundleName, int instIndex) = 0; + virtual AccessTokenID AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID) = 0; + virtual int GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfoParcel& nativeTokenInfoRes) = 0; + virtual int GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfoParcel& hapTokenInfoRes) = 0; + virtual int UpdateHapToken( + AccessTokenID tokenID, const std::string& appIDDesc, const HapPolicyParcel& policyParcel) = 0; + + virtual int GetHapTokenInfoFromRemote(AccessTokenID tokenID, + HapTokenInfoForSyncParcel& hapSyncParcel) = 0; + virtual int GetAllNativeTokenInfo(std::vector& nativeTokenInfoRes) = 0; + virtual int SetRemoteHapTokenInfo(const std::string& deviceID, + HapTokenInfoForSyncParcel& hapSyncParcel) = 0; + virtual int SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoParcel) = 0; + virtual int DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) = 0; + virtual int DeleteRemoteDeviceTokens(const std::string& deviceID) = 0; + + virtual int DumpToken(std::string& dumpInfo) = 0; + + enum class InterfaceCode { + VERIFY_ACCESSTOKEN = 0xff10, + GET_DEF_PERMISSION = 0xff11, + GET_DEF_PERMISSIONS = 0xff12, + GET_REQ_PERMISSIONS = 0xff13, + GET_PERMISSION_FLAG = 0xff14, + GRANT_PERMISSION = 0xff15, + REVOKE_PERMISSION = 0xff16, + CLEAR_USER_GRANT_PERMISSION = 0xff17, + ALLOC_TOKEN_HAP = 0xff18, + TOKEN_DELETE = 0xff19, + GET_TOKEN_TYPE = 0xff20, + CHECK_NATIVE_DCAP = 0xff21, + GET_HAP_TOKEN_ID = 0xff22, + ALLOC_LOCAL_TOKEN_ID = 0xff23, + GET_NATIVE_TOKENINFO = 0xff24, + GET_HAP_TOKENINFO = 0xff25, + UPDATE_HAP_TOKEN = 0xff26, + + GET_HAP_TOKEN_FROM_REMOTE = 0xff27, + GET_ALL_NATIVE_TOKEN_FROM_REMOTE = 0xff28, + SET_REMOTE_HAP_TOKEN_INFO = 0xff29, + SET_REMOTE_NATIVE_TOKEN_INFO = 0xff2a, + DELETE_REMOTE_TOKEN_INFO = 0xff2b, + DELETE_REMOTE_DEVICE_TOKEN = 0xff2c, + + DUMP = 0xff30, + }; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // I_ACCESSTOKEN_MANAGER_H diff --git a/frameworks/accesstoken/include/native_token_info_parcel.h b/frameworks/accesstoken/include/native_token_info_parcel.h new file mode 100644 index 0000000000000000000000000000000000000000..80bf8909cba6cc20826ab2b4276572fc058f91dc --- /dev/null +++ b/frameworks/accesstoken/include/native_token_info_parcel.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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 NATIVE_TOKEN_INFO_PARCEL_H +#define NATIVE_TOKEN_INFO_PARCEL_H + +#include "native_token_info.h" + +#include "parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct NativeTokenInfoParcel final : public Parcelable { + NativeTokenInfoParcel() = default; + + ~NativeTokenInfoParcel() override = default; + + bool Marshalling(Parcel &out) const override; + + static NativeTokenInfoParcel *Unmarshalling(Parcel &in); + + NativeTokenInfo nativeTokenInfoParams; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // NATIVE_TOKEN_INFO_PARCEL_H diff --git a/frameworks/accesstoken/include/permission_def_parcel.h b/frameworks/accesstoken/include/permission_def_parcel.h new file mode 100644 index 0000000000000000000000000000000000000000..52e0a80c4197ea155f98ba126a7c13df22ac02f1 --- /dev/null +++ b/frameworks/accesstoken/include/permission_def_parcel.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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 PERMISSION_DEF_PARCEL_H +#define PERMISSION_DEF_PARCEL_H + +#include "permission_def.h" +#include "parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct PermissionDefParcel final : public Parcelable { + PermissionDefParcel() = default; + + ~PermissionDefParcel() override = default; + + bool Marshalling(Parcel &out) const override; + + static PermissionDefParcel *Unmarshalling(Parcel &in); + + PermissionDef permissionDef; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_DEF_PARCEL_H diff --git a/frameworks/accesstoken/include/permission_state_full_parcel.h b/frameworks/accesstoken/include/permission_state_full_parcel.h new file mode 100644 index 0000000000000000000000000000000000000000..f4b8714a7a832d6291adff4992eee953e60f8994 --- /dev/null +++ b/frameworks/accesstoken/include/permission_state_full_parcel.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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_STATE_FULL_PARCEL_H +#define INTERFACES_INNER_KITS_PERMISSION_PERMISSION_STATE_FULL_PARCEL_H + +#include "permission_state_full.h" +#include "parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct PermissionStateFullParcel final : public Parcelable { + PermissionStateFullParcel() = default; + + ~PermissionStateFullParcel() override = default; + + bool Marshalling(Parcel &out) const override; + + static PermissionStateFullParcel *Unmarshalling(Parcel &in); + + PermissionStateFull permStatFull; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // INTERFACES_INNER_KITS_PERMISSION_PERMISSION_STATE_FULL_PARCEL_H diff --git a/frameworks/accesstoken/src/hap_info_parcel.cpp b/frameworks/accesstoken/src/hap_info_parcel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0e3d984a4e0764e108080ab227cf5a97b3088c9 --- /dev/null +++ b/frameworks/accesstoken/src/hap_info_parcel.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 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 "hap_info_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 HapInfoParcel::Marshalling(Parcel& out) const +{ + RETURN_IF_FALSE(out.WriteInt32(this->hapInfoParameter.userID)); + RETURN_IF_FALSE(out.WriteString(this->hapInfoParameter.bundleName)); + RETURN_IF_FALSE(out.WriteInt32(this->hapInfoParameter.instIndex)); + RETURN_IF_FALSE(out.WriteString(this->hapInfoParameter.appIDDesc)); + return true; +} + +HapInfoParcel* HapInfoParcel::Unmarshalling(Parcel& in) +{ + auto* hapInfoParcel = new (std::nothrow) HapInfoParcel(); + RELEASE_IF_FALSE(hapInfoParcel != nullptr, hapInfoParcel); + RELEASE_IF_FALSE(in.ReadInt32(hapInfoParcel->hapInfoParameter.userID), hapInfoParcel); + hapInfoParcel->hapInfoParameter.bundleName = in.ReadString(); + RELEASE_IF_FALSE(in.ReadInt32(hapInfoParcel->hapInfoParameter.instIndex), hapInfoParcel); + hapInfoParcel->hapInfoParameter.appIDDesc = in.ReadString(); + + return hapInfoParcel; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/frameworks/accesstoken/src/hap_policy_parcel.cpp b/frameworks/accesstoken/src/hap_policy_parcel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fe2a079ce567b4c73a33b60a68480c8a9c4487da --- /dev/null +++ b/frameworks/accesstoken/src/hap_policy_parcel.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021 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 "hap_policy_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 HapPolicyParcel::Marshalling(Parcel& out) const +{ + RETURN_IF_FALSE(out.WriteInt32(this->hapPolicyParameter.apl)); + RETURN_IF_FALSE(out.WriteString(this->hapPolicyParameter.domain)); + + const std::vector& permList = this->hapPolicyParameter.permList; + int32_t permListSize = (int32_t)permList.size(); + RETURN_IF_FALSE(out.WriteInt32(permListSize)); + + for (int i = 0; i < permListSize; i++) { + PermissionDefParcel permDefParcel; + permDefParcel.permissionDef = permList[i]; + out.WriteParcelable(&permDefParcel); + } + + const std::vector& permStateList = this->hapPolicyParameter.permStateList; + int32_t permStateListSize = (int32_t)permStateList.size(); + RETURN_IF_FALSE(out.WriteInt32(permStateListSize)); + + for (int i = 0; i < permStateListSize; i++) { + PermissionStateFullParcel permStateParcel; + permStateParcel.permStatFull = permStateList[i]; + out.WriteParcelable(&permStateParcel); + } + + return true; +} + +HapPolicyParcel* HapPolicyParcel::Unmarshalling(Parcel& in) +{ + auto* hapPolicyParcel = new (std::nothrow) HapPolicyParcel(); + RELEASE_IF_FALSE(hapPolicyParcel != nullptr, hapPolicyParcel); + + int32_t apl; + RELEASE_IF_FALSE(in.ReadInt32(apl), hapPolicyParcel); + hapPolicyParcel->hapPolicyParameter.apl = ATokenAplEnum(apl); + + hapPolicyParcel->hapPolicyParameter.domain = in.ReadString(); + + int permListSize; + RELEASE_IF_FALSE(in.ReadInt32(permListSize), hapPolicyParcel); + + for (int i = 0; i < permListSize; i++) { + sptr permDefParcel = in.ReadParcelable(); + RELEASE_IF_FALSE(permDefParcel != nullptr, hapPolicyParcel); + hapPolicyParcel->hapPolicyParameter.permList.emplace_back(permDefParcel->permissionDef); + } + + int permStateListSize; + RELEASE_IF_FALSE(in.ReadInt32(permStateListSize), hapPolicyParcel); + for (int i = 0; i < permStateListSize; i++) { + sptr permissionStateParcel = in.ReadParcelable(); + RELEASE_IF_FALSE(permissionStateParcel != nullptr, hapPolicyParcel); + hapPolicyParcel->hapPolicyParameter.permStateList.emplace_back(permissionStateParcel->permStatFull); + } + return hapPolicyParcel; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/accesstoken/src/hap_token_info_for_sync_parcel.cpp b/frameworks/accesstoken/src/hap_token_info_for_sync_parcel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f3d642868d5f3a7d9909003d1288afbc0948758 --- /dev/null +++ b/frameworks/accesstoken/src/hap_token_info_for_sync_parcel.cpp @@ -0,0 +1,76 @@ +/* + * 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 "hap_token_info_for_sync_parcel.h" +#include "hap_token_info_parcel.h" +#include "permission_state_full_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 HapTokenInfoForSyncParcel::Marshalling(Parcel& out) const +{ + HapTokenInfoParcel baseInfoParcel; + baseInfoParcel.hapTokenInfoParams = this->hapTokenInfoForSyncParams.baseInfo; + out.WriteParcelable(&baseInfoParcel); + + const std::vector& permStateList = this->hapTokenInfoForSyncParams.permStateList; + int32_t permStateListSize = (int32_t)permStateList.size(); + RETURN_IF_FALSE(out.WriteInt32(permStateListSize)); + + for (int i = 0; i < permStateListSize; i++) { + PermissionStateFullParcel permStateParcel; + permStateParcel.permStatFull = permStateList[i]; + out.WriteParcelable(&permStateParcel); + } + + return true; +} + +HapTokenInfoForSyncParcel* HapTokenInfoForSyncParcel::Unmarshalling(Parcel& in) +{ + auto* hapTokenInfoForSyncParcel = new (std::nothrow) HapTokenInfoForSyncParcel(); + RELEASE_IF_FALSE(hapTokenInfoForSyncParcel != nullptr, hapTokenInfoForSyncParcel); + + sptr baseInfoParcel = in.ReadParcelable(); + RELEASE_IF_FALSE(baseInfoParcel != nullptr, hapTokenInfoForSyncParcel); + hapTokenInfoForSyncParcel->hapTokenInfoForSyncParams.baseInfo = baseInfoParcel->hapTokenInfoParams; + + int permStateListSize; + RELEASE_IF_FALSE(in.ReadInt32(permStateListSize), hapTokenInfoForSyncParcel); + for (int i = 0; i < permStateListSize; i++) { + sptr permissionStateParcel = in.ReadParcelable(); + RELEASE_IF_FALSE(permissionStateParcel != nullptr, hapTokenInfoForSyncParcel); + hapTokenInfoForSyncParcel->hapTokenInfoForSyncParams.permStateList.emplace_back( + permissionStateParcel->permStatFull); + } + return hapTokenInfoForSyncParcel; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + diff --git a/frameworks/accesstoken/src/hap_token_info_parcel.cpp b/frameworks/accesstoken/src/hap_token_info_parcel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a349518c03b3bdb005f771d049d14a4c02b69f1 --- /dev/null +++ b/frameworks/accesstoken/src/hap_token_info_parcel.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 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 "hap_token_info_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 HapTokenInfoParcel::Marshalling(Parcel& out) const +{ + RETURN_IF_FALSE(out.WriteInt32(this->hapTokenInfoParams.apl)); + RETURN_IF_FALSE(out.WriteUint8(this->hapTokenInfoParams.ver)); + RETURN_IF_FALSE(out.WriteInt32(this->hapTokenInfoParams.userID)); + RETURN_IF_FALSE(out.WriteString(this->hapTokenInfoParams.bundleName)); + RETURN_IF_FALSE(out.WriteInt32(this->hapTokenInfoParams.instIndex)); + RETURN_IF_FALSE(out.WriteString(this->hapTokenInfoParams.appID)); + RETURN_IF_FALSE(out.WriteString(this->hapTokenInfoParams.deviceID)); + RETURN_IF_FALSE(out.WriteUint32(this->hapTokenInfoParams.tokenID)); + RETURN_IF_FALSE(out.WriteUint32(this->hapTokenInfoParams.tokenAttr)); + return true; +} + +HapTokenInfoParcel* HapTokenInfoParcel::Unmarshalling(Parcel& in) +{ + auto* hapTokenInfoParcel = new (std::nothrow) HapTokenInfoParcel(); + RELEASE_IF_FALSE(hapTokenInfoParcel != nullptr, hapTokenInfoParcel); + int apl; + uint8_t ver; + RELEASE_IF_FALSE(in.ReadInt32(apl), hapTokenInfoParcel); + hapTokenInfoParcel->hapTokenInfoParams.apl = ATokenAplEnum(apl); + RELEASE_IF_FALSE(in.ReadUint8(ver), hapTokenInfoParcel); + hapTokenInfoParcel->hapTokenInfoParams.ver = ver; + RELEASE_IF_FALSE(in.ReadInt32(hapTokenInfoParcel->hapTokenInfoParams.userID), hapTokenInfoParcel); + hapTokenInfoParcel->hapTokenInfoParams.bundleName = in.ReadString(); + RELEASE_IF_FALSE(in.ReadInt32(hapTokenInfoParcel->hapTokenInfoParams.instIndex), hapTokenInfoParcel); + hapTokenInfoParcel->hapTokenInfoParams.appID = in.ReadString(); + hapTokenInfoParcel->hapTokenInfoParams.deviceID = in.ReadString(); + RELEASE_IF_FALSE(in.ReadUint32(hapTokenInfoParcel->hapTokenInfoParams.tokenID), hapTokenInfoParcel); + RELEASE_IF_FALSE(in.ReadUint32(hapTokenInfoParcel->hapTokenInfoParams.tokenAttr), hapTokenInfoParcel); + return hapTokenInfoParcel; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/accesstoken/src/native_token_info_parcel.cpp b/frameworks/accesstoken/src/native_token_info_parcel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..50795dc3639b7582487c11128d8cae684313bc98 --- /dev/null +++ b/frameworks/accesstoken/src/native_token_info_parcel.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021 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 "native_token_info_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 NativeTokenInfoParcel::Marshalling(Parcel& out) const +{ + RETURN_IF_FALSE(out.WriteInt32(this->nativeTokenInfoParams.apl)); + RETURN_IF_FALSE(out.WriteUint8(this->nativeTokenInfoParams.ver)); + RETURN_IF_FALSE(out.WriteString(this->nativeTokenInfoParams.processName)); + RETURN_IF_FALSE(out.WriteUint32(this->nativeTokenInfoParams.tokenID)); + RETURN_IF_FALSE(out.WriteUint32(this->nativeTokenInfoParams.tokenAttr)); + + int dcapSize = (int)(this->nativeTokenInfoParams.dcap).size(); + RETURN_IF_FALSE(out.WriteInt32(dcapSize)); + + for (auto dcapItem : this->nativeTokenInfoParams.dcap) { + RETURN_IF_FALSE(out.WriteString(dcapItem)); + } + + return true; +} + +NativeTokenInfoParcel* NativeTokenInfoParcel::Unmarshalling(Parcel& in) +{ + auto* nativeTokenInfoParcel = new (std::nothrow) NativeTokenInfoParcel(); + RELEASE_IF_FALSE(nativeTokenInfoParcel != nullptr, nativeTokenInfoParcel); + + int32_t apl; + uint8_t ver; + RELEASE_IF_FALSE(in.ReadInt32(apl), nativeTokenInfoParcel); + RELEASE_IF_FALSE(in.ReadUint8(ver), nativeTokenInfoParcel); + nativeTokenInfoParcel->nativeTokenInfoParams.apl = ATokenAplEnum(apl); + nativeTokenInfoParcel->nativeTokenInfoParams.ver = ver; + + nativeTokenInfoParcel->nativeTokenInfoParams.processName = in.ReadString(); + RELEASE_IF_FALSE(in.ReadUint32(nativeTokenInfoParcel->nativeTokenInfoParams.tokenID), nativeTokenInfoParcel); + RELEASE_IF_FALSE(in.ReadUint32(nativeTokenInfoParcel->nativeTokenInfoParams.tokenAttr), nativeTokenInfoParcel); + + int dcapSize; + RELEASE_IF_FALSE(in.ReadInt32(dcapSize), nativeTokenInfoParcel); + + for (int i = 0; i < dcapSize; i++) { + std::string dcapsItem; + RELEASE_IF_FALSE(in.ReadString(dcapsItem), nativeTokenInfoParcel); + nativeTokenInfoParcel->nativeTokenInfoParams.dcap.emplace_back(dcapsItem); + } + return nativeTokenInfoParcel; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/accesstoken/src/permission_def_parcel.cpp b/frameworks/accesstoken/src/permission_def_parcel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09943e9a04725d43096c7aa1b2260d329927a320 --- /dev/null +++ b/frameworks/accesstoken/src/permission_def_parcel.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 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_def_parcel.h" + +#include "access_token.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 PermissionDefParcel::Marshalling(Parcel& out) const +{ + RETURN_IF_FALSE(out.WriteString(this->permissionDef.permissionName)); + RETURN_IF_FALSE(out.WriteString(this->permissionDef.bundleName)); + RETURN_IF_FALSE(out.WriteInt32(this->permissionDef.grantMode)); + RETURN_IF_FALSE(out.WriteInt32(this->permissionDef.availableLevel)); + RETURN_IF_FALSE(out.WriteBool(this->permissionDef.provisionEnable)); + RETURN_IF_FALSE(out.WriteBool(this->permissionDef.distributedSceneEnable)); + RETURN_IF_FALSE(out.WriteString(this->permissionDef.label)); + RETURN_IF_FALSE(out.WriteInt32(this->permissionDef.labelId)); + RETURN_IF_FALSE(out.WriteString(this->permissionDef.description)); + RETURN_IF_FALSE(out.WriteInt32(this->permissionDef.descriptionId)); + return true; +} + +PermissionDefParcel* PermissionDefParcel::Unmarshalling(Parcel& in) +{ + auto* permissionDefParcel = new (std::nothrow) PermissionDefParcel(); + RELEASE_IF_FALSE(permissionDefParcel != nullptr, permissionDefParcel); + permissionDefParcel->permissionDef.permissionName = in.ReadString(); + permissionDefParcel->permissionDef.bundleName = in.ReadString(); + RELEASE_IF_FALSE(in.ReadInt32(permissionDefParcel->permissionDef.grantMode), permissionDefParcel); + + int level; + RELEASE_IF_FALSE(in.ReadInt32(level), permissionDefParcel); + permissionDefParcel->permissionDef.availableLevel = ATokenAplEnum(level); + + RELEASE_IF_FALSE(in.ReadBool(permissionDefParcel->permissionDef.provisionEnable), permissionDefParcel); + RELEASE_IF_FALSE(in.ReadBool(permissionDefParcel->permissionDef.distributedSceneEnable), permissionDefParcel); + permissionDefParcel->permissionDef.label = in.ReadString(); + RELEASE_IF_FALSE(in.ReadInt32(permissionDefParcel->permissionDef.labelId), permissionDefParcel); + permissionDefParcel->permissionDef.description = in.ReadString(); + RELEASE_IF_FALSE(in.ReadInt32(permissionDefParcel->permissionDef.descriptionId), permissionDefParcel); + return permissionDefParcel; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/frameworks/accesstoken/src/permission_state_full_parcel.cpp b/frameworks/accesstoken/src/permission_state_full_parcel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a5dd6fe5cdbf69db08a04302875af6572b34610 --- /dev/null +++ b/frameworks/accesstoken/src/permission_state_full_parcel.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021 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_state_full_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 PermissionStateFullParcel::Marshalling(Parcel& out) const +{ + RETURN_IF_FALSE(out.WriteString(this->permStatFull.permissionName)); + RETURN_IF_FALSE(out.WriteBool(this->permStatFull.isGeneral)); + + RETURN_IF_FALSE(out.WriteInt32((int32_t)(this->permStatFull.resDeviceID.size()))); + for (auto devId : this->permStatFull.resDeviceID) { + RETURN_IF_FALSE(out.WriteString(devId)); + } + + RETURN_IF_FALSE(out.WriteInt32((int32_t)(this->permStatFull.grantStatus.size()))); + for (auto grantStat : this->permStatFull.grantStatus) { + RETURN_IF_FALSE(out.WriteInt32(grantStat)); + } + + RETURN_IF_FALSE(out.WriteInt32((int32_t)(this->permStatFull.grantFlags.size()))); + for (auto grantFlag : this->permStatFull.grantFlags) { + RETURN_IF_FALSE(out.WriteInt32(grantFlag)); + } + return true; +} + +PermissionStateFullParcel* PermissionStateFullParcel::Unmarshalling(Parcel& in) +{ + auto* permissionStateParcel = new (std::nothrow) PermissionStateFullParcel(); + RELEASE_IF_FALSE(permissionStateParcel != nullptr, permissionStateParcel); + + RELEASE_IF_FALSE(in.ReadString(permissionStateParcel->permStatFull.permissionName), permissionStateParcel); + RELEASE_IF_FALSE(in.ReadBool(permissionStateParcel->permStatFull.isGeneral), permissionStateParcel); + + int resIdSize = 0; + RELEASE_IF_FALSE(in.ReadInt32(resIdSize), permissionStateParcel); + for (int i = 0; i < resIdSize; i++) { + std::string resId; + RELEASE_IF_FALSE(in.ReadString(resId), permissionStateParcel); + permissionStateParcel->permStatFull.resDeviceID.emplace_back(resId); + } + + int grantStatsSize = 0; + RELEASE_IF_FALSE(in.ReadInt32(grantStatsSize), permissionStateParcel); + for (int i = 0; i < grantStatsSize; i++) { + int grantStat; + RELEASE_IF_FALSE(in.ReadInt32(grantStat), permissionStateParcel); + permissionStateParcel->permStatFull.grantStatus.emplace_back(grantStat); + } + + int grantFlagSize = 0; + RELEASE_IF_FALSE(in.ReadInt32(grantFlagSize), permissionStateParcel); + for (int i = 0; i < grantFlagSize; i++) { + int flag; + RELEASE_IF_FALSE(in.ReadInt32(flag), permissionStateParcel); + permissionStateParcel->permStatFull.grantFlags.emplace_back(flag); + } + return permissionStateParcel; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/build.gradle b/frameworks/com.ohos.permissionmanager/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..924a888a108e0af16c918e3b049937f48089a7bf --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/build.gradle @@ -0,0 +1,33 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.5.2' + classpath 'com.huawei.ohos:decctest:1.2.7.2' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} diff --git a/frameworks/com.ohos.permissionmanager/entry/.gitignore b/frameworks/com.ohos.permissionmanager/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7a94f4dcf381f03ff21f28f8a2494b58023f --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/frameworks/com.ohos.permissionmanager/entry/build.gradle b/frameworks/com.ohos.permissionmanager/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..0f0156791bf6048a230e13abccb9d631170209dc --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.huawei.ohos.hap' +apply plugin: 'com.huawei.ohos.decctest' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:2.0.0.200' +} +decc { + supportType = ['html','xml'] +} diff --git a/frameworks/com.ohos.permissionmanager/entry/proguard-rules.pro b/frameworks/com.ohos.permissionmanager/entry/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/entry/src/main/config.json b/frameworks/com.ohos.permissionmanager/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..165e0d3bd16be20696ddac1f4660634cb7ffb98f --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/main/config.json @@ -0,0 +1,63 @@ +{ + "app": { + "bundleName": "com.ohos.permissionmanager", + "vendor": "ohos", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.ohos.permissionmanager", + "name": ".MyApplication", + "mainAbility": "com.ohos.permissionmanager.MainAbility", + "deviceType": [ + "phone", + "tablet" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "visible": true, + "name": "com.ohos.permissionmanager.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/index" + ], + "name": "default", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/entry/src/main/ets/default/app.ets b/frameworks/com.ohos.permissionmanager/entry/src/main/ets/default/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..2a3b6238737330f469fc124b0669aacd9a376056 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/main/ets/default/app.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 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. + */ + +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} diff --git a/frameworks/com.ohos.permissionmanager/entry/src/main/ets/default/pages/index.ets b/frameworks/com.ohos.permissionmanager/entry/src/main/ets/default/pages/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..4572857a3fb9c18efbf83a9af8674fc175f2dbeb --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/main/ets/default/pages/index.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 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. + */ + +@Entry +@Component +struct Index { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Text('Hello World') + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + .height('100%') + } +} diff --git a/frameworks/com.ohos.permissionmanager/entry/src/main/java/com/ohos/permissionmanager/MainAbility.java b/frameworks/com.ohos.permissionmanager/entry/src/main/java/com/ohos/permissionmanager/MainAbility.java new file mode 100644 index 0000000000000000000000000000000000000000..5e73933e0b4c0b4d24db9021f2d89c66d6bbe8d9 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/main/java/com/ohos/permissionmanager/MainAbility.java @@ -0,0 +1,16 @@ +package com.ohos.permissionmanager; + +import ohos.ace.ability.AceAbility; +import ohos.aafwk.content.Intent; + +public class MainAbility extends AceAbility { + @Override + public void onStart(Intent intent) { + super.onStart(intent); + } + + @Override + public void onStop() { + super.onStop(); + } +} diff --git a/frameworks/com.ohos.permissionmanager/entry/src/main/java/com/ohos/permissionmanager/MyApplication.java b/frameworks/com.ohos.permissionmanager/entry/src/main/java/com/ohos/permissionmanager/MyApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..8c75d4e56c1ee06e2ee83469c50be84ef00af14e --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/main/java/com/ohos/permissionmanager/MyApplication.java @@ -0,0 +1,10 @@ +package com.ohos.permissionmanager; + +import ohos.aafwk.ability.AbilityPackage; + +public class MyApplication extends AbilityPackage { + @Override + public void onInitialize() { + super.onInitialize(); + } +} diff --git a/frameworks/com.ohos.permissionmanager/entry/src/main/resources/base/element/string.json b/frameworks/com.ohos.permissionmanager/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..bc3df790ef54add880b08cf9dbd43bc45a9137d4 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/main/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "entry_MainAbility" + }, + { + "name": "mainability_description", + "value": "eTS_Empty Ability" + } + ] +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/entry/src/main/resources/base/media/icon.png b/frameworks/com.ohos.permissionmanager/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/frameworks/com.ohos.permissionmanager/entry/src/main/resources/base/media/icon.png differ diff --git a/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/app.ets b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..fd310895976fc0623ac1bdc3ded2ab5209393f62 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/app.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 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. + */ + +export default { + onCreate() { + console.info('Application onCreate') + }, + onShow() { + console.info('Application onShow') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} diff --git a/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/i18n/en-US.json b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/i18n/en-US.json new file mode 100644 index 0000000000000000000000000000000000000000..55561b83737c3c31d082fbfa11e5fc987a351104 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/i18n/en-US.json @@ -0,0 +1,8 @@ +{ + "strings": { + "hello": "Hello", + "world": "World" + }, + "Files": { + } +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/i18n/zh-CN.json b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/i18n/zh-CN.json new file mode 100644 index 0000000000000000000000000000000000000000..cce1af06761a42add0cac1a0567aa3237eda8cb4 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/i18n/zh-CN.json @@ -0,0 +1,8 @@ +{ + "strings": { + "hello": "您好", + "world": "世界" + }, + "Files": { + } +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/pages/index/index.ets b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/pages/index/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..2ebd82564e904d46ae1a9c3ca8867307af17f6de --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/default/pages/index/index.ets @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 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. + */ + +import {Core, ExpectExtend, InstrumentLog} from "deccjsunit/index" +import testsuite from "../../../test/List.test.ets" +import featureAbility from "@ohos.ability.featureAbility" + +@Entry +@Component +struct MyComponent { + aboutToAppear() { + console.info("start run testcase!!!!") + featureAbility.getWant() + .then((Want) => { + const core = Core.getInstance() + const expectExtend = new ExpectExtend({ + 'id': 'extend' + }) + const instrumentLog = new InstrumentLog({ + 'id': 'report', 'unity': 'true' + }) + core.addService('expect', expectExtend) + core.addService('report', instrumentLog) + core.init() + core.subscribeEvent('spec', instrumentLog) + core.subscribeEvent('suite', instrumentLog) + core.subscribeEvent('task', instrumentLog) + const configService = core.getDefaultService('config') + configService.setConfig(Want.parameters) + testsuite() + core.execute() + console.info('Operation successful. Data: ' + JSON.stringify(Want)); + }) + .catch((error) => { + console.error('Operation failed. Cause: ' + JSON.stringify(error)); + }) + } + + build() { + Flex({ + direction: FlexDirection.Column, + alignItems: ItemAlign.Center, + justifyContent: FlexAlign.Center + }) { + Text('Hello World') + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + .height('100%') + } +} diff --git a/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/test/ExampleJsunit.test.ets b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/test/ExampleJsunit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..35824cab41eb5d75507485b5d95e23c8d4d57f2d --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/test/ExampleJsunit.test.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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. + */ + +import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from "deccjsunit/index" +import app from '@system.app' + +export default function exampleJsunit() { + describe('appInfoTest', function () { + it('app_info_test_001', 0, function () { + var info = app.getInfo() + expect("1.0").assertEqual('1.0') + expect(info.versionCode).assertEqual('3') + }) + }) +} diff --git a/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/test/List.test.ets b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..e659c7498c0278c228641fa8eabf91893a84d8e7 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2021 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. + */ + +import exampleJsunit from "../test/ExampleJsunit.test.ets" + +export default function testsuite() { + exampleJsunit() +} diff --git a/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/java/com/ohos/permissionmanager/ExampleOhosTest.java b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/java/com/ohos/permissionmanager/ExampleOhosTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9482d133c3b1866f581978213dce868e966f5e9d --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/java/com/ohos/permissionmanager/ExampleOhosTest.java @@ -0,0 +1,14 @@ +package com.ohos.permissionmanager; + +import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ExampleOhosTest { + @Test + public void testBundleName() { + final String actualBundleName = AbilityDelegatorRegistry.getArguments().getTestBundleName(); + assertEquals("com.ohos.permissionmanager", actualBundleName); + } +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/resources/base/element/string.json b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..998415d3588045c96c5d9db329c45087769c1d92 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "app_name", + "value": "finalApplication" + }, + { + "name": "mainability_description", + "value": "hap sample empty page" + } + ] +} diff --git a/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/resources/base/media/icon.png b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/frameworks/com.ohos.permissionmanager/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/frameworks/com.ohos.permissionmanager/gradle.properties b/frameworks/com.ohos.permissionmanager/gradle.properties new file mode 100644 index 0000000000000000000000000000000000000000..be492496f9a20ac2d980ef4fc30061f4184c1c40 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/gradle.properties @@ -0,0 +1,13 @@ +# Project-wide Gradle settings. +# IDE (e.g. DevEco Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# If the Chinese output is garbled, please configure the following parameter. +# This function is enabled by default when the DevEco Studio builds the hap/app,if you need disable gradle parallel,you should set org.gradle.parallel false. +# more information see https://docs.gradle.org/current/userguide/performance.html +# org.gradle.parallel=false +# org.gradle.jvmargs=-Dfile.encoding=GBK \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/gradlew b/frameworks/com.ohos.permissionmanager/gradlew new file mode 100644 index 0000000000000000000000000000000000000000..120f1adf94a915f110fef9c186e9138ee25bcc97 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright (c) 2021 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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ]; do + ls=$(ls -ld "$PRG") + link=$(expr "$ls" : '.*-> \(.*\)$') + if expr "$link" : '/.*' >/dev/null; then + PRG="$link" + else + PRG=$(dirname "$PRG")"/$link" + fi +done +SAVED="$(pwd)" +cd "$(dirname \"$PRG\")/" >/dev/null +APP_HOME="$(pwd -P)" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=$(basename "$0") + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn() { + echo "$*" +} + +die() { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$(uname)" in +CYGWIN*) + cygwin=true + ;; +Darwin*) + darwin=true + ;; +MINGW*) + msys=true + ;; +NONSTOP*) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ]; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then + MAX_FD_LIMIT=$(ulimit -H -n) + if [ $? -eq 0 ]; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ]; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ]; then + APP_HOME=$(cygpath --path --mixed "$APP_HOME") + CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") + JAVACMD=$(cygpath --unix "$JAVACMD") + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) + SEP="" + for dir in $ROOTDIRSRAW; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ]; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@"; do + CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) + CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition + eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") + else + eval $(echo args$i)="\"$arg\"" + fi + i=$(expr $i + 1) + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save() { + for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/frameworks/com.ohos.permissionmanager/gradlew.bat b/frameworks/com.ohos.permissionmanager/gradlew.bat new file mode 100644 index 0000000000000000000000000000000000000000..acdc32e2dae3e8e42e391878d96766acce16af0a --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright (c) 2021 Huawei Device Co., Ltd. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/frameworks/com.ohos.permissionmanager/package.json b/frameworks/com.ohos.permissionmanager/package.json new file mode 100644 index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/package.json @@ -0,0 +1 @@ +{} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/.gitignore b/frameworks/com.ohos.permissionmanager/permissionmanager/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7a94f4dcf381f03ff21f28f8a2494b58023f --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/build.gradle b/frameworks/com.ohos.permissionmanager/permissionmanager/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..f6df7ecdb12da752cca18e02b7fa62b63bba70ed --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/build.gradle @@ -0,0 +1,28 @@ +apply plugin: 'com.huawei.ohos.hap' +apply plugin: 'com.huawei.ohos.decctest' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } + entryModules "entry" +} + +dependencies { + entryImplementation project(':entry') + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:2.0.0.200' +} +decc { + supportType = ['html','xml'] +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/proguard-rules.pro b/frameworks/com.ohos.permissionmanager/permissionmanager/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/config.json b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..afb90ba92dd0d249784ae17efee38482454b0e11 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/config.json @@ -0,0 +1,74 @@ +{ + "app": { + "bundleName": "com.ohos.permissionmanager", + "vendor": "ohos", + "version": { + "code": 1, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.ohos.permissionmanager", + "name": ".MyApplication", + "mainAbility": "com.ohos.permissionmanager.GrantAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "permissionmanager", + "moduleType": "feature", + "installationFree": false + }, + "abilities": [ + { + "visible": true, + "name": "com.ohos.permissionmanager.GrantAbility", + "description": "$string:grantability_description", + "label": "$string:permissionmanager_GrantAbility", + "type": "page", + "launchType": "standard", + "srcPath": "dynamic" + } + ], + "js": [ + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/dialogPlus" + ], + "name": "dynamic", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ], + "reqPermissions": [ + { + "name": "ohos.permission.GET_SENSITIVE_PERMISSIONS", + "reason": "get sensitive permissions" + }, + { + "name": "ohos.permission.GRANT_SENSITIVE_PERMISSIONS", + "reason": "grant sensitive permissions" + }, + { + "name": "ohos.permission.REVOKE_SENSITIVE_PERMISSIONS", + "reason": "revoke sensitive permissions" + }, + { + "name": "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", + "reason": "get applicationInfo" + }, + { + "name": "ohos.permission.GET_BUNDLE_INFO", + "reason": "get applicationInfo" + } + ] + } +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/default/app.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/default/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..2a3b6238737330f469fc124b0669aacd9a376056 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/default/app.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 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. + */ + +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/app.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..2a3b6238737330f469fc124b0669aacd9a376056 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/app.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 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. + */ + +export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/components/dialog.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/components/dialog.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd5ed3e8feda29e8fc5dc2a697d078bbf92942d3 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/components/dialog.ets @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2021 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. + */ + +import { getPermissionGroup } from '../utils/utils.ets' +import { BundleFlag, USER_ID } from '../model/bundle.ets' +import Constants from '../utils/constant.ets' +import featureAbility from '@ohos.ability.featureAbility' +import abilityAccessCtrl from '@ohos.abilityAccessCtrl' +import bundle from '@ohos.bundle' +import Resmgr from '@ohos.resourceManager' + +@Extend(Button) function customizeButton() { + .backgroundColor($r('app.color.default_background_color')) + .fontColor($r('app.color.button_color')) +} + +@CustomDialog +export struct privacyDialog { + @Link count: number + @Link result: Array + controller: CustomDialogController + cancel: (group, accessTokenId, permissionList, userFixedFlag) => void + confirm: (group, accessTokenId, permissionList, userFixedFlag) => void + @State accessTokenId: number = 0 + @State initStatus: number = Constants.INIT_NEED_TO_WAIT + @State reqPerms: Array = [] + @State grantGroups: Array = [] + @State userFixedFlag: number = 2 // means user fixed + @State appName: string = "" + + build() { + Column() { + if ((this.initStatus != Constants.INIT_NEED_TO_WAIT) && this.verify(this.reqPerms[this.count])) { + Image(this.grantGroups[this.count].icon) + .width(Constants.DIALOG_ICON_WIDTH) + .height(Constants.DIALOG_ICON_HEIGHT) + .margin({ + top: Constants.DIALOG_ICON_MARGIN_TOP + }) + Text(`${this.count + 1} / ${this.reqPerms.length}`) + .fontSize(Constants.DIALOG_LABEL_FONT_SIZE) + .fontColor($r('app.color.secondary_font_color')) + .margin({ + top: Constants.DIALOG_LABEL_MARGIN_TOP + }) + Column() { + Row() { + Flex({ justifyContent: FlexAlign.Start }) { + Text("是否允许" + this.appName + "访问" + + this.grantGroups[this.count].groupName).fontSize(Constants.DIALOG_REQ_FONT_SIZE) + .fontColor($r('app.color.secondary_font_color')) + .margin({ + top: Constants.DIALOG_REQ_MARGIN_TOP, + left: Constants.DIALOG_REQ_MARGIN_LEFT + }) + } + } + Row() { + Flex({ justifyContent: FlexAlign.Start }) { + Text("用于" + this.grantGroups[this.count].description).fontSize(Constants.DIALOG_DESP_FONT_SIZE) + .fontColor($r('app.color.secondary_font_color')) + .margin({ + top: Constants.DIALOG_DESP_MARGIN_TOP, + left: Constants.DIALOG_DESP_MARGIN_LEFT + }) + } + } + } + } + Row() { + Flex({ justifyContent: FlexAlign.SpaceAround }) { + Button('禁止') + .fontSize(Constants.BUTTON_FONT_SIZE) + .onClick(() => { + this.cancel(this.grantGroups[this.count], this.accessTokenId, this.reqPerms, this.userFixedFlag) + if (this.count === this.reqPerms.length) { + this.controller.close() + } + }).customizeButton() + Text('|').fontSize(Constants.BUTTON_DIVIDER_FONT_SIZE).fontColor($r('app.color.divider_color')) + Button('允许') + .fontSize(Constants.BUTTON_FONT_SIZE) + .onClick(() => { + this.confirm(this.grantGroups[this.count], this.accessTokenId, this.reqPerms, this.userFixedFlag) + if (this.count === this.reqPerms.length) { + this.controller.close() + } + }).customizeButton() + }.margin({ + top: Constants.BUTTON_MARGIN_TOP + }) + } + } + .backgroundColor($r('app.color.default_background_color')) + .borderRadius(Constants.DIALOG_BORDER_RADIUS) + .height(Constants.DIALOG_HEIGHT) + .width(Constants.DIALOG_WIDTH) + } + async verify(permission) { + if((this.initStatus == Constants.INIT_NEED_TO_TERMINATED) || (this.count >= this.grantGroups.length)) { + this.controller.close() + this.aboutToDisappear() + return false + } + if(this.grantGroups[this.count] == 0) { + this.result[this.count] = -1 + this.count ++ + return false + } + var acManager = abilityAccessCtrl.createAtManager() + var flag = await acManager.getPermissionFlags(this.accessTokenId, permission) + if(flag == this.userFixedFlag) { + console.log("GrantAbility permission has been fixed:" + permission) + var ret = await acManager.verifyAccessToken(this.accessTokenId, permission) + if (ret == 0) { + this.result[this.count] = 0 + } else { + this.result[this.count] = -1 + } + this.count ++ + return false + } + this.result[this.count] = -1 + return true + } + + getApplicationName(uid) { + bundle.getNameForUid(uid).then((data) => { + console.log("GrantAbility getApplicationName bundleName:" + data) + bundle.getApplicationInfo(data, BundleFlag.GET_BUNDLE_DEFAULT, USER_ID).then(applicationInfo => { + Resmgr.getResourceManager(data).then(item => { + item.getString(applicationInfo.labelId, (err, value) => { + if (value == undefined) { + this.appName = applicationInfo.label + } else { + this.appName = value + } + console.log("GrantAbility hap label:" + applicationInfo.label + ", value:"+this.appName) + }) + }) + }).catch(err => { + console.log("GrantAbility applicationInfo error :" + err) + this.initStatus = Constants.INIT_NEED_TO_TERMINATED + }) + }).catch(err => { + console.log("GrantAbility getNameForUid error :" + JSON.stringify(err)) + this.initStatus = Constants.INIT_NEED_TO_TERMINATED + }) + } + + aboutToAppear() { + this.count = 0; + this.initStatus = Constants.INIT_NEED_TO_WAIT + this.result = [] + featureAbility.getWant((err, want) => { + if (err.code != 0) { + console.log("GrantAbility featureAbility.getWant err:" + err) + this.initStatus = Constants.INIT_NEED_TO_TERMINATED + return + } + this.reqPerms = want.parameters['ohos.user.grant.permission'] + this.accessTokenId = want.parameters['ohos.aafwk.param.callerToken'] + if (this.reqPerms == undefined || this.accessTokenId == undefined || this.reqPerms.length == 0) { + console.log("GrantAbility invalid parameters") + this.initStatus = Constants.INIT_NEED_TO_TERMINATED + return + } + console.log("GrantAbility request permission=" + JSON.stringify(this.reqPerms) + ", tokenId = " + this.accessTokenId) + this.reqPerms.forEach(item => { + var group = getPermissionGroup(item) + if(!group) { + this.grantGroups.push(0) + console.log("GrantAbility permission not find:" + item) + }else { + this.grantGroups.push(group) + } + }) + this.initStatus = Constants.INIT_NEED_TO_VERIFY + this.getApplicationName(want.parameters['ohos.aafwk.param.callerUid']) + }) + } + + aboutToDisappear() { + var ret: number = Constants.RESULT_SUCCESS + if (this.initStatus == Constants.INIT_NEED_TO_TERMINATED) { + ret = Constants.RESULT_FAILURE + } + console.log("GrantAbility code:" + ret + ", result=" + JSON.stringify(this.result)) + featureAbility.terminateSelfWithResult({ + resultCode: ret, + want: { + parameters: { + "ohos.user.grant.permission": this.reqPerms, + "ohos.user.grant.permission.result": this.result + } + } + }) + } +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/model/bundle.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/model/bundle.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d34276d39d2cfb0e6b4a56dd09dc75dbcea7914 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/model/bundle.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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. + */ + +export const BundleFlag = { + GET_BUNDLE_DEFAULT : 0x00000000, + GET_BUNDLE_WITH_ABILITIES : 0x00000001, + GET_ABILITY_INFO_WITH_PERMISSION : 0x00000002, + GET_ABILITY_INFO_WITH_APPLICATION : 0x00000004, + GET_APPLICATION_INFO_WITH_PERMISSION : 0x00000008, + GET_BUNDLE_WITH_REQUESTED_PERMISSION : 0x00000010, + GET_ALL_APPLICATION_INFO : 0xFFFF0000, + /** + * @since 8 + */ + GET_ABILITY_INFO_WITH_METADATA : 0x00000020, + /** + * @since 8 + */ + GET_APPLICATION_INFO_WITH_METADATA : 0x00000040, + /** + * @since 8 + */ + GET_ABILITY_INFO_SYSTEMAPP_ONLY : 0x00000080 +} + +export const USER_ID: number = 100 \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/model/permissionGroup.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/model/permissionGroup.ets new file mode 100644 index 0000000000000000000000000000000000000000..087c521e3a0728fabc5cea08c975b085fccd0044 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/model/permissionGroup.ets @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2021 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. + */ + +export const permissionGroups: any[] = [ + { + "permissionName": "ohos.permission.LOCATION_IN_BACKGROUND", + "groupName": "LOCATION", + "label": "定位权限", + "description": "允许应用在后台运行时获取位置信息。", + "groupId": 0 + }, + { + "permissionName": "ohos.permission.LOCATION", + "groupName": "LOCATION", + "label": "定位权限", + "description": "允许应用在前台运行时获取位置信息。", + "groupId": 0 + }, + { + "permissionName": "ohos.permission.CAMERA", + "groupName": "CAMERA", + "label": "拍摄照片和录制视频", + "description": "允许应用拍摄照片和视频。", + "groupId": 1 + }, + { + "permissionName": "ohos.permission.MICROPHONE", + "groupName": "MICROPHONE", + "label": "录制音频", + "description": "允许应用打开或关闭录音通路。", + "groupId": 2 + }, + { + "permissionName": "ohos.permission.ANSWER_CALL", + "groupName": "PHONE", + "label": "接听电话", + "description": "允许应用接听电话。", + "groupId": 3 + }, + { + "permissionName": "ohos.permission.MANAGE_VOICEMAIL", + "groupName": "PHONE", + "label": "语音信箱", + "description": "允许应用管理语音信箱。", + "groupId": 3 + }, + { + "permissionName": "ohos.permission.READ_CELL_MESSAGES", + "groupName": "SMS", + "label": "读取小区广播", + "description": "允许应用读取设备接收的小区广播信息。", + "groupId": 4 + }, + { + "permissionName": "ohos.permission.READ_MESSAGES", + "groupName": "SMS", + "label": "读取短彩信", + "description": "允许应用读取设备接收的短彩信信息。", + "groupId": 4 + }, + { + "permissionName": "ohos.permission.RECEIVE_MMS", + "groupName": "SMS", + "label": "接收彩信", + "description": "允许应用接收彩信。", + "groupId": 4 + }, + { + "permissionName": "ohos.permission.RECEIVE_SMS", + "groupName": "SMS", + "label": "接收短信", + "description": "允许应用接收短信。", + "groupId": 4 + }, + { + "permissionName": "ohos.permission.RECEIVE_WAP_MESSAGES", + "groupName": "SMS", + "label": "接收WAP消息", + "description": "允许应用接收和处理WAP消息。", + "groupId": 4 + }, + { + "permissionName": "ohos.permission.SEND_MESSAGES", + "groupName": "SMS", + "label": "发送短彩信", + "description": "允许应用发送短彩信", + "groupId": 4 + }, + { + "permissionName": "ohos.permission.READ_CONTACTS", + "groupName": "CONTACTS", + "label": "读取通讯录", + "description": "允许应用读取设备上存储的联系人信息。", + "groupId": 5 + }, + { + "permissionName": "ohos.permission.WRITE_CONTACTS", + "groupName": "CONTACTS", + "label": "新建/修改/删除通讯录", + "description": "允许应用新建/修改/删除设备上存储的联系人信息。", + "groupId": 5 + }, + { + "permissionName": "ohos.permission.READ_CALL_LOG", + "groupName": "CALL_LOG", + "label": "读取通话记录", + "description": "允许应用读取设备上的通话记录信息。", + "groupId": 6 + }, + { + "permissionName": "ohos.permission.WRITE_CALL_LOG", + "groupName": "CALL_LOG", + "label": "新建/修改/删除通话记录", + "description": "允许新建/修改/删除设备上的通话记录信息。", + "groupId": 6 + }, + { + "permissionName": "ohos.permission.MEDIA_LOCATION", + "groupName": "MEDIA", + "label": "允许应用访问拍摄位置", + "description": "应用访问用户媒体文件中的拍摄位置信息如经纬度信息。", + "groupId": 7 + }, + { + "permissionName": "ohos.permission.READ_MEDIA", + "groupName": "MEDIA", + "label": "允许应用读取媒体文件", + "description": "允许应用访问户媒体文件,如视频、音频、图片等。", + "groupId": 7 + }, + { + "permissionName": "ohos.permission.WRITE_MEDIA", + "groupName": "MEDIA", + "label": "允许应用读写媒体文件", + "description": "允许应用读写户媒体文件,如视频、音频、图片等。", + "groupId": 7 + }, + { + "permissionName": "ohos.permission.READ_CALENDAR", + "groupName": "CALENDAR", + "label": "读取日历", + "description": "允许应用读取日历。", + "groupId": 8 + }, + { + "permissionName": "ohos.permission.WRITE_CALENDAR", + "groupName": "CALENDAR", + "label": "修建/修改/删除日历", + "description": "允许应用修建/修改/删除日历。", + "groupId": 8 + }, + { + "permissionName": "ohos.permission.ACTIVITY_MOTION", + "groupName": "SPORT", + "label": "读取用户的运动状态", + "description": "允许应用程序读取用户的运动状态。", + "groupId": 9 + }, + { + "permissionName": "ohos.permission.READ_HEALTH_DATA", + "groupName": "HEALTH", + "label": "读取用户的健康数据", + "description": "允许应用程序读取用户的健康数据。", + "groupId": 10 + }, + { + "permissionName": "ohos.permission.DISTRIBUTED_DATASYNC", + "groupName": "OTHER", + "label": "允许不同设备间数据交换", + "description": "允许应用与远程设备交换用户数据(如图片、音乐、视频、及应用数据等)。", + "groupId": 11 + } +] + +export const groups: any[] = [ + { + "name": "LOCATION", + "groupName": "位置信息", + "icon": $r('app.media.ic_public_gps'), + "description": "访问您的位置信息", + "permissions": [ + "ohos.permission.LOCATION_IN_BACKGROUND", + "ohos.permission.LOCATION" + ] + }, + { + "name": "CAMERA", + "groupName": "相机", + "icon": $r('app.media.ic_public_camera'), + "description": "访问您的相机", + "permissions": [ + "ohos.permission.CAMERA" + ] + }, + { + "name": "MICROPHONE", + "groupName": "麦克风", + "icon": $r('app.media.ic_public_voice'), + "description": "访问您的麦克风", + "permissions": [ + "ohos.permission.MICROPHONE" + ] + }, + { + "name": "PHONE", + "groupName": "电话", + "icon": $r('app.media.ic_public_phone'), + "description": "拨打电话和管理通话", + "permissions": [ + "ohos.permission.ANSWER_CALL", + "ohos.permission.MANAGE_VOICEMAIL" + ] + }, + { + "name": "SMS", + "groupName": "信息", + "icon": $r('app.media.ic_public_message'), + "description": "发送和查看短信", + "permissions": [ + "ohos.permission.READ_CELL_MESSAGES", + "ohos.permission.READ_MESSAGES", + "ohos.permission.RECEIVE_MMS", + "ohos.permission.RECEIVE_SMS", + "ohos.permission.RECEIVE_WAP_MESSAGES", + "ohos.permission.SEND_MESSAGES" + ] + }, + { + "name": "CONTACTS", + "groupName": "通讯录", + "icon": $r('app.media.ic_public_contacts_group'), + "description": "访问您的通讯录", + "permissions": [ + "ohos.permission.READ_CONTACTS", + "ohos.permission.WRITE_CONTACTS" + ] + }, + { + "name": "CALL_LOG", + "groupName": "通话记录", + "icon": $r('app.media.ic_call_logs'), + "description": "读取和写入手机通话记录", + "permissions": [ + "ohos.permission.READ_CALL_LOG", + "ohos.permission.WRITE_CALL_LOG" + ] + }, + { + "name": "MEDIA", + "groupName": "媒体和文件", + "icon": $r('app.media.ic_public_folder'), + "description": "访问您的媒体和文件", + "permissions": [ + "ohos.permission.MEDIA_LOCATION", + "ohos.permission.READ_MEDIA", + "ohos.permission.WRITE_MEDIA" + ] + }, + { + "name": "CALENDAR", + "groupName": "日历", + "icon": $r('app.media.ic_public_calendar'), + "description": "访问日历和活动", + "permissions": [ + "ohos.permission.READ_CALENDAR", + "ohos.permission.WRITE_CALENDAR" + ] + }, + { + "name": "SPORT", + "groupName": "健身运动", + "icon": $r('app.media.ic_sport'), + "description": "访问您的运动状态", + "permissions": [ + "ohos.permission.ACTIVITY_MOTION" + ] + }, + { + "name": "HEALTH", + "groupName": "身体传感器", + "icon": $r('app.media.ic_ssensor'), + "description": "访问您的健康数据", + "permissions": [ + "ohos.permission.READ_HEALTH_DATA" + ] + }, + { + "name": "OTHER", + "groupName": "其他权限", + "icon": $r('app.media.ic_more'), + "description": "访问您的其他权限", + "permissions": [ + "ohos.permission.DISTRIBUTED_DATASYNC" + ] + } +] + +export const userGrantPermissions: string[] = [ + "ohos.permission.LOCATION_IN_BACKGROUND", + "ohos.permission.LOCATION", + "ohos.permission.CAMERA", + "ohos.permission.MICROPHONE", + "ohos.permission.ANSWER_CALL", + "ohos.permission.MANAGE_VOICEMAIL", + "ohos.permission.READ_CELL_MESSAGES", + "ohos.permission.READ_MESSAGES", + "ohos.permission.RECEIVE_MMS", + "ohos.permission.RECEIVE_SMS", + "ohos.permission.RECEIVE_WAP_MESSAGES", + "ohos.permission.SEND_MESSAGES", + "ohos.permission.READ_CONTACTS", + "ohos.permission.WRITE_CONTACTS", + "ohos.permission.READ_CALL_LOG", + "ohos.permission.WRITE_CALL_LOG", + "ohos.permission.MEDIA_LOCATION", + "ohos.permission.READ_MEDIA", + "ohos.permission.WRITE_MEDIA", + "ohos.permission.READ_CALENDAR", + "ohos.permission.WRITE_CALENDAR", + "ohos.permission.ACTIVITY_MOTION", + "ohos.permission.READ_HEALTH_DATA", + "ohos.permission.DISTRIBUTED_DATASYNC" +] \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/utils/constant.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/utils/constant.ets new file mode 100644 index 0000000000000000000000000000000000000000..076e169609c8883a2e96741e8ec4165df90c5584 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/utils/constant.ets @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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. + */ + +export default class Constants { + // icon of dialog + static DIALOG_ICON_WIDTH = 24; + static DIALOG_ICON_HEIGHT = 24; + static DIALOG_ICON_MARGIN_TOP = 24; + + // label text of dialog + static DIALOG_LABEL_FONT_SIZE = 14; + static DIALOG_LABEL_MARGIN_TOP = 2; + + // request text of dialog + static DIALOG_REQ_FONT_SIZE = 16; + static DIALOG_REQ_MARGIN_TOP = 16; + static DIALOG_REQ_MARGIN_LEFT = 24; + + // description text of dialog + static DIALOG_DESP_FONT_SIZE = 14; + static DIALOG_DESP_MARGIN_TOP = 2; + static DIALOG_DESP_MARGIN_LEFT = 24; + + static BUTTON_FONT_SIZE = 16; + static BUTTON_DIVIDER_FONT_SIZE = 30; + static BUTTON_MARGIN_TOP = 8; + + static DIALOG_BORDER_RADIUS = 24; + static DIALOG_HEIGHT = 186; + static DIALOG_WIDTH = "100%"; + + // initial check status + static INIT_NEED_TO_WAIT = 0 + static INIT_NEED_TO_VERIFY = 1 + static INIT_NEED_TO_TERMINATED = 2 + + static RESULT_SUCCESS = 1 + static RESULT_FAILURE = 0 +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/utils/utils.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/utils/utils.ets new file mode 100644 index 0000000000000000000000000000000000000000..7c28551a84183baa31366619d5d1092a396a72d1 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/common/utils/utils.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 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. + */ +import { permissionGroups, groups } from "../model/permissionGroup.ets" + +export function getPermissionGroup(permission: string) { + for (var i = 0; i < permissionGroups.length; i++) { + if (permissionGroups[i].permissionName == permission) { + return groups[permissionGroups[i].groupId] + } + } +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/pages/dialogPlus.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/pages/dialogPlus.ets new file mode 100644 index 0000000000000000000000000000000000000000..b6ef9eb80a991b2cae80e76f42c6bbd737f7aad7 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/ets/dynamic/pages/dialogPlus.ets @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 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. + */ + +import { privacyDialog } from "../common/components/dialog.ets" +import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; + +@Entry +@Component +struct dialogPlusPage { + @State count: number = 0 + @State result: Array = [] + privacyDialogController: CustomDialogController = new CustomDialogController({ + builder: privacyDialog({ cancel: this.privacyCancel, confirm: this.privacyAccept, count:$count, result: $result }), + cancel: this.privacyExist, + autoCancel: true, + alignment: DialogAlignment.Center + }) + async privacyAccept(group, accessTokenId, permissionList, userFixedFlag) { + var acManager = abilityAccessCtrl.createAtManager() + group.permissions.forEach(async permission => { + const result = await acManager.grantUserGrantedPermission(accessTokenId, permission, userFixedFlag) + var index = permissionList.indexOf(permission) + if (index == -1) { + console.log("GrantAbility grant permission:" + permission) + }else { + if (result == 0) { + this.result[index] = 0 + console.log("GrantAbility grant permission:" + permission) + } else { + console.log("GrantAbility failed to grant permission:" + permission + " ret:" + result) + } + } + }) + this.count ++ + } + async privacyCancel(group, accessTokenId, permissionList, userFixedFlag) { + var acManager = abilityAccessCtrl.createAtManager() + group.permissions.forEach(async permission => { + const result = await acManager.revokeUserGrantedPermission(accessTokenId, permission, userFixedFlag) + var index = permissionList.indexOf(permission) + if (index != -1 && result == 0) { + this.result[index] = -1 + console.log("GrantAbility revoke permission:" + permission) + } + }) + this.count ++ + } + privacyExist() { + console.info("exist") + } + aboutToAppear() { + this.privacyDialogController.open() + } + build() { + } +} + diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/java/com/ohos/permissionmanager/MainAbility.java b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/java/com/ohos/permissionmanager/MainAbility.java new file mode 100644 index 0000000000000000000000000000000000000000..7ef8838383eeac5dc9918221e9fa8bb06e6b5d0b --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/java/com/ohos/permissionmanager/MainAbility.java @@ -0,0 +1,17 @@ +package com.ohos.permissionmanager; + +import ohos.ace.ability.AceAbility; +import ohos.aafwk.content.Intent; + +public class MainAbility extends AceAbility { + @Override + public void onStart(Intent intent) { + setInstanceName("main_ability"); + super.onStart(intent); + } + + @Override + public void onStop() { + super.onStop(); + } +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/java/com/ohos/permissionmanager/MyApplication.java b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/java/com/ohos/permissionmanager/MyApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..8c75d4e56c1ee06e2ee83469c50be84ef00af14e --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/java/com/ohos/permissionmanager/MyApplication.java @@ -0,0 +1,10 @@ +package com.ohos.permissionmanager; + +import ohos.aafwk.ability.AbilityPackage; + +public class MyApplication extends AbilityPackage { + @Override + public void onInitialize() { + super.onInitialize(); + } +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/element/color.json b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..f2bfa884ace3d175f2bb84a18bea1efd25c35f03 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/element/color.json @@ -0,0 +1,48 @@ +{ + "color": [ + { + "name": "text_color", + "value": "#182331" + }, + { + "name": "background_color", + "value": "#f1f3f5" + }, + { + "name": "title_text_color", + "value": "#182431" + }, + { + "name": "active_background_color", + "value": "#e5f3ff" + }, + { + "name": "divider_color", + "value": "#f3f4f6" + }, + { + "name": "text_decoration_color", + "value": "#f3f4f6" + }, + { + "name": "icon_color", + "value": "#18233199" + }, + { + "name": "default_background_color", + "value": "#ffffff" + }, + { + "name": "button_color", + "value": "#0a59f7" + }, + { + "name": "secondary_font_color", + "value": "#808080" + }, + { + "name": "toggle_color", + "value": "#409eff" + } + ] +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/element/string.json b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..854142d255e4c7e4f3adf55693abc13f92b74dc5 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/element/string.json @@ -0,0 +1,88 @@ +{ + "string": [ + { + "name": "permissionmanager_MainAbility", + "value": "permissionmanager_MainAbility" + }, + { + "name": "mainability_description", + "value": "eTS_Empty Ability" + }, + { + "name": "entry_MainAbility", + "value": "entry_MainAbility" + }, + { + "name": "mainability_description", + "value": "ETS_Category Ability" + }, + { + "name": "permissionmanager_GrantAbility", + "value": "permissionmanager_GrantAbility" + }, + { + "name": "permissionmanager_description", + "value": "eTS_Empty Ability" + }, + { + "name": "settings", + "value": "设置" + }, + { + "name": "permission_access_record", + "value": "权限访问记录" + }, + { + "name": "authority_management", + "value": "权限管理" + }, + { + "name": "privacy", + "value": "隐私" + }, + { + "name": "authority_message", + "value": "近7天的应用访问权限" + }, + { + "name": "other_permissions", + "value": "其它权限" + }, + { + "name": "app_name", + "value": "应用名称" + }, + { + "name": "location_info", + "value": "位置信息" + }, + { + "name": "media_document", + "value": "媒体和文件" + }, + { + "name": "calendar", + "value": "日历" + }, + { + "name": "allowed", + "value": "已允许" + }, + { + "name": "banned", + "value": "已禁止" + }, + { + "name": "location_info_message", + "value": "系统定位服务开关开启时,已允许19个应用获取此设备的位置。" + }, + { + "name": "grantability_description", + "value": "eTS_Empty Ability" + }, + { + "name": "entry_GrantAbility", + "value": "entry_GrantAbility" + } + ] +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_call_logs.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_call_logs.svg new file mode 100644 index 0000000000000000000000000000000000000000..42f8ad97c0a031fd0a42731e8994418e1d6accc2 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_call_logs.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_dropzone.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_dropzone.svg new file mode 100644 index 0000000000000000000000000000000000000000..960483f7f3398245eafe7c9d6182419a32ebeb05 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_dropzone.svg @@ -0,0 +1,19 @@ + + + IC/ic_floatingwindow + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_exercise.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_exercise.svg new file mode 100644 index 0000000000000000000000000000000000000000..b488a424376659859601df4743a9293877be0e1e --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_exercise.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_forward.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_forward.svg new file mode 100644 index 0000000000000000000000000000000000000000..abac736115811fb7111ecea37f3fa063d627bd17 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_forward.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_more.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_more.svg new file mode 100644 index 0000000000000000000000000000000000000000..3fdc1e9d60f7ce2d533c53e8ee3d6df8ee66287a --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_more.svg @@ -0,0 +1,7 @@ + + + HM/ic/24x24/more1.5 + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_nearby.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_nearby.svg new file mode 100644 index 0000000000000000000000000000000000000000..4b201c865105325c085d7c761baef6087e4e57d3 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_nearby.svg @@ -0,0 +1,7 @@ + + + HM/ic/24x24/ic_nearby + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_calendar.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_calendar.svg new file mode 100644 index 0000000000000000000000000000000000000000..56e634cab80c7c51f6e38ddb1c59b89f9e9a2baf --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_calendar.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_calendar + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_camera.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_camera.svg new file mode 100644 index 0000000000000000000000000000000000000000..7be7ccc417a4ebbc23bf5197cea49d08abbec754 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_camera.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_camera + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_contacts_group.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_contacts_group.svg new file mode 100644 index 0000000000000000000000000000000000000000..6805946fbe89097ff97221526e71921b286ee3df --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_contacts_group.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_contacts_group + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_folder.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_folder.svg new file mode 100644 index 0000000000000000000000000000000000000000..c2a26b5df06901f6e4aa1797a288ea8618d5b006 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_folder.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_folder + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_gps.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_gps.svg new file mode 100644 index 0000000000000000000000000000000000000000..88ad317dd06bf9c5902463893ec8a6a3d0c3988b --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_gps.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_gps + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_message.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_message.svg new file mode 100644 index 0000000000000000000000000000000000000000..3191fb6e4f6fef84d30b90259cf3e634c9486315 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_message.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_message + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_phone.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_phone.svg new file mode 100644 index 0000000000000000000000000000000000000000..c78bb4fb53ef7e00eb8b21c95e7a0eae1b8c344b --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_phone.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_phone + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_voice.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_voice.svg new file mode 100644 index 0000000000000000000000000000000000000000..ac9311b1293177f0c5d68961e236d16a1e9d350f --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_public_voice.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_voice + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_sport.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_sport.svg new file mode 100644 index 0000000000000000000000000000000000000000..58c9f7a83c3a4445fb385f4d86cd12891dcf3354 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_sport.svg @@ -0,0 +1,7 @@ + + + HM/ic/24x24/s0324ok + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_ssensor.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_ssensor.svg new file mode 100644 index 0000000000000000000000000000000000000000..31a035d87a91bad5b1da207b5d39acfd12794ca2 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/ic_ssensor.svg @@ -0,0 +1,9 @@ + + + HM/ic/24x24/ssensor + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/in_app_installations.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/in_app_installations.svg new file mode 100644 index 0000000000000000000000000000000000000000..c40993ab5cedaefb586f94faf4c578f8faa93c57 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/in_app_installations.svg @@ -0,0 +1,13 @@ + + + HM/ic/24x24/in-app installations + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/noinstallationpackage.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/noinstallationpackage.svg new file mode 100644 index 0000000000000000000000000000000000000000..5b10a66c6b63e6d73bfb96492ec59a900ed5335c --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/noinstallationpackage.svg @@ -0,0 +1,17 @@ + + + EmptyPage/08 NoInstallationPackage + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/nopermission.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/nopermission.svg new file mode 100644 index 0000000000000000000000000000000000000000..fe47a1df835fe7c7a296aa92bf009875373f30ad --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/nopermission.svg @@ -0,0 +1,16 @@ + + + EmptyPage/18 NoPermission + + + + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/searchnoresult.svg b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/searchnoresult.svg new file mode 100644 index 0000000000000000000000000000000000000000..e948acc0bbb8bc715385ff841418b60b81eb0997 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/main/resources/base/media/searchnoresult.svg @@ -0,0 +1,22 @@ + + + EmptyPage/05 SearchNoResult + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/app.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/app.ets new file mode 100644 index 0000000000000000000000000000000000000000..fd310895976fc0623ac1bdc3ded2ab5209393f62 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/app.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 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. + */ + +export default { + onCreate() { + console.info('Application onCreate') + }, + onShow() { + console.info('Application onShow') + }, + onDestroy() { + console.info('Application onDestroy') + }, +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/i18n/en-US.json b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/i18n/en-US.json new file mode 100644 index 0000000000000000000000000000000000000000..55561b83737c3c31d082fbfa11e5fc987a351104 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/i18n/en-US.json @@ -0,0 +1,8 @@ +{ + "strings": { + "hello": "Hello", + "world": "World" + }, + "Files": { + } +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/i18n/zh-CN.json b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/i18n/zh-CN.json new file mode 100644 index 0000000000000000000000000000000000000000..cce1af06761a42add0cac1a0567aa3237eda8cb4 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/i18n/zh-CN.json @@ -0,0 +1,8 @@ +{ + "strings": { + "hello": "您好", + "world": "世界" + }, + "Files": { + } +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/pages/index/index.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/pages/index/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..2ebd82564e904d46ae1a9c3ca8867307af17f6de --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/default/pages/index/index.ets @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 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. + */ + +import {Core, ExpectExtend, InstrumentLog} from "deccjsunit/index" +import testsuite from "../../../test/List.test.ets" +import featureAbility from "@ohos.ability.featureAbility" + +@Entry +@Component +struct MyComponent { + aboutToAppear() { + console.info("start run testcase!!!!") + featureAbility.getWant() + .then((Want) => { + const core = Core.getInstance() + const expectExtend = new ExpectExtend({ + 'id': 'extend' + }) + const instrumentLog = new InstrumentLog({ + 'id': 'report', 'unity': 'true' + }) + core.addService('expect', expectExtend) + core.addService('report', instrumentLog) + core.init() + core.subscribeEvent('spec', instrumentLog) + core.subscribeEvent('suite', instrumentLog) + core.subscribeEvent('task', instrumentLog) + const configService = core.getDefaultService('config') + configService.setConfig(Want.parameters) + testsuite() + core.execute() + console.info('Operation successful. Data: ' + JSON.stringify(Want)); + }) + .catch((error) => { + console.error('Operation failed. Cause: ' + JSON.stringify(error)); + }) + } + + build() { + Flex({ + direction: FlexDirection.Column, + alignItems: ItemAlign.Center, + justifyContent: FlexAlign.Center + }) { + Text('Hello World') + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + .height('100%') + } +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/test/ExampleJsunit.test.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/test/ExampleJsunit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..35824cab41eb5d75507485b5d95e23c8d4d57f2d --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/test/ExampleJsunit.test.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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. + */ + +import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from "deccjsunit/index" +import app from '@system.app' + +export default function exampleJsunit() { + describe('appInfoTest', function () { + it('app_info_test_001', 0, function () { + var info = app.getInfo() + expect("1.0").assertEqual('1.0') + expect(info.versionCode).assertEqual('3') + }) + }) +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/test/List.test.ets b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..e659c7498c0278c228641fa8eabf91893a84d8e7 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2021 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. + */ + +import exampleJsunit from "../test/ExampleJsunit.test.ets" + +export default function testsuite() { + exampleJsunit() +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/java/com/ohos/permissionmanager/ExampleOhosTest.java b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/java/com/ohos/permissionmanager/ExampleOhosTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9482d133c3b1866f581978213dce868e966f5e9d --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/java/com/ohos/permissionmanager/ExampleOhosTest.java @@ -0,0 +1,14 @@ +package com.ohos.permissionmanager; + +import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ExampleOhosTest { + @Test + public void testBundleName() { + final String actualBundleName = AbilityDelegatorRegistry.getArguments().getTestBundleName(); + assertEquals("com.ohos.permissionmanager", actualBundleName); + } +} \ No newline at end of file diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/resources/base/element/string.json b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..0ad161e668b74a19e5820d0d5f43d017b6d43173 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "app_name", + "value": "PermissionManager" + }, + { + "name": "mainability_description", + "value": "hap sample empty page" + } + ] +} diff --git a/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/resources/base/media/icon.png b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/frameworks/com.ohos.permissionmanager/permissionmanager/src/ohosTest/resources/base/media/icon.png differ diff --git a/frameworks/com.ohos.permissionmanager/settings.gradle b/frameworks/com.ohos.permissionmanager/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4bc3f8f5570c80bbdafc2d541c60ae3cf2890248 --- /dev/null +++ b/frameworks/com.ohos.permissionmanager/settings.gradle @@ -0,0 +1 @@ +include ':entry', ':permissionmanager' diff --git a/services/accesstoken/BUILD.gn b/frameworks/common/BUILD.gn similarity index 60% rename from services/accesstoken/BUILD.gn rename to frameworks/common/BUILD.gn index a58bc6e088e1356b89ac291c459b351fb5ff70c5..aad20da4291e8d3e68c8079673435811f72fdd02 100644 --- a/services/accesstoken/BUILD.gn +++ b/frameworks/common/BUILD.gn @@ -13,32 +13,37 @@ import("//build/ohos.gni") -ohos_shared_library("accesstoken_manager_service") { +################################################################ +# C++, Main source file here. +################################################################ +config("accesstoken_common_cxx_public_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +ohos_shared_library("accesstoken_common_cxx") { subsystem_name = "security" part_name = "access_token" + public_configs = [ ":accesstoken_common_cxx_public_config" ] + include_dirs = [ - "main/cpp/include", + "include", "//utils/system/safwk/native/include", - "//base/security/access_token/frameworks/accesstoken", - "//base/security/access_token/interfaces/innerkits/accesstoken//main/cpp/include", + "//third_party/mbedtls/include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", ] sources = [ - "main/cpp/src/accesstoken_manager_service.cpp", - "main/cpp/src/accesstoken_manager_stub.cpp", + "src/data_validator.cpp", + "src/random_mbedtls.cpp", ] - cflags_cc = [ "-DHILOG_ENABLE" ] - deps = [ + "//third_party/mbedtls:mbedtls_shared", "//utils/native/base:utils", ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] - external_deps = [ - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", - "safwk:system_ability_fwk", - "samgr_standard:samgr_proxy", - ] + cflags_cc = [ "-DHILOG_ENABLE" ] } diff --git a/frameworks/accesstoken/accesstoken_log.h b/frameworks/common/include/accesstoken_log.h similarity index 56% rename from frameworks/accesstoken/accesstoken_log.h rename to frameworks/common/include/accesstoken_log.h index 9435908dd840dc20a8fdf3738a87b7fd312ec903..ac4aaa1078074ddd2c51f119760664702c9ded3c 100644 --- a/frameworks/accesstoken/accesstoken_log.h +++ b/frameworks/common/include/accesstoken_log.h @@ -22,21 +22,26 @@ #ifndef __cplusplus -#define ACCESSTOKEN_LOG_DEBUG(fmt, ...) HILOG_DEBUG(LOG_CORE, fmt, ##__VA_ARGS__) -#define ACCESSTOKEN_LOG_INFO(fmt, ...) HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__) -#define ACCESSTOKEN_LOG_WARN(fmt, ...) HILOG_WARN(LOG_CORE, fmt, ##__VA_ARGS__) -#define ACCESSTOKEN_LOG_ERROR(fmt, ...) HILOG_ERROR(LOG_CORE, fmt, ##__VA_ARGS__) -#define ACCESSTOKEN_LOG_FATAL(fmt, ...) HILOG_FATAL(LOG_CORE, fmt, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_DEBUG(fmt, ...) HILOG_DEBUG(LOG_CORE, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_INFO(fmt, ...) HILOG_INFO(LOG_CORE, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_WARN(fmt, ...) HILOG_WARN(LOG_CORE, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_ERROR(fmt, ...) HILOG_ERROR(LOG_CORE, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_FATAL(fmt, ...) HILOG_FATAL(LOG_CORE, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) #else -#define ACCESSTOKEN_LOG_DEBUG(label, fmt, ...) OHOS::HiviewDFX::HiLog::Debug(label, fmt, ##__VA_ARGS__) -#define ACCESSTOKEN_LOG_INFO(label, fmt, ...) OHOS::HiviewDFX::HiLog::Info(label, fmt, ##__VA_ARGS__) -#define ACCESSTOKEN_LOG_WARN(label, fmt, ...) OHOS::HiviewDFX::HiLog::Warn(label, fmt, ##__VA_ARGS__) -#define ACCESSTOKEN_LOG_ERROR(label, fmt, ...) OHOS::HiviewDFX::HiLog::Error(label, fmt, ##__VA_ARGS__) -#define ACCESSTOKEN_LOG_FATAL(label, fmt, ...) OHOS::HiviewDFX::HiLog::Fatal(label, fmt, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_DEBUG(label, fmt, ...) \ + OHOS::HiviewDFX::HiLog::Debug(label, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_INFO(label, fmt, ...) \ + OHOS::HiviewDFX::HiLog::Info(label, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_WARN(label, fmt, ...) \ + OHOS::HiviewDFX::HiLog::Warn(label, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_ERROR(label, fmt, ...) \ + OHOS::HiviewDFX::HiLog::Error(label, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_FATAL(label, fmt, ...) \ + OHOS::HiviewDFX::HiLog::Fatal(label, "[%{public}s]:" fmt, __func__, ##__VA_ARGS__) -#endif // __cplusplus +#endif // __cplusplus /* define LOG_TAG as "security_*" at your submodule, * means your submodule name such as "security_dac" */ #undef LOG_TAG @@ -58,6 +63,6 @@ static constexpr unsigned int SECURITY_DOMAIN_ACCESSTOKEN = 0xD002F01; #define ACCESSTOKEN_LOG_ERROR(fmt, ...) printf("[%s] error: %s: " fmt "\n", LOG_TAG, __func__, ##__VA_ARGS__) #define ACCESSTOKEN_LOG_FATAL(fmt, ...) printf("[%s] fatal: %s: " fmt "\n", LOG_TAG, __func__, ##__VA_ARGS__) -#endif // HILOG_ENABLE +#endif // HILOG_ENABLE -#endif // ACCESSTOKEN_LOG_H +#endif // ACCESSTOKEN_LOG_H diff --git a/frameworks/common/include/data_validator.h b/frameworks/common/include/data_validator.h new file mode 100644 index 0000000000000000000000000000000000000000..8821598cf66fa638851a47fcb909188a09db5944 --- /dev/null +++ b/frameworks/common/include/data_validator.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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 "access_token.h" + +#ifndef DATA_VALIDATOR_H +#define DATA_VALIDATOR_H +namespace OHOS { +namespace Security { +namespace AccessToken { +class DataValidator final { +public: + static bool IsBundleNameValid(const std::string& bundleName); + + static bool IsPermissionNameValid(const std::string& permissionName); + + static bool IsUserIdValid(const int userId); + + static bool IsAppIDDescValid(const std::string& appIDDesc); + + static bool IsDomainValid(const std::string& domain); + + static bool IsAplNumValid(const int apl); + + static bool IsProcessNameValid(const std::string& processName); + + static bool IsDeviceIdValid(const std::string& deviceId); + + static bool IsLabelValid(const std::string& label); + + static bool IsDescValid(const std::string& desc); + static bool IsPermissionFlagValid(int flag); + static bool IsDcapValid(const std::string& dcap); + static bool IsTokenIDValid(AccessTokenID id); +private: + const static int MAX_LENGTH = 256; + const static int MAX_APPIDDESC_LENGTH = 10240; + const static int MAX_DCAP_LENGTH = 1024; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // DATA_VALIDATOR_H diff --git a/frameworks/common/include/random.h b/frameworks/common/include/random.h new file mode 100644 index 0000000000000000000000000000000000000000..9362764210314841612be570b5edb67170e0b3ad --- /dev/null +++ b/frameworks/common/include/random.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 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_RANDOM_H +#define ACCESSTOKEN_RANDOM_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +unsigned int GetRandomUint32(); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* ACCESSTOKEN_RANDOM_H */ diff --git a/frameworks/common/include/random_mbedtls.h b/frameworks/common/include/random_mbedtls.h new file mode 100644 index 0000000000000000000000000000000000000000..ffd3ddd147ee2478af4cac6e74196d9c27f455ce --- /dev/null +++ b/frameworks/common/include/random_mbedtls.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 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 ACCESS_TOKEN_RANDOM_MBEDTLS +#define ACCESS_TOKEN_RANDOM_MBEDTLS + +#include "rwlock.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/entropy.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class RandomMbedtls { +public: + static RandomMbedtls& GetInstance(); + int GenerateRandomArray(unsigned char *randStr, unsigned int len); + ~RandomMbedtls() {}; + static unsigned int GetRandomUint32(); + +private: + RandomMbedtls() : initFlag_(false) {}; + mbedtls_entropy_context entropy_; + mbedtls_ctr_drbg_context ctrDrbg_; + OHOS::Utils::RWLock randomLock_; + bool initFlag_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESS_TOKEN_RANDOM_MBEDTLS diff --git a/frameworks/common/src/data_validator.cpp b/frameworks/common/src/data_validator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a28479e7e0286183b504d0b98ba539116d413fe9 --- /dev/null +++ b/frameworks/common/src/data_validator.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 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 "data_validator.h" +#include "access_token.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +bool DataValidator::IsBundleNameValid(const std::string& bundleName) +{ + return !bundleName.empty() && (bundleName.length() <= MAX_LENGTH); +} + +bool DataValidator::IsLabelValid(const std::string& label) +{ + return label.length() <= MAX_LENGTH; +} + +bool DataValidator::IsDescValid(const std::string& desc) +{ + return desc.length() <= MAX_LENGTH; +} + +bool DataValidator::IsPermissionNameValid(const std::string& permissionName) +{ + return !permissionName.empty() && (permissionName.length() <= MAX_LENGTH); +} + +bool DataValidator::IsUserIdValid(const int userId) +{ + return userId >= 0; +} + +bool DataValidator::IsAppIDDescValid(const std::string& appIDDesc) +{ + return !appIDDesc.empty() && (appIDDesc.length() <= MAX_APPIDDESC_LENGTH); +} + +bool DataValidator::IsDomainValid(const std::string& domain) +{ + return !domain.empty() && (domain.length() <= MAX_LENGTH); +} + +bool DataValidator::IsAplNumValid(const int apl) +{ + return (apl == APL_NORMAL || apl == APL_SYSTEM_BASIC || apl == APL_SYSTEM_CORE); +} + +bool DataValidator::IsProcessNameValid(const std::string& processName) +{ + return !processName.empty() && (processName.length() <= MAX_LENGTH); +} + +bool DataValidator::IsDeviceIdValid(const std::string& deviceId) +{ + return !deviceId.empty() && (deviceId.length() <= MAX_LENGTH); +} + +bool DataValidator::IsDcapValid(const std::string& dcap) +{ + return !dcap.empty() && (dcap.length() <= MAX_DCAP_LENGTH); +} + +bool DataValidator::IsPermissionFlagValid(int flag) +{ + return flag == DEFAULT_PERMISSION_FLAGS || + flag == PermissionFlag::PERMISSION_USER_SET || + flag == PermissionFlag::PERMISSION_USER_FIXED || + flag == PermissionFlag::PERMISSION_SYSTEM_FIXED; +} + +bool DataValidator::IsTokenIDValid(AccessTokenID id) +{ + return id != 0; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/frameworks/common/src/random_mbedtls.cpp b/frameworks/common/src/random_mbedtls.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20d7dfbbcaf6e4d50df90e605e5ccdbbb1fec644 --- /dev/null +++ b/frameworks/common/src/random_mbedtls.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 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 "random_mbedtls.h" +#include "access_token.h" + +using OHOS::Security::AccessToken::RandomMbedtls; +using OHOS::Security::AccessToken::RET_SUCCESS; + +namespace OHOS { +namespace Security { +namespace AccessToken { +extern "C" unsigned int GetRandomUint32() +{ + unsigned int rand; + int ret = RandomMbedtls::GetInstance().GenerateRandomArray((unsigned char *)&rand, sizeof(rand)); + if (ret != RET_SUCCESS) { + return 0; + } + return rand; +} + +int RandomMbedtls::GenerateRandomArray(unsigned char *randStr, unsigned int len) +{ + if (randStr == NULL || len == 0) { + return RET_FAILED; + } + int ret; + + Utils::UniqueWriteGuard infoGuard(this->randomLock_); + if (initFlag_ == false) { + mbedtls_ctr_drbg_init(&ctrDrbg_); + mbedtls_entropy_init(&entropy_); + ret = mbedtls_ctr_drbg_seed(&ctrDrbg_, mbedtls_entropy_func, &entropy_, NULL, 0); + if (ret != 0) { + return RET_FAILED; + } + initFlag_ = true; + } + + ret = mbedtls_ctr_drbg_random(&ctrDrbg_, randStr, len); + if (ret != 0) { + return RET_FAILED; + } + return RET_SUCCESS; +} + +RandomMbedtls& RandomMbedtls::GetInstance() +{ + static RandomMbedtls instance; + return instance; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/frameworks/tokensync/include/i_token_sync_manager.h b/frameworks/tokensync/include/i_token_sync_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..8975482ce13dfad5d6b746852b3fe04c2a50f7c8 --- /dev/null +++ b/frameworks/tokensync/include/i_token_sync_manager.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 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 I_TOKENSYNC_MANAGER_H +#define I_TOKENSYNC_MANAGER_H + +#include + +#include "iremote_broker.h" +#include "errors.h" + +#include "access_token.h" +#include "hap_token_info_for_sync_parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class ITokenSyncManager : public IRemoteBroker { +public: + static const int SA_ID_TOKENSYNC_MANAGER_SERVICE = 3504; + + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.security.accesstoken.ITokenSyncManager"); + + virtual int GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID) = 0; + virtual int DeleteRemoteHapTokenInfo(AccessTokenID tokenID) = 0; + virtual int UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo) = 0; + + enum class InterfaceCode { + GET_REMOTE_HAP_TOKEN_INFO = 0xff01, + DELETE_REMOTE_HAP_TOKEN_INFO = 0xff02, + UPDATE_REMOTE_HAP_TOKEN_INFO = 0xff03 + }; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // I_TOKENSYNC_MANAGER_H diff --git a/interfaces/innerkits/accesstoken/BUILD.gn b/interfaces/innerkits/accesstoken/BUILD.gn index 2cc576843c7f6a990473d776dec065d9a24188c8..2c353eec68bd0b100cf39b1c18503b677a2e630a 100644 --- a/interfaces/innerkits/accesstoken/BUILD.gn +++ b/interfaces/innerkits/accesstoken/BUILD.gn @@ -16,9 +16,9 @@ import("//build/ohos.gni") ################################################################ # C++, Main, source file here. ################################################################ -config("accesstoken_sdk_cxx_public_config_standard") { +config("accesstoken") { visibility = [ ":*" ] - include_dirs = [ "main/cpp/include" ] + include_dirs = [ "include" ] } ohos_shared_library("libaccesstoken_sdk") { @@ -27,25 +27,26 @@ ohos_shared_library("libaccesstoken_sdk") { output_name = "libaccesstoken_sdk" - public_configs = [ ":accesstoken_sdk_cxx_public_config_standard" ] + public_configs = [ ":accesstoken" ] include_dirs = [ "//utils/native/base/include", - "main/cpp/include", - "main/cpp/src", - "//base/security/access_token/frameworks/accesstoken", - "//base/security/access_token/nterfaces/innerkits/accesstoken/main/cpp/include", + "include", + "src", + "//base/security/access_token/frameworks/accesstoken/include", + "//base/security/access_token/frameworks/common/include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", ] sources = [ - "main/cpp/src/accesstoken_kit.cpp", - "main/cpp/src/accesstoken_manager_client.cpp", - "main/cpp/src/accesstoken_manager_proxy.cpp", + "src/accesstoken_kit.cpp", + "src/accesstoken_manager_client.cpp", + "src/accesstoken_manager_proxy.cpp", ] deps = [ - "//base/security/permission/frameworks/permission_standard/permissioncommunicationadapter:permission_standard_communication_adapter_cxx", - "//base/security/permission/frameworks/permission_standard/permissioninfrastructure:permission_standard_infrastructure_cxx", + "//base/security/access_token/frameworks/accesstoken:accesstoken_communication_adapter_cxx", + "//base/security/access_token/frameworks/common:accesstoken_common_cxx", "//utils/native/base:utils", ] diff --git a/interfaces/innerkits/accesstoken/include/access_token.h b/interfaces/innerkits/accesstoken/include/access_token.h new file mode 100644 index 0000000000000000000000000000000000000000..d4b050ed75dd721ceedb18ca6e5e484cc41aacfc --- /dev/null +++ b/interfaces/innerkits/accesstoken/include/access_token.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021 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 ACCESS_TOKEN_DEF_H +#define ACCESS_TOKEN_DEF_H + +namespace OHOS { +namespace Security { +namespace AccessToken { +typedef unsigned int AccessTokenID; +typedef unsigned int AccessTokenAttr; +static const int DEFAULT_TOKEN_VERSION = 1; +static const int DEFAULT_PERMISSION_FLAGS = 0; +static const int FIRSTCALLER_TOKENID_DEFAULT = 0; + +enum AccessTokenKitRet { + RET_FAILED = -1, + RET_SUCCESS = 0, +}; + +typedef struct { + unsigned int tokenUniqueID : 24; + unsigned int res : 3; + unsigned int type : 2; + unsigned int version : 3; +} AccessTokenIDInner; + +typedef enum TypeATokenTypeEnum { + TOKEN_INVALID = -1, + TOKEN_HAP = 0, + TOKEN_NATIVE, +} ATokenTypeEnum; + +typedef enum TypeATokenAplEnum { + APL_NORMAL = 1, + APL_SYSTEM_BASIC = 2, + APL_SYSTEM_CORE = 3, +} ATokenAplEnum; + +typedef union { + unsigned long long tokenIDEx; + struct { + AccessTokenID tokenID; + AccessTokenAttr tokenAttr; + } tokenIdExStruct; +} AccessTokenIDEx; + +typedef enum TypePermissionState { + PERMISSION_DENIED = -1, + PERMISSION_GRANTED = 0, +} PermissionState; + +typedef enum TypeGrantMode { + USER_GRANT = 0, + SYSTEM_GRANT = 1, +} GrantMode; + +typedef enum TypePermissionFlag { + PERMISSION_USER_SET = 1 << 0, + PERMISSION_USER_FIXED = 1 << 1, + PERMISSION_SYSTEM_FIXED = 1 << 2, +} PermissionFlag; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESS_TOKEN_DEF_H diff --git a/interfaces/innerkits/accesstoken/main/cpp/include/accesstoken.h b/interfaces/innerkits/accesstoken/include/accesstoken.h old mode 100644 new mode 100755 similarity index 100% rename from interfaces/innerkits/accesstoken/main/cpp/include/accesstoken.h rename to interfaces/innerkits/accesstoken/include/accesstoken.h diff --git a/interfaces/innerkits/accesstoken/include/accesstoken_kit.h b/interfaces/innerkits/accesstoken/include/accesstoken_kit.h new file mode 100644 index 0000000000000000000000000000000000000000..495f451d9de18a8ea95305f16d8fef812470bf84 --- /dev/null +++ b/interfaces/innerkits/accesstoken/include/accesstoken_kit.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 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_KIT_H +#define INTERFACES_INNER_KITS_ACCESSTOKEN_KIT_H + +#include +#include + +#include "access_token.h" +#include "hap_token_info.h" +#include "native_token_info.h" +#include "permission_def.h" +#include "permission_state_full.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class AccessTokenKit { +public: + static AccessTokenIDEx AllocHapToken(const HapInfoParams& info, const HapPolicyParams& policy); + static AccessTokenID AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID); + static int UpdateHapToken(AccessTokenID tokenID, const std::string& appIDDesc, const HapPolicyParams& policy); + static int DeleteToken(AccessTokenID tokenID); + /* Get token type by ATM service */ + static ATokenTypeEnum GetTokenType(AccessTokenID tokenID); + /* Get token type from flag in tokenId, which doesn't depend on ATM service */ + static ATokenTypeEnum GetTokenTypeFlag(AccessTokenID tokenID); + static int CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap); + static AccessTokenID GetHapTokenID(int userID, const std::string& bundleName, int instIndex); + static int GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo& hapTokenInfoRes); + static int GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& nativeTokenInfoRes); + static int VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName); + static int VerifyAccessToken( + AccessTokenID callerTokenID, AccessTokenID firstTokenID, const std::string& permissionName); + static int GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult); + static int GetDefPermissions(AccessTokenID tokenID, std::vector& permList); + static int GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant); + static int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName); + 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); + static int GetHapTokenInfoFromRemote(AccessTokenID tokenID, HapTokenInfoForSync& hapSync); + static int GetAllNativeTokenInfo(std::vector& nativeTokenInfosRes); + static int SetRemoteHapTokenInfo(const std::string& deviceID, const HapTokenInfoForSync& hapSync); + static int SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoList); + static int DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID); + static int DeleteRemoteDeviceTokens(const std::string& deviceID); + static int DumpToken(std::string& dumpInfo); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif diff --git a/interfaces/innerkits/accesstoken/include/hap_token_info.h b/interfaces/innerkits/accesstoken/include/hap_token_info.h new file mode 100644 index 0000000000000000000000000000000000000000..1d38ae6840fb11aa908edfbc1485e9d98f2fdfb1 --- /dev/null +++ b/interfaces/innerkits/accesstoken/include/hap_token_info.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021 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_HAP_TOKEN_INFO_H +#define ACCESSTOKEN_HAP_TOKEN_INFO_H + +#include "access_token.h" +#include "permission_def.h" +#include "permission_state_full.h" +#include +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +class HapInfoParams final { +public: + int userID; + std::string bundleName; + int instIndex; + std::string appIDDesc; +}; + +class HapPolicyParams final { +public: + ATokenAplEnum apl; + std::string domain; + std::vector permList; + std::vector permStateList; +}; + +class HapTokenInfo final { +public: + ATokenAplEnum apl; + char ver; + int userID; + std::string bundleName; + int instIndex; + std::string appID; + std::string deviceID; + AccessTokenID tokenID; + AccessTokenAttr tokenAttr; +}; + +class HapTokenInfoForSync final { +public: + HapTokenInfo baseInfo; + std::vector permStateList; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_HAP_TOKEN_INFO_H diff --git a/interfaces/innerkits/accesstoken/include/native_token_info.h b/interfaces/innerkits/accesstoken/include/native_token_info.h new file mode 100644 index 0000000000000000000000000000000000000000..60b427f3598d5fc059a3f4fa10ab15d185a01f0c --- /dev/null +++ b/interfaces/innerkits/accesstoken/include/native_token_info.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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_NATIVE_TOKEN_INFO_H +#define ACCESSTOKEN_NATIVE_TOKEN_INFO_H + +#include "access_token.h" +#include +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +class NativeTokenInfo final { +public: + ATokenAplEnum apl; + unsigned char ver; + std::string processName; + std::vector dcap; + AccessTokenID tokenID; + AccessTokenAttr tokenAttr; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_NATIVE_TOKEN_INFO_H diff --git a/interfaces/innerkits/accesstoken/include/permission_def.h b/interfaces/innerkits/accesstoken/include/permission_def.h new file mode 100644 index 0000000000000000000000000000000000000000..f3cc81b63cd1062be2c225b6de4bd4f71339805e --- /dev/null +++ b/interfaces/innerkits/accesstoken/include/permission_def.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 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_DEF_H +#define INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_DEF_H + +#include + +#include "access_token.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class PermissionDef final { +public: + std::string permissionName; + std::string bundleName; + int grantMode; + TypeATokenAplEnum availableLevel; + bool provisionEnable; + bool distributedSceneEnable; + std::string label; + int labelId; + std::string description; + int descriptionId; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_DEF_H diff --git a/interfaces/innerkits/accesstoken/include/permission_state_full.h b/interfaces/innerkits/accesstoken/include/permission_state_full.h new file mode 100644 index 0000000000000000000000000000000000000000..7805a3d9e7ac5698ddc9325ff4910046668f5004 --- /dev/null +++ b/interfaces/innerkits/accesstoken/include/permission_state_full.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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_STATE_FULL_H +#define INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_STATE_FULL_H + +#include +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +class PermissionStateFull final { +public: + std::string permissionName; + bool isGeneral; + std::vector resDeviceID; + std::vector grantStatus; + std::vector grantFlags; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // INTERFACES_INNER_KITS_ACCESSTOKEN_PERMISSION_STATE_FULL_H diff --git a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_proxy.cpp b/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_proxy.cpp deleted file mode 100644 index ce8d6ec7f793bf28900da3a21276e24233863a88..0000000000000000000000000000000000000000 --- a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_proxy.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2021 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_manager_proxy.h" - -#include "accesstoken_log.h" - -#include "parcel.h" -#include "string_ex.h" - -namespace OHOS { -namespace Security { -namespace AccessToken { -namespace { -static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenManagerProxy"}; -} - -AccessTokenManagerProxy::AccessTokenManagerProxy(const sptr& impl) - : IRemoteProxy(impl) -{} - -AccessTokenManagerProxy::~AccessTokenManagerProxy() -{} - -int AccessTokenManagerProxy::VerifyAccesstoken(AccessTokenID tokenID, const std::string& permissionName) -{ - MessageParcel data; - data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); - if (!data.WriteUint32(tokenID)) { - ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s: Failed to write tokenID", __func__); - return PERMISSION_DENIED; - } - if (!data.WriteString(permissionName)) { - ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s: Failed to write permissionName", __func__); - return PERMISSION_DENIED; - } - - MessageParcel reply; - MessageOption option; - sptr remote = Remote(); - if (remote == nullptr) { - ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s: remote service null.", __func__); - return PERMISSION_DENIED; - } - int32_t requestResult = remote->SendRequest( - static_cast(IAccessTokenManager::InterfaceCode::VERIFY_ACCESSTOKEN), data, reply, option); - if (requestResult != NO_ERROR) { - ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s send request fail, result: %{public}d", __func__, requestResult); - return PERMISSION_DENIED; - } - - int32_t result = reply.ReadInt32(); - ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s get result from server data = %{public}d", __func__, result); - return result; -} - -} // namespace AccessToken -} // namespace Security -} // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dbdad0dabddef5fa2bad6a598504565c3634d143 --- /dev/null +++ b/interfaces/innerkits/accesstoken/src/accesstoken_kit.cpp @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2021 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 "accesstoken_log.h" +#include "accesstoken_manager_client.h" +#include "data_validator.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenKit"}; +} // namespace + +AccessTokenIDEx AccessTokenKit::AllocHapToken(const HapInfoParams& info, const HapPolicyParams& policy) +{ + AccessTokenIDEx res = {0}; + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if ((!DataValidator::IsUserIdValid(info.userID)) || !DataValidator::IsAppIDDescValid(info.appIDDesc) + || !DataValidator::IsBundleNameValid(info.bundleName) || !DataValidator::IsAplNumValid(policy.apl) + || !DataValidator::IsDomainValid(policy.domain)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "input param failed"); + return res; + } + + return AccessTokenManagerClient::GetInstance().AllocHapToken(info, policy); +} + +AccessTokenID AccessTokenKit::AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID=%{public}s tokenID=%{public}d", + __func__, remoteDeviceID.c_str(), remoteTokenID); + return AccessTokenManagerClient::GetInstance().AllocLocalTokenID(remoteDeviceID, remoteTokenID); +} + +int AccessTokenKit::UpdateHapToken(AccessTokenID tokenID, const std::string& appIDDesc, const HapPolicyParams& policy) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if ((tokenID == 0) || (!DataValidator::IsAppIDDescValid(appIDDesc)) + || (!DataValidator::IsAplNumValid(policy.apl))) { + ACCESSTOKEN_LOG_ERROR(LABEL, "input param failed"); + return RET_FAILED; + } + return AccessTokenManagerClient::GetInstance().UpdateHapToken(tokenID, appIDDesc, policy); +} + +int AccessTokenKit::DeleteToken(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d", tokenID); + return AccessTokenManagerClient::GetInstance().DeleteToken(tokenID); +} + +ATokenTypeEnum AccessTokenKit::GetTokenType(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return TOKEN_INVALID; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d", tokenID); + return AccessTokenManagerClient::GetInstance().GetTokenType(tokenID); +} + +ATokenTypeEnum AccessTokenKit::GetTokenTypeFlag(AccessTokenID tokenID) +{ + if (tokenID == 0) { + return TOKEN_INVALID; + } + AccessTokenIDInner *idInner = (AccessTokenIDInner *)&tokenID; + return (ATokenTypeEnum)(idInner->type); +} + +int AccessTokenKit::CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return RET_FAILED; + } + if (!DataValidator::IsDcapValid(dcap)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "dcap is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d, dcap=%{public}s", tokenID, dcap.c_str()); + return AccessTokenManagerClient::GetInstance().CheckNativeDCap(tokenID, dcap); +} + +AccessTokenID AccessTokenKit::GetHapTokenID(int userID, const std::string& bundleName, int instIndex) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (!DataValidator::IsUserIdValid(userID) || !DataValidator::IsBundleNameValid(bundleName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "hap token param failed"); + return 0; + } + ACCESSTOKEN_LOG_INFO(LABEL, "int userID=%{public}d, bundleName=%{public}s, instIndex=%{public}d", + userID, bundleName.c_str(), instIndex); + return AccessTokenManagerClient::GetInstance().GetHapTokenID(userID, bundleName, instIndex); +} + +int AccessTokenKit::GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo& hapTokenInfoRes) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d", tokenID); + + return AccessTokenManagerClient::GetInstance().GetHapTokenInfo(tokenID, hapTokenInfoRes); +} + +int AccessTokenKit::GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& nativeTokenInfoRes) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d", tokenID); + + return AccessTokenManagerClient::GetInstance().GetNativeTokenInfo(tokenID, nativeTokenInfoRes); +} + +int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return PERMISSION_DENIED; + } + if (!DataValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "permissionName is invalid"); + return PERMISSION_DENIED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d, permissionName=%{public}s", tokenID, permissionName.c_str()); + return AccessTokenManagerClient::GetInstance().VerifyAccessToken(tokenID, permissionName); +} + +int AccessTokenKit::VerifyAccessToken( + AccessTokenID callerTokenID, AccessTokenID firstTokenID, const std::string& permissionName) +{ + 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::GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (!DataValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "permissionName is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "permissionName=%{public}s", permissionName.c_str()); + + int ret = AccessTokenManagerClient::GetInstance().GetDefPermission(permissionName, permissionDefResult); + ACCESSTOKEN_LOG_INFO(LABEL, "GetDefPermission bundleName = %{public}s", permissionDefResult.bundleName.c_str()); + + return ret; +} + +int AccessTokenKit::GetDefPermissions(AccessTokenID tokenID, std::vector& permDefList) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d", tokenID); + + return AccessTokenManagerClient::GetInstance().GetDefPermissions(tokenID, permDefList); +} + +int AccessTokenKit::GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d, isSystemGrant=%{public}d", tokenID, isSystemGrant); + + return AccessTokenManagerClient::GetInstance().GetReqPermissions(tokenID, reqPermList, isSystemGrant); +} + +int AccessTokenKit::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return DEFAULT_PERMISSION_FLAGS; + } + if (!DataValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "permissionName is invalid"); + return DEFAULT_PERMISSION_FLAGS; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d, permissionName=%{public}s", tokenID, permissionName.c_str()); + return AccessTokenManagerClient::GetInstance().GetPermissionFlag(tokenID, permissionName); +} + +int AccessTokenKit::GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return RET_FAILED; + } + if (!DataValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "permissionName is invalid"); + return RET_FAILED; + } + if (!DataValidator::IsPermissionFlagValid(flag)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "flag is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d, permissionName=%{public}s, flag=%{public}d", + tokenID, permissionName.c_str(), flag); + return AccessTokenManagerClient::GetInstance().GrantPermission(tokenID, permissionName, flag); +} + +int AccessTokenKit::RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return RET_FAILED; + } + if (!DataValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "permissionName is invalid"); + return RET_FAILED; + } + if (!DataValidator::IsPermissionFlagValid(flag)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "flag is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d, permissionName=%{public}s, flag=%{public}d", + tokenID, permissionName.c_str(), flag); + return AccessTokenManagerClient::GetInstance().RevokePermission(tokenID, permissionName, flag); +} + +int AccessTokenKit::ClearUserGrantedPermissionState(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d", tokenID); + return AccessTokenManagerClient::GetInstance().ClearUserGrantedPermissionState(tokenID); +} + +int AccessTokenKit::GetHapTokenInfoFromRemote(AccessTokenID tokenID, HapTokenInfoForSync& hapSync) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + if (tokenID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID is invalid"); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d", tokenID); + + return AccessTokenManagerClient::GetInstance().GetHapTokenInfoFromRemote(tokenID, hapSync); +} + +int AccessTokenKit::GetAllNativeTokenInfo(std::vector& nativeTokenInfosRes) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + + return AccessTokenManagerClient::GetInstance().GetAllNativeTokenInfo(nativeTokenInfosRes); +} + +int AccessTokenKit::SetRemoteHapTokenInfo(const std::string& deviceID, + const HapTokenInfoForSync& hapSync) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID=%{public}s tokenID=%{public}d", + __func__, deviceID.c_str(), hapSync.baseInfo.tokenID); + return AccessTokenManagerClient::GetInstance().SetRemoteHapTokenInfo(deviceID, hapSync); +} + +int AccessTokenKit::SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoList) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID=%{public}s", __func__, deviceID.c_str()); + return AccessTokenManagerClient::GetInstance() + .SetRemoteNativeTokenInfo(deviceID, nativeTokenInfoList); +} + +int AccessTokenKit::DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID=%{public}s tokenID=%{public}d", + __func__, deviceID.c_str(), tokenID); + return AccessTokenManagerClient::GetInstance().DeleteRemoteToken(deviceID, tokenID); +} + +int AccessTokenKit::DeleteRemoteDeviceTokens(const std::string& deviceID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID=%{public}s", __func__, deviceID.c_str()); + return AccessTokenManagerClient::GetInstance().DeleteRemoteDeviceTokens(deviceID); +} + +int AccessTokenKit::DumpToken(std::string& dumpInfo) +{ + return AccessTokenManagerClient::GetInstance().DumpToken(dumpInfo); +} +} // 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 new file mode 100644 index 0000000000000000000000000000000000000000..f7e5d4f0dfd56ddf023a4424ca14f1c58e25c8b9 --- /dev/null +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.cpp @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2021 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_manager_client.h" + +#include "accesstoken_log.h" +#include "accesstoken_manager_proxy.h" +#include "hap_token_info.h" +#include "hap_token_info_for_sync_parcel.h" +#include "iservice_registry.h" +#include "native_token_info.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenManagerClient" +}; +} // namespace + +AccessTokenManagerClient& AccessTokenManagerClient::GetInstance() +{ + static AccessTokenManagerClient instance; + return instance; +} + +AccessTokenManagerClient::AccessTokenManagerClient() +{} + +AccessTokenManagerClient::~AccessTokenManagerClient() +{} + +int AccessTokenManagerClient::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return PERMISSION_DENIED; + } + return proxy->VerifyAccessToken(tokenID, permissionName); +} + +int AccessTokenManagerClient::GetDefPermission( + const std::string& permissionName, PermissionDef& permissionDefResult) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + PermissionDefParcel permissionDefParcel; + int result = proxy->GetDefPermission(permissionName, permissionDefParcel); + permissionDefResult = permissionDefParcel.permissionDef; + return result; +} + +int AccessTokenManagerClient::GetDefPermissions(AccessTokenID tokenID, std::vector& permList) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + std::vector parcelList; + int result = proxy->GetDefPermissions(tokenID, parcelList); + for (auto permParcel : parcelList) { + PermissionDef perm = permParcel.permissionDef; + permList.emplace_back(perm); + } + return result; +} + +int AccessTokenManagerClient::GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + std::vector parcelList; + int result = proxy->GetReqPermissions(tokenID, parcelList, isSystemGrant); + for (auto permParcel : parcelList) { + PermissionStateFull perm = permParcel.permStatFull; + reqPermList.emplace_back(perm); + } + return result; +} + +int AccessTokenManagerClient::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return DEFAULT_PERMISSION_FLAGS; + } + return proxy->GetPermissionFlag(tokenID, permissionName); +} + +int AccessTokenManagerClient::GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + return proxy->GrantPermission(tokenID, permissionName, flag); +} + +int AccessTokenManagerClient::RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + return proxy->RevokePermission(tokenID, permissionName, flag); +} + +int AccessTokenManagerClient::ClearUserGrantedPermissionState(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + return proxy->ClearUserGrantedPermissionState(tokenID); +} + +AccessTokenIDEx AccessTokenManagerClient::AllocHapToken(const HapInfoParams& info, const HapPolicyParams& policy) +{ + AccessTokenIDEx res = { 0 }; + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return res; + } + HapInfoParcel hapInfoParcel; + HapPolicyParcel hapPolicyParcel; + hapInfoParcel.hapInfoParameter = info; + hapPolicyParcel.hapPolicyParameter = policy; + + return proxy->AllocHapToken(hapInfoParcel, hapPolicyParcel); +} + +int AccessTokenManagerClient::DeleteToken(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + return proxy->DeleteToken(tokenID); +} + +ATokenTypeEnum AccessTokenManagerClient::GetTokenType(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return TOKEN_INVALID; + } + return (ATokenTypeEnum)(proxy->GetTokenType(tokenID)); +} + +int AccessTokenManagerClient::CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + return proxy->CheckNativeDCap(tokenID, dcap); +} + +AccessTokenID AccessTokenManagerClient::GetHapTokenID(int userID, const std::string& bundleName, int instIndex) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + return proxy->GetHapTokenID(userID, bundleName, instIndex); +} + +AccessTokenID AccessTokenManagerClient::AllocLocalTokenID( + const std::string& remoteDeviceID, AccessTokenID remoteTokenID) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + return proxy->AllocLocalTokenID(remoteDeviceID, remoteTokenID); +} + +int AccessTokenManagerClient::UpdateHapToken( + AccessTokenID tokenID, const std::string& appIDDesc, const HapPolicyParams& policy) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + HapPolicyParcel hapPolicyParcel; + hapPolicyParcel.hapPolicyParameter = policy; + return proxy->UpdateHapToken(tokenID, appIDDesc, hapPolicyParcel); +} + +int AccessTokenManagerClient::GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo& hapTokenInfoRes) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + HapTokenInfoParcel hapTokenInfoParcel; + int res = proxy->GetHapTokenInfo(tokenID, hapTokenInfoParcel); + + hapTokenInfoRes = hapTokenInfoParcel.hapTokenInfoParams; + return res; +} + +int AccessTokenManagerClient::GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& nativeTokenInfoRes) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + NativeTokenInfoParcel nativeTokenInfoParcel; + int res = proxy->GetNativeTokenInfo(tokenID, nativeTokenInfoParcel); + nativeTokenInfoRes = nativeTokenInfoParcel.nativeTokenInfoParams; + return res; +} + +int AccessTokenManagerClient::GetHapTokenInfoFromRemote(AccessTokenID tokenID, HapTokenInfoForSync& hapSync) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + + HapTokenInfoForSyncParcel hapSyncParcel; + int res = proxy->GetHapTokenInfoFromRemote(tokenID, hapSyncParcel); + hapSync = hapSyncParcel.hapTokenInfoForSyncParams; + return res; +} + +int AccessTokenManagerClient::GetAllNativeTokenInfo(std::vector& nativeTokenInfosRes) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + + std::vector parcelList; + int result = proxy->GetAllNativeTokenInfo(parcelList); + for (auto nativeTokenParcel : parcelList) { + NativeTokenInfo native = nativeTokenParcel.nativeTokenInfoParams; + nativeTokenInfosRes.emplace_back(native); + } + + return result; +} + +int AccessTokenManagerClient::SetRemoteHapTokenInfo(const std::string& deviceID, const HapTokenInfoForSync& hapSync) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + + HapTokenInfoForSyncParcel hapSyncParcel; + hapSyncParcel.hapTokenInfoForSyncParams = hapSync; + + int res = proxy->SetRemoteHapTokenInfo(deviceID, hapSyncParcel); + return res; +} + +int AccessTokenManagerClient::SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoList) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + std::vector hapTokenInfoParcels; + for (auto native : nativeTokenInfoList) { + NativeTokenInfoParcel nativeTokenInfoParcel; + nativeTokenInfoParcel.nativeTokenInfoParams = native; + hapTokenInfoParcels.emplace_back(nativeTokenInfoParcel); + } + PermissionStateFullParcel permStateParcel; + int res = proxy->SetRemoteNativeTokenInfo(deviceID, hapTokenInfoParcels); + return res; +} + +int AccessTokenManagerClient::DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + + int res = proxy->DeleteRemoteToken(deviceID, tokenID); + return res; +} + +int AccessTokenManagerClient::DeleteRemoteDeviceTokens(const std::string& deviceID) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + + int res = proxy->DeleteRemoteDeviceTokens(deviceID); + return res; +} + +int AccessTokenManagerClient::DumpToken(std::string& dumpInfo) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return RET_FAILED; + } + AccessTokenID res = proxy->DumpToken(dumpInfo); + return res; +} + +sptr AccessTokenManagerClient::GetProxy() +{ + if (proxy_ == nullptr) { + std::lock_guard lock(proxyMutex_); + if (proxy_ == nullptr) { + auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (sam == nullptr) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbilityManager is null"); + return nullptr; + } + auto accesstokenSa = sam->GetSystemAbility(IAccessTokenManager::SA_ID_ACCESSTOKEN_MANAGER_SERVICE); + if (accesstokenSa == nullptr) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbility %{public}d is null", + IAccessTokenManager::SA_ID_ACCESSTOKEN_MANAGER_SERVICE); + return nullptr; + } + + auto proxy = iface_cast(accesstokenSa); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "iface_cast get null"); + return nullptr; + } + proxy_ = proxy; + } + } + return proxy_; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h new file mode 100644 index 0000000000000000000000000000000000000000..d3cc13fcafe7b3aaeb3fa8efd0cd8f3e6e0ec39c --- /dev/null +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_client.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 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_MANAGER_CLIENT_H +#define ACCESSTOKEN_MANAGER_CLIENT_H + +#include +#include +#include + +#include "access_token.h" +#include "hap_info_parcel.h" +#include "hap_policy_parcel.h" +#include "hap_token_info.h" +#include "i_accesstoken_manager.h" +#include "native_token_info.h" +#include "nocopyable.h" +#include "permission_def.h" +#include "permission_state_full.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class AccessTokenManagerClient final { +public: + static AccessTokenManagerClient& GetInstance(); + + virtual ~AccessTokenManagerClient(); + + int VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName); + int GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult); + int GetDefPermissions(AccessTokenID tokenID, std::vector& permList); + int GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant); + int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName); + int GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag); + int RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag); + int ClearUserGrantedPermissionState(AccessTokenID tokenID); + AccessTokenIDEx AllocHapToken(const HapInfoParams& info, const HapPolicyParams& policy); + int DeleteToken(AccessTokenID tokenID); + ATokenTypeEnum GetTokenType(AccessTokenID tokenID); + int CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap); + AccessTokenID GetHapTokenID(int userID, const std::string& bundleName, int instIndex); + AccessTokenID AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID); + int UpdateHapToken(AccessTokenID tokenID, const std::string& appIDDesc, const HapPolicyParams& policy); + int GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo& hapTokenInfoRes); + int GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& nativeTokenInfoRes); + int GetHapTokenInfoFromRemote(AccessTokenID tokenID, HapTokenInfoForSync& hapSync); + int GetAllNativeTokenInfo(std::vector& nativeTokenInfosRes); + int SetRemoteHapTokenInfo(const std::string& deviceID, const HapTokenInfoForSync& hapSync); + int SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoList); + int DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID); + int DeleteRemoteDeviceTokens(const std::string& deviceID); + int DumpToken(std::string& dumpInfo); + +private: + AccessTokenManagerClient(); + + DISALLOW_COPY_AND_MOVE(AccessTokenManagerClient); + std::mutex proxyMutex_; + sptr proxy_ = nullptr; + sptr GetProxy(); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_MANAGER_CLIENT_H diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e34fd92521c8517ab0b101c2458c13452ca5f97f --- /dev/null +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.cpp @@ -0,0 +1,830 @@ +/* + * Copyright (c) 2021 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_manager_proxy.h" + +#include "accesstoken_log.h" + +#include "parcel.h" +#include "string_ex.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenManagerProxy"}; +} + +AccessTokenManagerProxy::AccessTokenManagerProxy(const sptr& impl) + : IRemoteProxy(impl) { +} + +AccessTokenManagerProxy::~AccessTokenManagerProxy() +{} + +int AccessTokenManagerProxy::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return PERMISSION_DENIED; + } + if (!data.WriteString(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permissionName"); + return PERMISSION_DENIED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return PERMISSION_DENIED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::VERIFY_ACCESSTOKEN), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return PERMISSION_DENIED; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::GetDefPermission( + const std::string& permissionName, PermissionDefParcel& permissionDefResult) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteString(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permissionName"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_DEF_PERMISSION), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + sptr resultSptr = reply.ReadParcelable(); + if (resultSptr == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "read permission def parcel fail"); + return RET_FAILED; + } + permissionDefResult = *resultSptr; + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::GetDefPermissions(AccessTokenID tokenID, + std::vector& permList) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_DEF_PERMISSIONS), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t size = reply.ReadInt32(); + for (int i = 0; i < size; i++) { + sptr permissionDef = reply.ReadParcelable(); + if (permissionDef != nullptr) { + permList.emplace_back(*permissionDef); + } + } + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return RET_FAILED; + } + if (!data.WriteInt32(isSystemGrant)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write isSystemGrant"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_REQ_PERMISSIONS), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t size = reply.ReadInt32(); + for (int i = 0; i < size; i++) { + sptr permissionReq = reply.ReadParcelable(); + if (permissionReq != nullptr) { + reqPermList.emplace_back(*permissionReq); + } + } + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return DEFAULT_PERMISSION_FLAGS; + } + if (!data.WriteString(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permissionName"); + return DEFAULT_PERMISSION_FLAGS; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return DEFAULT_PERMISSION_FLAGS; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_PERMISSION_FLAG), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return DEFAULT_PERMISSION_FLAGS; + } + + int32_t result = reply.ReadInt32(); + 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; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return RET_FAILED; + } + if (!data.WriteString(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permissionName"); + return RET_FAILED; + } + if (!data.WriteInt32(flag)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write flag"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GRANT_PERMISSION), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return RET_FAILED; + } + if (!data.WriteString(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permissionName"); + return RET_FAILED; + } + if (!data.WriteInt32(flag)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write flag"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::REVOKE_PERMISSION), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::ClearUserGrantedPermissionState(AccessTokenID tokenID) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::CLEAR_USER_GRANT_PERMISSION), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +AccessTokenIDEx AccessTokenManagerProxy::AllocHapToken( + const HapInfoParcel& hapInfo, const HapPolicyParcel& policyParcel) +{ + MessageParcel data; + AccessTokenIDEx res; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + + if (!data.WriteParcelable(&hapInfo)) { + res.tokenIDEx = 0; + return res; + } + if (!data.WriteParcelable(&policyParcel)) { + res.tokenIDEx = 0; + return res; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + res.tokenIDEx = 0; + return res; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::ALLOC_TOKEN_HAP), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + res.tokenIDEx = 0; + return res; + } + + unsigned long long result = reply.ReadUint64(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}llu", result); + res.tokenIDEx = result; + return res; +} + +int AccessTokenManagerProxy::DeleteToken(AccessTokenID tokenID) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::TOKEN_DELETE), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::GetTokenType(AccessTokenID tokenID) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_TOKEN_TYPE), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return RET_FAILED; + } + if (!data.WriteString(dcap)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write dcap"); + return RET_FAILED; + } + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::CHECK_NATIVE_DCAP), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +AccessTokenID AccessTokenManagerProxy::GetHapTokenID(int userID, const std::string& bundleName, int instIndex) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + + if (!data.WriteInt32(userID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return 0; + } + if (!data.WriteString(bundleName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write dcap"); + return 0; + } + if (!data.WriteInt32(instIndex)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write dcap"); + return 0; + } + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return 0; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_HAP_TOKEN_ID), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return 0; + } + + int result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "result from server data = %{public}d", result); + return result; +} + +AccessTokenID AccessTokenManagerProxy::AllocLocalTokenID( + const std::string& remoteDeviceID, AccessTokenID remoteTokenID) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + + if (!data.WriteString(remoteDeviceID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write dcap"); + return 0; + } + if (!data.WriteUint32(remoteTokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write dcap"); + return 0; + } + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return 0; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::ALLOC_LOCAL_TOKEN_ID), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "request fail, result: %{public}d", requestResult); + return 0; + } + + AccessTokenID result = reply.ReadUint32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfoParcel& nativeTokenInfoRes) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permissionName"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_NATIVE_TOKENINFO), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + sptr resultSptr = reply.ReadParcelable(); + if (resultSptr == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "ReadParcelable fail"); + return RET_FAILED; + } + nativeTokenInfoRes = *resultSptr; + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfoParcel& hapTokenInfoRes) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write permissionName"); + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_HAP_TOKENINFO), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + sptr resultSptr = reply.ReadParcelable(); + if (resultSptr == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "ReadParcelable fail"); + return RET_FAILED; + } + hapTokenInfoRes = *resultSptr; + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::UpdateHapToken(AccessTokenID tokenID, + const std::string& appIDDesc, const HapPolicyParcel& policyParcel) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + return RET_FAILED; + } + if (!data.WriteString(appIDDesc)) { + return RET_FAILED; + } + if (!data.WriteParcelable(&policyParcel)) { + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::UPDATE_HAP_TOKEN), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::GetHapTokenInfoFromRemote(AccessTokenID tokenID, + HapTokenInfoForSyncParcel& hapSyncParcel) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_HAP_TOKEN_FROM_REMOTE), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + sptr hapResult = reply.ReadParcelable(); + if (hapResult == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "ReadParcelable fail"); + return RET_FAILED; + } + hapSyncParcel = *hapResult; + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::GetAllNativeTokenInfo(std::vector& nativeTokenInfoRes) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::GET_ALL_NATIVE_TOKEN_FROM_REMOTE), + data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t size = reply.ReadInt32(); + for (int i = 0; i < size; i++) { + sptr nativeResult = reply.ReadParcelable(); + if (nativeResult != nullptr) { + nativeTokenInfoRes.emplace_back(*nativeResult); + } + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::SetRemoteHapTokenInfo(const std::string& deviceID, + HapTokenInfoForSyncParcel& hapSyncParcel) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteString(deviceID)) { + return RET_FAILED; + } + if (!data.WriteParcelable(&hapSyncParcel)) { + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::SET_REMOTE_HAP_TOKEN_INFO), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoParcel) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteString(deviceID)) { + return RET_FAILED; + } + if (!data.WriteUint32(nativeTokenInfoParcel.size())) { + return RET_FAILED; + } + for (NativeTokenInfoParcel& parcel : nativeTokenInfoParcel) { + if (!data.WriteParcelable(&parcel)) { + return RET_FAILED; + } + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::SET_REMOTE_NATIVE_TOKEN_INFO), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteString(deviceID)) { + return RET_FAILED; + } + + if (!data.WriteUint32(tokenID)) { + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::DELETE_REMOTE_TOKEN_INFO), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::DeleteRemoteDeviceTokens(const std::string& deviceID) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + if (!data.WriteString(deviceID)) { + return RET_FAILED; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::DELETE_REMOTE_DEVICE_TOKEN), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int AccessTokenManagerProxy::DumpToken(std::string& dumpInfo) +{ + MessageParcel data; + data.WriteInterfaceToken(IAccessTokenManager::GetDescriptor()); + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return RET_FAILED; + } + int32_t requestResult = remote->SendRequest( + static_cast(IAccessTokenManager::InterfaceCode::DUMP), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return RET_FAILED; + } + + dumpInfo = reply.ReadString(); + AccessTokenID result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..55655a6f4e76c3e9169689c4d477524bb1512c7d --- /dev/null +++ b/interfaces/innerkits/accesstoken/src/accesstoken_manager_proxy.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021 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_MANAGER_PROXY_H +#define ACCESSTOKEN_MANAGER_PROXY_H + +#include +#include + +#include "access_token.h" +#include "hap_info_parcel.h" +#include "hap_policy_parcel.h" +#include "hap_token_info_parcel.h" +#include "hap_token_info_for_sync_parcel.h" +#include "i_accesstoken_manager.h" +#include "iremote_proxy.h" +#include "native_token_info_parcel.h" +#include "permission_def_parcel.h" +#include "permission_state_full_parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class AccessTokenManagerProxy : public IRemoteProxy { +public: + explicit AccessTokenManagerProxy(const sptr& impl); + virtual ~AccessTokenManagerProxy() override; + + int VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) override; + int GetDefPermission(const std::string& permissionName, PermissionDefParcel& permissionDefResult) override; + int GetDefPermissions(AccessTokenID tokenID, std::vector& permList) override; + int GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) 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; + int ClearUserGrantedPermissionState(AccessTokenID tokenID) override; + int GetTokenType(AccessTokenID tokenID) override; + int CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) override; + AccessTokenID GetHapTokenID(int userID, const std::string& bundleName, int instIndex) override; + AccessTokenID AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID) override; + AccessTokenIDEx AllocHapToken(const HapInfoParcel& hapInfo, const HapPolicyParcel& policyParcel) override; + int DeleteToken(AccessTokenID tokenID) override; + int UpdateHapToken(AccessTokenID tokenID, const std::string& appIDDesc, + const HapPolicyParcel& policyPar) override; + int GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfoParcel& hapTokenInfoRes) override; + int GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfoParcel& nativeTokenInfoRes) override; + + int GetHapTokenInfoFromRemote(AccessTokenID tokenID, HapTokenInfoForSyncParcel& hapSyncParcel) override; + int GetAllNativeTokenInfo(std::vector& nativeTokenInfoRes) override; + int SetRemoteHapTokenInfo(const std::string& deviceID, HapTokenInfoForSyncParcel& hapSyncParcel) override; + int SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoParcel) override; + int DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) override; + int DeleteRemoteDeviceTokens(const std::string& deviceID) override; + + int DumpToken(std::string& dumpInfo) override; +private: + static inline BrokerDelegator delegator_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_MANAGER_PROXY_H diff --git a/interfaces/innerkits/accesstoken/test/BUILD.gn b/interfaces/innerkits/accesstoken/test/BUILD.gn old mode 100755 new mode 100644 index a61294493aa5b096203ec73b1f644abca06eb99a..e981ea0ecf5a727ad60cb44cee149ab70e44a03d --- a/interfaces/innerkits/accesstoken/test/BUILD.gn +++ b/interfaces/innerkits/accesstoken/test/BUILD.gn @@ -20,17 +20,23 @@ ohos_unittest("libaccesstoken_sdk_test") { include_dirs = [ "//utils/native/base/include", - "//base/security/access_token/interfaces/innerkits/accesstoken/main/cpp/include/", + "//third_party/googletest/include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", + "//base/security/access_token/interfaces/innerkits/nativetoken/include", + "//base/security/access_token/frameworks/common/include", ] - sources = [ "unittest/cpp/src/accesstoken_kit_test.cpp" ] + sources = [ "unittest/src/accesstoken_kit_test.cpp" ] cflags_cc = [ "-DHILOG_ENABLE" ] deps = [ "//base/security/access_token/interfaces/innerkits/accesstoken:libaccesstoken_sdk", + "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", "//utils/native/base:utils", ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] } group("unittest") { diff --git a/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp b/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c80c6301d2294f90e1e1fd1ee80aacdd2b327db0 --- /dev/null +++ b/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.cpp @@ -0,0 +1,2999 @@ +/* + * Copyright (c) 2021 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_test.h" +#include + +#include "accesstoken_kit.h" +#include "nativetoken_kit.h" +#include "accesstoken_log.h" + +using namespace testing::ext; +using namespace OHOS::Security::AccessToken; + +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenKitTest"}; + +static PermissionStateFull g_grantPermissionReq = { + .permissionName = "ohos.permission.GRANT_SENSITIVE_PERMISSIONS", + .isGeneral = true, + .resDeviceID = {"device"}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED} +}; +static PermissionStateFull g_revokePermissionReq = { + .permissionName = "ohos.permission.REVOKE_SENSITIVE_PERMISSIONS", + .isGeneral = true, + .resDeviceID = {"device"}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED} +}; + +static PermissionDef g_infoManagerTestPermDef1 = { + .permissionName = "ohos.permission.test1", + .bundleName = "accesstoken_test", + .grantMode = 1, + .label = "label", + .labelId = 1, + .description = "open the door", + .descriptionId = 1, + .availableLevel = APL_NORMAL +}; + +static PermissionDef g_infoManagerTestPermDef2 = { + .permissionName = "ohos.permission.test2", + .bundleName = "accesstoken_test", + .grantMode = 1, + .label = "label", + .labelId = 1, + .description = "break the door", + .descriptionId = 1, + .availableLevel = APL_NORMAL +}; + +static PermissionStateFull g_infoManagerTestState1 = { + .grantFlags = {1}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"} +}; + +static PermissionStateFull g_infoManagerTestState2 = { + .permissionName = "ohos.permission.test2", + .isGeneral = false, + .grantFlags = {1, 2}, + .grantStatus = {PermissionState::PERMISSION_GRANTED, PermissionState::PERMISSION_GRANTED}, + .resDeviceID = {"device 1", "device 2"} +}; + +static HapInfoParams g_infoManagerTestInfoParms = { + .bundleName = "accesstoken_test", + .userID = 1, + .instIndex = 0, + .appIDDesc = "testtesttesttest" +}; + +static HapPolicyParams g_infoManagerTestPolicyPrams = { + .apl = APL_NORMAL, + .domain = "test.domain", + .permList = {g_infoManagerTestPermDef1, g_infoManagerTestPermDef2}, + .permStateList = {g_infoManagerTestState1, g_infoManagerTestState2} +}; + +static HapInfoParams g_infoManagerTestInfoParmsBak = { + .bundleName = "accesstoken_test", + .userID = 1, + .instIndex = 0, + .appIDDesc = "testtesttesttest" +}; + +static HapPolicyParams g_infoManagerTestPolicyPramsBak = { + .apl = APL_NORMAL, + .domain = "test.domain", + .permList = {g_infoManagerTestPermDef1, g_infoManagerTestPermDef2}, + .permStateList = {g_infoManagerTestState1, g_infoManagerTestState2} +}; +} + +void AccessTokenKitTest::SetUpTestCase() +{ + // make test case clean + AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + AccessTokenKit::DeleteToken(tokenID); + + tokenID = AccessTokenKit::GetHapTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + AccessTokenKit::DeleteToken(tokenID); +} + +void AccessTokenKitTest::TearDownTestCase() +{ +} + +void AccessTokenKitTest::SetUp() +{ + g_infoManagerTestInfoParms = g_infoManagerTestInfoParmsBak; + g_infoManagerTestPolicyPrams = g_infoManagerTestPolicyPramsBak; + HapInfoParams info = { + .userID = TEST_USER_ID, + .bundleName = TEST_BUNDLE_NAME, + .instIndex = 0, + .appIDDesc = "appIDDesc", + }; + + HapPolicyParams policy = { + .apl = APL_NORMAL, + .domain = "domain" + }; + + PermissionDef permissionDefAlpha = { + .permissionName = TEST_PERMISSION_NAME_ALPHA, + .bundleName = TEST_BUNDLE_NAME, + .grantMode = GrantMode::USER_GRANT, + .availableLevel = APL_NORMAL, + .provisionEnable = false, + .distributedSceneEnable = false + }; + + PermissionDef permissionDefBeta = { + .permissionName = TEST_PERMISSION_NAME_BETA, + .bundleName = TEST_BUNDLE_NAME, + .grantMode = GrantMode::SYSTEM_GRANT, + .availableLevel = APL_NORMAL, + .provisionEnable = false, + .distributedSceneEnable = false + }; + policy.permList.emplace_back(permissionDefAlpha); + policy.permList.emplace_back(permissionDefBeta); + + PermissionStateFull permStatAlpha = { + .permissionName = TEST_PERMISSION_NAME_ALPHA, + .isGeneral = true, + .resDeviceID = {"device"}, + .grantStatus = {PermissionState::PERMISSION_DENIED}, + .grantFlags = {PermissionFlag::PERMISSION_USER_SET} + }; + PermissionStateFull permStatBeta = { + .permissionName = TEST_PERMISSION_NAME_BETA, + .isGeneral = true, + .resDeviceID = {"device"}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .grantFlags = {PermissionFlag::PERMISSION_USER_SET} + }; + policy.permStateList.emplace_back(permStatAlpha); + policy.permStateList.emplace_back(permStatBeta); + policy.permStateList.emplace_back(g_grantPermissionReq); + policy.permStateList.emplace_back(g_revokePermissionReq); + + AccessTokenKit::AllocHapToken(info, policy); + AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + AccessTokenKit::DeleteToken(tokenID); + (void)remove("/data/token.json"); +} + +void AccessTokenKitTest::TearDown() +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + AccessTokenKit::DeleteToken(tokenID); +} + +unsigned int AccessTokenKitTest::GetAccessTokenID(int userID, std::string bundleName, int instIndex) +{ + return AccessTokenKit::GetHapTokenID(userID, bundleName, instIndex); +} + +void AccessTokenKitTest::DeleteTestToken() const +{ + AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + int ret = AccessTokenKit::DeleteToken(tokenID); + if (tokenID != 0) { + ASSERT_EQ(RET_SUCCESS, ret); + } +} + +void AccessTokenKitTest::AllocTestToken() const +{ + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_NE(0, tokenIdEx.tokenIdExStruct.tokenID); +} + +/** + * @tc.name: GetDefPermission001 + * @tc.desc: Get permission definition info after AllocHapToken function has been invoked. + * @tc.type: FUNC + * @tc.require:AR000GM5FC AR000GK6TG + */ +HWTEST_F(AccessTokenKitTest, GetDefPermission001, TestSize.Level1) +{ + PermissionDef permDefResultAlpha; + int ret = AccessTokenKit::GetDefPermission(TEST_PERMISSION_NAME_ALPHA, permDefResultAlpha); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(TEST_PERMISSION_NAME_ALPHA, permDefResultAlpha.permissionName); + + PermissionDef permDefResultBeta; + ret = AccessTokenKit::GetDefPermission(TEST_PERMISSION_NAME_BETA, permDefResultBeta); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(TEST_PERMISSION_NAME_BETA, permDefResultBeta.permissionName); +} + +/** + * @tc.name: GetDefPermission002 + * @tc.desc: Get permission definition info that permission is invalid. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetDefPermission002, TestSize.Level1) +{ + PermissionDef permDefResult; + int ret = AccessTokenKit::GetDefPermission(TEST_PERMISSION_NAME_GAMMA, permDefResult); + ASSERT_EQ(RET_FAILED, ret); + + ret = AccessTokenKit::GetDefPermission("", permDefResult); + ASSERT_EQ(RET_FAILED, ret); + + std::string invalidPerm(INVALID_PERMNAME_LEN, 'a'); + ret = AccessTokenKit::GetDefPermission(invalidPerm, permDefResult); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: GetDefPermission003 + * @tc.desc: GetDefPermission is invoked multiple times. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetDefPermission003, TestSize.Level0) +{ + int ret = RET_FAILED; + for (int i = 0; i < CYCLE_TIMES; i++) { + PermissionDef permDefResultAlpha; + ret = AccessTokenKit::GetDefPermission(TEST_PERMISSION_NAME_ALPHA, permDefResultAlpha); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(TEST_PERMISSION_NAME_ALPHA, permDefResultAlpha.permissionName); + } +} + +/** + * @tc.name: GetDefPermissions001 + * @tc.desc: Get permission definition info list after AllocHapToken function has been invoked. + * @tc.type: FUNC + * @tc.require:AR000GM5FC AR000GK6TG + */ +HWTEST_F(AccessTokenKitTest, GetDefPermissions001, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + std::vector permDefList; + int ret = AccessTokenKit::GetDefPermissions(tokenID, permDefList); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(2, permDefList.size()); +} + +/** + * @tc.name: GetDefPermissions002 + * @tc.desc: Get permission definition info list after clear permission definition list + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetDefPermissions002, TestSize.Level1) +{ + HapPolicyParams testPolicyPrams = g_infoManagerTestPolicyPrams; + testPolicyPrams.permList.clear(); + AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, testPolicyPrams); + + AccessTokenID tokenID = GetAccessTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + ASSERT_NE(0, tokenID); + + std::vector permDefList; + int ret = AccessTokenKit::GetDefPermissions(tokenID, permDefList); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(0, permDefList.size()); + + AccessTokenKit::DeleteToken(tokenID); +} + +/** + * @tc.name: GetDefPermissions003 + * @tc.desc: Get permission definition info list that tokenID is invalid. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetDefPermissions003, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + AccessTokenKit::DeleteToken(tokenID); + + std::vector permDefList; + int ret = AccessTokenKit::GetDefPermissions(TEST_TOKENID_INVALID, permDefList); + ASSERT_EQ(RET_FAILED, ret); + + std::vector permDefListRes; + ret = AccessTokenKit::GetDefPermissions(tokenID, permDefListRes); + ASSERT_EQ(RET_FAILED, ret); + ASSERT_EQ(0, permDefListRes.size()); +} + +/** + * @tc.name: GetDefPermissions004 + * @tc.desc: GetDefPermissions is invoked multiple times. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetDefPermissions004, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = RET_FAILED; + for (int i = 0; i < CYCLE_TIMES; i++) { + std::vector permDefList; + ret = ret = AccessTokenKit::GetDefPermissions(tokenID, permDefList); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(2, permDefList.size()); + } +} + +/** + * @tc.name: GetReqPermissions001 + * @tc.desc: Get user granted permission state info. + * @tc.type: FUNC + * @tc.require:AR000GM5FC AR000GK6TG + */ +HWTEST_F(AccessTokenKitTest, GetReqPermissions001, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + std::vector permStatList; + int ret = AccessTokenKit::GetReqPermissions(tokenID, permStatList, false); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(1, permStatList.size()); + ASSERT_EQ(TEST_PERMISSION_NAME_ALPHA, permStatList[0].permissionName); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(ret, permStatList[0].grantStatus[0]); +} + +/** + * @tc.name: GetReqPermissions002 + * @tc.desc: Get system granted permission state info. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetReqPermissions002, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + std::vector permStatList; + int ret = AccessTokenKit::GetReqPermissions(tokenID, permStatList, true); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(3, permStatList.size()); + ASSERT_EQ(TEST_PERMISSION_NAME_BETA, permStatList[0].permissionName); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_BETA); + ASSERT_EQ(ret, permStatList[0].grantStatus[0]); +} + +/** + * @tc.name: GetReqPermissions003 + * @tc.desc: Get user granted permission state info after clear request permission list. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetReqPermissions003, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + + HapTokenInfo hapInfo; + int ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapInfo); + ASSERT_EQ(RET_SUCCESS, ret); + + HapPolicyParams policy = { + .apl = hapInfo.apl, + .domain = "domain" + }; + policy.permStateList.clear(); + + ret = AccessTokenKit::UpdateHapToken(tokenID, hapInfo.appID, policy); + ASSERT_EQ(RET_SUCCESS, ret); + + std::vector permStatUserList; + ret = AccessTokenKit::GetReqPermissions(tokenID, permStatUserList, false); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(0, permStatUserList.size()); + + std::vector permStatSystemList; + ret = AccessTokenKit::GetReqPermissions(tokenID, permStatSystemList, true); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(0, permStatSystemList.size()); +} + +/** + * @tc.name: GetReqPermissions004 + * @tc.desc: Get permission state info list that tokenID is invalid. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetReqPermissions004, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + + std::vector permStatList; + int ret = AccessTokenKit::GetReqPermissions(TEST_TOKENID_INVALID, permStatList, false); + ASSERT_EQ(RET_FAILED, ret); + + AccessTokenKit::DeleteToken(tokenID); + + ret = AccessTokenKit::GetReqPermissions(tokenID, permStatList, false); + ASSERT_EQ(RET_FAILED, ret); + ASSERT_EQ(0, permStatList.size()); +} + +/** + * @tc.name: GetReqPermissions005 + * @tc.desc: GetReqPermissions is invoked multiple times. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetReqPermissions005, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = RET_FAILED; + for (int i = 0; i < CYCLE_TIMES; i++) { + std::vector permStatList; + ret = ret = AccessTokenKit::GetReqPermissions(tokenID, permStatList, false); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(1, permStatList.size()); + ASSERT_EQ(TEST_PERMISSION_NAME_ALPHA, permStatList[0].permissionName); + } +} + +/** + * @tc.name: GetPermissionFlag001 + * @tc.desc: Get permission flag after grant permission. + * @tc.type: FUNC + * @tc.require:AR000GM5FC AR000GK6TG + */ +HWTEST_F(AccessTokenKitTest, GetPermissionFlag001, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::GetPermissionFlag(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_USER_FIXED, ret); +} + +/** + * @tc.name: GetPermissionFlag002 + * @tc.desc: Get permission flag that tokenID or permission is invalid. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetPermissionFlag002, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + + int ret = AccessTokenKit::GetPermissionFlag(tokenID, TEST_PERMISSION_NAME_GAMMA); + ASSERT_EQ(DEFAULT_PERMISSION_FLAGS, ret); + + ret = AccessTokenKit::GetPermissionFlag(tokenID, ""); + ASSERT_EQ(DEFAULT_PERMISSION_FLAGS, ret); + + std::string invalidPerm(INVALID_PERMNAME_LEN, 'a'); + ret = AccessTokenKit::GetPermissionFlag(tokenID, invalidPerm); + ASSERT_EQ(DEFAULT_PERMISSION_FLAGS, ret); + + ret = AccessTokenKit::GetPermissionFlag(TEST_TOKENID_INVALID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(DEFAULT_PERMISSION_FLAGS, ret); + + AccessTokenKit::DeleteToken(tokenID); + + ret = AccessTokenKit::GetPermissionFlag(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(DEFAULT_PERMISSION_FLAGS, ret); +} + +/** + * @tc.name: GetPermissionFlag003 + * @tc.desc: GetPermissionFlag is invoked multiple times. + * @tc.type: FUNC + * @tc.require:AR000GM5FC + */ +HWTEST_F(AccessTokenKitTest, GetPermissionFlag003, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = RET_FAILED; + for (int i = 0; i < CYCLE_TIMES; i++) { + 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); + ASSERT_EQ(PERMISSION_USER_FIXED, ret); + } +} + +/** + * @tc.name: VerifyAccessToken001 + * @tc.desc: Verify user granted permission. + * @tc.type: FUNC + * @tc.require:AR000GK6T8 AR000GK6TG + */ +HWTEST_F(AccessTokenKitTest, VerifyAccessToken001, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_GRANTED, ret); + + ret = AccessTokenKit::RevokePermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_DENIED, ret); +} + +/** + * @tc.name: VerifyAccessToken002 + * @tc.desc: Verify system granted permission. + * @tc.type: FUNC + * @tc.require:AR000GK6T8 + */ +HWTEST_F(AccessTokenKitTest, VerifyAccessToken002, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_BETA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_BETA); + ASSERT_EQ(PERMISSION_GRANTED, ret); + + ret = AccessTokenKit::RevokePermission(tokenID, TEST_PERMISSION_NAME_BETA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_BETA); + ASSERT_EQ(PERMISSION_DENIED, ret); +} + +/** + * @tc.name: VerifyAccessToken003 + * @tc.desc: Verify permission that tokenID or permission is invalid. + * @tc.type: FUNC + * @tc.require:AR000GK6T8 + */ +HWTEST_F(AccessTokenKitTest, VerifyAccessToken003, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_GAMMA); + ASSERT_EQ(PERMISSION_DENIED, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, ""); + ASSERT_EQ(PERMISSION_DENIED, ret); + + std::string invalidPerm(INVALID_PERMNAME_LEN, 'a'); + ret = AccessTokenKit::VerifyAccessToken(tokenID, invalidPerm); + ASSERT_EQ(PERMISSION_DENIED, ret); + + AccessTokenKit::VerifyAccessToken(TEST_TOKENID_INVALID, TEST_PERMISSION_NAME_BETA); + ASSERT_EQ(PERMISSION_DENIED, ret); + + AccessTokenKit::DeleteToken(tokenID); + + AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_BETA); + ASSERT_EQ(PERMISSION_DENIED, ret); +} + +/** + * @tc.name: VerifyAccessToken004 + * @tc.desc: Verify permission after update. + * @tc.type: FUNC + * @tc.require:AR000GK6T8 + */ +HWTEST_F(AccessTokenKitTest, VerifyAccessToken004, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + + int ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + HapTokenInfo hapInfo; + ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapInfo); + ASSERT_EQ(RET_SUCCESS, ret); + + std::vector permDefList; + ret = AccessTokenKit::GetDefPermissions(tokenID, permDefList); + ASSERT_EQ(RET_SUCCESS, ret); + + std::vector permStatList; + ret = AccessTokenKit::GetReqPermissions(tokenID, permStatList, false); + ASSERT_EQ(RET_SUCCESS, ret); + + HapPolicyParams policy = { + .apl = hapInfo.apl, + .domain = "domain", + .permList = permDefList, + .permStateList = permStatList + }; + + ret = AccessTokenKit::UpdateHapToken(tokenID, hapInfo.appID, policy); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_GRANTED, ret); +} + +/** + * @tc.name: GrantPermission001 + * @tc.desc: Grant permission that has ohos.permission.GRANT_SENSITIVE_PERMISSIONS + * @tc.type: FUNC + * @tc.require:AR000GK6TF AR000GK6TG + */ +HWTEST_F(AccessTokenKitTest, GrantPermission001, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_GRANTED, ret); + + ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_BETA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_GRANTED, ret); +} + +/** + * @tc.name: GrantPermission002 + * @tc.desc: Grant permission that tokenID or permission is invalid. + * @tc.type: FUNC + * @tc.require:AR000GK6TF + */ +HWTEST_F(AccessTokenKitTest, GrantPermission002, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + + int ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_GAMMA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::GrantPermission(tokenID, "", PERMISSION_USER_FIXED); + ASSERT_EQ(RET_FAILED, ret); + + std::string invalidPerm(INVALID_PERMNAME_LEN, 'a'); + ret = AccessTokenKit::GrantPermission(tokenID, invalidPerm, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_FAILED, ret); + + ret = AccessTokenKit::GrantPermission(TEST_TOKENID_INVALID, TEST_PERMISSION_NAME_BETA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_FAILED, ret); + + AccessTokenKit::DeleteToken(tokenID); + + ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_BETA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); +} + +/** + * @tc.name: GrantPermission003 + * @tc.desc: GrantPermission is invoked multiple times. + * @tc.type: FUNC + * @tc.require:AR000GK6TF + */ +HWTEST_F(AccessTokenKitTest, GrantPermission003, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = RET_FAILED; + for (int i = 0; i < CYCLE_TIMES; i++) { + ret = AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_GRANTED, ret); + + ret = AccessTokenKit::GetPermissionFlag(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_USER_FIXED, ret); + } +} + +/** + * @tc.name: RevokePermission001 + * @tc.desc: Revoke permission that has ohos.permission.GRANT_SENSITIVE_PERMISSIONS + * @tc.type: FUNC + * @tc.require:AR000GK6TF AR000GK6TG + */ +HWTEST_F(AccessTokenKitTest, RevokePermission001, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = AccessTokenKit::RevokePermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_DENIED, ret); + + ret = AccessTokenKit::RevokePermission(tokenID, TEST_PERMISSION_NAME_BETA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_DENIED, ret); +} + +/** + * @tc.name: RevokePermission002 + * @tc.desc: Revoke permission that tokenID or permission is invalid. + * @tc.type: FUNC + * @tc.require:AR000GK6TF + */ +HWTEST_F(AccessTokenKitTest, RevokePermission002, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + + int ret = AccessTokenKit::RevokePermission(tokenID, TEST_PERMISSION_NAME_GAMMA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::RevokePermission(tokenID, "", PERMISSION_USER_FIXED); + ASSERT_EQ(RET_FAILED, ret); + + std::string invalidPerm(INVALID_PERMNAME_LEN, 'a'); + ret = AccessTokenKit::RevokePermission(tokenID, invalidPerm, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_FAILED, ret); + + ret = AccessTokenKit::RevokePermission(TEST_TOKENID_INVALID, TEST_PERMISSION_NAME_BETA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_FAILED, ret); + + AccessTokenKit::DeleteToken(tokenID); + + ret = AccessTokenKit::RevokePermission(tokenID, TEST_PERMISSION_NAME_BETA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); +} + +/** + * @tc.name: RevokePermission003 + * @tc.desc: RevokePermission is invoked multiple times. + * @tc.type: FUNC + * @tc.require:AR000GK6TF + */ +HWTEST_F(AccessTokenKitTest, RevokePermission003, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = RET_FAILED; + for (int i = 0; i < CYCLE_TIMES; i++) { + ret = AccessTokenKit::RevokePermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_DENIED, ret); + + ret = AccessTokenKit::GetPermissionFlag(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_USER_FIXED, ret); + } +} + +/** + * @tc.name: ClearUserGrantedPermissionState001 + * @tc.desc: Clear user/system granted permission after ClearUserGrantedPermissionState has been invoked. + * @tc.type: FUNC + * @tc.require:AR000GK6TF AR000GK6TG + */ +HWTEST_F(AccessTokenKitTest, ClearUserGrantedPermissionState001, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = AccessTokenKit::ClearUserGrantedPermissionState(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_DENIED, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_BETA); + ASSERT_EQ(PERMISSION_GRANTED, ret); +} + +/** + * @tc.name: ClearUserGrantedPermissionState002 + * @tc.desc: Clear user/system granted permission that tokenID or permission is invalid. + * @tc.type: FUNC + * @tc.require:AR000GK6TF + */ +HWTEST_F(AccessTokenKitTest, ClearUserGrantedPermissionState002, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + + int ret = AccessTokenKit::ClearUserGrantedPermissionState(TEST_TOKENID_INVALID); + ASSERT_EQ(RET_FAILED, ret); + + AccessTokenKit::DeleteToken(tokenID); + + ret = AccessTokenKit::ClearUserGrantedPermissionState(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} + +/** + * @tc.name: ClearUserGrantedPermissionState003 + * @tc.desc: ClearUserGrantedPermissionState is invoked multiple times. + * @tc.type: FUNC + * @tc.require:AR000GK6TF + */ +HWTEST_F(AccessTokenKitTest, ClearUserGrantedPermissionState003, TestSize.Level0) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + int ret = RET_FAILED; + for (int i = 0; i < CYCLE_TIMES; i++) { + ret = AccessTokenKit::ClearUserGrantedPermissionState(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + ASSERT_EQ(PERMISSION_DENIED, ret); + } +} + +/** + * @tc.name: GetTokenType001 + * @tc.desc: get the token type. + * @tc.type: FUNC + * @tc.require:AR000GK6TH + */ +HWTEST_F(AccessTokenKitTest, GetTokenType001, TestSize.Level0) +{ + AllocTestToken(); + AccessTokenID tokenID = GetAccessTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + int ret = AccessTokenKit::GetTokenType(tokenID); + ASSERT_EQ(TOKEN_HAP, ret); + DeleteTestToken(); +} + +/** + * @tc.name: GetHapTokenInfo001 + * @tc.desc: get the token info and verify. + * @tc.type: FUNC + * @tc.require:AR000GK6TH + */ +HWTEST_F(AccessTokenKitTest, GetHapTokenInfo001, TestSize.Level0) +{ + HapTokenInfo hapTokenInfoRes; + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + int ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapTokenInfoRes); + ASSERT_EQ(RET_SUCCESS, ret); + + ASSERT_EQ(hapTokenInfoRes.apl, APL_NORMAL); + ASSERT_EQ(hapTokenInfoRes.userID, TEST_USER_ID); + ASSERT_EQ(hapTokenInfoRes.tokenID, tokenID); + ASSERT_EQ(hapTokenInfoRes.tokenAttr, 0); + ASSERT_EQ(hapTokenInfoRes.instIndex, 0); + + ASSERT_EQ(hapTokenInfoRes.appID, "appIDDesc"); + + ASSERT_EQ(hapTokenInfoRes.bundleName, TEST_BUNDLE_NAME); +} + +/** + * @tc.name: GetHapTokenInfo002 + * @tc.desc: try to get the token info with invalid tokenId. + * @tc.type: FUNC + * @tc.require:AR000GK6TH + */ +HWTEST_F(AccessTokenKitTest, GetHapTokenInfo002, TestSize.Level0) +{ + HapTokenInfo hapTokenInfoRes; + int ret = AccessTokenKit::GetHapTokenInfo(TEST_TOKENID_INVALID, hapTokenInfoRes); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: DeleteToken001 + * @tc.desc: Cannot get permission definition info after DeleteToken function has been invoked. + * @tc.type: FUNC + * @tc.require:AR000GK6TI + */ +HWTEST_F(AccessTokenKitTest, DeleteToken001, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + PermissionDef permDefResultAlpha; + int ret = AccessTokenKit::GetDefPermission(TEST_PERMISSION_NAME_ALPHA, permDefResultAlpha); + ASSERT_EQ(TEST_PERMISSION_NAME_ALPHA, permDefResultAlpha.permissionName); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + + PermissionDef defResult; + ret = AccessTokenKit::GetDefPermission(TEST_PERMISSION_NAME_ALPHA, defResult); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: DeleteToken002 + * @tc.desc: Delete invalid tokenID. + * @tc.type: FUNC + * @tc.require:AR000GK6TI + */ +HWTEST_F(AccessTokenKitTest, DeleteToken002, TestSize.Level1) +{ + int ret = AccessTokenKit::DeleteToken(TEST_USER_ID_INVALID); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: DeleteToken002 + * @tc.desc: Delete invalid tokenID. + * @tc.type: FUNC + * @tc.require:AR000GK6TI + */ +HWTEST_F(AccessTokenKitTest, DeleteToken003, TestSize.Level1) +{ + HapTokenInfo hapTokenInfoRes; + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + + int ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapTokenInfoRes); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapTokenInfoRes); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: DeleteToken004 + * @tc.desc: alloc a tokenId successfully, delete it successfully the first time and fail to delte it again. + * @tc.type: FUNC + * @tc.require:AR000GK6TI + */ +HWTEST_F(AccessTokenKitTest, DeleteToken004, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + GTEST_LOG_(INFO) << "tokenIdEx.tokenIdExStruct.tokenID :" << tokenIdEx.tokenIdExStruct.tokenID; + AccessTokenID tokenID = GetAccessTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + + int ret = AccessTokenKit::DeleteToken(tokenID); + GTEST_LOG_(INFO) << "g_infoManagerTestInfoParms.userID :" << g_infoManagerTestInfoParms.userID; + GTEST_LOG_(INFO) << "g_infoManagerTestInfoParms.bundleName :" << g_infoManagerTestInfoParms.bundleName.c_str(); + GTEST_LOG_(INFO) << "g_infoManagerTestInfoParms.instIndex :" << g_infoManagerTestInfoParms.instIndex; + GTEST_LOG_(INFO) << "tokenID :" << tokenID; + ASSERT_EQ(RET_SUCCESS, ret); + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: GetHapTokenID001 + * @tc.desc: get hap tokenid. + * @tc.type: FUNC + * @tc.require:AR000GK6TH + */ +HWTEST_F(AccessTokenKitTest, GetHapTokenID001, TestSize.Level1) +{ + HapTokenInfo hapTokenInfoRes; + AccessTokenID tokenID; + tokenID = AccessTokenKit::GetHapTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + + int ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapTokenInfoRes); + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ(hapTokenInfoRes.bundleName, TEST_BUNDLE_NAME); +} + +/** + * @tc.name: GetHapTokenID002 + * @tc.desc: cannot get hap tokenid with invalid userId. + * @tc.type: FUNC + * @tc.require:AR000GK6TH + */ +HWTEST_F(AccessTokenKitTest, GetHapTokenID002, TestSize.Level1) +{ + AccessTokenID tokenID; + tokenID = AccessTokenKit::GetHapTokenID(TEST_USER_ID_INVALID, TEST_BUNDLE_NAME, 0); + ASSERT_EQ(0, tokenID); +} + +/** + * @tc.name: GetHapTokenID003 + * @tc.desc: cannot get hap tokenid with invalid bundlename. + * @tc.type: FUNC + * @tc.require:AR000GK6TH + */ +HWTEST_F(AccessTokenKitTest, GetHapTokenID003, TestSize.Level1) +{ + AccessTokenID tokenID; + tokenID = AccessTokenKit::GetHapTokenID(TEST_USER_ID, "invalid bundlename", 0); + ASSERT_EQ(0, tokenID); +} + +/** + * @tc.name: GetHapTokenID003 + * @tc.desc: cannot get hap tokenid with invalid bundlename. + * @tc.type: FUNC + * @tc.require:AR000GK6TH + */ +HWTEST_F(AccessTokenKitTest, GetHapTokenID004, TestSize.Level1) +{ + AccessTokenID tokenID; + tokenID = AccessTokenKit::GetHapTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0xffff); + ASSERT_EQ(0, tokenID); +} + +/** + * @tc.name: AllocHapToken001 + * @tc.desc: alloc a tokenId successfully, delete it successfully the first time and fail to delte it again. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken001, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + GTEST_LOG_(INFO) << "tokenIdEx.tokenIdExStruct.tokenID :" << tokenIdEx.tokenIdExStruct.tokenID; + AccessTokenID tokenID = GetAccessTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + GTEST_LOG_(INFO) << "tokenID :" << tokenID; + int ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: AllocHapToken002 + * @tc.desc: alloc a tokenId successfully, + * and fail to alloc it with the same info and policy again. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken002, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + AccessTokenID tokenID; + int ret; + + tokenID = GetAccessTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + + ret = AccessTokenKit::DeleteToken(tokenID); + GTEST_LOG_(INFO) << "DeleteToken ret:" << ret; + GTEST_LOG_(INFO) << "tokenID :" << tokenID; + + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + GTEST_LOG_(INFO) << "tokenIdEx.tokenIdExStruct.tokenID :" << tokenIdEx.tokenIdExStruct.tokenID; + + tokenID = GetAccessTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + GTEST_LOG_(INFO) << "tokenID :" << tokenID; + ASSERT_NE(0, tokenID); + + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_EQ(0, tokenIdEx.tokenIdExStruct.tokenID); + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} + +/** + * @tc.name: AllocHapToken003 + * @tc.desc: cannot alloc a tokenId with invalid bundlename. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken003, TestSize.Level1) +{ + std::string invalidBundleName (INVALID_BUNDLENAME_LEN, 'x'); + AccessTokenIDEx tokenIdEx = {0}; + int ret; + AccessTokenID tokenID; + + DeleteTestToken(); + GTEST_LOG_(INFO) << "get hap token info:" << invalidBundleName.length(); + g_infoManagerTestInfoParms.bundleName = invalidBundleName; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + + ASSERT_EQ(0, tokenIdEx.tokenIdExStruct.tokenID); + + tokenID = GetAccessTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + ASSERT_EQ(0, tokenID); + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_FAILED, ret); + + g_infoManagerTestInfoParms.bundleName = "accesstoken_test"; +} + +/** + * @tc.name: AllocHapToken004 + * @tc.desc: cannot alloc a tokenId with invalid apl. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken004, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + AccessTokenID tokenID; + ATokenAplEnum typeBackUp = g_infoManagerTestPolicyPrams.apl; + DeleteTestToken(); + + g_infoManagerTestPolicyPrams.apl = (ATokenAplEnum)5; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + + ASSERT_EQ(0, tokenIdEx.tokenIdExStruct.tokenID); + + tokenID = GetAccessTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + ASSERT_EQ(0, tokenID); + int ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_FAILED, ret); + g_infoManagerTestPolicyPrams.apl = typeBackUp; +} + +/** + * @tc.name: AllocHapToken005 + * @tc.desc: can alloc a tokenId when bundlename in permdef is different with bundlename in info. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken005, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + std::string backUp; + std::string backUpPermission; + std::string bundleNameBackUp = g_infoManagerTestPermDef1.bundleName; + DeleteTestToken(); + + backUp = g_infoManagerTestPolicyPrams.permList[0].bundleName; + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + + g_infoManagerTestPolicyPrams.permList[0].bundleName = "invalid_bundleName"; + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp01"; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_NE(0, tokenIdEx.tokenIdExStruct.tokenID); + + PermissionDef permDefResultBeta; + int ret = AccessTokenKit::GetDefPermission( + g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResultBeta); + ASSERT_EQ(RET_SUCCESS, ret); + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[1].permissionName, permDefResultBeta); + ASSERT_EQ(RET_SUCCESS, ret); + g_infoManagerTestPolicyPrams.permList[0].bundleName = backUp; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; +} + +/** + * @tc.name: AllocHapToken006 + * @tc.desc: can alloc a tokenId with a invalid permList permissionName. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken006, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + std::string backUp; + DeleteTestToken(); + + const std::string invalidPermissionName (INVALID_PERMNAME_LEN, 'x'); + backUp = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = invalidPermissionName; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_NE(0, tokenIdEx.tokenIdExStruct.tokenID); + + PermissionDef permDefResultBeta; + int ret = AccessTokenKit::GetDefPermission(invalidPermissionName, permDefResultBeta); + ASSERT_EQ(RET_FAILED, ret); + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[1].permissionName, permDefResultBeta); + ASSERT_EQ(RET_SUCCESS, ret); + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUp; +} + +/** + * @tc.name: AllocHapToken007 + * @tc.desc: can alloc a tokenId with invalid permdef. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken007, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + std::string backUp; + std::string backUpPermission; + DeleteTestToken(); + + const std::string invalidBundleName (INVALID_BUNDLENAME_LEN, 'x'); + backUp = g_infoManagerTestPolicyPrams.permList[0].bundleName; + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp02"; + g_infoManagerTestPolicyPrams.permList[0].bundleName = invalidBundleName; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_NE(0, tokenIdEx.tokenIdExStruct.tokenID); + + PermissionDef permDefResultBeta; + int ret = AccessTokenKit::GetDefPermission( + g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResultBeta); + ASSERT_EQ(RET_FAILED, ret); + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[1].permissionName, permDefResultBeta); + ASSERT_EQ(RET_SUCCESS, ret); + g_infoManagerTestPolicyPrams.permList[0].bundleName = backUp; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; +} + +/** + * @tc.name: AllocHapToken008 + * @tc.desc: can alloc a tokenId with invalid permdef. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken008, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + std::string backUp; + std::string backUpPermission; + DeleteTestToken(); + + const std::string invalidLabel (INVALID_LABEL_LEN, 'x'); + backUp = g_infoManagerTestPolicyPrams.permList[0].label; + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp03"; + g_infoManagerTestPolicyPrams.permList[0].label = invalidLabel; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_NE(0, tokenIdEx.tokenIdExStruct.tokenID); + + PermissionDef permDefResultBeta; + int ret = AccessTokenKit::GetDefPermission( + g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResultBeta); + ASSERT_EQ(RET_FAILED, ret); + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[1].permissionName, permDefResultBeta); + ASSERT_EQ(RET_SUCCESS, ret); + g_infoManagerTestPolicyPrams.permList[0].label = backUp; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; +} + +/** + * @tc.name: AllocHapToken009 + * @tc.desc: can alloc a tokenId with invalid permdef. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken009, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + std::string backUp; + std::string backUpPermission; + DeleteTestToken(); + + const std::string invalidDescription (INVALID_DESCRIPTION_LEN, 'x'); + backUp = g_infoManagerTestPolicyPrams.permList[0].description; + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp04"; + g_infoManagerTestPolicyPrams.permList[0].description = invalidDescription; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_NE(0, tokenIdEx.tokenIdExStruct.tokenID); + + PermissionDef permDefResultBeta; + int ret = AccessTokenKit::GetDefPermission( + g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResultBeta); + ASSERT_EQ(RET_FAILED, ret); + ret = AccessTokenKit::GetDefPermission( + g_infoManagerTestPolicyPrams.permList[1].permissionName, permDefResultBeta); + ASSERT_EQ(RET_SUCCESS, ret); + + g_infoManagerTestPolicyPrams.permList[0].description = backUp; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; +} + +static bool ExistInVector(vector array, unsigned int value) +{ + vector::iterator it; + it = find(array.begin(), array.end(), value); + if (it != array.end()) { + return true; + } else { + return false; + } +} + +/** + * @tc.name: AllocHapToken010 + * @tc.desc: alloc and delete in a loop. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken010, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + AccessTokenID tokenID; + int ret; + bool exist = false; + int allocFlag = 0; + int deleteFlag = 0; + + DeleteTestToken(); + vector obj; + for (int i = 0; i < CYCLE_TIMES; i++) { + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + tokenID = GetAccessTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + + exist = ExistInVector(obj, tokenID); + if (exist) { + allocFlag = 1; + } + obj.push_back(tokenID); + + ret = AccessTokenKit::DeleteToken(tokenID); + if (RET_SUCCESS != ret) { + deleteFlag = 1; + } + } + ASSERT_EQ(allocFlag, 0); + ASSERT_EQ(deleteFlag, 0); +} + +/** + * @tc.name: AllocHapToken011 + * @tc.desc: cannot alloc a tokenId with invalid appIDDesc. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken011, TestSize.Level1) +{ + std::string invalidAppIDDesc (INVALID_APPIDDESC_LEN, 'x'); + std::string backup; + AccessTokenIDEx tokenIdEx = {0}; + + DeleteTestToken(); + backup = g_infoManagerTestInfoParms.appIDDesc; + g_infoManagerTestInfoParms.appIDDesc = invalidAppIDDesc; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_EQ(0, tokenIdEx.tokenIdExStruct.tokenID); + g_infoManagerTestInfoParms.appIDDesc = backup; +} + +/** + * @tc.name: AllocHapToken012 + * @tc.desc: cannot alloc a tokenId with invalid bundleName. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken012, TestSize.Level1) +{ + std::string backup; + AccessTokenIDEx tokenIdEx = {0}; + + backup = g_infoManagerTestInfoParms.bundleName; + g_infoManagerTestInfoParms.bundleName = ""; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_EQ(0, tokenIdEx.tokenIdExStruct.tokenID); + g_infoManagerTestInfoParms.bundleName = backup; +} + +/** + * @tc.name: AllocHapToken013 + * @tc.desc: cannot alloc a tokenId with invalid appIDDesc. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken013, TestSize.Level1) +{ + std::string backup; + AccessTokenIDEx tokenIdEx = {0}; + + backup = g_infoManagerTestInfoParms.appIDDesc; + g_infoManagerTestInfoParms.appIDDesc = ""; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_EQ(0, tokenIdEx.tokenIdExStruct.tokenID); + g_infoManagerTestInfoParms.appIDDesc = backup; +} + +/** + * @tc.name: AllocHapToken014 + * @tc.desc: can alloc a tokenId with permList permissionName as "". + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken014, TestSize.Level1) +{ + std::string backup; + AccessTokenIDEx tokenIdEx = {0}; + + backup = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = ""; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + PermissionDef permDefResultBeta; + int ret = AccessTokenKit::GetDefPermission("", permDefResultBeta); + ASSERT_EQ(RET_FAILED, ret); + g_infoManagerTestPolicyPrams.permList[0].permissionName = backup; +} + +/** + * @tc.name: AllocHapToken015 + * @tc.desc: can alloc a tokenId with permList bundleName as "". + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken015, TestSize.Level1) +{ + std::string backup; + std::string backUpPermission; + AccessTokenIDEx tokenIdEx = {0}; + + backup = g_infoManagerTestPolicyPrams.permList[0].bundleName; + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].bundleName = ""; + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp05"; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + + PermissionDef permDefResultBeta; + int ret = AccessTokenKit::GetDefPermission( + g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResultBeta); + ASSERT_EQ(RET_FAILED, ret); + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[1].permissionName, permDefResultBeta); + ASSERT_EQ(RET_SUCCESS, ret); + g_infoManagerTestPolicyPrams.permList[0].bundleName = backup; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; +} + +/** + * @tc.name: AllocHapToken016 + * @tc.desc: can alloc a tokenId with label as "". + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken016, TestSize.Level1) +{ + std::string backup; + std::string backUpPermission; + AccessTokenIDEx tokenIdEx = {0}; + + backup = g_infoManagerTestPolicyPrams.permList[0].label; + g_infoManagerTestPolicyPrams.permList[0].label = ""; + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp06"; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + + PermissionDef permDefResult; + int ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult); + ASSERT_EQ(ret, RET_SUCCESS); + g_infoManagerTestPolicyPrams.permList[0].label = backup; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; +} + +/** + * @tc.name: AllocHapToken017 + * @tc.desc: cannot alloc a tokenId with invalid permdef. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, AllocHapToken017, TestSize.Level1) +{ + std::string backUpPermission; + std::string backup; + AccessTokenIDEx tokenIdEx = {0}; + + backup = g_infoManagerTestPolicyPrams.permList[0].description; + g_infoManagerTestPolicyPrams.permList[0].description = ""; + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp07"; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + + PermissionDef permDefResult; + int ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult); + ASSERT_EQ(ret, RET_SUCCESS); + g_infoManagerTestPolicyPrams.permList[0].description = backup; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; +} + +/** + * @tc.name: UpdateHapToken001 + * @tc.desc: alloc a tokenId successfully, update it successfully and verify it. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, UpdateHapToken001, TestSize.Level1) +{ + int userID = g_infoManagerTestInfoParms.userID; + const std::string bundleName = g_infoManagerTestInfoParms.bundleName; + int instIndex = g_infoManagerTestInfoParms.instIndex; + + const std::string appIDDesc = "housework app"; + + DeleteTestToken(); + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + GTEST_LOG_(INFO) << "tokenID :" << tokenIdEx.tokenIdExStruct.tokenID; + AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(userID, bundleName, instIndex); + GTEST_LOG_(INFO) << "tokenID :" << tokenID; + g_infoManagerTestPolicyPrams.apl = APL_SYSTEM_BASIC; + + int ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); + ASSERT_EQ(0, ret); + + HapTokenInfo hapTokenInfoRes; + ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapTokenInfoRes); + ASSERT_EQ(RET_SUCCESS, ret); + + ASSERT_EQ(hapTokenInfoRes.appID, "housework app"); + ASSERT_EQ(hapTokenInfoRes.apl, APL_SYSTEM_BASIC); + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} + +/** + * @tc.name: UpdateHapToken002 + * @tc.desc: cannot update hap token info with invalid userId. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, UpdateHapToken002, TestSize.Level1) +{ + int ret = AccessTokenKit::UpdateHapToken(TEST_USER_ID_INVALID, "appIDDesc", g_infoManagerTestPolicyPrams); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: UpdateHapToken003 + * @tc.desc: cannot update hap token info with invalid appIDDesc. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, UpdateHapToken003, TestSize.Level1) +{ + int userID = g_infoManagerTestInfoParms.userID; + const std::string bundleName = g_infoManagerTestInfoParms.bundleName; + int instIndex = g_infoManagerTestInfoParms.instIndex; + + const std::string appIDDesc (INVALID_APPIDDESC_LEN, 'x'); + + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + + AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(userID, bundleName, instIndex); + + int ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); + ASSERT_EQ(RET_FAILED, ret); + + HapTokenInfo hapTokenInfoRes; + ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapTokenInfoRes); + ASSERT_EQ(RET_SUCCESS, ret); + + ASSERT_EQ(hapTokenInfoRes.appID, "testtesttesttest"); + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} + +/** + * @tc.name: UpdateHapToken004 + * @tc.desc: cannot update a tokenId with invalid apl. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, UpdateHapToken004, TestSize.Level1) +{ + int userID = g_infoManagerTestInfoParms.userID; + const std::string bundleName = g_infoManagerTestInfoParms.bundleName; + int instIndex = g_infoManagerTestInfoParms.instIndex; + + const std::string appIDDesc = "housework app"; + + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + + AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(userID, bundleName, instIndex); + + g_infoManagerTestPolicyPrams.apl = (ATokenAplEnum)5; + + int ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); + ASSERT_EQ(RET_FAILED, ret); + + HapTokenInfo hapTokenInfoRes; + ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapTokenInfoRes); + ASSERT_EQ(RET_SUCCESS, ret); + + ASSERT_EQ(hapTokenInfoRes.apl, APL_NORMAL); + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} + +/** + * @tc.name: UpdateHapToken005 + * @tc.desc: cannot update a tokenId with invalid string value. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, UpdateHapToken005, TestSize.Level1) +{ + std::string backUpPermission; + const std::string appIDDesc = g_infoManagerTestInfoParms.appIDDesc; + PermissionDef permDefResult; + + DeleteTestToken(); + AccessTokenIDEx tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + AccessTokenID tokenID = tokenIdEx.tokenIdExStruct.tokenID; + ASSERT_NE(0, tokenID); + + std::string backup = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = ""; + int ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult); + ASSERT_EQ(RET_FAILED, ret); + g_infoManagerTestPolicyPrams.permList[0].permissionName = backup; + + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp11"; + backup = g_infoManagerTestPolicyPrams.permList[0].bundleName; + g_infoManagerTestPolicyPrams.permList[0].bundleName = ""; + ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult); + ASSERT_EQ(RET_FAILED, ret); + g_infoManagerTestPolicyPrams.permList[0].bundleName = backup; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; + + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp12"; + backup = g_infoManagerTestPolicyPrams.permList[0].label; + g_infoManagerTestPolicyPrams.permList[0].label = ""; + ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); + ASSERT_EQ(RET_SUCCESS, ret); + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult); + ASSERT_EQ(RET_SUCCESS, ret); + g_infoManagerTestPolicyPrams.permList[0].label = backup; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; + + backUpPermission = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.testtmp13"; + backup = g_infoManagerTestPolicyPrams.permList[0].description; + g_infoManagerTestPolicyPrams.permList[0].description = ""; + ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); + ASSERT_EQ(RET_SUCCESS, ret); + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult); + ASSERT_EQ(RET_SUCCESS, ret); + g_infoManagerTestPolicyPrams.permList[0].description = backup; + g_infoManagerTestPolicyPrams.permList[0].permissionName = backUpPermission; + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} + +/** + * @tc.name: UpdateHapToken006 + * @tc.desc: update a batch of tokenId. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, UpdateHapToken006, TestSize.Level1) +{ + int allocFlag = 0; + int updateFlag = 0; + int deleteFlag = 0; + AccessTokenIDEx tokenIdEx = {0}; + AccessTokenID tokenID; + int ret; + vector obj; + bool exist; + const std::string appIDDesc = g_infoManagerTestInfoParms.appIDDesc; + HapInfoParams infoManagerTestInfo = g_infoManagerTestInfoParms; + DeleteTestToken(); + + for (int i = 0; i < CYCLE_TIMES; i++) { + tokenIdEx = AccessTokenKit::AllocHapToken(infoManagerTestInfo, g_infoManagerTestPolicyPrams); + tokenID = GetAccessTokenID(infoManagerTestInfo.userID, + infoManagerTestInfo.bundleName, + infoManagerTestInfo.instIndex); + + exist = ExistInVector(obj, tokenID); + if (exist) { + allocFlag = 1; + break; + } + obj.push_back(tokenID); + infoManagerTestInfo.userID++; + } + + infoManagerTestInfo.instIndex = 1; + g_infoManagerTestPolicyPrams.apl = APL_SYSTEM_BASIC; + for (int i = 0; i < obj.size(); i++) { + ret = AccessTokenKit::UpdateHapToken(obj[i], appIDDesc, g_infoManagerTestPolicyPrams); + if (RET_SUCCESS != ret) { + updateFlag = 1; + break; + } + } + g_infoManagerTestPolicyPrams.apl = APL_NORMAL; + + for (int i = 0; i < obj.size(); i++) { + ret = AccessTokenKit::DeleteToken(obj[i]); + if (RET_SUCCESS != ret) { + deleteFlag = 1; + } + } + ASSERT_EQ(allocFlag, 0); + ASSERT_EQ(updateFlag, 0); + ASSERT_EQ(deleteFlag, 0); +} + +/** + * @tc.name: UpdateHapToken007 + * @tc.desc: add new permissdef. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, UpdateHapToken007, TestSize.Level1) +{ + int ret; + std::string backup; + const std::string appIDDesc = g_infoManagerTestInfoParms.appIDDesc; + DeleteTestToken(); + + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + AccessTokenID tokenID = tokenIdEx.tokenIdExStruct.tokenID; + GTEST_LOG_(INFO) << "tokenID :" << tokenID; + + PermissionDef permDefResult; + /* check permission define befor update */ + ret = AccessTokenKit::GetDefPermission("ohos.permission.test3", permDefResult); + ASSERT_EQ(RET_FAILED, ret); + + backup = g_infoManagerTestPolicyPrams.permList[0].permissionName; + g_infoManagerTestPolicyPrams.permList[0].permissionName = "ohos.permission.test3"; + ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); + ASSERT_EQ(RET_SUCCESS, ret); + g_infoManagerTestPolicyPrams.permList[0].permissionName = backup; + + GTEST_LOG_(INFO) << "permissionName :" << g_infoManagerTestPolicyPrams.permList[0].permissionName; + + ret = AccessTokenKit::GetDefPermission("ohos.permission.test3", permDefResult); + if (ret != RET_SUCCESS) { + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + } + ASSERT_EQ(RET_SUCCESS, ret); + ASSERT_EQ("ohos.permission.test3", permDefResult.permissionName); + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} +/** + * @tc.name: UpdateHapToken008 + * @tc.desc: modify permissdef's grantMode. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, UpdateHapToken008, TestSize.Level1) +{ + int ret; + std::string backup; + const std::string appIDDesc = g_infoManagerTestInfoParms.appIDDesc; + DeleteTestToken(); + + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + AccessTokenID tokenID = tokenIdEx.tokenIdExStruct.tokenID; + GTEST_LOG_(INFO) << "tokenID :" << tokenID; + + PermissionDef permDefResult; + /* check permission define befor update */ + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult); + ASSERT_EQ(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult.permissionName); + ASSERT_EQ("label", permDefResult.label); + ASSERT_EQ(1, permDefResult.grantMode); + ASSERT_EQ(RET_SUCCESS, ret); + + backup = g_infoManagerTestPolicyPrams.permList[0].label; + g_infoManagerTestPolicyPrams.permList[0].grantMode = 0; + g_infoManagerTestPolicyPrams.permList[0].label = "updated label"; + ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, g_infoManagerTestPolicyPrams); + ASSERT_EQ(RET_SUCCESS, ret); + g_infoManagerTestPolicyPrams.permList[0].label = backup; + g_infoManagerTestPolicyPrams.permList[0].grantMode = 1; + + /* check permission define after update */ + ret = AccessTokenKit::GetDefPermission(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult); + ASSERT_EQ(g_infoManagerTestPolicyPrams.permList[0].permissionName, permDefResult.permissionName); + ASSERT_EQ("updated label", permDefResult.label); + ASSERT_EQ(0, permDefResult.grantMode); + ASSERT_EQ(RET_SUCCESS, ret); + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} + +/** + * @tc.name: UpdateHapToken009 + * @tc.desc: old permission define will not update its grantStatus. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, UpdateHapToken009, TestSize.Level1) +{ + int ret; + std::vector permDefList; + const std::string appIDDesc = g_infoManagerTestInfoParms.appIDDesc; + PermissionDef infoManagerTestPermDef = g_infoManagerTestPermDef1; + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionState::PERMISSION_DENIED}, + .grantStatus = {3}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + + HapPolicyParams infoManagerTestPolicyPrams = { + .apl = APL_NORMAL, + .domain = "test.domain", + .permList = {infoManagerTestPermDef}, + .permStateList = {infoManagerTestState}}; + + DeleteTestToken(); + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + AccessTokenID tokenID = tokenIdEx.tokenIdExStruct.tokenID; + GTEST_LOG_(INFO) << "tokenID :" << tokenID; + + ret = AccessTokenKit::VerifyAccessToken(tokenID, "ohos.permission.test1"); + ASSERT_EQ(ret, g_infoManagerTestState1.grantStatus[0]); + + ret = AccessTokenKit::UpdateHapToken(tokenID, appIDDesc, infoManagerTestPolicyPrams); + + ret = AccessTokenKit::VerifyAccessToken(tokenID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_DENIED); + + ret = AccessTokenKit::DeleteToken(tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} + +static void *ThreadTestFunc01(void *args) +{ + ATokenTypeEnum type; + AccessTokenID tokenID; + + for (int i = 0; i < CYCLE_TIMES; i++) { + tokenID = AccessTokenKit::GetHapTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + type = AccessTokenKit::GetTokenType(tokenID); + if (type != TOKEN_HAP) { + GTEST_LOG_(INFO) << "ThreadTestFunc01 failed" << tokenID; + } + } + return NULL; +} + +static void *ThreadTestFunc02(void *args) +{ + int ret; + AccessTokenID tokenID; + HapTokenInfo hapTokenInfoRes; + + for (int i = 0; i < CYCLE_TIMES; i++) { + tokenID = AccessTokenKit::GetHapTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, + g_infoManagerTestInfoParms.instIndex); + ret = AccessTokenKit::GetHapTokenInfo(tokenID, hapTokenInfoRes); + if (ret != RET_SUCCESS) { + GTEST_LOG_(INFO) << "ThreadTestFunc02 failed" << tokenID; + } + } + return NULL; +} + +/** + * @tc.name: AllocHapToken011 + * @tc.desc: Mulitpulthread test. + * @tc.type: FUNC + * @tc.require:AR000GK6TJ + */ +HWTEST_F(AccessTokenKitTest, Mulitpulthread001, TestSize.Level1) +{ + int ret; + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_NE(0, tokenIdEx.tokenIdExStruct.tokenID); + pthread_t tid[2]; + (void)pthread_create(&tid[0], 0, &ThreadTestFunc01, NULL); + (void)pthread_create(&tid[1], 0, &ThreadTestFunc01, NULL); + pthread_join(tid[0], NULL); + pthread_join(tid[1], NULL); + + (void)pthread_create(&tid[0], 0, &ThreadTestFunc02, NULL); + (void)pthread_create(&tid[1], 0, &ThreadTestFunc02, NULL); + pthread_join(tid[0], NULL); + pthread_join(tid[1], NULL); + + ret = AccessTokenKit::DeleteToken(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_EQ(RET_SUCCESS, ret); +} + +void ConcurrencyTask(unsigned int tokenID) +{ + for (int i = 0; i < CYCLE_TIMES; i++) { + AccessTokenKit::GrantPermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_FIXED); + AccessTokenKit::GetPermissionFlag(tokenID, TEST_PERMISSION_NAME_ALPHA); + AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + + AccessTokenKit::RevokePermission(tokenID, TEST_PERMISSION_NAME_ALPHA, PERMISSION_USER_SET); + AccessTokenKit::GetPermissionFlag(tokenID, TEST_PERMISSION_NAME_ALPHA); + AccessTokenKit::VerifyAccessToken(tokenID, TEST_PERMISSION_NAME_ALPHA); + } +} + +/** + * @tc.name: ConcurrencyTest001 + * @tc.desc: Concurrency testing + * @tc.type: FUNC + * @tc.require:AR000GM5FC AR000GK6T8 AR000GK6TF + */ +HWTEST_F(AccessTokenKitTest, ConcurrencyTest001, TestSize.Level1) +{ + AccessTokenID tokenID = GetAccessTokenID(TEST_USER_ID, TEST_BUNDLE_NAME, 0); + ASSERT_NE(0, tokenID); + std::vector threadVec; + for (int i = 0; i < THREAD_NUM; i++) { + threadVec.emplace_back(std::thread(ConcurrencyTask, tokenID)); + } + for (auto it = threadVec.begin(); it != threadVec.end(); it++) { + it->join(); + } +} + +/** + * @tc.name: CheckNativeDCap001 + * @tc.desc: cannot Check native dcap with invalid tokenID. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(AccessTokenKitTest, CheckNativeDCap001, TestSize.Level1) +{ + AccessTokenID tokenID = 0; + const std::string dcap = "AT_CAP"; + int ret = AccessTokenKit::CheckNativeDCap(tokenID, dcap); + ASSERT_EQ(RET_FAILED, ret); + + tokenID = 1; + ret = AccessTokenKit::CheckNativeDCap(tokenID, dcap); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: CheckNativeDCap002 + * @tc.desc: cannot Check native dcap with invalid dcap. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(AccessTokenKitTest, CheckNativeDCap002, TestSize.Level1) +{ + AccessTokenID tokenID = 0Xff; + const std::string invalidDcap (INVALID_DCAP_LEN, 'x'); + int ret = AccessTokenKit::CheckNativeDCap(tokenID, invalidDcap); + ASSERT_EQ(RET_FAILED, ret); +} + +/** + * @tc.name: GetNativeTokenInfo001 + * @tc.desc: cannot get native token with invalid tokenID. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(AccessTokenKitTest, GetNativeTokenInfo001, TestSize.Level1) +{ + AccessTokenID tokenID = 0; + NativeTokenInfo findInfo; + int ret = AccessTokenKit::GetNativeTokenInfo(tokenID, findInfo); + ASSERT_EQ(ret, RET_FAILED); + + tokenID = 0xff; + ret = AccessTokenKit::GetNativeTokenInfo(tokenID, findInfo); + ASSERT_EQ(ret, RET_FAILED); +} + +/** + * @tc.name: GetTokenTypeFlag001 + * @tc.desc: cannot get token type with tokenID. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(AccessTokenKitTest, GetTokenTypeFlag001, TestSize.Level1) +{ + AccessTokenID tokenID = 0; + ATokenTypeEnum ret = AccessTokenKit::GetTokenTypeFlag(tokenID); + ASSERT_EQ(ret, TOKEN_INVALID); +} + +/** + * @tc.name: GetTokenTypeFlag002 + * @tc.desc: Get token type with native tokenID. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(AccessTokenKitTest, GetTokenTypeFlag002, TestSize.Level1) +{ + uint64_t tokenId01 = GetAccessTokenId("GetTokenTypeFlag002", nullptr, 0, "system_core"); + + AccessTokenID tokenID = tokenId01 & 0xffffffff; + ATokenTypeEnum ret = AccessTokenKit::GetTokenTypeFlag(tokenID); + ASSERT_EQ(ret, TOKEN_NATIVE); +} + +/** + * @tc.name: GetTokenTypeFlag003 + * @tc.desc: Get token type with hap tokenID. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(AccessTokenKitTest, GetTokenTypeFlag003, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + ASSERT_NE(0, tokenIdEx.tokenIdExStruct.tokenID); + + ATokenTypeEnum ret = AccessTokenKit::GetTokenTypeFlag(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_EQ(ret, TOKEN_HAP); + + int res = AccessTokenKit::DeleteToken(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_EQ(RET_SUCCESS, res); +} + +/** + * @tc.name: SetRemoteHapTokenInfo001 + * @tc.desc: set remote hap token info success + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo001, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo001 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + // Get local map token ID + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + // check local map token + HapTokenInfo resultInfo; + ret = AccessTokenKit::GetHapTokenInfo(mapID, resultInfo); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(resultInfo.apl, remoteTokenInfo.baseInfo.apl); + ASSERT_EQ(resultInfo.ver, remoteTokenInfo.baseInfo.ver); + ASSERT_EQ(resultInfo.userID, remoteTokenInfo.baseInfo.userID); + ASSERT_EQ(resultInfo.bundleName, remoteTokenInfo.baseInfo.bundleName); + ASSERT_EQ(resultInfo.instIndex, remoteTokenInfo.baseInfo.instIndex); + ASSERT_EQ(resultInfo.appID, remoteTokenInfo.baseInfo.appID); + ASSERT_EQ(resultInfo.deviceID, remoteTokenInfo.baseInfo.deviceID); + ASSERT_NE(resultInfo.tokenID, remoteTokenInfo.baseInfo.tokenID); // tokenID already is map tokenID + ASSERT_EQ(resultInfo.tokenAttr, remoteTokenInfo.baseInfo.tokenAttr); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_GRANTED); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: SetRemoteHapTokenInfo002 + * @tc.desc: set remote hap token info, token info is wrong + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo002, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo002 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo rightBaseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + HapTokenInfo wrongBaseInfo = rightBaseInfo; + wrongBaseInfo.apl = (ATokenAplEnum)11; // wrong apl + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = wrongBaseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_NE(ret, RET_SUCCESS); + + std::string wrongStr(10241, 'x'); + + wrongBaseInfo = rightBaseInfo; + wrongBaseInfo.appID = wrongStr; // wrong appID + remoteTokenInfo.baseInfo = wrongBaseInfo; + ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_NE(ret, RET_SUCCESS); + + wrongBaseInfo = rightBaseInfo; + wrongBaseInfo.bundleName = wrongStr; // wrong bundleName + remoteTokenInfo.baseInfo = wrongBaseInfo; + ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_NE(ret, RET_SUCCESS); + + wrongBaseInfo = rightBaseInfo; + wrongBaseInfo.deviceID = wrongStr; // wrong deviceID + remoteTokenInfo.baseInfo = wrongBaseInfo; + ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_NE(ret, RET_SUCCESS); + + wrongBaseInfo = rightBaseInfo; + wrongBaseInfo.tokenID = 0; // wrong tokenID + remoteTokenInfo.baseInfo = wrongBaseInfo; + ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_NE(ret, RET_SUCCESS); +} + +/** + * @tc.name: SetRemoteHapTokenInfo003 + * @tc.desc: set remote hap token wrong permission grant + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo003, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo003 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {11}, // wrong flags + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + // Get local map token ID + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_DENIED); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: SetRemoteHapTokenInfo004 + * @tc.desc: update remote hap token when remote exist + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo004, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo004 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED}, + .grantStatus = {PermissionState::PERMISSION_DENIED}, // first denied + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + // Get local map token ID + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_DENIED); + + remoteTokenInfo.permStateList[0].grantStatus[0] = PermissionState::PERMISSION_GRANTED; // second granted + ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_GRANTED); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: SetRemoteHapTokenInfo005 + * @tc.desc: add remote hap token, it can not grant by GrantPermission + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo005, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo005 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED}, + .grantStatus = {PermissionState::PERMISSION_DENIED}, // first denied + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + // Get local map token ID + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_DENIED); + + ret = AccessTokenKit::GrantPermission(mapID, "ohos.permission.test1", PermissionFlag::PERMISSION_SYSTEM_FIXED); + ASSERT_EQ(ret, RET_SUCCESS); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_DENIED); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: SetRemoteHapTokenInfo006 + * @tc.desc: add remote hap token, it can not revoke by RevokePermission + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo006, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo006 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, // first grant + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + // Get local map token ID + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_GRANTED); + + ret = AccessTokenKit::RevokePermission(mapID, "ohos.permission.test1", PermissionFlag::PERMISSION_SYSTEM_FIXED); + ASSERT_EQ(ret, RET_SUCCESS); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_GRANTED); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: SetRemoteHapTokenInfo007 + * @tc.desc: add remote hap token, it can not delete by DeleteToken + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo007, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo007 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED}, + .grantStatus = {PermissionState::PERMISSION_DENIED}, // first denied + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + // Get local map token ID + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + ret = AccessTokenKit::DeleteToken(mapID); + ASSERT_EQ(ret, RET_FAILED); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: SetRemoteHapTokenInfo008 + * @tc.desc: add remote hap token, it can not update by UpdateHapToken + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo008, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo008 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_SYSTEM_FIXED}, + .grantStatus = {PermissionState::PERMISSION_DENIED}, // first denied + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + // Get local map token ID + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + HapPolicyParams policy; + + ret = AccessTokenKit::UpdateHapToken(mapID, "updateFailed", policy); + ASSERT_EQ(ret, RET_FAILED); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: SetRemoteHapTokenInfo009 + * @tc.desc: add remote hap token, it can not clear by ClearUserGrantedPermissionState + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo009, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo009 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_USER_SET}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + // Get local map token ID + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_GRANTED); + + ret = AccessTokenKit::ClearUserGrantedPermissionState(mapID); + ASSERT_EQ(ret, RET_SUCCESS); + + ret = AccessTokenKit::VerifyAccessToken(mapID, "ohos.permission.test1"); + ASSERT_EQ(ret, PermissionState::PERMISSION_GRANTED); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: SetRemoteHapTokenInfo010 + * @tc.desc: tokenID is not hap token + * @tc.type: FUNC + * @tc.require:AR000GK6T5 + */ +HWTEST_F(AccessTokenKitTest, SetRemoteHapTokenInfo010, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "SetRemoteHapTokenInfo009 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x28100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_USER_SET}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_NE(ret, RET_SUCCESS); +} + +/** + * @tc.name: DeleteRemoteDeviceToken001 + * @tc.desc: delete exist device mapping tokenId + * @tc.type: FUNC + * @tc.require:AR000GK6TA + */ +HWTEST_F(AccessTokenKitTest, DeleteRemoteDeviceToken001, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "DeleteRemoteDeviceTokens001 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_USER_SET}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + HapTokenInfo info; + ret = AccessTokenKit::GetHapTokenInfo(mapID, info); + ASSERT_EQ(ret, RET_SUCCESS); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_EQ(ret, RET_SUCCESS); + + ret = AccessTokenKit::GetHapTokenInfo(mapID, info); + ASSERT_NE(ret, RET_SUCCESS); +} + +/** + * @tc.name: DeleteRemoteDeviceToken002 + * @tc.desc: delete exist device mapping tokenId + * @tc.type: FUNC + * @tc.require:AR000GK6TA + */ +HWTEST_F(AccessTokenKitTest, DeleteRemoteDeviceToken002, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "DeleteRemoteDeviceTokens001 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_USER_SET}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + HapTokenInfo info; + ret = AccessTokenKit::GetHapTokenInfo(mapID, info); + ASSERT_EQ(ret, RET_SUCCESS); + + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0); + ASSERT_NE(ret, RET_SUCCESS); + + // deviceID is wrong + std::string wrongStr(10241, 'x'); + deviceID = wrongStr; + ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_NE(ret, RET_SUCCESS); +} + +/** + * @tc.name: DeleteRemoteDeviceToken003 + * @tc.desc: delete exist device mapping tokenId + * @tc.type: FUNC + * @tc.require:AR000GK6TA + */ +HWTEST_F(AccessTokenKitTest, DeleteRemoteDeviceToken003, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "DeleteRemoteDeviceToken003 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + + int ret = AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + ASSERT_NE(ret, RET_SUCCESS); +} + +/** + * @tc.name: DeleteRemoteDeviceTokens001 + * @tc.desc: delete all mapping tokens of exist device + * @tc.type: FUNC + * @tc.require:AR000GK6TA + */ +HWTEST_F(AccessTokenKitTest, DeleteRemoteDeviceTokens001, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "DeleteRemoteDeviceTokens001 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100001); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_USER_SET}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + HapTokenInfoForSync remoteTokenInfo1 = remoteTokenInfo; + remoteTokenInfo1.baseInfo.tokenID = 0x20100001; + remoteTokenInfo1.baseInfo.bundleName = "com.ohos.access_token1"; + ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo1); + ASSERT_EQ(ret, RET_SUCCESS); + + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + AccessTokenID mapID1 = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100001); + ASSERT_NE(mapID1, 0); + + ret = AccessTokenKit::DeleteRemoteDeviceTokens(deviceID); + ASSERT_EQ(ret, RET_SUCCESS); + + HapTokenInfo info; + ret = AccessTokenKit::GetHapTokenInfo(mapID, info); + ASSERT_NE(ret, RET_SUCCESS); + ret = AccessTokenKit::GetHapTokenInfo(mapID1, info); + ASSERT_NE(ret, RET_SUCCESS); +} + +/** + * @tc.name: DeleteRemoteDeviceTokens002 + * @tc.desc: delete all mapping tokens of NOT exist device + * @tc.type: FUNC + * @tc.require:AR000GK6TA + */ +HWTEST_F(AccessTokenKitTest, DeleteRemoteDeviceTokens002, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "DeleteRemoteDeviceTokens002 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100001); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_USER_SET}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + HapTokenInfoForSync remoteTokenInfo1 = remoteTokenInfo; + remoteTokenInfo1.baseInfo.tokenID = 0x20100001; + remoteTokenInfo1.baseInfo.bundleName = "com.ohos.access_token1"; + ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo1); + ASSERT_EQ(ret, RET_SUCCESS); + + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + AccessTokenID mapID1 = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100001); + ASSERT_NE(mapID1, 0); + + ret = AccessTokenKit::DeleteRemoteDeviceTokens("1111111"); + ASSERT_NE(ret, RET_SUCCESS); + + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100001); +} + +/** + * @tc.name: GetHapTokenInfoFromRemote001 + * @tc.desc: get normal local tokenInfo + * @tc.type: FUNC + * @tc.require:AR000GK6TA + */ +HWTEST_F(AccessTokenKitTest, GetHapTokenInfoFromRemote001, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "GetHapTokenInfoFromRemote001 start."); + AccessTokenIDEx tokenIdEx = {0}; + tokenIdEx = AccessTokenKit::AllocHapToken(g_infoManagerTestInfoParms, g_infoManagerTestPolicyPrams); + AccessTokenID localTokenID = tokenIdEx.tokenIdExStruct.tokenID; + + HapTokenInfoForSync infoSync; + int ret = AccessTokenKit::GetHapTokenInfoFromRemote(localTokenID, infoSync); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(infoSync.baseInfo.apl, g_infoManagerTestPolicyPrams.apl); + ASSERT_EQ(infoSync.permStateList.size(), 2); + ASSERT_EQ(infoSync.permStateList[1].grantFlags.size(), 2); + + ASSERT_EQ(infoSync.permStateList[0].permissionName, g_infoManagerTestPolicyPrams.permStateList[0].permissionName); + ASSERT_EQ(infoSync.permStateList[0].grantFlags[0], g_infoManagerTestPolicyPrams.permStateList[0].grantFlags[0]); + ASSERT_EQ(infoSync.permStateList[0].grantStatus[0], g_infoManagerTestPolicyPrams.permStateList[0].grantStatus[0]); + ASSERT_EQ(infoSync.permStateList[0].resDeviceID[0], g_infoManagerTestPolicyPrams.permStateList[0].resDeviceID[0]); + ASSERT_EQ(infoSync.permStateList[0].isGeneral, g_infoManagerTestPolicyPrams.permStateList[0].isGeneral); + + ASSERT_EQ(infoSync.permStateList[1].permissionName, g_infoManagerTestPolicyPrams.permStateList[1].permissionName); + ASSERT_EQ(infoSync.permStateList[1].grantFlags[0], g_infoManagerTestPolicyPrams.permStateList[1].grantFlags[0]); + ASSERT_EQ(infoSync.permStateList[1].grantStatus[0], g_infoManagerTestPolicyPrams.permStateList[1].grantStatus[0]); + ASSERT_EQ(infoSync.permStateList[1].resDeviceID[0], g_infoManagerTestPolicyPrams.permStateList[1].resDeviceID[0]); + ASSERT_EQ(infoSync.permStateList[1].isGeneral, g_infoManagerTestPolicyPrams.permStateList[1].isGeneral); + + ASSERT_EQ(infoSync.permStateList[1].grantFlags[1], g_infoManagerTestPolicyPrams.permStateList[1].grantFlags[1]); + ASSERT_EQ(infoSync.permStateList[1].grantStatus[1], g_infoManagerTestPolicyPrams.permStateList[1].grantStatus[1]); + ASSERT_EQ(infoSync.permStateList[1].resDeviceID[1], g_infoManagerTestPolicyPrams.permStateList[1].resDeviceID[1]); + + ASSERT_EQ(infoSync.baseInfo.bundleName, g_infoManagerTestInfoParms.bundleName); + ASSERT_EQ(infoSync.baseInfo.userID, g_infoManagerTestInfoParms.userID); + ASSERT_EQ(infoSync.baseInfo.instIndex, g_infoManagerTestInfoParms.instIndex); + ASSERT_EQ(infoSync.baseInfo.appID, g_infoManagerTestInfoParms.appIDDesc); + ASSERT_EQ(infoSync.baseInfo.ver, 1); + ASSERT_EQ(infoSync.baseInfo.tokenID, localTokenID); + ASSERT_EQ(infoSync.baseInfo.tokenAttr, 0); + + AccessTokenKit::DeleteToken(localTokenID); +} + +/** + * @tc.name: GetHapTokenInfoFromRemote002 + * @tc.desc: get normal mapping tokenInfo + * @tc.type: FUNC + * @tc.require:AR000GK6TA + */ +HWTEST_F(AccessTokenKitTest, GetHapTokenInfoFromRemote002, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "GetHapTokenInfoFromRemote002 start."); + std::string deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2"; + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); + HapTokenInfo baseInfo = { + .apl = APL_NORMAL, + .ver = 1, + .userID = 1, + .bundleName = "com.ohos.access_token", + .instIndex = 1, + .appID = "testtesttesttest", + .deviceID = "ea82205d1f9964346ee12e17ec0f362bb7203fca7c62d82899ffa917f9cbe6b2", + .tokenID = 0x20100000, + .tokenAttr = 0 + }; + + PermissionStateFull infoManagerTestState = { + .grantFlags = {PermissionFlag::PERMISSION_USER_SET}, + .grantStatus = {PermissionState::PERMISSION_GRANTED}, + .isGeneral = true, + .permissionName = "ohos.permission.test1", + .resDeviceID = {"local"}}; + std::vector permStateList; + permStateList.emplace_back(infoManagerTestState); + + HapTokenInfoForSync remoteTokenInfo = { + .baseInfo = baseInfo, + .permStateList =permStateList + }; + + int ret = AccessTokenKit::SetRemoteHapTokenInfo(deviceID, remoteTokenInfo); + ASSERT_EQ(ret, RET_SUCCESS); + + AccessTokenID mapID = AccessTokenKit::AllocLocalTokenID(deviceID, 0x20100000); + ASSERT_NE(mapID, 0); + + HapTokenInfoForSync infoSync; + ret = AccessTokenKit::GetHapTokenInfoFromRemote(mapID, infoSync); + ASSERT_NE(ret, RET_SUCCESS); + + AccessTokenKit::DeleteRemoteToken(deviceID, 0x20100000); +} + +/** + * @tc.name: GetHapTokenInfoFromRemote003 + * @tc.desc: get normal mapping tokenInfo + * @tc.type: FUNC + * @tc.require:AR000GK6TA + */ +HWTEST_F(AccessTokenKitTest, GetHapTokenInfoFromRemote003, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "GetHapTokenInfoFromRemote003 start."); + HapTokenInfoForSync infoSync; + int ret = AccessTokenKit::GetHapTokenInfoFromRemote(0, infoSync); + ASSERT_NE(ret, RET_SUCCESS); +} diff --git a/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.h b/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.h new file mode 100644 index 0000000000000000000000000000000000000000..dfdd20e85dc3a510579e6cfac669ac0912a85a28 --- /dev/null +++ b/interfaces/innerkits/accesstoken/test/unittest/src/accesstoken_kit_test.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 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_KIT_TEST_H +#define ACCESSTOKEN_KIT_TEST_H + +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +static const std::string TEST_BUNDLE_NAME = "ohos"; +static const std::string TEST_PERMISSION_NAME_ALPHA = "ohos.permission.ALPHA"; +static const std::string TEST_PERMISSION_NAME_BETA = "ohos.permission.BETA"; +static const std::string TEST_PERMISSION_NAME_GAMMA = "ohos.permission.GAMMA"; +static const int TEST_USER_ID = 0; +static const int TEST_USER_ID_INVALID = -1; +static const unsigned int TEST_TOKENID_INVALID = 0; +static const int INVALID_BUNDLENAME_LEN = 260; +static const int INVALID_APPIDDESC_LEN = 10244; +static const int INVALID_LABEL_LEN = 260; +static const int INVALID_DESCRIPTION_LEN = 260; +static const int INVALID_PERMNAME_LEN = 260; +static const int CYCLE_TIMES = 100; +static const int THREAD_NUM = 3; +static const int INVALID_DCAP_LEN = 1025; +class AccessTokenKitTest : public testing::Test { +public: + static void SetUpTestCase(); + + static void TearDownTestCase(); + + void SetUp(); + + void TearDown(); + unsigned int GetAccessTokenID(int userID, std::string bundleName, int instIndex); + void DeleteTestToken() const; + void AllocTestToken() const; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_KIT_TEST_H diff --git a/interfaces/innerkits/nativetoken/BUILD.gn b/interfaces/innerkits/nativetoken/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..5a4163d3be70cb500db2d82bf8630d4dc37d2c62 --- /dev/null +++ b/interfaces/innerkits/nativetoken/BUILD.gn @@ -0,0 +1,48 @@ +# Copyright (C) 2021 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. + +import("//build/ohos.gni") + +################################################################ +# C, Main, source file here. +################################################################ +config("accesstokenlib") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +ohos_static_library("libnativetoken") { + subsystem_name = "security" + part_name = "access_token" + output_name = "libnativetoken" + + public_configs = [ ":accesstokenlib" ] + + cflags = [ "-Wall" ] + + include_dirs = [ + "include", + "src", + "//third_party/cJSON", + "//third_party/bounds_checking_function/include", + ] + + sources = [ "src/nativetoken.c" ] + + deps = [ + "//third_party/bounds_checking_function:libsec_static", + "//third_party/cJSON:cjson_static", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] +} diff --git a/interfaces/innerkits/nativetoken/include/nativetoken.h b/interfaces/innerkits/nativetoken/include/nativetoken.h new file mode 100644 index 0000000000000000000000000000000000000000..71c34e2c263d141b367f75750f31d7b4fe3cf74d --- /dev/null +++ b/interfaces/innerkits/nativetoken/include/nativetoken.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 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 ACCESSTOKENs and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "cJSON.h" +#include "securec.h" +#include "nativetoken_log.h" + +#ifndef NATIVE_TOKEN_H +#define NATIVE_TOKEN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_PROCESS_NAME_LEN 256 +#define TOKEN_ID_CFG_FILE_PATH "/data/service/el0/access_token/nativetoken.json" +#define TOKEN_ID_CFG_DIR_PATH "/data/service/el0/access_token" +#define TOKEN_NATIVE_TYPE 1 +#define DEFAULT_AT_VERSION 1 +#define TRANSFER_KEY_WORDS "NativeTokenInfo" +#define MAX_JSON_FILE_LEN 102400 +#define MAX_DCAPS_NUM 32 +#define MAX_DCAP_LEN 1024 +#define MAX_PARAMTER_LEN 128 +#define SYSTEM_PROP_NATIVE_RECEPTOR "rw.nativetoken.receptor.startup" +#define PATH_MAX_LEN 4096 + +#define ATRET_FAILED 1 +#define ATRET_SUCCESS 0 + +#define DCAPS_KEY_NAME "dcaps" +#define TOKENID_KEY_NAME "tokenId" +#define TOKEN_ATTR_KEY_NAME "tokenAttr" +#define APL_KEY_NAME "APL" +#define VERSION_KEY_NAME "version" +#define PROCESS_KEY_NAME "processName" + +#define SYSTEM_CORE 3 +#define SYSTEM_BASIC 2 +#define NORMAL 1 + +typedef unsigned int NativeAtId; +typedef unsigned int NativeAtAttr; + +typedef struct { + unsigned int tokenUniqueId : 24; + unsigned int reserved : 3; + unsigned int type : 2; + unsigned int version : 3; +} AtInnerInfo; + +typedef struct { + NativeAtId tokenId; + NativeAtAttr tokenAttr; +} NativeAtIdEx; + +typedef struct TokenList { + NativeAtId tokenId; + int32_t apl; + char *dcaps[MAX_DCAPS_NUM]; + int dcapsNum; + char processName[MAX_PROCESS_NAME_LEN + 1]; + struct TokenList *next; +} NativeTokenList; + +extern int32_t GetFileBuff(const char *cfg, char **retBuff); +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_TOKEN_H \ No newline at end of file diff --git a/interfaces/innerkits/nativetoken/include/nativetoken_kit.h b/interfaces/innerkits/nativetoken/include/nativetoken_kit.h new file mode 100644 index 0000000000000000000000000000000000000000..564dcb76fd6b5d07054417d374895fe459fc877e --- /dev/null +++ b/interfaces/innerkits/nativetoken/include/nativetoken_kit.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 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_NATIVE_TOKEN_H +#define INTERFACES_INNER_KITS_NATIVE_TOKEN_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint64_t GetAccessTokenId(const char *processname, const char **dcap, int32_t dacpNum, const char *aplStr); + +#ifdef __cplusplus +} +#endif + +#endif // INTERFACES_INNER_KITS_NATIVE_TOKEN_H diff --git a/interfaces/innerkits/nativetoken/include/nativetoken_log.h b/interfaces/innerkits/nativetoken/include/nativetoken_log.h new file mode 100644 index 0000000000000000000000000000000000000000..a0338d25e7ee0b78321a60a69805dfbb1331d6ac --- /dev/null +++ b/interfaces/innerkits/nativetoken/include/nativetoken_log.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 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 ACCESSTOKENs and + * limitations under the License. + */ + +#ifndef ACCESSTOKEN_LOG_H +#define ACCESSTOKEN_LOG_H + +#ifdef HILOG_ENABLE + +#include "hilog/log.h" + +#define ACCESSTOKEN_LOG_DEBUG(fmt, ...) HILOG_DEBUG(LOG_CORE, fmt, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_INFO(fmt, ...) HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_WARN(fmt, ...) HILOG_WARN(LOG_CORE, fmt, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_ERROR(fmt, ...) ACCESSTOKEN_LOG_ERROR(LOG_CORE, fmt, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_FATAL(fmt, ...) HILOG_FATAL(LOG_CORE, fmt, ##__VA_ARGS__) + +/* define LOG_TAG as "security_*" at your submodule, * means your submodule name such as "security_dac" */ +#undef LOG_TAG +#undef LOG_DOMAIN + +#else + +#include +#include + +/* define LOG_TAG as "security_*" at your submodule, * means your submodule name such as "security_dac" */ +#define LOG_TAG "accssToken_" + +#define ACCESSTOKEN_LOG_DEBUG(fmt, ...) printf("[%s] debug: " fmt "\n", LOG_TAG, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_INFO(fmt, ...) printf("[%s] info: " fmt "\n", LOG_TAG, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_WARN(fmt, ...) printf("[%s] warn: " fmt "\n", LOG_TAG, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_ERROR(fmt, ...) printf("[%s] error: " fmt "\n", LOG_TAG, ##__VA_ARGS__) +#define ACCESSTOKEN_LOG_FATAL(fmt, ...) printf("[%s] fatal: " fmt "\n", LOG_TAG, ##__VA_ARGS__) + +#endif // HILOG_ENABLE + +#endif // ACCESSTOKEN_LOG_H diff --git a/interfaces/innerkits/nativetoken/src/nativetoken.c b/interfaces/innerkits/nativetoken/src/nativetoken.c new file mode 100644 index 0000000000000000000000000000000000000000..f39d36eefd2275572dcf8810b6e97002c4d9561d --- /dev/null +++ b/interfaces/innerkits/nativetoken/src/nativetoken.c @@ -0,0 +1,735 @@ +/* + * Copyright (c) 2021 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 ACCESSTOKENs and + * limitations under the License. + */ +#include "nativetoken.h" +#include "nativetoken_kit.h" + +NativeTokenList *g_tokenListHead; +int32_t g_isNativeTokenInited = 0; + +int32_t GetFileBuff(const char *cfg, char **retBuff) +{ + struct stat fileStat; + int32_t ret; + + char filePath[PATH_MAX_LEN + 1] = {0}; + if (realpath(cfg, filePath) == NULL) { + if (errno == ENOENT) { + /* file doesn't exist */ + *retBuff = NULL; + return ATRET_SUCCESS; + } + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:invalid filePath.", __func__); + return ATRET_FAILED; + } + + if (stat(filePath, &fileStat) != 0) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:stat file failed.", __func__); + return ATRET_FAILED; + } + + int32_t fileSize = (int32_t)fileStat.st_size; + if ((fileSize < 0) || (fileSize > MAX_JSON_FILE_LEN)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:stat file size is invalid.", __func__); + return ATRET_FAILED; + } + + FILE *cfgFd = fopen(filePath, "r"); + if (cfgFd == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:fopen file failed.", __func__); + return ATRET_FAILED; + } + + char *buff = (char *)malloc((size_t)(fileSize + 1)); + if (buff == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:memory alloc failed.", __func__); + fclose(cfgFd); + return ATRET_FAILED; + } + + if (fread(buff, (size_t)fileSize, 1, cfgFd) != 1) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:fread failed.", __func__); + free(buff); + buff = NULL; + ret = ATRET_FAILED; + } else { + buff[fileSize] = '\0'; + *retBuff = buff; + ret = ATRET_SUCCESS; + } + + fclose(cfgFd); + return ret; +} + +void FreeDcaps(char *dcaps[MAX_DCAPS_NUM], int32_t num) +{ + for (int32_t i = 0; i <= num; i++) { + if (dcaps[i] != NULL) { + free(dcaps[i]); + dcaps[i] = NULL; + } + } +} + +int32_t GetprocessNameFromJson(cJSON *cjsonItem, NativeTokenList *tokenNode) +{ + cJSON *processNameJson = cJSON_GetObjectItem(cjsonItem, PROCESS_KEY_NAME); + if (cJSON_IsString(processNameJson) == 0 || (strlen(processNameJson->valuestring) > MAX_PROCESS_NAME_LEN)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:processNameJson is invalid.", __func__); + return ATRET_FAILED; + } + + if (strcpy_s(tokenNode->processName, MAX_PROCESS_NAME_LEN + 1, processNameJson->valuestring) != EOK) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:strcpy_s failed.", __func__); + return ATRET_FAILED; + } + return ATRET_SUCCESS; +} + +int32_t GetTokenIdFromJson(cJSON *cjsonItem, NativeTokenList *tokenNode) +{ + cJSON *tokenIdJson = cJSON_GetObjectItem(cjsonItem, TOKENID_KEY_NAME); + if ((cJSON_IsNumber(tokenIdJson) == 0) || (cJSON_GetNumberValue(tokenIdJson) <= 0)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:tokenIdJson is invalid.", __func__); + return ATRET_FAILED; + } + tokenNode->tokenId = (NativeAtId)tokenIdJson->valueint; + return ATRET_SUCCESS; +} + +int32_t GetAplFromJson(cJSON *cjsonItem, NativeTokenList *tokenNode) +{ + cJSON *aplJson = cJSON_GetObjectItem(cjsonItem, APL_KEY_NAME); + if (cJSON_IsNumber(aplJson) == 0) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:aplJson is invalid.", __func__); + return ATRET_FAILED; + } + int apl = cJSON_GetNumberValue(aplJson); + if (apl <= 0 || apl > SYSTEM_CORE) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:apl = %d in file is invalid.", __func__, apl); + return ATRET_FAILED; + } + tokenNode->apl = aplJson->valueint; + return ATRET_SUCCESS; +} + +int32_t GetDcapsInfoFromJson(cJSON *cjsonItem, NativeTokenList *tokenNode) +{ + cJSON *dcapsJson = cJSON_GetObjectItem(cjsonItem, DCAPS_KEY_NAME); + int32_t dcapSize = cJSON_GetArraySize(dcapsJson); + + tokenNode->dcapsNum = dcapSize; + for (int32_t i = 0; i < dcapSize; i++) { + cJSON *dcapItem = cJSON_GetArrayItem(dcapsJson, i); + if (dcapItem == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:cJSON_GetArrayItem failed.", __func__); + return ATRET_FAILED; + } + size_t length = strlen(dcapItem->valuestring); + if (cJSON_IsString(dcapItem) == 0 || (length > MAX_DCAP_LEN)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:dcapItem is invalid.", __func__); + return ATRET_FAILED; + } + tokenNode->dcaps[i] = (char *)malloc(sizeof(char) * length); + if (tokenNode->dcaps[i] == NULL) { + FreeDcaps(tokenNode->dcaps, i - 1); + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:malloc invalid.", __func__); + return ATRET_FAILED; + } + if (strcpy_s(tokenNode->dcaps[i], length + 1, dcapItem->valuestring) != EOK) { + FreeDcaps(tokenNode->dcaps, i); + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:strcpy_s failed.", __func__); + return ATRET_FAILED; + } + } + return ATRET_SUCCESS; +} + +int32_t GetTokenList(const cJSON *object) +{ + int32_t arraySize; + int32_t i; + int ret; + NativeTokenList *tmp = NULL; + + if (object == NULL) { + return ATRET_FAILED; + } + arraySize = cJSON_GetArraySize(object); + for (i = 0; i < arraySize; i++) { + tmp = (NativeTokenList *)malloc(sizeof(NativeTokenList)); + if (tmp == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:memory alloc failed.", __func__); + return ATRET_FAILED; + } + cJSON *cjsonItem = cJSON_GetArrayItem(object, i); + if (cjsonItem == NULL) { + free(tmp); + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:cJSON_GetArrayItem failed.", __func__); + return ATRET_FAILED; + } + ret = GetprocessNameFromJson(cjsonItem, tmp); + ret |= GetTokenIdFromJson(cjsonItem, tmp); + ret |= GetAplFromJson(cjsonItem, tmp); + ret |= GetDcapsInfoFromJson(cjsonItem, tmp); + if (ret != ATRET_SUCCESS) { + free(tmp); + return ret; + } + + tmp->next = g_tokenListHead->next; + g_tokenListHead->next = tmp; + } + return ATRET_SUCCESS; +} + +int32_t ParseTokenInfoFromCfg(const char *filename) +{ + char *fileBuff = NULL; + cJSON *record = NULL; + int32_t ret; + + if (filename == NULL || filename[0] == '\0') { + return ATRET_FAILED; + } + ret = GetFileBuff(filename, &fileBuff); + if (ret != ATRET_SUCCESS) { + return ret; + } + if (fileBuff == NULL) { + return ATRET_SUCCESS; + } + record = cJSON_Parse(fileBuff); + free(fileBuff); + fileBuff = NULL; + + ret = GetTokenList(record); + cJSON_Delete(record); + + return ret; +} + +int32_t AtlibInit(void) +{ + g_tokenListHead = (NativeTokenList *)malloc(sizeof(NativeTokenList)); + if (g_tokenListHead == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:g_tokenListHead memory alloc failed.", __func__); + return ATRET_FAILED; + } + g_tokenListHead->next = NULL; + + int32_t ret = ParseTokenInfoFromCfg(TOKEN_ID_CFG_FILE_PATH); + if (ret != ATRET_SUCCESS) { + free(g_tokenListHead); + g_tokenListHead = NULL; + return ret; + } + g_isNativeTokenInited = 1; + + return ATRET_SUCCESS; +} + +int GetRandomTokenId(uint32_t *randNum) +{ + uint32_t random; + int len; + int fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + return ATRET_FAILED; + } + len = read(fd, &random, sizeof(random)); + (void)close(fd); + if (len != sizeof(random)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:read failed.", __func__); + return ATRET_FAILED; + } + *randNum = random; + return ATRET_SUCCESS; +} + +NativeAtId CreateNativeTokenId(void) +{ + uint32_t rand; + NativeAtId tokenId; + AtInnerInfo *innerId = (AtInnerInfo *)(&tokenId); + + int ret = GetRandomTokenId(&rand); + if (ret != ATRET_SUCCESS) { + return 0; + } + + innerId->reserved = 0; + innerId->tokenUniqueId = rand & (0xFFFFFF); + innerId->type = TOKEN_NATIVE_TYPE; + innerId->version = 1; + return tokenId; +} + +int32_t GetAplLevel(const char *aplStr) +{ + if (aplStr == NULL) { + return 0; + } + if (strcmp(aplStr, "system_core") == 0) { + return SYSTEM_CORE; // system_core means apl level is 3 + } + if (strcmp(aplStr, "system_basic") == 0) { + return SYSTEM_BASIC; // system_basic means apl level is 2 + } + if (strcmp(aplStr, "normal") == 0) { + return NORMAL; + } + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:aplStr is invalid.", __func__); + return 0; +} +int32_t NeedSetUidGid(int16_t *uid, int16_t *gid, int *needSet) +{ + struct stat buf; + if (stat(TOKEN_ID_CFG_FILE_PATH, &buf) == 0) { + *needSet = 0; + return ATRET_SUCCESS; + } + if (errno != ENOENT) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:stat %s is invalid %d.", + __func__, TOKEN_ID_CFG_FILE_PATH, errno); + return ATRET_FAILED; + } + if (stat(TOKEN_ID_CFG_DIR_PATH, &buf) != 0) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:stat %s is invalid %d.", + __func__, TOKEN_ID_CFG_DIR_PATH, errno); + return ATRET_FAILED; + } + *uid = buf.st_uid; + *gid = buf.st_gid; + *needSet = 1; + ACCESSTOKEN_LOG_INFO("[ATLIB-%s]:needSet is true.", __func__); + return ATRET_SUCCESS; +} + +void WriteToFile(const cJSON *root) +{ + int32_t strLen; + int32_t writtenLen; + + char *jsonStr = NULL; + jsonStr = cJSON_PrintUnformatted(root); + if (jsonStr == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:cJSON_PrintUnformatted failed.", __func__); + return; + } + + do { + int16_t uid; + int16_t gid; + int needSet = 0; + if (NeedSetUidGid(&uid, &gid, &needSet) != ATRET_SUCCESS) { + break; + } + int32_t fd = open(TOKEN_ID_CFG_FILE_PATH, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP); + if (fd < 0) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:open failed.", __func__); + break; + } + strLen = strlen(jsonStr); + writtenLen = write(fd, (void *)jsonStr, (size_t)strLen); + close(fd); + if (writtenLen != strLen) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:write failed, writtenLen is %d.", __func__, writtenLen); + break; + } + if ((needSet == 1) && chown(TOKEN_ID_CFG_FILE_PATH, uid, gid) != 0) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:chown failed, errno is %d.", __func__, errno); + break; + } + } while (0); + + cJSON_free(jsonStr); + return; +} + +int32_t AddDcapsArray(cJSON *object, const NativeTokenList *curr) +{ + cJSON *dcapsArr = cJSON_CreateArray(); + if (dcapsArr == NULL) { + return ATRET_FAILED; + } + for (int32_t i = 0; i < curr->dcapsNum; i++) { + cJSON *item = cJSON_CreateString(curr->dcaps[i]); + if (item == NULL || !cJSON_AddItemToArray(dcapsArr, item)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:tokenAttr cJSON_AddItemToArray failed.", __func__); + cJSON_Delete(item); + cJSON_Delete(dcapsArr); + return ATRET_FAILED; + } + } + if (!cJSON_AddItemToObject(object, DCAPS_KEY_NAME, dcapsArr)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:dcaps cJSON_AddItemToObject failed.", __func__); + cJSON_Delete(dcapsArr); + return ATRET_FAILED; + } + return ATRET_SUCCESS; +} + +static cJSON *CreateNativeTokenJsonObject(const NativeTokenList *curr) +{ + cJSON *object = cJSON_CreateObject(); + if (object == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:cJSON_CreateObject failed.", __func__); + return NULL; + } + + cJSON *item = cJSON_CreateString(curr->processName); + if (item == NULL || !cJSON_AddItemToObject(object, PROCESS_KEY_NAME, item)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:processName cJSON_AddItemToObject failed.", __func__); + cJSON_Delete(item); + cJSON_Delete(object); + return NULL; + } + + item = cJSON_CreateNumber(curr->apl); + if (item == NULL || !cJSON_AddItemToObject(object, APL_KEY_NAME, item)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:APL cJSON_AddItemToObject failed.", __func__); + cJSON_Delete(item); + cJSON_Delete(object); + return NULL; + } + + item = cJSON_CreateNumber(DEFAULT_AT_VERSION); + if (item == NULL || !cJSON_AddItemToObject(object, VERSION_KEY_NAME, item)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:version cJSON_AddItemToObject failed.", __func__); + cJSON_Delete(item); + cJSON_Delete(object); + return NULL; + } + + item = cJSON_CreateNumber(curr->tokenId); + if (item == NULL || !cJSON_AddItemToObject(object, TOKENID_KEY_NAME, item)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:tokenId cJSON_AddItemToObject failed.", __func__); + cJSON_Delete(item); + cJSON_Delete(object); + return NULL; + } + + item = cJSON_CreateNumber(0); + if (item == NULL || !cJSON_AddItemToObject(object, TOKEN_ATTR_KEY_NAME, item)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:tokenAttr cJSON_AddItemToObject failed.", __func__); + cJSON_Delete(item); + cJSON_Delete(object); + return NULL; + } + int ret = AddDcapsArray(object, curr); + if (ret != ATRET_SUCCESS) { + cJSON_Delete(object); + } + return object; +} + +void SaveTokenIdToCfg(const NativeTokenList *curr) +{ + char *fileBuff = NULL; + cJSON *record = NULL; + int32_t ret; + + ret = GetFileBuff(TOKEN_ID_CFG_FILE_PATH, &fileBuff); + if (ret != ATRET_SUCCESS) { + return; + } + + if (fileBuff == NULL) { + record = cJSON_CreateArray(); + } else { + record = cJSON_Parse(fileBuff); + free(fileBuff); + fileBuff = NULL; + } + + if (record == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:get record failed.", __func__); + return; + } + + cJSON *node = CreateNativeTokenJsonObject(curr); + if (node == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:CreateNativeTokenJsonObject failed.", __func__); + cJSON_Delete(record); + return; + } + cJSON_AddItemToArray(record, node); + + WriteToFile(record); + cJSON_Delete(record); + return; +} + +int32_t CheckProcessInfo(const char *processname, const char **dcaps, + int32_t dacpNum, const char *aplStr, int32_t *aplRet) +{ + if ((processname == NULL) || strlen(processname) > MAX_PROCESS_NAME_LEN + || strlen(processname) == 0) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:processname is invalid.", __func__); + return ATRET_FAILED; + } + + if (((dcaps == NULL) && (dacpNum != 0)) || dacpNum > MAX_DCAPS_NUM || dacpNum < 0) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:dcaps is null or dacpNum is invalid.", __func__); + return ATRET_FAILED; + } + for (int32_t i = 0; i < dacpNum; i++) { + if (strlen(dcaps[i]) > MAX_DCAP_LEN) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:dcap length is invalid.", __func__); + return ATRET_FAILED; + } + } + + int32_t apl = GetAplLevel(aplStr); + if (apl == 0) { + return ATRET_FAILED; + } + *aplRet = apl; + return ATRET_SUCCESS; +} + +int32_t NativeTokenIdCheck(NativeAtId tokenId) +{ + NativeTokenList *tokenNode = g_tokenListHead; + while (tokenNode != NULL) { + if (tokenNode->tokenId == tokenId) { + return 1; + } + tokenNode = tokenNode->next; + } + return 0; +} + +static int32_t AddNewTokenToListAndCfgFile(const char *processname, const char **dcapsIn, + int32_t dacpNumIn, int32_t aplIn, NativeAtId *tokenId) +{ + NativeTokenList *tokenNode; + NativeAtId id; + int32_t repeat; + + do { + id = CreateNativeTokenId(); + repeat = NativeTokenIdCheck(id); + } while (repeat == 1); + + tokenNode = (NativeTokenList *)malloc(sizeof(NativeTokenList)); + if (tokenNode == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:memory alloc failed.", __func__); + return ATRET_FAILED; + } + tokenNode->tokenId = id; + tokenNode->apl = aplIn; + if (strcpy_s(tokenNode->processName, MAX_PROCESS_NAME_LEN + 1, processname) != EOK) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:strcpy_s failed.", __func__); + free(tokenNode); + return ATRET_FAILED; + } + tokenNode->dcapsNum = dacpNumIn; + + for (int32_t i = 0; i < dacpNumIn; i++) { + tokenNode->dcaps[i] = (char *)malloc(sizeof(char) * (strlen(dcapsIn[i]) + 1)); + if (tokenNode->dcaps[i] != NULL && + (strcpy_s(tokenNode->dcaps[i], strlen(dcapsIn[i]) + 1, dcapsIn[i]) != EOK)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:copy dcapsIn[%d] failed.", __func__, i); + FreeDcaps(tokenNode->dcaps, i); + free(tokenNode); + return ATRET_FAILED; + } + } + tokenNode->next = g_tokenListHead->next; + g_tokenListHead->next = tokenNode; + + *tokenId = id; + + SaveTokenIdToCfg(tokenNode); + return ATRET_SUCCESS; +} + +int32_t CompareProcessInfo(NativeTokenList *tokenNode, const char **dcapsIn, int32_t dacpNumIn, int32_t aplIn) +{ + if (tokenNode->apl != aplIn) { + return 1; + } + if (tokenNode->dcapsNum != dacpNumIn) { + return 1; + } + for (int32_t i = 0; i < dacpNumIn; i++) { + if (strcmp(tokenNode->dcaps[i], dcapsIn[i]) != 0) { + return 1; + } + } + return 0; +} + +int32_t UpdateTokenInfoInList(NativeTokenList *tokenNode, const char **dcapsIn, int32_t dacpNumIn, int32_t aplIn) +{ + tokenNode->apl = aplIn; + + for (int32_t i = 0; i < tokenNode->dcapsNum; i++) { + free(tokenNode->dcaps[i]); + tokenNode->dcaps[i] = NULL; + } + + tokenNode->dcapsNum = dacpNumIn; + for (int32_t i = 0; i < dacpNumIn; i++) { + int32_t len = strlen(dcapsIn[i]) + 1; + tokenNode->dcaps[i] = (char *)malloc(sizeof(char) * len); + if (tokenNode->dcaps[i] != NULL && (strcpy_s(tokenNode->dcaps[i], len, dcapsIn[i]) != EOK)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:copy dcapsIn[%d] failed.", __func__, i); + FreeDcaps(tokenNode->dcaps, i); + return ATRET_FAILED; + } + } + return ATRET_SUCCESS; +} + +int32_t UpdateItemcontent(const NativeTokenList *tokenNode, cJSON *record) +{ + cJSON *itemApl = cJSON_CreateNumber(tokenNode->apl); + if (itemApl == NULL) { + return ATRET_FAILED; + } + if (!cJSON_ReplaceItemInObject(record, APL_KEY_NAME, itemApl)) { + cJSON_Delete(itemApl); + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:APL update failed.", __func__); + return ATRET_FAILED; + } + + cJSON *dcapsArr = cJSON_CreateArray(); + if (dcapsArr == NULL) { + return ATRET_FAILED; + } + for (int32_t i = 0; i < tokenNode->dcapsNum; i++) { + cJSON *item = cJSON_CreateString(tokenNode->dcaps[i]); + if (item == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:cJSON_CreateString failed.", __func__); + cJSON_Delete(dcapsArr); + return ATRET_FAILED; + } + if (!cJSON_AddItemToArray(dcapsArr, item)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:cJSON_AddItemToArray failed.", __func__); + cJSON_Delete(item); + return ATRET_FAILED; + } + } + if (!cJSON_ReplaceItemInObject(record, DCAPS_KEY_NAME, dcapsArr)) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:dcaps update failed.", __func__); + cJSON_Delete(dcapsArr); + return ATRET_FAILED; + } + return ATRET_SUCCESS; +} + +int32_t UpdateGoalItemFromRecord(const NativeTokenList *tokenNode, cJSON *record) +{ + int32_t arraySize = cJSON_GetArraySize(record); + for (int32_t i = 0; i < arraySize; i++) { + cJSON *cjsonItem = cJSON_GetArrayItem(record, i); + if (cjsonItem == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:cJSON_GetArrayItem failed.", __func__); + return ATRET_FAILED; + } + cJSON *processNameJson = cJSON_GetObjectItem(cjsonItem, PROCESS_KEY_NAME); + if (processNameJson == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:processNameJson is null.", __func__); + return ATRET_FAILED; + } + if (strcmp(processNameJson->valuestring, tokenNode->processName) == 0) { + return UpdateItemcontent(tokenNode, cjsonItem); + } + } + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:cannot find process in config file.", __func__); + return ATRET_FAILED; +} + +int32_t UpdateTokenInfoInCfgFile(NativeTokenList *tokenNode) +{ + cJSON *record = NULL; + char *fileBuff = NULL; + + int32_t ret = GetFileBuff(TOKEN_ID_CFG_FILE_PATH, &fileBuff); + if (ret != ATRET_SUCCESS) { + return ret; + } + + if (fileBuff == NULL) { + record = cJSON_CreateArray(); + } else { + record = cJSON_Parse(fileBuff); + free(fileBuff); + fileBuff = NULL; + } + + if (record == NULL) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:get record failed.", __func__); + return ATRET_FAILED; + } + + ret = UpdateGoalItemFromRecord(tokenNode, record); + if (ret != ATRET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR("[ATLIB-%s]:UpdateGoalItemFromRecord failed.", __func__); + cJSON_Delete(record); + return ATRET_FAILED; + } + + WriteToFile(record); + cJSON_Delete(record); + return ATRET_SUCCESS; +} + +uint64_t GetAccessTokenId(const char *processname, const char **dcaps, int32_t dacpNum, const char *aplStr) +{ + NativeAtId tokenId = 0; + uint64_t result = 0; + int32_t apl; + NativeAtIdEx *atPoint = (NativeAtIdEx *)(&result); + + if ((g_isNativeTokenInited == 0) && (AtlibInit() != ATRET_SUCCESS)) { + return 0; + } + + int32_t ret = CheckProcessInfo(processname, dcaps, dacpNum, aplStr, &apl); + if (ret != ATRET_SUCCESS) { + return 0; + } + + NativeTokenList *tokenNode = g_tokenListHead; + while (tokenNode != NULL) { + if (strcmp(tokenNode->processName, processname) == 0) { + tokenId = tokenNode->tokenId; + break; + } + tokenNode = tokenNode->next; + } + + if (tokenNode == NULL) { + ret = AddNewTokenToListAndCfgFile(processname, dcaps, dacpNum, apl, &tokenId); + } else { + int32_t needUpdate = CompareProcessInfo(tokenNode, dcaps, dacpNum, apl); + if (needUpdate != 0) { + ret = UpdateTokenInfoInList(tokenNode, dcaps, dacpNum, apl); + ret |= UpdateTokenInfoInCfgFile(tokenNode); + } + } + if (ret != ATRET_SUCCESS) { + return 0; + } + + atPoint->tokenId = tokenId; + atPoint->tokenAttr = 0; + return result; +} \ No newline at end of file diff --git a/interfaces/innerkits/nativetoken/test/BUILD.gn b/interfaces/innerkits/nativetoken/test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..6b14f56e06e729f142c5a50743ff54bd3571bd2a --- /dev/null +++ b/interfaces/innerkits/nativetoken/test/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (C) 2021 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. + +import("//build/test.gni") + +ohos_unittest("libnativetoken_test") { + subsystem_name = "security" + part_name = "access_token" + module_out_path = part_name + "/" + part_name + + include_dirs = [ + "//third_party/cJSON", + "//third_party/bounds_checking_function/include", + "//base/security/access_token/interfaces/innerkits/nativetoken/include", + ] + + sources = [ "unittest/src/nativetoken_kit_test.cpp" ] + + deps = [ + "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", + "//third_party/bounds_checking_function:libsec_static", + "//third_party/cJSON:cjson_static", + "//third_party/googletest:gmock", + "//third_party/googletest:gtest", + ] +} + +group("unittest") { + testonly = true + deps = [ ":libnativetoken_test" ] +} diff --git a/interfaces/innerkits/nativetoken/test/unittest/src/nativetoken_kit_test.cpp b/interfaces/innerkits/nativetoken/test/unittest/src/nativetoken_kit_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..74b986ccf4f3a00b781086cc0f6603b2d91bbc14 --- /dev/null +++ b/interfaces/innerkits/nativetoken/test/unittest/src/nativetoken_kit_test.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2021 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 "nativetoken_kit_test.h" +#include +#include "nativetoken.h" +#include "nativetoken_kit.h" + +using namespace testing::ext; +using namespace OHOS::Security; + +extern NativeTokenList *g_tokenListHead; +extern int32_t g_isNativeTokenInited; +extern int32_t GetFileBuff(const char *cfg, char **retBuff); + +void TokenLibKitTest::SetUpTestCase() +{} + +void TokenLibKitTest::TearDownTestCase() +{} + +void TokenLibKitTest::SetUp() +{ + g_isNativeTokenInited = 0; +} + +void TokenLibKitTest::TearDown() +{ + while (g_tokenListHead->next != nullptr) { + NativeTokenList *tmp = g_tokenListHead->next; + g_tokenListHead->next = tmp->next; + free(tmp); + tmp = nullptr; + } +} + +int Start(const char *processName) +{ + const char *processname = processName; + const char **dcaps = (const char **)malloc(sizeof(char *) * 2); + dcaps[0] = "AT_CAP"; + dcaps[1] = "ST_CAP"; + int dcapNum = 2; + uint64_t tokenId; + tokenId = GetAccessTokenId(processname, dcaps, dcapNum, "system_core"); + free(dcaps); + return tokenId; +} + +/** + * @tc.name: GetAccessTokenId001 + * @tc.desc: cannot getAccessTokenId with invalid processName. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(TokenLibKitTest, GetAccessTokenId001, TestSize.Level1) +{ + const char **dcaps = (const char **)malloc(sizeof(char *) * 2); + dcaps[0] = "AT_CAP"; + dcaps[1] = "ST_CAP"; + int dcapNum = 2; + uint64_t tokenId; + tokenId = GetAccessTokenId("", dcaps, dcapNum, "system_core"); + ASSERT_EQ(tokenId, 0); + tokenId = GetAccessTokenId(nullptr, dcaps, dcapNum, "system_core"); + ASSERT_EQ(tokenId, 0); + + /* 257 is invalid processName length */ + const std::string invalidProcName (257, 'x'); + tokenId = GetAccessTokenId(invalidProcName.c_str(), dcaps, dcapNum, "system_core"); + ASSERT_EQ(tokenId, 0); + + /* 255 is valid processName length */ + const std::string validProcName01 (255, 'x'); + tokenId = GetAccessTokenId(validProcName01.c_str(), dcaps, dcapNum, "system_core"); + ASSERT_NE(tokenId, 0); + + /* 256 is valid processName length */ + const std::string validProcName02 (256, 'x'); + tokenId = GetAccessTokenId(validProcName02.c_str(), dcaps, dcapNum, "system_core"); + ASSERT_NE(tokenId, 0); + free(dcaps); +} + +/** + * @tc.name: GetAccessTokenId002 + * @tc.desc: cannot getAccessTokenId with invalid dcapNum. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(TokenLibKitTest, GetAccessTokenId002, TestSize.Level1) +{ + const char **dcaps = (const char **)malloc(sizeof(char *) * 32); + dcaps[0] = "AT_CAP"; + dcaps[1] = "ST_CAP"; + int dcapNum = -1; + uint64_t tokenId; + tokenId = GetAccessTokenId("GetAccessTokenId002", dcaps, dcapNum, "system_core"); + ASSERT_EQ(tokenId, 0); + + /* 33 is invalid dcapNum */ + dcapNum = 33; + tokenId = GetAccessTokenId("GetAccessTokenId002_00", dcaps, dcapNum, "system_core"); + ASSERT_EQ(tokenId, 0); + + for (int32_t i = 0; i < 32; i++) { + dcaps[i] = "AT_CAP"; + } + /* 32 is valid dcapNum */ + dcapNum = 32; + tokenId = GetAccessTokenId("GetAccessTokenId002_01", dcaps, dcapNum, "system_core"); + ASSERT_NE(tokenId, 0); + + /* 31 is valid dcapNum */ + dcapNum = 31; + tokenId = GetAccessTokenId("GetAccessTokenId002_02", dcaps, dcapNum, "system_core"); + ASSERT_NE(tokenId, 0); + + free(dcaps); +} + +/** + * @tc.name: GetAccessTokenId003 + * @tc.desc: cannot getAccessTokenId with invalid dcaps. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(TokenLibKitTest, GetAccessTokenId003, TestSize.Level1) +{ + const char **dcaps = (const char **)malloc(sizeof(char *) * 2); + dcaps[0] = "AT_CAP"; + dcaps[1] = "ST_CAP"; + int dcapNum = 2; + uint64_t tokenId; + tokenId = GetAccessTokenId("GetAccessTokenId003", nullptr, dcapNum, "system_core"); + ASSERT_EQ(tokenId, 0); + + dcapNum = 0; + tokenId = GetAccessTokenId("GetAccessTokenId003_01", nullptr, dcapNum, "system_core"); + ASSERT_NE(tokenId, 0); + + dcapNum = 2; + /* 1025 is invalid dcap length */ + const std::string invalidDcap (1025, 'x'); + dcaps[0] = invalidDcap.c_str(); + tokenId = GetAccessTokenId("GetAccessTokenId003_02", dcaps, dcapNum, "system_core"); + ASSERT_EQ(tokenId, 0); + + /* 1024 is valid dcap length */ + const std::string validDcap01 (1024, 'x'); + dcaps[0] = validDcap01.c_str(); + tokenId = GetAccessTokenId("GetAccessTokenId003_03", dcaps, dcapNum, "system_core"); + ASSERT_NE(tokenId, 0); + + /* 1023 is valid dcap length */ + const std::string validDcap02 (1023, 'x'); + dcaps[0] = validDcap02.c_str(); + tokenId = GetAccessTokenId("GetAccessTokenId003_04", dcaps, dcapNum, "system_core"); + ASSERT_NE(tokenId, 0); + + free(dcaps); +} + +/** + * @tc.name: GetAccessTokenId004 + * @tc.desc: cannot getAccessTokenId with invalid APL. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(TokenLibKitTest, GetAccessTokenId004, TestSize.Level1) +{ + const char **dcaps = (const char **)malloc(sizeof(char *) * 2); + dcaps[0] = "AT_CAP"; + dcaps[1] = "ST_CAP"; + int dcapNum = 2; + uint64_t tokenId; + tokenId = GetAccessTokenId("GetAccessTokenId003", dcaps, dcapNum, nullptr); + ASSERT_EQ(tokenId, 0); + + tokenId = GetAccessTokenId("GetAccessTokenId003", dcaps, dcapNum, "system_invalid"); + ASSERT_EQ(tokenId, 0); + + free(dcaps); +} + +/** + * @tc.name: GetAccessTokenId005 + * @tc.desc: Get AccessTokenId successfully. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(TokenLibKitTest, GetAccessTokenId005, TestSize.Level1) +{ + uint64_t tokenId01 = Start("GetAccessTokenId005"); + ASSERT_NE(tokenId01, 0); + uint64_t tokenId02 = Start("GetAccessTokenId005"); + ASSERT_NE(tokenId02, 0); + + ASSERT_EQ(tokenId01, tokenId02); +} + +/** + * @tc.name: GetAccessTokenId006 + * @tc.desc: Get AccessTokenId with new processName and check g_tokenListHead. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(TokenLibKitTest, GetAccessTokenId006, TestSize.Level1) +{ + uint64_t tokenID; + tokenID = Start("GetAccessTokenId006"); + ASSERT_NE(tokenID, 0); + + char *fileBuff = nullptr; + int ret = GetFileBuff(TOKEN_ID_CFG_FILE_PATH, &fileBuff); + ASSERT_EQ(ret, ATRET_SUCCESS); + string s = "GetAccessTokenId006"; + char *pos = strstr(fileBuff, s.c_str()); + ASSERT_NE(pos, nullptr); +} + +/** + * @tc.name: GetAccessTokenId007 + * @tc.desc: Get a batch of AccessTokenId. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(TokenLibKitTest, GetAccessTokenId007, TestSize.Level1) +{ + char processName[200][MAX_PROCESS_NAME_LEN]; + /* enable 200 process before fondation is prepared */ + for (int32_t i = 0; i < 200; i++) { + processName[i][0] = '\0'; + int ret = sprintf_s(processName[i], MAX_PROCESS_NAME_LEN, "processName_%d", i); + ASSERT_NE(ret, 0); + uint64_t tokenId = Start(processName[i]); + ASSERT_NE(tokenId, 0); + } + char *fileBuff = nullptr; + int ret = GetFileBuff(TOKEN_ID_CFG_FILE_PATH, &fileBuff); + ASSERT_EQ(ret, 0); + for (int32_t i = 0; i < 200; i++) { + char *pos = strstr(fileBuff, processName[i]); + ASSERT_NE(pos, nullptr); + } + free(fileBuff); +} + +/** + * @tc.name: GetAccessTokenId008 + * @tc.desc: Get AccessTokenId and check the config file. + * @tc.type: FUNC + * @tc.require:AR000GK6TD + */ +HWTEST_F(TokenLibKitTest, GetAccessTokenId008, TestSize.Level1) +{ + Start("process1"); + Start("process2"); + Start("process3"); + Start("process4"); + Start("process5"); + Start("foundation"); + Start("process6"); + Start("process7"); + Start("process8"); + Start("process9"); + Start("process10"); + Start("process15"); + Start("process16"); + Start("process17"); + Start("process18"); + Start("process19"); + + char *fileBuff = nullptr; + int ret = GetFileBuff(TOKEN_ID_CFG_FILE_PATH, &fileBuff); + ASSERT_EQ(ret, 0); + char *pos = strstr(fileBuff, "process1"); + ASSERT_NE(pos, nullptr); + pos = strstr(fileBuff, "process2"); + ASSERT_NE(pos, nullptr); + pos = strstr(fileBuff, "process3"); + ASSERT_NE(pos, nullptr); + pos = strstr(fileBuff, "process4"); + ASSERT_NE(pos, nullptr); + pos = strstr(fileBuff, "process5"); + ASSERT_NE(pos, nullptr); + pos = strstr(fileBuff, "process6"); + ASSERT_NE(pos, nullptr); + pos = strstr(fileBuff, "process7"); + ASSERT_NE(pos, nullptr); + pos = strstr(fileBuff, "process8"); + ASSERT_NE(pos, nullptr); + pos = strstr(fileBuff, "process9"); + ASSERT_NE(pos, nullptr); + free(fileBuff); +} diff --git a/interfaces/innerkits/nativetoken/test/unittest/src/nativetoken_kit_test.h b/interfaces/innerkits/nativetoken/test/unittest/src/nativetoken_kit_test.h new file mode 100644 index 0000000000000000000000000000000000000000..8aa651750f1c4f3574a207244d2ab18b9748b7aa --- /dev/null +++ b/interfaces/innerkits/nativetoken/test/unittest/src/nativetoken_kit_test.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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 TOKENSYNC_KIT_TEST_H +#define TOKENSYNC_KIT_TEST_H + +#include + +namespace OHOS { +namespace Security { +static const int BUFF_LEN = 102400; +static const int DELAY_ONE_SECONDS = 5; +static const int DELAY_FIVE_SECONDS = 10; +class TokenLibKitTest : public testing::Test { +public: + static void SetUpTestCase(); + + static void TearDownTestCase(); + + void SetUp(); + + void TearDown(); + void ResetFile(void); + void PthreadCloseTrigger(void); +}; +} // namespace Security +} // namespace OHOS +#endif // TOKENSYNC_KIT_TEST_H diff --git a/interfaces/innerkits/token_setproc/BUILD.gn b/interfaces/innerkits/token_setproc/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..1cdcc6f30fa29c6f692687978be72557a8d4818b --- /dev/null +++ b/interfaces/innerkits/token_setproc/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (C) 2021 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. + +import("//build/ohos.gni") + +################################################################ +# C, Main, source file here. +################################################################ +config("token_setproc") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +ohos_static_library("libtoken_setproc") { + subsystem_name = "security" + part_name = "access_token" + output_name = "libtoken_setproc" + + public_configs = [ ":token_setproc" ] + + cflags = [ "-Wall" ] + + include_dirs = [ + "include", + "src", + ] + + sources = [ "src/token_setproc.c" ] + + deps = [] +} diff --git a/interfaces/innerkits/token_setproc/include/token_setproc.h b/interfaces/innerkits/token_setproc/include/token_setproc.h new file mode 100644 index 0000000000000000000000000000000000000000..81c75d92a8e3ee037873e1f005da985311305c72 --- /dev/null +++ b/interfaces/innerkits/token_setproc/include/token_setproc.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 TOKEN_SETPROC_H +#define TOKEN_SETPROC_H +#include + +#ifdef __cplusplus +extern "C" { +#endif + +uint64_t GetSelfTokenID(); + +int SetSelfTokenID(uint64_t tokenID); + +uint64_t GetFirstCallerTokenID(); + +int SetFirstCallerTokenID(uint64_t tokenID); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/interfaces/innerkits/token_setproc/src/token_setproc.c b/interfaces/innerkits/token_setproc/src/token_setproc.c new file mode 100644 index 0000000000000000000000000000000000000000..b2d09dbef5e0e164992bdfe4069f57214e58b470 --- /dev/null +++ b/interfaces/innerkits/token_setproc/src/token_setproc.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021 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 "token_setproc.h" + +#include +#include +#include +#include +#include + +#define ACCESS_TOKEN_ID_IOCTL_BASE 'A' + +enum { + GET_TOKEN_ID = 1, + SET_TOKEN_ID, + GET_FTOKEN_ID, + SET_FTOKEN_ID, + ACCESS_TOKENID_MAX_NR, +}; + +#define ACCESS_TOKENID_GET_TOKENID \ + _IOR(ACCESS_TOKEN_ID_IOCTL_BASE, GET_TOKEN_ID, unsigned long long) +#define ACCESS_TOKENID_SET_TOKENID \ + _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_TOKEN_ID, unsigned long long) +#define ACCESS_TOKENID_GET_FTOKENID \ + _IOR(ACCESS_TOKEN_ID_IOCTL_BASE, GET_FTOKEN_ID, unsigned long long) +#define ACCESS_TOKENID_SET_FTOKENID \ + _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_FTOKEN_ID, unsigned long long) + +#define ACCESS_TOKEN_OK 0 +#define ACCESS_TOKEN_ERROR (-1) + +#define INVAL_TOKEN_ID 0x0 +#define TOKEN_ID_LOWMASK 0xffffffff + +#define TOKENID_DEVNODE "/dev/access_token_id" + +uint64_t GetSelfTokenID() +{ + uint64_t token = INVAL_TOKEN_ID; + int fd = open(TOKENID_DEVNODE, O_RDWR); + if (fd < 0) { + return INVAL_TOKEN_ID; + } + int ret = ioctl(fd, ACCESS_TOKENID_GET_TOKENID, &token); + if (ret) { + close(fd); + return INVAL_TOKEN_ID; + } + + close(fd); + return token; +} + +int SetSelfTokenID(uint64_t tokenID) +{ + int fd = open(TOKENID_DEVNODE, O_RDWR); + if (fd < 0) { + return ACCESS_TOKEN_ERROR; + } + int ret = ioctl(fd, ACCESS_TOKENID_SET_TOKENID, &tokenID); + if (ret) { + close(fd); + return ACCESS_TOKEN_ERROR; + } + + close(fd); + return ACCESS_TOKEN_OK; +} + +uint64_t GetFirstCallerTokenID() +{ + uint64_t token = INVAL_TOKEN_ID; + int fd = open(TOKENID_DEVNODE, O_RDWR); + if (fd < 0) { + return INVAL_TOKEN_ID; + } + int ret = ioctl(fd, ACCESS_TOKENID_GET_FTOKENID, &token); + if (ret) { + close(fd); + return INVAL_TOKEN_ID; + } + + close(fd); + return token; +} + + +int SetFirstCallerTokenID(uint64_t tokenID) +{ + int fd = open(TOKENID_DEVNODE, O_RDWR); + if (fd < 0) { + return ACCESS_TOKEN_ERROR; + } + int ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, &tokenID); + if (ret) { + close(fd); + return ACCESS_TOKEN_ERROR; + } + + close(fd); + return ACCESS_TOKEN_OK; +} diff --git a/interfaces/innerkits/token_setproc/test/BUILD.gn b/interfaces/innerkits/token_setproc/test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..9cac0ef6575dff6f3bcef74c713cdd852941cc81 --- /dev/null +++ b/interfaces/innerkits/token_setproc/test/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (C) 2021 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. + +import("//build/test.gni") + +ohos_unittest("libtoken_setproc_test") { + subsystem_name = "security" + part_name = "access_token" + module_out_path = part_name + "/" + part_name + + include_dirs = [ + "//base/security/access_token/interfaces/innerkits/token_setproc/include", + ] + + sources = [ "unittest/src/tokensetproc_kit_test.cpp" ] + cflags_cc = [ "-fexceptions" ] + + deps = [ + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + "//third_party/googletest:gmock", + "//third_party/googletest:gtest", + ] +} + +group("unittest") { + testonly = true + deps = [ ":libtoken_setproc_test" ] +} diff --git a/interfaces/innerkits/token_setproc/test/unittest/src/tokensetproc_kit_test.cpp b/interfaces/innerkits/token_setproc/test/unittest/src/tokensetproc_kit_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5fe3f833c5a6486f5b489479abf2c07136ba771e --- /dev/null +++ b/interfaces/innerkits/token_setproc/test/unittest/src/tokensetproc_kit_test.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "tokensetproc_kit_test.h" + +#include "token_setproc.h" + +using namespace testing::ext; +using namespace OHOS::Security; + +void TokensetprocKitTest::SetUpTestCase() +{} + +void TokensetprocKitTest::TearDownTestCase() +{} + +void TokensetprocKitTest::SetUp() +{} + +void TokensetprocKitTest::TearDown() +{} \ No newline at end of file diff --git a/interfaces/innerkits/token_setproc/test/unittest/src/tokensetproc_kit_test.h b/interfaces/innerkits/token_setproc/test/unittest/src/tokensetproc_kit_test.h new file mode 100644 index 0000000000000000000000000000000000000000..29bef17d2590d7867c5693ac490d95bd9756d104 --- /dev/null +++ b/interfaces/innerkits/token_setproc/test/unittest/src/tokensetproc_kit_test.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 TOKENSYNC_KIT_TEST_H +#define TOKENSYNC_KIT_TEST_H + +#include + +namespace OHOS { +namespace Security { +class TokensetprocKitTest : public testing::Test { +public: + static void SetUpTestCase(); + + static void TearDownTestCase(); + + void SetUp(); + + void TearDown(); +}; +} // namespace Security +} // namespace OHOS +#endif diff --git a/interfaces/innerkits/tokensync/BUILD.gn b/interfaces/innerkits/tokensync/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..aa92f46a9d3d122da6b910c5c2a06944c21c525b --- /dev/null +++ b/interfaces/innerkits/tokensync/BUILD.gn @@ -0,0 +1,68 @@ +# Copyright (C) 2021 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. + +import("//build/ohos.gni") + +################################################################ +# C++, Main, source file here. +################################################################ +config("tokensync") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +ohos_shared_library("libtokensync_sdk") { + subsystem_name = "security" + part_name = "access_token" + + output_name = "libtokensync_sdk" + + public_configs = [ ":tokensync" ] + + include_dirs = [ + "//utils/native/base/include", + "include", + "src", + "//base/security/access_token/frameworks/tokensync/include", + "//base/security/access_token/frameworks/common/include", + "//base/security/access_token/interfaces/innerkits/tokensync/include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", + "//base/security/access_token/frameworks/accesstoken/include", + + #"//base/security/permission/interfaces/innerkits/permission_standard/permissionsdk/main/cpp/include/permission", + ] + + sources = [ + #"main/cpp/src/permission/permission_kit.cpp", + #"main/cpp/src/permission/permission_manager_client.cpp", + #"main/cpp/src/permission/permission_manager_proxy.cpp", + "src/token_sync_kit.cpp", + "src/token_sync_manager_client.cpp", + "src/token_sync_manager_proxy.cpp", + ] + + deps = [ + #"//base/security/permission/frameworks/permission_standard/permissioncommunicationadapter:permission_standard_communication_adapter_cxx", + #"//base/security/permission/frameworks/permission_standard/permissioninfrastructure:permission_standard_infrastructure_cxx", + "//base/security/access_token/frameworks/accesstoken:accesstoken_communication_adapter_cxx", + "//utils/native/base:utils", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "samgr_standard:samgr_proxy", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] +} diff --git a/interfaces/innerkits/tokensync/include/token_sync_kit.h b/interfaces/innerkits/tokensync/include/token_sync_kit.h new file mode 100644 index 0000000000000000000000000000000000000000..e72b005947c006673defc560166e58835fdcdece --- /dev/null +++ b/interfaces/innerkits/tokensync/include/token_sync_kit.h @@ -0,0 +1,38 @@ +/* + * 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_TOKENSYNC_KIT_H +#define INTERFACES_INNER_KITS_TOKENSYNC_KIT_H + +#include +#include + +#include "access_token.h" +#include "hap_token_info.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class TokenSyncKit { +public: + static int GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID); + static int DeleteRemoteHapTokenInfo(AccessTokenID tokenID); + static int UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif diff --git a/interfaces/innerkits/tokensync/src/token_sync_kit.cpp b/interfaces/innerkits/tokensync/src/token_sync_kit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..090153e7bb389f52b4cc4bad36364b81f1901897 --- /dev/null +++ b/interfaces/innerkits/tokensync/src/token_sync_kit.cpp @@ -0,0 +1,53 @@ +/* + * 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 "token_sync_kit.h" + +#include +#include + +#include "accesstoken_log.h" +#include "token_sync_manager_client.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +using namespace std; + +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenSyncKit"}; +} // namespace + +int TokenSyncKit::GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID=%{public}s tokenID=%{public}d", + __func__, deviceID.c_str(), tokenID); + return TokenSyncManagerClient::GetInstance().GetRemoteHapTokenInfo(deviceID, tokenID); +} + +int TokenSyncKit::DeleteRemoteHapTokenInfo(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID=%{public}d", __func__, tokenID); + return TokenSyncManagerClient::GetInstance().DeleteRemoteHapTokenInfo(tokenID); +} + +int TokenSyncKit::UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called tokenID=%{public}d", __func__, tokenInfo.baseInfo.tokenID); + return TokenSyncManagerClient::GetInstance().UpdateRemoteHapTokenInfo(tokenInfo); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_client.cpp b/interfaces/innerkits/tokensync/src/token_sync_manager_client.cpp similarity index 37% rename from interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_client.cpp rename to interfaces/innerkits/tokensync/src/token_sync_manager_client.cpp index a5de7d88eb882295421bdda5b6bed135a87ca48d..3cd5a9d56002d8cc5dda0025f4395d80f7563286 100644 --- a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_client.cpp +++ b/interfaces/innerkits/tokensync/src/token_sync_manager_client.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,65 +13,85 @@ * limitations under the License. */ -#include "accesstoken_manager_client.h" +#include "token_sync_manager_client.h" #include "accesstoken_log.h" - +#include "hap_token_info_for_sync_parcel.h" #include "iservice_registry.h" namespace OHOS { namespace Security { namespace AccessToken { namespace { -static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { - LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenManagerClient" -}; +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenSyncManagerClient"}; } // namespace -AccessTokenManagerClient& AccessTokenManagerClient::GetInstance() +TokenSyncManagerClient& TokenSyncManagerClient::GetInstance() { - static AccessTokenManagerClient instance; + static TokenSyncManagerClient instance; return instance; } -AccessTokenManagerClient::AccessTokenManagerClient() +TokenSyncManagerClient::TokenSyncManagerClient() {} -AccessTokenManagerClient::~AccessTokenManagerClient() +TokenSyncManagerClient::~TokenSyncManagerClient() {} -int AccessTokenManagerClient::VerifyAccesstoken(AccessTokenID tokenID, const std::string& permissionName) const +int TokenSyncManagerClient::GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID) const +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return -1; + } + return proxy->GetRemoteHapTokenInfo(deviceID, tokenID); +} + +int TokenSyncManagerClient::DeleteRemoteHapTokenInfo(AccessTokenID tokenID) const +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); + auto proxy = GetProxy(); + if (proxy == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return -1; + } + return proxy->DeleteRemoteHapTokenInfo(tokenID); +} + +int TokenSyncManagerClient::UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo) const { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: called!", __func__); auto proxy = GetProxy(); if (proxy == nullptr) { - ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s: proxy is null", __func__); - return PERMISSION_DENIED; + ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null"); + return -1; } - return proxy->VerifyAccesstoken(tokenID, permissionName); + return proxy->UpdateRemoteHapTokenInfo(tokenInfo); } -sptr AccessTokenManagerClient::GetProxy() const +sptr TokenSyncManagerClient::GetProxy() const { auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (sam == nullptr) { - ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: GetSystemAbilityManager is null", __func__); + ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbilityManager is null"); return nullptr; } - auto accesstokenSa = sam->GetSystemAbility(IAccessTokenManager::SA_ID_ACCESSTOKEN_MANAGER_SERVICE); - if (accesstokenSa == nullptr) { - ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: GetSystemAbility %{public}d is null", __func__, - IAccessTokenManager::SA_ID_ACCESSTOKEN_MANAGER_SERVICE); + auto tokensyncSa = sam->GetSystemAbility(ITokenSyncManager::SA_ID_TOKENSYNC_MANAGER_SERVICE); + if (tokensyncSa == nullptr) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbility %{public}d is null", + ITokenSyncManager::SA_ID_TOKENSYNC_MANAGER_SERVICE); return nullptr; } - auto proxy = iface_cast(accesstokenSa); + auto proxy = iface_cast(tokensyncSa); if (proxy == nullptr) { - ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s: iface_cast get null", __func__); + ACCESSTOKEN_LOG_DEBUG(LABEL, "iface_cast get null"); return nullptr; } return proxy; } } // namespace AccessToken } // namespace Security -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/services/accesstoken/main/cpp/include/accesstoken_manager_service.h b/interfaces/innerkits/tokensync/src/token_sync_manager_client.h similarity index 49% rename from services/accesstoken/main/cpp/include/accesstoken_manager_service.h rename to interfaces/innerkits/tokensync/src/token_sync_manager_client.h index 8174ae72f6a7f3a6dd727d32afe011a88beb45d6..f416cba312c54cadceed163f8adf490741000aaf 100644 --- a/services/accesstoken/main/cpp/include/accesstoken_manager_service.h +++ b/interfaces/innerkits/tokensync/src/token_sync_manager_client.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,35 +13,37 @@ * limitations under the License. */ -#ifndef ACCESSTOKEN_MANAGER_SERVICE_H -#define ACCESSTOKEN_MANAGER_SERVICE_H +#ifndef ACCESSTOKEN_MANAGER_CLIENT_H +#define ACCESSTOKEN_MANAGER_CLIENT_H -#include "accesstoken_manager_stub.h" -#include "singleton.h" -#include "iremote_object.h" -#include "system_ability.h" +#include + +#include "access_token.h" +#include "hap_token_info.h" +#include "i_token_sync_manager.h" #include "nocopyable.h" namespace OHOS { namespace Security { namespace AccessToken { -enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; -class AccessTokenManagerService final : public SystemAbility, public AccessTokenManagerStub { - DECLARE_DELAYED_SINGLETON(AccessTokenManagerService); - DECLEAR_SYSTEM_ABILITY(AccessTokenManagerService); - +class TokenSyncManagerClient final { public: - void OnStart() override; - void OnStop() override; + static TokenSyncManagerClient& GetInstance(); - int VerifyAccesstoken(AccessTokenID tokenID, const std::string& permissionName) override; + virtual ~TokenSyncManagerClient(); + + int GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID) const; + int DeleteRemoteHapTokenInfo(AccessTokenID tokenID) const; + int UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo) const; private: - bool Initialize() const; + TokenSyncManagerClient(); + + DISALLOW_COPY_AND_MOVE(TokenSyncManagerClient); - ServiceRunningState state_; + sptr GetProxy() const; }; } // namespace AccessToken } // namespace Security } // namespace OHOS -#endif // ACCESSTOKEN_MANAGER_SERVICE_H +#endif // ACCESSTOKEN_MANAGER_CLIENT_H diff --git a/interfaces/innerkits/tokensync/src/token_sync_manager_proxy.cpp b/interfaces/innerkits/tokensync/src/token_sync_manager_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf603c5909894e0d7f322b7fa14abc7cd655a384 --- /dev/null +++ b/interfaces/innerkits/tokensync/src/token_sync_manager_proxy.cpp @@ -0,0 +1,128 @@ +/* + * 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 "token_sync_manager_proxy.h" + +#include "accesstoken_log.h" +#include "parcel.h" +#include "string_ex.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenSyncManagerProxy"}; +} + +TokenSyncManagerProxy::TokenSyncManagerProxy(const sptr& impl) : IRemoteProxy(impl) +{} + +TokenSyncManagerProxy::~TokenSyncManagerProxy() +{} + +int TokenSyncManagerProxy::GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID) +{ + MessageParcel data; + data.WriteInterfaceToken(ITokenSyncManager::GetDescriptor()); + if (!data.WriteString(deviceID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write deviceID"); + return -1; + } + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return -1; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return -1; + } + int32_t requestResult = remote->SendRequest( + static_cast(ITokenSyncManager::InterfaceCode::GET_REMOTE_HAP_TOKEN_INFO), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return -1; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int TokenSyncManagerProxy::DeleteRemoteHapTokenInfo(AccessTokenID tokenID) +{ + MessageParcel data; + data.WriteInterfaceToken(ITokenSyncManager::GetDescriptor()); + if (!data.WriteUint32(tokenID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenID"); + return -1; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return -1; + } + int32_t requestResult = remote->SendRequest( + static_cast(ITokenSyncManager::InterfaceCode::DELETE_REMOTE_HAP_TOKEN_INFO), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return -1; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} + +int TokenSyncManagerProxy::UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo) +{ + MessageParcel data; + data.WriteInterfaceToken(ITokenSyncManager::GetDescriptor()); + + HapTokenInfoForSyncParcel tokenInfoParcel; + tokenInfoParcel.hapTokenInfoForSyncParams = tokenInfo; + + if (!data.WriteParcelable(&tokenInfoParcel)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to write tokenInfo"); + return -1; + } + + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return -1; + } + int32_t requestResult = remote->SendRequest( + static_cast(ITokenSyncManager::InterfaceCode::UPDATE_REMOTE_HAP_TOKEN_INFO), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return -1; + } + + int32_t result = reply.ReadInt32(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "get result from server data = %{public}d", result); + return result; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/interfaces/innerkits/tokensync/src/token_sync_manager_proxy.h b/interfaces/innerkits/tokensync/src/token_sync_manager_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..6e251e9612d32f642be1ec246d7fd026d1b63960 --- /dev/null +++ b/interfaces/innerkits/tokensync/src/token_sync_manager_proxy.h @@ -0,0 +1,45 @@ +/* + * 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 TOKENSYNC_MANAGER_PROXY_H +#define TOKENSYNC_MANAGER_PROXY_H + +#include + +#include "access_token.h" +#include "hap_token_info_for_sync_parcel.h" +#include "i_token_sync_manager.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class TokenSyncManagerProxy : public IRemoteProxy { +public: + explicit TokenSyncManagerProxy(const sptr& impl); + virtual ~TokenSyncManagerProxy() override; + + int GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID) override; + int DeleteRemoteHapTokenInfo(AccessTokenID tokenID) override; + int UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // TOKENSYNC_MANAGER_PROXY_H diff --git a/interfaces/innerkits/tokensync/test/BUILD.gn b/interfaces/innerkits/tokensync/test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..87a14097bf1e6345aeb8597bb12132bcb2dcf9d3 --- /dev/null +++ b/interfaces/innerkits/tokensync/test/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (C) 2021 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. + +import("//build/test.gni") + +ohos_unittest("libtokensync_sdk_test") { + subsystem_name = "security" + part_name = "access_token" + module_out_path = part_name + "/" + part_name + + include_dirs = [ + "//utils/native/base/include", + "//third_party/googletest/include", + "//base/security/access_token/interfaces/innerkits/tokensync/include", + + #"//base/security/permission/interfaces/innerkits/permission_standard/permissionsdk/main/cpp/include/permission/", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", + ] + + sources = [ "unittest/src/token_sync_kit_test.cpp" ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + deps = [ + #"//base/security/permission/frameworks/permission_standard/permissioninfrastructure:permission_standard_infrastructure_cxx", + "//base/security/access_token/interfaces/innerkits/tokensync:libtokensync_sdk", + "//utils/native/base:utils", + ] +} + +group("unittest") { + testonly = true + deps = [ ":libtokensync_sdk_test" ] +} diff --git a/interfaces/innerkits/accesstoken/test/unittest/cpp/src/accesstoken_kit_test.cpp b/interfaces/innerkits/tokensync/test/unittest/src/token_sync_kit_test.cpp old mode 100755 new mode 100644 similarity index 52% rename from interfaces/innerkits/accesstoken/test/unittest/cpp/src/accesstoken_kit_test.cpp rename to interfaces/innerkits/tokensync/test/unittest/src/token_sync_kit_test.cpp index 7fbf82406a97720a7a04c6b8de520cacbc67b662..f4587575b34f69b858bce6663c3dfac86978bd74 --- a/interfaces/innerkits/accesstoken/test/unittest/cpp/src/accesstoken_kit_test.cpp +++ b/interfaces/innerkits/tokensync/test/unittest/src/token_sync_kit_test.cpp @@ -13,37 +13,24 @@ * limitations under the License. */ -#include "accesstoken_kit_test.h" +#include "token_sync_kit_test.h" -#include "accesstoken_kit.h" +#include "token_sync_kit.h" using namespace testing::ext; using namespace OHOS::Security::AccessToken; -void AccessTokenKitTest::SetUpTestCase() +void TokenSyncKitTest::SetUpTestCase() {} -void AccessTokenKitTest::TearDownTestCase() -{} - -void AccessTokenKitTest::SetUp() -{} - -void AccessTokenKitTest::TearDown() -{} +void TokenSyncKitTest::TearDownTestCase() +{ +} -/** - * @tc.name: VerifyAccesstoken001 - * @tc.desc: Verify user granted permission - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F(AccessTokenKitTest, VerifyAccesstoken001, TestSize.Level0) +void TokenSyncKitTest::SetUp() { - AccessTokenID tokenID = 1; - const std::string TEST_PERMISSION_NAME = "ohos.permission.TEST"; +} - int ret = AccessTokenKit::VerifyAccesstoken(tokenID, TEST_PERMISSION_NAME); - ASSERT_EQ(PERMISSION_GRANTED, ret); +void TokenSyncKitTest::TearDown() +{} -} \ No newline at end of file diff --git a/interfaces/innerkits/accesstoken/test/unittest/cpp/src/accesstoken_kit_test.h b/interfaces/innerkits/tokensync/test/unittest/src/token_sync_kit_test.h similarity index 86% rename from interfaces/innerkits/accesstoken/test/unittest/cpp/src/accesstoken_kit_test.h rename to interfaces/innerkits/tokensync/test/unittest/src/token_sync_kit_test.h index 5784ad6f4cccb0584a0794179a4b32e6de6212c6..1cb07f236b89a505565630b2bd89991f91a04f45 100644 --- a/interfaces/innerkits/accesstoken/test/unittest/cpp/src/accesstoken_kit_test.h +++ b/interfaces/innerkits/tokensync/test/unittest/src/token_sync_kit_test.h @@ -13,15 +13,15 @@ * limitations under the License. */ -#ifndef ACCESSTOKEN_KIT_TEST_H -#define ACCESSTOKEN_KIT_TEST_H +#ifndef TOKENSYNC_KIT_TEST_H +#define TOKENSYNC_KIT_TEST_H #include namespace OHOS { namespace Security { namespace AccessToken { -class AccessTokenKitTest : public testing::Test { +class TokenSyncKitTest : public testing::Test { public: static void SetUpTestCase(); @@ -34,4 +34,4 @@ public: } // namespace AccessToken } // namespace Security } // namespace OHOS -#endif // ACCESSTOKEN_KIT_TEST_H +#endif // TOKENSYNC_KIT_TEST_H diff --git a/interfaces/kits/BUILD.gn b/interfaces/kits/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..cf2e891f45c8dcb8c021206503fd70779de42fa1 --- /dev/null +++ b/interfaces/kits/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2021 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. + +import("//build/ohos.gni") + +group("napi_packages") { + deps = [] + if (support_jsapi) { + deps += [ "//base/security/access_token/interfaces/kits/accesstoken:libabilityaccessctrl" ] + } +} diff --git a/interfaces/kits/accesstoken/BUILD.gn b/interfaces/kits/accesstoken/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..ae9e53c0a75ea43194f16f2b9e6f8e250d4defcf --- /dev/null +++ b/interfaces/kits/accesstoken/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (c) 2021 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. + +import("//build/ohos.gni") + +ohos_shared_library("libabilityaccessctrl") { + include_dirs = [ + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", + "//foundation/ace/napi/interfaces/kits", + "//third_party/json/single_include", + "//third_party/node/src", + "//utils/system/safwk/native/include", + "//foundation/communication/dsoftbus/interfaces/kits/transport", + "//foundation/communication/dsoftbus/interfaces/kits/common", + "//foundation/communication/dsoftbus/interfaces/kits/bus_center", + "//third_party/json/include", + "//foundation/aafwk/standard/interfaces/innerkits/ability_manager/include", + "//base/security/access_token/frameworks/common/include", + "//base/security/access_token/interfaces/kits/accesstoken/napi/include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", + ] + + sources = [ "//base/security/access_token/interfaces/kits/accesstoken/napi/src/napi_atmanager.cpp" ] + + deps = [ + "//base/notification/ans_standard/frameworks/ans/core:ans_core", + "//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits", + "//base/security/access_token/interfaces/innerkits/accesstoken:libaccesstoken_sdk", + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", + "//foundation/aafwk/standard/interfaces/innerkits/base:base", + "//foundation/ace/napi:ace_napi", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//utils/native/base:utils", + ] + cflags_cc = [ "-DHILOG_ENABLE" ] + external_deps = [ + "ability_base:want", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] + + relative_install_dir = "module" + subsystem_name = "security" + part_name = "access_token" +} diff --git a/interfaces/kits/accesstoken/napi/include/napi_atmanager.h b/interfaces/kits/accesstoken/napi/include/napi_atmanager.h new file mode 100644 index 0000000000000000000000000000000000000000..3fee43806253cab76c5cefd05943e9037f532000 --- /dev/null +++ b/interfaces/kits/accesstoken/napi/include/napi_atmanager.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 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 NAPI_ATMANAGER_H_ +#define NAPI_ATMANAGER_H_ + +#include +#include +#include +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +#define ASYN_THREAD_EXEC_SUCC 0 +#define ASYN_THREAD_EXEC_FAIL -1 +#define ACCESSTOKEN_PERMISSION_GRANT_FAIL -1 +#define ACCESSTOKEN_PERMISSION_GRANT_SUCC 0 +#define ACCESSTOKEN_PERMISSION_REVOKE_FAIL -1 +#define ACCESSTOKEN_PERMISSION_REVOKE_SUCC 0 +#define VALUE_BUFFER_SIZE 128 + +const std::string ATMANAGER_CLASS_NAME = "atManager"; + +struct AtManagerAsyncContext { + napi_env env = nullptr; + uint32_t tokenId = 0; + char permissionName[ VALUE_BUFFER_SIZE ] = { 0 }; + size_t pNameLen = 0; + int flag = 0; + int result = 0; // callback or promise return result + int status = ASYN_THREAD_EXEC_FAIL; // napi_create_async_work-execute function exec result, default failure + + napi_deferred deferred = nullptr; // promise handle + napi_ref callbackRef = nullptr; // callback handle + napi_async_work work = nullptr; // work handle +}; + +class NapiAtManager { +public: + static napi_value Init(napi_env env, napi_value exports); + +private: + static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); + static napi_value CreateAtManager(napi_env env, napi_callback_info cbInfo); + static napi_value VerifyAccessToken(napi_env env, napi_callback_info info); + static napi_value GrantUserGrantedPermission(napi_env env, napi_callback_info info); + static napi_value RevokeUserGrantedPermission(napi_env env, napi_callback_info info); + static napi_value GetPermissionFlags(napi_env env, napi_callback_info info); + + static void ParseInputVerifyPermissionOrGetFlag(const napi_env env, const napi_callback_info info, + AtManagerAsyncContext& asyncContext); + static void VerifyAccessTokenExecute(napi_env env, void *data); + static void VerifyAccessTokenComplete(napi_env env, napi_status status, void *data); + static void ParseInputGrantOrRevokePermission(const napi_env env, const napi_callback_info info, + AtManagerAsyncContext& asyncContext); + static void GrantUserGrantedPermissionExcute(napi_env env, void *data); + static void GrantUserGrantedPermissionComplete(napi_env env, napi_status status, void *data); + static void RevokeUserGrantedPermissionExcute(napi_env env, void *data); + static void RevokeUserGrantedPermissionComplete(napi_env env, napi_status status, void *data); + static void GetPermissionFlagsExcute(napi_env env, void *data); + static void GetPermissionFlagsComplete(napi_env env, napi_status status, void *data); + + static napi_ref constructorRef_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +/* + * function for module exports + */ +static napi_value Init(napi_env env, napi_value exports); + +#endif /* NAPI_ATMANAGER_H_ */ diff --git a/interfaces/kits/accesstoken/napi/src/napi_atmanager.cpp b/interfaces/kits/accesstoken/napi/src/napi_atmanager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..02dd841c4922adfbf9249e6adfdbd9602063059c --- /dev/null +++ b/interfaces/kits/accesstoken/napi/src/napi_atmanager.cpp @@ -0,0 +1,589 @@ +/* + * Copyright (c) 2021 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 "napi_atmanager.h" + +#include +#include +#include +#include + +#include "accesstoken_kit.h" +#include "accesstoken_log.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenAbilityAccessCtrl" +}; +} // namespace + +napi_ref NapiAtManager::constructorRef_; + +napi_value NapiAtManager::Init(napi_env env, napi_value exports) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "enter init."); + + napi_property_descriptor descriptor[] = { DECLARE_NAPI_FUNCTION("createAtManager", CreateAtManager) }; + + NAPI_CALL(env, napi_define_properties(env, + exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor)); + + napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION("verifyAccessToken", VerifyAccessToken), + DECLARE_NAPI_FUNCTION("grantUserGrantedPermission", GrantUserGrantedPermission), + DECLARE_NAPI_FUNCTION("revokeUserGrantedPermission", RevokeUserGrantedPermission), + DECLARE_NAPI_FUNCTION("getPermissionFlags", GetPermissionFlags) + }; + + napi_value cons = nullptr; + NAPI_CALL(env, napi_define_class(env, ATMANAGER_CLASS_NAME.c_str(), ATMANAGER_CLASS_NAME.size(), + JsConstructor, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons)); + + NAPI_CALL(env, napi_create_reference(env, cons, 1, &constructorRef_)); + NAPI_CALL(env, napi_set_named_property(env, exports, ATMANAGER_CLASS_NAME.c_str(), cons)); + + return exports; +} + +napi_value NapiAtManager::JsConstructor(napi_env env, napi_callback_info cbinfo) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "enter JsConstructor"); + + napi_value thisVar = nullptr; + + NAPI_CALL(env, napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr)); + + return thisVar; +} + +napi_value NapiAtManager::CreateAtManager(napi_env env, napi_callback_info cbInfo) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "enter CreateAtManager"); + + napi_value instance = nullptr; + napi_value cons = nullptr; + + if (napi_get_reference_value(env, constructorRef_, &cons) != napi_ok) { + return nullptr; + } + + ACCESSTOKEN_LOG_DEBUG(LABEL, "Get a reference to the global variable constructorRef_ complete"); + + if (napi_new_instance(env, cons, 0, nullptr, &instance) != napi_ok) { + return nullptr; + } + + ACCESSTOKEN_LOG_DEBUG(LABEL, "New the js instance complete"); + + return instance; +} + +void NapiAtManager::ParseInputVerifyPermissionOrGetFlag(const napi_env env, const napi_callback_info info, + AtManagerAsyncContext& asyncContext) +{ + size_t argc = 2; + + napi_value argv[2] = { 0 }; + napi_value thisVar = nullptr; + + void *data = nullptr; + + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); + + asyncContext.env = env; + + // parse input tokenId and permissionName + for (size_t i = 0; i < argc; i++) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[i], &valueType); + + if (valueType == napi_number) { + napi_get_value_uint32(env, argv[i], &(asyncContext.tokenId)); // get tokenId + } else if (valueType == napi_string) { + napi_get_value_string_utf8(env, argv[i], asyncContext.permissionName, + VALUE_BUFFER_SIZE, &(asyncContext.pNameLen)); // get permissionName + } else { + ACCESSTOKEN_LOG_ERROR(LABEL, "Type matching failed"); + asyncContext.result = -1; + } + } + + ACCESSTOKEN_LOG_DEBUG(LABEL, "tokenID = %{public}d", asyncContext.tokenId); + ACCESSTOKEN_LOG_DEBUG(LABEL, "permissionName = %{public}s", asyncContext.permissionName); +} + +void NapiAtManager::VerifyAccessTokenExecute(napi_env env, void *data) +{ + AtManagerAsyncContext* asyncContext = (AtManagerAsyncContext *)data; + + // use innerkit class method to verify permission + asyncContext->result = AccessTokenKit::VerifyAccessToken(asyncContext->tokenId, + asyncContext->permissionName); + + // set status according to the innerkit class method return + if ((asyncContext->result == PERMISSION_GRANTED) || (asyncContext->result == PERMISSION_DENIED)) { + asyncContext->status = ASYN_THREAD_EXEC_SUCC; // granted and denied regard as function exec success + } else { + asyncContext->status = ASYN_THREAD_EXEC_FAIL; // other regard as function exec failure + } +} + +void NapiAtManager::VerifyAccessTokenComplete(napi_env env, napi_status status, void *data) +{ + AtManagerAsyncContext* asyncContext = (AtManagerAsyncContext*)data; + napi_value result; + + ACCESSTOKEN_LOG_DEBUG(LABEL, "tokenId = %{public}d, permissionName = %{public}s, verify result = %{public}d.", + asyncContext->tokenId, asyncContext->permissionName, asyncContext->result); + + if (asyncContext->status == ASYN_THREAD_EXEC_SUCC) { + // execute succ, use resolve to return result by the deferred create before + napi_create_int32(env, asyncContext->result, &result); // verify result + napi_resolve_deferred(env, asyncContext->deferred, result); + } else { + // execute fail, use reject to return default PERMISSION_DENIED by the deferred create before + napi_create_int32(env, PERMISSION_DENIED, &result); // verify result + napi_reject_deferred(env, asyncContext->deferred, result); + } + + // after return the result, free resources + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; +} + +napi_value NapiAtManager::VerifyAccessToken(napi_env env, napi_callback_info info) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "VerifyAccessToken begin."); + + auto *asyncContext = new AtManagerAsyncContext(); // for async work deliver data + if (asyncContext == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "new struct fail."); + return nullptr; + } + + ParseInputVerifyPermissionOrGetFlag(env, info, *asyncContext); + if (asyncContext->result == -1) { + delete asyncContext; + return nullptr; + } + + napi_value result = nullptr; + + napi_create_promise(env, &(asyncContext->deferred), &result); // create delay promise object + + napi_value resource = nullptr; // resource name + napi_create_string_utf8(env, "VerifyAccessToken", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work( // define work + env, nullptr, resource, VerifyAccessTokenExecute, VerifyAccessTokenComplete, + (void *)asyncContext, &(asyncContext->work)); + napi_queue_async_work(env, asyncContext->work); // add async work handle to the napi queue and wait for result + + ACCESSTOKEN_LOG_DEBUG(LABEL, "VerifyAccessToken end."); + + return result; +} + +void NapiAtManager::ParseInputGrantOrRevokePermission(const napi_env env, const napi_callback_info info, + AtManagerAsyncContext& asyncContext) +{ + size_t argc = 4; + + napi_value argv[4] = { 0 }; + napi_value thisVar = nullptr; + + void *data = nullptr; + + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); + + asyncContext.env = env; + + // parse input tokenId and permissionName + for (size_t i = 0; i < argc; i++) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[i], &valueType); + + if ((i == 0) && (valueType == napi_number)) { + napi_get_value_uint32(env, argv[i], &(asyncContext.tokenId)); // get tokenId + } else if (valueType == napi_string) { + napi_get_value_string_utf8(env, argv[i], asyncContext.permissionName, + VALUE_BUFFER_SIZE, &(asyncContext.pNameLen)); // get permissionName + } else if (valueType == napi_number) { + napi_get_value_int32(env, argv[i], &(asyncContext.flag)); // get flag + } else if (valueType == napi_function) { + napi_create_reference(env, argv[i], 1, &asyncContext.callbackRef); // get probably callback + } else { + ACCESSTOKEN_LOG_ERROR(LABEL, "Type matching failed"); + asyncContext.result = -1; + } + } + + ACCESSTOKEN_LOG_DEBUG(LABEL, "tokenID = %{public}d", asyncContext.tokenId); + ACCESSTOKEN_LOG_DEBUG(LABEL, "permissionName = %{public}s", asyncContext.permissionName); + ACCESSTOKEN_LOG_DEBUG(LABEL, "flag = %{public}d", asyncContext.flag); +} + +void NapiAtManager::GrantUserGrantedPermissionExcute(napi_env env, void *data) +{ + AtManagerAsyncContext* asyncContext = (AtManagerAsyncContext *)data; + PermissionDef permissionDef; + + // struct init, can not use = { 0 } or memset otherwise program crashdump + permissionDef.grantMode = 0; + permissionDef.availableLevel = APL_NORMAL; + permissionDef.provisionEnable = false; + permissionDef.distributedSceneEnable = false; + permissionDef.labelId = 0; + permissionDef.descriptionId = 0; + + // use innerkit class method to check if the permission grantmode is USER_GRANT-0 + AccessTokenKit::GetDefPermission(asyncContext->permissionName, permissionDef); + + ACCESSTOKEN_LOG_DEBUG(LABEL, "permissionName = %{public}s, grantmode = %{public}d.", asyncContext->permissionName, + permissionDef.grantMode); + + if (permissionDef.grantMode != USER_GRANT) { + // system_grant permission, return fail directly + asyncContext->result = ACCESSTOKEN_PERMISSION_GRANT_FAIL; + asyncContext->status = ASYN_THREAD_EXEC_SUCC; + } else { + // user_grant permission, use innerkit class method to grant permission + asyncContext->result = AccessTokenKit::GrantPermission(asyncContext->tokenId, + asyncContext->permissionName, + asyncContext->flag); + + ACCESSTOKEN_LOG_DEBUG(LABEL, + "tokenId = %{public}d, permissionName = %{public}s, flag = %{public}d, grant result = %{public}d.", + asyncContext->tokenId, asyncContext->permissionName, asyncContext->flag, asyncContext->result); + + // set status according to the innerkit class method return + if ((asyncContext->result == ACCESSTOKEN_PERMISSION_GRANT_SUCC) + || (asyncContext->result == ACCESSTOKEN_PERMISSION_GRANT_FAIL)) { + asyncContext->status = ASYN_THREAD_EXEC_SUCC; // success or failure regard as function exec success + } else { + asyncContext->status = ASYN_THREAD_EXEC_FAIL; // other regard as function exec failure + } + } +} + +void NapiAtManager::GrantUserGrantedPermissionComplete(napi_env env, napi_status status, void *data) +{ + AtManagerAsyncContext* asyncContext = (AtManagerAsyncContext*)data; + napi_value result = nullptr; + + if (asyncContext->status == ASYN_THREAD_EXEC_SUCC) { + // execute succ, consider asyncContext->result as return result + napi_create_int32(env, asyncContext->result, &result); + } else { + // execute fail, set default failure result + napi_create_int32(env, ACCESSTOKEN_PERMISSION_GRANT_FAIL, &result); + } + + if (asyncContext->deferred) { + // promise type + if (asyncContext->status == ASYN_THREAD_EXEC_SUCC) { + // innerkit class methon exec success, use resolve to return result + napi_resolve_deferred(env, asyncContext->deferred, result); + } else { + // innerkit class methon exec failure, use reject to return result + napi_reject_deferred(env, asyncContext->deferred, result); + } + } else { + // callback type + napi_value callback = nullptr; + napi_value thisValue = nullptr; // recv napi value + napi_value thatValue = nullptr; // result napi value + + // set call function params->napi_call_function(env, recv, func, argc, argv, result) + napi_get_undefined(env, &thisValue); // can not null otherwise js code can not get return + napi_create_int32(env, 0, &thatValue); // can not null otherwise js code can not get return + napi_get_reference_value(env, asyncContext->callbackRef, &callback); + napi_call_function(env, thisValue, callback, 1, &result, &thatValue); + napi_delete_reference(env, asyncContext->callbackRef); // release callback handle + } + + // after return the result, free resources + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; +} + +napi_value NapiAtManager::GrantUserGrantedPermission(napi_env env, napi_callback_info info) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "GrantUserGrantedPermission begin."); + + auto *asyncContext = new (std::nothrow) AtManagerAsyncContext(); // for async work deliver data + if (asyncContext == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "new struct fail."); + return nullptr; + } + + ParseInputGrantOrRevokePermission(env, info, *asyncContext); + if (asyncContext->result == -1) { + delete asyncContext; + return nullptr; + } + + napi_value result = nullptr; + + if (asyncContext->callbackRef == nullptr) { + // when callback null, create delay promise object for returning result in async work complete function + napi_create_promise(env, &(asyncContext->deferred), &result); + } else { + // callback not null, use callback type to return result + napi_get_undefined(env, &result); + } + + napi_value resource = nullptr; // resource name + napi_create_string_utf8(env, "GrantUserGrantedPermission", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work( // define work + env, nullptr, resource, GrantUserGrantedPermissionExcute, GrantUserGrantedPermissionComplete, + (void *)asyncContext, &(asyncContext->work)); + + napi_queue_async_work(env, asyncContext->work); // add async work handle to the napi queue and wait for result + + ACCESSTOKEN_LOG_DEBUG(LABEL, "GrantUserGrantedPermission end."); + + return result; +} + +void NapiAtManager::RevokeUserGrantedPermissionExcute(napi_env env, void *data) +{ + AtManagerAsyncContext* asyncContext = (AtManagerAsyncContext *)data; + PermissionDef permissionDef; + + // struct init, can not use = { 0 } or memset otherwise program crashdump + permissionDef.grantMode = 0; + permissionDef.availableLevel = APL_NORMAL; + permissionDef.provisionEnable = false; + permissionDef.distributedSceneEnable = false; + permissionDef.labelId = 0; + permissionDef.descriptionId = 0; + + // use innerkit class method to check if the permission grantmode is USER_GRANT-0 + AccessTokenKit::GetDefPermission(asyncContext->permissionName, permissionDef); + + ACCESSTOKEN_LOG_DEBUG(LABEL, "permissionName = %{public}s, grantmode = %{public}d.", asyncContext->permissionName, + permissionDef.grantMode); + + if (permissionDef.grantMode != USER_GRANT) { + // system_grant permission, return fail directly + asyncContext->result = ACCESSTOKEN_PERMISSION_REVOKE_FAIL; + asyncContext->status = ASYN_THREAD_EXEC_SUCC; + } else { + // user_grant permission, use innerkit class method to grant permission + asyncContext->result = AccessTokenKit::RevokePermission(asyncContext->tokenId, + asyncContext->permissionName, asyncContext->flag); + + ACCESSTOKEN_LOG_DEBUG(LABEL, + "tokenId = %{public}d, permissionName = %{public}s, flag = %{public}d, revoke result = %{public}d.", + asyncContext->tokenId, asyncContext->permissionName, asyncContext->flag, asyncContext->result); + + // set status according to the innerkit class method return + if ((asyncContext->result == ACCESSTOKEN_PERMISSION_REVOKE_SUCC) + || (asyncContext->result == ACCESSTOKEN_PERMISSION_REVOKE_FAIL)) { + asyncContext->status = ASYN_THREAD_EXEC_SUCC; // success or failure regard as function exec success + } else { + asyncContext->status = ASYN_THREAD_EXEC_FAIL; // other regard as function exec failure + } + } +} + +void NapiAtManager::RevokeUserGrantedPermissionComplete(napi_env env, napi_status status, void *data) +{ + AtManagerAsyncContext* asyncContext = (AtManagerAsyncContext*)data; + napi_value result = nullptr; + + if (asyncContext->status == ASYN_THREAD_EXEC_SUCC) { + // execute succ, consider asyncContext->result as return result + napi_create_int32(env, asyncContext->result, &result); + } else { + // execute fail, set default failure result + napi_create_int32(env, ACCESSTOKEN_PERMISSION_GRANT_FAIL, &result); + } + + if (asyncContext->deferred) { + // promise type + if (asyncContext->status == ASYN_THREAD_EXEC_SUCC) { + // innerkit class methon exec success, use resolve to return result + napi_resolve_deferred(env, asyncContext->deferred, result); + } else { + // innerkit class methon exec failure, use reject to return result + napi_reject_deferred(env, asyncContext->deferred, result); + } + } else { + // callback type + napi_value callback = nullptr; + napi_value thisValue = nullptr; // recv napi value + napi_value thatValue = nullptr; // result napi value + + // set call function params->napi_call_function(env, recv, func, argc, argv, result) + napi_get_undefined(env, &thisValue); // can not null otherwise js code can not get return + napi_create_int32(env, 0, &thatValue); // can not null otherwise js code can not get return + napi_get_reference_value(env, asyncContext->callbackRef, &callback); + napi_call_function(env, thisValue, callback, 1, &result, &thatValue); + napi_delete_reference(env, asyncContext->callbackRef); // release callback handle + } + + // after return the result, free resources + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; +} + +napi_value NapiAtManager::RevokeUserGrantedPermission(napi_env env, napi_callback_info info) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "RevokeUserGrantedPermission begin."); + + auto *asyncContext = new AtManagerAsyncContext(); // for async work deliver data + if (asyncContext == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "new struct fail."); + return nullptr; + } + + ParseInputGrantOrRevokePermission(env, info, *asyncContext); + if (asyncContext->result == -1) { + delete asyncContext; + return nullptr; + } + + napi_value result = nullptr; + + if (asyncContext->callbackRef == nullptr) { + // when callback null, create delay promise object for returning result in async work complete function + napi_create_promise(env, &(asyncContext->deferred), &result); + } else { + // callback not null, use callback type to return result + napi_get_undefined(env, &result); + } + + napi_value resource = nullptr; // resource name + napi_create_string_utf8(env, "RevokeUserGrantedPermission", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work( // define work + env, nullptr, resource, RevokeUserGrantedPermissionExcute, RevokeUserGrantedPermissionComplete, + (void *)asyncContext, &(asyncContext->work)); + + napi_queue_async_work(env, asyncContext->work); // add async work handle to the napi queue and wait for result + + ACCESSTOKEN_LOG_DEBUG(LABEL, "RevokeUserGrantedPermission end."); + + return result; +} + +void NapiAtManager::GetPermissionFlagsExcute(napi_env env, void *data) +{ + AtManagerAsyncContext* asyncContext = (AtManagerAsyncContext *)data; + + // use innerkit class method to get permission flag + asyncContext->flag = AccessTokenKit::GetPermissionFlag(asyncContext->tokenId, + asyncContext->permissionName); + asyncContext->status = ASYN_THREAD_EXEC_SUCC; // status default failure +} + +void NapiAtManager::GetPermissionFlagsComplete(napi_env env, napi_status status, void *data) +{ + AtManagerAsyncContext* asyncContext = (AtManagerAsyncContext*)data; + napi_value result; + + ACCESSTOKEN_LOG_DEBUG(LABEL, "permissionName = %{public}s, tokenId = %{public}d, flag = %{public}d.", + asyncContext->permissionName, asyncContext->tokenId, asyncContext->flag); + + if (asyncContext->status == ASYN_THREAD_EXEC_SUCC) { + // execute succ, use resolve to return result by the deferred create before + napi_create_int32(env, asyncContext->flag, &result); + napi_resolve_deferred(env, asyncContext->deferred, result); + } else { + // execute fail, this way may not match, but for code strict, still keep + napi_create_int32(env, asyncContext->flag, &result); + napi_reject_deferred(env, asyncContext->deferred, result); + } + + // after return the result, free resources + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; +} + +napi_value NapiAtManager::GetPermissionFlags(napi_env env, napi_callback_info info) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "GetPermissionFlags begin."); + + auto *asyncContext = new AtManagerAsyncContext(); // for async work deliver data + if (asyncContext == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "new struct fail."); + return nullptr; + } + + ParseInputVerifyPermissionOrGetFlag(env, info, *asyncContext); + if (asyncContext->result == -1) { + delete asyncContext; + return nullptr; + } + + napi_value result = nullptr; + + napi_create_promise(env, &(asyncContext->deferred), &result); // create delay promise object + + napi_value resource = nullptr; // resource name + napi_create_string_utf8(env, "VerifyAccessToken", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work( // define work + env, nullptr, resource, GetPermissionFlagsExcute, GetPermissionFlagsComplete, + (void *)asyncContext, &(asyncContext->work)); + napi_queue_async_work(env, asyncContext->work); // add async work handle to the napi queue and wait for result + + ACCESSTOKEN_LOG_DEBUG(LABEL, "GetPermissionFlags end."); + + return result; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +EXTERN_C_START +/* + * function for module exports + */ +static napi_value Init(napi_env env, napi_value exports) +{ + ACCESSTOKEN_LOG_DEBUG(OHOS::Security::AccessToken::LABEL, "Register end, start init."); + + return OHOS::Security::AccessToken::NapiAtManager::Init(env, exports); +} +EXTERN_C_END + +/* + * Module define + */ +static napi_module _module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "abilityAccessCtrl", + .nm_priv = ((void *)0), + .reserved = {0} +}; + +/* + * Module register function + */ +extern "C" __attribute__((constructor)) void AbilityAccessCtrlmoduleRegister(void) +{ + napi_module_register(&_module); +} diff --git a/ohos.build b/ohos.build index f8bc9d11fc3b32f44714844cd5f9e93365e2372e..dcd83476236ce9997c20f6f4f254893566b8819e 100644 --- a/ohos.build +++ b/ohos.build @@ -11,18 +11,39 @@ "name": "//base/security/access_token/interfaces/innerkits/accesstoken:libaccesstoken_sdk", "header": { "header_files": [ - "accesstoken.h", "accesstoken_kit.h" ], - "header_base": "//base/security/access_token/interfaces/innerkits/accesstoken/main/cpp/include" + "header_base": "//base/security/access_token/interfaces/innerkits/accesstoken/include" + } + }, + { + "name": "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", + "header": { + "header_files": [ + "nativetoken_kit.h" + ], + "header_base": "//base/security/access_token/interfaces/innerkits/nativetoken/include" + } + }, + { + "name": "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + "header": { + "header_files": [ + "token_setproc.h" + ], + "header_base": "//base/security/access_token/interfaces/innerkits/token_setproc/include" } } ], "module_list": [ - "//base/security/access_token:accesstoken_build_module_standard" + "//base/security/access_token:accesstoken_build_module", + "//base/security/access_token:tokensync_build_module" ], "test_list": [ - "//base/security/access_token:accesstoken_build_module_standard_test" + "//base/security/access_token:accesstoken_build_module_test", + "//base/security/access_token/interfaces/innerkits/accesstoken/test:unittest", + "//base/security/access_token/interfaces/innerkits/nativetoken/test:unittest", + "//base/security/access_token/interfaces/innerkits/token_setproc/test:unittest" ] } } diff --git a/services/accesstoken/main/cpp/src/accesstoken_manager_service.cpp b/services/accesstoken/main/cpp/src/accesstoken_manager_service.cpp deleted file mode 100644 index 2b4bda1093836067b613bb27d0a177437d82c90d..0000000000000000000000000000000000000000 --- a/services/accesstoken/main/cpp/src/accesstoken_manager_service.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2021 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_manager_service.h" - -#include "accesstoken.h" -#include "accesstoken_log.h" - -namespace OHOS { -namespace Security { -namespace AccessToken { -namespace { -static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenManagerService"}; -} - -const bool REGISTER_RESULT = - SystemAbility::MakeAndRegisterAbility(DelayedSingleton::GetInstance().get()); - -AccessTokenManagerService::AccessTokenManagerService() - : SystemAbility(SA_ID_ACCESSTOKEN_MANAGER_SERVICE, true), state_(ServiceRunningState::STATE_NOT_START) -{ - ACCESSTOKEN_LOG_INFO(LABEL, "AccessTokenManagerService()"); -} - -AccessTokenManagerService::~AccessTokenManagerService() -{ - ACCESSTOKEN_LOG_INFO(LABEL, "~AccessTokenManagerService()"); -} - -void AccessTokenManagerService::OnStart() -{ - if (state_ == ServiceRunningState::STATE_RUNNING) { - ACCESSTOKEN_LOG_INFO(LABEL, "AccessTokenManagerService has already started!"); - return; - } - ACCESSTOKEN_LOG_INFO(LABEL, "AccessTokenManagerService is starting"); - if (!Initialize()) { - ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to initialize"); - return; - } - state_ = ServiceRunningState::STATE_RUNNING; - bool ret = Publish(DelayedSingleton::GetInstance().get()); - if (!ret) { - ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to publish service!"); - return; - } - ACCESSTOKEN_LOG_INFO(LABEL, "Congratulations, AccessTokenManagerService start successfully!"); -} - -void AccessTokenManagerService::OnStop() -{ - ACCESSTOKEN_LOG_INFO(LABEL, "stop service"); - state_ = ServiceRunningState::STATE_NOT_START; -} - -int AccessTokenManagerService::VerifyAccesstoken(AccessTokenID tokenID, const std::string &permissionName) -{ - ACCESSTOKEN_LOG_INFO(LABEL, - "%{public}s called, tokenID: %{public}d, permissionName: %{public}s", __func__, - tokenID, permissionName.c_str()); - return PERMISSION_GRANTED; -} - -bool AccessTokenManagerService::Initialize() const -{ - return true; -} -} // namespace AccessToken -} // namespace Security -} // namespace OHOS \ No newline at end of file diff --git a/services/accesstokenmanager/BUILD.gn b/services/accesstokenmanager/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..62358bea192b55648977a879be6d73c4eaa8efd6 --- /dev/null +++ b/services/accesstokenmanager/BUILD.gn @@ -0,0 +1,82 @@ +# Copyright (c) 2021 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. + +import("//build/ohos.gni") + +ohos_prebuilt_etc("access_token.rc") { + source = "access_token.cfg" + relative_install_dir = "init" + subsystem_name = "security" + part_name = "access_token" +} + +ohos_shared_library("accesstoken_manager_service") { + subsystem_name = "security" + part_name = "access_token" + + include_dirs = [ + "main/cpp/include/service", + "main/cpp/include/token", + "main/cpp/include/permission", + "main/cpp/include/database", + "//utils/system/safwk/native/include", + "//base/security/access_token/frameworks/common/include", + "//base/security/access_token/frameworks/accesstoken/include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", + "//base/security/access_token/interfaces/innerkits/tokensync/include", + "//third_party/json/include", + ] + + sources = [ + "main/cpp/src/database/data_storage.cpp", + "main/cpp/src/database/data_translator.cpp", + "main/cpp/src/database/generic_values.cpp", + "main/cpp/src/database/sqlite_helper.cpp", + "main/cpp/src/database/sqlite_storage.cpp", + "main/cpp/src/database/statement.cpp", + "main/cpp/src/database/variant_value.cpp", + "main/cpp/src/permission/permission_definition_cache.cpp", + "main/cpp/src/permission/permission_manager.cpp", + "main/cpp/src/permission/permission_policy_set.cpp", + "main/cpp/src/permission/permission_validator.cpp", + "main/cpp/src/service/accesstoken_manager_service.cpp", + "main/cpp/src/service/accesstoken_manager_stub.cpp", + "main/cpp/src/token/accesstoken_id_manager.cpp", + "main/cpp/src/token/accesstoken_info_manager.cpp", + "main/cpp/src/token/accesstoken_remote_token_manager.cpp", + "main/cpp/src/token/hap_token_info_inner.cpp", + "main/cpp/src/token/native_token_info_inner.cpp", + "main/cpp/src/token/native_token_receptor.cpp", + "main/cpp/src/token/token_modify_notifier.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + deps = [ + #"//base/security/accesstoken/frameworks/accesstooken/permissioncommunicationadapter:permission_standard_communication_adapter_cxx", + #"//base/security/accesstoken/frameworks/accesstooken/common:permission_standard_infrastructure_cxx", + "//base/security/access_token/frameworks/accesstoken:accesstoken_communication_adapter_cxx", + "//base/security/access_token/frameworks/common:accesstoken_common_cxx", + "//base/security/access_token/interfaces/innerkits/tokensync:libtokensync_sdk", + "//base/security/access_token/services/accesstokenmanager:access_token.rc", + "//third_party/sqlite:sqlite", + "//utils/native/base:utils", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] +} diff --git a/services/accesstokenmanager/access_token.cfg b/services/accesstokenmanager/access_token.cfg new file mode 100644 index 0000000000000000000000000000000000000000..b790a72f0f0fa1f173410a5c8c23b2c800c34d45 --- /dev/null +++ b/services/accesstokenmanager/access_token.cfg @@ -0,0 +1,18 @@ +{ + "jobs" : [{ + "name" : "pre-init", + "cmds" : [ + "mkdir /data/service/el0/access_token 0750 root system", + "load_access_token_id " + ] + } + ], + "services" : [{ + "name" : "accesstoken_service", + "path" : ["/system/bin/sa_main", "/system/profile/accesstoken_service.xml"], + "importance" : -20, + "uid" : "system", + "gid" : ["system"] + } + ] +} diff --git a/services/accesstokenmanager/access_token.rc b/services/accesstokenmanager/access_token.rc new file mode 100644 index 0000000000000000000000000000000000000000..68b9f548b6f5f31b3fc30abc1da6be5c14c380d4 --- /dev/null +++ b/services/accesstokenmanager/access_token.rc @@ -0,0 +1,22 @@ +# Copyright (C) 2021 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. + +on late-fs + start accesstoken_service + +service accesstoken_service /system/bin/sa_main /system/profile/accesstoken_service.xml + class accesstoken_service + priority -20 + user system + group system + seclabel u:r:accesstoken_service:s0 diff --git a/services/accesstokenmanager/main/cpp/include/database/data_storage.h b/services/accesstokenmanager/main/cpp/include/database/data_storage.h new file mode 100644 index 0000000000000000000000000000000000000000..9233596bbb9931ea52eb3fb95d6d6a7f5a9bf01a --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/database/data_storage.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 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 DATA_STORAGE_H +#define DATA_STORAGE_H + +#include +#include + +#include "generic_values.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class DataStorage { +public: + enum DataType { + ACCESSTOKEN_HAP_INFO, + ACCESSTOKEN_NATIVE_INFO, + ACCESSTOKEN_PERMISSION_DEF, + ACCESSTOKEN_PERMISSION_STATE, + }; + + static DataStorage& GetRealDataStorage(); + + virtual ~DataStorage() = default; + + virtual int Add(const DataType type, const std::vector& values) = 0; + + virtual int Remove(const DataType type, const GenericValues& conditions) = 0; + + virtual int Modify(const DataType type, const GenericValues& modifyValues, const GenericValues& conditions) = 0; + + virtual int Find(const DataType type, std::vector& results) = 0; + + virtual int RefreshAll(const DataType type, const std::vector& values) = 0; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // DATA_STORAGE_H diff --git a/services/accesstokenmanager/main/cpp/include/database/data_translator.h b/services/accesstokenmanager/main/cpp/include/database/data_translator.h new file mode 100644 index 0000000000000000000000000000000000000000..1be472818eab2de3bcd06bb96afd0ecceabfcb71 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/database/data_translator.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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 DATA_TRANSLATOR_H +#define DATA_TRANSLATOR_H + +#include + +#include "hap_token_info_inner.h" +#include "native_token_info_inner.h" +#include "generic_values.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class DataTranslator final { +public: + static int TranslationIntoGenericValues(const PermissionDef& inPermissionDef, GenericValues& outGenericValues); + static int TranslationIntoPermissionDef(const GenericValues& inGenericValues, PermissionDef& outPermissionDef); + static int TranslationIntoGenericValues(const PermissionStateFull& inPermissionState, + const unsigned int grantIndex, GenericValues& outGenericValues); + static int TranslationIntoPermissionStateFull(const GenericValues& inGenericValues, + PermissionStateFull& outPermissionState); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // DATA_TRANSLATOR_H diff --git a/services/accesstokenmanager/main/cpp/include/database/field_const.h b/services/accesstokenmanager/main/cpp/include/database/field_const.h new file mode 100644 index 0000000000000000000000000000000000000000..a73a3a9d314fda1c6c70ad8461ab5681645cf8b4 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/database/field_const.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 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 FIELD_CONST_H +#define FIELD_CONST_H + +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +const std::string FIELD_TOKEN_ID = "token_id"; +const std::string FIELD_USER_ID = "user_id"; +const std::string FIELD_BUNDLE_NAME = "bundle_name"; +const std::string FIELD_INST_INDEX = "inst_index"; +const std::string FIELD_APP_ID = "app_id"; +const std::string FIELD_DEVICE_ID = "device_id"; +const std::string FIELD_APL = "apl"; +const std::string FIELD_TOKEN_VERSION = "token_version"; +const std::string FIELD_TOKEN_ATTR = "token_attr"; +const std::string FIELD_PROCESS_NAME = "process_name"; +const std::string FIELD_DCAP = "dcap"; +const std::string FIELD_PERMISSION_NAME = "permission_name"; +const std::string FIELD_GRANT_MODE = "grant_mode"; +const std::string FIELD_AVAILABLE_LEVEL = "available_level"; +const std::string FIELD_PROVISION_ENABLE = "provision_enable"; +const std::string FIELD_DISTRIBUTED_SCENE_ENABLE = "distributed_scene_enable"; +const std::string FIELD_LABEL = "label"; +const std::string FIELD_LABEL_ID = "label_id"; +const std::string FIELD_DESCRIPTION = "description"; +const std::string FIELD_DESCRIPTION_ID = "description_id"; +const std::string FIELD_GRANT_STATE = "grant_state"; +const std::string FIELD_GRANT_FLAG = "grant_flag"; +const std::string FIELD_GRANT_IS_GENERAL = "is_general"; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // FIELD_CONST_H diff --git a/services/accesstokenmanager/main/cpp/include/database/generic_values.h b/services/accesstokenmanager/main/cpp/include/database/generic_values.h new file mode 100644 index 0000000000000000000000000000000000000000..55c6b7ba64fb1636c2585dde5000811bb9120ed8 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/database/generic_values.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 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 GENERIC_VALUES_H +#define GENERIC_VALUES_H + +#include +#include +#include + +#include "variant_value.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class GenericValues final { +public: + GenericValues() = default; + virtual ~GenericValues() = default; + + void Put(const std::string& key, int value); + + void Put(const std::string& key, const std::string& value); + + void Put(const std::string& key, const VariantValue& value); + + std::vector GetAllKeys() const; + + VariantValue Get(const std::string& key) const; + + int GetInt(const std::string& key) const; + + std::string GetString(const std::string& key) const; + +private: + std::map map_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // GENERIC_VALUES_H diff --git a/services/accesstokenmanager/main/cpp/include/database/sqlite_helper.h b/services/accesstokenmanager/main/cpp/include/database/sqlite_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..003859839211d37a85d318c30ef86e0b148ebe9a --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/database/sqlite_helper.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 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 SQLITE_HELPER_H +#define SQLITE_HELPER_H + +#include + +#include "statement.h" + +#include "sqlite3sym.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class SqliteHelper { +public: + explicit SqliteHelper(const std::string& dbName, const std::string& dbPath, int version); + virtual ~SqliteHelper(); + + void Open(); + void Close(); + + int BeginTransaction() const; + int CommitTransaction() const; + int RollbackTransaction() const; + + Statement Prepare(const std::string& sql) const; + int ExecuteSql(const std::string& sql) const; + std::string SpitError() const; + + virtual void OnCreate() = 0; + virtual void OnUpdate() = 0; + +private: + inline static const std::string PRAGMA_VERSION_COMMAND = "PRAGMA user_version"; + static const int GENERAL_ERROR = -1; + + const std::string dbName_; + const std::string dbPath_; + int currentVersion_; + sqlite3* db_; + + int GetVersion() const; + void SetVersion() const; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // SQLITE_HELPER_H diff --git a/services/accesstokenmanager/main/cpp/include/database/sqlite_storage.h b/services/accesstokenmanager/main/cpp/include/database/sqlite_storage.h new file mode 100644 index 0000000000000000000000000000000000000000..5aeb7871341fbd0d0d4f0762a3ca69704a9d2885 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/database/sqlite_storage.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 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 SQLITE_STORAGE_H +#define SQLITE_STORAGE_H + +#include "data_storage.h" +#include "sqlite_helper.h" +#include "field_const.h" + +#include "nocopyable.h" +#include "rwlock.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class SqliteStorage : public DataStorage, public SqliteHelper { +public: + enum ExecuteResult { FAILURE = -1, SUCCESS }; + + struct SqliteTable { + public: + std::string tableName_; + std::vector tableColumnNames_; + }; + + static SqliteStorage& GetInstance(); + + ~SqliteStorage() override; + + int Add(const DataType type, const std::vector& values) override; + + int Remove(const DataType type, const GenericValues& conditions) override; + + int Modify(const DataType type, const GenericValues& modifyValues, const GenericValues& conditions) override; + + int Find(const DataType type, std::vector& results) override; + + int RefreshAll(const DataType type, const std::vector& values) override; + + void OnCreate() override; + void OnUpdate() override; + +private: + SqliteStorage(); + DISALLOW_COPY_AND_MOVE(SqliteStorage); + + std::map dataTypeToSqlTable_; + OHOS::Utils::RWLock rwLock_; + + int CreateHapTokenInfoTable() const; + int CreateNativeTokenInfoTable() const; + int CreatePermissionDefinitionTable() const; + int CreatePermissionStateTable() const; + + std::string CreateInsertPrepareSqlCmd(const DataType type) const; + std::string CreateDeletePrepareSqlCmd( + const DataType type, const std::vector& columnNames = std::vector()) const; + std::string CreateUpdatePrepareSqlCmd(const DataType type, const std::vector& modifyColumns, + const std::vector& conditionColumns) const; + std::string CreateSelectPrepareSqlCmd(const DataType type) const; + +private: + inline static const std::string HAP_TOKEN_INFO_TABLE = "hap_token_info_table"; + inline static const std::string NATIVE_TOKEN_INFO_TABLE = "native_token_info_table"; + inline static const std::string PERMISSION_DEF_TABLE = "permission_definition_table"; + inline static const std::string PERMISSION_STATE_TABLE = "permission_state_table"; + inline static const std::string DATABASE_NAME = "access_token.db"; + inline static const std::string DATABASE_PATH = "/data/system/"; + static const int DATABASE_VERSION = 1; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // SQLITE_STORAGE_H diff --git a/services/accesstokenmanager/main/cpp/include/database/statement.h b/services/accesstokenmanager/main/cpp/include/database/statement.h new file mode 100644 index 0000000000000000000000000000000000000000..e84ec0b2fe71f814c82843855dbd9703d4626127 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/database/statement.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 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 STATEMENT_H +#define STATEMENT_H + +#include + +#include "variant_value.h" + +#include "sqlite3sym.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class Statement final { +public: + enum State { BUSY, ROW, DONE, MISUSE, UNKNOWN }; + + Statement(sqlite3* db, const std::string& sql); + virtual ~Statement(); + + void Bind(const int index, const std::string& text); + void Bind(const int index, int value); + void Bind(const std::string& tableColumnName, const VariantValue& value); + + State Step(); + int Reset(); + + std::string GetColumnString(const int column) const; + int GetColumnInt(const int column) const; + std::string GetColumnName(const int column) const; + int GetParameterIndex(const std::string& name) const; + int GetColumnCount() const; + VariantValue GetValue(const int column) const; + +private: + sqlite3* db_; + sqlite3_stmt* statement_; + const std::string sql_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // STATEMENT_H diff --git a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_client.h b/services/accesstokenmanager/main/cpp/include/database/variant_value.h old mode 100755 new mode 100644 similarity index 59% rename from interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_client.h rename to services/accesstokenmanager/main/cpp/include/database/variant_value.h index 758e6f59845c8e89cb35b70631ef84390d8efa91..cfb16f8e1648b814d8bf923d7582c5a36a5294b9 --- a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_client.h +++ b/services/accesstokenmanager/main/cpp/include/database/variant_value.h @@ -13,32 +13,40 @@ * limitations under the License. */ -#ifndef ACCESSTOKEN_MANAGER_CLIENT_H -#define ACCESSTOKEN_MANAGER_CLIENT_H +#ifndef VARIANT_VALUE_H +#define VARIANT_VALUE_H #include - -#include "i_accesstoken_manager.h" -#include "nocopyable.h" +#include namespace OHOS { namespace Security { namespace AccessToken { -class AccessTokenManagerClient final { +enum class ValueType { + TYPE_NULL, + TYPE_INT, + TYPE_STRING, +}; + +class VariantValue final { public: - static AccessTokenManagerClient& GetInstance(); + VariantValue(); + virtual ~VariantValue(); - virtual ~AccessTokenManagerClient(); + explicit VariantValue(int value); + explicit VariantValue(const std::string& value); - int VerifyAccesstoken(AccessTokenID tokenID, const std::string& permissionName) const; -private: - AccessTokenManagerClient(); + ValueType GetType() const; + int GetInt() const; + std::string GetString() const; - DISALLOW_COPY_AND_MOVE(AccessTokenManagerClient); + static const int DEFAULT_VALUE = -1; - sptr GetProxy() const; +private: + ValueType type_; + std::variant value_; }; } // namespace AccessToken } // namespace Security } // namespace OHOS -#endif // ACCESSTOKEN_MANAGER_CLIENT_H +#endif // VARIANT_VALUE_H diff --git a/services/accesstokenmanager/main/cpp/include/permission/permission_definition_cache.h b/services/accesstokenmanager/main/cpp/include/permission/permission_definition_cache.h new file mode 100644 index 0000000000000000000000000000000000000000..969509549fa13748ead6a52ffc47dce33b82ec83 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/permission/permission_definition_cache.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 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 PERMISSION_DEFINITION_CACHE_H +#define PERMISSION_DEFINITION_CACHE_H + +#include +#include + +#include "permission_def.h" + +#include "rwlock.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class PermissionDefinitionCache final { +public: + static PermissionDefinitionCache& GetInstance(); + + virtual ~PermissionDefinitionCache(); + + bool Insert(const PermissionDef& info); + + bool Update(const PermissionDef& info); + + void DeleteByBundleName(const std::string& bundleName); + + int FindByPermissionName(const std::string& permissionName, PermissionDef& info); + + bool IsSystemGrantedPermission(const std::string& permissionName); + + bool IsUserGrantedPermission(const std::string& permissionName); + + bool HasDefinition(const std::string& permissionName); + +private: + PermissionDefinitionCache(); + + bool IsGrantedModeEqualInner(const std::string& permissionName, int grantMode) const; + + DISALLOW_COPY_AND_MOVE(PermissionDefinitionCache); + + /** + * key: the permission name. + * value: the object of PermissionDef. + */ + std::map permissionDefinitionMap_; + + OHOS::Utils::RWLock cacheLock_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_DEFINITION_CACHE_H diff --git a/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..fcc3087cc2f0876d193a737b6fe6937ffc146a39 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/permission/permission_manager.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 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 PERMISSION_MANAGER_H +#define PERMISSION_MANAGER_H + +#include +#include + +#include "access_token.h" +#include "hap_token_info_inner.h" +#include "permission_def.h" +#include "permission_state_full.h" + +#include "rwlock.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class PermissionManager final { +public: + static PermissionManager& GetInstance(); + virtual ~PermissionManager(); + + void AddDefPermissions(std::shared_ptr tokenInfo, bool updateFlag); + void RemoveDefPermissions(AccessTokenID tokenID); + int VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName); + int GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult); + int GetDefPermissions(AccessTokenID tokenID, std::vector& permList); + int GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant); + int GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName); + void GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag); + void RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag); + void ClearUserGrantedPermissionState(AccessTokenID tokenID); +private: + PermissionManager(); + void UpdateTokenPermissionState( + AccessTokenID tokenID, const std::string& permissionName, bool isGranted, int flag); + std::string TransferPermissionDefToString(const PermissionDef& inPermissionDef); + + DISALLOW_COPY_AND_MOVE(PermissionManager); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_MANAGER_H diff --git a/services/accesstokenmanager/main/cpp/include/permission/permission_policy_set.h b/services/accesstokenmanager/main/cpp/include/permission/permission_policy_set.h new file mode 100644 index 0000000000000000000000000000000000000000..3208b6f2072f86c1530b9f8fab7a650bee63499a --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/permission/permission_policy_set.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 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 PERMISSION_POLICY_SET_H +#define PERMISSION_POLICY_SET_H + +#include +#include +#include + +#include "access_token.h" +#include "generic_values.h" +#include "permission_def.h" +#include "permission_state_full.h" +#include "rwlock.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct PermissionPolicySet final { +public: + PermissionPolicySet() : tokenId_(0) {}; + virtual ~PermissionPolicySet(); + + static std::shared_ptr BuildPermissionPolicySet(AccessTokenID tokenId, + const std::vector& permList, const std::vector& permStateList); + static std::shared_ptr RestorePermissionPolicy(AccessTokenID tokenId, + const std::vector& permDefRes, const std::vector& permStateRes); + void StorePermissionPolicySet(std::vector& permDefValueList, + std::vector& permStateValueList); + void Update(const std::vector& permList, const std::vector& permStateList); + + int VerifyPermissStatus(const std::string& permissionName); + void GetDefPermissions(std::vector& permList); + void GetPermissionStateFulls(std::vector& permList); + int QueryPermissionFlag(const std::string& permissionName); + void UpdatePermissionStatus(const std::string& permissionName, bool isGranted, int flag); + void ToString(std::string& info); + void GetPermissionStateList(std::vector& stateList); + +private: + static void MergePermissionStateFull(std::vector& permStateList, + const PermissionStateFull& state); + void UpdatePermStateFull(const PermissionStateFull& permOld, PermissionStateFull& permNew); + void StorePermissionDef(std::vector& valueList) const; + void StorePermissionState(std::vector& valueList) const; + void PermDefToString(const PermissionDef& def, std::string& info) const; + void PermStateFullToString(const PermissionStateFull& state, std::string& info) const; + + OHOS::Utils::RWLock permPolicySetLock_; + std::vector permList_; + std::vector permStateList_; + AccessTokenID tokenId_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_POLICY_SET_H + diff --git a/services/accesstokenmanager/main/cpp/include/permission/permission_validator.h b/services/accesstokenmanager/main/cpp/include/permission/permission_validator.h new file mode 100644 index 0000000000000000000000000000000000000000..99dad5945bc90c0c8c5397c1af0c2e8b1f9a249d --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/permission/permission_validator.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 PERMISSION_VALIDATOR_H +#define PERMISSION_VALIDATOR_H +#include "permission_def.h" +#include "permission_state_full.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct PermissionValidator final { +public: + PermissionValidator() {}; + ~PermissionValidator() {}; + + static bool IsPermissionNameValid(const std::string& permissionName); + static bool IsPermissionFlagValid(int flag); + static bool IsPermissionDefValid(const PermissionDef& permDef); + static bool IsPermissionStateValid(const PermissionStateFull& permState); + static void FilterInvalidPermisionDef( + const std::vector& permList, std::vector& result); + static void FilterInvalidPermisionState( + const std::vector& permList, std::vector& result); + static bool IsGrantModeValid(int grantMode); + static bool IsGrantStatusValid(int grantStaus); +private: + static void DeduplicateResDevID(const PermissionStateFull& permState, PermissionStateFull& result); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_VALIDATOR_H + diff --git a/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h new file mode 100644 index 0000000000000000000000000000000000000000..cbb3cfa143bfe2c8263872da670c478911df9d48 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_service.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021 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_MANAGER_SERVICE_H +#define ACCESSTOKEN_MANAGER_SERVICE_H + +#include +#include + +#include "accesstoken_manager_stub.h" +#include "iremote_object.h" +#include "nocopyable.h" +#include "singleton.h" +#include "system_ability.h" +#include "hap_token_info.h" +#include "access_token.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; +class AccessTokenManagerService final : public SystemAbility, public AccessTokenManagerStub { + DECLARE_DELAYED_SINGLETON(AccessTokenManagerService); + DECLEAR_SYSTEM_ABILITY(AccessTokenManagerService); + +public: + void OnStart() override; + void OnStop() override; + + AccessTokenIDEx AllocHapToken(const HapInfoParcel& info, const HapPolicyParcel& policy) override; + int VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) override; + int GetDefPermission(const std::string& permissionName, PermissionDefParcel& permissionDefResult) override; + int GetDefPermissions(AccessTokenID tokenID, std::vector& permList) override; + int GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) 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; + int ClearUserGrantedPermissionState(AccessTokenID tokenID) override; + int DeleteToken(AccessTokenID tokenID) override; + int GetTokenType(AccessTokenID tokenID) override; + int CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) override; + AccessTokenID GetHapTokenID(int userID, const std::string& bundleName, int instIndex) override; + AccessTokenID AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID) override; + int GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfoParcel& InfoParcel) override; + int GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfoParcel& InfoParcel) override; + int UpdateHapToken(AccessTokenID tokenID, + const std::string& appIDDesc, const HapPolicyParcel& policyParcel) override; + int GetHapTokenInfoFromRemote(AccessTokenID tokenID, HapTokenInfoForSyncParcel& hapSyncParcel) override; + int GetAllNativeTokenInfo(std::vector& nativeTokenInfosRes) override; + int SetRemoteHapTokenInfo(const std::string& deviceID, HapTokenInfoForSyncParcel& hapSyncParcel) override; + int SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoParcel) override; + int DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) override; + int DeleteRemoteDeviceTokens(const std::string& deviceID) override; + + int DumpToken(std::string& dumpInfo) override; +private: + bool Initialize() const; + + ServiceRunningState state_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_MANAGER_SERVICE_H diff --git a/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_stub.h b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..c4fbb77e17aad1acf09db4d25745008f0cb1b968 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/service/accesstoken_manager_stub.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 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_MANAGER_STUB_H +#define ACCESSTOKEN_MANAGER_STUB_H + +#include "i_accesstoken_manager.h" + +#include + +#include "iremote_stub.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class AccessTokenManagerStub : public IRemoteStub { +public: + AccessTokenManagerStub(); + virtual ~AccessTokenManagerStub(); + + int OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& options) override; + +private: + void VerifyAccessTokenInner(MessageParcel& data, MessageParcel& reply); + void GetDefPermissionInner(MessageParcel& data, MessageParcel& reply); + void GetDefPermissionsInner(MessageParcel& data, MessageParcel& reply); + void GetReqPermissionsInner(MessageParcel& data, MessageParcel& reply); + void GetPermissionFlagInner(MessageParcel& data, MessageParcel& reply); + void GrantPermissionInner(MessageParcel& data, MessageParcel& reply); + void RevokePermissionInner(MessageParcel& data, MessageParcel& reply); + void ClearUserGrantedPermissionStateInner(MessageParcel& data, MessageParcel& reply); + void AllocHapTokenInner(MessageParcel& data, MessageParcel& reply); + void DeleteTokenInfoInner(MessageParcel& data, MessageParcel& reply); + void AllocNativeTokenInner(MessageParcel& data, MessageParcel& reply); + void UpdateHapTokenInner(MessageParcel& data, MessageParcel& reply); + void GetHapTokenInfoInner(MessageParcel& data, MessageParcel& reply); + void GetNativeTokenInfoInner(MessageParcel& data, MessageParcel& reply); + void AllocLocalTokenIDInner(MessageParcel& data, MessageParcel& reply); + void GetHapTokenIDInner(MessageParcel& data, MessageParcel& reply); + void CheckNativeDCapInner(MessageParcel& data, MessageParcel& reply); + void GetTokenTypeInner(MessageParcel& data, MessageParcel& reply); + + void GetHapTokenInfoFromRemoteInner(MessageParcel& data, MessageParcel& reply); + void GetAllNativeTokenInfoInner(MessageParcel& data, MessageParcel& reply); + void SetRemoteHapTokenInfoInner(MessageParcel& data, MessageParcel& reply); + void SetRemoteNativeTokenInfoInner(MessageParcel& data, MessageParcel& reply); + void DeleteRemoteTokenInner(MessageParcel& data, MessageParcel& reply); + void DeleteRemoteDeviceTokensInner(MessageParcel& data, MessageParcel& reply); + void GetRemoteHapTokenIDInner(MessageParcel& data, MessageParcel& reply); + void DumpTokenInner(MessageParcel& data, MessageParcel& reply); + + bool IsAuthorizedCalling() const; + static const int SYSTEM_UID = 1000; + static const int ROOT_UID = 0; + + using RequestFuncType = void (AccessTokenManagerStub::*)(MessageParcel &data, MessageParcel &reply); + std::map requestFuncMap_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_MANAGER_STUB_H diff --git a/services/accesstokenmanager/main/cpp/include/token/accesstoken_id_manager.h b/services/accesstokenmanager/main/cpp/include/token/accesstoken_id_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..336228323a1b2a4ebd43a392d090c0bf51a7edab --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/token/accesstoken_id_manager.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 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_TOKEN_ID_MANAGER_H +#define ACCESSTOKEN_TOKEN_ID_MANAGER_H + +#include +#include + +#include "access_token.h" +#include "nocopyable.h" +#include "rwlock.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +static constexpr unsigned int TOKEN_RANDOM_MASK = (1 << 24) - 1; +static const int MAX_CREATE_TOKEN_ID_RETRY = 2; + +class AccessTokenIDManager final { +public: + static AccessTokenIDManager& GetInstance(); + virtual ~AccessTokenIDManager() = default; + + int AddTokenId(AccessTokenID id, ATokenTypeEnum type); + AccessTokenID CreateAndRegisterTokenId(ATokenTypeEnum type); + int RegisterTokenId(AccessTokenID id, ATokenTypeEnum type); + void ReleaseTokenId(AccessTokenID id); + ATokenTypeEnum GetTokenIdType(AccessTokenID id); + static ATokenTypeEnum GetTokenIdTypeEnum(AccessTokenID id); + +private: + AccessTokenIDManager() = default; + DISALLOW_COPY_AND_MOVE(AccessTokenIDManager); + AccessTokenID CreateTokenId(ATokenTypeEnum type) const; + + OHOS::Utils::RWLock tokenIdLock_; + std::set tokenIdSet_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_TOKEN_ID_MANAGER_H diff --git a/services/accesstokenmanager/main/cpp/include/token/accesstoken_info_manager.h b/services/accesstokenmanager/main/cpp/include/token/accesstoken_info_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..3c43293803adb1d97c5664dcd2ec5cfd58f2e193 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/token/accesstoken_info_manager.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 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_TOKEN_INFO_MANAGER_H +#define ACCESSTOKEN_TOKEN_INFO_MANAGER_H + +#include +#include +#include + +#include "access_token.h" +#include "hap_token_info.h" +#include "hap_token_info_inner.h" +#include "native_token_info.h" +#include "native_token_info_inner.h" +#include "nocopyable.h" +#include "rwlock.h" +#include "thread_pool.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class AccessTokenInfoManager final { +public: + static AccessTokenInfoManager& GetInstance(); + ~AccessTokenInfoManager(); + void Init(); + std::shared_ptr GetHapTokenInfoInner(AccessTokenID id); + int GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo& InfoParcel); + std::shared_ptr GetNativeTokenInfoInner(AccessTokenID id); + int GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& InfoParcel); + std::shared_ptr GetHapPermissionPolicySet(AccessTokenID id); + int RemoveHapTokenInfo(AccessTokenID id); + int RemoveNativeTokenInfo(AccessTokenID id); + int CreateHapTokenInfo(const HapInfoParams& info, const HapPolicyParams& policy, AccessTokenIDEx& tokenIdEx); + int CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap); + AccessTokenID GetHapTokenID(int userID, const std::string& bundleName, int instIndex); + AccessTokenID AllocLocalTokenID(const std::string& remoteDeviceID, AccessTokenID remoteTokenID); + void ProcessNativeTokenInfos(const std::vector>& tokenInfos); + int UpdateHapToken(AccessTokenID tokenID, const std::string& appIDDesc, const HapPolicyParams& policy); + void Dump(std::string& dumpInfo); + void RefreshTokenInfoIfNeeded(); + + /* tokensync needed */ + int GetHapTokenSync(AccessTokenID tokenID, HapTokenInfoForSync& hapSync); + int GetHapTokenInfoFromRemote(AccessTokenID tokenID, + HapTokenInfoForSync& hapSync); + void GetAllNativeTokenInfo(std::vector& nativeTokenInfosRes); + int SetRemoteHapTokenInfo(const std::string& deviceID, HapTokenInfoForSync& hapSync); + int SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoList); + int DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID); + int DeleteRemoteDeviceTokens(const std::string& deviceID); + +private: + AccessTokenInfoManager(); + DISALLOW_COPY_AND_MOVE(AccessTokenInfoManager); + + void InitHapTokenInfos(); + void InitNativeTokenInfos(); + int AddHapTokenInfo(const std::shared_ptr& info); + int AddNativeTokenInfo(const std::shared_ptr& info); + std::string GetHapUniqueStr(const std::shared_ptr& info) const; + std::string GetHapUniqueStr(const int& userID, const std::string& bundleName, const int& instIndex) const; + bool TryUpdateExistNativeToken(const std::shared_ptr& infoPtr); + int AllocNativeToken(const std::shared_ptr& infoPtr); + void StoreAllTokenInfo(); + int CreateRemoteHapTokenInfo(AccessTokenID mapID, HapTokenInfoForSync& hapSync); + int UpdateRemoteHapTokenInfo(AccessTokenID mapID, HapTokenInfoForSync& hapSync); + + OHOS::ThreadPool tokenDataWorker_; + bool hasInited_; + + OHOS::Utils::RWLock hapTokenInfoLock_; + OHOS::Utils::RWLock nativeTokenInfoLock_; + OHOS::Utils::RWLock managerLock_; + + std::map> hapTokenInfoMap_; + std::map hapTokenIdMap_; + std::map> nativeTokenInfoMap_; + std::map nativeTokenIdMap_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_TOKEN_INFO_MANAGER_H diff --git a/services/accesstokenmanager/main/cpp/include/token/accesstoken_remote_token_manager.h b/services/accesstokenmanager/main/cpp/include/token/accesstoken_remote_token_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..8cb735f6f6cf4f49e04f539a39d5f3936c643fb8 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/token/accesstoken_remote_token_manager.h @@ -0,0 +1,61 @@ +/* + * 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 ACCESSTOKEN_TOKEN_REMOTE_TOKEN_MANAGER_H +#define ACCESSTOKEN_TOKEN_REMOTE_TOKEN_MANAGER_H + +#include +#include +#include + +#include "access_token.h" +#include "hap_token_info.h" +#include "hap_token_info_inner.h" +#include "native_token_info.h" +#include "native_token_info_inner.h" +#include "nocopyable.h" +#include "rwlock.h" +#include "thread_pool.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class AccessTokenRemoteDevice final { +public: + std::string DeviceID_; // networkID + std::map MappingTokenIDPairMap_; +}; + +class AccessTokenRemoteTokenManager final { +public: + static AccessTokenRemoteTokenManager& GetInstance(); + ~AccessTokenRemoteTokenManager(); + AccessTokenID MapRemoteDeviceTokenToLocal(const std::string& deviceID, AccessTokenID remoteID); + int GetDeviceAllRemoteTokenID(const std::string& deviceID, std::vector& mapIDs); + AccessTokenID GetDeviceMappingTokenID(const std::string& deviceID, AccessTokenID remoteID); + int RemoveDeviceMappingTokenID(const std::string& deviceID, AccessTokenID remoteID); + +private: + AccessTokenRemoteTokenManager(); + DISALLOW_COPY_AND_MOVE(AccessTokenRemoteTokenManager); + + OHOS::Utils::RWLock remoteDeviceLock_; + std::map remoteDeviceMap_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_TOKEN_REMOTE_TOKEN_MANAGER_H + diff --git a/services/accesstokenmanager/main/cpp/include/token/hap_token_info_inner.h b/services/accesstokenmanager/main/cpp/include/token/hap_token_info_inner.h new file mode 100644 index 0000000000000000000000000000000000000000..add61cb1d14de9112bbaa7cc6d53ad4969e101e5 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/token/hap_token_info_inner.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 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_HAP_TOKEN_INFO_INNER_H +#define ACCESSTOKEN_HAP_TOKEN_INFO_INNER_H + +#include +#include +#include + +#include "access_token.h" +#include "generic_values.h" +#include "hap_token_info.h" +#include "permission_def.h" +#include "permission_policy_set.h" +#include "permission_state_full.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class HapTokenInfoInner final { +public: + HapTokenInfoInner(); + HapTokenInfoInner(AccessTokenID id, const HapInfoParams& info, const HapPolicyParams& policy); + HapTokenInfoInner(AccessTokenID id, const HapTokenInfo &info, + const std::vector& permStateList); + virtual ~HapTokenInfoInner(); + + void Update(const std::string& appIDDesc, const HapPolicyParams& policy); + void TranslateToHapTokenInfo(HapTokenInfo& InfoParcel) const; + void StoreHapInfo(std::vector& hapInfoValues, + std::vector& permDefValues, + std::vector& permStateValues) const; + int RestoreHapTokenInfo(AccessTokenID tokenId, GenericValues& tokenValue, + const std::vector& permDefRes, const std::vector& permStateRes); + + std::shared_ptr GetHapInfoPermissionPolicySet() const; + HapTokenInfo GetHapInfoBasic() const; + int GetUserID() const; + std::string GetBundleName() const; + int GetInstIndex() const; + AccessTokenID GetTokenID() const; + void SetPermissionPolicySet(std::shared_ptr& policySet); + void ToString(std::string& info) const; + bool IsRemote() const; + void SetRemote(bool isRemote); + +private: + void StoreHapBasicInfo(std::vector& valueList) const; + void TranslationIntoGenericValues(GenericValues& outGenericValues) const; + int RestoreHapTokenBasicInfo(const GenericValues& inGenericValues); + + HapTokenInfo tokenInfoBasic_; + + // true means sync from remote. + bool isRemote_; + + std::shared_ptr permPolicySet_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_HAP_TOKEN_INFO_INNER_H diff --git a/services/accesstokenmanager/main/cpp/include/token/native_token_info_inner.h b/services/accesstokenmanager/main/cpp/include/token/native_token_info_inner.h new file mode 100644 index 0000000000000000000000000000000000000000..527d176d1a8f346e1a4e7b486f4a436f37585595 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/token/native_token_info_inner.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 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_NATIVE_TOKEN_INFO_INNER_H +#define ACCESSTOKEN_NATIVE_TOKEN_INFO_INNER_H + +#include "access_token.h" +#include "native_token_info.h" +#include +#include +#include "generic_values.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +static const std::string JSON_PROCESS_NAME = "processName"; +static const std::string JSON_APL = "APL"; +static const std::string JSON_VERSION = "version"; +static const std::string JSON_TOKEN_ID = "tokenId"; +static const std::string JSON_TOKEN_ATTR = "tokenAttr"; +static const std::string JSON_DCAPS = "dcaps"; + +class NativeTokenInfoInner final { +public: + NativeTokenInfoInner(); + NativeTokenInfoInner(NativeTokenInfo& info); + virtual ~NativeTokenInfoInner(); + + int Init(AccessTokenID id, const std::string& processName, int apl, + const std::vector& dcap); + void StoreNativeInfo(std::vector& valueList) const; + void TranslateToNativeTokenInfo(NativeTokenInfo& InfoParcel) const; + void SetDcaps(const std::string& dcapStr); + void ToString(std::string& info) const; + int RestoreNativeTokenInfo(AccessTokenID tokenId, const GenericValues& inGenericValues); + void Update(AccessTokenID tokenId, const std::string& processName, + int apl, const std::vector& dcap); + + std::vector GetDcap() const; + AccessTokenID GetTokenID() const; + std::string GetProcessName() const; + NativeTokenInfo GetNativeTokenInfo() const; + bool IsRemote() const; + void SetRemote(bool isRemote); + +private: + int TranslationIntoGenericValues(GenericValues& outGenericValues) const; + std::string DcapToString(const std::vector& dcap) const; + + // true means sync from remote. + bool isRemote_; + NativeTokenInfo tokenInfoBasic_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_NATIVE_TOKEN_INFO_INNER_H diff --git a/services/accesstokenmanager/main/cpp/include/token/native_token_receptor.h b/services/accesstokenmanager/main/cpp/include/token/native_token_receptor.h new file mode 100644 index 0000000000000000000000000000000000000000..53097f3fc8586c8ae1ea11da979e666766f081a6 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/token/native_token_receptor.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 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_NATIVE_TOKEN_RECEPTOR_H +#define ACCESSTOKEN_NATIVE_TOKEN_RECEPTOR_H + +#include +#include + +#include "access_token.h" +#include "nlohmann/json.hpp" +#include "native_token_info_inner.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +const std::string NATIVE_TOKEN_CONFIG_FILE = "/data/service/el0/access_token/nativetoken.json"; +constexpr int MAX_NATIVE_CONFIG_FILE_SIZE = 5 * 1024 * 1024; // 5M +constexpr size_t BUFFER_SIZE = 1024; +class NativeTokenReceptor final { +public: + static NativeTokenReceptor& GetInstance(); + virtual ~NativeTokenReceptor() = default; + int Init(); + +private: + NativeTokenReceptor() : ready_(false) {}; + DISALLOW_COPY_AND_MOVE(NativeTokenReceptor); + int ReadCfgFile(std::string &nativeRawData); + void FromJson(const nlohmann::json &jsonObject, + std::vector>& tokenInfos); + void ParserNativeRawData(const std::string& nativeRawData, + std::vector>& tokenInfos); + void from_json(const nlohmann::json& j, NativeTokenInfo& p); + + bool ready_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ACCESSTOKEN_NATIVE_TOKEN_RECEPTOR_H diff --git a/services/accesstokenmanager/main/cpp/include/token/token_modify_notifier.h b/services/accesstokenmanager/main/cpp/include/token/token_modify_notifier.h new file mode 100644 index 0000000000000000000000000000000000000000..c884f37b224028219bedeb999272811bd2fdb19a --- /dev/null +++ b/services/accesstokenmanager/main/cpp/include/token/token_modify_notifier.h @@ -0,0 +1,56 @@ +/* + * 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 TOKEN_MODIFY_NOTIFIER_H +#define TOKEN_MODIFY_NOTIFIER_H + +#include +#include + +#include "access_token.h" +#include "nocopyable.h" +#include "rwlock.h" +#include "thread_pool.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class TokenModifyNotifier final { +public: + static TokenModifyNotifier& GetInstance(); + ~TokenModifyNotifier(); + void AddHapTokenObservation(AccessTokenID tokenID); + void NotifyTokenDelete(AccessTokenID tokenID); + void NotifyTokenModify(AccessTokenID tokenID); + void NotifyTokenChangedIfNeed(); + void NotifyTokenSyncTask(); + +private: + TokenModifyNotifier(); + DISALLOW_COPY_AND_MOVE(TokenModifyNotifier); + + bool hasInited_; + OHOS::Utils::RWLock initLock_; + OHOS::Utils::RWLock Notifylock_; + OHOS::ThreadPool notifyTokenWorker_; + std::set observationSet_; + std::vector deleteTokenList_; + std::vector modifiedTokenList_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // TOKEN_MODIFY_NOTIFIER_H + diff --git a/interfaces/innerkits/accesstoken/main/cpp/include/accesstoken_kit.h b/services/accesstokenmanager/main/cpp/src/database/data_storage.cpp similarity index 71% rename from interfaces/innerkits/accesstoken/main/cpp/include/accesstoken_kit.h rename to services/accesstokenmanager/main/cpp/src/database/data_storage.cpp index 22fedd97a90f46c80ed4b1c0e784c90b8464b5c1..90559c6c21a5eb387454fb2359357496a90e4558 100644 --- a/interfaces/innerkits/accesstoken/main/cpp/include/accesstoken_kit.h +++ b/services/accesstokenmanager/main/cpp/src/database/data_storage.cpp @@ -13,20 +13,17 @@ * limitations under the License. */ -#ifndef INTERFACES_INNER_KITS_ACCESSTOKEN_KIT_H -#define INTERFACES_INNER_KITS_ACCESSTOKEN_KIT_H +#include "data_storage.h" -#include -#include "accesstoken.h" +#include "sqlite_storage.h" namespace OHOS { namespace Security { namespace AccessToken { -class AccessTokenKit { -public: - static int VerifyAccesstoken(AccessTokenID tokenID, const std::string& permissionName); -}; +DataStorage& DataStorage::GetRealDataStorage() +{ + return SqliteStorage::GetInstance(); +} } // namespace AccessToken } // namespace Security -} // namespace OHOS -#endif +} // namespace OHOS \ No newline at end of file diff --git a/services/accesstokenmanager/main/cpp/src/database/data_translator.cpp b/services/accesstokenmanager/main/cpp/src/database/data_translator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d601e0ed4af8dbcabedb8dbd783b753b19a9fa81 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/database/data_translator.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2021 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 "data_translator.h" + +#include + +#include "accesstoken_log.h" +#include "data_validator.h" +#include "field_const.h" +#include "permission_validator.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "DataTranslator"}; +} + +int DataTranslator::TranslationIntoGenericValues(const PermissionDef& inPermissionDef, GenericValues& outGenericValues) +{ + outGenericValues.Put(FIELD_PERMISSION_NAME, inPermissionDef.permissionName); + outGenericValues.Put(FIELD_BUNDLE_NAME, inPermissionDef.bundleName); + outGenericValues.Put(FIELD_GRANT_MODE, inPermissionDef.grantMode); + outGenericValues.Put(FIELD_AVAILABLE_LEVEL, inPermissionDef.availableLevel); + outGenericValues.Put(FIELD_PROVISION_ENABLE, inPermissionDef.provisionEnable ? 1 : 0); + outGenericValues.Put(FIELD_DISTRIBUTED_SCENE_ENABLE, inPermissionDef.distributedSceneEnable ? 1 : 0); + outGenericValues.Put(FIELD_LABEL, inPermissionDef.label); + outGenericValues.Put(FIELD_LABEL_ID, inPermissionDef.labelId); + outGenericValues.Put(FIELD_DESCRIPTION, inPermissionDef.description); + outGenericValues.Put(FIELD_DESCRIPTION_ID, inPermissionDef.descriptionId); + return RET_SUCCESS; +} + +int DataTranslator::TranslationIntoPermissionDef(const GenericValues& inGenericValues, PermissionDef& outPermissionDef) +{ + outPermissionDef.permissionName = inGenericValues.GetString(FIELD_PERMISSION_NAME); + outPermissionDef.bundleName = inGenericValues.GetString(FIELD_BUNDLE_NAME); + outPermissionDef.grantMode = inGenericValues.GetInt(FIELD_GRANT_MODE); + int aplNum = inGenericValues.GetInt(FIELD_AVAILABLE_LEVEL); + if (!DataValidator::IsAplNumValid(aplNum)) { + ACCESSTOKEN_LOG_WARN(LABEL, "Apl is wrong."); + return RET_FAILED; + } + outPermissionDef.availableLevel = (ATokenAplEnum)aplNum; + outPermissionDef.provisionEnable = (inGenericValues.GetInt(FIELD_PROVISION_ENABLE) == 1); + outPermissionDef.distributedSceneEnable = (inGenericValues.GetInt(FIELD_DISTRIBUTED_SCENE_ENABLE) == 1); + outPermissionDef.label = inGenericValues.GetString(FIELD_LABEL); + outPermissionDef.labelId = inGenericValues.GetInt(FIELD_LABEL_ID); + outPermissionDef.description = inGenericValues.GetString(FIELD_DESCRIPTION); + outPermissionDef.descriptionId = inGenericValues.GetInt(FIELD_DESCRIPTION_ID); + return RET_SUCCESS; +} + +int DataTranslator::TranslationIntoGenericValues(const PermissionStateFull& inPermissionState, + const unsigned int grantIndex, GenericValues& outGenericValues) +{ + if (grantIndex >= inPermissionState.resDeviceID.size() || grantIndex >= inPermissionState.grantStatus.size() + || grantIndex >= inPermissionState.grantFlags.size()) { + ACCESSTOKEN_LOG_WARN(LABEL, "perm status grant size is wrong"); + return RET_FAILED; + } + outGenericValues.Put(FIELD_PERMISSION_NAME, inPermissionState.permissionName); + outGenericValues.Put(FIELD_DEVICE_ID, inPermissionState.resDeviceID[grantIndex]); + outGenericValues.Put(FIELD_GRANT_IS_GENERAL, inPermissionState.isGeneral ? 1 : 0); + outGenericValues.Put(FIELD_GRANT_STATE, inPermissionState.grantStatus[grantIndex]); + outGenericValues.Put(FIELD_GRANT_FLAG, inPermissionState.grantFlags[grantIndex]); + return RET_SUCCESS; +} + +int DataTranslator::TranslationIntoPermissionStateFull(const GenericValues& inGenericValues, + PermissionStateFull& outPermissionState) +{ + outPermissionState.isGeneral = ((inGenericValues.GetInt(FIELD_GRANT_IS_GENERAL) == 1) ? true : false); + outPermissionState.permissionName = inGenericValues.GetString(FIELD_PERMISSION_NAME); + if (!DataValidator::IsPermissionNameValid(outPermissionState.permissionName)) { + ACCESSTOKEN_LOG_WARN(LABEL, "permission name is wrong"); + return RET_FAILED; + } + + std::string devID = inGenericValues.GetString(FIELD_DEVICE_ID); + if (!DataValidator::IsDeviceIdValid(devID)) { + ACCESSTOKEN_LOG_WARN(LABEL, "devID is wrong"); + return RET_FAILED; + } + outPermissionState.resDeviceID.push_back(devID); + + int grantStatus = (PermissionState)inGenericValues.GetInt(FIELD_GRANT_STATE); + if (!PermissionValidator::IsGrantStatusValid(grantStatus)) { + ACCESSTOKEN_LOG_WARN(LABEL, "grantStatus is wrong"); + return RET_FAILED; + } + outPermissionState.grantStatus.push_back(grantStatus); + + int grantFlag = (PermissionState)inGenericValues.GetInt(FIELD_GRANT_FLAG); + if (!PermissionValidator::IsPermissionFlagValid(grantFlag)) { + ACCESSTOKEN_LOG_WARN(LABEL, "grantFlag is wrong"); + return RET_FAILED; + } + outPermissionState.grantFlags.push_back(grantFlag); + return RET_SUCCESS; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/database/generic_values.cpp b/services/accesstokenmanager/main/cpp/src/database/generic_values.cpp new file mode 100644 index 0000000000000000000000000000000000000000..db130ace6e4fcbb6e28f8c6da1d7e68eceb220e1 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/database/generic_values.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 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 "generic_values.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +void GenericValues::Put(const std::string& key, int value) +{ + map_.insert(std::make_pair(key, VariantValue(value))); +} + +void GenericValues::Put(const std::string& key, const std::string& value) +{ + map_.insert(std::make_pair(key, VariantValue(value))); +} + +void GenericValues::Put(const std::string& key, const VariantValue& value) +{ + map_.insert(std::make_pair(key, value)); +} + +VariantValue GenericValues::Get(const std::string& key) const +{ + auto iter = map_.find(key); + if (iter == map_.end()) { + return VariantValue(); + } + return iter->second; +} + +int GenericValues::GetInt(const std::string& key) const +{ + auto it = map_.find(key); + if (it == map_.end()) { + return VariantValue::DEFAULT_VALUE; + } + return it->second.GetInt(); +} + +std::string GenericValues::GetString(const std::string& key) const +{ + auto it = map_.find(key); + if (it == map_.end()) { + return std::string(); + } + return it->second.GetString(); +} + +std::vector GenericValues::GetAllKeys() const +{ + std::vector keys; + for (auto it = map_.begin(); it != map_.end(); ++it) { + keys.emplace_back(it->first); + } + return keys; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/accesstokenmanager/main/cpp/src/database/sqlite_helper.cpp b/services/accesstokenmanager/main/cpp/src/database/sqlite_helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0e878fd339a08c34691353f25aaed6dd234fa8af --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/database/sqlite_helper.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2021 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 "sqlite_helper.h" + +#include "accesstoken_log.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "SqliteHelper"}; +} + +SqliteHelper::SqliteHelper(const std::string& dbName, const std::string& dbPath, int version) + : dbName_(dbName), dbPath_(dbPath), currentVersion_(version), db_(nullptr) +{} + +SqliteHelper::~SqliteHelper() +{} + +void SqliteHelper::Open() +{ + if (db_ != nullptr) { + return; + } + if (dbName_.empty() || dbPath_.empty() || currentVersion_ < 0) { + return; + } + std::string fileName = dbPath_ + dbName_; + int res = sqlite3_open(fileName.c_str(), &db_); + if (res != SQLITE_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to open db: %{public}s", sqlite3_errmsg(db_)); + return; + } + + int version = GetVersion(); + if (version == currentVersion_) { + return; + } + + BeginTransaction(); + if (version == 0) { + OnCreate(); + } else { + if (version < currentVersion_) { + OnUpdate(); + } + } + SetVersion(); + CommitTransaction(); +} + +void SqliteHelper::Close() +{ + if (db_ == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "do open data base first!"); + return; + } + int ret = sqlite3_close(db_); + if (ret != SQLITE_OK) { + ACCESSTOKEN_LOG_WARN(LABEL, "sqlite3_close error, ret=%{public}d", ret); + return; + } + db_ = nullptr; +} + +int SqliteHelper::BeginTransaction() const +{ + if (db_ == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "do open data base first!"); + return GENERAL_ERROR; + } + char* errorMessage = nullptr; + int result = 0; + int ret = sqlite3_exec(db_, "BEGIN;", nullptr, nullptr, &errorMessage); + if (ret != SQLITE_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage); + result = GENERAL_ERROR; + } + sqlite3_free(errorMessage); + return result; +} + +int SqliteHelper::CommitTransaction() const +{ + if (db_ == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "do open data base first!"); + return GENERAL_ERROR; + } + char* errorMessage = nullptr; + int result = 0; + int ret = sqlite3_exec(db_, "COMMIT;", nullptr, nullptr, &errorMessage); + if (ret != SQLITE_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage); + result = GENERAL_ERROR; + } + sqlite3_free(errorMessage); + return result; +} + +int SqliteHelper::RollbackTransaction() const +{ + if (db_ == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "do open data base first!"); + return GENERAL_ERROR; + } + int result = 0; + char* errorMessage = nullptr; + int ret = sqlite3_exec(db_, "ROLLBACK;", nullptr, nullptr, &errorMessage); + if (ret != SQLITE_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage); + result = GENERAL_ERROR; + } + sqlite3_free(errorMessage); + return result; +} + +Statement SqliteHelper::Prepare(const std::string& sql) const +{ + return Statement(db_, sql); +} + +int SqliteHelper::ExecuteSql(const std::string& sql) const +{ + if (db_ == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "do open data base first!"); + return GENERAL_ERROR; + } + char* errorMessage = nullptr; + int result = 0; + int res = sqlite3_exec(db_, sql.c_str(), nullptr, nullptr, &errorMessage); + if (res != SQLITE_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage); + result = GENERAL_ERROR; + } + sqlite3_free(errorMessage); + return result; +} + +int SqliteHelper::GetVersion() const +{ + if (db_ == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "do open data base first!"); + return GENERAL_ERROR; + } + auto statement = Prepare(PRAGMA_VERSION_COMMAND); + int version = 0; + while (statement.Step() == Statement::State::ROW) { + version = statement.GetColumnInt(0); + } + ACCESSTOKEN_LOG_INFO(LABEL, "version: %{public}d", version); + return version; +} + +void SqliteHelper::SetVersion() const +{ + if (db_ == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "do open data base first!"); + return; + } + auto statement = Prepare(PRAGMA_VERSION_COMMAND + " = " + std::to_string(currentVersion_)); + statement.Step(); +} + +std::string SqliteHelper::SpitError() const +{ + if (db_ == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "do open data base first!"); + return ""; + } + return sqlite3_errmsg(db_); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/accesstokenmanager/main/cpp/src/database/sqlite_storage.cpp b/services/accesstokenmanager/main/cpp/src/database/sqlite_storage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f929760e36b91c0a9bcef9432eee4156e0095efc --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/database/sqlite_storage.cpp @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2021 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 "sqlite_storage.h" + +#include "accesstoken_log.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "SqliteStorage"}; +} + +SqliteStorage& SqliteStorage::GetInstance() +{ + static SqliteStorage instance; + return instance; +} + +SqliteStorage::~SqliteStorage() +{ + Close(); +} + +void SqliteStorage::OnCreate() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__); + CreateHapTokenInfoTable(); + CreateNativeTokenInfoTable(); + CreatePermissionDefinitionTable(); + CreatePermissionStateTable(); +} + +void SqliteStorage::OnUpdate() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__); +} + +SqliteStorage::SqliteStorage() : SqliteHelper(DATABASE_NAME, DATABASE_PATH, DATABASE_VERSION) +{ + SqliteTable hapTokenInfoTable; + hapTokenInfoTable.tableName_ = HAP_TOKEN_INFO_TABLE; + hapTokenInfoTable.tableColumnNames_ = { + FIELD_TOKEN_ID, FIELD_USER_ID, + FIELD_BUNDLE_NAME, FIELD_INST_INDEX, + FIELD_APP_ID, FIELD_DEVICE_ID, + FIELD_APL, FIELD_TOKEN_VERSION, + FIELD_TOKEN_ATTR + }; + + SqliteTable NativeTokenInfoTable; + NativeTokenInfoTable.tableName_ = NATIVE_TOKEN_INFO_TABLE; + NativeTokenInfoTable.tableColumnNames_ = { + FIELD_TOKEN_ID, FIELD_PROCESS_NAME, + FIELD_TOKEN_VERSION, FIELD_TOKEN_ATTR, + FIELD_DCAP, FIELD_APL + }; + + SqliteTable permissionDefTable; + permissionDefTable.tableName_ = PERMISSION_DEF_TABLE; + permissionDefTable.tableColumnNames_ = { + FIELD_TOKEN_ID, FIELD_PERMISSION_NAME, + FIELD_BUNDLE_NAME, FIELD_GRANT_MODE, + FIELD_AVAILABLE_LEVEL, FIELD_PROVISION_ENABLE, + FIELD_DISTRIBUTED_SCENE_ENABLE, FIELD_LABEL, + FIELD_LABEL_ID, FIELD_DESCRIPTION, + FIELD_DESCRIPTION_ID + }; + + SqliteTable permissionStateTable; + permissionStateTable.tableName_ = PERMISSION_STATE_TABLE; + permissionStateTable.tableColumnNames_ = { + FIELD_TOKEN_ID, FIELD_PERMISSION_NAME, + FIELD_DEVICE_ID, FIELD_GRANT_IS_GENERAL, + FIELD_GRANT_STATE, FIELD_GRANT_FLAG + }; + + dataTypeToSqlTable_ = { + {ACCESSTOKEN_HAP_INFO, hapTokenInfoTable}, + {ACCESSTOKEN_NATIVE_INFO, NativeTokenInfoTable}, + {ACCESSTOKEN_PERMISSION_DEF, permissionDefTable}, + {ACCESSTOKEN_PERMISSION_STATE, permissionStateTable}, + }; + + Open(); +} + +int SqliteStorage::Add(const DataType type, const std::vector& values) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::string prepareSql = CreateInsertPrepareSqlCmd(type); + auto statement = Prepare(prepareSql); + BeginTransaction(); + bool isExecuteSuccessfully = true; + for (auto value : values) { + std::vector columnNames = value.GetAllKeys(); + for (auto columnName : columnNames) { + statement.Bind(columnName, value.Get(columnName)); + } + int ret = statement.Step(); + if (ret != Statement::State::DONE) { + ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", SpitError().c_str()); + isExecuteSuccessfully = false; + } + statement.Reset(); + } + if (!isExecuteSuccessfully) { + ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction."); + RollbackTransaction(); + return FAILURE; + } + ACCESSTOKEN_LOG_INFO(LABEL, "commit transaction."); + CommitTransaction(); + return SUCCESS; +} + +int SqliteStorage::Remove(const DataType type, const GenericValues& conditions) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::vector columnNames = conditions.GetAllKeys(); + std::string prepareSql = CreateDeletePrepareSqlCmd(type, columnNames); + auto statement = Prepare(prepareSql); + for (auto columnName : columnNames) { + statement.Bind(columnName, conditions.Get(columnName)); + } + int ret = statement.Step(); + return (ret == Statement::State::DONE) ? SUCCESS : FAILURE; +} + +int SqliteStorage::Modify(const DataType type, const GenericValues& modifyValues, const GenericValues& conditions) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::vector modifyColumns = modifyValues.GetAllKeys(); + std::vector conditionColumns = conditions.GetAllKeys(); + std::string prepareSql = CreateUpdatePrepareSqlCmd(type, modifyColumns, conditionColumns); + auto statement = Prepare(prepareSql); + for (auto columnName : modifyColumns) { + statement.Bind(columnName, modifyValues.Get(columnName)); + } + for (auto columnName : conditionColumns) { + statement.Bind(columnName, conditions.Get(columnName)); + } + int ret = statement.Step(); + return (ret == Statement::State::DONE) ? SUCCESS : FAILURE; +} + +int SqliteStorage::Find(const DataType type, std::vector& results) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::string prepareSql = CreateSelectPrepareSqlCmd(type); + auto statement = Prepare(prepareSql); + while (statement.Step() == Statement::State::ROW) { + int columnCount = statement.GetColumnCount(); + GenericValues value; + for (int i = 0; i < columnCount; i++) { + value.Put(statement.GetColumnName(i), statement.GetValue(i)); + } + results.emplace_back(value); + } + return SUCCESS; +} + +int SqliteStorage::RefreshAll(const DataType type, const std::vector& values) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::string deleteSql = CreateDeletePrepareSqlCmd(type); + std::string insertSql = CreateInsertPrepareSqlCmd(type); + auto deleteStatement = Prepare(deleteSql); + auto insertStatement = Prepare(insertSql); + BeginTransaction(); + bool canCommit = deleteStatement.Step() == Statement::State::DONE; + for (auto value : values) { + std::vector columnNames = value.GetAllKeys(); + for (auto columnName : columnNames) { + insertStatement.Bind(columnName, value.Get(columnName)); + } + int ret = insertStatement.Step(); + if (ret != Statement::State::DONE) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "insert failed, errorMsg: %{public}s", SpitError().c_str()); + canCommit = false; + } + insertStatement.Reset(); + } + if (!canCommit) { + ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction."); + RollbackTransaction(); + return FAILURE; + } + ACCESSTOKEN_LOG_INFO(LABEL, "commit transaction."); + CommitTransaction(); + return SUCCESS; +} + +std::string SqliteStorage::CreateInsertPrepareSqlCmd(const DataType type) const +{ + auto it = dataTypeToSqlTable_.find(type); + if (it == dataTypeToSqlTable_.end()) { + return std::string(); + } + std::string sql = "insert into " + it->second.tableName_ + " values("; + int i = 1; + for (const auto& columnName : it->second.tableColumnNames_) { + sql.append(":" + columnName); + if (i < (int) it->second.tableColumnNames_.size()) { + sql.append(","); + } + i += 1; + } + sql.append(")"); + return sql; +} + +std::string SqliteStorage::CreateDeletePrepareSqlCmd( + const DataType type, const std::vector& columnNames) const +{ + auto it = dataTypeToSqlTable_.find(type); + if (it == dataTypeToSqlTable_.end()) { + return std::string(); + } + std::string sql = "delete from " + it->second.tableName_ + " where 1 = 1"; + for (auto columnName : columnNames) { + sql.append(" and "); + sql.append(columnName + "=:" + columnName); + } + return sql; +} + +std::string SqliteStorage::CreateUpdatePrepareSqlCmd(const DataType type, const std::vector& modifyColumns, + const std::vector& conditionColumns) const +{ + if (modifyColumns.empty()) { + return std::string(); + } + + auto it = dataTypeToSqlTable_.find(type); + if (it == dataTypeToSqlTable_.end()) { + return std::string(); + } + + std::string sql = "update " + it->second.tableName_ + " set "; + int i = 1; + for (const auto& columnName : modifyColumns) { + sql.append(columnName + "=:" + columnName); + if (i < (int) modifyColumns.size()) { + sql.append(","); + } + i += 1; + } + + if (!conditionColumns.empty()) { + sql.append(" where 1 = 1"); + for (const auto& columnName : conditionColumns) { + sql.append(" and "); + sql.append(columnName + "=:" + columnName); + } + } + return sql; +} + +std::string SqliteStorage::CreateSelectPrepareSqlCmd(const DataType type) const +{ + auto it = dataTypeToSqlTable_.find(type); + if (it == dataTypeToSqlTable_.end()) { + return std::string(); + } + std::string sql = "select * from " + it->second.tableName_; + return sql; +} + +int SqliteStorage::CreateHapTokenInfoTable() const +{ + auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_HAP_INFO); + if (it == dataTypeToSqlTable_.end()) { + return FAILURE; + } + std::string sql = "create table if not exists "; + sql.append(it->second.tableName_ + " (") + .append(FIELD_TOKEN_ID + " integer not null,") + .append(FIELD_USER_ID + " integer not null,") + .append(FIELD_BUNDLE_NAME + " text not null,") + .append(FIELD_INST_INDEX + " integer not null,") + .append(FIELD_APP_ID + " text not null,") + .append(FIELD_DEVICE_ID + " text not null,") + .append(FIELD_APL + " integer not null,") + .append(FIELD_TOKEN_VERSION + " integer not null,") + .append(FIELD_TOKEN_ATTR + " integer not null,") + .append("primary key(" + FIELD_TOKEN_ID) + .append("))"); + return ExecuteSql(sql); +} + +int SqliteStorage::CreateNativeTokenInfoTable() const +{ + auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_NATIVE_INFO); + if (it == dataTypeToSqlTable_.end()) { + return FAILURE; + } + std::string sql = "create table if not exists "; + sql.append(it->second.tableName_ + " (") + .append(FIELD_TOKEN_ID + " integer not null,") + .append(FIELD_PROCESS_NAME + " text not null,") + .append(FIELD_TOKEN_VERSION + " integer not null,") + .append(FIELD_TOKEN_ATTR + " integer not null,") + .append(FIELD_DCAP + " text not null,") + .append(FIELD_APL + " integer not null,") + .append("primary key(" + FIELD_TOKEN_ID) + .append("))"); + return ExecuteSql(sql); +} + +int SqliteStorage::CreatePermissionDefinitionTable() const +{ + auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_DEF); + if (it == dataTypeToSqlTable_.end()) { + return FAILURE; + } + std::string sql = "create table if not exists "; + sql.append(it->second.tableName_ + " (") + .append(FIELD_TOKEN_ID + " integer not null,") + .append(FIELD_PERMISSION_NAME + " text not null,") + .append(FIELD_BUNDLE_NAME + " text not null,") + .append(FIELD_GRANT_MODE + " integer not null,") + .append(FIELD_AVAILABLE_LEVEL + " integer not null,") + .append(FIELD_PROVISION_ENABLE + " integer not null,") + .append(FIELD_DISTRIBUTED_SCENE_ENABLE + " integer not null,") + .append(FIELD_LABEL + " text not null,") + .append(FIELD_LABEL_ID + " integer not null,") + .append(FIELD_DESCRIPTION + " text not null,") + .append(FIELD_DESCRIPTION_ID + " integer not null,") + .append("primary key(" + FIELD_TOKEN_ID) + .append("," + FIELD_PERMISSION_NAME) + .append("))"); + return ExecuteSql(sql); +} + +int SqliteStorage::CreatePermissionStateTable() const +{ + auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_STATE); + if (it == dataTypeToSqlTable_.end()) { + return FAILURE; + } + std::string sql = "create table if not exists "; + sql.append(it->second.tableName_ + " (") + .append(FIELD_TOKEN_ID + " integer not null,") + .append(FIELD_PERMISSION_NAME + " text not null,") + .append(FIELD_DEVICE_ID + " text not null,") + .append(FIELD_GRANT_IS_GENERAL + " integer not null,") + .append(FIELD_GRANT_STATE + " integer not null,") + .append(FIELD_GRANT_FLAG + " integer not null,") + .append("primary key(" + FIELD_TOKEN_ID) + .append("," + FIELD_PERMISSION_NAME) + .append("," + FIELD_DEVICE_ID) + .append("))"); + return ExecuteSql(sql); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/database/statement.cpp b/services/accesstokenmanager/main/cpp/src/database/statement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42d2e3656cee9892ade9ef89d8f3ea5a3dcd3f4c --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/database/statement.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2021 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 "statement.h" + +#include "accesstoken_log.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "Statement"}; +} + +Statement::Statement(sqlite3* db, const std::string& sql) : db_(db), sql_(sql) +{ + if (sqlite3_prepare_v2(db, sql.c_str(), sql.size(), &statement_, nullptr) != SQLITE_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot prepare, errorMsg: %{public}s", sqlite3_errmsg(db_)); + } +} + +Statement::~Statement() +{ + sqlite3_finalize(statement_); + statement_ = nullptr; +} + +void Statement::Bind(const int index, const std::string& text) +{ + if (sqlite3_bind_text(statement_, index, text.c_str(), text.size(), SQLITE_TRANSIENT) != SQLITE_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot bind string, errorMsg: %{public}s", sqlite3_errmsg(db_)); + } +} + +void Statement::Bind(const int index, int value) +{ + if (sqlite3_bind_int(statement_, index, value) != SQLITE_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot bind int, errorMsg: %{public}s", sqlite3_errmsg(db_)); + } +} + +int Statement::GetColumnInt(const int column) const +{ + return sqlite3_column_int(statement_, column); +} + +std::string Statement::GetColumnString(const int column) const +{ + return std::string(reinterpret_cast(sqlite3_column_text(statement_, column))); +} + +std::string Statement::GetColumnName(const int column) const +{ + return sqlite3_column_name(statement_, column); +} + +Statement::State Statement::Step() +{ + int ret = sqlite3_step(statement_); + switch (ret) { + case SQLITE_ROW: + return Statement::State::ROW; + case SQLITE_DONE: + return Statement::State::DONE; + case SQLITE_BUSY: + return Statement::State::BUSY; + case SQLITE_MISUSE: + return Statement::State::MISUSE; + default: + return Statement::State::UNKNOWN; + } +} + +int Statement::GetParameterIndex(const std::string& name) const +{ + return sqlite3_bind_parameter_index(statement_, name.c_str()); +} + +void Statement::Bind(const std::string& tableColumnName, const VariantValue& value) +{ + int index = GetParameterIndex(":" + tableColumnName); + if (value.GetType() == ValueType::TYPE_STRING) { + Bind(index, value.GetString()); + } else if (value.GetType() == ValueType::TYPE_INT) { + Bind(index, value.GetInt()); + } +} + +int Statement::Reset() +{ + return sqlite3_reset(statement_); +} + +int Statement::GetColumnCount() const +{ + return sqlite3_column_count(statement_); +} + +VariantValue Statement::GetValue(const int column) const +{ + int type = sqlite3_column_type(statement_, column); + switch (type) { + case SQLITE_INTEGER: + return VariantValue(GetColumnInt(column)); + case SQLITE_TEXT: + return VariantValue(GetColumnString(column)); + default: + return VariantValue(); + } +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_kit.cpp b/services/accesstokenmanager/main/cpp/src/database/variant_value.cpp similarity index 51% rename from interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_kit.cpp rename to services/accesstokenmanager/main/cpp/src/database/variant_value.cpp index 1e0e8e06e7bc66a3c83dd00cbc9a4a2b9a6409a5..3dae3273105551fd698c8f270de4b0d8198d9802 100644 --- a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_kit.cpp +++ b/services/accesstokenmanager/main/cpp/src/database/variant_value.cpp @@ -13,29 +13,48 @@ * limitations under the License. */ -#include "accesstoken_kit.h" - -#include -#include - -#include "accesstoken_log.h" -#include "accesstoken_manager_client.h" +#include "variant_value.h" namespace OHOS { namespace Security { namespace AccessToken { -using namespace std; +VariantValue::VariantValue() : type_(ValueType::TYPE_NULL) +{} + +VariantValue::~VariantValue() +{} + +VariantValue::VariantValue(int value) : type_(ValueType::TYPE_INT) +{ + value_ = value; +} + +VariantValue::VariantValue(const std::string& value) : type_(ValueType::TYPE_STRING) +{ + value_ = value; +} + +ValueType VariantValue::GetType() const +{ + return type_; +} -namespace { -static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenKit"}; -} // namespace +int VariantValue::GetInt() const +{ + if (type_ != ValueType::TYPE_INT) { + return DEFAULT_VALUE; + } + + return std::get(value_); +} -int AccessTokenKit::VerifyAccesstoken(AccessTokenID tokenID, const std::string &permissionName) +std::string VariantValue::GetString() const { - ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); - ACCESSTOKEN_LOG_INFO(LABEL, "tokenID=%{public}d, permissionName=%{public}s", - tokenID, permissionName.c_str()); - return AccessTokenManagerClient::GetInstance().VerifyAccesstoken(tokenID, permissionName); + if (type_ != ValueType::TYPE_STRING) { + return std::string(); + } + + return std::get(value_); } } // namespace AccessToken } // namespace Security diff --git a/services/accesstokenmanager/main/cpp/src/permission/permission_definition_cache.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_definition_cache.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54917c49cc0c8236eef79fb02ba0289e38b44cc6 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_definition_cache.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021 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_definition_cache.h" + +#include "access_token.h" +#include "accesstoken_log.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "PermissionDefinitionCache" +}; +} + +PermissionDefinitionCache& PermissionDefinitionCache::GetInstance() +{ + static PermissionDefinitionCache instance; + return instance; +} + +PermissionDefinitionCache::PermissionDefinitionCache() +{} + +PermissionDefinitionCache::~PermissionDefinitionCache() +{} + +bool PermissionDefinitionCache::Insert(const PermissionDef& info) +{ + Utils::UniqueWriteGuard cacheGuard(this->cacheLock_); + auto it = permissionDefinitionMap_.find(info.permissionName); + if (it != permissionDefinitionMap_.end()) { + ACCESSTOKEN_LOG_WARN(LABEL, "info for permission: %{public}s has been insert, please check!", + info.permissionName.c_str()); + return false; + } + permissionDefinitionMap_[info.permissionName] = info; + return true; +} + +bool PermissionDefinitionCache::Update(const PermissionDef& info) +{ + Utils::UniqueWriteGuard cacheGuard(this->cacheLock_); + permissionDefinitionMap_[info.permissionName] = info; + return true; +} + +void PermissionDefinitionCache::DeleteByBundleName(const std::string& bundleName) +{ + Utils::UniqueWriteGuard cacheGuard(this->cacheLock_); + auto it = permissionDefinitionMap_.begin(); + while (it != permissionDefinitionMap_.end()) { + if (bundleName == it->second.bundleName) { + permissionDefinitionMap_.erase(it++); + } else { + ++it; + } + } +} + +int PermissionDefinitionCache::FindByPermissionName(const std::string& permissionName, PermissionDef& info) +{ + Utils::UniqueReadGuard cacheGuard(this->cacheLock_); + auto it = permissionDefinitionMap_.find(permissionName); + if (it == permissionDefinitionMap_.end()) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "can not find definition info for permission: %{public}s", + permissionName.c_str()); + return RET_FAILED; + } + info = it->second; + return RET_SUCCESS; +} + +bool PermissionDefinitionCache::IsSystemGrantedPermission(const std::string& permissionName) +{ + Utils::UniqueReadGuard cacheGuard(this->cacheLock_); + return IsGrantedModeEqualInner(permissionName, SYSTEM_GRANT); +} + +bool PermissionDefinitionCache::IsUserGrantedPermission(const std::string& permissionName) +{ + Utils::UniqueReadGuard cacheGuard(this->cacheLock_); + return IsGrantedModeEqualInner(permissionName, USER_GRANT); +} + +bool PermissionDefinitionCache::IsGrantedModeEqualInner(const std::string& permissionName, int grantMode) const +{ + auto it = permissionDefinitionMap_.find(permissionName); + if (it == permissionDefinitionMap_.end()) { + return false; + } + return it->second.grantMode == grantMode; +} + +bool PermissionDefinitionCache::HasDefinition(const std::string& permissionName) +{ + Utils::UniqueReadGuard cacheGuard(this->cacheLock_); + return permissionDefinitionMap_.count(permissionName) == 1; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..392991accf696a8e87599592c28755716b56fbe2 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_manager.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2021 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_manager.h" +#include "access_token.h" +#include "accesstoken_info_manager.h" +#include "accesstoken_log.h" +#include "permission_definition_cache.h" +#include "permission_validator.h" +#include "token_modify_notifier.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "PermissionManager"}; +} + +PermissionManager& PermissionManager::GetInstance() +{ + static PermissionManager instance; + return instance; +} + +PermissionManager::PermissionManager() +{ +} + +PermissionManager::~PermissionManager() +{ +} + +void PermissionManager::AddDefPermissions(std::shared_ptr tokenInfo, bool updateFlag) +{ + if (tokenInfo == nullptr) { + return; + } + std::shared_ptr permPolicySet = tokenInfo->GetHapInfoPermissionPolicySet(); + if (permPolicySet == nullptr) { + return; + } + std::vector permList; + permPolicySet->GetDefPermissions(permList); + for (auto perm : permList) { + if (!PermissionValidator::IsPermissionDefValid(perm)) { + ACCESSTOKEN_LOG_INFO(LABEL, "invalid permission definition info: %{public}s", + TransferPermissionDefToString(perm).c_str()); + continue; + } + + if (updateFlag) { + PermissionDefinitionCache::GetInstance().Update(perm); + continue; + } + + if (!PermissionDefinitionCache::GetInstance().HasDefinition(perm.permissionName)) { + PermissionDefinitionCache::GetInstance().Insert(perm); + } else { + ACCESSTOKEN_LOG_INFO(LABEL, "permission %{public}s has define", + TransferPermissionDefToString(perm).c_str()); + } + } +} + +void PermissionManager::RemoveDefPermissions(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + std::shared_ptr tokenInfo = + AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID); + if (tokenInfo == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params(tokenID: 0x%{public}x)!", tokenID); + return; + } + std::string bundleName = tokenInfo->GetBundleName(); + PermissionDefinitionCache::GetInstance().DeleteByBundleName(bundleName); +} + +int PermissionManager::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s", __func__, + tokenID, permissionName.c_str()); + if (!PermissionValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return PERMISSION_DENIED; + } + std::shared_ptr tokenInfoPtr = + AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID); + if (tokenInfoPtr == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "can not find tokenInfo!"); + return PERMISSION_DENIED; + } + + if (!tokenInfoPtr->IsRemote() && !PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "no definition for permission: %{public}s!", permissionName.c_str()); + return PERMISSION_DENIED; + } + std::shared_ptr permPolicySet = + AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID); + if (permPolicySet == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return PERMISSION_DENIED; + } + + return permPolicySet->VerifyPermissStatus(permissionName); +} + +int PermissionManager::GetDefPermission(const std::string& permissionName, PermissionDef& permissionDefResult) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permissionName: %{public}s", __func__, permissionName.c_str()); + if (!PermissionValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return RET_FAILED; + } + if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "no definition for permission: %{public}s!", permissionName.c_str()); + return RET_FAILED; + } + return PermissionDefinitionCache::GetInstance().FindByPermissionName(permissionName, permissionDefResult); +} + +int PermissionManager::GetDefPermissions(AccessTokenID tokenID, std::vector& permList) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + std::shared_ptr permPolicySet = + AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID); + if (permPolicySet == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return RET_FAILED; + } + + permPolicySet->GetDefPermissions(permList); + return RET_SUCCESS; +} + +int PermissionManager::GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x, isSystemGrant: %{public}d", + __func__, tokenID, isSystemGrant); + std::shared_ptr permPolicySet = + AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID); + if (permPolicySet == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return RET_FAILED; + } + + GrantMode mode = isSystemGrant ? SYSTEM_GRANT : USER_GRANT; + std::vector tmpList; + permPolicySet->GetPermissionStateFulls(tmpList); + for (auto perm : tmpList) { + PermissionDef permDef; + GetDefPermission(perm.permissionName, permDef); + if (permDef.grantMode == mode) { + reqPermList.emplace_back(perm); + } + } + return RET_SUCCESS; +} + +int PermissionManager::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s", + __func__, tokenID, permissionName.c_str()); + if (!PermissionValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return DEFAULT_PERMISSION_FLAGS; + } + if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "no definition for permission: %{public}s!", permissionName.c_str()); + return DEFAULT_PERMISSION_FLAGS; + } + std::shared_ptr permPolicySet = + AccessTokenInfoManager::GetInstance().GetHapPermissionPolicySet(tokenID); + if (permPolicySet == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return DEFAULT_PERMISSION_FLAGS; + } + return permPolicySet->QueryPermissionFlag(permissionName); +} + +void PermissionManager::UpdateTokenPermissionState( + AccessTokenID tokenID, const std::string& permissionName, bool isGranted, int flag) +{ + std::shared_ptr infoPtr = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID); + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return; + } + if (infoPtr->IsRemote()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote token can not update"); + return; + } + + std::shared_ptr permPolicySet = infoPtr->GetHapInfoPermissionPolicySet(); + if (permPolicySet == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return; + } + + permPolicySet->UpdatePermissionStatus(permissionName, isGranted, flag); + TokenModifyNotifier::GetInstance().NotifyTokenModify(tokenID); +} + +void PermissionManager::GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s, flag: %{public}d", + __func__, tokenID, permissionName.c_str(), flag); + if (!PermissionValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return; + } + if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "no definition for permission: %{public}s!", permissionName.c_str()); + return; + } + if (!PermissionValidator::IsPermissionFlagValid(flag)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return; + } + UpdateTokenPermissionState(tokenID, permissionName, true, flag); +} + +void PermissionManager::RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s, flag: %{public}d", + __func__, tokenID, permissionName.c_str(), flag); + if (!PermissionValidator::IsPermissionNameValid(permissionName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return; + } + if (!PermissionDefinitionCache::GetInstance().HasDefinition(permissionName)) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "no definition for permission: %{public}s!", permissionName.c_str()); + return; + } + if (!PermissionValidator::IsPermissionFlagValid(flag)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return; + } + UpdateTokenPermissionState(tokenID, permissionName, false, flag); +} + +void PermissionManager::ClearUserGrantedPermissionState(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + std::shared_ptr infoPtr = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID); + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return; + } + if (infoPtr->IsRemote()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote token can not clear."); + return; + } + + std::shared_ptr permPolicySet = infoPtr->GetHapInfoPermissionPolicySet(); + if (permPolicySet == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!"); + return; + } + + std::vector permList; + permPolicySet->GetPermissionStateFulls(permList); + for (auto& perm : permList) { + PermissionDef permDef; + bool isGranted = false; + GetDefPermission(perm.permissionName, permDef); + isGranted = (permDef.grantMode == SYSTEM_GRANT) ? true : false; + permPolicySet->UpdatePermissionStatus(perm.permissionName, isGranted, DEFAULT_PERMISSION_FLAGS); + } +} + +std::string PermissionManager::TransferPermissionDefToString(const PermissionDef& inPermissionDef) +{ + std::string infos; + infos.append(R"({"permissionName": ")" + inPermissionDef.permissionName + R"(")"); + infos.append(R"(, "bundleName": ")" + inPermissionDef.bundleName + R"(")"); + infos.append(R"(, "grantMode": )" + std::to_string(inPermissionDef.grantMode)); + infos.append(R"(, "availableLevel": )" + std::to_string(inPermissionDef.availableLevel)); + infos.append(R"(, "provisionEnable": )" + std::to_string(inPermissionDef.provisionEnable)); + infos.append(R"(, "distributedSceneEnable": )" + std::to_string(inPermissionDef.distributedSceneEnable)); + infos.append(R"(, "label": ")" + inPermissionDef.label + R"(")"); + infos.append(R"(, "labelId": )" + std::to_string(inPermissionDef.labelId)); + infos.append(R"(, "description": ")" + inPermissionDef.description + R"(")"); + infos.append(R"(, "descriptionId": )" + std::to_string(inPermissionDef.descriptionId)); + infos.append("}"); + return infos; +} +} // namespace AccessToken +} // namespace Security +} diff --git a/services/accesstokenmanager/main/cpp/src/permission/permission_policy_set.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_policy_set.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9cb3d050755137a1fe4df66b5e0eb202a6144661 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_policy_set.cpp @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2021 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_policy_set.h" + +#include "accesstoken_log.h" +#include "data_storage.h" +#include "data_translator.h" +#include "field_const.h" +#include "permission_validator.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "PermissionPolicySet"}; +} + +PermissionPolicySet::~PermissionPolicySet() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, + "%{public}s called, tokenID: 0x%{public}x destruction", __func__, tokenId_); +} + +std::shared_ptr PermissionPolicySet::BuildPermissionPolicySet( + AccessTokenID tokenId, const std::vector& permList, + const std::vector& permStateList) +{ + std::shared_ptr policySet = std::make_shared(); + if (policySet != nullptr) { + PermissionValidator::FilterInvalidPermisionDef(permList, policySet->permList_); + PermissionValidator::FilterInvalidPermisionState(permStateList, policySet->permStateList_); + policySet->tokenId_ = tokenId; + } + return policySet; +} + +void PermissionPolicySet::UpdatePermStateFull(const PermissionStateFull& permOld, PermissionStateFull& permNew) +{ + if (permNew.isGeneral == permOld.isGeneral) { + permNew.resDeviceID = permOld.resDeviceID; + permNew.grantStatus = permOld.grantStatus; + permNew.grantFlags = permOld.grantFlags; + } +} + +void PermissionPolicySet::Update(const std::vector& permList, + const std::vector& permStateList) +{ + std::vector permFilterList; + std::vector permStateFilterList; + + PermissionValidator::FilterInvalidPermisionDef(permList, permFilterList); + PermissionValidator::FilterInvalidPermisionState(permStateList, permStateFilterList); + + Utils::UniqueWriteGuard infoGuard(this->permPolicySetLock_); + for (const PermissionDef& permNew : permFilterList) { + bool found = false; + for (PermissionDef& permOld : permList_) { + if (permNew.permissionName == permOld.permissionName) { + permOld = permNew; + found = true; + break; + } + } + if (!found) { + permList_.emplace_back(permNew); + } + } + + for (PermissionStateFull& permStateNew : permStateFilterList) { + for (const PermissionStateFull& permStateOld : permStateList_) { + if (permStateNew.permissionName == permStateOld.permissionName) { + UpdatePermStateFull(permStateOld, permStateNew); + break; + } + } + } + permStateList_ = permStateFilterList; +} + +std::shared_ptr PermissionPolicySet::RestorePermissionPolicy(AccessTokenID tokenId, + const std::vector& permDefRes, const std::vector& permStateRes) +{ + std::shared_ptr policySet = std::make_shared(); + if (policySet == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x new failed.", tokenId); + return nullptr; + } + policySet->tokenId_ = tokenId; + + for (GenericValues defValue : permDefRes) { + if ((AccessTokenID)defValue.GetInt(FIELD_TOKEN_ID) == tokenId) { + PermissionDef def; + int ret = DataTranslator::TranslationIntoPermissionDef(defValue, def); + if (ret == RET_SUCCESS) { + policySet->permList_.emplace_back(def); + } else { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x permDef is wrong.", tokenId); + } + } + } + + for (GenericValues stateValue : permStateRes) { + if ((AccessTokenID)stateValue.GetInt(FIELD_TOKEN_ID) == tokenId) { + PermissionStateFull state; + int ret = DataTranslator::TranslationIntoPermissionStateFull(stateValue, state); + if (ret == RET_SUCCESS) { + MergePermissionStateFull(policySet->permStateList_, state); + } else { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x permState is wrong.", tokenId); + } + } + } + return policySet; +} + +void PermissionPolicySet::MergePermissionStateFull(std::vector& permStateList, + const PermissionStateFull& state) +{ + for (auto iter = permStateList.begin(); iter != permStateList.end(); iter++) { + if (state.permissionName == iter->permissionName) { + iter->resDeviceID.emplace_back(state.resDeviceID[0]); + iter->grantStatus.emplace_back(state.grantStatus[0]); + iter->grantFlags.emplace_back(state.grantFlags[0]); + return; + } + } + permStateList.emplace_back(state); +} + +void PermissionPolicySet::StorePermissionDef(std::vector& valueList) const +{ + for (auto permissionDef : permList_) { + GenericValues genericValues; + genericValues.Put(FIELD_TOKEN_ID, tokenId_); + DataTranslator::TranslationIntoGenericValues(permissionDef, genericValues); + valueList.emplace_back(genericValues); + } +} + +void PermissionPolicySet::StorePermissionState(std::vector& valueList) const +{ + for (auto permissionState : permStateList_) { + if (permissionState.isGeneral) { + GenericValues genericValues; + genericValues.Put(FIELD_TOKEN_ID, tokenId_); + DataTranslator::TranslationIntoGenericValues(permissionState, 0, genericValues); + valueList.emplace_back(genericValues); + continue; + } + + unsigned int stateSize = permissionState.resDeviceID.size(); + for (unsigned int i = 0; i < stateSize; i++) { + GenericValues genericValues; + genericValues.Put(FIELD_TOKEN_ID, tokenId_); + DataTranslator::TranslationIntoGenericValues(permissionState, i, genericValues); + valueList.emplace_back(genericValues); + } + } +} + +void PermissionPolicySet::StorePermissionPolicySet(std::vector& permDefValueList, + std::vector& permStateValueList) +{ + Utils::UniqueReadGuard infoGuard(this->permPolicySetLock_); + StorePermissionDef(permDefValueList); + StorePermissionState(permStateValueList); +} + +int PermissionPolicySet::VerifyPermissStatus(const std::string& permissionName) +{ + Utils::UniqueReadGuard infoGuard(this->permPolicySetLock_); + for (auto perm : permStateList_) { + if (perm.permissionName == permissionName) { + if (perm.isGeneral == true) { + return perm.grantStatus[0]; + } else { + return PERMISSION_DENIED; + } + } + } + return PERMISSION_DENIED; +} + +void PermissionPolicySet::GetDefPermissions(std::vector& permList) +{ + Utils::UniqueReadGuard infoGuard(this->permPolicySetLock_); + permList.assign(permList_.begin(), permList_.end()); +} + +void PermissionPolicySet::GetPermissionStateFulls(std::vector& permList) +{ + Utils::UniqueReadGuard infoGuard(this->permPolicySetLock_); + permList.assign(permStateList_.begin(), permStateList_.end()); +} + +int PermissionPolicySet::QueryPermissionFlag(const std::string& permissionName) +{ + Utils::UniqueReadGuard infoGuard(this->permPolicySetLock_); + for (auto perm : permStateList_) { + if (perm.permissionName == permissionName) { + if (perm.isGeneral == true) { + return perm.grantFlags[0]; + } else { + return DEFAULT_PERMISSION_FLAGS; + } + } + } + return DEFAULT_PERMISSION_FLAGS; +} + +void PermissionPolicySet::UpdatePermissionStatus(const std::string& permissionName, bool isGranted, int flag) +{ + Utils::UniqueWriteGuard infoGuard(this->permPolicySetLock_); + for (auto& perm : permStateList_) { + if (perm.permissionName == permissionName) { + if (perm.isGeneral == true) { + perm.grantStatus[0] = isGranted ? PERMISSION_GRANTED : PERMISSION_DENIED; + perm.grantFlags[0] = flag; + } else { + return; + } + } + } +} + +void PermissionPolicySet::GetPermissionStateList(std::vector& stateList) +{ + Utils::UniqueReadGuard infoGuard(this->permPolicySetLock_); + for (auto& state : permStateList_) { + stateList.emplace_back(state); + } +} + +void PermissionPolicySet::PermDefToString(const PermissionDef& def, std::string& info) const +{ + info.append(R"({"permissionName": ")" + def.permissionName + R"(")"); + info.append(R"(, "bundleName": ")" + def.bundleName + R"(")"); + info.append(R"(, "grantMode": )" + std::to_string(def.grantMode)); + info.append(R"(, "availableLevel": )" + std::to_string(def.availableLevel)); + info.append(R"(, "provisionEnable": )" + std::to_string(def.provisionEnable)); + info.append(R"(, "distributedSceneEnable": )" + std::to_string(def.distributedSceneEnable)); + info.append(R"(, "label": ")" + def.label + R"(")"); + info.append(R"(, "labelId": )" + std::to_string(def.labelId)); + info.append(R"(, "description": ")" + def.description + R"(")"); + info.append(R"(, "descriptionId": )" + std::to_string(def.descriptionId)); + info.append(R"(})"); +} + +void PermissionPolicySet::PermStateFullToString(const PermissionStateFull& state, std::string& info) const +{ + info.append(R"({"permissionName": ")" + state.permissionName + R"(")"); + info.append(R"(, "isGeneral": )" + std::to_string(state.isGeneral)); + + info.append(R"(, "resDeviceIDList": [ )"); + for (auto iter = state.resDeviceID.begin(); iter != state.resDeviceID.end(); iter++) { + info.append(R"({"resDeviceID": ")" + *iter + R"("})"); + if (iter != (state.resDeviceID.end() - 1)) { + info.append(","); + } + } + + info.append(R"(], "grantStatusList": [)"); + for (auto iter = state.grantStatus.begin(); iter != state.grantStatus.end(); iter++) { + info.append(R"({"grantStatus": )" + std::to_string(*iter) + "}"); + if (iter != (state.grantStatus.end() - 1)) { + info.append(","); + } + } + + info.append(R"(], "grantFlagsList": [)"); + for (auto iter = state.grantFlags.begin(); iter != state.grantFlags.end(); iter++) { + info.append(R"({"grantFlag": )" + std::to_string(*iter) + "}"); + if (iter != (state.grantFlags.end() - 1)) { + info.append(","); + } + } + + info.append(R"(]})"); +} + +void PermissionPolicySet::ToString(std::string& info) +{ + Utils::UniqueReadGuard infoGuard(this->permPolicySetLock_); + info.append(",\n\t"); + info.append(R"("permDefList": [)"); + for (auto iter = permList_.begin(); iter != permList_.end(); iter++) { + info.append("\n\t\t"); + PermDefToString(*iter, info); + if (iter != (permList_.end() - 1)) { + info.append(","); + } + } + info.append("]"); + + info.append(",\n\t"); + info.append(R"("permStateList": [)"); + for (auto iter = permStateList_.begin(); iter != permStateList_.end(); iter++) { + info.append("\n\t\t"); + PermStateFullToString(*iter, info); + if (iter != (permStateList_.end() - 1)) { + info.append(","); + } + } + info.append("]"); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/permission/permission_validator.cpp b/services/accesstokenmanager/main/cpp/src/permission/permission_validator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..848675ec4aa2680176826d7213cf931001967dfa --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/permission/permission_validator.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2021 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_validator.h" + +#include + +#include "access_token.h" +#include "data_validator.h" +#include "permission_definition_cache.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +bool PermissionValidator::IsGrantModeValid(int grantMode) +{ + return grantMode == GrantMode::SYSTEM_GRANT || grantMode == GrantMode::USER_GRANT; +} + +bool PermissionValidator::IsGrantStatusValid(int grantStaus) +{ + return grantStaus == PermissionState::PERMISSION_GRANTED || grantStaus == PermissionState::PERMISSION_DENIED; +} + +bool PermissionValidator::IsPermissionFlagValid(int flag) +{ + return flag == DEFAULT_PERMISSION_FLAGS || + flag == PermissionFlag::PERMISSION_USER_SET || + flag == PermissionFlag::PERMISSION_USER_FIXED || + flag == PermissionFlag::PERMISSION_SYSTEM_FIXED; +} + +bool PermissionValidator::IsPermissionNameValid(const std::string& permissionName) +{ + return DataValidator::IsPermissionNameValid(permissionName); +} + +bool PermissionValidator::IsPermissionDefValid(const PermissionDef& permDef) +{ + if (!DataValidator::IsLabelValid(permDef.label)) { + return false; + } + if (!DataValidator::IsDescValid(permDef.description)) { + return false; + } + if (!DataValidator::IsBundleNameValid(permDef.bundleName)) { + return false; + } + if (!DataValidator::IsPermissionNameValid(permDef.permissionName)) { + return false; + } + if (!IsGrantModeValid(permDef.grantMode)) { + return false; + } + return DataValidator::IsAplNumValid(permDef.availableLevel); +} + +bool PermissionValidator::IsPermissionStateValid(const PermissionStateFull& permState) +{ + if (!DataValidator::IsPermissionNameValid(permState.permissionName)) { + return false; + } + + size_t resDevIdSize = permState.resDeviceID.size(); + size_t grantStatSize = permState.grantStatus.size(); + size_t grantFlagSize = permState.grantFlags.size(); + if ((grantStatSize != resDevIdSize) || (grantFlagSize != resDevIdSize)) { + return false; + } + + for (uint32_t i = 0; i < resDevIdSize; i++) { + if (!IsGrantStatusValid(permState.grantStatus[i]) || + !IsPermissionFlagValid(permState.grantFlags[i])) { + return false; + } + } + return true; +} + + +void PermissionValidator::FilterInvalidPermisionDef( + const std::vector& permList, std::vector& result) +{ + std::set permDefSet; + for (auto it = permList.begin(); it != permList.end(); ++it) { + std::string permName = it->permissionName; + if (!IsPermissionDefValid(*it) || permDefSet.count(permName) != 0) { + continue; + } + permDefSet.insert(permName); + result.emplace_back(*it); + } +} + +void PermissionValidator::DeduplicateResDevID(const PermissionStateFull& permState, PermissionStateFull& result) +{ + std::set resDevId; + auto stateIter = permState.grantStatus.begin(); + auto flagIter = permState.grantFlags.begin(); + for (auto it = permState.resDeviceID.begin(); it != permState.resDeviceID.end(); ++it, ++stateIter, ++flagIter) { + if (resDevId.count(*it) != 0) { + continue; + } + resDevId.insert(*it); + result.resDeviceID.emplace_back(*it); + result.grantStatus.emplace_back(*stateIter); + result.grantFlags.emplace_back(*flagIter); + } + result.permissionName = permState.permissionName; + result.isGeneral = permState.isGeneral; +} + +void PermissionValidator::FilterInvalidPermisionState( + const std::vector& permList, std::vector& result) +{ + std::set permStateSet; + for (auto it = permList.begin(); it != permList.end(); ++it) { + std::string permName = it->permissionName; + PermissionStateFull res; + if (!IsPermissionStateValid(*it) || permStateSet.count(permName) != 0) { + continue; + } + DeduplicateResDevID(*it, res); + permStateSet.insert(permName); + result.emplace_back(res); + } +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4fe4e741bb38c80904e0f01a7ab945a8c1dd6ad4 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2021 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_manager_service.h" + +#include "access_token.h" +#include "accesstoken_id_manager.h" +#include "accesstoken_info_manager.h" +#include "accesstoken_log.h" +#include "hap_token_info.h" +#include "hap_token_info_inner.h" +#include "native_token_info_inner.h" +#include "native_token_receptor.h" +#include "permission_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenManagerService" +}; +} + +const bool REGISTER_RESULT = + SystemAbility::MakeAndRegisterAbility(DelayedSingleton::GetInstance().get()); + +AccessTokenManagerService::AccessTokenManagerService() + : SystemAbility(SA_ID_ACCESSTOKEN_MANAGER_SERVICE, true), state_(ServiceRunningState::STATE_NOT_START) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "AccessTokenManagerService()"); +} + +AccessTokenManagerService::~AccessTokenManagerService() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "~AccessTokenManagerService()"); +} + +void AccessTokenManagerService::OnStart() +{ + if (state_ == ServiceRunningState::STATE_RUNNING) { + ACCESSTOKEN_LOG_INFO(LABEL, "AccessTokenManagerService has already started!"); + return; + } + ACCESSTOKEN_LOG_INFO(LABEL, "AccessTokenManagerService is starting"); + if (!Initialize()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to initialize"); + return; + } + state_ = ServiceRunningState::STATE_RUNNING; + bool ret = Publish(DelayedSingleton::GetInstance().get()); + if (!ret) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to publish service!"); + return; + } + ACCESSTOKEN_LOG_INFO(LABEL, "Congratulations, AccessTokenManagerService start successfully!"); +} + +void AccessTokenManagerService::OnStop() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "stop service"); + state_ = ServiceRunningState::STATE_NOT_START; +} + +int AccessTokenManagerService::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s", __func__, + tokenID, permissionName.c_str()); + return PermissionManager::GetInstance().VerifyAccessToken(tokenID, permissionName); +} + +int AccessTokenManagerService::GetDefPermission( + const std::string& permissionName, PermissionDefParcel& permissionDefResult) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, permissionName: %{public}s", __func__, permissionName.c_str()); + return PermissionManager::GetInstance().GetDefPermission(permissionName, permissionDefResult.permissionDef); +} + +int AccessTokenManagerService::GetDefPermissions(AccessTokenID tokenID, std::vector& permList) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + std::vector permVec; + int ret = PermissionManager::GetInstance().GetDefPermissions(tokenID, permVec); + for (auto perm : permVec) { + PermissionDefParcel permPrcel; + permPrcel.permissionDef = perm; + permList.emplace_back(permPrcel); + } + return ret; +} + +int AccessTokenManagerService::GetReqPermissions( + AccessTokenID tokenID, std::vector& reqPermList, bool isSystemGrant) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x, isSystemGrant: %{public}d", __func__, tokenID, isSystemGrant); + + std::vector permList; + int ret = PermissionManager::GetInstance().GetReqPermissions(tokenID, permList, isSystemGrant); + + for (auto& perm : permList) { + PermissionStateFullParcel permPrcel; + permPrcel.permStatFull = perm; + reqPermList.emplace_back(permPrcel); + } + return ret; +} + +int AccessTokenManagerService::GetPermissionFlag(AccessTokenID tokenID, const std::string& permissionName) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s", __func__, + tokenID, permissionName.c_str()); + return PermissionManager::GetInstance().GetPermissionFlag(tokenID, permissionName); +} + +int AccessTokenManagerService::GrantPermission(AccessTokenID tokenID, const std::string& permissionName, int flag) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s, flag: %{public}d", __func__, + tokenID, permissionName.c_str(), flag); + PermissionManager::GetInstance().GrantPermission(tokenID, permissionName, flag); + AccessTokenInfoManager::GetInstance().RefreshTokenInfoIfNeeded(); + return RET_SUCCESS; +} + +int AccessTokenManagerService::RevokePermission(AccessTokenID tokenID, const std::string& permissionName, int flag) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x, permissionName: %{public}s, flag: %{public}d", __func__, + tokenID, permissionName.c_str(), flag); + PermissionManager::GetInstance().RevokePermission(tokenID, permissionName, flag); + AccessTokenInfoManager::GetInstance().RefreshTokenInfoIfNeeded(); + return RET_SUCCESS; +} + +int AccessTokenManagerService::ClearUserGrantedPermissionState(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + PermissionManager::GetInstance().ClearUserGrantedPermissionState(tokenID); + AccessTokenInfoManager::GetInstance().RefreshTokenInfoIfNeeded(); + return RET_SUCCESS; +} + +AccessTokenIDEx AccessTokenManagerService::AllocHapToken(const HapInfoParcel& info, const HapPolicyParcel& policy) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + AccessTokenIDEx tokenIdEx; + tokenIdEx.tokenIDEx = 0LL; + + int ret = AccessTokenInfoManager::GetInstance().CreateHapTokenInfo( + info.hapInfoParameter, policy.hapPolicyParameter, tokenIdEx); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_INFO(LABEL, "hap token info create failed"); + } + return tokenIdEx; +} + +int AccessTokenManagerService::DeleteToken(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + // only support hap token deletion + return AccessTokenInfoManager::GetInstance().RemoveHapTokenInfo(tokenID); +} + +int AccessTokenManagerService::GetTokenType(AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + return AccessTokenIDManager::GetInstance().GetTokenIdType(tokenID); +} + +int AccessTokenManagerService::CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x, dcap: %{public}s", + __func__, tokenID, dcap.c_str()); + return AccessTokenInfoManager::GetInstance().CheckNativeDCap(tokenID, dcap); +} + +AccessTokenID AccessTokenManagerService::GetHapTokenID(int userID, const std::string& bundleName, int instIndex) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, userID: %{public}d, bundleName: %{public}s, instIndex: %{public}d", + __func__, userID, bundleName.c_str(), instIndex); + return AccessTokenInfoManager::GetInstance().GetHapTokenID(userID, bundleName, instIndex); +} + +AccessTokenID AccessTokenManagerService::AllocLocalTokenID( + const std::string& remoteDeviceID, AccessTokenID remoteTokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, remoteDeviceID: %{public}s, remoteTokenID: %{public}d", + __func__, remoteDeviceID.c_str(), remoteTokenID); + return AccessTokenInfoManager::GetInstance().AllocLocalTokenID(remoteDeviceID, remoteTokenID); +} + +int AccessTokenManagerService::UpdateHapToken(AccessTokenID tokenID, const std::string& appIDDesc, + const HapPolicyParcel& policyParcel) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + + return AccessTokenInfoManager::GetInstance().UpdateHapToken(tokenID, appIDDesc, + policyParcel.hapPolicyParameter); +} + +int AccessTokenManagerService::GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfoParcel& InfoParcel) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + + return AccessTokenInfoManager::GetInstance().GetHapTokenInfo(tokenID, InfoParcel.hapTokenInfoParams); +} + +int AccessTokenManagerService::GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfoParcel& InfoParcel) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + + return AccessTokenInfoManager::GetInstance().GetNativeTokenInfo(tokenID, InfoParcel.nativeTokenInfoParams); +} + +int AccessTokenManagerService::GetHapTokenInfoFromRemote(AccessTokenID tokenID, + HapTokenInfoForSyncParcel& hapSyncParcel) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, tokenID: 0x%{public}x", __func__, tokenID); + + return AccessTokenInfoManager::GetInstance().GetHapTokenInfoFromRemote(tokenID, + hapSyncParcel.hapTokenInfoForSyncParams); +} + +int AccessTokenManagerService::GetAllNativeTokenInfo(std::vector& nativeTokenInfosRes) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called", __func__); + + std::vector nativeVec; + AccessTokenInfoManager::GetInstance().GetAllNativeTokenInfo(nativeVec); + for (auto& native : nativeVec) { + NativeTokenInfoParcel nativeParcel; + nativeParcel.nativeTokenInfoParams = native; + nativeTokenInfosRes.emplace_back(nativeParcel); + } + + return RET_SUCCESS; +} + +int AccessTokenManagerService::SetRemoteHapTokenInfo(const std::string& deviceID, + HapTokenInfoForSyncParcel& hapSyncParcel) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID: 0x%{public}s", __func__, deviceID.c_str()); + + return AccessTokenInfoManager::GetInstance().SetRemoteHapTokenInfo(deviceID, + hapSyncParcel.hapTokenInfoForSyncParams); +} + +int AccessTokenManagerService::SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoParcel) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID: 0x%{public}s", __func__, deviceID.c_str()); + + std::vector nativeList; + + for (auto& nativeParcel : nativeTokenInfoParcel) { + nativeList.emplace_back(nativeParcel.nativeTokenInfoParams); + } + + return AccessTokenInfoManager::GetInstance().SetRemoteNativeTokenInfo(deviceID, nativeList); +} + +int AccessTokenManagerService::DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID: %{public}s, token id %{public}d", + __func__, deviceID.c_str(), tokenID); + + return AccessTokenInfoManager::GetInstance().DeleteRemoteToken(deviceID, tokenID); +} + +int AccessTokenManagerService::DeleteRemoteDeviceTokens(const std::string& deviceID) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, deviceID: %{public}s", __func__, deviceID.c_str()); + + return AccessTokenInfoManager::GetInstance().DeleteRemoteDeviceTokens(deviceID); +} + +int AccessTokenManagerService::DumpToken(std::string& dumpInfo) +{ + AccessTokenInfoManager::GetInstance().Dump(dumpInfo); + return 0; +} + +bool AccessTokenManagerService::Initialize() const +{ + AccessTokenInfoManager::GetInstance().Init(); + NativeTokenReceptor::GetInstance().Init(); + return true; +} +} // namespace AccessToken +} // namespace Security +} diff --git a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afb050cda7924bb3a27792e46234d5eb0207118e --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_stub.cpp @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2021 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_manager_stub.h" + +#include "accesstoken_log.h" + +#include "ipc_skeleton.h" +#include "string_ex.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenManagerStub"}; +} + +int32_t AccessTokenManagerStub::OnRemoteRequest( + uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, code: %{public}d", __func__, code); + std::u16string descriptor = data.ReadInterfaceToken(); + if (descriptor != IAccessTokenManager::GetDescriptor()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "get unexpect descriptor: %{public}s", Str16ToStr8(descriptor).c_str()); + return -1; + } + auto itFunc = requestFuncMap_.find(code); + if (itFunc != requestFuncMap_.end()) { + auto requestFunc = itFunc->second; + if (requestFunc != nullptr) { + (this->*requestFunc)(data, reply); + } else { + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return NO_ERROR; +} + +void AccessTokenManagerStub::DeleteTokenInfoInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "permission denied"); + reply.WriteInt32(RET_FAILED); + return; + } + AccessTokenID tokenID = data.ReadUint32(); + int result = this->DeleteToken(tokenID); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::VerifyAccessTokenInner(MessageParcel& data, MessageParcel& reply) +{ + AccessTokenID tokenID = data.ReadUint32(); + std::string permissionName = data.ReadString(); + int result = this->VerifyAccessToken(tokenID, permissionName); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GetDefPermissionInner(MessageParcel& data, MessageParcel& reply) +{ + std::string permissionName = data.ReadString(); + PermissionDefParcel permissionDefParcel; + int result = this->GetDefPermission(permissionName, permissionDefParcel); + reply.WriteParcelable(&permissionDefParcel); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GetDefPermissionsInner(MessageParcel& data, MessageParcel& reply) +{ + AccessTokenID tokenID = data.ReadUint32(); + std::vector permList; + + int result = this->GetDefPermissions(tokenID, permList); + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permList size: %{public}d", __func__, (int) permList.size()); + reply.WriteInt32((int32_t)permList.size()); + for (auto permDef : permList) { + reply.WriteParcelable(&permDef); + } + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GetReqPermissionsInner(MessageParcel& data, MessageParcel& reply) +{ + AccessTokenID tokenID = data.ReadUint32(); + int isSystemGrant = data.ReadInt32(); + std::vector permList; + + int result = this->GetReqPermissions(tokenID, permList, isSystemGrant); + ACCESSTOKEN_LOG_INFO(LABEL, "permList size: %{public}d", (int) permList.size()); + reply.WriteInt32((int32_t)permList.size()); + for (auto permDef : permList) { + reply.WriteParcelable(&permDef); + } + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GetPermissionFlagInner(MessageParcel& data, MessageParcel& reply) +{ + unsigned int callingTokenID = IPCSkeleton::GetCallingTokenID(); + ACCESSTOKEN_LOG_INFO(LABEL, "callingTokenID: %{public}d", callingTokenID); + AccessTokenID tokenID = data.ReadUint32(); + std::string permissionName = data.ReadString(); + if (!IsAuthorizedCalling() && + VerifyAccessToken(callingTokenID, "ohos.permission.GRANT_SENSITIVE_PERMISSIONS") == PERMISSION_DENIED && + VerifyAccessToken(callingTokenID, "ohos.permission.REVOKE_SENSITIVE_PERMISSIONS") == PERMISSION_DENIED && + VerifyAccessToken(callingTokenID, "ohos.permission.GET_SENSITIVE_PERMISSIONS") == PERMISSION_DENIED) { + ACCESSTOKEN_LOG_INFO(LABEL, "permission denied"); + reply.WriteInt32(DEFAULT_PERMISSION_FLAGS); + return; + } + int result = this->GetPermissionFlag(tokenID, permissionName); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GrantPermissionInner(MessageParcel& data, MessageParcel& reply) +{ + unsigned int callingTokenID = IPCSkeleton::GetCallingTokenID(); + ACCESSTOKEN_LOG_INFO(LABEL, "callingTokenID: %{public}d", callingTokenID); + AccessTokenID tokenID = data.ReadUint32(); + std::string permissionName = data.ReadString(); + int flag = data.ReadInt32(); + if (!IsAuthorizedCalling() && + VerifyAccessToken(callingTokenID, "ohos.permission.GRANT_SENSITIVE_PERMISSIONS") == PERMISSION_DENIED) { + ACCESSTOKEN_LOG_INFO(LABEL, "permission denied"); + reply.WriteInt32(RET_FAILED); + return; + } + int result = this->GrantPermission(tokenID, permissionName, flag); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::RevokePermissionInner(MessageParcel& data, MessageParcel& reply) +{ + unsigned int callingTokenID = IPCSkeleton::GetCallingTokenID(); + ACCESSTOKEN_LOG_INFO(LABEL, "callingTokenID: %{public}d", callingTokenID); + AccessTokenID tokenID = data.ReadUint32(); + std::string permissionName = data.ReadString(); + int flag = data.ReadInt32(); + if (!IsAuthorizedCalling() && + VerifyAccessToken(callingTokenID, "ohos.permission.REVOKE_SENSITIVE_PERMISSIONS") == PERMISSION_DENIED) { + ACCESSTOKEN_LOG_INFO(LABEL, "permission denied"); + reply.WriteInt32(RET_FAILED); + return; + } + int result = this->RevokePermission(tokenID, permissionName, flag); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::ClearUserGrantedPermissionStateInner(MessageParcel& data, MessageParcel& reply) +{ + AccessTokenID tokenID = data.ReadUint32(); + int result = this->ClearUserGrantedPermissionState(tokenID); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::AllocHapTokenInner(MessageParcel& data, MessageParcel& reply) +{ + AccessTokenIDEx res = {0}; + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + + sptr hapInfoParcel = data.ReadParcelable(); + sptr hapPolicyParcel = data.ReadParcelable(); + + res = this->AllocHapToken(*hapInfoParcel, *hapPolicyParcel); + reply.WriteUint64(res.tokenIDEx); +} + +void AccessTokenManagerStub::GetTokenTypeInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + AccessTokenID tokenID = data.ReadUint32(); + int result = this->GetTokenType(tokenID); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::CheckNativeDCapInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + AccessTokenID tokenID = data.ReadUint32(); + std::string dCap = data.ReadString(); + int result = this->CheckNativeDCap(tokenID, dCap); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GetHapTokenIDInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + int userID = data.ReadInt32(); + std::string bundleName = data.ReadString(); + int instIndex = data.ReadInt32(); + AccessTokenID result = this->GetHapTokenID(userID, bundleName, instIndex); + reply.WriteUint32(result); +} + +void AccessTokenManagerStub::AllocLocalTokenIDInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + std::string remoteDeviceID = data.ReadString(); + AccessTokenID remoteTokenID = data.ReadUint32(); + AccessTokenID result = this->AllocLocalTokenID(remoteDeviceID, remoteTokenID); + reply.WriteUint32(result); +} + +void AccessTokenManagerStub::UpdateHapTokenInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + AccessTokenID tokenID = data.ReadUint32(); + std::string appIDDesc = data.ReadString(); + sptr policyParcel = data.ReadParcelable(); + + int32_t result = this->UpdateHapToken(tokenID, appIDDesc, *policyParcel); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GetHapTokenInfoInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + HapTokenInfoParcel hapTokenInfoParcel; + AccessTokenID tokenID = data.ReadUint32(); + int result = this->GetHapTokenInfo(tokenID, hapTokenInfoParcel); + reply.WriteParcelable(&hapTokenInfoParcel); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GetNativeTokenInfoInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + AccessTokenID tokenID = data.ReadUint32(); + NativeTokenInfoParcel nativeTokenInfoParcel; + int result = this->GetNativeTokenInfo(tokenID, nativeTokenInfoParcel); + reply.WriteParcelable(&nativeTokenInfoParcel); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GetHapTokenInfoFromRemoteInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + AccessTokenID tokenID = data.ReadUint32(); + HapTokenInfoForSyncParcel hapTokenParcel; + + int result = this->GetHapTokenInfoFromRemote(tokenID, hapTokenParcel); + reply.WriteParcelable(&hapTokenParcel); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::GetAllNativeTokenInfoInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + std::vector nativeTokenInfosRes; + int result = this->GetAllNativeTokenInfo(nativeTokenInfosRes); + reply.WriteUint32(nativeTokenInfosRes.size()); + for (auto native : nativeTokenInfosRes) { + reply.WriteParcelable(&native); + } + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::SetRemoteHapTokenInfoInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + std::string deviceID = data.ReadString(); + sptr hapTokenParcel = data.ReadParcelable(); + int result = this->SetRemoteHapTokenInfo(deviceID, *hapTokenParcel); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::SetRemoteNativeTokenInfoInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + std::string deviceID = data.ReadString(); + + std::vector nativeTokenInfoParcel; + uint32_t size = data.ReadUint32(); + + for (uint32_t i = 0; i < size; i++) { + sptr nativeParcel = data.ReadParcelable(); + nativeTokenInfoParcel.emplace_back(*nativeParcel); + } + + int result = this->SetRemoteNativeTokenInfo(deviceID, nativeTokenInfoParcel); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::DeleteRemoteTokenInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + std::string deviceID = data.ReadString(); + AccessTokenID tokenID = data.ReadUint32(); + + int result = this->DeleteRemoteToken(deviceID, tokenID); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::DeleteRemoteDeviceTokensInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + std::string deviceID = data.ReadString(); + + int result = this->DeleteRemoteDeviceTokens(deviceID); + reply.WriteInt32(result); +} + +void AccessTokenManagerStub::DumpTokenInner(MessageParcel& data, MessageParcel& reply) +{ + if (!IsAuthorizedCalling()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, permission denied", __func__); + reply.WriteInt32(RET_FAILED); + return; + } + std::string dumpInfo; + int result = this->DumpToken(dumpInfo); + reply.WriteString(dumpInfo); + reply.WriteUint32(result); +} + +bool AccessTokenManagerStub::IsAuthorizedCalling() const +{ + int callingUid = IPCSkeleton::GetCallingUid(); + ACCESSTOKEN_LOG_INFO(LABEL, "Calling uid: %{public}d", callingUid); + return callingUid == SYSTEM_UID || callingUid == ROOT_UID; +} + +AccessTokenManagerStub::AccessTokenManagerStub() +{ + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::VERIFY_ACCESSTOKEN)] = + &AccessTokenManagerStub::VerifyAccessTokenInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_DEF_PERMISSION)] = + &AccessTokenManagerStub::GetDefPermissionInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_DEF_PERMISSIONS)] = + &AccessTokenManagerStub::GetDefPermissionsInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_REQ_PERMISSIONS)] = + &AccessTokenManagerStub::GetReqPermissionsInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_PERMISSION_FLAG)] = + &AccessTokenManagerStub::GetPermissionFlagInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GRANT_PERMISSION)] = + &AccessTokenManagerStub::GrantPermissionInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::REVOKE_PERMISSION)] = + &AccessTokenManagerStub::RevokePermissionInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::CLEAR_USER_GRANT_PERMISSION)] = + &AccessTokenManagerStub::ClearUserGrantedPermissionStateInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::ALLOC_TOKEN_HAP)] = + &AccessTokenManagerStub::AllocHapTokenInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::TOKEN_DELETE)] = + &AccessTokenManagerStub::DeleteTokenInfoInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_TOKEN_TYPE)] = + &AccessTokenManagerStub::GetTokenTypeInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::CHECK_NATIVE_DCAP)] = + &AccessTokenManagerStub::CheckNativeDCapInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_HAP_TOKEN_ID)] = + &AccessTokenManagerStub::GetHapTokenIDInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::ALLOC_LOCAL_TOKEN_ID)] = + &AccessTokenManagerStub::AllocLocalTokenIDInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_NATIVE_TOKENINFO)] = + &AccessTokenManagerStub::GetNativeTokenInfoInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_HAP_TOKENINFO)] = + &AccessTokenManagerStub::GetHapTokenInfoInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::UPDATE_HAP_TOKEN)] = + &AccessTokenManagerStub::UpdateHapTokenInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_HAP_TOKEN_FROM_REMOTE)] = + &AccessTokenManagerStub::GetHapTokenInfoFromRemoteInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::GET_ALL_NATIVE_TOKEN_FROM_REMOTE)] = + &AccessTokenManagerStub::GetAllNativeTokenInfoInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::SET_REMOTE_HAP_TOKEN_INFO)] = + &AccessTokenManagerStub::SetRemoteHapTokenInfoInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::SET_REMOTE_NATIVE_TOKEN_INFO)] = + &AccessTokenManagerStub::SetRemoteNativeTokenInfoInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::DELETE_REMOTE_TOKEN_INFO)] = + &AccessTokenManagerStub::DeleteRemoteTokenInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::DELETE_REMOTE_DEVICE_TOKEN)] = + &AccessTokenManagerStub::DeleteRemoteDeviceTokensInner; + requestFuncMap_[static_cast(IAccessTokenManager::InterfaceCode::DUMP)] = + &AccessTokenManagerStub::DumpTokenInner; +} + +AccessTokenManagerStub::~AccessTokenManagerStub() +{ + requestFuncMap_.clear(); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/token/accesstoken_id_manager.cpp b/services/accesstokenmanager/main/cpp/src/token/accesstoken_id_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7bedb75559322bd9988fd1d0c96a7643f9e4a7cb --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/token/accesstoken_id_manager.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021 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_id_manager.h" + +#include + +#include "accesstoken_log.h" +#include "data_validator.h" +#include "random.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenIDManager"}; +} + +ATokenTypeEnum AccessTokenIDManager::GetTokenIdTypeEnum(AccessTokenID id) +{ + AccessTokenIDInner *idInner = (AccessTokenIDInner *)&id; + return (ATokenTypeEnum)idInner->type; +} + +ATokenTypeEnum AccessTokenIDManager::GetTokenIdType(AccessTokenID id) +{ + { + Utils::UniqueReadGuard idGuard(this->tokenIdLock_); + if (tokenIdSet_.count(id) == 0) { + return TOKEN_INVALID; + } + } + return GetTokenIdTypeEnum(id); +} + +int AccessTokenIDManager::RegisterTokenId(AccessTokenID id, ATokenTypeEnum type) +{ + AccessTokenIDInner *idInner = (AccessTokenIDInner *)&id; + if (idInner->version != DEFAULT_TOKEN_VERSION || idInner->type != type) { + return RET_FAILED; + } + + Utils::UniqueWriteGuard idGuard(this->tokenIdLock_); + if (tokenIdSet_.count(id) != 0) { + return RET_FAILED; + } + + tokenIdSet_.insert(id); + return RET_SUCCESS; +} + +AccessTokenID AccessTokenIDManager::CreateTokenId(ATokenTypeEnum type) const +{ + unsigned int rand = GetRandomUint32(); + if (rand == 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "get random failed"); + return 0; + } + + AccessTokenIDInner innerId = {0}; + innerId.version = DEFAULT_TOKEN_VERSION; + innerId.type = type; + innerId.res = 0; + innerId.tokenUniqueID = rand & TOKEN_RANDOM_MASK; + AccessTokenID tokenId = *(AccessTokenID *)&innerId; + return tokenId; +} + +AccessTokenID AccessTokenIDManager::CreateAndRegisterTokenId(ATokenTypeEnum type) +{ + AccessTokenID tokenId = 0; + // random maybe repeat, retry twice. + for (int i = 0; i < MAX_CREATE_TOKEN_ID_RETRY; i++) { + tokenId = CreateTokenId(type); + if (tokenId == 0) { + ACCESSTOKEN_LOG_WARN(LABEL, "create tokenId failed"); + return 0; + } + + int ret = RegisterTokenId(tokenId, type); + if (ret == RET_SUCCESS) { + break; + } 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"); + } + } + return tokenId; +} + +void AccessTokenIDManager::ReleaseTokenId(AccessTokenID id) +{ + Utils::UniqueWriteGuard idGuard(this->tokenIdLock_); + if (tokenIdSet_.count(id) == 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "id %{public}x is not exist", id); + return; + } + tokenIdSet_.erase(id); +} + +AccessTokenIDManager& AccessTokenIDManager::GetInstance() +{ + static AccessTokenIDManager instance; + return instance; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/token/accesstoken_info_manager.cpp b/services/accesstokenmanager/main/cpp/src/token/accesstoken_info_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c504c2c7215e83395fdefac9cfa133595393bdfd --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/token/accesstoken_info_manager.cpp @@ -0,0 +1,846 @@ +/* + * Copyright (c) 2021 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_info_manager.h" + +#include "accesstoken_id_manager.h" +#include "accesstoken_log.h" +#include "accesstoken_remote_token_manager.h" +#include "data_storage.h" +#include "data_translator.h" +#include "data_validator.h" +#include "field_const.h" +#include "generic_values.h" +#include "hap_token_info_inner.h" +#include "permission_manager.h" +#include "token_modify_notifier.h" +#include "token_sync_kit.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenInfoManager"}; +} + +AccessTokenInfoManager::AccessTokenInfoManager() : hasInited_(false) {} + +AccessTokenInfoManager::~AccessTokenInfoManager() +{ + if (!hasInited_) { + return; + } + this->tokenDataWorker_.Stop(); + this->hasInited_ = false; +} + +void AccessTokenInfoManager::Init() +{ + OHOS::Utils::UniqueWriteGuard lk(this->managerLock_); + if (hasInited_) { + return; + } + + ACCESSTOKEN_LOG_INFO(LABEL, "init begin!"); + InitHapTokenInfos(); + InitNativeTokenInfos(); + this->tokenDataWorker_.Start(1); + hasInited_ = true; + ACCESSTOKEN_LOG_INFO(LABEL, "Init success"); +} + +void AccessTokenInfoManager::InitHapTokenInfos() +{ + std::vector hapTokenRes; + std::vector permDefRes; + std::vector permStateRes; + + DataStorage::GetRealDataStorage().Find(DataStorage::ACCESSTOKEN_HAP_INFO, hapTokenRes); + DataStorage::GetRealDataStorage().Find(DataStorage::ACCESSTOKEN_PERMISSION_DEF, permDefRes); + DataStorage::GetRealDataStorage().Find(DataStorage::ACCESSTOKEN_PERMISSION_STATE, permStateRes); + + for (GenericValues& tokenValue : hapTokenRes) { + AccessTokenID tokenId = (AccessTokenID)tokenValue.GetInt(FIELD_TOKEN_ID); + int ret = AccessTokenIDManager::GetInstance().RegisterTokenId(tokenId, TOKEN_HAP); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x add id failed.", tokenId); + continue; + } + std::shared_ptr hap = std::make_shared(); + if (hap == nullptr) { + AccessTokenIDManager::GetInstance().ReleaseTokenId(tokenId); + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x alloc failed.", tokenId); + continue; + } + ret = hap->RestoreHapTokenInfo(tokenId, tokenValue, permDefRes, permStateRes); + if (ret != RET_SUCCESS) { + AccessTokenIDManager::GetInstance().ReleaseTokenId(tokenId); + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x restore failed.", tokenId); + continue; + } + + ret = AddHapTokenInfo(hap); + if (ret != RET_SUCCESS) { + AccessTokenIDManager::GetInstance().ReleaseTokenId(tokenId); + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x add failed.", tokenId); + continue; + } + ACCESSTOKEN_LOG_INFO(LABEL, + " restore hap token 0x%{public}x bundle name %{public}s user %{public}d inst %{public}d ok!", + tokenId, hap->GetBundleName().c_str(), hap->GetUserID(), hap->GetInstIndex()); + } +} + +void AccessTokenInfoManager::InitNativeTokenInfos() +{ + std::vector nativeTokenResults; + DataStorage::GetRealDataStorage().Find(DataStorage::ACCESSTOKEN_NATIVE_INFO, nativeTokenResults); + for (GenericValues nativeTokenValue : nativeTokenResults) { + AccessTokenID tokenId = (AccessTokenID)nativeTokenValue.GetInt(FIELD_TOKEN_ID); + int ret = AccessTokenIDManager::GetInstance().RegisterTokenId(tokenId, TOKEN_NATIVE); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x add failed.", tokenId); + continue; + } + std::shared_ptr native = std::make_shared(); + if (native == nullptr) { + AccessTokenIDManager::GetInstance().ReleaseTokenId(tokenId); + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x alloc failed.", tokenId); + continue; + } + + ret = native->RestoreNativeTokenInfo(tokenId, nativeTokenValue); + if (ret != RET_SUCCESS) { + AccessTokenIDManager::GetInstance().ReleaseTokenId(tokenId); + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x restore failed.", tokenId); + continue; + } + + ret = AddNativeTokenInfo(native); + if (ret != RET_SUCCESS) { + AccessTokenIDManager::GetInstance().ReleaseTokenId(tokenId); + ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId 0x%{public}x add failed.", tokenId); + continue; + } + ACCESSTOKEN_LOG_INFO(LABEL, + "restore native token 0x%{public}x process name %{public}s ok!", + tokenId, native->GetProcessName().c_str()); + } +} + +std::string AccessTokenInfoManager::GetHapUniqueStr(const int& userID, + const std::string& bundleName, const int& instIndex) const +{ + return bundleName + "&" + std::to_string(userID) + "&" + std::to_string(instIndex); +} + +std::string AccessTokenInfoManager::GetHapUniqueStr(const std::shared_ptr& info) const +{ + if (info == nullptr) { + return std::string(""); + } + return GetHapUniqueStr(info->GetUserID(), info->GetBundleName(), info->GetInstIndex()); +} + +int AccessTokenInfoManager::AddHapTokenInfo(const std::shared_ptr& info) +{ + if (info == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "token info is null."); + return RET_FAILED; + } + AccessTokenID id = info->GetTokenID(); + + { + Utils::UniqueWriteGuard infoGuard(this->hapTokenInfoLock_); + if (hapTokenInfoMap_.count(id) > 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "token %{public}x info has exist.", id); + return RET_FAILED; + } + + if (!info->IsRemote()) { + std::string HapUniqueKey = GetHapUniqueStr(info); + if (hapTokenIdMap_.count(HapUniqueKey) > 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "token %{public}x Unique info has exist.", id); + return RET_FAILED; + } + hapTokenIdMap_[HapUniqueKey] = id; + } + hapTokenInfoMap_[id] = info; + } + if (!info->IsRemote()) { + PermissionManager::GetInstance().AddDefPermissions(info, false); + } + return RET_SUCCESS; +} + +int AccessTokenInfoManager::AddNativeTokenInfo(const std::shared_ptr& info) +{ + if (info == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "token info is null."); + return RET_FAILED; + } + + AccessTokenID id = info->GetTokenID(); + std::string processName = info->GetProcessName(); + Utils::UniqueWriteGuard infoGuard(this->nativeTokenInfoLock_); + if (nativeTokenInfoMap_.count(id) > 0) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x has exist.", id); + return RET_FAILED; + } + if (!info->IsRemote()) { + if (nativeTokenIdMap_.count(processName) > 0) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x process name %{public}s has exist.", id, processName.c_str()); + return RET_FAILED; + } + nativeTokenIdMap_[processName] = id; + } + nativeTokenInfoMap_[id] = info; + + return RET_SUCCESS; +} + +std::shared_ptr AccessTokenInfoManager::GetHapTokenInfoInner(AccessTokenID id) +{ + Utils::UniqueReadGuard infoGuard(this->hapTokenInfoLock_); + if (hapTokenInfoMap_.count(id) == 0) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x is invalid.", id); + return nullptr; + } + return hapTokenInfoMap_[id]; +} + +int AccessTokenInfoManager::GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo& InfoParcel) +{ + std::shared_ptr infoPtr = GetHapTokenInfoInner(tokenID); + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x is invalid.", tokenID); + return RET_FAILED; + } + infoPtr->TranslateToHapTokenInfo(InfoParcel); + return RET_SUCCESS; +} + +std::shared_ptr AccessTokenInfoManager::GetHapPermissionPolicySet(AccessTokenID id) +{ + std::shared_ptr infoPtr = GetHapTokenInfoInner(id); + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x is invalid.", id); + return nullptr; + } + return infoPtr->GetHapInfoPermissionPolicySet(); +} + +std::shared_ptr AccessTokenInfoManager::GetNativeTokenInfoInner(AccessTokenID id) +{ + Utils::UniqueReadGuard infoGuard(this->nativeTokenInfoLock_); + if (nativeTokenInfoMap_.count(id) == 0) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x is invalid.", id); + return nullptr; + } + return nativeTokenInfoMap_[id]; +} + +int AccessTokenInfoManager::GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& InfoParcel) +{ + std::shared_ptr infoPtr = GetNativeTokenInfoInner(tokenID); + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x is invalid.", tokenID); + return RET_FAILED; + } + + infoPtr->TranslateToNativeTokenInfo(InfoParcel); + return RET_SUCCESS; +} + +int AccessTokenInfoManager::RemoveHapTokenInfo(AccessTokenID id) +{ + ATokenTypeEnum type = AccessTokenIDManager::GetInstance().GetTokenIdType(id); + if (type != TOKEN_HAP) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x is not hap.", id); + return RET_FAILED; + } + + // make sure that RemoveDefPermissions is called outside of the lock to avoid deadlocks. + PermissionManager::GetInstance().RemoveDefPermissions(id); + { + Utils::UniqueWriteGuard infoGuard(this->hapTokenInfoLock_); + if (hapTokenInfoMap_.count(id) == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "hap token %{public}x no exist.", id); + return RET_FAILED; + } + + const std::shared_ptr info = hapTokenInfoMap_[id]; + if (info == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "hap token %{public}x is null.", id); + return RET_FAILED; + } + if (info->IsRemote()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote hap token %{public}x can not delete.", id); + return RET_FAILED; + } + std::string HapUniqueKey = GetHapUniqueStr(info); + if (hapTokenIdMap_.count(HapUniqueKey) != 0) { + hapTokenIdMap_.erase(HapUniqueKey); + } + hapTokenInfoMap_.erase(id); + } + + AccessTokenIDManager::GetInstance().ReleaseTokenId(id); + ACCESSTOKEN_LOG_INFO(LABEL, "remove hap token 0x%{public}x ok!", id); + RefreshTokenInfoIfNeeded(); + TokenModifyNotifier::GetInstance().NotifyTokenDelete(id); + + return RET_SUCCESS; +} + +int AccessTokenInfoManager::RemoveNativeTokenInfo(AccessTokenID id) +{ + ATokenTypeEnum type = AccessTokenIDManager::GetInstance().GetTokenIdType(id); + if (type != TOKEN_NATIVE) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x is not hap.", id); + return RET_FAILED; + } + + bool isRemote = false; + { + Utils::UniqueWriteGuard infoGuard(this->nativeTokenInfoLock_); + if (nativeTokenInfoMap_.count(id) == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "native token %{public}x is null.", id); + return RET_FAILED; + } + + std::shared_ptr info = nativeTokenInfoMap_[id]; + if (info->IsRemote()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote native token %{public}x can not delete.", id); + return RET_FAILED; + } + std::string processName = nativeTokenInfoMap_[id]->GetProcessName(); + if (nativeTokenIdMap_.count(processName) != 0) { + nativeTokenIdMap_.erase(processName); + } + nativeTokenInfoMap_.erase(id); + } + AccessTokenIDManager::GetInstance().ReleaseTokenId(id); + ACCESSTOKEN_LOG_INFO(LABEL, "remove native token 0x%{public}x ok!", id); + if (!isRemote) { + RefreshTokenInfoIfNeeded(); + } + return RET_SUCCESS; +} + +int AccessTokenInfoManager::CreateHapTokenInfo( + const HapInfoParams& info, const HapPolicyParams& policy, AccessTokenIDEx& tokenIdEx) +{ + if (!DataValidator::IsUserIdValid(info.userID) || !DataValidator::IsBundleNameValid(info.bundleName) + || !DataValidator::IsAppIDDescValid(info.appIDDesc) || !DataValidator::IsDomainValid(policy.domain)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "hap token param failed"); + return RET_FAILED; + } + + AccessTokenID tokenId = AccessTokenIDManager::GetInstance().CreateAndRegisterTokenId(TOKEN_HAP); + if (tokenId == 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "token Id create failed"); + return RET_FAILED; + } + + std::shared_ptr tokenInfo = std::make_shared(tokenId, info, policy); + if (tokenInfo == nullptr) { + AccessTokenIDManager::GetInstance().ReleaseTokenId(tokenId); + ACCESSTOKEN_LOG_INFO(LABEL, "alloc token info failed"); + return RET_FAILED; + } + + int ret = AddHapTokenInfo(tokenInfo); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_WARN(LABEL, "%{public}s add token info failed", info.bundleName.c_str()); + AccessTokenIDManager::GetInstance().ReleaseTokenId(tokenId); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, + "create hap token 0x%{public}x bundle name %{public}s user %{public}d inst %{public}d ok!", + tokenId, tokenInfo->GetBundleName().c_str(), tokenInfo->GetUserID(), tokenInfo->GetInstIndex()); + + tokenIdEx.tokenIdExStruct.tokenID = tokenId; + tokenIdEx.tokenIdExStruct.tokenAttr = 0; + RefreshTokenInfoIfNeeded(); + return RET_SUCCESS; +} + +int AccessTokenInfoManager::CheckNativeDCap(AccessTokenID tokenID, const std::string& dcap) +{ + std::shared_ptr infoPtr = GetNativeTokenInfoInner(tokenID); + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x is invalid.", tokenID); + return RET_FAILED; + } + + std::vector dcaps = infoPtr->GetDcap(); + for (auto iter = dcaps.begin(); iter != dcaps.end(); iter++) { + if (*iter == dcap) { + return RET_SUCCESS; + } + } + return RET_FAILED; +} + +AccessTokenID AccessTokenInfoManager::GetHapTokenID(int userID, const std::string& bundleName, int instIndex) +{ + Utils::UniqueReadGuard infoGuard(this->hapTokenInfoLock_); + std::string HapUniqueKey = GetHapUniqueStr(userID, bundleName, instIndex); + if (hapTokenIdMap_.count(HapUniqueKey) > 0) { + return hapTokenIdMap_[HapUniqueKey]; + } + return 0; +} + +bool AccessTokenInfoManager::TryUpdateExistNativeToken(const std::shared_ptr& infoPtr) +{ + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "info is null"); + return false; + } + + Utils::UniqueWriteGuard infoGuard(this->nativeTokenInfoLock_); + AccessTokenID id = infoPtr->GetTokenID(); + std::string processName = infoPtr->GetProcessName(); + bool idExist = (nativeTokenInfoMap_.count(id) > 0); + bool processExist = (nativeTokenIdMap_.count(processName) > 0); + // id is exist, but it is not this process, so neither update nor add. + if (idExist && !processExist) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token Id is exist, but process name is not exist, can not update."); + return true; + } + + // this process is exist, but id is not same, perhaps libat lose his data, we need delete old, add new later. + if (!idExist && processExist) { + AccessTokenID idRemove = nativeTokenIdMap_[processName]; + nativeTokenIdMap_.erase(processName); + if (nativeTokenInfoMap_.count(idRemove) > 0) { + nativeTokenInfoMap_.erase(idRemove); + } + AccessTokenIDManager::GetInstance().ReleaseTokenId(idRemove); + return false; + } + + if (!idExist && !processExist) { + return false; + } + + nativeTokenInfoMap_[id] = infoPtr; + return true; +} + +void AccessTokenInfoManager::ProcessNativeTokenInfos( + const std::vector>& tokenInfos) +{ + for (auto& infoPtr: tokenInfos) { + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "token info from libat is null"); + continue; + } + bool isUpdated = TryUpdateExistNativeToken(infoPtr); + if (!isUpdated) { + ACCESSTOKEN_LOG_INFO(LABEL, + "token 0x%{public}x process name %{public}s is new, add to manager!", + infoPtr->GetTokenID(), infoPtr->GetProcessName().c_str()); + AccessTokenID id = infoPtr->GetTokenID(); + int ret = AccessTokenIDManager::GetInstance().RegisterTokenId(id, TOKEN_NATIVE); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "token Id register fail"); + continue; + } + ret = AddNativeTokenInfo(infoPtr); + if (ret != RET_SUCCESS) { + AccessTokenIDManager::GetInstance().ReleaseTokenId(id); + ACCESSTOKEN_LOG_ERROR(LABEL, + "token 0x%{public}x process name %{public}s add to manager failed!", + infoPtr->GetTokenID(), infoPtr->GetProcessName().c_str()); + } + } + } + RefreshTokenInfoIfNeeded(); +} + +int AccessTokenInfoManager::UpdateHapToken(AccessTokenID tokenID, + const std::string& appIDDesc, const HapPolicyParams& policy) +{ + if (!DataValidator::IsAppIDDescValid(appIDDesc)) { + ACCESSTOKEN_LOG_INFO(LABEL, "token 0x%{public}x parm format error!", tokenID); + return RET_FAILED; + } + std::shared_ptr infoPtr = GetHapTokenInfoInner(tokenID); + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_INFO(LABEL, "token 0x%{public}x is null, can not update!", tokenID); + return RET_FAILED; + } + + if (infoPtr->IsRemote()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote hap token 0x%{public}x can not update!", tokenID); + return RET_FAILED; + } + + { + Utils::UniqueWriteGuard infoGuard(this->hapTokenInfoLock_); + infoPtr->Update(appIDDesc, policy); + ACCESSTOKEN_LOG_INFO(LABEL, + "token 0x%{public}x bundle name %{public}s user %{public}d inst %{public}d update ok!", + tokenID, infoPtr->GetBundleName().c_str(), infoPtr->GetUserID(), infoPtr->GetInstIndex()); + } + + PermissionManager::GetInstance().AddDefPermissions(infoPtr, true); + TokenModifyNotifier::GetInstance().NotifyTokenModify(tokenID); + RefreshTokenInfoIfNeeded(); + return RET_SUCCESS; +} + +int AccessTokenInfoManager::GetHapTokenSync(AccessTokenID tokenID, HapTokenInfoForSync& hapSync) +{ + std::shared_ptr infoPtr = GetHapTokenInfoInner(tokenID); + if (infoPtr == nullptr || infoPtr->IsRemote()) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x is invalid.", tokenID); + return RET_FAILED; + } + hapSync.baseInfo = infoPtr->GetHapInfoBasic(); + std::shared_ptr permSetPtr = infoPtr->GetHapInfoPermissionPolicySet(); + if (permSetPtr == nullptr) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x permSet is invalid.", tokenID); + return RET_FAILED; + } + permSetPtr->GetPermissionStateList(hapSync.permStateList); + return RET_SUCCESS; +} + +int AccessTokenInfoManager::GetHapTokenInfoFromRemote(AccessTokenID tokenID, + HapTokenInfoForSync& hapSync) +{ + int ret = GetHapTokenSync(tokenID, hapSync); + TokenModifyNotifier::GetInstance().AddHapTokenObservation(tokenID); + return ret; +} + +void AccessTokenInfoManager::GetAllNativeTokenInfo(std::vector& nativeTokenInfosRes) +{ + Utils::UniqueReadGuard infoGuard(this->nativeTokenInfoLock_); + for (auto nativeTokenInner : nativeTokenInfoMap_) { + std::shared_ptr nativeTokenInnerPtr = nativeTokenInner.second; + if (nativeTokenInnerPtr == nullptr || nativeTokenInnerPtr->IsRemote()) { + continue; + } + NativeTokenInfo token; + nativeTokenInnerPtr->TranslateToNativeTokenInfo(token); + nativeTokenInfosRes.emplace_back(token); + } + return; +} + +int AccessTokenInfoManager::UpdateRemoteHapTokenInfo(AccessTokenID mapID, HapTokenInfoForSync& hapSync) +{ + std::shared_ptr infoPtr = GetHapTokenInfoInner(mapID); + if (infoPtr == nullptr) { + ACCESSTOKEN_LOG_INFO(LABEL, "token 0x%{public}x is null, can not update!", mapID); + return RET_FAILED; + } + + std::vector permList = {}; + std::shared_ptr newPermPolicySet = + PermissionPolicySet::BuildPermissionPolicySet(mapID, permList, hapSync.permStateList); + + { + Utils::UniqueWriteGuard infoGuard(this->hapTokenInfoLock_); + infoPtr->SetPermissionPolicySet(newPermPolicySet); + } + return RET_SUCCESS; +} + +int AccessTokenInfoManager::CreateRemoteHapTokenInfo(AccessTokenID mapID, HapTokenInfoForSync& hapSync) +{ + // update remote token mapping id + hapSync.baseInfo.tokenID = mapID; + std::shared_ptr hap = std::make_shared(mapID, + hapSync.baseInfo, hapSync.permStateList); + if (hap == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "alloc local token failed."); + return RET_FAILED; + } + hap->SetRemote(true); + + int ret = AddHapTokenInfo(hap); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "add local token failed."); + return RET_FAILED; + } + + return RET_SUCCESS; +} + +int AccessTokenInfoManager::SetRemoteHapTokenInfo(const std::string& deviceID, HapTokenInfoForSync& hapSync) +{ + if (!DataValidator::IsDeviceIdValid(deviceID) + || !DataValidator::IsUserIdValid(hapSync.baseInfo.userID) + || !DataValidator::IsBundleNameValid(hapSync.baseInfo.bundleName) + || !DataValidator::IsAplNumValid(hapSync.baseInfo.apl) + || !DataValidator::IsTokenIDValid(hapSync.baseInfo.tokenID) + || !DataValidator::IsAppIDDescValid(hapSync.baseInfo.appID) + || !DataValidator::IsDeviceIdValid(hapSync.baseInfo.deviceID) + || hapSync.baseInfo.ver != DEFAULT_TOKEN_VERSION + || AccessTokenIDManager::GetInstance().GetTokenIdTypeEnum(hapSync.baseInfo.tokenID) != TOKEN_HAP) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s parms invalid", deviceID.c_str()); + return RET_FAILED; + } + + AccessTokenID remoteID = hapSync.baseInfo.tokenID; + AccessTokenID mapID = AccessTokenRemoteTokenManager::GetInstance().GetDeviceMappingTokenID(deviceID, remoteID); + if (mapID != 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "device %{public}s token %{public}x update exist remote hap token %{public}x.", + deviceID.c_str(), remoteID, mapID); + return UpdateRemoteHapTokenInfo(mapID, hapSync); + } + + mapID = AccessTokenRemoteTokenManager::GetInstance().MapRemoteDeviceTokenToLocal(deviceID, remoteID); + if (mapID == 0) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "device %{public}s token %{public}x map failed.", deviceID.c_str(), remoteID); + return RET_FAILED; + } + + if (CreateRemoteHapTokenInfo(mapID, hapSync) == RET_FAILED) { + AccessTokenRemoteTokenManager::GetInstance().RemoveDeviceMappingTokenID(deviceID, mapID); + ACCESSTOKEN_LOG_INFO(LABEL, "device %{public}s token %{public}x map to local token %{public}x failed.", + deviceID.c_str(), remoteID, mapID); + return RET_FAILED; + } + ACCESSTOKEN_LOG_INFO(LABEL, "device %{public}s token %{public}x map to local token %{public}x success.", + deviceID.c_str(), remoteID, mapID); + return RET_SUCCESS; +} + +int AccessTokenInfoManager::SetRemoteNativeTokenInfo(const std::string& deviceID, + std::vector& nativeTokenInfoList) +{ + if (!DataValidator::IsDeviceIdValid(deviceID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s parms invalid", deviceID.c_str()); + return RET_FAILED; + } + + for (NativeTokenInfo& nativeToken : nativeTokenInfoList) { + if (!DataValidator::IsAplNumValid(nativeToken.apl) + || nativeToken.ver != DEFAULT_TOKEN_VERSION + || !DataValidator::IsProcessNameValid(nativeToken.processName)) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "device %{public}s token %{public}x is invalid.", deviceID.c_str(), nativeToken.tokenID); + continue; + } + + AccessTokenID remoteID = nativeToken.tokenID; + AccessTokenID mapID = AccessTokenRemoteTokenManager::GetInstance().GetDeviceMappingTokenID(deviceID, remoteID); + if (mapID == 0) { + mapID = AccessTokenRemoteTokenManager::GetInstance().MapRemoteDeviceTokenToLocal(deviceID, remoteID); + } + if (mapID == 0) { + AccessTokenRemoteTokenManager::GetInstance().RemoveDeviceMappingTokenID(deviceID, mapID); + ACCESSTOKEN_LOG_ERROR( + LABEL, "device %{public}s token %{public}x map failed.", + deviceID.c_str(), remoteID); + continue; + } + nativeToken.tokenID = mapID; + ACCESSTOKEN_LOG_INFO(LABEL, "device %{public}s token %{public}x map to local token %{public}x.", + deviceID.c_str(), remoteID, mapID); + + std::shared_ptr nativePtr = std::make_shared(nativeToken); + if (nativePtr == nullptr) { + AccessTokenRemoteTokenManager::GetInstance().RemoveDeviceMappingTokenID(deviceID, mapID); + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s tokenId 0x%{public}x alloc local token failed.", + deviceID.c_str(), remoteID); + continue; + } + nativePtr->SetRemote(true); + int ret = AddNativeTokenInfo(nativePtr); + if (ret != RET_SUCCESS) { + AccessTokenRemoteTokenManager::GetInstance().RemoveDeviceMappingTokenID(deviceID, mapID); + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s tokenId 0x%{public}x add local token failed.", + deviceID.c_str(), remoteID); + continue; + } + ACCESSTOKEN_LOG_INFO(LABEL, "device %{public}s token %{public}x map token %{public}x add success.", + deviceID.c_str(), remoteID, mapID); + } + + return RET_SUCCESS; +} + +int AccessTokenInfoManager::DeleteRemoteToken(const std::string& deviceID, AccessTokenID tokenID) +{ + if (!DataValidator::IsDeviceIdValid(deviceID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s parms invalid", deviceID.c_str()); + return RET_FAILED; + } + AccessTokenID mapID = AccessTokenRemoteTokenManager::GetInstance().GetDeviceMappingTokenID(deviceID, tokenID); + if (mapID == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s tokenId 0x%{public}x is not mapped", + deviceID.c_str(), tokenID); + return RET_FAILED; + } + + ATokenTypeEnum type = AccessTokenIDManager::GetInstance().GetTokenIdTypeEnum(mapID); + if (type == TOKEN_HAP) { + Utils::UniqueWriteGuard infoGuard(this->hapTokenInfoLock_); + if (hapTokenInfoMap_.count(mapID) == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "hap token %{public}x no exist.", mapID); + return RET_FAILED; + } + hapTokenInfoMap_.erase(mapID); + } else if (type == TOKEN_NATIVE) { + Utils::UniqueWriteGuard infoGuard(this->nativeTokenInfoLock_); + if (nativeTokenInfoMap_.count(mapID) == 0) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "native token %{public}x is null.", mapID); + return RET_FAILED; + } + nativeTokenInfoMap_.erase(mapID); + } else { + ACCESSTOKEN_LOG_ERROR(LABEL, "mapping tokenId 0x%{public}x type is unknown", mapID); + } + + return AccessTokenRemoteTokenManager::GetInstance().RemoveDeviceMappingTokenID(deviceID, tokenID); +} + +int AccessTokenInfoManager::DeleteRemoteDeviceTokens(const std::string& deviceID) +{ + if (!DataValidator::IsDeviceIdValid(deviceID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s parms invalid", deviceID.c_str()); + return RET_FAILED; + } + std::vector remoteTokens; + int ret = AccessTokenRemoteTokenManager::GetInstance().GetDeviceAllRemoteTokenID(deviceID, remoteTokens); + if (ret == RET_FAILED) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s have no remote token", deviceID.c_str()); + return RET_FAILED; + } + for (AccessTokenID remoteID : remoteTokens) { + DeleteRemoteToken(deviceID, remoteID); + } + return RET_SUCCESS; +} + +AccessTokenID AccessTokenInfoManager::AllocLocalTokenID(const std::string& remoteDeviceID, + AccessTokenID remoteTokenID) +{ + if (!DataValidator::IsDeviceIdValid(remoteDeviceID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s parms invalid", remoteDeviceID.c_str()); + return 0; + } + AccessTokenID mapID = AccessTokenRemoteTokenManager::GetInstance().GetDeviceMappingTokenID(remoteDeviceID, + remoteTokenID); + if (mapID != 0) { + return mapID; + } + int ret = TokenSyncKit::GetRemoteHapTokenInfo(remoteDeviceID, remoteTokenID); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s token %{public}x sync failed", + remoteDeviceID.c_str(), remoteTokenID); + return 0; + } + + return AccessTokenRemoteTokenManager::GetInstance().GetDeviceMappingTokenID(remoteDeviceID, remoteTokenID); +} + +AccessTokenInfoManager& AccessTokenInfoManager::GetInstance() +{ + static AccessTokenInfoManager instance; + return instance; +} + +void AccessTokenInfoManager::StoreAllTokenInfo() +{ + std::vector hapInfoValues; + std::vector permDefValues; + std::vector permStateValues; + std::vector nativeTokenValues; + { + Utils::UniqueReadGuard infoGuard(this->hapTokenInfoLock_); + for (auto iter = hapTokenInfoMap_.begin(); iter != hapTokenInfoMap_.end(); iter++) { + if (iter->second != nullptr) { + iter->second->StoreHapInfo(hapInfoValues, permDefValues, permStateValues); + } + } + } + + { + Utils::UniqueReadGuard infoGuard(this->nativeTokenInfoLock_); + for (auto iter = nativeTokenInfoMap_.begin(); iter != nativeTokenInfoMap_.end(); iter++) { + if (iter->second != nullptr) { + iter->second->StoreNativeInfo(nativeTokenValues); + } + } + } + + DataStorage::GetRealDataStorage().RefreshAll(DataStorage::ACCESSTOKEN_HAP_INFO, hapInfoValues); + DataStorage::GetRealDataStorage().RefreshAll(DataStorage::ACCESSTOKEN_NATIVE_INFO, nativeTokenValues); + DataStorage::GetRealDataStorage().RefreshAll(DataStorage::ACCESSTOKEN_PERMISSION_DEF, permDefValues); + DataStorage::GetRealDataStorage().RefreshAll(DataStorage::ACCESSTOKEN_PERMISSION_STATE, permStateValues); +} + +void AccessTokenInfoManager::RefreshTokenInfoIfNeeded() +{ + if (tokenDataWorker_.GetCurTaskNum() > 1) { + ACCESSTOKEN_LOG_INFO(LABEL, "has refresh task!"); + return; + } + + tokenDataWorker_.AddTask([]() { + AccessTokenInfoManager::GetInstance().StoreAllTokenInfo(); + + // Sleep for one second to avoid frequent refresh of the database. + std::this_thread::sleep_for(std::chrono::seconds(1)); + }); +} + +void AccessTokenInfoManager::Dump(std::string& dumpInfo) +{ + Utils::UniqueReadGuard hapInfoGuard(this->hapTokenInfoLock_); + for (auto iter = hapTokenInfoMap_.begin(); iter != hapTokenInfoMap_.end(); iter++) { + if (iter->second != nullptr) { + dumpInfo.append("\n"); + iter->second->ToString(dumpInfo); + dumpInfo.append("\n"); + } + } + + Utils::UniqueReadGuard nativeInfoGuard(this->nativeTokenInfoLock_); + for (auto iter = nativeTokenInfoMap_.begin(); iter != nativeTokenInfoMap_.end(); iter++) { + if (iter->second != nullptr) { + dumpInfo.append("\n"); + iter->second->ToString(dumpInfo); + dumpInfo.append("\n"); + } + } +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/token/accesstoken_remote_token_manager.cpp b/services/accesstokenmanager/main/cpp/src/token/accesstoken_remote_token_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17cb414d01beee1a148d2daa4db2fa344bebaabb --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/token/accesstoken_remote_token_manager.cpp @@ -0,0 +1,154 @@ +/* + * 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 "accesstoken_remote_token_manager.h" + +#include "accesstoken_id_manager.h" +#include "accesstoken_log.h" +#include "data_validator.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, + SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenRemoteTokenManager"}; +} +AccessTokenRemoteTokenManager::AccessTokenRemoteTokenManager() +{} + +AccessTokenRemoteTokenManager::~AccessTokenRemoteTokenManager() +{ +} + +AccessTokenRemoteTokenManager& AccessTokenRemoteTokenManager::GetInstance() +{ + static AccessTokenRemoteTokenManager instance; + return instance; +} + +AccessTokenID AccessTokenRemoteTokenManager::MapRemoteDeviceTokenToLocal(const std::string& deviceID, + AccessTokenID remoteID) +{ + if (!DataValidator::IsDeviceIdValid(deviceID) || !DataValidator::IsTokenIDValid(remoteID)) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "device %{public}s or token %{public}x is invalid.", deviceID.c_str(), remoteID); + return 0; + } + ATokenTypeEnum tokeType = AccessTokenIDManager::GetInstance().GetTokenIdTypeEnum(remoteID); + if (tokeType != TOKEN_HAP && tokeType != TOKEN_NATIVE) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "token %{public}x type is invalid.", remoteID); + return 0; + } + + AccessTokenID mapID = 0; + Utils::UniqueWriteGuard infoGuard(this->remoteDeviceLock_); + std::map* mapPtr = nullptr; + if (remoteDeviceMap_.count(deviceID) > 0) { + AccessTokenRemoteDevice& device = remoteDeviceMap_[deviceID]; + if (device.MappingTokenIDPairMap_.count(remoteID) > 0) { + mapID = device.MappingTokenIDPairMap_[remoteID]; + ACCESSTOKEN_LOG_ERROR( + LABEL, "device %{public}s token %{public}x has already mapped, maptokenID is %{public}x.", + deviceID.c_str(), remoteID, mapID); + return mapID; + } + mapPtr = &device.MappingTokenIDPairMap_; + } else { + AccessTokenRemoteDevice device; + remoteDeviceMap_[deviceID] = device; + mapPtr = &remoteDeviceMap_[deviceID].MappingTokenIDPairMap_; + } + + mapID = AccessTokenIDManager::GetInstance().CreateAndRegisterTokenId(tokeType); + if (mapID == 0) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "device %{public}s token %{public}x map local Token failed.", + deviceID.c_str(), remoteID); + return 0; + } + mapPtr->insert(std::pair(remoteID, mapID)); + return mapID; +} + +int AccessTokenRemoteTokenManager::GetDeviceAllRemoteTokenID(const std::string& deviceID, + std::vector& remoteIDs) +{ + if (!DataValidator::IsDeviceIdValid(deviceID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s is valid.", deviceID.c_str()); + return RET_FAILED; + } + Utils::UniqueReadGuard infoGuard(this->remoteDeviceLock_); + if (remoteDeviceMap_.count(deviceID) < 1) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s has not mapping.", deviceID.c_str()); + return RET_FAILED; + } + + for (auto mapEntry : remoteDeviceMap_[deviceID].MappingTokenIDPairMap_) { + remoteIDs.emplace_back(mapEntry.first); + } + return RET_SUCCESS; +} + +AccessTokenID AccessTokenRemoteTokenManager::GetDeviceMappingTokenID(const std::string& deviceID, + AccessTokenID remoteID) +{ + if (!DataValidator::IsDeviceIdValid(deviceID) || !DataValidator::IsTokenIDValid(remoteID)) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "device %{public}s or token %{public}x is invalid.", deviceID.c_str(), remoteID); + return 0; + } + + Utils::UniqueReadGuard infoGuard(this->remoteDeviceLock_); + if (remoteDeviceMap_.count(deviceID) < 1 || + remoteDeviceMap_[deviceID].MappingTokenIDPairMap_.count(remoteID) < 1) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s has not mapping.", deviceID.c_str()); + return 0; + } + + return remoteDeviceMap_[deviceID].MappingTokenIDPairMap_[remoteID]; +} + +int AccessTokenRemoteTokenManager::RemoveDeviceMappingTokenID(const std::string& deviceID, + AccessTokenID remoteID) +{ + if (!DataValidator::IsDeviceIdValid(deviceID) || !DataValidator::IsTokenIDValid(remoteID)) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "device %{public}s or token %{public}x is invalid.", deviceID.c_str(), remoteID); + return RET_FAILED; + } + + Utils::UniqueWriteGuard infoGuard(this->remoteDeviceLock_); + if (remoteDeviceMap_.count(deviceID) < 1 || + remoteDeviceMap_[deviceID].MappingTokenIDPairMap_.count(remoteID) < 1) { + ACCESSTOKEN_LOG_ERROR(LABEL, "device %{public}s has not mapping.", deviceID.c_str()); + return RET_FAILED; + } + + AccessTokenID mapID = remoteDeviceMap_[deviceID].MappingTokenIDPairMap_[remoteID]; + AccessTokenIDManager::GetInstance().ReleaseTokenId(mapID); + + remoteDeviceMap_[deviceID].MappingTokenIDPairMap_.erase(remoteID); + + if (remoteDeviceMap_[deviceID].MappingTokenIDPairMap_.size() == 0) { + remoteDeviceMap_.erase(deviceID); + } + return RET_SUCCESS; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + diff --git a/services/accesstokenmanager/main/cpp/src/token/hap_token_info_inner.cpp b/services/accesstokenmanager/main/cpp/src/token/hap_token_info_inner.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bb2ab3d95f25d16cab186cf30db2fa166798a357 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/token/hap_token_info_inner.cpp @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2021 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 "hap_token_info_inner.h" + +#include "accesstoken_id_manager.h" +#include "accesstoken_log.h" +#include "data_translator.h" +#include "data_validator.h" +#include "field_const.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "HapTokenInfoInner"}; +} + +HapTokenInfoInner::HapTokenInfoInner() : isRemote_(false) +{ + tokenInfoBasic_.ver = DEFAULT_TOKEN_VERSION; + tokenInfoBasic_.tokenID = 0; + tokenInfoBasic_.tokenAttr = 0; + tokenInfoBasic_.userID = 0; + tokenInfoBasic_.instIndex = 0; + tokenInfoBasic_.apl = APL_NORMAL; +} + +HapTokenInfoInner::HapTokenInfoInner(AccessTokenID id, + const HapInfoParams &info, const HapPolicyParams &policy) : isRemote_(false) +{ + tokenInfoBasic_.tokenID = id; + tokenInfoBasic_.userID = info.userID; + tokenInfoBasic_.ver = DEFAULT_TOKEN_VERSION; + tokenInfoBasic_.tokenAttr = 0; + tokenInfoBasic_.bundleName = info.bundleName; + tokenInfoBasic_.instIndex = info.instIndex; + tokenInfoBasic_.appID = info.appIDDesc; + tokenInfoBasic_.deviceID = "0"; + tokenInfoBasic_.apl = policy.apl; + permPolicySet_ = PermissionPolicySet::BuildPermissionPolicySet(id, policy.permList, policy.permStateList); +} + +HapTokenInfoInner::HapTokenInfoInner(AccessTokenID id, + const HapTokenInfo &info, const std::vector& permStateList) : isRemote_(false) +{ + tokenInfoBasic_ = info; + const std::vector permDefList; + permPolicySet_ = PermissionPolicySet::BuildPermissionPolicySet(id, permDefList, permStateList); +} + +HapTokenInfoInner::~HapTokenInfoInner() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, + "tokenID: 0x%{public}x destruction", tokenInfoBasic_.tokenID); +} + +void HapTokenInfoInner::Update(const std::string& appIDDesc, const HapPolicyParams& policy) +{ + tokenInfoBasic_.appID = appIDDesc; + tokenInfoBasic_.apl = policy.apl; + if (permPolicySet_ == nullptr) { + permPolicySet_ = PermissionPolicySet::BuildPermissionPolicySet(tokenInfoBasic_.tokenID, + policy.permList, policy.permStateList); + return; + } + + permPolicySet_->Update(policy.permList, policy.permStateList); + return; +} + +void HapTokenInfoInner::TranslateToHapTokenInfo(HapTokenInfo& InfoParcel) const +{ + InfoParcel = tokenInfoBasic_; +} + +void HapTokenInfoInner::TranslationIntoGenericValues(GenericValues& outGenericValues) const +{ + outGenericValues.Put(FIELD_TOKEN_ID, tokenInfoBasic_.tokenID); + outGenericValues.Put(FIELD_USER_ID, tokenInfoBasic_.userID); + outGenericValues.Put(FIELD_BUNDLE_NAME, tokenInfoBasic_.bundleName); + outGenericValues.Put(FIELD_INST_INDEX, tokenInfoBasic_.instIndex); + outGenericValues.Put(FIELD_APP_ID, tokenInfoBasic_.appID); + outGenericValues.Put(FIELD_DEVICE_ID, tokenInfoBasic_.deviceID); + outGenericValues.Put(FIELD_APL, tokenInfoBasic_.apl); + outGenericValues.Put(FIELD_TOKEN_VERSION, tokenInfoBasic_.ver); + outGenericValues.Put(FIELD_TOKEN_ATTR, tokenInfoBasic_.tokenAttr); +} + +int HapTokenInfoInner::RestoreHapTokenBasicInfo(const GenericValues& inGenericValues) +{ + tokenInfoBasic_.userID = inGenericValues.GetInt(FIELD_USER_ID); + tokenInfoBasic_.bundleName = inGenericValues.GetString(FIELD_BUNDLE_NAME); + if (!DataValidator::IsBundleNameValid(tokenInfoBasic_.bundleName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x bundle name is error", tokenInfoBasic_.tokenID); + return RET_FAILED; + } + + tokenInfoBasic_.instIndex = inGenericValues.GetInt(FIELD_INST_INDEX); + tokenInfoBasic_.appID = inGenericValues.GetString(FIELD_APP_ID); + if (!DataValidator::IsAppIDDescValid(tokenInfoBasic_.appID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x appID is error", tokenInfoBasic_.tokenID); + return RET_FAILED; + } + + tokenInfoBasic_.deviceID = inGenericValues.GetString(FIELD_DEVICE_ID); + if (!DataValidator::IsDeviceIdValid(tokenInfoBasic_.deviceID)) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x devId is error", tokenInfoBasic_.tokenID); + return RET_FAILED; + } + int aplNum = inGenericValues.GetInt(FIELD_APL); + if (DataValidator::IsAplNumValid(aplNum)) { + tokenInfoBasic_.apl = (ATokenAplEnum)aplNum; + } else { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x apl is error, value %{public}d", + tokenInfoBasic_.tokenID, aplNum); + return RET_FAILED; + } + tokenInfoBasic_.ver = (char)inGenericValues.GetInt(FIELD_TOKEN_VERSION); + if (tokenInfoBasic_.ver != DEFAULT_TOKEN_VERSION) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x version is error, version %{public}d", + tokenInfoBasic_.tokenID, tokenInfoBasic_.ver); + return RET_FAILED; + } + tokenInfoBasic_.tokenAttr = (uint32_t)inGenericValues.GetInt(FIELD_TOKEN_ATTR); + return RET_SUCCESS; +} + +int HapTokenInfoInner::RestoreHapTokenInfo(AccessTokenID tokenId, + GenericValues& tokenValue, const std::vector& permDefRes, + const std::vector& permStateRes) +{ + tokenInfoBasic_.tokenID = tokenId; + int ret = RestoreHapTokenBasicInfo(tokenValue); + if (ret != RET_SUCCESS) { + return RET_FAILED; + } + permPolicySet_ = PermissionPolicySet::RestorePermissionPolicy(tokenId, + permDefRes, permStateRes); + return RET_SUCCESS; +} + +void HapTokenInfoInner::StoreHapBasicInfo(std::vector& valueList) const +{ + GenericValues genericValues; + TranslationIntoGenericValues(genericValues); + valueList.emplace_back(genericValues); +} + +void HapTokenInfoInner::StoreHapInfo(std::vector& hapInfoValues, + std::vector& permDefValues, + std::vector& permStateValues) const +{ + if (isRemote_) { + ACCESSTOKEN_LOG_INFO(LABEL, + "token %{public}x is remote hap token, will not store", tokenInfoBasic_.tokenID); + return; + } + StoreHapBasicInfo(hapInfoValues); + if (permPolicySet_ != nullptr) { + permPolicySet_->StorePermissionPolicySet(permDefValues, permStateValues); + } +} + +std::shared_ptr HapTokenInfoInner::GetHapInfoPermissionPolicySet() const +{ + return permPolicySet_; +} + +int HapTokenInfoInner::GetUserID() const +{ + return tokenInfoBasic_.userID; +} + +std::string HapTokenInfoInner::GetBundleName() const +{ + return tokenInfoBasic_.bundleName; +} + +int HapTokenInfoInner::GetInstIndex() const +{ + return tokenInfoBasic_.instIndex; +} + +AccessTokenID HapTokenInfoInner::GetTokenID() const +{ + return tokenInfoBasic_.tokenID; +} + +HapTokenInfo HapTokenInfoInner::GetHapInfoBasic() const +{ + return tokenInfoBasic_; +} + +void HapTokenInfoInner::SetPermissionPolicySet(std::shared_ptr& policySet) +{ + permPolicySet_ = policySet; +} + +bool HapTokenInfoInner::IsRemote() const +{ + return isRemote_; +} + +void HapTokenInfoInner::SetRemote(bool isRemote) +{ + isRemote_ = isRemote; +} + +void HapTokenInfoInner::ToString(std::string& info) const +{ + info.append(R"({"tokenID": )" + std::to_string(tokenInfoBasic_.tokenID)); + info.append(R"(, "tokenAttr": )" + std::to_string(tokenInfoBasic_.tokenAttr)); + info.append(R"(, "ver": )" + std::to_string(tokenInfoBasic_.ver)); + info.append(R"(, "userId": )" + std::to_string(tokenInfoBasic_.userID)); + info.append(R"(, "bundleName": ")" + tokenInfoBasic_.bundleName + R"(")"); + info.append(R"(, "instIndex": )" + std::to_string(tokenInfoBasic_.instIndex)); + info.append(R"(, "appID": ")" + tokenInfoBasic_.appID + R"(")"); + info.append(R"(, "deviceID": ")" + tokenInfoBasic_.deviceID + R"(")"); + info.append(R"(, "apl": )" + std::to_string(tokenInfoBasic_.apl)); + info.append(R"(, "isRemote": )" + std::to_string(isRemote_)); + + if (permPolicySet_ != nullptr) { + permPolicySet_->ToString(info); + } + info.append("}"); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/token/native_token_info_inner.cpp b/services/accesstokenmanager/main/cpp/src/token/native_token_info_inner.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0e5f70d85920a81bf480958a3c4e0048f71eff60 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/token/native_token_info_inner.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2021 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 "native_token_info_inner.h" + +#include "data_translator.h" +#include "data_validator.h" +#include "field_const.h" +#include "nlohmann/json.hpp" + +#include "accesstoken_log.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "NativeTokenInfoInner"}; +} + +NativeTokenInfoInner::NativeTokenInfoInner() : isRemote_(false) +{ + tokenInfoBasic_.ver = DEFAULT_TOKEN_VERSION; + tokenInfoBasic_.tokenID = 0; + tokenInfoBasic_.tokenAttr = 0; + tokenInfoBasic_.apl = APL_NORMAL; +} + +NativeTokenInfoInner::NativeTokenInfoInner(NativeTokenInfo& native) +{ + tokenInfoBasic_ = native; +} + +NativeTokenInfoInner::~NativeTokenInfoInner() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, + "tokenID: 0x%{public}x destruction", tokenInfoBasic_.tokenID); +} + +int NativeTokenInfoInner::Init(AccessTokenID id, const std::string& processName, + int apl, const std::vector& dcap) +{ + tokenInfoBasic_.tokenID = id; + if (!DataValidator::IsProcessNameValid(processName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x process name is null", tokenInfoBasic_.tokenID); + return RET_FAILED; + } + tokenInfoBasic_.processName = processName; + if (!DataValidator::IsAplNumValid(apl)) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x init failed, apl %{public}d is invalid", + tokenInfoBasic_.tokenID, apl); + return RET_FAILED; + } + tokenInfoBasic_.apl = (ATokenAplEnum)apl; + tokenInfoBasic_.dcap = dcap; + return RET_SUCCESS; +} + +std::string NativeTokenInfoInner::DcapToString(const std::vector& dcap) const +{ + std::string dcapStr; + for (auto iter = dcap.begin(); iter != dcap.end(); iter++) { + dcapStr.append(*iter); + if (iter != (dcap.end() - 1)) { + dcapStr.append(","); + } + } + return dcapStr; +} + +int NativeTokenInfoInner::TranslationIntoGenericValues(GenericValues& outGenericValues) const +{ + outGenericValues.Put(FIELD_TOKEN_ID, tokenInfoBasic_.tokenID); + outGenericValues.Put(FIELD_PROCESS_NAME, tokenInfoBasic_.processName); + outGenericValues.Put(FIELD_APL, tokenInfoBasic_.apl); + outGenericValues.Put(FIELD_TOKEN_VERSION, tokenInfoBasic_.ver); + outGenericValues.Put(FIELD_DCAP, DcapToString(tokenInfoBasic_.dcap)); + outGenericValues.Put(FIELD_TOKEN_ATTR, tokenInfoBasic_.tokenAttr); + + return RET_SUCCESS; +} + +int NativeTokenInfoInner::RestoreNativeTokenInfo(AccessTokenID tokenId, const GenericValues& inGenericValues) +{ + tokenInfoBasic_.tokenID = tokenId; + tokenInfoBasic_.processName = inGenericValues.GetString(FIELD_PROCESS_NAME); + if (!DataValidator::IsProcessNameValid(tokenInfoBasic_.processName)) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x process name is null", tokenInfoBasic_.tokenID); + return RET_FAILED; + } + int aplNum = inGenericValues.GetInt(FIELD_APL); + if (!DataValidator::IsAplNumValid(aplNum)) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x apl is error, value %{public}d", + tokenInfoBasic_.tokenID, aplNum); + return RET_FAILED; + } + tokenInfoBasic_.apl = (ATokenAplEnum)aplNum; + tokenInfoBasic_.ver = (char)inGenericValues.GetInt(FIELD_TOKEN_VERSION); + if (tokenInfoBasic_.ver != DEFAULT_TOKEN_VERSION) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "tokenID: 0x%{public}x version is error, version %{public}d", + tokenInfoBasic_.tokenID, tokenInfoBasic_.ver); + return RET_FAILED; + } + + SetDcaps(inGenericValues.GetString(FIELD_DCAP)); + tokenInfoBasic_.tokenAttr = (uint32_t)inGenericValues.GetInt(FIELD_TOKEN_ATTR); + return RET_SUCCESS; +} + +void NativeTokenInfoInner::TranslateToNativeTokenInfo(NativeTokenInfo& InfoParcel) const +{ + InfoParcel.apl = tokenInfoBasic_.apl; + InfoParcel.ver = tokenInfoBasic_.ver; + InfoParcel.processName = tokenInfoBasic_.processName; + InfoParcel.dcap = tokenInfoBasic_.dcap; + InfoParcel.tokenID = tokenInfoBasic_.tokenID; + InfoParcel.tokenAttr = tokenInfoBasic_.tokenAttr; +} + +void NativeTokenInfoInner::StoreNativeInfo(std::vector& valueList) const +{ + if (isRemote_) { + return; + } + GenericValues genericValues; + TranslationIntoGenericValues(genericValues); + valueList.emplace_back(genericValues); +} + +AccessTokenID NativeTokenInfoInner::GetTokenID() const +{ + return tokenInfoBasic_.tokenID; +} + +std::vector NativeTokenInfoInner::GetDcap() const +{ + return tokenInfoBasic_.dcap; +} + +std::string NativeTokenInfoInner::GetProcessName() const +{ + return tokenInfoBasic_.processName; +} + +bool NativeTokenInfoInner::IsRemote() const +{ + return isRemote_; +} + +void NativeTokenInfoInner::SetRemote(bool isRemote) +{ + isRemote_ = isRemote; +} + +void NativeTokenInfoInner::SetDcaps(const std::string& dcapStr) +{ + std::string::size_type start = 0; + while (true) { + std::string::size_type offset = dcapStr.find(',', start); + if (offset == std::string::npos) { + tokenInfoBasic_.dcap.push_back(dcapStr.substr(start)); + break; + } + tokenInfoBasic_.dcap.push_back(dcapStr.substr(start, offset)); + start = offset + 1; + } +} + +void NativeTokenInfoInner::ToString(std::string& info) const +{ + info.append(R"({"tokenID": )" + std::to_string(tokenInfoBasic_.tokenID)); + info.append(R"(, "tokenAttr": )" + std::to_string(tokenInfoBasic_.tokenAttr)); + info.append(R"(, "ver": )" + std::to_string(tokenInfoBasic_.ver)); + info.append(R"(, "processName": ")" + tokenInfoBasic_.processName + R"(")"); + info.append(R"(, "apl": )" + std::to_string(tokenInfoBasic_.apl)); + info.append(R"(, "dcap": ")" + DcapToString(tokenInfoBasic_.dcap) + R"(")"); + info.append(R"(, "isRemote": )" + std::to_string(isRemote_)); + info.append("}"); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/token/native_token_receptor.cpp b/services/accesstokenmanager/main/cpp/src/token/native_token_receptor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6369f017d125f8b804171bd1302c99fb9c95ef1 --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/token/native_token_receptor.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include + +#include "accesstoken_id_manager.h" +#include "accesstoken_info_manager.h" +#include "accesstoken_log.h" +#include "data_validator.h" +#include "native_token_receptor.h" +#include "securec.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "NativeTokenReceptor"}; +} + +// nlohmann json need the function named from_json to parse NativeTokenInfo +void from_json(const nlohmann::json& j, std::shared_ptr& p) +{ + NativeTokenInfo native; + if (j.find(JSON_PROCESS_NAME) != j.end()) { + native.processName = j.at(JSON_PROCESS_NAME).get(); + if (!DataValidator::IsProcessNameValid(native.processName)) { + return; + } + } else { + return; + } + + if (j.find(JSON_APL) != j.end()) { + int aplNum = j.at(JSON_APL).get(); + if (DataValidator::IsAplNumValid(aplNum)) { + native.apl = (ATokenAplEnum)aplNum; + } else { + return; + } + } else { + return; + } + + if (j.find(JSON_VERSION) != j.end()) { + native.ver = (uint8_t)j.at(JSON_VERSION).get(); + if (native.ver != DEFAULT_TOKEN_VERSION) { + return; + } + } else { + return; + } + + if (j.find(JSON_TOKEN_ID) != j.end()) { + native.tokenID = j.at(JSON_TOKEN_ID).get(); + if (native.tokenID == 0 && + AccessTokenIDManager::GetTokenIdTypeEnum(native.tokenID) != TOKEN_NATIVE) { + return; + } + } else { + return; + } + + if (j.find(JSON_TOKEN_ATTR) != j.end()) { + native.tokenAttr = j.at(JSON_TOKEN_ATTR).get(); + } else { + return; + } + + if (j.find(JSON_DCAPS) != j.end()) { + native.dcap = j.at(JSON_DCAPS).get>(); + } else { + return; + } + p = std::make_shared(native); +} + +void NativeTokenReceptor::ParserNativeRawData(const std::string& nativeRawData, + std::vector>& tokenInfos) +{ + nlohmann::json jsonRes = nlohmann::json::parse(nativeRawData, nullptr, false); + for (auto it = jsonRes.begin(); it != jsonRes.end(); it++) { + auto token = it->get>(); + if (token != nullptr) { + tokenInfos.emplace_back(token); + } + } +} + +int NativeTokenReceptor::ReadCfgFile(std::string& nativeRawData) +{ + int32_t fd = open(NATIVE_TOKEN_CONFIG_FILE.c_str(), O_RDONLY); + if (fd < 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "open failed errno %{public}d.", errno); + return RET_FAILED; + } + struct stat statBuffer; + + if (fstat(fd, &statBuffer) != 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fstat failed."); + close(fd); + return RET_FAILED; + } + + if (statBuffer.st_size == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "config file size is invalid."); + close(fd); + return RET_FAILED; + } + if (statBuffer.st_size > MAX_NATIVE_CONFIG_FILE_SIZE) { + ACCESSTOKEN_LOG_ERROR(LABEL, "config file size is too large."); + close(fd); + return RET_FAILED; + } + nativeRawData.reserve(statBuffer.st_size); + + char buff[BUFFER_SIZE] = { 0 }; + ssize_t readLen = 0; + while ((readLen = read(fd, buff, BUFFER_SIZE)) > 0) { + nativeRawData.append(buff, readLen); + } + close(fd); + + if (readLen == 0) { + return RET_SUCCESS; + } + return RET_FAILED; +} + +int NativeTokenReceptor::Init() +{ + if (ready_) { + ACCESSTOKEN_LOG_ERROR(LABEL, "native token has been inited."); + return RET_SUCCESS; + } + + std::string nativeRawData; + int ret = ReadCfgFile(nativeRawData); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "readCfgFile failed."); + return RET_FAILED; + } + std::vector> tokenInfos; + ParserNativeRawData(nativeRawData, tokenInfos); + AccessTokenInfoManager::GetInstance().ProcessNativeTokenInfos(tokenInfos); + + ready_ = true; + ACCESSTOKEN_LOG_INFO(LABEL, "init ok."); + return RET_SUCCESS; +} + +NativeTokenReceptor& NativeTokenReceptor::GetInstance() +{ + static NativeTokenReceptor instance; + return instance; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/accesstokenmanager/main/cpp/src/token/token_modify_notifier.cpp b/services/accesstokenmanager/main/cpp/src/token/token_modify_notifier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49ba60e8faff80ed611d2f1f1401ed8977aeb79b --- /dev/null +++ b/services/accesstokenmanager/main/cpp/src/token/token_modify_notifier.cpp @@ -0,0 +1,119 @@ +/* + * 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 "token_modify_notifier.h" + +#include "accesstoken_id_manager.h" +#include "accesstoken_info_manager.h" +#include "accesstoken_log.h" +#include "hap_token_info.h" +#include "hap_token_info_inner.h" +#include "token_sync_kit.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenModifyNotifier"}; +} + +TokenModifyNotifier::TokenModifyNotifier() : hasInited_(false) {} + +TokenModifyNotifier::~TokenModifyNotifier() {} + +void TokenModifyNotifier::AddHapTokenObservation(AccessTokenID tokenID) +{ + if (AccessTokenIDManager::GetInstance().GetTokenIdType(tokenID) != TOKEN_HAP) { + ACCESSTOKEN_LOG_INFO(LABEL, "Observation token is not hap token"); + return; + } + Utils::UniqueWriteGuard infoGuard(this->Notifylock_); + if (observationSet_.count(tokenID) <= 0) { + observationSet_.insert(tokenID); + } +} + +void TokenModifyNotifier::NotifyTokenDelete(AccessTokenID tokenID) +{ + Utils::UniqueWriteGuard infoGuard(this->Notifylock_); + if (observationSet_.count(tokenID) <= 0) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "hap token is not observed"); + return; + } + observationSet_.erase(tokenID); + deleteTokenList_.emplace_back(tokenID); + NotifyTokenChangedIfNeed(); +} + +void TokenModifyNotifier::NotifyTokenModify(AccessTokenID tokenID) +{ + Utils::UniqueWriteGuard infoGuard(this->Notifylock_); + if (observationSet_.count(tokenID) <= 0) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "hap token is not observed"); + return; + } + modifiedTokenList_.emplace_back(tokenID); + NotifyTokenChangedIfNeed(); +} + +TokenModifyNotifier& TokenModifyNotifier::GetInstance() +{ + static TokenModifyNotifier instance; + + if (!instance.hasInited_) { + Utils::UniqueWriteGuard infoGuard(instance.initLock_); + if (!instance.hasInited_) { + instance.notifyTokenWorker_.Start(1); + instance.hasInited_ = true; + } + } + + return instance; +} + +void TokenModifyNotifier::NotifyTokenSyncTask() +{ + Utils::UniqueWriteGuard infoGuard(this->Notifylock_); + for (AccessTokenID deleteToken : deleteTokenList_) { + TokenSyncKit::DeleteRemoteHapTokenInfo(deleteToken); + } + + for (AccessTokenID modifyToken : modifiedTokenList_) { + HapTokenInfoForSync hapSync; + int ret = AccessTokenInfoManager::GetInstance().GetHapTokenSync(modifyToken, hapSync); + if (ret != RET_SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "the hap token 0x%{public}x need to sync is not found!", modifyToken); + continue; + } + TokenSyncKit::UpdateRemoteHapTokenInfo(hapSync); + } + deleteTokenList_.clear(); + modifiedTokenList_.clear(); +} +void TokenModifyNotifier::NotifyTokenChangedIfNeed() +{ + if (notifyTokenWorker_.GetCurTaskNum() > 1) { + ACCESSTOKEN_LOG_INFO(LABEL, " has notify task!"); + return; + } + + notifyTokenWorker_.AddTask([]() { + TokenModifyNotifier::GetInstance().NotifyTokenSyncTask(); + }); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + diff --git a/services/accesstoken/main/sa_profile/3503.xml b/services/accesstokenmanager/main/sa_profile/3503.xml old mode 100755 new mode 100644 similarity index 94% rename from services/accesstoken/main/sa_profile/3503.xml rename to services/accesstokenmanager/main/sa_profile/3503.xml index 622c5f8a5bcaad7bb69f6a0e585925d3ea2b7256..d20563c4603417e3bc8da37829532ecf5be110d3 --- a/services/accesstoken/main/sa_profile/3503.xml +++ b/services/accesstokenmanager/main/sa_profile/3503.xml @@ -13,7 +13,7 @@ limitations under the License. --> - foundation + accesstoken_service 3503 libaccesstoken_manager_service.z.so @@ -21,4 +21,4 @@ false 1 - \ No newline at end of file + diff --git a/services/accesstoken/main/sa_profile/BUILD.gn b/services/accesstokenmanager/main/sa_profile/BUILD.gn similarity index 100% rename from services/accesstoken/main/sa_profile/BUILD.gn rename to services/accesstokenmanager/main/sa_profile/BUILD.gn diff --git a/services/accesstokenmanager/test/BUILD.gn b/services/accesstokenmanager/test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..208ff66dde4913d96ed23f98b25b168c0d2905f4 --- /dev/null +++ b/services/accesstokenmanager/test/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (c) 2021 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. + +import("//build/test.gni") + +ohos_unittest("libaccesstoken_manager_service_standard_test") { + subsystem_name = "security" + part_name = "access_token" + module_out_path = part_name + "/" + part_name + + include_dirs = [ + "//utils/native/base/include", + "//third_party/googletest/include", + "//base/security/access_token/services/accesstokenmanager/main/cpp/include/service", + "//base/security/access_token/services/accesstokenmanager/main/cpp/include/token", + "//base/security/access_token/services/accesstokenmanager/main/cpp/include/permission", + "//base/security/access_token/services/accesstokenmanager/main/cpp/include/database", + "//base/security/access_token/frameworks/common/include", + "//base/security/access_token/frameworks/accesstoken/include", + "//base/security/access_token/interfaces/innerkits/accesstoken/main/cpp/include", + "//base/security/access_token/interfaces/innerkits/nativetoken/include", + "//third_party/json/include", + "//third_party/cJSON", + ] + + sources = [ + "unittest/cpp/src/accesstoken_info_manager_test.cpp", + "unittest/cpp/src/native_token_receptor_test.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + deps = [ + "//base/security/access_token/frameworks/accesstoken:accesstoken_communication_adapter_cxx", + "//base/security/access_token/frameworks/common:accesstoken_common_cxx", + "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", + "//base/security/access_token/services/accesstokenmanager/:accesstoken_manager_service", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] +} + +group("unittest") { + testonly = true + deps = [ ":libaccesstoken_manager_service_standard_test" ] +} diff --git a/services/accesstokenmanager/test/unittest/cpp/src/accesstoken_info_manager_test.cpp b/services/accesstokenmanager/test/unittest/cpp/src/accesstoken_info_manager_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d981b08d9fade47f44b341d5b427d44009afee1d --- /dev/null +++ b/services/accesstokenmanager/test/unittest/cpp/src/accesstoken_info_manager_test.cpp @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2021 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_info_manager_test.h" + +#include +#include +#include "accesstoken_info_manager.h" +#include "accesstoken_log.h" + +using namespace testing::ext; +using namespace OHOS::Security::AccessToken; + +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenInfoManagerTest" +}; + +static PermissionDef g_infoManagerTestPermDef1 = { + .permissionName = "open the door", + .bundleName = "accesstoken_test", + .grantMode = 1, + .label = "label", + .labelId = 1, + .description = "open the door", + .descriptionId = 1, + .availableLevel = APL_NORMAL, + .provisionEnable = false, + .distributedSceneEnable = false +}; + +static PermissionDef g_infoManagerTestPermDef2 = { + .permissionName = "break the door", + .bundleName = "accesstoken_test", + .grantMode = 1, + .label = "label", + .labelId = 1, + .description = "break the door", + .descriptionId = 1, + .availableLevel = APL_NORMAL, + .provisionEnable = false, + .distributedSceneEnable = false +}; + +static PermissionStateFull g_infoManagerTestState1 = { + .grantFlags = {1}, + .grantStatus = {1}, + .isGeneral = true, + .permissionName = "open the door", + .resDeviceID = {"local"} +}; + +static PermissionStateFull g_infoManagerTestState2 = { + .permissionName = "break the door", + .isGeneral = false, + .grantFlags = {1, 2}, + .grantStatus = {1, 3}, + .resDeviceID = {"device 1", "device 2"} +}; + +static HapInfoParams g_infoManagerTestInfoParms = { + .bundleName = "accesstoken_test", + .userID = 1, + .instIndex = 0, + .appIDDesc = "testtesttesttest" +}; + +static HapPolicyParams g_infoManagerTestPolicyPrams = { + .apl = APL_NORMAL, + .domain = "test.domain", + .permList = {g_infoManagerTestPermDef1, g_infoManagerTestPermDef2}, + .permStateList = {g_infoManagerTestState1, g_infoManagerTestState2} +}; +} + +void AccessTokenInfoManagerTest::SetUpTestCase() +{} + +void AccessTokenInfoManagerTest::TearDownTestCase() +{} + +void AccessTokenInfoManagerTest::SetUp() +{} + +void AccessTokenInfoManagerTest::TearDown() +{} + +HWTEST_F(AccessTokenInfoManagerTest, Init001, TestSize.Level1) +{ + AccessTokenInfoManager::GetInstance().Init(); + std::string dumpInfo; + AccessTokenInfoManager::GetInstance().Dump(dumpInfo); + GTEST_LOG_(INFO) << "dump all:" << dumpInfo.c_str(); + + // delete test token + AccessTokenID getTokenId = AccessTokenInfoManager::GetInstance().GetHapTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, g_infoManagerTestInfoParms.instIndex); + + if (getTokenId != 0) { + int ret = AccessTokenInfoManager::GetInstance().RemoveHapTokenInfo(getTokenId); + ASSERT_EQ(RET_SUCCESS, ret); + } + + ASSERT_EQ(RET_SUCCESS, RET_SUCCESS); +} + +/** + * @tc.name: CreateHapTokenInfo001 + * @tc.desc: Verify the CreateHapTokenInfo add one hap token function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(AccessTokenInfoManagerTest, CreateHapTokenInfo001, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + int ret = AccessTokenInfoManager::GetInstance().CreateHapTokenInfo(g_infoManagerTestInfoParms, + g_infoManagerTestPolicyPrams, tokenIdEx); + ASSERT_EQ(RET_SUCCESS, ret); + GTEST_LOG_(INFO) << "add a hap token"; + + std::shared_ptr tokenInfo; + tokenInfo = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_NE(nullptr, tokenInfo); + std::string infoDes; + tokenInfo->ToString(infoDes); + GTEST_LOG_(INFO) << "get hap token info:" << infoDes.c_str(); + + ret = AccessTokenInfoManager::GetInstance().RemoveHapTokenInfo(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + GTEST_LOG_(INFO) << "remove the token info"; + + tokenInfo = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_EQ(nullptr, tokenInfo); +} + +/** + * @tc.name: CreateHapTokenInfo002 + * @tc.desc: Verify the CreateHapTokenInfo add one hap token twice function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(AccessTokenInfoManagerTest, CreateHapTokenInfo002, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "AddHapToken001 fill data"); + + AccessTokenIDEx tokenIdEx = {0}; + int ret = AccessTokenInfoManager::GetInstance().CreateHapTokenInfo(g_infoManagerTestInfoParms, + g_infoManagerTestPolicyPrams, tokenIdEx); + ASSERT_EQ(RET_SUCCESS, ret); + GTEST_LOG_(INFO) << "add a hap token"; + + AccessTokenIDEx tokenIdEx1 = {0}; + ret = AccessTokenInfoManager::GetInstance().CreateHapTokenInfo(g_infoManagerTestInfoParms, + g_infoManagerTestPolicyPrams, tokenIdEx1); + ASSERT_EQ(RET_FAILED, ret); + ASSERT_EQ(0, tokenIdEx1.tokenIdExStruct.tokenID); + GTEST_LOG_(INFO) << "add same hap token"; + + std::shared_ptr tokenInfo; + tokenInfo = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_NE(nullptr, tokenInfo); + + std::string infoDes; + tokenInfo->ToString(infoDes); + GTEST_LOG_(INFO) << "get hap token info:" << infoDes.c_str(); + + ret = AccessTokenInfoManager::GetInstance().RemoveHapTokenInfo(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + GTEST_LOG_(INFO) << "remove the token info"; +} + +/** + * @tc.name: GetHapTokenID001 + * @tc.desc: Verify the GetHapTokenID by userID/bundleName/instIndex, function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(AccessTokenInfoManagerTest, GetHapTokenID001, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + int ret = AccessTokenInfoManager::GetInstance().CreateHapTokenInfo(g_infoManagerTestInfoParms, + g_infoManagerTestPolicyPrams, tokenIdEx); + ASSERT_EQ(RET_SUCCESS, ret); + GTEST_LOG_(INFO) << "add a hap token"; + + AccessTokenID getTokenId = AccessTokenInfoManager::GetInstance().GetHapTokenID(g_infoManagerTestInfoParms.userID, + g_infoManagerTestInfoParms.bundleName, g_infoManagerTestInfoParms.instIndex); + ASSERT_EQ(tokenIdEx.tokenIdExStruct.tokenID, getTokenId); + GTEST_LOG_(INFO) << "find hap info"; + + std::shared_ptr tokenInfo; + tokenInfo = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_NE(nullptr, tokenInfo); + GTEST_LOG_(INFO) << "remove the token info"; + + ret = AccessTokenInfoManager::GetInstance().RemoveHapTokenInfo(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + GTEST_LOG_(INFO) << "remove the token info"; +} + +/** + * @tc.name: UpdateHapToken001 + * @tc.desc: Verify the UpdateHapToken token function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(AccessTokenInfoManagerTest, UpdateHapToken001, TestSize.Level1) +{ + AccessTokenIDEx tokenIdEx = {0}; + int ret = AccessTokenInfoManager::GetInstance().CreateHapTokenInfo(g_infoManagerTestInfoParms, + g_infoManagerTestPolicyPrams, tokenIdEx); + ASSERT_EQ(RET_SUCCESS, ret); + GTEST_LOG_(INFO) << "add a hap token"; + + HapPolicyParams policy = g_infoManagerTestPolicyPrams; + policy.apl = APL_SYSTEM_BASIC; + ret = AccessTokenInfoManager::GetInstance().UpdateHapToken(tokenIdEx.tokenIdExStruct.tokenID, + std::string("updateAppId"), policy); + ASSERT_EQ(RET_SUCCESS, ret); + GTEST_LOG_(INFO) << "update the hap token"; + + std::shared_ptr tokenInfo; + tokenInfo = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_NE(nullptr, tokenInfo); + std::string infoDes; + tokenInfo->ToString(infoDes); + GTEST_LOG_(INFO) << "get hap token info:" << infoDes.c_str(); + + ret = AccessTokenInfoManager::GetInstance().RemoveHapTokenInfo(tokenIdEx.tokenIdExStruct.tokenID); + ASSERT_EQ(RET_SUCCESS, ret); + GTEST_LOG_(INFO) << "remove the token info"; +} diff --git a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_proxy.h b/services/accesstokenmanager/test/unittest/cpp/src/accesstoken_info_manager_test.h similarity index 58% rename from interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_proxy.h rename to services/accesstokenmanager/test/unittest/cpp/src/accesstoken_info_manager_test.h index e0c99c62dc48c7f9c5f9b51106077cb0d4e33a64..3d92f465012463b0cae197e70846727999270286 100644 --- a/interfaces/innerkits/accesstoken/main/cpp/src/accesstoken_manager_proxy.h +++ b/services/accesstokenmanager/test/unittest/cpp/src/accesstoken_info_manager_test.h @@ -13,26 +13,25 @@ * limitations under the License. */ -#ifndef ACCESSTOKEN_MANAGER_PROXY_H -#define ACCESSTOKEN_MANAGER_PROXY_H +#ifndef ACCESSTOKEN_INFO_MANAGER_TEST_H +#define ACCESSTOKEN_INFO_MANAGER_TEST_H -#include "i_accesstoken_manager.h" - -#include "iremote_proxy.h" +#include namespace OHOS { namespace Security { namespace AccessToken { -class AccessTokenManagerProxy : public IRemoteProxy { +class AccessTokenInfoManagerTest : public testing::Test { public: - explicit AccessTokenManagerProxy(const sptr& impl); - virtual ~AccessTokenManagerProxy() override; + static void SetUpTestCase(); + + static void TearDownTestCase(); + + void SetUp(); - int VerifyAccesstoken(AccessTokenID tokenID, const std::string& permissionName) override; -private: - static inline BrokerDelegator delegator_; + void TearDown(); }; } // namespace AccessToken } // namespace Security } // namespace OHOS -#endif // ACCESSTOKEN_MANAGER_PROXY_H +#endif // ACCESSTOKEN_INFO_MANAGER_TEST_H diff --git a/services/accesstokenmanager/test/unittest/cpp/src/native_token_receptor_test.cpp b/services/accesstokenmanager/test/unittest/cpp/src/native_token_receptor_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1602a6592841e51db97ed65f2b63e48993cdb78 --- /dev/null +++ b/services/accesstokenmanager/test/unittest/cpp/src/native_token_receptor_test.cpp @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2021 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 "native_token_receptor_test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "accesstoken_info_manager.h" +#include "data_storage.h" +#include "field_const.h" +#define private public +#include "nativetoken_kit.h" +#include "native_token_receptor.h" +#undef private +#include "securec.h" + +using namespace testing::ext; +using namespace OHOS::Security::AccessToken; + +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "NativeTokenReceptorTest"}; +} + +void NativeTokenReceptorTest::SetUpTestCase() +{ + // delete all test 0x28100000 - 0x28100007 + for (unsigned int i = 0x28100000; i <= 0x28100007; i++) { + AccessTokenInfoManager::GetInstance().RemoveNativeTokenInfo(i); + } +} + +void NativeTokenReceptorTest::TearDownTestCase() +{} + +void NativeTokenReceptorTest::SetUp() +{} + +void NativeTokenReceptorTest::TearDown() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test down!"); +} + +/** + * @tc.name: ParserNativeRawData001 + * @tc.desc: Verify processing right native token json. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, ParserNativeRawData001, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test ParserNativeRawData001!"); + std::string testStr = R"([)"\ + R"({"processName":"process6","APL":3,"version":1,"tokenId":685266937,"tokenAttr":0,)"\ + R"("dcaps":["AT_CAP","ST_CAP"]},)"\ + R"({"processName":"process5","APL":3,"version":1,"tokenId":678065606,"tokenAttr":0,)"\ + R"("dcaps":["AT_CAP","ST_CAP"]}])"; + + NativeTokenReceptor& receptor = NativeTokenReceptor::GetInstance(); + std::vector> tokenInfos; + receptor.ParserNativeRawData(testStr, tokenInfos); + int size = tokenInfos.size(); + ASSERT_EQ(2, size); + ASSERT_NE(nullptr, tokenInfos[0]); + ASSERT_NE(nullptr, tokenInfos[1]); + + ASSERT_EQ("process6", tokenInfos[0]->GetProcessName()); + ASSERT_EQ(685266937, tokenInfos[0]->GetTokenID()); + ASSERT_EQ(2, tokenInfos[0]->GetDcap().size()); + ASSERT_EQ("AT_CAP", (tokenInfos[0]->GetDcap())[0]); + ASSERT_EQ("ST_CAP", (tokenInfos[0]->GetDcap())[1]); + + ASSERT_EQ("process5", tokenInfos[1]->GetProcessName()); + ASSERT_EQ(678065606, tokenInfos[1]->GetTokenID()); + ASSERT_EQ(2, tokenInfos[1]->GetDcap().size()); + ASSERT_EQ("AT_CAP", (tokenInfos[1]->GetDcap())[0]); + ASSERT_EQ("ST_CAP", (tokenInfos[1]->GetDcap())[1]); +} + +/** + * @tc.name: ParserNativeRawData002 + * @tc.desc: Verify processing wrong native token json. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, ParserNativeRawData002, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test ParserNativeRawData002!"); + std::string testStr = R"([{"processName":""}])"; + std::vector> tokenInfos; + + NativeTokenReceptor& receptor = NativeTokenReceptor::GetInstance(); + + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); + + testStr = R"([{"processName":"", }])"; + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); + + testStr = R"([{"processName":"process6"}, {}])"; + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); + + testStr = R"([{"processName":""}, {"":"", ""}])"; + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); + + testStr = R"([{"processName":"process6", "tokenId":685266937, "APL":3, "version":new}])"; + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); + + testStr = R"([{"processName":"process6", "tokenId":685266937, "APL":7, "version":1}])"; + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); + + testStr = R"({"NativeToken":[{"processName":"process6", "tokenId":685266937, "APL":7, "version":1}]})"; + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); + + testStr = R"({"NativeToken":[{"processName":"process6", "tokenId":685266937, "APL":7, "version":1}])"; + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); + + testStr = R"(["NativeToken":])"; + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); + + testStr = R"([)"; + receptor.ParserNativeRawData(testStr, tokenInfos); + ASSERT_EQ(0, tokenInfos.size()); +} + +namespace OHOS { +namespace Security { +namespace AccessToken { + extern void from_json(const nlohmann::json& j, std::shared_ptr& p); +} +} +} + +/** + * @tc.name: from_json001 + * @tc.desc: Verify from json right case. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, from_json001, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test from_json001!"); + nlohmann::json j = nlohmann::json{ + {"processName", "process6"}, + {"APL", APL_SYSTEM_CORE}, + {"version", 1}, + {"tokenId", 685266937}, + {"tokenAttr", 0}, + {"dcaps", {"AT_CAP", "ST_CAP"}}}; + std::shared_ptr p; + from_json(j, p); + ASSERT_NE((p == nullptr), true); +} + +/** + * @tc.name: from_json002 + * @tc.desc: Verify from json wrong case. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, from_json002, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test from_json002!"); + // version wrong + nlohmann::json j = nlohmann::json{ + {"processName", "process6"}, {"APL", APL_SYSTEM_CORE}, + {"version", 2}, {"tokenId", 685266937}, + {"tokenAttr", 0}, + {"dcaps", {"AT_CAP", "ST_CAP"}}}; + std::shared_ptr p; + from_json(j, p); + ASSERT_EQ((p == nullptr), true); + + // APL wrong + j = nlohmann::json{ + {"processName", "process6"}, + {"APL", -1}, {"version", 1}, + {"tokenId", 685266937}, {"tokenAttr", 0}, + {"dcaps", {"AT_CAP", "ST_CAP"}}}; + from_json(j, p); + ASSERT_EQ((p == nullptr), true); + + // tokenId wrong + j = nlohmann::json{ + {"processName", "process6"}, + {"APL", APL_SYSTEM_BASIC}, {"version", 1}, + {"tokenId", 0}, {"tokenAttr", 0}, + {"dcaps", {"AT_CAP", "ST_CAP"}}}; + from_json(j, p); + ASSERT_EQ((p == nullptr), true); + + // process name empty + j = nlohmann::json{ + {"processName", ""}, + {"APL", APL_SYSTEM_BASIC}, {"version", 1}, + {"tokenId", 685266937}, {"tokenAttr", 0}, + {"dcaps", {"AT_CAP", "ST_CAP"}}}; + from_json(j, p); + ASSERT_EQ((p == nullptr), true); + + // process name too long + std::string name(512, 'c'); + j = nlohmann::json{ + {"processName", name}, + {"APL", APL_SYSTEM_BASIC}, {"version", 1}, + {"tokenId", 685266937}, {"tokenAttr", 0}, + {"dcaps", {"AT_CAP", "ST_CAP"}}}; + from_json(j, p); + ASSERT_EQ((p == nullptr), true); + + // lose process name + j = nlohmann::json{ + {"APL", APL_SYSTEM_BASIC}, + {"version", 1}, {"tokenId", 685266937}, + {"tokenAttr", 0}, {"dcaps", {"AT_CAP", "ST_CAP"}}}; + from_json(j, p); + ASSERT_EQ((p == nullptr), true); +} + +/** + * @tc.name: ProcessNativeTokenInfos001 + * @tc.desc: test add one native token + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, ProcessNativeTokenInfos001, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test ProcessNativeTokenInfos001!"); + std::vector> tokenInfos; + + // test process one + NativeTokenInfo info = { + .apl = APL_NORMAL, + .ver = 1, + .processName = "native_token_test0", + .tokenID = 0x28100000, + .tokenAttr = 0, + .dcap = {"AT_CAP", "ST_CAP"} + }; + std::shared_ptr nativeToken = std::make_shared(info); + tokenInfos.emplace_back(nativeToken); + AccessTokenInfoManager::GetInstance().ProcessNativeTokenInfos(tokenInfos); + NativeTokenInfo findInfo; + int ret = AccessTokenInfoManager::GetInstance().GetNativeTokenInfo(info.tokenID, findInfo); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(findInfo.apl, info.apl); + ASSERT_EQ(findInfo.ver, info.ver); + ASSERT_EQ(findInfo.processName, info.processName); + ASSERT_EQ(findInfo.tokenID, info.tokenID); + ASSERT_EQ(findInfo.tokenAttr, info.tokenAttr); + ASSERT_EQ(findInfo.dcap, info.dcap); + + // wait fresh tokens to sql. + sleep(3); + + // get sql data + std::vector nativeTokenResults; + DataStorage::GetRealDataStorage().Find(DataStorage::ACCESSTOKEN_NATIVE_INFO, nativeTokenResults); + for (GenericValues nativeTokenValue : nativeTokenResults) { + AccessTokenID tokenId = (AccessTokenID)nativeTokenValue.GetInt(FIELD_TOKEN_ID); + if (tokenId != info.tokenID) { + continue; + } + GTEST_LOG_(INFO) <<"apl " << nativeTokenValue.GetInt(FIELD_APL); + std::shared_ptr native = std::make_shared(); + ASSERT_NE(native, nullptr); + ret = native->RestoreNativeTokenInfo(tokenId, nativeTokenValue); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(native->GetTokenID(), info.tokenID); + ASSERT_EQ(native->GetProcessName(), info.processName); + ASSERT_EQ(native->GetDcap(), info.dcap); + } + + ret = AccessTokenInfoManager::GetInstance().RemoveNativeTokenInfo(info.tokenID); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: ProcessNativeTokenInfos002 + * @tc.desc: test add two native tokens. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, ProcessNativeTokenInfos002, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test ProcessNativeTokenInfos002!"); + std::vector> tokenInfos; + + NativeTokenInfo info1 = { + .apl = APL_NORMAL, + .ver = 1, + .processName = "native_token_test1", + .tokenID = 0x28100001, + .tokenAttr = 0, + .dcap = {"AT_CAP", "ST_CAP"} + }; + + NativeTokenInfo info2 = { + .apl = APL_NORMAL, + .ver = 1, + .processName = "native_token_test2", + .tokenID = 0x28100002, + .tokenAttr = 0, + .dcap = {"AT_CAP", "ST_CAP"} + }; + + std::shared_ptr nativeToken1 = std::make_shared(info1); + tokenInfos.emplace_back(nativeToken1); + + std::shared_ptr nativeToken2 = std::make_shared(info2); + tokenInfos.emplace_back(nativeToken2); + + AccessTokenInfoManager::GetInstance().ProcessNativeTokenInfos(tokenInfos); + NativeTokenInfo findInfo; + + int ret = AccessTokenInfoManager::GetInstance().GetNativeTokenInfo(info1.tokenID, findInfo); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(findInfo.apl, info1.apl); + ASSERT_EQ(findInfo.ver, info1.ver); + ASSERT_EQ(findInfo.processName, info1.processName); + ASSERT_EQ(findInfo.tokenID, info1.tokenID); + ASSERT_EQ(findInfo.tokenAttr, info1.tokenAttr); + ASSERT_EQ(findInfo.dcap, info1.dcap); + + ret = AccessTokenInfoManager::GetInstance().GetNativeTokenInfo(info2.tokenID, findInfo); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(findInfo.apl, info2.apl); + ASSERT_EQ(findInfo.ver, info2.ver); + ASSERT_EQ(findInfo.processName, info2.processName); + ASSERT_EQ(findInfo.tokenID, info2.tokenID); + ASSERT_EQ(findInfo.tokenAttr, info2.tokenAttr); + ASSERT_EQ(findInfo.dcap, info2.dcap); + + ret = AccessTokenInfoManager::GetInstance().RemoveNativeTokenInfo(info1.tokenID); + ASSERT_EQ(ret, RET_SUCCESS); + + ret = AccessTokenInfoManager::GetInstance().RemoveNativeTokenInfo(info2.tokenID); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: ProcessNativeTokenInfos003 + * @tc.desc: test add nullptr tokenInfo. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, ProcessNativeTokenInfos003, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test ProcessNativeTokenInfos003!"); + std::vector> tokenInfos; + + std::shared_ptr nativeToken1 = std::make_shared(); + tokenInfos.emplace_back(nativeToken1); + AccessTokenInfoManager::GetInstance().ProcessNativeTokenInfos(tokenInfos); + ASSERT_EQ(RET_SUCCESS, RET_SUCCESS); +} + +/** + * @tc.name: ProcessNativeTokenInfos004 + * @tc.desc: test add repeat id, but process doesnt + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, ProcessNativeTokenInfos004, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test ProcessNativeTokenInfos004!"); + std::vector> tokenInfos; + + NativeTokenInfo info3 = { + .apl = APL_NORMAL, + .ver = 1, + .processName = "native_token_test3", + .tokenID = 0x28100003, + .tokenAttr = 0, + .dcap = {"AT_CAP", "ST_CAP"} + }; + + NativeTokenInfo info4 = { + .apl = APL_NORMAL, + .ver = 1, + .processName = "native_token_test4", + .tokenID = 0x28100003, + .tokenAttr = 0, + .dcap = {"AT_CAP", "ST_CAP"} + }; + + std::shared_ptr nativeToken3 = std::make_shared(info3); + tokenInfos.emplace_back(nativeToken3); + + std::shared_ptr nativeToken4 = std::make_shared(info4); + tokenInfos.emplace_back(nativeToken4); + + AccessTokenInfoManager::GetInstance().ProcessNativeTokenInfos(tokenInfos); + + NativeTokenInfo findInfo; + int ret = AccessTokenInfoManager::GetInstance().GetNativeTokenInfo(info3.tokenID, findInfo); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(findInfo.apl, info3.apl); + ASSERT_EQ(findInfo.ver, info3.ver); + ASSERT_EQ(findInfo.processName, info3.processName); + ASSERT_EQ(findInfo.tokenID, info3.tokenID); + ASSERT_EQ(findInfo.tokenAttr, info3.tokenAttr); + ASSERT_EQ(findInfo.dcap, info3.dcap); + + ret = AccessTokenInfoManager::GetInstance().RemoveNativeTokenInfo(info3.tokenID); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: ProcessNativeTokenInfos005 + * @tc.desc: test add repeat process, but id doesnt + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, ProcessNativeTokenInfos005, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test ProcessNativeTokenInfos005!"); + std::vector> tokenInfos; + + NativeTokenInfo info5 = { + .apl = APL_NORMAL, + .ver = 1, + .processName = "native_token_test5", + .tokenID = 0x28100005, + .tokenAttr = 0, + .dcap = {"AT_CAP", "ST_CAP"} + }; + + NativeTokenInfo info6 = { + .apl = APL_NORMAL, + .ver = 1, + .processName = "native_token_test5", + .tokenID = 0x28100006, + .tokenAttr = 0, + .dcap = {"AT_CAP", "ST_CAP"} + }; + + std::shared_ptr nativeToken5 = std::make_shared(info5); + tokenInfos.emplace_back(nativeToken5); + + std::shared_ptr nativeToken6 = std::make_shared(info6); + tokenInfos.emplace_back(nativeToken6); + + AccessTokenInfoManager::GetInstance().ProcessNativeTokenInfos(tokenInfos); + + NativeTokenInfo findInfo; + int ret = AccessTokenInfoManager::GetInstance().GetNativeTokenInfo(info5.tokenID, findInfo); + ASSERT_EQ(ret, RET_FAILED); + + ret = AccessTokenInfoManager::GetInstance().GetNativeTokenInfo(info6.tokenID, findInfo); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(findInfo.apl, info6.apl); + ASSERT_EQ(findInfo.ver, info6.ver); + ASSERT_EQ(findInfo.processName, info6.processName); + ASSERT_EQ(findInfo.tokenID, info6.tokenID); + ASSERT_EQ(findInfo.tokenAttr, info6.tokenAttr); + ASSERT_EQ(findInfo.dcap, info6.dcap); + + ret = AccessTokenInfoManager::GetInstance().RemoveNativeTokenInfo(info6.tokenID); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: ProcessNativeTokenInfos006 + * @tc.desc: test add repeat process and id + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, ProcessNativeTokenInfos006, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test ProcessNativeTokenInfos006!"); + std::vector> tokenInfos; + + NativeTokenInfo info7 = { + .apl = APL_NORMAL, + .ver = 1, + .processName = "native_token_test7", + .tokenID = 0x28100007, + .tokenAttr = 0, + .dcap = {"AT_CAP", "ST_CAP"} + }; + + NativeTokenInfo info8 = { + .apl = APL_SYSTEM_BASIC, + .ver = 1, + .processName = "native_token_test7", + .tokenID = 0x28100007, + .tokenAttr = 0, + .dcap = {"AT_CAP"} + }; + + std::shared_ptr nativeToken7 = std::make_shared(info7); + tokenInfos.emplace_back(nativeToken7); + + std::shared_ptr nativeToken8 = std::make_shared(info8); + tokenInfos.emplace_back(nativeToken8); + + AccessTokenInfoManager::GetInstance().ProcessNativeTokenInfos(tokenInfos); + + NativeTokenInfo findInfo; + int ret = AccessTokenInfoManager::GetInstance().GetNativeTokenInfo(info7.tokenID, findInfo); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(findInfo.apl, info8.apl); + ASSERT_EQ(findInfo.ver, info8.ver); + ASSERT_EQ(findInfo.processName, info8.processName); + ASSERT_EQ(findInfo.tokenID, info8.tokenID); + ASSERT_EQ(findInfo.tokenAttr, info8.tokenAttr); + ASSERT_EQ(findInfo.dcap, info8.dcap); + + ret = AccessTokenInfoManager::GetInstance().RemoveNativeTokenInfo(info8.tokenID); + ASSERT_EQ(ret, RET_SUCCESS); +} + +/** + * @tc.name: init001 + * @tc.desc: test get native cfg + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(NativeTokenReceptorTest, init001, TestSize.Level1) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "test init001!"); + std::vector> tokenInfos; + + const char **dcaps = (const char **)malloc(sizeof(char *) * 1); + dcaps[0] = "AT_CAP_01"; + int dcapNum = 1; + char processName[32]; + strcpy(processName, "native_token_test7"); + char apl[32]; + strcpy(apl, "system_core"); + + uint64_t tokenId = ::GetAccessTokenId(processName, dcaps, dcapNum, apl); + ASSERT_NE(tokenId, 0); + + NativeTokenReceptor::GetInstance().Init(); + NativeTokenInfo findInfo; + int ret = AccessTokenInfoManager::GetInstance().GetNativeTokenInfo(tokenId, findInfo); + ASSERT_EQ(ret, RET_SUCCESS); + ASSERT_EQ(findInfo.processName, processName); + + ret = AccessTokenInfoManager::GetInstance().RemoveNativeTokenInfo(tokenId); + ASSERT_EQ(ret, RET_SUCCESS); +} diff --git a/services/accesstokenmanager/test/unittest/cpp/src/native_token_receptor_test.h b/services/accesstokenmanager/test/unittest/cpp/src/native_token_receptor_test.h new file mode 100644 index 0000000000000000000000000000000000000000..1df01e7d45c2a77f575ca71b99762bf2b5ec7a14 --- /dev/null +++ b/services/accesstokenmanager/test/unittest/cpp/src/native_token_receptor_test.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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 NATIVE_TOKEN_RECEPTOR_TEST_H +#define NATIVE_TOKEN_RECEPTOR_TEST_H + +#include +#include "accesstoken_log.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class NativeTokenReceptorTest : public testing::Test { +public: + static void SetUpTestCase(); + + static void TearDownTestCase(); + + void SetUp(); + + void TearDown(); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // NATIVE_TOKEN_RECEPTOR_TEST_H diff --git a/services/tokensyncmanager/BUILD.gn b/services/tokensyncmanager/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..ef99ca14c932b560463e66c30e6026d5926ec81b --- /dev/null +++ b/services/tokensyncmanager/BUILD.gn @@ -0,0 +1,92 @@ +# Copyright (c) 2021 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. + +import("//build/ohos.gni") + +ohos_prebuilt_etc("token_sync.rc") { + source = "token_sync.cfg" + relative_install_dir = "init" + subsystem_name = "security" + part_name = "access_token" +} + +ohos_shared_library("token_sync_manager_service") { + subsystem_name = "security" + part_name = "access_token" + + include_dirs = [ + "include/service", + "include/remote", + "include/command", + "include/common", + "include/device", + "include/protocol", + "//third_party/json/include", + "//utils/system/safwk/native/include", + "//third_party/json/include", + "//base/security/access_token/frameworks/common/include", + "//base/security/access_token/frameworks/accesstoken/include", + "//base/security/access_token/frameworks/tokensync/include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", + "//foundation/communication/dsoftbus/interfaces/kits/transport", + "//foundation/communication/dsoftbus/interfaces/kits/common", + "//foundation/communication/dsoftbus/interfaces/kits/bus_center", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base/include", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + ] + + sources = [ + "src/command/base_remote_command.cpp", + "src/command/delete_remote_token_command.cpp", + "src/command/sync_remote_hap_token_command.cpp", + "src/command/sync_remote_native_token_command.cpp", + "src/command/update_remote_hap_token_command.cpp", + "src/common/constant.cpp", + "src/device/device_info_manager.cpp", + "src/device/device_info_repository.cpp", + "src/remote/remote_command_executor.cpp", + "src/remote/remote_command_factory.cpp", + "src/remote/remote_command_manager.cpp", + "src/remote/soft_bus_channel.cpp", + "src/remote/soft_bus_device_connection_listener.cpp", + "src/remote/soft_bus_manager.cpp", + "src/remote/soft_bus_session_listener.cpp", + "src/service/token_sync_event_handler.cpp", + "src/service/token_sync_manager_service.cpp", + "src/service/token_sync_manager_stub.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + deps = [ + "//base/security/access_token/frameworks/accesstoken:accesstoken_communication_adapter_cxx", + "//base/security/access_token/frameworks/common:accesstoken_common_cxx", + "//base/security/access_token/interfaces/innerkits/accesstoken:libaccesstoken_sdk", + "//base/security/access_token/services/tokensyncmanager:token_sync.rc", + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", + "//foundation/aafwk/standard/interfaces/innerkits/base:base", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + "//third_party/zlib:libz", + "//utils/native/base:utils", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] +} diff --git a/services/tokensyncmanager/include/command/base_remote_command.h b/services/tokensyncmanager/include/command/base_remote_command.h new file mode 100644 index 0000000000000000000000000000000000000000..6af5f58a0b4508e138f89f2402d303932bdb81d7 --- /dev/null +++ b/services/tokensyncmanager/include/command/base_remote_command.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 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 BASE_REMOTE_COMMON_H +#define BASE_REMOTE_COMMON_H + +#include + +#include "constant.h" +#include "hap_token_info.h" +#include "native_token_info.h" +#include "nlohmann/json.hpp" +#include "permission_state_full.h" +#include "remote_protocol.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +/** + * The base class for command. You can treat this as remote command header. + */ +class BaseRemoteCommand { +public: + BaseRemoteCommand() = default; + virtual ~BaseRemoteCommand() = default; + + /* Prepare() is called in requestor */ + virtual void Prepare() = 0; + + /* Execute() is called in responser */ + virtual void Execute() = 0; + + /* Finish() is called in requestor, after get response, but the command object is not same with the request */ + virtual void Finish() = 0; + + virtual std::string ToJsonPayload() = 0; + nlohmann::json ToRemoteProtocolJson(); + void FromRemoteProtocolJson(const nlohmann::json& jsonObject); + + void ToPermStateJson(nlohmann::json& permStateJson, const PermissionStateFull& state); + void FromPermStateListJson(const nlohmann::json& hapTokenJson, + std::vector& permStateList); + + void FromHapTokenBasicInfoJson(const nlohmann::json& hapTokenJson, + HapTokenInfo& hapTokenBasicInfo); + + nlohmann::json ToHapTokenInfosJson(const HapTokenInfoForSync &tokenInfo); + void FromHapTokenInfoJson(const nlohmann::json& hapTokenJson, HapTokenInfoForSync& hapTokenInfo); + nlohmann::json ToNativeTokenInfoJson(const NativeTokenInfo& tokenInfo); + void FromNativeTokenInfoJson(const nlohmann::json& nativeTokenJson, NativeTokenInfo& nativeTokenInfo); + RemoteProtocol remoteProtocol_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // BASE_REMOTE_COMMON_H diff --git a/services/tokensyncmanager/include/command/delete_remote_token_command.h b/services/tokensyncmanager/include/command/delete_remote_token_command.h new file mode 100644 index 0000000000000000000000000000000000000000..97e3a2444aba3847c30bdca4f901e6c58f62786d --- /dev/null +++ b/services/tokensyncmanager/include/command/delete_remote_token_command.h @@ -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. + */ + +#ifndef DELETE_REMOTE_TOKEN_COMMAND_H +#define DELETE_REMOTE_TOKEN_COMMAND_H + +#include "base_remote_command.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +/** + * Command which used to get all native token info from other device. + */ +class DeleteRemoteTokenCommand : public BaseRemoteCommand { +public: + void Prepare() override; + + void Execute() override; + + void Finish() override; + + std::string ToJsonPayload() override; + + DeleteRemoteTokenCommand(const std::string &json); + DeleteRemoteTokenCommand(const std::string &srcDeviceId, const std::string &dstDeviceId, + AccessTokenID deleteID); + virtual ~DeleteRemoteTokenCommand() = default; + +private: + /** + * The command name. Should be equal to class name. + */ + const std::string COMMAND_NAME = "DeleteRemoteTokenCommand"; + AccessTokenID deleteTokenId_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/tokensyncmanager/include/command/sync_remote_hap_token_command.h b/services/tokensyncmanager/include/command/sync_remote_hap_token_command.h new file mode 100644 index 0000000000000000000000000000000000000000..3783c0c9c96b850c18cf5cef8b484a420faed172 --- /dev/null +++ b/services/tokensyncmanager/include/command/sync_remote_hap_token_command.h @@ -0,0 +1,59 @@ +/* + * 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 SYNC_REMOTE_HAP_TOKEN_COMMAND_H +#define SYNC_REMOTE_HAP_TOKEN_COMMAND_H + +#include + +#include "access_token.h" +#include "base_remote_command.h" +#include "hap_token_info.h" +#include "permission_state_full.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +/** + * Command which used to get all native token info from other device. + */ +class SyncRemoteHapTokenCommand : public BaseRemoteCommand { +public: + void Prepare() override; + + void Execute() override; + + void Finish() override; + + std::string ToJsonPayload() override; + + SyncRemoteHapTokenCommand(const std::string &json); + SyncRemoteHapTokenCommand( const std::string &srcDeviceId, + const std::string &dstDeviceId, AccessTokenID id); + virtual ~SyncRemoteHapTokenCommand() = default; + +private: + /** + * The command name. Should be equal to class name. + */ + const std::string COMMAND_NAME = "SyncRemoteHapTokenCommand"; + HapTokenInfoForSync hapTokenInfo_; + AccessTokenID requestTokenId_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif + diff --git a/services/tokensyncmanager/include/command/sync_remote_native_token_command.h b/services/tokensyncmanager/include/command/sync_remote_native_token_command.h new file mode 100644 index 0000000000000000000000000000000000000000..e398d780427dc00b1b39bed652478f15a6ef7433 --- /dev/null +++ b/services/tokensyncmanager/include/command/sync_remote_native_token_command.h @@ -0,0 +1,55 @@ +/* + * 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 SYNC_REMOTE_NATIVE_TOKEN_COMMAND_H +#define SYNC_REMOTE_NATIVE_TOKEN_COMMAND_H + +#include +#include + +#include "base_remote_command.h" +#include "native_token_info.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +/** + * Command which used to get all native token info from other device. + */ +class SyncRemoteNativeTokenCommand : public BaseRemoteCommand { +public: + void Prepare() override; + + void Execute() override; + + void Finish() override; + + std::string ToJsonPayload() override; + + SyncRemoteNativeTokenCommand(const std::string &json); + SyncRemoteNativeTokenCommand(const std::string &srcDeviceId, const std::string &dstDeviceId); + virtual ~SyncRemoteNativeTokenCommand() = default; + +private: + /** + * The command name. Should be equal to class name. + */ + const std::string COMMAND_NAME = "SyncRemoteNativeTokenCommand"; + std::vector nativeTokenInfo_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/tokensyncmanager/include/command/update_remote_hap_token_command.h b/services/tokensyncmanager/include/command/update_remote_hap_token_command.h new file mode 100644 index 0000000000000000000000000000000000000000..1e6f889195d65ab11d9e03054308fb9253295583 --- /dev/null +++ b/services/tokensyncmanager/include/command/update_remote_hap_token_command.h @@ -0,0 +1,56 @@ +/* + * 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 UPDATE_REMOTE_HAP_TOKEN_COMMAND_H +#define UPDATE_REMOTE_HAP_TOKEN_COMMAND_H + +#include + +#include "access_token.h" +#include "base_remote_command.h" +#include "hap_token_info.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +/** + * Command which used to get all native token info from other device. + */ +class UpdateRemoteHapTokenCommand : public BaseRemoteCommand { +public: + void Prepare() override; + + void Execute() override; + + void Finish() override; + + std::string ToJsonPayload() override; + + UpdateRemoteHapTokenCommand(const std::string &json); + UpdateRemoteHapTokenCommand(const std::string &srcDeviceId, const std::string &dstDeviceId, + const HapTokenInfoForSync& tokenInfo); + virtual ~UpdateRemoteHapTokenCommand() = default; + +private: + /** + * The command name. Should be equal to class name. + */ + const std::string COMMAND_NAME = "UpdateRemoteHapTokenCommand"; + HapTokenInfoForSync updateTokenInfo_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/tokensyncmanager/include/common/constant.h b/services/tokensyncmanager/include/common/constant.h new file mode 100644 index 0000000000000000000000000000000000000000..be2191d963779e4dcdc75e1c0864734d2abbb62f --- /dev/null +++ b/services/tokensyncmanager/include/common/constant.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 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 CONSTANT_H +#define CONSTANT_H + +#include +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +class Constant { +public: + /** + * Indicates message format version, should be compatible. + */ + const static int32_t DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION = 2; + + /** + * Status code, indicates general success. + */ + const static int32_t SUCCESS = 0; + + /** + * Status code, indicates general failure. + */ + const static int32_t FAILURE = -1; + + /** + * Status code, indicates failure but can retry. + */ + const static int32_t FAILURE_BUT_CAN_RETRY = -2; + + /** + * Status Code, indicates invalid command. + */ + const static int32_t INVALID_COMMAND = -14; + + /** + * Session Id, indicates invalid session. + */ + const static int32_t INVALID_SESSION = -1; + + /** + * Command status code, indicate a status of command before RPC call. + */ + const static int32_t STATUS_CODE_BEFORE_RPC = 100001; + + /** + * Command result string, indicates success. + */ + static const std::string COMMAND_RESULT_SUCCESS; + + /** + * Command result string, indicates failed. + */ + static const std::string COMMAND_RESULT_FAILED; + + /** + * Device id length. + */ + const static int32_t DEVICE_UUID_LENGTH = 65; + + /** + * Command status code, indicate a status of command before RPC call. + */ + const static int32_t DELAY_SYNC_TOKEN_MS = 3000; + + static constexpr int32_t ENCRYPTLEN = 4; + static constexpr int32_t ENCRYPTBEGIN = 0; + static constexpr int32_t ENCRYPTEND = 3; + static std::string EncryptDevId(std::string deviceId); + + /** + * GetLocalDeviceId + */ + static std::string GetLocalDeviceId(); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // CONSTANT_H \ No newline at end of file diff --git a/services/tokensyncmanager/include/device/device_info.h b/services/tokensyncmanager/include/device/device_info.h new file mode 100644 index 0000000000000000000000000000000000000000..958aa080352b6a933df0e1cbf72072e34600e64d --- /dev/null +++ b/services/tokensyncmanager/include/device/device_info.h @@ -0,0 +1,46 @@ +/* + * 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 DEVICE_INFO_H +#define DEVICE_INFO_H + +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +enum DeviceIdType { + NETWORK_ID, + UNIVERSALLY_UNIQUE_ID, + UNIQUE_DISABILITY_ID, + UNKNOWN, +}; + +struct DeviceId { + std::string networkId; + std::string universallyUniqueId; + std::string uniqueDisabilityId; +}; + +struct DeviceInfo { + DeviceId deviceId; + std::string deviceName; + std::string deviceType; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // DEVICE_INFO_H \ No newline at end of file diff --git a/services/tokensyncmanager/include/device/device_info_manager.h b/services/tokensyncmanager/include/device/device_info_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..b5be6c8270854fe30c6f151c3f5d5f4b44b6c95f --- /dev/null +++ b/services/tokensyncmanager/include/device/device_info_manager.h @@ -0,0 +1,104 @@ +/* + * 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 DEVICE_INFO_MANAGER_H +#define DEVICE_INFO_MANAGER_H + +#include + +#include "accesstoken_log.h" +#include "data_validator.h" +#include "device_info_repository.h" +#include "ipc_skeleton.h" +#include "parameter.h" +#include "soft_bus_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class DeviceInfoManager { +public: + static DeviceInfoManager &GetInstance(); + + /** + * Get device info by device id. + * + * @param nodeId Device id. + * @param deviceIdType Device id type {@link DeviceIdType} + * @return Optional deviceInfo + */ + bool GetDeviceInfo(const std::string &nodeId, DeviceIdType deviceIdType, DeviceInfo &deviceInfo) const; + + /** + * Check device info exist. Online and local device info will be here. + * + * @param nodeId Device id. + * @param deviceIdType Device id type {@link DeviceIdType} + * @return True for exist, false otherwise. + */ + bool ExistDeviceInfo(const std::string &nodeId, DeviceIdType deviceIdType) const; + + /** + * Add device info with device ids and device properties. + * + * @param networkId Device networkId. + * @param universallyUniqueId Device uuid. + * @param uniqueDisabilityId Device udid. + * @param deviceName Device name. + * @param deviceType Device type. + */ + void AddDeviceInfo(const std::string &networkId, const std::string &universallyUniqueId, + const std::string &uniqueDisabilityId, const std::string &deviceName, const std::string &deviceType); + + /** + * Remote all device info. + */ + void RemoveAllRemoteDeviceInfo(); + + /** + * Remove one device info. + * + * @param nodeId Device id. + */ + void RemoveRemoteDeviceInfo(const std::string &nodeId, DeviceIdType deviceIdType); + + /** + * Convert nodeId to deviceId(UUID) if possible. + * + * @param nodeId which is considered as indefinite id, maybe deviceId(UUID) or networkId. + * @return The deviceId if local or device online, otherwise return empty string. + */ + std::string ConvertToUniversallyUniqueIdOrFetch(const std::string &nodeId) const; + + /** + * Convert nodeId to deviceId(UDID) if possible. + * + * @param nodeId which is considered as indefinite id, maybe deviceId(UDID) or networkId. + * @return The deviceId if local or device online, otherwise return empty string. + */ + std::string ConvertToUniqueDisabilityIdOrFetch(const std::string &nodeId) const; + + /** + * Check nodeId is uuid or not. + * + * @param nodeId Node id. + * @return True if node id is uuid. False otherwise. + */ + bool IsDeviceUniversallyUniqueId(const std::string &nodeId) const; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // DEVICE_INFO_MANAGER_H \ No newline at end of file diff --git a/services/tokensyncmanager/include/device/device_info_repository.h b/services/tokensyncmanager/include/device/device_info_repository.h new file mode 100644 index 0000000000000000000000000000000000000000..319e76838de8b37c1f2ef4ee39e81573a67a47ec --- /dev/null +++ b/services/tokensyncmanager/include/device/device_info_repository.h @@ -0,0 +1,77 @@ +/* + * 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 DEVICE_INFO_REPOSITORY_H +#define DEVICE_INFO_REPOSITORY_H + +#include +#include +#include +#include + +#include "constant.h" +#include "device_info.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class DeviceInfoRepository { +public: + static DeviceInfoRepository &GetInstance(); + + std::vector ListDeviceInfo(); + + bool FindDeviceInfo(const std::string &nodeId, DeviceIdType type, DeviceInfo &deviceInfo); + + void DeleteAllDeviceInfoExceptOne(const DeviceInfo deviceInfo); + + void SaveDeviceInfo(const DeviceInfo deviceInfo); + + void SaveDeviceInfo(const DeviceId deviceId, const std::string &deviceName, const std::string &deviceType); + + void SaveDeviceInfo(const std::string &networkId, const std::string &universallyUniqueId, + const std::string &uniqueDisabilityId, const std::string &deviceName, const std::string &deviceType); + + void DeleteDeviceInfo(const std::string &nodeId, const DeviceIdType type); + + void Clear(); + +private: + bool FindDeviceIdByNodeIdLocked(const std::string &nodeId, const DeviceIdType type, DeviceId &deviceId) const; + + bool FindDeviceInfoByDeviceIdLocked(const DeviceId deviceId, DeviceInfo &deviceInfo) const; + + bool FindDeviceIdByNetworkIdLocked(const std::string &networkId, DeviceId &deviceId) const; + + bool FindDeviceIdByUniversallyUniqueIdLocked(const std::string &universallyUniqueId, DeviceId &deviceId) const; + + bool FindDeviceIdByUniqueDisabilityIdLocked(const std::string &uniqueDisabilityId, DeviceId &deviceId) const; + + void DeleteDeviceInfoByDeviceIdLocked(const DeviceId deviceId); + + std::map deviceIdMapByNetworkId_; + + std::map deviceIdMapByUniversallyUniqueId_; + + std::map deviceIdMapByUniqueDisabilityId_; + + std::map deviceInfoMap_; + + std::recursive_mutex stackLock_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // DEVICE_INFO_REPOSITORY_H \ No newline at end of file diff --git a/services/tokensyncmanager/include/protocol/remote_protocol.h b/services/tokensyncmanager/include/protocol/remote_protocol.h new file mode 100644 index 0000000000000000000000000000000000000000..97ada420baa8a95570e8e95dfb4f44e6cd433e3c --- /dev/null +++ b/services/tokensyncmanager/include/protocol/remote_protocol.h @@ -0,0 +1,38 @@ +/* + * 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 REMOTE_PROTOCOL_H +#define REMOTE_PROTOCOL_H + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct RemoteProtocol { + std::string commandName; + std::string uniqueId; + int32_t requestVersion; + std::string srcDeviceId; + std::string srcDeviceLevel; + std::string dstDeviceId; + std::string dstDeviceLevel; + int32_t statusCode; + std::string message; + int32_t responseVersion; + std::string responseDeviceId; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/tokensyncmanager/include/remote/remote_command_executor.h b/services/tokensyncmanager/include/remote/remote_command_executor.h new file mode 100644 index 0000000000000000000000000000000000000000..f8982a9b53072d7482ed137bf86519652ecfa060 --- /dev/null +++ b/services/tokensyncmanager/include/remote/remote_command_executor.h @@ -0,0 +1,158 @@ +/* + * 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 REMOTE_COMMAND_EXECUTOR_H +#define REMOTE_COMMAND_EXECUTOR_H + +#include +#include + +#include "accesstoken_log.h" +#include "base_remote_command.h" +#include "remote_command_factory.h" +#include "rpc_channel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class RemoteCommandExecutor final { +public: + RemoteCommandExecutor(const std::string &targetNodeId); + virtual ~RemoteCommandExecutor(); + + const std::shared_ptr &GetChannel() const + { + return ptrChannel_; + } + void SetChannel(const std::shared_ptr &ptrChannel) + { + ptrChannel_ = ptrChannel; + } + + /** + * @brief Factory method to create a rpc channel. we will only create SoftBusChannel by now. + * + * @param targetNodeId target device node id(udid) + * @return Returns a shared_ptr if the operation is successful, returns nullptr otherwise. + * @see SoftBusChannel + * @since 1.0 + * @version 1.0 + */ + static const std::shared_ptr CreateChannel(const std::string &targetNodeId); + + /** + * @brief Process one command given. + * + * @param ptrCommand BaseRemoteCommand to execute. + * @return Returns SUCCESS if the operation is successful, returns minus integer otherwise. + * @see void + * @since 1.0 + * @version 1.0 + */ + int ProcessOneCommand(const std::shared_ptr &ptrCommand); + + /** + * @brief Add one command into the buffer + * + * @param ptrCommand BaseRemoteCommand to execute. + * @return Returns SUCCESS if the operation is successful, returns INVALID_COMMAND otherwise. + * @see ProcessBufferedCommands + * @since 1.0 + * @version 1.0 + */ + int AddCommand(const std::shared_ptr &ptrCommand); + + /** + * @brief Process all the command in the buffer + * + * @param standalone true if run in a new thread or event runner, otherwise false. + * @return Returns SUCCESS if the operation is successful, returns FAILURE otherwise. + * @see AddCommand ProcessOneCommand + * @since 1.0 + * @version 1.0 + */ + int ProcessBufferedCommands(bool standalone = false); + + /** + * @brief Process all the command in the buffer within a new thread. in deconstruct, we need to join this thread if + * needed. + * + * @param ptrCommand BaseRemoteCommand to execute. + * @return void + * @see ProcessBufferedCommands + * @since 1.0 + * @version 1.0 + */ + void ProcessBufferedCommandsWithThread(); + +private: + /** + * @brief execute a command in a specific place. + * for remote command, transfor the command json string by channel to softbus, and wait for softbus to response a + * json string. while remote response a json string, construct a remote command and finish it. + * if command buffer is empty, close the rpc channel. + * + * @param ptrCommand BaseRemoteCommand to execute. + * @param isRemote where to run. true for remote, false for local. + * @return Returns SUCCESS if the operation is successful, returns FAILURE otherwise. + * @see ProcessBufferedCommands + * @since 1.0 + * @version 1.0 + */ + int ExecuteRemoteCommand(const std::shared_ptr &ptrCommand, bool isRemote); + + /** + * @brief create a rpc channel if not exist. + * + * @param ptrCommand BaseRemoteCommand to execute. + * @param isRemote where to run. true for remote, false for local. + * @return void + * @see ProcessBufferedCommands + * @since 1.0 + * @version 1.0 + */ + void CreateChannelIfNeeded(); + + /** + * @brief finish a command + * + * @param ptrCommand BaseRemoteCommand to execute. + * @return Returns SUCCESS if the operation is successful, returns FAILURE otherwise. + * @see ProcessBufferedCommands + * @since 1.0 + * @version 1.0 + */ + int ClientProcessResult(const std::shared_ptr &ptrCommand); + +private: + // target device node id(udid) + std::string targetNodeId_; + + // cached channel for buffered commands + std::shared_ptr ptrChannel_; + + // mutex to lock commands buffer for concurrent access. + std::recursive_mutex mutex_; + + // commands buffer + std::deque> commands_; + + // consumer running flag, true if the consumer is RUNNING, false otherwise. @see ProcessBufferedCommands + bool running_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // REMOTE_COMMAND_EXECUTOR_H diff --git a/services/tokensyncmanager/include/remote/remote_command_factory.h b/services/tokensyncmanager/include/remote/remote_command_factory.h new file mode 100644 index 0000000000000000000000000000000000000000..f9967cc208ea736051848cf3dea9c5b03fafd644 --- /dev/null +++ b/services/tokensyncmanager/include/remote/remote_command_factory.h @@ -0,0 +1,58 @@ +/* + * 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 REMOTE_COMMAND_FACTORY_H +#define REMOTE_COMMAND_FACTORY_H + +#include +#include +#include + +#include "access_token.h" +#include "delete_remote_token_command.h" +#include "hap_token_info.h" +#include "sync_remote_hap_token_command.h" +#include "sync_remote_native_token_command.h" +#include "update_remote_hap_token_command.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class RemoteCommandFactory { +public: + static RemoteCommandFactory &GetInstance(); + + std::shared_ptr NewSyncRemoteHapTokenCommand(const std::string &srcDeviceId, + const std::string &dstDeviceId, AccessTokenID tokenID); + + std::shared_ptr NewDeleteRemoteTokenCommand(const std::string &srcDeviceId, + const std::string &dstDeviceId, AccessTokenID tokenID); + + std::shared_ptr NewUpdateRemoteHapTokenCommand(const std::string &srcDeviceId, + const std::string &dstDeviceId, const HapTokenInfoForSync& tokenInfo); + + std::shared_ptr NewSyncRemoteNativeTokenCommand(const std::string &srcDeviceId, + const std::string &dstDeviceId); + + std::shared_ptr NewRemoteCommandFromJson( + const std::string &commandName, const std::string &commandJsonString); + +private: + const std::string TAG = "RemoteCommandFactory"; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // REMOTE_COMMAND_FACTORY_H diff --git a/services/tokensyncmanager/include/remote/remote_command_manager.h b/services/tokensyncmanager/include/remote/remote_command_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..b40619eda8fb6f8ee8de48946e8d6d2e5001ae26 --- /dev/null +++ b/services/tokensyncmanager/include/remote/remote_command_manager.h @@ -0,0 +1,165 @@ +/* + * 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 REMOTE_COMMAND_MANAGER_H +#define REMOTE_COMMAND_MANAGER_H + +#include +#include +#include +#include + +#include "accesstoken_log.h" +#include "base_remote_command.h" +#include "constant.h" +#include "data_validator.h" +#include "remote_command_executor.h" +#include "rpc_channel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class RemoteCommandManager final { +public: + ~RemoteCommandManager(); + + /** + * @brief Singleton instance get method. + * + * @since 1.0 + * @version 1.0 + */ + static RemoteCommandManager &GetInstance(); + + /** + * @brief Init method. + * + * @see + * @since 1.0 + * @version 1.0 + */ + void Init(); + + /** + * @brief Execute a command now. + * + * @param udid The udid of a device which you want to execute on. if udid is empty, return -1. + * @param command A command extend BaseRemoteCommand. if command is nullptr, return -1. + * @return The execute result, returned from RemoteCommandExecutor. + * @see RemoteCommandExecutor.ExecuteOneCommand + * @since 1.0 + * @version 1.0 + */ + int ExecuteCommand(const std::string &udid, const std::shared_ptr &command); + + /** + * @brief Add a command to buffer. + * + * @param udid The udid of a device which you want to execute on. + * @param command A command extend BaseRemoteCommand. + * @return The add result, returned from RemoteCommandExecutor. by now, SUCCESS: 0. INVALID_COMMAND: -14 + * @see RemoteCommandExecutor.AddCommand + * @since 1.0 + * @version 1.0 + */ + int AddCommand(const std::string &udid, const std::shared_ptr &command); + + /** + * @brief Execute all buffered commands for given device. + * + * @param udid The udid of a device which you want to execute on. + * @return The execute result. SUCCESS: 0; FAILURE: -1. + * @see RemoteCommandExecutor.ProcessBufferedCommands + * @since 1.0 + * @version 1.0 + */ + int ProcessDeviceCommandImmediately(const std::string &udid); + + /** + * @brief Execute all buffered commands for all device asynchronized. + * + * @return The loop result. SUCCESS: 0. + * @see RemoteCommandExecutor.ProcessBufferedCommandsWithThread + * @since 1.0 + * @version 1.0 + */ + int Loop(); + + /** + * @brief Clear buffered commands. + * + * @since 1.0 + * @version 1.0 + */ + void Clear(); + + /** + * @brief Remove a command from buffer. + * + * @param udid The udid of a device which you want to remove. + */ + void RemoveCommand(const std::string &udid); + + /** + * @brief For event of device online, prepare channel and build connection with peer device. + * + * @param peerNodeId The udid of peer device. + * @return Result code indicates if notify successfully. SUCCESS: 0, FAILURE: -1. + * @since 1.0 + * @version 1.0 + */ + int NotifyDeviceOnline(const std::string &peerNodeId); + + /** + * @brief For event of device offline, clean caches related to peer device. + * + * @param peerNodeId The peer device's nodeId, maybe uuid or udid . + * @return Result code indicates if notify successfully. SUCCESS: 0, FAILURE: -1. + * @since 1.0 + * @version 1.0 + */ + int NotifyDeviceOffline(const std::string &peerNodeId); + + /** + * @brief Get remote command executor's channel for given nodeId. + * + * @param nodeId The peer device's nodeId, maybe uuid or udid or networkId. + * @return Channel instance if remote command executor has been created, null otherwise. + */ + std::shared_ptr GetExecutorChannel(const std::string &nodeId); + +private: + RemoteCommandManager(); + + // executors buffer + std::map> executors_; + // executors buffer mutex + std::mutex mutex_; + + /** + * @brief Fetch a executor from executors buffer. If not found, create one and cache it to buffer. + * + * @param nodeId The udid of a device which you want to get executor. + * @see void + * @since 1.0 + * @version 1.0 + */ + std::shared_ptr GetOrCreateRemoteCommandExecutor(const std::string &nodeId); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif diff --git a/services/tokensyncmanager/include/remote/rpc_channel.h b/services/tokensyncmanager/include/remote/rpc_channel.h new file mode 100644 index 0000000000000000000000000000000000000000..c8f61456a13d5b13ae543b8cdb152da294c43367 --- /dev/null +++ b/services/tokensyncmanager/include/remote/rpc_channel.h @@ -0,0 +1,80 @@ +/* + * 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 RPC_CHANNEL_H +#define RPC_CHANNEL_H + +namespace OHOS { +namespace Security { +namespace AccessToken { +/* + * Channel used for communicate with peer devices. + */ +class RpcChannel { +public: + /** + * @brief Build connection with peer device. + * + * @return Result code represent if build successfully. 0 indicates success, -1 indicates failure. + * @since 1.0 + * @version 1.0 + */ + virtual int BuildConnection() = 0; + + /** + * @brief Execute BaseRemoteCommand at peer device. + * + * @param commandName The name of Command. + * @param jsonPayload The json payload of command. + * @return Executed result response string. + * @since 1.0 + * @version 1.0 + */ + virtual std::string ExecuteCommand(const std::string &commandName, const std::string &jsonPayload) = 0; + + /** + * @brief Handle data received. This interface only use for soft bus channel. + * + * @param session Session with peer device. + * @param bytes Data sent from the peer device. + * @param length Data length sent from the peer device. + * @since 1.0 + * @version 1.0 + */ + virtual void HandleDataReceived(int session, const unsigned char *bytes, int length) + {} + + /** + * @brief Close rpc connection when no data is being transmitted. + * + * @since 1.0 + * @version 1.0 + */ + virtual void CloseConnection() + {} + + /** + * @brief Release resources when the device offline. + * + * @since 1.0 + * @version 1.0 + */ + virtual void Release() {}; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/tokensyncmanager/include/remote/soft_bus_channel.h b/services/tokensyncmanager/include/remote/soft_bus_channel.h new file mode 100644 index 0000000000000000000000000000000000000000..f7e52e79e7cd6bff52d24f1009e8fa6941dd02a5 --- /dev/null +++ b/services/tokensyncmanager/include/remote/soft_bus_channel.h @@ -0,0 +1,365 @@ +/* + * 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 SOFT_BUS_CHANNEL_H +#define SOFT_BUS_CHANNEL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "accesstoken_log.h" +#include "nlohmann/json.hpp" +#include "rpc_channel.h" +#include "session.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class SoftBusChannel final : public RpcChannel, public std::enable_shared_from_this { +public: + SoftBusChannel(const std::string &deviceId); + virtual ~SoftBusChannel(); + + /** + * @brief Build connection with peer device. + * + * @return Result code, 0 indicated build successfully, -1 indicates failure. + * @since 1.0 + * @version 1.0 + * @see Release + */ + int BuildConnection() override; + + /** + * @brief Execute BaseRemoteCommand at peer device. + * + * @param commandName The name of Command. + * @param jsonPayload The json payload of command. + * @return Executed result response string. + * @since 1.0 + * @version 1.0 + */ + std::string ExecuteCommand(const std::string &commandName, const std::string &jsonPayload) override; + + /** + * @brief Handle data received. This interface only use for soft bus channel. + * + * @param session Session with peer device. + * @param bytes Data sent from the peer device. + * @param length Data length sent from the peer device. + * @since 1.0 + * @version 1.0 + */ + void HandleDataReceived(int session, const unsigned char *bytes, int length) override; + + /** + * @brief Close rpc connection when no data is being transmitted. it will run in a delayed task. + * + * @since 1.0 + * @version 1.0 + */ + void CloseConnection() override; + + /** + * @brief Release resources when the device offline. + * + * @since 1.0 + * @version 1.0 + */ + void Release() override; + +private: + /** + * @brief compress json command to char array command. + * + * @param type request or response + * @param id unique message id + * @param commandName command name + * @param jsonPayload command notated by json string + * @param bytes transfer data array + * @param bytesLength transfer data length + * @return The execute result, SUCCESS: 0; FAILURE: -1. + * @see Compress + * @since 1.0 + * @version 1.0 + */ + int PrepareBytes(const std::string &type, const std::string &id, const std::string &commandName, + const std::string &jsonPayload, const unsigned char *bytes, int &bytesLength); + + /** + * @brief compress string to char array. + * + * @param json string to be compressed + * @param compressedBytes compressed data array + * @param compressedLength compressed data length + * @return The execute result, SUCCESS: 0; FAILURE: -1. + * @since 1.0 + * @version 1.0 + */ + int Compress(const std::string &json, const unsigned char *compressedBytes, int &compressedLength); + + /** + * @brief decompress char array to string. + * + * @param bytes compressed data array + * @param length compressed data length + * @return decompressed string + * @since 1.0 + * @version 1.0 + */ + std::string Decompress(const unsigned char *bytes, const int length); + + /** + * @brief transfer request data to soft bus. + * + * @param bytes data array to transfer + * @param bytesLength data length + * @return The execute result, SUCCESS: 0; FAILURE: -1. + * @since 1.0 + * @version 1.0 + */ + int SendRequestBytes(const unsigned char *bytes, const int bytesLength); + + /** + * @brief transfer response data to soft bus. + * + * @param session response session id + * @param bytes data array to transfer + * @param bytesLength data length + * @return The execute result, SUCCESS: 0; FAILURE: -1. + * @since 1.0 + * @version 1.0 + */ + int SendResponseBytes(int session, const unsigned char *bytes, const int bytesLength); + + /** + * @brief enforce session is available. if session is opened, reopen it. + * + * @return The execute result, SUCCESS: 0; FAILURE: -1. + * @since 1.0 + * @version 1.0 + */ + int CheckSessionMayReopenLocked(); + + /** + * @brief check session is available. + * + * @return The execute result, available: true, otherwise: false. + * @since 1.0 + * @version 1.0 + */ + bool IsSessionAvailable(); + + /** + * @brief cancel closing connection. + * + * @since 1.0 + * @version 1.0 + */ + void CancelCloseConnectionIfNeeded(); + + /** + * @brief request callback for HandleDataReceived + * + * @param id unique message id + * @param commandName command name + * @param jsonPayload command notated by json string + * @return decompressed string + * @see HandleDataReceived + * @since 1.0 + * @version 1.0 + */ + void HandleRequest( + int session, const std::string &id, const std::string &commandName, const std::string &jsonPayload); + + /** + * @brief response callback for HandleDataReceived + * + * @param id unique message id + * @param jsonPayload command notated by json string + * @return decompressed string + * @see HandleDataReceived + * @since 1.0 + * @version 1.0 + */ + void HandleResponse(const std::string &id, const std::string &jsonPayload); + + /** + * @brief temp function to generate uuid. + * + * @param buf uuid string + * @param bufSize uuid string size + * @since 1.0 + * @version 1.0 + */ + void random_uuid(char buf[37], int bufSize) + { + const int xbase = 15; + const int bbase = 255; + const int index6 = 6; + const int index8 = 8; + const int index3 = 3; + const int index5 = 5; + const int index7 = 7; + const int index9 = 9; + const int blen = 2; + const int uuidlen = 16; + const char *c = "89ab"; + char *p = buf; + int n; + + for (n = 0; n < uuidlen; ++n) { + int b = rand() % bbase; + switch (n) { + case index6: + if (sprintf_s(p, bufSize, "4%x", b % xbase) < 0) { + return; + } + break; + case index8: + if (sprintf_s(p, bufSize, "%c%x", c[rand() % strlen(c)], b % xbase) < 0) { + return; + } + break; + default: + if (sprintf_s(p, bufSize, "%02x", b) < 0) { + return; + } + break; + } + p += blen; + if (n == index3 || n == index5 || n == index7 || n == index9) { + *p++ = '-'; + break; + } + } + *p = 0; + // prevent array length warning + if (p - buf == bufSize) { + return; + } + n = 0; + } + + // bind device id for this channel + std::string deviceId_; + + // channel mutex + std::mutex mutex_; + + // connection closing state. true: in closing, false: otherwise + bool isDelayClosing_; + + // soft bus session mutex + std::mutex sessionMutex_; + + // soft bus session id, -1 for invalid session id. + int session_; + + // soft bus session busy flag, true: busy, false: otherwise + bool isSessionUsing_; + + // communication callbacks map. key: unique message id, value: response callback. + std::map> callbacks_; + + // callback function arguments: response string variable + std::string responseResult_; + // callback function execute variable + std::condition_variable loadedCond_; +}; + +class SoftBusMessage { +public: + SoftBusMessage( + const std::string &type, const std::string &id, const std::string &commandName, const std::string &jsonPayload) + : type_(type), id_(id), commandName_(commandName), jsonPayload_(jsonPayload) + {} + ~SoftBusMessage() = default; + + bool IsValid() const + { + if (this->type_.empty()) { + return false; + } + if (this->id_.empty()) { + return false; + } + if (this->commandName_.empty()) { + return false; + } + return !(this->jsonPayload_.empty()); + } + + /** + * Convert SoftBusMessage object to corresponding json string. + * + * @return Soft bus message json string. + */ + std::string ToJson() const + { + nlohmann::json json; + json["type"] = this->type_; + json["id"] = this->id_; + json["commandName"] = this->commandName_; + json["jsonPayload"] = this->jsonPayload_; + return json.dump(); + } + + const std::string &GetType() const + { + return type_; + } + const std::string &GetId() const + { + return id_; + } + const std::string &GetCommandName() const + { + return commandName_; + } + const std::string &GetJsonPayload() const + { + return jsonPayload_; + } + + static std::shared_ptr FromJson(const std::string &jsonString) + { + nlohmann::json json; + if (!json.accept(jsonString)) { + return nullptr; + } + json = json.parse(jsonString); + std::shared_ptr message = std::make_shared( + json.at("type"), json.at("id"), json.at("commandName"), json.at("jsonPayload")); + return message; + } + +private: + std::string type_; + std::string id_; + std::string commandName_; + std::string jsonPayload_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // SOFT_BUS_CHANNEL_H diff --git a/services/tokensyncmanager/include/remote/soft_bus_device_connection_listener.h b/services/tokensyncmanager/include/remote/soft_bus_device_connection_listener.h new file mode 100644 index 0000000000000000000000000000000000000000..c8722cbe1fa218b84bcb3573354f5971c03a1936 --- /dev/null +++ b/services/tokensyncmanager/include/remote/soft_bus_device_connection_listener.h @@ -0,0 +1,76 @@ +/* + * 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 SOFT_BUS_DEVICE_CONNECTION_LISTENER_H +#define SOFT_BUS_DEVICE_CONNECTION_LISTENER_H + +#include +#include +#include + +#include "accesstoken_log.h" +#include "device_manager_callback.h" +#include "dm_device_info.h" +#include "softbus_bus_center.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +using OHOS::DistributedHardware::DeviceStateCallback; +using OHOS::DistributedHardware::DmDeviceInfo; +using OHOS::DistributedHardware::DmInitCallback; + +class MyDmInitCallback final : public DmInitCallback { + void OnRemoteDied() override + {} +}; + +class SoftBusDeviceConnectionListener final : public DeviceStateCallback { +public: + SoftBusDeviceConnectionListener(); + ~SoftBusDeviceConnectionListener(); + + /** + * @brief node online callback + * + * @param deviceInfo node info + */ + void OnDeviceOnline(const DmDeviceInfo &deviceInfo) override; + + /** + * @brief node offline callback + * + * @param deviceInfo node info + */ + void OnDeviceOffline(const DmDeviceInfo &deviceInfo) override; + + /** + * @brief node ready callback + * + * @param deviceInfo node info + */ + void OnDeviceReady(const DmDeviceInfo &deviceInfo) override; + + /** + * @brief node changed callback + * + * @param deviceInfo node info + */ + void OnDeviceChanged(const DmDeviceInfo &deviceInfo) override; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif diff --git a/services/tokensyncmanager/include/remote/soft_bus_manager.h b/services/tokensyncmanager/include/remote/soft_bus_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..0cbfd84eacdada87ed2137f1190069ce6ca3a2e8 --- /dev/null +++ b/services/tokensyncmanager/include/remote/soft_bus_manager.h @@ -0,0 +1,136 @@ +/* + * 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 SOFT_BUS_MANAGER_H +#define SOFT_BUS_MANAGER_H + +#include +#include +#include +#include +#include + +#include "accesstoken_log.h" +#include "device_manager.h" +#include "remote_command_executor.h" +#include "session.h" +#include "soft_bus_device_connection_listener.h" +#include "soft_bus_session_listener.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class SoftBusManager final { +public: + virtual ~SoftBusManager(); + + /** + * @brief Get instance of SoftBusManager + * + * @return SoftBusManager's instance. + * @since 1.0 + * @version 1.0 + */ + static SoftBusManager &GetInstance(); + + /** + * @brief Bind soft bus service. + * + * @since 1.0 + * @version 1.0 + */ + void Initialize(); + + /** + * @brief Unbind soft bus service when DPMS has been destroyed. + * + * @since 1.0 + * @version 1.0 + */ + void Destroy(); + + /** + * @brief Open session with the peer device sychronized. + * + * @param deviceUdid The udid of peer device. + * @return Session id if open successfully, otherwise return -1(Constant::FAILURE). + * @since 1.0 + * @version 1.0 + */ + int OpenSession(const std::string &deviceUdid); + + /** + * @brief Close session with the peer device. + * + * @param session The session id need to close. + * @return 0 if close successfully, otherwise return -1(Constant::FAILURE). + * @since 1.0 + * @version 1.0 + */ + int CloseSession(int sessionId); + + /** + * @brief Get UUID(networkId) by deviceNodeId. + * + * @param deviceNodeId The valid networkId or deviceId(UDID) or deviceUuid. + * @return uuid if deviceManager is ready, empty string otherwise. + * @since 1.0 + * @version 1.0 + */ + std::string GetUniversallyUniqueIdByNodeId(const std::string &deviceNodeId); + + /** + * @brief Get deviceId(UDID) by deviceNodeId. + * + * @param deviceNodeId The valid networkId or deviceId(UDID) or deviceUuid. + * @return udid if deviceManager work correctly, empty string otherwise. + * @since 1.0 + * @version 1.0 + */ + std::string GetUniqueDisabilityIdByNodeId(const std::string &deviceNodeId); + +public: + static const std::string SESSION_NAME; + +private: + SoftBusManager(); + + /** + * @brief Fulfill local device info + * + * @return 0 if operate successfully, otherwise return -1(Constant::FAILURE). + * @since 1.0 + * @version 1.0 + */ + int FulfillLocalDeviceInfo(); + std::string GetUuidByNodeId(const std::string &nodeId) const; + std::string GetUdidByNodeId(const std::string &nodeId) const; + + const static std::string ACCESS_TOKEN_PACKAGE_NAME; + + // soft bus session server opened flag + bool isSoftBusServiceBindSuccess_; + std::atomic_bool inited_; + + // init mutex + std::mutex mutex_; + + // fulfill thread mutex + std::mutex fulfillMutex_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // SOFT_BUS_MANAGER_H diff --git a/services/tokensyncmanager/include/remote/soft_bus_session_listener.h b/services/tokensyncmanager/include/remote/soft_bus_session_listener.h new file mode 100644 index 0000000000000000000000000000000000000000..1b0a1f69a929dc7bf402ef14f89a7a39fa6e8dd7 --- /dev/null +++ b/services/tokensyncmanager/include/remote/soft_bus_session_listener.h @@ -0,0 +1,114 @@ +/* + * 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 SOFT_BUS_SESSION_LISTENER_H +#define SOFT_BUS_SESSION_LISTENER_H + +#include +#include +#include + +#include "accesstoken_log.h" +#include "session.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class SoftBusSessionListener final { +public: + /** + * @brief Called when a session is opened. + * + * This function can be used to verify the session or initialize resources related to the session. + * + * @param sessionId Indicates the session ID. + * @param result 0 if the session is opened successfully, returns an error code otherwise. + * @return Returns 0 if the session connection is accepted; returns a non-zero value + * otherwise (you do not need to call {@link CloseSession} to close the session). + * @since 1.0 + * @version 1.0 + */ + static int32_t OnSessionOpened(int32_t sessionId, int32_t result); + + /** + * @brief Called when a session is closed. + * + * This function can be used to release resources related to the session. + * You do not need to call {@link CloseSession}. + * + * @param sessionId Indicates the session ID. + * @since 1.0 + * @version 1.0 + */ + static void OnSessionClosed(int32_t sessionId); + + /** + * @brief Called when data is received. + * + * This function is used to notify that data is received. + * + * @param sessionId Indicates the session ID. + * @param data Indicates the pointer to the data received. + * @param dataLen Indicates the length of the data received. + * @since 1.0 + * @version 1.0 + */ + static void OnMessageReceived(int32_t sessionId, const void *data, uint32_t dataLen); + + /** + * @brief Called when message is received. + * + * This function is used to notify that message is received. + * + * @param sessionId Indicates the session ID. + * @param data Indicates the pointer to the message data received. + * @param dataLen Indicates the length of the message received. + * @since 1.0 + * @version 1.0 + */ + static void OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen); + + /** + * @brief get the state of a session. + * + * This function is used to verify that session is opened. + * + * @param sessionId Indicates the session ID. + * @return -2: sessionId not used, -1: session is in opening, greater than 0: session is opened. + * @since 1.0 + * @version 1.0 + */ + static int64_t GetSessionState(int32_t sessionId); + + static void DeleteSessionIdFromMap(int32_t sessionId); + + static const int64_t STATE_OPENING = -1; + static const int64_t STATE_NOTFOUND = -2; + +private: + /** + * key: sessionId, value: status. + * status: -1: opening, >0: opened timestamp + */ + static std::map g_SessionOpenedMap_; + /** + * mutex for map + */ + static std::mutex g_SessionMutex_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // SOFT_BUS_SESSION_LISTENER_H diff --git a/services/tokensyncmanager/include/service/token_sync_event_handler.h b/services/tokensyncmanager/include/service/token_sync_event_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..f9a0caf36e0ef615a1307cece641460628443b35 --- /dev/null +++ b/services/tokensyncmanager/include/service/token_sync_event_handler.h @@ -0,0 +1,43 @@ +/* + * 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 TOKEN_SYNC_EVENT_HANDLER_H +#define TOKEN_SYNC_EVENT_HANDLER_H + +#include + +#include "event_handler.h" +#include "event_runner.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class TokenSyncEventHandler : public AppExecFwk::EventHandler { +public: + TokenSyncEventHandler(const std::shared_ptr &runner); + virtual ~TokenSyncEventHandler(); + + bool ProxyPostTask(const Callback &callback, int64_t delayTime); + + bool ProxyPostTask(const Callback &callback, const std::string &name = std::string(), int64_t delayTime = 0); + + void ProxyRemoveTask(const std::string &name); + +private: +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // TOKEN_SYNC_EVENT_HANDLER_H diff --git a/services/tokensyncmanager/include/service/token_sync_manager_service.h b/services/tokensyncmanager/include/service/token_sync_manager_service.h new file mode 100644 index 0000000000000000000000000000000000000000..6209899741352ea7a7de82393b619c05163bfaad --- /dev/null +++ b/services/tokensyncmanager/include/service/token_sync_manager_service.h @@ -0,0 +1,60 @@ +/* + * 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 TOKEN_SYNC_MANAGER_SERVICE_H +#define TOKEN_SYNC_MANAGER_SERVICE_H + +#include + +#include "event_handler.h" +#include "hap_token_info_for_sync_parcel.h" +#include "iremote_object.h" +#include "nocopyable.h" +#include "singleton.h" +#include "system_ability.h" +#include "token_sync_event_handler.h" +#include "token_sync_manager_stub.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; +class TokenSyncManagerService final : public SystemAbility, public TokenSyncManagerStub { + DECLARE_DELAYED_SINGLETON(TokenSyncManagerService); + DECLEAR_SYSTEM_ABILITY(TokenSyncManagerService); + +public: + void OnStart() override; + void OnStop() override; + + std::shared_ptr GetSendEventHandler(); + std::shared_ptr GetRecvEventHandler(); + int GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID) override; + int DeleteRemoteHapTokenInfo(AccessTokenID tokenID) override; + int UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo) override; + +private: + bool Initialize(); + + std::shared_ptr sendRunner_; + std::shared_ptr recvRunner_; + std::shared_ptr sendHandler_; + std::shared_ptr recvHandler_; + ServiceRunningState state_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // TOKEN_SYNC_MANAGER_SERVICE_H diff --git a/services/accesstoken/main/cpp/include/accesstoken_manager_stub.h b/services/tokensyncmanager/include/service/token_sync_manager_stub.h similarity index 60% rename from services/accesstoken/main/cpp/include/accesstoken_manager_stub.h rename to services/tokensyncmanager/include/service/token_sync_manager_stub.h index ffcbf3d577336d85fc8ad417bfcd7701674ef10e..f16fd8dd75dab71eb574b3e398940996b1364e5f 100644 --- a/services/accesstoken/main/cpp/include/accesstoken_manager_stub.h +++ b/services/tokensyncmanager/include/service/token_sync_manager_stub.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,29 +13,29 @@ * limitations under the License. */ -#ifndef ACCESSTOKEN_MANAGER_STUB_H -#define ACCESSTOKEN_MANAGER_STUB_H - -#include "i_accesstoken_manager.h" +#ifndef TOKEN_SYNC_MANAGER_STUB_H +#define TOKEN_SYNC_MANAGER_STUB_H +#include "i_token_sync_manager.h" #include "iremote_stub.h" #include "nocopyable.h" namespace OHOS { namespace Security { namespace AccessToken { -class AccessTokenManagerStub : public IRemoteStub { +class TokenSyncManagerStub : public IRemoteStub { public: - AccessTokenManagerStub() = default; - virtual ~AccessTokenManagerStub() = default; + TokenSyncManagerStub() = default; + virtual ~TokenSyncManagerStub() = default; int OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& options) override; private: - void VerifyAccessTokenInner(MessageParcel& data, MessageParcel& reply); - + void GetRemoteHapTokenInfoInner(MessageParcel& data, MessageParcel& reply); + void DeleteRemoteHapTokenInfoInner(MessageParcel& data, MessageParcel& reply); + void UpdateRemoteHapTokenInfoInner(MessageParcel& data, MessageParcel& reply); }; } // namespace AccessToken } // namespace Security } // namespace OHOS -#endif // ACCESSTOKEN_MANAGER_STUB_H +#endif // TOKEN_SYNC_MANAGER_STUB_H diff --git a/services/tokensyncmanager/sa_profile/3504.xml b/services/tokensyncmanager/sa_profile/3504.xml new file mode 100644 index 0000000000000000000000000000000000000000..c8ea08efdfb27e807a890937bfe6083dc9c2664f --- /dev/null +++ b/services/tokensyncmanager/sa_profile/3504.xml @@ -0,0 +1,24 @@ + + + + token_sync_service + + 3504 + libtoken_sync_manager_service.z.so + true + true + 1 + + diff --git a/services/tokensyncmanager/sa_profile/BUILD.gn b/services/tokensyncmanager/sa_profile/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..4491128f6337573adf2d7c2af314ac1343fdb2c6 --- /dev/null +++ b/services/tokensyncmanager/sa_profile/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (c) 2021 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. + +import("//build/ohos/sa_profile/sa_profile.gni") + +ohos_sa_profile("tokensync_sa_profile_standard") { + part_name = "access_token" + + sources = [ "3504.xml" ] +} diff --git a/services/tokensyncmanager/src/command/base_remote_command.cpp b/services/tokensyncmanager/src/command/base_remote_command.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6aaf74b60d977d3f2c3a845b5e1a2e7d9dab096 --- /dev/null +++ b/services/tokensyncmanager/src/command/base_remote_command.cpp @@ -0,0 +1,259 @@ +/* + * 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 "base_remote_command.h" + +#include "accesstoken_log.h" +#include "data_validator.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "BaseRemoteCommand"}; +} + +void BaseRemoteCommand::FromRemoteProtocolJson(const nlohmann::json& jsonObject) +{ + if (jsonObject.find("commandName") != jsonObject.end() && jsonObject.at("commandName").is_string()) { + remoteProtocol_.commandName = jsonObject.at("commandName").get(); + } + if (jsonObject.find("uniqueId") != jsonObject.end() && jsonObject.at("uniqueId").is_string()) { + remoteProtocol_.uniqueId = jsonObject.at("uniqueId").get(); + } + if (jsonObject.find("requestVersion") != jsonObject.end() && jsonObject.at("requestVersion").is_number()) { + remoteProtocol_.requestVersion = jsonObject.at("requestVersion").get(); + } + if (jsonObject.find("srcDeviceId") != jsonObject.end() && jsonObject.at("srcDeviceId").is_string()) { + remoteProtocol_.srcDeviceId = jsonObject.at("srcDeviceId").get(); + } + if (jsonObject.find("srcDeviceLevel") != jsonObject.end() && jsonObject.at("srcDeviceLevel").is_string()) { + remoteProtocol_.srcDeviceLevel = jsonObject.at("srcDeviceLevel").get(); + } + if (jsonObject.find("dstDeviceId") != jsonObject.end() && jsonObject.at("dstDeviceId").is_string()) { + remoteProtocol_.dstDeviceId = jsonObject.at("dstDeviceId").get(); + } + if (jsonObject.find("dstDeviceLevel") != jsonObject.end() && jsonObject.at("dstDeviceLevel").is_string()) { + remoteProtocol_.dstDeviceLevel = jsonObject.at("dstDeviceLevel").get(); + } + if (jsonObject.find("statusCode") != jsonObject.end() && jsonObject.at("statusCode").is_number()) { + remoteProtocol_.statusCode = jsonObject.at("statusCode").get(); + } + if (jsonObject.find("message") != jsonObject.end() && jsonObject.at("message").is_string()) { + remoteProtocol_.message = jsonObject.at("message").get(); + } + if (jsonObject.find("responseVersion") != jsonObject.end() && jsonObject.at("responseVersion").is_number()) { + remoteProtocol_.responseVersion = jsonObject.at("responseVersion").get(); + } + if (jsonObject.find("responseDeviceId") != jsonObject.end() && jsonObject.at("responseDeviceId").is_string()) { + remoteProtocol_.responseDeviceId = jsonObject.at("responseDeviceId").get(); + } +} + +nlohmann::json BaseRemoteCommand::ToRemoteProtocolJson() +{ + nlohmann::json j; + j["commandName"] = remoteProtocol_.commandName; + j["uniqueId"] = remoteProtocol_.uniqueId; + j["requestVersion"] = remoteProtocol_.requestVersion; + j["srcDeviceId"] = remoteProtocol_.srcDeviceId; + j["srcDeviceLevel"] = remoteProtocol_.srcDeviceLevel; + j["dstDeviceId"] = remoteProtocol_.dstDeviceId; + j["dstDeviceLevel"] = remoteProtocol_.dstDeviceLevel; + j["statusCode"] = remoteProtocol_.statusCode; + j["message"] = remoteProtocol_.message; + j["responseVersion"] = remoteProtocol_.responseVersion; + j["responseDeviceId"] = remoteProtocol_.responseDeviceId; + return j; +} + +nlohmann::json BaseRemoteCommand::ToNativeTokenInfoJson(const NativeTokenInfo& tokenInfo) +{ + nlohmann::json DcapsJson = nlohmann::json(tokenInfo.dcap); + nlohmann::json nativeTokenJson = nlohmann::json { + {"processName", tokenInfo.processName}, + {"apl", tokenInfo.apl}, + {"version", tokenInfo.ver}, + {"tokenId", tokenInfo.tokenID}, + {"tokenAttr", tokenInfo.tokenAttr}, + {"dcaps", DcapsJson}, + }; + return nativeTokenJson; +} + +void BaseRemoteCommand::ToPermStateJson(nlohmann::json& permStateJson, const PermissionStateFull& state) +{ + if (state.resDeviceID.size() != state.grantStatus.size() || state.resDeviceID.size() != state.grantFlags.size()) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "state grant config size is invalid"); + return; + } + nlohmann::json permConfigsJson; + int size = state.resDeviceID.size(); + for (int i = 0; i < size; i++) { + nlohmann::json permConfigJson = nlohmann::json { + {"resDeviceID", state.resDeviceID[i]}, + {"grantStatus", state.grantStatus[i]}, + {"grantFlags", state.grantFlags[i]}, + }; + permConfigsJson.emplace_back(permConfigJson); + } + + permStateJson["permissionName"] = state.permissionName; + permStateJson["isGeneral"] = state.isGeneral; + permStateJson["grantConfig"] = permConfigsJson; +} + +nlohmann::json BaseRemoteCommand::ToHapTokenInfosJson(const HapTokenInfoForSync& tokenInfo) +{ + nlohmann::json permStatesJson; + for (auto& permState : tokenInfo.permStateList) { + nlohmann::json permStateJson; + ToPermStateJson(permStateJson, permState); + permStatesJson.emplace_back(permStateJson); + } + + nlohmann::json hapTokensJson = nlohmann::json { + {"version", tokenInfo.baseInfo.ver}, + {"tokenID", tokenInfo.baseInfo.tokenID}, + {"tokenAttr", tokenInfo.baseInfo.tokenAttr}, + {"userID", tokenInfo.baseInfo.userID}, + {"bundleName", tokenInfo.baseInfo.bundleName}, + {"instIndex", tokenInfo.baseInfo.instIndex}, + {"appID", tokenInfo.baseInfo.appID}, + {"deviceID", tokenInfo.baseInfo.deviceID}, + {"apl", tokenInfo.baseInfo.apl}, + {"permState", permStatesJson} + }; + return hapTokensJson; +} + +void BaseRemoteCommand::FromHapTokenBasicInfoJson(const nlohmann::json& hapTokenJson, + HapTokenInfo& hapTokenBasicInfo) +{ + if (hapTokenJson.find("version") != hapTokenJson.end() && hapTokenJson.at("version").is_number()) { + hapTokenJson.at("version").get_to(hapTokenBasicInfo.ver); } + if (hapTokenJson.find("tokenID") != hapTokenJson.end() && hapTokenJson.at("tokenID").is_number()) { + hapTokenJson.at("tokenID").get_to(hapTokenBasicInfo.tokenID); + } + if (hapTokenJson.find("tokenAttr") != hapTokenJson.end() && hapTokenJson.at("tokenAttr").is_number()) { + hapTokenJson.at("tokenAttr").get_to(hapTokenBasicInfo.tokenAttr); + } + if (hapTokenJson.find("userID") != hapTokenJson.end() && hapTokenJson.at("userID").is_number()) { + hapTokenJson.at("userID").get_to(hapTokenBasicInfo.userID); + } + if (hapTokenJson.find("bundleName") != hapTokenJson.end() && hapTokenJson.at("bundleName").is_string()) { + hapTokenJson.at("bundleName").get_to(hapTokenBasicInfo.bundleName); + } + if (hapTokenJson.find("instIndex") != hapTokenJson.end() && hapTokenJson.at("instIndex").is_number()) { + hapTokenJson.at("instIndex").get_to(hapTokenBasicInfo.instIndex); + } + if (hapTokenJson.find("appID") != hapTokenJson.end() && hapTokenJson.at("appID").is_string()) { + hapTokenJson.at("appID").get_to(hapTokenBasicInfo.appID); + } + if (hapTokenJson.find("deviceID") != hapTokenJson.end() && hapTokenJson.at("deviceID").is_string()) { + hapTokenJson.at("deviceID").get_to(hapTokenBasicInfo.deviceID); + } + if (hapTokenJson.find("apl") != hapTokenJson.end() && hapTokenJson.at("apl").is_number()) { + int apl = hapTokenJson.at("apl").get(); + if (DataValidator::IsAplNumValid(apl)) { + hapTokenBasicInfo.apl = (ATokenAplEnum)apl; + } + } +} + +void BaseRemoteCommand::FromPermStateListJson(const nlohmann::json& hapTokenJson, + std::vector& permStateList) +{ + if (hapTokenJson.find("permState") != hapTokenJson.end() + && hapTokenJson.at("permState").is_array() + && hapTokenJson.at("permState").size() > 0) { + nlohmann::json permissionsJson = hapTokenJson.at("permState").get(); + for (auto permissionJson : permissionsJson) { + PermissionStateFull permission; + if (permissionJson.find("permissionName") == permissionJson.end() + || !permissionJson.at("permissionName").is_string() + || permissionJson.find("isGeneral") == permissionJson.end() + || !permissionJson.at("isGeneral").is_boolean() + || permissionJson.find("grantConfig") == permissionJson.end() + || !permissionJson.at("grantConfig").is_array() + || permissionJson.at("grantConfig").size() == 0) { + continue; + } + permissionJson.at("permissionName").get_to(permission.permissionName); + permissionJson.at("isGeneral").get_to(permission.isGeneral); + nlohmann::json grantConfigsJson = permissionJson.at("grantConfig").get(); + for (auto grantConfigJson :grantConfigsJson) { + if (grantConfigJson.find("resDeviceID") == grantConfigJson.end() + || !grantConfigJson.at("resDeviceID").is_string() + || grantConfigJson.find("grantStatus") == grantConfigJson.end() + || !grantConfigJson.at("grantStatus").is_number() + || grantConfigJson.find("grantFlags") == grantConfigJson.end() + || !grantConfigJson.at("grantFlags").is_number()) { + continue; + } + std::string deviceID; + grantConfigJson.at("resDeviceID").get_to(deviceID); + int grantStatus; + grantConfigJson.at("grantStatus").get_to(grantStatus); + int grantFlags; + grantConfigJson.at("grantFlags").get_to(grantFlags); + permission.resDeviceID.emplace_back(deviceID); + permission.grantStatus.emplace_back(grantStatus); + permission.grantFlags.emplace_back(grantFlags); + } + permStateList.emplace_back(permission); + } + } +} + +void BaseRemoteCommand::FromHapTokenInfoJson(const nlohmann::json& hapTokenJson, + HapTokenInfoForSync& hapTokenInfo) +{ + FromHapTokenBasicInfoJson(hapTokenJson, hapTokenInfo.baseInfo); + if (hapTokenInfo.baseInfo.tokenID == 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "Hap token basic info is error."); + return; + } + FromPermStateListJson(hapTokenJson, hapTokenInfo.permStateList); +} + +void BaseRemoteCommand::FromNativeTokenInfoJson(const nlohmann::json& nativeTokenJson, + NativeTokenInfo& nativeTokenInfo) +{ + if (nativeTokenJson.find("processName") != nativeTokenJson.end() && nativeTokenJson.at("processName").is_string()) { + nativeTokenInfo.processName = nativeTokenJson.at("processName").get(); + } + if (nativeTokenJson.find("apl") != nativeTokenJson.end() && nativeTokenJson.at("apl").is_number()) { + int apl = nativeTokenJson.at("apl").get(); + if (DataValidator::IsAplNumValid(apl)) { + nativeTokenInfo.apl = (ATokenAplEnum)apl; + } + } + if (nativeTokenJson.find("version") != nativeTokenJson.end() && nativeTokenJson.at("version").is_number()) { + nativeTokenInfo.ver = nativeTokenJson.at("version").get(); + } + if (nativeTokenJson.find("tokenId") != nativeTokenJson.end() && nativeTokenJson.at("tokenId").is_number()) { + nativeTokenInfo.tokenID = nativeTokenJson.at("tokenId").get(); + } + if (nativeTokenJson.find("tokenAttr") != nativeTokenJson.end() && nativeTokenJson.at("tokenAttr").is_number()) { + nativeTokenInfo.tokenAttr = nativeTokenJson.at("tokenAttr").get(); + } + if (nativeTokenJson.find("dcaps") != nativeTokenJson.end() && nativeTokenJson.at("dcaps").is_array() + && nativeTokenJson.at("dcaps").size() > 0 && (nativeTokenJson.at("dcaps"))[0].is_string()) { + nativeTokenInfo.dcap = nativeTokenJson.at("dcaps").get>(); + } +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/command/delete_remote_token_command.cpp b/services/tokensyncmanager/src/command/delete_remote_token_command.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65a3c04afd4ad6181d0f4ce23a278943cc72cf7c --- /dev/null +++ b/services/tokensyncmanager/src/command/delete_remote_token_command.cpp @@ -0,0 +1,104 @@ +/* + * 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 "delete_remote_token_command.h" + +#include "accesstoken_kit.h" +#include "accesstoken_log.h" +#include "base_remote_command.h" +#include "device_info.h" +#include "device_info_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "DeleteRemoteTokenCommand"}; +} + +DeleteRemoteTokenCommand::DeleteRemoteTokenCommand( + const std::string &srcDeviceId, const std::string &dstDeviceId, AccessTokenID deleteID) + : deleteTokenId_(deleteID) +{ + remoteProtocol_.commandName = COMMAND_NAME; + remoteProtocol_.uniqueId = COMMAND_NAME; + remoteProtocol_.srcDeviceId = srcDeviceId; + remoteProtocol_.dstDeviceId = dstDeviceId; + remoteProtocol_.responseVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; + remoteProtocol_.requestVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; +} + +DeleteRemoteTokenCommand::DeleteRemoteTokenCommand(const std::string& json) +{ + nlohmann::json jsonObject = nlohmann::json::parse(json, nullptr, false); + BaseRemoteCommand::FromRemoteProtocolJson(jsonObject); + + if (jsonObject.find("tokenId") != jsonObject.end() && jsonObject.at("tokenId").is_number()) { + deleteTokenId_ = jsonObject.at("tokenId").get(); + } +} + +std::string DeleteRemoteTokenCommand::ToJsonPayload() +{ + nlohmann::json j = BaseRemoteCommand::ToRemoteProtocolJson(); + j["tokenId"] = deleteTokenId_; + return j.dump(); +} + +void DeleteRemoteTokenCommand::Prepare() +{ + remoteProtocol_.statusCode = Constant::SUCCESS; + remoteProtocol_.message = Constant::COMMAND_RESULT_SUCCESS; + ACCESSTOKEN_LOG_DEBUG(LABEL, "end as: DeleteRemoteTokenCommand"); +} + +void DeleteRemoteTokenCommand::Execute() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "execute: start as: DeleteRemoteTokenCommand"); + remoteProtocol_.responseDeviceId = Constant::GetLocalDeviceId(); + remoteProtocol_.responseVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; + + DeviceInfo devInfo; + bool result = DeviceInfoManager::GetInstance().GetDeviceInfo(remoteProtocol_.srcDeviceId, + DeviceIdType::UNKNOWN, devInfo); + if (!result) { + ACCESSTOKEN_LOG_INFO(LABEL, "error: get remote networkId failed"); + remoteProtocol_.statusCode = Constant::FAILURE_BUT_CAN_RETRY; + return; + } + + std::string networkID = devInfo.deviceId.networkId; + int ret = AccessTokenKit::DeleteRemoteToken(networkID, deleteTokenId_); + if (ret != RET_SUCCESS) { + remoteProtocol_.statusCode = Constant::FAILURE_BUT_CAN_RETRY; + remoteProtocol_.message = Constant::COMMAND_RESULT_FAILED; + } else { + remoteProtocol_.statusCode = Constant::SUCCESS; + remoteProtocol_.message = Constant::COMMAND_RESULT_SUCCESS; + } + + ACCESSTOKEN_LOG_INFO(LABEL, "execute: end as: DeleteRemoteTokenCommand"); +} + +void DeleteRemoteTokenCommand::Finish() +{ + remoteProtocol_.statusCode = Constant::SUCCESS; + ACCESSTOKEN_LOG_INFO(LABEL, "Finish: end as: DeleteUidPermissionCommand"); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + diff --git a/services/tokensyncmanager/src/command/sync_remote_hap_token_command.cpp b/services/tokensyncmanager/src/command/sync_remote_hap_token_command.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fde09adb0439356654d768eb55a8021fb736045e --- /dev/null +++ b/services/tokensyncmanager/src/command/sync_remote_hap_token_command.cpp @@ -0,0 +1,109 @@ +/* + * 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 "sync_remote_hap_token_command.h" + +#include "accesstoken_kit.h" +#include "accesstoken_log.h" +#include "base_remote_command.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "SyncRemoteHapTokenCommand"}; +} + +SyncRemoteHapTokenCommand::SyncRemoteHapTokenCommand( + const std::string &srcDeviceId, const std::string &dstDeviceId, AccessTokenID id) : requestTokenId_(id) +{ + remoteProtocol_.commandName = COMMAND_NAME; + remoteProtocol_.uniqueId = COMMAND_NAME; + remoteProtocol_.srcDeviceId = srcDeviceId; + remoteProtocol_.dstDeviceId = dstDeviceId; + remoteProtocol_.responseVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; + remoteProtocol_.requestVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; + hapTokenInfo_.baseInfo.apl = APL_NORMAL; + hapTokenInfo_.baseInfo.appID = ""; + hapTokenInfo_.baseInfo.bundleName = ""; + hapTokenInfo_.baseInfo.deviceID = ""; + hapTokenInfo_.baseInfo.instIndex = 0; + hapTokenInfo_.baseInfo.tokenAttr = 0; + hapTokenInfo_.baseInfo.tokenID = 0; + hapTokenInfo_.baseInfo.userID = 0; + hapTokenInfo_.baseInfo.ver = DEFAULT_TOKEN_VERSION; +} + +SyncRemoteHapTokenCommand::SyncRemoteHapTokenCommand(const std::string &json) +{ + nlohmann::json jsonObject = nlohmann::json::parse(json, nullptr, false); + BaseRemoteCommand::FromRemoteProtocolJson(jsonObject); + if (jsonObject.find("requestTokenId") != jsonObject.end() && jsonObject.at("requestTokenId").is_number()) { + jsonObject.at("requestTokenId").get_to(requestTokenId_); + } + + if (jsonObject.find("HapTokenInfo") != jsonObject.end()) { + nlohmann::json hapTokenJson = jsonObject.at("HapTokenInfo").get(); + BaseRemoteCommand::FromHapTokenInfoJson(hapTokenJson, hapTokenInfo_); + } +} + +std::string SyncRemoteHapTokenCommand::ToJsonPayload() +{ + nlohmann::json j = BaseRemoteCommand::ToRemoteProtocolJson(); + j["requestTokenId"] = requestTokenId_; + j["HapTokenInfo"] = BaseRemoteCommand::ToHapTokenInfosJson(hapTokenInfo_); + return j.dump(); +} + +void SyncRemoteHapTokenCommand::Prepare() +{ + remoteProtocol_.statusCode = Constant::SUCCESS; + remoteProtocol_.message = Constant::COMMAND_RESULT_SUCCESS; + ACCESSTOKEN_LOG_DEBUG(LABEL, " end as: SyncRemoteHapTokenCommand"); +} + +void SyncRemoteHapTokenCommand::Execute() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "execute: start as: SyncRemoteHapTokenCommand"); + remoteProtocol_.responseDeviceId = Constant::GetLocalDeviceId(); + remoteProtocol_.responseVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; + + int ret = AccessTokenKit::GetHapTokenInfoFromRemote(requestTokenId_, hapTokenInfo_); + if (ret != RET_SUCCESS) { + remoteProtocol_.statusCode = Constant::FAILURE_BUT_CAN_RETRY; + remoteProtocol_.message = Constant::COMMAND_RESULT_FAILED; + } else { + remoteProtocol_.statusCode = Constant::SUCCESS; + remoteProtocol_.message = Constant::COMMAND_RESULT_SUCCESS; + } + + ACCESSTOKEN_LOG_INFO(LABEL, "execute: end as: SyncRemoteHapTokenCommand"); +} + +void SyncRemoteHapTokenCommand::Finish() +{ + if (remoteProtocol_.statusCode != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Finish: end as: SyncRemoteHapTokenCommand get remote result error."); + return; + } + AccessTokenKit::SetRemoteHapTokenInfo(remoteProtocol_.dstDeviceId, hapTokenInfo_); + remoteProtocol_.statusCode = Constant::SUCCESS; + ACCESSTOKEN_LOG_INFO(LABEL, "Finish: end as: SyncRemoteHapTokenCommand"); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/command/sync_remote_native_token_command.cpp b/services/tokensyncmanager/src/command/sync_remote_native_token_command.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f45e64230800e879ac1288c7f9a7c4399936b13 --- /dev/null +++ b/services/tokensyncmanager/src/command/sync_remote_native_token_command.cpp @@ -0,0 +1,120 @@ +/* + * 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 "sync_remote_native_token_command.h" + +#include "accesstoken_kit.h" +#include "accesstoken_log.h" +#include "base_remote_command.h" +#include "device_info_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "SyncRemoteNativeTokenCommand"}; +} + +SyncRemoteNativeTokenCommand::SyncRemoteNativeTokenCommand( + const std::string &srcDeviceId, const std::string &dstDeviceId) +{ + remoteProtocol_.commandName = COMMAND_NAME; + remoteProtocol_.uniqueId = COMMAND_NAME; + remoteProtocol_.srcDeviceId = srcDeviceId; + remoteProtocol_.dstDeviceId = dstDeviceId; + remoteProtocol_.responseVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; + remoteProtocol_.requestVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; +} + +SyncRemoteNativeTokenCommand::SyncRemoteNativeTokenCommand(const std::string &json) +{ + nlohmann::json jsonObject = nlohmann::json::parse(json, nullptr, false); + BaseRemoteCommand::FromRemoteProtocolJson(jsonObject); + + if (jsonObject.find("NativeTokenInfos") != jsonObject.end() && jsonObject.at("NativeTokenInfos").is_array()) { + nlohmann::json nativeTokenListJson = jsonObject.at("NativeTokenInfos"); + for (auto& tokenJson : nativeTokenListJson) { + NativeTokenInfo token; + BaseRemoteCommand::FromNativeTokenInfoJson(tokenJson, token); + nativeTokenInfo_.emplace_back(token); + } + } +} + +std::string SyncRemoteNativeTokenCommand::ToJsonPayload() +{ + nlohmann::json j = BaseRemoteCommand::ToRemoteProtocolJson(); + nlohmann::json nativeTokensJson; + for (auto token : nativeTokenInfo_) { + nlohmann::json tokenJson = BaseRemoteCommand::ToNativeTokenInfoJson(token); + nativeTokensJson.emplace_back(tokenJson); + } + j["NativeTokenInfos"] = nativeTokensJson; + return j.dump(); +} + +void SyncRemoteNativeTokenCommand::Prepare() +{ + remoteProtocol_.statusCode = Constant::SUCCESS; + remoteProtocol_.message = Constant::COMMAND_RESULT_SUCCESS; + ACCESSTOKEN_LOG_DEBUG(LABEL, "end as: SyncRemoteNativeTokenCommand"); +} + +void SyncRemoteNativeTokenCommand::Execute() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "execute: start as: SyncRemoteNativeTokenCommand"); + remoteProtocol_.responseDeviceId = Constant::GetLocalDeviceId(); + remoteProtocol_.responseVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; + + int ret = AccessTokenKit::GetAllNativeTokenInfo(nativeTokenInfo_); + if (ret != RET_SUCCESS) { + remoteProtocol_.statusCode = Constant::FAILURE_BUT_CAN_RETRY; + remoteProtocol_.message = Constant::COMMAND_RESULT_FAILED; + } else { + remoteProtocol_.statusCode = Constant::SUCCESS; + remoteProtocol_.message = Constant::COMMAND_RESULT_SUCCESS; + } + + ACCESSTOKEN_LOG_INFO(LABEL, "execute: end as: SyncRemoteNativeTokenCommand"); +} + +void SyncRemoteNativeTokenCommand::Finish() +{ + if (remoteProtocol_.statusCode != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Finish: end as: SyncRemoteHapTokenCommand get remote result error."); + return; + } + + DeviceInfo devInfo; + bool result = DeviceInfoManager::GetInstance().GetDeviceInfo(remoteProtocol_.dstDeviceId, + DeviceIdType::UNKNOWN, devInfo); + if (!result) { + ACCESSTOKEN_LOG_ERROR(LABEL, "SyncRemoteNativeTokenCommand: get remote networkId failed"); + remoteProtocol_.statusCode = Constant::FAILURE_BUT_CAN_RETRY; + return; + } + int ret = AccessTokenKit::SetRemoteNativeTokenInfo(devInfo.deviceId.networkId, nativeTokenInfo_); + if (ret == RET_SUCCESS) { + remoteProtocol_.statusCode = Constant::SUCCESS; + } else { + remoteProtocol_.statusCode = Constant::FAILURE_BUT_CAN_RETRY; + } + ACCESSTOKEN_LOG_INFO(LABEL, "Finish: end as: SyncRemoteNativeTokenCommand ret %{public}d", ret); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + diff --git a/services/tokensyncmanager/src/command/update_remote_hap_token_command.cpp b/services/tokensyncmanager/src/command/update_remote_hap_token_command.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6910c984cf10dad81e8f46dc6ea7dc3e1a8c61d5 --- /dev/null +++ b/services/tokensyncmanager/src/command/update_remote_hap_token_command.cpp @@ -0,0 +1,105 @@ +/* + * 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 "update_remote_hap_token_command.h" + +#include "accesstoken_kit.h" +#include "accesstoken_log.h" +#include "base_remote_command.h" +#include "device_info_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "UpdateRemoteHapTokenCommand"}; +} + +UpdateRemoteHapTokenCommand::UpdateRemoteHapTokenCommand( + const std::string &srcDeviceId, const std::string &dstDeviceId, const HapTokenInfoForSync& tokenInfo) + : updateTokenInfo_(tokenInfo) +{ + remoteProtocol_.commandName = COMMAND_NAME; + remoteProtocol_.uniqueId = COMMAND_NAME; + remoteProtocol_.srcDeviceId = srcDeviceId; + remoteProtocol_.dstDeviceId = dstDeviceId; + remoteProtocol_.responseVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; + remoteProtocol_.requestVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; +} + +UpdateRemoteHapTokenCommand::UpdateRemoteHapTokenCommand(const std::string &json) +{ + nlohmann::json jsonObject = nlohmann::json::parse(json, nullptr, false); + BaseRemoteCommand::FromRemoteProtocolJson(jsonObject); + + if (jsonObject.find("HapTokenInfos") != jsonObject.end()) { + nlohmann::json hapTokenJson = jsonObject.at("HapTokenInfos").get(); + BaseRemoteCommand::FromHapTokenInfoJson(hapTokenJson, updateTokenInfo_); + } +} + +std::string UpdateRemoteHapTokenCommand::ToJsonPayload() +{ + nlohmann::json j = BaseRemoteCommand::ToRemoteProtocolJson(); + j["HapTokenInfos"] = BaseRemoteCommand::ToHapTokenInfosJson(updateTokenInfo_); + return j.dump(); +} + +void UpdateRemoteHapTokenCommand::Prepare() +{ + remoteProtocol_.statusCode = Constant::SUCCESS; + remoteProtocol_.message = Constant::COMMAND_RESULT_SUCCESS; + ACCESSTOKEN_LOG_DEBUG(LABEL, "end as: UpdateRemoteHapTokenCommand"); +} + +void UpdateRemoteHapTokenCommand::Execute() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "execute: start as: UpdateRemoteHapTokenCommand"); + + remoteProtocol_.responseDeviceId = Constant::GetLocalDeviceId(); + remoteProtocol_.responseVersion = Constant::DISTRIBUTED_ACCESS_TOKEN_SERVICE_VERSION; + + DeviceInfo devInfo; + bool result = DeviceInfoManager::GetInstance().GetDeviceInfo(remoteProtocol_.srcDeviceId, + DeviceIdType::UNKNOWN, devInfo); + if (!result) { + ACCESSTOKEN_LOG_INFO(LABEL, "UpdateRemoteHapTokenCommand: get remote networkId failed"); + remoteProtocol_.statusCode = Constant::FAILURE_BUT_CAN_RETRY; + return; + } + + std::string networkID = devInfo.deviceId.networkId; + int ret = AccessTokenKit::SetRemoteHapTokenInfo(networkID, updateTokenInfo_); + if (ret != RET_SUCCESS) { + remoteProtocol_.statusCode = Constant::FAILURE_BUT_CAN_RETRY; + remoteProtocol_.message = Constant::COMMAND_RESULT_FAILED; + } else { + remoteProtocol_.statusCode = Constant::SUCCESS; + remoteProtocol_.message = Constant::COMMAND_RESULT_SUCCESS; + } + + ACCESSTOKEN_LOG_INFO(LABEL, "execute: end as: UpdateRemoteHapTokenCommand"); +} + +void UpdateRemoteHapTokenCommand::Finish() +{ + remoteProtocol_.statusCode = Constant::SUCCESS; + ACCESSTOKEN_LOG_INFO(LABEL, "Finish: end as: DeleteUidPermissionCommand"); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + diff --git a/services/tokensyncmanager/src/common/constant.cpp b/services/tokensyncmanager/src/common/constant.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dfa24e22ffc07e62457e6ddbd0b1da43d1829ead --- /dev/null +++ b/services/tokensyncmanager/src/common/constant.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 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 "constant.h" +#include "parameter.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +const std::string Constant::COMMAND_RESULT_SUCCESS = "success"; +const std::string Constant::COMMAND_RESULT_FAILED = "execute command failed"; + +std::string Constant::EncryptDevId(std::string deviceId) +{ + std::string result = deviceId; + if (deviceId.size() >= ENCRYPTLEN) { + result.replace(ENCRYPTBEGIN, ENCRYPTEND, "****"); + } else { + result.replace(ENCRYPTBEGIN, result.size() - 1, "****"); + } + return result; +} + +std::string Constant::GetLocalDeviceId() +{ + char deviceIdCharArray[Constant::DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(deviceIdCharArray, Constant::DEVICE_UUID_LENGTH); + return deviceIdCharArray; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/device/device_info_manager.cpp b/services/tokensyncmanager/src/device/device_info_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1066ad4554100f546cbe80b841a013662cfabb97 --- /dev/null +++ b/services/tokensyncmanager/src/device/device_info_manager.cpp @@ -0,0 +1,167 @@ +/* + * 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 "device_info_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "DeviceInfoManager"}; +} +DeviceInfoManager &DeviceInfoManager::GetInstance() +{ + static DeviceInfoManager instance; + return instance; +} + +bool DeviceInfoManager::GetDeviceInfo( + const std::string &nodeId, DeviceIdType deviceIdType, DeviceInfo &deviceInfo) const +{ + return DeviceInfoRepository::GetInstance().FindDeviceInfo(nodeId, deviceIdType, deviceInfo); +} + +bool DeviceInfoManager::ExistDeviceInfo(const std::string &nodeId, DeviceIdType deviceIdType) const +{ + DeviceInfo deviceInfo; + return DeviceInfoRepository::GetInstance().FindDeviceInfo(nodeId, deviceIdType, deviceInfo); +} + +void DeviceInfoManager::AddDeviceInfo(const std::string &networkId, const std::string &universallyUniqueId, + const std::string &uniqueDisabilityId, const std::string &deviceName, const std::string &deviceType) +{ + if (!DataValidator::IsDeviceIdValid(networkId) || + !DataValidator::IsDeviceIdValid(universallyUniqueId) || + !DataValidator::IsDeviceIdValid(uniqueDisabilityId) || deviceName.empty() || deviceType.empty()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "addDeviceInfo: input param is invalid"); + } + DeviceInfoRepository::GetInstance().SaveDeviceInfo( + networkId, universallyUniqueId, uniqueDisabilityId, deviceName, deviceType); +} + +void DeviceInfoManager::RemoveAllRemoteDeviceInfo() +{ + char deviceIdCharArray[Constant::DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(deviceIdCharArray, Constant::DEVICE_UUID_LENGTH); + DeviceInfo localDeviceInfoOpt; + if (DeviceInfoRepository::GetInstance().FindDeviceInfo( + deviceIdCharArray, DeviceIdType::UNIQUE_DISABILITY_ID, localDeviceInfoOpt)) { + DeviceInfoRepository::GetInstance().DeleteAllDeviceInfoExceptOne(localDeviceInfoOpt); + } +} + +void DeviceInfoManager::RemoveRemoteDeviceInfo(const std::string &nodeId, DeviceIdType deviceIdType) +{ + if (!DataValidator::IsDeviceIdValid(nodeId)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "removeDeviceInfoByNetworkId: nodeId is invalid"); + } else { + DeviceInfo deviceInfo; + char deviceIdCharArray[Constant::DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(deviceIdCharArray, Constant::DEVICE_UUID_LENGTH); + if (DeviceInfoRepository::GetInstance().FindDeviceInfo(nodeId, deviceIdType, deviceInfo)) { + if (deviceInfo.deviceId.uniqueDisabilityId != deviceIdCharArray) { + DeviceInfoRepository::GetInstance().DeleteDeviceInfo(nodeId, deviceIdType); + } + } + } +} + +std::string DeviceInfoManager::ConvertToUniversallyUniqueIdOrFetch(const std::string &nodeId) const +{ + std::string result; + if (!DataValidator::IsDeviceIdValid(nodeId)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "ConvertToUniversallyUniqueIdOrFetch: nodeId is invalid."); + return result; + } + DeviceInfo deviceInfo; + if (DeviceInfoRepository::GetInstance().FindDeviceInfo(nodeId, DeviceIdType::UNKNOWN, deviceInfo)) { + std::string universallyUniqueId = deviceInfo.deviceId.universallyUniqueId; + if (universallyUniqueId.empty()) { + std::string udid = SoftBusManager::GetInstance().GetUniversallyUniqueIdByNodeId(nodeId); + if (!udid.empty()) { + result = udid; + } + } else { + result = universallyUniqueId; + } + } + return result; +} + +std::string DeviceInfoManager::ConvertToUniqueDisabilityIdOrFetch(const std::string &nodeId) const +{ + std::string result; + if (!DataValidator::IsDeviceIdValid(nodeId)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "ConvertToUniqueDisabilityIdOrFetch: nodeId is invalid."); + return result; + } + DeviceInfo deviceInfo; + if (DeviceInfoRepository::GetInstance().FindDeviceInfo(nodeId, DeviceIdType::UNKNOWN, deviceInfo)) { + std::string uniqueDisabilityId = deviceInfo.deviceId.uniqueDisabilityId; + if (uniqueDisabilityId.empty()) { + std::string udid = SoftBusManager::GetInstance().GetUniqueDisabilityIdByNodeId(nodeId); + if (!udid.empty()) { + result = udid; + } else { + ACCESSTOKEN_LOG_DEBUG(LABEL, + "FindDeviceInfo succeed, udid and local udid is empty, nodeId(%{public}s)", + Constant::EncryptDevId(nodeId).c_str()); + } + } else { + ACCESSTOKEN_LOG_DEBUG(LABEL, + "FindDeviceInfo succeed, udid is empty, nodeId(%{public}s) ", + Constant::EncryptDevId(nodeId).c_str()); + result = uniqueDisabilityId; + } + } else { + ACCESSTOKEN_LOG_DEBUG( + LABEL, "FindDeviceInfo failed, nodeId(%{public}s)", Constant::EncryptDevId(nodeId).c_str()); + auto list = DeviceInfoRepository::GetInstance().ListDeviceInfo(); + auto iter = list.begin(); + for (; iter != list.end(); iter++) { + DeviceInfo info = (*iter); + ACCESSTOKEN_LOG_DEBUG( + LABEL, ">>> DeviceInfoRepository device name: %{public}s", info.deviceName.c_str()); + ACCESSTOKEN_LOG_DEBUG( + LABEL, ">>> DeviceInfoRepository device type: %{public}s", info.deviceType.c_str()); + ACCESSTOKEN_LOG_DEBUG(LABEL, + ">>> DeviceInfoRepository device network id: %{public}s", + Constant::EncryptDevId(info.deviceId.networkId).c_str()); + ACCESSTOKEN_LOG_DEBUG(LABEL, + ">>> DeviceInfoRepository device udid: %{public}s", + Constant::EncryptDevId(info.deviceId.uniqueDisabilityId).c_str()); + ACCESSTOKEN_LOG_DEBUG(LABEL, + ">>> DeviceInfoRepository device uuid: %{public}s", + Constant::EncryptDevId(info.deviceId.universallyUniqueId).c_str()); + } + } + return result; +} + +bool DeviceInfoManager::IsDeviceUniversallyUniqueId(const std::string &nodeId) const +{ + if (!DataValidator::IsDeviceIdValid(nodeId)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "IsDeviceUniversallyUniqueId: nodeId is invalid"); + return false; + } + DeviceInfo deviceInfo; + if (DeviceInfoRepository::GetInstance().FindDeviceInfo(nodeId, DeviceIdType::UNIVERSALLY_UNIQUE_ID, deviceInfo)) { + return deviceInfo.deviceId.universallyUniqueId == nodeId; + } + return false; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/tokensyncmanager/src/device/device_info_repository.cpp b/services/tokensyncmanager/src/device/device_info_repository.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6bbff99c1cc81bdda4823b3e3831c85b8a9587bf --- /dev/null +++ b/services/tokensyncmanager/src/device/device_info_repository.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2021 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 "device_info_repository.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +DeviceInfoRepository &DeviceInfoRepository::GetInstance() +{ + static DeviceInfoRepository instance; + return instance; +} + +std::vector DeviceInfoRepository::ListDeviceInfo() +{ + std::lock_guard guard(stackLock_); + std::vector deviceInfo; + + std::map::iterator it; + std::map::iterator itEnd; + it = deviceInfoMap_.begin(); + itEnd = deviceInfoMap_.end(); + while (it != itEnd) { + deviceInfo.push_back(it->second); + it++; + } + return deviceInfo; +} + +bool DeviceInfoRepository::FindDeviceInfo(const std::string &nodeId, DeviceIdType type, DeviceInfo &deviceInfo) +{ + std::lock_guard guard(stackLock_); + DeviceId deviceId; + if (FindDeviceIdByNodeIdLocked(nodeId, type, deviceId)) { + return FindDeviceInfoByDeviceIdLocked(deviceId, deviceInfo); + } + return false; +} + +bool DeviceInfoRepository::FindDeviceIdByNodeIdLocked( + const std::string &nodeId, const DeviceIdType type, DeviceId &deviceId) const +{ + if (type == DeviceIdType::NETWORK_ID) { + return FindDeviceIdByNetworkIdLocked(nodeId, deviceId); + } else if (type == DeviceIdType::UNIVERSALLY_UNIQUE_ID) { + return FindDeviceIdByUniversallyUniqueIdLocked(nodeId, deviceId); + } else if (type == DeviceIdType::UNIQUE_DISABILITY_ID) { + return FindDeviceIdByUniqueDisabilityIdLocked(nodeId, deviceId); + } else if (type == DeviceIdType::UNKNOWN) { + if (FindDeviceIdByNetworkIdLocked(nodeId, deviceId)) { + return true; + } else if (FindDeviceIdByUniversallyUniqueIdLocked(nodeId, deviceId)) { + return true; + } else if (FindDeviceIdByUniqueDisabilityIdLocked(nodeId, deviceId)) { + return true; + } + return false; + } else { + return false; + } +} + +bool DeviceInfoRepository::FindDeviceInfoByDeviceIdLocked(const DeviceId deviceId, DeviceInfo &deviceInfo) const +{ + std::string deviceInfoKey = deviceId.networkId + deviceId.universallyUniqueId + deviceId.uniqueDisabilityId; + if (deviceInfoMap_.count(deviceInfoKey) > 0) { + deviceInfo = deviceInfoMap_.at(deviceInfoKey); + return true; + } + return false; +} + +bool DeviceInfoRepository::FindDeviceIdByNetworkIdLocked(const std::string &networkId, DeviceId &deviceId) const +{ + if (deviceIdMapByNetworkId_.count(networkId) > 0) { + deviceId = deviceIdMapByNetworkId_.at(networkId); + return true; + } + return false; +} + +bool DeviceInfoRepository::FindDeviceIdByUniversallyUniqueIdLocked( + const std::string &universallyUniqueId, DeviceId &deviceId) const +{ + if (deviceIdMapByUniversallyUniqueId_.count(universallyUniqueId) > 0) { + deviceId = deviceIdMapByUniversallyUniqueId_.at(universallyUniqueId); + return true; + } + return false; +} + +bool DeviceInfoRepository::FindDeviceIdByUniqueDisabilityIdLocked( + const std::string &uniqueDisabilityId, DeviceId &deviceId) const +{ + if (deviceIdMapByUniqueDisabilityId_.count(uniqueDisabilityId) > 0) { + deviceId = deviceIdMapByUniqueDisabilityId_.at(uniqueDisabilityId); + return true; + } + return false; +} + +void DeviceInfoRepository::DeleteAllDeviceInfoExceptOne(const DeviceInfo deviceInfo) +{ + std::lock_guard guard(stackLock_); + deviceIdMapByNetworkId_.clear(); + deviceIdMapByUniversallyUniqueId_.clear(); + deviceIdMapByUniqueDisabilityId_.clear(); + deviceInfoMap_.clear(); + SaveDeviceInfo(deviceInfo); +} + +void DeviceInfoRepository::SaveDeviceInfo(const DeviceInfo deviceInfo) +{ + SaveDeviceInfo(deviceInfo.deviceId, deviceInfo.deviceName, deviceInfo.deviceType); +} + +void DeviceInfoRepository::SaveDeviceInfo( + const DeviceId deviceId, const std::string &deviceName, const std::string &deviceType) +{ + SaveDeviceInfo( + deviceId.networkId, deviceId.universallyUniqueId, deviceId.uniqueDisabilityId, deviceName, deviceType); +} + +void DeviceInfoRepository::SaveDeviceInfo(const std::string &networkId, const std::string &universallyUniqueId, + const std::string &uniqueDisabilityId, const std::string &deviceName, const std::string &deviceType) +{ + std::lock_guard guard(stackLock_); + + DeleteDeviceInfo(networkId, DeviceIdType::NETWORK_ID); + DeleteDeviceInfo(universallyUniqueId, DeviceIdType::UNIVERSALLY_UNIQUE_ID); + DeleteDeviceInfo(uniqueDisabilityId, DeviceIdType::UNIQUE_DISABILITY_ID); + + DeviceId deviceId; + deviceId.networkId = networkId; + deviceId.universallyUniqueId = universallyUniqueId; + deviceId.uniqueDisabilityId = uniqueDisabilityId; + + DeviceInfo deviceInfo; + deviceInfo.deviceId = deviceId; + deviceInfo.deviceName = deviceName; + deviceInfo.deviceType = deviceType; + + const std::string deviceInfoKey = networkId + universallyUniqueId + uniqueDisabilityId; + deviceIdMapByNetworkId_.insert(std::pair(networkId, deviceId)); + deviceIdMapByUniversallyUniqueId_.insert(std::pair(universallyUniqueId, deviceId)); + deviceIdMapByUniqueDisabilityId_.insert(std::pair(uniqueDisabilityId, deviceId)); + deviceInfoMap_.insert(std::pair(deviceInfoKey, deviceInfo)); +} + +void DeviceInfoRepository::DeleteDeviceInfo(const std::string &nodeId, const DeviceIdType type) +{ + std::lock_guard guard(stackLock_); + DeviceId deviceId; + if (FindDeviceIdByNodeIdLocked(nodeId, type, deviceId)) { + DeleteDeviceInfoByDeviceIdLocked(deviceId); + } +} + +void DeviceInfoRepository::DeleteDeviceInfoByDeviceIdLocked(const DeviceId deviceId) +{ + deviceIdMapByNetworkId_.erase(deviceId.networkId); + deviceIdMapByUniversallyUniqueId_.erase(deviceId.universallyUniqueId); + deviceIdMapByUniqueDisabilityId_.erase(deviceId.uniqueDisabilityId); + const std::string deviceInfoKey = deviceId.networkId + deviceId.universallyUniqueId + deviceId.uniqueDisabilityId; + deviceInfoMap_.erase(deviceInfoKey); +} + +void DeviceInfoRepository::Clear() +{ + std::lock_guard guard(stackLock_); + deviceIdMapByNetworkId_.clear(); + deviceIdMapByUniversallyUniqueId_.clear(); + deviceIdMapByUniqueDisabilityId_.clear(); + deviceInfoMap_.clear(); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/tokensyncmanager/src/remote/remote_command_executor.cpp b/services/tokensyncmanager/src/remote/remote_command_executor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e6200b465978b987b4c44256480629e9afdd18f8 --- /dev/null +++ b/services/tokensyncmanager/src/remote/remote_command_executor.cpp @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2021 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 "remote_command_executor.h" + +#include "device_info_manager.h" +#include "parameter.h" +#include "singleton.h" +#include "soft_bus_channel.h" +#include "token_sync_event_handler.h" +#include "token_sync_manager_service.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "RemoteCommandExecutor"}; +static const std::string TASK_NAME = "RemoteCommandExecutor::ProcessBufferedCommandsWithThread"; +} // namespace +RemoteCommandExecutor::RemoteCommandExecutor(const std::string &targetNodeId) + : targetNodeId_(targetNodeId), ptrChannel_(nullptr), mutex_(), commands_(), running_(false) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "RemoteCommandExecutor()"); +} + +RemoteCommandExecutor::~RemoteCommandExecutor() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "~RemoteCommandExecutor() begin"); + running_ = false; + ACCESSTOKEN_LOG_DEBUG(LABEL, "~RemoteCommandExecutor() end"); +} + +const std::shared_ptr RemoteCommandExecutor::CreateChannel(const std::string &targetNodeId) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "CreateChannel: targetNodeId=%{public}s", targetNodeId.c_str()); + // only consider SoftBusChannel + std::shared_ptr ptrChannel = std::make_shared(targetNodeId); + if (ptrChannel == nullptr) { + ACCESSTOKEN_LOG_INFO( + LABEL, "CreateChannel: create channel failed, targetNodeId=%{public}s", targetNodeId.c_str()); + } + return ptrChannel; +} + +/* + * called by RemoteCommandExecutor, RemoteCommandManager + */ +int RemoteCommandExecutor::ProcessOneCommand(const std::shared_ptr &ptrCommand) +{ + if (ptrCommand == nullptr) { + ACCESSTOKEN_LOG_WARN( + LABEL, "targetNodeId %{public}s, attempt to process on null command.", targetNodeId_.c_str()); + return Constant::SUCCESS; + } + const std::string uniqueId = ptrCommand->remoteProtocol_.uniqueId; + ACCESSTOKEN_LOG_INFO(LABEL, + "targetNodeId %{public}s, process one command start, uniqueId: %{public}s", + targetNodeId_.c_str(), + uniqueId.c_str()); + + ptrCommand->Prepare(); + int status = ptrCommand->remoteProtocol_.statusCode; + if (status != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "targetNodeId %{public}s, process one command error, uniqueId: %{public}s, message: " + "prepare failure code %{public}d", + targetNodeId_.c_str(), + uniqueId.c_str(), + status); + return status; + } + + char localUdid[Constant::DEVICE_UUID_LENGTH] = {0}; + ::GetDevUdid(localUdid, Constant::DEVICE_UUID_LENGTH); + if (targetNodeId_ == localUdid) { + return ExecuteRemoteCommand(ptrCommand, false); + } + + // otherwise a remote device + CreateChannelIfNeeded(); + if (ptrChannel_ == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "targetNodeId %{public}s, channel is null.", targetNodeId_.c_str()); + return Constant::FAILURE; + } + if (ptrChannel_->BuildConnection() != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "targetNodeId %{public}s, channel is not ready.", targetNodeId_.c_str()); + return Constant::FAILURE; + } + + return ExecuteRemoteCommand(ptrCommand, true); +} + +/* + * called by RemoteCommandManager + */ +int RemoteCommandExecutor::AddCommand(const std::shared_ptr &ptrCommand) +{ + if (ptrCommand == nullptr) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "targetNodeId %{public}s, attempt to add an empty command.", + targetNodeId_.c_str()); + return Constant::INVALID_COMMAND; + } + + const std::string uniqueId = ptrCommand->remoteProtocol_.uniqueId; + ACCESSTOKEN_LOG_DEBUG( + LABEL, "targetNodeId %{public}s, add uniqueId %{public}s", targetNodeId_.c_str(), uniqueId.c_str()); + + std::unique_lock lock(mutex_); + + // make sure do not have the same command in the command buffer + for (auto bufferedCommand : commands_) { + if (bufferedCommand->remoteProtocol_.uniqueId == uniqueId) { + ACCESSTOKEN_LOG_WARN(LABEL, + "targetNodeId %{public}s, add uniqueId %{public}s, already exist in the buffer, skip", + targetNodeId_.c_str(), + uniqueId.c_str()); + return Constant::SUCCESS; + } + } + + commands_.push_back(ptrCommand); + return Constant::SUCCESS; +} + +/* + * called by RemoteCommandExecutor.ProcessCommandThread, RemoteCommandManager + */ +int RemoteCommandExecutor::ProcessBufferedCommands(bool standalone) +{ + ACCESSTOKEN_LOG_INFO( + LABEL, "begin, targetNodeId: %{public}s, standalone: %{public}d", targetNodeId_.c_str(), standalone); + + std::unique_lock lock(mutex_); + + if (commands_.empty()) { + ACCESSTOKEN_LOG_WARN(LABEL, "no command, targetNodeId %{public}s", targetNodeId_.c_str()); + running_ = false; + return Constant::SUCCESS; + } + + running_ = true; + while (true) { + // interrupt + if (running_ == false) { + ACCESSTOKEN_LOG_INFO( + LABEL, "end with running flag == false, targetNodeId: %{public}s", targetNodeId_.c_str()); + return Constant::FAILURE; + } + // end + if (commands_.empty()) { + running_ = false; + ACCESSTOKEN_LOG_INFO(LABEL, "end, no command left, targetNodeId: %{public}s", targetNodeId_.c_str()); + return Constant::SUCCESS; + } + + // consume queue to execute + const std::shared_ptr bufferedCommand = commands_.front(); + int status = ProcessOneCommand(bufferedCommand); + if (status == Constant::SUCCESS) { + commands_.pop_front(); + continue; + } else if (status == Constant::FAILURE_BUT_CAN_RETRY) { + ACCESSTOKEN_LOG_WARN(LABEL, + "execute failed and wait to retry, targetNodeId: %{public}s, message: %{public}s, and will retry ", + targetNodeId_.c_str(), + bufferedCommand->remoteProtocol_.message.c_str()); + + // now, the retry at once will have no effective because the network problem + // so if the before the step, one command is added, and run this function + // it should also not need to restart to process the commands buffer at once. + running_ = false; + return Constant::FAILURE; + } else { + // this command failed, move on to execute next command + commands_.pop_front(); + ACCESSTOKEN_LOG_ERROR(LABEL, + "execute failed, targetNodeId: %{public}s, commandName: %{public}s, message: %{public}s", + targetNodeId_.c_str(), + bufferedCommand->remoteProtocol_.commandName.c_str(), + bufferedCommand->remoteProtocol_.message.c_str()); + } + } +} + +/* + * called by RemoteCommandManager + */ +void RemoteCommandExecutor::ProcessBufferedCommandsWithThread() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "begin, targetNodeId: %{public}s", targetNodeId_.c_str()); + + std::unique_lock lock(mutex_); + + if (commands_.empty()) { + ACCESSTOKEN_LOG_INFO(LABEL, "No buffered commands. targetNodeId: %{public}s", targetNodeId_.c_str()); + return; + } + if (running_) { + // task is running, do not need to start one more + ACCESSTOKEN_LOG_WARN(LABEL, "task busy. targetNodeId: %{public}s", targetNodeId_.c_str()); + return; + } + + running_ = true; + const std::function runner = std::bind(&RemoteCommandExecutor::ProcessBufferedCommands, this, true); + + std::shared_ptr handler = + DelayedSingleton::GetInstance()->GetSendEventHandler(); + if (handler == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler"); + return; + } + bool result = handler->ProxyPostTask(runner, TASK_NAME); + if (result == false) { + ACCESSTOKEN_LOG_ERROR(LABEL, "post task failed, targetNodeId: %{public}s", targetNodeId_.c_str()); + } + ACCESSTOKEN_LOG_INFO(LABEL, + "post task succeed, targetNodeId: %{public}s, taskName: %{public}s", + targetNodeId_.c_str(), + TASK_NAME.c_str()); +} + +int RemoteCommandExecutor::ExecuteRemoteCommand( + const std::shared_ptr &ptrCommand, const bool isRemote) +{ + std::string uniqueId = ptrCommand->remoteProtocol_.uniqueId; + ACCESSTOKEN_LOG_INFO(LABEL, + "targetNodeId %{public}s, uniqueId %{public}s, remote %{public}d: start to execute", + targetNodeId_.c_str(), + uniqueId.c_str(), + isRemote); + + ptrCommand->remoteProtocol_.statusCode = Constant::STATUS_CODE_BEFORE_RPC; + + if (!isRemote) { + // Local device, play myself. + ptrCommand->Execute(); + int code = ClientProcessResult(ptrCommand); + ACCESSTOKEN_LOG_DEBUG(LABEL, + "command finished with status: %{public}d, message: %{public}s", + ptrCommand->remoteProtocol_.statusCode, + ptrCommand->remoteProtocol_.message.c_str()); + return code; + } + + std::string responseString = + ptrChannel_->ExecuteCommand(ptrCommand->remoteProtocol_.commandName, ptrCommand->ToJsonPayload()); + ACCESSTOKEN_LOG_INFO(LABEL, "command executed uniqueId %{public}s", uniqueId.c_str()); + if (responseString.empty()) { + ACCESSTOKEN_LOG_WARN(LABEL, + "targetNodeId %{public}s, uniqueId %{public}s, execute remote command error, response is empty.", + targetNodeId_.c_str(), + uniqueId.c_str()); + return Constant::FAILURE; + } + + std::shared_ptr ptrResponseCommand = + RemoteCommandFactory::GetInstance().NewRemoteCommandFromJson( + ptrCommand->remoteProtocol_.commandName, responseString); + if (ptrResponseCommand == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "targetNodeId %{public}s, get null response command!", targetNodeId_.c_str()); + return Constant::FAILURE; + } + int32_t result = ClientProcessResult(ptrResponseCommand); + if (commands_.empty()) { + ptrChannel_->CloseConnection(); + } + ACCESSTOKEN_LOG_DEBUG(LABEL, + "command finished with status: %{public}d, message: %{public}s", + ptrResponseCommand->remoteProtocol_.statusCode, + ptrResponseCommand->remoteProtocol_.message.c_str()); + return result; +} + +void RemoteCommandExecutor::CreateChannelIfNeeded() +{ + std::unique_lock lock(mutex_); + if (ptrChannel_ != nullptr) { + ACCESSTOKEN_LOG_INFO(LABEL, "targetNodeId %{public}s, channel is exist.", targetNodeId_.c_str()); + return; + } + + ptrChannel_ = CreateChannel(targetNodeId_); +} + +int RemoteCommandExecutor::ClientProcessResult(const std::shared_ptr &ptrCommand) +{ + std::string uniqueId = ptrCommand->remoteProtocol_.uniqueId; + if (ptrCommand->remoteProtocol_.statusCode == Constant::STATUS_CODE_BEFORE_RPC) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "targetNodeId %{public}s, uniqueId %{public}s, status code after RPC is same as before, the remote side " + "may not " + "support this command", + targetNodeId_.c_str(), + uniqueId.c_str()); + return Constant::FAILURE; + } + + ptrCommand->Finish(); + int status = ptrCommand->remoteProtocol_.statusCode; + if (status != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "targetNodeId %{public}s, uniqueId %{public}s, execute failed, message: %{public}s", + targetNodeId_.c_str(), + uniqueId.c_str(), + ptrCommand->remoteProtocol_.message.c_str()); + } else { + ACCESSTOKEN_LOG_INFO(LABEL, + "targetNodeId %{public}s, uniqueId %{public}s, execute succeed.", + targetNodeId_.c_str(), + uniqueId.c_str()); + } + return status; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/remote/remote_command_factory.cpp b/services/tokensyncmanager/src/remote/remote_command_factory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..266ef585b83ca5e7df284e6c0cfaf11c2ec47c34 --- /dev/null +++ b/services/tokensyncmanager/src/remote/remote_command_factory.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 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 "remote_command_factory.h" + +#include "nlohmann/json.hpp" + +namespace OHOS { +namespace Security { +namespace AccessToken { +RemoteCommandFactory &RemoteCommandFactory::GetInstance() +{ + static RemoteCommandFactory instance; + return instance; +} + +std::shared_ptr RemoteCommandFactory::NewSyncRemoteHapTokenCommand( + const std::string &srcDeviceId, const std::string &dstDeviceId, AccessTokenID tokenID) +{ + return std::make_shared(srcDeviceId, dstDeviceId, tokenID); +} + +std::shared_ptr RemoteCommandFactory::NewDeleteRemoteTokenCommand( + const std::string &srcDeviceId, const std::string &dstDeviceId, AccessTokenID tokenID) +{ + return std::make_shared(srcDeviceId, dstDeviceId, tokenID); +} + +std::shared_ptr RemoteCommandFactory::NewUpdateRemoteHapTokenCommand( + const std::string &srcDeviceId, const std::string &dstDeviceId, const HapTokenInfoForSync& tokenInfo) +{ + return std::make_shared(srcDeviceId, dstDeviceId, tokenInfo); +} + +std::shared_ptr RemoteCommandFactory::NewSyncRemoteNativeTokenCommand( + const std::string &srcDeviceId, const std::string &dstDeviceId) +{ + return std::make_shared(srcDeviceId, dstDeviceId); +} + +std::shared_ptr RemoteCommandFactory::NewRemoteCommandFromJson( + const std::string &commandName, const std::string &commandJsonString) +{ + const std::string SYNC_HAP_COMMAND_NAME = "SyncRemoteHapTokenCommand"; + const std::string DELETE_TOKEN_COMMAND_NAME = "DeleteRemoteTokenCommand"; + const std::string UPDATE_HAP_COMMAND_NAME = "UpdateRemoteHapTokenCommand"; + const std::string SYNC_NATIVE_COMMAND_NAME = "SyncRemoteNativeTokenCommand"; + + if (commandName == SYNC_HAP_COMMAND_NAME) { + return std::make_shared(commandJsonString); + } else if (commandName == DELETE_TOKEN_COMMAND_NAME) { + return std::make_shared(commandJsonString); + } else if (commandName == UPDATE_HAP_COMMAND_NAME) { + return std::make_shared(commandJsonString); + } else if (commandName == SYNC_NATIVE_COMMAND_NAME) { + return std::make_shared(commandJsonString); + } else { + return nullptr; + } +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/remote/remote_command_manager.cpp b/services/tokensyncmanager/src/remote/remote_command_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d98fada78af5659d94592bfb878c85fc6115075 --- /dev/null +++ b/services/tokensyncmanager/src/remote/remote_command_manager.cpp @@ -0,0 +1,292 @@ +/* + * 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 "remote_command_manager.h" +#include "device_info_manager.h" +#include "sync_remote_native_token_command.h" +#include "remote_command_factory.h" +#include "token_sync_event_handler.h" +#include "token_sync_manager_service.h" +#include "accesstoken_kit.h" + +#include + + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "RemoteCommandManager"}; +} +RemoteCommandManager::RemoteCommandManager() : executors_(), mutex_() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "RemoteCommandManager()"); +} + +RemoteCommandManager::~RemoteCommandManager() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "~RemoteCommandManager()"); +} + +RemoteCommandManager &RemoteCommandManager::GetInstance() +{ + static RemoteCommandManager instance; + return instance; +} + +void RemoteCommandManager::Init() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "Init()"); +} + +int RemoteCommandManager::AddCommand(const std::string &udid, const std::shared_ptr &command) +{ + if (udid.empty() || command == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "invalid udid: %{public}s, or null command", udid.c_str()); + return Constant::FAILURE; + } + std::string uniqueId = command->remoteProtocol_.uniqueId; + ACCESSTOKEN_LOG_INFO(LABEL, "udid: %{public}s, add uniqueId: %{public}s", udid.c_str(), uniqueId.c_str()); + + std::shared_ptr executor = GetOrCreateRemoteCommandExecutor(udid); + if (executor == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "cannot get or create remote command executor"); + return Constant::FAILURE; + } + + int result = executor->AddCommand(command); + ACCESSTOKEN_LOG_INFO(LABEL, "udid: %{public}s, add command result: %{public}d ", udid.c_str(), result); + return result; +} + +void RemoteCommandManager::RemoveCommand(const std::string &udid) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "remove command, udid: %{public}s", udid.c_str()); + executors_.erase(udid); +} + +int RemoteCommandManager::ExecuteCommand(const std::string &udid, const std::shared_ptr &command) +{ + if (udid.empty() || command == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "invalid udid: %{public}s, or null command", udid.c_str()); + return Constant::FAILURE; + } + std::string uniqueId = command->remoteProtocol_.uniqueId; + ACCESSTOKEN_LOG_INFO(LABEL, "start with udid: %{public}s , uniqueId: %{public}s ", udid.c_str(), uniqueId.c_str()); + + std::shared_ptr executor = GetOrCreateRemoteCommandExecutor(udid); + if (executor == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "cannot get or create remote command executor"); + return Constant::FAILURE; + } + + int result = executor->ProcessOneCommand(command); + ACCESSTOKEN_LOG_INFO(LABEL, "remoteCommandExecutor processOneCommand result:%{public}d ", result); + return result; +} + +int RemoteCommandManager::ProcessDeviceCommandImmediately(const std::string &udid) +{ + if (udid.empty()) { + ACCESSTOKEN_LOG_WARN(LABEL, "invalid udid: %{public}s", udid.c_str()); + return Constant::FAILURE; + } + ACCESSTOKEN_LOG_INFO(LABEL, "start with udid:%{public}s ", udid.c_str()); + auto executorIt = executors_.find(udid); + if (executorIt == executors_.end()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "no executor found, udid:%{public}s", udid.c_str()); + return Constant::FAILURE; + } + + auto executor = executorIt->second; + if (executor == nullptr) { + ACCESSTOKEN_LOG_INFO(LABEL, "RemoteCommandExecutor is null for udid %{public}s ", udid.c_str()); + return Constant::FAILURE; + } + + int result = executor->ProcessBufferedCommands(); + ACCESSTOKEN_LOG_INFO(LABEL, "processBufferedCommands result: %{public}d", result); + return result; +} + +int RemoteCommandManager::Loop() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "start"); + for (auto it = executors_.begin(); it != executors_.end(); it++) { + ACCESSTOKEN_LOG_INFO(LABEL, "udid:%{public}s", it->first.c_str()); + (*it).second->ProcessBufferedCommandsWithThread(); + } + return Constant::SUCCESS; +} + +/** + * caller: service connection listener + */ +void RemoteCommandManager::Clear() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "remove all remote command executors."); + + std::map> dummy; + executors_.swap(dummy); + executors_.clear(); +} + +/** + * caller: device listener + */ +int RemoteCommandManager::NotifyDeviceOnline(const std::string &nodeId) +{ + if (!DataValidator::IsDeviceIdValid(nodeId)) { + ACCESSTOKEN_LOG_INFO(LABEL, "invalid nodeId: %{public}s", nodeId.c_str()); + return Constant::FAILURE; + } + ACCESSTOKEN_LOG_INFO(LABEL, "operation start with nodeId: %{public}s", nodeId.c_str()); + + auto executor = GetOrCreateRemoteCommandExecutor(nodeId); + std::unique_lock lock(mutex_); + if (executor == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "cannot get or create remote command executor"); + return Constant::FAILURE; + } + + if (executor->GetChannel() == nullptr) { + auto channel = RemoteCommandExecutor::CreateChannel(nodeId); + if (channel == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "create channel failed."); + return Constant::FAILURE; + } + executor->SetChannel(channel); + } + + lock.unlock(); + + std::function delayed = ([=]() { + const std::shared_ptr syncRemoteNativeTokenCommand = + RemoteCommandFactory::GetInstance().NewSyncRemoteNativeTokenCommand(Constant::GetLocalDeviceId(), + nodeId); + + const int32_t resultCode = RemoteCommandManager::GetInstance().ExecuteCommand( + nodeId, syncRemoteNativeTokenCommand); + if (resultCode != Constant::SUCCESS) { + ACCESSTOKEN_LOG_INFO(LABEL, + "%{public}s: RemoteExecutorManager executeCommand syncRemoteNativeTokenCommand failed, return %d", + __func__, resultCode); + return; + } + }); + + std::shared_ptr handler = + DelayedSingleton::GetInstance()->GetSendEventHandler(); + if (handler == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler"); + return Constant::FAILURE; + } + handler->ProxyPostTask(delayed, "HandleDeviceOnline", Constant::DELAY_SYNC_TOKEN_MS); + + return Constant::SUCCESS; +} + +/** + * caller: device listener + */ +int RemoteCommandManager::NotifyDeviceOffline(const std::string &nodeId) +{ + if (!DataValidator::IsDeviceIdValid(nodeId)) { + ACCESSTOKEN_LOG_INFO(LABEL, "invalid nodeId: %{public}s", nodeId.c_str()); + return Constant::FAILURE; + } + ACCESSTOKEN_LOG_INFO(LABEL, "operation start with nodeId: %{public}s", nodeId.c_str()); + + auto channel = GetExecutorChannel(nodeId); + if (channel != nullptr) { + channel->Release(); + } + + std::unique_lock lock(mutex_); + RemoveCommand(nodeId); + lock.unlock(); + + DeviceInfo devInfo; + bool result = DeviceInfoManager::GetInstance().GetDeviceInfo(nodeId, DeviceIdType::UNKNOWN, devInfo); + if (!result) { + ACCESSTOKEN_LOG_INFO(LABEL, "get remote networkId failed"); + return Constant::FAILURE; + } + std::string networkId = devInfo.deviceId.networkId; + std::function delayed = ([=]() { + AccessTokenKit::DeleteRemoteDeviceTokens(networkId); + }); + + std::shared_ptr handler = + DelayedSingleton::GetInstance()->GetSendEventHandler(); + if (handler == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler"); + return Constant::FAILURE; + } + handler->ProxyPostTask(delayed, "HandleDeviceOffline"); + + ACCESSTOKEN_LOG_INFO(LABEL, "complete"); + return Constant::SUCCESS; +} + +std::shared_ptr RemoteCommandManager::GetOrCreateRemoteCommandExecutor(const std::string &nodeId) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "begin, nodeId %{public}s", nodeId.c_str()); + + std::unique_lock lock(mutex_); + auto executorIter = executors_.find(nodeId); + if (executorIter != executors_.end()) { + return executorIter->second; + } + + auto executor = std::make_shared(nodeId); + if (executor == nullptr) { + ACCESSTOKEN_LOG_INFO(LABEL, "cannot create remote command executor, nodeId: %{public}s", nodeId.c_str()); + return nullptr; + } + + executors_.insert(std::pair>(nodeId, executor)); + ACCESSTOKEN_LOG_DEBUG(LABEL, "executor added, nodeId: %{public}s", nodeId.c_str()); + return executor; +} + +/** + * caller: session listener(onBytesReceived), device listener(offline) + */ +std::shared_ptr RemoteCommandManager::GetExecutorChannel(const std::string &nodeId) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "convert udid start, nodeId:%{public}s", nodeId.c_str()); + std::string udid = DeviceInfoManager::GetInstance().ConvertToUniqueDisabilityIdOrFetch(nodeId); + ACCESSTOKEN_LOG_DEBUG(LABEL, "convert udid, nodeId:%{public}s, udid: %{public}s", nodeId.c_str(), udid.c_str()); + if (!DataValidator::IsDeviceIdValid(udid)) { + ACCESSTOKEN_LOG_WARN( + LABEL, "converted udid is invalid, nodeId:%{public}s, udid: %{public}s", nodeId.c_str(), udid.c_str()); + return nullptr; + } + std::map>::iterator iter = executors_.find(udid); + if (iter == executors_.end()) { + ACCESSTOKEN_LOG_INFO(LABEL, "executor not found"); + return nullptr; + } + std::shared_ptr executor = iter->second; + if (executor == nullptr) { + ACCESSTOKEN_LOG_INFO(LABEL, "executor is null"); + return nullptr; + } + return executor->GetChannel(); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/remote/soft_bus_channel.cpp b/services/tokensyncmanager/src/remote/soft_bus_channel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..97e028db7ed32afd65c9633feb2f4aea8eeb098d --- /dev/null +++ b/services/tokensyncmanager/src/remote/soft_bus_channel.cpp @@ -0,0 +1,416 @@ +/* + * 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 "soft_bus_channel.h" + +#include + +#include "device_info_manager.h" +#include "token_sync_event_handler.h" +#include "token_sync_manager_service.h" +#include "singleton.h" +#include "soft_bus_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "SoftBusChannel"}; +} +namespace { +static const std::string REQUEST_TYPE = "request"; +static const std::string RESPONSE_TYPE = "response"; +static const std::string TASK_NAME_CLOSE_SESSION = "atm_soft_bus_channel_close_session"; +static const long EXECUTE_COMMAND_TIME_OUT = 3000; +static const long WAIT_SESSION_CLOSE_MILLISECONDS = 5 * 1000; +// send buf size for header +static const int RPC_TRANSFER_HEAD_BYTES_LENGTH = 1024 * 256; +// decompress buf size +static const int RPC_TRANSFER_BYTES_MAX_LENGTH = 1024 * 1024; +} // namespace +SoftBusChannel::SoftBusChannel(const std::string &deviceId) + : deviceId_(deviceId), mutex_(), callbacks_(), responseResult_(""), loadedCond_() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "SoftBusChannel(deviceId)"); + isDelayClosing_ = false; + session_ = Constant::INVALID_SESSION; + isSessionUsing_ = false; +} + +SoftBusChannel::~SoftBusChannel() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "~SoftBusChannel()"); +} + +int SoftBusChannel::BuildConnection() +{ + CancelCloseConnectionIfNeeded(); + if (session_ != Constant::INVALID_SESSION) { + ACCESSTOKEN_LOG_INFO(LABEL, "session is exist, no need open again."); + return Constant::SUCCESS; + } + + std::unique_lock lock(sessionMutex_); + if (session_ == Constant::INVALID_SESSION) { + ACCESSTOKEN_LOG_INFO(LABEL, "open session with device: %{public}s", (deviceId_.c_str())); + int session = SoftBusManager::GetInstance().OpenSession(deviceId_); + if (session == Constant::INVALID_SESSION) { + ACCESSTOKEN_LOG_ERROR(LABEL, "open session failed."); + return Constant::FAILURE; + } + session_ = session; + } + return Constant::SUCCESS; +} + +void SoftBusChannel::CloseConnection() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "close connection"); + std::unique_lock lock(mutex_); + if (isDelayClosing_) { + return; + } + + std::shared_ptr handler = + DelayedSingleton::GetInstance()->GetSendEventHandler(); + if (handler == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler"); + return; + } + auto thisPtr = shared_from_this(); + std::function delayed = ([thisPtr]() { + std::unique_lock lock(thisPtr->sessionMutex_); + if (thisPtr->isSessionUsing_) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "session is in using, cancel close session"); + } else { + SoftBusManager::GetInstance().CloseSession(thisPtr->session_); + thisPtr->session_ = Constant::INVALID_SESSION; + ACCESSTOKEN_LOG_INFO(LABEL, "close session for device: %{public}s", thisPtr->deviceId_.c_str()); + } + thisPtr->isDelayClosing_ = false; + }); + + ACCESSTOKEN_LOG_DEBUG(LABEL, "close session after %{public}ld ms", WAIT_SESSION_CLOSE_MILLISECONDS); + handler->ProxyPostTask(delayed, TASK_NAME_CLOSE_SESSION, WAIT_SESSION_CLOSE_MILLISECONDS); + + isDelayClosing_ = true; +} + +void SoftBusChannel::Release() +{ + std::shared_ptr handler = + DelayedSingleton::GetInstance()->GetSendEventHandler(); + if (handler == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler"); + return; + } + handler->ProxyRemoveTask(TASK_NAME_CLOSE_SESSION); +} + +std::string SoftBusChannel::ExecuteCommand(const std::string &commandName, const std::string &jsonPayload) +{ + if (commandName.empty() || jsonPayload.empty()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params, commandName: %{public}s, jsonPayload: %{public}s", + commandName.c_str(), jsonPayload.c_str()); + return ""; + } + + // to use a lib like libuuid + int uuidStrLen = 37; // 32+4+1 + char uuidbuf[uuidStrLen]; + random_uuid(uuidbuf, uuidStrLen); + std::string uuid(uuidbuf); + ACCESSTOKEN_LOG_DEBUG(LABEL, "generated message uuid: %{public}s", uuid.c_str()); + + int len = RPC_TRANSFER_HEAD_BYTES_LENGTH + jsonPayload.length(); + unsigned char *buf = (unsigned char *) malloc(len + 1); + if (buf == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "no enough memory: %{public}d", len); + return ""; + } + memset_s(buf, len + 1, 0, len + 1); + int result = PrepareBytes(REQUEST_TYPE, uuid, commandName, jsonPayload, buf, len); + if (result != Constant::SUCCESS) { + free(buf); + return ""; + } + + std::unique_lock lock(sessionMutex_); + std::function callback = [&](const std::string &result) { + ACCESSTOKEN_LOG_INFO(LABEL, "onResponse called, data: %{public}s", result.c_str()); + responseResult_ = std::string(result); + loadedCond_.notify_all(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "onResponse called end"); + }; + callbacks_.insert(std::pair>(uuid, callback)); + + isSessionUsing_ = true; + lock.unlock(); + + int retCode = SendRequestBytes(buf, len); + free(buf); + + std::unique_lock lock2(sessionMutex_); + if (retCode != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request data failed: %{public}d ", retCode); + callbacks_.erase(uuid); + isSessionUsing_ = false; + return ""; + } + + ACCESSTOKEN_LOG_DEBUG(LABEL, "wait command response"); + if (loadedCond_.wait_for(lock2, std::chrono::milliseconds(EXECUTE_COMMAND_TIME_OUT)) == std::cv_status::timeout) { + ACCESSTOKEN_LOG_WARN(LABEL, "time out to wait response."); + callbacks_.erase(uuid); + isSessionUsing_ = false; + return ""; + } + + isSessionUsing_ = false; + return responseResult_; +} + +void SoftBusChannel::HandleDataReceived(int session, const unsigned char *bytes, int length) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "HandleDataReceived"); + + if (session <= 0 || length <= 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params: session: %{public}d, data length: %{public}d", session, length); + return; + } + std::string receiveData = Decompress(bytes, length); + if (receiveData.empty()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid parameter bytes"); + return; + } + std::shared_ptr message = SoftBusMessage::FromJson(receiveData); + if (message == nullptr) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "invalid json string: %{public}s", receiveData.c_str()); + return; + } + if (!message->IsValid()) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "invalid data, has empty field: %{public}s", receiveData.c_str()); + return; + } + + std::string type = message->GetType(); + if (REQUEST_TYPE == (type)) { + std::function delayed = ([=]() { + HandleRequest(session, message->GetId(), message->GetCommandName(), message->GetJsonPayload()); + }); + + std::shared_ptr handler = + DelayedSingleton::GetInstance()->GetRecvEventHandler(); + if (handler == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler"); + return; + } + handler->ProxyPostTask(delayed, "HandleDataReceived_HandleRequest"); + } else if (RESPONSE_TYPE == (type)) { + HandleResponse(message->GetId(), message->GetJsonPayload()); + } else { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid type: %{public}s ", type.c_str()); + } +} + +int SoftBusChannel::PrepareBytes(const std::string &type, const std::string &id, const std::string &commandName, + const std::string &jsonPayload, const unsigned char *bytes, int &bytesLength) +{ + SoftBusMessage messageEntity(type, id, commandName, jsonPayload); + std::string json = messageEntity.ToJson(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "softbus message json: %{public}s", json.c_str()); + return Compress(json, bytes, bytesLength); +} + +int SoftBusChannel::Compress(const std::string &json, const unsigned char *compressedBytes, int &compressedLength) +{ + uLong len = compressBound(json.size()); + // length will not so that long + if (compressedLength > 0 && (int) len > compressedLength) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "compress error. data length overflow, bound length: %{public}d, buffer length: %{public}d", (int) len, + compressedLength); + return Constant::FAILURE; + } + + int result = compress((Byte *) compressedBytes, &len, (unsigned char *) json.c_str(), json.size() + 1); + if (result != Z_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "compress failed! error code: %{public}d", result); + return result; + } + ACCESSTOKEN_LOG_DEBUG(LABEL, "compress complete. compress %{public}d bytes to %{public}d", compressedLength, + (int) len); + compressedLength = len; + return Constant::SUCCESS; +} + +std::string SoftBusChannel::Decompress(const unsigned char *bytes, const int length) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "input length: %{public}d", length); + uLong len = RPC_TRANSFER_BYTES_MAX_LENGTH; + unsigned char *buf = (unsigned char *) malloc(len + 1); + if (buf == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "no enough memory!"); + return ""; + } + memset_s(buf, len + 1, 0, len + 1); + int result = uncompress(buf, &len, (unsigned char *) bytes, length); + if (result != Z_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, + "uncompress failed, error code: %{public}d, bound length: %{public}d, buffer length: %{public}d", result, + (int) len, length); + free(buf); + return ""; + } + buf[len] = '\0'; + std::string str((char *) buf); + free(buf); + ACCESSTOKEN_LOG_DEBUG(LABEL, "done, output: %{public}s", str.c_str()); + return str; +} + +int SoftBusChannel::SendRequestBytes(const unsigned char *bytes, const int bytesLength) +{ + if (bytesLength == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "bytes data is invalid."); + return Constant::FAILURE; + } + + std::unique_lock lock(sessionMutex_); + if (CheckSessionMayReopenLocked() != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "session invalid and reopen failed!"); + return Constant::FAILURE; + } + + ACCESSTOKEN_LOG_DEBUG(LABEL, "send len (after compress len)= %{public}d", bytesLength); + int result = ::SendBytes(session_, bytes, bytesLength); + if (result != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fail to send! result= %{public}d", result); + return Constant::FAILURE; + } + ACCESSTOKEN_LOG_DEBUG(LABEL, "send successfully."); + return Constant::SUCCESS; +} + +int SoftBusChannel::CheckSessionMayReopenLocked() +{ + // when session is opened, we got a valid sessionid, when session closed, we will reset sessionid. + if (IsSessionAvailable()) { + return Constant::SUCCESS; + } + int session = SoftBusManager::GetInstance().OpenSession(deviceId_); + if (session != Constant::INVALID_SESSION) { + session_ = session; + return Constant::SUCCESS; + } + return Constant::FAILURE; +} + +bool SoftBusChannel::IsSessionAvailable() +{ + if (session_ == Constant::INVALID_SESSION) { + return false; + } + return session_ > Constant::INVALID_SESSION; +} + +void SoftBusChannel::CancelCloseConnectionIfNeeded() +{ + std::unique_lock lock(mutex_); + if (!isDelayClosing_) { + return; + } + ACCESSTOKEN_LOG_DEBUG(LABEL, "cancel close connection"); + + Release(); + isDelayClosing_ = false; +} + +void SoftBusChannel::HandleRequest(int session, const std::string &id, const std::string &commandName, + const std::string &jsonPayload) +{ + std::shared_ptr command = + RemoteCommandFactory::GetInstance().NewRemoteCommandFromJson(commandName, jsonPayload); + if (command == nullptr) { + // send result back directly + ACCESSTOKEN_LOG_WARN(LABEL, "command %{public}s cannot get from json %{public}s", commandName.c_str(), + jsonPayload.c_str()); + + int sendlen = RPC_TRANSFER_HEAD_BYTES_LENGTH + jsonPayload.length(); + unsigned char *sendbuf = (unsigned char *) malloc(sendlen + 1); + if (sendbuf == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "no enough memory: %{public}d", sendlen); + return; + } + memset_s(sendbuf, sendlen + 1, 0, sendlen + 1); + int sendResult = PrepareBytes(RESPONSE_TYPE, id, commandName, jsonPayload, sendbuf, sendlen); + if (sendResult != Constant::SUCCESS) { + free(sendbuf); + return; + } + int sendResultCode = SendResponseBytes(session, sendbuf, sendlen); + free(sendbuf); + ACCESSTOKEN_LOG_DEBUG(LABEL, "send response result= %{public}d ", sendResultCode); + return; + } + + // execute command + command->Execute(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "command uniqueId: %{public}s, finish with status: %{public}d, message: %{public}s", + command->remoteProtocol_.uniqueId.c_str(), command->remoteProtocol_.statusCode, + command->remoteProtocol_.message.c_str()); + + // send result back + std::string resultJsonPayload = command->ToJsonPayload(); + int len = RPC_TRANSFER_HEAD_BYTES_LENGTH + resultJsonPayload.length(); + unsigned char *buf = (unsigned char *) malloc(len + 1); + if (buf == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "no enough memory: %{public}d", len); + return; + } + memset_s(buf, len + 1, 0, len + 1); + int result = PrepareBytes(RESPONSE_TYPE, id, commandName, resultJsonPayload, buf, len); + if (result != Constant::SUCCESS) { + free(buf); + return; + } + int retCode = SendResponseBytes(session, buf, len); + free(buf); + ACCESSTOKEN_LOG_DEBUG(LABEL, "send response result= %{public}d", retCode); +} + +void SoftBusChannel::HandleResponse(const std::string &id, const std::string &jsonPayload) +{ + std::unique_lock lock(sessionMutex_); + auto callback = callbacks_.find(id); + if (callback != callbacks_.end()) { + (callback->second)(jsonPayload); + callbacks_.erase(callback); + } +} + +int SoftBusChannel::SendResponseBytes(int session, const unsigned char *bytes, const int bytesLength) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "send len (after compress len)= %{public}d", bytesLength); + int result = ::SendBytes(session, bytes, bytesLength); + if (result != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "fail to send! result= %{public}d", result); + return Constant::FAILURE; + } + ACCESSTOKEN_LOG_DEBUG(LABEL, "send successfully."); + return Constant::SUCCESS; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/remote/soft_bus_device_connection_listener.cpp b/services/tokensyncmanager/src/remote/soft_bus_device_connection_listener.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f10ba7cfa0bfe09d18a7eaedb80fb633e14413b1 --- /dev/null +++ b/services/tokensyncmanager/src/remote/soft_bus_device_connection_listener.cpp @@ -0,0 +1,93 @@ +/* + * 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 "soft_bus_device_connection_listener.h" +#include "remote_command_manager.h" +#include "soft_bus_manager.h" +#include "device_info_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "SoftBusDeviceConnectionListener"}; +} +SoftBusDeviceConnectionListener::SoftBusDeviceConnectionListener() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "SoftBusDeviceConnectionListener()"); +} +SoftBusDeviceConnectionListener::~SoftBusDeviceConnectionListener() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "~SoftBusDeviceConnectionListener()"); +} + +void SoftBusDeviceConnectionListener::OnDeviceOnline(const DmDeviceInfo &info) +{ + std::string networkId = info.deviceId; + std::string uuid = SoftBusManager::GetInstance().GetUniversallyUniqueIdByNodeId(networkId); + std::string udid = SoftBusManager::GetInstance().GetUniqueDisabilityIdByNodeId(networkId); + + ACCESSTOKEN_LOG_INFO(LABEL, + "networkId: %{public}s, uuid: %{public}s, udid: %{public}s", + networkId.c_str(), + uuid.c_str(), + udid.c_str()); + + if (uuid != "" && udid != "") { + DeviceInfoManager::GetInstance().AddDeviceInfo( + networkId, uuid, udid, info.deviceName, std::to_string(info.deviceTypeId)); + RemoteCommandManager::GetInstance().NotifyDeviceOnline(udid); + } else { + ACCESSTOKEN_LOG_ERROR(LABEL, "uuid or udid is empty, online failed."); + } + // no need to load local permissions by now. +} + +void SoftBusDeviceConnectionListener::OnDeviceOffline(const DmDeviceInfo &info) +{ + std::string networkId = info.deviceId; + std::string uuid = DeviceInfoManager::GetInstance().ConvertToUniversallyUniqueIdOrFetch(networkId); + std::string udid = DeviceInfoManager::GetInstance().ConvertToUniqueDisabilityIdOrFetch(networkId); + + ACCESSTOKEN_LOG_INFO(LABEL, + "networkId: %{public}s, uuid: %{public}s, udid: %{public}s", + networkId.c_str(), + uuid.c_str(), + udid.c_str()); + + if (uuid != "" && udid != "") { + RemoteCommandManager::GetInstance().NotifyDeviceOffline(uuid); + RemoteCommandManager::GetInstance().NotifyDeviceOffline(udid); + DeviceInfoManager::GetInstance().RemoveRemoteDeviceInfo(networkId, DeviceIdType::NETWORK_ID); + } else { + ACCESSTOKEN_LOG_ERROR(LABEL, "uuid or udid is empty, offline failed."); + } +} + +void SoftBusDeviceConnectionListener::OnDeviceReady(const DmDeviceInfo &info) +{ + std::string networkId = info.deviceId; + ACCESSTOKEN_LOG_INFO(LABEL, "networkId: %{public}s", networkId.c_str()); +} + +void SoftBusDeviceConnectionListener::OnDeviceChanged(const DmDeviceInfo &info) +{ + std::string networkId = info.deviceId; + ACCESSTOKEN_LOG_INFO(LABEL, "networkId: %{public}s", networkId.c_str()); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/remote/soft_bus_manager.cpp b/services/tokensyncmanager/src/remote/soft_bus_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6262abace16eec749d52bd4d18a7b26f26e6016c --- /dev/null +++ b/services/tokensyncmanager/src/remote/soft_bus_manager.cpp @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2021 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 "soft_bus_manager.h" + +#include + +#include "device_info_manager.h" +#include "parameter.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "SoftBusManager"}; +} +namespace { +static const std::string SESSION_GROUP_ID = "atm_dsoftbus_session_group_id"; +static const SessionAttribute SESSION_ATTR = {.dataType = TYPE_BYTES}; + +static const int REASON_EXIST = -3; +static const int OPENSESSION_RETRY_TIMES = 10 * 3; +static const int OPENSESSION_RETRY_INTERVAL_MS = 100; +static const int UDID_MAX_LENGTH = 128; // udid/uuid max length +} // namespace + +const std::string SoftBusManager::ACCESS_TOKEN_PACKAGE_NAME = "ohos.security.distributed_access_token"; +const std::string SoftBusManager::SESSION_NAME = "ohos.security.atm_channel"; + +SoftBusManager::SoftBusManager() : isSoftBusServiceBindSuccess_(false), inited_(false), mutex_(), fulfillMutex_() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "SoftBusManager()"); +} + +SoftBusManager::~SoftBusManager() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "~SoftBusManager()"); +} + +SoftBusManager &SoftBusManager::GetInstance() +{ + static SoftBusManager instance; + return instance; +} + +void SoftBusManager::Initialize() +{ + bool inited = false; + // cas failed means already inited. + if (!inited_.compare_exchange_strong(inited, true)) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "already initialized, skip"); + return; + } + + std::function runner = [&]() { + auto sleepTime = std::chrono::milliseconds(1000); + while (1) { + std::unique_lock lock(mutex_); + std::string packageName = ACCESS_TOKEN_PACKAGE_NAME; + std::shared_ptr ptrDmInitCallback = std::make_shared(); + int ret = + DistributedHardware::DeviceManager::GetInstance().InitDeviceManager(packageName, ptrDmInitCallback); + if (ret != ERR_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Initialize: InitDeviceManager error, result: %{public}d", ret); + std::this_thread::sleep_for(sleepTime); + continue; + } + + std::string extra = ""; + std::shared_ptr ptrDeviceStateCallback = + std::make_shared(); + ret = DistributedHardware::DeviceManager::GetInstance().RegisterDevStateCallback(packageName, extra, + ptrDeviceStateCallback); + if (ret != ERR_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Initialize: RegisterDevStateCallback error, result: %{public}d", ret); + std::this_thread::sleep_for(sleepTime); + continue; + } + + // register session listener + ISessionListener sessionListener; + sessionListener.OnSessionOpened = SoftBusSessionListener::OnSessionOpened; + sessionListener.OnSessionClosed = SoftBusSessionListener::OnSessionClosed; + sessionListener.OnBytesReceived = SoftBusSessionListener::OnBytesReceived; + sessionListener.OnMessageReceived = SoftBusSessionListener::OnMessageReceived; + + ret = ::CreateSessionServer(ACCESS_TOKEN_PACKAGE_NAME.c_str(), SESSION_NAME.c_str(), &sessionListener); + ACCESSTOKEN_LOG_INFO(LABEL, "Initialize: createSessionServer, result: %{public}d", ret); + // REASON_EXIST + if ((ret != Constant::SUCCESS) && (ret != REASON_EXIST)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Initialize: CreateSessionServer error, result: %{public}d", ret); + + std::this_thread::sleep_for(sleepTime); + continue; + } + + isSoftBusServiceBindSuccess_ = true; + this->FulfillLocalDeviceInfo(); + return; + } + }; + + std::thread initThread(runner); + initThread.detach(); + ACCESSTOKEN_LOG_DEBUG(LABEL, "Initialize thread started"); +} + +void SoftBusManager::Destroy() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "destroy, init: %{public}d, isSoftBusServiceBindSuccess: %{public}d", inited_.load(), + isSoftBusServiceBindSuccess_); + + if (inited_.load() == false) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "not inited, skip"); + return; + } + + std::unique_lock lock(mutex_); + if (inited_.load() == false) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "not inited, skip"); + return; + } + + if (isSoftBusServiceBindSuccess_) { + int32_t ret = ::RemoveSessionServer(ACCESS_TOKEN_PACKAGE_NAME.c_str(), SESSION_NAME.c_str()); + ACCESSTOKEN_LOG_DEBUG(LABEL, "destroy, RemoveSessionServer: %{public}d", ret); + isSoftBusServiceBindSuccess_ = false; + } + + std::string packageName = ACCESS_TOKEN_PACKAGE_NAME; + int ret = DistributedHardware::DeviceManager::GetInstance().UnRegisterDevStateCallback(packageName); + if (ret != ERR_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "UnRegisterDevStateCallback failed, code: %{public}d", ret); + } + ret = DistributedHardware::DeviceManager::GetInstance().UnInitDeviceManager(packageName); + if (ret != ERR_OK) { + ACCESSTOKEN_LOG_ERROR(LABEL, "UnInitDeviceManager failed, code: %{public}d", ret); + } + + inited_.store(false); + + ACCESSTOKEN_LOG_DEBUG(LABEL, "destroy, done"); +} + +int32_t SoftBusManager::OpenSession(const std::string &deviceId) +{ + DeviceInfo info; + bool result = DeviceInfoManager::GetInstance().GetDeviceInfo(deviceId, DeviceIdType::UNKNOWN, info); + if (result == false) { + ACCESSTOKEN_LOG_WARN(LABEL, "device info notfound for deviceId %{public}s", deviceId.c_str()); + return Constant::FAILURE; + } + std::string networkId = info.deviceId.networkId; + ACCESSTOKEN_LOG_INFO(LABEL, "openSession, networkId: %{public}s", networkId.c_str()); + + // async open session, should waitting for OnSessionOpened event. + int sessionId = ::OpenSession(SESSION_NAME.c_str(), SESSION_NAME.c_str(), networkId.c_str(), + SESSION_GROUP_ID.c_str(), &SESSION_ATTR); + + ACCESSTOKEN_LOG_DEBUG(LABEL, "session info: sessionId: %{public}d, uuid: %{public}s, udid: %{public}s", sessionId, + info.deviceId.universallyUniqueId.c_str(), info.deviceId.uniqueDisabilityId.c_str()); + + // wait session opening + int retryTimes = 0; + int logSpan = 10; + auto sleepTime = std::chrono::milliseconds(OPENSESSION_RETRY_INTERVAL_MS); + while (retryTimes++ < OPENSESSION_RETRY_TIMES) { + if (SoftBusSessionListener::GetSessionState(sessionId) < 0) { + std::this_thread::sleep_for(sleepTime); + if (retryTimes % logSpan == 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "openSession, waitting for: %{public}d ms", + retryTimes * OPENSESSION_RETRY_INTERVAL_MS); + } + continue; + } + break; + } + int64_t state = SoftBusSessionListener::GetSessionState(sessionId); + if (state < 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "openSession, timeout, session: %{public}" PRId64, state); + return Constant::FAILURE; + } + + SoftBusSessionListener::DeleteSessionIdFromMap(sessionId); + + ACCESSTOKEN_LOG_DEBUG(LABEL, "openSession, succeed, session: %{public}" PRId64, state); + return sessionId; +} + +int SoftBusManager::CloseSession(int sessionId) +{ + if (sessionId < 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "closeSession: session is invalid"); + return Constant::FAILURE; + } + + ::CloseSession(sessionId); + ACCESSTOKEN_LOG_INFO(LABEL, "closeSession "); + return Constant::SUCCESS; +} + + +std::string SoftBusManager::GetUniversallyUniqueIdByNodeId(const std::string &nodeId) +{ + if (!DataValidator::IsDeviceIdValid(nodeId)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid nodeId: %{public}s", nodeId.c_str()); + return ""; + } + + std::string uuid = GetUuidByNodeId(nodeId); + if (uuid.empty()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "softbus return null or empty string [%{public}s]", uuid.c_str()); + return ""; + } + + DeviceInfo info; + bool result = DeviceInfoManager::GetInstance().GetDeviceInfo(uuid, DeviceIdType::UNIVERSALLY_UNIQUE_ID, info); + if (result == false) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "local device info not found for uuid %{public}s", uuid.c_str()); + } else { + std::string dimUuid = info.deviceId.universallyUniqueId; + if (uuid == dimUuid) { + // refresh cache + std::function fulfillDeviceInfo = std::bind(&SoftBusManager::FulfillLocalDeviceInfo, this); + std::thread fulfill(fulfillDeviceInfo); + fulfill.detach(); + } + } + + return uuid; +} + +std::string SoftBusManager::GetUniqueDisabilityIdByNodeId(const std::string &nodeId) +{ + if (!DataValidator::IsDeviceIdValid(nodeId)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "invalid nodeId: %{public}s", nodeId.c_str()); + return ""; + } + std::string udid = GetUdidByNodeId(nodeId); + if (udid.empty()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "softbus return null or empty string: %{public}s", udid.c_str()); + return ""; + } + char localUdid[Constant::DEVICE_UUID_LENGTH] = {0}; + ::GetDevUdid(localUdid, Constant::DEVICE_UUID_LENGTH); + if (udid == localUdid) { + // refresh cache + std::function fulfillDeviceInfo = std::bind(&SoftBusManager::FulfillLocalDeviceInfo, this); + std::thread fulfill(fulfillDeviceInfo); + fulfill.detach(); + } + return udid; +} + +std::string SoftBusManager::GetUuidByNodeId(const std::string &nodeId) const +{ + uint8_t *info = (uint8_t *) malloc(UDID_MAX_LENGTH + 1); + if (info == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "no enough memory: %{public}d", UDID_MAX_LENGTH); + return ""; + } + memset_s(info, UDID_MAX_LENGTH + 1, 0, UDID_MAX_LENGTH + 1); + int32_t ret = ::GetNodeKeyInfo(ACCESS_TOKEN_PACKAGE_NAME.c_str(), nodeId.c_str(), + NodeDeviceInfoKey::NODE_KEY_UUID, info, UDID_MAX_LENGTH); + if (ret != Constant::SUCCESS) { + free(info); + ACCESSTOKEN_LOG_WARN(LABEL, "GetNodeKeyInfo error, return code: %{public}d", ret); + return ""; + } + std::string uuid((char *) info); + free(info); + ACCESSTOKEN_LOG_DEBUG(LABEL, "call softbus finished. nodeId(in): %{public}s, uuid: %{public}s", nodeId.c_str(), + uuid.c_str()); + return uuid; +} + +std::string SoftBusManager::GetUdidByNodeId(const std::string &nodeId) const +{ + uint8_t *info = (uint8_t *) malloc(UDID_MAX_LENGTH + 1); + if (info == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "no enough memory: %{public}d", UDID_MAX_LENGTH); + return ""; + } + memset_s(info, UDID_MAX_LENGTH + 1, 0, UDID_MAX_LENGTH + 1); + int32_t ret = ::GetNodeKeyInfo(ACCESS_TOKEN_PACKAGE_NAME.c_str(), nodeId.c_str(), + NodeDeviceInfoKey::NODE_KEY_UDID, info, UDID_MAX_LENGTH); + if (ret != Constant::SUCCESS) { + free(info); + ACCESSTOKEN_LOG_WARN(LABEL, "GetNodeKeyInfo error, code: %{public}d", ret); + return ""; + } + std::string udid((char *) info); + free(info); + ACCESSTOKEN_LOG_DEBUG(LABEL, "call softbus finished: nodeId(in): %{public}s, udid: %{public}s", nodeId.c_str(), + udid.c_str()); + return udid; +} + +int SoftBusManager::FulfillLocalDeviceInfo() +{ + // repeated task will just skip + if (!fulfillMutex_.try_lock()) { + ACCESSTOKEN_LOG_INFO(LABEL, "FulfillLocalDeviceInfo already running, skip."); + return Constant::SUCCESS; + } + + NodeBasicInfo info; + int32_t ret = ::GetLocalNodeDeviceInfo(ACCESS_TOKEN_PACKAGE_NAME.c_str(), &info); + if (ret != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "GetLocalNodeDeviceInfo error"); + fulfillMutex_.unlock(); + return Constant::FAILURE; + } + + ACCESSTOKEN_LOG_DEBUG(LABEL, "call softbus finished, networkId:%{public}s, name:%{public}s, type:%{public}d", + info.networkId, info.deviceName, info.deviceTypeId); + + std::string uuid = GetUuidByNodeId(info.networkId); + std::string udid = GetUdidByNodeId(info.networkId); + if (uuid.empty() || udid.empty()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "FulfillLocalDeviceInfo: uuid or udid is empty, abort."); + fulfillMutex_.unlock(); + return Constant::FAILURE; + } + + DeviceInfoManager::GetInstance().AddDeviceInfo(info.networkId, uuid, udid, info.deviceName, + std::to_string(info.deviceTypeId)); + ACCESSTOKEN_LOG_DEBUG(LABEL, "AddDeviceInfo finished, networkId:%{public}s, uuid:%{public}s, udid:%{public}s", + info.networkId, uuid.c_str(), udid.c_str()); + + fulfillMutex_.unlock(); + return Constant::SUCCESS; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/remote/soft_bus_session_listener.cpp b/services/tokensyncmanager/src/remote/soft_bus_session_listener.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e138da60acced0f614c88d34e6b4cc3861e9caa5 --- /dev/null +++ b/services/tokensyncmanager/src/remote/soft_bus_session_listener.cpp @@ -0,0 +1,135 @@ +/* + * 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 "soft_bus_session_listener.h" +#include "remote_command_manager.h" +#include "soft_bus_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "SoftBusSessionListener"}; +} +namespace { +// Indicates the pointer to the session name, which is the unique ID of the session server. The value cannot be empty +// and can contain a maximum of 64 characters. +static const int32_t SESSION_NAME_MAXLENGTH = 64; +static const int32_t SESSION_ACCEPTED = 0; +static const int32_t SESSION_REFUSED = -1; +} // namespace + +std::mutex SoftBusSessionListener::g_SessionMutex_; +std::map SoftBusSessionListener::g_SessionOpenedMap_; + +int32_t SoftBusSessionListener::OnSessionOpened(int32_t session, int32_t result) +{ + if (result != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "OnSessionOpened, result: %{public}d", result); + return SESSION_REFUSED; + } + + int32_t len = SESSION_NAME_MAXLENGTH + 1; + char contents[len]; + int32_t resultCode = ::GetPeerSessionName(session, contents, len); + if (resultCode != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "OnSessionOpened, GetPeerSessionName failed, result: %{public}d", resultCode); + return SESSION_REFUSED; + } + std::string peerSessionName(contents); + if (SoftBusManager::SESSION_NAME != peerSessionName) { + ACCESSTOKEN_LOG_ERROR(LABEL, "OnSessionOpened, unknown session name."); + return SESSION_REFUSED; + } + + ACCESSTOKEN_LOG_INFO(LABEL, "OnSessionOpened, id = %{public}d", session); + + // store session state: opening + std::lock_guard guard(g_SessionMutex_); + auto iter = g_SessionOpenedMap_.find(session); + if (iter == g_SessionOpenedMap_.end()) { + g_SessionOpenedMap_.insert(std::pair(session, (int64_t) 1)); + } else { + iter->second = iter->second + 1; + } + + return SESSION_ACCEPTED; +} + +void SoftBusSessionListener::OnSessionClosed(int32_t session) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "OnSessionClosed"); + + // clear session state + std::lock_guard guard(g_SessionMutex_); + auto iter = g_SessionOpenedMap_.find(session); + if (iter != g_SessionOpenedMap_.end()) { + g_SessionOpenedMap_.erase(iter); + } +} + +void SoftBusSessionListener::OnMessageReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "OnMessageReceived: data length = %{public}u", dataLen); +} + +void SoftBusSessionListener::OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + if (sessionId == Constant::INVALID_SESSION || dataLen == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "params invalid, data length: %{public}d", dataLen); + return; + } + + int32_t len = SESSION_NAME_MAXLENGTH + 1; + char contents[len]; + int32_t resultCode = ::GetPeerDeviceId(sessionId, contents, len); + if (resultCode != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "GetPeerDeviceId, failed, result: %{public}d", resultCode); + return; + } + std::string networkId(contents); + ACCESSTOKEN_LOG_INFO(LABEL, "networkId = %{public}s, data length = %{public}u", contents, dataLen); + auto channel = RemoteCommandManager::GetInstance().GetExecutorChannel(networkId); + if (channel == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "GetExecutorChannel, failed, networkId: %{public}s", contents); + return; + } + channel->HandleDataReceived(sessionId, (unsigned char *) data, dataLen); +} + +int64_t SoftBusSessionListener::GetSessionState(int32_t sessionId) +{ + // get session state + std::lock_guard guard(g_SessionMutex_); + auto iter = g_SessionOpenedMap_.find(sessionId); + if (iter == g_SessionOpenedMap_.end()) { + return STATE_NOTFOUND; + } + return (iter->second); +} + +void SoftBusSessionListener::DeleteSessionIdFromMap(int32_t sessionID) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "DeleteSessionIdFromMap"); + // delete sessionId in map + std::lock_guard guard(g_SessionMutex_); + auto iter = g_SessionOpenedMap_.find(sessionID); + if (iter != g_SessionOpenedMap_.end()) { + g_SessionOpenedMap_.erase(iter); + } +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/tokensyncmanager/src/service/token_sync_event_handler.cpp b/services/tokensyncmanager/src/service/token_sync_event_handler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5aa524193ab10de50c494357342c67030ef29bb5 --- /dev/null +++ b/services/tokensyncmanager/src/service/token_sync_event_handler.cpp @@ -0,0 +1,54 @@ +/* + * 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 "token_sync_event_handler.h" + +#include "accesstoken_log.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenSyncEventHandler"}; +} +TokenSyncEventHandler::TokenSyncEventHandler( + const std::shared_ptr &runner) + : AppExecFwk::EventHandler(runner) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "enter"); +} +TokenSyncEventHandler::~TokenSyncEventHandler() = default; + +bool TokenSyncEventHandler::ProxyPostTask(const Callback &callback, int64_t delayTime) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "PostTask without name"); + return AppExecFwk::EventHandler::PostTask(callback, delayTime); +} + +bool TokenSyncEventHandler::ProxyPostTask( + const Callback &callback, const std::string &name, int64_t delayTime) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "PostTask with name"); + return AppExecFwk::EventHandler::PostTask(callback, name, delayTime); +} + +void TokenSyncEventHandler::ProxyRemoveTask(const std::string &name) +{ + AppExecFwk::EventHandler::RemoveTask(name); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/tokensyncmanager/src/service/token_sync_manager_service.cpp b/services/tokensyncmanager/src/service/token_sync_manager_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a3c034b8cef019501acf2d470d2440956c49c88 --- /dev/null +++ b/services/tokensyncmanager/src/service/token_sync_manager_service.cpp @@ -0,0 +1,198 @@ +/* + * 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 "token_sync_manager_service.h" + +#include + +#include "accesstoken_log.h" +#include "device_info_repository.h" +#include "device_info.h" +#include "remote_command_manager.h" +#include "soft_bus_manager.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenSyncManagerService"}; +} + +const bool REGISTER_RESULT = + SystemAbility::MakeAndRegisterAbility(DelayedSingleton::GetInstance().get()); + +TokenSyncManagerService::TokenSyncManagerService() + : SystemAbility(SA_ID_TOKENSYNC_MANAGER_SERVICE, true), state_(ServiceRunningState::STATE_NOT_START) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "TokenSyncManagerService()"); +} + +TokenSyncManagerService::~TokenSyncManagerService() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "~TokenSyncManagerService()"); +} + +void TokenSyncManagerService::OnStart() +{ + if (state_ == ServiceRunningState::STATE_RUNNING) { + ACCESSTOKEN_LOG_INFO(LABEL, "TokenSyncManagerService has already started!"); + return; + } + ACCESSTOKEN_LOG_INFO(LABEL, "TokenSyncManagerService is starting"); + if (!Initialize()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to initialize"); + return; + } + state_ = ServiceRunningState::STATE_RUNNING; + bool ret = Publish(DelayedSingleton::GetInstance().get()); + if (!ret) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to publish service!"); + return; + } + ACCESSTOKEN_LOG_INFO(LABEL, "Congratulations, TokenSyncManagerService start successfully!"); +} + +void TokenSyncManagerService::OnStop() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "stop service"); + state_ = ServiceRunningState::STATE_NOT_START; +} + +std::shared_ptr TokenSyncManagerService::GetSendEventHandler() +{ + return sendHandler_; +} + +std::shared_ptr TokenSyncManagerService::GetRecvEventHandler() +{ + return recvHandler_; +} + +int TokenSyncManagerService::GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID) +{ + if (!DataValidator::IsDeviceIdValid(deviceID) || tokenID == 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "Params is wrong."); + return RET_FAILED; + } + DeviceInfo devInfo; + bool result = DeviceInfoRepository::GetInstance().FindDeviceInfo(deviceID, DeviceIdType::UNKNOWN, devInfo); + if (!result) { + ACCESSTOKEN_LOG_INFO(LABEL, "FindDeviceInfo failed"); + return Constant::FAILURE; + } + std::string udid = devInfo.deviceId.uniqueDisabilityId; + const std::shared_ptr syncRemoteHapTokenCommand = + RemoteCommandFactory::GetInstance().NewSyncRemoteHapTokenCommand(Constant::GetLocalDeviceId(), + deviceID, tokenID); + + const int32_t resultCode = RemoteCommandManager::GetInstance().ExecuteCommand(udid, syncRemoteHapTokenCommand); + if (resultCode != Constant::SUCCESS) { + ACCESSTOKEN_LOG_INFO(LABEL, + "RemoteExecutorManager executeCommand SyncRemoteHapTokenCommand failed, return %d", resultCode); + return resultCode; + } + ACCESSTOKEN_LOG_INFO(LABEL, "get resultCode: %d", resultCode); + return RET_SUCCESS; +} + +int TokenSyncManagerService::DeleteRemoteHapTokenInfo(AccessTokenID tokenID) +{ + if (tokenID == 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "Params is wrong, token id is invalid."); + return RET_FAILED; + } + + std::vector devices = DeviceInfoRepository::GetInstance().ListDeviceInfo(); + std::string localUdid = Constant::GetLocalDeviceId(); + for (DeviceInfo device : devices) { + if (device.deviceId.uniqueDisabilityId == localUdid) { + ACCESSTOKEN_LOG_INFO(LABEL, "no need notify local device"); + continue; + } + const std::shared_ptr deleteRemoteTokenCommand = + RemoteCommandFactory::GetInstance().NewDeleteRemoteTokenCommand(Constant::GetLocalDeviceId(), + device.deviceId.networkId, tokenID); + + const int32_t resultCode = RemoteCommandManager::GetInstance().ExecuteCommand( + device.deviceId.uniqueDisabilityId, deleteRemoteTokenCommand); + if (resultCode != Constant::SUCCESS) { + ACCESSTOKEN_LOG_INFO(LABEL, + "RemoteExecutorManager executeCommand DeleteRemoteTokenCommand failed, return %d", resultCode); + continue; + } + ACCESSTOKEN_LOG_INFO(LABEL, "get resultCode: %d", resultCode); + } + return RET_SUCCESS; +} + +int TokenSyncManagerService::UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& tokenInfo) +{ + std::vector devices = DeviceInfoRepository::GetInstance().ListDeviceInfo(); + std::string localUdid = Constant::GetLocalDeviceId(); + for (DeviceInfo device : devices) { + if (device.deviceId.uniqueDisabilityId == localUdid) { + ACCESSTOKEN_LOG_INFO(LABEL, "no need notify local device"); + continue; + } + + const std::shared_ptr updateRemoteHapTokenCommand = + RemoteCommandFactory::GetInstance().NewUpdateRemoteHapTokenCommand(Constant::GetLocalDeviceId(), + device.deviceId.networkId, tokenInfo); + + const int32_t resultCode = RemoteCommandManager::GetInstance().ExecuteCommand( + device.deviceId.uniqueDisabilityId, updateRemoteHapTokenCommand); + if (resultCode != Constant::SUCCESS) { + ACCESSTOKEN_LOG_INFO(LABEL, + "RemoteExecutorManager executeCommand updateRemoteHapTokenCommand failed, return %d", resultCode); + continue; + } + ACCESSTOKEN_LOG_INFO(LABEL, "get resultCode: %d", resultCode); + } + + return RET_SUCCESS; +} + +bool TokenSyncManagerService::Initialize() +{ + sendRunner_ = AppExecFwk::EventRunner::Create(true); + if (!sendRunner_) { + ACCESSTOKEN_LOG_ERROR(LABEL, "failed to create a sendRunner."); + return false; + } + + sendHandler_ = std::make_shared(sendRunner_); + if (!sendHandler_) { + ACCESSTOKEN_LOG_ERROR(LABEL, "sendHandler_ is nullpter."); + return false; + } + + recvRunner_ = AppExecFwk::EventRunner::Create(true); + if (!recvRunner_) { + ACCESSTOKEN_LOG_ERROR(LABEL, "failed to create a recvRunner."); + return false; + } + + recvHandler_ = std::make_shared(recvRunner_); + if (!recvHandler_) { + ACCESSTOKEN_LOG_ERROR(LABEL, "recvHandler_ is nullpter."); + return false; + } + + SoftBusManager::GetInstance().Initialize(); + return true; +} +} // namespace AccessToken +} // namespace Security +} diff --git a/services/accesstoken/main/cpp/src/accesstoken_manager_stub.cpp b/services/tokensyncmanager/src/service/token_sync_manager_stub.cpp similarity index 41% rename from services/accesstoken/main/cpp/src/accesstoken_manager_stub.cpp rename to services/tokensyncmanager/src/service/token_sync_manager_stub.cpp index a8b1c6cef1c0d79327be52956cc7bd70963bb7f1..c44fc70bdb7d59cee41841776352892203422581 100644 --- a/services/accesstoken/main/cpp/src/accesstoken_manager_stub.cpp +++ b/services/tokensyncmanager/src/service/token_sync_manager_stub.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,11 +13,10 @@ * limitations under the License. */ -#include "accesstoken_manager_stub.h" +#include "token_sync_manager_stub.h" -#include "accesstoken.h" #include "accesstoken_log.h" - +#include "hap_token_info_for_sync_parcel.h" #include "ipc_skeleton.h" #include "string_ex.h" @@ -25,23 +24,27 @@ namespace OHOS { namespace Security { namespace AccessToken { namespace { -static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { - LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenManagerStub" -}; +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenSyncManagerStub"}; } -int32_t AccessTokenManagerStub::OnRemoteRequest( +int32_t TokenSyncManagerStub::OnRemoteRequest( uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) { ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, code: %{public}d", __func__, code); std::u16string descriptor = data.ReadInterfaceToken(); - if (descriptor != IAccessTokenManager::GetDescriptor()) { + if (descriptor != ITokenSyncManager::GetDescriptor()) { ACCESSTOKEN_LOG_ERROR(LABEL, "get unexpect descriptor: %{public}s", Str16ToStr8(descriptor).c_str()); - return RET_FAILED; + return -1; } switch (code) { - case static_cast(IAccessTokenManager::InterfaceCode::VERIFY_ACCESSTOKEN): - VerifyAccessTokenInner(data, reply); + case static_cast(ITokenSyncManager::InterfaceCode::GET_REMOTE_HAP_TOKEN_INFO): + GetRemoteHapTokenInfoInner(data, reply); + break; + case static_cast(ITokenSyncManager::InterfaceCode::DELETE_REMOTE_HAP_TOKEN_INFO): + DeleteRemoteHapTokenInfoInner(data, reply); + break; + case static_cast(ITokenSyncManager::InterfaceCode::UPDATE_REMOTE_HAP_TOKEN_INFO): + UpdateRemoteHapTokenInfoInner(data, reply); break; default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -49,13 +52,33 @@ int32_t AccessTokenManagerStub::OnRemoteRequest( return NO_ERROR; } -void AccessTokenManagerStub::VerifyAccessTokenInner(MessageParcel& data, MessageParcel& reply) +void TokenSyncManagerStub::GetRemoteHapTokenInfoInner(MessageParcel& data, MessageParcel& reply) { - AccessTokenID tokenID = data.ReadUint32(); - std::string permissionName = data.ReadString(); - int result = this->VerifyAccesstoken(tokenID, permissionName); + std::string deviceID = data.ReadString(); + int tokenID = data.ReadUint32(); + + HapTokenInfoForSync tokenInfo; + int result = this->GetRemoteHapTokenInfo(deviceID, tokenID); + reply.WriteInt32(result); +} + +void TokenSyncManagerStub::DeleteRemoteHapTokenInfoInner(MessageParcel& data, MessageParcel& reply) +{ + std::string deviceID = data.ReadString(); + int tokenID = data.ReadUint32(); + int result = this->DeleteRemoteHapTokenInfo(tokenID); + reply.WriteInt32(result); +} + +void TokenSyncManagerStub::UpdateRemoteHapTokenInfoInner(MessageParcel& data, MessageParcel& reply) +{ + sptr tokenInfoParcelPtr = data.ReadParcelable(); + int result = RET_FAILED; + if (tokenInfoParcelPtr != nullptr) { + result = this->UpdateRemoteHapTokenInfo(tokenInfoParcelPtr->hapTokenInfoForSyncParams); + } reply.WriteInt32(result); } } // namespace AccessToken } // namespace Security -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/services/tokensyncmanager/token_sync.cfg b/services/tokensyncmanager/token_sync.cfg new file mode 100644 index 0000000000000000000000000000000000000000..e8e2f4782d23b4d8d6cd3a09d6136de1d6b4c239 --- /dev/null +++ b/services/tokensyncmanager/token_sync.cfg @@ -0,0 +1,17 @@ +{ + "jobs" : [{ + "name" : "late-fs", + "cmds" : [ + "start token_sync_service" + ] + } + ], + "services" : [{ + "name" : "token_sync_service", + "path" : ["/system/bin/sa_main", "/system/profile/token_sync_service.xml"], + "importance" : -20, + "uid" : "system", + "gid" : ["system"] + } + ] +} \ No newline at end of file diff --git a/services/tokensyncmanager/token_sync.rc b/services/tokensyncmanager/token_sync.rc new file mode 100644 index 0000000000000000000000000000000000000000..804c898ad03e8caec661d2a7a360e343fb44ce98 --- /dev/null +++ b/services/tokensyncmanager/token_sync.rc @@ -0,0 +1,22 @@ +# 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. + +on late-fs + start token_sync_service + +service token_sync_service /system/bin/sa_main /system/profile/token_sync_service.xml + class token_sync_service + priority -20 + user system + group system + seclabel u:r:token_sync_service:s0