• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 com.android.server.integrity.engine;
18 
19 import static android.content.integrity.Rule.DENY;
20 import static android.content.integrity.Rule.FORCE_ALLOW;
21 
22 import android.annotation.NonNull;
23 import android.content.integrity.AppInstallMetadata;
24 import android.content.integrity.Rule;
25 
26 import com.android.server.integrity.model.IntegrityCheckResult;
27 
28 import java.util.List;
29 import java.util.stream.Collectors;
30 
31 /**
32  * A helper class for evaluating rules against app install metadata to find if there are matching
33  * rules.
34  */
35 final class RuleEvaluator {
36 
37     /**
38      * Match the list of rules against an app install metadata.
39      *
40      * <p>Rules must be in disjunctive normal form (DNF). A rule should contain AND'ed formulas
41      * only. All rules are OR'ed together by default.
42      *
43      * @param rules The list of rules to evaluate.
44      * @param appInstallMetadata Metadata of the app to be installed, and to evaluate the rules
45      *     against.
46      * @return result of the integrity check
47      */
48     @NonNull
evaluateRules( List<Rule> rules, AppInstallMetadata appInstallMetadata)49     static IntegrityCheckResult evaluateRules(
50             List<Rule> rules, AppInstallMetadata appInstallMetadata) {
51 
52         // Identify the rules that match the {@code appInstallMetadata}.
53         List<Rule> matchedRules =
54                 rules.stream()
55                         .filter(rule -> rule.getFormula().matches(appInstallMetadata))
56                         .collect(Collectors.toList());
57 
58         // Identify the matched power allow rules and terminate early if we have any.
59         List<Rule> matchedPowerAllowRules =
60                 matchedRules.stream()
61                         .filter(rule -> rule.getEffect() == FORCE_ALLOW)
62                         .collect(Collectors.toList());
63 
64         if (!matchedPowerAllowRules.isEmpty()) {
65             return IntegrityCheckResult.allow(matchedPowerAllowRules);
66         }
67 
68         // Identify the matched deny rules.
69         List<Rule> matchedDenyRules =
70                 matchedRules.stream()
71                         .filter(rule -> rule.getEffect() == DENY)
72                         .collect(Collectors.toList());
73 
74         if (!matchedDenyRules.isEmpty()) {
75             return IntegrityCheckResult.deny(matchedDenyRules);
76         }
77 
78         // When no rules are denied, return default allow result.
79         return IntegrityCheckResult.allow();
80     }
81 }
82