1 /* 2 * Copyright (C) 2022 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 "firewall_manager.h" 17 18 #include <fstream> 19 #include <sstream> 20 21 #include "iptables_wrapper.h" 22 #include "net_manager_constants.h" 23 #include "netnative_log_wrapper.h" 24 25 namespace OHOS { 26 namespace nmd { 27 using namespace NetManagerStandard; 28 namespace { 29 static constexpr const char *CONFIG_FILE_PATH = "/proc/self/uid_map"; SetFireWallCommand(const std::string & chainName,std::string command)30 bool SetFireWallCommand(const std::string &chainName, std::string command) 31 { 32 bool ret = false; 33 ret = ret || 34 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 35 36 command = "-t filter -A " + chainName + " -i lo -j RETURN"; 37 ret = ret || 38 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 39 command = "-t filter -A " + chainName + " -o lo -j RETURN"; 40 ret = ret || 41 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 42 command = "-t filter -A " + chainName + " -p tcp --tcp-flags RST RST -j RETURN"; 43 ret = ret || 44 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 45 return ret; 46 } 47 } // namespace 48 49 static constexpr uint32_t SYSTEM_UID_RANGE = 9999; 50 static constexpr uint32_t DEFAULT_MAX_UID_RANGE = UINT_MAX; FirewallManager()51 FirewallManager::FirewallManager() : chainInitFlag_(false), firewallType_(FirewallType::TYPE_ALLOWED_LIST) 52 { 53 strMaxUid_ = ReadMaxUidConfig(); 54 FirewallChainStatus status = {}; 55 status.enable = false; 56 status.type = FirewallType::TYPE_ALLOWED_LIST; 57 firewallChainStatus_[ChainType::CHAIN_OHFW_DOZABLE] = status; 58 firewallChainStatus_[ChainType::CHAIN_OHFW_POWERSAVING] = status; 59 firewallChainStatus_[ChainType::CHAIN_OHFW_UNDOZABLE] = status; 60 firewallChainStatus_[ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX] = status; 61 } 62 ~FirewallManager()63 FirewallManager::~FirewallManager() 64 { 65 DeInitChain(); 66 } 67 CheckChainInitialization()68 inline void FirewallManager::CheckChainInitialization() 69 { 70 if (chainInitFlag_ == false) { 71 InitChain(); 72 InitDefaultRules(); 73 } 74 } 75 ReadMaxUidConfig()76 std::string FirewallManager::ReadMaxUidConfig() 77 { 78 NETNATIVE_LOG_D("ReadMaxUidConfig"); 79 std::string maxUid; 80 std::string content; 81 82 std::ifstream file(CONFIG_FILE_PATH); 83 if (!file.is_open()) { 84 NETNATIVE_LOGE("ReadMaxUidConfig fstream failed"); 85 return std::to_string(DEFAULT_MAX_UID_RANGE); 86 } 87 88 std::ostringstream oss; 89 oss << file.rdbuf(); 90 content = oss.str(); 91 auto index = content.find_last_of(' '); 92 maxUid = content.substr(index + 1); 93 // if unavailable value use default value 94 if (maxUid.size() == 0) { 95 return std::to_string(DEFAULT_MAX_UID_RANGE); 96 } 97 98 return maxUid; 99 } 100 IsFirewallChian(ChainType chain)101 int32_t FirewallManager::IsFirewallChian(ChainType chain) 102 { 103 if (chain != ChainType::CHAIN_OHFW_DOZABLE && chain != ChainType::CHAIN_OHFW_POWERSAVING 104 && chain != ChainType::CHAIN_OHFW_UNDOZABLE && chain != ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX) { 105 return NETMANAGER_ERROR; 106 } 107 return NETMANAGER_SUCCESS; 108 } 109 FetchChainName(ChainType chain)110 std::string FirewallManager::FetchChainName(ChainType chain) 111 { 112 NETNATIVE_LOG_D("FirewallManager FetchChainName: chain=%{public}d", chain); 113 std::string chainName; 114 switch (chain) { 115 case ChainType::CHAIN_OHFW_INPUT: 116 chainName = "ohfw_INPUT"; 117 break; 118 case ChainType::CHAIN_OHFW_OUTPUT: 119 chainName = "ohfw_OUTPUT"; 120 break; 121 case ChainType::CHAIN_OHFW_FORWARD: 122 chainName = "ohfw_FORWARD"; 123 break; 124 case ChainType::CHAIN_OHFW_DOZABLE: 125 chainName = "ohfw_dozable"; 126 break; 127 case ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX: 128 chainName = "ohfw_allowed_list_box"; 129 break; 130 case ChainType::CHAIN_OHFW_POWERSAVING: 131 chainName = "ohfw_powersaving"; 132 break; 133 case ChainType::CHAIN_OHFW_UNDOZABLE: 134 chainName = "ohfw_undozable"; 135 break; 136 default: 137 chainName = "oh_unusable"; 138 break; 139 } 140 return chainName; 141 } 142 FetchChainType(ChainType chain)143 FirewallType FirewallManager::FetchChainType(ChainType chain) 144 { 145 FirewallType firewallType; 146 switch (chain) { 147 case ChainType::CHAIN_OHFW_DOZABLE: 148 firewallType = FirewallType::TYPE_ALLOWED_LIST; 149 break; 150 case ChainType::CHAIN_OHFW_POWERSAVING: 151 firewallType = FirewallType::TYPE_ALLOWED_LIST; 152 break; 153 case ChainType::CHAIN_OHFW_UNDOZABLE: 154 firewallType = FirewallType::TYPE_DENIDE_LIST; 155 break; 156 default: 157 firewallType = FirewallType::TYPE_ALLOWED_LIST; 158 break; 159 } 160 return firewallType; 161 } 162 InitChain()163 int32_t FirewallManager::InitChain() 164 { 165 NETNATIVE_LOG_D("FirewallManager InitChain"); 166 bool ret = false; 167 ret = (IptablesNewChain(ChainType::CHAIN_OHFW_INPUT) == NETMANAGER_ERROR) || 168 (IptablesNewChain(ChainType::CHAIN_OHFW_OUTPUT) == NETMANAGER_ERROR) || 169 (IptablesNewChain(ChainType::CHAIN_OHFW_FORWARD) == NETMANAGER_ERROR) || 170 (IptablesNewChain(ChainType::CHAIN_OHFW_DOZABLE) == NETMANAGER_ERROR) || 171 (IptablesNewChain(ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX) == NETMANAGER_ERROR) || 172 (IptablesNewChain(ChainType::CHAIN_OHFW_POWERSAVING) == NETMANAGER_ERROR) || 173 (IptablesNewChain(ChainType::CHAIN_OHFW_UNDOZABLE) == NETMANAGER_ERROR); 174 chainInitFlag_ = true; 175 return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR; 176 } 177 DeInitChain()178 int32_t FirewallManager::DeInitChain() 179 { 180 NETNATIVE_LOG_D("FirewallManager DeInitChain"); 181 bool ret = false; 182 ret = (IptablesDeleteChain(ChainType::CHAIN_OHFW_INPUT) == NETMANAGER_ERROR) || 183 (IptablesDeleteChain(ChainType::CHAIN_OHFW_OUTPUT) == NETMANAGER_ERROR) || 184 (IptablesDeleteChain(ChainType::CHAIN_OHFW_FORWARD) == NETMANAGER_ERROR) || 185 (IptablesDeleteChain(ChainType::CHAIN_OHFW_DOZABLE) == NETMANAGER_ERROR) || 186 (IptablesDeleteChain(ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX) == NETMANAGER_ERROR) || 187 (IptablesDeleteChain(ChainType::CHAIN_OHFW_POWERSAVING) == NETMANAGER_ERROR) || 188 (IptablesDeleteChain(ChainType::CHAIN_OHFW_UNDOZABLE) == NETMANAGER_ERROR); 189 chainInitFlag_ = false; 190 return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR; 191 } 192 InitDefaultRules()193 int32_t FirewallManager::InitDefaultRules() 194 { 195 NETNATIVE_LOG_D("FirewallManager InitDefaultRules"); 196 bool ret = false; 197 std::string chainName = FetchChainName(ChainType::CHAIN_OHFW_INPUT); 198 std::string command = "-t filter -A INPUT -j " + chainName; 199 ret = ret || 200 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 201 chainName = FetchChainName(ChainType::CHAIN_OHFW_OUTPUT); 202 command = "-t filter -A OUTPUT -j " + chainName; 203 ret = ret || 204 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 205 return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR; 206 } 207 ClearAllRules()208 int32_t FirewallManager::ClearAllRules() 209 { 210 NETNATIVE_LOG_D("FirewallManager ClearAllRules"); 211 bool ret = false; 212 213 std::string chainName = FetchChainName(ChainType::CHAIN_OHFW_DOZABLE); 214 std::string command = "-t filter -F " + chainName; 215 ret = ret || 216 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 217 218 chainName = FetchChainName(ChainType::CHAIN_OHFW_POWERSAVING); 219 command = "-t filter -F " + chainName; 220 ret = 221 ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 222 223 chainName = FetchChainName(ChainType::CHAIN_OHFW_UNDOZABLE); 224 command = "-t filter -F " + chainName; 225 ret = 226 ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 227 228 chainName = FetchChainName(ChainType::CHAIN_OHFW_INPUT); 229 command = "-t filter -F " + chainName; 230 ret = 231 ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 232 233 chainName = FetchChainName(ChainType::CHAIN_OHFW_OUTPUT); 234 command = "-t filter -F " + chainName; 235 ret = ret || 236 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 237 chainName = FetchChainName(ChainType::CHAIN_OHFW_FORWARD); 238 command = "-t filter -F " + chainName; 239 ret = ret || 240 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 241 chainName = FetchChainName(ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX); 242 command = "-t filter -F " + chainName; 243 ret = ret || 244 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 245 return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR; 246 } 247 IptablesNewChain(ChainType chain)248 int32_t FirewallManager::IptablesNewChain(ChainType chain) 249 { 250 NETNATIVE_LOG_D("FirewallManager NewChain: chain=%{public}d", chain); 251 std::string command = "-t filter -N " + FetchChainName(chain); 252 return IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command); 253 } 254 IptablesDeleteChain(ChainType chain)255 int32_t FirewallManager::IptablesDeleteChain(ChainType chain) 256 { 257 NETNATIVE_LOG_D("FirewallManager DeleteChain: chain=%{public}d", chain); 258 bool ret = false; 259 std::string command = "-t filter -F " + FetchChainName(chain); 260 ret = ret || 261 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 262 command = "-t filter -X " + FetchChainName(chain); 263 ret = ret || 264 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 265 return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR; 266 } 267 IptablesSetRule(const std::string & chainName,const std::string & option,const std::string & target,uint32_t uid)268 int32_t FirewallManager::IptablesSetRule(const std::string &chainName, const std::string &option, 269 const std::string &target, uint32_t uid) 270 { 271 NETNATIVE_LOG_D("FirewallManager IptablesSetRule"); 272 std::string command = 273 "-t filter " + option + " " + chainName + " -m owner --uid-owner " + std::to_string(uid) + " -j " + target; 274 return IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command); 275 } 276 SetUidsAllowedListChain(ChainType chain,const std::vector<uint32_t> & uids)277 int32_t FirewallManager::SetUidsAllowedListChain(ChainType chain, const std::vector<uint32_t> &uids) 278 { 279 NETNATIVE_LOG_D("FirewallManager SetUidsAllowedListChain: chain=%{public}d", chain); 280 if (chain != ChainType::CHAIN_OHFW_DOZABLE && chain != ChainType::CHAIN_OHFW_POWERSAVING) { 281 return NETMANAGER_ERROR; 282 } 283 284 bool ret = false; 285 std::unique_lock<std::mutex> lock(firewallMutex_); 286 CheckChainInitialization(); 287 288 std::string command; 289 const auto &chainName = FetchChainName(chain); 290 291 command = "-t filter -F " + chainName; 292 ret = ret || 293 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 294 295 std::string allowedListChainName = FetchChainName(ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX); 296 command = "-t filter -A " + chainName + " -j " + allowedListChainName; 297 ret = ret || 298 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 299 std::for_each(uids.begin(), uids.end(), [&command, &chainName, &ret](uint32_t uid) { 300 std::string strUid = std::to_string(uid); 301 command = "-t filter -A " + chainName + " -m owner --uid-owner " + strUid + " -j RETURN"; 302 ret = ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == 303 NETMANAGER_ERROR); 304 }); 305 306 command = 307 "-t filter -A " + chainName + " -m owner --uid-owner 0-" + std::to_string(SYSTEM_UID_RANGE) + " -j RETURN"; 308 ret = ret || 309 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 310 command = "-t filter -A " + chainName + " -m owner ! --uid-owner 0-" + strMaxUid_ + " -j RETURN"; 311 312 ret = SetFireWallCommand(chainName, command); 313 314 command = "-t filter -A " + chainName + " -j DROP"; 315 ret = ret || 316 (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == NETMANAGER_ERROR); 317 if (ret == false) { 318 FirewallChainStatus status = firewallChainStatus_[chain]; 319 status.uids = uids; 320 firewallChainStatus_[chain] = status; 321 } 322 323 return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR; 324 } 325 SetUidsDeniedListChain(ChainType chain,const std::vector<uint32_t> & uids)326 int32_t FirewallManager::SetUidsDeniedListChain(ChainType chain, const std::vector<uint32_t> &uids) 327 { 328 NETNATIVE_LOG_D("FirewallManager SetUidsDeniedListChain: chain=%{public}d", chain); 329 if (chain != ChainType::CHAIN_OHFW_UNDOZABLE) { 330 return NETMANAGER_ERROR; 331 } 332 333 std::unique_lock<std::mutex> lock(firewallMutex_); 334 bool ret = false; 335 CheckChainInitialization(); 336 337 std::string command; 338 const auto &chainName = FetchChainName(chain); 339 340 command = "-t filter -F " + chainName; 341 342 ret = SetFireWallCommand(chainName, command); 343 344 std::for_each(uids.begin(), uids.end(), [&command, &chainName, &ret](uint32_t uid) { 345 std::string strUid = std::to_string(uid); 346 command = "-t filter -A " + chainName + " -m owner --uid-owner " + strUid + " -j DROP"; 347 ret = ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == 348 NETMANAGER_ERROR); 349 }); 350 351 if (ret == false) { 352 FirewallChainStatus status = firewallChainStatus_[chain]; 353 status.uids = uids; 354 firewallChainStatus_[chain] = status; 355 } 356 357 return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR; 358 } 359 EnableChain(ChainType chain,bool enable)360 int32_t FirewallManager::EnableChain(ChainType chain, bool enable) 361 { 362 NETNATIVE_LOG_D("FirewallManager EnableChain: chain=%{public}d, enable=%{public}d", chain, enable); 363 if (IsFirewallChian(chain) == NETMANAGER_ERROR) { 364 return NETMANAGER_ERROR; 365 } 366 367 bool ret = false; 368 std::unique_lock<std::mutex> lock(firewallMutex_); 369 CheckChainInitialization(); 370 371 std::string chainName; 372 std::string fChainName; 373 chainName = FetchChainName(chain); 374 std::string command; 375 376 if (enable == true && firewallChainStatus_[chain].enable == false) { 377 fChainName = FetchChainName(ChainType::CHAIN_OHFW_OUTPUT); 378 command = "-t filter -A " + fChainName + " -j " + chainName; 379 ret = ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == 380 NETMANAGER_ERROR); 381 } else if (enable == false && firewallChainStatus_[chain].enable == true) { 382 fChainName = FetchChainName(ChainType::CHAIN_OHFW_OUTPUT); 383 command = "-t filter -D " + fChainName + " -j " + chainName; 384 ret = ret || (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4V6, command) == 385 NETMANAGER_ERROR); 386 } else { 387 NETNATIVE_LOGI("FirewallManager::EnableChain chain was %{public}s, do not repeat", 388 enable == true ? "true" : "false"); 389 return NETMANAGER_ERROR; 390 } 391 392 if (ret == false) { 393 firewallType_ = FetchChainType(chain); 394 firewallChainStatus_[chain].enable = enable; 395 } 396 397 return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR; 398 } 399 SetUidRule(ChainType chain,uint32_t uid,FirewallRule firewallRule)400 int32_t FirewallManager::SetUidRule(ChainType chain, uint32_t uid, FirewallRule firewallRule) 401 { 402 NETNATIVE_LOGI("FirewallManager SetUidRule: chain=%{public}d, uid=%{public}d, firewallRule=%{public}d", chain, 403 uid, firewallRule); 404 if (IsFirewallChian(chain) == NETMANAGER_ERROR) { 405 return NETMANAGER_ERROR; 406 } 407 408 bool ret = false; 409 std::unique_lock<std::mutex> lock(firewallMutex_); 410 CheckChainInitialization(); 411 412 std::string op; 413 std::string target; 414 std::string chainName = FetchChainName(chain); 415 FirewallType firewallType = FetchChainType(chain); 416 if (firewallType == FirewallType::TYPE_DENIDE_LIST) { 417 target = "DROP"; 418 op = (firewallRule == FirewallRule::RULE_DENY) ? "-A" : "-D"; 419 } else { 420 if (chain != ChainType::CHAIN_OHFW_ALLOWED_LIST_BOX) { 421 target = "RETURN"; 422 } else { 423 target = "ACCEPT"; 424 } 425 op = (firewallRule == FirewallRule::RULE_ALLOW) ? "-I" : "-D"; 426 } 427 428 FirewallChainStatus status = firewallChainStatus_[chain]; 429 std::vector<uint32_t>::iterator iter = std::find(status.uids.begin(), status.uids.end(), uid); 430 if (op != "-D" && iter == status.uids.end()) { 431 status.uids.push_back(uid); 432 ret = ret || (IptablesSetRule(chainName, op, target, uid) == NETMANAGER_ERROR); 433 } else if (op == "-D" && iter != status.uids.end()) { 434 status.uids.erase(iter); 435 ret = ret || (IptablesSetRule(chainName, op, target, uid) == NETMANAGER_ERROR); 436 } else { 437 NETNATIVE_LOGE("FirewallManager::SetUidRule error"); 438 return NETMANAGER_ERROR; 439 } 440 441 if (ret == false) { 442 firewallChainStatus_[chain] = status; 443 } 444 445 return ret == false ? NETMANAGER_SUCCESS : NETMANAGER_ERROR; 446 } 447 } // namespace nmd 448 } // namespace OHOS 449