• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         authRequestContext_->reason = ERR_DM_AUTH_OPEN_SESSION_FAILED;
430         if (authRequestState_ != nullptr) {
431             authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
432         }
433     }
434     return DM_OK;
435 }
436 
StartNegotiate(const int32_t & sessionId)437 void DmAuthManager::StartNegotiate(const int32_t &sessionId)
438 {
439     if (authResponseContext_ == nullptr) {
440         LOGE("DmAuthManager::StartNegotiate error, authResponseContext_ is nullptr");
441         return;
442     }
443     LOGI("DmAuthManager::StartNegotiate session id is %d", sessionId);
444     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
445     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
446     authRequestContext_->localDeviceId = localDeviceId;
447     authResponseContext_->localDeviceId = localDeviceId;
448     authResponseContext_->reply = ERR_DM_AUTH_REJECT;
449     authResponseContext_->authType = authRequestContext_->authType;
450     authResponseContext_->deviceId = authRequestContext_->deviceId;
451     authMessageProcessor_->SetResponseContext(authResponseContext_);
452     std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_NEGOTIATE);
453     softbusConnector_->GetSoftbusSession()->SendData(sessionId, message);
454     timer_->StartTimer(std::string(NEGOTIATE_TIMEOUT_TASK), NEGOTIATE_TIMEOUT,
455         [this] (std::string name) {
456             DmAuthManager::HandleAuthenticateTimeout(name);
457         });
458 }
459 
RespNegotiate(const int32_t & sessionId)460 void DmAuthManager::RespNegotiate(const int32_t &sessionId)
461 {
462     if (authResponseContext_ == nullptr) {
463         LOGE("failed to RespNegotiate because authResponseContext_ is nullptr");
464         return;
465     }
466     LOGI("DmAuthManager::EstablishAuthChannel session id is %d", sessionId);
467     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
468     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
469     bool ret = hiChainConnector_->IsDevicesInGroup(authResponseContext_->localDeviceId, localDeviceId);
470     if (ret) {
471         LOGE("DmAuthManager::EstablishAuthChannel device is in group");
472         authResponseContext_->reply = ERR_DM_AUTH_PEER_REJECT;
473     } else {
474         authResponseContext_->reply = ERR_DM_AUTH_REJECT;
475     }
476     authResponseContext_->localDeviceId = localDeviceId;
477 
478     std::shared_ptr<IAuthentication> authentication = authenticationMap_[authResponseContext_->authType];
479     if (authentication == nullptr) {
480         LOGE("DmAuthManager::AuthenticateDevice authType %d not support.", authResponseContext_->authType);
481         authResponseContext_->reply = ERR_DM_UNSUPPORTED_AUTH_TYPE;
482     } else {
483         authPtr_ = authenticationMap_[authResponseContext_->authType];
484     }
485 
486     std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_RESP_NEGOTIATE);
487     nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
488     if (jsonObject.is_discarded()) {
489         softbusConnector_->GetSoftbusSession()->SendData(sessionId, message);
490     }
491 
492     if (IsIdenticalAccount()) {
493         jsonObject[TAG_IDENTICAL_ACCOUNT] = true;
494     }
495     authResponseContext_ = authResponseState_->GetAuthContext();
496     if (jsonObject[TAG_CRYPTO_SUPPORT] == true && authResponseContext_->cryptoSupport) {
497         if (jsonObject[TAG_CRYPTO_NAME] == authResponseContext_->cryptoName &&
498             jsonObject[TAG_CRYPTO_VERSION] == authResponseContext_->cryptoVer) {
499             isCryptoSupport_ = true;
500             softbusConnector_->GetSoftbusSession()->SendData(sessionId, message);
501             return;
502         }
503     }
504     jsonObject[TAG_CRYPTO_SUPPORT] = false;
505     message = jsonObject.dump();
506     softbusConnector_->GetSoftbusSession()->SendData(sessionId, message);
507     timer_->StartTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK), WAIT_REQUEST_TIMEOUT,
508         [this] (std::string name) {
509             DmAuthManager::HandleAuthenticateTimeout(name);
510         });
511 }
512 
SendAuthRequest(const int32_t & sessionId)513 void DmAuthManager::SendAuthRequest(const int32_t &sessionId)
514 {
515     if (authResponseContext_ == nullptr) {
516         LOGE("failed to SendAuthRequest because authResponseContext_ is nullptr");
517         return;
518     }
519     LOGI("DmAuthManager::EstablishAuthChannel session id");
520     timer_->DeleteTimer(std::string(NEGOTIATE_TIMEOUT_TASK));
521     if (authResponseContext_->cryptoSupport) {
522         isCryptoSupport_ = true;
523     }
524 
525     if (authResponseContext_->isIdenticalAccount) { // identicalAccount joinLNN indirectly, no need to verify
526         if (IsIdenticalAccount()) {
527             softbusConnector_->JoinLnn(authResponseContext_->deviceId);
528             authResponseContext_->state = AuthState::AUTH_REQUEST_FINISH;
529             authRequestContext_->reason = DM_OK;
530             authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
531             return;
532         }
533     }
534     if (authResponseContext_->reply == ERR_DM_AUTH_PEER_REJECT) {
535         if (hiChainConnector_->IsDevicesInGroup(authResponseContext_->localDeviceId,
536                                                 authRequestContext_->localDeviceId)) {
537             authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
538             return;
539         }
540     }
541 
542     std::vector<std::string> messageList = authMessageProcessor_->CreateAuthRequestMessage();
543     for (auto msg : messageList) {
544         softbusConnector_->GetSoftbusSession()->SendData(sessionId, msg);
545     }
546     timer_->StartTimer(std::string(CONFIRM_TIMEOUT_TASK), CONFIRM_TIMEOUT,
547         [this] (std::string name) {
548             DmAuthManager::HandleAuthenticateTimeout(name);
549         });
550 }
551 
StartAuthProcess(const int32_t & action)552 int32_t DmAuthManager::StartAuthProcess(const int32_t &action)
553 {
554     if (authResponseContext_ == nullptr) {
555         LOGE("failed to StartAuthProcess because authResponseContext_ is nullptr");
556         return ERR_DM_AUTH_NOT_START;
557     }
558     LOGI("DmAuthManager::StartAuthProcess");
559     authResponseContext_->reply = action;
560     if (authResponseContext_->reply == USER_OPERATION_TYPE_ALLOW_AUTH &&
561         authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_CONFIRM) {
562         authResponseState_->TransitionTo(std::make_shared<AuthResponseGroupState>());
563     } else {
564         authMessageProcessor_->SetResponseContext(authResponseContext_);
565         std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_RESP_AUTH);
566         softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message);
567     }
568     return DM_OK;
569 }
570 
StartRespAuthProcess()571 void DmAuthManager::StartRespAuthProcess()
572 {
573     if (authResponseContext_ == nullptr) {
574         LOGE("failed to StartRespAuthProcess because authResponseContext_ is nullptr");
575         return;
576     }
577     LOGI("DmAuthManager::StartRespAuthProcess sessionId = %d", authResponseContext_->sessionId);
578     timer_->DeleteTimer(std::string(CONFIRM_TIMEOUT_TASK));
579     if (authResponseContext_->reply == USER_OPERATION_TYPE_ALLOW_AUTH) {
580         timer_->StartTimer(std::string(INPUT_TIMEOUT_TASK), INPUT_TIMEOUT,
581             [this] (std::string name) {
582                 DmAuthManager::HandleAuthenticateTimeout(name);
583             });
584         authRequestState_->TransitionTo(std::make_shared<AuthRequestJoinState>());
585     } else {
586         LOGE("do not accept");
587         authResponseContext_->state = AuthState::AUTH_REQUEST_REPLY;
588         authRequestContext_->reason = ERR_DM_AUTH_PEER_REJECT;
589         authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
590     }
591 }
592 
CreateGroup()593 int32_t DmAuthManager::CreateGroup()
594 {
595     if (authResponseContext_ == nullptr) {
596         LOGE("failed to CreateGroup because authResponseContext_ is nullptr");
597         return ERR_DM_FAILED;
598     }
599     LOGI("DmAuthManager::CreateGroup start");
600     authResponseContext_->groupName = GenerateGroupName();
601     authResponseContext_->requestId = GenRandLongLong(MIN_REQUEST_ID, MAX_REQUEST_ID);
602     hiChainConnector_->CreateGroup(authResponseContext_->requestId, authResponseContext_->groupName);
603     return DM_OK;
604 }
605 
AddMember(int32_t pinCode)606 int32_t DmAuthManager::AddMember(int32_t pinCode)
607 {
608     if (authResponseContext_ == nullptr) {
609         LOGE("failed to AddMember because authResponseContext_ is nullptr");
610         return ERR_DM_FAILED;
611     }
612     LOGI("DmAuthManager::AddMember start group id %s", GetAnonyString(authResponseContext_->groupId).c_str());
613     timer_->DeleteTimer(std::string(INPUT_TIMEOUT_TASK));
614     nlohmann::json jsonObject;
615     jsonObject[TAG_GROUP_ID] = authResponseContext_->groupId;
616     jsonObject[TAG_GROUP_NAME] = authResponseContext_->groupName;
617     jsonObject[PIN_CODE_KEY] = pinCode;
618     jsonObject[TAG_REQUEST_ID] = authResponseContext_->requestId;
619     jsonObject[TAG_DEVICE_ID] = authResponseContext_->deviceId;
620     std::string connectInfo = jsonObject.dump();
621     timer_->StartTimer(std::string(ADD_TIMEOUT_TASK), ADD_TIMEOUT,
622         [this] (std::string name) {
623             DmAuthManager::HandleAuthenticateTimeout(name);
624         });
625     int32_t ret = hiChainConnector_->AddMember(authRequestContext_->deviceId, connectInfo);
626     if (ret != 0) {
627         LOGE("DmAuthManager::AddMember failed, ret: %d", ret);
628         return ERR_DM_FAILED;
629     }
630     return DM_OK;
631 }
632 
GetConnectAddr(std::string deviceId)633 std::string DmAuthManager::GetConnectAddr(std::string deviceId)
634 {
635     LOGI("DmAuthManager::GetConnectAddr");
636     std::string connectAddr;
637     if (softbusConnector_->GetConnectAddr(deviceId, connectAddr) == nullptr) {
638         LOGE("DmAuthManager::GetConnectAddr error");
639     }
640     return connectAddr;
641 }
642 
JoinNetwork()643 int32_t DmAuthManager::JoinNetwork()
644 {
645     if (authResponseContext_ == nullptr) {
646         LOGE("failed to JoinNeWork because authResponseContext_ is nullptr");
647         return ERR_DM_FAILED;
648     }
649     LOGI("DmAuthManager JoinNetwork start");
650     timer_->DeleteTimer(std::string(AUTHENTICATE_TIMEOUT_TASK));
651     authResponseContext_->state = AuthState::AUTH_REQUEST_FINISH;
652     authRequestContext_->reason = DM_OK;
653     authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
654     return DM_OK;
655 }
656 
AuthenticateFinish()657 void DmAuthManager::AuthenticateFinish()
658 {
659     if (authResponseContext_ == nullptr) {
660         LOGE("failed to AuthenticateFinish because authResponseContext_ is nullptr");
661         return;
662     }
663     LOGI("DmAuthManager::AuthenticateFinish start");
664     if (authResponseState_ != nullptr) {
665         if (authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_FINISH && authPtr_ != nullptr) {
666             UpdateInputDialogDisplay(false);
667         }
668         if (isFinishOfLocal_) {
669             authMessageProcessor_->SetResponseContext(authResponseContext_);
670             std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_REQ_AUTH_TERMINATE);
671             softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message);
672         }
673         timer_->DeleteAll();
674         isFinishOfLocal_ = true;
675         authResponseContext_ = nullptr;
676         authResponseState_ = nullptr;
677         authMessageProcessor_ = nullptr;
678         authPtr_ = nullptr;
679     } else if (authRequestState_ != nullptr) {
680         if (isFinishOfLocal_) {
681             authMessageProcessor_->SetResponseContext(authResponseContext_);
682             std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_REQ_AUTH_TERMINATE);
683             softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message);
684         } else {
685             authRequestContext_->reason = authResponseContext_->reply;
686         }
687         if ((authResponseContext_->state == AuthState::AUTH_REQUEST_JOIN ||
688             authResponseContext_->state == AuthState::AUTH_REQUEST_FINISH) && authPtr_ != nullptr) {
689             UpdateInputDialogDisplay(false);
690         }
691         listener_->OnAuthResult(authRequestContext_->hostPkgName, authRequestContext_->deviceId,
692                                 authRequestContext_->token, authResponseContext_->state, authRequestContext_->reason);
693         softbusConnector_->GetSoftbusSession()->CloseAuthSession(authRequestContext_->sessionId);
694         timer_->DeleteAll();
695         isFinishOfLocal_ = true;
696         authRequestContext_ = nullptr;
697         authResponseContext_ = nullptr;
698         authRequestState_ = nullptr;
699         authMessageProcessor_ = nullptr;
700         authPtr_ = nullptr;
701         authTimes_ = 0;
702     }
703     LOGI("DmAuthManager::AuthenticateFinish complete");
704 }
705 
CancelDisplay()706 void DmAuthManager::CancelDisplay()
707 {
708     LOGI("DmAuthManager::CancelDisplay start");
709     nlohmann::json jsonObj;
710     jsonObj[CANCEL_DISPLAY_KEY] = CANCEL_PIN_CODE_DISPLAY;
711     std::string paramJson = jsonObj.dump();
712     std::string pkgName = "com.ohos.devicemanagerui";
713     listener_->OnUiCall(pkgName, paramJson);
714 }
715 
UpdateInputDialogDisplay(bool isShow)716 void DmAuthManager::UpdateInputDialogDisplay(bool isShow)
717 {
718     LOGI("DmAuthManager::UpdateInputDialogDisplay start");
719     nlohmann::json jsonObj;
720     jsonObj[VERIFY_FAILED] = isShow;
721     jsonObj.dump();
722     std::string paramJson = jsonObj.dump();
723     std::string pkgName = "com.ohos.devicemanagerui";
724     listener_->OnUiCall(pkgName, paramJson);
725 }
726 
GeneratePincode()727 int32_t DmAuthManager::GeneratePincode()
728 {
729     return GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE);
730 }
731 
GenerateGroupName()732 std::string DmAuthManager::GenerateGroupName()
733 {
734     if (authResponseContext_ == nullptr) {
735         LOGE("failed to GenerateGroupName because authResponseContext_ is nullptr.");
736         return "";
737     }
738     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
739     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
740     std::string sLocalDeviceId = localDeviceId;
741     uint32_t interceptLength = sLocalDeviceId.size() / DEVICE_ID_HALF;
742     std::string groupName = authResponseContext_->targetPkgName + sLocalDeviceId.substr(0, interceptLength)
743                             + authResponseContext_->localDeviceId.substr(0, interceptLength);
744     return groupName;
745 }
746 
GetIsCryptoSupport()747 bool DmAuthManager::GetIsCryptoSupport()
748 {
749     if (authResponseState_ == nullptr) {
750         return false;
751     }
752     if (authRequestState_ == nullptr) {
753         if (authResponseState_->GetStateType() == AuthState::AUTH_REQUEST_NEGOTIATE_DONE) {
754             return false;
755         }
756     } else {
757         if (authRequestState_->GetStateType() == AuthState::AUTH_REQUEST_NEGOTIATE ||
758             authRequestState_->GetStateType() == AuthState::AUTH_REQUEST_NEGOTIATE_DONE) {
759             return false;
760         }
761     }
762 
763     return isCryptoSupport_;
764 }
765 
SetAuthRequestState(std::shared_ptr<AuthRequestState> authRequestState)766 int32_t DmAuthManager::SetAuthRequestState(std::shared_ptr<AuthRequestState> authRequestState)
767 {
768     authRequestState_ = authRequestState;
769     return DM_OK;
770 }
771 
SetAuthResponseState(std::shared_ptr<AuthResponseState> authResponseState)772 int32_t DmAuthManager::SetAuthResponseState(std::shared_ptr<AuthResponseState> authResponseState)
773 {
774     authResponseState_ = authResponseState;
775     return DM_OK;
776 }
777 
GetPinCode()778 int32_t DmAuthManager::GetPinCode()
779 {
780     if (authResponseContext_ == nullptr) {
781         LOGE("failed to GetPinCode because authResponseContext_ is nullptr");
782         return ERR_DM_AUTH_NOT_START;
783     }
784     LOGI("ShowConfigDialog start add member pin code.");
785     return authResponseContext_->code;
786 }
787 
ShowConfigDialog()788 void DmAuthManager::ShowConfigDialog()
789 {
790     if (authResponseContext_ == nullptr) {
791         LOGE("failed to ShowConfigDialog because authResponseContext_ is nullptr");
792         return;
793     }
794     LOGI("ShowConfigDialog start");
795     dmAbilityMgr_ = std::make_shared<DmAbilityManager>();
796     nlohmann::json jsonObj;
797     jsonObj[TAG_AUTH_TYPE] = AUTH_TYPE_PIN;
798     jsonObj[TAG_TOKEN] = authResponseContext_->token;
799     jsonObj[TARGET_PKG_NAME_KEY] = authResponseContext_->targetPkgName;
800     jsonObj.dump();
801     const std::string params = jsonObj.dump();
802     std::shared_ptr<ShowConfirm> showConfirm_ = std::make_shared<ShowConfirm>();
803     showConfirm_->ShowConfirmDialog(params, shared_from_this(), dmAbilityMgr_);
804     LOGI("ShowConfigDialog end");
805 }
806 
ShowAuthInfoDialog()807 void DmAuthManager::ShowAuthInfoDialog()
808 {
809     if (authResponseContext_ == nullptr) {
810         LOGE("failed to ShowAuthInfoDialog because authResponseContext_ is nullptr");
811         return;
812     }
813     LOGI("DmAuthManager::ShowAuthInfoDialog start %d", authResponseContext_->code);
814     nlohmann::json jsonObj;
815     jsonObj[PIN_CODE_KEY] = authResponseContext_->code;
816     std::string authParam = jsonObj.dump();
817     authPtr_->ShowAuthInfo(authParam, shared_from_this());
818 }
819 
ShowStartAuthDialog()820 void DmAuthManager::ShowStartAuthDialog()
821 {
822     if (authResponseContext_ == nullptr) {
823         LOGE("failed to ShowStartAuthDialog because authResponseContext_ is nullptr");
824         return;
825     }
826     LOGI("DmAuthManager::ShowStartAuthDialog start");
827     authPtr_->StartAuth(authResponseContext_->authToken, shared_from_this());
828 }
829 
GetAuthenticationParam(DmAuthParam & authParam)830 int32_t DmAuthManager::GetAuthenticationParam(DmAuthParam &authParam)
831 {
832     return DM_OK;
833 }
834 
OnUserOperation(int32_t action,const std::string & params)835 int32_t DmAuthManager::OnUserOperation(int32_t action, const std::string &params)
836 {
837     if (authResponseContext_ == nullptr) {
838         LOGE("Authenticate is not start");
839         return ERR_DM_AUTH_NOT_START;
840     }
841 
842     switch (action) {
843         case USER_OPERATION_TYPE_ALLOW_AUTH:
844         case USER_OPERATION_TYPE_CANCEL_AUTH:
845             StartAuthProcess(action);
846             break;
847         case USER_OPERATION_TYPE_AUTH_CONFIRM_TIMEOUT:
848             AuthenticateFinish();
849             break;
850         case USER_OPERATION_TYPE_CANCEL_PINCODE_DISPLAY:
851             break;
852         case USER_OPERATION_TYPE_CANCEL_PINCODE_INPUT:
853             SetReasonAndFinish(ERR_DM_INPUT_PARA_INVALID, AuthState::AUTH_REQUEST_JOIN);
854             break;
855         case USER_OPERATION_TYPE_DONE_PINCODE_INPUT:
856             AddMember(std::stoi(params));
857             break;
858         default:
859             LOGE("this action id not support");
860             break;
861     }
862     return DM_OK;
863 }
864 
UserSwitchEventCallback(int32_t userId)865 void DmAuthManager::UserSwitchEventCallback (int32_t userId)
866 {
867     LOGI("switch user event happen and this user groups will be deleted with userId: %d", userId);
868     nlohmann::json jsonObj;
869     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
870     std::string queryParams = jsonObj.dump();
871     std::vector<GroupInfo> groupList;
872 
873     int32_t oldUserId = MultipleUserConnector::GetSwitchOldUserId();
874     MultipleUserConnector::SetSwitchOldUserId(userId);
875     if (!hiChainConnector_->GetGroupInfo(oldUserId, queryParams, groupList)) {
876         LOGE("failed to get device join groups");
877         return;
878     }
879     for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
880         int32_t ret = hiChainConnector_->DeleteGroup(oldUserId, iter->groupId);
881         if (ret != DM_OK) {
882             LOGE("fail to delete group");
883         }
884     }
885 
886     if (!hiChainConnector_->GetGroupInfo(userId, queryParams, groupList)) {
887         LOGE("failed to get device join groups");
888         return;
889     }
890     for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
891         int32_t ret = hiChainConnector_->DeleteGroup(userId, iter->groupId);
892         if (ret != DM_OK) {
893             LOGE("fail to delete group");
894         }
895     }
896 }
897 
SetPageId(int32_t pageId)898 int32_t DmAuthManager::SetPageId(int32_t pageId)
899 {
900     if (authResponseContext_ == nullptr) {
901         LOGE("Authenticate is not start");
902         return ERR_DM_AUTH_NOT_START;
903     }
904     authResponseContext_->pageId = pageId;
905     return DM_OK;
906 }
907 
SetReasonAndFinish(int32_t reason,int32_t state)908 int32_t DmAuthManager::SetReasonAndFinish(int32_t reason, int32_t state)
909 {
910     if (authResponseContext_ == nullptr) {
911         LOGE("Authenticate is not start");
912         return ERR_DM_AUTH_NOT_START;
913     }
914     authResponseContext_->state = state;
915     authResponseContext_->reply = reason;
916     if (authRequestState_ != nullptr && authRequestState_->GetStateType() != AuthState::AUTH_REQUEST_FINISH) {
917         authRequestContext_->reason = reason;
918         authRequestState_->TransitionTo(std::make_shared<AuthRequestFinishState>());
919     } else if (authResponseState_ != nullptr && authResponseState_->GetStateType() != AuthState::AUTH_RESPONSE_FINISH) {
920         authResponseState_->TransitionTo(std::make_shared<AuthResponseFinishState>());
921     }
922     return DM_OK;
923 }
924 
IsIdenticalAccount()925 bool DmAuthManager::IsIdenticalAccount()
926 {
927     nlohmann::json jsonObj;
928     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP;
929     std::string queryParams = jsonObj.dump();
930 
931     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
932     if (osAccountUserId < 0) {
933         LOGE("get current process account user id failed");
934         return false;
935     }
936     std::vector<GroupInfo> groupList;
937     if (!hiChainConnector_->GetGroupInfo(osAccountUserId, queryParams, groupList)) {
938         return false;
939     }
940     return true;
941 }
942 } // namespace DistributedHardware
943 } // namespace OHOS