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