diff options
Diffstat (limited to 'src')
4 files changed, 62 insertions, 60 deletions
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java index e3f3520..951555c 100644 --- a/src/com/android/providers/contacts/CallLogProvider.java +++ b/src/com/android/providers/contacts/CallLogProvider.java @@ -230,7 +230,7 @@ public class CallLogProvider extends ContentProvider { // permission and also requires the additional voicemail param set. if (hasVoicemailValue(values)) { checkIsAllowVoicemailRequest(uri); - mVoicemailPermissions.checkCallerHasFullAccess(); + mVoicemailPermissions.checkCallerHasManageAccess(); } if (mCallsInserter == null) { SQLiteDatabase db = mDbHelper.getWritableDatabase(); @@ -331,8 +331,10 @@ public class CallLogProvider extends ContentProvider { private void checkVoicemailPermissionAndAddRestriction(Uri uri, SelectionBuilder selectionBuilder, boolean isQuery) { if (isAllowVoicemailRequest(uri)) { - if (!(isQuery && mVoicemailPermissions.callerHasFullReadAccess())) { - mVoicemailPermissions.checkCallerHasFullAccess(); + if (isQuery) { + mVoicemailPermissions.checkCallerHasFullReadAccess(); + } else { + mVoicemailPermissions.checkCallerHasManageAccess(); } } else { selectionBuilder.addClause(EXCLUDE_VOICEMAIL_SELECTION); diff --git a/src/com/android/providers/contacts/DbModifierWithNotification.java b/src/com/android/providers/contacts/DbModifierWithNotification.java index fda8321..c25e171 100644 --- a/src/com/android/providers/contacts/DbModifierWithNotification.java +++ b/src/com/android/providers/contacts/DbModifierWithNotification.java @@ -18,7 +18,7 @@ package com.android.providers.contacts; import static android.Manifest.permission.ADD_VOICEMAIL; -import static com.android.providers.contacts.Manifest.permission.READ_WRITE_ALL_VOICEMAIL; +import static android.Manifest.permission.READ_ALL_VOICEMAIL; import android.content.ComponentName; import android.content.ContentUris; @@ -210,7 +210,8 @@ public class DbModifierWithNotification implements DatabaseModifier { // Ignore any package that is not affected by the change and don't have full access // either. if (!modifiedPackages.contains(component.getPackageName()) && - !mVoicemailPermissions.packageHasFullAccess(component.getPackageName())) { + !mVoicemailPermissions.packageHasFullReadAccess( + component.getPackageName())) { continue; } @@ -221,7 +222,7 @@ public class DbModifierWithNotification implements DatabaseModifier { callingPackages.contains(component.getPackageName())); } String permissionNeeded = modifiedPackages.contains(component.getPackageName()) ? - ADD_VOICEMAIL : READ_WRITE_ALL_VOICEMAIL; + ADD_VOICEMAIL : READ_ALL_VOICEMAIL; mContext.sendBroadcast(intent, permissionNeeded); Log.v(TAG, String.format("Sent intent. act:%s, url:%s, comp:%s, perm:%s," + " self_change:%s", intent.getAction(), intent.getData(), diff --git a/src/com/android/providers/contacts/VoicemailContentProvider.java b/src/com/android/providers/contacts/VoicemailContentProvider.java index 79e549b..ec5c6ad 100644 --- a/src/com/android/providers/contacts/VoicemailContentProvider.java +++ b/src/com/android/providers/contacts/VoicemailContentProvider.java @@ -99,14 +99,14 @@ public class VoicemailContentProvider extends ContentProvider @Override public Uri insert(Uri uri, ContentValues values) { - UriData uriData = checkPermissionsAndCreateUriData(uri, values); + UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri, values); return getTableDelegate(uriData).insert(uriData, values); } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - UriData uriData = checkPermissionsAndCreateUriDataForReadOperation(uri); + UriData uriData = checkPermissionsAndCreateUriDataForRead(uri); SelectionBuilder selectionBuilder = new SelectionBuilder(selection); selectionBuilder.addClause(getPackageRestrictionClause(true/*isQuery*/)); return getTableDelegate(uriData).query(uriData, projection, selectionBuilder.build(), @@ -115,7 +115,7 @@ public class VoicemailContentProvider extends ContentProvider @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - UriData uriData = checkPermissionsAndCreateUriData(uri, values); + UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri, values); SelectionBuilder selectionBuilder = new SelectionBuilder(selection); selectionBuilder.addClause(getPackageRestrictionClause(false/*isQuery*/)); return getTableDelegate(uriData).update(uriData, values, selectionBuilder.build(), @@ -124,7 +124,7 @@ public class VoicemailContentProvider extends ContentProvider @Override public int delete(Uri uri, String selection, String[] selectionArgs) { - UriData uriData = checkPermissionsAndCreateUriData(uri); + UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri); SelectionBuilder selectionBuilder = new SelectionBuilder(selection); selectionBuilder.addClause(getPackageRestrictionClause(false/*isQuery*/)); return getTableDelegate(uriData).delete(uriData, selectionBuilder.build(), selectionArgs); @@ -134,9 +134,9 @@ public class VoicemailContentProvider extends ContentProvider public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { UriData uriData = null; if (mode.equals("r")) { - uriData = checkPermissionsAndCreateUriDataForReadOperation(uri); + uriData = checkPermissionsAndCreateUriDataForRead(uri); } else { - uriData = checkPermissionsAndCreateUriData(uri); + uriData = checkPermissionsAndCreateUriDataForWrite(uri); } // openFileHelper() relies on "_data" column to be populated with the file path. return getTableDelegate(uriData).openFile(uriData, mode); @@ -247,8 +247,9 @@ public class VoicemailContentProvider extends ContentProvider uriData.getSourcePackage() : getCallingPackage_(); values.put(SOURCE_PACKAGE_FIELD, provider); } + // You must have access to the provider given in values. - if (!mVoicemailPermissions.callerHasFullAccess()) { + if (!mVoicemailPermissions.callerHasManageAccess()) { checkPackagesMatch(getCallingPackage_(), values.getAsString(VoicemailContract.SOURCE_PACKAGE_FIELD), uriData.getUri()); @@ -278,10 +279,10 @@ public class VoicemailContentProvider extends ContentProvider } /** - * Performs necessary voicemail permission checks common to all operations and returns - * the structured representation, {@link UriData}, of the supplied uri. + * Ensures that the caller has the permissions to perform a query/read operation, and + * then returns the structured representation {@link UriData} of the supplied uri. */ - private UriData checkPermissionsAndCreateUriDataForReadOperation(Uri uri) { + private UriData checkPermissionsAndCreateUriDataForRead(Uri uri) { // If the caller has been explicitly granted read permission to this URI then no need to // check further. if (context().checkCallingUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION) @@ -293,26 +294,29 @@ public class VoicemailContentProvider extends ContentProvider return UriData.createUriData(uri); } - return checkPermissionsAndCreateUriData(uri); + return checkPermissionsAndCreateUriData(uri, true); } /** * Performs necessary voicemail permission checks common to all operations and returns * the structured representation, {@link UriData}, of the supplied uri. */ - private UriData checkPermissionsAndCreateUriData(Uri uri) { - mVoicemailPermissions.checkCallerHasOwnVoicemailAccess(); + private UriData checkPermissionsAndCreateUriData(Uri uri, boolean read) { UriData uriData = UriData.createUriData(uri); - checkPackagePermission(uriData); + if (!hasReadWritePermission(read)) { + mVoicemailPermissions.checkCallerHasOwnVoicemailAccess(); + checkPackagePermission(uriData); + } return uriData; } /** - * Same as {@link #checkPackagePermission(UriData)}. In addition does permission check - * on the ContentValues. + * Ensures that the caller has the permissions to perform an update/delete operation, and + * then returns the structured representation {@link UriData} of the supplied uri. + * Also does a permission check on the ContentValues. */ - private UriData checkPermissionsAndCreateUriData(Uri uri, ContentValues... valuesArray) { - UriData uriData = checkPermissionsAndCreateUriData(uri); + private UriData checkPermissionsAndCreateUriDataForWrite(Uri uri, ContentValues... valuesArray) { + UriData uriData = checkPermissionsAndCreateUriData(uri, false); for (ContentValues values : valuesArray) { checkSourcePackageSameIfSet(uriData, values); } @@ -329,13 +333,13 @@ public class VoicemailContentProvider extends ContentProvider String errorMsg = String.format("Permission denied for URI: %s\n. " + "Package %s cannot perform this operation for %s. Requires %s permission.", uri, callingPackage, voicemailSourcePackage, - Manifest.permission.READ_WRITE_ALL_VOICEMAIL); + android.Manifest.permission.MANAGE_VOICEMAIL); throw new SecurityException(errorMsg); } } /** - * Checks that either the caller has READ_WRITE_ALL_VOICEMAIL permission, + * Checks that either the caller has the MANAGE_VOICEMAIL permission, * or has the ADD_VOICEMAIL permission and is using a URI that matches * /voicemail/?source_package=[source-package] where [source-package] is the same as the calling * package. @@ -343,13 +347,13 @@ public class VoicemailContentProvider extends ContentProvider * @throws SecurityException if the check fails. */ private void checkPackagePermission(UriData uriData) { - if (!mVoicemailPermissions.callerHasFullAccess()) { + if (!mVoicemailPermissions.callerHasManageAccess()) { if (!uriData.hasSourcePackage()) { // You cannot have a match if this is not a provider URI. throw new SecurityException(String.format( "Provider %s does not have %s permission." + "\nPlease set query parameter '%s' in the URI.\nURI: %s", - getCallingPackage_(), Manifest.permission.READ_WRITE_ALL_VOICEMAIL, + getCallingPackage_(), android.Manifest.permission.MANAGE_VOICEMAIL, VoicemailContract.PARAM_KEY_SOURCE_PACKAGE, uriData.getUri())); } checkPackagesMatch(getCallingPackage_(), uriData.getSourcePackage(), uriData.getUri()); @@ -381,7 +385,7 @@ public class VoicemailContentProvider extends ContentProvider // which one we return. String bestSoFar = callerPackages[0]; for (String callerPackage : callerPackages) { - if (mVoicemailPermissions.packageHasFullAccess(callerPackage)) { + if (mVoicemailPermissions.packageHasManageAccess(callerPackage)) { // Full always wins, we can return early. return callerPackage; } @@ -397,12 +401,21 @@ public class VoicemailContentProvider extends ContentProvider * access to all data. */ private String getPackageRestrictionClause(boolean isQuery) { - if (isQuery && mVoicemailPermissions.callerHasFullReadAccess()) { - return null; - } - if (mVoicemailPermissions.callerHasFullAccess()) { + if (hasReadWritePermission(isQuery)) { return null; } return getEqualityClause(Voicemails.SOURCE_PACKAGE, getCallingPackage_()); } + + /** + * Whether or not the calling package has the appropriate read/write permission + * + * @param read Whether or not this operation is a read + * + * @return True if the package has the permission required to perform the read/write operation + */ + private boolean hasReadWritePermission(boolean read) { + return read ? mVoicemailPermissions.callerHasFullReadAccess() : + mVoicemailPermissions.callerHasManageAccess(); + } } diff --git a/src/com/android/providers/contacts/VoicemailPermissions.java b/src/com/android/providers/contacts/VoicemailPermissions.java index 570399c..b32f79c 100644 --- a/src/com/android/providers/contacts/VoicemailPermissions.java +++ b/src/com/android/providers/contacts/VoicemailPermissions.java @@ -36,16 +36,15 @@ public class VoicemailPermissions { return callerHasPermission(android.Manifest.permission.ADD_VOICEMAIL); } - /** Determine if the calling process has full read access to all voicemails. */ public boolean callerHasFullReadAccess() { return callerHasPermission(android.Manifest.permission.READ_ALL_VOICEMAIL); } - /** Determines if the calling process has access to all voicemails. */ - public boolean callerHasFullAccess() { - return callerHasOwnVoicemailAccess() && - callerHasPermission(Manifest.permission.READ_WRITE_ALL_VOICEMAIL); + /** Determine if the calling process has the permission required to update and remove all + * voicemails */ + public boolean callerHasManageAccess() { + return callerHasPermission(android.Manifest.permission.MANAGE_VOICEMAIL); } /** @@ -72,16 +71,10 @@ public class VoicemailPermissions { } } - /** - * Checks that the caller has permissions to access ALL voicemails. - * - * @throws SecurityException if the caller does not have the voicemail source permission. - */ - public void checkCallerHasFullAccess() { - if (!callerHasFullAccess()) { - throw new SecurityException(String.format("The caller must have permissions %s AND %s", - android.Manifest.permission.ADD_VOICEMAIL, - Manifest.permission.READ_WRITE_ALL_VOICEMAIL)); + public void checkCallerHasManageAccess() { + if (!callerHasManageAccess()) { + throw new SecurityException(String.format("The caller must have %s permission: ", + android.Manifest.permission.MANAGE_VOICEMAIL)); } } @@ -96,26 +89,19 @@ public class VoicemailPermissions { return packageHasPermission(packageName, android.Manifest.permission.READ_ALL_VOICEMAIL); } - /** Determines if the given package has full access. */ - public boolean packageHasFullAccess(String packageName) { - return packageHasOwnVoicemailAccess(packageName) && - packageHasPermission(packageName, Manifest.permission.READ_WRITE_ALL_VOICEMAIL); + /** Determines if the given package has manage access. */ + public boolean packageHasManageAccess(String packageName) { + return packageHasPermission(packageName, android.Manifest.permission.MANAGE_VOICEMAIL); } /** Determines if the given package has the given permission. */ private boolean packageHasPermission(String packageName, String permission) { return mContext.getPackageManager().checkPermission(permission, packageName) - == PackageManager.PERMISSION_GRANTED; + == PackageManager.PERMISSION_GRANTED; } /** Determines if the calling process has the given permission. */ private boolean callerHasPermission(String permission) { - // We need to check against both the calling or self permission in order for the Contacts - // app to be allowed access. - // The reason is that the Contacts app shares its process with the ContactsProvider and - // therefore its requests are not considered to be IPCs, since they are coming from the same - // process, even if, technically, from a different package. - return mContext.checkCallingOrSelfPermission(permission) - == PackageManager.PERMISSION_GRANTED; + return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED; } } |