1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net;
18 
19 import static android.content.pm.PackageManager.GET_SIGNATURES;
20 import static android.net.NetworkPolicy.CYCLE_NONE;
21 import static android.text.format.Time.MONTH_DAY;
22 
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.content.pm.PackageManager.NameNotFoundException;
27 import android.content.pm.Signature;
28 import android.os.RemoteException;
29 import android.os.UserHandle;
30 import android.text.format.Time;
31 import android.util.DebugUtils;
32 
33 import com.google.android.collect.Sets;
34 
35 import java.util.HashSet;
36 
37 /**
38  * Manager for creating and modifying network policy rules.
39  *
40  * {@hide}
41  */
42 public class NetworkPolicyManager {
43 
44     /* POLICY_* are masks and can be ORed */
45     /** No specific network policy, use system default. */
46     public static final int POLICY_NONE = 0x0;
47     /** Reject network usage on metered networks when application in background. */
48     public static final int POLICY_REJECT_METERED_BACKGROUND = 0x1;
49     /** Allow network use (metered or not) in the background in battery save mode. */
50     public static final int POLICY_ALLOW_BACKGROUND_BATTERY_SAVE = 0x2;
51 
52     /*
53      * Rules defining whether an uid has access to a network given its type (metered / non-metered).
54      *
55      * These rules are bits and can be used in bitmask operations; in particular:
56      * - rule & RULE_MASK_METERED: returns the metered-networks status.
57      * - rule & RULE_MASK_ALL: returns the all-networks status.
58      *
59      * The RULE_xxx_ALL rules applies to all networks (metered or non-metered), but on
60      * metered networks, the RULE_xxx_METERED rules should be checked first. For example,
61      * if the device is on Battery Saver Mode and Data Saver Mode simulatenously, and a uid
62      * is whitelisted for the former but not the latter, its status would be
63      * RULE_REJECT_METERED | RULE_ALLOW_ALL, meaning it could have access to non-metered
64      * networks but not to metered networks.
65      *
66      * See network-policy-restrictions.md for more info.
67      */
68     /** No specific rule was set */
69     public static final int RULE_NONE = 0;
70     /** Allow traffic on metered networks. */
71     public static final int RULE_ALLOW_METERED = 1 << 0;
72     /** Temporarily allow traffic on metered networks because app is on foreground. */
73     public static final int RULE_TEMPORARY_ALLOW_METERED = 1 << 1;
74     /** Reject traffic on metered networks. */
75     public static final int RULE_REJECT_METERED = 1 << 2;
76     /** Network traffic should be allowed on all networks (metered or non-metered), although
77      * metered-network restrictions could still apply. */
78     public static final int RULE_ALLOW_ALL = 1 << 5;
79     /** Reject traffic on all networks. */
80     public static final int RULE_REJECT_ALL = 1 << 6;
81     /** Mask used to get the {@code RULE_xxx_METERED} rules */
82     public static final int MASK_METERED_NETWORKS = 0b00001111;
83     /** Mask used to get the {@code RULE_xxx_ALL} rules */
84     public static final int MASK_ALL_NETWORKS     = 0b11110000;
85 
86     public static final int FIREWALL_RULE_DEFAULT = 0;
87     public static final int FIREWALL_RULE_ALLOW = 1;
88     public static final int FIREWALL_RULE_DENY = 2;
89 
90     public static final int FIREWALL_TYPE_WHITELIST = 0;
91     public static final int FIREWALL_TYPE_BLACKLIST = 1;
92 
93     public static final int FIREWALL_CHAIN_NONE = 0;
94     public static final int FIREWALL_CHAIN_DOZABLE = 1;
95     public static final int FIREWALL_CHAIN_STANDBY = 2;
96     public static final int FIREWALL_CHAIN_POWERSAVE = 3;
97 
98     public static final String FIREWALL_CHAIN_NAME_NONE = "none";
99     public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable";
100     public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby";
101     public static final String FIREWALL_CHAIN_NAME_POWERSAVE = "powersave";
102 
103     private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
104 
105     /**
106      * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it
107      * applies to.
108      */
109     public static final String EXTRA_NETWORK_TEMPLATE = "android.net.NETWORK_TEMPLATE";
110 
111     private final Context mContext;
112     private INetworkPolicyManager mService;
113 
NetworkPolicyManager(Context context, INetworkPolicyManager service)114     public NetworkPolicyManager(Context context, INetworkPolicyManager service) {
115         if (service == null) {
116             throw new IllegalArgumentException("missing INetworkPolicyManager");
117         }
118         mContext = context;
119         mService = service;
120     }
121 
from(Context context)122     public static NetworkPolicyManager from(Context context) {
123         return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
124     }
125 
126     /**
127      * Set policy flags for specific UID.
128      *
129      * @param policy {@link #POLICY_NONE} or combination of flags like
130      * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
131      */
setUidPolicy(int uid, int policy)132     public void setUidPolicy(int uid, int policy) {
133         try {
134             mService.setUidPolicy(uid, policy);
135         } catch (RemoteException e) {
136             throw e.rethrowFromSystemServer();
137         }
138     }
139 
140     /**
141      * Add policy flags for specific UID.  The given policy bits will be set for
142      * the uid.  Policy flags may be either
143      * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
144      */
addUidPolicy(int uid, int policy)145     public void addUidPolicy(int uid, int policy) {
146         try {
147             mService.addUidPolicy(uid, policy);
148         } catch (RemoteException e) {
149             throw e.rethrowFromSystemServer();
150         }
151     }
152 
153     /**
154      * Clear/remove policy flags for specific UID.  The given policy bits will be set for
155      * the uid.  Policy flags may be either
156      * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
157      */
removeUidPolicy(int uid, int policy)158     public void removeUidPolicy(int uid, int policy) {
159         try {
160             mService.removeUidPolicy(uid, policy);
161         } catch (RemoteException e) {
162             throw e.rethrowFromSystemServer();
163         }
164     }
165 
getUidPolicy(int uid)166     public int getUidPolicy(int uid) {
167         try {
168             return mService.getUidPolicy(uid);
169         } catch (RemoteException e) {
170             throw e.rethrowFromSystemServer();
171         }
172     }
173 
getUidsWithPolicy(int policy)174     public int[] getUidsWithPolicy(int policy) {
175         try {
176             return mService.getUidsWithPolicy(policy);
177         } catch (RemoteException e) {
178             throw e.rethrowFromSystemServer();
179         }
180     }
181 
registerListener(INetworkPolicyListener listener)182     public void registerListener(INetworkPolicyListener listener) {
183         try {
184             mService.registerListener(listener);
185         } catch (RemoteException e) {
186             throw e.rethrowFromSystemServer();
187         }
188     }
189 
unregisterListener(INetworkPolicyListener listener)190     public void unregisterListener(INetworkPolicyListener listener) {
191         try {
192             mService.unregisterListener(listener);
193         } catch (RemoteException e) {
194             throw e.rethrowFromSystemServer();
195         }
196     }
197 
setNetworkPolicies(NetworkPolicy[] policies)198     public void setNetworkPolicies(NetworkPolicy[] policies) {
199         try {
200             mService.setNetworkPolicies(policies);
201         } catch (RemoteException e) {
202             throw e.rethrowFromSystemServer();
203         }
204     }
205 
getNetworkPolicies()206     public NetworkPolicy[] getNetworkPolicies() {
207         try {
208             return mService.getNetworkPolicies(mContext.getOpPackageName());
209         } catch (RemoteException e) {
210             throw e.rethrowFromSystemServer();
211         }
212     }
213 
setRestrictBackground(boolean restrictBackground)214     public void setRestrictBackground(boolean restrictBackground) {
215         try {
216             mService.setRestrictBackground(restrictBackground);
217         } catch (RemoteException e) {
218             throw e.rethrowFromSystemServer();
219         }
220     }
221 
getRestrictBackground()222     public boolean getRestrictBackground() {
223         try {
224             return mService.getRestrictBackground();
225         } catch (RemoteException e) {
226             throw e.rethrowFromSystemServer();
227         }
228     }
229 
230     /**
231      * Resets network policy settings back to factory defaults.
232      *
233      * @hide
234      */
factoryReset(String subscriber)235     public void factoryReset(String subscriber) {
236         try {
237             mService.factoryReset(subscriber);
238         } catch (RemoteException e) {
239             throw e.rethrowFromSystemServer();
240         }
241     }
242 
243     /**
244      * Compute the last cycle boundary for the given {@link NetworkPolicy}. For
245      * example, if cycle day is 20th, and today is June 15th, it will return May
246      * 20th. When cycle day doesn't exist in current month, it snaps to the 1st
247      * of following month.
248      *
249      * @hide
250      */
computeLastCycleBoundary(long currentTime, NetworkPolicy policy)251     public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
252         if (policy.cycleDay == CYCLE_NONE) {
253             throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
254         }
255 
256         final Time now = new Time(policy.cycleTimezone);
257         now.set(currentTime);
258 
259         // first, find cycle boundary for current month
260         final Time cycle = new Time(now);
261         cycle.hour = cycle.minute = cycle.second = 0;
262         snapToCycleDay(cycle, policy.cycleDay);
263 
264         if (Time.compare(cycle, now) >= 0) {
265             // cycle boundary is beyond now, use last cycle boundary; start by
266             // pushing ourselves squarely into last month.
267             final Time lastMonth = new Time(now);
268             lastMonth.hour = lastMonth.minute = lastMonth.second = 0;
269             lastMonth.monthDay = 1;
270             lastMonth.month -= 1;
271             lastMonth.normalize(true);
272 
273             cycle.set(lastMonth);
274             snapToCycleDay(cycle, policy.cycleDay);
275         }
276 
277         return cycle.toMillis(true);
278     }
279 
280     /** {@hide} */
computeNextCycleBoundary(long currentTime, NetworkPolicy policy)281     public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
282         if (policy.cycleDay == CYCLE_NONE) {
283             throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
284         }
285 
286         final Time now = new Time(policy.cycleTimezone);
287         now.set(currentTime);
288 
289         // first, find cycle boundary for current month
290         final Time cycle = new Time(now);
291         cycle.hour = cycle.minute = cycle.second = 0;
292         snapToCycleDay(cycle, policy.cycleDay);
293 
294         if (Time.compare(cycle, now) <= 0) {
295             // cycle boundary is before now, use next cycle boundary; start by
296             // pushing ourselves squarely into next month.
297             final Time nextMonth = new Time(now);
298             nextMonth.hour = nextMonth.minute = nextMonth.second = 0;
299             nextMonth.monthDay = 1;
300             nextMonth.month += 1;
301             nextMonth.normalize(true);
302 
303             cycle.set(nextMonth);
304             snapToCycleDay(cycle, policy.cycleDay);
305         }
306 
307         return cycle.toMillis(true);
308     }
309 
310     /**
311      * Snap to the cycle day for the current month given; when cycle day doesn't
312      * exist, it snaps to last second of current month.
313      *
314      * @hide
315      */
snapToCycleDay(Time time, int cycleDay)316     public static void snapToCycleDay(Time time, int cycleDay) {
317         if (cycleDay > time.getActualMaximum(MONTH_DAY)) {
318             // cycle day isn't valid this month; snap to last second of month
319             time.month += 1;
320             time.monthDay = 1;
321             time.second = -1;
322         } else {
323             time.monthDay = cycleDay;
324         }
325         time.normalize(true);
326     }
327 
328     /**
329      * Check if given UID can have a {@link #setUidPolicy(int, int)} defined,
330      * usually to protect critical system services.
331      */
332     @Deprecated
isUidValidForPolicy(Context context, int uid)333     public static boolean isUidValidForPolicy(Context context, int uid) {
334         // first, quick-reject non-applications
335         if (!UserHandle.isApp(uid)) {
336             return false;
337         }
338 
339         if (!ALLOW_PLATFORM_APP_POLICY) {
340             final PackageManager pm = context.getPackageManager();
341             final HashSet<Signature> systemSignature;
342             try {
343                 systemSignature = Sets.newHashSet(
344                         pm.getPackageInfo("android", GET_SIGNATURES).signatures);
345             } catch (NameNotFoundException e) {
346                 throw new RuntimeException("problem finding system signature", e);
347             }
348 
349             try {
350                 // reject apps signed with platform cert
351                 for (String packageName : pm.getPackagesForUid(uid)) {
352                     final HashSet<Signature> packageSignature = Sets.newHashSet(
353                             pm.getPackageInfo(packageName, GET_SIGNATURES).signatures);
354                     if (packageSignature.containsAll(systemSignature)) {
355                         return false;
356                     }
357                 }
358             } catch (NameNotFoundException e) {
359             }
360         }
361 
362         // nothing found above; we can apply policy to UID
363         return true;
364     }
365 
366     /*
367      * @hide
368      */
uidRulesToString(int uidRules)369     public static String uidRulesToString(int uidRules) {
370         final StringBuilder string = new StringBuilder().append(uidRules).append(" (");
371         if (uidRules == RULE_NONE) {
372             string.append("NONE");
373         } else {
374             string.append(DebugUtils.flagsToString(NetworkPolicyManager.class, "RULE_", uidRules));
375         }
376         string.append(")");
377         return string.toString();
378     }
379 }
380