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 return true;
225 }
226 int32_t ret = DefaultInitDslmCred(&info->credInfo);
227 if (ret == SUCCESS && info->credInfo.credLevel > 0) {
228 info->machine.currState = STATE_SUCCESS;
229 info->result = SUCCESS;
230 return true;
231 }
232
233 ret = OnPeerStatusReceiver(device, ONLINE_STATUS_ONLINE, devType);
234 if (ret != SUCCESS) {
235 SECURITY_LOG_ERROR("make self online failed");
236 }
237 return true;
238 }
239
InitDslmProcess(void)240 bool InitDslmProcess(void)
241 {
242 static bool isInited = false;
243 static Mutex initMutex = INITED_MUTEX;
244
245 if (GetMessengerStatus() == false) {
246 return false;
247 }
248
249 if (isInited == true) {
250 return true;
251 }
252
253 LockMutex(&initMutex);
254 bool result = InitSelfDeviceSecureLevel();
255 if (result) {
256 isInited = true;
257 }
258 UnlockMutex(&initMutex);
259 return isInited;
260 }
261
DeinitDslmProcess(void)262 bool DeinitDslmProcess(void)
263 {
264 return true;
265 }
266
RefreshDeviceOnlineStatus(const DeviceIdentify * deviceId)267 static const DeviceIdentify *RefreshDeviceOnlineStatus(const DeviceIdentify *deviceId)
268 {
269 uint32_t devType = 0;
270 if (deviceId == NULL) {
271 return NULL;
272 }
273
274 if (deviceId->identity[0] == 0) {
275 SECURITY_LOG_INFO("RefreshDeviceOnlineStatus to self");
276 return GetSelfDevice(&devType);
277 }
278
279 if (GetPeerDeviceOnlineStatus(deviceId, &devType)) {
280 (void)OnPeerStatusReceiver(deviceId, ONLINE_STATUS_ONLINE, devType);
281 }
282
283 if (IsSameDevice(deviceId, GetSelfDevice((&devType)))) {
284 (void)InitSelfDeviceSecureLevel();
285 }
286
287 return deviceId;
288 }
289
290 #ifdef __cplusplus
291 }
292 #endif
293