public boolean checkIntent( FirewallIntentResolver resolver, ComponentName resolvedComponent, int intentType, Intent intent, int callerUid, int callerPid, String resolvedType, int receivingUid) { boolean log = false; boolean block = false; // For the first pass, find all the rules that have at least one intent-filter or // component-filter that matches this intent List<Rule> candidateRules; candidateRules = resolver.queryIntent(intent, resolvedType, false, 0); if (candidateRules == null) { candidateRules = new ArrayList<Rule>(); } resolver.queryByComponent(resolvedComponent, candidateRules); // For the second pass, try to match the potentially more specific conditions in each // rule against the intent for (int i = 0; i < candidateRules.size(); i++) { Rule rule = candidateRules.get(i); if (rule.matches( this, resolvedComponent, intent, callerUid, callerPid, resolvedType, receivingUid)) { block |= rule.getBlock(); log |= rule.getLog(); // if we've already determined that we should both block and log, there's no need // to continue trying rules if (block && log) { break; } } } if (log) { logIntent(intentType, intent, callerUid, resolvedType); } return !block; }
/** Reads rules from the given file and add them to the given resolvers */ private void readRules(File rulesFile, FirewallIntentResolver[] resolvers) { // some temporary lists to hold the rules while we parse the xml file, so that we can // add the rules all at once, after we know there weren't any major structural problems // with the xml file List<List<Rule>> rulesByType = new ArrayList<List<Rule>>(3); for (int i = 0; i < 3; i++) { rulesByType.add(new ArrayList<Rule>()); } FileInputStream fis; try { fis = new FileInputStream(rulesFile); } catch (FileNotFoundException ex) { // Nope, no rules. Nothing else to do! return; } try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(fis, null); XmlUtils.beginDocument(parser, TAG_RULES); int outerDepth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, outerDepth)) { int ruleType = -1; String tagName = parser.getName(); if (tagName.equals(TAG_ACTIVITY)) { ruleType = TYPE_ACTIVITY; } else if (tagName.equals(TAG_BROADCAST)) { ruleType = TYPE_BROADCAST; } else if (tagName.equals(TAG_SERVICE)) { ruleType = TYPE_SERVICE; } if (ruleType != -1) { Rule rule = new Rule(); List<Rule> rules = rulesByType.get(ruleType); // if we get an error while parsing a particular rule, we'll just ignore // that rule and continue on with the next rule try { rule.readFromXml(parser); } catch (XmlPullParserException ex) { Slog.e(TAG, "Error reading an intent firewall rule from " + rulesFile, ex); continue; } rules.add(rule); } } } catch (XmlPullParserException ex) { // if there was an error outside of a specific rule, then there are probably // structural problems with the xml file, and we should completely ignore it Slog.e(TAG, "Error reading intent firewall rules from " + rulesFile, ex); return; } catch (IOException ex) { Slog.e(TAG, "Error reading intent firewall rules from " + rulesFile, ex); return; } finally { try { fis.close(); } catch (IOException ex) { Slog.e(TAG, "Error while closing " + rulesFile, ex); } } for (int ruleType = 0; ruleType < rulesByType.size(); ruleType++) { List<Rule> rules = rulesByType.get(ruleType); FirewallIntentResolver resolver = resolvers[ruleType]; for (int ruleIndex = 0; ruleIndex < rules.size(); ruleIndex++) { Rule rule = rules.get(ruleIndex); for (int i = 0; i < rule.getIntentFilterCount(); i++) { resolver.addFilter(rule.getIntentFilter(i)); } for (int i = 0; i < rule.getComponentFilterCount(); i++) { resolver.addComponentFilter(rule.getComponentFilter(i), rule); } } } }