blob: c0eee69b4b0d4dcfd8e97eaadd8c904bf7d6bbf9 [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.firewall;
import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.os.Process;
import android.os.RemoteException;
import android.util.Slog;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
class SenderFilter {
private static final String ATTR_TYPE = "type";
private static final String VAL_SIGNATURE = "signature";
private static final String VAL_SYSTEM = "system";
private static final String VAL_SYSTEM_OR_SIGNATURE = "system|signature";
private static final String VAL_USER_ID = "userId";
static boolean isPrivilegedApp(int callerUid, int callerPid) {
if (callerUid == Process.SYSTEM_UID || callerUid == 0 ||
callerPid == Process.myPid() || callerPid == 0) {
return true;
}
IPackageManager pm = AppGlobals.getPackageManager();
try {
return (pm.getFlagsForUid(callerUid) & ApplicationInfo.FLAG_PRIVILEGED) != 0;
} catch (RemoteException ex) {
Slog.e(IntentFirewall.TAG, "Remote exception while retrieving uid flags",
ex);
}
return false;
}
public static final FilterFactory FACTORY = new FilterFactory("sender") {
@Override
public Filter newFilter(XmlPullParser parser) throws IOException, XmlPullParserException {
String typeString = parser.getAttributeValue(null, ATTR_TYPE);
if (typeString == null) {
throw new XmlPullParserException("type attribute must be specified for <sender>",
parser, null);
}
if (typeString.equals(VAL_SYSTEM)) {
return SYSTEM;
} else if (typeString.equals(VAL_SIGNATURE)) {
return SIGNATURE;
} else if (typeString.equals(VAL_SYSTEM_OR_SIGNATURE)) {
return SYSTEM_OR_SIGNATURE;
} else if (typeString.equals(VAL_USER_ID)) {
return USER_ID;
}
throw new XmlPullParserException(
"Invalid type attribute for <sender>: " + typeString, parser, null);
}
};
private static final Filter SIGNATURE = new Filter() {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
int callerUid, int callerPid, String resolvedType, int receivingUid) {
return ifw.signaturesMatch(callerUid, receivingUid);
}
};
private static final Filter SYSTEM = new Filter() {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
int callerUid, int callerPid, String resolvedType, int receivingUid) {
return isPrivilegedApp(callerUid, callerPid);
}
};
private static final Filter SYSTEM_OR_SIGNATURE = new Filter() {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
int callerUid, int callerPid, String resolvedType, int receivingUid) {
return isPrivilegedApp(callerUid, callerPid) ||
ifw.signaturesMatch(callerUid, receivingUid);
}
};
private static final Filter USER_ID = new Filter() {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
int callerUid, int callerPid, String resolvedType, int receivingUid) {
// This checks whether the caller is either the system process, or has the same user id
// I.e. the same app, or an app that uses the same shared user id.
// This is the same set of applications that would be able to access the component if
// it wasn't exported.
return ifw.checkComponentPermission(null, callerPid, callerUid, receivingUid, false);
}
};
}