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