• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "network/devsl_dispatcher.h"
17 
18 #include "device_manager.h"
19 #include "device/device_manager_agent.h"
20 #include "ipc/i_daemon.h"
21 #include "securec.h"
22 #include "security_label.h"
23 #include "softbus_bus_center.h"
24 #include "utils_log.h"
25 
26 namespace OHOS {
27 namespace Storage {
28 namespace DistributedFile {
29 std::map<std::string, std::vector<std::weak_ptr<KernelTalker>>> DevslDispatcher::talkersMap_;
30 std::map<std::string, std::string> DevslDispatcher::idMap_;
31 std::mutex DevslDispatcher::mutex;
32 std::mutex DevslDispatcher::devslMapMutex_;
33 std::map<std::string, int32_t> DevslDispatcher::devslMap_;
34 
Start()35 int32_t DevslDispatcher::Start()
36 {
37     int32_t status = DATASL_OnStart();
38     if (status != 0) {
39         LOGE("devsl dispatcher start error %{public}d", status);
40     }
41 
42     return status;
43 }
44 
Stop()45 void DevslDispatcher::Stop()
46 {
47     DATASL_OnStop();
48 }
49 
MakeDevslQueryParams(const std::string & udid)50 DEVSLQueryParams DevslDispatcher::MakeDevslQueryParams(const std::string &udid)
51 {
52     DEVSLQueryParams queryParams;
53     if (memcpy_s(queryParams.udid, MAX_UDID_LENGTH, udid.c_str(), udid.size())) {
54         LOGE("devsl dispatcher memcpy error");
55     }
56     queryParams.udidLen = udid.size();
57 
58     return queryParams;
59 }
60 
DevslGetRegister(const std::string & cid,std::weak_ptr<KernelTalker> talker)61 uint32_t DevslDispatcher::DevslGetRegister(const std::string &cid, std::weak_ptr<KernelTalker> talker)
62 {
63     std::string udid;
64     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
65     deviceManager.GetUdidByNetworkId(IDaemon::SERVICE_NAME, cid, udid);
66 
67     std::lock_guard<std::mutex> lock(mutex);
68     DEVSLQueryParams queryParams = MakeDevslQueryParams(udid);
69     int status = DATASL_GetHighestSecLevelAsync(&queryParams, &DevslDispatcher::DevslGottonCallback);
70     if (status != 0) {
71         LOGE("devsl dispatcher register callback error %{public}d", status);
72         return 0;
73     }
74 
75     idMap_[udid] = cid;
76     auto iter = talkersMap_.find(udid);
77     if (iter == talkersMap_.end()) {
78         std::vector<std::weak_ptr<KernelTalker>> talkers;
79         talkers.push_back(talker);
80         talkersMap_.emplace(udid, talkers);
81     } else {
82         iter->second.push_back(talker);
83     }
84 
85     return 0;
86 }
87 
DevslGottonCallbackAsync(const std::string udid,uint32_t devsl)88 void DevslDispatcher::DevslGottonCallbackAsync(const std::string udid, uint32_t devsl)
89 {
90     std::lock_guard<std::mutex> lock(mutex);
91 
92     auto it = talkersMap_.find(udid);
93     if (it == talkersMap_.end()) {
94         LOGE("devsl dispatcher callback, there is no talker");
95         return;
96     }
97 
98     for (auto talker : it->second) {
99         auto realTalker = talker.lock();
100         if (!realTalker) {
101             continue;
102         }
103 
104         auto iter = idMap_.find(udid);
105         if (iter != idMap_.end()) {
106             realTalker->SinkDevslTokernel(iter->second, devsl);
107         }
108     }
109 
110     talkersMap_.erase(it);
111 }
112 
DevslGottonCallback(DEVSLQueryParams * queryParams,int32_t result,uint32_t levelInfo)113 void DevslDispatcher::DevslGottonCallback(DEVSLQueryParams *queryParams, int32_t result, uint32_t levelInfo)
114 {
115     LOGI("devsl dispatcher callback");
116     if (result != 0) {
117         levelInfo = DATA_SEC_LEVEL1;
118         LOGE("devsl dispatcher dsl get callback result : %{public}d", result);
119     }
120     if (queryParams == nullptr) {
121         LOGE("queryParams is nullptr.");
122         return;
123     }
124     std::string udid(reinterpret_cast<char *>(queryParams->udid), queryParams->udidLen);
125     std::thread callbackThread =
126         std::thread([udid, levelInfo]() { DevslGottonCallbackAsync(udid, levelInfo); });
127     callbackThread.detach();
128 }
129 
GetSecurityLabel(const std::string & path)130 int32_t DevslDispatcher::GetSecurityLabel(const std::string &path)
131 {
132     if (path.empty()) {
133         LOGE("GetSecurityLabel path is empty");
134         return -1;
135     }
136 
137     static std::map<std::string, SecurityLabel> labels = {
138         {"s1", SecurityLabel::S1},
139         {"s2", SecurityLabel::S2},
140         {"s3", SecurityLabel::S3},
141         {"s4", SecurityLabel::S4},
142     };
143 
144     std::string current = OHOS::FileManagement::ModuleSecurityLabel::SecurityLabel::GetSecurityLabel(path);
145     auto iter = labels.find(current);
146     if (iter == labels.end()) {
147         LOGE("GetSecurityLabel cannot find label= %{public}s", current.c_str());
148         return -1;
149     }
150     return static_cast<int32_t>(iter->second);
151 }
152 
CompareDevslWithLocal(const std::string & peerNetworkId,const std::vector<std::string> & paths)153 bool DevslDispatcher::CompareDevslWithLocal(const std::string &peerNetworkId, const std::vector<std::string> &paths)
154 {
155     if (paths.size() == 0) {
156         return false;
157     }
158 
159     auto remoteDevsl = GetDeviceDevsl(peerNetworkId);
160     if (remoteDevsl < 0) {
161         LOGE("remoteDevsl < 0");
162         return false;
163     }
164 
165     for (auto path : paths) {
166         auto securityLabel = GetSecurityLabel(path);
167         if (securityLabel < 0) {
168             LOGE("localDevsl < 0");
169             return false;
170         }
171         if (remoteDevsl < securityLabel) {
172             LOGE("remoteDevsl=%{public}d, securityLabel=%{public}d",
173                  remoteDevsl, securityLabel);
174             return false;
175         }
176     }
177     return true;
178 }
179 
GetDeviceDevsl(const std::string & networkId)180 int32_t DevslDispatcher::GetDeviceDevsl(const std::string &networkId)
181 {
182     if (networkId.empty()) {
183         LOGE("GetDeviceDevsl networkId is empty");
184         return -1;
185     }
186     std::lock_guard<std::mutex> lock(mutex);
187     auto iter = devslMap_.find(networkId);
188     if (iter != devslMap_.end()) {
189         LOGI("find devsl in map");
190         return iter->second;
191     }
192 
193     std::string udid;
194     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
195     deviceManager.GetUdidByNetworkId(IDaemon::SERVICE_NAME, networkId, udid);
196 
197     DEVSLQueryParams queryParams = MakeDevslQueryParams(udid);
198     uint32_t levelInfo;
199     auto ret = DATASL_GetHighestSecLevel(&queryParams, &levelInfo);
200     if (ret != 0) {
201         LOGE("devsl dispatcher register callback error %{public}d", ret);
202         return -1;
203     }
204     devslMap_[networkId] = static_cast<int32_t>(levelInfo);
205     return devslMap_[networkId];
206 }
207 } // namespace DistributedFile
208 } // namespace Storage
209 } // namespace OHOS
210