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 "dslm_core_process.h"
17
18 #include <stdbool.h>
19 #include <stddef.h>
20 #include <stdint.h>
21 #include <unistd.h>
22
23 #include "securec.h"
24
25 #include "device_security_defines.h"
26 #include "dslm_callback_info.h"
27 #include "dslm_core_defines.h"
28 #include "dslm_cred.h"
29 #include "dslm_credential.h"
30 #include "dslm_device_list.h"
31 #include "dslm_fsm_process.h"
32 #include "dslm_hievent.h"
33 #include "dslm_hitrace.h"
34 #include "dslm_messenger_wrapper.h"
35 #include "dslm_msg_serialize.h"
36 #include "dslm_msg_utils.h"
37 #include "dslm_notify_node.h"
38 #include "utils_datetime.h"
39 #include "utils_log.h"
40 #include "utils_mutex.h"
41 #include "utils_state_machine.h"
42
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46
47 #define MAX_NOTIFY_SIZE 64
48 #define DEFAULT_TYPE 10
49
50 static const DeviceIdentify *RefreshDeviceOnlineStatus(const DeviceIdentify *deviceId);
51
OnPeerMsgRequestInfoReceived(const DeviceIdentify * deviceId,const uint8_t * msg,uint32_t len)52 int32_t OnPeerMsgRequestInfoReceived(const DeviceIdentify *deviceId, const uint8_t *msg, uint32_t len)
53 {
54 if (deviceId == NULL || msg == NULL || len == 0) {
55 return ERR_INVALID_PARA;
56 }
57
58 SECURITY_LOG_DEBUG("msg is %s", (char *)msg);
59 MessageBuff buff = {.length = len, .buff = (uint8_t *)msg};
60
61 RequestObject reqObject;
62 (void)memset_s(&reqObject, sizeof(RequestObject), 0, sizeof(RequestObject));
63
64 // Parse the msg
65 int32_t ret = ParseDeviceSecInfoRequest(&buff, &reqObject);
66 if (ret != SUCCESS) {
67 return ret;
68 }
69
70 // process
71 DslmCredBuff *cred = NULL;
72 ret = DefaultRequestDslmCred(deviceId, &reqObject, &cred);
73 if (ret != SUCCESS) {
74 return ret;
75 }
76
77 // build and send response
78 MessageBuff *resBuff = NULL;
79 ret = BuildDeviceSecInfoResponse(reqObject.challenge, cred, &resBuff);
80 if (ret == SUCCESS) {
81 SendMsgToDevice(0, deviceId, resBuff->buff, resBuff->length);
82 FreeMessageBuff(resBuff);
83 }
84 DestroyDslmCred(cred);
85
86 return SUCCESS;
87 }
88
OnPeerMsgResponseInfoReceived(const DeviceIdentify * deviceId,const uint8_t * msg,uint32_t len)89 int32_t OnPeerMsgResponseInfoReceived(const DeviceIdentify *deviceId, const uint8_t *msg, uint32_t len)
90 {
91 if (deviceId == NULL || msg == NULL || len == 0) {
92 return ERR_INVALID_PARA;
93 }
94 SECURITY_LOG_DEBUG("msg is %s", (char *)msg);
95
96 DslmDeviceInfo *deviceInfo = GetDslmDeviceInfo(deviceId);
97 if (deviceInfo == NULL) {
98 SECURITY_LOG_ERROR("no existed device");
99 return ERR_NOEXIST_DEVICE;
100 }
101
102 MessageBuff buff = {
103 .length = len,
104 .buff = (uint8_t *)msg,
105 };
106
107 ScheduleDslmStateMachine(deviceInfo, EVENT_CRED_RSP, &buff);
108 ReportHiEventInfoSync(deviceInfo);
109 return SUCCESS;
110 }
111
OnMsgSendResultNotifier(const DeviceIdentify * deviceId,uint64_t transNo,uint32_t result)112 int32_t OnMsgSendResultNotifier(const DeviceIdentify *deviceId, uint64_t transNo, uint32_t result)
113 {
114 SECURITY_LOG_INFO("msg trans is %{public}u result %{public}u", (uint32_t)transNo, result);
115
116 if (result == SUCCESS) {
117 return SUCCESS;
118 }
119
120 DslmDeviceInfo *deviceInfo = GetDslmDeviceInfo(deviceId);
121 if (deviceInfo == NULL) {
122 return SUCCESS;
123 }
124
125 SECURITY_LOG_INFO("current DslmDeviceInfo transNum is %{public}u", (uint32_t)deviceInfo->transNum);
126 if (deviceInfo->transNum != transNo) {
127 return SUCCESS;
128 }
129
130 if (deviceInfo->credInfo.credLevel != 0) {
131 return SUCCESS;
132 }
133
134 ScheduleDslmStateMachine(deviceInfo, EVENT_MSG_SEND_FAILED, &result);
135
136 return SUCCESS;
137 }
138
OnRequestDeviceSecLevelInfo(const DeviceIdentify * deviceId,const RequestOption * option,uint32_t owner,uint32_t cookie,RequestCallback callback)139 int32_t OnRequestDeviceSecLevelInfo(const DeviceIdentify *deviceId, const RequestOption *option, uint32_t owner,
140 uint32_t cookie, RequestCallback callback)
141 {
142 if (deviceId == NULL || option == NULL || callback == NULL) {
143 SECURITY_LOG_ERROR("invalid params");
144 return ERR_INVALID_PARA;
145 }
146
147 if (GetMessengerStatus() != true) {
148 SECURITY_LOG_ERROR("softbus service not startup complete");
149 return ERR_MSG_NOT_INIT;
150 }
151
152 const DeviceIdentify *curr = RefreshDeviceOnlineStatus(deviceId);
153
154 DslmDeviceInfo *deviceInfo = GetDslmDeviceInfo(curr);
155 if (deviceInfo == NULL) {
156 SECURITY_LOG_ERROR("input device not exist");
157 return ERR_NOEXIST_DEVICE;
158 }
159
160 ReportHiEventAppInvoke(deviceInfo);
161
162 if (deviceInfo->onlineStatus != ONLINE_STATUS_ONLINE) {
163 SECURITY_LOG_ERROR("input device not online");
164 return ERR_NOT_ONLINE;
165 }
166
167 if (deviceInfo->notifyListSize >= MAX_NOTIFY_SIZE) {
168 SECURITY_LOG_ERROR("input device's notifyList is overloaded");
169 return ERR_SA_BUSY;
170 }
171
172 DslmNotifyListNode notifyNode;
173 (void)memset_s(¬ifyNode, sizeof(notifyNode), 0, sizeof(notifyNode));
174 notifyNode.owner = owner;
175 notifyNode.cookie = cookie;
176 notifyNode.requestCallback = callback;
177 notifyNode.start = GetMillisecondSinceBoot();
178 notifyNode.keep = option->timeout * 1000; // 1000 ms per second
179 ScheduleDslmStateMachine(deviceInfo, EVENT_SDK_GET, ¬ifyNode);
180 return SUCCESS;
181 }
182
OnPeerStatusReceiver(const DeviceIdentify * deviceId,uint32_t status,int32_t level)183 int32_t OnPeerStatusReceiver(const DeviceIdentify *deviceId, uint32_t status, int32_t level)
184 {
185 DslmDeviceInfo *info = CreatOrGetDslmDeviceInfo(deviceId);
186 if (info == NULL) {
187 return SUCCESS;
188 }
189
190 if (info->onlineStatus == status) {
191 return SUCCESS;
192 }
193
194 uint32_t event = (status == ONLINE_STATUS_ONLINE) ? EVENT_DEVICE_ONLINE : EVENT_DEVICE_OFFLINE;
195
196 ScheduleDslmStateMachine(info, event, &level);
197 return SUCCESS;
198 }
199
InitSelfDeviceSecureLevel(void)200 bool InitSelfDeviceSecureLevel(void)
201 {
202 int32_t level = 0;
203 const DeviceIdentify *device = GetSelfDevice(&level);
204 if (device->length == 0) {
205 SECURITY_LOG_ERROR("GetSelfDevice failed");
206 ReportHiEventInitSelfFailed("GetSelfDevice failed");
207 return false;
208 }
209
210 DslmDeviceInfo *info = CreatOrGetDslmDeviceInfo(device);
211 if (info == NULL) {
212 SECURITY_LOG_ERROR("CreatOrGetDslmDeviceInfo failed");
213 ReportHiEventInitSelfFailed("CreatOrGetDslmDeviceInfo failed");
214 return false;
215 }
216
217 info->onlineStatus = ONLINE_STATUS_ONLINE;
218 info->osType = DEFAULT_TYPE;
219 if (info->lastOnlineTime == 0) {
220 info->lastOnlineTime = GetMillisecondSinceBoot();
221 }
222 if (level > 0) {
223 info->credInfo.credLevel = (uint32_t)level;
224 }
225 if (info->credInfo.credLevel > 0) {
226 info->result = SUCCESS;
227 info->machine.currState = STATE_SUCCESS;
228 return true;
229 }
230
231 info->machine.currState = STATE_FAILED;
232 int32_t ret = DefaultInitDslmCred(&info->credInfo);
233 if (ret == SUCCESS && info->credInfo.credLevel > 0) {
234 info->machine.currState = STATE_SUCCESS;
235 info->result = SUCCESS;
236 return true;
237 }
238
239 ret = OnPeerStatusReceiver(device, ONLINE_STATUS_ONLINE, level);
240 if (ret != SUCCESS) {
241 SECURITY_LOG_ERROR("make self online failed");
242 }
243 return true;
244 }
245
InitDslmProcess(void)246 bool InitDslmProcess(void)
247 {
248 static bool isInited = false;
249 static Mutex initMutex = INITED_MUTEX;
250
251 if (GetMessengerStatus() == false) {
252 return false;
253 }
254
255 if (isInited == true) {
256 return true;
257 }
258
259 LockMutex(&initMutex);
260 bool result = InitSelfDeviceSecureLevel();
261 if (result) {
262 isInited = true;
263 }
264 UnlockMutex(&initMutex);
265 return isInited;
266 }
267
DeinitDslmProcess(void)268 bool DeinitDslmProcess(void)
269 {
270 return true;
271 }
272
RefreshDeviceOnlineStatus(const DeviceIdentify * deviceId)273 static const DeviceIdentify *RefreshDeviceOnlineStatus(const DeviceIdentify *deviceId)
274 {
275 int32_t level = 0;
276 if (deviceId == NULL) {
277 return NULL;
278 }
279
280 if (deviceId->identity[0] == 0) {
281 SECURITY_LOG_INFO("RefreshDeviceOnlineStatus to self");
282 return GetSelfDevice(&level);
283 }
284
285 if (GetPeerDeviceOnlineStatus(deviceId, &level)) {
286 (void)OnPeerStatusReceiver(deviceId, ONLINE_STATUS_ONLINE, level);
287 }
288
289 if (IsSameDevice(deviceId, GetSelfDevice(&level))) {
290 (void)InitSelfDeviceSecureLevel();
291 }
292
293 return deviceId;
294 }
295
296 #ifdef __cplusplus
297 }
298 #endif
299