1 /*
2 * Copyright (C) 2023 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 "compatible_auth_sub_session_common.h"
17
18 #include "account_auth_plugin_proxy.h"
19 #include "account_module_defines.h"
20 #include "account_related_group_auth.h"
21 #include "compatible_auth_sub_session_util.h"
22 #include "data_manager.h"
23 #include "dev_auth_module_manager.h"
24 #include "group_auth_data_operation.h"
25 #include "hc_log.h"
26 #include "hc_time.h"
27 #include "hc_types.h"
28 #include "hitrace_adapter.h"
29 #include "performance_dumper.h"
30
31 #define MIN_PROTOCOL_VERSION "1.0.0"
32 IMPLEMENT_HC_VECTOR(ParamsVecForAuth, void *, 1)
33
34 static void GetAccountRelatedCandidateGroups(int32_t osAccountId, const CJson *param, bool isDeviceLevel, bool isClient,
35 GroupEntryVec *vec)
36 {
37 QueryGroupParams queryParams = InitQueryGroupParams();
38 if (!isDeviceLevel || !isClient) {
39 queryParams.groupVisibility = GROUP_VISIBILITY_PUBLIC;
40 }
41 BaseGroupAuth *groupAuth = GetGroupAuth(ACCOUNT_RELATED_GROUP_AUTH_TYPE);
42 if (groupAuth == NULL) {
43 LOGE("Account related group auth object is null!");
44 return;
45 }
46 ((AccountRelatedGroupAuth *)groupAuth)->getAccountCandidateGroup(osAccountId, param, &queryParams, vec);
47 if (vec->size(vec) != 0) {
48 return;
49 }
50 LOGI("Account related groups not found!");
51 if (HasAccountAuthPlugin() != HC_SUCCESS) {
52 return;
53 }
54 CJson *input = CreateJson();
55 if (input == NULL) {
56 return;
57 }
58 CJson *output = CreateJson();
59 if (output == NULL) {
60 FreeJson(input);
61 return;
62 }
63 int32_t ret = ExcuteCredMgrCmd(osAccountId, QUERY_SELF_CREDENTIAL_INFO, input, output);
64 if (ret != HC_SUCCESS) {
65 LOGE("Account cred is empty.");
66 }
67 FreeJson(input);
68 FreeJson(output);
69 }
70
GetAccountUnrelatedCandidateGroups(int32_t osAccountId,bool isDeviceLevel,bool isClient,GroupEntryVec * vec)71 static void GetAccountUnrelatedCandidateGroups(int32_t osAccountId, bool isDeviceLevel, bool isClient,
72 GroupEntryVec *vec)
73 {
74 QueryGroupParams queryParams = InitQueryGroupParams();
75 if (!isDeviceLevel || !isClient) {
76 queryParams.groupVisibility = GROUP_VISIBILITY_PUBLIC;
77 }
78 queryParams.groupType = PEER_TO_PEER_GROUP;
79 if (QueryGroups(osAccountId, &queryParams, vec) != HC_SUCCESS) {
80 LOGE("Failed to query p2p groups!");
81 return;
82 }
83 if (vec->size(vec) == 0) {
84 LOGI("p2p groups not found!");
85 }
86 }
87
GetCandidateGroups(int32_t osAccountId,const CJson * param,GroupEntryVec * vec)88 static void GetCandidateGroups(int32_t osAccountId, const CJson *param, GroupEntryVec *vec)
89 {
90 bool isDeviceLevel = false;
91 bool isClient = true;
92 (void)GetBoolFromJson(param, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
93 if (GetBoolFromJson(param, FIELD_IS_CLIENT, &isClient) != HC_SUCCESS) {
94 LOGE("Failed to get isClient!");
95 return;
96 }
97 if (isDeviceLevel && isClient) {
98 LOGI("Try to get device-level candidate groups for auth.");
99 }
100 GetAccountRelatedCandidateGroups(osAccountId, param, isDeviceLevel, isClient, vec);
101 GetAccountUnrelatedCandidateGroups(osAccountId, isDeviceLevel, isClient, vec);
102 }
103
GetGroupInfoByGroupId(int32_t osAccountId,const char * groupId,GroupEntryVec * groupEntryVec)104 static void GetGroupInfoByGroupId(int32_t osAccountId, const char *groupId,
105 GroupEntryVec *groupEntryVec)
106 {
107 QueryGroupParams queryParams = InitQueryGroupParams();
108 queryParams.groupId = groupId;
109 if (QueryGroups(osAccountId, &queryParams, groupEntryVec) != HC_SUCCESS) {
110 LOGE("Failed to query groups for groupId: %s!", groupId);
111 }
112 }
113
AddGeneralParams(const char * groupId,int32_t groupType,const TrustedDeviceEntry * localAuthInfo,CJson * paramsData)114 static int32_t AddGeneralParams(const char *groupId, int32_t groupType, const TrustedDeviceEntry *localAuthInfo,
115 CJson *paramsData)
116 {
117 if (AddStringToJson(paramsData, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
118 LOGE("Failed to add groupId for client auth!");
119 return HC_ERR_JSON_ADD;
120 }
121 int32_t authForm = GroupTypeToAuthForm(groupType);
122 if (AddIntToJson(paramsData, FIELD_AUTH_FORM, authForm) != HC_SUCCESS) {
123 LOGE("Failed to add authFrom for client auth!");
124 return HC_ERR_JSON_ADD;
125 }
126 const char *serviceType = StringGet(&(localAuthInfo->serviceType));
127 if ((groupType == COMPATIBLE_GROUP) && (serviceType != NULL)) {
128 if (AddStringToJson(paramsData, FIELD_SERVICE_TYPE, serviceType) != HC_SUCCESS) {
129 LOGE("Failed to add serviceType for client compatible group auth!");
130 return HC_ERR_JSON_ADD;
131 }
132 } else {
133 if (AddStringToJson(paramsData, FIELD_SERVICE_TYPE, groupId) != HC_SUCCESS) {
134 LOGE("Failed to add serviceType with groupId for client auth!");
135 return HC_ERR_JSON_ADD;
136 }
137 }
138 return HC_SUCCESS;
139 }
140
ExtractAndAddParams(int32_t osAccountId,const char * groupId,const TrustedGroupEntry * groupInfo,CJson * paramsData)141 static int32_t ExtractAndAddParams(int32_t osAccountId, const char *groupId,
142 const TrustedGroupEntry *groupInfo, CJson *paramsData)
143 {
144 TrustedDeviceEntry *localAuthInfo = CreateDeviceEntry();
145 if (localAuthInfo == NULL) {
146 LOGE("Failed to allocate memory for localAuthInfo!");
147 return HC_ERR_ALLOC_MEMORY;
148 }
149 int32_t groupType = groupInfo->type;
150 int32_t authForm = GroupTypeToAuthForm(groupType);
151 int32_t res = GaGetLocalDeviceInfo(osAccountId, groupId, localAuthInfo);
152 if (res != HC_SUCCESS) {
153 DestroyDeviceEntry(localAuthInfo);
154 return res;
155 }
156 res = AddGeneralParams(groupId, groupType, localAuthInfo, paramsData);
157 if (res != HC_SUCCESS) {
158 DestroyDeviceEntry(localAuthInfo);
159 return res;
160 }
161 BaseGroupAuth *groupAuth = GetGroupAuth(GetAuthType(authForm));
162 if (groupAuth == NULL) {
163 LOGE("Failed to get group auth handle!");
164 DestroyDeviceEntry(localAuthInfo);
165 return HC_ERR_NULL_PTR;
166 }
167 res = groupAuth->fillDeviceAuthInfo(osAccountId, groupInfo, localAuthInfo, paramsData);
168 DestroyDeviceEntry(localAuthInfo);
169 if (res != HC_SUCCESS) {
170 LOGE("Failed to fill device auth info!");
171 }
172 return res;
173 }
174
AddUpgradeFlagToParams(CJson * paramsData,int32_t osAccountId,const char * peerUdid,const char * peerAuthId,const char * groupId)175 static int32_t AddUpgradeFlagToParams(CJson *paramsData, int32_t osAccountId, const char *peerUdid,
176 const char *peerAuthId, const char *groupId)
177 {
178 TrustedDeviceEntry *peerDeviceEntry = CreateDeviceEntry();
179 if (peerDeviceEntry == NULL) {
180 LOGE("Failed to allocate memory for deviceEntry!");
181 return HC_ERR_ALLOC_MEMORY;
182 }
183 int32_t res;
184 if (peerUdid != NULL) {
185 res = GaGetTrustedDeviceEntryById(osAccountId, peerUdid, true, groupId, peerDeviceEntry);
186 } else if (peerAuthId != NULL) {
187 res = GaGetTrustedDeviceEntryById(osAccountId, peerAuthId, false, groupId, peerDeviceEntry);
188 } else {
189 LOGE("Both the input udid and authId is null!");
190 res = HC_ERROR;
191 }
192 if (res != HC_SUCCESS) {
193 LOGE("Failed to get peer device entry!");
194 DestroyDeviceEntry(peerDeviceEntry);
195 return res;
196 }
197 bool isPeerFromUpgrade = peerDeviceEntry->upgradeFlag == 1;
198 DestroyDeviceEntry(peerDeviceEntry);
199 if (AddBoolToJson(paramsData, FIELD_IS_PEER_FROM_UPGRADE, isPeerFromUpgrade) != HC_SUCCESS) {
200 LOGE("Failed to add peer upgrade flag!");
201 return HC_ERR_JSON_ADD;
202 }
203 TrustedDeviceEntry *selfDeviceEntry = CreateDeviceEntry();
204 if (selfDeviceEntry == NULL) {
205 LOGE("Failed to allocate memory for selfDeviceEntry!");
206 return HC_ERR_ALLOC_MEMORY;
207 }
208 res = GaGetLocalDeviceInfo(osAccountId, groupId, selfDeviceEntry);
209 if (res != HC_SUCCESS) {
210 DestroyDeviceEntry(selfDeviceEntry);
211 return res;
212 }
213 bool isSelfFromUpgrade = selfDeviceEntry->upgradeFlag == 1;
214 DestroyDeviceEntry(selfDeviceEntry);
215 if (AddBoolToJson(paramsData, FIELD_IS_SELF_FROM_UPGRADE, isSelfFromUpgrade) != HC_SUCCESS) {
216 LOGE("Failed to add self upgrade flag!");
217 return HC_ERR_JSON_ADD;
218 }
219 return HC_SUCCESS;
220 }
221
FillAuthParams(int32_t osAccountId,const CJson * param,const GroupEntryVec * vec,ParamsVecForAuth * paramsVec)222 static int32_t FillAuthParams(int32_t osAccountId, const CJson *param,
223 const GroupEntryVec *vec, ParamsVecForAuth *paramsVec)
224 {
225 const char *pkgName = GetStringFromJson(param, FIELD_SERVICE_PKG_NAME);
226 if (pkgName == NULL) {
227 LOGE("Pkg name is null, can't extract params from db!");
228 return HC_ERR_NULL_PTR;
229 }
230 const char *peerUdid = GetStringFromJson(param, FIELD_PEER_CONN_DEVICE_ID);
231 const char *peerAuthId = GetStringFromJson(param, FIELD_PEER_ID_FROM_REQUEST);
232 if (peerAuthId == NULL) {
233 peerAuthId = GetStringFromJson(param, FIELD_PEER_AUTH_ID);
234 }
235 uint32_t index;
236 TrustedGroupEntry **ptr = NULL;
237 FOR_EACH_HC_VECTOR(*vec, index, ptr) {
238 const TrustedGroupEntry *groupInfo = (TrustedGroupEntry *)(*ptr);
239 const char *groupId = StringGet(&(groupInfo->id));
240 if (groupId == NULL) {
241 continue;
242 }
243 if (!GaIsGroupAccessible(osAccountId, groupId, pkgName)) {
244 continue;
245 }
246 if (!GaIsDeviceInGroup(groupInfo->type, osAccountId, peerUdid, peerAuthId, groupId)) {
247 continue;
248 }
249 CJson *paramsData = DuplicateJson(param);
250 if (paramsData == NULL) {
251 LOGE("Failed to duplicate auth param data!");
252 return HC_ERR_JSON_FAIL;
253 }
254 if (groupInfo->type == PEER_TO_PEER_GROUP &&
255 AddUpgradeFlagToParams(paramsData, osAccountId, peerUdid, peerAuthId, groupId) != HC_SUCCESS) {
256 LOGE("Failed to add upgrade flag!");
257 FreeJson(paramsData);
258 continue;
259 }
260 if (ExtractAndAddParams(osAccountId, groupId, groupInfo, paramsData) != HC_SUCCESS) {
261 LOGE("Failed to extract and add param!");
262 FreeJson(paramsData);
263 continue;
264 }
265 PRINT_SENSITIVE_DATA("GroupId", groupId);
266 LOGI("Group type is %d.", groupInfo->type);
267 paramsVec->pushBack(paramsVec, (const void **)¶msData);
268 }
269 LOGI("The candidate group size is: %u", paramsVec->size(paramsVec));
270 return HC_SUCCESS;
271 }
272
GetCandidateAuthInfo(int32_t osAccountId,const char * groupId,const CJson * param,ParamsVecForAuth * authParamsVec)273 static int32_t GetCandidateAuthInfo(int32_t osAccountId, const char *groupId,
274 const CJson *param, ParamsVecForAuth *authParamsVec)
275 {
276 GroupEntryVec vec = CreateGroupEntryVec();
277 if (groupId == NULL) {
278 LOGI("No groupId specified, extract group info without groupId.");
279 GetCandidateGroups(osAccountId, param, &vec);
280 } else {
281 LOGI("GroupId specified, extract group info with the groupId.");
282 GetGroupInfoByGroupId(osAccountId, groupId, &vec);
283 }
284 if (vec.size(&vec) == 0) {
285 LOGW("No satisfied candidate group!");
286 ClearGroupEntryVec(&vec);
287 return HC_ERR_NO_CANDIDATE_GROUP;
288 }
289 int32_t res = FillAuthParams(osAccountId, param, &vec, authParamsVec);
290 ClearGroupEntryVec(&vec);
291 return res;
292 }
293
AddInfoToErrorData(CJson * sendToPeer,const CJson * authParam)294 static int32_t AddInfoToErrorData(CJson *sendToPeer, const CJson *authParam)
295 {
296 int32_t authForm = AUTH_FORM_INVALID_TYPE;
297 if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
298 LOGE("Failed to get authForm from authParam!");
299 return HC_ERR_JSON_GET;
300 }
301 if (AddIntToJson(sendToPeer, FIELD_AUTH_FORM, authForm) != HC_SUCCESS) {
302 LOGE("Failed to add authForm for peer!");
303 return HC_ERR_JSON_ADD;
304 }
305 int32_t step = ERR_MSG;
306 if (GetIntFromJson(sendToPeer, FIELD_STEP, &step) != HC_SUCCESS) {
307 LOGI("Not has step in json, use default step value!");
308 }
309 if ((authForm == AUTH_FORM_IDENTICAL_ACCOUNT) && (AddIntToJson(sendToPeer, FIELD_STEP, step) != HC_SUCCESS)) {
310 LOGE("Failed to add step for peer!");
311 return HC_ERR_JSON_ADD;
312 }
313 return HC_SUCCESS;
314 }
315
AddVersionMsgToError(CJson * errorToPeer)316 static int32_t AddVersionMsgToError(CJson *errorToPeer)
317 {
318 CJson *version = CreateJson();
319 if (version == NULL) {
320 LOGE("Failed to create json for version!");
321 return HC_ERR_JSON_CREATE;
322 }
323 CJson *payload = CreateJson();
324 if (payload == NULL) {
325 LOGE("Failed to create json for payload!");
326 FreeJson(version);
327 return HC_ERR_JSON_CREATE;
328 }
329 int32_t res = HC_SUCCESS;
330 do {
331 if (AddStringToJson(version, FIELD_MIN_VERSION, MIN_PROTOCOL_VERSION) != HC_SUCCESS) {
332 LOGE("Failed to add min version to json!");
333 res = HC_ERR_JSON_ADD;
334 break;
335 }
336 if (AddStringToJson(version, FIELD_CURRENT_VERSION, MIN_PROTOCOL_VERSION) != HC_SUCCESS) {
337 LOGE("Failed to add max version to json!");
338 res = HC_ERR_JSON_ADD;
339 break;
340 }
341 if (AddObjToJson(payload, FIELD_VERSION, version) != HC_SUCCESS) {
342 LOGE("Add version object to errorToPeer failed.");
343 res = HC_ERR_JSON_ADD;
344 break;
345 }
346 if (AddIntToJson(payload, FIELD_ERROR_CODE, -1) != HC_SUCCESS) {
347 LOGE("Failed to add errorCode for peer!");
348 res = HC_ERR_JSON_ADD;
349 break;
350 }
351 if (AddObjToJson(errorToPeer, FIELD_PAYLOAD, payload) != HC_SUCCESS) {
352 LOGE("Failed to add error data!");
353 res = HC_ERR_JSON_ADD;
354 break;
355 }
356 } while (0);
357 FreeJson(version);
358 FreeJson(payload);
359 return res;
360 }
361
PrepareErrorMsgToPeer(const CJson * authParam,CJson * errorToPeer)362 static int32_t PrepareErrorMsgToPeer(const CJson *authParam, CJson *errorToPeer)
363 {
364 int32_t res = AddInfoToErrorData(errorToPeer, authParam);
365 if (res != HC_SUCCESS) {
366 LOGE("Failed to add info to error data!");
367 return res;
368 }
369 if (AddIntToJson(errorToPeer, FIELD_GROUP_ERROR_MSG, GROUP_ERR_MSG) != HC_SUCCESS) {
370 LOGE("Failed to add groupErrorMsg for peer!");
371 return HC_ERR_JSON_ADD;
372 }
373 if (AddIntToJson(errorToPeer, FIELD_MESSAGE, GROUP_ERR_MSG) != HC_SUCCESS) {
374 LOGE("Failed to add message for peer!");
375 return HC_ERR_JSON_ADD;
376 }
377 return AddVersionMsgToError(errorToPeer);
378 }
379
ReturnErrorToPeerBySession(const CJson * authParam,const DeviceAuthCallback * callback)380 static int32_t ReturnErrorToPeerBySession(const CJson *authParam, const DeviceAuthCallback *callback)
381 {
382 int64_t requestId = 0;
383 if (GetInt64FromJson(authParam, FIELD_REQUEST_ID, &requestId) != HC_SUCCESS) {
384 LOGE("Failed to get request ID!");
385 return HC_ERR_JSON_GET;
386 }
387 CJson *errorToPeer = CreateJson();
388 if (errorToPeer == NULL) {
389 LOGE("Failed to allocate memory for errorToPeer!");
390 return HC_ERR_ALLOC_MEMORY;
391 }
392 int32_t res = PrepareErrorMsgToPeer(authParam, errorToPeer);
393 if (res != HC_SUCCESS) {
394 FreeJson(errorToPeer);
395 return res;
396 }
397 char *errorToPeerStr = PackJsonToString(errorToPeer);
398 FreeJson(errorToPeer);
399 if (errorToPeerStr == NULL) {
400 LOGE("Failed to pack errorToPeer to string!");
401 return HC_ERR_ALLOC_MEMORY;
402 }
403 if ((callback == NULL) || (callback->onTransmit == NULL)) {
404 LOGE("The callback of onTransmit is null!");
405 FreeJsonString(errorToPeerStr);
406 return HC_ERR_NULL_PTR;
407 }
408 LOGD("Begin transmit error msg to peer by session!");
409 if (!callback->onTransmit(requestId, (uint8_t *)errorToPeerStr, HcStrlen(errorToPeerStr) + 1)) {
410 LOGE("Failed to transmit error msg by session!");
411 FreeJsonString(errorToPeerStr);
412 return HC_ERR_TRANSMIT_FAIL;
413 }
414 LOGD("End transmit error msg to peer by session!");
415 FreeJsonString(errorToPeerStr);
416 return HC_SUCCESS;
417 }
418
ReturnErrorToPeerByTask(CJson * sendToPeer,const CJson * authParam,const DeviceAuthCallback * callback)419 static int32_t ReturnErrorToPeerByTask(CJson *sendToPeer, const CJson *authParam,
420 const DeviceAuthCallback *callback)
421 {
422 int64_t requestId = 0;
423 if (GetInt64FromJson(authParam, FIELD_REQUEST_ID, &requestId) != HC_SUCCESS) {
424 LOGE("Failed to get request id!");
425 return HC_ERR_JSON_GET;
426 }
427 int32_t res = AddInfoToErrorData(sendToPeer, authParam);
428 if (res != HC_SUCCESS) {
429 LOGE("Failed to add info to error data!");
430 return res;
431 }
432 char *sendToPeerStr = PackJsonToString(sendToPeer);
433 if (sendToPeerStr == NULL) {
434 LOGE("Failed to pack json to string!");
435 return HC_ERR_ALLOC_MEMORY;
436 }
437 if ((callback == NULL) || (callback->onTransmit == NULL)) {
438 LOGE("The callback of onTransmit is null!");
439 FreeJsonString(sendToPeerStr);
440 return HC_ERR_NULL_PTR;
441 }
442 LOGD("Begin transmit error msg to peer by task!");
443 if (!callback->onTransmit(requestId, (uint8_t *)sendToPeerStr, HcStrlen(sendToPeerStr) + 1)) {
444 LOGE("Failed to transmit error msg by task!");
445 FreeJsonString(sendToPeerStr);
446 return HC_ERR_TRANSMIT_FAIL;
447 }
448 LOGD("End transmit error msg to peer by task!");
449 FreeJsonString(sendToPeerStr);
450 return HC_SUCCESS;
451 }
452
ReturnTransmitData(const CompatibleAuthSubSession * session,CJson * out,bool isClientFirst)453 static int32_t ReturnTransmitData(const CompatibleAuthSubSession *session, CJson *out, bool isClientFirst)
454 {
455 CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
456 if (sendToPeer == NULL) {
457 LOGI("The transmit data to peer is null!");
458 return HC_ERR_JSON_GET;
459 }
460 CJson *authParam = (session->paramsList).get(&(session->paramsList), session->currentIndex);
461 if (authParam == NULL) {
462 LOGE("The json data in session is null!");
463 return HC_ERR_NULL_PTR;
464 }
465 int64_t requestId = 0;
466 if (GetInt64FromJson(authParam, FIELD_REQUEST_ID, &requestId) != HC_SUCCESS) {
467 LOGE("Failed to get request id!");
468 return HC_ERR_JSON_GET;
469 }
470
471 int32_t ret = AddGroupAuthTransmitData(session, isClientFirst, sendToPeer);
472 if (ret != HC_SUCCESS) {
473 LOGE("Failed to add extra data!");
474 return ret;
475 }
476 char *outStr = PackJsonToString(sendToPeer);
477 if (outStr == NULL) {
478 LOGE("Failed to pack outStr for onTransmit!");
479 return HC_ERR_ALLOC_MEMORY;
480 }
481
482 int32_t authForm = AUTH_FORM_INVALID_TYPE;
483 if (GetIntFromJson(sendToPeer, FIELD_AUTH_FORM, &authForm) == HC_SUCCESS) {
484 LOGI("AuthForm is %d.", authForm);
485 }
486
487 const DeviceAuthCallback *callback = session->base.callback;
488 if ((callback == NULL) || (callback->onTransmit == NULL)) {
489 LOGE("The callback for transmit is null!");
490 FreeJsonString(outStr);
491 return HC_ERR_NULL_PTR;
492 }
493 LOGI("Start to transmit data to peer for auth!");
494 DEV_AUTH_START_TRACE(TRACE_TAG_SEND_DATA);
495 UPDATE_PERFORM_DATA_BY_SELF_INDEX(requestId, HcGetCurTimeInMillis());
496 if (!callback->onTransmit(requestId, (uint8_t *)outStr, HcStrlen(outStr) + 1)) {
497 LOGE("Failed to transmit data to peer!");
498 FreeJsonString(outStr);
499 return HC_ERR_TRANSMIT_FAIL;
500 }
501 DEV_AUTH_FINISH_TRACE();
502 LOGI("End transmit data to peer for auth!");
503 FreeJsonString(outStr);
504 return HC_SUCCESS;
505 }
506
ReturnFinishData(const CompatibleAuthSubSession * session,const CJson * out)507 static void ReturnFinishData(const CompatibleAuthSubSession *session, const CJson *out)
508 {
509 ParamsVecForAuth list = session->paramsList;
510 const CJson *authParam = list.get(&list, session->currentIndex);
511 if (authParam == NULL) {
512 LOGE("The json data in session is null!");
513 return;
514 }
515 int64_t requestId = 0;
516 if (GetInt64FromJson(authParam, FIELD_REQUEST_ID, &requestId) != HC_SUCCESS) {
517 LOGE("Failed to get request id!");
518 return;
519 }
520 int32_t authForm = AUTH_FORM_INVALID_TYPE;
521 if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
522 LOGE("Failed to get auth type!");
523 return;
524 }
525 BaseGroupAuth *groupAuth = GetGroupAuth(GetAuthType(authForm));
526 if (groupAuth != NULL) {
527 DEV_AUTH_START_TRACE(TRACE_TAG_ON_SESSION_FINISH);
528 groupAuth->onFinish(requestId, authParam, out, session->base.callback);
529 DEV_AUTH_FINISH_TRACE();
530 }
531 }
532
AuthOnNextGroupIfExist(CompatibleAuthSubSession * session)533 int32_t AuthOnNextGroupIfExist(CompatibleAuthSubSession *session)
534 {
535 if (session->currentIndex >= session->paramsList.size(&session->paramsList) - 1) {
536 LOGD("There is no alternative auth group.");
537 return HC_ERR_NO_CANDIDATE_GROUP;
538 }
539 session->currentIndex++;
540 CJson *paramInNextSession = (session->paramsList).get(&(session->paramsList), session->currentIndex);
541 if (paramInNextSession == NULL) {
542 LOGE("The json data in session is null!");
543 return HC_ERR_NULL_PTR;
544 }
545 int64_t requestId = 0;
546 if (GetInt64FromJson(paramInNextSession, FIELD_REQUEST_ID, &requestId) != HC_SUCCESS) {
547 LOGE("Failed to get request id!");
548 return HC_ERR_JSON_GET;
549 }
550 RESET_PERFORM_DATA(requestId);
551 CJson *outNext = CreateJson();
552 if (outNext == NULL) {
553 LOGE("Failed to create json for outNext!");
554 return HC_ERR_ALLOC_MEMORY;
555 }
556 int32_t res;
557 do {
558 int32_t status = 0;
559 res = CreateAndProcessAuthTask(session, paramInNextSession, outNext, &status);
560 if (res != HC_SUCCESS) {
561 break;
562 }
563 res = HandleAuthTaskStatus(session, outNext, status, true);
564 } while (0);
565 if (res != HC_SUCCESS) {
566 LOGW("Failed to auth on current group, try to auth on next group!");
567 DestroyTask(session->base.curTaskId, GetAuthModuleType(paramInNextSession));
568 res = ProcessClientAuthError(session, outNext);
569 }
570 FreeJson(outNext);
571 return res;
572 }
573
CreateAuthParamsList(ParamsVecForAuth * vec)574 void CreateAuthParamsList(ParamsVecForAuth *vec)
575 {
576 *vec = CREATE_HC_VECTOR(ParamsVecForAuth);
577 }
578
DestroyAuthParamsList(ParamsVecForAuth * vec)579 void DestroyAuthParamsList(ParamsVecForAuth *vec)
580 {
581 DESTROY_HC_VECTOR(ParamsVecForAuth, vec);
582 }
583
GetAuthParamsVec(int32_t osAccountId,const CJson * param,ParamsVecForAuth * authParamsVec)584 int32_t GetAuthParamsVec(int32_t osAccountId, const CJson *param, ParamsVecForAuth *authParamsVec)
585 {
586 const char *groupId = GetStringFromJson(param, FIELD_GROUP_ID);
587 if (groupId == NULL) {
588 groupId = GetStringFromJson(param, FIELD_SERVICE_TYPE);
589 }
590 return GetCandidateAuthInfo(osAccountId, groupId, param, authParamsVec);
591 }
592
CreateAndProcessAuthTask(CompatibleAuthSubSession * session,CJson * paramInSession,CJson * out,int32_t * status)593 int32_t CreateAndProcessAuthTask(CompatibleAuthSubSession *session, CJson *paramInSession, CJson *out, int32_t *status)
594 {
595 int32_t moduleType = GetAuthModuleType(paramInSession);
596 if (moduleType == DAS_MODULE) {
597 const char *servicePkgName = GetStringFromJson(paramInSession, FIELD_SERVICE_PKG_NAME);
598 if (servicePkgName == NULL) {
599 LOGE("servicePkgName is null!");
600 return HC_ERR_JSON_GET;
601 }
602 if (AddStringToJson(paramInSession, FIELD_PKG_NAME, servicePkgName) != HC_SUCCESS) {
603 LOGE("Failed to add pkg name to json!");
604 return HC_ERR_JSON_ADD;
605 }
606 }
607 session->base.curTaskId = 0;
608 DEV_AUTH_START_TRACE(TRACE_TAG_CREATE_AUTH_TASK);
609 int32_t res = CreateTask(&(session->base.curTaskId), paramInSession, out, moduleType);
610 DEV_AUTH_FINISH_TRACE();
611 if (res != HC_SUCCESS) {
612 LOGE("Failed to create task for auth!");
613 return res;
614 }
615 DEV_AUTH_START_TRACE(TRACE_TAG_PROCESS_AUTH_TASK);
616 res = ProcessTask(session->base.curTaskId, paramInSession, out, status, moduleType);
617 DEV_AUTH_FINISH_TRACE();
618 ClearCachedData(paramInSession);
619 if (res != HC_SUCCESS) {
620 DestroyTask(session->base.curTaskId, GetAuthModuleType(paramInSession));
621 LOGE("Failed to process task for auth!");
622 }
623 return res;
624 }
625
ClearCachedData(CJson * paramInSession)626 void ClearCachedData(CJson *paramInSession)
627 {
628 DeleteItemFromJson(paramInSession, FIELD_PAYLOAD);
629 DeleteItemFromJson(paramInSession, FIELD_SELF_AUTH_ID);
630 DeleteItemFromJson(paramInSession, FIELD_OPERATION_CODE);
631 }
632
ProcessClientAuthError(CompatibleAuthSubSession * session,const CJson * out)633 int32_t ProcessClientAuthError(CompatibleAuthSubSession *session, const CJson *out)
634 {
635 ParamsVecForAuth list = session->paramsList;
636 CJson *paramInSession = list.get(&list, session->currentIndex);
637 if (paramInSession == NULL) {
638 LOGE("The json data in session is null!");
639 return HC_ERR_NULL_PTR;
640 }
641 CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
642 if (sendToPeer != NULL && ReturnErrorToPeerByTask(sendToPeer, paramInSession,
643 session->base.callback) != HC_SUCCESS) {
644 LOGE("Failed to return task's error msg to peer!");
645 return HC_ERR_INFORM_ERR;
646 }
647 int32_t res = AuthOnNextGroupIfExist(session);
648 if (res != HC_SUCCESS) {
649 LOGE("Failed to auth on next group!");
650 }
651 return res;
652 }
653
ProcessServerAuthError(CompatibleAuthSubSession * session,const CJson * out)654 void ProcessServerAuthError(CompatibleAuthSubSession *session, const CJson *out)
655 {
656 ParamsVecForAuth list = session->paramsList;
657 CJson *paramInSession = list.get(&list, session->currentIndex);
658 if (paramInSession == NULL) {
659 LOGE("The json data in session is null!");
660 return;
661 }
662 CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
663 if (sendToPeer != NULL && ReturnErrorToPeerByTask(sendToPeer, paramInSession,
664 session->base.callback) != HC_SUCCESS) {
665 LOGE("Failed to return task's error msg to peer!");
666 }
667 }
668
AddGroupAuthTransmitData(const CompatibleAuthSubSession * session,bool isClientFirst,CJson * sendToPeer)669 int32_t AddGroupAuthTransmitData(const CompatibleAuthSubSession *session, bool isClientFirst, CJson *sendToPeer)
670 {
671 ParamsVecForAuth list = session->paramsList;
672 CJson *authParam = list.get(&list, session->currentIndex);
673 if (authParam == NULL) {
674 LOGE("The json data in session is null!");
675 return HC_ERR_NULL_PTR;
676 }
677 bool isDeviceLevel = false;
678 if (isClientFirst) {
679 (void)GetBoolFromJson(authParam, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
680 }
681 if (AddBoolToJson(sendToPeer, FIELD_IS_DEVICE_LEVEL, isDeviceLevel) != HC_SUCCESS) {
682 LOGE("Failed to add device level!");
683 return HC_ERR_JSON_ADD;
684 }
685 bool isClient = true;
686 if (GetBoolFromJson(authParam, FIELD_IS_CLIENT, &isClient)) {
687 LOGE("Failed to get isClient!");
688 return HC_ERR_JSON_GET;
689 }
690 if (isClient && (session->currentIndex < (list.size(&list) - 1))) {
691 CJson *nextParam = list.get(&list, session->currentIndex + 1);
692 if (nextParam == NULL) {
693 LOGE("Failed to get next auth params!");
694 return HC_ERR_NULL_PTR;
695 }
696 const char *altGroup = GetStringFromJson(nextParam, FIELD_SERVICE_TYPE);
697 if ((altGroup != NULL) && (AddStringToJson(sendToPeer, FIELD_ALTERNATIVE, altGroup) != HC_SUCCESS)) {
698 LOGE("Failed to add alternative group!");
699 return HC_ERR_JSON_ADD;
700 }
701 }
702 return HC_SUCCESS;
703 }
704
HandleAuthTaskStatus(const CompatibleAuthSubSession * session,CJson * out,int32_t status,bool isClientFirst)705 int32_t HandleAuthTaskStatus(const CompatibleAuthSubSession *session, CJson *out, int32_t status, bool isClientFirst)
706 {
707 int32_t res = HC_SUCCESS;
708 switch (status) {
709 case IGNORE_MSG:
710 LOGI("Ignore this msg.");
711 break;
712 case CONTINUE:
713 res = ReturnTransmitData(session, out, isClientFirst);
714 if (res != HC_SUCCESS) {
715 LOGE("Failed to transmit data to peer!");
716 }
717 break;
718 case FINISH:
719 ReturnFinishData(session, out);
720 ClearSensitiveStringInJson(out, FIELD_SESSION_KEY);
721 res = FINISH;
722 break;
723 default:
724 LOGE("Invalid status after process task!");
725 res = HC_ERR_INVALID_PARAMS;
726 break;
727 }
728 return res;
729 }
730
NotifyPeerAuthError(const CJson * authParam,const DeviceAuthCallback * callback)731 void NotifyPeerAuthError(const CJson *authParam, const DeviceAuthCallback *callback)
732 {
733 if (ReturnErrorToPeerBySession(authParam, callback) != HC_SUCCESS) {
734 LOGE("Failed to return error to peer by session!");
735 }
736 }