• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-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 "auth_session_server.h"
17 #include "auth_session_common.h"
18 #include "auth_session_common_util.h"
19 #include "auth_session_util.h"
20 #include "base_group_auth.h"
21 #include "common_defs.h"
22 #include "dev_auth_module_manager.h"
23 #include "device_auth_defines.h"
24 #include "hc_log.h"
25 #include "hc_types.h"
26 #include "os_account_adapter.h"
27 #include "session_common.h"
28 
29 static int32_t ProcessServerAuthSession(Session *session, CJson *in);
30 
CombineServerParams(const CJson * confirmationJson,CJson * dataFromClient)31 static int32_t CombineServerParams(const CJson *confirmationJson, CJson *dataFromClient)
32 {
33     int32_t authForm = AUTH_FORM_INVALID_TYPE;
34     if (GetIntFromJson(dataFromClient, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
35         LOGE("Failed to get auth form in data sent by client for the first time!");
36         return HC_ERR_JSON_GET;
37     }
38     int32_t osAccountId = ANY_OS_ACCOUNT;
39     (void)GetIntFromJson(confirmationJson, FIELD_OS_ACCOUNT_ID, &osAccountId);
40     osAccountId = DevAuthGetRealOsAccountLocalId(osAccountId);
41     if (osAccountId == INVALID_OS_ACCOUNT) {
42         return HC_ERR_INVALID_PARAMS;
43     }
44     if (AddIntToJson(dataFromClient, FIELD_OS_ACCOUNT_ID, osAccountId) != HC_SUCCESS) {
45         LOGE("Failed to add os accountId for server in onRequest confirm!");
46         return HC_ERR_JSON_ADD;
47     }
48     int32_t groupAuthType = GetGroupAuthType(authForm);
49     BaseGroupAuth *groupAuthHandle = GetGroupAuth(groupAuthType);
50     if (groupAuthHandle == NULL) {
51         LOGE("Failed to get group auth handle!");
52         return HC_ERR_NOT_SUPPORT;
53     }
54     int32_t res = groupAuthHandle->combineServerConfirmParams(confirmationJson, dataFromClient);
55     if (res != HC_SUCCESS) {
56         LOGE("Failed to combine server confirm params!");
57     }
58     return res;
59 }
60 
GetAuthInfoForServer(CJson * dataFromClient,ParamsVec * authParamsVec)61 static int32_t GetAuthInfoForServer(CJson *dataFromClient, ParamsVec *authParamsVec)
62 {
63     int32_t authForm = AUTH_FORM_INVALID_TYPE;
64     if (GetIntFromJson(dataFromClient, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
65         LOGE("Failed to get auth form!");
66         return HC_ERR_JSON_FAIL;
67     }
68     int32_t groupAuthType = GetGroupAuthType(authForm);
69     BaseGroupAuth *groupAuthHandle = GetGroupAuth(groupAuthType);
70     if (groupAuthHandle == NULL) {
71         LOGE("Failed to get group auth handle!");
72         return HC_ERR_NOT_SUPPORT;
73     }
74     return groupAuthHandle->getAuthParamForServer(dataFromClient, authParamsVec);
75 }
76 
StartServerRequest(const CJson * dataFromClient,const DeviceAuthCallback * callback)77 static char *StartServerRequest(const CJson *dataFromClient, const DeviceAuthCallback *callback)
78 {
79     CJson *reqParam = CreateJson();
80     if (reqParam == NULL) {
81         LOGE("Failed to create reqParam json!");
82         return NULL;
83     }
84     char *confirmation = NULL;
85     do {
86         int32_t authForm = AUTH_FORM_INVALID_TYPE;
87         if (GetIntFromJson(dataFromClient, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
88             LOGE("Failed to get auth form!");
89             break;
90         }
91         int32_t groupAuthType = GetGroupAuthType(authForm);
92         BaseGroupAuth *groupAuthHandle = GetGroupAuth(groupAuthType);
93         if (groupAuthHandle == NULL) {
94             LOGE("Failed to get group auth handle!");
95             break;
96         }
97         int32_t res = groupAuthHandle->getReqParams(dataFromClient, reqParam);
98         if (res != HC_SUCCESS) {
99             LOGE("Failed to get request params!");
100             break;
101         }
102         confirmation = GetServerConfirmation(dataFromClient, reqParam, callback);
103     } while (0);
104     FreeJson(reqParam);
105     return confirmation;
106 }
107 
AddAuthParamByRequest(CJson * dataFromClient,const DeviceAuthCallback * callback,ParamsVec * authParamsVec)108 static int32_t AddAuthParamByRequest(CJson *dataFromClient, const DeviceAuthCallback *callback,
109     ParamsVec *authParamsVec)
110 {
111     char *confirmation = StartServerRequest(dataFromClient, callback);
112     if (confirmation == NULL) {
113         LOGE("Failed to get confirmation from server!");
114         return HC_ERR_SERVER_CONFIRM_FAIL;
115     }
116     CJson *confirmationJson = CreateJsonFromString(confirmation);
117     FreeJsonString(confirmation);
118     if (confirmationJson == NULL) {
119         LOGE("Failed to create json from string!");
120         return HC_ERR_JSON_FAIL;
121     }
122     int32_t serverConfirm = REQUEST_ACCEPTED;
123     (void)GetIntFromJson(confirmationJson, FIELD_CONFIRMATION, &serverConfirm);
124     if ((uint32_t)serverConfirm == REQUEST_REJECTED) {
125         LOGE("Server reject to response.");
126         FreeJson(confirmationJson);
127         return HC_ERR_REQ_REJECTED;
128     }
129 
130     int32_t res = CombineServerParams(confirmationJson, dataFromClient);
131     FreeJson(confirmationJson);
132     if (res != HC_SUCCESS) {
133         LOGE("Failed to combine server params!");
134         return res;
135     }
136 
137     res = GetAuthInfoForServer(dataFromClient, authParamsVec);
138     if (res != HC_SUCCESS) {
139         LOGE("Failed to fill device auth info for server!");
140     }
141     return res;
142 }
143 
ProcessServerAuthTask(AuthSession * session,int32_t moduleType,CJson * in,CJson * out)144 static int32_t ProcessServerAuthTask(AuthSession *session, int32_t moduleType, CJson *in, CJson *out)
145 {
146     int32_t status = 0;
147     CJson *paramInSession = (session->paramsList).get(&(session->paramsList), session->currentIndex);
148     if (paramInSession == NULL) {
149         LOGE("The json data in session is null!");
150         return HC_ERR_NULL_PTR;
151     }
152     int32_t res = ProcessTask(session->curTaskId, in, out, &status, moduleType);
153     DeleteItemFromJson(in, FIELD_PAYLOAD);
154     if (res != HC_SUCCESS) {
155         LOGE("Failed to process task, res = %d!", res);
156         if (InformAuthError(session, out, res) != HC_SUCCESS) {
157             LOGE("Failed to inform auth error!");
158         }
159         return res;
160     }
161     res = ProcessTaskStatusForAuth(session, paramInSession, out, status);
162     return res;
163 }
164 
StartServerAuthTask(AuthSession * session,const CJson * receivedData)165 static int32_t StartServerAuthTask(AuthSession *session, const CJson *receivedData)
166 {
167     CJson *paramInSession = (session->paramsList).get(&(session->paramsList), session->currentIndex);
168     if (paramInSession == NULL) {
169         LOGE("The json data in session is null!");
170         return HC_ERR_NULL_PTR;
171     }
172     ProcessDeviceLevel(receivedData, paramInSession);
173     CJson *out = CreateJson();
174     if (out == NULL) {
175         LOGE("Failed to create json!");
176         InformPeerAuthError(receivedData, session->base.callback);
177         InformLocalAuthError(receivedData, session->base.callback);
178         return HC_ERR_ALLOC_MEMORY;
179     }
180     int32_t status = 0;
181     int32_t res = CreateAndProcessTask(session, paramInSession, out, &status);
182     if (res != HC_SUCCESS) {
183         LOGE("Failed to process server auth task, res = %d!", res);
184         if (InformAuthError(session, out, res) != HC_SUCCESS) {
185             LOGE("Failed to inform auth error!");
186         }
187         FreeJson(out);
188         return res;
189     }
190     res = ProcessTaskStatusForAuth(session, receivedData, out, status);
191     FreeJson(out);
192     return res;
193 }
194 
CheckServerGroupAuthMsg(const CJson * in,const CJson * paramInSession,const DeviceAuthCallback * callback)195 static int32_t CheckServerGroupAuthMsg(const CJson *in, const CJson *paramInSession, const DeviceAuthCallback *callback)
196 {
197     int32_t groupErrMsg = 0;
198     if (GetIntFromJson(in, FIELD_GROUP_ERROR_MSG, &groupErrMsg) != HC_SUCCESS) {
199         return HC_SUCCESS;
200     }
201     InformLocalAuthError(paramInSession, callback);
202     return HC_ERR_PEER_ERROR;
203 }
204 
ProcessServerAuthSession(Session * session,CJson * in)205 static int32_t ProcessServerAuthSession(Session *session, CJson *in)
206 {
207     LOGI("Begin process server authSession.");
208     if ((session == NULL) || (in == NULL)) {
209         LOGE("Invalid input params!");
210         return HC_ERR_INVALID_PARAMS;
211     }
212     AuthSession *realSession = (AuthSession *)session;
213     CJson *paramInSession = (realSession->paramsList).get(&(realSession->paramsList), realSession->currentIndex);
214     if (paramInSession == NULL) {
215         LOGE("Failed to get param in session!");
216         return HC_ERR_NULL_PTR;
217     }
218     int32_t res = CheckServerGroupAuthMsg(in, paramInSession, realSession->base.callback);
219     if (res != HC_SUCCESS) {
220         LOGE("Peer device's group has error, so we stop server auth session!");
221         return res;
222     }
223     CJson *out = CreateJson();
224     if (out == NULL) {
225         LOGE("Failed to create json for out!");
226         InformPeerAuthError(paramInSession, realSession->base.callback);
227         InformLocalAuthError(paramInSession, realSession->base.callback);
228         return HC_ERR_ALLOC_MEMORY;
229     }
230     int32_t moduleType = GetAuthModuleType(paramInSession);
231     res = ProcessServerAuthTask(realSession, moduleType, in, out);
232     FreeJson(out);
233     if (res == FINISH) {
234         LOGI("End process server authSession.");
235     }
236     return res;
237 }
238 
CreateServerAuthSessionInner(CJson * param,const DeviceAuthCallback * callback)239 static AuthSession *CreateServerAuthSessionInner(CJson *param, const DeviceAuthCallback *callback)
240 {
241     ParamsVec authVec;
242     CreateAuthParamsVec(&authVec);
243     int32_t res = AddAuthParamByRequest(param, callback, &authVec);
244     DeleteCachedData(param);
245     if ((res != HC_SUCCESS) || (authVec.size(&authVec) == 0)) {
246         LOGE("Failed to add auth param for server, res = %d, candidate auth group = %u!", res, authVec.size(&authVec));
247         DestroyAuthParamsVec(&authVec);
248         InformPeerAuthError(param, callback);
249         InformLocalAuthError(param, callback);
250         return NULL;
251     }
252 
253     AuthSession *session = (AuthSession *)HcMalloc(sizeof(AuthSession), 0);
254     if (session == NULL) {
255         LOGE("Failed to malloc memory for session!");
256         DestroyAuthParamsVec(&authVec);
257         InformPeerAuthError(param, callback);
258         InformLocalAuthError(param, callback);
259         return NULL;
260     }
261     session->base.type = TYPE_SERVER_AUTH_SESSION;
262     session->base.process = ProcessServerAuthSession;
263     session->base.destroy = DestroyAuthSession;
264     session->base.callback = callback;
265     session->base.appId = GetDuplicateServicePkgName(param);
266     session->currentIndex = 0;
267     session->paramsList = authVec;
268     res = GenerateSessionOrTaskId(&session->base.sessionId);
269     if (res != HC_SUCCESS) {
270         LOGE("Failed to generate session id!");
271         DestroyAuthSession((Session *)session);
272         InformPeerAuthError(param, callback);
273         InformLocalAuthError(param, callback);
274         return NULL;
275     }
276 
277     res = StartServerAuthTask(session, param);
278     if (res != HC_SUCCESS) {
279         LOGE("Failed to start server auth task!");
280         DestroyAuthSession((Session *)session);
281         return NULL;
282     }
283     return (AuthSession *)session;
284 }
285 
CreateServerAuthSession(CJson * param,const DeviceAuthCallback * callback)286 Session *CreateServerAuthSession(CJson *param, const DeviceAuthCallback *callback)
287 {
288     AuthSession *session = CreateServerAuthSessionInner(param, callback);
289     if (session == NULL) {
290         LOGE("Failed to create server auth session!");
291         return NULL;
292     }
293     return (Session *)session;
294 }
295