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 }