From 71dc0536d91be7a0fed00618e37361946441cbb6 Mon Sep 17 00:00:00 2001 From: Haryslee Date: Wed, 14 May 2025 23:36:43 +0800 Subject: [PATCH] feat: customize for save button Signed-off-by: Haryslee --- .../include/sec_comp_client.h | 3 +- .../src/sec_comp_caller_authorization.cpp | 2 +- .../src/sec_comp_client.cpp | 29 +++- .../security_component/src/sec_comp_kit.cpp | 5 + .../test/unittest/src/sec_comp_kit_test.cpp | 22 +++ .../test/unittest/src/test_common.cpp | 6 + .../security_component/src/sec_comp_base.cpp | 135 +++++++++++++----- .../include/sec_comp_base.h | 9 ++ .../include/sec_comp_info.h | 10 ++ .../security_component/include/sec_comp_kit.h | 1 + .../sa/ISecCompService.idl | 3 +- .../sa/sa_main/first_use_dialog.cpp | 56 ++++++-- .../sa/sa_main/first_use_dialog.h | 5 +- .../sa/sa_main/sec_comp_entity.cpp | 7 +- .../sa/sa_main/sec_comp_entity.h | 41 +++++- .../sa/sa_main/sec_comp_info_helper.cpp | 2 + .../sa/sa_main/sec_comp_manager.cpp | 65 ++++++--- .../sa/sa_main/sec_comp_manager.h | 2 + .../sa/sa_main/sec_comp_service.cpp | 13 +- .../sa/sa_main/sec_comp_service.h | 1 + .../sa/test/mock/include/accesstoken_kit.h | 5 + .../unittest/src/first_use_dialog_test.cpp | 44 ++++++ .../src/sec_comp_service_mock_test.cpp | 4 +- .../unittest/src/sec_comp_stub_mock_test.h | 6 + .../sa/test/unittest/src/sec_comp_stub_test.h | 6 + .../test/unittest/src/service_test_common.cpp | 6 + .../security_component/common/fuzz_common.cpp | 6 + 27 files changed, 418 insertions(+), 76 deletions(-) diff --git a/frameworks/inner_api/security_component/include/sec_comp_client.h b/frameworks/inner_api/security_component/include/sec_comp_client.h index a48f18b..46328a4 100644 --- a/frameworks/inner_api/security_component/include/sec_comp_client.h +++ b/frameworks/inner_api/security_component/include/sec_comp_client.h @@ -37,7 +37,7 @@ public: int32_t RegisterWriteToRawdata(SecCompType type, const std::string& componentInfo, SecCompRawdata& rawData); int32_t UpdateWriteToRawdata(int32_t scId, const std::string& componentInfo, SecCompRawdata& rawData); int32_t UnregisterWriteToRawdata(int32_t scId, SecCompRawdata& rawData); - int32_t ReportWriteToRawdata(SecCompInfo& secCompInfo, SecCompRawdata& rawData); + int32_t ReportWriteToRawdata(SecCompInfo& secCompInfo, SecCompRawdata& rawData, std::string& message); int32_t PreRegisterWriteToRawdata(SecCompRawdata& rawData); int32_t RegisterSecurityComponent(SecCompType type, const std::string& componentInfo, int32_t& scId); int32_t UpdateSecurityComponent(int32_t scId, const std::string& componentInfo); @@ -49,6 +49,7 @@ public: bool IsServiceExist(); bool LoadService(); bool IsSystemAppCalling(); + bool HasCustomPermissionForSecComp(); void FinishStartSASuccess(const sptr& remoteObject); void FinishStartSAFail(); diff --git a/frameworks/inner_api/security_component/src/sec_comp_caller_authorization.cpp b/frameworks/inner_api/security_component/src/sec_comp_caller_authorization.cpp index 99fa80a..3fa48ad 100644 --- a/frameworks/inner_api/security_component/src/sec_comp_caller_authorization.cpp +++ b/frameworks/inner_api/security_component/src/sec_comp_caller_authorization.cpp @@ -21,7 +21,7 @@ namespace OHOS { namespace Security { namespace SecurityComponent { namespace { -static constexpr int32_t MAX_FUNC_ASM_SIZE = 0x280; +static constexpr int32_t MAX_FUNC_ASM_SIZE = 0x380; static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompCallerAuthorization"}; static constexpr size_t MAX_CALLER_SIZE = 10; diff --git a/frameworks/inner_api/security_component/src/sec_comp_client.cpp b/frameworks/inner_api/security_component/src/sec_comp_client.cpp index ed6d3d0..0708f20 100644 --- a/frameworks/inner_api/security_component/src/sec_comp_client.cpp +++ b/frameworks/inner_api/security_component/src/sec_comp_client.cpp @@ -14,6 +14,7 @@ */ #include "sec_comp_client.h" +#include "accesstoken_kit.h" #include "ipc_skeleton.h" #include "iservice_registry.h" #include "sec_comp_click_event_parcel.h" @@ -236,7 +237,7 @@ int32_t SecCompClient::UnregisterSecurityComponent(int32_t scId) return serviceRes; } -int32_t SecCompClient::ReportWriteToRawdata(SecCompInfo& secCompInfo, SecCompRawdata& rawData) +int32_t SecCompClient::ReportWriteToRawdata(SecCompInfo& secCompInfo, SecCompRawdata& rawData, std::string& message) { MessageParcel dataParcel; @@ -250,6 +251,11 @@ int32_t SecCompClient::ReportWriteToRawdata(SecCompInfo& secCompInfo, SecCompRaw return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL; } + if (!dataParcel.WriteString(message)) { + SC_LOG_ERROR(LABEL, "Report write message failed."); + return SC_SERVICE_ERROR_PARCEL_OPERATE_FAIL; + } + sptr parcel = new (std::nothrow) SecCompClickEventParcel(); if (parcel == nullptr) { SC_LOG_ERROR(LABEL, "Report new click event parcel failed."); @@ -279,7 +285,7 @@ int32_t SecCompClient::ReportSecurityComponentClickEvent(SecCompInfo& secCompInf std::lock_guard lock(useIPCMutex_); SecCompRawdata rawData; - int32_t res = ReportWriteToRawdata(secCompInfo, rawData); + int32_t res = ReportWriteToRawdata(secCompInfo, rawData, message); if (res != SC_OK) { return res; } @@ -333,6 +339,25 @@ bool SecCompClient::IsSystemAppCalling() return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken); } +bool SecCompClient::HasCustomPermissionForSecComp() +{ + auto proxy = GetProxy(true); + if (proxy == nullptr) { + SC_LOG_ERROR(LABEL, "Proxy is null"); + return false; + } + + std::lock_guard lock(useIPCMutex_); + bool hasCustomPermission; + int32_t res = proxy->HasCustomPermissionForSecComp(hasCustomPermission); + if (res != SC_OK) { + SC_LOG_ERROR(LABEL, "Get custom permission status failed, result: %{public}d.", res); + return false; + } + + return hasCustomPermission; +} + int32_t SecCompClient::PreRegisterWriteToRawdata(SecCompRawdata& rawData) { MessageParcel dataParcel; diff --git a/frameworks/inner_api/security_component/src/sec_comp_kit.cpp b/frameworks/inner_api/security_component/src/sec_comp_kit.cpp index 970abec..81f5b33 100644 --- a/frameworks/inner_api/security_component/src/sec_comp_kit.cpp +++ b/frameworks/inner_api/security_component/src/sec_comp_kit.cpp @@ -170,6 +170,11 @@ bool SecCompKit::IsSystemAppCalling() { return SecCompClient::GetInstance().IsSystemAppCalling(); } + +bool SecCompKit::HasCustomPermissionForSecComp() +{ + return SecCompClient::GetInstance().HasCustomPermissionForSecComp(); +} } // namespace SecurityComponent } // namespace Security } // namespace OHOS diff --git a/frameworks/inner_api/security_component/test/unittest/src/sec_comp_kit_test.cpp b/frameworks/inner_api/security_component/test/unittest/src/sec_comp_kit_test.cpp index 235c4a8..a011484 100644 --- a/frameworks/inner_api/security_component/test/unittest/src/sec_comp_kit_test.cpp +++ b/frameworks/inner_api/security_component/test/unittest/src/sec_comp_kit_test.cpp @@ -241,3 +241,25 @@ HWTEST_F(SecCompKitTest, OnLoadSystemAbilitySuccess001, TestSize.Level0) loadCallback->OnLoadSystemAbilitySuccess(systemAbilityId, nullptr); loadCallback->OnLoadSystemAbilityFail(systemAbilityId); } + +/** + * @tc.name: IsSystemAppCalling001 + * @tc.desc: Test whether the app is system app. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(SecCompKitTest, IsSystemAppCalling001, TestSize.Level0) +{ + EXPECT_EQ(false, SecCompKit::IsSystemAppCalling()); +} + +/** + * @tc.name: HasCustomPermissionForSecComp001 + * @tc.desc: Test whether the app has custom permission for security component. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(SecCompKitTest, HasCustomPermissionForSecComp001, TestSize.Level0) +{ + EXPECT_EQ(false, SecCompKit::HasCustomPermissionForSecComp()); +} diff --git a/frameworks/inner_api/security_component/test/unittest/src/test_common.cpp b/frameworks/inner_api/security_component/test/unittest/src/test_common.cpp index f8b4261..17f0417 100644 --- a/frameworks/inner_api/security_component/test/unittest/src/test_common.cpp +++ b/frameworks/inner_api/security_component/test/unittest/src/test_common.cpp @@ -94,6 +94,8 @@ void TestCommon::BuildLocationComponentInfo(nlohmann::json& jsonComponent) jsonComponent[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = 0.0; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = false; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = false; + jsonComponent[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = false; + jsonComponent[JsonTagConstants::JSON_TIP_POSITION] = TipPosition::ABOVE_BOTTOM; } void TestCommon::BuildSaveComponentInfo(nlohmann::json& jsonComponent) @@ -123,6 +125,8 @@ void TestCommon::BuildSaveComponentInfo(nlohmann::json& jsonComponent) jsonComponent[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = 0.0; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = false; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = false; + jsonComponent[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = false; + jsonComponent[JsonTagConstants::JSON_TIP_POSITION] = TipPosition::ABOVE_BOTTOM; } void TestCommon::BuildPasteComponentInfo(nlohmann::json& jsonComponent) @@ -152,6 +156,8 @@ void TestCommon::BuildPasteComponentInfo(nlohmann::json& jsonComponent) jsonComponent[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = 0.0; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = false; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = false; + jsonComponent[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = false; + jsonComponent[JsonTagConstants::JSON_TIP_POSITION] = TipPosition::ABOVE_BOTTOM; } } // namespace SecurityComponent } // namespace Security diff --git a/frameworks/security_component/src/sec_comp_base.cpp b/frameworks/security_component/src/sec_comp_base.cpp index 78c87e9..b6e091f 100644 --- a/frameworks/security_component/src/sec_comp_base.cpp +++ b/frameworks/security_component/src/sec_comp_base.cpp @@ -77,12 +77,14 @@ const std::string JsonTagConstants::JSON_LINEAR_GRADIENT_BLUR_RADIUS_TAG = "blur const std::string JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG = "foregroundBlurRadius"; const std::string JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG = "isOverlayTextSet"; const std::string JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG = "isOverlayNodeCovered"; +const std::string JsonTagConstants::JSON_TIP_POSITION = "tipPosition"; +const std::string JsonTagConstants::JSON_IS_CUSTOMIZABLE = "isCustomizable"; bool SecCompBase::ParseNonCompatibleChange(const nlohmann::json& json) { std::string tag = JsonTagConstants::JSON_NON_COMPATIBLE_CHANGE_TAG; if ((json.find(tag) == json.end()) || !json.at(tag).is_boolean()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } hasNonCompatibleChange_ = json.at(tag).get(); @@ -96,15 +98,15 @@ bool SecCompBase::ParseNonCompatibleChange(const nlohmann::json& json) if (!ParseDimension(json, JsonTagConstants::JSON_LINEAR_GRADIENT_BLUR_RADIUS_TAG, blurRadius_)) { return false; } - + if (!ParseDimension(json, JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG, foregroundBlurRadius_)) { return false; } - + if (!ParseBool(json, JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG, isOverlayTextSet_)) { return false; } - + if (!ParseBool(json, JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG, isOverlayNodeCovered_)) { return false; } @@ -115,7 +117,7 @@ bool SecCompBase::ParseNonCompatibleChange(const nlohmann::json& json) bool SecCompBase::ParseDimension(const nlohmann::json& json, const std::string& tag, DimensionT& res) { if ((json.find(tag) == json.end()) || !json.at(tag).is_number_float()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } @@ -126,7 +128,7 @@ bool SecCompBase::ParseDimension(const nlohmann::json& json, const std::string& bool SecCompBase::ParseColor(const nlohmann::json& json, const std::string& tag, SecCompColor& res) { if ((json.find(tag) == json.end()) || !json.at(tag).is_number()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } @@ -137,7 +139,7 @@ bool SecCompBase::ParseColor(const nlohmann::json& json, const std::string& tag, bool SecCompBase::ParseBool(const nlohmann::json& json, const std::string& tag, bool& res) { if ((json.find(tag) == json.end()) || !json.at(tag).is_boolean()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } @@ -148,7 +150,7 @@ bool SecCompBase::ParseBool(const nlohmann::json& json, const std::string& tag, bool SecCompBase::ParseString(const nlohmann::json& json, const std::string& tag, std::string& res) { if ((json.find(tag) == json.end()) || !json.at(tag).is_string()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } @@ -159,7 +161,7 @@ bool SecCompBase::ParseString(const nlohmann::json& json, const std::string& tag bool SecCompBase::ParsePadding(const nlohmann::json& json, const std::string& tag, PaddingSize& res) { if ((json.find(tag) == json.end()) || !json.at(tag).is_object()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } @@ -182,7 +184,7 @@ bool SecCompBase::ParsePadding(const nlohmann::json& json, const std::string& ta bool SecCompBase::ParseBorderRadius(const nlohmann::json& json, const std::string& tag, BorderRadius& res) { if ((json.find(tag) == json.end()) || !json.at(tag).is_object()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } @@ -205,7 +207,7 @@ bool SecCompBase::ParseBorderRadius(const nlohmann::json& json, const std::strin bool SecCompBase::ParseColors(const nlohmann::json& json, const std::string& tag) { if ((json.find(tag) == json.end()) || !json.at(tag).is_object()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } auto jsonColors = json.at(tag); @@ -224,7 +226,7 @@ bool SecCompBase::ParseColors(const nlohmann::json& json, const std::string& tag bool SecCompBase::ParseBorders(const nlohmann::json& json, const std::string& tag) { if ((json.find(tag) == json.end()) || !json.at(tag).is_object()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } auto jsonBorder = json.at(tag); @@ -234,7 +236,7 @@ bool SecCompBase::ParseBorders(const nlohmann::json& json, const std::string& ta bool SecCompBase::ParseSize(const nlohmann::json& json, const std::string& tag) { if ((json.find(tag) == json.end()) || !json.at(tag).is_object()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } @@ -266,7 +268,7 @@ bool SecCompBase::ParseSize(const nlohmann::json& json, const std::string& tag) bool SecCompBase::ParseParent(const nlohmann::json& json, const std::string& tag) { if ((json.find(tag) == json.end()) || !json.at(tag).is_object()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } auto jsonParent = json.at(tag); @@ -297,7 +299,7 @@ bool SecCompBase::ParseParent(const nlohmann::json& json, const std::string& tag bool SecCompBase::ParseRect(const nlohmann::json& json, const std::string& tag, SecCompRect& rect) { if ((json.find(tag) == json.end()) || !json.at(tag).is_object()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } @@ -324,7 +326,7 @@ bool SecCompBase::ParseRect(const nlohmann::json& json, const std::string& tag, bool SecCompBase::ParseType(const nlohmann::json& json, const std::string& tag) { if ((json.find(tag) == json.end()) || !json.at(tag).is_number()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } int32_t value = json.at(tag).get(); @@ -341,7 +343,7 @@ bool SecCompBase::ParseType(const nlohmann::json& json, const std::string& tag) bool SecCompBase::ParseValue(const nlohmann::json& json, const std::string& tag, int32_t& value) { if ((json.find(tag) == json.end()) || !json.at(tag).is_number()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } value = json.at(tag).get(); @@ -352,7 +354,7 @@ bool SecCompBase::ParseValue(const nlohmann::json& json, const std::string& tag, bool SecCompBase::ParseDisplayId(const nlohmann::json& json, const std::string& tag) { if ((json.find(tag) == json.end()) || !json.at(tag).is_number()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } displayId_ = json.at(tag).get(); @@ -363,7 +365,7 @@ bool SecCompBase::ParseDisplayId(const nlohmann::json& json, const std::string& bool SecCompBase::ParseCrossAxisState(const nlohmann::json& json, const std::string& tag) { if ((json.find(tag) == json.end()) || !json.at(tag).is_number()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } int32_t value = json.at(tag).get(); @@ -381,53 +383,108 @@ bool SecCompBase::ParseWearable(const nlohmann::json& json, const std::string& t { if ((json.find(tag) == json.end()) || !json.at(tag).is_boolean()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } isWearableDevice_ = json.at(tag).get(); return true; } -bool SecCompBase::FromJson(const nlohmann::json& jsonSrc, std::string& message, bool isClicked) +bool SecCompBase::ParseTipPosition(const nlohmann::json& json, const std::string& tag) { - SC_LOG_DEBUG(LABEL, "Button info %{public}s.", jsonSrc.dump().c_str()); - if (!ParseType(jsonSrc, JsonTagConstants::JSON_SC_TYPE)) { + if ((json.find(tag) == json.end()) || !json.at(tag).is_number()) { + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } - if (!ParseValue(jsonSrc, JsonTagConstants::JSON_NODE_ID, nodeId_)) { + int32_t value = json.at(tag).get(); + if ((value < static_cast(TipPosition::ABOVE_BOTTOM)) || + (value > static_cast(TipPosition::BELOW_TOP))) { + SC_LOG_ERROR(LABEL, "Save tip position: %{public}d is invalid.", value); return false; } - if (!ParseWearable(jsonSrc, JsonTagConstants::JSON_IS_WEARABLE)) { + + tipPosition_ = static_cast(value); + return true; +} + +bool SecCompBase::ParseComponentInfo(const nlohmann::json& json, std::string& message, bool isClicked) +{ + if (!ParseRect(json, JsonTagConstants::JSON_RECT, rect_)) { + return false; + } + if (!ParseSize(json, JsonTagConstants::JSON_SIZE_TAG)) { + return false; + } + if (!ParseColors(json, JsonTagConstants::JSON_COLORS_TAG)) { return false; } - if (!ParseRect(jsonSrc, JsonTagConstants::JSON_RECT, rect_)) { + if (!ParseBorders(json, JsonTagConstants::JSON_BORDER_TAG)) { return false; } - if (!ParseRect(jsonSrc, JsonTagConstants::JSON_WINDOW_RECT, windowRect_)) { + if (!ParseStyle(json, JsonTagConstants::JSON_STYLE_TAG, message, isClicked)) { return false; } - if (!ParseSize(jsonSrc, JsonTagConstants::JSON_SIZE_TAG)) { + return true; +} + +bool SecCompBase::ParseWindowInfo(const nlohmann::json& json) +{ + if (!ParseRect(json, JsonTagConstants::JSON_WINDOW_RECT, windowRect_)) { return false; } - if (!ParseColors(jsonSrc, JsonTagConstants::JSON_COLORS_TAG)) { + if (!ParseValue(json, JsonTagConstants::JSON_WINDOW_ID, windowId_)) { return false; } - if (!ParseBorders(jsonSrc, JsonTagConstants::JSON_BORDER_TAG)) { + return true; +} + +bool SecCompBase::ParseDisplayInfo(const nlohmann::json& json) +{ + if (!ParseDisplayId(json, JsonTagConstants::JSON_DISPLAY_ID)) { + return false; + } + if (!ParseCrossAxisState(json, JsonTagConstants::JSON_CROSS_AXIS_STATE)) { + return false; + } + return true; +} + +bool SecCompBase::ParseCustomInfo(const nlohmann::json& json) +{ + if (!ParseBool(json, JsonTagConstants::JSON_IS_CUSTOMIZABLE, isCustomizable_)) { + return false; + } + if (!ParseTipPosition(json, JsonTagConstants::JSON_TIP_POSITION)) { + return false; + } + return true; +} + +bool SecCompBase::FromJson(const nlohmann::json& jsonSrc, std::string& message, bool isClicked) +{ + SC_LOG_DEBUG(LABEL, "Button info %{public}s.", jsonSrc.dump().c_str()); + if (!ParseType(jsonSrc, JsonTagConstants::JSON_SC_TYPE)) { + return false; + } + if (!ParseValue(jsonSrc, JsonTagConstants::JSON_NODE_ID, nodeId_)) { + return false; + } + if (!ParseWearable(jsonSrc, JsonTagConstants::JSON_IS_WEARABLE)) { return false; } if (!ParseParent(jsonSrc, JsonTagConstants::JSON_PARENT_TAG)) { return false; } - if (!ParseStyle(jsonSrc, JsonTagConstants::JSON_STYLE_TAG, message, isClicked)) { + if (!ParseComponentInfo(jsonSrc, message, isClicked)) { return false; } - if (!ParseValue(jsonSrc, JsonTagConstants::JSON_WINDOW_ID, windowId_)) { + if (!ParseWindowInfo(jsonSrc)) { return false; } - if (!ParseDisplayId(jsonSrc, JsonTagConstants::JSON_DISPLAY_ID)) { + if (!ParseDisplayInfo(jsonSrc)) { return false; } - if (!ParseCrossAxisState(jsonSrc, JsonTagConstants::JSON_CROSS_AXIS_STATE)) { + if (!ParseCustomInfo(jsonSrc)) { return false; } if (!ParseNonCompatibleChange(jsonSrc)) { @@ -521,6 +578,8 @@ void SecCompBase::ToJson(nlohmann::json& jsonRes) const jsonRes[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = foregroundBlurRadius_; jsonRes[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = isOverlayTextSet_; jsonRes[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = isOverlayNodeCovered_; + jsonRes[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = isCustomizable_; + jsonRes[JsonTagConstants::JSON_TIP_POSITION] = tipPosition_; } std::string SecCompBase::ToJsonStr() const @@ -533,7 +592,7 @@ std::string SecCompBase::ToJsonStr() const bool SecCompBase::CompareComponentBasicInfo(SecCompBase *other, bool isRectCheck) const { if (other == nullptr) { - SC_LOG_ERROR(LABEL, "other is nullptr."); + SC_LOG_ERROR(LABEL, "Other is nullptr."); return false; } @@ -558,7 +617,7 @@ bool SecCompBase::CompareComponentBasicInfo(SecCompBase *other, bool isRectCheck bool SecCompBase::ParseStyle(const nlohmann::json& json, const std::string& tag, std::string& message, bool isClicked) { if ((json.find(tag) == json.end()) || !json.at(tag).is_object()) { - SC_LOG_ERROR(LABEL, "json: %{public}s tag invalid.", tag.c_str()); + SC_LOG_ERROR(LABEL, "Json: %{public}s tag invalid.", tag.c_str()); return false; } auto jsonStyle = json.at(tag); @@ -580,14 +639,14 @@ bool SecCompBase::ParseStyle(const nlohmann::json& json, const std::string& tag, text_ = jsonStyle.at(JsonTagConstants::JSON_TEXT_TAG).get(); icon_ = jsonStyle.at(JsonTagConstants::JSON_ICON_TAG).get(); if (!IsTextIconTypeValid(message, isClicked)) { - SC_LOG_ERROR(LABEL, "text or icon is invalid."); + SC_LOG_ERROR(LABEL, "Text or icon is invalid."); return false; } bg_ = static_cast(jsonStyle.at(JsonTagConstants::JSON_BG_TAG).get()); if ((bg_ != SecCompBackground::NO_BG_TYPE) && (bg_ != SecCompBackground::CAPSULE) && (bg_ != SecCompBackground::CIRCLE) && (bg_ != SecCompBackground::NORMAL) && (bg_ != SecCompBackground::ROUNDED_RECTANGLE)) { - SC_LOG_ERROR(LABEL, "bg is invalid."); + SC_LOG_ERROR(LABEL, "Background is invalid."); return false; } return true; diff --git a/interfaces/inner_api/security_component/include/sec_comp_base.h b/interfaces/inner_api/security_component/include/sec_comp_base.h index a1d250e..e95c5ff 100644 --- a/interfaces/inner_api/security_component/include/sec_comp_base.h +++ b/interfaces/inner_api/security_component/include/sec_comp_base.h @@ -94,6 +94,8 @@ public: static const std::string JSON_FOREGROUND_BLUR_RADIUS_TAG; static const std::string JSON_IS_OVERLAY_TEXT_SET_TAG; static const std::string JSON_IS_OVERLAY_NODE_SET_TAG; + static const std::string JSON_IS_CUSTOMIZABLE; + static const std::string JSON_TIP_POSITION; }; class __attribute__((visibility("default"))) SecCompBase { @@ -159,6 +161,8 @@ public: bool isIconExceeded_ = false; bool isBorderCovered_ = false; bool isWearableDevice_ = false; + TipPosition tipPosition_ = TipPosition::ABOVE_BOTTOM; + bool isCustomizable_ = false; protected: virtual bool IsTextIconTypeValid(std::string& message, bool isClicked) = 0; virtual bool IsCorrespondenceType() = 0; @@ -180,9 +184,14 @@ private: bool ParseValue(const nlohmann::json& json, const std::string& tag, int32_t& value); bool ParseDisplayId(const nlohmann::json& json, const std::string& tag); bool ParseCrossAxisState(const nlohmann::json& json, const std::string& tag); + bool ParseTipPosition(const nlohmann::json& json, const std::string& tag); bool ParseWearable(const nlohmann::json& json, const std::string& tag); void ToJsonRect(nlohmann::json& jsonRes) const; void ToJsonSize(nlohmann::json& jsonRes) const; + bool ParseComponentInfo(const nlohmann::json& json, std::string& message, bool isClicked); + bool ParseWindowInfo(const nlohmann::json& json); + bool ParseDisplayInfo(const nlohmann::json& json); + bool ParseCustomInfo(const nlohmann::json& json); }; } // namespace SecurityComponent } // namespace Security diff --git a/interfaces/inner_api/security_component/include/sec_comp_info.h b/interfaces/inner_api/security_component/include/sec_comp_info.h index f81aadc..6ff6a08 100644 --- a/interfaces/inner_api/security_component/include/sec_comp_info.h +++ b/interfaces/inner_api/security_component/include/sec_comp_info.h @@ -76,6 +76,16 @@ enum CrossAxisState { STATE_NO_CROSS, }; +enum TipPosition { + ABOVE_BOTTOM = 0, + BELOW_TOP, +}; + +enum NotifyType { + DIALOG = 0, + TOAST, +}; + inline bool IsComponentTypeValid(int32_t type) { return (type > UNKNOWN_SC_TYPE && type < MAX_SC_TYPE); diff --git a/interfaces/inner_api/security_component/include/sec_comp_kit.h b/interfaces/inner_api/security_component/include/sec_comp_kit.h index 7b0db4d..92370c1 100644 --- a/interfaces/inner_api/security_component/include/sec_comp_kit.h +++ b/interfaces/inner_api/security_component/include/sec_comp_kit.h @@ -36,6 +36,7 @@ public: static bool IsServiceExist(); static bool LoadService(); static bool IsSystemAppCalling(); + static bool HasCustomPermissionForSecComp(); }; } // namespace SecurityComponent } // namespace Security diff --git a/services/security_component_service/sa/ISecCompService.idl b/services/security_component_service/sa/ISecCompService.idl index 5973e7e..8686e80 100644 --- a/services/security_component_service/sa/ISecCompService.idl +++ b/services/security_component_service/sa/ISecCompService.idl @@ -23,5 +23,6 @@ interface OHOS.Security.SecurityComponent.ISecCompService { void ReportSecurityComponentClickEvent([in] IRemoteObject callerToken, [in] IRemoteObject dialogCallback, [in] SecCompRawdata rawData, [out] SecCompRawdata rawReply); void VerifySavePermission([in] unsigned int tokenId, [out] boolean ret); + void HasCustomPermissionForSecComp([out] boolean hasCustomPermission); void PreRegisterSecCompProcess([in] SecCompRawdata rawData, [out] SecCompRawdata rawReply); -} \ No newline at end of file +} diff --git a/services/security_component_service/sa/sa_main/first_use_dialog.cpp b/services/security_component_service/sa/sa_main/first_use_dialog.cpp index c92cd6c..688f848 100644 --- a/services/security_component_service/sa/sa_main/first_use_dialog.cpp +++ b/services/security_component_service/sa/sa_main/first_use_dialog.cpp @@ -52,13 +52,21 @@ const std::string WINDOW_ID_KEY = "ohos.ability.params.windowId"; const std::string CALLER_UID_KEY = "ohos.caller.uid"; const std::string DISPLAY_WIDTH = "ohos.display.width"; const std::string DISPLAY_HEIGHT = "ohos.display.height"; +const std::string DISPLAY_TOP = "ohos.display.top"; const std::string DIALOG_OFFSET = "ohos.dialog.offset"; +const std::string NOTIFY_TYPE = "ohos.ability.notify.type"; +const std::string TOAST_POSITION = "ohos.toast.position"; +const std::string TOAST_OFFSET = "ohos.toast.offset"; constexpr int32_t DISPLAY_HALF_RATIO = 2; constexpr uint32_t MAX_CFG_FILE_SIZE = 100 * 1024; // 100k constexpr uint64_t LOCATION_BUTTON_FIRST_USE = 1 << 0; constexpr uint64_t SAVE_BUTTON_FIRST_USE = 1 << 1; +constexpr int32_t ABOVE_BOTTOM_OFFSET = 80; +constexpr int32_t BELOW_TOP_OFFSET = 112; static std::mutex g_instanceMutex; +static std::unordered_map tipPositionsMap = {{TipPosition::ABOVE_BOTTOM, ABOVE_BOTTOM_OFFSET}, + {TipPosition::BELOW_TOP, BELOW_TOP_OFFSET}}; } void SecCompDialogSrvCallback::OnDialogClosed(int32_t result) @@ -302,10 +310,10 @@ int32_t FirstUseDialog::GrantDialogWaitEntity(int32_t scId) return res; } -bool FirstUseDialog::SetDialogInfo(AAFwk::Want& want, const uint64_t displayId, const CrossAxisState crossAxisState) +bool FirstUseDialog::SetDisplayInfo(AAFwk::Want& want, const DisplayInfo& displayInfo) { sptr display = - OHOS::Rosen::DisplayManager::GetInstance().GetDisplayById(displayId); + OHOS::Rosen::DisplayManager::GetInstance().GetDisplayById(displayInfo.displayId); if (display == nullptr) { SC_LOG_ERROR(LABEL, "Get display manager failed"); return false; @@ -321,7 +329,7 @@ bool FirstUseDialog::SetDialogInfo(AAFwk::Want& want, const uint64_t displayId, int32_t height = info->GetHeight(); int32_t offset = 0; /* crossAxisState is CROSS */ - if (crossAxisState == CrossAxisState::STATE_CROSS) { + if (displayInfo.crossAxisState == CrossAxisState::STATE_CROSS) { height = info->GetPhysicalHeight(); offset = static_cast(info->GetAvailableHeight()) / DISPLAY_HALF_RATIO; } @@ -334,6 +342,36 @@ bool FirstUseDialog::SetDialogInfo(AAFwk::Want& want, const uint64_t displayId, return true; } +void FirstUseDialog::StartToastAbility(const std::shared_ptr entity, + const sptr callerToken, const DisplayInfo& displayInfo) +{ + if (!entity->AllowToShowToast()) { + return; + } + bool needToShow = AccessToken::AccessTokenKit::IsToastShownNeeded(entity->pid_); + if (!needToShow) { + SC_LOG_INFO(LABEL, "Process pid=%{public}d needs not to show", entity->pid_); + return; + } + AAFwk::Want want; + want.SetElementName(GRANT_ABILITY_BUNDLE_NAME, GRANT_ABILITY_ABILITY_NAME); + want.SetParam(NOTIFY_TYPE, NotifyType::TOAST); + want.SetParam(TOAST_POSITION, entity->componentInfo_->tipPosition_); + want.SetParam(TOAST_OFFSET, tipPositionsMap[entity->componentInfo_->tipPosition_]); + int32_t superFoldOffsetY = 0; + if (entity->IsInPCVirtualScreen(displayInfo.crossAxisState)) { + superFoldOffsetY = displayInfo.superFoldOffsetY; + } + want.SetParam(DISPLAY_TOP, superFoldOffsetY); + if (!SetDisplayInfo(want, displayInfo)) { + SC_LOG_ERROR(LABEL, "Set display info failed."); + return; + } + + int startRes = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(want, callerToken); + SC_LOG_INFO(LABEL, "Start toast ability res %{public}d", startRes); +} + void FirstUseDialog::StartDialogAbility(std::shared_ptr entity, sptr callerToken, sptr dialogCallback, const DisplayInfo& displayInfo) { @@ -344,7 +382,7 @@ void FirstUseDialog::StartDialogAbility(std::shared_ptr entity, s } else if (type == SAVE_COMPONENT) { typeNum = 1; } else { - SC_LOG_ERROR(LABEL, "unknown type."); + SC_LOG_ERROR(LABEL, "Unknown type."); return; } int32_t scId = entity->scId_; @@ -361,15 +399,16 @@ void FirstUseDialog::StartDialogAbility(std::shared_ptr entity, s want.SetParam(TOKEN_KEY, callerToken); want.SetParam(CALLBACK_KEY, srvCallback); want.SetParam(WINDOW_ID_KEY, displayInfo.windowId); + want.SetParam(NOTIFY_TYPE, NotifyType::DIALOG); int32_t uid = IPCSkeleton::GetCallingUid(); want.SetParam(CALLER_UID_KEY, uid); - if (!SetDialogInfo(want, displayInfo.displayId, displayInfo.crossAxisState)) { - SC_LOG_ERROR(LABEL, "Set dialog info failed."); + if (!SetDisplayInfo(want, displayInfo)) { + SC_LOG_ERROR(LABEL, "Set display info failed."); return; } int startRes = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(want, callerToken); - SC_LOG_INFO(LABEL, "start ability res %{public}d", startRes); + SC_LOG_INFO(LABEL, "Start ability res %{public}d", startRes); if (startRes != 0) { dialogWaitMap_.erase(scId); } @@ -460,7 +499,8 @@ int32_t FirstUseDialog::NotifyFirstUseDialog(std::shared_ptr enti uint64_t compTypes = firstUseMap_[tokenId]; if ((compTypes & typeMask) == typeMask) { - SC_LOG_INFO(LABEL, "no need notify again."); + SC_LOG_INFO(LABEL, "no need notify dialog again."); + StartToastAbility(entity, callerToken, displayInfo); return SC_OK; } StartDialogAbility(entity, callerToken, dialogCallback, displayInfo); diff --git a/services/security_component_service/sa/sa_main/first_use_dialog.h b/services/security_component_service/sa/sa_main/first_use_dialog.h index a705d60..9ba63e2 100644 --- a/services/security_component_service/sa/sa_main/first_use_dialog.h +++ b/services/security_component_service/sa/sa_main/first_use_dialog.h @@ -56,6 +56,7 @@ struct DisplayInfo { const uint64_t displayId; const CrossAxisState crossAxisState; const int32_t windowId; + const int32_t superFoldOffsetY; }; static FirstUseDialog& GetInstance(); @@ -82,7 +83,9 @@ private: void SaveFirstUseRecord(void); void StartDialogAbility(std::shared_ptr entity, sptr callerToken, sptr dialogCallback, const DisplayInfo& displayInfo); - bool SetDialogInfo(AAFwk::Want& want, const uint64_t displayId, const CrossAxisState crossAxisState); + void StartToastAbility(const std::shared_ptr entity, const sptr callerToken, + const DisplayInfo& displayInfo); + bool SetDisplayInfo(AAFwk::Want& want, const DisplayInfo& displayInfo); void SendSaveEventHandler(void); std::mutex useMapMutex_; diff --git a/services/security_component_service/sa/sa_main/sec_comp_entity.cpp b/services/security_component_service/sa/sa_main/sec_comp_entity.cpp index d6a4d22..c38eb6d 100644 --- a/services/security_component_service/sa/sa_main/sec_comp_entity.cpp +++ b/services/security_component_service/sa/sa_main/sec_comp_entity.cpp @@ -121,7 +121,7 @@ bool SecCompEntity::IsInPCVirtualScreen(const CrossAxisState crossAxisState) con } int32_t SecCompEntity::CheckClickInfo(SecCompClickEvent& clickInfo, int32_t superFoldOffsetY, - const CrossAxisState crossAxisState, std::string& message) const + const CrossAxisState crossAxisState, std::string& message) { bool isInPCVirtualScreen = IsInPCVirtualScreen(crossAxisState); SC_LOG_INFO(LABEL, "The cross axis state: %{public}d, the fold offset y: %{public}d.", @@ -130,10 +130,13 @@ int32_t SecCompEntity::CheckClickInfo(SecCompClickEvent& clickInfo, int32_t supe clickInfo.point.touchY += superFoldOffsetY; componentInfo_->rect_.y_ += superFoldOffsetY; } + message.clear(); if (!WindowInfoHelper::CheckOtherWindowCoverComp(componentInfo_->windowId_, componentInfo_->rect_, message)) { SC_LOG_ERROR(LABEL, "Component may be covered by other window"); - return SC_SERVICE_ERROR_CLICK_EVENT_INVALID; + if (!AllowToBypassSecurityCheck(message)) { + return SC_SERVICE_ERROR_CLICK_EVENT_INVALID; + } } int32_t res = SC_SERVICE_ERROR_CLICK_EVENT_INVALID; diff --git a/services/security_component_service/sa/sa_main/sec_comp_entity.h b/services/security_component_service/sa/sa_main/sec_comp_entity.h index c49f970..83118b1 100644 --- a/services/security_component_service/sa/sa_main/sec_comp_entity.h +++ b/services/security_component_service/sa/sa_main/sec_comp_entity.h @@ -45,9 +45,46 @@ public: return isGrant_; } + void SetCustomAuthorizationStatus(bool isCustomAuthorized) + { + isCustomAuthorized_ = isCustomAuthorized; + } + + bool AllowToBypassSecurityCheck(const std::string& errMessage) + { + if (errMessage.empty()) { + return false; + } + if (!isCustomAuthorized_) { + return false; + } + if (GetType() != SecCompType::SAVE_COMPONENT) { + return false; + } + bypassSecurityCheck_ = true; + return true; + } + + bool AllowToShowToast() const + { + if (componentInfo_ == nullptr) { + return false; + } + if (!isCustomAuthorized_) { + return false; + } + if (GetType() != SecCompType::SAVE_COMPONENT) { + return false; + } + if (!(componentInfo_->isCustomizable_ || bypassSecurityCheck_)) { + return false; + } + return true; + } + bool CompareComponentBasicInfo(SecCompBase* other, bool isRectCheck) const; int32_t CheckClickInfo(SecCompClickEvent& clickInfo, int32_t superFoldOffsetY, const CrossAxisState crossAxisState, - std::string& message) const; + std::string& message); bool IsInPCVirtualScreen(const CrossAxisState crossAxisState) const; std::shared_ptr componentInfo_; @@ -55,6 +92,8 @@ public: int32_t scId_; int32_t pid_; int32_t uid_; + bool isCustomAuthorized_ = false; + bool bypassSecurityCheck_ = false; private: int32_t CheckKeyEvent(const SecCompClickEvent& clickInfo) const; diff --git a/services/security_component_service/sa/sa_main/sec_comp_info_helper.cpp b/services/security_component_service/sa/sa_main/sec_comp_info_helper.cpp index 71e67f3..ae6624c 100644 --- a/services/security_component_service/sa/sa_main/sec_comp_info_helper.cpp +++ b/services/security_component_service/sa/sa_main/sec_comp_info_helper.cpp @@ -64,6 +64,7 @@ SecCompBase* SecCompInfoHelper::ParseComponent(SecCompType type, const nlohmann: std::string& message, bool isClicked) { SecCompBase* comp = nullptr; + message.clear(); switch (type) { case LOCATION_COMPONENT: comp = ConstructComponent(jsonComponent, message, isClicked); @@ -189,6 +190,7 @@ bool SecCompInfoHelper::CheckRectValid(const SecCompRect& rect, const SecCompRec return false; } + message.clear(); if (IsOutOfScreen(rect, curScreenWidth, curScreenHeight, message, screenInfo.isWearable)) { return false; } diff --git a/services/security_component_service/sa/sa_main/sec_comp_manager.cpp b/services/security_component_service/sa/sa_main/sec_comp_manager.cpp index a1ae81c..cd92d96 100644 --- a/services/security_component_service/sa/sa_main/sec_comp_manager.cpp +++ b/services/security_component_service/sa/sa_main/sec_comp_manager.cpp @@ -42,6 +42,7 @@ static constexpr unsigned long REPORT_REMOTE_OBJECT_SIZE = 2UL; static std::mutex g_instanceMutex; const std::string START_DIALOG = "start dialog, onclick will be trap after dialog closed."; constexpr int32_t SA_ID_SECURITY_COMPONENT_SERVICE = 3506; +const std::string CUSTOMIZE_SAVE_BUTTON = "ohos.permission.CUSTOMIZE_SAVE_BUTTON"; } SecCompManager::SecCompManager() @@ -403,6 +404,8 @@ int32_t SecCompManager::RegisterSecurityComponent(SecCompType type, int32_t registerId = CreateScId(); std::shared_ptr entity = std::make_shared(component, caller.tokenId, registerId, caller.pid, caller.uid); + bool isCustomAuthorized = SecCompManager::GetInstance().HasCustomPermissionForSecComp(); + entity->SetCustomAuthorizationStatus(isCustomAuthorized); int32_t ret = AddSecurityComponentToList(caller.pid, caller.tokenId, entity); if (ret == SC_OK) { scId = registerId; @@ -483,7 +486,13 @@ int32_t SecCompManager::CheckClickSecurityComponentInfo(std::shared_ptrGetType()); - return SC_SERVICE_ERROR_COMPONENT_INFO_INVALID; + /** + * If the ptr of reportComponentInfo is not nullptr, the string of message is not empty only when the icon of + * save button is picture. + */ + if (!(reportComponentInfo && sc->AllowToBypassSecurityCheck(message))) { + return SC_SERVICE_ERROR_COMPONENT_INFO_INVALID; + } } if (report && (report->isClipped_ || report->hasNonCompatibleChange_)) { HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "CLIP_CHECK_FAILED", @@ -491,12 +500,7 @@ int32_t SecCompManager::CheckClickSecurityComponentInfo(std::shared_ptrdisplayId_, - .crossAxisState = report->crossAxisState_, - .isWearable = report->isWearableDevice_ - }; - + SecCompInfoHelper::ScreenInfo screenInfo = {report->displayId_, report->crossAxisState_, report->isWearableDevice_}; if ((!SecCompInfoHelper::CheckRectValid(reportComponentInfo->rect_, reportComponentInfo->windowRect_, screenInfo, message))) { SC_LOG_ERROR(LABEL, "compare component info failed."); @@ -504,7 +508,9 @@ int32_t SecCompManager::CheckClickSecurityComponentInfo(std::shared_ptrGetType()); - return SC_SERVICE_ERROR_COMPONENT_INFO_INVALID; + if (!sc->AllowToBypassSecurityCheck(message)) { + return SC_SERVICE_ERROR_COMPONENT_INFO_INVALID; + } } int32_t enhanceRes = SecCompEnhanceAdapter::CheckComponentInfoEnhance(caller.pid, reportComponentInfo, jsonComponent); @@ -554,8 +560,8 @@ void SecCompManager::GetFoldOffsetY(const CrossAxisState crossAxisState) SC_LOG_INFO(LABEL, "height: %{public}d, posY: %{public}d", rect.height_, rect.posY_); } -int32_t SecCompManager::ReportSecurityComponentClickEvent(SecCompInfo& info, const nlohmann::json& compJson, - const SecCompCallerInfo& caller, const std::vector>& remote, std::string& message) +int32_t SecCompManager::CheckClickEventParams(const SecCompCallerInfo& caller, + const std::vector>& remote) { if (remote.size() < REPORT_REMOTE_OBJECT_SIZE) { SC_LOG_ERROR(LABEL, "remote object size is invalid"); @@ -565,26 +571,35 @@ int32_t SecCompManager::ReportSecurityComponentClickEvent(SecCompInfo& info, con SC_LOG_ERROR(LABEL, "app is in MaliciousAppList, never allow it"); return SC_ENHANCE_ERROR_IN_MALICIOUS_LIST; } + return SC_OK; +} +int32_t SecCompManager::ReportSecurityComponentClickEvent(SecCompInfo& info, const nlohmann::json& compJson, + const SecCompCallerInfo& caller, const std::vector>& remote, std::string& message) +{ + int32_t res = CheckClickEventParams(caller, remote); + if (res != SC_OK) { + return res; + } OHOS::Utils::UniqueReadGuard lk(this->componentInfoLock_); std::shared_ptr sc = GetSecurityComponentFromList(caller.pid, info.scId); if (sc == nullptr) { SC_LOG_ERROR(LABEL, "Can not find target component"); return SC_SERVICE_ERROR_COMPONENT_NOT_EXIST; } - int32_t res = CheckClickSecurityComponentInfo(sc, info.scId, compJson, caller, message); + if (!message.empty()) { + if (!sc->AllowToBypassSecurityCheck(message)) { + return SC_SERVICE_ERROR_CLICK_EVENT_INVALID; + } + } + res = CheckClickSecurityComponentInfo(sc, info.scId, compJson, caller, message); if (res != SC_OK) { return res; } - SecCompBase* reportComponentInfo = SecCompInfoHelper::ParseComponent(sc->GetType(), compJson, message, true); - std::shared_ptr report(reportComponentInfo); - if (report == nullptr) { - return SC_SERVICE_ERROR_COMPONENT_INFO_INVALID; - } - GetFoldOffsetY(report->crossAxisState_); + GetFoldOffsetY(sc->componentInfo_->crossAxisState_); - res = sc->CheckClickInfo(info.clickInfo, superFoldOffsetY_, report->crossAxisState_, message); + res = sc->CheckClickInfo(info.clickInfo, superFoldOffsetY_, sc->componentInfo_->crossAxisState_, message); if (res != SC_OK) { ReportEvent("CLICK_INFO_CHECK_FAILED", HiviewDFX::HiSysEvent::EventType::SECURITY, info.scId, sc->GetType()); @@ -595,7 +610,8 @@ int32_t SecCompManager::ReportSecurityComponentClickEvent(SecCompInfo& info, con return SC_SERVICE_ERROR_CLICK_EVENT_INVALID; } - const FirstUseDialog::DisplayInfo displayInfo = {report->displayId_, report->crossAxisState_, report->windowId_}; + const FirstUseDialog::DisplayInfo displayInfo = {sc->componentInfo_->displayId_, + sc->componentInfo_->crossAxisState_, sc->componentInfo_->windowId_, superFoldOffsetY_}; if (FirstUseDialog::GetInstance().NotifyFirstUseDialog(sc, remote[0], remote[1], displayInfo) == SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE) { @@ -662,6 +678,17 @@ bool SecCompManager::Initialize() return true; } + +bool SecCompManager::HasCustomPermissionForSecComp() +{ + uint32_t callingTokenID = IPCSkeleton::GetCallingTokenID(); + if (AccessToken::AccessTokenKit::VerifyAccessToken(callingTokenID, CUSTOMIZE_SAVE_BUTTON) == + AccessToken::TypePermissionState::PERMISSION_GRANTED) { + return true; + } + SC_LOG_INFO(LABEL, "Permission denied(tokenID=%{public}d)", callingTokenID); + return false; +} } // namespace SecurityComponent } // namespace Security } // namespace OHOS diff --git a/services/security_component_service/sa/sa_main/sec_comp_manager.h b/services/security_component_service/sa/sa_main/sec_comp_manager.h index a477be9..f8b6488 100644 --- a/services/security_component_service/sa/sa_main/sec_comp_manager.h +++ b/services/security_component_service/sa/sa_main/sec_comp_manager.h @@ -59,6 +59,7 @@ public: int32_t UnregisterSecurityComponent(int32_t scId, const SecCompCallerInfo& caller); int32_t ReportSecurityComponentClickEvent(SecCompInfo& secCompInfo, const nlohmann::json& jsonComponent, const SecCompCallerInfo& caller, const std::vector>& remote, std::string& message); + int32_t CheckClickEventParams(const SecCompCallerInfo& caller, const std::vector>& remote); void NotifyProcessForeground(int32_t pid); void NotifyProcessBackground(int32_t pid); void NotifyProcessDied(int32_t pid, bool isProcessCached); @@ -67,6 +68,7 @@ public: void ExitSaProcess(); void ExitWhenAppMgrDied(); int32_t AddSecurityComponentProcess(const SecCompCallerInfo& caller); + bool HasCustomPermissionForSecComp(); private: SecCompManager(); diff --git a/services/security_component_service/sa/sa_main/sec_comp_service.cpp b/services/security_component_service/sa/sa_main/sec_comp_service.cpp index 23f0c63..c08c300 100644 --- a/services/security_component_service/sa/sa_main/sec_comp_service.cpp +++ b/services/security_component_service/sa/sa_main/sec_comp_service.cpp @@ -531,6 +531,12 @@ int32_t SecCompService::ReportSecurityComponentClickEvent(const sptr clickInfoParcel = deserializedData.ReadParcelable(); if (clickInfoParcel == nullptr) { SC_LOG_ERROR(LABEL, "Report read clickInfo info failed"); @@ -539,7 +545,6 @@ int32_t SecCompService::ReportSecurityComponentClickEvent(const sptrclickInfoParams_ }; - std::string message; res = ReportSecurityComponentClickEventBody(secCompInfo, callerToken, dialogCallback, message); res = ReportWriteToRawdata(res, message, rawReply); } while (0); @@ -626,6 +631,12 @@ int32_t SecCompService::VerifySavePermission(AccessToken::AccessTokenID tokenId, return SC_OK; } +int32_t SecCompService::HasCustomPermissionForSecComp(bool& hasCustomPermission) +{ + hasCustomPermission = SecCompManager::GetInstance().HasCustomPermissionForSecComp(); + return SC_OK; +} + bool SecCompService::IsMediaLibraryCalling() { int32_t uid = IPCSkeleton::GetCallingUid(); diff --git a/services/security_component_service/sa/sa_main/sec_comp_service.h b/services/security_component_service/sa/sa_main/sec_comp_service.h index 10bfd0e..077e13a 100644 --- a/services/security_component_service/sa/sa_main/sec_comp_service.h +++ b/services/security_component_service/sa/sa_main/sec_comp_service.h @@ -52,6 +52,7 @@ public: const sptr& dialogCallback, const SecCompRawdata& rawData, SecCompRawdata& rawReply) override; int32_t VerifySavePermission(AccessToken::AccessTokenID tokenId, bool& isGranted) override; int32_t PreRegisterSecCompProcess(const SecCompRawdata& rawData, SecCompRawdata& rawReply) override; + int32_t HasCustomPermissionForSecComp(bool& hasCustomPermission) override; int Dump(int fd, const std::vector& args) override; diff --git a/services/security_component_service/sa/test/mock/include/accesstoken_kit.h b/services/security_component_service/sa/test/mock/include/accesstoken_kit.h index 7e660bb..2300be9 100644 --- a/services/security_component_service/sa/test/mock/include/accesstoken_kit.h +++ b/services/security_component_service/sa/test/mock/include/accesstoken_kit.h @@ -62,6 +62,11 @@ public: return static_cast(idInner->dlpFlag); } + static bool IsToastShownNeeded(int32_t pid) + { + return false; + } + static std::mutex mutex_; static std::map> permMap_; static int getHapTokenInfoRes; diff --git a/services/security_component_service/sa/test/unittest/src/first_use_dialog_test.cpp b/services/security_component_service/sa/test/unittest/src/first_use_dialog_test.cpp index cada115..dadebff 100644 --- a/services/security_component_service/sa/test/unittest/src/first_use_dialog_test.cpp +++ b/services/security_component_service/sa/test/unittest/src/first_use_dialog_test.cpp @@ -459,6 +459,50 @@ HWTEST_F(FirstUseDialogTest, NotifyFirstUseDialog001, TestSize.Level0) sleep(3); } +/* + * @tc.name: NotifyFirstUseDialog002 + * @tc.desc: Test NotifyFirstUseDialog + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(FirstUseDialogTest, NotifyFirstUseDialog002, TestSize.Level0) +{ + FirstUseDialog diag; + diag.secHandler_ = nullptr; + + const FirstUseDialog::DisplayInfo displayInfo = {0, CrossAxisState::STATE_INVALID, 0}; + + // entity + std::shared_ptr entity = std::make_shared(nullptr, 0, 0, 0, 0); + std::shared_ptr runner = AppExecFwk::EventRunner::Create(true); + ASSERT_NE(nullptr, runner); + // handler + std::shared_ptr handler = std::make_shared(runner); + diag.secHandler_ = handler; + + sptr testRemoteObject = new TestRemoteObject(std::u16string()); + // first use save button + entity->componentInfo_ = std::make_shared(); + entity->componentInfo_->type_ = SAVE_COMPONENT; + entity->tokenId_ = 0; + EXPECT_EQ(diag.NotifyFirstUseDialog(entity, testRemoteObject, testRemoteObject, displayInfo), + SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE); + EXPECT_EQ(0, static_cast(diag.firstUseMap_[0])); + + // second use save button + EXPECT_EQ(diag.NotifyFirstUseDialog(entity, testRemoteObject, testRemoteObject, displayInfo), + SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE); + EXPECT_EQ(0, static_cast(diag.firstUseMap_[0])); + + entity->isCustomAuthorized_ = true; + std::string message = "message"; + EXPECT_EQ(true, entity->AllowToBypassSecurityCheck(message)); + diag.StartToastAbility(entity, testRemoteObject, displayInfo); + + // wait for event handler done + sleep(3); +} + /* * @tc.name: GrantDialogWaitEntity001 * @tc.desc: Test GrantDialogWaitEntity diff --git a/services/security_component_service/sa/test/unittest/src/sec_comp_service_mock_test.cpp b/services/security_component_service/sa/test/unittest/src/sec_comp_service_mock_test.cpp index 6c554cd..4b24313 100644 --- a/services/security_component_service/sa/test/unittest/src/sec_comp_service_mock_test.cpp +++ b/services/security_component_service/sa/test/unittest/src/sec_comp_service_mock_test.cpp @@ -844,6 +844,8 @@ HWTEST_F(SecCompServiceMockTest, ReportSecurityComponentClickEvent002, TestSize. MessageParcel data; data.WriteInt32(scId); data.WriteString(locationInfo); + std::string message = ""; + data.WriteString(message); sptr parcel = new (std::nothrow) SecCompClickEventParcel(); ASSERT_NE(nullptr, parcel); parcel->clickInfoParams_ = clickInfo1; @@ -857,4 +859,4 @@ HWTEST_F(SecCompServiceMockTest, ReportSecurityComponentClickEvent002, TestSize. secCompService_->ReportSecurityComponentClickEvent(nullptr, nullptr, rawdata, rawReply)); ASSERT_TRUE(SecCompEnhanceAdapter::EnhanceSrvDeserialize(rawReply, reply)); EXPECT_EQ(SC_OK, reply.ReadInt32()); -} \ No newline at end of file +} diff --git a/services/security_component_service/sa/test/unittest/src/sec_comp_stub_mock_test.h b/services/security_component_service/sa/test/unittest/src/sec_comp_stub_mock_test.h index a68bd85..711b18a 100644 --- a/services/security_component_service/sa/test/unittest/src/sec_comp_stub_mock_test.h +++ b/services/security_component_service/sa/test/unittest/src/sec_comp_stub_mock_test.h @@ -58,6 +58,12 @@ public: { return 0; }; + + int32_t HasCustomPermissionForSecComp(bool& hasCustomPermission) override + { + hasCustomPermission = false; + return 0; + }; }; class SecCompStubMockTest : public testing::Test { diff --git a/services/security_component_service/sa/test/unittest/src/sec_comp_stub_test.h b/services/security_component_service/sa/test/unittest/src/sec_comp_stub_test.h index e5112e4..8091b15 100644 --- a/services/security_component_service/sa/test/unittest/src/sec_comp_stub_test.h +++ b/services/security_component_service/sa/test/unittest/src/sec_comp_stub_test.h @@ -57,6 +57,12 @@ public: { return 0; }; + + int32_t HasCustomPermissionForSecComp(bool& hasCustomPermission) override + { + hasCustomPermission = false; + return 0; + }; }; class SecCompStubTest : public testing::Test { diff --git a/services/security_component_service/sa/test/unittest/src/service_test_common.cpp b/services/security_component_service/sa/test/unittest/src/service_test_common.cpp index 88fd914..12bab4e 100644 --- a/services/security_component_service/sa/test/unittest/src/service_test_common.cpp +++ b/services/security_component_service/sa/test/unittest/src/service_test_common.cpp @@ -90,6 +90,8 @@ void ServiceTestCommon::BuildLocationComponentJson(nlohmann::json& jsonComponent jsonComponent[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = 0.0; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = false; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = false; + jsonComponent[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = false; + jsonComponent[JsonTagConstants::JSON_TIP_POSITION] = TipPosition::ABOVE_BOTTOM; } void ServiceTestCommon::BuildSaveComponentJson(nlohmann::json& jsonComponent) @@ -164,6 +166,8 @@ void ServiceTestCommon::BuildSaveComponentJson(nlohmann::json& jsonComponent) jsonComponent[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = 0.0; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = false; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = false; + jsonComponent[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = false; + jsonComponent[JsonTagConstants::JSON_TIP_POSITION] = TipPosition::ABOVE_BOTTOM; } void ServiceTestCommon::BuildPasteComponentJson(nlohmann::json& jsonComponent) @@ -238,6 +242,8 @@ void ServiceTestCommon::BuildPasteComponentJson(nlohmann::json& jsonComponent) jsonComponent[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = 0.0; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = false; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = false; + jsonComponent[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = false; + jsonComponent[JsonTagConstants::JSON_TIP_POSITION] = TipPosition::ABOVE_BOTTOM; } } // namespace SecurityComponent } // namespace Security diff --git a/test/fuzztest/security_component/common/fuzz_common.cpp b/test/fuzztest/security_component/common/fuzz_common.cpp index 072c8af..b3786a1 100644 --- a/test/fuzztest/security_component/common/fuzz_common.cpp +++ b/test/fuzztest/security_component/common/fuzz_common.cpp @@ -107,6 +107,8 @@ std::string CompoRandomGenerator::ConstructLocationJson() jsonComponent[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = 0.0; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = false; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = false; + jsonComponent[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = false; + jsonComponent[JsonTagConstants::JSON_TIP_POSITION] = TipPosition::ABOVE_BOTTOM; compoJson_ = jsonComponent; return compoJson_.dump(); } @@ -160,6 +162,8 @@ std::string CompoRandomGenerator::ConstructSaveJson() jsonComponent[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = 0.0; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = false; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = false; + jsonComponent[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = false; + jsonComponent[JsonTagConstants::JSON_TIP_POSITION] = TipPosition::ABOVE_BOTTOM; compoJson_ = jsonComponent; return compoJson_.dump(); } @@ -213,6 +217,8 @@ std::string CompoRandomGenerator::ConstructPasteJson() jsonComponent[JsonTagConstants::JSON_FOREGROUND_BLUR_RADIUS_TAG] = 0.0; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_TEXT_SET_TAG] = false; jsonComponent[JsonTagConstants::JSON_IS_OVERLAY_NODE_SET_TAG] = false; + jsonComponent[JsonTagConstants::JSON_IS_CUSTOMIZABLE] = false; + jsonComponent[JsonTagConstants::JSON_TIP_POSITION] = TipPosition::ABOVE_BOTTOM; compoJson_ = jsonComponent; return compoJson_.dump(); } -- Gitee