• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "data_collection.h"
17 #include <cinttypes>
18 #include "json_cfg.h"
19 #include "security_collector_log.h"
20 #include "collector_cfg_marshalling.h"
21 #include "i_collector.h"
22 #include "event_define.h"
23 
24 namespace OHOS::Security::SecurityCollector {
25 namespace {
26     std::string configPathPre = "/system/etc/";
27     const std::string &SA_CONFIG_PATH = configPathPre + SECURITY_GUARD_COLLECTOR_CFG_SOURCE;
28 }
29 
GetInstance()30 DataCollection &DataCollection::GetInstance()
31 {
32     static DataCollection instance;
33     return instance;
34 }
35 
StartCollectors(const std::vector<int64_t> & eventIds,std::shared_ptr<ICollectorFwk> api)36 bool DataCollection::StartCollectors(const std::vector<int64_t>& eventIds, std::shared_ptr<ICollectorFwk> api)
37 {
38     LOGI("StartCollectors start");
39     if (eventIds.empty() || !api) {
40         LOGE("Invalid input parameter");
41         return false;
42     }
43     std::vector<int64_t> loadedEventIds_;
44     for (int64_t eventId : eventIds) {
45         LOGI("StartCollectors eventId is 0x%{public}" PRIx64, eventId);
46         if (IsCollectorStarted(eventId)) {
47             LOGI("Collector already started, eventId is 0x%{public}" PRIx64, eventId);
48             continue;
49         }
50         std::string collectorPath;
51         ErrorCode ret = GetCollectorPath(eventId, collectorPath);
52         if (ret != SUCCESS) {
53             LOGE("GetCollectorPath failed, eventId is 0x%{public}" PRIx64, eventId);
54             StopCollectors(loadedEventIds_);
55             return false;
56         }
57         ret = LoadCollector(eventId, collectorPath, api);
58         if (ret != SUCCESS) {
59             LOGE("Load collector failed, eventId is 0x%{public}" PRIx64, eventId);
60             StopCollectors(loadedEventIds_);
61             return false;
62         }
63         loadedEventIds_.push_back(eventId);
64     }
65     LOGI("StartCollectors finish");
66     return true;
67 }
68 
SecurityGuardSubscribeCollector(const std::vector<int64_t> & eventIds)69 bool DataCollection::SecurityGuardSubscribeCollector(const std::vector<int64_t>& eventIds)
70 {
71     LOGI("Start to subscribe collectors start");
72     for (int64_t eventId : eventIds) {
73         LOGI("StartCollectors eventId is 0x%{public}" PRIx64, eventId);
74         if (IsCollectorStarted(eventId)) {
75             LOGI("Collector already started, eventId is 0x%{public}" PRIx64, eventId);
76             continue;
77         }
78         std::string collectorPath;
79         ErrorCode ret = GetCollectorPath(eventId, collectorPath);
80         if (ret != SUCCESS) {
81             LOGE("GetCollectorPath failed, eventId is 0x%{public}" PRIx64, eventId);
82             continue;
83         }
84         ret = LoadCollector(eventId, collectorPath, nullptr);
85         if (ret != SUCCESS) {
86             LOGE("LoadCollector failed, eventId is 0x%{public}" PRIx64, eventId);
87             continue;
88         }
89     }
90     LOGI("StartCollectors finish");
91     return true;
92 }
93 
IsCollectorStarted(int64_t eventId)94 bool DataCollection::IsCollectorStarted(int64_t eventId)
95 {
96     std::lock_guard<std::mutex> lock(mutex_);
97     auto it = eventIdToLoaderMap_.find(eventId);
98     return it != eventIdToLoaderMap_.end();
99 }
100 
StopCollectors(const std::vector<int64_t> & eventIds)101 bool DataCollection::StopCollectors(const std::vector<int64_t>& eventIds)
102 {
103     LOGI("StopCollectors start");
104     if (eventIds.empty()) {
105         LOGW("The eventId list is empty");
106         return true;
107     }
108     bool ret = true;
109     std::lock_guard<std::mutex> lock(mutex_);
110     for (int64_t eventId : eventIds) {
111         LOGI("StopCollectors eventId is 0x%{public}" PRIx64, eventId);
112         auto loader = eventIdToLoaderMap_.find(eventId);
113         if (loader == eventIdToLoaderMap_.end()) {
114             LOGI("Collector not found, eventId is 0x%{public}" PRIx64, eventId);
115             continue;
116         }
117         ICollector* collector = loader->second.CallGetCollector();
118         if (collector == nullptr) {
119             LOGE("CallGetCollector error");
120             ret = false;
121         } else {
122             int result = collector->Stop();
123             int isStartWithSub = collector->IsStartWithSub();
124             if (isStartWithSub == 1) {
125                 result = collector->Unsubscribe(eventId);
126             }
127             if (result != 0) {
128                 LOGE("Failed to stop collector, eventId is 0x%{public}" PRIx64, eventId);
129                 ret = false;
130             }
131             LOGI("Stop collector");
132             eventIdToLoaderMap_.erase(loader);
133         }
134     }
135     LOGI("StopCollectors finish");
136     return ret;
137 }
138 
CloseLib()139 void DataCollection::CloseLib()
140 {
141     std::lock_guard<std::mutex> lock(closeLibmutex_);
142     for (auto &it : needCloseLibMap_) {
143         it.second.UnLoadLib();
144     }
145     needCloseLibMap_.clear();
146 }
LoadCollector(int64_t eventId,std::string path,std::shared_ptr<ICollectorFwk> api)147 ErrorCode DataCollection::LoadCollector(int64_t eventId, std::string path, std::shared_ptr<ICollectorFwk> api)
148 {
149     LOGI("Start LoadCollector");
150     LibLoader loader(path);
151     ErrorCode ret = loader.LoadLib();
152     if (ret != SUCCESS) {
153         LOGE("LoadLib error, ret=%{public}d, path : %{public}s", ret, path.c_str());
154         return FAILED;
155     }
156     {
157         std::lock_guard<std::mutex> lock(closeLibmutex_);
158         needCloseLibMap_.emplace(eventId, loader);
159     }
160     ICollector* collector = loader.CallGetCollector();
161     if (collector == nullptr) {
162         LOGE("CallGetCollector error");
163         return FAILED;
164     }
165     int result = collector->Start(api);
166     int isStartWithSub = collector->IsStartWithSub();
167     if (isStartWithSub == 1) {
168         result = collector->Subscribe(eventId);
169     }
170     if (result != 0) {
171         LOGE("Failed to start collector");
172         return FAILED;
173     }
174     std::lock_guard<std::mutex> lock(mutex_);
175     eventIdToLoaderMap_.emplace(eventId, loader);
176     LOGI("End LoadCollector");
177     return SUCCESS;
178 }
179 
GetCollectorPath(int64_t eventId,std::string & path)180 ErrorCode DataCollection::GetCollectorPath(int64_t eventId, std::string& path)
181 {
182     LOGI("Start GetCollectorPath");
183     std::ifstream stream(SA_CONFIG_PATH, std::ios::in);
184     if (!stream.is_open()) {
185         LOGE("Stream error, %{public}s", strerror(errno));
186         return STREAM_ERROR;
187     }
188     ErrorCode ret = CheckFileStream(stream);
189     if (ret != SUCCESS) {
190         LOGE("check file stream error, ret=%{public}d", ret);
191         stream.close();
192         return ret;
193     }
194     nlohmann::json json = nlohmann::json::parse(stream, nullptr, false);
195     stream.close();
196 
197     if (json.is_discarded()) {
198         LOGE("json is discarded");
199         return JSON_ERR;
200     }
201 
202     std::vector<ModuleCfgSt> moduleCfgs;
203     if (!SecurityGuard::JsonCfg::Unmarshal<ModuleCfgSt>(moduleCfgs, json, MODULES)) {
204         LOGE("Unmarshal moduleCfgs error");
205         return JSON_ERR;
206     }
207 
208     auto it = std::find_if(moduleCfgs.begin(), moduleCfgs.end(),
209         [eventId] (const ModuleCfgSt &module) {
210             auto ifIt = std::find(module.eventId.begin(), module.eventId.end(), eventId);
211             if (ifIt != module.eventId.end()) {
212                 LOGI("success to find the event id: 0x%{public}" PRIx64, eventId);
213                 return true;
214             } else {
215                 return false;
216             }
217         });
218     if (it != moduleCfgs.end()) {
219         path = it->modulePath + it->moduleName;
220         return SUCCESS;
221     }
222 
223     LOGE("The eventId does not exist");
224     return FAILED;
225 }
226 
GetCollectorType(int64_t eventId,int32_t & collectorType)227 ErrorCode DataCollection::GetCollectorType(int64_t eventId, int32_t& collectorType)
228 {
229     LOGI("Start GetCollectorType");
230     std::ifstream stream(SA_CONFIG_PATH, std::ios::in);
231     if (!stream.is_open()) {
232         LOGE("Stream error, %{public}s", strerror(errno));
233         return STREAM_ERROR;
234     }
235 
236     ErrorCode ret = CheckFileStream(stream);
237     if (ret != SUCCESS) {
238         LOGE("check file stream error, ret=%{public}d", ret);
239         stream.close();
240         return ret;
241     }
242 
243     nlohmann::json json = nlohmann::json::parse(stream, nullptr, false);
244     stream.close();
245 
246     if (json.is_discarded()) {
247         LOGE("json is discarded");
248         return JSON_ERR;
249     }
250 
251     std::vector<ModuleCfgSt> moduleCfgs;
252     if (!SecurityGuard::JsonCfg::Unmarshal<ModuleCfgSt>(moduleCfgs, json, MODULES)) {
253         LOGE("Unmarshal moduleCfgs error");
254         return JSON_ERR;
255     }
256 
257     auto it = std::find_if(moduleCfgs.begin(), moduleCfgs.end(),
258         [eventId] (const ModuleCfgSt &module) {
259             auto ifIt = std::find(module.eventId.begin(), module.eventId.end(), eventId);
260             if (ifIt != module.eventId.end()) {
261                 return true;
262             } else {
263                 return false;
264             }
265         });
266     if (it != moduleCfgs.end()) {
267         collectorType = it->collectorType;
268         LOGI("get event 0x%{public}" PRIx64 "collector type is %{public}d.", eventId, collectorType);
269         return SUCCESS;
270     }
271 
272     LOGE("The eventId does not exist");
273     return FAILED;
274 }
275 
CheckFileStream(std::ifstream & stream)276 ErrorCode DataCollection::CheckFileStream(std::ifstream &stream)
277 {
278     if (!stream.is_open()) {
279         LOGE("stream open error, %{public}s", strerror(errno));
280         return STREAM_ERROR;
281     }
282 
283     stream.seekg(0, std::ios::end);
284     std::ios::pos_type len = stream.tellg();
285     if (len == 0) {
286         LOGE("stream is empty");
287         return STREAM_ERROR;
288     }
289     stream.seekg(0, std::ios::beg);
290     return SUCCESS;
291 }
292 
LoadCollector(std::string path,const SecurityEventRuler & ruler,std::vector<SecurityEvent> & events)293 ErrorCode DataCollection::LoadCollector(std::string path, const SecurityEventRuler &ruler,
294     std::vector<SecurityEvent> &events)
295 {
296     LOGI("Start LoadCollector");
297     LibLoader loader(path);
298     ErrorCode ret = loader.LoadLib();
299     if (ret != SUCCESS) {
300         LOGE("LoadLib error, ret=%{public}d", ret);
301         return FAILED;
302     }
303     {
304         std::lock_guard<std::mutex> lock(closeLibmutex_);
305         needCloseLibMap_.emplace(ruler.GetEventId(), loader);
306     }
307     ICollector* collector = loader.CallGetCollector();
308     if (collector == nullptr) {
309         LOGE("CallGetCollector error");
310         return FAILED;
311     }
312     int result = collector->Query(ruler, events);
313     if (result != 0) {
314         LOGE("Failed to start collector");
315         return FAILED;
316     }
317     LOGI("End LoadCollector");
318     return SUCCESS;
319 }
320 
QuerySecurityEvent(const std::vector<SecurityEventRuler> rulers,std::vector<SecurityEvent> & events)321 int32_t DataCollection::QuerySecurityEvent(const std::vector<SecurityEventRuler> rulers,
322     std::vector<SecurityEvent> &events)
323 {
324     LOGI("QuerySecurityEvent start");
325     if (rulers.empty()) {
326         LOGE("Invalid input parameter");
327         return false;
328     }
329     for (const auto &ruler : rulers) {
330         LOGI("QuerySecurityEvent eventId is 0x%{public}" PRIx64, ruler.GetEventId());
331         std::string collectorPath;
332         ErrorCode ret = GetCollectorPath(ruler.GetEventId(), collectorPath);
333         if (ret != SUCCESS) {
334             LOGE("GetCollectorPath failed, eventId is 0x%{public}" PRIx64, ruler.GetEventId());
335             return false;
336         }
337         ret = LoadCollector(collectorPath, ruler, events);
338         if (ret != SUCCESS) {
339             LOGE("Load collector failed, eventId is 0x%{public}" PRIx64, ruler.GetEventId());
340             return false;
341         }
342     }
343     LOGI("StartCollectors finish");
344     return true;
345 }
346 
Mute(const SecurityCollectorEventMuteFilter & filter,const std::string & sdkFlag)347 bool DataCollection::Mute(const SecurityCollectorEventMuteFilter &filter, const std::string &sdkFlag)
348 {
349     if (!IsCollectorStarted(filter.eventId)) {
350         LOGE("collector not start, eventId is 0x%{public}" PRIx64, filter.eventId);
351         return false;
352     }
353     std::lock_guard<std::mutex> lock(mutex_);
354     auto loader = eventIdToLoaderMap_.at(filter.eventId);
355     ICollector* collector = loader.CallGetCollector();
356     if (collector == nullptr) {
357         LOGE("CallGetCollector error");
358         return false;
359     }
360     if (collector->Mute(filter, sdkFlag) != 0) {
361         LOGE("fail to set mute to collector, eventId is 0x%{public}" PRIx64, filter.eventId);
362         return false;
363     }
364     return true;
365 }
366 
Unmute(const SecurityCollectorEventMuteFilter & filter,const std::string & sdkFlag)367 bool DataCollection::Unmute(const SecurityCollectorEventMuteFilter &filter, const std::string &sdkFlag)
368 {
369     if (!IsCollectorStarted(filter.eventId)) {
370         LOGE("collector not start, eventId is 0x%{public}" PRIx64, filter.eventId);
371         return false;
372     }
373     std::lock_guard<std::mutex> lock(mutex_);
374     auto loader = eventIdToLoaderMap_.at(filter.eventId);
375     ICollector* collector = loader.CallGetCollector();
376     if (collector == nullptr) {
377         LOGE("CallGetCollector error");
378         return false;
379     }
380     if (collector->Unmute(filter, sdkFlag) != 0) {
381         LOGE("fail to set unmute to collector, eventId is 0x%{public}" PRIx64, filter.eventId);
382         return false;
383     }
384     return true;
385 }
386 }