• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.security.cts;
18 
19 import android.util.Xml;
20 
21 import com.google.common.collect.HashMultimap;
22 import com.google.common.collect.Multimap;
23 import org.xmlpull.v1.XmlPullParser;
24 import org.xmlpull.v1.XmlPullParserException;
25 
26 import java.io.InputStream;
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.HashMap;
31 
32 
33 /**
34  * A class for generating representations of SELinux avc rules parsed from an xml file.
35  */
36 public class SELinuxPolicyRule {
37     public final List<String> source_types;
38     public final List<String> target_types;
39     public final Multimap<String, String> obj_classes;
40     public final String name;
41     public final String type;
42 
SELinuxPolicyRule(List<String> source_types, List<String> target_types, Multimap<String, String> obj_classes, String name, String type)43     private SELinuxPolicyRule(List<String> source_types, List<String> target_types,
44             Multimap<String, String> obj_classes, String name, String type) {
45         this.source_types = source_types;
46         this.target_types = target_types;
47         this.obj_classes = obj_classes;
48         this.name = name;
49         this.type = type;
50     }
51 
readRule(XmlPullParser xpp)52     public static SELinuxPolicyRule readRule(XmlPullParser xpp) throws IOException, XmlPullParserException {
53         List<String> source_types = new ArrayList<String>();
54         List<String> target_types = new ArrayList<String>();
55         Multimap<String, String> obj_classes = HashMultimap.create();
56         xpp.require(XmlPullParser.START_TAG, null, "avc_rule");
57         String ruleName = xpp.getAttributeValue(null, "name");
58         String ruleType = xpp.getAttributeValue(null, "type");
59         while (xpp.next() != XmlPullParser.END_TAG) {
60             if (xpp.getEventType() != XmlPullParser.START_TAG) {
61                 continue;
62             }
63             String name = xpp.getName();
64             if (name.equals("type")) {
65                 if (xpp.getAttributeValue(null, "type").equals("source")) {
66                     source_types.add(readType(xpp));
67                 } else if (xpp.getAttributeValue(null, "type").equals("target")) {
68                     target_types.add(readType(xpp));
69                 } else {
70                     skip(xpp);
71                 }
72             } else if (name.equals("obj_class")) {
73                 String obj_name = xpp.getAttributeValue(null, "name");
74                 List<String> perms = readObjClass(xpp);
75                 obj_classes.putAll(obj_name, perms);
76             } else {
77                 skip(xpp);
78             }
79         }
80         return new SELinuxPolicyRule(source_types, target_types, obj_classes, ruleName, ruleType);
81     }
82 
readRulesFile(InputStream in)83     public static List<SELinuxPolicyRule> readRulesFile(InputStream in) throws IOException, XmlPullParserException {
84         List<SELinuxPolicyRule> rules = new ArrayList<SELinuxPolicyRule>();
85         XmlPullParser xpp = Xml.newPullParser();
86         xpp.setInput(in, null);
87         xpp.nextTag();
88         xpp.require(XmlPullParser.START_TAG, null, "SELinux_AVC_Rules");
89 
90         /* read rules */
91         while (xpp.next()  != XmlPullParser.END_TAG) {
92             if (xpp.getEventType() != XmlPullParser.START_TAG) {
93                 continue;
94             }
95             String name = xpp.getName();
96             if (name.equals("avc_rule")) {
97                 SELinuxPolicyRule r = readRule(xpp);
98                 rules.add(r);
99             } else {
100                 skip(xpp);
101             }
102         }
103         return rules;
104     }
105 
readObjClass(XmlPullParser xpp)106     private static List<String> readObjClass(XmlPullParser xpp) throws IOException, XmlPullParserException {
107         List<String> perms = new ArrayList<String>();
108         xpp.require(XmlPullParser.START_TAG, null, "obj_class");
109         while (xpp.next() != XmlPullParser.END_TAG) {
110         if (xpp.getEventType() != XmlPullParser.START_TAG) {
111                 continue;
112             }
113             String name = xpp.getName();
114             if (name.equals("permission")) {
115                 perms.add(readPermission(xpp));
116             } else {
117                 skip(xpp);
118             }
119         }
120         return perms;
121     }
122 
readType(XmlPullParser xpp)123     private static String readType(XmlPullParser xpp) throws IOException, XmlPullParserException {
124         xpp.require(XmlPullParser.START_TAG, null, "type");
125         String type = readText(xpp);
126         xpp.require(XmlPullParser.END_TAG, null, "type");
127         return type;
128     }
129 
readPermission(XmlPullParser xpp)130     private static String readPermission(XmlPullParser xpp) throws IOException, XmlPullParserException {
131         xpp.require(XmlPullParser.START_TAG, null, "permission");
132         String permission = readText(xpp);
133         xpp.require(XmlPullParser.END_TAG, null, "permission");
134         return permission;
135     }
136 
readText(XmlPullParser xpp)137     private static String readText(XmlPullParser xpp) throws IOException, XmlPullParserException {
138         String result = "";
139         if (xpp.next() == XmlPullParser.TEXT) {
140             result = xpp.getText();
141             xpp.nextTag();
142         }
143         return result;
144     }
145 
skip(XmlPullParser xpp)146     public static void skip(XmlPullParser xpp) throws XmlPullParserException, IOException {
147         if (xpp.getEventType() != XmlPullParser.START_TAG) {
148             throw new IllegalStateException();
149         }
150         int depth = 1;
151         while (depth != 0) {
152             switch (xpp.next()) {
153             case XmlPullParser.END_TAG:
154                 depth--;
155                 break;
156             case XmlPullParser.START_TAG:
157                 depth++;
158                 break;
159             }
160         }
161     }
162 }
163