1 /*
2 * Copyright (c) 2024 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 <filesystem>
17 #include <system_error>
18
19 #include "hilog/log.h"
20 #include "netmgr_ext_log_wrapper.h"
21 #include "netfirewall_database.h"
22
23 using namespace OHOS::NativeRdb;
24
25 namespace OHOS {
26 namespace NetManagerStandard {
27 std::shared_ptr<NetFirewallDataBase> NetFirewallDataBase::instance_ = nullptr;
28
NetFirewallDataBase()29 NetFirewallDataBase::NetFirewallDataBase()
30 {
31 if (!std::filesystem::exists(FIREWALL_DB_PATH)) {
32 std::error_code ec;
33 if (std::filesystem::create_directories(FIREWALL_DB_PATH, ec)) {
34 NETMGR_EXT_LOG_D("create_directories success :%{public}s", FIREWALL_DB_PATH.c_str());
35 } else {
36 NETMGR_EXT_LOG_E("create_directories error :%{public}s : %s", FIREWALL_DB_PATH.c_str(),
37 ec.message().c_str());
38 }
39 }
40 std::string firewallDatabaseName = FIREWALL_DB_PATH + FIREWALL_DB_NAME;
41 int32_t errCode = OHOS::NativeRdb::E_OK;
42 OHOS::NativeRdb::RdbStoreConfig config(firewallDatabaseName);
43 config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
44 NetFirewallDataBaseCallBack sqliteOpenHelperCallback;
45 store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION, sqliteOpenHelperCallback, errCode);
46 if (errCode == OHOS::NativeRdb::E_SQLITE_CORRUPT) {
47 if (!RestoreDatabaseWhenInit()) {
48 NETMGR_EXT_LOG_E("Create and restore db error");
49 return;
50 }
51 NETMGR_EXT_LOG_I("Create db error, restore db success");
52 errCode = OHOS::NativeRdb::E_OK;
53 }
54 if (errCode != OHOS::NativeRdb::E_OK) {
55 NETMGR_EXT_LOG_E("GetRdbStore errCode :%{public}d", errCode);
56 } else {
57 NETMGR_EXT_LOG_D("GetRdbStore success :%{public}d", errCode);
58 }
59 }
60
GetInstance()61 std::shared_ptr<NetFirewallDataBase> NetFirewallDataBase::GetInstance()
62 {
63 if (instance_ == nullptr) {
64 NETMGR_EXT_LOG_W("reset to new instance");
65 instance_.reset(new NetFirewallDataBase());
66 return instance_;
67 }
68 return instance_;
69 }
70
BeginTransaction()71 int32_t NetFirewallDataBase::BeginTransaction()
72 {
73 if (store_ == nullptr) {
74 NETMGR_EXT_LOG_E("BeginTransaction store_ is nullptr");
75 return FIREWALL_RDB_NO_INIT;
76 }
77 int32_t ret = store_->BeginTransaction();
78 if (ret != OHOS::NativeRdb::E_OK) {
79 NETMGR_EXT_LOG_E("BeginTransaction fail :%{public}d", ret);
80 return FIREWALL_RDB_EXECUTE_FAILTURE;
81 }
82 return FIREWALL_OK;
83 }
84
Commit()85 int32_t NetFirewallDataBase::Commit()
86 {
87 if (store_ == nullptr) {
88 NETMGR_EXT_LOG_E("Commit store_ is nullptr");
89 return FIREWALL_RDB_NO_INIT;
90 }
91 int32_t ret = store_->Commit();
92 if (ret != OHOS::NativeRdb::E_OK) {
93 NETMGR_EXT_LOG_E("Commit fail :%{public}d", ret);
94 return FIREWALL_RDB_EXECUTE_FAILTURE;
95 }
96 return FIREWALL_OK;
97 }
98
RollBack()99 int32_t NetFirewallDataBase::RollBack()
100 {
101 if (store_ == nullptr) {
102 NETMGR_EXT_LOG_E("RollBack store_ is nullptr");
103 return FIREWALL_RDB_NO_INIT;
104 }
105 int32_t ret = store_->RollBack();
106 if (ret != OHOS::NativeRdb::E_OK) {
107 NETMGR_EXT_LOG_E("RollBack fail :%{public}d", ret);
108 return FIREWALL_RDB_EXECUTE_FAILTURE;
109 }
110 return FIREWALL_OK;
111 }
112
Insert(const OHOS::NativeRdb::ValuesBucket &insertValues, const std::string tableName)113 int64_t NetFirewallDataBase::Insert(const OHOS::NativeRdb::ValuesBucket &insertValues, const std::string tableName)
114 {
115 if (store_ == nullptr) {
116 NETMGR_EXT_LOG_E("Insert store_ is nullptr");
117 return FIREWALL_RDB_NO_INIT;
118 }
119 int64_t outRowId = 0;
120 int32_t ret = store_->Insert(outRowId, tableName, insertValues);
121 NETMGR_EXT_LOG_D("Insert id=%{public}" PRIu64 "", outRowId);
122 if (ret == OHOS::NativeRdb::E_SQLITE_CORRUPT) {
123 NETMGR_EXT_LOG_E("Insert error, restore db");
124 if (RestoreDatabase()) {
125 int32_t ret = store_->Insert(outRowId, tableName, insertValues);
126 }
127 }
128 if (ret != OHOS::NativeRdb::E_OK) {
129 NETMGR_EXT_LOG_E("Insert ret :%{public}d", ret);
130 return FIREWALL_RDB_EXECUTE_FAILTURE;
131 }
132 if (tableName == FIREWALL_TABLE_NAME) {
133 BackupDatebase();
134 }
135 return outRowId;
136 }
137
138
Update(const std::string &tableName, int32_t &changedRows, const OHOS::NativeRdb::ValuesBucket &values, const std::string &whereClause, const std::vector<std::string> &whereArgs)139 int32_t NetFirewallDataBase::Update(const std::string &tableName, int32_t &changedRows,
140 const OHOS::NativeRdb::ValuesBucket &values, const std::string &whereClause,
141 const std::vector<std::string> &whereArgs)
142 {
143 if (store_ == nullptr) {
144 NETMGR_EXT_LOG_E("Update(whereClause) store_ is nullptr");
145 return FIREWALL_RDB_NO_INIT;
146 }
147 int32_t ret = store_->Update(changedRows, tableName, values, whereClause, whereArgs);
148 if (ret == OHOS::NativeRdb::E_SQLITE_CORRUPT) {
149 NETMGR_EXT_LOG_E("Update error, restore db");
150 if (RestoreDatabase()) {
151 int32_t ret = store_->Update(changedRows, tableName, values, whereClause, whereArgs);
152 }
153 }
154 if (ret != OHOS::NativeRdb::E_OK) {
155 NETMGR_EXT_LOG_E("Update(whereClause) ret :%{public}d", ret);
156 return FIREWALL_RDB_EXECUTE_FAILTURE;
157 }
158 if (tableName == FIREWALL_TABLE_NAME) {
159 BackupDatebase();
160 }
161 return FIREWALL_OK;
162 }
163
164
Delete(const std::string &tableName, int32_t &changedRows, const std::string &whereClause, const std::vector<std::string> &whereArgs)165 int32_t NetFirewallDataBase::Delete(const std::string &tableName, int32_t &changedRows, const std::string &whereClause,
166 const std::vector<std::string> &whereArgs)
167 {
168 if (store_ == nullptr) {
169 NETMGR_EXT_LOG_E("Delete store_ is nullptr");
170 return FIREWALL_RDB_NO_INIT;
171 }
172 int32_t ret = store_->Delete(changedRows, tableName, whereClause, whereArgs);
173 if (ret == OHOS::NativeRdb::E_SQLITE_CORRUPT) {
174 NETMGR_EXT_LOG_E("Delete error, restore db");
175 if (RestoreDatabase()) {
176 int32_t ret = store_->Delete(changedRows, tableName, whereClause, whereArgs);
177 }
178 }
179 if (ret != OHOS::NativeRdb::E_OK) {
180 NETMGR_EXT_LOG_E("Delete(whereClause) ret :%{public}d", ret);
181 return FIREWALL_RDB_EXECUTE_FAILTURE;
182 }
183 if (tableName == FIREWALL_TABLE_NAME) {
184 BackupDatebase();
185 }
186 return FIREWALL_OK;
187 }
188
189
Query( const OHOS::NativeRdb::AbsRdbPredicates &predicates, const std::vector<std::string> &columns)190 std::shared_ptr<OHOS::NativeRdb::ResultSet> NetFirewallDataBase::Query(
191 const OHOS::NativeRdb::AbsRdbPredicates &predicates, const std::vector<std::string> &columns)
192 {
193 if (store_ == nullptr) {
194 NETMGR_EXT_LOG_E("Query(AbsRdbPredicates) store_ is nullptr");
195 return nullptr;
196 }
197 return store_->Query(predicates, columns);
198 }
199
Count(int64_t &outValue, const OHOS::NativeRdb::AbsRdbPredicates &predicates)200 int32_t NetFirewallDataBase::Count(int64_t &outValue, const OHOS::NativeRdb::AbsRdbPredicates &predicates)
201 {
202 if (store_ == nullptr) {
203 NETMGR_EXT_LOG_E("Count(AbsRdbPredicates) store_ is nullptr");
204 return FIREWALL_RDB_NO_INIT;
205 }
206 return store_->Count(outValue, predicates);
207 }
208
QuerySql(const std::string &sql, const std::vector<std::string> &selectionArgs)209 std::shared_ptr<OHOS::NativeRdb::ResultSet> NetFirewallDataBase::QuerySql(const std::string &sql,
210 const std::vector<std::string> &selectionArgs)
211 {
212 if (store_ == nullptr) {
213 NETMGR_EXT_LOG_E("QuerySql(AbsRdbPredicates) store_ is nullptr");
214 return nullptr;
215 }
216 return store_->QuerySql(sql, selectionArgs);
217 }
218
BackupDatebase()219 void NetFirewallDataBase::BackupDatebase()
220 {
221 if (store_ == nullptr) {
222 NETMGR_EXT_LOG_E("store_ is null");
223 return;
224 }
225
226 if (backing_.exchange(true)) {
227 NETMGR_EXT_LOG_I("Backup is processing");
228 return;
229 }
230 std::string fileName = FIREWALL_DB_PATH + FIREWALL_BACKUP_DB_NAME;
231 std::thread thread([fileName, rdbStore = store_] {
232 auto errCode = rdbStore->Backup(fileName);
233 NetFirewallDataBase::GetInstance()->backing_ = false;
234 if (errCode != E_OK) {
235 NETMGR_EXT_LOG_E("Backup Datebase error");
236 return;
237 }
238 NETMGR_EXT_LOG_D("Backup Datebase success");
239 });
240 thread.detach();
241 }
242
RestoreDatabaseWhenInit()243 bool NetFirewallDataBase::RestoreDatabaseWhenInit()
244 {
245 std::string backupFile = FIREWALL_DB_PATH + FIREWALL_BACKUP_DB_NAME;
246 if (access(backupFile.c_str(), F_OK) != 0) {
247 NETMGR_EXT_LOG_I("Backup db is not exist");
248 return false;
249 }
250 std::string firewallFile = FIREWALL_DB_PATH + FIREWALL_DB_NAME;
251 if (rename(backupFile.c_str(), firewallFile.c_str()) != 0) {
252 return false;
253 }
254 int32_t errCode = OHOS::NativeRdb::E_OK;
255 OHOS::NativeRdb::RdbStoreConfig config(firewallFile);
256 config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
257 NetFirewallDataBaseCallBack sqliteOpenHelperCallback;
258 store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION, sqliteOpenHelperCallback, errCode);
259 if (errCode != OHOS::NativeRdb::E_OK) {
260 NETMGR_EXT_LOG_E("Restore GetRdbStore errCode :%{public}d", errCode);
261 return false;
262 } else {
263 NETMGR_EXT_LOG_D("Restore GetRdbStore success");
264 }
265 return true;
266 }
267
RestoreDatabase()268 bool NetFirewallDataBase::RestoreDatabase()
269 {
270 if (store_ == nullptr) {
271 NETMGR_EXT_LOG_E("store_ is null");
272 return false;
273 }
274 auto fileName = FIREWALL_DB_PATH + FIREWALL_BACKUP_DB_NAME;
275 if (access(fileName.c_str(), F_OK) != 0) {
276 NETMGR_EXT_LOG_I("Backup db is not exist");
277 return false;
278 }
279 int32_t errCode = store_->Restore(fileName);
280 if (errCode == E_OK) {
281 NETMGR_EXT_LOG_I("Restore db success");
282 return true;
283 }
284
285 // Failed to restore the db. Try to rebuild the db from the backup db.
286 store_ = nullptr;
287 return RestoreDatabaseWhenInit();
288 }
289
OnCreate(OHOS::NativeRdb::RdbStore &store)290 int32_t NetFirewallDataBaseCallBack::OnCreate(OHOS::NativeRdb::RdbStore &store)
291 {
292 std::map<std::string, std::string> netfirewallTableMap;
293 netfirewallTableMap.insert(std::pair<std::string, std::string>(FIREWALL_TABLE_NAME, CREATE_FIREWALL_TABLE));
294 netfirewallTableMap.insert(std::pair<std::string, std::string>(INTERCEPT_RECORD_TABLE, CREATE_RECORD_TABLE));
295 for (const auto &pair : netfirewallTableMap) {
296 std::string sql = pair.second;
297 int32_t ret = store.ExecuteSql(sql);
298 if (ret != OHOS::NativeRdb::E_OK) {
299 NETMGR_EXT_LOG_E("OnCreate %{public}s, failed: %{public}d", pair.first.c_str(), ret);
300 return FIREWALL_RDB_EXECUTE_FAILTURE;
301 }
302 NETMGR_EXT_LOG_D("DB OnCreate Done %{public}s ", pair.first.c_str());
303 }
304 return FIREWALL_OK;
305 }
306
OnUpgrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion)307 int32_t NetFirewallDataBaseCallBack::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion)
308 {
309 NETMGR_EXT_LOG_D("DB OnUpgrade Enter");
310 (void)store;
311 (void)oldVersion;
312 (void)newVersion;
313 return FIREWALL_OK;
314 }
315
OnDowngrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion)316 int32_t NetFirewallDataBaseCallBack::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion,
317 int32_t newVersion)
318 {
319 NETMGR_EXT_LOG_D("DB OnDowngrade Enter");
320 (void)store;
321 (void)oldVersion;
322 (void)newVersion;
323 return FIREWALL_OK;
324 }
325 } // namespace NetManagerStandard
326 } // namespace OHOS