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