• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "iptables_manager.h"
17 
18 #include <iostream>
19 #include <unordered_map>
20 
21 #include "domain_chain_rule.h"
22 #include "edm_log.h"
23 #include "executer_factory.h"
24 #include "firewall_chain_rule.h"
25 #include "iexecuter.h"
26 #include "rule_utils.h"
27 
28 namespace OHOS {
29 namespace EDM {
30 namespace IPTABLES {
31 
32 const int32_t MAX_DOMAIN_LENGTH = 255;
33 
34 bool IptablesManager::g_chainInit = false;
35 bool IptablesManager::g_defaultFirewallOutputChainInit = false;
36 bool IptablesManager::g_defaultFirewallForwardChainInit = false;
37 bool IptablesManager::g_defaultDomainOutputChainInit = false;
38 bool IptablesManager::g_defaultDomainForwardChainInit = false;
39 std::shared_ptr<IptablesManager> IptablesManager::instance_ = nullptr;
40 std::mutex IptablesManager::mutexLock_;
41 
GetInstance()42 std::shared_ptr<IptablesManager> IptablesManager::GetInstance()
43 {
44     if (instance_ == nullptr) {
45         std::lock_guard<std::mutex> lock(mutexLock_);
46         if (instance_ == nullptr) {
47             instance_ = std::make_shared<IptablesManager>();
48         }
49     }
50     return instance_;
51 }
52 
AddFirewallRule(const FirewallRuleParcel & firewall)53 ErrCode IptablesManager::AddFirewallRule(const FirewallRuleParcel& firewall)
54 {
55     auto rule = firewall.GetRule();
56     std::string chainName;
57     Direction direction = std::get<FIREWALL_DICECTION_IND>(rule);
58     if (!CheckAddFirewallParams(direction, rule)) {
59         return EdmReturnErrCode::PARAM_ERROR;
60     }
61     Action action = std::get<FIREWALL_ACTION_IND>(rule);
62 
63     if (!GetFirewallChainName(direction, action, chainName)) {
64         return EdmReturnErrCode::PARAM_ERROR;
65     }
66     auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
67     if (executer == nullptr) {
68         EDMLOGE("AddFirewallRule:GetExecuter fail, this should not happen.");
69         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
70     }
71     if (action == Action::ALLOW) {
72         SetDefaultFirewallDenyChain(direction);
73     }
74     auto chainRule = std::make_shared<FirewallChainRule>(rule);
75     return executer->Add(chainRule);
76 }
77 
RemoveFirewallRule(const FirewallRuleParcel & firewall)78 ErrCode IptablesManager::RemoveFirewallRule(const FirewallRuleParcel& firewall)
79 {
80     auto rule = firewall.GetRule();
81     Direction direction = std::get<FIREWALL_DICECTION_IND>(rule);
82     Action action = std::get<FIREWALL_ACTION_IND>(rule);
83     if (!CheckRemoveFirewallParams(direction, rule)) {
84         return EdmReturnErrCode::PARAM_ERROR;
85     }
86     std::vector<std::string> chainNameList;
87     ErrCode ret = GetRemoveChainName(direction, action, chainNameList);
88     if (ret != ERR_OK) {
89         EDMLOGE("RemoveFirewallRule: illegal parameter: action, direction");
90         return ret;
91     }
92 
93     if (chainNameList.size() > 1) {
94         bool ifParamNotEmpty = !std::get<FIREWALL_SRCADDR_IND>(rule).empty() ||
95             !std::get<FIREWALL_DESTADDR_IND>(rule).empty() || !std::get<FIREWALL_SRCPORT_IND>(rule).empty() ||
96             !std::get<FIREWALL_DESTPORT_IND>(rule).empty() || !std::get<FIREWALL_APPUID_IND>(rule).empty();
97         if (std::get<FIREWALL_PROT_IND>(rule) != IPTABLES::Protocol::INVALID || ifParamNotEmpty) {
98             EDMLOGE("RemoveFirewallRule: illegal parameter: Too many parameters set");
99             return EdmReturnErrCode::PARAM_ERROR;
100         }
101         // flash chain
102         for (const auto& chainName : chainNameList) {
103             auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
104             if (executer == nullptr) {
105                 EDMLOGE("RemoveFirewallRule:GetExecuter fail, this should not happen.");
106                 continue;
107             }
108             executer->Remove(nullptr);
109         }
110     } else if (chainNameList.size() == 1) {
111         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainNameList[0]);
112         if (executer == nullptr) {
113             EDMLOGE("RemoveFirewallRule:GetExecuter fail, this should not happen.");
114         } else {
115             auto chainRule = std::make_shared<FirewallChainRule>(rule);
116             executer->Remove(chainRule);
117         }
118     }
119     if (!ExistOutputAllowFirewallRule()) {
120         ClearDefaultFirewallOutputDenyChain();
121     }
122     if (!ExistForwardAllowFirewallRule()) {
123         ClearDefaultFirewallForwardDenyChain();
124     }
125     return ERR_OK;
126 }
127 
GetFirewallRules(std::vector<FirewallRuleParcel> & list)128 ErrCode IptablesManager::GetFirewallRules(std::vector<FirewallRuleParcel>& list)
129 {
130     std::vector<std::string> inputRuleList;
131     std::vector<std::string> inputChainVector{EDM_ALLOW_INPUT_CHAIN_NAME,
132         EDM_DENY_INPUT_CHAIN_NAME, EDM_REJECT_INPUT_CHAIN_NAME};
133     for (const auto& chainName : inputChainVector) {
134         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
135         if (executer == nullptr) {
136             EDMLOGE("GetFirewallRules:GetExecuter fail, this should not happen.");
137             continue;
138         }
139         executer->GetAll(inputRuleList);
140     }
141     ConvertFirewallRuleList(list, inputRuleList, Direction::INPUT);
142 
143     std::vector<std::string> outputRuleList;
144     std::vector<std::string> outputChainVector{EDM_ALLOW_OUTPUT_CHAIN_NAME,
145         EDM_DENY_OUTPUT_CHAIN_NAME, EDM_REJECT_OUTPUT_CHAIN_NAME};
146     for (const auto& chainName : outputChainVector) {
147         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
148         if (executer == nullptr) {
149             EDMLOGE("GetFirewallRules:GetExecuter fail, this should not happen.");
150             continue;
151         }
152         executer->GetAll(outputRuleList);
153     }
154     ConvertFirewallRuleList(list, outputRuleList, Direction::OUTPUT);
155 
156     std::vector<std::string> forwardRuleList;
157     std::vector<std::string> forwardChainVector{EDM_ALLOW_FORWARD_CHAIN_NAME,
158         EDM_DENY_FORWARD_CHAIN_NAME, EDM_REJECT_FORWARD_CHAIN_NAME};
159     for (const auto& chainName : forwardChainVector) {
160         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
161         if (executer == nullptr) {
162             EDMLOGE("GetFirewallRules:GetExecuter fail, this should not happen.");
163             continue;
164         }
165         executer->GetAll(forwardRuleList);
166     }
167     ConvertFirewallRuleList(list, forwardRuleList, Direction::FORWARD);
168     return ERR_OK;
169 }
170 
AddDomainFilterRule(const DomainFilterRuleParcel & DomainFilter)171 ErrCode IptablesManager::AddDomainFilterRule(const DomainFilterRuleParcel& DomainFilter)
172 {
173     auto rule = DomainFilter.GetRule();
174     Action action = std::get<DOMAIN_ACTION_IND>(rule);
175     std::string domainName = std::get<DOMAIN_DOMAINNAME_IND>(rule);
176     std::string chainName;
177     Direction direction = std::get<DOMAIN_DIRECTION_IND>(rule);
178     if (direction == Direction::FORWARD && !std::get<DOMAIN_APPUID_IND>(rule).empty()) {
179         EDMLOGE("AddDomainFilterRule: illegal parameter: appUid");
180         return EdmReturnErrCode::PARAM_ERROR;
181     }
182     if (action == Action::ALLOW) {
183         chainName = EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME;
184         if (direction == Direction::FORWARD) {
185             chainName = EDM_DNS_ALLOW_FORWARD_CHAIN_NAME;
186         }
187     } else if (action == Action::DENY) {
188         chainName = EDM_DNS_DENY_OUTPUT_CHAIN_NAME;
189         if (direction == Direction::FORWARD) {
190             chainName = EDM_DNS_DENY_FORWARD_CHAIN_NAME;
191         }
192     } else if (action == Action::REJECT) {
193         chainName = EDM_DNS_REJECT_OUTPUT_CHAIN_NAME;
194         if (direction == Direction::FORWARD) {
195             chainName = EDM_DNS_REJECT_FORWARD_CHAIN_NAME;
196         }
197     } else {
198         EDMLOGE("AddDomainFilterRule: illegal parameter: action");
199         return EdmReturnErrCode::PARAM_ERROR;
200     }
201     if (domainName.empty() || domainName.length() > MAX_DOMAIN_LENGTH) {
202         EDMLOGE("AddDomainFilterRule: illegal parameter: domainName");
203         return EdmReturnErrCode::PARAM_ERROR;
204     }
205     auto index = domainName.find_first_of("|/");
206     if (index != std::string ::npos) {
207         EDMLOGE("AddDomainFilterRule: illegal parameter: domainName");
208         return EdmReturnErrCode::PARAM_ERROR;
209     }
210 
211     auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
212     if (executer == nullptr) {
213         EDMLOGE("AddDomainFilterRule:GetExecuter fail, this should not happen.");
214         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
215     }
216     if (action == Action::ALLOW) {
217         EDMLOGD("AddDomainFilterRule:GetExecuter before SetDefaultDomainDenyChain.");
218         SetDefaultDomainDenyChain(direction);
219     }
220     auto chainRule = std::make_shared<DomainChainRule>(rule);
221     return executer->Add(chainRule);
222 }
223 
RemoveDomainFilterRules(const DomainFilterRuleParcel & DomainFilter)224 ErrCode IptablesManager::RemoveDomainFilterRules(const DomainFilterRuleParcel& DomainFilter)
225 {
226     auto rule = DomainFilter.GetRule();
227     Action action = std::get<DOMAIN_ACTION_IND>(rule);
228     std::string appUid = std::get<DOMAIN_APPUID_IND>(rule);
229     std::string domainName = std::get<DOMAIN_DOMAINNAME_IND>(rule);
230     Direction direction = std::get<DOMAIN_DIRECTION_IND>(rule);
231     if (!CheckRemoveDomainParams(direction, action, appUid, domainName)) {
232         return EdmReturnErrCode::PARAM_ERROR;
233     }
234     std::vector<std::string> chainNameList;
235     ErrCode ret = GetDomainRemoveChainName(direction, action, chainNameList);
236     if (ret != ERR_OK) {
237         EDMLOGE("RemoveDomainRule: illegal parameter: action, direction");
238         return ret;
239     }
240     if (chainNameList.size() > 1) {
241         for (const auto& chainName : chainNameList) {
242             auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
243             if (executer == nullptr) {
244                 EDMLOGE("RemoveDomainFilterRules:GetExecuter fail, this should not happen.");
245                 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
246             }
247             // flush chain
248             executer->Remove(nullptr);
249         }
250     } else if (chainNameList.size() == 1) {
251         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainNameList[0]);
252         if (executer == nullptr) {
253             EDMLOGE("RemoveDomainFilterRules:GetExecuter fail, this should not happen.");
254             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
255         }
256         auto chainRule = std::make_shared<DomainChainRule>(rule);
257         executer->Remove(chainRule);
258     }
259 
260     if (!ExistOutputAllowDomainRule()) {
261         ClearDefaultDomainOutputDenyChain();
262     }
263     if (!ExistForwardAllowDomainRule()) {
264         ClearDefaultDomainForwardDenyChain();
265     }
266     return ERR_OK;
267 }
268 
GetDomainFilterRules(std::vector<DomainFilterRuleParcel> & list)269 ErrCode IptablesManager::GetDomainFilterRules(std::vector<DomainFilterRuleParcel>& list)
270 {
271     std::vector<std::string> outputRuleList;
272     std::vector<std::string> outputChainVector{EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME,
273         EDM_DNS_DENY_OUTPUT_CHAIN_NAME, EDM_DNS_REJECT_OUTPUT_CHAIN_NAME};
274     for (const auto& chainName : outputChainVector) {
275         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
276         if (executer == nullptr) {
277             EDMLOGE("ChainExistRule executer null");
278             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
279         }
280         executer->GetAll(outputRuleList);
281     }
282     for (const auto& rule : outputRuleList) {
283         DomainChainRule chainRule{rule};
284         DomainFilterRuleParcel domain{chainRule.ToFilterRule(Direction::OUTPUT)};
285         list.emplace_back(domain);
286     }
287 
288     std::vector<std::string> forwardRuleList;
289     std::vector<std::string> forwardChainVector{EDM_DNS_ALLOW_FORWARD_CHAIN_NAME,
290         EDM_DNS_DENY_FORWARD_CHAIN_NAME, EDM_DNS_REJECT_FORWARD_CHAIN_NAME};
291     for (const auto& chainName : forwardChainVector) {
292         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
293         if (executer == nullptr) {
294             EDMLOGE("GetFirewallRules:GetExecuter fail, this should not happen.");
295             continue;
296         }
297         executer->GetAll(forwardRuleList);
298     }
299     for (const auto& rule : forwardRuleList) {
300         DomainChainRule chainRule{rule};
301         DomainFilterRuleParcel domain{chainRule.ToFilterRule(Direction::FORWARD)};
302         list.emplace_back(domain);
303     }
304 
305     return ERR_OK;
306 }
307 
GetRemoveChainName(Direction direction,Action action,std::vector<std::string> & chainNameList)308 ErrCode IptablesManager::GetRemoveChainName(Direction direction, Action action, std::vector<std::string>& chainNameList)
309 {
310     if (direction == Direction::INPUT) {
311         GetRemoveInputChainName(action, chainNameList);
312     } else if (direction == Direction::OUTPUT) {
313         GetRemoveOutputChainName(action, chainNameList);
314     } else if (direction == Direction::FORWARD) {
315         GetRemoveForwardChainName(action, chainNameList);
316     } else {
317         if (action == Action::INVALID) {
318             chainNameList.emplace_back(EDM_ALLOW_INPUT_CHAIN_NAME);
319             chainNameList.emplace_back(EDM_ALLOW_OUTPUT_CHAIN_NAME);
320             chainNameList.emplace_back(EDM_ALLOW_FORWARD_CHAIN_NAME);
321             chainNameList.emplace_back(EDM_DENY_INPUT_CHAIN_NAME);
322             chainNameList.emplace_back(EDM_DENY_OUTPUT_CHAIN_NAME);
323             chainNameList.emplace_back(EDM_DENY_FORWARD_CHAIN_NAME);
324             chainNameList.emplace_back(EDM_REJECT_INPUT_CHAIN_NAME);
325             chainNameList.emplace_back(EDM_REJECT_OUTPUT_CHAIN_NAME);
326             chainNameList.emplace_back(EDM_REJECT_FORWARD_CHAIN_NAME);
327         } else {
328             EDMLOGE("GetRemoveChainName: illegal parameter: direction, action");
329             return EdmReturnErrCode::PARAM_ERROR;
330         }
331     }
332     return ERR_OK;
333 }
334 
GetRemoveInputChainName(Action action,std::vector<std::string> & chainNameList)335 void IptablesManager::GetRemoveInputChainName(Action action,
336     std::vector<std::string>& chainNameList)
337 {
338     if (action == Action::ALLOW) {
339         chainNameList.emplace_back(EDM_ALLOW_INPUT_CHAIN_NAME);
340     } else if (action == Action::DENY) {
341         chainNameList.emplace_back(EDM_DENY_INPUT_CHAIN_NAME);
342     } else if (action == Action::REJECT) {
343         chainNameList.emplace_back(EDM_REJECT_INPUT_CHAIN_NAME);
344     } else {
345         chainNameList.emplace_back(EDM_ALLOW_INPUT_CHAIN_NAME);
346         chainNameList.emplace_back(EDM_DENY_INPUT_CHAIN_NAME);
347         chainNameList.emplace_back(EDM_REJECT_INPUT_CHAIN_NAME);
348     }
349 }
350 
GetRemoveOutputChainName(Action action,std::vector<std::string> & chainNameList)351 void IptablesManager::GetRemoveOutputChainName(Action action,
352     std::vector<std::string>& chainNameList)
353 {
354     if (action == Action::ALLOW) {
355         chainNameList.emplace_back(EDM_ALLOW_OUTPUT_CHAIN_NAME);
356     } else if (action == Action::DENY) {
357         chainNameList.emplace_back(EDM_DENY_OUTPUT_CHAIN_NAME);
358     } else if (action == Action::REJECT) {
359         chainNameList.emplace_back(EDM_REJECT_OUTPUT_CHAIN_NAME);
360     } else {
361         chainNameList.emplace_back(EDM_ALLOW_OUTPUT_CHAIN_NAME);
362         chainNameList.emplace_back(EDM_DENY_OUTPUT_CHAIN_NAME);
363         chainNameList.emplace_back(EDM_REJECT_OUTPUT_CHAIN_NAME);
364     }
365 }
366 
GetRemoveForwardChainName(Action action,std::vector<std::string> & chainNameList)367 void IptablesManager::GetRemoveForwardChainName(Action action,
368     std::vector<std::string>& chainNameList)
369 {
370     if (action == Action::ALLOW) {
371         chainNameList.emplace_back(EDM_ALLOW_FORWARD_CHAIN_NAME);
372     } else if (action == Action::DENY) {
373         chainNameList.emplace_back(EDM_DENY_FORWARD_CHAIN_NAME);
374     } else if (action == Action::REJECT) {
375         chainNameList.emplace_back(EDM_REJECT_FORWARD_CHAIN_NAME);
376     } else {
377         chainNameList.emplace_back(EDM_ALLOW_FORWARD_CHAIN_NAME);
378         chainNameList.emplace_back(EDM_DENY_FORWARD_CHAIN_NAME);
379         chainNameList.emplace_back(EDM_REJECT_FORWARD_CHAIN_NAME);
380     }
381 }
382 
GetDomainRemoveChainName(Direction direction,Action action,std::vector<std::string> & chainNameList)383 ErrCode IptablesManager::GetDomainRemoveChainName(Direction direction, Action action,
384     std::vector<std::string>& chainNameList)
385 {
386     if (direction == Direction::OUTPUT) {
387         GetDomainRemoveOutputChainName(action, chainNameList);
388     } else if (direction == Direction::FORWARD) {
389         GetDomainRemoveForwardChainName(action, chainNameList);
390     } else {
391         if (action == Action::INVALID) {
392             chainNameList.emplace_back(EDM_DNS_ALLOW_FORWARD_CHAIN_NAME);
393             chainNameList.emplace_back(EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME);
394             chainNameList.emplace_back(EDM_DNS_DENY_FORWARD_CHAIN_NAME);
395             chainNameList.emplace_back(EDM_DNS_DENY_OUTPUT_CHAIN_NAME);
396             chainNameList.emplace_back(EDM_DNS_REJECT_FORWARD_CHAIN_NAME);
397             chainNameList.emplace_back(EDM_DNS_REJECT_OUTPUT_CHAIN_NAME);
398         } else {
399             GetDomainRemoveOutputChainName(action, chainNameList);
400         }
401     }
402     return ERR_OK;
403 }
404 
GetDomainRemoveOutputChainName(Action action,std::vector<std::string> & chainNameList)405 void IptablesManager::GetDomainRemoveOutputChainName(Action action,
406     std::vector<std::string>& chainNameList)
407 {
408     if (action == Action::ALLOW) {
409         chainNameList.emplace_back(EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME);
410     } else if (action == Action::DENY) {
411         chainNameList.emplace_back(EDM_DNS_DENY_OUTPUT_CHAIN_NAME);
412     } else if (action == Action::REJECT) {
413         chainNameList.emplace_back(EDM_DNS_REJECT_OUTPUT_CHAIN_NAME);
414     } else {
415         chainNameList.emplace_back(EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME);
416         chainNameList.emplace_back(EDM_DNS_DENY_OUTPUT_CHAIN_NAME);
417         chainNameList.emplace_back(EDM_DNS_REJECT_OUTPUT_CHAIN_NAME);
418     }
419 }
420 
GetDomainRemoveForwardChainName(Action action,std::vector<std::string> & chainNameList)421 void IptablesManager::GetDomainRemoveForwardChainName(Action action,
422     std::vector<std::string>& chainNameList)
423 {
424     if (action == Action::ALLOW) {
425         chainNameList.emplace_back(EDM_DNS_ALLOW_FORWARD_CHAIN_NAME);
426     } else if (action == Action::DENY) {
427         chainNameList.emplace_back(EDM_DNS_DENY_FORWARD_CHAIN_NAME);
428     } else if (action == Action::REJECT) {
429         chainNameList.emplace_back(EDM_DNS_REJECT_FORWARD_CHAIN_NAME);
430     } else {
431         chainNameList.emplace_back(EDM_DNS_ALLOW_FORWARD_CHAIN_NAME);
432         chainNameList.emplace_back(EDM_DNS_DENY_FORWARD_CHAIN_NAME);
433         chainNameList.emplace_back(EDM_DNS_REJECT_FORWARD_CHAIN_NAME);
434     }
435 }
436 
HasInit()437 bool IptablesManager::HasInit()
438 {
439     return g_chainInit;
440 }
441 
Init()442 void IptablesManager::Init()
443 {
444     if (!g_chainInit) {
445         EDMLOGD("IptablesManager:start init.");
446         std::vector<std::shared_ptr<IExecuter>> allExecuter = ExecuterFactory::GetInstance()->GetAllExecuter();
447         for (const auto &executer : allExecuter) {
448             ErrCode ret = executer->CreateChain();
449             if (ret != ERR_OK) {
450                 EDMLOGE("Init CreateChain fail, this should not happen.");
451                 return;
452             }
453         }
454         for (const auto &executer : allExecuter) {
455             ErrCode ret = executer->Init();
456             if (ret != ERR_OK) {
457                 EDMLOGE("Init fail, this should not happen.");
458                 return;
459             }
460         }
461         g_chainInit = true;
462     }
463 }
464 
SetDefaultFirewallDenyChain(Direction direction)465 void IptablesManager::SetDefaultFirewallDenyChain(Direction direction)
466 {
467     if (!g_defaultFirewallOutputChainInit && (direction == Direction::OUTPUT || direction == Direction::INPUT)) {
468         FirewallRule firewallRule1{Direction::OUTPUT, Action::DENY, Protocol::UDP, "", "", "", "", ""};
469         FirewallRule firewallRule2{Direction::OUTPUT, Action::DENY, Protocol::TCP, "", "", "", "", ""};
470 
471         std::vector<std::shared_ptr<ChainRule>> chainRuleVector{std::make_shared<FirewallChainRule>(),
472             std::make_shared<FirewallChainRule>(firewallRule1), std::make_shared<FirewallChainRule>(firewallRule2)};
473 
474         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DENY_OUTPUT_CHAIN_NAME);
475         for (const auto& chainRule : chainRuleVector) {
476             if (executer == nullptr) {
477                 EDMLOGE("SetDefaultFirewallDenyChain:GetExecuter fail, this should not happen.");
478             } else {
479                 executer->Add(chainRule);
480                 g_defaultFirewallOutputChainInit = true;
481             }
482         }
483     }
484     if (!g_defaultFirewallForwardChainInit && direction == Direction::FORWARD) {
485         FirewallRule firewallRule1{Direction::FORWARD, Action::DENY, Protocol::UDP, "", "", "", "", ""};
486         FirewallRule firewallRule2{Direction::FORWARD, Action::DENY, Protocol::TCP, "", "", "", "", ""};
487 
488         std::vector<std::shared_ptr<ChainRule>> chainRuleVector{std::make_shared<FirewallChainRule>(),
489             std::make_shared<FirewallChainRule>(firewallRule1), std::make_shared<FirewallChainRule>(firewallRule2)};
490 
491         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DENY_FORWARD_CHAIN_NAME);
492         for (const auto& chainRule : chainRuleVector) {
493             if (executer == nullptr) {
494                 EDMLOGE("SetDefaultFirewallDenyChain:GetExecuter fail, this should not happen.");
495             } else {
496                 executer->Add(chainRule);
497                 g_defaultFirewallForwardChainInit = true;
498             }
499         }
500     }
501 }
502 
ClearDefaultFirewallOutputDenyChain()503 void IptablesManager::ClearDefaultFirewallOutputDenyChain()
504 {
505     if (g_defaultFirewallOutputChainInit) {
506         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DENY_OUTPUT_CHAIN_NAME);
507         if (executer == nullptr) {
508             EDMLOGE("ClearDefaultFirewallOutputDenyChain:GetExecuter fail, this should not happen.");
509         } else {
510             executer->Remove(nullptr);
511             g_defaultFirewallOutputChainInit = false;
512         }
513     }
514 }
515 
ClearDefaultFirewallForwardDenyChain()516 void IptablesManager::ClearDefaultFirewallForwardDenyChain()
517 {
518     if (g_defaultFirewallForwardChainInit) {
519         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DENY_FORWARD_CHAIN_NAME);
520         if (executer == nullptr) {
521             EDMLOGE("ClearDefaultFirewallForwardDenyChain:GetExecuter fail, this should not happen.");
522         } else {
523             executer->Remove(nullptr);
524             g_defaultFirewallForwardChainInit = false;
525         }
526     }
527 }
528 
SetDefaultDomainDenyChain(Direction direction)529 void IptablesManager::SetDefaultDomainDenyChain(Direction direction)
530 {
531     if (!g_defaultDomainOutputChainInit && direction == Direction::OUTPUT) {
532         DomainFilterRule domainFilterRule{Action::DENY, "", "", Direction::OUTPUT};
533         std::shared_ptr<ChainRule> chainRule = std::make_shared<DomainChainRule>(domainFilterRule);
534         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DNS_DENY_OUTPUT_CHAIN_NAME);
535         if (executer == nullptr) {
536             EDMLOGE("SetDefaultDomainDenyChain:GetExecuter fail, this should not happen.");
537         } else {
538             executer->Add(chainRule);
539             g_defaultDomainOutputChainInit = true;
540         }
541     }
542 
543     if (!g_defaultDomainForwardChainInit && direction == Direction::FORWARD) {
544         DomainFilterRule domainFilterRule{Action::DENY, "", "", Direction::FORWARD};
545         std::shared_ptr<ChainRule> chainRule = std::make_shared<DomainChainRule>(domainFilterRule);
546         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DNS_DENY_FORWARD_CHAIN_NAME);
547         if (executer == nullptr) {
548             EDMLOGE("SetDefaultDomainDenyChain:GetExecuter fail, this should not happen.");
549         } else {
550             executer->Add(chainRule);
551             g_defaultDomainForwardChainInit = true;
552         }
553     }
554 }
555 
ClearDefaultDomainOutputDenyChain()556 void IptablesManager::ClearDefaultDomainOutputDenyChain()
557 {
558     if (g_defaultDomainOutputChainInit) {
559         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DNS_DENY_OUTPUT_CHAIN_NAME);
560         if (executer == nullptr) {
561             EDMLOGE("ClearDefaultDomainDenyChain:GetExecuter fail, this should not happen.");
562         } else {
563             executer->Remove(nullptr);
564             g_defaultDomainOutputChainInit = false;
565         }
566     }
567 }
568 
ClearDefaultDomainForwardDenyChain()569 void IptablesManager::ClearDefaultDomainForwardDenyChain()
570 {
571     if (g_defaultDomainForwardChainInit) {
572         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DNS_DENY_FORWARD_CHAIN_NAME);
573         if (executer == nullptr) {
574             EDMLOGE("ClearDefaultDomainDenyChain:GetExecuter fail, this should not happen.");
575         } else {
576             executer->Remove(nullptr);
577             g_defaultDomainForwardChainInit = false;
578         }
579     }
580 }
581 
ExistOutputAllowFirewallRule()582 bool IptablesManager::ExistOutputAllowFirewallRule()
583 {
584     std::vector<std::string> chainNameVector{EDM_ALLOW_INPUT_CHAIN_NAME, EDM_ALLOW_OUTPUT_CHAIN_NAME};
585     return ChainExistRule(chainNameVector);
586 }
587 
ExistForwardAllowFirewallRule()588 bool IptablesManager::ExistForwardAllowFirewallRule()
589 {
590     std::vector<std::string> chainNameVector{EDM_ALLOW_FORWARD_CHAIN_NAME};
591     return ChainExistRule(chainNameVector);
592 }
593 
ExistOutputAllowDomainRule()594 bool IptablesManager::ExistOutputAllowDomainRule()
595 {
596     std::vector<std::string> chainNameVector{EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME};
597     return ChainExistRule(chainNameVector);
598 }
599 
ExistForwardAllowDomainRule()600 bool IptablesManager::ExistForwardAllowDomainRule()
601 {
602     std::vector<std::string> chainNameVector{EDM_DNS_ALLOW_FORWARD_CHAIN_NAME};
603     return ChainExistRule(chainNameVector);
604 }
605 
CheckAddFirewallParams(Direction direction,FirewallRule rule)606 bool IptablesManager::CheckAddFirewallParams(Direction direction, FirewallRule rule)
607 {
608     if ((direction == Direction::INPUT || direction == Direction::FORWARD) &&
609         !std::get<FIREWALL_APPUID_IND>(rule).empty()) {
610         EDMLOGE("AddFirewallRule: illegal parameter: appUid");
611         return false;
612     }
613     if (std::get<FIREWALL_PROT_IND>(rule) == Protocol::ALL &&
614         (!std::get<FIREWALL_SRCPORT_IND>(rule).empty() || !std::get<FIREWALL_DESTPORT_IND>(rule).empty())) {
615         EDMLOGE("AddFirewallRule: illegal parameter: protocol");
616         return false;
617     }
618     return true;
619 }
620 
CheckRemoveFirewallParams(Direction direction,FirewallRule rule)621 bool IptablesManager::CheckRemoveFirewallParams(Direction direction, FirewallRule rule)
622 {
623     if ((direction == Direction::INPUT || direction == Direction::FORWARD) &&
624         !std::get<FIREWALL_APPUID_IND>(rule).empty()) {
625         EDMLOGE("RemoveFirewallRule: illegal parameter: appUid");
626         return false;
627     }
628     if (std::get<FIREWALL_PROT_IND>(rule) == Protocol::ALL &&
629         (!std::get<FIREWALL_SRCPORT_IND>(rule).empty() || !std::get<FIREWALL_DESTPORT_IND>(rule).empty())) {
630         EDMLOGE("RemoveFirewallRule: illegal parameter: protocol");
631         return false;
632     }
633     return true;
634 }
635 
CheckRemoveDomainParams(Direction direction,Action action,std::string appUid,std::string domainName)636 bool IptablesManager::CheckRemoveDomainParams(Direction direction, Action action,
637     std::string appUid, std::string domainName)
638 {
639     if (direction == Direction::FORWARD && !appUid.empty()) {
640         EDMLOGE("RemoveDomainFilterRules: illegal parameter: appUid");
641         return false;
642     }
643     if (domainName.empty() && !appUid.empty()) {
644         EDMLOGE("RemoveDomainFilterRules: illegal parameter: appUid");
645         return false;
646     }
647     if (!domainName.empty() && domainName.length() > MAX_DOMAIN_LENGTH) {
648         EDMLOGE("RemoveDomainFilterRules: illegal parameter: domainName");
649         return false;
650     }
651     auto index = domainName.find_first_of("|/");
652     if (index != std::string ::npos) {
653         EDMLOGE("RemoveDomainFilterRules: illegal parameter: domainName");
654         return false;
655     }
656 
657     if (action == Action::INVALID && (!appUid.empty() || !domainName.empty())) {
658         EDMLOGE("RemoveDomainFilterRules: illegal parameter: Too many parameters set");
659         return false;
660     }
661 
662     return true;
663 }
664 
GetFirewallChainName(Direction direction,Action action,std::string & chainName)665 bool IptablesManager::GetFirewallChainName(Direction direction, Action action, std::string& chainName)
666 {
667     if (action == Action::ALLOW && direction == Direction::INPUT) {
668         chainName = EDM_ALLOW_INPUT_CHAIN_NAME;
669     } else if (action == Action::ALLOW && direction == Direction::OUTPUT) {
670         chainName = EDM_ALLOW_OUTPUT_CHAIN_NAME;
671     } else if (action == Action::ALLOW && direction == Direction::FORWARD) {
672         chainName = EDM_ALLOW_FORWARD_CHAIN_NAME;
673     } else if (action == Action::DENY && direction == Direction::INPUT) {
674         chainName = EDM_DENY_INPUT_CHAIN_NAME;
675     } else if (action == Action::DENY && direction == Direction::OUTPUT) {
676         chainName = EDM_DENY_OUTPUT_CHAIN_NAME;
677     } else if (action == Action::DENY && direction == Direction::FORWARD) {
678         chainName = EDM_DENY_FORWARD_CHAIN_NAME;
679     } else if (action == Action::REJECT && direction == Direction::INPUT) {
680         chainName = EDM_REJECT_INPUT_CHAIN_NAME;
681     } else if (action == Action::REJECT && direction == Direction::OUTPUT) {
682         chainName = EDM_REJECT_OUTPUT_CHAIN_NAME;
683     } else if (action == Action::REJECT && direction == Direction::FORWARD) {
684         chainName = EDM_REJECT_FORWARD_CHAIN_NAME;
685     } else {
686         EDMLOGE("AddFirewallRule: illegal parameter: action, direction");
687         return false;
688     }
689     return true;
690 }
691 
ChainExistRule(const std::vector<std::string> & chainNames)692 bool IptablesManager::ChainExistRule(const std::vector<std::string>& chainNames)
693 {
694     std::vector<std::string> ruleList;
695     for (const auto& chainName : chainNames) {
696         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
697         if (executer == nullptr) {
698             EDMLOGE("ChainExistRule executer null");
699             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
700         }
701         executer->GetAll(ruleList);
702         if (!ruleList.empty()) {
703             return true;
704         }
705     }
706     return false;
707 }
708 
ConvertFirewallRuleList(std::vector<FirewallRuleParcel> & list,std::vector<std::string> ruleList,Direction direction)709 void IptablesManager::ConvertFirewallRuleList(std::vector<FirewallRuleParcel>& list,
710     std::vector<std::string> ruleList, Direction direction)
711 {
712     for (const auto& rule : ruleList) {
713         FirewallChainRule firewallRule{rule};
714         FirewallRuleParcel firewall{firewallRule.ToFilterRule(direction)};
715         list.emplace_back(firewall);
716     }
717 }
718 
719 } // namespace IPTABLES
720 } // namespace EDM
721 } // namespace OHOS