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