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