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