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