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 "acquire_data_subscribe_manager.h"
17 
18 #include "acquire_data_callback_proxy.h"
19 #include "database_manager.h"
20 #include "security_guard_define.h"
21 #include "security_collector_subscribe_info.h"
22 #include "security_guard_log.h"
23 #include "task_handler.h"
24 #include "event_define.h"
25 #include "config_define.h"
26 #include "config_data_manager.h"
27 #include "collector_manager.h"
28 #include "data_collection.h"
29 namespace OHOS::Security::SecurityGuard {
GetInstance()30 AcquireDataSubscribeManager& AcquireDataSubscribeManager::GetInstance()
31 {
32     static AcquireDataSubscribeManager instance;
33     return instance;
34 }
35 
AcquireDataSubscribeManager()36 AcquireDataSubscribeManager::AcquireDataSubscribeManager() : listener_(std::make_shared<DbListener>()) {}
37 
InsertSubscribeRecord(const SecurityCollector::SecurityCollectorSubscribeInfo & subscribeInfo,const sptr<IRemoteObject> & callback)38 int AcquireDataSubscribeManager::InsertSubscribeRecord(
39     const SecurityCollector::SecurityCollectorSubscribeInfo &subscribeInfo, const sptr<IRemoteObject> &callback)
40 {
41     EventCfg config;
42     bool isSuccess = ConfigDataManager::GetInstance().GetEventConfig(subscribeInfo.GetEvent().eventId, config);
43     if (!isSuccess) {
44         SGLOGE("GetEventConfig error");
45         return BAD_PARAM;
46     }
47     int64_t event = subscribeInfo.GetEvent().eventId;
48     if (eventIdToSubscriberMap_.count(event)) {
49         eventIdToSubscriberMap_[subscribeInfo.GetEvent().eventId].insert(callback);
50         return SUCCESS;
51     }
52     int32_t code = DatabaseManager::GetInstance().SubscribeDb({subscribeInfo.GetEvent().eventId}, listener_);
53     if (code != SUCCESS) {
54         SGLOGE("SubscribeDb error");
55         return code;
56     }
57     code = SubscribeSc(event);
58     if (code != SUCCESS) {
59         SGLOGE("SubscribeSc error");
60         return code;
61     }
62     eventIdToSubscriberMap_[subscribeInfo.GetEvent().eventId].insert(callback);
63     SGLOGI("insert eventIdToSubscriberMap_ size %{public}zu", eventIdToSubscriberMap_.size());
64     for (auto iter : eventIdToSubscriberMap_) {
65         SGLOGI("insert eventIdToSubscriberMap_.callback size %{public}zu", iter.second.size());
66     }
67     return SUCCESS;
68 }
69 
SubscribeSc(int64_t eventId)70 int AcquireDataSubscribeManager::SubscribeSc(int64_t eventId)
71 {
72     if (scSubscribeMap_.count(eventId)) {
73         return SUCCESS;
74     }
75     EventCfg config;
76     bool isSuccess = ConfigDataManager::GetInstance().GetEventConfig(eventId, config);
77     if (!isSuccess) {
78         SGLOGE("GetEventConfig error");
79         return BAD_PARAM;
80     }
81     if (config.dbTable == "risk_event" && config.eventType == static_cast<uint32_t>(EventTypeEnum::SUBSCRIBE_COLL)) {
82         SecurityCollector::Event scEvent;
83         scEvent.eventId = eventId;
84         auto subscriber = std::make_shared<AcquireDataSubscribeManager::SecurityCollectorSubscriber>(scEvent);
85         // 订阅SG
86         if (config.prog == "security_guard") {
87             if (!SecurityCollector::DataCollection::GetInstance().SecurityGuardSubscribeCollector({eventId})) {
88                 SGLOGI("Subscribe SG failed, eventId=%{public}" PRId64 "", eventId);
89                 return FAILED;
90             }
91         } else {
92             // 订阅SC
93             int code = SecurityCollector::CollectorManager::GetInstance().Subscribe(subscriber);
94             if (code != SUCCESS) {
95                 SGLOGI("Subscribe SC failed, code=%{public}d", code);
96                 return code;
97             }
98         }
99         scSubscribeMap_[scEvent.eventId] = subscriber;
100     }
101     SGLOGI("SubscribeSc scSubscribeMap_size  %{public}zu", scSubscribeMap_.size());
102     return SUCCESS;
103 }
104 
UnSubscribeSc(int64_t eventId)105 int AcquireDataSubscribeManager::UnSubscribeSc(int64_t eventId)
106 {
107     EventCfg config;
108     bool isSuccess = ConfigDataManager::GetInstance().GetEventConfig(eventId, config);
109     if (!isSuccess) {
110         SGLOGE("GetEventConfig error");
111         return BAD_PARAM;
112     }
113     if (config.dbTable == "risk_event" && config.eventType == static_cast<uint32_t>(EventTypeEnum::SUBSCRIBE_COLL)) {
114         auto it = scSubscribeMap_.find(eventId);
115         if (it == scSubscribeMap_.end()) {
116             return FAILED;
117         }
118         // 解订阅SG
119         if (config.prog == "security_guard") {
120             if (!SecurityCollector::DataCollection::GetInstance().StopCollectors({eventId})) {
121                 SGLOGE("UnSubscribe SG failed, eventId=%{public}" PRId64 "", eventId);
122                 return FAILED;
123             }
124         } else {
125             // 解订阅SC
126             int ret = SecurityCollector::CollectorManager::GetInstance().Unsubscribe(it->second);
127             if (ret != SUCCESS) {
128                 SGLOGE("UnSubscribe SC failed, ret=%{public}d", ret);
129                 return ret;
130             }
131         }
132         it->second = nullptr;
133         scSubscribeMap_.erase(it);
134     }
135     SGLOGI("UnSubscribeSc scSubscribeMap_size  %{public}zu", scSubscribeMap_.size());
136     return SUCCESS;
137 }
138 
RemoveSubscribeRecord(const sptr<IRemoteObject> & callback)139 int AcquireDataSubscribeManager::RemoveSubscribeRecord(const sptr<IRemoteObject> &callback)
140 {
141     std::lock_guard<std::mutex> lock(mutex_);
142     for (auto iter = eventIdToSubscriberMap_.begin(); iter != eventIdToSubscriberMap_.end();) {
143         auto iterSet = iter->second.find(callback);
144         if (iterSet == iter->second.end()) {
145             ++iter;
146             continue;
147         }
148         iter->second.erase(iterSet);
149         if (iter->second.empty()) {
150             int ret = DatabaseManager::GetInstance().UnSubscribeDb({iter->first}, listener_);
151             if (ret != SUCCESS) {
152                 SGLOGE("UnSubscribeDb error");
153                 return ret;
154             }
155             ret = UnSubscribeSc(iter->first);
156             if (ret != SUCCESS) {
157                 SGLOGE("UnSubscribeSc error");
158                 return ret;
159             }
160             iter = eventIdToSubscriberMap_.erase(iter);
161             continue;
162         }
163         ++iter;
164     }
165     SGLOGI("remove eventIdToSubscriberMap_ size %{public}zu", eventIdToSubscriberMap_.size());
166     for (auto iter : eventIdToSubscriberMap_) {
167         SGLOGI("remove eventIdToSubscriberMap_.callback size %{public}zu", iter.second.size());
168     }
169     return SUCCESS;
170 }
171 
Publish(const SecEvent & events)172 bool AcquireDataSubscribeManager::Publish(const SecEvent &events)
173 {
174     std::lock_guard<std::mutex> lock(mutex_);
175     auto iter = eventIdToSubscriberMap_.find(events.eventId);
176     if (iter == eventIdToSubscriberMap_.end()) {
177         return true;
178     }
179     auto listerers = iter->second;
180     for (const auto &listener : listerers) {
181         auto proxy = iface_cast<IAcquireDataCallback>(listener);
182         if (proxy == nullptr) {
183             return false;
184         }
185         SecurityCollector::Event event {
186             .eventId = events.eventId,
187             .version = events.version,
188             .content = events.content,
189             .timestamp = events.date
190         };
191         SecurityGuard::TaskHandler::Task task = [proxy, event] () {
192             proxy->OnNotify(event);
193         };
194         if (event.eventId == SecurityCollector::FILE_EVENTID ||
195             event.eventId == SecurityCollector::PROCESS_EVENTID ||
196             event.eventId == SecurityCollector::NETWORK_EVENTID) {
197             SecurityGuard::TaskHandler::GetInstance()->AddMinorsTask(task);
198         } else {
199             SecurityGuard::TaskHandler::GetInstance()->AddTask(task);
200         }
201     }
202     return true;
203 }
204 
OnChange(uint32_t optType,const SecEvent & events)205 void AcquireDataSubscribeManager::DbListener::OnChange(uint32_t optType, const SecEvent &events)
206 {
207     AcquireDataSubscribeManager::GetInstance().Publish(events);
208 }
209 }