• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }