1 /*
2 * Copyright (c) 2022 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 "dm_auth_manager.h"
17
18 #include <string>
19
20 #include "auth_message_processor.h"
21 #include "dm_ability_manager.h"
22 #include "dm_anonymous.h"
23 #include "dm_config_manager.h"
24 #include "dm_constants.h"
25 #include "dm_log.h"
26 #include "dm_random.h"
27 #include "multiple_user_connector.h"
28 #include "nlohmann/json.hpp"
29 #include "parameter.h"
30 #include "show_confirm.h"
31
32 namespace OHOS {
33 namespace DistributedHardware {
34 const int32_t AUTHENTICATE_TIMEOUT = 120;
35 const int32_t CONFIRM_TIMEOUT = 60;
36 const int32_t NEGOTIATE_TIMEOUT = 10;
37 const int32_t INPUT_TIMEOUT = 60;
38 const int32_t ADD_TIMEOUT = 10;
39 const int32_t WAIT_NEGOTIATE_TIMEOUT = 10;
40 const int32_t WAIT_REQUEST_TIMEOUT = 10;
41 const int32_t CANCEL_PIN_CODE_DISPLAY = 1;
42 const int32_t DEVICE_ID_HALF = 2;
43 const int32_t MAX_AUTH_TIMES = 3;
44 const int32_t MIN_PIN_TOKEN = 10000000;
45 const int32_t MAX_PIN_TOKEN = 90000000;
46 const int32_t MIN_PIN_CODE = 100000;
47 const int32_t MAX_PIN_CODE = 999999;
48 const int32_t DM_AUTH_TYPE_MAX = 4;
49 const int32_t DM_AUTH_TYPE_MIN = 1;
50 const int32_t AUTH_SESSION_SIDE_SERVER = 0;
51
52 constexpr const char* APP_NAME_KEY = "appName";
53 constexpr const char* APP_ICON_KEY = "appIcon";
54 constexpr const char* TARGET_PKG_NAME_KEY = "targetPkgName";
55 constexpr const char* APP_DESCRIPTION_KEY = "appDescription";
56 constexpr const char* CANCEL_DISPLAY_KEY = "cancelPinCodeDisplay";
57 constexpr const char* VERIFY_FAILED = "verifyFailed";
58
DmAuthManager(std::shared_ptr<SoftbusConnector> softbusConnector,std::shared_ptr<IDeviceManagerServiceListener> listener,std::shared_ptr<HiChainConnector> hiChainConnector)59 DmAuthManager::DmAuthManager(std::shared_ptr<SoftbusConnector> softbusConnector,
60 std::shared_ptr<IDeviceManagerServiceListener> listener,
61 std::shared_ptr<HiChainConnector> hiChainConnector)
62 : softbusConnector_(softbusConnector), hiChainConnector_(hiChainConnector), listener_(listener)
63 {
64 LOGI("DmAuthManager constructor");
65 DmConfigManager &dmConfigManager = DmConfigManager::GetInstance();
66 dmConfigManager.GetAuthAdapter(authenticationMap_);
67 }
68
~DmAuthManager()69 DmAuthManager::~DmAuthManager()
70 {
71 LOGI("DmAuthManager destructor");
72 }
73
AuthenticateDevice(const std::string & pkgName,int32_t authType,const std::string & deviceId,const std::string & extra)74 int32_t DmAuthManager::AuthenticateDevice(const std::string &pkgName, int32_t authType, const std::string &deviceId,
75 const std::string &extra)
76 {
77 LOGI("DmAuthManager::AuthenticateDevice start auth type %d", authType);
78 if (authType < DM_AUTH_TYPE_MIN || authType > DM_AUTH_TYPE_MAX) {
79 LOGE("AuthenticateDevice failed, authType is illegal");
80 return ERR_DM_AUTH_FAILED;
81 }
82 if (pkgName.empty() || deviceId.empty()) {
83 LOGE("DmAuthManager::AuthenticateDevice failed, pkgName is %s, deviceId is %s, extra is %s",
84 pkgName.c_str(), GetAnonyString(deviceId).c_str(), extra.c_str());
85 return ERR_DM_INPUT_PARA_INVALID;
86 }
87 std::shared_ptr<IAuthentication> authentication = authenticationMap_[authType];
88 if (listener_ == nullptr) {
89 LOGE("DmAuthManager::AuthenticateDevice is empty nullptr");
90 return ERR_DM_INPUT_PARA_INVALID;
91 }
92 if (authentication == nullptr) {
93 LOGE("DmAuthManager::AuthenticateDevice authType %d not support.", authType);
94 listener_->OnAuthResult(pkgName, deviceId, "", AuthState::AUTH_REQUEST_INIT, ERR_DM_UNSUPPORTED_AUTH_TYPE);
95 return ERR_DM_UNSUPPORTED_AUTH_TYPE;
96 }
97
98 if (authRequestState_ != nullptr || authResponseState_ != nullptr) {
99 LOGE("DmAuthManager::AuthenticateDevice %s is request authentication.", pkgName.c_str());
100 listener_->OnAuthResult(pkgName, deviceId, "", AuthState::AUTH_REQUEST_INIT, ERR_DM_AUTH_BUSINESS_BUSY);
101 return ERR_DM_AUTH_BUSINESS_BUSY;
102 }
103
104 if (!softbusConnector_->HaveDeviceInMap(deviceId)) {
105 LOGE("AuthenticateDevice failed, the discoveryDeviceInfoMap_ not have this device");
106 listener_->OnAuthResult(pkgName, deviceId, "", AuthState::AUTH_REQUEST_INIT, ERR_DM_INPUT_PARA_INVALID);
107 return ERR_DM_INPUT_PARA_INVALID;
108 }
109
110 authPtr_ = authenticationMap_[authType];
111 if (timer_ == nullptr) {
112 timer_ = std::make_shared<DmTimer>();
113 }
114 timer_->StartTimer(std::string(AUTHENTICATE_TIMEOUT_TASK), AUTHENTICATE_TIMEOUT,
115 [this] (std::string name) {
116 DmAuthManager::HandleAuthenticateTimeout(name);
117 });
118 authMessageProcessor_ = std::make_shared<AuthMessageProcessor>(shared_from_this());
119 authResponseContext_ = std::make_shared<DmAuthResponseContext>();
120 authRequestContext_ = std::make_shared<DmAuthRequestContext>();
121 authRequestContext_->hostPkgName = pkgName;
122 authRequestContext_->authType = authType;
123 authRequestContext_->deviceId = deviceId;
124 nlohmann::json jsonObject = nlohmann::json::parse(extra, nullptr, false);
125 if (!jsonObject.is_discarded()) {
126 if (IsString(jsonObject, TARGET_PKG_NAME_KEY)) {
127 authRequestContext_->targetPkgName = jsonObject[TARGET_PKG_NAME_KEY].get<std::string>();
128 }
129 if (IsString(jsonObject, APP_NAME_KEY)) {
130 authRequestContext_->appName = jsonObject[APP_NAME_KEY].get<std::string>();
131 }
132 if (IsString(jsonObject, APP_DESCRIPTION_KEY)) {
133 authRequestContext_->appDesc = jsonObject[APP_DESCRIPTION_KEY].get<std::string>();
134 }
135 if (IsString(jsonObject, APP_THUMBNAIL)) {
136 authRequestContext_->appThumbnail = jsonObject[APP_THUMBNAIL].get<std::string>();
137 }
138 if (IsString(jsonObject, APP_ICON_KEY)) {
139 authRequestContext_->appIcon = jsonObject[APP_ICON_KEY].get<std::string>();
140 }
141 }
142 authRequestContext_->token = std::to_string(GenRandInt(MIN_PIN_TOKEN, MAX_PIN_TOKEN));
143 authMessageProcessor_->SetRequestContext(authRequestContext_);
144 authRequestState_ = std::make_shared<AuthRequestInitState>();
145 authRequestState_->SetAuthManager(shared_from_this());
146 authRequestState_->SetAuthContext(authRequestContext_);
147 authRequestState_->Enter();
148 LOGI("DmAuthManager::AuthenticateDevice complete");
149 return DM_OK;
150 }
151
UnAuthenticateDevice(const std::string & pkgName,const std::string & deviceId)152 int32_t DmAuthManager::UnAuthenticateDevice(const std::string &pkgName, const std::string &deviceId)
153 {
154 if (pkgName.empty()) {
155 LOGE("Invalid parameter, pkgName is empty.");
156 return ERR_DM_FAILED;
157 }
158 std::string deviceUdid;
159 int32_t ret = SoftbusConnector::GetUdidByNetworkId(deviceId.c_str(), deviceUdid);
160 if (ret != DM_OK) {
161 LOGE("UnAuthenticateDevice GetNodeKeyInfo failed");
162 return ERR_DM_FAILED;
163 }
164
165 std::vector<OHOS::DistributedHardware::GroupInfo> groupList;
166 hiChainConnector_->GetRelatedGroups(deviceUdid, groupList);
167 if (groupList.size() > 0) {
168 std::string groupId = "";
169 groupId = groupList.front().groupId;
170 LOGI("DmAuthManager::UnAuthenticateDevice groupId = %s, deviceId = %s, deviceUdid = %s",
171 GetAnonyString(groupId).c_str(), GetAnonyString(deviceId).c_str(), GetAnonyString(deviceUdid).c_str());
172 hiChainConnector_->DeleteGroup(groupId);
173 } else {
174 LOGE("DmAuthManager::UnAuthenticateDevice groupList.size = 0");
175 return ERR_DM_FAILED;
176 }
177 return DM_OK;
178 }
179
VerifyAuthentication(const std::string & authParam)180 int32_t DmAuthManager::VerifyAuthentication(const std::string &authParam)
181 {
182 LOGI("DmAuthManager::VerifyAuthentication");
183 if (authResponseContext_ == nullptr) {
184 LOGE("authResponseContext_ is not init");
185 return ERR_DM_AUTH_NOT_START;
186 }
187 timer_->DeleteTimer(std::string(INPUT_TIMEOUT_TASK));
188 int32_t ret = authPtr_->VerifyAuthentication(authResponseContext_->authToken, authParam);
189 switch (ret) {
190 case DM_OK:
191 authRequestState_->TransitionTo(std::make_shared<AuthRequestJoinState>());
192 break;
193 case ERR_DM_INPUT_PARA_INVALID:
194 listener_->OnVerifyAuthResult(authRequestContext_->hostPkgName, authRequestContext_->deviceId,
195 ERR_DM_INPUT_PARA_INVALID, "");
196 break;
197 default:
198 authRequestContext_->reason = ERR_DM_INPUT_PARA_INVALID;
199 authResponseContext_->state = authRequestState_->GetStateType();
200 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
201 break;
202 }
203 LOGI("DmAuthManager::VerifyAuthentication complete");
204 return DM_OK;
205 }
206
OnSessionOpened(int32_t sessionId,int32_t sessionSide,int32_t result)207 void DmAuthManager::OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result)
208 {
209 LOGI("DmAuthManager::OnSessionOpened sessionId = %d result = %d", sessionId, result);
210 if (sessionSide == AUTH_SESSION_SIDE_SERVER) {
211 if (authResponseState_ == nullptr && authRequestState_ == nullptr) {
212 authMessageProcessor_ = std::make_shared<AuthMessageProcessor>(shared_from_this());
213 authResponseState_ = std::make_shared<AuthResponseInitState>();
214 authResponseState_->SetAuthManager(shared_from_this());
215 authResponseState_->Enter();
216 authResponseContext_ = std::make_shared<DmAuthResponseContext>();
217 timer_ = std::make_shared<DmTimer>();
218 timer_->StartTimer(std::string(AUTHENTICATE_TIMEOUT_TASK), AUTHENTICATE_TIMEOUT,
219 [this] (std::string name) {
220 DmAuthManager::HandleAuthenticateTimeout(name);
221 });
222 timer_->StartTimer(std::string(WAIT_NEGOTIATE_TIMEOUT_TASK), WAIT_NEGOTIATE_TIMEOUT,
223 [this] (std::string name) {
224 DmAuthManager::HandleAuthenticateTimeout(name);
225 });
226 } else {
227 std::shared_ptr<AuthMessageProcessor> authMessageProcessor =
228 std::make_shared<AuthMessageProcessor>(shared_from_this());
229 std::shared_ptr<DmAuthResponseContext> authResponseContext = std::make_shared<DmAuthResponseContext>();
230 authResponseContext->reply = ERR_DM_AUTH_BUSINESS_BUSY;
231 authMessageProcessor->SetResponseContext(authResponseContext);
232 std::string message = authMessageProcessor->CreateSimpleMessage(MSG_TYPE_REQ_AUTH_TERMINATE);
233 softbusConnector_->GetSoftbusSession()->SendData(sessionId, message);
234 }
235 } else {
236 if (authResponseState_ == nullptr && authRequestState_ != nullptr &&
237 authRequestState_->GetStateType() == AuthState::AUTH_REQUEST_INIT) {
238 authRequestContext_->sessionId = sessionId;
239 authRequestState_->SetAuthContext(authRequestContext_);
240 authMessageProcessor_->SetRequestContext(authRequestContext_);
241 authRequestState_->TransitionTo(std::make_shared<AuthRequestNegotiateState>());
242 } else {
243 LOGE("DmAuthManager::OnSessionOpened but request state is wrong");
244 }
245 }
246 }
247
OnSessionClosed(const int32_t sessionId)248 void DmAuthManager::OnSessionClosed(const int32_t sessionId)
249 {
250 LOGI("DmAuthManager::OnSessionOpened sessionId = %d", sessionId);
251 }
252
OnDataReceived(const int32_t sessionId,const std::string message)253 void DmAuthManager::OnDataReceived(const int32_t sessionId, const std::string message)
254 {
255 if (authResponseContext_ == nullptr || authMessageProcessor_ == nullptr) {
256 LOGE("OnDataReceived failed, authResponseContext or authMessageProcessor_ is nullptr.");
257 return;
258 }
259
260 authResponseContext_->sessionId = sessionId;
261 authMessageProcessor_->SetResponseContext(authResponseContext_);
262 int32_t ret = authMessageProcessor_->ParseMessage(message);
263 if (ret != DM_OK) {
264 LOGE("OnDataReceived failed, parse input message error.");
265 return;
266 }
267
268 if ((authRequestState_ != nullptr) && (authResponseState_ == nullptr)) {
269 // source device auth process
270 authRequestContext_ = authMessageProcessor_->GetRequestContext();
271 authRequestState_->SetAuthContext(authRequestContext_);
272 LOGI("OnDataReceived for source device, authResponseContext msgType = %d, authRequestState stateType = %d",
273 authResponseContext_->msgType, authRequestState_->GetStateType());
274
275 switch (authResponseContext_->msgType) {
276 case MSG_TYPE_RESP_AUTH:
277 if (authRequestState_->GetStateType() == AuthState::AUTH_REQUEST_NEGOTIATE_DONE) {
278 authRequestState_->TransitionTo(std::make_shared<AuthRequestReplyState>());
279 }
280 break;
281 case MSG_TYPE_RESP_NEGOTIATE:
282 if (authRequestState_->GetStateType() == AuthState::AUTH_REQUEST_NEGOTIATE) {
283 authRequestState_->TransitionTo(std::make_shared<AuthRequestNegotiateDoneState>());
284 }
285 break;
286 case MSG_TYPE_REQ_AUTH_TERMINATE:
287 if (authRequestState_->GetStateType() != AuthState::AUTH_REQUEST_FINISH) {
288 isFinishOfLocal_ = false;
289 authResponseContext_->state = authRequestState_->GetStateType();
290 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
291 }
292 break;
293 default:
294 break;
295 }
296 } else if ((authResponseState_ != nullptr) && (authRequestState_ == nullptr)) {
297 // sink device auth process
298 authResponseState_->SetAuthContext(authResponseContext_);
299 LOGI("OnDataReceived for sink device, authResponseContext msgType = %d, authResponseState stateType = %d",
300 authResponseContext_->msgType, authResponseState_->GetStateType());
301
302 switch (authResponseContext_->msgType) {
303 case MSG_TYPE_NEGOTIATE:
304 if (authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_INIT) {
305 timer_->DeleteTimer(std::string(WAIT_NEGOTIATE_TIMEOUT_TASK));
306 authResponseState_->TransitionTo(std::make_shared<AuthResponseNegotiateState>());
307 } else {
308 LOGE("Device manager auth state error");
309 }
310 break;
311 case MSG_TYPE_REQ_AUTH:
312 if (authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_NEGOTIATE) {
313 timer_->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK));
314 authResponseState_->TransitionTo(std::make_shared<AuthResponseConfirmState>());
315 } else {
316 LOGE("Device manager auth state error");
317 }
318 break;
319 case MSG_TYPE_REQ_AUTH_TERMINATE:
320 if (authResponseState_->GetStateType() != AuthState::AUTH_RESPONSE_FINISH) {
321 isFinishOfLocal_ = false;
322 authResponseState_->TransitionTo(std::make_shared<AuthResponseFinishState>());
323 }
324 break;
325 default:
326 break;
327 }
328 } else {
329 LOGE("DmAuthManager::OnDataReceived failed, authRequestState_ or authResponseState_ is invalid.");
330 }
331 }
332
OnGroupCreated(int64_t requestId,const std::string & groupId)333 void DmAuthManager::OnGroupCreated(int64_t requestId, const std::string &groupId)
334 {
335 if (authResponseContext_ == nullptr) {
336 LOGE("failed to OnGroupCreated because authResponseContext_ is nullptr");
337 return;
338 }
339 if (authResponseState_ == nullptr) {
340 LOGE("DmAuthManager::AuthenticateDevice end");
341 return;
342 }
343 LOGI("DmAuthManager::OnGroupCreated start group id %s", GetAnonyString(groupId).c_str());
344 if (groupId == "{}") {
345 authResponseContext_->reply = ERR_DM_CREATE_GROUP_FAILED;
346 authMessageProcessor_->SetResponseContext(authResponseContext_);
347 std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_RESP_AUTH);
348 softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message);
349 return;
350 }
351
352 int32_t pinCode = GeneratePincode();
353 nlohmann::json jsonObj;
354 jsonObj[PIN_TOKEN] = authResponseContext_->token;
355 jsonObj[QR_CODE_KEY] = GenerateGroupName();
356 jsonObj[NFC_CODE_KEY] = GenerateGroupName();
357 authResponseContext_->authToken = jsonObj.dump();
358 LOGI("DmAuthManager::OnGroupCreated start group id %s", GetAnonyString(groupId).c_str());
359 authResponseContext_->groupId = groupId;
360 authResponseContext_->code = pinCode;
361 authMessageProcessor_->SetResponseContext(authResponseContext_);
362 std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_RESP_AUTH);
363 softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message);
364 authResponseState_->TransitionTo(std::make_shared<AuthResponseShowState>());
365 }
366
OnMemberJoin(int64_t requestId,int32_t status)367 void DmAuthManager::OnMemberJoin(int64_t requestId, int32_t status)
368 {
369 if (authResponseContext_ == nullptr) {
370 LOGE("failed to OnMemberJoin because authResponseContext_ is nullptr");
371 return;
372 }
373 LOGI("DmAuthManager OnMemberJoin start authTimes %d", authTimes_);
374 if ((authRequestState_ != nullptr) && (authResponseState_ == nullptr)) {
375 authTimes_++;
376 timer_->DeleteTimer(std::string(ADD_TIMEOUT_TASK));
377 if (status != DM_OK || authResponseContext_->requestId != requestId) {
378 if (authRequestState_ != nullptr && authTimes_ >= MAX_AUTH_TIMES) {
379 authResponseContext_->state = AuthState::AUTH_REQUEST_JOIN;
380 authRequestContext_->reason = ERR_DM_INPUT_PARA_INVALID;
381 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
382 } else {
383 timer_->StartTimer(std::string(INPUT_TIMEOUT_TASK), INPUT_TIMEOUT,
384 [this] (std::string name) {
385 DmAuthManager::HandleAuthenticateTimeout(name);
386 });
387 UpdateInputDialogDisplay(true);
388 }
389 } else {
390 authRequestState_->TransitionTo(std::make_shared<AuthRequestNetworkState>());
391 }
392 } else if ((authResponseState_ != nullptr) && (authRequestState_ == nullptr)) {
393 if (status == DM_OK && authResponseContext_->requestId == requestId &&
394 authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_SHOW) {
395 UpdateInputDialogDisplay(false);
396 }
397 } else {
398 LOGE("DmAuthManager::OnMemberJoin failed, authRequestState_ or authResponseState_ is invalid.");
399 }
400 }
401
HandleAuthenticateTimeout(std::string name)402 void DmAuthManager::HandleAuthenticateTimeout(std::string name)
403 {
404 LOGI("DmAuthManager::HandleAuthenticateTimeout start timer name %s", name.c_str());
405 if (authRequestState_ != nullptr && authRequestState_->GetStateType() != AuthState::AUTH_REQUEST_FINISH) {
406 if (authResponseContext_ == nullptr) {
407 authResponseContext_ = std::make_shared<DmAuthResponseContext>();
408 }
409 authResponseContext_->state = authRequestState_->GetStateType();
410 authRequestContext_->reason = ERR_DM_TIME_OUT;
411 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
412 }
413
414 if (authResponseState_ != nullptr && authResponseState_->GetStateType() != AuthState::AUTH_RESPONSE_FINISH) {
415 authResponseContext_->state = authResponseState_->GetStateType();
416 authResponseContext_->reply = ERR_DM_TIME_OUT;
417 authResponseState_->TransitionTo(std::make_shared<AuthResponseFinishState>());
418 }
419 LOGI("DmAuthManager::HandleAuthenticateTimeout start complete");
420 }
421
EstablishAuthChannel(const std::string & deviceId)422 int32_t DmAuthManager::EstablishAuthChannel(const std::string &deviceId)
423 {
424 int32_t sessionId = softbusConnector_->GetSoftbusSession()->OpenAuthSession(deviceId);
425 if (sessionId < 0) {
426 LOGE("OpenAuthSession failed, stop the authentication");
427 authResponseContext_ = std::make_shared<DmAuthResponseContext>();
428 authResponseContext_->state = AuthState::AUTH_REQUEST_NEGOTIATE;
429 if (authRequestContext_ != nullptr) {
430 authRequestContext_->reason = ERR_DM_AUTH_OPEN_SESSION_FAILED;
431 }
432 if (authRequestState_ != nullptr) {
433 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
434 }
435 }
436 return DM_OK;
437 }
438
StartNegotiate(const int32_t & sessionId)439 void DmAuthManager::StartNegotiate(const int32_t &sessionId)
440 {
441 if (authResponseContext_ == nullptr) {
442 LOGE("DmAuthManager::StartNegotiate error, authResponseContext_ is nullptr");
443 return;
444 }
445 LOGI("DmAuthManager::StartNegotiate session id is %d", sessionId);
446 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
447 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
448 authRequestContext_->localDeviceId = localDeviceId;
449 authResponseContext_->localDeviceId = localDeviceId;
450 authResponseContext_->reply = ERR_DM_AUTH_REJECT;
451 authResponseContext_->authType = authRequestContext_->authType;
452 authResponseContext_->deviceId = authRequestContext_->deviceId;
453 authMessageProcessor_->SetResponseContext(authResponseContext_);
454 std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_NEGOTIATE);
455 softbusConnector_->GetSoftbusSession()->SendData(sessionId, message);
456 timer_->StartTimer(std::string(NEGOTIATE_TIMEOUT_TASK), NEGOTIATE_TIMEOUT,
457 [this] (std::string name) {
458 DmAuthManager::HandleAuthenticateTimeout(name);
459 });
460 }
461
RespNegotiate(const int32_t & sessionId)462 void DmAuthManager::RespNegotiate(const int32_t &sessionId)
463 {
464 if (authResponseContext_ == nullptr) {
465 LOGE("failed to RespNegotiate because authResponseContext_ is nullptr");
466 return;
467 }
468 LOGI("DmAuthManager::EstablishAuthChannel session id is %d", sessionId);
469 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
470 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
471 bool ret = hiChainConnector_->IsDevicesInGroup(authResponseContext_->localDeviceId, localDeviceId);
472 if (ret) {
473 LOGE("DmAuthManager::EstablishAuthChannel device is in group");
474 authResponseContext_->reply = ERR_DM_AUTH_PEER_REJECT;
475 } else {
476 authResponseContext_->reply = ERR_DM_AUTH_REJECT;
477 }
478 authResponseContext_->localDeviceId = localDeviceId;
479
480 std::shared_ptr<IAuthentication> authentication = authenticationMap_[authResponseContext_->authType];
481 if (authentication == nullptr) {
482 LOGE("DmAuthManager::AuthenticateDevice authType %d not support.", authResponseContext_->authType);
483 authResponseContext_->reply = ERR_DM_UNSUPPORTED_AUTH_TYPE;
484 } else {
485 authPtr_ = authenticationMap_[authResponseContext_->authType];
486 }
487
488 std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_RESP_NEGOTIATE);
489 nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
490 if (jsonObject.is_discarded()) {
491 softbusConnector_->GetSoftbusSession()->SendData(sessionId, message);
492 }
493
494 if (IsIdenticalAccount()) {
495 jsonObject[TAG_IDENTICAL_ACCOUNT] = true;
496 }
497 authResponseContext_ = authResponseState_->GetAuthContext();
498 if (jsonObject[TAG_CRYPTO_SUPPORT] == true && authResponseContext_->cryptoSupport) {
499 if (jsonObject[TAG_CRYPTO_NAME] == authResponseContext_->cryptoName &&
500 jsonObject[TAG_CRYPTO_VERSION] == authResponseContext_->cryptoVer) {
501 isCryptoSupport_ = true;
502 softbusConnector_->GetSoftbusSession()->SendData(sessionId, message);
503 return;
504 }
505 }
506 jsonObject[TAG_CRYPTO_SUPPORT] = false;
507 message = jsonObject.dump();
508 softbusConnector_->GetSoftbusSession()->SendData(sessionId, message);
509 timer_->StartTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK), WAIT_REQUEST_TIMEOUT,
510 [this] (std::string name) {
511 DmAuthManager::HandleAuthenticateTimeout(name);
512 });
513 }
514
SendAuthRequest(const int32_t & sessionId)515 void DmAuthManager::SendAuthRequest(const int32_t &sessionId)
516 {
517 if (authResponseContext_ == nullptr) {
518 LOGE("failed to SendAuthRequest because authResponseContext_ is nullptr");
519 return;
520 }
521 LOGI("DmAuthManager::EstablishAuthChannel session id");
522 timer_->DeleteTimer(std::string(NEGOTIATE_TIMEOUT_TASK));
523 if (authResponseContext_->cryptoSupport) {
524 isCryptoSupport_ = true;
525 }
526
527 if (authResponseContext_->isIdenticalAccount) { // identicalAccount joinLNN indirectly, no need to verify
528 if (IsIdenticalAccount()) {
529 softbusConnector_->JoinLnn(authResponseContext_->deviceId);
530 authResponseContext_->state = AuthState::AUTH_REQUEST_FINISH;
531 authRequestContext_->reason = DM_OK;
532 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
533 return;
534 }
535 }
536 if (authResponseContext_->reply == ERR_DM_AUTH_PEER_REJECT) {
537 if (hiChainConnector_->IsDevicesInGroup(authResponseContext_->localDeviceId,
538 authRequestContext_->localDeviceId)) {
539 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
540 return;
541 }
542 }
543
544 std::vector<std::string> messageList = authMessageProcessor_->CreateAuthRequestMessage();
545 for (auto msg : messageList) {
546 softbusConnector_->GetSoftbusSession()->SendData(sessionId, msg);
547 }
548 timer_->StartTimer(std::string(CONFIRM_TIMEOUT_TASK), CONFIRM_TIMEOUT,
549 [this] (std::string name) {
550 DmAuthManager::HandleAuthenticateTimeout(name);
551 });
552 }
553
StartAuthProcess(const int32_t & action)554 int32_t DmAuthManager::StartAuthProcess(const int32_t &action)
555 {
556 if (authResponseContext_ == nullptr) {
557 LOGE("failed to StartAuthProcess because authResponseContext_ is nullptr");
558 return ERR_DM_AUTH_NOT_START;
559 }
560 LOGI("DmAuthManager::StartAuthProcess");
561 authResponseContext_->reply = action;
562 if (authResponseContext_->reply == USER_OPERATION_TYPE_ALLOW_AUTH &&
563 authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_CONFIRM) {
564 authResponseState_->TransitionTo(std::make_shared<AuthResponseGroupState>());
565 } else {
566 authMessageProcessor_->SetResponseContext(authResponseContext_);
567 std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_RESP_AUTH);
568 softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message);
569 }
570 return DM_OK;
571 }
572
StartRespAuthProcess()573 void DmAuthManager::StartRespAuthProcess()
574 {
575 if (authResponseContext_ == nullptr) {
576 LOGE("failed to StartRespAuthProcess because authResponseContext_ is nullptr");
577 return;
578 }
579 LOGI("DmAuthManager::StartRespAuthProcess sessionId = %d", authResponseContext_->sessionId);
580 timer_->DeleteTimer(std::string(CONFIRM_TIMEOUT_TASK));
581 if (authResponseContext_->reply == USER_OPERATION_TYPE_ALLOW_AUTH) {
582 timer_->StartTimer(std::string(INPUT_TIMEOUT_TASK), INPUT_TIMEOUT,
583 [this] (std::string name) {
584 DmAuthManager::HandleAuthenticateTimeout(name);
585 });
586 authRequestState_->TransitionTo(std::make_shared<AuthRequestJoinState>());
587 } else {
588 LOGE("do not accept");
589 authResponseContext_->state = AuthState::AUTH_REQUEST_REPLY;
590 authRequestContext_->reason = ERR_DM_AUTH_PEER_REJECT;
591 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
592 }
593 }
594
CreateGroup()595 int32_t DmAuthManager::CreateGroup()
596 {
597 if (authResponseContext_ == nullptr) {
598 LOGE("failed to CreateGroup because authResponseContext_ is nullptr");
599 return ERR_DM_FAILED;
600 }
601 LOGI("DmAuthManager::CreateGroup start");
602 authResponseContext_->groupName = GenerateGroupName();
603 authResponseContext_->requestId = GenRandLongLong(MIN_REQUEST_ID, MAX_REQUEST_ID);
604 hiChainConnector_->CreateGroup(authResponseContext_->requestId, authResponseContext_->groupName);
605 return DM_OK;
606 }
607
AddMember(int32_t pinCode)608 int32_t DmAuthManager::AddMember(int32_t pinCode)
609 {
610 if (authResponseContext_ == nullptr) {
611 LOGE("failed to AddMember because authResponseContext_ is nullptr");
612 return ERR_DM_FAILED;
613 }
614 LOGI("DmAuthManager::AddMember start group id %s", GetAnonyString(authResponseContext_->groupId).c_str());
615 timer_->DeleteTimer(std::string(INPUT_TIMEOUT_TASK));
616 nlohmann::json jsonObject;
617 jsonObject[TAG_GROUP_ID] = authResponseContext_->groupId;
618 jsonObject[TAG_GROUP_NAME] = authResponseContext_->groupName;
619 jsonObject[PIN_CODE_KEY] = pinCode;
620 jsonObject[TAG_REQUEST_ID] = authResponseContext_->requestId;
621 jsonObject[TAG_DEVICE_ID] = authResponseContext_->deviceId;
622 std::string connectInfo = jsonObject.dump();
623 timer_->StartTimer(std::string(ADD_TIMEOUT_TASK), ADD_TIMEOUT,
624 [this] (std::string name) {
625 DmAuthManager::HandleAuthenticateTimeout(name);
626 });
627 int32_t ret = hiChainConnector_->AddMember(authRequestContext_->deviceId, connectInfo);
628 if (ret != 0) {
629 LOGE("DmAuthManager::AddMember failed, ret: %d", ret);
630 return ERR_DM_FAILED;
631 }
632 return DM_OK;
633 }
634
GetConnectAddr(std::string deviceId)635 std::string DmAuthManager::GetConnectAddr(std::string deviceId)
636 {
637 LOGI("DmAuthManager::GetConnectAddr");
638 std::string connectAddr;
639 if (softbusConnector_->GetConnectAddr(deviceId, connectAddr) == nullptr) {
640 LOGE("DmAuthManager::GetConnectAddr error");
641 }
642 return connectAddr;
643 }
644
JoinNetwork()645 int32_t DmAuthManager::JoinNetwork()
646 {
647 if (authResponseContext_ == nullptr) {
648 LOGE("failed to JoinNeWork because authResponseContext_ is nullptr");
649 return ERR_DM_FAILED;
650 }
651 LOGI("DmAuthManager JoinNetwork start");
652 timer_->DeleteTimer(std::string(AUTHENTICATE_TIMEOUT_TASK));
653 authResponseContext_->state = AuthState::AUTH_REQUEST_FINISH;
654 authRequestContext_->reason = DM_OK;
655 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
656 return DM_OK;
657 }
658
AuthenticateFinish()659 void DmAuthManager::AuthenticateFinish()
660 {
661 if (authResponseContext_ == nullptr) {
662 LOGE("failed to AuthenticateFinish because authResponseContext_ is nullptr");
663 return;
664 }
665 LOGI("DmAuthManager::AuthenticateFinish start");
666 if (authResponseState_ != nullptr) {
667 if (authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_FINISH && authPtr_ != nullptr) {
668 UpdateInputDialogDisplay(false);
669 }
670 if (isFinishOfLocal_) {
671 authMessageProcessor_->SetResponseContext(authResponseContext_);
672 std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_REQ_AUTH_TERMINATE);
673 softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message);
674 }
675 timer_->DeleteAll();
676 isFinishOfLocal_ = true;
677 authResponseContext_ = nullptr;
678 authResponseState_ = nullptr;
679 authMessageProcessor_ = nullptr;
680 authPtr_ = nullptr;
681 } else if (authRequestState_ != nullptr) {
682 if (isFinishOfLocal_) {
683 authMessageProcessor_->SetResponseContext(authResponseContext_);
684 std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_REQ_AUTH_TERMINATE);
685 softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message);
686 } else {
687 authRequestContext_->reason = authResponseContext_->reply;
688 }
689 if ((authResponseContext_->state == AuthState::AUTH_REQUEST_JOIN ||
690 authResponseContext_->state == AuthState::AUTH_REQUEST_FINISH) && authPtr_ != nullptr) {
691 UpdateInputDialogDisplay(false);
692 }
693 listener_->OnAuthResult(authRequestContext_->hostPkgName, authRequestContext_->deviceId,
694 authRequestContext_->token, authResponseContext_->state, authRequestContext_->reason);
695 softbusConnector_->GetSoftbusSession()->CloseAuthSession(authRequestContext_->sessionId);
696 timer_->DeleteAll();
697 isFinishOfLocal_ = true;
698 authRequestContext_ = nullptr;
699 authResponseContext_ = nullptr;
700 authRequestState_ = nullptr;
701 authMessageProcessor_ = nullptr;
702 authPtr_ = nullptr;
703 authTimes_ = 0;
704 }
705 LOGI("DmAuthManager::AuthenticateFinish complete");
706 }
707
CancelDisplay()708 void DmAuthManager::CancelDisplay()
709 {
710 LOGI("DmAuthManager::CancelDisplay start");
711 nlohmann::json jsonObj;
712 jsonObj[CANCEL_DISPLAY_KEY] = CANCEL_PIN_CODE_DISPLAY;
713 std::string paramJson = jsonObj.dump();
714 std::string pkgName = "com.ohos.devicemanagerui";
715 listener_->OnUiCall(pkgName, paramJson);
716 }
717
UpdateInputDialogDisplay(bool isShow)718 void DmAuthManager::UpdateInputDialogDisplay(bool isShow)
719 {
720 LOGI("DmAuthManager::UpdateInputDialogDisplay start");
721 nlohmann::json jsonObj;
722 jsonObj[VERIFY_FAILED] = isShow;
723 jsonObj.dump();
724 std::string paramJson = jsonObj.dump();
725 std::string pkgName = "com.ohos.devicemanagerui";
726 listener_->OnUiCall(pkgName, paramJson);
727 }
728
GeneratePincode()729 int32_t DmAuthManager::GeneratePincode()
730 {
731 return GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE);
732 }
733
GenerateGroupName()734 std::string DmAuthManager::GenerateGroupName()
735 {
736 if (authResponseContext_ == nullptr) {
737 LOGE("failed to GenerateGroupName because authResponseContext_ is nullptr.");
738 return "";
739 }
740 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
741 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
742 std::string sLocalDeviceId = localDeviceId;
743 uint32_t interceptLength = sLocalDeviceId.size() / DEVICE_ID_HALF;
744 std::string groupName = authResponseContext_->targetPkgName + sLocalDeviceId.substr(0, interceptLength)
745 + authResponseContext_->localDeviceId.substr(0, interceptLength);
746 return groupName;
747 }
748
GetIsCryptoSupport()749 bool DmAuthManager::GetIsCryptoSupport()
750 {
751 if (authResponseState_ == nullptr) {
752 return false;
753 }
754 if (authRequestState_ == nullptr) {
755 if (authResponseState_->GetStateType() == AuthState::AUTH_REQUEST_NEGOTIATE_DONE) {
756 return false;
757 }
758 } else {
759 if (authRequestState_->GetStateType() == AuthState::AUTH_REQUEST_NEGOTIATE ||
760 authRequestState_->GetStateType() == AuthState::AUTH_REQUEST_NEGOTIATE_DONE) {
761 return false;
762 }
763 }
764
765 return isCryptoSupport_;
766 }
767
SetAuthRequestState(std::shared_ptr<AuthRequestState> authRequestState)768 int32_t DmAuthManager::SetAuthRequestState(std::shared_ptr<AuthRequestState> authRequestState)
769 {
770 authRequestState_ = authRequestState;
771 return DM_OK;
772 }
773
SetAuthResponseState(std::shared_ptr<AuthResponseState> authResponseState)774 int32_t DmAuthManager::SetAuthResponseState(std::shared_ptr<AuthResponseState> authResponseState)
775 {
776 authResponseState_ = authResponseState;
777 return DM_OK;
778 }
779
GetPinCode()780 int32_t DmAuthManager::GetPinCode()
781 {
782 if (authResponseContext_ == nullptr) {
783 LOGE("failed to GetPinCode because authResponseContext_ is nullptr");
784 return ERR_DM_AUTH_NOT_START;
785 }
786 LOGI("ShowConfigDialog start add member pin code.");
787 return authResponseContext_->code;
788 }
789
ShowConfigDialog()790 void DmAuthManager::ShowConfigDialog()
791 {
792 if (authResponseContext_ == nullptr) {
793 LOGE("failed to ShowConfigDialog because authResponseContext_ is nullptr");
794 return;
795 }
796 LOGI("ShowConfigDialog start");
797 dmAbilityMgr_ = std::make_shared<DmAbilityManager>();
798 nlohmann::json jsonObj;
799 jsonObj[TAG_AUTH_TYPE] = AUTH_TYPE_PIN;
800 jsonObj[TAG_TOKEN] = authResponseContext_->token;
801 jsonObj[TARGET_PKG_NAME_KEY] = authResponseContext_->targetPkgName;
802 jsonObj.dump();
803 const std::string params = jsonObj.dump();
804 std::shared_ptr<ShowConfirm> showConfirm_ = std::make_shared<ShowConfirm>();
805 showConfirm_->ShowConfirmDialog(params, shared_from_this(), dmAbilityMgr_);
806 LOGI("ShowConfigDialog end");
807 }
808
ShowAuthInfoDialog()809 void DmAuthManager::ShowAuthInfoDialog()
810 {
811 if (authResponseContext_ == nullptr) {
812 LOGE("failed to ShowAuthInfoDialog because authResponseContext_ is nullptr");
813 return;
814 }
815 LOGI("DmAuthManager::ShowAuthInfoDialog start %d", authResponseContext_->code);
816 nlohmann::json jsonObj;
817 jsonObj[PIN_CODE_KEY] = authResponseContext_->code;
818 std::string authParam = jsonObj.dump();
819 authPtr_->ShowAuthInfo(authParam, shared_from_this());
820 }
821
ShowStartAuthDialog()822 void DmAuthManager::ShowStartAuthDialog()
823 {
824 if (authResponseContext_ == nullptr) {
825 LOGE("failed to ShowStartAuthDialog because authResponseContext_ is nullptr");
826 return;
827 }
828 LOGI("DmAuthManager::ShowStartAuthDialog start");
829 authPtr_->StartAuth(authResponseContext_->authToken, shared_from_this());
830 }
831
GetAuthenticationParam(DmAuthParam & authParam)832 int32_t DmAuthManager::GetAuthenticationParam(DmAuthParam &authParam)
833 {
834 return DM_OK;
835 }
836
OnUserOperation(int32_t action,const std::string & params)837 int32_t DmAuthManager::OnUserOperation(int32_t action, const std::string ¶ms)
838 {
839 if (authResponseContext_ == nullptr) {
840 LOGE("Authenticate is not start");
841 return ERR_DM_AUTH_NOT_START;
842 }
843
844 switch (action) {
845 case USER_OPERATION_TYPE_ALLOW_AUTH:
846 case USER_OPERATION_TYPE_CANCEL_AUTH:
847 StartAuthProcess(action);
848 break;
849 case USER_OPERATION_TYPE_AUTH_CONFIRM_TIMEOUT:
850 AuthenticateFinish();
851 break;
852 case USER_OPERATION_TYPE_CANCEL_PINCODE_DISPLAY:
853 break;
854 case USER_OPERATION_TYPE_CANCEL_PINCODE_INPUT:
855 SetReasonAndFinish(ERR_DM_INPUT_PARA_INVALID, AuthState::AUTH_REQUEST_JOIN);
856 break;
857 case USER_OPERATION_TYPE_DONE_PINCODE_INPUT:
858 AddMember(std::stoi(params));
859 break;
860 default:
861 LOGE("this action id not support");
862 break;
863 }
864 return DM_OK;
865 }
866
UserSwitchEventCallback(int32_t userId)867 void DmAuthManager::UserSwitchEventCallback (int32_t userId)
868 {
869 LOGI("switch user event happen and this user groups will be deleted with userId: %d", userId);
870 nlohmann::json jsonObj;
871 jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
872 std::string queryParams = jsonObj.dump();
873 std::vector<GroupInfo> groupList;
874
875 int32_t oldUserId = MultipleUserConnector::GetSwitchOldUserId();
876 MultipleUserConnector::SetSwitchOldUserId(userId);
877 if (!hiChainConnector_->GetGroupInfo(oldUserId, queryParams, groupList)) {
878 LOGE("failed to get device join groups");
879 return;
880 }
881 for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
882 int32_t ret = hiChainConnector_->DeleteGroup(oldUserId, iter->groupId);
883 if (ret != DM_OK) {
884 LOGE("fail to delete group");
885 }
886 }
887
888 if (!hiChainConnector_->GetGroupInfo(userId, queryParams, groupList)) {
889 LOGE("failed to get device join groups");
890 return;
891 }
892 for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
893 int32_t ret = hiChainConnector_->DeleteGroup(userId, iter->groupId);
894 if (ret != DM_OK) {
895 LOGE("fail to delete group");
896 }
897 }
898 }
899
SetPageId(int32_t pageId)900 int32_t DmAuthManager::SetPageId(int32_t pageId)
901 {
902 if (authResponseContext_ == nullptr) {
903 LOGE("Authenticate is not start");
904 return ERR_DM_AUTH_NOT_START;
905 }
906 authResponseContext_->pageId = pageId;
907 return DM_OK;
908 }
909
SetReasonAndFinish(int32_t reason,int32_t state)910 int32_t DmAuthManager::SetReasonAndFinish(int32_t reason, int32_t state)
911 {
912 if (authResponseContext_ == nullptr) {
913 LOGE("Authenticate is not start");
914 return ERR_DM_AUTH_NOT_START;
915 }
916 authResponseContext_->state = state;
917 authResponseContext_->reply = reason;
918 if (authRequestState_ != nullptr && authRequestState_->GetStateType() != AuthState::AUTH_REQUEST_FINISH) {
919 authRequestContext_->reason = reason;
920 authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
921 } else if (authResponseState_ != nullptr && authResponseState_->GetStateType() != AuthState::AUTH_RESPONSE_FINISH) {
922 authResponseState_->TransitionTo(std::make_shared<AuthResponseFinishState>());
923 }
924 return DM_OK;
925 }
926
IsIdenticalAccount()927 bool DmAuthManager::IsIdenticalAccount()
928 {
929 nlohmann::json jsonObj;
930 jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP;
931 std::string queryParams = jsonObj.dump();
932
933 int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
934 if (osAccountUserId < 0) {
935 LOGE("get current process account user id failed");
936 return false;
937 }
938 std::vector<GroupInfo> groupList;
939 if (!hiChainConnector_->GetGroupInfo(osAccountUserId, queryParams, groupList)) {
940 return false;
941 }
942 return true;
943 }
944 } // namespace DistributedHardware
945 } // namespace OHOS