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