1 /*
2 * Copyright (C) 2025 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 #include "net_policy_db_clone.h"
16 #include <sstream>
17 #include <sys/stat.h>
18 #include <sys/sendfile.h>
19 #include <iostream>
20 #include <fstream>
21 #include <fcntl.h>
22 #include "iservice_registry.h"
23 #include "net_manager_constants.h"
24 #include "netmanager_base_common_utils.h"
25 #include "system_ability_definition.h"
26 #include "net_access_policy_rdb.h"
27 #include "net_policy_core.h"
28 #include "net_mgr_log_wrapper.h"
29 #include "net_policy_rule.h"
30 #include "net_bundle_impl.h"
31 #include "bundle_mgr_interface.h"
32 #include "bundle_mgr_proxy.h"
33
34 namespace OHOS {
35 namespace NetManagerStandard {
36 namespace {
37 const int32_t MAIN_USER_ID = 100;
38 const int32_t NET_ACCESS_POLICY_ALLOW_VALUE = 1;
GetBundleMgrProxy()39 sptr<AppExecFwk::BundleMgrProxy> GetBundleMgrProxy()
40 {
41 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
42 if (!systemAbilityManager) {
43 NETMGR_LOG_E("fail to get system ability mgr.");
44 return nullptr;
45 }
46
47 auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
48 if (!remoteObject) {
49 NETMGR_LOG_E("fail to get bundle manager proxy.");
50 return nullptr;
51 }
52
53 sptr<AppExecFwk::BundleMgrProxy> bundleMgrProxy = iface_cast<AppExecFwk::BundleMgrProxy>(remoteObject);
54 if (bundleMgrProxy == nullptr) {
55 NETMGR_LOG_E("Failed to get bundle manager proxy.");
56 return nullptr;
57 }
58 return bundleMgrProxy;
59 }
60 }
61
GetInstance()62 NetPolicyDBClone &NetPolicyDBClone::GetInstance()
63 {
64 static NetPolicyDBClone gNetPolicyDBClone;
65 return gNetPolicyDBClone;
66 }
67
OnBackup(UniqueFd & fd,const std::string & backupInfo)68 int32_t NetPolicyDBClone::OnBackup(UniqueFd &fd, const std::string &backupInfo)
69 {
70 NetAccessPolicyRDB netAccessPolicyRdb;
71 std::vector<NetAccessPolicyData> result = netAccessPolicyRdb.QueryAll();
72 NETMGR_LOG_I("OnBackup size: %{public}zu", result.size());
73
74 std::string content;
75 std::ostringstream ss;
76 sptr<AppExecFwk::BundleMgrProxy> bundleMgrProxy = GetBundleMgrProxy();
77 if (bundleMgrProxy == nullptr) {
78 NETMGR_LOG_E("Failed to get bundle manager proxy.");
79 return NETMANAGER_ERR_INTERNAL;
80 }
81 for (size_t i = 0; i < result.size(); i++) {
82 if (result[i].wifiPolicy && result[i].cellularPolicy) {
83 continue;
84 }
85 std::string uidBundleName;
86 if (bundleMgrProxy->GetNameForUid(result[i].uid, uidBundleName) != ERR_OK) {
87 NETMGR_LOG_E("GetNameForUid error. uid:%{public}d", result[i].uid);
88 continue;
89 }
90 ss << uidBundleName << " " << result[i].wifiPolicy << " " << result[i].cellularPolicy << std::endl;
91 }
92 content = ss.str();
93 bool writeRet = CommonUtils::WriteFile(POLICY_DATABASE_BACKUP_FILE, content);
94 if (!writeRet) {
95 return -1;
96 }
97
98 fd = UniqueFd(open(POLICY_DATABASE_BACKUP_FILE, O_RDONLY));
99 if (fd.Get() < 0) {
100 NETMGR_LOG_E("OnBackup open fail.");
101 return -1;
102 }
103 NETMGR_LOG_I("OnBackup end. fd: %{public}d.", fd.Get());
104 return 0;
105 }
106
OnRestore(UniqueFd & fd,const std::string & backupInfo)107 int32_t NetPolicyDBClone::OnRestore(UniqueFd &fd, const std::string &backupInfo)
108 {
109 if (!FdClone(fd)) {
110 return -1;
111 }
112
113 std::ifstream file;
114 file.open(POLICY_DATABASE_BACKUP_FILE);
115 if (!file.is_open()) {
116 NETMGR_LOG_E("Failed to open backup file");
117 return -1;
118 }
119
120 sptr<AppExecFwk::BundleMgrProxy> bundleMgrProxy = GetBundleMgrProxy();
121 if (bundleMgrProxy == nullptr) {
122 NETMGR_LOG_E("Failed to get bundle manager proxy.");
123 return NETMANAGER_ERR_INTERNAL;
124 }
125 std::shared_ptr<NetPolicyRule> netPolicyRule =
126 DelayedSingleton<NetPolicyCore>::GetInstance()->CreateCore<NetPolicyRule>();
127 if (netPolicyRule == nullptr) {
128 return -1;
129 }
130
131 std::string line;
132 NetAccessPolicyRDB netAccessPolicyRdb;
133 while (std::getline(file, line)) {
134 std::istringstream iss(line);
135 std::string bundleName;
136 NetAccessPolicyData policyData;
137 if (!(iss >> bundleName >> policyData.wifiPolicy >> policyData.cellularPolicy)) {
138 NETMGR_LOG_E("istringstream error");
139 continue;
140 }
141 policyData.uid = bundleMgrProxy->GetUidByBundleName(bundleName, MAIN_USER_ID);
142 if (policyData.uid == -1) {
143 NETMGR_LOG_E("Failed to get uid from bundleName. [%{public}s]", bundleName.c_str());
144 continue;
145 }
146 policyData.setFromConfigFlag = 1;
147 int32_t insertRet = netAccessPolicyRdb.InsertData(policyData);
148 if (insertRet != NETMANAGER_SUCCESS) {
149 NETMGR_LOG_E("insert error");
150 continue;
151 }
152 NetworkAccessPolicy policy;
153 policy.wifiAllow = policyData.wifiPolicy == NET_ACCESS_POLICY_ALLOW_VALUE ? true : false;
154 policy.cellularAllow = policyData.cellularPolicy == NET_ACCESS_POLICY_ALLOW_VALUE ? true : false;
155 (void)netPolicyRule->SetNetworkAccessPolicy(policyData.uid, policy, true);
156 }
157
158 file.close();
159 return 0;
160 }
161
FdClone(UniqueFd & fd)162 bool NetPolicyDBClone::FdClone(UniqueFd &fd)
163 {
164 struct stat statBuf;
165 if (fd.Get() < 0 || fstat(fd.Get(), &statBuf) < 0) {
166 NETMGR_LOG_E("OnRestore fstat fd fail.");
167 return false;
168 }
169
170 int destFd = open(POLICY_DATABASE_BACKUP_FILE, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
171 if (destFd < 0) {
172 NETMGR_LOG_E("OnRestore open file fail.");
173 return false;
174 }
175 if (sendfile(destFd, fd.Get(), nullptr, statBuf.st_size) < 0) {
176 NETMGR_LOG_E("OnRestore fd sendfile(size: %{public}d) to destFd fail.",
177 static_cast<int>(statBuf.st_size));
178 close(destFd);
179 return false;
180 }
181 close(destFd);
182 return true;
183 }
184
185 }
186 }
187