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