• 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         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 &params)
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