/* * Copyright (c) 2022-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 "device_manager_service_impl.h" #include #include #include #include #include "app_manager.h" #include "bundle_mgr_interface.h" #include "bundle_mgr_proxy.h" #include "dm_error_type.h" #include "dm_anonymous.h" #include "dm_constants.h" #include "dm_crypto.h" #include "dm_distributed_hardware_load.h" #include "dm_log.h" #include "dm_radar_helper.h" #include "dm_softbus_cache.h" #include "multiple_user_connector.h" #include "iservice_registry.h" #include "system_ability_definition.h" #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE)) #include "dm_common_event_manager.h" #include "parameter.h" #include "dm_random.h" #include "common_event_support.h" #include "ffrt.h" using namespace OHOS::EventFwk; #endif namespace OHOS { namespace DistributedHardware { namespace { // One year 365 * 24 * 60 * 60 constexpr int32_t MAX_ALWAYS_ALLOW_SECONDS = 31536000; constexpr int32_t BROADCAST_CREDID_LENGTH = 6; constexpr int32_t MIN_PIN_CODE = 100000; constexpr int32_t MAX_PIN_CODE = 999999; // New protocol field definition. To avoid dependency on the new protocol header file, // do not directly depend on the new protocol header file. constexpr int32_t MSG_TYPE_REQ_ACL_NEGOTIATE = 80; constexpr int32_t MSG_TYPE_RESP_ACL_NEGOTIATE = 90; constexpr int32_t MSG_TYPE_REQ_AUTH_TERMINATE = 104; constexpr int32_t AUTH_SRC_FINISH_STATE = 12; constexpr int32_t MAX_DATA_LEN = 65535; constexpr int32_t ULTRASONIC_AUTHTYPE = 6; constexpr const char* DM_TAG_LOGICAL_SESSION_ID = "logicalSessionId"; constexpr const char* DM_TAG_PEER_DISPLAY_ID = "peerDisplayId"; constexpr const char* DM_TAG_ACCESSEE_USER_ID = "accesseeUserId"; constexpr const char* DM_TAG_EXTRA_INFO = "extraInfo"; constexpr const char* FILED_AUTHORIZED_APP_LIST = "authorizedAppList"; constexpr const char* CHANGE_PINTYPE = "1"; constexpr const char* BIND_CALLER_USERID = "bindCallerUserId"; const char* IS_NEED_JOIN_LNN = "IsNeedJoinLnn"; constexpr const char* NEED_JOIN_LNN = "0"; constexpr const char* NO_NEED_JOIN_LNN = "1"; // currently, we just support one bind session in one device at same time constexpr size_t MAX_NEW_PROC_SESSION_COUNT_TEMP = 1; const int32_t USLEEP_TIME_US_500000 = 500000; // 500ms const int32_t USLEEP_TIME_US_550000 = 550000; // 550ms const int32_t USLEEP_TIME_US_20000 = 20000; // 20ms const int32_t OPEN_AUTH_SESSION_TIMEOUT = 15000; // 15000ms const int32_t MAX_TRY_STOP_CNT = 5; const int32_t DEFAULT_SESSION_ID = -1; const std::map BUNDLENAME_MAPPING = { { "wear_link_service", "watch_system_service" } }; static bool IsMessageOldVersion(const JsonObject &jsonObject, std::shared_ptr session) { std::string dmVersion = ""; std::string edition = ""; if (jsonObject[TAG_DMVERSION].IsString()) { dmVersion = jsonObject[TAG_DMVERSION].Get(); } if (jsonObject[TAG_EDITION].IsString()) { edition = jsonObject[TAG_EDITION].Get(); } dmVersion = AuthManagerBase::ConvertSrcVersion(dmVersion, edition); // Assign the physical session version and release the semaphore. session->version_ = dmVersion; // If the version number is higher than 5.0.4 (the highest version of the old protocol), // there is no need to switch to the old protocol. if (CompareVersion(dmVersion, DM_VERSION_5_0_OLD_MAX) == true) { return false; } return true; } std::string CreateTerminateMessage(void) { JsonObject jsonObject; jsonObject[TAG_MSG_TYPE] = MSG_TYPE_REQ_AUTH_TERMINATE; jsonObject[TAG_REPLY] = ERR_DM_VERSION_INCOMPATIBLE; jsonObject[TAG_AUTH_FINISH] = false; return jsonObject.Dump(); } } Session::Session(int sessionId, std::string deviceId) { sessionId_ = sessionId; deviceId_ = deviceId; } DeviceManagerServiceImpl::DeviceManagerServiceImpl() { LOGI("DeviceManagerServiceImpl constructor"); } DeviceManagerServiceImpl::~DeviceManagerServiceImpl() { LOGI("DeviceManagerServiceImpl destructor"); } static uint64_t StringToUint64(const std::string& str) { // Calculate the length of the substring, taking the minimum of the string length and 8 size_t subStrLength = std::min(str.length(), static_cast(8U)); // Extract substring std::string substr = str.substr(str.length() - subStrLength); // Convert substring to uint64_t uint64_t result = 0; for (size_t i = 0; i < subStrLength; ++i) { result <<= 8; // Shift left 8 bits result |= static_cast(substr[i]); } return result; } static uint64_t GetTokenId(bool isSrcSide, int32_t displayId, std::string &bundleName) { uint64_t tokenId = 0; if (isSrcSide) { // src end tokenId = IPCSkeleton::GetCallingTokenID(); } else { // sink end int64_t tmpTokenId; // get userId int32_t targetUserId = AuthManagerBase::DmGetUserId(displayId); if (targetUserId == -1) { return tokenId; } if (AppManager::GetInstance().GetHapTokenIdByName(targetUserId, bundleName, 0, tmpTokenId) == DM_OK) { tokenId = static_cast(tmpTokenId); } else if (AppManager::GetInstance().GetNativeTokenIdByName(bundleName, tmpTokenId) == DM_OK) { tokenId = static_cast(tmpTokenId); } else { // get deviceId, take the 8 character value as tokenId char localDeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); std::string deviceId = std::string(localDeviceId); if (deviceId.length() != 0) { tokenId = StringToUint64(deviceId); } } } return tokenId; } void DeviceManagerServiceImpl::NotifyCleanEvent(uint64_t logicalSessionId) { LOGI("logicalSessionId: %{public}" PRIu64 ".", logicalSessionId); ffrt::submit([=]() { CleanAuthMgrByLogicalSessionId(logicalSessionId); }); } void DeviceManagerServiceImpl::ImportConfig(std::shared_ptr authMgr, uint64_t tokenId, const std::string &pkgName) { // Import configuration std::lock_guard configsLock(configsMapMutex_); if (configsMap_.find(tokenId) != configsMap_.end()) { authMgr->ImportAuthCode(configsMap_[tokenId]->pkgName, configsMap_[tokenId]->authCode); authMgr->RegisterAuthenticationType(configsMap_[tokenId]->authenticationType); LOGI("import authCode Successful tokenId %{public}s, pkgName %{public}s, authCode %{public}s.", GetAnonyInt32(tokenId).c_str(), pkgName.c_str(), GetAnonyString(configsMap_[tokenId]->authCode).c_str()); configsMap_[tokenId] = nullptr; configsMap_.erase(tokenId); return; } for (auto it = configsMap_.begin(); it != configsMap_.end();) { if (it->second != nullptr && pkgName == it->second->pkgName) { authMgr->ImportAuthCode(it->second->pkgName, it->second->authCode); authMgr->RegisterAuthenticationType(it->second->authenticationType); LOGI("import authCode by pkgName Successful."); it->second = nullptr; it = configsMap_.erase(it); return; } else { ++it; } } } void DeviceManagerServiceImpl::ImportAuthCodeToConfig(std::shared_ptr authMgr, uint64_t tokenId) { if (authMgr == nullptr) { LOGE("authMgr is null."); return; } std::string pkgName; std::string authCode; authMgr->GetAuthCodeAndPkgName(pkgName, authCode); std::lock_guard configsLock(configsMapMutex_); if (configsMap_.find(tokenId) == configsMap_.end()) { configsMap_[tokenId] = std::make_shared(); } configsMap_[tokenId]->pkgName = pkgName; configsMap_[tokenId]->authCode = authCode; } int32_t DeviceManagerServiceImpl::InitNewProtocolAuthMgr(bool isSrcSide, uint64_t tokenId, uint64_t logicalSessionId, const std::string &pkgName, int sessionId) { LOGI("isSrcSide:%{public}d, tokenId: %{public}s, logicalSesId: %{public}" PRIu64 ", pkgname:%{public}s", isSrcSide, GetAnonyInt32(tokenId).c_str(), logicalSessionId, pkgName.c_str()); std::shared_ptr authMgr = nullptr; // Create a new auth_mgr, create authMgr if (isSrcSide) { // src end authMgr = std::make_shared(softbusConnector_, hiChainConnector_, listener_, hiChainAuthConnector_); } else { // sink end authMgr = std::make_shared(softbusConnector_, hiChainConnector_, listener_, hiChainAuthConnector_); } CleanNotifyCallback cleanNotifyCallback = [=](const auto &logicalSessionId) { this->NotifyCleanEvent(logicalSessionId); }; // Register resource destruction notification function authMgr->RegisterCleanNotifyCallback(cleanNotifyCallback); CHECK_NULL_RETURN(hiChainAuthConnector_, ERR_DM_POINT_NULL); hiChainAuthConnector_->RegisterHiChainAuthCallbackById(logicalSessionId, authMgr); LOGI("Initialize authMgr token: %{public}" PRId64 ".", tokenId); ImportConfig(authMgr, tokenId, pkgName); return AddAuthMgr(tokenId, sessionId, authMgr); } int32_t DeviceManagerServiceImpl::InitOldProtocolAuthMgr(uint64_t tokenId, const std::string &pkgName, int sessionId) { LOGI("tokenId: %{public}s, pkgname:%{public}s", GetAnonyInt32(tokenId).c_str(), pkgName.c_str()); { std::lock_guard lock(authMgrMtx_); if (authMgr_ == nullptr) { CreateGlobalClassicalAuthMgr(); } authMgr_->PrepareSoftbusSessionCallback(); ImportConfig(authMgr_, tokenId, pkgName); int32_t ret = AddAuthMgr(tokenId, sessionId, authMgr_); if (ret != DM_OK) { authMgr_->ClearSoftbusSessionCallback(); return ret; } } { // The value of logicalSessionId in the old protocol is always 0. std::lock_guard tokenIdLock(logicalSessionId2TokenIdMapMtx_); logicalSessionId2TokenIdMap_[0] = tokenId; } return DM_OK; } int32_t DeviceManagerServiceImpl::InitAndRegisterAuthMgr(bool isSrcSide, uint64_t tokenId, std::shared_ptr session, uint64_t logicalSessionId, const std::string &pkgName) { if (session == nullptr) { LOGE("InitAndRegisterAuthMgr, The physical link is not created."); return ERR_DM_AUTH_OPEN_SESSION_FAILED; } // If version is empty, allow creation for the first time, create a new protocol auth_mgr to negotiate version; // subsequent creations wait, and directly use version to create the corresponding auth_mgr after release. if (session->version_ == "") { bool expected = false; if (session->flag_.compare_exchange_strong(expected, true)) { LOGI("The physical link is being created and the dual-end device version is aligned."); } else { // Do not allow simultaneous version negotiation, return error directly LOGE("Version negotiation is not allowed at the same time."); return ERR_DM_AUTH_BUSINESS_BUSY; } } if (session->version_ == "" || CompareVersion(session->version_, DM_VERSION_5_0_OLD_MAX)) { return InitNewProtocolAuthMgr(isSrcSide, tokenId, logicalSessionId, pkgName, session->sessionId_); } LOGI("InitAndRegisterAuthMgr old authMgr."); return InitOldProtocolAuthMgr(tokenId, pkgName, session->sessionId_); } void DeviceManagerServiceImpl::CleanSessionMap(std::shared_ptr session) { if (session == nullptr) { return; } session->logicalSessionCnt_.fetch_sub(1); if (session->logicalSessionCnt_.load(std::memory_order_relaxed) <= 0) { { std::lock_guard lock(isNeedJoinLnnMtx_); if (isNeedJoinLnn_) { usleep(USLEEP_TIME_US_500000); } isNeedJoinLnn_ = true; } CleanSessionMap(session->sessionId_); } } void DeviceManagerServiceImpl::CleanSessionMap(int sessionId) { LOGI("In sessionId:%{public}d.", sessionId); if (softbusConnector_ != nullptr) { softbusConnector_->GetSoftbusSession()->CloseAuthSession(sessionId); } { std::lock_guard lock(mapMutex_); std::shared_ptr session = nullptr; if (sessionsMap_.find(sessionId) != sessionsMap_.end()) { session = sessionsMap_[sessionId]; sessionsMap_.erase(sessionId); } if (session != nullptr && deviceId2SessionIdMap_.find(session->deviceId_) != deviceId2SessionIdMap_.end()) { deviceId2SessionIdMap_.erase(session->deviceId_); } if (sessionEnableMutexMap_.find(sessionId) != sessionEnableMutexMap_.end()) { sessionStopMap_.erase(sessionId); sessionEnableMap_.erase(sessionId); sessionEnableCvReadyMap_.erase(sessionId); sessionEnableMutexMap_.erase(sessionId); } } } void DeviceManagerServiceImpl::CleanSessionMapByLogicalSessionId(uint64_t logicalSessionId) { { std::lock_guard tokenIdLock(logicalSessionId2TokenIdMapMtx_); logicalSessionId2TokenIdMap_.erase(logicalSessionId); } int32_t sessionId = 0; { std::lock_guard sessionIdLock(logicalSessionId2SessionIdMapMtx_); if (logicalSessionId2SessionIdMap_.find(logicalSessionId) == logicalSessionId2SessionIdMap_.end()) { return; } sessionId = logicalSessionId2SessionIdMap_[logicalSessionId]; logicalSessionId2SessionIdMap_.erase(logicalSessionId); } auto session = GetCurSession(sessionId); if (session != nullptr) { CleanSessionMap(session); } return; } void DeviceManagerServiceImpl::CleanAuthMgrByLogicalSessionId(uint64_t logicalSessionId) { uint64_t tokenId = 0; { std::lock_guard tokenIdLock(logicalSessionId2TokenIdMapMtx_); if (logicalSessionId2TokenIdMap_.find(logicalSessionId) != logicalSessionId2TokenIdMap_.end()) { tokenId = logicalSessionId2TokenIdMap_[logicalSessionId]; } else { LOGE("logicalSessionId(%{public}" PRIu64 ") can not find the tokenId.", logicalSessionId); return; } } CleanSessionMapByLogicalSessionId(logicalSessionId); if (logicalSessionId == 0 && authMgr_ != nullptr) { authMgr_->SetTransferReady(true); authMgr_->ClearSoftbusSessionCallback(); } hiChainAuthConnector_->UnRegisterHiChainAuthCallbackById(logicalSessionId); EraseAuthMgr(tokenId); return; } std::shared_ptr DeviceManagerServiceImpl::GetAuthMgr() { uint64_t tokenId = IPCSkeleton::GetCallingTokenID(); return GetAuthMgrByTokenId(tokenId); } int32_t DeviceManagerServiceImpl::AddAuthMgr(uint64_t tokenId, int sessionId, std::shared_ptr authMgr) { if (authMgr == nullptr) { LOGE("authMgr is nullptr."); return ERR_DM_POINT_NULL; } { std::lock_guard mapLock(mapMutex_); if (sessionEnableMap_.find(sessionId) != sessionEnableMap_.end() && !sessionEnableMap_[sessionId]) { LOGE("session is not open, no need add authMgr."); return ERR_DM_AUTH_OPEN_SESSION_FAILED; } } { std::lock_guard lock(authMgrMapMtx_); if (authMgrMap_.size() >= MAX_NEW_PROC_SESSION_COUNT_TEMP) { LOGE("Other bind session exist, can not start new one. authMgrMap_.size:%{public}zu", authMgrMap_.size()); return ERR_DM_AUTH_BUSINESS_BUSY; } authMgrMap_[tokenId] = authMgr; } { std::lock_guard mapLock(tokenIdSessionIdMapMtx_); if (tokenIdSessionIdMap_.find(tokenId) == tokenIdSessionIdMap_.end()) { tokenIdSessionIdMap_[tokenId] = sessionId; } } return DM_OK; } void DeviceManagerServiceImpl::EraseAuthMgr(uint64_t tokenId) { { std::lock_guard lock(authMgrMapMtx_); if (authMgrMap_.find(tokenId) != authMgrMap_.end()) { LOGI("authMgrMap_ erase token: %{public}" PRIu64 ".", tokenId); authMgrMap_.erase(tokenId); } } { std::lock_guard lock(tokenIdSessionIdMapMtx_); LOGI("tokenIdSessionIdMap_ erase token: %{public}" PRIu64 ".", tokenId); tokenIdSessionIdMap_.erase(tokenId); } } // Needed in the callback function std::shared_ptr DeviceManagerServiceImpl::GetAuthMgrByTokenId(uint64_t tokenId) { { std::lock_guard lock(authMgrMapMtx_); if (authMgrMap_.find(tokenId) != authMgrMap_.end()) { LOGI("authMgrMap_ token: %{public}" PRIu64 ".", tokenId); return authMgrMap_[tokenId]; } } LOGE("authMgrMap_ not found, token: %{public}" PRIu64 ".", tokenId); return nullptr; } std::shared_ptr DeviceManagerServiceImpl::GetCurrentAuthMgr() { uint64_t tokenId = 0; { std::lock_guard tokenIdLock(logicalSessionId2TokenIdMapMtx_); if (logicalSessionId2TokenIdMap_.find(0) != logicalSessionId2TokenIdMap_.end()) { tokenId = logicalSessionId2TokenIdMap_[0]; } } { std::lock_guard lock(authMgrMapMtx_); for (auto &pair : authMgrMap_) { if (pair.first != tokenId) { return pair.second; } } } return authMgr_; } static uint64_t GenerateRandNum(int sessionId) { // Get the current timestamp auto timestamp = std::chrono::duration_cast(std::chrono::high_resolution_clock::now(). time_since_epoch()).count(); // Generate random numbers std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> rand_dis(1, 0xFFFFFFFF); uint32_t randomNumber = static_cast(rand_dis(gen)); // Combination of random numbers uint64_t randNum = (static_cast(timestamp) << 32) | (static_cast(sessionId) << 16) | static_cast(randomNumber); return randNum; } int32_t DeviceManagerServiceImpl::Initialize(const std::shared_ptr &listener) { LOGI("Initialize"); if (softbusConnector_ == nullptr) { softbusConnector_ = std::make_shared(); } if (hiChainConnector_ == nullptr) { hiChainConnector_ = std::make_shared(); } if (mineHiChainConnector_ == nullptr) { mineHiChainConnector_ = std::make_shared(); } if (hiChainAuthConnector_ == nullptr) { hiChainAuthConnector_ = std::make_shared(); } if (deviceStateMgr_ == nullptr) { deviceStateMgr_ = std::make_shared(softbusConnector_, listener, hiChainConnector_, hiChainAuthConnector_); deviceStateMgr_->RegisterSoftbusStateCallback(); } if (credentialMgr_ == nullptr) { credentialMgr_ = std::make_shared(hiChainConnector_, listener); } if (dpInitedCallback_ == nullptr) { dpInitedCallback_ = sptr(new DpInitedCallback()); DeviceProfileConnector::GetInstance().SubscribeDeviceProfileInited(dpInitedCallback_); } listener_ = listener; CreateGlobalClassicalAuthMgr(); if (authMgr_ != nullptr) { authMgr_->ClearSoftbusSessionCallback(); } LOGI("Init success, singleton initialized"); return DM_OK; } void DeviceManagerServiceImpl::ReleaseMaps() { { std::lock_guard lock(authMgrMapMtx_); for (auto& pair : authMgrMap_) { pair.second = nullptr; } authMgrMap_.clear(); } for (auto& pair : sessionsMap_) { pair.second = nullptr; } sessionsMap_.clear(); { std::lock_guard configsLock(configsMapMutex_); for (auto& pair : configsMap_) { pair.second = nullptr; } configsMap_.clear(); } deviceId2SessionIdMap_.clear(); sessionEnableMutexMap_.clear(); sessionEnableCvMap_.clear(); sessionStopMap_.clear(); sessionEnableMap_.clear(); sessionEnableCvReadyMap_.clear(); { std::lock_guard tokenIdLock(logicalSessionId2TokenIdMapMtx_); logicalSessionId2TokenIdMap_.clear(); } { std::lock_guard sessionIdLock(logicalSessionId2SessionIdMapMtx_); logicalSessionId2SessionIdMap_.clear(); } } void DeviceManagerServiceImpl::Release() { LOGI("Release"); #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE)) commonEventManager_ = nullptr; #endif if (softbusConnector_ != nullptr) { softbusConnector_->UnRegisterConnectorCallback(); softbusConnector_->UnRegisterSoftbusStateCallback(); if (softbusConnector_->GetSoftbusSession() != nullptr) { softbusConnector_->GetSoftbusSession()->UnRegisterSessionCallback(); } } if (hiChainConnector_ != nullptr) { hiChainConnector_->UnRegisterHiChainCallback(); } if (hiChainAuthConnector_ != nullptr) { hiChainAuthConnector_->UnRegisterHiChainAuthCallback(); } authMgr_ = nullptr; ReleaseMaps(); deviceStateMgr_ = nullptr; softbusConnector_ = nullptr; abilityMgr_ = nullptr; hiChainConnector_ = nullptr; DeviceProfileConnector::GetInstance().UnSubscribeDeviceProfileInited(); dpInitedCallback_ = nullptr; } int32_t DeviceManagerServiceImpl::UnAuthenticateDevice(const std::string &pkgName, const std::string &udid, int32_t bindLevel) { if (pkgName.empty() || udid.empty()) { LOGE("DeviceManagerServiceImpl::UnAuthenticateDevice failed, pkgName is %{public}s, udid is %{public}s", pkgName.c_str(), GetAnonyString(udid).c_str()); return ERR_DM_INPUT_PARA_INVALID; } auto authMgr = GetAuthMgr(); if (authMgr == nullptr) { LOGE("authMgr is nullptr, invoke the old protocal."); if (authMgr_ == nullptr) { LOGE("classical authMgr_ is nullptr"); return ERR_DM_POINT_NULL; } return authMgr_->UnAuthenticateDevice(pkgName, udid, bindLevel); } return authMgr->UnAuthenticateDevice(pkgName, udid, bindLevel); } int32_t DeviceManagerServiceImpl::StopAuthenticateDevice(const std::string &pkgName) { if (pkgName.empty()) { LOGE("DeviceManagerServiceImpl::StopAuthenticateDevice failed"); return ERR_DM_INPUT_PARA_INVALID; } uint64_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t sessionId = DEFAULT_SESSION_ID; int32_t tryCnt = 0; while (tryCnt < MAX_TRY_STOP_CNT) { { std::lock_guard lock(tokenIdSessionIdMapMtx_); if (tokenIdSessionIdMap_.find(tokenId) == tokenIdSessionIdMap_.end()) { LOGI("sessionId not create, pkgName:%{public}s, tokenId:%{public}" PRIu64, pkgName.c_str(), tokenId); return DM_OK; } sessionId = tokenIdSessionIdMap_[tokenId]; } if (sessionId > 0) { break; } usleep(USLEEP_TIME_US_20000); tryCnt++; } if (sessionId == DEFAULT_SESSION_ID) { LOGE("sessionId is creating, pkgName:%{public}s, tokenId:%{public}" PRIu64, pkgName.c_str(), tokenId); return ERR_DM_AUTH_BUSINESS_BUSY; } LOGI("pkgName:%{public}s, sessionId:%{public}d, tokenId:%{public}" PRIu64, pkgName.c_str(), sessionId, tokenId); if (sessionEnableCvMap_.find(sessionId) != sessionEnableCvMap_.end()) { std::unique_lock cvLock(sessionEnableMutexMap_[sessionId]); if (sessionEnableMap_.find(sessionId) != sessionEnableMap_.end() && !sessionEnableMap_[sessionId]) { sessionStopMap_[sessionId] = true; } sessionEnableCvReadyMap_[sessionId] = true; sessionEnableCvMap_[sessionId].notify_all(); LOGI("notify_all by stop, sessionId:%{public}d, tokenId:%{public}" PRIu64, sessionId, tokenId); } auto authMgr = GetAuthMgrByTokenId(tokenId); int32_t ret = DM_OK; if (authMgr != nullptr) { ret = authMgr->StopAuthenticateDevice(pkgName); if (ret == DM_OK) { usleep(USLEEP_TIME_US_550000); } } else { CleanSessionMap(sessionId); } EraseAuthMgr(tokenId); return ret; } int32_t DeviceManagerServiceImpl::UnBindDevice(const std::string &pkgName, const std::string &udid, int32_t bindLevel) { if (pkgName.empty() || udid.empty()) { LOGE("DeviceManagerServiceImpl::UnBindDevice failed, pkgName is %{public}s, udid is %{public}s", pkgName.c_str(), GetAnonyString(udid).c_str()); return ERR_DM_INPUT_PARA_INVALID; } std::string extra = ""; char localDeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); return DeleteAclV2(pkgName, std::string(localDeviceId), udid, bindLevel, extra); } int32_t DeviceManagerServiceImpl::UnBindDevice(const std::string &pkgName, const std::string &udid, int32_t bindLevel, const std::string &extra) { if (pkgName.empty() || udid.empty()) { LOGE("DeviceManagerServiceImpl::UnBindDevice failed, pkgName is %{public}s, udid is %{public}s", pkgName.c_str(), GetAnonyString(udid).c_str()); return ERR_DM_INPUT_PARA_INVALID; } char localDeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); return DeleteAclV2(pkgName, std::string(localDeviceId), udid, bindLevel, extra); } int32_t DeviceManagerServiceImpl::SetUserOperation(std::string &pkgName, int32_t action, const std::string ¶ms) { if (pkgName.empty() || params.empty()) { LOGE("DeviceManagerServiceImpl::SetUserOperation error: Invalid parameter, pkgName: %{public}s, extra:" "%{public}s", pkgName.c_str(), params.c_str()); return ERR_DM_INPUT_PARA_INVALID; } auto authMgr = GetCurrentAuthMgr(); if (authMgr != nullptr) { authMgr->OnUserOperation(action, params); } return DM_OK; } void DeviceManagerServiceImpl::CreateGlobalClassicalAuthMgr() { LOGI("global classical authMgr_ not exit, create one"); CHECK_NULL_VOID(softbusConnector_); CHECK_NULL_VOID(hiChainConnector_); CHECK_NULL_VOID(hiChainAuthConnector_); // Create old auth_mar, only create an independent one authMgr_ = std::make_shared(softbusConnector_, hiChainConnector_, listener_, hiChainAuthConnector_); CleanNotifyCallback cleanNotifyCallback = [=](const auto &logicalSessionId) { this->NotifyCleanEvent(logicalSessionId); }; authMgr_->RegisterCleanNotifyCallback(cleanNotifyCallback); softbusConnector_->RegisterConnectorCallback(authMgr_); softbusConnector_->GetSoftbusSession()->RegisterSessionCallback(authMgr_); hiChainConnector_->RegisterHiChainCallback(authMgr_); hiChainAuthConnector_->RegisterHiChainAuthCallback(authMgr_); } void DeviceManagerServiceImpl::HandleOffline(DmDeviceState devState, DmDeviceInfo &devInfo) { std::string trustDeviceId = deviceStateMgr_->GetUdidByNetWorkId(std::string(devInfo.networkId)); LOGI("deviceStateMgr Udid: %{public}s", GetAnonyString(trustDeviceId).c_str()); if (trustDeviceId == "") { LOGE("HandleOffline not get udid in deviceStateMgr."); return; } std::string udisHash = softbusConnector_->GetDeviceUdidHashByUdid(trustDeviceId); if (memcpy_s(devInfo.deviceId, DM_MAX_DEVICE_ID_LEN, udisHash.c_str(), udisHash.length()) != 0) { return; } char localUdid[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdid, DEVICE_UUID_LENGTH); std::string requestDeviceId = std::string(localUdid); ProcessInfo processInfo; processInfo.pkgName = std::string(DM_PKG_NAME); processInfo.userId = MultipleUserConnector::GetFirstForegroundUserId(); uint32_t bindType = DeviceProfileConnector::GetInstance().CheckBindType(trustDeviceId, requestDeviceId); std::map userIdAndBindLevel = DeviceProfileConnector::GetInstance().GetUserIdAndBindLevel(requestDeviceId, trustDeviceId); if (userIdAndBindLevel.empty() || userIdAndBindLevel.find(processInfo.userId) == userIdAndBindLevel.end()) { userIdAndBindLevel[processInfo.userId] = INVALIED_TYPE; } std::vector processInfoVec; for (const auto &item : userIdAndBindLevel) { if (static_cast(item.second) == INVALIED_TYPE) { LOGI("The offline device is identical account bind type."); devInfo.authForm = DmAuthForm::IDENTICAL_ACCOUNT; processInfo.userId = item.first; processInfoVec.push_back(processInfo); } else if (static_cast(item.second) == USER && bindType == SHARE_TYPE) { LOGI("The offline device is device bind level and share bind type."); devInfo.authForm = DmAuthForm::SHARE; processInfo.userId = item.first; processInfoVec.push_back(processInfo); } else if (static_cast(item.second) == USER && bindType != SHARE_TYPE) { LOGI("The offline device is device bind type."); devInfo.authForm = DmAuthForm::PEER_TO_PEER; processInfo.userId = item.first; processInfoVec.push_back(processInfo); } else if (static_cast(item.second) == SERVICE || static_cast(item.second) == APP) { LOGI("The offline device is PEER_TO_PEER_TYPE bind type, %{public}" PRIu32, item.second); processInfoVec = DeviceProfileConnector::GetInstance().GetProcessInfoFromAclByUserId( requestDeviceId, trustDeviceId, item.first); std::set processInfoSet(processInfoVec.begin(), processInfoVec.end()); processInfoVec.assign(processInfoSet.begin(), processInfoSet.end()); } deviceStateMgr_->HandleDeviceStatusChange(devState, devInfo, processInfoVec); } } void DeviceManagerServiceImpl::HandleOnline(DmDeviceState devState, DmDeviceInfo &devInfo) { LOGI("networkId: %{public}s.", GetAnonyString(devInfo.networkId).c_str()); std::string trustDeviceId = ""; if (softbusConnector_->GetUdidByNetworkId(devInfo.networkId, trustDeviceId) != DM_OK) { LOGE("HandleOnline get udid failed."); return; } std::string udisHash = softbusConnector_->GetDeviceUdidHashByUdid(trustDeviceId); if (memcpy_s(devInfo.deviceId, DM_MAX_DEVICE_ID_LEN, udisHash.c_str(), udisHash.length()) != 0) { LOGE("get deviceId: %{public}s failed", GetAnonyString(udisHash).c_str()); return; } char localUdid[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdid, DEVICE_UUID_LENGTH); std::string requestDeviceId = std::string(localUdid); uint32_t bindType = DeviceProfileConnector::GetInstance().CheckBindType(trustDeviceId, requestDeviceId); LOGI("The online device bind type is %{public}" PRIu32, bindType); ProcessInfo processInfo; processInfo.pkgName = std::string(DM_PKG_NAME); processInfo.userId = MultipleUserConnector::GetFirstForegroundUserId(); SetOnlineProcessInfo(bindType, processInfo, devInfo, requestDeviceId, trustDeviceId, devState); } void DeviceManagerServiceImpl::SetOnlineProcessInfo(const uint32_t &bindType, ProcessInfo &processInfo, DmDeviceInfo &devInfo, const std::string &requestDeviceId, const std::string &trustDeviceId, DmDeviceState devState) { std::vector processInfoVec; if (bindType == IDENTICAL_ACCOUNT_TYPE) { devInfo.authForm = DmAuthForm::IDENTICAL_ACCOUNT; processInfoVec.push_back(processInfo); } else if (bindType == DEVICE_PEER_TO_PEER_TYPE) { devInfo.authForm = DmAuthForm::PEER_TO_PEER; processInfoVec.push_back(processInfo); } else if (bindType == DEVICE_ACROSS_ACCOUNT_TYPE) { devInfo.authForm = DmAuthForm::ACROSS_ACCOUNT; processInfoVec.push_back(processInfo); } else if (bindType == APP_PEER_TO_PEER_TYPE || bindType == SERVICE_PEER_TO_PEER_TYPE) { processInfoVec = DeviceProfileConnector::GetInstance().GetProcessInfoFromAclByUserId(requestDeviceId, trustDeviceId, MultipleUserConnector::GetFirstForegroundUserId()); std::set processInfoSet(processInfoVec.begin(), processInfoVec.end()); processInfoVec.assign(processInfoSet.begin(), processInfoSet.end()); devInfo.authForm = DmAuthForm::PEER_TO_PEER; } else if (bindType == APP_ACROSS_ACCOUNT_TYPE || bindType == SERVICE_ACROSS_ACCOUNT_TYPE) { processInfoVec = DeviceProfileConnector::GetInstance().GetProcessInfoFromAclByUserId(requestDeviceId, trustDeviceId, MultipleUserConnector::GetFirstForegroundUserId()); std::set processInfoSet(processInfoVec.begin(), processInfoVec.end()); processInfoVec.assign(processInfoSet.begin(), processInfoSet.end()); devInfo.authForm = DmAuthForm::ACROSS_ACCOUNT; } else if (bindType == SHARE_TYPE) { if (CheckSharePeerSrc(trustDeviceId, requestDeviceId)) { LOGI("ProcessDeviceStateChange authForm is share, peer is src."); return; } devInfo.authForm = DmAuthForm::SHARE; processInfoVec.push_back(processInfo); } LOGI("HandleOnline success devInfo authForm is %{public}d.", devInfo.authForm); deviceStateMgr_->HandleDeviceStatusChange(devState, devInfo, processInfoVec); return; } bool DeviceManagerServiceImpl::CheckSharePeerSrc(const std::string &peerUdid, const std::string &localUdid) { std::vector profiles = DeviceProfileConnector::GetInstance().GetAccessControlProfile(); for (auto &aclItem : profiles) { if (aclItem.GetBindType() == DM_SHARE && aclItem.GetTrustDeviceId() == peerUdid) { if (aclItem.GetAccesser().GetAccesserDeviceId() == peerUdid && aclItem.GetAccessee().GetAccesseeDeviceId() == localUdid) { return true; } if (aclItem.GetAccesser().GetAccesserDeviceId() == localUdid && aclItem.GetAccessee().GetAccesseeDeviceId() == peerUdid) { return false; } } } return false; } void DeviceManagerServiceImpl::HandleDeviceStatusChange(DmDeviceState devState, DmDeviceInfo &devInfo) { LOGI("start, devState = %{public}d, networkId: %{public}s.", devState, GetAnonyString(devInfo.networkId).c_str()); if (deviceStateMgr_ == nullptr) { LOGE("deviceStateMgr_ is nullpter!"); return; } if (devState == DEVICE_STATE_ONLINE) { HandleOnline(devState, devInfo); } else if (devState == DEVICE_STATE_OFFLINE) { HandleOffline(devState, devInfo); } else { std::string udiddHash = GetUdidHashByNetworkId(devInfo.networkId); if (memcpy_s(devInfo.deviceId, DM_MAX_DEVICE_ID_LEN, udiddHash.c_str(), udiddHash.length()) != 0) { LOGE("get deviceId: %{public}s failed", GetAnonyString(udiddHash).c_str()); return; } ProcessInfo processInfo; processInfo.pkgName = std::string(DM_PKG_NAME); processInfo.userId = MultipleUserConnector::GetFirstForegroundUserId(); std::vector processInfoVec; processInfoVec.push_back(processInfo); deviceStateMgr_->HandleDeviceStatusChange(devState, devInfo, processInfoVec); } } std::string DeviceManagerServiceImpl::GetUdidHashByNetworkId(const std::string &networkId) { if (softbusConnector_ == nullptr) { LOGE("softbusConnector_ is nullpter!"); return ""; } std::string udid = ""; int32_t ret = softbusConnector_->GetUdidByNetworkId(networkId.c_str(), udid); if (ret != DM_OK) { LOGE("GetUdidByNetworkId failed ret: %{public}d", ret); return ""; } return softbusConnector_->GetDeviceUdidHashByUdid(udid); } int DeviceManagerServiceImpl::OnSessionOpened(int sessionId, int result) { bool isNeedCloseSession = false; if (sessionEnableCvMap_.find(sessionId) != sessionEnableCvMap_.end()) { std::lock_guard lock(sessionEnableMutexMap_[sessionId]); if (result == 0) { LOGI("OnSessionOpened successful, sessionId: %{public}d", sessionId); if (sessionStopMap_.find(sessionId) != sessionStopMap_.end() && sessionStopMap_[sessionId]) { isNeedCloseSession = true; } else { sessionEnableMap_[sessionId] = true; } } else { LOGE("OnSessionOpened failed, sessionId: %{public}d, res: %{public}d", sessionId, result); } sessionEnableCvReadyMap_[sessionId] = true; sessionEnableCvMap_[sessionId].notify_all(); } std::string peerUdid = ""; softbusConnector_->GetSoftbusSession()->GetPeerDeviceId(sessionId, peerUdid); struct RadarInfo info = { .funcName = "OnSessionOpened", .stageRes = static_cast(StageRes::STAGE_SUCC), .isTrust = static_cast(TrustStatus::NOT_TRUST), .peerUdid = peerUdid, .channelId = sessionId, }; if (!DmRadarHelper::GetInstance().ReportAuthSessionOpenCb(info)) { LOGE("ReportAuthSessionOpenCb failed"); } if (isNeedCloseSession) { CleanSessionMap(sessionId); return DM_OK; } // Get the remote deviceId, sink end gives sessionsMap[deviceId] = session; { std::lock_guard lock(mapMutex_); if (sessionsMap_.find(sessionId) == sessionsMap_.end()) { sessionsMap_[sessionId] = std::make_shared(sessionId, peerUdid); } } return SoftbusSession::OnSessionOpened(sessionId, result); } void DeviceManagerServiceImpl::OnSessionClosed(int sessionId) { SoftbusSession::OnSessionClosed(sessionId); } static JsonObject GetJsonObjectFromData(const void *data, unsigned int dataLen) { std::string message = std::string(reinterpret_cast(data), dataLen); return JsonObject(message); } // When downgrading the version, determine whether it is src or sink based on the message. // src: Received 90 message. // sink: Received 80 message. static bool IsAuthManagerSourceByMessage(int32_t msgType) { return msgType == MSG_TYPE_RESP_ACL_NEGOTIATE; } // Get the current session object std::shared_ptr DeviceManagerServiceImpl::GetCurSession(int sessionId) { std::shared_ptr curSession = nullptr; // Get the remote deviceId, sink end gives sessionsMap[deviceId] = session; { std::lock_guard lock(mapMutex_); if (sessionsMap_.find(sessionId) != sessionsMap_.end()) { curSession = sessionsMap_[sessionId]; } else { LOGE("OnBytesReceived, The local session cannot be found."); } } return curSession; } std::shared_ptr DeviceManagerServiceImpl::GetAuthMgrByMessage(int32_t msgType, uint64_t logicalSessionId, const JsonObject &jsonObject, std::shared_ptr curSession) { uint64_t tokenId = 0; if (msgType == MSG_TYPE_REQ_ACL_NEGOTIATE) { std::string bundleName; int32_t displayId = 0; if (jsonObject[TAG_PEER_BUNDLE_NAME_V2].IsString()) { bundleName = jsonObject[TAG_PEER_BUNDLE_NAME_V2].Get(); } if (jsonObject[DM_TAG_PEER_DISPLAY_ID].IsNumberInteger()) { displayId = jsonObject[DM_TAG_PEER_DISPLAY_ID].Get(); } tokenId = GetTokenId(false, displayId, bundleName); if (tokenId == 0) { LOGE("GetAuthMgrByMessage, Get tokenId failed."); return nullptr; } if (InitAndRegisterAuthMgr(false, tokenId, curSession, logicalSessionId, "") != DM_OK) { return nullptr; } curSession->logicalSessionSet_.insert(logicalSessionId); std::lock_guard tokenIdLock(logicalSessionId2TokenIdMapMtx_); if (logicalSessionId2TokenIdMap_.find(logicalSessionId) != logicalSessionId2TokenIdMap_.end()) { LOGE("GetAuthMgrByMessage, logicalSessionId exists in logicalSessionId2TokenIdMap_."); return nullptr; } logicalSessionId2TokenIdMap_[logicalSessionId] = tokenId; } else { if (curSession->logicalSessionSet_.find(logicalSessionId) == curSession->logicalSessionSet_.end()) { LOGE("GetAuthMgrByMessage, The logical session ID does not exist in the physical session."); return nullptr; } std::lock_guard tokenIdLock(logicalSessionId2TokenIdMapMtx_); tokenId = logicalSessionId2TokenIdMap_[logicalSessionId]; } return GetAuthMgrByTokenId(tokenId); } int32_t DeviceManagerServiceImpl::GetLogicalIdAndTokenIdBySessionId(uint64_t &logicalSessionId, uint64_t &tokenId, int32_t sessionId) { std::lock_guard sessionIdLock(logicalSessionId2SessionIdMapMtx_); for (auto& pair : logicalSessionId2SessionIdMap_) { if (pair.second == sessionId) { logicalSessionId = pair.first; std::lock_guard tokenIdLock(logicalSessionId2TokenIdMapMtx_); tokenId = logicalSessionId2TokenIdMap_[logicalSessionId]; } } if (logicalSessionId == 0 || tokenId == 0) { LOGE("can not find logicalSessionId and tokenId."); return ERR_DM_AUTH_FAILED; } return DM_OK; } int32_t DeviceManagerServiceImpl::TransferSrcOldAuthMgr(std::shared_ptr curSession) { // New Old Receive 90, destroy new authMgr, create old authMgr, source side // The old protocol has only one session, reverse lookup logicalSessionId and tokenId CHECK_NULL_RETURN(curSession, ERR_DM_POINT_NULL); int sessionId = curSession->sessionId_; uint64_t logicalSessionId = 0; uint64_t tokenId = 0; int32_t ret = GetLogicalIdAndTokenIdBySessionId(logicalSessionId, tokenId, sessionId); if (ret != DM_OK) { LOGE("failed, logicalSessionId: %{public}" PRIu64 ", tokenId: %{public}s", logicalSessionId, GetAnonyInt32(tokenId).c_str()); return ret; } std::string pkgName; PeerTargetId peerTargetId; std::map bindParam; auto authMgr = GetAuthMgrByTokenId(tokenId); if (authMgr == nullptr) { LOGE("DeviceManagerServiceImpl::TransferSrcOldAuthMgr authManager is nullptr"); return ERR_DM_POINT_NULL; } authMgr->GetBindTargetParams(pkgName, peerTargetId, bindParam); int32_t authType = -1; authMgr->ParseAuthType(bindParam, authType); ImportAuthCodeToConfig(authMgr, tokenId); EraseAuthMgr(tokenId); if (InitAndRegisterAuthMgr(true, tokenId, curSession, logicalSessionId, "") != DM_OK) { return ERR_DM_AUTH_FAILED; } ret = TransferByAuthType(authType, curSession, authMgr, bindParam, logicalSessionId); if (ret != DM_OK) { LOGE("DeviceManagerServiceImpl::TransferByAuthType TransferByAuthType failed."); return ret; } authMgr->DeleteTimer(); authMgr = nullptr; if (authMgr_->BindTarget(pkgName, peerTargetId, bindParam, sessionId, 0) != DM_OK) { LOGE("DeviceManagerServiceImpl::TransferSrcOldAuthMgr authManager BindTarget failed"); return ERR_DM_AUTH_FAILED; } if (authType == DmAuthType::AUTH_TYPE_IMPORT_AUTH_CODE) { int32_t sessionSide = GetSessionSide(curSession->sessionId_); authMgr_->OnSessionOpened(curSession->sessionId_, sessionSide, 0); } LOGI("src transfer to old version success"); authMgr_->SetTransferReady(false); return DM_OK; } int32_t DeviceManagerServiceImpl::TransferByAuthType(int32_t authType, std::shared_ptr curSession, std::shared_ptr authMgr, std::map &bindParam, uint64_t logicalSessionId) { int sessionId = curSession->sessionId_; if (authType == DmAuthType::AUTH_TYPE_IMPORT_AUTH_CODE) { authMgr_->EnableInsensibleSwitching(); curSession->logicalSessionSet_.insert(0); { std::lock_guard sessionIdLock(logicalSessionId2SessionIdMapMtx_); logicalSessionId2SessionIdMap_[0] = sessionId; } authMgr->OnSessionDisable(); } else { authMgr_->DisableInsensibleSwitching(); // send stop message // Cannot stop using the new protocol. The new protocol is a signal mechanism and cannot be stopped serially. // There will be a delay, causing new objects to be created before the stop is complete. // Then the timeout mechanism of the new protocol will stop SoftBus again. std::string endMessage = CreateTerminateMessage(); CHECK_NULL_RETURN(softbusConnector_, ERR_DM_POINT_NULL); (void)softbusConnector_->GetSoftbusSession()->SendData(sessionId, endMessage); // Close new protocol session CleanAuthMgrByLogicalSessionId(logicalSessionId); } if (authType == ULTRASONIC_AUTHTYPE) { int32_t ret = ChangeUltrasonicTypeToPin(bindParam); if (ret != DM_OK) { LOGE("DeviceManagerServiceImpl::TransferSrcOldAuthMgr ChangeUltrasonicTypeToPin failed."); return ret; } } return DM_OK; } int32_t DeviceManagerServiceImpl::ChangeUltrasonicTypeToPin(std::map &bindParam) { auto iter = bindParam.find(PARAM_KEY_AUTH_TYPE); if (iter == bindParam.end()) { LOGE("DeviceManagerServiceImpl::ChangeUltrasonicTypeToPin bindParam:%{public}s not exist.", PARAM_KEY_AUTH_TYPE); return ERR_DM_AUTH_FAILED; } iter->second = CHANGE_PINTYPE; LOGI("bindParam:%{public}s PINTYPE.", PARAM_KEY_AUTH_TYPE); return DM_OK; } int32_t DeviceManagerServiceImpl::TransferSinkOldAuthMgr(const JsonObject &jsonObject, std::shared_ptr curSession) { // Old New Received 80, New Old authMgr, Sink End std::string bundleName; if (jsonObject[TAG_BUNDLE_NAME].IsString()) { bundleName = jsonObject[TAG_BUNDLE_NAME].Get(); } else if (jsonObject[TAG_PEER_BUNDLE_NAME].IsString()) { bundleName = jsonObject[TAG_PEER_BUNDLE_NAME].Get(); } else if (jsonObject[TAG_HOST_PKGLABEL].IsString()) { bundleName = jsonObject[TAG_HOST_PKGLABEL].Get(); } else { LOGE("DeviceManagerServiceImpl::TransferSinkOldAuthMgr can not find bundleName."); return ERR_DM_AUTH_FAILED; } if (softbusConnector_ == nullptr) { LOGE("softbusConnector_ is nullpter!"); return ERR_DM_AUTH_FAILED; } int32_t deviceType = softbusConnector_->GetLocalDeviceTypeId(); if (deviceType == DmDeviceType::DEVICE_TYPE_WATCH && BUNDLENAME_MAPPING.find(bundleName) != BUNDLENAME_MAPPING.end()) { bundleName = BUNDLENAME_MAPPING.find(bundleName)->second; } uint64_t tokenId = GetTokenId(false, -1, bundleName); if (InitAndRegisterAuthMgr(false, tokenId, curSession, 0, bundleName) != DM_OK) { // Internal error log printing completed return ERR_DM_AUTH_FAILED; } // Parameter 2 sessionSide is 0, authMgr_ is empty, it must be the sink end. // The src end will create the protocol object when BindTarget. authMgr_->OnSessionOpened(curSession->sessionId_, 0, 0); LOGI("sink transfer to old version success"); authMgr_->SetTransferReady(false); return DM_OK; } int32_t DeviceManagerServiceImpl::TransferOldAuthMgr(int32_t msgType, const JsonObject &jsonObject, std::shared_ptr curSession) { int ret = DM_OK; if ((authMgr_ == nullptr || authMgr_->IsTransferReady()) && (msgType == MSG_TYPE_REQ_ACL_NEGOTIATE || msgType == MSG_TYPE_RESP_ACL_NEGOTIATE)) { if (IsMessageOldVersion(jsonObject, curSession)) { if (IsAuthManagerSourceByMessage(msgType)) { ret = TransferSrcOldAuthMgr(curSession); } else { ret = TransferSinkOldAuthMgr(jsonObject, curSession); } } } return ret; } void DeviceManagerServiceImpl::OnBytesReceived(int sessionId, const void *data, unsigned int dataLen) { if (sessionId < 0 || data == nullptr || dataLen <= 0 || dataLen > MAX_DATA_LEN) { LOGE("[OnBytesReceived] Fail to receive data from softbus with sessionId: %{public}d, dataLen: %{public}d.", sessionId, dataLen); return; } LOGI("start, sessionId: %{public}d, dataLen: %{public}d.", sessionId, dataLen); JsonObject jsonObject = GetJsonObjectFromData(data, dataLen); if (jsonObject.IsDiscarded() || !IsInt32(jsonObject, TAG_MSG_TYPE)) { LOGE("OnBytesReceived, MSG_TYPE parse failed."); return; } int32_t msgType = jsonObject[TAG_MSG_TYPE].Get(); uint64_t logicalSessionId = 0; if (IsUint64(jsonObject, DM_TAG_LOGICAL_SESSION_ID)) { logicalSessionId = jsonObject[DM_TAG_LOGICAL_SESSION_ID].Get(); } std::shared_ptr curSession = GetCurSession(sessionId); if (curSession == nullptr) { LOGE("InitAndRegisterAuthMgr, The physical link is not created."); return; } std::shared_ptr authMgr = nullptr; if (logicalSessionId != 0) { authMgr = GetAuthMgrByMessage(msgType, logicalSessionId, jsonObject, curSession); if (authMgr == nullptr) { return; } if (msgType == MSG_TYPE_REQ_ACL_NEGOTIATE || msgType == MSG_TYPE_RESP_ACL_NEGOTIATE) { curSession->version_ = DM_CURRENT_VERSION; } } else { /**         Monitor old messages on ports 80/90         1. New-to-old: When the src side receives a 90 message and detects a version mismatch, it receives the 90 message, destroys the current new authMgr, creates a new old protocol authMgr, and re-BindTarget.         2. Old-to-new: When the sink side receives an 80 message and detects a version mismatch, it receives the 80 message, directly creates a new old protocol authMgr, and re-OnSessionOpened and OnBytesReceived.         */ if (curSession->version_ == "") { if (TransferOldAuthMgr(msgType, jsonObject, curSession) != DM_OK) { LOGE("DeviceManagerServiceImpl::OnBytesReceived TransferOldAuthMgr failed"); return; } } else { LOGI("Reuse Old AuthMgr, sessionId: %{public}d.", sessionId); } authMgr = authMgr_; } std::string message = std::string(reinterpret_cast(data), dataLen); if (msgType == AUTH_DEVICE_REQ_NEGOTIATE || msgType == AUTH_DEVICE_RESP_NEGOTIATE) { authMgr->OnAuthDeviceDataReceived(sessionId, message); } else { authMgr->OnDataReceived(sessionId, message); } return; } int32_t DeviceManagerServiceImpl::RequestCredential(const std::string &reqJsonStr, std::string &returnJsonStr) { if (reqJsonStr.empty()) { LOGE("reqJsonStr is empty"); return ERR_DM_INPUT_PARA_INVALID; } if (credentialMgr_== nullptr) { LOGE("credentialMgr_ is nullptr"); return ERR_DM_POINT_NULL; } return credentialMgr_->RequestCredential(reqJsonStr, returnJsonStr); } int32_t DeviceManagerServiceImpl::ImportCredential(const std::string &pkgName, const std::string &credentialInfo) { if (pkgName.empty() || credentialInfo.empty()) { LOGE("DeviceManagerServiceImpl::ImportCredential failed, pkgName is %{public}s, credentialInfo is %{public}s", pkgName.c_str(), GetAnonyString(credentialInfo).c_str()); return ERR_DM_INPUT_PARA_INVALID; } if (credentialMgr_== nullptr) { LOGE("credentialMgr_ is nullptr"); return ERR_DM_POINT_NULL; } isCredentialType_.store(true); return credentialMgr_->ImportCredential(pkgName, credentialInfo); } int32_t DeviceManagerServiceImpl::DeleteCredential(const std::string &pkgName, const std::string &deleteInfo) { if (pkgName.empty() || deleteInfo.empty()) { LOGE("DeviceManagerServiceImpl::DeleteCredential failed, pkgName is %{public}s, deleteInfo is %{public}s", pkgName.c_str(), GetAnonyString(deleteInfo).c_str()); return ERR_DM_INPUT_PARA_INVALID; } if (credentialMgr_== nullptr) { LOGE("credentialMgr_ is nullptr"); return ERR_DM_POINT_NULL; } isCredentialType_.store(false); return credentialMgr_->DeleteCredential(pkgName, deleteInfo); } int32_t DeviceManagerServiceImpl::MineRequestCredential(const std::string &pkgName, std::string &returnJsonStr) { (void)pkgName; if (mineHiChainConnector_->RequestCredential(returnJsonStr) != DM_OK) { LOGE("failed to get device credential from hichain"); return ERR_DM_HICHAIN_CREDENTIAL_REQUEST_FAILED; } return DM_OK; } int32_t DeviceManagerServiceImpl::CheckCredential(const std::string &pkgName, const std::string &reqJsonStr, std::string &returnJsonStr) { (void)pkgName; if (reqJsonStr.empty()) { LOGE("reqJsonStr is empty"); return ERR_DM_INPUT_PARA_INVALID; } if (mineHiChainConnector_->CheckCredential(reqJsonStr, returnJsonStr) != DM_OK) { LOGE("failed to check devices credential status"); return ERR_DM_HICHAIN_CREDENTIAL_CHECK_FAILED; } return DM_OK; } int32_t DeviceManagerServiceImpl::ImportCredential(const std::string &pkgName, const std::string &reqJsonStr, std::string &returnJsonStr) { (void)pkgName; if (reqJsonStr.empty()) { LOGE("reqJsonStr is empty"); return ERR_DM_INPUT_PARA_INVALID; } if (mineHiChainConnector_->ImportCredential(reqJsonStr, returnJsonStr) != DM_OK) { LOGE("failed to import devices credential"); return ERR_DM_HICHAIN_CREDENTIAL_IMPORT_FAILED; } isCredentialType_.store(true); return DM_OK; } int32_t DeviceManagerServiceImpl::DeleteCredential(const std::string &pkgName, const std::string &reqJsonStr, std::string &returnJsonStr) { (void)pkgName; if (reqJsonStr.empty()) { LOGE("reqJsonStr is empty"); return ERR_DM_INPUT_PARA_INVALID; } if (mineHiChainConnector_->DeleteCredential(reqJsonStr, returnJsonStr) != DM_OK) { LOGE("failed to delete devices credential"); return ERR_DM_HICHAIN_CREDENTIAL_DELETE_FAILED; } isCredentialType_.store(false); return DM_OK; } int32_t DeviceManagerServiceImpl::RegisterCredentialCallback(const std::string &pkgName) { if (pkgName.empty()) { LOGE("RegisterCredentialCallback failed, pkgName is empty"); return ERR_DM_INPUT_PARA_INVALID; } if (credentialMgr_ == nullptr) { LOGE("credentialMgr_ is nullptr"); return ERR_DM_POINT_NULL; } return credentialMgr_->RegisterCredentialCallback(pkgName); } int32_t DeviceManagerServiceImpl::UnRegisterCredentialCallback(const std::string &pkgName) { if (pkgName.empty()) { LOGE("UnRegisterCredentialCallback failed, pkgName is empty"); return ERR_DM_INPUT_PARA_INVALID; } if (credentialMgr_== nullptr) { LOGE("credentialMgr_ is nullptr"); return ERR_DM_POINT_NULL; } return credentialMgr_->UnRegisterCredentialCallback(pkgName); } int32_t DeviceManagerServiceImpl::RegisterUiStateCallback(const std::string &pkgName) { if (pkgName.empty()) { LOGE("RegisterUiStateCallback failed, pkgName is empty"); return ERR_DM_INPUT_PARA_INVALID; } auto authMgr = GetCurrentAuthMgr(); if (authMgr == nullptr) { LOGE("authMgr is nullptr"); return ERR_DM_POINT_NULL; } return authMgr->RegisterUiStateCallback(pkgName); } int32_t DeviceManagerServiceImpl::UnRegisterUiStateCallback(const std::string &pkgName) { if (pkgName.empty()) { LOGE("UnRegisterUiStateCallback failed, pkgName is empty"); return ERR_DM_INPUT_PARA_INVALID; } auto authMgr = GetCurrentAuthMgr(); if (authMgr == nullptr) { LOGE("authMgr is nullptr"); return ERR_DM_POINT_NULL; } return authMgr->UnRegisterUiStateCallback(pkgName); } int32_t DeviceManagerServiceImpl::PraseNotifyEventJson(const std::string &event, JsonObject &jsonObject) { jsonObject.Parse(event); if (jsonObject.IsDiscarded()) { LOGE("event prase error."); return ERR_DM_FAILED; } if ((!jsonObject.Contains("extra")) || (!jsonObject["extra"].IsObject())) { LOGE("extra error"); return ERR_DM_FAILED; } if ((!jsonObject["extra"].Contains("deviceId")) || (!jsonObject["extra"]["deviceId"].IsString())) { LOGE("NotifyEvent deviceId invalid"); return ERR_DM_FAILED; } return DM_OK; } int32_t DeviceManagerServiceImpl::NotifyEvent(const std::string &pkgName, const int32_t eventId, const std::string &event) { LOGI("NotifyEvent begin, pkgName : %{public}s, eventId : %{public}d", pkgName.c_str(), eventId); if ((eventId <= DM_NOTIFY_EVENT_START) || (eventId >= DM_NOTIFY_EVENT_BUTT)) { LOGE("NotifyEvent eventId invalid"); return ERR_DM_INPUT_PARA_INVALID; } if (eventId == DM_NOTIFY_EVENT_ONDEVICEREADY) { JsonObject jsonObject; if (PraseNotifyEventJson(event, jsonObject) != DM_OK) { LOGE("NotifyEvent json invalid"); return ERR_DM_INPUT_PARA_INVALID; } std::string deviceId; jsonObject["extra"]["deviceId"].GetTo(deviceId); if (deviceStateMgr_== nullptr) { LOGE("deviceStateMgr_ is nullptr"); return ERR_DM_POINT_NULL; } if (deviceStateMgr_->ProcNotifyEvent(eventId, deviceId) != DM_OK) { LOGE("NotifyEvent failed"); return ERR_DM_INPUT_PARA_INVALID; }; } return DM_OK; } int32_t DeviceManagerServiceImpl::GetGroupType(std::vector &deviceList) { LOGI("begin"); if (softbusConnector_ == nullptr || hiChainConnector_ == nullptr) { LOGE("softbusConnector_ or hiChainConnector_ is nullptr"); return ERR_DM_POINT_NULL; } for (auto it = deviceList.begin(); it != deviceList.end(); ++it) { std::string udid = ""; int32_t ret = softbusConnector_->GetUdidByNetworkId(it->networkId, udid); if (ret != DM_OK) { LOGE("GetUdidByNetworkId failed ret: %{public}d", ret); return ret; } std::string deviceId = softbusConnector_->GetDeviceUdidHashByUdid(udid); if (memcpy_s(it->deviceId, DM_MAX_DEVICE_ID_LEN, deviceId.c_str(), deviceId.length()) != 0) { LOGE("get deviceId: %{public}s failed", GetAnonyString(deviceId).c_str()); return ERR_DM_SECURITY_FUNC_FAILED; } it->authForm = hiChainConnector_->GetGroupType(udid); } return DM_OK; } int32_t DeviceManagerServiceImpl::GetUdidHashByNetWorkId(const char *networkId, std::string &deviceId) { if (softbusConnector_ == nullptr || hiChainConnector_ == nullptr) { LOGE("softbusConnector_ or hiChainConnector_ is nullptr"); return ERR_DM_POINT_NULL; } std::string udid = ""; int32_t ret = softbusConnector_->GetUdidByNetworkId(networkId, udid); if (ret != DM_OK) { LOGE("GetUdidByNetworkId failed ret: %{public}d", ret); return ret; } deviceId = softbusConnector_->GetDeviceUdidHashByUdid(udid); return DM_OK; } std::shared_ptr DeviceManagerServiceImpl::GetConfigByTokenId() { uint64_t tokenId = IPCSkeleton::GetCallingTokenID(); std::lock_guard configsLock(configsMapMutex_); if (configsMap_.find(tokenId) == configsMap_.end()) { configsMap_[tokenId] = std::make_shared(); } return configsMap_[tokenId]; } int32_t DeviceManagerServiceImpl::ImportAuthCode(const std::string &pkgName, const std::string &authCode) { if (pkgName.empty() || authCode.empty()) { LOGE("ImportAuthCode failed, pkgName or authCode is empty"); return ERR_DM_INPUT_PARA_INVALID; } LOGI("pkgName is %{public}s, authCode is %{public}s", pkgName.c_str(), GetAnonyString(authCode).c_str()); auto authMgr = GetAuthMgr(); if (authMgr != nullptr) { authMgr->ImportAuthCode(pkgName, authCode); } auto config = GetConfigByTokenId(); config->pkgName = pkgName; config->authCode = authCode; // If registered multiple times, only the last one is kept return DM_OK; } int32_t DeviceManagerServiceImpl::ExportAuthCode(std::string &authCode) { int32_t ret = GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE); authCode = std::to_string(ret); LOGI("ExportAuthCode success, authCode: %{public}s.", GetAnonyString(authCode).c_str()); return DM_OK; } static JsonObject GetExtraJsonObject(const std::map &bindParam) { std::string extra; auto iter = bindParam.find(PARAM_KEY_BIND_EXTRA_DATA); if (iter != bindParam.end()) { extra = iter->second; } else { extra = ConvertMapToJsonString(bindParam); } return JsonObject(extra); } static int32_t GetHmlInfo(const JsonObject &jsonObject, bool &hmlEnable160M, int32_t &hmlActionId) { if (jsonObject[PARAM_KEY_HML_ENABLE_160M].IsBoolean()) { hmlEnable160M = jsonObject[PARAM_KEY_HML_ENABLE_160M].Get(); LOGI("hmlEnable160M %{public}d", hmlEnable160M); } if (!IsString(jsonObject, PARAM_KEY_HML_ACTIONID)) { LOGE("PARAM_KEY_HML_ACTIONID is not string"); return ERR_DM_INPUT_PARA_INVALID; } std::string actionIdStr = jsonObject[PARAM_KEY_HML_ACTIONID].Get(); if (!IsNumberString(actionIdStr)) { LOGE("PARAM_KEY_HML_ACTIONID is not number"); return ERR_DM_INPUT_PARA_INVALID; } int32_t actionId = std::atoi(actionIdStr.c_str()); if (actionId <= 0) { LOGE("PARAM_KEY_HML_ACTIONID is <= 0"); return ERR_DM_INPUT_PARA_INVALID; } hmlActionId = actionId; return DM_OK; } static bool IsHmlSessionType(const JsonObject &jsonObject) { std::string connSessionType; if (jsonObject[PARAM_KEY_CONN_SESSIONTYPE].IsString()) { connSessionType = jsonObject[PARAM_KEY_CONN_SESSIONTYPE].Get(); LOGI("connSessionType %{public}s", connSessionType.c_str()); } return connSessionType == CONN_SESSION_TYPE_HML; } int DeviceManagerServiceImpl::OpenAuthSession(const std::string& deviceId, const std::map &bindParam) { bool hmlEnable160M = false; int32_t hmlActionId = 0; int invalidSessionId = -1; JsonObject jsonObject = GetExtraJsonObject(bindParam); if (jsonObject.IsDiscarded()) { LOGE("extra string not a json type."); return invalidSessionId; } if (softbusConnector_ == nullptr) { return invalidSessionId; } if (IsHmlSessionType(jsonObject)) { auto ret = GetHmlInfo(jsonObject, hmlEnable160M, hmlActionId); if (ret != DM_OK) { LOGE("OpenAuthSession failed, GetHmlInfo failed."); return ret; } LOGI("hmlActionId %{public}d, hmlEnable160M %{public}d", hmlActionId, hmlEnable160M); CHECK_NULL_RETURN(listener_, ERR_DM_FAILED); return listener_->OpenAuthSessionWithPara(deviceId, hmlActionId, hmlEnable160M); } else { return softbusConnector_->GetSoftbusSession()->OpenAuthSession(deviceId); } } std::shared_ptr DeviceManagerServiceImpl::GetOrCreateSession(const std::string& deviceId, const std::map &bindParam, uint64_t tokenId) { std::shared_ptr instance; int sessionId = -1; // Check again whether the corresponding object already exists (because other threads may have created it during // the lock acquisition in the previous step) std::lock_guard lock(mapMutex_); if (deviceId2SessionIdMap_.find(deviceId) != deviceId2SessionIdMap_.end()) { sessionId = deviceId2SessionIdMap_[deviceId]; } if (sessionsMap_.find(sessionId) != sessionsMap_.end()) { return sessionsMap_[sessionId]; } sessionId = OpenAuthSession(deviceId, bindParam); if (sessionId < 0) { LOGE("OpenAuthSession failed, stop the authentication"); return nullptr; } { std::lock_guard lock(tokenIdSessionIdMapMtx_); tokenIdSessionIdMap_[tokenId] = sessionId; } std::unique_lock cvLock(sessionEnableMutexMap_[sessionId]); sessionEnableCvReadyMap_[sessionId] = false; sessionStopMap_[sessionId] = false; sessionEnableMap_[sessionId] = false; if (!sessionEnableCvMap_[sessionId].wait_for(cvLock, std::chrono::milliseconds(OPEN_AUTH_SESSION_TIMEOUT), [&] { return sessionEnableCvReadyMap_[sessionId]; })) { LOGE("wait session enable timeout or enable fail, sessionId: %{public}d.", sessionId); return nullptr; } if (sessionStopMap_.find(sessionId) != sessionStopMap_.end() && sessionStopMap_[sessionId]) { LOGW("stop by caller, sessionId: %{public}d.", sessionId); return nullptr; } if (sessionEnableMap_.find(sessionId) != sessionEnableMap_.end() && !sessionEnableMap_[sessionId]) { LOGW("Open session failed, sessionId: %{public}d.", sessionId); return nullptr; } instance = std::make_shared(sessionId, deviceId); deviceId2SessionIdMap_[deviceId] = sessionId; sessionsMap_[sessionId] = instance; return instance; } int32_t DeviceManagerServiceImpl::GetDeviceInfo(const PeerTargetId &targetId, std::string &addrType, std::string &deviceId, std::shared_ptr deviceInfo, int32_t &index) { ConnectionAddr addr; if (!targetId.wifiIp.empty() && targetId.wifiIp.length() <= IP_STR_MAX_LEN) { LOGI("parse wifiIp: %{public}s.", GetAnonyString(targetId.wifiIp).c_str()); if (!addrType.empty()) { addr.type = static_cast(std::atoi(addrType.c_str())); } else { addr.type = ConnectionAddrType::CONNECTION_ADDR_WLAN; } if (memcpy_s(addr.info.ip.ip, IP_STR_MAX_LEN, targetId.wifiIp.c_str(), targetId.wifiIp.length()) != 0) { LOGE("get ip addr: %{public}s failed", GetAnonyString(targetId.wifiIp).c_str()); return ERR_DM_SECURITY_FUNC_FAILED; } addr.info.ip.port = targetId.wifiPort; deviceInfo->addr[index] = addr; deviceId = targetId.wifiIp; index++; } else if (!targetId.brMac.empty() && targetId.brMac.length() <= BT_MAC_LEN) { LOGI("parse brMac: %{public}s.", GetAnonyString(targetId.brMac).c_str()); addr.type = ConnectionAddrType::CONNECTION_ADDR_BR; if (memcpy_s(addr.info.br.brMac, BT_MAC_LEN, targetId.brMac.c_str(), targetId.brMac.length()) != 0) { LOGE("get brMac addr: %{public}s failed", GetAnonyString(targetId.brMac).c_str()); return ERR_DM_SECURITY_FUNC_FAILED; } deviceInfo->addr[index] = addr; deviceId = targetId.brMac; index++; } else if (!targetId.bleMac.empty() && targetId.bleMac.length() <= BT_MAC_LEN) { LOGI("parse bleMac: %{public}s.", GetAnonyString(targetId.bleMac).c_str()); addr.type = ConnectionAddrType::CONNECTION_ADDR_BLE; if (memcpy_s(addr.info.ble.bleMac, BT_MAC_LEN, targetId.bleMac.c_str(), targetId.bleMac.length()) != 0) { LOGE("get bleMac addr: %{public}s failed", GetAnonyString(targetId.bleMac).c_str()); return ERR_DM_SECURITY_FUNC_FAILED; } if (!targetId.deviceId.empty()) { Crypto::ConvertHexStringToBytes(addr.info.ble.udidHash, UDID_HASH_LEN, targetId.deviceId.c_str(), targetId.deviceId.length()); } deviceInfo->addr[index] = addr; deviceId = targetId.bleMac; index++; } else { LOGE("DeviceManagerServiceImpl::GetDeviceInfo failed, not addr."); return ERR_DM_INPUT_PARA_INVALID; } return DM_OK; } bool DeviceManagerServiceImpl::IsAuthNewVersion(int32_t bindLevel, std::string localUdid, std::string remoteUdid, int32_t tokenId, int32_t userId) { std::string extraInfo = DeviceProfileConnector::GetInstance().IsAuthNewVersion( bindLevel, localUdid, remoteUdid, tokenId, userId); JsonObject extraInfoJson(extraInfo); if (extraInfoJson.IsDiscarded()) { LOGE("IsAuthNewVersion extraInfoJson error"); return false; } if (!extraInfoJson[TAG_DMVERSION].IsString()) { LOGE("IsAuthNewVersion PARAM_KEY_OS_VERSION error"); return false; } std::string dmVersion = extraInfoJson[TAG_DMVERSION].Get(); if (CompareVersion(dmVersion, std::string(DM_VERSION_5_1_0)) || dmVersion == std::string(DM_VERSION_5_1_0)) { return true; } return false; } int32_t DeviceManagerServiceImpl::ParseConnectAddr(const PeerTargetId &targetId, std::string &deviceId, const std::map &bindParam) { std::string addrType; if (bindParam.count(PARAM_KEY_CONN_ADDR_TYPE) != 0) { addrType = bindParam.at(PARAM_KEY_CONN_ADDR_TYPE); } std::string isNeedJoinLnnStr; if (bindParam.find(IS_NEED_JOIN_LNN) != bindParam.end()) { isNeedJoinLnnStr = bindParam.at(IS_NEED_JOIN_LNN); } LOGI("isNeedJoinLnnStr: %{public}s.", isNeedJoinLnnStr.c_str()); { std::lock_guard lock(isNeedJoinLnnMtx_); if (isNeedJoinLnnStr == NEED_JOIN_LNN || isNeedJoinLnnStr == NO_NEED_JOIN_LNN) { isNeedJoinLnn_ = std::atoi(isNeedJoinLnnStr.c_str()); } } std::shared_ptr deviceInfo = std::make_shared(); int32_t index = 0; int32_t ret = GetDeviceInfo(targetId, addrType, deviceId, deviceInfo, index); if (ret != DM_OK) { LOGE("GetDeviceInfo failed, ret: %{public}d", ret); } deviceInfo->addrNum = static_cast(index); if (softbusConnector_->AddMemberToDiscoverMap(deviceId, deviceInfo) != DM_OK) { LOGE("DeviceManagerServiceImpl::ParseConnectAddr failed, AddMemberToDiscoverMap failed."); return ERR_DM_INPUT_PARA_INVALID; } deviceInfo = nullptr; return DM_OK; } void DeviceManagerServiceImpl::SaveTokenIdAndSessionId(uint64_t &tokenId, int32_t &sessionId, uint64_t &logicalSessionId) { { std::lock_guard tokenIdLock(logicalSessionId2TokenIdMapMtx_); logicalSessionId2TokenIdMap_[logicalSessionId] = tokenId; } { std::lock_guard sessionIdLock(logicalSessionId2SessionIdMapMtx_); logicalSessionId2SessionIdMap_[logicalSessionId] = sessionId; } } bool DeviceManagerServiceImpl::ParseConnectAddrAndSetProcessInfo(PeerTargetId &targetId, const std::map &bindParam, ProcessInfo &processInfo, const std::string &pkgName, uint64_t tokenId) { processInfo.pkgName = pkgName; if (bindParam.count(BIND_CALLER_USERID) != 0) { processInfo.userId = std::atoi(bindParam.at(BIND_CALLER_USERID).c_str()); } std::string deviceId = ""; if (ParseConnectAddr(targetId, deviceId, bindParam) == DM_OK) { targetId.deviceId = deviceId; } else { if (targetId.deviceId.empty()) { LOGE("DeviceManagerServiceImpl::BindTarget failed, ParseConnectAddr failed."); OnAuthResultAndOnBindResult(processInfo, targetId, "", ERR_DM_INPUT_PARA_INVALID, tokenId); return false; } } return true; } void DeviceManagerServiceImpl::OnAuthResultAndOnBindResult(const ProcessInfo &processInfo, const PeerTargetId &targetId, const std::string &deviceId, int32_t reason, uint64_t tokenId) { { std::lock_guard lock(tokenIdSessionIdMapMtx_); auto iter = tokenIdSessionIdMap_.find(tokenId); if (iter != tokenIdSessionIdMap_.end()) { tokenIdSessionIdMap_.erase(iter); } } CHECK_NULL_VOID(listener_); listener_->OnAuthResult(processInfo, deviceId, "", DmAuthStatus::STATUS_DM_AUTH_DEFAULT, reason); listener_->OnBindResult(processInfo, targetId, reason, DmAuthStatus::STATUS_DM_AUTH_DEFAULT, ""); } void DeviceManagerServiceImpl::BindTargetImpl(uint64_t tokenId, const std::string &pkgName, const PeerTargetId &targetId, const std::map &bindParam) { PeerTargetId targetIdTmp = const_cast(targetId); ProcessInfo processInfo; if (!ParseConnectAddrAndSetProcessInfo(targetIdTmp, bindParam, processInfo, pkgName, tokenId)) { return; } // Created only at the source end. The same target device will not be created repeatedly with the new protocol. std::shared_ptr curSession = GetOrCreateSession(targetIdTmp.deviceId, bindParam, tokenId); if (curSession == nullptr) { LOGE("create session failed. Target deviceId: %{public}s.", GetAnonyString(targetIdTmp.deviceId).c_str()); OnAuthResultAndOnBindResult(processInfo, targetId, targetIdTmp.deviceId, ERR_DM_TIME_OUT, tokenId); return; } // Logical session random number int sessionId = curSession->sessionId_; uint64_t logicalSessionId = 0; if (curSession->version_ == "" || CompareVersion(curSession->version_, DM_VERSION_5_0_OLD_MAX)) { logicalSessionId = GenerateRandNum(sessionId); if (curSession->logicalSessionSet_.find(logicalSessionId) != curSession->logicalSessionSet_.end()) { LOGE("Failed to create the logical session."); CleanSessionMap(sessionId); OnAuthResultAndOnBindResult(processInfo, targetId, targetIdTmp.deviceId, ERR_DM_INPUT_PARA_INVALID, tokenId); return; } } // Create on the src end. int32_t ret = InitAndRegisterAuthMgr(true, tokenId, curSession, logicalSessionId, ""); if (ret != DM_OK) { LOGE("InitAndRegisterAuthMgr failed, ret %{public}d.", ret); CleanSessionMap(sessionId); OnAuthResultAndOnBindResult(processInfo, targetId, targetIdTmp.deviceId, ret, tokenId); return; } curSession->logicalSessionSet_.insert(logicalSessionId); curSession->logicalSessionCnt_.fetch_add(1); SaveTokenIdAndSessionId(tokenId, sessionId, logicalSessionId); auto authMgr = GetAuthMgrByTokenId(tokenId); if (authMgr == nullptr) { CleanAuthMgrByLogicalSessionId(logicalSessionId); OnAuthResultAndOnBindResult(processInfo, targetId, targetIdTmp.deviceId, ERR_DM_POINT_NULL, tokenId); return; } authMgr->SetBindTargetParams(targetId); if ((ret = authMgr->BindTarget(pkgName, targetIdTmp, bindParam, sessionId, logicalSessionId)) != DM_OK) { LOGE("authMgr BindTarget failed, ret %{public}d.", ret); CleanAuthMgrByLogicalSessionId(logicalSessionId); OnAuthResultAndOnBindResult(processInfo, targetId, targetIdTmp.deviceId, ret, tokenId); } LOGI("end, tokenId %{public}s.", GetAnonyInt32(tokenId).c_str()); return; } int32_t DeviceManagerServiceImpl::BindTarget(const std::string &pkgName, const PeerTargetId &targetId, const std::map &bindParam) { if (pkgName.empty()) { LOGE("BindTarget failed, pkgName is empty."); return ERR_DM_INPUT_PARA_INVALID; } DmBindCallerInfo bindCallerInfo; GetBindCallerInfo(bindCallerInfo, pkgName); std::map bindParamTmp; SetBindCallerInfoToBindParam(bindParam, bindParamTmp, bindCallerInfo); uint64_t tokenId = IPCSkeleton::GetCallingTokenID(); LOGI("DeviceManagerServiceImpl In, pkgName:%{public}s, tokenId:%{public}" PRIu64, pkgName.c_str(), tokenId); { std::lock_guard lock(tokenIdSessionIdMapMtx_); if (tokenIdSessionIdMap_.find(tokenId) != tokenIdSessionIdMap_.end()) { LOGE("BindTarget failed, this device is being bound. please try again later," "pkgName:%{public}s, tokenId:%{public}" PRIu64, pkgName.c_str(), tokenId); return ERR_DM_AUTH_BUSINESS_BUSY; } if (tokenIdSessionIdMap_.size() >= MAX_NEW_PROC_SESSION_COUNT_TEMP) { LOGE("Other bind exist, can not start new one. size:%{public}zu", tokenIdSessionIdMap_.size()); return ERR_DM_AUTH_BUSINESS_BUSY; } tokenIdSessionIdMap_[tokenId] = DEFAULT_SESSION_ID; } std::thread newThread(&DeviceManagerServiceImpl::BindTargetImpl, this, tokenId, pkgName, targetId, bindParamTmp); newThread.detach(); return DM_OK; } int32_t DeviceManagerServiceImpl::DpAclAdd(const std::string &udid) { LOGI("start udid %{public}s.", GetAnonyString(udid).c_str()); MultipleUserConnector::SetSwitchOldUserId(MultipleUserConnector::GetCurrentAccountUserID()); MultipleUserConnector::SetSwitchOldAccountId(MultipleUserConnector::GetOhosAccountId()); if (deviceStateMgr_->CheckIsOnline(udid)) { LOGI("DeviceManagerServiceImpl DpAclAdd identical account and online"); ProcessInfo processInfo; processInfo.pkgName = std::string(DM_PKG_NAME); processInfo.userId = MultipleUserConnector::GetFirstForegroundUserId(); softbusConnector_->SetProcessInfo(processInfo); deviceStateMgr_->OnDeviceOnline(udid, DmAuthForm::IDENTICAL_ACCOUNT); } return DM_OK; } int32_t DeviceManagerServiceImpl::IsSameAccount(const std::string &udid) { if (udid.empty()) { LOGE("DeviceManagerServiceImpl::IsSameAccount error: udid: %{public}s", GetAnonyString(udid).c_str()); return ERR_DM_INPUT_PARA_INVALID; } return DeviceProfileConnector::GetInstance().IsSameAccount(udid); } uint64_t DeviceManagerServiceImpl::GetTokenIdByNameAndDeviceId(std::string extra, std::string requestDeviceId) { if (extra.empty()) { LOGE("DeviceManagerServiceImpl::GetTokenIdByNameAndDeviceId error: extra."); return ERR_DM_INPUT_PARA_INVALID; } if (requestDeviceId.empty()) { LOGE("DeviceManagerServiceImpl::GetTokenIdByNameAndDeviceId error: requestDeviceId."); return ERR_DM_INPUT_PARA_INVALID; } return DeviceProfileConnector::GetInstance().GetTokenIdByNameAndDeviceId(extra, requestDeviceId); } std::unordered_map DeviceManagerServiceImpl::GetAppTrustDeviceIdList( std::string pkgname) { char localDeviceId[DEVICE_UUID_LENGTH]; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); std::string deviceId = reinterpret_cast(localDeviceId); return DeviceProfileConnector::GetInstance().GetAppTrustDeviceList(pkgname, deviceId); } void DeviceManagerServiceImpl::LoadHardwareFwkService() { DmDistributedHardwareLoad::GetInstance().LoadDistributedHardwareFwk(); } void DeviceManagerServiceImpl::HandleIdentAccountLogout(const DMAclQuadInfo &info, const std::string &accountId) { LOGI("localUdid %{public}s, localUserId %{public}d, peerUdid %{public}s, peerUserId %{public}d.", GetAnonyString(info.localUdid).c_str(), info.localUserId, GetAnonyString(info.peerUdid).c_str(), info.peerUserId); DmOfflineParam offlineParam; bool notifyOffline = DeviceProfileConnector::GetInstance().DeleteAclForAccountLogOut(info, accountId, offlineParam); CHECK_NULL_VOID(hiChainConnector_); hiChainConnector_->DeleteAllGroup(info.localUserId); CHECK_NULL_VOID(hiChainAuthConnector_); { std::lock_guard lock(logoutMutex_); hiChainAuthConnector_->DeleteCredential(info.peerUdid, info.localUserId, info.peerUserId); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); } std::set pkgNameSet; GetBundleName(info, pkgNameSet); if (notifyOffline) { CHECK_NULL_VOID(softbusConnector_); softbusConnector_->SetProcessInfoVec(offlineParam.processVec); CHECK_NULL_VOID(listener_); listener_->SetExistPkgName(pkgNameSet); CHECK_NULL_VOID(deviceStateMgr_); deviceStateMgr_->OnDeviceOffline(info.peerUdid); } } void DeviceManagerServiceImpl::GetBundleName(const DMAclQuadInfo &info, std::set &pkgNameSet) { std::vector profiles = DeviceProfileConnector::GetInstance().GetAllAclIncludeLnnAcl(); for (auto &item : profiles) { std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId(); std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId(); int32_t accesserUserId = item.GetAccesser().GetAccesserUserId(); int32_t accesseeUserId = item.GetAccessee().GetAccesseeUserId(); std::string accesserPkgName = item.GetAccesser().GetAccesserBundleName(); std::string accesseePkgName = item.GetAccessee().GetAccesseeBundleName(); if (accesserUdid == info.localUdid && accesserUserId == info.localUserId && accesseeUdid == info.peerUdid && accesseeUserId == info.peerUserId && (!accesserPkgName.empty())) { pkgNameSet.insert(accesserPkgName); continue; } if (accesserUdid == info.peerUdid && accesserUserId == info.peerUserId && accesseeUdid == info.localUdid && accesseeUserId == info.localUserId && (!accesseePkgName.empty())) { pkgNameSet.insert(accesseePkgName); continue; } } } void DeviceManagerServiceImpl::HandleUserRemoved(std::vector peerUdids, int32_t preUserId) { LOGI("PreUserId %{public}d.", preUserId); char localDeviceId[DEVICE_UUID_LENGTH]; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); std::string localUdid = reinterpret_cast(localDeviceId); std::multimap peerUserIdMap; // key: peerUdid value: peerUserId DmOfflineParam offlineParam; DeviceProfileConnector::GetInstance().DeleteAclForUserRemoved(localUdid, preUserId, peerUdids, peerUserIdMap, offlineParam); CHECK_NULL_VOID(hiChainConnector_); hiChainConnector_->DeleteAllGroup(preUserId); if (peerUserIdMap.empty()) { LOGE("peerUserIdMap is empty"); return; } CHECK_NULL_VOID(hiChainAuthConnector_); for (const auto &item : peerUserIdMap) { hiChainAuthConnector_->DeleteCredential(item.first, preUserId, item.second); } DeleteSkCredAndAcl(offlineParam.needDelAclInfos); } void DeviceManagerServiceImpl::HandleRemoteUserRemoved(int32_t userId, const std::string &remoteUdid) { LOGI("remoteUdid %{public}s, userId %{public}d", GetAnonyString(remoteUdid).c_str(), userId); std::vector localUserIds; DmOfflineParam offlineParam; DeviceProfileConnector::GetInstance().DeleteAclForRemoteUserRemoved(remoteUdid, userId, localUserIds, offlineParam); if (localUserIds.empty()) { return; } CHECK_NULL_VOID(hiChainAuthConnector_); std::vector> delInfoVec; for (int32_t localUserId : localUserIds) { delInfoVec.push_back(std::pair(localUserId, remoteUdid)); hiChainAuthConnector_->DeleteCredential(remoteUdid, localUserId, userId); } CHECK_NULL_VOID(hiChainConnector_); hiChainConnector_->DeleteGroupByACL(delInfoVec, localUserIds); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); } void DeviceManagerServiceImpl::HandleUserSwitched(const std::vector &deviceVec, int32_t currentUserId, int32_t beforeUserId) { LOGI("currentUserId: %{public}s, beforeUserId: %{public}s", GetAnonyInt32(currentUserId).c_str(), GetAnonyInt32(beforeUserId).c_str()); char localDeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); std::string localUdid = static_cast(localDeviceId); DeviceProfileConnector::GetInstance().HandleUserSwitched(localUdid, deviceVec, currentUserId, beforeUserId); } void DeviceManagerServiceImpl::ScreenCommonEventCallback(std::string commonEventType) { if (commonEventType == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED) { LOGI("on screen locked."); std::lock_guard lock(authMgrMapMtx_); for (auto& pair : authMgrMap_) { if (pair.second != nullptr) { LOGI("tokenId: %{public}s.", GetAnonyInt32(pair.first).c_str()); pair.second->OnScreenLocked(); } } return; } LOGI("error."); } bool DeviceManagerServiceImpl::CheckIsSameAccount(const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid) { return DeviceProfileConnector::GetInstance().CheckIsSameAccount(caller, srcUdid, callee, sinkUdid); } bool DeviceManagerServiceImpl::CheckAccessControl(const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid) { CHECK_NULL_RETURN(hiChainConnector_, ERR_DM_POINT_NULL); if (!hiChainConnector_->IsDevicesInP2PGroup(srcUdid, sinkUdid)) { return DeviceProfileConnector::GetInstance().CheckAccessControl(caller, srcUdid, callee, sinkUdid); } else { return true; } } void DeviceManagerServiceImpl::HandleDeviceNotTrust(const std::string &udid) { LOGI("udid: %{public}s.", GetAnonyString(udid).c_str()); if (udid.empty()) { LOGE("HandleDeviceNotTrust udid is empty."); return; } DeviceProfileConnector::GetInstance().DeleteAccessControlList(udid); CHECK_NULL_VOID(hiChainConnector_); hiChainConnector_->DeleteAllGroupByUdid(udid); } int32_t DeviceManagerServiceImpl::GetBindLevel(const std::string &pkgName, const std::string &localUdid, const std::string &udid, uint64_t &tokenId) { return DeviceProfileConnector::GetInstance().GetBindLevel(pkgName, localUdid, udid, tokenId); } std::map DeviceManagerServiceImpl::GetDeviceIdAndBindLevel(int32_t userId) { char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); std::vector userIds; userIds.push_back(userId); return DeviceProfileConnector::GetInstance().GetDeviceIdAndBindLevel(userIds, localUdid); } std::vector DeviceManagerServiceImpl::GetDeviceIdByUserIdAndTokenId(int32_t userId, int32_t tokenId) { char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); std::vector userIds; userIds.push_back(userId); return DeviceProfileConnector::GetInstance().GetDeviceIdAndUdidListByTokenId(userIds, localUdid, tokenId); } std::multimap DeviceManagerServiceImpl::GetDeviceIdAndUserId(int32_t userId, const std::string &accountId) { char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); return DeviceProfileConnector::GetInstance().GetDeviceIdAndUserId(userId, accountId, localUdid); } void DeviceManagerServiceImpl::HandleAccountLogoutEvent(int32_t remoteUserId, const std::string &remoteAccountHash, const std::string &remoteUdid) { char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); std::multimap devIdAndUserMap = DeviceProfileConnector::GetInstance().GetDevIdAndUserIdByActHash(localUdid, remoteUdid, remoteUserId, remoteAccountHash); CHECK_NULL_VOID(listener_); std::string uuid = ""; SoftbusCache::GetInstance().GetUuidByUdid(remoteUdid, uuid); listener_->OnDeviceTrustChange(remoteUdid, uuid, DmAuthForm::IDENTICAL_ACCOUNT); for (const auto &item : devIdAndUserMap) { DmOfflineParam offlineParam; LOGI("remoteUdid %{public}s.", GetAnonyString(remoteUdid).c_str()); DMAclQuadInfo info = {item.first, item.second, remoteUdid, remoteUserId}; bool notifyOffline = DeviceProfileConnector::GetInstance().DeleteAclByActhash(info, remoteAccountHash, offlineParam); CHECK_NULL_VOID(hiChainConnector_); hiChainConnector_->DeleteAllGroup(item.second); CHECK_NULL_VOID(hiChainAuthConnector_); { std::lock_guard lock(logoutMutex_); hiChainAuthConnector_->DeleteCredential(remoteUdid, item.second, remoteUserId); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); } std::set pkgNameSet; GetBundleName(info, pkgNameSet); if (notifyOffline) { CHECK_NULL_VOID(softbusConnector_); softbusConnector_->SetProcessInfoVec(offlineParam.processVec); CHECK_NULL_VOID(listener_); listener_->SetExistPkgName(pkgNameSet); CHECK_NULL_VOID(deviceStateMgr_); deviceStateMgr_->OnDeviceOffline(remoteUdid); } } } DmAuthForm DeviceManagerServiceImpl::ConvertBindTypeToAuthForm(int32_t bindType) { LOGI("BindType %{public}d.", bindType); DmAuthForm authForm = DmAuthForm::INVALID_TYPE; if (static_cast(bindType) == DM_IDENTICAL_ACCOUNT) { authForm = IDENTICAL_ACCOUNT; } else if (static_cast(bindType) == DM_POINT_TO_POINT) { authForm = PEER_TO_PEER; } else if (static_cast(bindType) == DM_ACROSS_ACCOUNT) { authForm = ACROSS_ACCOUNT; } else { LOGE("Invalied bindType."); } return authForm; } int32_t DeviceManagerServiceImpl::DeleteGroup(const std::string &pkgName, const std::string &deviceId) { LOGI("start"); if (pkgName.empty()) { LOGE("Invalid parameter, pkgName is empty."); return ERR_DM_FAILED; } std::vector groupList; CHECK_NULL_RETURN(hiChainConnector_, ERR_DM_POINT_NULL); hiChainConnector_->GetRelatedGroups(deviceId, groupList); for (const auto &item : groupList) { std::string groupId = item.groupId; hiChainConnector_->DeleteGroup(groupId); } return DM_OK; } void DeviceManagerServiceImpl::HandleDevUnBindEvent(int32_t remoteUserId, const std::string &remoteUdid) { char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); DmOfflineParam offlineParam; int32_t bindType = DeviceProfileConnector::GetInstance().HandleDevUnBindEvent( remoteUserId, remoteUdid, localUdid, offlineParam); if (static_cast(bindType) == DM_INVALIED_TYPE) { LOGE("Invalied bindtype."); return; } DeleteGroup(DM_PKG_NAME, remoteUdid); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); } void DeviceManagerServiceImpl::HandleAppUnBindEvent(int32_t remoteUserId, const std::string &remoteUdid, int32_t tokenId) { LOGI("tokenId = %{public}s.", GetAnonyInt32(tokenId).c_str()); char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); DmOfflineParam offlineParam = DeviceProfileConnector::GetInstance().HandleAppUnBindEvent(remoteUserId, remoteUdid, tokenId, localUdid); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); //first, not app/service/user/DM_IDENTICAL_ACCOUNT acl, determin if need clear lnn acl if (offlineParam.allLeftAppOrSvrAclInfos.empty() && offlineParam.allUserAclInfos.empty() && !offlineParam.allLnnAclInfos.empty()) { LOGI("No acl exist, clear lnn acl"); DeleteSkCredAndAcl(offlineParam.allLnnAclInfos); } //second, not user/DM_IDENTICAL_ACCOUNT acl, but app/service acl exist //determin if need report offline to unbind bundle if (!offlineParam.allLeftAppOrSvrAclInfos.empty() && offlineParam.allUserAclInfos.empty()) { LOGI("after clear target acl, No user acl exist, report offline"); CHECK_NULL_VOID(softbusConnector_); softbusConnector_->SetProcessInfoVec(offlineParam.processVec); softbusConnector_->HandleDeviceOffline(remoteUdid); } //third, not lnn acl, determin if delete Credential if (offlineParam.allLnnAclInfos.empty()) { CHECK_NULL_VOID(hiChainAuthConnector_); hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID(), remoteUserId); } } void DeviceManagerServiceImpl::HandleAppUnBindEvent(int32_t remoteUserId, const std::string &remoteUdid, int32_t tokenId, int32_t peerTokenId) { LOGI("DeviceManagerServiceImpl::HandleAppUnBindEvent remoteUserId: %{public}s, remoteUdid: %{public}s," "tokenId = %{public}s, peerTokenId = %{public}s.", GetAnonyInt32(remoteUserId).c_str(), GetAnonyString(remoteUdid).c_str(), GetAnonyInt32(tokenId).c_str(), GetAnonyInt32(peerTokenId).c_str()); char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); DmOfflineParam offlineParam = DeviceProfileConnector::GetInstance().HandleAppUnBindEvent(remoteUserId, remoteUdid, tokenId, localUdid, peerTokenId); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); //first, not app/service/user/DM_IDENTICAL_ACCOUNT acl, determin if need clear lnn acl if (offlineParam.allLeftAppOrSvrAclInfos.empty() && offlineParam.allUserAclInfos.empty() && !offlineParam.allLnnAclInfos.empty()) { LOGI("No acl exist, clear lnn acl"); DeleteSkCredAndAcl(offlineParam.allLnnAclInfos); } //second, not user/DM_IDENTICAL_ACCOUNT acl, but app/service acl exist //determin if need report offline to unbind bundle if (!offlineParam.allLeftAppOrSvrAclInfos.empty() && offlineParam.allUserAclInfos.empty()) { LOGI("after clear target acl, No user acl exist, report offline"); CHECK_NULL_VOID(softbusConnector_); softbusConnector_->SetProcessInfoVec(offlineParam.processVec); softbusConnector_->HandleDeviceOffline(remoteUdid); } //third, not lnn acl, determin if delete Credential if (offlineParam.allLnnAclInfos.empty()) { CHECK_NULL_VOID(hiChainAuthConnector_); hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID(), remoteUserId); } } void DeviceManagerServiceImpl::HandleServiceUnBindEvent(int32_t userId, const std::string &remoteUdid, int32_t remoteTokenId) { LOGI("remoteTokenId = %{public}s, userId: %{public}d, remoteUdid: %{public}s.", GetAnonyInt32(remoteTokenId).c_str(), userId, GetAnonyString(remoteUdid).c_str()); char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); DmOfflineParam offlineParam = DeviceProfileConnector::GetInstance().HandleServiceUnBindEvent(userId, remoteUdid, localUdid, remoteTokenId); //first, app/service acl exist, determin if need local acl DeleteSkCredAndAcl(offlineParam.needDelAclInfos); //second, not app/service/user/DM_IDENTICAL_ACCOUNT acl exist, determin if need clear lnn acl if (offlineParam.allLeftAppOrSvrAclInfos.empty() && offlineParam.allUserAclInfos.empty()) { LOGI("No acl exist, clear lnn acl"); DeleteSkCredAndAcl(offlineParam.allLnnAclInfos); } //Third, not user/DM_IDENTICAL_ACCOUNT acl exist but app/service acl exist, //determin if need report offline to unbind bundle if (!offlineParam.allLeftAppOrSvrAclInfos.empty() && offlineParam.allUserAclInfos.empty()) { LOGI("after clear target acl, No user acl exist, report offline"); softbusConnector_->SetProcessInfoVec(offlineParam.processVec); softbusConnector_->HandleDeviceOffline(remoteUdid); } } void DeviceManagerServiceImpl::HandleSyncUserIdEvent(const std::vector &foregroundUserIds, const std::vector &backgroundUserIds, const std::string &remoteUdid, bool isCheckUserStatus) { LOGI("remote udid: %{public}s, foregroundUserIds: %{public}s, backgroundUserIds: %{public}s", GetAnonyString(remoteUdid).c_str(), GetIntegerList(foregroundUserIds).c_str(), GetIntegerList(backgroundUserIds).c_str()); char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); std::vector rmtFrontUserIdsTemp(foregroundUserIds.begin(), foregroundUserIds.end()); std::vector rmtBackUserIdsTemp(backgroundUserIds.begin(), backgroundUserIds.end()); std::vector localUserIds; int32_t ret = MultipleUserConnector::GetForegroundUserIds(localUserIds); if (ret != DM_OK) { LOGE("Get foreground userids failed, ret: %{public}d", ret); return; } if (isCheckUserStatus) { MultipleUserConnector::ClearLockedUser(localUserIds); } DmOfflineParam offlineParam; DeviceProfileConnector::GetInstance().UpdateACL(localUdid, localUserIds, remoteUdid, rmtFrontUserIdsTemp, rmtBackUserIdsTemp, offlineParam); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); DeviceProfileConnector::GetInstance().HandleSyncBackgroundUserIdEvent(rmtBackUserIdsTemp, remoteUdid, localUserIds, localUdid); DeviceProfileConnector::GetInstance().HandleSyncForegroundUserIdEvent(rmtFrontUserIdsTemp, remoteUdid, localUserIds, localUdid); } void DeviceManagerServiceImpl::HandleDeviceScreenStatusChange(DmDeviceInfo &devInfo) { LOGI("In"); CHECK_NULL_VOID(deviceStateMgr_); CHECK_NULL_VOID(softbusConnector_); std::string trustDeviceId = ""; if (softbusConnector_->GetUdidByNetworkId(devInfo.networkId, trustDeviceId) != DM_OK) { LOGE("get udid failed."); return; } std::string udidHash = softbusConnector_->GetDeviceUdidHashByUdid(trustDeviceId); if (memcpy_s(devInfo.deviceId, DM_MAX_DEVICE_ID_LEN, udidHash.c_str(), udidHash.length()) != 0) { LOGE("get deviceId: %{public}s failed", GetAnonyString(udidHash).c_str()); return; } char localUdid[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdid, DEVICE_UUID_LENGTH); std::string requestDeviceId = static_cast(localUdid); uint32_t bindType = DeviceProfileConnector::GetInstance().CheckBindType(trustDeviceId, requestDeviceId); LOGI("bind type is %{public}d.", bindType); std::vector processInfoVec; if (bindType == INVALIED_TYPE) { return; } else if (bindType == IDENTICAL_ACCOUNT_TYPE || bindType == DEVICE_PEER_TO_PEER_TYPE || bindType == DEVICE_ACROSS_ACCOUNT_TYPE) { ProcessInfo processInfo; processInfo.pkgName = std::string(DM_PKG_NAME); processInfo.userId = MultipleUserConnector::GetFirstForegroundUserId(); processInfoVec.push_back(processInfo); } else if (bindType == APP_PEER_TO_PEER_TYPE || bindType == APP_ACROSS_ACCOUNT_TYPE) { processInfoVec = DeviceProfileConnector::GetInstance().GetProcessInfoFromAclByUserId(requestDeviceId, trustDeviceId, MultipleUserConnector::GetFirstForegroundUserId()); } deviceStateMgr_->HandleDeviceScreenStatusChange(devInfo, processInfoVec); } int32_t DeviceManagerServiceImpl::SyncLocalAclListProcess(const DevUserInfo &localDevUserInfo, const DevUserInfo &remoteDevUserInfo, std::string remoteAclList) { CHECK_NULL_RETURN(softbusConnector_, ERR_DM_POINT_NULL); return softbusConnector_->SyncLocalAclListProcess(localDevUserInfo, remoteDevUserInfo, remoteAclList); } int32_t DeviceManagerServiceImpl::GetAclListHash(const DevUserInfo &localDevUserInfo, const DevUserInfo &remoteDevUserInfo, std::string &aclList) { CHECK_NULL_RETURN(softbusConnector_, ERR_DM_POINT_NULL); return softbusConnector_->GetAclListHash(localDevUserInfo, remoteDevUserInfo, aclList); } void DeviceManagerServiceImpl::HandleCredentialAuthStatus(const std::string &deviceList, uint16_t deviceTypeId, int32_t errcode) { CHECK_NULL_VOID(credentialMgr_); credentialMgr_->HandleCredentialAuthStatus(deviceList, deviceTypeId, errcode); } int32_t DeviceManagerServiceImpl::ProcessAppUnintall(const std::string &appId, int32_t accessTokenId) { CHECK_NULL_RETURN(listener_, ERR_DM_POINT_NULL); std::vector profiles = DeviceProfileConnector::GetInstance().GetAllAclIncludeLnnAcl(); LOGI("delete ACL size is %{public}zu, appId %{public}s", profiles.size(), GetAnonyString(appId).c_str()); if (profiles.size() == 0) { return DM_OK; } char localDeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localDeviceId); std::vector> delACLInfoVec; std::vector userIdVec; std::map delProfileMap; DeleteAclByTokenId(accessTokenId, profiles, delProfileMap, delACLInfoVec, userIdVec); for (auto item : delProfileMap) { DmOfflineParam lnnAclParam; bool isLastLnnAcl = false; for (auto it : profiles) { CheckIsLastLnnAcl(it, item.second, lnnAclParam, isLastLnnAcl, localUdid); } if (!isLastLnnAcl) { DeleteSkCredAndAcl(lnnAclParam.needDelAclInfos); } } if (delACLInfoVec.size() == 0) { return DM_OK; } if (userIdVec.size() == 0) { return DM_OK; } CHECK_NULL_RETURN(hiChainConnector_, ERR_DM_POINT_NULL); hiChainConnector_->DeleteGroupByACL(delACLInfoVec, userIdVec); return DM_OK; } int32_t DeviceManagerServiceImpl::ProcessAppUninstall(int32_t userId, int32_t accessTokenId) { LOGE("DeviceManagerServiceImpl::ProcessAppUninstall userId = %{public}s, accessTokenId = %{public}s.", GetAnonyInt32(userId).c_str(), GetAnonyInt32(accessTokenId).c_str()); CHECK_NULL_RETURN(listener_, ERR_DM_POINT_NULL); std::vector profiles = DeviceProfileConnector::GetInstance().GetAllAclIncludeLnnAcl(); LOGI("delete ACL size is %{public}zu", profiles.size()); if (profiles.size() == 0) { return DM_OK; } char localDeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localDeviceId); std::vector> delACLInfoVec; std::vector userIdVec; GetDelACLInfoVec(accessTokenId, profiles, delACLInfoVec, userIdVec, userId); if (delACLInfoVec.size() == 0 || userIdVec.size() == 0) { return DM_OK; } CHECK_NULL_RETURN(hiChainConnector_, ERR_DM_POINT_NULL); hiChainConnector_->DeleteGroupByACL(delACLInfoVec, userIdVec); return DM_OK; } void DeviceManagerServiceImpl::ProcessUnBindApp(int32_t userId, int32_t accessTokenId, const std::string &extra, const std::string &udid) { LOGI("DeviceManagerServiceImpl::ProcessUnBindApp userId = %{public}s, accessTokenId = %{public}s," "extra = %{public}s.", GetAnonyInt32(userId).c_str(), GetAnonyInt32(accessTokenId).c_str(), GetAnonyString(extra).c_str()); JsonObject extraInfoJson(extra); if (extraInfoJson.IsDiscarded()) { LOGE("ParseExtra extraInfoJson error"); HandleAppUnBindEvent(userId, udid, accessTokenId); return; } if (extraInfoJson.Contains(TAG_PEER_TOKENID) && extraInfoJson[TAG_PEER_TOKENID].IsNumberInteger()) { uint64_t peerTokenId = extraInfoJson[TAG_PEER_TOKENID].Get(); HandleAppUnBindEvent(userId, udid, accessTokenId, static_cast(peerTokenId)); } return; } void DeviceManagerServiceImpl::CheckIsLastLnnAcl(DistributedDeviceProfile::AccessControlProfile profile, DistributedDeviceProfile::AccessControlProfile delProfile, DmOfflineParam &lnnAclParam, bool &isLastLnnAcl, const std::string &localUdid) { if (DeviceProfileConnector::GetInstance().IsLnnAcl(profile) && CheckLnnAcl(delProfile, profile)) { if (profile.GetAccesser().GetAccesserDeviceId() == localUdid) { DeviceProfileConnector::GetInstance().CacheAcerAclId(profile, lnnAclParam.needDelAclInfos); } if (profile.GetAccessee().GetAccesseeDeviceId() == localUdid) { DeviceProfileConnector::GetInstance().CacheAceeAclId(profile, lnnAclParam.needDelAclInfos); } } if (!DeviceProfileConnector::GetInstance().IsLnnAcl(profile) && CheckLnnAcl(delProfile, profile)) { isLastLnnAcl = true; } } void DeviceManagerServiceImpl::DeleteAclByTokenId(const int32_t accessTokenId, std::vector &profiles, std::map &delProfileMap, std::vector> &delACLInfoVec, std::vector &userIdVec) { for (auto &item : profiles) { int64_t accesssertokenId = item.GetAccesser().GetAccesserTokenId(); int64_t accessseetokenId = item.GetAccessee().GetAccesseeTokenId(); if (accessTokenId != static_cast(accesssertokenId) && accessTokenId != static_cast(accessseetokenId)) { continue; } if (accessTokenId == static_cast(accesssertokenId)) { DmOfflineParam offlineParam; delProfileMap[item.GetAccessControlId()] = item; DeviceProfileConnector::GetInstance().CacheAcerAclId(item, offlineParam.needDelAclInfos); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); listener_->OnAppUnintall(item.GetAccesser().GetAccesserBundleName()); if (item.GetBindLevel() == USER) { userIdVec.push_back(item.GetAccesser().GetAccesserUserId()); delACLInfoVec.push_back(std::pair(item.GetAccesser().GetAccesserUserId(), item.GetAccessee().GetAccesseeDeviceId())); } } if (accessTokenId == static_cast(accessseetokenId)) { DmOfflineParam offlineParam; DeviceProfileConnector::GetInstance().CacheAceeAclId(item, offlineParam.needDelAclInfos); delProfileMap[item.GetAccessControlId()] = item; DeleteSkCredAndAcl(offlineParam.needDelAclInfos); listener_->OnAppUnintall(item.GetAccessee().GetAccesseeBundleName()); if (item.GetBindLevel() == USER) { userIdVec.push_back(item.GetAccessee().GetAccesseeUserId()); delACLInfoVec.push_back(std::pair(item.GetAccessee().GetAccesseeUserId(), item.GetAccesser().GetAccesserDeviceId())); } } } for (auto item : delProfileMap) { for (auto it = profiles.begin(); it != profiles.end();) { if (item.first == it->GetAccessControlId()) { it = profiles.erase(it); } else { it++; } } } } void DeviceManagerServiceImpl::GetDelACLInfoVec(const int32_t &accessTokenId, std::vector &profiles, std::vector> &delACLInfoVec, std::vector &userIdVec, const uint32_t &userId) { std::map delProfileMap; char localDeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localDeviceId); for (auto &item : profiles) { int64_t accesssertokenId = item.GetAccesser().GetAccesserTokenId(); int64_t accessseetokenId = item.GetAccessee().GetAccesseeTokenId(); if (accessTokenId != static_cast(accesssertokenId) && accessTokenId != static_cast(accessseetokenId)) { continue; } if (accessTokenId == static_cast(accesssertokenId) && userId == item.GetAccesser().GetAccesserUserId() && localUdid == item.GetAccessee().GetAccesseeDeviceId()) { DmOfflineParam offlineParam; delProfileMap[item.GetAccessControlId()] = item; DeviceProfileConnector::GetInstance().CacheAcerAclId(item, offlineParam.needDelAclInfos); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); if (item.GetBindLevel() == USER) { userIdVec.push_back(item.GetAccessee().GetAccesseeUserId()); delACLInfoVec.push_back(std::pair(item.GetAccessee().GetAccesseeUserId(), item.GetAccesser().GetAccesserDeviceId())); } } if (accessTokenId == static_cast(accessseetokenId) && userId == item.GetAccessee().GetAccesseeUserId() && localUdid == item.GetAccesser().GetAccesserDeviceId()) { DmOfflineParam offlineParam; DeviceProfileConnector::GetInstance().CacheAceeAclId(item, offlineParam.needDelAclInfos); delProfileMap[item.GetAccessControlId()] = item; DeleteSkCredAndAcl(offlineParam.needDelAclInfos); if (item.GetBindLevel() == USER) { userIdVec.push_back(item.GetAccesser().GetAccesserUserId()); delACLInfoVec.push_back(std::pair(item.GetAccesser().GetAccesserUserId(), item.GetAccessee().GetAccesseeDeviceId())); } } } DeleteAclByDelProfileMap(delProfileMap, profiles, localUdid); } void DeviceManagerServiceImpl::DeleteAclByDelProfileMap( const std::map &delProfileMap, std::vector &profiles, const std::string &localUdid) { for (auto item : delProfileMap) { for (auto it = profiles.begin(); it != profiles.end();) { if (item.first == it->GetAccessControlId()) { it = profiles.erase(it); } else { it++; } } } for (auto item : delProfileMap) { DmOfflineParam lnnAclParam; bool isLastLnnAcl = false; for (auto it : profiles) { CheckIsLastLnnAcl(it, item.second, lnnAclParam, isLastLnnAcl, localUdid); } if (!isLastLnnAcl) { DeleteSkCredAndAcl(lnnAclParam.needDelAclInfos); } } } bool DeviceManagerServiceImpl::CheckLnnAcl(DistributedDeviceProfile::AccessControlProfile delProfile, DistributedDeviceProfile::AccessControlProfile lastprofile) { if ((delProfile.GetAccesser().GetAccesserDeviceId() == lastprofile.GetAccesser().GetAccesserDeviceId() && delProfile.GetAccesser().GetAccesserUserId() == lastprofile.GetAccesser().GetAccesserUserId() && delProfile.GetAccessee().GetAccesseeDeviceId() == lastprofile.GetAccessee().GetAccesseeDeviceId() && delProfile.GetAccessee().GetAccesseeUserId() == lastprofile.GetAccessee().GetAccesseeUserId()) || (delProfile.GetAccesser().GetAccesserDeviceId() == lastprofile.GetAccessee().GetAccesseeDeviceId() && delProfile.GetAccesser().GetAccesserUserId() == lastprofile.GetAccessee().GetAccesseeUserId() && delProfile.GetAccessee().GetAccesseeDeviceId() == lastprofile.GetAccesser().GetAccesserDeviceId() && delProfile.GetAccessee().GetAccesseeUserId() == lastprofile.GetAccesser().GetAccesserUserId())) { return true; } return false; } std::multimap DeviceManagerServiceImpl::GetDeviceIdAndUserId(int32_t localUserId) { LOGI("localUserId %{public}d.", localUserId); char localdeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localdeviceId, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localdeviceId); return DeviceProfileConnector::GetInstance().GetDeviceIdAndUserId(localUdid, localUserId); } int32_t DeviceManagerServiceImpl::SaveOnlineDeviceInfo(const std::vector &deviceList) { CHECK_NULL_RETURN(deviceStateMgr_, ERR_DM_POINT_NULL); for (auto item : deviceList) { deviceStateMgr_->SaveOnlineDeviceInfo(item); } return DM_OK; } void DeviceManagerServiceImpl::HandleDeviceUnBind(int32_t bindType, const std::string &peerUdid, const std::string &localUdid, int32_t localUserId, const std::string &localAccountId) { return DeviceProfileConnector::GetInstance().HandleDeviceUnBind(bindType, peerUdid, localUdid, localUserId, localAccountId); } int32_t DeviceManagerServiceImpl::RegisterAuthenticationType(int32_t authenticationType) { if (authenticationType != USER_OPERATION_TYPE_ALLOW_AUTH && authenticationType != USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS) { LOGE("Invalid parameter."); return ERR_DM_INPUT_PARA_INVALID; } auto authMgr = GetAuthMgr(); if (authMgr == nullptr) { auto config = GetConfigByTokenId(); config->authenticationType = authenticationType; // only the last registration is retained return DM_OK; } return authMgr->RegisterAuthenticationType(authenticationType); } void DeviceManagerServiceImpl::DeleteAlwaysAllowTimeOut() { LOGI("Start"); std::vector profiles = DeviceProfileConnector::GetInstance().GetAllAccessControlProfile(); std::string remoteUdid = ""; int32_t remoteUserId = -1; int64_t currentTime = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); int32_t currentUserId = MultipleUserConnector::GetCurrentAccountUserID(); char localDeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localDeviceId); for (auto &item : profiles) { if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) { continue; } if ((currentTime - item.GetLastAuthTime()) > MAX_ALWAYS_ALLOW_SECONDS && item.GetLastAuthTime() > 0) { DeviceProfileConnector::GetInstance().DeleteAccessControlById(item.GetAccessControlId()); if (item.GetAccesser().GetAccesserUserId() == currentUserId && item.GetAccesser().GetAccesserDeviceId() == localUdid) { remoteUserId = item.GetAccessee().GetAccesseeUserId(); } if (item.GetAccessee().GetAccesseeUserId() == currentUserId && item.GetAccessee().GetAccesseeDeviceId() == localUdid) { remoteUserId = item.GetAccesser().GetAccesserUserId(); } remoteUdid = item.GetTrustDeviceId(); CheckDeleteCredential(remoteUdid, remoteUserId); } } } void DeviceManagerServiceImpl::CheckDeleteCredential(const std::string &remoteUdid, int32_t remoteUserId) { std::vector profiles = DeviceProfileConnector::GetInstance().GetAllAccessControlProfile(); bool leftAcl = false; for (auto &item : profiles) { if (item.GetTrustDeviceId() == remoteUdid) { leftAcl = true; } } if (!leftAcl) { LOGI("CheckDeleteCredential delete credential"); hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID(), remoteUserId); } } void DeviceManagerServiceImpl::HandleCredentialDeleted(const char *credId, const char *credInfo, const std::string &localUdid, std::string &remoteUdid, bool &isSendBroadCast) { std::vector profiles; { std::lock_guard lock(logoutMutex_); profiles = DeviceProfileConnector::GetInstance().GetAccessControlProfile(); } JsonObject jsonObject; jsonObject.Parse(std::string(credInfo)); if (jsonObject.IsDiscarded()) { LOGE("credInfo prase error."); return; } std::string deviceIdTag = "deviceId"; std::string userIdTag = "osAccountId"; int32_t localUserId = MultipleUserConnector::GetCurrentAccountUserID(); int32_t userId = 0; if (IsString(jsonObject, deviceIdTag)) { remoteUdid = jsonObject[deviceIdTag].Get(); } if (IsInt32(jsonObject, userIdTag)) { userId = jsonObject[userIdTag].Get(); } for (const auto &item : profiles) { if (item.GetBindType() != DM_SHARE) { continue; } if ((item.GetAccesser().GetAccesserCredentialIdStr() == credId && item.GetAccesser().GetAccesserDeviceId() == localUdid && item.GetAccesser().GetAccesserUserId() == localUserId && item.GetAccessee().GetAccesseeUserId() == userId && item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) || (item.GetAccessee().GetAccesseeCredentialIdStr() == credId && item.GetAccessee().GetAccesseeDeviceId() == localUdid && item.GetAccessee().GetAccesseeUserId() == localUserId && item.GetAccesser().GetAccesserUserId() == userId && item.GetAccesser().GetAccesserDeviceId() == remoteUdid)) { isSendBroadCast = true; DeleteSessionKey(userId, item); DeviceProfileConnector::GetInstance().DeleteAccessControlById(item.GetAccessControlId()); } } } void DeviceManagerServiceImpl::HandleShareUnbindBroadCast(const std::string &credId, const int32_t &userId, const std::string &localUdid) { std::vector profiles; { std::lock_guard lock(logoutMutex_); profiles = DeviceProfileConnector::GetInstance().GetAccessControlProfile(); } int32_t localUserId = MultipleUserConnector::GetCurrentAccountUserID(); for (const auto &item : profiles) { if (item.GetBindType() != DM_SHARE) { continue; } std::string accesserCredId = ""; std::string accesseeCredId = ""; for (int32_t i = 0; i < BROADCAST_CREDID_LENGTH; i++) { accesserCredId += item.GetAccesser().GetAccesserCredentialIdStr()[i]; accesseeCredId += item.GetAccessee().GetAccesseeCredentialIdStr()[i]; } if (accesserCredId == credId && item.GetAccessee().GetAccesseeDeviceId() == localUdid && item.GetAccessee().GetAccesseeUserId() == localUserId && item.GetAccesser().GetAccesserUserId() == userId) { DeleteSessionKey(userId, item); DeviceProfileConnector::GetInstance().DeleteAccessControlById(item.GetAccessControlId()); } if (accesseeCredId == credId && item.GetAccesser().GetAccesserDeviceId() == localUdid && item.GetAccesser().GetAccesserUserId() == localUserId && item.GetAccessee().GetAccesseeUserId() == userId) { DeleteSessionKey(userId, item); DeviceProfileConnector::GetInstance().DeleteAccessControlById(item.GetAccessControlId()); } } } int32_t DeviceManagerServiceImpl::CheckDeviceInfoPermission(const std::string &localUdid, const std::string &peerDeviceId) { int32_t ret = DeviceProfileConnector::GetInstance().CheckDeviceInfoPermission(localUdid, peerDeviceId); if (ret != DM_OK) { LOGE("CheckDeviceInfoPermission failed, ret: %{public}d", ret); return ret; } return DM_OK; } int32_t DeviceManagerServiceImpl::DeleteAcl(const std::string &pkgName, const std::string &localUdid, const std::string &remoteUdid, int32_t bindLevel, const std::string &extra) { LOGI("pkgName %{public}s, localUdid %{public}s, remoteUdid %{public}s, bindLevel %{public}d.", pkgName.c_str(), GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), bindLevel); if (static_cast(bindLevel) == USER) { DeleteGroup(pkgName, remoteUdid); } DmOfflineParam offlineParam = DeviceProfileConnector::GetInstance().DeleteAccessControlList(pkgName, localUdid, remoteUdid, bindLevel, extra); if (offlineParam.bindType == INVALIED_TYPE) { LOGE("Acl not contain the pkgname bind data."); return ERR_DM_FAILED; } CHECK_NULL_RETURN(softbusConnector_, ERR_DM_POINT_NULL); CHECK_NULL_RETURN(hiChainAuthConnector_, ERR_DM_POINT_NULL); if (static_cast(bindLevel) == APP) { ProcessInfo processInfo; processInfo.pkgName = pkgName; processInfo.userId = MultipleUserConnector::GetFirstForegroundUserId(); if (offlineParam.leftAclNumber != 0) { LOGI("The pkgName unbind app-level type leftAclNumber not zero."); softbusConnector_->SetProcessInfoVec(offlineParam.processVec); softbusConnector_->HandleDeviceOffline(remoteUdid); return DM_OK; } if (offlineParam.leftAclNumber == 0) { LOGI("The pkgName unbind app-level type leftAclNumber is zero."); softbusConnector_->SetProcessInfoVec(offlineParam.processVec); hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID(), offlineParam.peerUserId); return DM_OK; } } if (static_cast(bindLevel) == USER && offlineParam.leftAclNumber != 0) { LOGI("Unbind deivce-level, retain identical account bind type."); return DM_OK; } if (static_cast(bindLevel) == USER && offlineParam.leftAclNumber == 0) { LOGI("Unbind deivce-level, retain null."); hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID(), offlineParam.peerUserId); return DM_OK; } return ERR_DM_FAILED; } void DeviceManagerServiceImpl::DeleteCredential(DmAclIdParam &acl) { CHECK_NULL_VOID(hiChainAuthConnector_); JsonObject credJson; int32_t ret = hiChainAuthConnector_->QueryCredInfoByCredId(acl.userId, acl.credId, credJson); if (ret != DM_OK || !credJson.Contains(acl.credId)) { LOGE("DeleteCredential err, ret:%{public}d", ret); return; } if (!credJson[acl.credId].Contains(FILED_AUTHORIZED_APP_LIST)) { ret = hiChainAuthConnector_->DeleteCredential(acl.userId, acl.credId); if (ret != DM_OK) { LOGE("DeletecredId err, ret:%{public}d", ret); } return; } DistributedDeviceProfile::AccessControlProfile profile = DeviceProfileConnector::GetInstance().GetAccessControlProfileByAccessControlId(acl.accessControlId); if (profile.GetAccessControlId() != acl.accessControlId) { LOGE("DeleteCredential, no found profile"); return; } std::vector appList; credJson[acl.credId][FILED_AUTHORIZED_APP_LIST].Get(appList); auto erIt = std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccesser().GetAccesserTokenId())); if (erIt != appList.end()) { appList.erase(erIt); } auto eeIt = std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccessee().GetAccesseeTokenId())); if (eeIt != appList.end()) { appList.erase(eeIt); } if (appList.size() == 0) { ret = hiChainAuthConnector_->DeleteCredential(acl.userId, acl.credId); if (ret != DM_OK) { LOGE("DeletecredId err, ret:%{public}d", ret); } return; } hiChainAuthConnector_->UpdateCredential(acl.credId, acl.userId, appList); } int32_t DeviceManagerServiceImpl::DeleteSkCredAndAcl(const std::vector &acls) { LOGI("start."); int32_t ret = DM_OK; if (acls.empty()) { return ret; } CHECK_NULL_RETURN(hiChainAuthConnector_, ERR_DM_POINT_NULL); for (auto item : acls) { LOGI("DeleteSkCredAndAcl, userId:%{public}d, skId:%{public}d, credId:%{public}s", item.userId, item.skId, GetAnonyString(item.credId).c_str()); ret = DeviceProfileConnector::GetInstance().DeleteSessionKey(item.userId, item.skId); if (ret != DM_OK) { LOGE("DeleteSessionKey err, ret:%{public}d", ret); } DeleteCredential(item); DeviceProfileConnector::GetInstance().DeleteAccessControlById(item.accessControlId); } return ret; } int32_t DeviceManagerServiceImpl::DeleteAclForProcV2(const std::string &localUdid, uint32_t localTokenId, const std::string &remoteUdid, int32_t bindLevel, const std::string &extra, int32_t userId) { DmOfflineParam offlineParam = DeviceProfileConnector::GetInstance().FilterNeedDeleteACL( localUdid, localTokenId, remoteUdid, extra); //first, clear the unbind sk/cred/acl DeleteSkCredAndAcl(offlineParam.needDelAclInfos); //second, not app/service/user/DM_IDENTICAL_ACCOUNT acl exist, determin if need clear lnn acl if (offlineParam.allLeftAppOrSvrAclInfos.empty() && offlineParam.allUserAclInfos.empty()) { LOGI("No acl exist, clear lnn acl"); DeleteSkCredAndAcl(offlineParam.allLnnAclInfos); } //third, not user/DM_IDENTICAL_ACCOUNT acl exist but app/service acl exist //determin if need report offline to unbind bundle if (offlineParam.allUserAclInfos.empty() && !offlineParam.allLeftAppOrSvrAclInfos.empty()) { LOGI("after clear target acl, No user acl exist, report offline"); softbusConnector_->SetProcessInfoVec(offlineParam.processVec); softbusConnector_->HandleDeviceOffline(remoteUdid); } return DM_OK; } bool DeviceManagerServiceImpl::IsProxyUnbind(const std::string &extra) { if (extra.empty()) { return false; } JsonObject jsonObject; jsonObject.Parse(extra); if (jsonObject.IsDiscarded()) { return false; } if (IsString(jsonObject, PARAM_KEY_IS_PROXY_UNBIND) && jsonObject[PARAM_KEY_IS_PROXY_UNBIND].Get() == DM_VAL_TRUE) { return true; } return false; } int32_t DeviceManagerServiceImpl::DeleteAclV2(const std::string &pkgName, const std::string &localUdid, const std::string &remoteUdid, int32_t bindLevel, const std::string &extra) { LOGI("pkgName %{public}s, localUdid %{public}s, remoteUdid %{public}s, bindLevel %{public}d.", pkgName.c_str(), GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), bindLevel); int64_t tokenId = 0; int32_t userId = MultipleUserConnector::GetCurrentAccountUserID(); if (IsProxyUnbind(extra) != true) { uint32_t callingTokenId = 0; MultipleUserConnector::GetTokenId(callingTokenId); tokenId = static_cast(callingTokenId); } else { std::string bundleName = pkgName; AppManager::GetInstance().GetTokenIdByBundleName(userId, bundleName, tokenId); } bool isNewVersion = IsAuthNewVersion(bindLevel, localUdid, remoteUdid, tokenId, userId); if (!isNewVersion) { return DeleteAcl(pkgName, localUdid, remoteUdid, bindLevel, extra); } return DeleteAclForProcV2(localUdid, tokenId, remoteUdid, bindLevel, extra, userId); } void DeviceManagerServiceImpl::HandleCommonEventBroadCast(const std::vector &foregroundUserIds, const std::vector &backgroundUserIds, const std::string &remoteUdid) { LOGI("remote udid: %{public}s, foregroundUserIds: %{public}s, backgroundUserIds: %{public}s", GetAnonyString(remoteUdid).c_str(), GetIntegerList(foregroundUserIds).c_str(), GetIntegerList(backgroundUserIds).c_str()); std::vector rmtFrontUserIdsTemp(foregroundUserIds.begin(), foregroundUserIds.end()); std::vector rmtBackUserIdsTemp(backgroundUserIds.begin(), backgroundUserIds.end()); std::vector localUserIds; int32_t ret = MultipleUserConnector::GetForegroundUserIds(localUserIds); if (ret != DM_OK) { LOGE("Get foreground userids failed, ret: %{public}d", ret); return; } char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); MultipleUserConnector::ClearLockedUser(localUserIds); DmOfflineParam offlineParam; DeviceProfileConnector::GetInstance().UpdateACL(localUdid, localUserIds, remoteUdid, rmtFrontUserIdsTemp, rmtBackUserIdsTemp, offlineParam); DeleteSkCredAndAcl(offlineParam.needDelAclInfos); DeviceProfileConnector::GetInstance().HandleSyncBackgroundUserIdEvent(rmtBackUserIdsTemp, remoteUdid, localUserIds, localUdid); DeviceProfileConnector::GetInstance().HandleSyncForegroundUserIdEvent(rmtFrontUserIdsTemp, remoteUdid, localUserIds, localUdid); } void DeviceManagerServiceImpl::GetBindCallerInfo(DmBindCallerInfo &bindCallerInfo, const std::string &pkgName) { int32_t userId = -1; MultipleUserConnector::GetCallerUserId(userId); uint32_t callingTokenId = 0; MultipleUserConnector::GetCallingTokenId(callingTokenId); bool isSystemSA = false; std::string bundleName = ""; AppManager::GetInstance().GetCallerName(isSystemSA, bundleName); std::string processName = ""; AppManager::GetInstance().GetCallerProcessName(processName); int32_t bindLevel = static_cast(DmRole::DM_ROLE_FA); if (AppManager::GetInstance().IsSystemApp()) { bindLevel = static_cast(DmRole::DM_ROLE_FA); } if (AppManager::GetInstance().IsSystemSA()) { isSystemSA = true; bindLevel = static_cast(DmRole::DM_ROLE_SA); } if (AuthManagerBase::CheckProcessNameInWhiteList(bundleName)) { bindLevel = static_cast(DmRole::DM_ROLE_USER); } std::string hostPkgLabel = GetBundleLable(pkgName); bindCallerInfo.userId = userId; bindCallerInfo.tokenId = static_cast(callingTokenId); bindCallerInfo.bindLevel = bindLevel; bindCallerInfo.bundleName = bundleName; bindCallerInfo.hostPkgLabel = hostPkgLabel; bindCallerInfo.processName = processName; bindCallerInfo.isSystemSA = isSystemSA; LOGI("userId %{public}d, tokenId %{public}s, bindLevel %{public}d, bundleName %{public}s, hostPkgLabel %{public}s," "processName %{public}s, isSystemSA %{public}d", userId, GetAnonyInt32(callingTokenId).c_str(), bindLevel, GetAnonyString(bundleName).c_str(), GetAnonyString(hostPkgLabel).c_str(), GetAnonyString(processName).c_str(), isSystemSA); } std::string DeviceManagerServiceImpl::GetBundleLable(const std::string &bundleName) { auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgr == nullptr) { LOGE("Get ability manager failed"); return bundleName; } sptr object = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); if (object == nullptr) { LOGE("object is NULL."); return bundleName; } sptr bms = iface_cast(object); if (bms == nullptr) { LOGE("bundle manager service is NULL."); return bundleName; } auto bundleResourceProxy = bms->GetBundleResourceProxy(); if (bundleResourceProxy == nullptr) { LOGE("GetBundleResourceProxy fail"); return bundleName; } AppExecFwk::BundleResourceInfo resourceInfo; auto result = bundleResourceProxy->GetBundleResourceInfo(bundleName, static_cast(OHOS::AppExecFwk::ResourceFlag::GET_RESOURCE_INFO_ALL), resourceInfo); if (result != ERR_OK) { LOGE("GetBundleResourceInfo failed"); return bundleName; } LOGI("bundle resource label is %{public}s ", (resourceInfo.label).c_str()); return resourceInfo.label; } void DeviceManagerServiceImpl::SetBindCallerInfoToBindParam(const std::map &bindParam, std::map &bindParamTmp, const DmBindCallerInfo &bindCallerInfo) { bindParamTmp = const_cast &>(bindParam); bindParamTmp["bindCallerUserId"] = std::to_string(bindCallerInfo.userId); bindParamTmp["bindCallerTokenId"] = std::to_string(bindCallerInfo.tokenId); bindParamTmp["bindCallerBindLevel"] = std::to_string(bindCallerInfo.bindLevel); bindParamTmp["bindCallerBundleName"] = bindCallerInfo.bundleName; bindParamTmp["bindCallerHostPkgLabel"] = bindCallerInfo.hostPkgLabel; bindParamTmp["bindCallerProcessName"] = bindCallerInfo.processName; bindParamTmp["bindCallerIsSystemSA"] = bindCallerInfo.isSystemSA; } bool DeviceManagerServiceImpl::CheckSrcAccessControl(const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid) { return DeviceProfileConnector::GetInstance().CheckSrcAccessControl(caller, srcUdid, callee, sinkUdid); } bool DeviceManagerServiceImpl::CheckSinkAccessControl(const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid) { return DeviceProfileConnector::GetInstance().CheckSinkAccessControl(caller, srcUdid, callee, sinkUdid); } bool DeviceManagerServiceImpl::CheckSrcIsSameAccount(const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid) { return DeviceProfileConnector::GetInstance().CheckSrcIsSameAccount(caller, srcUdid, callee, sinkUdid); } bool DeviceManagerServiceImpl::CheckSinkIsSameAccount(const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid) { return DeviceProfileConnector::GetInstance().CheckSinkIsSameAccount(caller, srcUdid, callee, sinkUdid); } void DeviceManagerServiceImpl::DeleteHoDevice(const std::string &peerUdid, const std::vector &foreGroundUserIds, const std::vector &backGroundUserIds) { LOGI("peerudid %{public}s, foreGroundUserIds %{public}s, backGroundUserIds %{public}s.", GetAnonyString(peerUdid).c_str(), GetIntegerList(foreGroundUserIds).c_str(), GetIntegerList(backGroundUserIds).c_str()); //delete acl DeviceProfileConnector::GetInstance().DeleteHoDevice(peerUdid, foreGroundUserIds, backGroundUserIds); //delete group hiChainConnector_->DeleteHoDevice(peerUdid, foreGroundUserIds, backGroundUserIds); return; } void DeviceManagerServiceImpl::DeleteSessionKey(int32_t userId, const DistributedDeviceProfile::AccessControlProfile &profile) { int32_t skId = profile.GetAccesser().GetAccesserSessionKeyId(); DeviceProfileConnector::GetInstance().DeleteSessionKey(userId, skId); skId = profile.GetAccessee().GetAccesseeSessionKeyId(); DeviceProfileConnector::GetInstance().DeleteSessionKey(userId, skId); } extern "C" IDeviceManagerServiceImpl *CreateDMServiceObject(void) { return new DeviceManagerServiceImpl; } } // namespace DistributedHardware } // namespace OHOS