• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "access_control_profile.h"
17 #include "hichain_auth_connector.h"
18 #include "multiple_user_connector.h"
19 #include "dm_crypto.h"
20 #include "dm_auth_state.h"
21 #include "dm_auth_context.h"
22 #include "dm_auth_manager_base.h"
23 #include "dm_auth_state_machine.h"
24 #include "dm_crypto.h"
25 #include "dm_softbus_cache.h"
26 #if defined(SUPPORT_SCREENLOCK)
27 #include "screenlock_manager.h"
28 #endif
29 #include "dm_log.h"
30 #include <sys/time.h>
31 
32 namespace OHOS {
33 namespace DistributedHardware {
34 // clone task timeout map
35 const std::map<std::string, int32_t> TASK_TIME_OUT_MAP = {
36     { std::string(AUTHENTICATE_TIMEOUT_TASK), CLONE_AUTHENTICATE_TIMEOUT },
37     { std::string(NEGOTIATE_TIMEOUT_TASK), CLONE_NEGOTIATE_TIMEOUT },
38     { std::string(CONFIRM_TIMEOUT_TASK), CLONE_CONFIRM_TIMEOUT },
39     { std::string(ADD_TIMEOUT_TASK), CLONE_ADD_TIMEOUT },
40     { std::string(WAIT_NEGOTIATE_TIMEOUT_TASK), CLONE_WAIT_NEGOTIATE_TIMEOUT },
41     { std::string(WAIT_REQUEST_TIMEOUT_TASK), CLONE_WAIT_REQUEST_TIMEOUT },
42     { std::string(WAIT_PIN_AUTH_TIMEOUT_TASK), CLONE_PIN_AUTH_TIMEOUT },
43     { std::string(SESSION_HEARTBEAT_TIMEOUT_TASK), CLONE_SESSION_HEARTBEAT_TIMEOUT }
44 };
45 
46 constexpr int32_t ONBINDRESULT_MAPPING_NUM = 2;
47 constexpr int32_t MS_PER_SECOND = 1000;
48 constexpr int32_t US_PER_MSECOND = 1000;
49 constexpr int32_t GET_SYSTEMTIME_MAX_NUM = 3;
50 constexpr const static char* ONBINDRESULT_MAPPING_LIST[ONBINDRESULT_MAPPING_NUM] = {
51     "CollaborationFwk",
52     "cast_engine_service",
53 };
54 
55 const std::map<DmAuthStateType, DmAuthStatus> NEW_AND_OLD_STATE_MAPPING = {
56     { DmAuthStateType::AUTH_SRC_FINISH_STATE, DmAuthStatus::STATUS_DM_AUTH_FINISH },
57     { DmAuthStateType::AUTH_SINK_FINISH_STATE, DmAuthStatus::STATUS_DM_SINK_AUTH_FINISH },
58     { DmAuthStateType::AUTH_IDLE_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
59     { DmAuthStateType::AUTH_SRC_START_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
60     { DmAuthStateType::AUTH_SRC_NEGOTIATE_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
61     { DmAuthStateType::AUTH_SRC_CONFIRM_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
62     { DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
63     { DmAuthStateType::AUTH_SRC_PIN_INPUT_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
64     { DmAuthStateType::AUTH_SRC_REVERSE_ULTRASONIC_START_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
65     { DmAuthStateType::AUTH_SRC_REVERSE_ULTRASONIC_DONE_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
66     { DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
67     { DmAuthStateType::AUTH_SRC_PIN_AUTH_MSG_NEGOTIATE_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
68     { DmAuthStateType::AUTH_SRC_PIN_AUTH_DONE_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
69     { DmAuthStateType::AUTH_SRC_CREDENTIAL_EXCHANGE_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
70     { DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
71     { DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_NEGOTIATE_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
72     { DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_DONE_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT },
73     { DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE, DmAuthStatus::STATUS_DM_AUTH_DEFAULT }
74 };
75 
76 const std::map<int32_t, int32_t> NEW_AND_OLD_REPLAY_MAPPING = {
77     { DM_ALREADY_AUTHED, SOFTBUS_OK },
78     { SOFTBUS_OK, SOFTBUS_OK },
79     { DM_BIND_TRUST_TARGET, DM_OK }
80 };
81 
GetTaskTimeout(std::shared_ptr<DmAuthContext> context,const char * taskName,int32_t taskTimeOut)82 int32_t DmAuthState::GetTaskTimeout(std::shared_ptr<DmAuthContext> context, const char* taskName, int32_t taskTimeOut)
83 {
84     LOGI("GetTaskTimeout, taskName: %{public}s, authType_: %{public}d", taskName, context->authType);
85     if (AUTH_TYPE_IMPORT_AUTH_CODE == context->authType) {
86         auto timeout = TASK_TIME_OUT_MAP.find(std::string(taskName));
87         if (timeout != TASK_TIME_OUT_MAP.end()) {
88             return timeout->second;
89         }
90     }
91     return taskTimeOut;
92 }
93 
HandleAuthenticateTimeout(std::shared_ptr<DmAuthContext> context,std::string name)94 void DmAuthState::HandleAuthenticateTimeout(std::shared_ptr<DmAuthContext> context, std::string name)
95 {
96     LOGI("DmAuthContext::HandleAuthenticateTimeout start timer name %{public}s", name.c_str());
97     context->timer->DeleteTimer(name);
98     context->reason = ERR_DM_TIME_OUT;
99     context->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL);
100     LOGI("DmAuthContext::HandleAuthenticateTimeout complete");
101 }
102 
IsScreenLocked()103 bool DmAuthState::IsScreenLocked()
104 {
105     bool isLocked = false;
106 #if defined(SUPPORT_SCREENLOCK)
107     isLocked = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked();
108 #endif
109     LOGI("IsScreenLocked isLocked: %{public}d.", isLocked);
110     return isLocked;
111 }
112 
GetAuthorizedScope(int32_t bindLevel)113 DmAuthScope DmAuthState::GetAuthorizedScope(int32_t bindLevel)
114 {
115     DmAuthScope authorizedScope = DM_AUTH_SCOPE_INVALID;
116     if (bindLevel == static_cast<int32_t>(APP) || bindLevel == static_cast<int32_t>(SERVICE)) {
117         authorizedScope = DM_AUTH_SCOPE_APP;
118     } else if (bindLevel == static_cast<int32_t>(USER)) {
119         authorizedScope = DM_AUTH_SCOPE_USER;
120     }
121     return authorizedScope;
122 }
123 
SourceFinish(std::shared_ptr<DmAuthContext> context)124 void DmAuthState::SourceFinish(std::shared_ptr<DmAuthContext> context)
125 {
126     LOGI("SourceFinish reason:%{public}d, state:%{public}d", context->reason, context->state);
127     context->listener->OnAuthResult(context->processInfo, context->peerTargetId.deviceId, context->accessee.tokenIdHash,
128         GetOutputState(context->state), context->reason);
129     context->listener->OnBindResult(context->processInfo, context->peerTargetId,
130         GetOutputReplay(context->accesser.bundleName, context->reason),
131         GetOutputState(context->state), GenerateBindResultContent(context));
132     context->successFinished = true;
133 
134     if (context->reason != DM_OK && context->reason != DM_ALREADY_AUTHED && context->reason != DM_BIND_TRUST_TARGET) {
135         BindFail(context);
136     }
137     LOGI("SourceFinish notify online");
138     char deviceIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
139     Crypto::GetUdidHash(context->accessee.deviceId, reinterpret_cast<uint8_t *>(deviceIdHash));
140     if (SoftbusCache::GetInstance().CheckIsOnline(std::string(deviceIdHash))) {
141         SetProcessInfo(context);
142         int32_t authForm = context->accesser.transmitBindType == DM_POINT_TO_POINT_TYPE ?
143             DmAuthForm::PEER_TO_PEER : context->accesser.transmitBindType;
144         context->softbusConnector->HandleDeviceOnline(context->accessee.deviceId, authForm);
145     }
146 
147     context->authUiStateMgr->UpdateUiState(DmUiStateMsg::MSG_CANCEL_PIN_CODE_INPUT);
148     context->timer->DeleteAll();
149 }
150 
SinkFinish(std::shared_ptr<DmAuthContext> context)151 void DmAuthState::SinkFinish(std::shared_ptr<DmAuthContext> context)
152 {
153     LOGI("SinkFinish reason:%{public}d, state:%{public}d", context->reason, context->state);
154     context->processInfo.pkgName = context->accessee.pkgName;
155     context->listener->OnSinkBindResult(context->processInfo, context->peerTargetId,
156         GetOutputReplay(context->accessee.bundleName, context->reason),
157         GetOutputState(context->state), GenerateBindResultContent(context));
158     context->successFinished = true;
159     if (context->reason != DM_OK) {
160         BindFail(context);
161     } else {
162         SetAclInfo(context);
163         if (NeedAgreeAcl(context)) {
164             UpdateCredInfo(context);
165             context->authMessageProcessor->PutAccessControlList(context,
166                 context->accessee, context->accesser.deviceId);
167         }
168         LOGI("SinkFinish notify online");
169         char deviceIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
170         Crypto::GetUdidHash(context->accesser.deviceId, reinterpret_cast<uint8_t *>(deviceIdHash));
171         if (SoftbusCache::GetInstance().CheckIsOnline(std::string(deviceIdHash))) {
172             SetProcessInfo(context);
173             int32_t authForm = context->accessee.transmitBindType == DM_POINT_TO_POINT_TYPE ?
174                 DmAuthForm::PEER_TO_PEER : context->accessee.transmitBindType;
175             context->softbusConnector->HandleDeviceOnline(context->accesser.deviceId, authForm);
176         }
177     }
178 
179     context->authUiStateMgr->UpdateUiState(DmUiStateMsg::MSG_CANCEL_PIN_CODE_SHOW);
180     context->authUiStateMgr->UpdateUiState(DmUiStateMsg::MSG_CANCEL_CONFIRM_SHOW);
181     context->timer->DeleteAll();
182     context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_AUTH_RESP_FINISH, context); // 发送201给source侧
183 }
184 
GenerateBindResultContent(std::shared_ptr<DmAuthContext> context)185 std::string DmAuthState::GenerateBindResultContent(std::shared_ptr<DmAuthContext> context)
186 {
187     CHECK_NULL_RETURN(context, "");
188     DmAccess access = context->direction == DmAuthDirection::DM_AUTH_SOURCE ?
189         context->accessee : context->accesser;
190     JsonObject jsonObj;
191     LOGE("networkId: %{public}s", GetAnonyString(access.networkId).c_str());
192     jsonObj[DM_BIND_RESULT_NETWORK_ID] = access.networkId;
193     if (access.deviceId.empty()) {
194         jsonObj[TAG_DEVICE_ID] = "";
195     } else {
196         char deviceIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
197         Crypto::GetUdidHash(access.deviceId, reinterpret_cast<uint8_t *>(deviceIdHash));
198         jsonObj[TAG_DEVICE_ID] = deviceIdHash;
199     }
200     jsonObj[TAG_CONFIRM_OPERATION_V2] = context->confirmOperation;
201     if (context->remainingFrozenTime != 0) {
202         jsonObj[TAG_REMAINING_FROZEN_TIME] = context->remainingFrozenTime;
203     }
204     LOGI("remainingFrozenTime: %{public}" PRId64, context->remainingFrozenTime);
205     std::string content = jsonObj.Dump();
206     return content;
207 }
208 
NeedReqUserConfirm(std::shared_ptr<DmAuthContext> context)209 bool DmAuthState::NeedReqUserConfirm(std::shared_ptr<DmAuthContext> context)
210 {
211     // 不管是否有可信关系,都需要走pin码认证,主要指鸿蒙环PIN码导入场景
212     if (DmAuthState::IsImportAuthCodeCompatibility(context->authType)) {
213         return true;
214     }
215 
216     // 有ACL,跳转到结束状态,发200报文,直接组网
217     DmAccess access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee;
218     if (access.isAuthed) {
219         return false;
220     }
221 
222     return true;
223 }
224 
NeedAgreeAcl(std::shared_ptr<DmAuthContext> context)225 bool DmAuthState::NeedAgreeAcl(std::shared_ptr<DmAuthContext> context)
226 {
227     if (context == nullptr) {
228         return true;
229     }
230     if (context->direction == DM_AUTH_SOURCE) {
231         if (context->accesser.isUserLevelAuthed) {
232             LOGI("accesser user level authed");
233             return false;
234         }
235         if (!context->IsProxyBind || context->subjectProxyOnes.empty()) {
236             LOGI("accesser is authed");
237             return !context->accesser.isAuthed;
238         }
239         if (context->IsCallingProxyAsSubject && !context->accesser.isAuthed) {
240             LOGI("accesser is not authed");
241             return true;
242         }
243         return ProxyNeedAgreeAcl(context);
244     }
245     if (context->accessee.isUserLevelAuthed) {
246         LOGI("accessee user level authed");
247         return false;
248     }
249     if (!context->IsProxyBind || context->subjectProxyOnes.empty()) {
250         LOGI("accessee is authed");
251         return !context->accessee.isAuthed;
252     }
253     if (context->IsCallingProxyAsSubject && !context->accessee.isAuthed) {
254         LOGI("accessee is not authed");
255         return true;
256     }
257     return ProxyNeedAgreeAcl(context);
258 }
259 
ProxyNeedAgreeAcl(std::shared_ptr<DmAuthContext> context)260 bool DmAuthState::ProxyNeedAgreeAcl(std::shared_ptr<DmAuthContext> context)
261 {
262     CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
263     if (!context->IsProxyBind || context->subjectProxyOnes.empty()) {
264         return false;
265     }
266     if (context->direction == DM_AUTH_SOURCE) {
267         for (const auto &app : context->subjectProxyOnes) {
268             if (!app.proxyAccesser.isAuthed || app.IsNeedSetProxyRelationShip) {
269                 return true;
270             }
271         }
272         return false;
273     }
274     for (const auto &app : context->subjectProxyOnes) {
275         if (!app.proxyAccessee.isAuthed || app.IsNeedSetProxyRelationShip) {
276             return true;
277         }
278     }
279     return false;
280 }
281 
GetReuseSkId(std::shared_ptr<DmAuthContext> context,int32_t & skId)282 bool DmAuthState::GetReuseSkId(std::shared_ptr<DmAuthContext> context, int32_t &skId)
283 {
284     CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
285     DistributedDeviceProfile::AccessControlProfile profile;
286     GetReuseACL(context, profile);
287     if (!profile.GetAccesser().GetAccesserCredentialIdStr().empty() &&
288         !profile.GetAccessee().GetAccesseeCredentialIdStr().empty()) {
289         if (context->direction == DM_AUTH_SOURCE) {
290             if (context->accesser.deviceId == profile.GetAccesser().GetAccesserDeviceId()) {
291                 skId = profile.GetAccesser().GetAccesserSessionKeyId();
292                 context->reUseCreId = profile.GetAccesser().GetAccesserCredentialIdStr();
293                 context->accessee.deviceId = profile.GetAccessee().GetAccesseeDeviceId();
294                 return true;
295             }
296             skId = profile.GetAccessee().GetAccesseeSessionKeyId();
297             context->reUseCreId = profile.GetAccessee().GetAccesseeCredentialIdStr();
298             context->accessee.deviceId = profile.GetAccesser().GetAccesserDeviceId();
299             return true;
300         }
301         if (context->accessee.deviceId == profile.GetAccessee().GetAccesseeDeviceId()) {
302             skId = profile.GetAccessee().GetAccesseeSessionKeyId();
303             context->reUseCreId = profile.GetAccessee().GetAccesseeCredentialIdStr();
304             context->accesser.deviceId = profile.GetAccesser().GetAccesserDeviceId();
305             return true;
306         }
307         skId = profile.GetAccesser().GetAccesserSessionKeyId();
308         context->reUseCreId = profile.GetAccesser().GetAccesserCredentialIdStr();
309         context->accesser.deviceId = profile.GetAccessee().GetAccesseeDeviceId();
310         return true;
311     }
312     return false;
313 }
314 
GetReuseACL(std::shared_ptr<DmAuthContext> context,DistributedDeviceProfile::AccessControlProfile & profile)315 void DmAuthState::GetReuseACL(std::shared_ptr<DmAuthContext> context,
316     DistributedDeviceProfile::AccessControlProfile &profile)
317 {
318     if (context == nullptr) {
319         return;
320     }
321     if (!context->IsProxyBind || context->subjectProxyOnes.empty()) {
322         return;
323     }
324     DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee;
325     if (!access.aclTypeList.empty()) {
326         JsonObject aclTypeListJson;
327         aclTypeListJson.Parse(access.aclTypeList);
328         if (!aclTypeListJson.IsDiscarded() && aclTypeListJson.Contains("pointTopointAcl") &&
329             access.aclProfiles.find(DM_POINT_TO_POINT) != access.aclProfiles.end() &&
330             !access.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr().empty() &&
331             !access.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr().empty()) {
332             profile = access.aclProfiles[DM_POINT_TO_POINT];
333             return;
334         }
335     }
336     for (auto &app : context->subjectProxyOnes) {
337         DmProxyAccess &proxyAccess = context->direction == DM_AUTH_SOURCE ? app.proxyAccesser : app.proxyAccessee;
338         JsonObject aclList;
339         if (!proxyAccess.aclTypeList.empty()) {
340             aclList.Parse(proxyAccess.aclTypeList);
341         }
342         if (!aclList.IsDiscarded() && aclList.Contains("pointTopointAcl") &&
343             proxyAccess.aclProfiles.find(DM_POINT_TO_POINT) != proxyAccess.aclProfiles.end() &&
344             !proxyAccess.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr().empty() &&
345             !proxyAccess.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr().empty()) {
346             profile = proxyAccess.aclProfiles[DM_POINT_TO_POINT];
347             return;
348         }
349     }
350 }
351 
IsImportAuthCodeCompatibility(DmAuthType authType)352 bool DmAuthState::IsImportAuthCodeCompatibility(DmAuthType authType)
353 {
354     if (authType == DmAuthType::AUTH_TYPE_IMPORT_AUTH_CODE ||
355         authType == DmAuthType::AUTH_TYPE_NFC) {
356         return true;
357     }
358     return false;
359 }
360 
SetAclExtraInfo(std::shared_ptr<DmAuthContext> context)361 void DmAuthState::SetAclExtraInfo(std::shared_ptr<DmAuthContext> context)
362 {
363     DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee;
364     DmAccess &remoteAccess = (context->direction == DM_AUTH_SOURCE) ? context->accessee : context->accesser;
365     JsonObject jsonObj;
366     jsonObj[TAG_DMVERSION] = access.dmVersion;
367     access.extraInfo = jsonObj.Dump();
368     remoteAccess.extraInfo = jsonObj.Dump();
369 }
370 
SetAclInfo(std::shared_ptr<DmAuthContext> context)371 void DmAuthState::SetAclInfo(std::shared_ptr<DmAuthContext> context)
372 {
373     DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee;
374     DmAccess &remoteAccess = (context->direction == DM_AUTH_SOURCE) ? context->accessee : context->accesser;
375     SetAclExtraInfo(context);
376     access.lnnBindType = GetAclBindType(context, access.lnnCredentialId);
377     remoteAccess.lnnBindType = GetAclBindType(context, remoteAccess.lnnCredentialId);
378 
379     access.transmitBindType = GetAclBindType(context, access.transmitCredentialId);
380     remoteAccess.transmitBindType = GetAclBindType(context, remoteAccess.transmitCredentialId);
381 }
382 
GetAclBindType(std::shared_ptr<DmAuthContext> context,std::string credId)383 int32_t DmAuthState::GetAclBindType(std::shared_ptr<DmAuthContext> context, std::string credId)
384 {
385     DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee;
386     JsonObject result;
387     int32_t ret = context->hiChainAuthConnector->QueryCredInfoByCredId(access.userId, credId, result);
388     if (ret != DM_OK) {
389         LOGE("GetAclBindType QueryCredInfoByCredId failed, ret: %{public}d.", ret);
390         return DM_UNKNOWN_TYPE;
391     }
392     if (!result.Contains(credId)) {
393         LOGE("GetAclBindType result not contains credId.");
394         return DM_UNKNOWN_TYPE;
395     }
396     int32_t credType = result[credId][FILED_CRED_TYPE].Get<int32_t>();
397     if (credType == DM_AUTH_CREDENTIAL_ACCOUNT_RELATED) {
398         return DM_SAME_ACCOUNT_TYPE;
399     }
400     if (credType == DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED) {
401         return DM_POINT_TO_POINT_TYPE;
402     }
403     if (credType == DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS) {
404         return DM_SHARE;
405     }
406     return DM_UNKNOWN_TYPE;
407 }
408 
GetCredType(std::shared_ptr<DmAuthContext> context,const JsonItemObject & credInfo)409 uint32_t DmAuthState::GetCredType(std::shared_ptr<DmAuthContext> context, const JsonItemObject &credInfo)
410 {
411     int32_t credType = credInfo[FILED_CRED_TYPE].Get<int32_t>();
412     int32_t authorizedScope = credInfo[FILED_AUTHORIZED_SCOPE].Get<int32_t>();
413     int32_t subject = credInfo[FILED_SUBJECT].Get<int32_t>();
414     std::vector<std::string> appList;
415     credInfo[FILED_AUTHORIZED_APP_LIST].Get(appList);
416     if (credType == ACCOUNT_RELATED && authorizedScope == SCOPE_USER) {
417         return DM_IDENTICAL_ACCOUNT;
418     }
419     if (credType == ACCOUNT_ACROSS && authorizedScope == SCOPE_USER &&
420         context->direction == DM_AUTH_SOURCE && subject == SUBJECT_PRIMARY) {
421         return DM_SHARE;
422     }
423     if (credType == ACCOUNT_ACROSS && authorizedScope == SCOPE_USER &&
424         context->direction == DM_AUTH_SINK && subject == SUBJECT_SECONDARY) {
425         return DM_SHARE;
426     }
427     if (credType == ACCOUNT_UNRELATED && (authorizedScope == SCOPE_APP || authorizedScope == SCOPE_USER)) {
428         std::vector<std::string> tokenIdHashList;
429         for (std::string tokenId : appList) {
430             tokenIdHashList.push_back(Crypto::GetTokenIdHash(tokenId));
431         }
432         GetProxyCredInfo(context, credInfo, tokenIdHashList);
433         if (HaveSameTokenId(context, tokenIdHashList)) {
434             return DM_POINT_TO_POINT;
435         }
436     }
437     if (credType == ACCOUNT_UNRELATED && authorizedScope == SCOPE_USER && appList.empty()) {
438         return DM_LNN;
439     }
440     return DM_INVALIED_TYPE;
441 }
442 
GetProxyCredInfo(std::shared_ptr<DmAuthContext> context,const JsonItemObject & credInfo,const std::vector<std::string> & tokenIdHashList)443 int32_t DmAuthState::GetProxyCredInfo(std::shared_ptr<DmAuthContext> context, const JsonItemObject &credInfo,
444     const std::vector<std::string> &tokenIdHashList)
445 {
446     CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
447     if (!context->IsProxyBind) {
448         return DM_OK;
449     }
450     if (context->subjectProxyOnes.empty()) {
451         return ERR_DM_INPUT_PARA_INVALID;
452     }
453     if (!credInfo.Contains(FILED_CRED_ID) || !credInfo[FILED_CRED_ID].IsString()) {
454         return static_cast<int32_t>(DM_INVALIED_TYPE);
455     }
456     for (auto &app : context->subjectProxyOnes) {
457         if (std::find(tokenIdHashList.begin(), tokenIdHashList.end(), app.proxyAccesser.tokenIdHash)
458             != tokenIdHashList.end() &&
459             std::find(tokenIdHashList.begin(), tokenIdHashList.end(), app.proxyAccessee.tokenIdHash)
460             != tokenIdHashList.end()) {
461             JsonObject appCredInfo(credInfo.Dump());
462             appCredInfo[FILED_CRED_TYPE] = DM_POINT_TO_POINT;
463             JsonObject credInfoJson;
464             std::string credInfoJsonStr = context->direction == DM_AUTH_SOURCE ? app.proxyAccesser.credInfoJson :
465                 app.proxyAccessee.credInfoJson;
466             if (!credInfoJsonStr.empty()) {
467                 credInfoJson.Parse(credInfoJsonStr);
468             }
469             credInfoJson.Insert(credInfo[FILED_CRED_ID].Get<std::string>(), appCredInfo);
470             if (context->direction == DM_AUTH_SOURCE) {
471                 app.proxyAccesser.credInfoJson = credInfoJson.Dump();
472             } else {
473                 app.proxyAccessee.credInfoJson = credInfoJson.Dump();
474             }
475         }
476     }
477     return DM_OK;
478 }
479 
GetCredentialType(std::shared_ptr<DmAuthContext> context,const JsonItemObject & credInfo)480 uint32_t DmAuthState::GetCredentialType(std::shared_ptr<DmAuthContext> context, const JsonItemObject &credInfo)
481 {
482     CHECK_NULL_RETURN(context, DM_INVALIED_TYPE);
483     if (!credInfo.Contains(FILED_CRED_TYPE) || !credInfo[FILED_CRED_TYPE].IsNumberInteger() ||
484         !credInfo.Contains(FILED_AUTHORIZED_SCOPE) || !credInfo[FILED_AUTHORIZED_SCOPE].IsNumberInteger() ||
485         !credInfo.Contains(FILED_SUBJECT) || !credInfo[FILED_SUBJECT].IsNumberInteger()) {
486         LOGE("credType or authorizedScope invalid.");
487         return DM_INVALIED_TYPE;
488     }
489     return GetCredType(context, credInfo);
490 }
491 
HaveSameTokenId(std::shared_ptr<DmAuthContext> context,const std::vector<std::string> & tokenIdHashList)492 bool DmAuthState::HaveSameTokenId(std::shared_ptr<DmAuthContext> context,
493     const std::vector<std::string> &tokenIdHashList)
494 {
495     // Store the token of src and sink. The size must be greater than or equal to 2.
496     if (tokenIdHashList.size() < 2) {
497         LOGE("HaveSameTokenId invalid tokenList size.");
498         return false;
499     }
500     return std::find(tokenIdHashList.begin(), tokenIdHashList.end(),
501         context->accesser.tokenIdHash) != tokenIdHashList.end() &&
502         std::find(tokenIdHashList.begin(), tokenIdHashList.end(),
503         context->accessee.tokenIdHash) != tokenIdHashList.end();
504 }
505 
GetOutputState(int32_t state)506 int32_t DmAuthState::GetOutputState(int32_t state)
507 {
508     LOGI("state %{public}d.", state);
509     auto it = NEW_AND_OLD_STATE_MAPPING.find(static_cast<DmAuthStateType>(state));
510     if (it != NEW_AND_OLD_STATE_MAPPING.end()) {
511         return static_cast<int32_t>(it->second);
512     }
513     return static_cast<int32_t>(STATUS_DM_AUTH_DEFAULT);
514 }
515 
GetOutputReplay(const std::string & processName,int32_t replay)516 int32_t DmAuthState::GetOutputReplay(const std::string &processName, int32_t replay)
517 {
518     LOGI("replay %{public}d.", replay);
519     bool needMapFlag = false;
520     for (uint16_t index = 0; index < ONBINDRESULT_MAPPING_NUM; ++index) {
521         if (std::string(ONBINDRESULT_MAPPING_LIST[index]) == processName) {
522             LOGI("processName %{public}s new protocol param convert to old protocol param.", processName.c_str());
523             needMapFlag = true;
524             break;
525         }
526     }
527     if (needMapFlag) {
528         auto it = NEW_AND_OLD_REPLAY_MAPPING.find(replay);
529         if (it != NEW_AND_OLD_REPLAY_MAPPING.end()) {
530             return static_cast<int32_t>(it->second);
531         }
532     }
533     return replay;
534 }
535 
GetSysTimeMs()536 uint64_t DmAuthState::GetSysTimeMs()
537 {
538     struct timeval time;
539     time.tv_sec = 0;
540     time.tv_usec = 0;
541     int32_t retryNum = 0;
542     while (retryNum < GET_SYSTEMTIME_MAX_NUM) {
543         if (gettimeofday(&time, nullptr) != 0) {
544             retryNum++;
545             LOGE("GetSysTimeMs failed. retryNum: %{public}d", retryNum);
546             continue;
547         }
548         return (uint64_t) time.tv_sec * MS_PER_SECOND + (uint64_t)time.tv_usec / US_PER_MSECOND;
549     }
550     return 0;
551 }
552 
DeleteAcl(std::shared_ptr<DmAuthContext> context,const DistributedDeviceProfile::AccessControlProfile & profile)553 void DmAuthState::DeleteAcl(std::shared_ptr<DmAuthContext> context,
554     const DistributedDeviceProfile::AccessControlProfile &profile)
555 {
556     CHECK_NULL_VOID(context);
557     LOGI("direction %{public}d.", static_cast<int32_t>(context->direction));
558     CHECK_NULL_VOID(context->authMessageProcessor);
559     CHECK_NULL_VOID(context->hiChainAuthConnector);
560     DmAccess &access = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? context->accesser : context->accessee;
561     int32_t userId = access.userId;
562     int32_t sessionKeyId = access.deviceId == profile.GetAccesser().GetAccesserDeviceId() ?
563         profile.GetAccesser().GetAccesserSessionKeyId() : profile.GetAccessee().GetAccesseeSessionKeyId();
564     std::string credId = access.deviceId == profile.GetAccesser().GetAccesserDeviceId() ?
565         profile.GetAccesser().GetAccesserCredentialIdStr() : profile.GetAccessee().GetAccesseeCredentialIdStr();
566     context->authMessageProcessor->DeleteSessionKeyToDP(userId, sessionKeyId);
567     JsonObject credJson;
568     context->hiChainAuthConnector->QueryCredInfoByCredId(userId, credId, credJson);
569     if (credJson.Contains(credId)) {
570         DeleteCredential(context, userId, credJson[credId], profile);
571     }
572     DeviceProfileConnector::GetInstance().DeleteAccessControlById(profile.GetAccessControlId());
573 }
574 
SetProcessInfo(std::shared_ptr<DmAuthContext> context)575 void DmAuthState::SetProcessInfo(std::shared_ptr<DmAuthContext> context)
576 {
577     CHECK_NULL_VOID(context);
578     DmAccess localAccess = context->direction == DmAuthDirection::DM_AUTH_SOURCE ?
579         context->accesser : context->accessee;
580     std::vector<ProcessInfo> processInfoVec;
581     ProcessInfo processInfo;
582     processInfo.userId = localAccess.userId;
583     uint32_t bindLevel = static_cast<uint32_t>(localAccess.bindLevel);
584     if (bindLevel == APP || bindLevel == SERVICE) {
585         processInfo.pkgName = localAccess.pkgName;
586     } else if (bindLevel == USER) {
587         processInfo.pkgName = std::string(DM_PKG_NAME);
588     } else {
589         LOGE("bindlevel error %{public}d.", bindLevel);
590         return;
591     }
592     processInfoVec.push_back(processInfo);
593     if (context->IsProxyBind && !context->subjectProxyOnes.empty()) {
594         for (const auto &app : context->subjectProxyOnes) {
595             ProcessInfo processInfo;
596             processInfo.userId = localAccess.userId;
597             processInfo.pkgName = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? app.proxyAccesser.bundleName :
598                 app.proxyAccessee.bundleName;
599             processInfoVec.push_back(processInfo);
600         }
601     }
602     context->softbusConnector->SetProcessInfoVec(processInfoVec);
603 }
604 
FilterProfilesByContext(std::vector<DistributedDeviceProfile::AccessControlProfile> & profiles,std::shared_ptr<DmAuthContext> context)605 void DmAuthState::FilterProfilesByContext(
606     std::vector<DistributedDeviceProfile::AccessControlProfile> &profiles, std::shared_ptr<DmAuthContext> context)
607 {
608     CHECK_NULL_VOID(context);
609     std::vector<DistributedDeviceProfile::AccessControlProfile> aclProfilesVec;
610     for (const auto &item : profiles) {
611         std::string accesserDeviceIdHash = Crypto::GetUdidHash(item.GetAccesser().GetAccesserDeviceId());
612         std::string accesseeDeviceIdHash = Crypto::GetUdidHash(item.GetAccessee().GetAccesseeDeviceId());
613         if ((context->accesser.deviceIdHash == accesserDeviceIdHash &&
614             context->accessee.deviceIdHash == accesseeDeviceIdHash &&
615             context->accesser.userId == item.GetAccesser().GetAccesserUserId() &&
616             context->accessee.userId == item.GetAccessee().GetAccesseeUserId()) ||
617             (context->accessee.deviceIdHash == accesserDeviceIdHash &&
618             context->accesser.deviceIdHash == accesseeDeviceIdHash &&
619             context->accessee.userId == item.GetAccesser().GetAccesserUserId() &&
620             context->accesser.userId == item.GetAccessee().GetAccesseeUserId())) {
621             aclProfilesVec.push_back(item);
622         }
623     }
624     profiles.clear();
625     profiles.assign(aclProfilesVec.begin(), aclProfilesVec.end());
626 }
627 
GetSessionKey(std::shared_ptr<DmAuthContext> context)628 bool DmAuthState::GetSessionKey(std::shared_ptr<DmAuthContext> context)
629 {
630     int32_t skId = 0;
631     if (!GetReuseSkId(context, skId)) {
632         return false;
633     }
634     return context->authMessageProcessor->GetSessionKey(context->accesser.userId, skId) == DM_OK;
635 }
636 
IsAclHasCredential(const DistributedDeviceProfile::AccessControlProfile & profile,const std::string & credInfoJson,std::string & credId)637 bool DmAuthState::IsAclHasCredential(const DistributedDeviceProfile::AccessControlProfile &profile,
638     const std::string &credInfoJson, std::string &credId)
639 {
640     JsonObject credInfoJsonObj;
641     if (!credInfoJson.empty()) {
642         credInfoJsonObj.Parse(credInfoJson);
643     }
644     credId = profile.GetAccesser().GetAccesserCredentialIdStr();
645     if (credInfoJsonObj.Contains(credId)) {
646         return true;
647     }
648     credId = profile.GetAccessee().GetAccesseeCredentialIdStr();
649     if (credInfoJsonObj.Contains(credId)) {
650         return true;
651     }
652     return false;
653 }
654 
UpdateCredInfo(std::shared_ptr<DmAuthContext> context)655 void DmAuthState::UpdateCredInfo(std::shared_ptr<DmAuthContext> context)
656 {
657     CHECK_NULL_VOID(context);
658     if (!context->IsProxyBind || context->subjectProxyOnes.empty() || context->reUseCreId.empty()) {
659         return;
660     }
661     std::vector<std::string> tokenIds;
662     bool isAuthed = context->direction == DM_AUTH_SOURCE ? context->accesser.isAuthed : context->accessee.isAuthed;
663     if (context->IsCallingProxyAsSubject && !isAuthed) {
664         tokenIds.push_back(std::to_string(context->accesser.tokenId));
665         tokenIds.push_back(std::to_string(context->accessee.tokenId));
666     }
667     for (auto &app : context->subjectProxyOnes) {
668         if (context->direction == DM_AUTH_SOURCE ? app.proxyAccesser.isAuthed : app.proxyAccessee.isAuthed) {
669             continue;
670         }
671         tokenIds.push_back(std::to_string(app.proxyAccesser.tokenId));
672         tokenIds.push_back(std::to_string(app.proxyAccessee.tokenId));
673     }
674     if (tokenIds.empty()) {
675         return;
676     }
677     context->hiChainAuthConnector->AddTokensToCredential(context->reUseCreId, context->direction == DM_AUTH_SOURCE ?
678         context->accesser.userId : context->accessee.userId, tokenIds);
679 }
680 
IsNeedBind(std::shared_ptr<DmAuthContext> context)681 bool DmAuthState::IsNeedBind(std::shared_ptr<DmAuthContext> context)
682 {
683     if (context == nullptr) {
684         return true;
685     }
686     if (!context->IsProxyBind || context->subjectProxyOnes.empty()) {
687         LOGI("no proxy");
688         return context->needBind;
689     }
690     if (context->authType == DmAuthType::AUTH_TYPE_IMPORT_AUTH_CODE) {
691         LOGI("authType is import pin code");
692         return true;
693     }
694     if (context->needBind && context->needAgreeCredential && context->IsCallingProxyAsSubject) {
695         LOGI("subject need bind");
696         return context->needBind;
697     }
698     for (const auto &app : context->subjectProxyOnes) {
699         if (app.needBind || app.IsNeedSetProxyRelationShip) {
700             LOGI("proxy need bind");
701             return true;
702         }
703     }
704     return false;
705 }
706 
IsNeedAgreeCredential(std::shared_ptr<DmAuthContext> context)707 bool DmAuthState::IsNeedAgreeCredential(std::shared_ptr<DmAuthContext> context)
708 {
709     if (context == nullptr) {
710         return true;
711     }
712     if (!context->IsProxyBind || context->subjectProxyOnes.empty()) {
713         LOGI("no proxy");
714         return context->needAgreeCredential;
715     }
716     if (!context->needAgreeCredential) {
717         LOGI("subject not need agree credential");
718         return context->needAgreeCredential;
719     }
720     for (const auto &app : context->subjectProxyOnes) {
721         if (!app.needAgreeCredential) {
722             LOGI("proxy not need agree credential");
723             return app.needAgreeCredential;
724         }
725     }
726     return true;
727 }
728 
IsNeedAuth(std::shared_ptr<DmAuthContext> context)729 bool DmAuthState::IsNeedAuth(std::shared_ptr<DmAuthContext> context)
730 {
731     if (context == nullptr) {
732         return true;
733     }
734     if (!context->IsProxyBind || context->subjectProxyOnes.empty()) {
735         LOGI("no proxy");
736         return context->needAuth;
737     }
738     if (!context->needAuth) {
739         LOGI("subject not need auth");
740         return context->needAuth;
741     }
742     for (const auto &app : context->subjectProxyOnes) {
743         if (!app.needAuth) {
744             LOGI("proxy not need auth");
745             return app.needAuth;
746         }
747     }
748     return true;
749 }
750 
DeleteCredential(std::shared_ptr<DmAuthContext> context,int32_t userId,const JsonItemObject & credInfo,const DistributedDeviceProfile::AccessControlProfile & profile)751 void DmAuthState::DeleteCredential(std::shared_ptr<DmAuthContext> context, int32_t userId,
752     const JsonItemObject &credInfo, const DistributedDeviceProfile::AccessControlProfile &profile)
753 {
754     CHECK_NULL_VOID(context);
755     CHECK_NULL_VOID(context->hiChainAuthConnector);
756     if (!credInfo.Contains(FILED_CRED_ID) || !credInfo[FILED_CRED_ID].IsString()) {
757         return;
758     }
759     if (!credInfo.Contains(FILED_AUTHORIZED_APP_LIST)) {
760         context->hiChainAuthConnector->DeleteCredential(userId, credInfo[FILED_CRED_ID].Get<std::string>());
761         return;
762     }
763     std::vector<std::string> appList;
764     credInfo[FILED_AUTHORIZED_APP_LIST].Get(appList);
765     auto erIt = std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccesser().GetAccesserTokenId()));
766     if (erIt != appList.end()) {
767         appList.erase(erIt);
768     }
769     auto eeIt = std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccessee().GetAccesseeTokenId()));
770     if (eeIt != appList.end()) {
771         appList.erase(eeIt);
772     }
773     if (appList.size() == 0) {
774         context->hiChainAuthConnector->DeleteCredential(userId, credInfo[FILED_CRED_ID].Get<std::string>());
775         return;
776     }
777     context->hiChainAuthConnector->UpdateCredential(credInfo[FILED_CRED_ID].Get<std::string>(), userId, appList);
778 }
779 
DirectlyDeleteCredential(std::shared_ptr<DmAuthContext> context,int32_t userId,const JsonItemObject & credInfo)780 void DmAuthState::DirectlyDeleteCredential(std::shared_ptr<DmAuthContext> context, int32_t userId,
781     const JsonItemObject &credInfo)
782 {
783     CHECK_NULL_VOID(context);
784     CHECK_NULL_VOID(context->hiChainAuthConnector);
785     if (!credInfo.Contains(FILED_CRED_ID) || !credInfo[FILED_CRED_ID].IsString()) {
786         return;
787     }
788     context->hiChainAuthConnector->DeleteCredential(userId, credInfo[FILED_CRED_ID].Get<std::string>());
789 }
790 
DeleteAclAndSk(std::shared_ptr<DmAuthContext> context,const DistributedDeviceProfile::AccessControlProfile & profile)791 void DmAuthState::DeleteAclAndSk(std::shared_ptr<DmAuthContext> context,
792     const DistributedDeviceProfile::AccessControlProfile &profile)
793 {
794     CHECK_NULL_VOID(context);
795     CHECK_NULL_VOID(context->authMessageProcessor);
796     DmAccess &access = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? context->accesser : context->accessee;
797     int32_t userId = access.userId;
798     int32_t sessionKeyId = access.deviceId == profile.GetAccesser().GetAccesserDeviceId() ?
799         profile.GetAccesser().GetAccesserSessionKeyId() : profile.GetAccessee().GetAccesseeSessionKeyId();
800     context->authMessageProcessor->DeleteSessionKeyToDP(userId, sessionKeyId);
801     DeviceProfileConnector::GetInstance().DeleteAccessControlById(profile.GetAccessControlId());
802 }
803 
GetPeerDeviceId(std::shared_ptr<DmAuthContext> context,std::string & peerDeviceId)804 void DmAuthState::GetPeerDeviceId(std::shared_ptr<DmAuthContext> context, std::string &peerDeviceId)
805 {
806     CHECK_NULL_VOID(context);
807     if (context->accesser.aclProfiles.find(DM_IDENTICAL_ACCOUNT) != context->accesser.aclProfiles.end()) {
808         peerDeviceId = context->accesser.aclProfiles[DM_IDENTICAL_ACCOUNT].GetAccessee().GetAccesseeDeviceId();
809         if (!peerDeviceId.empty()) {
810             return;
811         }
812     }
813     if (context->accesser.aclProfiles.find(DM_SHARE) != context->accesser.aclProfiles.end()) {
814         peerDeviceId = context->accesser.aclProfiles[DM_SHARE].GetAccessee().GetAccesseeDeviceId();
815         if (peerDeviceId == context->accesser.deviceId) {
816             peerDeviceId = context->accesser.aclProfiles[DM_SHARE].GetAccesser().GetAccesserDeviceId();
817         }
818         if (!peerDeviceId.empty()) {
819             return;
820         }
821     }
822     if (context->accesser.aclProfiles.find(DM_POINT_TO_POINT) != context->accesser.aclProfiles.end()) {
823         peerDeviceId = context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeDeviceId();
824         if (peerDeviceId == context->accesser.deviceId) {
825             peerDeviceId = context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserDeviceId();
826         }
827         if (!peerDeviceId.empty()) {
828             return;
829         }
830     }
831     if (!context->IsProxyBind || context->subjectProxyOnes.empty()) {
832         return;
833     }
834     for (auto &app : context->subjectProxyOnes) {
835         if (app.proxyAccesser.aclProfiles.find(DM_POINT_TO_POINT) != app.proxyAccesser.aclProfiles.end()) {
836             peerDeviceId = app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeDeviceId();
837             if (peerDeviceId == context->accesser.deviceId) {
838                 peerDeviceId = app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserDeviceId();
839             }
840             if (!peerDeviceId.empty()) {
841                 return;
842             }
843         }
844     }
845     LOGE("failed");
846 }
847 
IsMatchCredentialAndP2pACL(JsonObject & credInfo,std::string & credId,const DistributedDeviceProfile::AccessControlProfile & profile)848 bool DmAuthState::IsMatchCredentialAndP2pACL(JsonObject &credInfo, std::string &credId,
849     const DistributedDeviceProfile::AccessControlProfile &profile)
850 {
851     if (!credInfo.Contains(credId) || !credInfo[credId].Contains(FILED_AUTHORIZED_SCOPE) ||
852         !credInfo[credId][FILED_AUTHORIZED_SCOPE].IsNumberInteger()) {
853         return false;
854     }
855     int32_t authorizedScope = credInfo[credId][FILED_AUTHORIZED_SCOPE].Get<int32_t>();
856     if (authorizedScope == static_cast<int32_t>(DM_AUTH_SCOPE_USER) && profile.GetBindLevel() == USER) {
857         return true;
858     }
859     if (authorizedScope == static_cast<int32_t>(DM_AUTH_SCOPE_APP) &&
860         (profile.GetBindLevel() == SERVICE || profile.GetBindLevel() == APP)) {
861         return true;
862     }
863     return false;
864 }
865 
BindFail(std::shared_ptr<DmAuthContext> context)866 void DmAuthState::BindFail(std::shared_ptr<DmAuthContext> context)
867 {
868     CHECK_NULL_VOID(context);
869     CHECK_NULL_VOID(context->hiChainAuthConnector);
870     if (context->reason == DM_BIND_TRUST_TARGET) {
871         return;
872     }
873     bool isDelLnnAcl = false;
874     DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee;
875     if (access.isGeneratedLnnCredThisBind) {
876         if (!access.lnnCredentialId.empty()) {
877             context->hiChainAuthConnector->DeleteCredential(access.userId, access.lnnCredentialId);
878         }
879         if (access.lnnSessionKeyId != 0) {
880             DeviceProfileConnector::GetInstance().DeleteSessionKey(access.userId, access.lnnSessionKeyId);
881         }
882         isDelLnnAcl = true;
883     }
884     std::vector<std::pair<int64_t, int64_t>> tokenIds;
885     if (!access.isAuthed && access.transmitSessionKeyId != 0) {
886         DeviceProfileConnector::GetInstance().DeleteSessionKey(access.userId, access.transmitSessionKeyId);
887         tokenIds.push_back(std::make_pair(context->accesser.tokenId, context->accessee.tokenId));
888     }
889     if (context->IsProxyBind && !context->subjectProxyOnes.empty()) {
890         for (auto &app : context->subjectProxyOnes) {
891             DmProxyAccess &proxyAccess = context->direction == DM_AUTH_SOURCE ? app.proxyAccesser : app.proxyAccessee;
892             if (proxyAccess.isAuthed || proxyAccess.transmitSessionKeyId == 0) {
893                 continue;
894             }
895             DeviceProfileConnector::GetInstance().DeleteSessionKey(access.userId, proxyAccess.transmitSessionKeyId);
896             tokenIds.push_back(std::make_pair(app.proxyAccesser.tokenId, app.proxyAccessee.tokenId));
897         }
898     }
899     if (access.isGeneratedTransmitThisBind && !access.transmitCredentialId.empty()) {
900         context->hiChainAuthConnector->DeleteCredential(access.userId, access.transmitCredentialId);
901     } else if (!context->reUseCreId.empty()) {
902         RemoveTokenIdsFromCredential(context, context->reUseCreId, tokenIds);
903     } else {
904         LOGE("no credential");
905     }
906     DeleteAcl(context, isDelLnnAcl, tokenIds);
907 }
908 
DeleteAcl(std::shared_ptr<DmAuthContext> context,bool isDelLnnAcl,std::vector<std::pair<int64_t,int64_t>> & tokenIds)909 void DmAuthState::DeleteAcl(std::shared_ptr<DmAuthContext> context, bool isDelLnnAcl,
910     std::vector<std::pair<int64_t, int64_t>> &tokenIds)
911 {
912     CHECK_NULL_VOID(context);
913     DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee;
914     DmAccess &remoteAccess = (context->direction == DM_AUTH_SOURCE) ? context->accessee : context->accesser;
915     if (remoteAccess.deviceId.empty()) {
916         return;
917     }
918     if (!isDelLnnAcl && tokenIds.empty()) {
919         return;
920     }
921     std::vector<DistributedDeviceProfile::AccessControlProfile> acls =
922         DeviceProfileConnector::GetInstance().GetAclList(access.deviceId, access.userId,
923         remoteAccess.deviceId, remoteAccess.userId);
924     for (DistributedDeviceProfile::AccessControlProfile acl : acls) {
925         if (isDelLnnAcl && DeviceProfileConnector::GetInstance().IsLnnAcl(acl)) {
926             DeviceProfileConnector::GetInstance().DeleteAccessControlById(acl.GetAccessControlId());
927             continue;
928         }
929         auto it = std::find(tokenIds.begin(), tokenIds.end(),
930             std::make_pair(acl.GetAccesser().GetAccesserTokenId(), acl.GetAccessee().GetAccesseeTokenId()));
931         if (it != tokenIds.end()) {
932             DeviceProfileConnector::GetInstance().DeleteAccessControlById(acl.GetAccessControlId());
933             continue;
934         }
935     }
936 }
937 
RemoveTokenIdsFromCredential(std::shared_ptr<DmAuthContext> context,const std::string & credId,std::vector<std::pair<int64_t,int64_t>> & tokenIds)938 void DmAuthState::RemoveTokenIdsFromCredential(std::shared_ptr<DmAuthContext> context, const std::string &credId,
939     std::vector<std::pair<int64_t, int64_t>> &tokenIds)
940 {
941     CHECK_NULL_VOID(context);
942     CHECK_NULL_VOID(context->hiChainAuthConnector);
943     DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee;
944     JsonObject credJson;
945     context->hiChainAuthConnector->QueryCredInfoByCredId(access.userId, credId, credJson);
946     if (!credJson.Contains(credId)) {
947         LOGE("query cred failed");
948         return;
949     }
950     if (!credJson[credId].Contains(FILED_AUTHORIZED_APP_LIST)) {
951         LOGE("applist is empty");
952         context->hiChainAuthConnector->DeleteCredential(access.userId, credId);
953         return;
954     }
955     std::vector<std::string> appList;
956     credJson[credId][FILED_AUTHORIZED_APP_LIST].Get(appList);
957     for (const auto& it : tokenIds) {
958         auto erIt = std::find(appList.begin(), appList.end(), std::to_string(it.first));
959         if (erIt != appList.end()) {
960             appList.erase(erIt);
961         }
962         auto eeIt = std::find(appList.begin(), appList.end(), std::to_string(it.second));
963         if (eeIt != appList.end()) {
964             appList.erase(eeIt);
965         }
966     }
967     if (appList.size() == 0) {
968         LOGE("applist is empty, delete credential");
969         context->hiChainAuthConnector->DeleteCredential(access.userId, credId);
970         return;
971     }
972     context->hiChainAuthConnector->UpdateCredential(credId, access.userId, appList);
973 }
974 
JoinLnn(std::shared_ptr<DmAuthContext> context)975 void DmAuthState::JoinLnn(std::shared_ptr<DmAuthContext> context)
976 {
977     CHECK_NULL_VOID(context);
978     CHECK_NULL_VOID(context->softbusConnector);
979     bool isForceJoin = false;
980     if (!context->accesser.isOnline) {
981         LOGI("The remote device is offline.");
982         isForceJoin = true;
983     }
984     if (context->connSessionType == CONN_SESSION_TYPE_HML) {
985         context->softbusConnector->JoinLnnByHml(context->sessionId, context->accesser.transmitSessionKeyId,
986             context->accessee.transmitSessionKeyId, isForceJoin);
987     } else {
988         char udidHashTmp[DM_MAX_DEVICE_ID_LEN] = {0};
989         if (Crypto::GetUdidHash(context->accessee.deviceId, reinterpret_cast<uint8_t*>(udidHashTmp)) == DM_OK) {
990             std::string peerUdidHash = std::string(udidHashTmp);
991             context->softbusConnector->JoinLNNBySkId(context->sessionId, context->accesser.transmitSessionKeyId,
992                 context->accessee.transmitSessionKeyId, context->accessee.addr, peerUdidHash, isForceJoin);
993         }
994     }
995 }
996 } // namespace DistributedHardware
997 } // namespace OHOS
998