From 1c256e9e50547f92f7e468fadd442157155d57c8 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 5 Feb 2016 19:24:30 +0100 Subject: external-provider: add permission check for status query --- .../keychain/provider/KeychainProvider.java | 2 +- .../keychain/remote/ApiPermissionHelper.java | 11 +++++ .../keychain/remote/KeychainExternalProvider.java | 47 +++++++++++++++++++--- .../keychain/remote/OpenPgpService.java | 1 + 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 87b8a3b65..0cb8e4675 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -1,7 +1,7 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2010-2014 Thialfihar - * Copyright (C) 2014 Vincent Breitmoser + * Copyright (C) 2014-2016 Vincent Breitmoser * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java index 1a6638bd9..3af8e70dd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java @@ -66,6 +66,17 @@ public class ApiPermissionHelper { } } + /** Returns true iff the caller is allowed, or false on any type of problem. + * This method should only be used in cases where error handling is dealt with separately. + */ + protected boolean isAllowedIgnoreErrors() { + try { + return isCallerAllowed(); + } catch (WrongPackageCertificateException e) { + return false; + } + } + /** * Checks if caller is allowed to access the API * diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/KeychainExternalProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/KeychainExternalProvider.java index 9ab4be08a..7eb5d558f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/KeychainExternalProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/KeychainExternalProvider.java @@ -1,7 +1,5 @@ /* - * Copyright (C) 2012-2014 Dominik Schürmann - * Copyright (C) 2010-2014 Thialfihar - * Copyright (C) 2014 Vincent Breitmoser + * Copyright (C) 2016 Vincent Breitmoser * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +18,7 @@ package org.sufficientlysecure.keychain.remote; +import java.security.AccessControlException; import java.util.Arrays; import java.util.HashMap; @@ -35,6 +34,9 @@ import android.support.annotation.NonNull; import android.text.TextUtils; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; @@ -42,14 +44,18 @@ import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.provider.KeychainExternalContract; import org.sufficientlysecure.keychain.provider.KeychainExternalContract.EmailStatus; +import org.sufficientlysecure.keychain.provider.SimpleContentResolverInterface; import org.sufficientlysecure.keychain.util.Log; -public class KeychainExternalProvider extends ContentProvider { +public class KeychainExternalProvider extends ContentProvider implements SimpleContentResolverInterface { private static final int EMAIL_STATUS = 101; + private static final int API_APPS = 301; + private static final int API_APPS_BY_PACKAGE_NAME = 302; - protected UriMatcher mUriMatcher; + private UriMatcher mUriMatcher; + private ApiPermissionHelper mApiPermissionHelper; /** @@ -70,6 +76,9 @@ public class KeychainExternalProvider extends ContentProvider { */ matcher.addURI(authority, KeychainExternalContract.BASE_EMAIL_STATUS, EMAIL_STATUS); + matcher.addURI(KeychainContract.CONTENT_AUTHORITY, KeychainContract.BASE_API_APPS, API_APPS); + matcher.addURI(KeychainContract.CONTENT_AUTHORITY, KeychainContract.BASE_API_APPS + "/*", API_APPS_BY_PACKAGE_NAME); + return matcher; } @@ -79,6 +88,7 @@ public class KeychainExternalProvider extends ContentProvider { @Override public boolean onCreate() { mUriMatcher = buildUriMatcher(); + mApiPermissionHelper = new ApiPermissionHelper(getContext(), new ApiDataAccessObject(this)); return true; } @@ -98,6 +108,12 @@ public class KeychainExternalProvider extends ContentProvider { case EMAIL_STATUS: return EmailStatus.CONTENT_TYPE; + case API_APPS: + return ApiApps.CONTENT_TYPE; + + case API_APPS_BY_PACKAGE_NAME: + return ApiApps.CONTENT_ITEM_TYPE; + default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -115,10 +131,15 @@ public class KeychainExternalProvider extends ContentProvider { int match = mUriMatcher.match(uri); - String groupBy; + String groupBy = null; switch (match) { case EMAIL_STATUS: { + boolean callerIsAllowed = mApiPermissionHelper.isAllowedIgnoreErrors(); + if (!callerIsAllowed) { + throw new AccessControlException("An application must register before use of KeychainExternalProvider!"); + } + HashMap projectionMap = new HashMap<>(); projectionMap.put(EmailStatus._ID, "email AS _id"); projectionMap.put(EmailStatus.EMAIL_ADDRESS, @@ -185,6 +206,20 @@ public class KeychainExternalProvider extends ContentProvider { break; } + case API_APPS: { + qb.setTables(Tables.API_APPS); + + break; + } + + case API_APPS_BY_PACKAGE_NAME: { + qb.setTables(Tables.API_APPS); + qb.appendWhere(ApiApps.PACKAGE_NAME + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + + break; + } + default: { throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")"); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 2bf14f876..d92393e64 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2013-2015 Dominik Schürmann + * Copyright (C) 2016 Vincent Breitmoser * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3