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 "messenger_device_status_manager.h"
17 
18 #include <cstdlib>
19 #include <memory>
20 #include <mutex>
21 #include <string>
22 
23 #include "device_manager.h"
24 #include "securec.h"
25 #include "singleton.h"
26 
27 #include "messenger_utils.h"
28 #include "utils_log.h"
29 #include "utils_mem.h"
30 #include "utils_json.h"
31 
32 #define PKG_NAME_LEN 128
33 #define TYPE_PLACE 8
34 #define DEFAULT_TYPE 10
35 #define LAPTOP_TYPE 12
36 #define SMART_DISPLAY_TYPE 2562
37 
38 static void GetDeviceSecurityLevelByNetworkId(const OHOS::DistributedHardware::DmDeviceInfo &info, int32_t &level);
39 
40 namespace OHOS {
41 namespace Security {
42 namespace DeviceSecurityLevel {
43 using namespace OHOS::DistributedHardware;
44 
45 class DeviceStatusControlBlock final : public Singleton<DeviceStatusControlBlock> {
46 public:
47     using StateReceiver = std::function<int32_t(const DeviceIdentify *devId, uint32_t status, int32_t level)>;
Reset(const std::string & pkgName,WorkQueue * queue,StateReceiver deviceStatusReceiver)48     void Reset(const std::string &pkgName, WorkQueue *queue, StateReceiver deviceStatusReceiver)
49     {
50         std::lock_guard<std::mutex> lock(mutex_);
51         pkgName_ = pkgName;
52         queue_ = queue;
53         receiver_ = deviceStatusReceiver;
54     }
GetPackageName() const55     const std::string &GetPackageName() const
56     {
57         return pkgName_;
58     }
59 
GetStateReceiver() const60     const StateReceiver &GetStateReceiver() const
61     {
62         return receiver_;
63     }
64 
GetQueue() const65     WorkQueue *GetQueue() const
66     {
67         return queue_;
68     }
69 
70 private:
71     std::mutex mutex_;
72     WorkQueue *queue_ {nullptr};
73     std::string pkgName_ {};
74     StateReceiver receiver_ {nullptr};
75 };
76 
77 class DslmStateReceiver final {
78 public:
79     DslmStateReceiver() = default;
80     ~DslmStateReceiver() = default;
81 };
82 
83 class DslmDeviceState final : public DeviceStateCallback,
84                               public DmInitCallback,
85                               public std::enable_shared_from_this<DslmDeviceState> {
86 public:
87     enum State : uint32_t {
88         EVENT_NODE_STATE_OFFLINE = 0,
89         EVENT_NODE_STATE_ONLINE = 1,
90     };
91 
92     struct QueueStatusData {
93         DeviceIdentify srcIdentity {0, {0}};
94         uint32_t status {0};
95         uint32_t level {0};
96     };
97 
98     DslmDeviceState() = default;
99     ~DslmDeviceState() override = default;
100 
OnDeviceOnline(const DmDeviceInfo & deviceInfo)101     void OnDeviceOnline(const DmDeviceInfo &deviceInfo) override
102     {
103     }
104 
OnDeviceOffline(const DmDeviceInfo & deviceInfo)105     void OnDeviceOffline(const DmDeviceInfo &deviceInfo) override
106     {
107         MessengerOnNodeStateChange(deviceInfo, EVENT_NODE_STATE_OFFLINE);
108     }
109 
OnDeviceChanged(const DmDeviceInfo & deviceInfo)110     void OnDeviceChanged(const DmDeviceInfo &deviceInfo) override
111     {
112     }
113 
OnDeviceReady(const DmDeviceInfo & deviceInfo)114     void OnDeviceReady(const DmDeviceInfo &deviceInfo) override
115     {
116         MessengerOnNodeStateChange(deviceInfo, EVENT_NODE_STATE_ONLINE);
117     }
118 
OnRemoteDied()119     void OnRemoteDied() override
120     {
121     }
122 
MessengerOnNodeStateChange(const DmDeviceInfo & info,State state)123     static void MessengerOnNodeStateChange(const DmDeviceInfo &info, State state)
124     {
125         DeviceIdentify identity = {DEVICE_ID_MAX_LEN, {0}};
126         int32_t level = 0;
127         if (!MessengerGetDeviceIdentifyByNetworkId(info.networkId, &identity)) {
128             SECURITY_LOG_ERROR("MessengerOnNodeStateChange copy device error");
129             return;
130         }
131         if (state == EVENT_NODE_STATE_ONLINE) {
132             GetDeviceSecurityLevelByNetworkId(info, level);
133         }
134         ProcessDeviceStatusReceiver(&identity, state, level);
135     }
136 
ProcessDeviceStatusReceiver(const DeviceIdentify * devId,uint32_t status,int32_t level)137     static void ProcessDeviceStatusReceiver(const DeviceIdentify *devId, uint32_t status, int32_t level)
138     {
139         if (devId == nullptr || devId->length == 0) {
140             SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, invalid input");
141             return;
142         }
143 
144         auto queue = DeviceStatusControlBlock::GetInstance().GetQueue();
145         if (queue == nullptr) {
146             SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, invalid queue");
147             return;
148         }
149 
150         QueueStatusData *data = new (std::nothrow) QueueStatusData;
151         if (data == nullptr) {
152             SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, malloc result null");
153             return;
154         }
155         data->srcIdentity = *devId;
156         if (level > 0) {
157             data->level = static_cast<uint32_t>(level);
158         }
159         data->status = status;
160 
161         uint32_t maskId = MaskDeviceIdentity((const char *)&devId->identity[0], DEVICE_ID_MAX_LEN);
162         SECURITY_LOG_INFO("OnlineStateChange device %{public}x*** change to %{public}s, level is %{public}d", maskId,
163             (status == EVENT_NODE_STATE_ONLINE) ? " online " : " offline ", level);
164 
165         auto process = [](const uint8_t *data, uint32_t len) {
166             if (data == nullptr || len == 0) {
167                 return;
168             }
169             auto *queueData = static_cast<const QueueStatusData *>(static_cast<const void *>(data));
170             if (len != sizeof(QueueStatusData)) {
171                 SECURITY_LOG_ERROR("ProcessDeviceStatusReceived, invalid input");
172                 return;
173             }
174             auto processor = DeviceStatusControlBlock::GetInstance().GetStateReceiver();
175             if (processor == nullptr) {
176                 SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, invalid queue");
177                 return;
178             }
179             processor(&queueData->srcIdentity, queueData->status, queueData->level);
180             delete queueData;
181         };
182         auto input = static_cast<uint8_t *>(static_cast<void *>(data));
183         auto ret = QueueWork(queue, process, input, sizeof(QueueStatusData));
184         if (ret != WORK_QUEUE_OK) {
185             SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, QueueWork failed, ret is %{public}u", ret);
186             delete data;
187             return;
188         }
189     }
190 };
191 
MessengerConvertNodeToIdentity(const std::string & networkId,DeviceIdentify & devId)192 static bool MessengerConvertNodeToIdentity(const std::string &networkId, DeviceIdentify &devId)
193 {
194     const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
195 
196     std::string udid;
197     int32_t ret = DeviceManager::GetInstance().GetUdidByNetworkId(name, networkId, udid);
198     if (ret != 0) {
199         SECURITY_LOG_ERROR("MessengerConvertNodeToIdentity GetUdidByNetworkId failed = %{public}d", ret);
200         return false;
201     }
202     auto size = (udid.size() < DEVICE_ID_MAX_LEN) ? udid.size() : DEVICE_ID_MAX_LEN;
203 
204     static_cast<void>(memset_s(&devId, sizeof(DeviceIdentify), 0, sizeof(DeviceIdentify)));
205     if (memcpy_s(devId.identity, DEVICE_ID_MAX_LEN, udid.c_str(), size) != EOK) {
206         SECURITY_LOG_ERROR("MessengerConvertNodeToIdentity memcpy error");
207         return false;
208     }
209     if (devId.identity[0] == 0) {
210         SECURITY_LOG_ERROR("MessengerConvertNodeToIdentity content error");
211         return false;
212     }
213     devId.length = DEVICE_ID_MAX_LEN;
214     return true;
215 }
216 
MessengerGetDeviceNodeBasicInfo(const DeviceIdentify & devId,DmDeviceInfo & info)217 static bool MessengerGetDeviceNodeBasicInfo(const DeviceIdentify &devId, DmDeviceInfo &info)
218 {
219     const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
220 
221     std::vector<DmDeviceInfo> deviceList;
222     int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(name, "", deviceList);
223     if (ret != 0) {
224         SECURITY_LOG_ERROR("MessengerGetDeviceOnlineStatus GetTrustedDeviceList failed = %{public}d", ret);
225         return false;
226     }
227 
228     bool find = false;
229     for (auto const &device : deviceList) {
230         DeviceIdentify curr = {DEVICE_ID_MAX_LEN, {0}};
231         bool convert = MessengerConvertNodeToIdentity(device.networkId, curr);
232         if (convert != true) {
233             continue;
234         }
235 
236         if (IsSameDevice(&devId, &curr)) {
237             find = true;
238             info = device;
239             break;
240         }
241     }
242     return find;
243 }
244 } // namespace DeviceSecurityLevel
245 } // namespace Security
246 } // namespace OHOS
247 
248 #ifdef __cplusplus
249 extern "C" {
250 #endif
251 using namespace OHOS::Security::DeviceSecurityLevel;
252 
GetDeviceSecurityLevelByNetworkId(const OHOS::DistributedHardware::DmDeviceInfo & info,int32_t & level)253 static void GetDeviceSecurityLevelByNetworkId(const OHOS::DistributedHardware::DmDeviceInfo &info, int32_t &level)
254 {
255     const char pkgName[PKG_NAME_LEN + 1] = "ohos.dslm";
256     int32_t ret = DeviceManager::GetInstance().GetDeviceSecurityLevel(pkgName, info.networkId, level);
257     SECURITY_LOG_INFO("GetDeviceSecurityLevelByNetworkId ret = %{public}d, level = %{public}d", ret, level);
258 
259     const char *jsonString = static_cast<const char *>(info.extraData.c_str());
260     DslmJsonHandle handle = DslmCreateJson(jsonString);
261     if (handle == nullptr) {
262         return;
263     }
264     uint32_t osType = static_cast<uint32_t>(DslmGetJsonFieldInt(handle, "OS_TYPE"));
265     SECURITY_LOG_INFO("device type is %{public}d", osType);
266     if (info.deviceTypeId == LAPTOP_TYPE || info.deviceTypeId == SMART_DISPLAY_TYPE) {
267         osType = DEFAULT_TYPE;
268         SECURITY_LOG_INFO("deviceTypeId is %{public}d", info.deviceTypeId);
269     }
270     level = static_cast<int32_t>(static_cast<uint32_t>(level) | (osType << TYPE_PLACE));
271     DslmDestroyJson(handle);
272     return;
273 }
274 
InitDeviceStatusManager(WorkQueue * queue,const char * pkgName,DeviceStatusReceiver deviceStatusReceiver)275 bool InitDeviceStatusManager(WorkQueue *queue, const char *pkgName, DeviceStatusReceiver deviceStatusReceiver)
276 {
277     if (queue == nullptr || pkgName == nullptr || deviceStatusReceiver == nullptr) {
278         return false;
279     }
280     const std::string name(pkgName);
281     DeviceStatusControlBlock::GetInstance().Reset(name, queue, deviceStatusReceiver);
282 
283     auto callback = std::make_shared<DslmDeviceState>();
284     if (callback == nullptr) {
285         SECURITY_LOG_ERROR("DslmDeviceState alloc failed");
286         return false;
287     }
288 
289     int tryTimes = 0;
290     int32_t ret = 0;
291     do {
292         tryTimes++;
293         ret = DeviceManager::GetInstance().InitDeviceManager(name, callback);
294         if (ret != 0) {
295             SECURITY_LOG_ERROR("InitDeviceManager failed = %{public}d", ret);
296             MessengerSleep(1); // sleep 1 second and try again
297             continue;
298         }
299     } while (ret != 0 && tryTimes < MAX_TRY_TIMES);
300 
301     if (ret != 0) {
302         SECURITY_LOG_ERROR("InitDeviceManager RegNodeDeviceStateCb failed = %{public}d", ret);
303         return false;
304     }
305 
306     auto process = [](const DeviceIdentify *devId, int32_t level, void *para) -> int32_t {
307         static_cast<void>(para);
308         DslmDeviceState::ProcessDeviceStatusReceiver(devId, DslmDeviceState::State::EVENT_NODE_STATE_ONLINE, level);
309         return 0;
310     };
311 
312     MessengerForEachDeviceProcess(process, nullptr);
313     SECURITY_LOG_INFO("InitDeviceManager RegNodeDeviceStateCb success");
314     return true;
315 }
316 
DeInitDeviceStatusManager(void)317 bool DeInitDeviceStatusManager(void)
318 {
319     const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
320     static_cast<void>(DeviceManager::GetInstance().UnInitDeviceManager(name));
321 
322     SECURITY_LOG_INFO("DeInitDeviceManager UnregNodeDeviceStateCb success");
323     return true;
324 }
325 
MessengerGetDeviceOnlineStatus(const DeviceIdentify * devId,int32_t * level)326 bool MessengerGetDeviceOnlineStatus(const DeviceIdentify *devId, int32_t *level)
327 {
328     if (devId == nullptr) {
329         return false;
330     }
331 
332     DmDeviceInfo info;
333     bool result = MessengerGetDeviceNodeBasicInfo(*devId, info);
334     if (result == true && level != nullptr) {
335         GetDeviceSecurityLevelByNetworkId(info, *level);
336     }
337     return result;
338 }
339 
MessengerGetSelfDeviceIdentify(DeviceIdentify * devId,int32_t * level)340 bool MessengerGetSelfDeviceIdentify(DeviceIdentify *devId, int32_t *level)
341 {
342     if (devId == nullptr || level == NULL) {
343         return false;
344     }
345 
346     const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
347 
348     DmDeviceInfo info;
349     int32_t ret = DeviceManager::GetInstance().GetLocalDeviceInfo(name, info);
350     if (ret != 0) {
351         SECURITY_LOG_ERROR("MessengerGetSelfDeviceIdentify GetLocalNodeDeviceInfo failed = %{public}d", ret);
352         return false;
353     }
354 
355     bool convert = MessengerConvertNodeToIdentity(info.networkId, *devId);
356     if (convert == false) {
357         return false;
358     }
359 
360     GetDeviceSecurityLevelByNetworkId(info, *level);
361     *level = static_cast<int32_t>(static_cast<uint32_t>(*level) & 0xFF);
362 
363     uint32_t maskId = MaskDeviceIdentity((const char *)&devId->identity[0], DEVICE_ID_MAX_LEN);
364     SECURITY_LOG_DEBUG("MessengerGetSelfDeviceIdentify device %{public}x***, level is %{public}d", maskId, *level);
365     return true;
366 }
367 
MessengerForEachDeviceProcess(const DeviceProcessor processor,void * para)368 void MessengerForEachDeviceProcess(const DeviceProcessor processor, void *para)
369 {
370     if (processor == nullptr) {
371         return;
372     }
373 
374     const auto &name = DeviceStatusControlBlock::GetInstance().GetPackageName();
375 
376     std::vector<DmDeviceInfo> deviceList;
377     int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(name, "", deviceList);
378     if (ret != 0) {
379         SECURITY_LOG_ERROR("MessengerForEachDeviceProcess GetTrustedDeviceList failed = %{public}d", ret);
380         return;
381     }
382 
383     for (auto const &device : deviceList) {
384         DeviceIdentify curr = {DEVICE_ID_MAX_LEN, {0}};
385         bool convert = MessengerConvertNodeToIdentity(device.networkId, curr);
386         int32_t level = 0;
387         GetDeviceSecurityLevelByNetworkId(device, level);
388 
389         if (convert == true) {
390             processor(&curr, level, para);
391         }
392     }
393 }
394 
MessengerGetNetworkIdByDeviceIdentify(const DeviceIdentify * devId,char * networkId,uint32_t len)395 bool MessengerGetNetworkIdByDeviceIdentify(const DeviceIdentify *devId, char *networkId, uint32_t len)
396 {
397     if (devId == nullptr || networkId == nullptr || len == 0) {
398         return false;
399     }
400     DmDeviceInfo info;
401     bool result = MessengerGetDeviceNodeBasicInfo(*devId, info);
402     if (result != true) {
403         return false;
404     }
405 
406     int32_t ret = strcpy_s(networkId, len, info.networkId);
407     if (ret != EOK) {
408         SECURITY_LOG_ERROR("MessengerGetNetworkIdByDeviceIdentify strcpy_s error");
409         return false;
410     }
411     return true;
412 }
413 
MessengerGetDeviceIdentifyByNetworkId(const char * networkId,DeviceIdentify * devId)414 bool MessengerGetDeviceIdentifyByNetworkId(const char *networkId, DeviceIdentify *devId)
415 {
416     if (networkId == nullptr || devId == nullptr) {
417         SECURITY_LOG_ERROR("MessengerGetDeviceIdentifyByNetworkId input error");
418         return false;
419     }
420     return MessengerConvertNodeToIdentity(networkId, *devId);
421 }
422 #ifdef __cplusplus
423 }
424 #endif
425