1 /* 2 * Copyright (C) 2013 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.firewall; 18 19 import android.content.ComponentName; 20 import android.content.Intent; 21 import android.net.Uri; 22 import org.xmlpull.v1.XmlPullParser; 23 import org.xmlpull.v1.XmlPullParserException; 24 25 import java.io.IOException; 26 27 class PortFilter implements Filter { 28 private static final String ATTR_EQUALS = "equals"; 29 private static final String ATTR_MIN = "min"; 30 private static final String ATTR_MAX = "max"; 31 32 private static final int NO_BOUND = -1; 33 34 // both bounds are inclusive 35 private final int mLowerBound; 36 private final int mUpperBound; 37 38 private PortFilter(int lowerBound, int upperBound) { 39 mLowerBound = lowerBound; 40 mUpperBound = upperBound; 41 } 42 43 @Override 44 public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent, 45 int callerUid, int callerPid, String resolvedType, int receivingUid) { 46 int port = -1; 47 Uri uri = intent.getData(); 48 if (uri != null) { 49 port = uri.getPort(); 50 } 51 return port != -1 && 52 (mLowerBound == NO_BOUND || mLowerBound <= port) && 53 (mUpperBound == NO_BOUND || mUpperBound >= port); 54 } 55 56 public static final FilterFactory FACTORY = new FilterFactory("port") { 57 @Override 58 public Filter newFilter(XmlPullParser parser) 59 throws IOException, XmlPullParserException { 60 int lowerBound = NO_BOUND; 61 int upperBound = NO_BOUND; 62 63 String equalsValue = parser.getAttributeValue(null, ATTR_EQUALS); 64 if (equalsValue != null) { 65 int value; 66 try { 67 value = Integer.parseInt(equalsValue); 68 } catch (NumberFormatException ex) { 69 throw new XmlPullParserException("Invalid port value: " + equalsValue, 70 parser, null); 71 } 72 lowerBound = value; 73 upperBound = value; 74 } 75 76 String lowerBoundString = parser.getAttributeValue(null, ATTR_MIN); 77 String upperBoundString = parser.getAttributeValue(null, ATTR_MAX); 78 if (lowerBoundString != null || upperBoundString != null) { 79 if (equalsValue != null) { 80 throw new XmlPullParserException( 81 "Port filter cannot use both equals and range filtering", 82 parser, null); 83 } 84 85 if (lowerBoundString != null) { 86 try { 87 lowerBound = Integer.parseInt(lowerBoundString); 88 } catch (NumberFormatException ex) { 89 throw new XmlPullParserException( 90 "Invalid minimum port value: " + lowerBoundString, 91 parser, null); 92 } 93 } 94 95 if (upperBoundString != null) { 96 try { 97 upperBound = Integer.parseInt(upperBoundString); 98 } catch (NumberFormatException ex) { 99 throw new XmlPullParserException( 100 "Invalid maximum port value: " + upperBoundString, 101 parser, null); 102 } 103 } 104 } 105 106 // an empty port filter is explicitly allowed, and checks for the existence of a port 107 return new PortFilter(lowerBound, upperBound); 108 } 109 }; 110 } 111