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 23using namespace OHOS::NativeRdb; 24 25namespace OHOS { 26namespace NetManagerStandard { 27std::shared_ptr<NetFirewallDataBase> NetFirewallDataBase::instance_ = nullptr; 28 29NetFirewallDataBase::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 61std::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 71int32_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 85int32_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 99int32_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 113int64_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 139int32_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 165int32_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 190std::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 200int32_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 209std::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 219void 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 243bool 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 268bool 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 290int32_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 307int32_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 316int32_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