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 a48f18b1b1d36ae34b25cb358783e8823b164b42..46328a4c4dcc850097c19e6b349cf56601eb6513 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 99fa80a23e9af8e86e9ac63f852e5f8c52ea41d1..3fa48ad03230a9e91a68faf15d942ec2438296dc 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 ed6d3d033ea57a13776201f842cf23fa7a2241c5..0708f2077d08ffc5e724a97b2c7c4adfb3bc8566 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 970abec21be19fe31bc960c94b6ca50b2f17ae73..81f5b33731f6aa79c5142221c401e8842cbf3d15 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 235c4a85e12b8d2278a4e2e5a28e8334aee50bad..a011484fb38df081d908439a39091a0e12441f94 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 f8b4261fb250aa140350fdc5d3851c04c6c6c83d..17f04178edce48665dc0547ee62b6464c913dce1 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 78c87e921e98c94273c417f15112f1636401bd6f..b6e091f30c377e1cd53f065a5a8b2a09e775ad29 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 a1d250ed8129af01018596b409c5e542807ac566..e95c5ff3ad211acf79298971186d1b2b569d3c5a 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 f81aadc35277cc43a1d7ee55ba98280bdcea468b..6ff6a0841481ad8bd4f7a5dc11eb260964758e01 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 7b0db4d282f618dd1f2917e72abf1744adabb5c9..92370c1941cfb8b58b7dbafa77cef1777967b180 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 5973e7e6c5f67891af2e97bbfe62abc7200d8427..8686e801de421125919c06f4231fa9a51e26fff1 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 c92cd6cb7e4b0c375edbac1eb04a0b5ebed754b8..688f848f41bcf621c14dbb3f7c40750230a2793d 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 a705d6057e264d75adbca39c1c5bcea925ec7f9f..9ba63e293f97c66801e7ce1630f9a7637429b4ef 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 d6a4d22e6ff96bf0c8c2ce6a9b5fd8b1dcb13146..c38eb6dd5df8fb87e8578a9099d2b983de15ee14 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 c49f970b29e0ae6dd10350f2838eb2ecfce6bb28..83118b12bbba509ee40b1aca5dc81f2097aeda4f 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 71e67f3662703fd181c9e89be726e7bb38f2125b..ae6624c88baa05a84343bd6cb7005408b0cb96ed 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 a1ae81c617ab6736b024a52ccc6e0ba357cdcac1..cd92d9625c548cc2d9ab055bf600360ddb905425 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 a477be90d19046a343707edad751672b60634590..f8b6488b2f12802846bbe33775b05eedb3dadffa 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 23f0c638d5636e6ab64d4d0f9b0dd6c158320a27..c08c300f499c42809dafb8c9e8b0aade8a7a10fd 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 10bfd0e42a9142690518334ca45a9a29b2a109b4..077e13ad066ca4baa4ad2da16dbb2593d9718051 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 7e660bb4af9443ff987e274a4e56fc5c31be75ea..2300be9978446422a9b6b6471e24a1ad896036ee 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 cada115572ba23af21b9e469b705d73b440987ce..dadebff3f2a882218da8021f1f45c1c921904f0e 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 6c554cdc22bce514665521de787e100572d56080..4b24313606d715f09cd24347bda9703e3ce05da9 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 a68bd853822f989736aef8baba10388631b640a7..711b18ab699c9c1750c6c0586e21d857611ee49c 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 e5112e49cab8e702456047707c80df1219f091fd..8091b153ecb574b778b83a6255f4e0b4b35886f0 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 88fd91498ca4cf5f346276abc36f20ee3c02e988..12bab4e8358c3b272ff178a42b0877798df988df 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 072c8afd52aa2a9e9c7ab9eb5f093273588e73cc..b3786a14a690bb5afd93fc71fabeb20634008e15 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(); }