1 /*
2  * Copyright (c) 2024 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 #include <arpa/inet.h>
16 #include <sstream>
17 
18 #include "netfirewall_parcel.h"
19 #include "net_mgr_log_wrapper.h"
20 #include "refbase.h"
21 
22 
23 namespace OHOS {
24 namespace NetManagerStandard {
25 namespace {
26 constexpr uint32_t FIREWALL_MAX_LIST_SIZE = 100;
27 }
28 // Firewall IP parameters
Marshalling(Parcel &parcel) const29 bool NetFirewallIpParam::Marshalling(Parcel &parcel) const
30 {
31     parcel.WriteUint8(family);
32     if (!parcel.WriteUint8(type)) {
33         return false;
34     }
35     parcel.WriteUint8(mask);
36     if (family == FAMILY_IPV4) {
37         parcel.WriteUint32(ipv4.startIp.s_addr);
38         if (type == MULTIPLE_IP) {
39             parcel.WriteUint32(ipv4.endIp.s_addr);
40         }
41         return true;
42     }
43     for (int32_t index = 0; index < IPV6_ARRAY_SIZE; index++) {
44         parcel.WriteUint8(ipv6.startIp.s6_addr[index]);
45         if (type == MULTIPLE_IP) {
46             parcel.WriteUint8(ipv6.endIp.s6_addr[index]);
47         }
48     }
49     return true;
50 }
51 
Unmarshalling(Parcel &parcel)52 sptr<NetFirewallIpParam> NetFirewallIpParam::Unmarshalling(Parcel &parcel)
53 {
54     sptr<NetFirewallIpParam> ptr = new (std::nothrow) NetFirewallIpParam();
55     if (ptr == nullptr) {
56         NETMGR_LOG_E("NetFirewallIpParam ptr is null");
57         return nullptr;
58     }
59     parcel.ReadUint8(ptr->family);
60     if (!parcel.ReadUint8(ptr->type)) {
61         return nullptr;
62     }
63     parcel.ReadUint8(ptr->mask);
64 
65     if (ptr->family == FAMILY_IPV4) {
66         parcel.ReadUint32(ptr->ipv4.startIp.s_addr);
67         if (ptr->type == MULTIPLE_IP) {
68             parcel.ReadUint32(ptr->ipv4.endIp.s_addr);
69         }
70         return ptr;
71     }
72     for (int32_t index = 0; index < IPV6_ARRAY_SIZE; index++) {
73         parcel.ReadUint8(ptr->ipv6.startIp.s6_addr[index]);
74         if (ptr->type == MULTIPLE_IP) {
75             parcel.ReadUint8(ptr->ipv6.endIp.s6_addr[index]);
76         }
77     }
78     return ptr;
79 }
80 
split(const std::string &text, char delim)81 std::vector<std::string> NetFirewallUtils::split(const std::string &text, char delim)
82 {
83     std::vector<std::string> tokens;
84     std::stringstream ss(text);
85     std::string item;
86     while (std::getline(ss, item, delim)) {
87         if (!item.empty()) {
88             tokens.emplace_back(item);
89         }
90     }
91     return tokens;
92 }
93 
erase(const std::string &src, const std::string &sub)94 std::string NetFirewallUtils::erase(const std::string &src, const std::string &sub)
95 {
96     size_t index = src.find(sub);
97     if (index == std::string::npos) {
98         return "";
99     }
100     return src.substr(index + sub.length(), src.length() - sub.length());
101 }
102 
GetStartIp() const103 std::string NetFirewallIpParam::GetStartIp() const
104 {
105     char ip[INET6_ADDRSTRLEN] = {};
106     if (this->family == FAMILY_IPV4) {
107         inet_ntop(AF_INET, &(this->ipv4.startIp), ip, INET_ADDRSTRLEN);
108     } else {
109         inet_ntop(AF_INET6, &(this->ipv6.startIp), ip, INET6_ADDRSTRLEN);
110     }
111     return ip;
112 }
113 
GetEndIp() const114 std::string NetFirewallIpParam::GetEndIp() const
115 {
116     if (this->type == SINGLE_IP) {
117         return "";
118     }
119     char ip[INET6_ADDRSTRLEN] = {};
120     if (this->family == FAMILY_IPV4) {
121         inet_ntop(AF_INET, &(this->ipv4.endIp), ip, INET_ADDRSTRLEN);
122     } else {
123         inet_ntop(AF_INET6, &(this->ipv6.endIp), ip, INET6_ADDRSTRLEN);
124     }
125     return ip;
126 }
127 
128 // Firewall port parameters
Marshalling(Parcel &parcel) const129 bool NetFirewallPortParam::Marshalling(Parcel &parcel) const
130 {
131     if (!parcel.WriteUint16(startPort)) {
132         return false;
133     }
134     if (!parcel.WriteUint16(endPort)) {
135         return false;
136     }
137     return true;
138 }
139 
Unmarshalling(Parcel &parcel)140 sptr<NetFirewallPortParam> NetFirewallPortParam::Unmarshalling(Parcel &parcel)
141 {
142     sptr<NetFirewallPortParam> ptr = new (std::nothrow) NetFirewallPortParam();
143     if (ptr == nullptr) {
144         NETMGR_LOG_E("NetFirewallPortParam ptr is null");
145         return nullptr;
146     }
147     if (!parcel.ReadUint16(ptr->startPort)) {
148         return nullptr;
149     }
150     if (!parcel.ReadUint16(ptr->endPort)) {
151         return nullptr;
152     }
153     return ptr;
154 }
155 
156 // Firewall domain name parameters
Marshalling(Parcel &parcel) const157 bool NetFirewallDomainParam::Marshalling(Parcel &parcel) const
158 {
159     if (!parcel.WriteBool(isWildcard)) {
160         return false;
161     }
162     if (!parcel.WriteString(domain)) {
163         return false;
164     }
165     return true;
166 }
167 
Unmarshalling(Parcel &parcel)168 sptr<NetFirewallDomainParam> NetFirewallDomainParam::Unmarshalling(Parcel &parcel)
169 {
170     sptr<NetFirewallDomainParam> ptr = new (std::nothrow) NetFirewallDomainParam();
171     if (ptr == nullptr) {
172         NETMGR_LOG_E("NetFirewallDomainParam ptr is null");
173         return nullptr;
174     }
175     if (!parcel.ReadBool(ptr->isWildcard)) {
176         return nullptr;
177     }
178     if (!parcel.ReadString(ptr->domain)) {
179         return nullptr;
180     }
181     return ptr;
182 }
183 
184 // Firewall DNS parameters
Marshalling(Parcel &parcel) const185 bool NetFirewallDnsParam::Marshalling(Parcel &parcel) const
186 {
187     if (!parcel.WriteString(primaryDns)) {
188         return false;
189     }
190     parcel.WriteString(standbyDns);
191     return true;
192 }
193 
Unmarshalling(Parcel &parcel)194 sptr<NetFirewallDnsParam> NetFirewallDnsParam::Unmarshalling(Parcel &parcel)
195 {
196     sptr<NetFirewallDnsParam> ptr = new (std::nothrow) NetFirewallDnsParam();
197     if (ptr == nullptr) {
198         NETMGR_LOG_E("NetFirewallDnsParam ptr is null");
199         return nullptr;
200     }
201     if (!parcel.ReadString(ptr->primaryDns)) {
202         return nullptr;
203     }
204     parcel.ReadString(ptr->standbyDns);
205     return ptr;
206 }
207 
MarshallingList(const std::vector<T> &list, Parcel &parcel)208 template <typename T> bool NetFirewallUtils::MarshallingList(const std::vector<T> &list, Parcel &parcel)
209 {
210     uint32_t size = static_cast<uint32_t>(list.size());
211     size = std::min(size, FIREWALL_MAX_LIST_SIZE);
212     if (!parcel.WriteUint32(size)) {
213         NETMGR_LOG_E("write netAddrList size to parcel failed");
214         return false;
215     }
216 
217     for (uint32_t index = 0; index < size; ++index) {
218         auto value = list[index];
219         if (!value.Marshalling(parcel)) {
220             NETMGR_LOG_E("write MarshallingList to parcel failed");
221             return false;
222         }
223     }
224     return true;
225 }
226 
UnmarshallingList(Parcel &parcel, std::vector<T> &list)227 template <typename T> bool NetFirewallUtils::UnmarshallingList(Parcel &parcel, std::vector<T> &list)
228 {
229     std::vector<T>().swap(list);
230 
231     uint32_t size = 0;
232     if (!parcel.ReadUint32(size)) {
233         NETMGR_LOG_E("Read UnmarshallingList list size failed");
234         return false;
235     }
236     size = std::min(size, FIREWALL_MAX_LIST_SIZE);
237     for (uint32_t i = 0; i < size; i++) {
238         auto value = T::Unmarshalling(parcel);
239         if (value == nullptr) {
240             return false;
241         }
242         list.emplace_back(*value);
243     }
244     return true;
245 }
246 
247 // Firewall rules, external interfaces
Marshalling(Parcel &parcel) const248 bool NetFirewallRule::Marshalling(Parcel &parcel) const
249 {
250     parcel.WriteInt32(ruleId);
251     if (!parcel.WriteString(ruleName)) {
252         return false;
253     }
254     parcel.WriteString(ruleDescription);
255     if (!parcel.WriteInt32(static_cast<int32_t>(ruleDirection))) {
256         return false;
257     }
258     if (!parcel.WriteInt32(static_cast<int32_t>(ruleAction))) {
259         return false;
260     }
261     if (!parcel.WriteInt32(static_cast<int32_t>(ruleType))) {
262         return false;
263     }
264     parcel.WriteBool(isEnabled);
265     parcel.WriteInt32(appUid);
266     NetFirewallUtils::MarshallingList(localIps, parcel);
267     NetFirewallUtils::MarshallingList(remoteIps, parcel);
268     parcel.WriteInt32(static_cast<int32_t>(protocol));
269     NetFirewallUtils::MarshallingList(localPorts, parcel);
270     NetFirewallUtils::MarshallingList(remotePorts, parcel);
271     NetFirewallUtils::MarshallingList(domains, parcel);
272     dns.Marshalling(parcel);
273     if (!parcel.WriteInt32(userId)) {
274         return false;
275     }
276     return true;
277 }
278 
Unmarshalling(Parcel &parcel)279 sptr<NetFirewallRule> NetFirewallRule::Unmarshalling(Parcel &parcel)
280 {
281     sptr<NetFirewallRule> ptr = new (std::nothrow) NetFirewallRule();
282     if (ptr == nullptr) {
283         NETMGR_LOG_E("NetFirewallRule ptr is null");
284         return nullptr;
285     }
286     parcel.ReadInt32(ptr->ruleId);
287 
288     if (!parcel.ReadString(ptr->ruleName)) {
289         return nullptr;
290     }
291     parcel.ReadString(ptr->ruleDescription);
292     int32_t ruleDirection = 0;
293     if (!parcel.ReadInt32(ruleDirection)) {
294         return nullptr;
295     }
296     ptr->ruleDirection = static_cast<NetFirewallRuleDirection>(ruleDirection);
297     int32_t ruleAction = 0;
298     if (!parcel.ReadInt32(ruleAction)) {
299         return nullptr;
300     }
301     ptr->ruleAction = static_cast<FirewallRuleAction>(ruleAction);
302     int32_t ruleType = 0;
303     if (!parcel.ReadInt32(ruleType)) {
304         return nullptr;
305     }
306     ptr->ruleType = static_cast<NetFirewallRuleType>(ruleType);
307     parcel.ReadBool(ptr->isEnabled);
308     parcel.ReadInt32(ptr->appUid);
309     NetFirewallUtils::UnmarshallingList(parcel, ptr->localIps);
310     NetFirewallUtils::UnmarshallingList(parcel, ptr->remoteIps);
311     int32_t protocol = 0;
312     if (parcel.ReadInt32(protocol)) {
313         ptr->protocol = static_cast<NetworkProtocol>(protocol);
314     }
315     NetFirewallUtils::UnmarshallingList(parcel, ptr->localPorts);
316     NetFirewallUtils::UnmarshallingList(parcel, ptr->remotePorts);
317     NetFirewallUtils::UnmarshallingList(parcel, ptr->domains);
318     sptr<NetFirewallDnsParam> dns = NetFirewallDnsParam::Unmarshalling(parcel);
319     if (dns != nullptr) {
320         ptr->dns = *dns;
321     }
322     if (!parcel.ReadInt32(ptr->userId)) {
323         return nullptr;
324     }
325     return ptr;
326 }
327 
ToString() const328 std::string NetFirewallRule::ToString() const
329 {
330     const std::string size = " size=";
331     std::stringstream ss;
332     ss << "NetFirewallRule:{" << NET_FIREWALL_RULE_ID << EQUAL << this->ruleId << COMMA << NET_FIREWALL_RULE_NAME <<
333         EQUAL << this->ruleName << COMMA << NET_FIREWALL_RULE_DESC << EQUAL << this->ruleDescription << COMMA <<
334         NET_FIREWALL_RULE_DIR << EQUAL << int(this->ruleDirection) << COMMA << NET_FIREWALL_RULE_ACTION << EQUAL <<
335         int(this->ruleAction) << COMMA << NET_FIREWALL_RULE_TYPE << EQUAL << int(this->ruleType) << COMMA <<
336         NET_FIREWALL_IS_ENABLED << EQUAL << this->isEnabled << COMMA << NET_FIREWALL_APP_ID << EQUAL << this->appUid <<
337         COMMA << NET_FIREWALL_PROTOCOL << EQUAL << int(this->protocol) << COMMA << NET_FIREWALL_USER_ID << EQUAL <<
338         this->userId << COMMA << NET_FIREWALL_LOCAL_IP << size << this->localIps.size() << COMMA <<
339         NET_FIREWALL_REMOTE_IP << size << this->remoteIps.size() << COMMA << NET_FIREWALL_LOCAL_PORT << size <<
340         this->localPorts.size() << COMMA << NET_FIREWALL_DOMAIN << size << this->remotePorts.size() << COMMA <<
341         NET_FIREWALL_REMOTE_PORT << size << this->domains.size() << "}";
342     return ss.str();
343 }
344 
Marshalling(Parcel &parcel) const345 bool NetFirewallBaseRule::Marshalling(Parcel &parcel) const
346 {
347     parcel.WriteInt32(userId);
348     parcel.WriteInt32(appUid);
349     return true;
350 }
351 
Unmarshalling(Parcel &parcel)352 sptr<NetFirewallBaseRule> NetFirewallBaseRule::Unmarshalling(Parcel &parcel)
353 {
354     sptr<NetFirewallBaseRule> ptr = new (std::nothrow) NetFirewallBaseRule();
355     if (ptr == nullptr) {
356         NETMGR_LOG_E("NetFirewallBaseRule ptr is null");
357         return nullptr;
358     }
359     parcel.ReadInt32(ptr->userId);
360     parcel.ReadInt32(ptr->appUid);
361     return ptr;
362 }
363 
UnmarshallingBase(Parcel &parcel, sptr<NetFirewallBaseRule> ptr)364 bool NetFirewallBaseRule::UnmarshallingBase(Parcel &parcel, sptr<NetFirewallBaseRule> ptr)
365 {
366     parcel.ReadInt32(ptr->userId);
367     parcel.ReadInt32(ptr->appUid);
368     return true;
369 }
370 
371 // IP rule data
Marshalling(Parcel &parcel) const372 bool NetFirewallIpRule::Marshalling(Parcel &parcel) const
373 {
374     NetFirewallBaseRule::Marshalling(parcel);
375     if (!parcel.WriteInt32(static_cast<int32_t>(ruleDirection))) {
376         return false;
377     }
378     if (!parcel.WriteInt32(static_cast<int32_t>(ruleAction))) {
379         return false;
380     }
381     parcel.WriteInt32(static_cast<int32_t>(protocol));
382     NetFirewallUtils::MarshallingList(localIps, parcel);
383     NetFirewallUtils::MarshallingList(remoteIps, parcel);
384     NetFirewallUtils::MarshallingList(localPorts, parcel);
385     NetFirewallUtils::MarshallingList(remotePorts, parcel);
386     return true;
387 }
388 
Unmarshalling(Parcel &parcel)389 sptr<NetFirewallIpRule> NetFirewallIpRule::Unmarshalling(Parcel &parcel)
390 {
391     sptr<NetFirewallIpRule> ptr = new (std::nothrow) NetFirewallIpRule();
392     if (ptr == nullptr) {
393         NETMGR_LOG_E("NetFirewallIpRule ptr is null");
394         return nullptr;
395     }
396     NetFirewallBaseRule::UnmarshallingBase(parcel, ptr);
397     int32_t ruleDirection = 0;
398     if (!parcel.ReadInt32(ruleDirection)) {
399         return nullptr;
400     }
401     ptr->ruleDirection = static_cast<NetFirewallRuleDirection>(ruleDirection);
402     int32_t ruleAction = 0;
403     if (!parcel.ReadInt32(ruleAction)) {
404         return nullptr;
405     }
406     ptr->ruleAction = static_cast<FirewallRuleAction>(ruleAction);
407     int32_t protocol = 0;
408     if (parcel.ReadInt32(protocol)) {
409         ptr->protocol = static_cast<NetworkProtocol>(protocol);
410     }
411     NetFirewallUtils::UnmarshallingList(parcel, ptr->localIps);
412     NetFirewallUtils::UnmarshallingList(parcel, ptr->remoteIps);
413     NetFirewallUtils::UnmarshallingList(parcel, ptr->localPorts);
414     NetFirewallUtils::UnmarshallingList(parcel, ptr->remotePorts);
415     return ptr;
416 }
417 
418 // domain rule data
Marshalling(Parcel &parcel) const419 bool NetFirewallDomainRule::Marshalling(Parcel &parcel) const
420 {
421     NetFirewallBaseRule::Marshalling(parcel);
422     if (!parcel.WriteInt32(static_cast<int32_t>(ruleAction))) {
423         return false;
424     }
425     NetFirewallUtils::MarshallingList(domains, parcel);
426     return true;
427 }
428 
Unmarshalling(Parcel &parcel)429 sptr<NetFirewallDomainRule> NetFirewallDomainRule::Unmarshalling(Parcel &parcel)
430 {
431     sptr<NetFirewallDomainRule> ptr = new (std::nothrow) NetFirewallDomainRule();
432     if (ptr == nullptr) {
433         NETMGR_LOG_E("NetFirewallDomainRule ptr is null");
434         return nullptr;
435     }
436     NetFirewallBaseRule::UnmarshallingBase(parcel, ptr);
437     int32_t ruleAction = 0;
438     if (!parcel.ReadInt32(ruleAction)) {
439         return nullptr;
440     }
441     ptr->ruleAction = static_cast<FirewallRuleAction>(ruleAction);
442     NetFirewallUtils::UnmarshallingList(parcel, ptr->domains);
443     return ptr;
444 }
445 
446 // DNS rule data
Marshalling(Parcel &parcel) const447 bool NetFirewallDnsRule::Marshalling(Parcel &parcel) const
448 {
449     NetFirewallBaseRule::Marshalling(parcel);
450     if (!parcel.WriteString(primaryDns)) {
451         return false;
452     }
453     parcel.WriteString(standbyDns);
454     return true;
455 }
456 
Unmarshalling(Parcel &parcel)457 sptr<NetFirewallDnsRule> NetFirewallDnsRule::Unmarshalling(Parcel &parcel)
458 {
459     sptr<NetFirewallDnsRule> ptr = new (std::nothrow) NetFirewallDnsRule();
460     if (ptr == nullptr) {
461         NETMGR_LOG_E("NetFirewallDnsRule ptr is null");
462         return nullptr;
463     }
464     NetFirewallBaseRule::UnmarshallingBase(parcel, ptr);
465     if (!parcel.ReadString(ptr->primaryDns)) {
466         return nullptr;
467     }
468     parcel.ReadString(ptr->standbyDns);
469     return ptr;
470 }
471 
472 // Interception Record
Marshalling(Parcel &parcel) const473 bool InterceptRecord::Marshalling(Parcel &parcel) const
474 {
475     parcel.WriteUint16(localPort);
476     parcel.WriteUint16(remotePort);
477     parcel.WriteUint16(protocol);
478     if (!parcel.WriteInt32(time)) {
479         return false;
480     }
481     if (!parcel.WriteString(localIp)) {
482         return false;
483     }
484     if (!parcel.WriteString(remoteIp)) {
485         return false;
486     }
487     if (!parcel.WriteInt32(appUid)) {
488         return false;
489     }
490     if (!parcel.WriteString(domain)) {
491         return false;
492     }
493     return true;
494 }
495 
Unmarshalling(Parcel &parcel)496 sptr<InterceptRecord> InterceptRecord::Unmarshalling(Parcel &parcel)
497 {
498     sptr<InterceptRecord> ptr = new (std::nothrow) InterceptRecord();
499     if (ptr == nullptr) {
500         NETMGR_LOG_E("InterceptRecord ptr is null");
501         return nullptr;
502     }
503     parcel.ReadUint16(ptr->localPort);
504     parcel.ReadUint16(ptr->remotePort);
505     parcel.ReadUint16(ptr->protocol);
506     if (!parcel.ReadInt32(ptr->time)) {
507         return nullptr;
508     }
509     if (!parcel.ReadString(ptr->localIp)) {
510         return nullptr;
511     }
512     if (!parcel.ReadString(ptr->remoteIp)) {
513         return nullptr;
514     }
515     if (!parcel.ReadInt32(ptr->appUid)) {
516         return nullptr;
517     }
518     if (!parcel.ReadString(ptr->domain)) {
519         return nullptr;
520     }
521     return ptr;
522 }
523 } // namespace NetManagerStandard
524 } // namespace OHOS