• 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     } else {
259         // this branch should never happen
260     }
261 
262     if (!ExistOutputAllowDomainRule()) {
263         ClearDefaultDomainOutputDenyChain();
264     }
265     if (!ExistForwardAllowDomainRule()) {
266         ClearDefaultDomainForwardDenyChain();
267     }
268     return ERR_OK;
269 }
270 
GetDomainFilterRules(std::vector<DomainFilterRuleParcel> & list)271 ErrCode IptablesManager::GetDomainFilterRules(std::vector<DomainFilterRuleParcel>& list)
272 {
273     std::vector<std::string> outputRuleList;
274     std::vector<std::string> outputChainVector{EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME,
275         EDM_DNS_DENY_OUTPUT_CHAIN_NAME, EDM_DNS_REJECT_OUTPUT_CHAIN_NAME};
276     for (const auto& chainName : outputChainVector) {
277         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
278         if (executer == nullptr) {
279             EDMLOGE("ChainExistRule executer null");
280             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
281         }
282         executer->GetAll(outputRuleList);
283     }
284     for (const auto& rule : outputRuleList) {
285         DomainChainRule chainRule{rule};
286         DomainFilterRuleParcel domain{chainRule.ToFilterRule(Direction::OUTPUT)};
287         list.emplace_back(domain);
288     }
289 
290     std::vector<std::string> forwardRuleList;
291     std::vector<std::string> forwardChainVector{EDM_DNS_ALLOW_FORWARD_CHAIN_NAME,
292         EDM_DNS_DENY_FORWARD_CHAIN_NAME, EDM_DNS_REJECT_FORWARD_CHAIN_NAME};
293     for (const auto& chainName : forwardChainVector) {
294         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
295         if (executer == nullptr) {
296             EDMLOGE("GetFirewallRules:GetExecuter fail, this should not happen.");
297             continue;
298         }
299         executer->GetAll(forwardRuleList);
300     }
301     for (const auto& rule : forwardRuleList) {
302         DomainChainRule chainRule{rule};
303         DomainFilterRuleParcel domain{chainRule.ToFilterRule(Direction::FORWARD)};
304         list.emplace_back(domain);
305     }
306 
307     return ERR_OK;
308 }
309 
GetRemoveChainName(Direction direction,Action action,std::vector<std::string> & chainNameList)310 ErrCode IptablesManager::GetRemoveChainName(Direction direction, Action action, std::vector<std::string>& chainNameList)
311 {
312     if (direction == Direction::INPUT) {
313         GetRemoveInputChainName(action, chainNameList);
314     } else if (direction == Direction::OUTPUT) {
315         GetRemoveOutputChainName(action, chainNameList);
316     } else if (direction == Direction::FORWARD) {
317         GetRemoveForwardChainName(action, chainNameList);
318     } else {
319         if (action == Action::INVALID) {
320             chainNameList.emplace_back(EDM_ALLOW_INPUT_CHAIN_NAME);
321             chainNameList.emplace_back(EDM_ALLOW_OUTPUT_CHAIN_NAME);
322             chainNameList.emplace_back(EDM_ALLOW_FORWARD_CHAIN_NAME);
323             chainNameList.emplace_back(EDM_DENY_INPUT_CHAIN_NAME);
324             chainNameList.emplace_back(EDM_DENY_OUTPUT_CHAIN_NAME);
325             chainNameList.emplace_back(EDM_DENY_FORWARD_CHAIN_NAME);
326             chainNameList.emplace_back(EDM_REJECT_INPUT_CHAIN_NAME);
327             chainNameList.emplace_back(EDM_REJECT_OUTPUT_CHAIN_NAME);
328             chainNameList.emplace_back(EDM_REJECT_FORWARD_CHAIN_NAME);
329         } else {
330             EDMLOGE("GetRemoveChainName: illegal parameter: direction, action");
331             return EdmReturnErrCode::PARAM_ERROR;
332         }
333     }
334     return ERR_OK;
335 }
336 
GetRemoveInputChainName(Action action,std::vector<std::string> & chainNameList)337 void IptablesManager::GetRemoveInputChainName(Action action,
338     std::vector<std::string>& chainNameList)
339 {
340     if (action == Action::ALLOW) {
341         chainNameList.emplace_back(EDM_ALLOW_INPUT_CHAIN_NAME);
342     } else if (action == Action::DENY) {
343         chainNameList.emplace_back(EDM_DENY_INPUT_CHAIN_NAME);
344     } else if (action == Action::REJECT) {
345         chainNameList.emplace_back(EDM_REJECT_INPUT_CHAIN_NAME);
346     } else {
347         chainNameList.emplace_back(EDM_ALLOW_INPUT_CHAIN_NAME);
348         chainNameList.emplace_back(EDM_DENY_INPUT_CHAIN_NAME);
349         chainNameList.emplace_back(EDM_REJECT_INPUT_CHAIN_NAME);
350     }
351 }
352 
GetRemoveOutputChainName(Action action,std::vector<std::string> & chainNameList)353 void IptablesManager::GetRemoveOutputChainName(Action action,
354     std::vector<std::string>& chainNameList)
355 {
356     if (action == Action::ALLOW) {
357         chainNameList.emplace_back(EDM_ALLOW_OUTPUT_CHAIN_NAME);
358     } else if (action == Action::DENY) {
359         chainNameList.emplace_back(EDM_DENY_OUTPUT_CHAIN_NAME);
360     } else if (action == Action::REJECT) {
361         chainNameList.emplace_back(EDM_REJECT_OUTPUT_CHAIN_NAME);
362     } else {
363         chainNameList.emplace_back(EDM_ALLOW_OUTPUT_CHAIN_NAME);
364         chainNameList.emplace_back(EDM_DENY_OUTPUT_CHAIN_NAME);
365         chainNameList.emplace_back(EDM_REJECT_OUTPUT_CHAIN_NAME);
366     }
367 }
368 
GetRemoveForwardChainName(Action action,std::vector<std::string> & chainNameList)369 void IptablesManager::GetRemoveForwardChainName(Action action,
370     std::vector<std::string>& chainNameList)
371 {
372     if (action == Action::ALLOW) {
373         chainNameList.emplace_back(EDM_ALLOW_FORWARD_CHAIN_NAME);
374     } else if (action == Action::DENY) {
375         chainNameList.emplace_back(EDM_DENY_FORWARD_CHAIN_NAME);
376     } else if (action == Action::REJECT) {
377         chainNameList.emplace_back(EDM_REJECT_FORWARD_CHAIN_NAME);
378     } else {
379         chainNameList.emplace_back(EDM_ALLOW_FORWARD_CHAIN_NAME);
380         chainNameList.emplace_back(EDM_DENY_FORWARD_CHAIN_NAME);
381         chainNameList.emplace_back(EDM_REJECT_FORWARD_CHAIN_NAME);
382     }
383 }
384 
GetDomainRemoveChainName(Direction direction,Action action,std::vector<std::string> & chainNameList)385 ErrCode IptablesManager::GetDomainRemoveChainName(Direction direction, Action action,
386     std::vector<std::string>& chainNameList)
387 {
388     if (direction == Direction::OUTPUT) {
389         GetDomainRemoveOutputChainName(action, chainNameList);
390     } else if (direction == Direction::FORWARD) {
391         GetDomainRemoveForwardChainName(action, chainNameList);
392     } else {
393         if (action == Action::INVALID) {
394             chainNameList.emplace_back(EDM_DNS_ALLOW_FORWARD_CHAIN_NAME);
395             chainNameList.emplace_back(EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME);
396             chainNameList.emplace_back(EDM_DNS_DENY_FORWARD_CHAIN_NAME);
397             chainNameList.emplace_back(EDM_DNS_DENY_OUTPUT_CHAIN_NAME);
398             chainNameList.emplace_back(EDM_DNS_REJECT_FORWARD_CHAIN_NAME);
399             chainNameList.emplace_back(EDM_DNS_REJECT_OUTPUT_CHAIN_NAME);
400         } else {
401             GetDomainRemoveOutputChainName(action, chainNameList);
402         }
403     }
404     return ERR_OK;
405 }
406 
GetDomainRemoveOutputChainName(Action action,std::vector<std::string> & chainNameList)407 void IptablesManager::GetDomainRemoveOutputChainName(Action action,
408     std::vector<std::string>& chainNameList)
409 {
410     if (action == Action::ALLOW) {
411         chainNameList.emplace_back(EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME);
412     } else if (action == Action::DENY) {
413         chainNameList.emplace_back(EDM_DNS_DENY_OUTPUT_CHAIN_NAME);
414     } else if (action == Action::REJECT) {
415         chainNameList.emplace_back(EDM_DNS_REJECT_OUTPUT_CHAIN_NAME);
416     } else {
417         chainNameList.emplace_back(EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME);
418         chainNameList.emplace_back(EDM_DNS_DENY_OUTPUT_CHAIN_NAME);
419         chainNameList.emplace_back(EDM_DNS_REJECT_OUTPUT_CHAIN_NAME);
420     }
421 }
422 
GetDomainRemoveForwardChainName(Action action,std::vector<std::string> & chainNameList)423 void IptablesManager::GetDomainRemoveForwardChainName(Action action,
424     std::vector<std::string>& chainNameList)
425 {
426     if (action == Action::ALLOW) {
427         chainNameList.emplace_back(EDM_DNS_ALLOW_FORWARD_CHAIN_NAME);
428     } else if (action == Action::DENY) {
429         chainNameList.emplace_back(EDM_DNS_DENY_FORWARD_CHAIN_NAME);
430     } else if (action == Action::REJECT) {
431         chainNameList.emplace_back(EDM_DNS_REJECT_FORWARD_CHAIN_NAME);
432     } else {
433         chainNameList.emplace_back(EDM_DNS_ALLOW_FORWARD_CHAIN_NAME);
434         chainNameList.emplace_back(EDM_DNS_DENY_FORWARD_CHAIN_NAME);
435         chainNameList.emplace_back(EDM_DNS_REJECT_FORWARD_CHAIN_NAME);
436     }
437 }
438 
HasInit()439 bool IptablesManager::HasInit()
440 {
441     return g_chainInit;
442 }
443 
Init()444 void IptablesManager::Init()
445 {
446     if (!g_chainInit) {
447         EDMLOGD("IptablesManager:start init.");
448         std::vector<std::shared_ptr<IExecuter>> allExecuter = ExecuterFactory::GetInstance()->GetAllExecuter();
449         for (const auto &executer : allExecuter) {
450             ErrCode ret = executer->CreateChain();
451             if (ret != ERR_OK) {
452                 EDMLOGE("Init CreateChain fail, this should not happen.");
453                 return;
454             }
455         }
456         for (const auto &executer : allExecuter) {
457             ErrCode ret = executer->Init();
458             if (ret != ERR_OK) {
459                 EDMLOGE("Init fail, this should not happen.");
460                 return;
461             }
462         }
463         g_chainInit = true;
464     }
465 }
466 
SetDefaultFirewallDenyChain(Direction direction)467 void IptablesManager::SetDefaultFirewallDenyChain(Direction direction)
468 {
469     if (!g_defaultFirewallOutputChainInit && (direction == Direction::OUTPUT || direction == Direction::INPUT)) {
470         FirewallRule firewallRule1{Direction::OUTPUT, Action::DENY, Protocol::UDP, "", "", "", "", ""};
471         FirewallRule firewallRule2{Direction::OUTPUT, Action::DENY, Protocol::TCP, "", "", "", "", ""};
472 
473         std::vector<std::shared_ptr<ChainRule>> chainRuleVector{std::make_shared<FirewallChainRule>(),
474             std::make_shared<FirewallChainRule>(firewallRule1), std::make_shared<FirewallChainRule>(firewallRule2)};
475 
476         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DENY_OUTPUT_CHAIN_NAME);
477         if (executer == nullptr) {
478             EDMLOGE("SetDefaultFirewallDenyChain:GetExecuter fail, this should not happen.");
479         } else {
480             for (const auto& chainRule : chainRuleVector) {
481                 executer->Add(chainRule);
482                 g_defaultFirewallOutputChainInit = true;
483             }
484         }
485     }
486     if (!g_defaultFirewallForwardChainInit && direction == Direction::FORWARD) {
487         FirewallRule firewallRule1{Direction::FORWARD, Action::DENY, Protocol::UDP, "", "", "", "", ""};
488         FirewallRule firewallRule2{Direction::FORWARD, Action::DENY, Protocol::TCP, "", "", "", "", ""};
489 
490         std::vector<std::shared_ptr<ChainRule>> chainRuleVector{std::make_shared<FirewallChainRule>(),
491             std::make_shared<FirewallChainRule>(firewallRule1), std::make_shared<FirewallChainRule>(firewallRule2)};
492 
493         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DENY_FORWARD_CHAIN_NAME);
494         if (executer == nullptr) {
495             EDMLOGE("SetDefaultFirewallDenyChain:GetExecuter fail, this should not happen.");
496         } else {
497             for (const auto& chainRule : chainRuleVector) {
498                 executer->Add(chainRule);
499                 g_defaultFirewallForwardChainInit = true;
500             }
501         }
502     }
503 }
504 
ClearDefaultFirewallOutputDenyChain()505 void IptablesManager::ClearDefaultFirewallOutputDenyChain()
506 {
507     auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DENY_OUTPUT_CHAIN_NAME);
508     if (executer == nullptr) {
509         EDMLOGE("ClearDefaultFirewallOutputDenyChain:GetExecuter fail, this should not happen.");
510     } else {
511         executer->Remove(nullptr);
512         g_defaultFirewallOutputChainInit = false;
513     }
514 }
515 
ClearDefaultFirewallForwardDenyChain()516 void IptablesManager::ClearDefaultFirewallForwardDenyChain()
517 {
518     auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DENY_FORWARD_CHAIN_NAME);
519     if (executer == nullptr) {
520         EDMLOGE("ClearDefaultFirewallForwardDenyChain:GetExecuter fail, this should not happen.");
521     } else {
522         executer->Remove(nullptr);
523         g_defaultFirewallForwardChainInit = false;
524     }
525 }
526 
SetDefaultDomainDenyChain(Direction direction)527 void IptablesManager::SetDefaultDomainDenyChain(Direction direction)
528 {
529     if (!g_defaultDomainOutputChainInit && direction == Direction::OUTPUT) {
530         DomainFilterRule domainFilterRule{Action::DENY, "", "", Direction::OUTPUT};
531         std::shared_ptr<ChainRule> chainRule = std::make_shared<DomainChainRule>(domainFilterRule);
532         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DNS_DENY_OUTPUT_CHAIN_NAME);
533         if (executer == nullptr) {
534             EDMLOGE("SetDefaultDomainDenyChain:GetExecuter fail, this should not happen.");
535         } else {
536             executer->Add(chainRule);
537             g_defaultDomainOutputChainInit = true;
538         }
539     }
540 
541     if (!g_defaultDomainForwardChainInit && direction == Direction::FORWARD) {
542         DomainFilterRule domainFilterRule{Action::DENY, "", "", Direction::FORWARD};
543         std::shared_ptr<ChainRule> chainRule = std::make_shared<DomainChainRule>(domainFilterRule);
544         auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DNS_DENY_FORWARD_CHAIN_NAME);
545         if (executer == nullptr) {
546             EDMLOGE("SetDefaultDomainDenyChain:GetExecuter fail, this should not happen.");
547         } else {
548             executer->Add(chainRule);
549             g_defaultDomainForwardChainInit = true;
550         }
551     }
552 }
553 
ClearDefaultDomainOutputDenyChain()554 void IptablesManager::ClearDefaultDomainOutputDenyChain()
555 {
556     auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DNS_DENY_OUTPUT_CHAIN_NAME);
557     if (executer == nullptr) {
558         EDMLOGE("ClearDefaultDomainDenyChain:GetExecuter fail, this should not happen.");
559     } else {
560         executer->Remove(nullptr);
561         g_defaultDomainOutputChainInit = false;
562     }
563 }
564 
ClearDefaultDomainForwardDenyChain()565 void IptablesManager::ClearDefaultDomainForwardDenyChain()
566 {
567     auto executer = ExecuterFactory::GetInstance()->GetExecuter(EDM_DEFAULT_DNS_DENY_FORWARD_CHAIN_NAME);
568     if (executer == nullptr) {
569         EDMLOGE("ClearDefaultDomainDenyChain:GetExecuter fail, this should not happen.");
570     } else {
571         executer->Remove(nullptr);
572         g_defaultDomainForwardChainInit = false;
573     }
574 }
575 
ExistOutputAllowFirewallRule()576 bool IptablesManager::ExistOutputAllowFirewallRule()
577 {
578     std::vector<std::string> chainNameVector{EDM_ALLOW_INPUT_CHAIN_NAME, EDM_ALLOW_OUTPUT_CHAIN_NAME};
579     return ChainExistRule(chainNameVector);
580 }
581 
ExistForwardAllowFirewallRule()582 bool IptablesManager::ExistForwardAllowFirewallRule()
583 {
584     std::vector<std::string> chainNameVector{EDM_ALLOW_FORWARD_CHAIN_NAME};
585     return ChainExistRule(chainNameVector);
586 }
587 
ExistOutputAllowDomainRule()588 bool IptablesManager::ExistOutputAllowDomainRule()
589 {
590     std::vector<std::string> chainNameVector{EDM_DNS_ALLOW_OUTPUT_CHAIN_NAME};
591     return ChainExistRule(chainNameVector);
592 }
593 
ExistForwardAllowDomainRule()594 bool IptablesManager::ExistForwardAllowDomainRule()
595 {
596     std::vector<std::string> chainNameVector{EDM_DNS_ALLOW_FORWARD_CHAIN_NAME};
597     return ChainExistRule(chainNameVector);
598 }
599 
CheckAddFirewallParams(Direction direction,FirewallRule rule)600 bool IptablesManager::CheckAddFirewallParams(Direction direction, FirewallRule rule)
601 {
602     if ((direction == Direction::INPUT || direction == Direction::FORWARD) &&
603         !std::get<FIREWALL_APPUID_IND>(rule).empty()) {
604         EDMLOGE("AddFirewallRule: illegal parameter: appUid");
605         return false;
606     }
607     if (std::get<FIREWALL_PROT_IND>(rule) == Protocol::ALL &&
608         (!std::get<FIREWALL_SRCPORT_IND>(rule).empty() || !std::get<FIREWALL_DESTPORT_IND>(rule).empty())) {
609         EDMLOGE("AddFirewallRule: illegal parameter: protocol");
610         return false;
611     }
612     return true;
613 }
614 
CheckRemoveFirewallParams(Direction direction,FirewallRule rule)615 bool IptablesManager::CheckRemoveFirewallParams(Direction direction, FirewallRule rule)
616 {
617     if ((direction == Direction::INPUT || direction == Direction::FORWARD) &&
618         !std::get<FIREWALL_APPUID_IND>(rule).empty()) {
619         EDMLOGE("RemoveFirewallRule: illegal parameter: appUid");
620         return false;
621     }
622     if (std::get<FIREWALL_PROT_IND>(rule) == Protocol::ALL &&
623         (!std::get<FIREWALL_SRCPORT_IND>(rule).empty() || !std::get<FIREWALL_DESTPORT_IND>(rule).empty())) {
624         EDMLOGE("RemoveFirewallRule: illegal parameter: protocol");
625         return false;
626     }
627     return true;
628 }
629 
CheckRemoveDomainParams(Direction direction,Action action,std::string appUid,std::string domainName)630 bool IptablesManager::CheckRemoveDomainParams(Direction direction, Action action,
631     std::string appUid, std::string domainName)
632 {
633     if (direction == Direction::FORWARD && !appUid.empty()) {
634         EDMLOGE("RemoveDomainFilterRules: illegal parameter: appUid");
635         return false;
636     }
637     if (domainName.empty() && !appUid.empty()) {
638         EDMLOGE("RemoveDomainFilterRules: illegal parameter: appUid");
639         return false;
640     }
641     if (!domainName.empty() && domainName.length() > MAX_DOMAIN_LENGTH) {
642         EDMLOGE("RemoveDomainFilterRules: illegal parameter: domainName");
643         return false;
644     }
645     auto index = domainName.find_first_of("|/");
646     if (index != std::string ::npos) {
647         EDMLOGE("RemoveDomainFilterRules: illegal parameter: domainName");
648         return false;
649     }
650 
651     if (action == Action::INVALID && (!appUid.empty() || !domainName.empty())) {
652         EDMLOGE("RemoveDomainFilterRules: illegal parameter: Too many parameters set");
653         return false;
654     }
655 
656     return true;
657 }
658 
GetFirewallChainName(Direction direction,Action action,std::string & chainName)659 bool IptablesManager::GetFirewallChainName(Direction direction, Action action, std::string& chainName)
660 {
661     if (action == Action::ALLOW && direction == Direction::INPUT) {
662         chainName = EDM_ALLOW_INPUT_CHAIN_NAME;
663     } else if (action == Action::ALLOW && direction == Direction::OUTPUT) {
664         chainName = EDM_ALLOW_OUTPUT_CHAIN_NAME;
665     } else if (action == Action::ALLOW && direction == Direction::FORWARD) {
666         chainName = EDM_ALLOW_FORWARD_CHAIN_NAME;
667     } else if (action == Action::DENY && direction == Direction::INPUT) {
668         chainName = EDM_DENY_INPUT_CHAIN_NAME;
669     } else if (action == Action::DENY && direction == Direction::OUTPUT) {
670         chainName = EDM_DENY_OUTPUT_CHAIN_NAME;
671     } else if (action == Action::DENY && direction == Direction::FORWARD) {
672         chainName = EDM_DENY_FORWARD_CHAIN_NAME;
673     } else if (action == Action::REJECT && direction == Direction::INPUT) {
674         chainName = EDM_REJECT_INPUT_CHAIN_NAME;
675     } else if (action == Action::REJECT && direction == Direction::OUTPUT) {
676         chainName = EDM_REJECT_OUTPUT_CHAIN_NAME;
677     } else if (action == Action::REJECT && direction == Direction::FORWARD) {
678         chainName = EDM_REJECT_FORWARD_CHAIN_NAME;
679     } else {
680         EDMLOGE("AddFirewallRule: illegal parameter: action, direction");
681         return false;
682     }
683     return true;
684 }
685 
ChainExistRule(const std::vector<std::string> & chainNames)686 bool IptablesManager::ChainExistRule(const std::vector<std::string>& chainNames)
687 {
688     std::vector<std::string> ruleList;
689     for (const auto& chainName : chainNames) {
690         auto executer = ExecuterFactory::GetInstance()->GetExecuter(chainName);
691         if (executer == nullptr) {
692             EDMLOGE("ChainExistRule executer null");
693             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
694         }
695         executer->GetAll(ruleList);
696         if (!ruleList.empty()) {
697             return true;
698         }
699     }
700     return false;
701 }
702 
ConvertFirewallRuleList(std::vector<FirewallRuleParcel> & list,std::vector<std::string> ruleList,Direction direction)703 void IptablesManager::ConvertFirewallRuleList(std::vector<FirewallRuleParcel>& list,
704     std::vector<std::string> ruleList, Direction direction)
705 {
706     for (const auto& rule : ruleList) {
707         FirewallChainRule firewallRule{rule};
708         FirewallRuleParcel firewall{firewallRule.ToFilterRule(direction)};
709         list.emplace_back(firewall);
710     }
711 }
712 
713 } // namespace IPTABLES
714 } // namespace EDM
715 } // namespace OHOS