1 /*
2  * Copyright (c) 2022-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 "net_policy_rule.h"
17 
18 #include "net_mgr_log_wrapper.h"
19 #include "iptables_type.h"
20 
21 namespace OHOS {
22 namespace NetManagerStandard {
23 NetPolicyRule::NetPolicyRule() = default;
24 
Init()25 void NetPolicyRule::Init()
26 {
27     // Init uid、policy and background allow status from file,and save uid、policy into uidPolicyRules_.
28     NETMGR_LOG_I("Start init uid and policy.");
29     const auto &uidsPolicies = GetFileInst()->ReadUidPolicies();
30     backgroundAllow_ = GetFileInst()->ReadBackgroundPolicy();
31     for (const auto &i : uidsPolicies) {
32         auto uid = CommonUtils::StrToUint(i.uid.c_str());
33         auto policy = CommonUtils::StrToUint(i.policy.c_str());
34         uidPolicyRules_[uid] = {.policy_ = policy};
35         TransPolicyToRule(uid, policy);
36     }
37 }
38 
TransPolicyToRule()39 void NetPolicyRule::TransPolicyToRule()
40 {
41     // When system status is changed,traverse uidPolicyRules_ to calculate the rule and netsys.
42     for (const auto &[uid, policy] : uidPolicyRules_) {
43         TransPolicyToRule(uid, policy.policy_);
44     }
45 }
46 
TransPolicyToRule(uint32_t uid)47 void NetPolicyRule::TransPolicyToRule(uint32_t uid)
48 {
49     uint32_t policy = 0;
50     const auto &itr = uidPolicyRules_.find(uid);
51     if (itr == uidPolicyRules_.end()) {
52         policy = NET_POLICY_NONE;
53     } else {
54         policy = itr->second.policy_;
55     }
56     NETMGR_LOG_D("TransPolicyToRule only with uid value: uid[%{public}u] policy[%{public}u]", uid, policy);
57     TransPolicyToRule(uid, policy);
58     return;
59 }
60 
TransPolicyToRule(uint32_t uid,uint32_t policy)61 int32_t NetPolicyRule::TransPolicyToRule(uint32_t uid, uint32_t policy)
62 {
63     if (!IsValidNetPolicy(policy)) {
64         NETMGR_LOG_E("policy[%{public}d] is invalid", policy);
65         return POLICY_ERR_INVALID_POLICY;
66     }
67     NetmanagerHiTrace::NetmanagerStartSyncTrace("TransPolicyToRule start");
68     auto policyRule = uidPolicyRules_.find(uid);
69     if (policyRule == uidPolicyRules_.end()) {
70         NETMGR_LOG_D("Don't find this uid, need to add uid:[%{public}u] policy[%{public}u].", uid, policy);
71         uidPolicyRules_[uid] = {.policy_ = policy};
72         GetCbInst()->NotifyNetUidPolicyChangeAsync(uid, policy);
73     } else {
74         if (policyRule->second.policy_ != policy) {
75             NETMGR_LOG_D("Update policy's value.uid:[%{public}u] policy[%{public}u]", uid, policy);
76             policyRule->second.policy_ = policy;
77             GetCbInst()->NotifyNetUidPolicyChangeAsync(uid, policy);
78         }
79     }
80 
81     auto policyCondition = BuildTransCondition(uid, policy);
82     TransConditionToRuleAndNetsys(policyCondition, uid, policy);
83     NetmanagerHiTrace::NetmanagerFinishSyncTrace("TransPolicyToRule end");
84     NETMGR_LOG_D("End TransPolicyToRule");
85     return NETMANAGER_SUCCESS;
86 }
87 
BuildTransCondition(uint32_t uid,uint32_t policy)88 uint32_t NetPolicyRule::BuildTransCondition(uint32_t uid, uint32_t policy)
89 {
90     // Integrate status values, the result of policyCondition will be use in TransConditionToRuleAndNetsys.
91     uint32_t policyCondition = ChangePolicyToPolicyTransitionCondition(policy);
92 
93     if (IsIdleMode()) {
94         policyCondition |= POLICY_TRANS_CONDITION_IDLE_MODE;
95     }
96     if (InIdleAllowedList(uid)) {
97         policyCondition |= POLICY_TRANS_CONDITION_IDLE_ALLOWEDLIST;
98     }
99     if (IsLimitByAdmin()) {
100         policyCondition |= POLICY_TRANS_CONDITION_ADMIN_RESTRICT;
101     }
102     if (IsPowerSave()) {
103         policyCondition |= POLICY_TRANS_CONDITION_POWERSAVE_MODE;
104     }
105     if (InPowerSaveAllowedList(uid)) {
106         policyCondition |= POLICY_TRANS_CONDITION_POWERSAVE_ALLOWEDLIST;
107     }
108     if (IsLimitedBackground()) {
109         policyCondition |= POLICY_TRANS_CONDITION_BACKGROUND_RESTRICT;
110     }
111     if (IsForeground(uid)) {
112         policyCondition |= POLICY_TRANS_CONDITION_FOREGROUND;
113     }
114     NETMGR_LOG_D("BuildTransCondition uid[%{public}u] policy[%{public}u]", uid, policy);
115     return policyCondition;
116 }
117 
TransConditionToRuleAndNetsys(uint32_t policyCondition,uint32_t uid,uint32_t policy)118 void NetPolicyRule::TransConditionToRuleAndNetsys(uint32_t policyCondition, uint32_t uid, uint32_t policy)
119 {
120     uint32_t conditionValue = GetMatchTransCondition(policyCondition);
121 
122     auto rule = MoveToRuleBit(conditionValue & POLICY_TRANS_RULE_MASK);
123     NETMGR_LOG_D("NetPolicyRule->uid:[%{public}u] policy:[%{public}u] rule:[%{public}u] policyCondition[%{public}u]",
124                  uid, policy, rule, policyCondition);
125     auto policyRuleNetsys = uidPolicyRules_.find(uid)->second;
126     auto netsys = conditionValue & POLICY_TRANS_NET_CTRL_MASK;
127 
128     if (policyRuleNetsys.netsys_ != netsys) {
129         NetsysCtrl(uid, netsys);
130         policyRuleNetsys.netsys_ = netsys;
131     } else {
132         NETMGR_LOG_I("Same netsys and uid ,don't need to do others.now netsys is: [%{public}u]", netsys);
133     }
134 
135     GetFileInst()->WritePolicyByUid(uid, policy);
136 
137     if (policyRuleNetsys.rule_ == rule) {
138         NETMGR_LOG_D("Same rule and uid ,don't need to do others.uid is:[%{public}u] rule is:[%{public}u]", uid, rule);
139         return;
140     }
141 
142     policyRuleNetsys.rule_ = rule;
143     GetCbInst()->NotifyNetUidRuleChangeAsync(uid, rule);
144 }
145 
GetMatchTransCondition(uint32_t policyCondition)146 uint32_t NetPolicyRule::GetMatchTransCondition(uint32_t policyCondition)
147 {
148     for (const auto &i : POLICY_TRANS_MAP) {
149         auto condition = MoveToConditionBit(i & POLICY_TRANS_CONDITION_MASK);
150         if ((policyCondition & condition) == condition) {
151             NETMGR_LOG_D("GetMatchTransCondition condition: %{public}d.", i);
152             return i;
153         }
154     }
155     return POLICY_TRANS_MAP.back();
156 }
157 
NetsysCtrl(uint32_t uid,uint32_t netsysCtrl)158 void NetPolicyRule::NetsysCtrl(uint32_t uid, uint32_t netsysCtrl)
159 {
160     switch (netsysCtrl) {
161         case POLICY_TRANS_CTRL_NONE:
162             ProcessCtrlNone(uid);
163             break;
164         case POLICY_TRANS_CTRL_REMOVE_ALL:
165             GetNetsysInst()->BandwidthRemoveAllowedList(uid);
166             GetNetsysInst()->BandwidthRemoveDeniedList(uid);
167             break;
168         case POLICY_TRANS_CTRL_ADD_DENIEDLIST:
169             GetNetsysInst()->BandwidthAddDeniedList(uid);
170             GetNetsysInst()->BandwidthRemoveAllowedList(uid);
171             break;
172         case POLICY_TRANS_CTRL_ADD_ALLOWEDLIST:
173             ProcessCtrlAddAllowedList(uid);
174             break;
175         default:
176             NETMGR_LOG_E("Error netsysCtrl value, need to check");
177             break;
178     }
179     NETMGR_LOG_D("uid:[%{public}u]   netsysCtrl: [%{public}u]", uid, netsysCtrl);
180 }
181 
ProcessCtrlNone(uint32_t uid)182 void NetPolicyRule::ProcessCtrlNone(uint32_t uid)
183 {
184     if (IsPowerSave()) {
185         GetNetsysInst()->PowerSaveUpdataAllowedList(uid, FirewallRule::RULE_DENY);
186     } else {
187         NETMGR_LOG_D("Don't need to do anything,keep now status.");
188     }
189 }
190 
ProcessCtrlAddAllowedList(uint32_t uid)191 void NetPolicyRule::ProcessCtrlAddAllowedList(uint32_t uid)
192 {
193     GetNetsysInst()->BandwidthRemoveDeniedList(uid);
194     GetNetsysInst()->BandwidthAddAllowedList(uid);
195     if (IsPowerSave()) {
196         GetNetsysInst()->PowerSaveUpdataAllowedList(uid, FirewallRule::RULE_ALLOW);
197     }
198 }
199 
MoveToConditionBit(uint32_t value)200 uint32_t NetPolicyRule::MoveToConditionBit(uint32_t value)
201 {
202     return value >> CONDITION_START_BIT;
203 }
204 
MoveToRuleBit(uint32_t value)205 uint32_t NetPolicyRule::MoveToRuleBit(uint32_t value)
206 {
207     return value >> RULE_START_BIT;
208 }
209 
ChangePolicyToPolicyTransitionCondition(uint32_t policy)210 uint32_t NetPolicyRule::ChangePolicyToPolicyTransitionCondition(uint32_t policy)
211 {
212     if (policy == NET_POLICY_NONE) {
213         return POLICY_TRANS_CONDITION_UID_POLICY_NONE;
214     }
215     return policy << 1;
216 }
217 
GetPolicyByUid(uint32_t uid,uint32_t & policy)218 int32_t NetPolicyRule::GetPolicyByUid(uint32_t uid, uint32_t &policy)
219 {
220     auto policyRule = uidPolicyRules_.find(uid);
221     if (policyRule == uidPolicyRules_.end()) {
222         NETMGR_LOG_D("Can't find uid:[%{public}u] and its policy, return default value.", uid);
223         policy = NET_POLICY_NONE;
224         return NETMANAGER_SUCCESS;
225     }
226     policy = policyRule->second.policy_;
227     return NETMANAGER_SUCCESS;
228 }
229 
GetUidsByPolicy(uint32_t policy,std::vector<uint32_t> & uids)230 int32_t NetPolicyRule::GetUidsByPolicy(uint32_t policy, std::vector<uint32_t> &uids)
231 {
232     if (!IsValidNetPolicy(policy)) {
233         return POLICY_ERR_INVALID_POLICY;
234     }
235     NETMGR_LOG_I("GetUidsByPolicy:policy:[%{public}u]", policy);
236     for (auto &iter : uidPolicyRules_) {
237         if (iter.second.policy_ == policy) {
238             uids.push_back(iter.first);
239         }
240     }
241     return NETMANAGER_SUCCESS;
242 }
243 
IsUidNetAllowed(uint32_t uid,bool metered,bool & isAllowed)244 int32_t NetPolicyRule::IsUidNetAllowed(uint32_t uid, bool metered, bool &isAllowed)
245 {
246     NETMGR_LOG_D("IsUidNetAllowed:uid[%{public}u] metered:[%{public}d]", uid, metered);
247     uint32_t rule = NetUidRule::NET_RULE_NONE;
248     auto iter = uidPolicyRules_.find(uid);
249     if (iter != uidPolicyRules_.end()) {
250         rule = iter->second.rule_;
251     }
252     NETMGR_LOG_I("IsUidNetAllowed:rule[%{public}u], backgroundAllow_[%{public}d]", rule, backgroundAllow_);
253     if (rule == NetUidRule::NET_RULE_REJECT_ALL) {
254         isAllowed = false;
255         return NETMANAGER_SUCCESS;
256     }
257 
258     if (!metered) {
259         isAllowed = true;
260         return NETMANAGER_SUCCESS;
261     }
262 
263     if (rule == NetUidRule::NET_RULE_REJECT_METERED) {
264         isAllowed = false;
265         return NETMANAGER_SUCCESS;
266     }
267 
268     if (rule == NetUidRule::NET_RULE_ALLOW_METERED) {
269         isAllowed = true;
270         return NETMANAGER_SUCCESS;
271     }
272 
273     if (rule == NetUidRule::NET_RULE_ALLOW_METERED_FOREGROUND) {
274         isAllowed = true;
275         return NETMANAGER_SUCCESS;
276     }
277 
278     if (!backgroundAllow_) {
279         isAllowed = false;
280         return NETMANAGER_SUCCESS;
281     }
282 
283     isAllowed = true;
284     return NETMANAGER_SUCCESS;
285 }
286 
SetBackgroundPolicy(bool allow)287 int32_t NetPolicyRule::SetBackgroundPolicy(bool allow)
288 {
289     if (backgroundAllow_ != allow) {
290         GetCbInst()->NotifyNetBackgroundPolicyChangeAsync(allow);
291         backgroundAllow_ = allow;
292         TransPolicyToRule();
293         GetFileInst()->WriteBackgroundPolicy(allow);
294         NetmanagerHiTrace::NetmanagerStartSyncTrace("SetBackgroundPolicy policy start");
295         GetNetsysInst()->BandwidthEnableDataSaver(!allow);
296         NetmanagerHiTrace::NetmanagerFinishSyncTrace("SetBackgroundPolicy policy end");
297         return NETMANAGER_SUCCESS;
298     }
299     NETMGR_LOG_I("Same background policy,don't need to repeat set. now background policy is:[%{public}d]", allow);
300     return NETMANAGER_ERR_PARAMETER_ERROR;
301 }
302 
GetBackgroundPolicyByUid(uint32_t uid,uint32_t & backgroundPolicyOfUid)303 int32_t NetPolicyRule::GetBackgroundPolicyByUid(uint32_t uid, uint32_t &backgroundPolicyOfUid)
304 {
305     uint32_t policy = 0;
306     GetPolicyByUid(uid, policy);
307     NETMGR_LOG_D("GetBackgroundPolicyByUid GetPolicyByUid uid: %{public}u policy: %{public}u.", uid, policy);
308     if ((policy & NET_POLICY_REJECT_METERED_BACKGROUND) != 0) {
309         backgroundPolicyOfUid = NET_BACKGROUND_POLICY_DISABLE;
310         return NETMANAGER_SUCCESS;
311     }
312 
313     if (backgroundAllow_) {
314         backgroundPolicyOfUid = NET_BACKGROUND_POLICY_ENABLE;
315         return NETMANAGER_SUCCESS;
316     }
317 
318     if ((policy & NET_POLICY_ALLOW_METERED_BACKGROUND) != 0) {
319         backgroundPolicyOfUid = NET_BACKGROUND_POLICY_TRUSTLIST;
320         return NETMANAGER_SUCCESS;
321     }
322     backgroundPolicyOfUid = NET_BACKGROUND_POLICY_DISABLE;
323     return NETMANAGER_SUCCESS;
324 }
325 
ResetPolicies()326 int32_t NetPolicyRule::ResetPolicies()
327 {
328     NETMGR_LOG_I("Reset uids-policies and backgroundpolicy");
329     for (auto iter : uidPolicyRules_) {
330         TransPolicyToRule(iter.first, NetUidPolicy::NET_POLICY_NONE);
331     }
332     return SetBackgroundPolicy(true);
333 }
334 
GetBackgroundPolicy(bool & backgroundPolicy)335 int32_t NetPolicyRule::GetBackgroundPolicy(bool &backgroundPolicy)
336 {
337     NETMGR_LOG_I("GetBackgroundPolicy:backgroundAllow_[%{public}d", backgroundAllow_);
338     backgroundPolicy = backgroundAllow_;
339     return NETMANAGER_SUCCESS;
340 }
341 
IsIdleMode()342 bool NetPolicyRule::IsIdleMode()
343 {
344     NETMGR_LOG_D("IsIdleMode:deviceIdleMode_[%{public}d", deviceIdleMode_);
345     return deviceIdleMode_;
346 }
347 
InIdleAllowedList(uint32_t uid)348 bool NetPolicyRule::InIdleAllowedList(uint32_t uid)
349 {
350     if (std::find(deviceIdleAllowedList_.begin(), deviceIdleAllowedList_.end(), uid) != deviceIdleAllowedList_.end()) {
351         return true;
352     }
353     return false;
354 }
355 
IsLimitByAdmin()356 bool NetPolicyRule::IsLimitByAdmin()
357 {
358     // to judge if limit by admin.
359     return false;
360 }
361 
IsForeground(uint32_t uid)362 bool NetPolicyRule::IsForeground(uint32_t uid)
363 {
364     std::lock_guard lock(foregroundUidListMutex_);
365     return std::find(foregroundUidList_.begin(), foregroundUidList_.end(), uid) != foregroundUidList_.end();
366 }
367 
IsPowerSave()368 bool NetPolicyRule::IsPowerSave()
369 {
370     return powerSaveMode_;
371 }
372 
InPowerSaveAllowedList(uint32_t uid)373 bool NetPolicyRule::InPowerSaveAllowedList(uint32_t uid)
374 {
375     return std::find(powerSaveAllowedList_.begin(), powerSaveAllowedList_.end(), uid) != powerSaveAllowedList_.end();
376 }
377 
IsLimitedBackground()378 bool NetPolicyRule::IsLimitedBackground()
379 {
380     return !backgroundAllow_;
381 }
382 
DeleteUid(uint32_t uid)383 void NetPolicyRule::DeleteUid(uint32_t uid)
384 {
385     NETMGR_LOG_D("DeleteUid:uid[%{public}u]", uid);
386 
387     const auto &it = std::find_if(uidPolicyRules_.begin(), uidPolicyRules_.end(),
388                                   [&uid](const auto &pair) { return pair.first == uid; });
389     if (it != uidPolicyRules_.end()) {
390         uidPolicyRules_.erase(it);
391     }
392     GetFileInst()->RemoveInexistentUid(uid);
393     GetNetsysInst()->BandwidthRemoveDeniedList(uid);
394     GetNetsysInst()->BandwidthRemoveAllowedList(uid);
395 }
396 
HandleEvent(int32_t eventId,const std::shared_ptr<PolicyEvent> & policyEvent)397 void NetPolicyRule::HandleEvent(int32_t eventId, const std::shared_ptr<PolicyEvent> &policyEvent)
398 {
399     switch (eventId) {
400         case NetPolicyEventHandler::MSG_DEVICE_IDLE_LIST_UPDATED:
401             deviceIdleAllowedList_ = policyEvent->deviceIdleList;
402             break;
403         case NetPolicyEventHandler::MSG_DEVICE_IDLE_MODE_CHANGED:
404             deviceIdleMode_ = policyEvent->deviceIdleMode;
405             TransPolicyToRule();
406             break;
407         case NetPolicyEventHandler::MSG_POWER_SAVE_MODE_CHANGED:
408             powerSaveMode_ = policyEvent->powerSaveMode;
409             TransPolicyToRule();
410             break;
411         case NetPolicyEventHandler::MSG_POWER_SAVE_LIST_UPDATED:
412             powerSaveAllowedList_ = policyEvent->powerSaveList;
413             break;
414         case NetPolicyEventHandler::MSG_UID_REMOVED:
415             DeleteUid(policyEvent->deletedUid);
416             break;
417         case NetPolicyEventHandler::MSG_UID_STATE_FOREGROUND:
418             UpdateForegroundUidList(policyEvent->uid, true);
419             TransPolicyToRule(policyEvent->uid);
420             break;
421         case NetPolicyEventHandler::MSG_UID_STATE_BACKGROUND:
422             UpdateForegroundUidList(policyEvent->uid, false);
423             TransPolicyToRule(policyEvent->uid);
424             break;
425         default:
426             break;
427     }
428 }
429 
UpdateForegroundUidList(uint32_t uid,bool isForeground)430 void NetPolicyRule::UpdateForegroundUidList(uint32_t uid, bool isForeground)
431 {
432     std::lock_guard lock(foregroundUidListMutex_);
433     if (isForeground) {
434         foregroundUidList_.insert(uid);
435         return;
436     }
437     foregroundUidList_.erase(uid);
438 }
439 
IsValidNetPolicy(uint32_t policy)440 bool NetPolicyRule::IsValidNetPolicy(uint32_t policy)
441 {
442     switch (policy) {
443         case NetUidPolicy::NET_POLICY_NONE:
444         case NetUidPolicy::NET_POLICY_ALLOW_METERED_BACKGROUND:
445         case NetUidPolicy::NET_POLICY_REJECT_METERED_BACKGROUND: {
446             return true;
447         }
448         default: {
449             NETMGR_LOG_E("Invalid policy [%{public}d]", policy);
450             return false;
451         }
452     }
453 }
454 
GetDumpMessage(std::string & message)455 void NetPolicyRule::GetDumpMessage(std::string &message)
456 {
457     static const std::string TAB = "    ";
458     message.append(TAB + "UidPolicy:\n");
459     std::for_each(uidPolicyRules_.begin(), uidPolicyRules_.end(), [&message](const auto &pair) {
460         message.append(TAB + TAB + "Uid: " + std::to_string(pair.first) + TAB + "Rule: " +
461                        std::to_string(pair.second.rule_) + TAB + "Policy:" + std::to_string(pair.second.policy_) + TAB +
462                        "NetSys: " + std::to_string(pair.second.netsys_) + "\n");
463     });
464     message.append(TAB + "DeviceIdleAllowedList: {");
465     std::for_each(deviceIdleAllowedList_.begin(), deviceIdleAllowedList_.end(),
466                   [&message](const auto &item) { message.append(std::to_string(item) + ", "); });
467     message.append("}\n");
468     message.append(TAB + "DeviceIdleMode: " + std::to_string(deviceIdleMode_) + "\n");
469     message.append(TAB + "PowerSaveAllowedList: {");
470     std::for_each(powerSaveAllowedList_.begin(), powerSaveAllowedList_.end(),
471                   [&message](const auto &item) { message.append(std::to_string(item) + ", "); });
472     message.append(TAB + "PowerSaveMode: " + std::to_string(powerSaveMode_) + "\n");
473     message.append(TAB + "BackgroundPolicy: " + std::to_string(backgroundAllow_) + "\n");
474 }
475 
SetNetworkAccessPolicy(uint32_t uid,NetworkAccessPolicy policy,bool reconfirmFlag,bool isBroker)476 int32_t NetPolicyRule::SetNetworkAccessPolicy(uint32_t uid, NetworkAccessPolicy policy, bool reconfirmFlag,
477                                               bool isBroker)
478 {
479     return GetNetsysInst()->SetNetworkAccessPolicy(uid, policy, reconfirmFlag, isBroker);
480 }
481 
DeleteNetworkAccessPolicy(uint32_t uid)482 int32_t NetPolicyRule::DeleteNetworkAccessPolicy(uint32_t uid)
483 {
484     return GetNetsysInst()->DeleteNetworkAccessPolicy(uid);
485 }
486 
PolicySetNicTrafficAllowed(const std::vector<std::string> & ifaceNames,bool status)487 int32_t NetPolicyRule::PolicySetNicTrafficAllowed(const std::vector<std::string> &ifaceNames, bool status)
488 {
489     return GetNetsysInst()->SetNicTrafficAllowed(ifaceNames, status);
490 }
491 } // namespace NetManagerStandard
492 } // namespace OHOS
493