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 "firewall_chain_rule.h"
17
18 #include <algorithm>
19 #include <iostream>
20 #include <sstream>
21 #include <string>
22
23 #include "rule_utils.h"
24
25 namespace OHOS {
26 namespace EDM {
27 namespace IPTABLES {
28
FirewallChainRule()29 FirewallChainRule::FirewallChainRule(): ChainRule()
30 {
31 target_ = ACCEPT_TARGET;
32 state_ = "RELATED,ESTABLISHED";
33 }
34
FirewallChainRule(FirewallRule firewallTuple)35 FirewallChainRule::FirewallChainRule(FirewallRule firewallTuple) : ChainRule(),
36 srcPort_(std::get<FIREWALL_SRCPORT_IND>(firewallTuple)),
37 destPort_(std::get<FIREWALL_DESTPORT_IND>(firewallTuple)),
38 appUid_(std::get<FIREWALL_APPUID_IND>(firewallTuple))
39 {
40 target_ = RuleUtils::EnumToString(std::get<FIREWALL_ACTION_IND>(firewallTuple));
41 prot_ = RuleUtils::EnumToString(std::get<FIREWALL_PROT_IND>(firewallTuple));
42 srcAddr_ = std::get<FIREWALL_SRCADDR_IND>(firewallTuple);
43 destAddr_ = std::get<FIREWALL_DESTADDR_IND>(firewallTuple);
44 }
45
FirewallChainRule(const std::string & rule)46 FirewallChainRule::FirewallChainRule(const std::string &rule) : ChainRule(rule)
47 {
48 GetOption(otherOptions_, "source IP range", srcAddr_);
49 GetOption(otherOptions_, "destination IP range", destAddr_);
50 std::string spt;
51 GetOption(otherOptions_, "spt:", spt);
52 if (spt.empty()) {
53 GetOption(otherOptions_, "spts:", spt);
54 if (spt.empty()) {
55 GetOption(otherOptions_, "multiport sports", spt);
56 }
57 }
58 srcPort_ = spt;
59 std::string dpt;
60 GetOption(otherOptions_, "dpt:", dpt);
61 if (dpt.empty()) {
62 GetOption(otherOptions_, "dpts:", dpt);
63 if (dpt.empty()) {
64 GetOption(otherOptions_, "multiport dports", dpt);
65 }
66 }
67 destPort_ = dpt;
68 GetOption(otherOptions_, "owner UID match", appUid_);
69 }
70
Parameter() const71 std::string FirewallChainRule::Parameter() const
72 {
73 std::ostringstream parameterString;
74 if (!prot_.empty()) {
75 parameterString << " -p ";
76 parameterString << prot_;
77 }
78 parameterString << IpToParameter(srcAddr_, "-s");
79 parameterString << IpToParameter(destAddr_, "-d");
80
81 std::string splitStr = ",";
82 auto sidx = srcPort_.find(splitStr);
83 auto didx = destPort_.find(splitStr);
84 std::string portOption = SPACE_OPTION;
85 if (sidx != std::string::npos || didx != std::string::npos) {
86 portOption = " -m multiport ";
87 }
88 parameterString << PortToParameter(srcPort_, "--sport", portOption);
89 parameterString << PortToParameter(destPort_, "--dport", portOption);
90 if (!appUid_.empty()) {
91 parameterString << " -m owner --uid-owner " << appUid_;
92 }
93 if (!state_.empty()) {
94 parameterString << " -m state --state " << state_;
95 }
96 return parameterString.str();
97 }
98
IpToParameter(const std::string & ip,const std::string & ipType)99 std::string FirewallChainRule::IpToParameter(const std::string &ip, const std::string &ipType)
100 {
101 if (ip.empty()) {
102 return {};
103 }
104 std::ostringstream parameterString;
105 std::string splitStr = "-";
106 auto idx = ip.find(splitStr);
107 if (idx == std::string::npos) {
108 parameterString << SPACE_OPTION << ipType << SPACE_OPTION << ip;
109 } else {
110 if (ipType == "-s") {
111 parameterString << " -m iprange --src-range " << ip;
112 } else {
113 parameterString << " -m iprange --dst-range " << ip;
114 }
115 }
116 return parameterString.str();
117 }
118
PortToParameter(const std::string & port,const std::string & portType,const std::string & portOption)119 std::string FirewallChainRule::PortToParameter(const std::string &port, const std::string &portType,
120 const std::string &portOption)
121 {
122 if (port.empty()) {
123 return {};
124 }
125 std::ostringstream parameterString;
126 parameterString << portOption << portType << SPACE_OPTION << port;
127 return parameterString.str();
128 }
129
ToFilterRule(Direction direction)130 FirewallRule FirewallChainRule::ToFilterRule(Direction direction)
131 {
132 Action action = RuleUtils::StringToAction(target_);
133 Protocol protocl = RuleUtils::StringProtocl(prot_);
134 return {direction, action, protocl, srcAddr_, destAddr_, srcPort_, destPort_, appUid_};
135 }
136
137 } // namespace IPTABLES
138 } // namespace EDM
139 } // namespace OHOS