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 "audit_event_mem_rdb_helper.h"
17
18 #include "rdb_predicates.h"
19
20 #include "audit_event_rdb_helper.h"
21 #include "config_data_manager.h"
22 #include "config_define.h"
23 #include "rdb_event_store_callback.h"
24 #include "security_guard_define.h"
25 #include "security_guard_log.h"
26 #include "security_guard_utils.h"
27
28 namespace OHOS::Security::SecurityGuard {
29 namespace {
30 constexpr uint32_t FLUSH_INTERVAL = 60 * 1000;
31 constexpr uint32_t DELETE_INTERVAL = 10000; // 1 hour
32 }
33
GetInstance()34 DatabaseHelper &AuditEventMemRdbHelper::GetInstance()
35 {
36 static AuditEventMemRdbHelper auditMemInstance;
37 static DatabaseHelper &instance = auditMemInstance;
38 return instance;
39 }
40
AuditEventMemRdbHelper()41 AuditEventMemRdbHelper::AuditEventMemRdbHelper() : DatabaseHelper("audit_event_mem")
42 {
43 dbPath_ = FOLDER_PATH + "audit_event_mem.db";
44 }
45
~AuditEventMemRdbHelper()46 AuditEventMemRdbHelper::~AuditEventMemRdbHelper()
47 {
48 Release();
49 }
50
Init()51 int AuditEventMemRdbHelper::Init()
52 {
53 int errCode = NativeRdb::E_ERROR;
54 NativeRdb::RdbStoreConfig config(dbPath_);
55 config.SetStorageMode(NativeRdb::StorageMode::MODE_MEMORY);
56 config.SetSecurityLevel(NativeRdb::SecurityLevel::S2);
57 std::string table = CreateTable();
58 std::vector<std::string> createTableVec;
59 createTableVec.push_back(table);
60 RdbEventStoreCallback callback(createTableVec);
61 CreateRdbStore(config, DB_VERSION, callback, errCode);
62 if (errCode != NativeRdb::E_OK) {
63 SGLOGE("create rdb store error, code=%{public}d", errCode);
64 return errCode;
65 }
66 errCode = Attach("audit_event_attach", FOLDER_PATH + "audit_event.db", {});
67 if (errCode != NativeRdb::E_OK) {
68 SGLOGE("attach audit_event error, code=%{public}d", errCode);
69 return errCode;
70 }
71
72 timer_.Setup();
73 timerId_ = timer_.Register([this] { this->FlushAllEvent(); }, FLUSH_INTERVAL);
74 return errCode;
75 }
76
Release()77 void AuditEventMemRdbHelper::Release()
78 {
79 if (timerId_ != 0) {
80 timer_.Unregister(timerId_);
81 }
82 timer_.Shutdown();
83 (void)FlushAllEvent();
84 }
85
QueryAllEvent(std::vector<SecEvent> & events)86 int AuditEventMemRdbHelper::QueryAllEvent(std::vector<SecEvent> &events)
87 {
88 NativeRdb::RdbPredicates predicates(AUDIT_TABLE);
89 int ret = QueryEventBase(predicates, events);
90 if (ret != NativeRdb::E_OK) {
91 SGLOGI("failed to query event, table=%{public}s, ret=%{public}d", AUDIT_TABLE, ret);
92 return DB_OPT_ERR;
93 }
94
95 NativeRdb::RdbPredicates predicates2(dbTable_);
96 ret = QueryEventBase(predicates, events);
97 if (ret != NativeRdb::E_OK) {
98 SGLOGI("failed to query event, table=%{public}s, ret=%{public}d", dbTable_.c_str(), ret);
99 return DB_OPT_ERR;
100 }
101 return SUCCESS;
102 }
103
QueryAllEventFromMem(std::vector<SecEvent> & events)104 int AuditEventMemRdbHelper::QueryAllEventFromMem(std::vector<SecEvent> &events)
105 {
106 return DatabaseHelper::QueryAllEvent(events);
107 }
108
QueryEventFromMemByDate(std::vector<SecEvent> & events,std::string date)109 int AuditEventMemRdbHelper::QueryEventFromMemByDate(std::vector<SecEvent> &events, std::string date)
110 {
111 NativeRdb::RdbPredicates predicates(dbTable_);
112 predicates.LessThan(DATE, date);
113 std::vector<std::string> columns { EVENT_ID, VERSION, DATE, CONTENT, USER_ID, DEVICE_ID };
114 std::shared_ptr<NativeRdb::ResultSet> resultSet = Query(predicates, columns);
115 if (resultSet == nullptr) {
116 SGLOGI("failed to get event");
117 return DB_OPT_ERR;
118 }
119 SecEventTableInfo table;
120 int32_t ret = GetResultSetTableInfo(resultSet, table);
121 if (ret != SUCCESS) {
122 return ret;
123 }
124 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
125 SecEvent event;
126 resultSet->GetLong(table.eventIdIndex, event.eventId);
127 resultSet->GetString(table.versionIndex, event.version);
128 resultSet->GetString(table.dateIndex, event.date);
129 resultSet->GetString(table.contentIndex, event.content);
130 resultSet->GetInt(table.userIdIndex, event.userId);
131 resultSet->GetString(table.deviceIdIndex, event.deviceId);
132 events.emplace_back(event);
133 }
134 resultSet->Close();
135 return SUCCESS;
136 }
137
DeleteRedundantData(const std::unordered_map<int64_t,int64_t> & countMap)138 void AuditEventMemRdbHelper::DeleteRedundantData(const std::unordered_map<int64_t, int64_t> &countMap)
139 {
140 for (const auto &entry : countMap) {
141 EventCfg config;
142 (void) ConfigDataManager::GetInstance().GetEventConfig(entry.first, config);
143 int64_t count = AuditEventRdbHelper::GetInstance().CountEventByEventId(entry.first);
144 if (count + entry.second >= config.storageRomNums) {
145 (void) AuditEventRdbHelper::GetInstance().DeleteOldEventByEventId(entry.first,
146 count + entry.second - config.storageRomNums);
147 }
148 }
149 }
150
DeleteFlushDataFromMem(std::string date)151 int AuditEventMemRdbHelper::DeleteFlushDataFromMem(std::string date)
152 {
153 NativeRdb::RdbPredicates predicates(dbTable_);
154 predicates.LessThan(DATE, date);
155 int32_t deleteRows;
156 int ret = Delete(deleteRows, predicates);
157 if (ret != NativeRdb::E_OK) {
158 SGLOGI("failed to delete event, ret=%{public}d", ret);
159 }
160 return ret;
161 }
162
DeleteExpiredDataFromMain(std::string date)163 int AuditEventMemRdbHelper::DeleteExpiredDataFromMain(std::string date)
164 {
165 NativeRdb::RdbPredicates predicateDel(AUDIT_TABLE);
166 int64_t time;
167 SecurityGuardUtils::StrToI64(date, time);
168 time -= DELETE_INTERVAL;
169 predicateDel.LessThan(DATE, std::to_string(time));
170 int32_t deleteRows;
171 int ret = Delete(deleteRows, predicateDel);
172 if (ret != NativeRdb::E_OK) {
173 SGLOGI("failed to delete event, ret=%{public}d", ret);
174 }
175 return ret;
176 }
177
FlushAllEvent()178 int AuditEventMemRdbHelper::FlushAllEvent()
179 {
180 SGLOGD("begin flush event from mem to file");
181 std::vector<SecEvent> events;
182 std::string date = SecurityGuardUtils::GetDate();
183 int ret = QueryEventFromMemByDate(events, date);
184 if (ret != NativeRdb::E_OK) {
185 SGLOGI("failed to query event, ret=%{public}d", ret);
186 return DB_OPT_ERR;
187 }
188 std::vector<NativeRdb::ValuesBucket> values;
189 std::unordered_map<int64_t, int64_t> countMap;
190 SGLOGD("flush event size is %{public}d", static_cast<int>(events.size()));
191 for (const SecEvent &event : events) {
192 countMap[event.eventId]++;
193 NativeRdb::ValuesBucket value;
194 SetValuesBucket(event, value);
195 values.emplace_back(value);
196 }
197
198 DeleteRedundantData(countMap);
199 countMap.clear();
200
201 int64_t rowId;
202 ret = BatchInsert(rowId, AUDIT_TABLE, values);
203 if (ret != NativeRdb::E_OK) {
204 SGLOGE("failed to batch insert event, ret=%{public}d", ret);
205 return DB_OPT_ERR;
206 }
207
208 ret = DeleteFlushDataFromMem(date);
209 if (ret != NativeRdb::E_OK) {
210 SGLOGE("failed to delete flush event, ret=%{public}d", ret);
211 return DB_OPT_ERR;
212 }
213
214 ret = DeleteExpiredDataFromMain(date);
215 if (ret != NativeRdb::E_OK) {
216 SGLOGE("failed to delete expired event, ret=%{public}d", ret);
217 return DB_OPT_ERR;
218 }
219 return SUCCESS;
220 }
221 } // namespace OHOS::Security::SecurityGuard