Home | History | Annotate | Download | only in firewall
      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.Intent;
     20 import android.content.pm.ApplicationInfo;
     21 import android.os.Process;
     22 import org.xmlpull.v1.XmlPullParser;
     23 import org.xmlpull.v1.XmlPullParserException;
     24 
     25 import java.io.IOException;
     26 
     27 class SenderFilter {
     28     private static final String ATTR_TYPE = "type";
     29 
     30     private static final String VAL_SIGNATURE = "signature";
     31     private static final String VAL_SYSTEM = "system";
     32     private static final String VAL_SYSTEM_OR_SIGNATURE = "system|signature";
     33     private static final String VAL_USER_ID = "userId";
     34 
     35     static boolean isSystemApp(ApplicationInfo callerApp, int callerUid, int callerPid) {
     36         if (callerUid == Process.SYSTEM_UID ||
     37                 callerPid == Process.myPid()) {
     38             return true;
     39         }
     40         if (callerApp == null) {
     41             return false;
     42         }
     43         return (callerApp.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
     44     }
     45 
     46     public static final FilterFactory FACTORY = new FilterFactory("sender") {
     47         @Override
     48         public Filter newFilter(XmlPullParser parser) throws IOException, XmlPullParserException {
     49             String typeString = parser.getAttributeValue(null, ATTR_TYPE);
     50             if (typeString == null) {
     51                 throw new XmlPullParserException("type attribute must be specified for <sender>",
     52                         parser, null);
     53             }
     54             if (typeString.equals(VAL_SYSTEM)) {
     55                 return SYSTEM;
     56             } else if (typeString.equals(VAL_SIGNATURE)) {
     57                 return SIGNATURE;
     58             } else if (typeString.equals(VAL_SYSTEM_OR_SIGNATURE)) {
     59                 return SYSTEM_OR_SIGNATURE;
     60             } else if (typeString.equals(VAL_USER_ID)) {
     61                 return USER_ID;
     62             }
     63             throw new XmlPullParserException(
     64                     "Invalid type attribute for <sender>: " + typeString, parser, null);
     65         }
     66     };
     67 
     68     private static final Filter SIGNATURE = new Filter() {
     69         @Override
     70         public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
     71                 int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
     72             if (callerApp == null) {
     73                 return false;
     74             }
     75             return ifw.signaturesMatch(callerUid, resolvedApp.uid);
     76         }
     77     };
     78 
     79     private static final Filter SYSTEM = new Filter() {
     80         @Override
     81         public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
     82                 int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
     83             if (callerApp == null) {
     84                 // if callerApp is null, the caller is the system process
     85                 return false;
     86             }
     87             return isSystemApp(callerApp, callerUid, callerPid);
     88         }
     89     };
     90 
     91     private static final Filter SYSTEM_OR_SIGNATURE = new Filter() {
     92         @Override
     93         public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
     94                 int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
     95             return isSystemApp(callerApp, callerUid, callerPid) ||
     96                     ifw.signaturesMatch(callerUid, resolvedApp.uid);
     97         }
     98     };
     99 
    100     private static final Filter USER_ID = new Filter() {
    101         @Override
    102         public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
    103                 int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
    104             // This checks whether the caller is either the system process, or has the same user id
    105             // I.e. the same app, or an app that uses the same shared user id.
    106             // This is the same set of applications that would be able to access the component if
    107             // it wasn't exported.
    108             return ifw.checkComponentPermission(null, callerPid, callerUid, resolvedApp.uid, false);
    109         }
    110     };
    111 }
    112