1 /*
2 * Copyright (C) 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 "idm_session.h"
17
18 #include "securec.h"
19 #include "adaptor_algorithm.h"
20 #include "adaptor_log.h"
21 #include "adaptor_memory.h"
22 #include "adaptor_time.h"
23 #include "linked_list.h"
24
25 #define SESSION_VALIDITY_PERIOD (10 * 60 * 1000)
26 #define MAX_CHALLENGE_GENERATION_TIMES 5
27 #define INVALID_CHALLENGE 0
28
29 // User IDM session information.
30 struct SessionInfo {
31 uint64_t scheduleId;
32 bool isScheduleValid;
33 int32_t userId;
34 uint64_t time;
35 uint64_t validAuthTokenTime;
36 uint64_t challenge;
37 } *g_session;
38
IsSessionExist()39 static bool IsSessionExist()
40 {
41 if (g_session == NULL) {
42 LOG_INFO("the session does not exist");
43 return false;
44 }
45 return true;
46 }
47
GenerateChallenge()48 static uint64_t GenerateChallenge()
49 {
50 uint64_t challenge = 0;
51
52 for (uint32_t i = 0; i < MAX_CHALLENGE_GENERATION_TIMES; i++) {
53 if (SecureRandom((uint8_t *)&challenge, sizeof(uint64_t)) != RESULT_SUCCESS) {
54 LOG_ERROR("get challenge failed");
55 return INVALID_CHALLENGE;
56 }
57 if (challenge != INVALID_CHALLENGE) {
58 break;
59 }
60 }
61 return challenge;
62 }
63
OpenEditSession(int32_t userId,uint64_t * challenge)64 ResultCode OpenEditSession(int32_t userId, uint64_t *challenge)
65 {
66 if (challenge == NULL) {
67 LOG_ERROR("challenge is null");
68 return RESULT_BAD_PARAM;
69 }
70 if (IsSessionExist()) {
71 (void)CloseEditSession();
72 }
73 g_session = Malloc(sizeof(struct SessionInfo));
74 if (g_session == NULL) {
75 LOG_ERROR("g_session malloc failed");
76 return RESULT_NO_MEMORY;
77 }
78 if (memset_s(g_session, sizeof(struct SessionInfo), 0, sizeof(struct SessionInfo)) != EOK) {
79 LOG_ERROR("g_session set failed");
80 Free(g_session);
81 g_session = NULL;
82 return RESULT_GENERAL_ERROR;
83 }
84 g_session->userId = userId;
85 g_session->challenge = GenerateChallenge();
86 if (g_session->challenge == INVALID_CHALLENGE) {
87 LOG_ERROR("challenge is invalid");
88 Free(g_session);
89 g_session = NULL;
90 return RESULT_GENERAL_ERROR;
91 }
92 g_session->time = GetSystemTime();
93 g_session->validAuthTokenTime = g_session->time;
94
95 *challenge = g_session->challenge;
96 g_session->isScheduleValid = false;
97 return RESULT_SUCCESS;
98 }
99
RefreshValidTokenTime(void)100 void RefreshValidTokenTime(void)
101 {
102 if (!IsSessionExist()) {
103 LOG_ERROR("session is invalid");
104 return;
105 }
106 g_session->validAuthTokenTime = GetSystemTime();
107 }
108
IsValidTokenTime(uint64_t tokenTime)109 bool IsValidTokenTime(uint64_t tokenTime)
110 {
111 if (!IsSessionExist()) {
112 LOG_ERROR("session is invalid");
113 return false;
114 }
115 return tokenTime >= g_session->validAuthTokenTime;
116 }
117
CloseEditSession()118 ResultCode CloseEditSession()
119 {
120 if (!IsSessionExist()) {
121 return RESULT_GENERAL_ERROR;
122 }
123 Free(g_session);
124 g_session = NULL;
125 return RESULT_SUCCESS;
126 }
127
GetUserId(int32_t * userId)128 ResultCode GetUserId(int32_t *userId)
129 {
130 if (userId == NULL || !IsSessionExist()) {
131 LOG_ERROR("param is invalid");
132 return RESULT_BAD_PARAM;
133 }
134 *userId = g_session->userId;
135 return RESULT_SUCCESS;
136 }
137
GetChallenge(uint64_t * challenge)138 ResultCode GetChallenge(uint64_t *challenge)
139 {
140 if (challenge == NULL || !IsSessionExist()) {
141 LOG_ERROR("param is invalid");
142 return RESULT_BAD_PARAM;
143 }
144 *challenge = g_session->challenge;
145 return RESULT_SUCCESS;
146 }
147
AssociateCoauthSchedule(uint64_t scheduleId)148 ResultCode AssociateCoauthSchedule(uint64_t scheduleId)
149 {
150 if (!IsSessionExist()) {
151 return RESULT_NEED_INIT;
152 }
153 g_session->scheduleId = scheduleId;
154 g_session->isScheduleValid = true;
155 return RESULT_SUCCESS;
156 }
157
BreakOffCoauthSchedule(void)158 void BreakOffCoauthSchedule(void)
159 {
160 if (!IsSessionExist()) {
161 return;
162 }
163 g_session->isScheduleValid = false;
164 }
165
GetScheduleId(uint64_t * scheduleId)166 ResultCode GetScheduleId(uint64_t *scheduleId)
167 {
168 if (scheduleId == NULL) {
169 LOG_ERROR("scheduleId is null");
170 return RESULT_BAD_PARAM;
171 }
172 if (!IsSessionExist() || g_session->isScheduleValid == false) {
173 return RESULT_NEED_INIT;
174 }
175 *scheduleId = g_session->scheduleId;
176 return RESULT_SUCCESS;
177 }
178
IsSessionTimeout(void)179 bool IsSessionTimeout(void)
180 {
181 if (!IsSessionExist()) {
182 return true;
183 }
184 uint64_t currentTime = GetSystemTime();
185 if (currentTime < g_session->time || currentTime - g_session->time > SESSION_VALIDITY_PERIOD) {
186 LOG_ERROR("timeout, %{public}llu, %{public}llu", currentTime, g_session->time);
187 return true;
188 }
189 return false;
190 }