diff --git a/common/include/dm_error_type.h b/common/include/dm_error_type.h index 2582e6da1b0c56b33cfa3c4823c64c0c1ad317bc..1c5128cefdb769e8135d19ae0a19905ea3b071c3 100644 --- a/common/include/dm_error_type.h +++ b/common/include/dm_error_type.h @@ -135,11 +135,12 @@ enum { ERR_DM_SHOW_CONFIRM_FAILED = 969298347, ERR_DM_PARSE_MESSAGE_FAILED = 969298348, ERR_DM_GET_BMS_FAILED = 969298349, - ERR_DM_GET_BUNDLE_NAME_FAILED = 969298349, + ERR_DM_GET_BUNDLE_NAME_FAILED = 969298354, ERR_DM_DESERIAL_CERT_FAILED = 969298350, ERR_DM_VERIFY_CERT_FAILED = 969298351, ERR_DM_GET_PARAM_FAILED = 969298352, ERR_DM_VERIFY_SAME_ACCOUNT_FAILED = 969298353, + ERR_DM_DEVICE_FREEZED = 969298355, }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/implementation/BUILD.gn b/services/implementation/BUILD.gn index 8bf0856665a610e485ef7eb2e2b0e32c883c31e1..a0acf9c811cae459e920f53b6d66ecaa931f3cd0 100644 --- a/services/implementation/BUILD.gn +++ b/services/implementation/BUILD.gn @@ -195,6 +195,7 @@ if (defined(ohos_lite)) { "src/authentication_v2/dm_auth_state.cpp", "src/authentication_v2/dm_auth_state_machine.cpp", "src/authentication_v2/dm_negotiate_process.cpp", + "src/authentication_v2/dm_freeze_process.cpp", "src/config/dm_config_manager.cpp", "src/credential/dm_credential_manager.cpp", "src/cryptomgr/crypto_mgr.cpp", diff --git a/services/implementation/include/authentication_v2/dm_freeze_process.h b/services/implementation/include/authentication_v2/dm_freeze_process.h new file mode 100644 index 0000000000000000000000000000000000000000..7b844f5addf3cccd76bb6253438093cb39e54bfe --- /dev/null +++ b/services/implementation/include/authentication_v2/dm_freeze_process.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_DM_FREEZE_PROCESS_V2_H +#define OHOS_DM_FREEZE_PROCESS_V2_H +#include +#include +#include + +#include "kv_adapter_manager.h" +#include "dm_single_instance.h" + +namespace OHOS { +namespace DistributedHardware { +typedef struct DeviceFreezeState { + int64_t startFreezeTimeStamp; + int64_t stopFreezeTimeStamp; + explicit DeviceFreezeState() : startFreezeTimeStamp(0), stopFreezeTimeStamp(0) {} + bool IsEmpty() const + { + return startFreezeTimeStamp == 0 && stopFreezeTimeStamp == 0; + } + void Reset() + { + startFreezeTimeStamp = 0; + stopFreezeTimeStamp = 0; + } +} DeviceFreezeState; + +typedef struct BindFailedEvents { + std::vector failedTimeStamps; + std::vector freezeTimeStamps; + explicit BindFailedEvents() : failedTimeStamps(), freezeTimeStamps() {} + bool IsEmpty() const + { + return failedTimeStamps.empty() && freezeTimeStamps.empty(); + } + void Reset() + { + failedTimeStamps.clear(); + freezeTimeStamps.clear(); + } +} BindFailedEvents; + +class FreezeProcess { +DM_DECLARE_SINGLE_INSTANCE_BASE(FreezeProcess); +public: + int32_t SyncFreezeData(); + bool IsFreezed(const std::string &bundleName, int32_t deviceType); + int32_t CleanFreezeRecord(const std::string &bundleName, int32_t deviceType); + int32_t DeleteFreezeRecord(const std::string &bundleName, int32_t deviceType); + int32_t UpdateFreezeRecord(const std::string &bundleName, int32_t deviceType); +private: + FreezeProcess() = default; + ~FreezeProcess() = default; + void ConvertJsonToDeviceFreezeState(const std::string &result, DeviceFreezeState &freezeStateObj); + void ConvertJsonToBindFailedEvents(const std::string &result, BindFailedEvents &bindFailedEvents); + void ConvertBindFailedEventsToJson(const BindFailedEvents &value, std::string &result); + void ConvertDeviceFreezeStateToJson(const DeviceFreezeState &value, std::string &result); + int32_t CleanBindFailedEvents(int64_t reservedDataTimeStamp); + int32_t CleanFreezeState(int64_t reservedDataTimeStamp); + int32_t UpdateFreezeState(int64_t nowTime); + void CalculateNextFreezeTime(int64_t nowFreezeTime, int64_t nextFreezeTime); + +private: + DeviceFreezeState freezeStateCache_; + BindFailedEvents bindFailedEventsCache_; + std::mutex freezeStateCacheMtx_; + std::mutex bindFailedEventsCacheMtx_; +}; + +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_FREEZE_PROCESS_V2_H \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp index d4ad34fae0b13352353a97b29234f8cad518bc87..727dfef398fca73269d3c467ce1c894f26266d5b 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp @@ -23,6 +23,7 @@ #include "dm_auth_state_machine.h" #include "dm_constants.h" #include "dm_crypto.h" +#include "dm_freeze_process.h" #include "multiple_user_connector.h" namespace OHOS { @@ -110,6 +111,18 @@ int32_t AuthSinkFinishState::Action(std::shared_ptr context) { LOGI("AuthSinkFinishState::Action start"); context->state = static_cast(GetStateType()); + int32_t ret = DM_OK; + LOGI("reason: %{public}d", context->reason); + if (context->reason == DM_OK) { + ret = FreezeProcess::GetInstance().DeleteFreezeRecord(context->accessee.bundleName, + context->accessee.deviceType); + LOGI("DeleteFreezeRecord ret: %{public}d", ret); + } + if (context->reason != DM_OK && context->reason != ERR_DM_DEVICE_FREEZED) { + ret = FreezeProcess::GetInstance().UpdateFreezeRecord(context->accessee.bundleName, + context->accessee.deviceType); + LOGI("UpdateFreezeData ret: %{public}d", ret); + } SinkFinish(context); LOGI("AuthSinkFinishState::Action ok"); if (context->cleanNotifyCallback != nullptr) { diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp index 45520435e26b0eeb64754304508592fadef847da..14046e717fe6a0086022b26ca9889df3a68207fc 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp @@ -32,6 +32,7 @@ #include "dm_random.h" #include "dm_auth_context.h" #include "dm_auth_state.h" +#include "dm_freeze_process.h" #include "deviceprofile_connector.h" #include "distributed_device_profile_errors.h" #include "device_auth.h" @@ -160,6 +161,7 @@ int32_t AuthSinkNegotiateStateMachine::RespQueryAcceseeIds(std::shared_ptraccessee.language = DmLanguageManager::GetInstance().GetSystemLanguage(); context->accessee.deviceName = context->listener->GetLocalDisplayDeviceNameForPrivacy(); context->accessee.networkId = context->softbusConnector->GetLocalDeviceNetworkId(); + context->accessee.deviceType = context->softbusConnector->GetLocalDeviceTypeId(); return DM_OK; } @@ -223,6 +225,10 @@ int32_t VerifyCertificate(std::shared_ptr context) int32_t AuthSinkNegotiateStateMachine::Action(std::shared_ptr context) { LOGI("AuthSinkNegotiateStateMachine::Action sessionid %{public}d", context->sessionId); + if (FreezeProcess::GetInstance().IsFreezed(context->accessee.bundleName, context->accessee.deviceType)) { + LOGE("Device is Freezed"); + return ERR_DM_DEVICE_FREEZED; + } // 1. Create an authorization timer if (context->timer != nullptr) { context->timer->StartTimer(std::string(AUTHENTICATE_TIMEOUT_TASK), diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp index 532809c3e2787957d7b2b30c87bfc14e487fe375..af1d2ed5a09654da93fcb1e510d0ec7d89fa6ef5 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp @@ -22,6 +22,7 @@ #include "dm_auth_state.h" #include "dm_auth_state_machine.h" #include "dm_dialog_manager.h" +#include "dm_freeze_process.h" #include "dm_log.h" #include "dm_negotiate_process.h" #include "dm_random.h" @@ -181,7 +182,10 @@ int32_t AuthSinkPinAuthStartState::Action(std::shared_ptr context LOGE("AuthSinkPinAuthStartState::Action invalid parameter."); return ERR_DM_INPUT_PARA_INVALID; } - + if (FreezeProcess::GetInstance().CleanFreezeRecord(context->accessee.bundleName, + context->accessee.deviceType) != DM_OK) { + LOGE("CleanFreezeRecord failed."); + } // process pincode auth auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); if (ret != DM_OK) { @@ -758,6 +762,10 @@ int32_t AuthSinkReverseUltrasonicDoneState::Action(std::shared_ptrtimer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); context->timer->DeleteTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK)); context->pinNegotiateStarted = true; + if (FreezeProcess::GetInstance().CleanFreezeRecord(context->accessee.bundleName, + context->accessee.deviceType) != DM_OK) { + LOGE("CleanFreezeRecord failed."); + } auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); if (ret != DM_OK) { LOGE("AuthSinkPinAuthStartState::Action call ProcessCredData err"); @@ -813,6 +821,10 @@ int32_t AuthSinkForwardUltrasonicDoneState::Action(std::shared_ptrtimer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); context->timer->DeleteTimer(std::string(GET_ULTRASONIC_PIN_TIMEOUT_TASK)); context->pinNegotiateStarted = true; + if (FreezeProcess::GetInstance().CleanFreezeRecord(context->accessee.bundleName, + context->accessee.deviceType) != DM_OK) { + LOGE("CleanFreezeRecord failed."); + } auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); if (ret != DM_OK) { LOGE("AuthSinkForwardUltrasonicDoneState::Action call ProcessCredData err"); diff --git a/services/implementation/src/authentication_v2/dm_freeze_process.cpp b/services/implementation/src/authentication_v2/dm_freeze_process.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ff6b52d75ab6cd00da3d80fa3d6902f08d982c40 --- /dev/null +++ b/services/implementation/src/authentication_v2/dm_freeze_process.cpp @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "dm_freeze_process.h" + +#include "cJSON.h" +#include "datetime_ex.h" +#include "dm_anonymous.h" +#include "dm_device_info.h" +#include "dm_error_type.h" +#include "dm_log.h" + +namespace OHOS { +namespace DistributedHardware { +namespace { +constexpr const char* BIND_FAILED_EVENTS_KEY = "bindFailedEvents"; +constexpr const char* FREEZE_STATE_KEY = "freezeState"; +constexpr const char* START_FREEZE_TIME_KEY = "startFreezeTimeStamp"; +constexpr const char* STOP_FREEZE_TIME_KEY = "stopFreezeTimeStamp"; +constexpr const char* FAILED_TIMES_STAMPS_KEY = "failedTimeStamps"; +constexpr const char* FREEZE_TIMES_STAMPS_KEY = "freezeTimeStamps"; +constexpr const char* CAST_BUNDLE_NAME = "cast_engine_service"; +constexpr int32_t MAX_CONTINUEOUS_BIND_FAILED_NUM = 2; +constexpr int64_t CONTINUEOUS_FAILED_INTERVAL = 6 * 60; +constexpr int64_t DATA_REFRESH_INTERVAL = 20 * 60; +constexpr int64_t NOT_FREEZE_TIME = 0; +constexpr int64_t FIRST_FREEZE_TIME = 60; +constexpr int64_t SECOND_FREEZE_TIME = 3 * 60; +constexpr int64_t THIRD_FREEZE_TIME = 5 * 60; +constexpr int64_t MAX_FREEZE_TIME = 10 * 60; +} + +DM_IMPLEMENT_SINGLE_INSTANCE(FreezeProcess); + +int32_t FreezeProcess::SyncFreezeData() +{ + LOGI("called"); + std::string freezeStatesValue; + int32_t ret = KVAdapterManager::GetInstance().GetFreezeData(FREEZE_STATE_KEY, freezeStatesValue); + if (ret != DM_OK) { + LOGE("Get freeze states data failed, ret: %{public}d", ret); + return ret; + } + DeviceFreezeState freezeStateObj; + ConvertJsonToDeviceFreezeState(freezeStatesValue, freezeStateObj); + { + std::lock_guard lock(freezeStateCacheMtx_); + freezeStateCache_ = freezeStateObj; + } + std::string bindFailedEventsValue; + ret = KVAdapterManager::GetInstance().GetFreezeData(BIND_FAILED_EVENTS_KEY, bindFailedEventsValue); + if (ret != DM_OK) { + LOGE("Get bind failed events data failed, ret: %{public}d", ret); + return ret; + } + BindFailedEvents bindFailedEventsObj; + ConvertJsonToBindFailedEvents(bindFailedEventsValue, bindFailedEventsObj); + std::lock_guard lock(bindFailedEventsCacheMtx_); + bindFailedEventsCache_ = bindFailedEventsObj; + LOGI("Sync freeze data success"); + return DM_OK; +} + +void FreezeProcess::ConvertJsonToDeviceFreezeState(const std::string &result, DeviceFreezeState &freezeStateObj) +{ + if (result.empty()) { + LOGE("result is empty"); + return; + } + cJSON *root = cJSON_Parse(result.c_str()); + if (root == nullptr) { + LOGE("cJSON_Parse failed"); + return; + } + cJSON *startFreezeTimeStampItem = cJSON_GetObjectItemCaseSensitive(root, START_FREEZE_TIME_KEY); + if (startFreezeTimeStampItem != nullptr && cJSON_IsNumber(startFreezeTimeStampItem)) { + freezeStateObj.startFreezeTimeStamp = startFreezeTimeStampItem->valueint; + } + cJSON *stopFreezeTimeStampItem = cJSON_GetObjectItemCaseSensitive(root, STOP_FREEZE_TIME_KEY); + if (stopFreezeTimeStampItem != nullptr && cJSON_IsNumber(stopFreezeTimeStampItem)) { + freezeStateObj.stopFreezeTimeStamp = stopFreezeTimeStampItem->valueint; + } + LOGI("ConvertJsonToDeviceFreezeState success"); + cJSON_Delete(root); +} + +void FreezeProcess::ConvertJsonToBindFailedEvents(const std::string &result, BindFailedEvents &bindFailedEventsObj) +{ + if (result.empty()) { + LOGE("result is empty"); + return; + } + cJSON *root = cJSON_Parse(result.c_str()); + if (root == nullptr) { + LOGE("cJSON_Parse failed"); + return; + } + cJSON *failedTimeStampsJson = cJSON_GetObjectItem(root, FAILED_TIMES_STAMPS_KEY); + if (failedTimeStampsJson != nullptr && cJSON_IsArray(failedTimeStampsJson)) { + cJSON *item; + cJSON_ArrayForEach(item, failedTimeStampsJson) + { + bindFailedEventsObj.failedTimeStamps.push_back(item->valueint); + } + } + cJSON *freezeTimeStampsJson = cJSON_GetObjectItem(root, FREEZE_TIMES_STAMPS_KEY); + if (freezeTimeStampsJson != nullptr && cJSON_IsArray(freezeTimeStampsJson)) { + cJSON *item; + cJSON_ArrayForEach(item, freezeTimeStampsJson) + { + bindFailedEventsObj.freezeTimeStamps.push_back(item->valueint); + } + } + LOGI("ConvertJsonToBindFailedEvents success"); + cJSON_Delete(root); +} + +bool FreezeProcess::IsFreezed(const std::string &bundleName, int32_t deviceType) +{ + if (bundleName == CAST_BUNDLE_NAME && deviceType == DEVICE_TYPE_TV) { + LOGI("device is TV, business is cast+, no need freeze"); + return false; + } + std::lock_guard lock(freezeStateCacheMtx_); + if (bindFailedEventsCache_.IsEmpty()) { + LOGI("bindFailedEventsCache is empty"); + return false; + } + int64_t nowTime = GetSecondsSince1970ToNow(); + int64_t stopFreezeTimeStamp = freezeStateCache_.stopFreezeTimeStamp; + return nowTime > stopFreezeTimeStamp ? false : true; +} + +int32_t FreezeProcess::CleanFreezeRecord(const std::string &bundleName, int32_t deviceType) +{ + if (bundleName == CAST_BUNDLE_NAME && deviceType == DEVICE_TYPE_TV) { + LOGI("device is TV, business is cast+, no need clean"); + return DM_OK; + } + int64_t reservedDataTimeStamp = GetSecondsSince1970ToNow() - DATA_REFRESH_INTERVAL; + if (CleanBindFailedEvents(reservedDataTimeStamp) != DM_OK) { + LOGE("CleanBindFailedEvents failed"); + return ERR_DM_FAILED; + } + if (CleanFreezeState(reservedDataTimeStamp) != DM_OK) { + LOGE("CleanFreezeState failed"); + return ERR_DM_FAILED; + } + LOGI("CleanFreezeRecord success"); + return DM_OK; +} + +int32_t FreezeProcess::CleanBindFailedEvents(int64_t reservedDataTimeStamp) +{ + std::lock_guard lock(bindFailedEventsCacheMtx_); + if (bindFailedEventsCache_.IsEmpty()) { + LOGI("bindFailedEventsCache is empty, no need to clean"); + return DM_OK; + } + BindFailedEvents bindFailedEventsTmp = bindFailedEventsCache_; + int32_t needCleanBindFailedStampNum = std::count_if(bindFailedEventsTmp.failedTimeStamps.begin(), + bindFailedEventsTmp.failedTimeStamps.end(), + [reservedDataTimeStamp](int64_t v) { return v < reservedDataTimeStamp; }); + if (needCleanBindFailedStampNum == 0) { + LOGI("no stamp is before 20mins, no need to clean"); + return DM_OK; + } + bindFailedEventsTmp.failedTimeStamps.erase( + std::remove_if(bindFailedEventsTmp.failedTimeStamps.begin(), + bindFailedEventsTmp.failedTimeStamps.end(), + [reservedDataTimeStamp](int64_t n) { return n < reservedDataTimeStamp; }), + bindFailedEventsTmp.failedTimeStamps.end()); + bindFailedEventsTmp.freezeTimeStamps.erase( + std::remove_if(bindFailedEventsTmp.freezeTimeStamps.begin(), + bindFailedEventsTmp.freezeTimeStamps.end(), + [reservedDataTimeStamp](int64_t n) { return n < reservedDataTimeStamp; }), + bindFailedEventsTmp.freezeTimeStamps.end()); + std::string valueStr = ""; + ConvertBindFailedEventsToJson(bindFailedEventsTmp, valueStr); + if (KVAdapterManager::GetInstance().PutFreezeData(BIND_FAILED_EVENTS_KEY, valueStr) != DM_OK) { + LOGE("CleanBindFailedEvents within 20mins failed"); + return ERR_DM_FAILED; + } + bindFailedEventsCache_ = bindFailedEventsTmp; + LOGI("CleanBindFailedEvents success"); + return DM_OK; +} + +int32_t FreezeProcess::CleanFreezeState(int64_t reservedDataTimeStamp) +{ + std::lock_guard lock(freezeStateCacheMtx_); + if (freezeStateCache_.IsEmpty()) { + LOGI("freezeStateCache is empty, no need to clean"); + return DM_OK; + } + if (freezeStateCache_.startFreezeTimeStamp >= reservedDataTimeStamp) { + LOGI("startFreezeTimeStamp is in 20 mins, no need to clean"); + return DM_OK; + } + if (KVAdapterManager::GetInstance().DeleteFreezeData(FREEZE_STATE_KEY) != DM_OK) { + LOGE("delete freeze states data within 20mins failed"); + return ERR_DM_FAILED; + } + freezeStateCache_.Reset(); + LOGI("CleanFreezeState success"); + return DM_OK; +} + +void FreezeProcess::ConvertBindFailedEventsToJson(const BindFailedEvents &value, std::string &result) +{ + JsonObject jsonObj; + jsonObj[FAILED_TIMES_STAMPS_KEY] = value.failedTimeStamps; + jsonObj[FREEZE_TIMES_STAMPS_KEY] = value.freezeTimeStamps; + result = SafetyDump(jsonObj); +} + +void FreezeProcess::ConvertDeviceFreezeStateToJson(const DeviceFreezeState &value, std::string &result) +{ + JsonObject jsonObj; + jsonObj[START_FREEZE_TIME_KEY] = value.startFreezeTimeStamp; + jsonObj[STOP_FREEZE_TIME_KEY] = value.stopFreezeTimeStamp; + result = SafetyDump(jsonObj); +} + +int32_t FreezeProcess::DeleteFreezeRecord(const std::string &bundleName, int32_t deviceType) +{ + if (bundleName == CAST_BUNDLE_NAME && deviceType == DEVICE_TYPE_TV) { + LOGI("device is TV, business is cast+, no need delete"); + return DM_OK; + } + if (KVAdapterManager::GetInstance().DeleteFreezeData(FREEZE_STATE_KEY) != DM_OK) { + LOGE("delete freezeStates data failed"); + return ERR_DM_FAILED; + } + { + std::lock_guard lock(freezeStateCacheMtx_); + freezeStateCache_.Reset(); + } + if (KVAdapterManager::GetInstance().DeleteFreezeData(BIND_FAILED_EVENTS_KEY) != DM_OK) { + LOGE("delete bindFailedEvents data failed"); + return ERR_DM_FAILED; + } + std::lock_guard lock(bindFailedEventsCacheMtx_); + bindFailedEventsCache_.Reset(); + return DM_OK; +} + +int32_t FreezeProcess::UpdateFreezeRecord(const std::string &bundleName, int32_t deviceType) +{ + if (bundleName == CAST_BUNDLE_NAME && deviceType == DEVICE_TYPE_TV) { + LOGI("device is TV, business is cast+, no need update"); + return DM_OK; + } + int64_t nowTime = GetSecondsSince1970ToNow(); + std::lock_guard lock(bindFailedEventsCacheMtx_); + BindFailedEvents bindFailedEventsTmp = bindFailedEventsCache_; + int64_t lastFreezeTimeStamps = 0; + if (!bindFailedEventsTmp.freezeTimeStamps.empty()) { + lastFreezeTimeStamps = bindFailedEventsTmp.freezeTimeStamps.back(); + } + int32_t continueBindFailedNum = std::count_if(bindFailedEventsTmp.failedTimeStamps.begin(), + bindFailedEventsTmp.failedTimeStamps.end(), + [nowTime, lastFreezeTimeStamps]( + int64_t v) { return v > nowTime - CONTINUEOUS_FAILED_INTERVAL && v > lastFreezeTimeStamps; }); + if (continueBindFailedNum < MAX_CONTINUEOUS_BIND_FAILED_NUM) { + bindFailedEventsTmp.failedTimeStamps.push_back(nowTime); + std::string bindFailedEventsStr = ""; + ConvertBindFailedEventsToJson(bindFailedEventsTmp, bindFailedEventsStr); + if (KVAdapterManager::GetInstance().PutFreezeData(BIND_FAILED_EVENTS_KEY, bindFailedEventsStr) != DM_OK) { + LOGE("UpdateBindFailedEvents failed"); + return ERR_DM_FAILED; + } + bindFailedEventsCache_ = bindFailedEventsTmp; + return DM_OK; + } + bindFailedEventsTmp.failedTimeStamps.push_back(nowTime); + bindFailedEventsTmp.freezeTimeStamps.push_back(nowTime); + std::string bindFailedEventsStr = ""; + ConvertBindFailedEventsToJson(bindFailedEventsTmp, bindFailedEventsStr); + if (KVAdapterManager::GetInstance().PutFreezeData(BIND_FAILED_EVENTS_KEY, bindFailedEventsStr) != DM_OK) { + LOGE("UpdateBindFailedEvents failed"); + return ERR_DM_FAILED; + } + bindFailedEventsCache_ = bindFailedEventsTmp; + return UpdateFreezeState(nowTime); +} + +int32_t FreezeProcess::UpdateFreezeState(int64_t nowTime) +{ + std::lock_guard lock(freezeStateCacheMtx_); + DeviceFreezeState freezeStateTmp = freezeStateCache_; + int64_t nextFreezeTime = 0; + CalculateNextFreezeTime(freezeStateTmp.stopFreezeTimeStamp - freezeStateTmp.startFreezeTimeStamp, nextFreezeTime); + freezeStateTmp.startFreezeTimeStamp = nowTime; + freezeStateTmp.stopFreezeTimeStamp = nowTime + nextFreezeTime; + std::string freezeStateStr = ""; + ConvertDeviceFreezeStateToJson(freezeStateTmp, freezeStateStr); + if (KVAdapterManager::GetInstance().PutFreezeData(FREEZE_STATE_KEY, freezeStateStr) != DM_OK) { + LOGE("UpdateFreezeState failed"); + return ERR_DM_FAILED; + } + freezeStateCache_ = freezeStateTmp; + return DM_OK; +} + +void FreezeProcess::CalculateNextFreezeTime(int64_t nowFreezeTime, int64_t nextFreezeTime) +{ + switch (nowFreezeTime) { + case NOT_FREEZE_TIME: + nextFreezeTime = FIRST_FREEZE_TIME; + break; + case FIRST_FREEZE_TIME: + nextFreezeTime = SECOND_FREEZE_TIME; + break; + case SECOND_FREEZE_TIME: + nextFreezeTime = THIRD_FREEZE_TIME; + break; + default: + nextFreezeTime = MAX_FREEZE_TIME; + break; + } +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/service/BUILD.gn b/services/service/BUILD.gn index 9b0bb3f6d2cd61d58c03f4cf3638c8a0edc265f3..c6d338d2fafeea7f9daae5f86fddc1164a82c1e5 100644 --- a/services/service/BUILD.gn +++ b/services/service/BUILD.gn @@ -59,6 +59,7 @@ if (defined(ohos_lite)) { "//foundation/distributedshedule/samgr_lite/interfaces/kits/samgr", "//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy/include", "${devicemanager_path}/radar/include", + "${devicemanager_path}/services/implementation/include/authentication_v2", "${softbuscache_parh}/include", ] @@ -148,6 +149,7 @@ if (defined(ohos_lite)) { "${common_path}/include/ipc/standard", "${devicemanager_path}/commondependency/include", "${devicemanager_path}/radar/include", + "${devicemanager_path}/services/implementation/include/authentication_v2", "${innerkits_path}/native_cpp/include", "${servicesimpl_path}/include/dependency/deviceprofile", "${softbuscache_parh}/include", @@ -240,6 +242,7 @@ if (defined(ohos_lite)) { deps = [ "${devicemanager_path}/commondependency:devicemanagerdependency", "${devicemanager_path}/radar:devicemanagerradar", + "${devicemanager_path}/services/implementation:devicemanagerserviceimpl", "${innerkits_path}/native_cpp:devicemanagersdk", "${json_path}:devicemanagerjson", "${softbuscache_parh}:dmdevicecache", @@ -382,6 +385,7 @@ if (defined(ohos_lite)) { deps = [ "${devicemanager_path}/commondependency:devicemanagerdependency", "${devicemanager_path}/radar:devicemanagerradar", + "${devicemanager_path}/services/implementation:devicemanagerserviceimpl", "${innerkits_path}/native_cpp:devicemanagersdk", "${json_path}:devicemanagerjson", "${softbuscache_parh}:dmdevicecache", diff --git a/services/service/src/ipc/standard/ipc_server_stub.cpp b/services/service/src/ipc/standard/ipc_server_stub.cpp index c85383af7292f05e11704bbdbc510063dd097d6b..b6b9fa9faeb4c789080587c0914d2f664fdaa3e4 100644 --- a/services/service/src/ipc/standard/ipc_server_stub.cpp +++ b/services/service/src/ipc/standard/ipc_server_stub.cpp @@ -33,6 +33,7 @@ #include "device_name_manager.h" #include "dm_error_type.h" #include "dm_device_info.h" +#include "dm_freeze_process.h" #include "ffrt.h" #include #include @@ -187,6 +188,9 @@ void IpcServerStub::OnAddSystemAbility(int32_t systemAbilityId, const std::strin #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE)) if (systemAbilityId == DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID) { KVAdapterManager::GetInstance().ReInit(); + if (FreezeProcess::GetInstance().SyncFreezeData() != DM_OK) { + LOGE("SyncFreezeData failed."); + } return; } #endif diff --git a/utils/include/kvadapter/kv_adapter.h b/utils/include/kvadapter/kv_adapter.h index 0e116398ec70e8c130e46907752490b6345b22f4..be755f7dd243d9585d2eaa7995df8d5c65152737 100644 --- a/utils/include/kvadapter/kv_adapter.h +++ b/utils/include/kvadapter/kv_adapter.h @@ -43,6 +43,7 @@ public: int32_t DeleteKvStore(); int32_t DeleteByAppId(const std::string &appId, const std::string &prefix); int32_t DeleteBatch(const std::vector &keys); + int32_t Delete(const std::string& key); void OnRemoteDied() override; private: diff --git a/utils/include/kvadapter/kv_adapter_manager.h b/utils/include/kvadapter/kv_adapter_manager.h index 18e28b356801c8e54cf97fc8d6f99d8c5a5df9a7..ccd6f74a4fd5a389320c8f51f679a03a30662df5 100644 --- a/utils/include/kvadapter/kv_adapter_manager.h +++ b/utils/include/kvadapter/kv_adapter_manager.h @@ -38,6 +38,9 @@ public: DM_EXPORT int32_t Get(const std::string &key, DmKVValue &value); DM_EXPORT int32_t DeleteAgedEntry(); DM_EXPORT int32_t AppUnintall(const std::string &appId); + DM_EXPORT int32_t GetFreezeData(const std::string &key, std::string &value); + DM_EXPORT int32_t PutFreezeData(const std::string &key, std::string &value); + DM_EXPORT int32_t DeleteFreezeData(const std::string &key); private: KVAdapterManager() = default; diff --git a/utils/src/kvadapter/kv_adapter.cpp b/utils/src/kvadapter/kv_adapter.cpp index 8d7dd41dd4e655e99aa6c8984916a190bc31fee0..b2affd78334a3a55f6c5419cb1403e3d081505d7 100644 --- a/utils/src/kvadapter/kv_adapter.cpp +++ b/utils/src/kvadapter/kv_adapter.cpp @@ -243,5 +243,24 @@ int32_t KVAdapter::DeleteBatch(const std::vector &keys) } return DM_OK; } + +int32_t KVAdapter::Delete(const std::string& key) +{ + DistributedKv::Status status; + { + std::lock_guard lock(kvAdapterMutex_); + if (kvStorePtr_ == nullptr) { + LOGE("kvStorePtr is nullptr!"); + return ERR_DM_POINT_NULL; + } + DistributedKv::Key kvKey(key); + status = kvStorePtr_->Delete(kvKey); + } + if (status != DistributedKv::Status::SUCCESS) { + LOGE("Delete kv by key failed!"); + return ERR_DM_FAILED; + } + return DM_OK; +} } // namespace DistributedHardware } // namespace OHOS diff --git a/utils/src/kvadapter/kv_adapter_manager.cpp b/utils/src/kvadapter/kv_adapter_manager.cpp index 8bd979267f3c3945af3d1fa33212ae92b17b8dc9..da4f504850a8144bb298f9daff0476fa13748749 100644 --- a/utils/src/kvadapter/kv_adapter_manager.cpp +++ b/utils/src/kvadapter/kv_adapter_manager.cpp @@ -28,6 +28,7 @@ namespace OHOS { namespace DistributedHardware { namespace { constexpr const char* DM_KV_STORE_PREFIX = "DM2_"; +constexpr const char* DM_KV_STORE_FREEZE_PREFIX = "anti_ddos_local_"; constexpr const char* DB_KEY_DELIMITER = "###"; constexpr int64_t DM_KV_STORE_REFRESH_TIME = 24 * 60 * 60; // one day constexpr int64_t MAX_SUPPORTED_EXIST_TIME = 3 * 24 * 60 * 60; // 3days @@ -147,5 +148,39 @@ DM_EXPORT int32_t KVAdapterManager::AppUnintall(const std::string &appId) } return DM_OK; } + +DM_EXPORT int32_t KVAdapterManager::GetFreezeData(const std::string &key, std::string &value) +{ + std::string dmKey = DM_KV_STORE_FREEZE_PREFIX + key; + CHECK_NULL_RETURN(kvAdapter_, ERR_DM_POINT_NULL); + if (kvAdapter_->Get(dmKey, value) != DM_OK) { + LOGE("Get freeze data failed, dmKey: %{public}s", GetAnonyString(dmKey).c_str()); + return ERR_DM_FAILED; + } + return DM_OK; +} + +DM_EXPORT int32_t KVAdapterManager::PutFreezeData(const std::string &key, std::string &value) +{ + std::string dmKey = DM_KV_STORE_FREEZE_PREFIX + key; + CHECK_NULL_RETURN(kvAdapter_, ERR_DM_POINT_NULL); + if (kvAdapter_->Put(dmKey, value) != DM_OK) { + LOGE("Insert freeze data failed, k:%{public}s, v:%{public}s", dmKey.c_str(), value.c_str()); + return ERR_DM_FAILED; + } + LOGI("Insert freeze data success, k:%{public}s, v:%{public}s", dmKey.c_str(), value.c_str()); + return DM_OK; +} + +DM_EXPORT int32_t KVAdapterManager::DeleteFreezeData(const std::string &key) +{ + std::string dmKey = DM_KV_STORE_FREEZE_PREFIX + key; + CHECK_NULL_RETURN(kvAdapter_, ERR_DM_POINT_NULL); + if (kvAdapter_->Delete(dmKey) != DM_OK) { + LOGE("delete freeze data failed, dmKey: %{public}s", GetAnonyString(dmKey).c_str()); + return ERR_DM_FAILED; + } + return DM_OK; +} } // namespace DistributedHardware } // namespace OHOS