14efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver/* 24efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * Copyright (C) 2013 The Android Open Source Project 34efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * 44efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * Licensed under the Apache License, Version 2.0 (the "License"); 54efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * you may not use this file except in compliance with the License. 64efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * You may obtain a copy of the License at 74efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * 84efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * http://www.apache.org/licenses/LICENSE-2.0 94efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * 104efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * Unless required by applicable law or agreed to in writing, software 114efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * distributed under the License is distributed on an "AS IS" BASIS, 124efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * See the License for the specific language governing permissions and 144efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver * limitations under the License. 154efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver */ 164efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 174efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruverpackage com.android.server.firewall; 184efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 19f5323fee2a7deaf264ed10fbe3d9c69055987e55Ben Gruverimport android.content.ComponentName; 204efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruverimport android.content.Intent; 214efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruverimport android.net.Uri; 224efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruverimport org.xmlpull.v1.XmlPullParser; 234efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruverimport org.xmlpull.v1.XmlPullParserException; 244efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 254efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruverimport java.io.IOException; 264efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 274efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruverclass PortFilter implements Filter { 284efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver private static final String ATTR_EQUALS = "equals"; 294efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver private static final String ATTR_MIN = "min"; 304efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver private static final String ATTR_MAX = "max"; 314efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 324efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver private static final int NO_BOUND = -1; 334efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 344efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver // both bounds are inclusive 354efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver private final int mLowerBound; 364efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver private final int mUpperBound; 374efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 384efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver private PortFilter(int lowerBound, int upperBound) { 394efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver mLowerBound = lowerBound; 404efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver mUpperBound = upperBound; 414efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 424efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 434efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver @Override 44f5323fee2a7deaf264ed10fbe3d9c69055987e55Ben Gruver public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent, 4549660c7c24f24c3394233e3bbf94c96281e8c408Ben Gruver int callerUid, int callerPid, String resolvedType, int receivingUid) { 464efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver int port = -1; 474efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver Uri uri = intent.getData(); 484efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver if (uri != null) { 494efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver port = uri.getPort(); 504efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 514efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver return port != -1 && 524efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver (mLowerBound == NO_BOUND || mLowerBound <= port) && 534efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver (mUpperBound == NO_BOUND || mUpperBound >= port); 544efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 554efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 564efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver public static final FilterFactory FACTORY = new FilterFactory("port") { 574efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver @Override 584efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver public Filter newFilter(XmlPullParser parser) 594efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver throws IOException, XmlPullParserException { 604efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver int lowerBound = NO_BOUND; 614efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver int upperBound = NO_BOUND; 624efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 634efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver String equalsValue = parser.getAttributeValue(null, ATTR_EQUALS); 644efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver if (equalsValue != null) { 654efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver int value; 664efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver try { 674efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver value = Integer.parseInt(equalsValue); 684efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } catch (NumberFormatException ex) { 694efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver throw new XmlPullParserException("Invalid port value: " + equalsValue, 704efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver parser, null); 714efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 724efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver lowerBound = value; 734efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver upperBound = value; 744efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 754efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 764efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver String lowerBoundString = parser.getAttributeValue(null, ATTR_MIN); 774efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver String upperBoundString = parser.getAttributeValue(null, ATTR_MAX); 784efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver if (lowerBoundString != null || upperBoundString != null) { 794efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver if (equalsValue != null) { 804efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver throw new XmlPullParserException( 814efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver "Port filter cannot use both equals and range filtering", 824efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver parser, null); 834efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 844efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 854efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver if (lowerBoundString != null) { 864efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver try { 874efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver lowerBound = Integer.parseInt(lowerBoundString); 884efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } catch (NumberFormatException ex) { 894efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver throw new XmlPullParserException( 904efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver "Invalid minimum port value: " + lowerBoundString, 914efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver parser, null); 924efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 934efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 944efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 954efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver if (upperBoundString != null) { 964efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver try { 974efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver upperBound = Integer.parseInt(upperBoundString); 984efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } catch (NumberFormatException ex) { 994efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver throw new XmlPullParserException( 1004efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver "Invalid maximum port value: " + upperBoundString, 1014efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver parser, null); 1024efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 1034efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 1044efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 1054efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver 1064efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver // an empty port filter is explicitly allowed, and checks for the existence of a port 1074efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver return new PortFilter(lowerBound, upperBound); 1084efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver } 1094efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver }; 1104efe9403afb0ba3b83fa647eb82e4f90d29f131bBen Gruver} 111