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