blob: da4366575c56dc7d8a69df96403eef25b82a4b8f [file] [log] [blame]
/*
* Copyright (C) 2009 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.cts.usespermissiondiffcertapp;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;
/**
* Tests that signature-enforced permissions cannot be accessed by apps signed
* with different certs than app that declares the permission.
*/
public class AccessPermissionWithDiffSigTest extends AndroidTestCase {
static final ComponentName GRANT_URI_PERM_COMP
= new ComponentName("com.android.cts.permissiondeclareapp",
"com.android.cts.permissiondeclareapp.GrantUriPermission");
static final Uri PERM_URI = Uri.parse("content://ctspermissionwithsignature");
static final Uri PERM_URI_GRANTING = Uri.parse("content://ctspermissionwithsignaturegranting");
static final Uri PRIV_URI = Uri.parse("content://ctsprivateprovider");
static final Uri PRIV_URI_GRANTING = Uri.parse("content://ctsprivateprovidergranting");
public void assertReadingContentUriNotAllowed(Uri uri, String msg) {
try {
getContext().getContentResolver().query(uri, null, null, null, null);
fail("expected SecurityException reading " + uri + ": " + msg);
} catch (SecurityException expected) {
assertNotNull("security exception's error message.", expected.getMessage());
}
}
public void assertWritingContentUriNotAllowed(Uri uri, String msg) {
try {
getContext().getContentResolver().insert(uri, new ContentValues());
fail("expected SecurityException writing " + uri + ": " + msg);
} catch (SecurityException expected) {
assertNotNull("security exception's error message.", expected.getMessage());
}
}
/**
* Test that the ctspermissionwithsignature content provider cannot be read,
* since this app lacks the required certs
*/
public void testReadProviderWithDiff() {
assertReadingContentUriRequiresPermission(PERM_URI,
"com.android.cts.permissionWithSignature");
}
/**
* Test that the ctspermissionwithsignature content provider cannot be written,
* since this app lacks the required certs
*/
public void testWriteProviderWithDiff() {
assertWritingContentUriRequiresPermission(PERM_URI,
"com.android.cts.permissionWithSignature");
}
/**
* Test that the ctsprivateprovider content provider cannot be read,
* since it is not exported from its app.
*/
public void testReadProviderWhenPrivate() {
assertReadingContentUriNotAllowed(PRIV_URI,
"shouldn't read private provider");
}
/**
* Test that the ctsprivateprovider content provider cannot be written,
* since it is not exported from its app.
*/
public void testWriteProviderWhenPrivate() {
assertWritingContentUriNotAllowed(PRIV_URI,
"shouldn't write private provider");
}
public void doTryGrantUriActivityPermissionToSelf(Uri uri, int mode) {
Intent grantIntent = new Intent();
grantIntent.setData(uri);
grantIntent.addFlags(mode | Intent.FLAG_ACTIVITY_NEW_TASK);
grantIntent.setClass(getContext(), ReceiveUriActivity.class);
try {
ReceiveUriActivity.clearStarted();
getContext().startActivity(grantIntent);
ReceiveUriActivity.waitForStart();
fail("expected SecurityException granting " + uri + " to activity");
} catch (SecurityException e) {
// This is what we want.
}
}
/**
* Test that we can't grant a permission to ourself.
*/
public void testGrantReadUriActivityPermissionToSelf() {
doTryGrantUriActivityPermissionToSelf(
Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
/**
* Test that we can't grant a permission to ourself.
*/
public void testGrantWriteUriActivityPermissionToSelf() {
doTryGrantUriActivityPermissionToSelf(
Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
/**
* Test that we can't grant a permission to ourself.
*/
public void testGrantReadUriActivityPrivateToSelf() {
doTryGrantUriActivityPermissionToSelf(
Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
/**
* Test that we can't grant a permission to ourself.
*/
public void testGrantWriteUriActivityPrivateToSelf() {
doTryGrantUriActivityPermissionToSelf(
Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
public void doTryGrantUriServicePermissionToSelf(Uri uri, int mode) {
Intent grantIntent = new Intent();
grantIntent.setData(uri);
grantIntent.addFlags(mode);
grantIntent.setClass(getContext(), ReceiveUriService.class);
try {
getContext().startService(grantIntent);
fail("expected SecurityException granting " + uri + " to service");
} catch (SecurityException e) {
// This is what we want.
}
}
/**
* Test that we can't grant a permission to ourself.
*/
public void testGrantReadUriServicePermissionToSelf() {
doTryGrantUriServicePermissionToSelf(
Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
/**
* Test that we can't grant a permission to ourself.
*/
public void testGrantWriteUriServicePermissionToSelf() {
doTryGrantUriServicePermissionToSelf(
Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
/**
* Test that we can't grant a permission to ourself.
*/
public void testGrantReadUriServicePrivateToSelf() {
doTryGrantUriServicePermissionToSelf(
Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
/**
* Test that we can't grant a permission to ourself.
*/
public void testGrantWriteUriServicePrivateToSelf() {
doTryGrantUriServicePermissionToSelf(
Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
void grantUriPermission(Uri uri, int mode, boolean service) {
Intent grantIntent = new Intent();
grantIntent.setData(uri);
grantIntent.addFlags(mode);
grantIntent.setClass(getContext(),
service ? ReceiveUriService.class : ReceiveUriActivity.class);
Intent intent = new Intent();
intent.setComponent(GRANT_URI_PERM_COMP);
intent.putExtra("intent", grantIntent);
intent.putExtra("service", service);
getContext().sendBroadcast(intent);
}
void doTestGrantActivityUriReadPermission(Uri uri) {
final Uri subUri = Uri.withAppendedPath(uri, "foo");
final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
// Precondition: no current access.
assertReadingContentUriNotAllowed(subUri, "shouldn't read when starting test");
assertReadingContentUriNotAllowed(sub2Uri, "shouldn't read when starting test");
ReceiveUriActivity.clearStarted();
grantUriPermission(subUri, Intent.FLAG_GRANT_READ_URI_PERMISSION, false);
ReceiveUriActivity.waitForStart();
// See if we now have access to the provider.
getContext().getContentResolver().query(subUri, null, null, null, null);
// But not writing.
assertWritingContentUriNotAllowed(subUri, "shouldn't write from granted read");
// And not to the base path.
assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
// And not to a sub path.
assertReadingContentUriNotAllowed(subSubUri, "shouldn't read non-granted sub URI");
// Dispose of activity.
ReceiveUriActivity.finishCurInstanceSync();
// Ensure reading no longer allowed.
assertReadingContentUriNotAllowed(subUri, "shouldn't read after losing granted URI");
}
void doTestGrantActivityUriWritePermission(Uri uri) {
final Uri subUri = Uri.withAppendedPath(uri, "foo");
final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
// Precondition: no current access.
assertWritingContentUriNotAllowed(subUri, "shouldn't write when starting test");
assertWritingContentUriNotAllowed(sub2Uri, "shouldn't write when starting test");
// --------------------------------
ReceiveUriActivity.clearStarted();
grantUriPermission(subUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
ReceiveUriActivity.waitForStart();
// See if we now have access to the provider.
getContext().getContentResolver().insert(subUri, new ContentValues());
// But not reading.
assertReadingContentUriNotAllowed(subUri, "shouldn't read from granted write");
// And not to the base path.
assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
// And not a sub-path.
assertWritingContentUriNotAllowed(subSubUri, "shouldn't write non-granted sub URI");
// --------------------------------
ReceiveUriActivity.clearNewIntent();
grantUriPermission(sub2Uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
ReceiveUriActivity.waitForNewIntent();
if (false) {
synchronized (this) {
Log.i("**", "******************************* WAITING!!!");
try {
wait(10000);
} catch (InterruptedException e) {
}
}
}
// See if we now have access to the provider.
getContext().getContentResolver().insert(sub2Uri, new ContentValues());
// And still have access to the original URI.
getContext().getContentResolver().insert(subUri, new ContentValues());
// But not reading.
assertReadingContentUriNotAllowed(sub2Uri, "shouldn't read from granted write");
// And not to the base path.
assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
// And not a sub-path.
assertWritingContentUriNotAllowed(sub2SubUri, "shouldn't write non-granted sub URI");
// And make sure we can't generate a permission to a running activity.
doTryGrantUriActivityPermissionToSelf(
Uri.withAppendedPath(uri, "hah"),
Intent.FLAG_GRANT_READ_URI_PERMISSION);
doTryGrantUriActivityPermissionToSelf(
Uri.withAppendedPath(uri, "hah"),
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// --------------------------------
// Dispose of activity.
ReceiveUriActivity.finishCurInstanceSync();
if (false) {
synchronized (this) {
Log.i("**", "******************************* WAITING!!!");
try {
wait(10000);
} catch (InterruptedException e) {
}
}
}
// Ensure writing no longer allowed.
assertWritingContentUriNotAllowed(subUri, "shouldn't write after losing granted URI");
assertWritingContentUriNotAllowed(sub2Uri, "shouldn't write after losing granted URI");
}
/**
* Test that the ctspermissionwithsignaturegranting content provider can grant a read
* permission.
*/
public void testGrantActivityReadPermissionFromStartActivity() {
doTestGrantActivityUriReadPermission(PERM_URI_GRANTING);
}
/**
* Test that the ctspermissionwithsignaturegranting content provider can grant a write
* permission.
*/
public void testGrantActivityWritePermissionFromStartActivity() {
doTestGrantActivityUriWritePermission(PERM_URI_GRANTING);
}
/**
* Test that the ctsprivateprovidergranting content provider can grant a read
* permission.
*/
public void testGrantActivityReadPrivateFromStartActivity() {
doTestGrantActivityUriReadPermission(PRIV_URI_GRANTING);
}
/**
* Test that the ctsprivateprovidergranting content provider can grant a write
* permission.
*/
public void testGrantActivityWritePrivateFromStartActivity() {
doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING);
}
void doTestGrantServiceUriReadPermission(Uri uri) {
final Uri subUri = Uri.withAppendedPath(uri, "foo");
final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
ReceiveUriService.stop(getContext());
// Precondition: no current access.
assertReadingContentUriNotAllowed(subUri, "shouldn't read when starting test");
assertReadingContentUriNotAllowed(sub2Uri, "shouldn't read when starting test");
// --------------------------------
ReceiveUriService.clearStarted();
grantUriPermission(subUri, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
ReceiveUriService.waitForStart();
int firstStartId = ReceiveUriService.getCurStartId();
// See if we now have access to the provider.
getContext().getContentResolver().query(subUri, null, null, null, null);
// But not writing.
assertWritingContentUriNotAllowed(subUri, "shouldn't write from granted read");
// And not to the base path.
assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
// And not to a sub path.
assertReadingContentUriNotAllowed(subSubUri, "shouldn't read non-granted sub URI");
// --------------------------------
// Send another Intent to it.
ReceiveUriService.clearStarted();
grantUriPermission(sub2Uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
ReceiveUriService.waitForStart();
if (false) {
synchronized (this) {
Log.i("**", "******************************* WAITING!!!");
try {
wait(10000);
} catch (InterruptedException e) {
}
}
}
// See if we now have access to the provider.
getContext().getContentResolver().query(sub2Uri, null, null, null, null);
// And still to the previous URI.
getContext().getContentResolver().query(subUri, null, null, null, null);
// But not writing.
assertWritingContentUriNotAllowed(sub2Uri, "shouldn't write from granted read");
// And not to the base path.
assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
// And not to a sub path.
assertReadingContentUriNotAllowed(sub2SubUri, "shouldn't read non-granted sub URI");
// --------------------------------
// Stop the first command.
ReceiveUriService.stopCurWithId(firstStartId);
// Ensure reading no longer allowed.
assertReadingContentUriNotAllowed(subUri, "shouldn't read after losing granted URI");
// And make sure we can't generate a permission to a running service.
doTryGrantUriActivityPermissionToSelf(subUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
doTryGrantUriActivityPermissionToSelf(subUri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// --------------------------------
// Dispose of service.
ReceiveUriService.stopSync(getContext());
// Ensure reading no longer allowed.
assertReadingContentUriNotAllowed(subUri, "shouldn't read after losing granted URI");
assertReadingContentUriNotAllowed(sub2Uri, "shouldn't read after losing granted URI");
}
void doTestGrantServiceUriWritePermission(Uri uri) {
final Uri subUri = Uri.withAppendedPath(uri, "foo");
final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
ReceiveUriService.stop(getContext());
// Precondition: no current access.
assertWritingContentUriNotAllowed(subUri, "shouldn't write when starting test");
assertWritingContentUriNotAllowed(sub2Uri, "shouldn't write when starting test");
// --------------------------------
ReceiveUriService.clearStarted();
grantUriPermission(subUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
ReceiveUriService.waitForStart();
int firstStartId = ReceiveUriService.getCurStartId();
// See if we now have access to the provider.
getContext().getContentResolver().insert(subUri, new ContentValues());
// But not reading.
assertReadingContentUriNotAllowed(subUri, "shouldn't read from granted write");
// And not to the base path.
assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
// And not a sub-path.
assertWritingContentUriNotAllowed(subSubUri, "shouldn't write non-granted sub URI");
// --------------------------------
// Send another Intent to it.
ReceiveUriService.clearStarted();
grantUriPermission(sub2Uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
ReceiveUriService.waitForStart();
// See if we now have access to the provider.
getContext().getContentResolver().insert(sub2Uri, new ContentValues());
// And still to the previous URI.
getContext().getContentResolver().insert(subUri, new ContentValues());
// But not reading.
assertReadingContentUriNotAllowed(sub2Uri, "shouldn't read from granted write");
// And not to the base path.
assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
// And not a sub-path.
assertWritingContentUriNotAllowed(sub2SubUri, "shouldn't write non-granted sub URI");
if (false) {
synchronized (this) {
Log.i("**", "******************************* WAITING!!!");
try {
wait(10000);
} catch (InterruptedException e) {
}
}
}
// --------------------------------
// Stop the first command.
ReceiveUriService.stopCurWithId(firstStartId);
// Ensure writing no longer allowed.
assertWritingContentUriNotAllowed(subUri, "shouldn't write after losing granted URI");
// And make sure we can't generate a permission to a running service.
doTryGrantUriActivityPermissionToSelf(subUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
doTryGrantUriActivityPermissionToSelf(subUri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// --------------------------------
// Dispose of service.
ReceiveUriService.stopSync(getContext());
// Ensure writing no longer allowed.
assertWritingContentUriNotAllowed(subUri, "shouldn't write after losing granted URI");
assertWritingContentUriNotAllowed(sub2Uri, "shouldn't write after losing granted URI");
}
public void testGrantActivityReadPermissionFromStartService() {
doTestGrantServiceUriReadPermission(PERM_URI_GRANTING);
}
public void testGrantActivityWritePermissionFromStartService() {
doTestGrantServiceUriWritePermission(PERM_URI_GRANTING);
}
public void testGrantActivityReadPrivateFromStartService() {
doTestGrantServiceUriReadPermission(PRIV_URI_GRANTING);
}
public void testGrantActivityWritePrivateFromStartService() {
doTestGrantServiceUriWritePermission(PRIV_URI_GRANTING);
}
}