1 /*
2 * Copyright (C) 2021 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 "session_manager.h"
17 #include "auth_session_client.h"
18 #include "auth_session_client_lite.h"
19 #include "auth_session_server.h"
20 #include "auth_session_server_lite.h"
21 #include "bind_session_client.h"
22 #include "bind_session_client_lite.h"
23 #include "bind_session_server.h"
24 #include "bind_session_server_lite.h"
25 #include "common_defs.h"
26 #include "device_auth.h"
27 #include "device_auth_defines.h"
28 #include "hc_dev_info.h"
29 #include "hc_log.h"
30 #include "hc_time.h"
31 #include "hc_vector.h"
32 #include "key_agree_session_client.h"
33 #include "key_agree_session_server.h"
34
35 typedef struct {
36 int64_t requestId;
37 int32_t type;
38 int64_t sessionId;
39 } RequestInfo;
40
41 DECLARE_HC_VECTOR(SessionManagerVec, void *);
42 IMPLEMENT_HC_VECTOR(SessionManagerVec, void *, 1)
43
44 DECLARE_HC_VECTOR(RequestInfoVec, RequestInfo);
45 IMPLEMENT_HC_VECTOR(RequestInfoVec, RequestInfo, 1)
46
47 static SessionManagerVec g_sessionManagerVec;
48 static RequestInfoVec g_requestVec;
49
50 typedef Session *(*CreateSessionFunc)(CJson *, const DeviceAuthCallback *);
51
52 typedef struct SessionManagerInfoStruct {
53 SessionTypeValue sessionType;
54 int requestType; /* only BIND_TYPE or AUTH_TYPE currently */
55 CreateSessionFunc createSessionFunc;
56 } SessionManagerInfo;
57
58 static const SessionManagerInfo SESSION_MANAGER_INFO[] = {
59 { TYPE_CLIENT_BIND_SESSION, BIND_TYPE, CreateClientBindSession },
60 { TYPE_SERVER_BIND_SESSION, BIND_TYPE, CreateServerBindSession },
61 { TYPE_CLIENT_AUTH_SESSION, AUTH_TYPE, CreateClientAuthSession },
62 { TYPE_SERVER_AUTH_SESSION, AUTH_TYPE, CreateServerAuthSession },
63 { TYPE_CLIENT_BIND_SESSION_LITE, BIND_TYPE, CreateLiteClientBindSession },
64 { TYPE_SERVER_BIND_SESSION_LITE, BIND_TYPE, CreateLiteServerBindSession },
65 { TYPE_CLIENT_AUTH_SESSION_LITE, AUTH_TYPE, CreateClientAuthSessionLite },
66 { TYPE_SERVER_AUTH_SESSION_LITE, AUTH_TYPE, CreateServerAuthSessionLite },
67 { TYPE_CLIENT_KEY_AGREE_SESSION, BIND_TYPE, CreateClientKeyAgreeSession },
68 { TYPE_SERVER_KEY_AGREE_SESSION, BIND_TYPE, CreateServerKeyAgreeSession }
69 };
70
GetSessionId(int64_t requestId,int64_t * sessionId)71 static int32_t GetSessionId(int64_t requestId, int64_t *sessionId)
72 {
73 uint32_t index;
74 RequestInfo *requestInfo = NULL;
75 FOR_EACH_HC_VECTOR(g_requestVec, index, requestInfo) {
76 if ((requestInfo != NULL) && (requestInfo->requestId == requestId)) {
77 *sessionId = requestInfo->sessionId;
78 return HC_SUCCESS;
79 }
80 }
81 return HC_ERR_REQUEST_NOT_FOUND;
82 }
83
GetSessionIdByType(int64_t requestId,int32_t type,int64_t * sessionId)84 static int32_t GetSessionIdByType(int64_t requestId, int32_t type, int64_t *sessionId)
85 {
86 uint32_t index;
87 RequestInfo *requestInfo = NULL;
88 FOR_EACH_HC_VECTOR(g_requestVec, index, requestInfo) {
89 if ((requestInfo != NULL) && (requestInfo->requestId == requestId)) {
90 if (requestInfo->type != type) {
91 LOGE("RequestId is match but type not match");
92 return HC_ERR_REQUEST_NOT_FOUND;
93 }
94 *sessionId = requestInfo->sessionId;
95 return HC_SUCCESS;
96 }
97 }
98 return HC_ERR_REQUEST_NOT_FOUND;
99 }
100
DestroyRequest(int64_t requestId)101 static void DestroyRequest(int64_t requestId)
102 {
103 uint32_t index;
104 RequestInfo *request = NULL;
105 FOR_EACH_HC_VECTOR(g_requestVec, index, request) {
106 if ((request != NULL) && (request->requestId == requestId)) {
107 RequestInfo tempRequest;
108 HC_VECTOR_POPELEMENT(&g_requestVec, &tempRequest, index);
109 return;
110 }
111 }
112 }
113
InitSessionManager(void)114 void InitSessionManager(void)
115 {
116 g_sessionManagerVec = CREATE_HC_VECTOR(SessionManagerVec);
117 g_requestVec = CREATE_HC_VECTOR(RequestInfoVec);
118 }
119
DestroySessionManager(void)120 void DestroySessionManager(void)
121 {
122 uint32_t index;
123 void **session = NULL;
124 FOR_EACH_HC_VECTOR(g_sessionManagerVec, index, session) {
125 if (session != NULL && (*session != NULL)) {
126 Session *temp = (Session *)(*session);
127 temp->destroy(temp);
128 }
129 }
130 DESTROY_HC_VECTOR(SessionManagerVec, &g_sessionManagerVec);
131 DESTROY_HC_VECTOR(RequestInfoVec, &g_requestVec);
132 }
133
IsRequestExist(int64_t requestId)134 bool IsRequestExist(int64_t requestId)
135 {
136 int64_t sessionId = 0;
137 return (GetSessionId(requestId, &sessionId) == HC_SUCCESS) ? true : false;
138 }
139
InformTimeOutAndDestroyRequest(const DeviceAuthCallback * callback,int64_t sessionId)140 static void InformTimeOutAndDestroyRequest(const DeviceAuthCallback *callback, int64_t sessionId)
141 {
142 if (callback == NULL || callback->onError == NULL) {
143 LOGD("Callback is null, can't inform timeout");
144 return;
145 }
146 int64_t requestId = 0;
147 uint32_t index;
148 RequestInfo *requestInfo = NULL;
149 FOR_EACH_HC_VECTOR(g_requestVec, index, requestInfo) {
150 if ((requestInfo != NULL) && (requestInfo->sessionId == sessionId)) {
151 requestId = requestInfo->requestId;
152 RequestInfo tempRequest;
153 HC_VECTOR_POPELEMENT(&g_requestVec, &tempRequest, index);
154 break;
155 }
156 }
157 LOGI("Begin to inform time out, requestId :%" PRId64, requestId);
158 callback->onError(requestId, AUTH_FORM_INVALID_TYPE, HC_ERR_TIME_OUT, NULL);
159 }
160
RemoveOverTimeSession(void)161 static void RemoveOverTimeSession(void)
162 {
163 uint32_t index = 0;
164 void **session = NULL;
165 while (index < g_sessionManagerVec.size(&(g_sessionManagerVec))) {
166 session = g_sessionManagerVec.getp(&(g_sessionManagerVec), index);
167 if (session == NULL || (*session == NULL)) {
168 index++;
169 continue;
170 }
171 Session *ptr = (Session *)(*session);
172 if (HcGetIntervalTime(ptr->createTime) < TIME_OUT_VALUE) {
173 index++;
174 } else {
175 InformTimeOutAndDestroyRequest(ptr->callback, ptr->sessionId);
176 ptr->destroy(ptr);
177 g_sessionManagerVec.eraseElement(&(g_sessionManagerVec), session, index);
178 }
179 session = g_sessionManagerVec.getp(&(g_sessionManagerVec), index);
180 }
181 }
182
ProcessSession(int64_t requestId,int32_t type,CJson * in)183 int32_t ProcessSession(int64_t requestId, int32_t type, CJson *in)
184 {
185 RemoveOverTimeSession();
186 int64_t sessionId = 0;
187 int32_t result = GetSessionIdByType(requestId, type, &sessionId);
188 if (result != HC_SUCCESS) {
189 LOGE("The corresponding session is not found!");
190 return result;
191 }
192 uint32_t index;
193 void **session = NULL;
194 FOR_EACH_HC_VECTOR(g_sessionManagerVec, index, session) {
195 if (session != NULL && (*session != NULL)) {
196 Session *ptr = (Session *)(*session);
197 if (ptr->sessionId == sessionId) {
198 return ptr->process(ptr, in);
199 }
200 }
201 }
202 return HC_ERR_SESSION_NOT_EXIST;
203 }
204
CheckForCreateSession(int64_t requestId,CJson * params,const DeviceAuthCallback * callback)205 static int32_t CheckForCreateSession(int64_t requestId, CJson *params, const DeviceAuthCallback *callback)
206 {
207 if ((params == NULL) && (callback == NULL)) {
208 LOGE("The input params or callback is NULL!");
209 return HC_ERR_INVALID_PARAMS;
210 }
211 if (IsRequestExist(requestId)) {
212 LOGE("A request with the request ID already exists!");
213 return HC_ERR_REQUEST_EXIST;
214 }
215 return HC_SUCCESS;
216 }
217
CreateSession(int64_t requestId,SessionTypeValue sessionType,CJson * params,const DeviceAuthCallback * callback)218 int32_t CreateSession(int64_t requestId, SessionTypeValue sessionType, CJson *params,
219 const DeviceAuthCallback *callback)
220 {
221 RemoveOverTimeSession();
222 int32_t res = CheckForCreateSession(requestId, params, callback);
223 if (res != HC_SUCCESS) {
224 return res;
225 }
226 uint32_t vecSize = g_sessionManagerVec.size(&g_sessionManagerVec);
227 LOGI("Current session num: %d", vecSize);
228 if (vecSize >= MAX_SESSION_COUNT) {
229 LOGE("Session vector is full.");
230 return HC_ERR_SESSION_IS_FULL;
231 }
232 RequestInfo requestInfo;
233 requestInfo.requestId = requestId;
234 Session *session = NULL;
235 for (uint32_t i = 0; i < sizeof(SESSION_MANAGER_INFO) / sizeof(SessionManagerInfo); i++) {
236 if (SESSION_MANAGER_INFO[i].sessionType == sessionType) {
237 session = SESSION_MANAGER_INFO[i].createSessionFunc(params, callback);
238 requestInfo.type = SESSION_MANAGER_INFO[i].requestType;
239 break;
240 }
241 }
242 if (session == NULL) {
243 LOGE("Failed to create session! Session Type: %d", sessionType);
244 return HC_ERR_CREATE_SESSION_FAIL;
245 }
246
247 requestInfo.sessionId = session->sessionId;
248 g_sessionManagerVec.pushBackT(&g_sessionManagerVec, (void *)session);
249 g_requestVec.pushBack(&g_requestVec, &requestInfo);
250 session->createTime = HcGetCurTime();
251 if (session->createTime <= 0) {
252 session->createTime = 0;
253 LOGE("Failed to get cur time.");
254 }
255 return HC_SUCCESS;
256 }
257
DestroySession(int64_t requestId)258 void DestroySession(int64_t requestId)
259 {
260 int64_t sessionId = 0;
261 if (GetSessionId(requestId, &sessionId) != HC_SUCCESS) {
262 LOGI("The corresponding session is not found. Therefore, the destruction operation is not required!");
263 return;
264 }
265 uint32_t index;
266 void **session = NULL;
267 FOR_EACH_HC_VECTOR(g_sessionManagerVec, index, session) {
268 if (session != NULL && (*session != NULL)) {
269 if (((Session *)(*session))->sessionId == sessionId) {
270 ((Session *)(*session))->destroy(((Session *)(*session)));
271 *session = NULL;
272 HC_VECTOR_POPELEMENT(&g_sessionManagerVec, session, index);
273 break;
274 }
275 }
276 }
277 DestroyRequest(requestId);
278 }
279
OnChannelOpened(int64_t requestId,int64_t channelId)280 void OnChannelOpened(int64_t requestId, int64_t channelId)
281 {
282 int64_t sessionId = 0;
283 if (GetSessionIdByType(requestId, BIND_TYPE, &sessionId) != HC_SUCCESS) {
284 LOGE("The corresponding session is not found!");
285 return;
286 }
287 uint32_t index;
288 void **session = NULL;
289 FOR_EACH_HC_VECTOR(g_sessionManagerVec, index, session) {
290 if (session == NULL || (*session == NULL) || (((Session *)(*session))->sessionId != sessionId)) {
291 continue;
292 }
293 int sessionType = ((Session *)(*session))->type;
294 if ((sessionType == TYPE_CLIENT_BIND_SESSION) ||
295 (sessionType == TYPE_CLIENT_BIND_SESSION_LITE) ||
296 (sessionType == TYPE_CLIENT_KEY_AGREE_SESSION)) {
297 BindSession *realSession = (BindSession *)(*session);
298 realSession->onChannelOpened(*session, channelId, requestId);
299 return;
300 }
301 LOGE("The type of the found session is not as expected!");
302 return;
303 }
304 }
305
OnConfirmed(int64_t requestId,CJson * returnData)306 void OnConfirmed(int64_t requestId, CJson *returnData)
307 {
308 int64_t sessionId = 0;
309 if (GetSessionIdByType(requestId, BIND_TYPE, &sessionId) != HC_SUCCESS) {
310 LOGE("The corresponding session is not found!");
311 return;
312 }
313 uint32_t index;
314 void **session = NULL;
315 FOR_EACH_HC_VECTOR(g_sessionManagerVec, index, session) {
316 if ((session == NULL) || (*session == NULL) || (((Session *)(*session))->sessionId != sessionId)) {
317 continue;
318 }
319 int sessionType = ((Session *)(*session))->type;
320 if ((sessionType == TYPE_SERVER_BIND_SESSION) ||
321 (sessionType == TYPE_SERVER_BIND_SESSION_LITE) ||
322 (sessionType == TYPE_SERVER_KEY_AGREE_SESSION)) {
323 BindSession *realSession = (BindSession *)(*session);
324 if (!realSession->isWaiting) {
325 LOGE("The found session is not in the waiting state!");
326 return;
327 }
328 realSession->onConfirmed(*session, returnData);
329 return;
330 }
331 LOGE("The type of the found session is not as expected!");
332 return;
333 }
334 }