external-provider: add permission check for status query

This commit is contained in:
Vincent Breitmoser
2016-02-05 19:24:30 +01:00
parent da3167476b
commit 1c256e9e50
4 changed files with 54 additions and 7 deletions

View File

@@ -1,7 +1,7 @@
/* /*
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org> * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
* Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com> * Copyright (C) 2014-2016 Vincent Breitmoser <v.breitmoser@mugenguild.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@@ -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 * Checks if caller is allowed to access the API
* *

View File

@@ -1,7 +1,5 @@
/* /*
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2016 Vincent Breitmoser <look@my.amazin.horse>
* Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
* Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -20,6 +18,7 @@
package org.sufficientlysecure.keychain.remote; package org.sufficientlysecure.keychain.remote;
import java.security.AccessControlException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@@ -35,6 +34,9 @@ import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import org.sufficientlysecure.keychain.Constants; 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.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; 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.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.provider.KeychainExternalContract; import org.sufficientlysecure.keychain.provider.KeychainExternalContract;
import org.sufficientlysecure.keychain.provider.KeychainExternalContract.EmailStatus; import org.sufficientlysecure.keychain.provider.KeychainExternalContract.EmailStatus;
import org.sufficientlysecure.keychain.provider.SimpleContentResolverInterface;
import org.sufficientlysecure.keychain.util.Log; 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 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(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; return matcher;
} }
@@ -79,6 +88,7 @@ public class KeychainExternalProvider extends ContentProvider {
@Override @Override
public boolean onCreate() { public boolean onCreate() {
mUriMatcher = buildUriMatcher(); mUriMatcher = buildUriMatcher();
mApiPermissionHelper = new ApiPermissionHelper(getContext(), new ApiDataAccessObject(this));
return true; return true;
} }
@@ -98,6 +108,12 @@ public class KeychainExternalProvider extends ContentProvider {
case EMAIL_STATUS: case EMAIL_STATUS:
return EmailStatus.CONTENT_TYPE; return EmailStatus.CONTENT_TYPE;
case API_APPS:
return ApiApps.CONTENT_TYPE;
case API_APPS_BY_PACKAGE_NAME:
return ApiApps.CONTENT_ITEM_TYPE;
default: default:
throw new UnsupportedOperationException("Unknown uri: " + uri); throw new UnsupportedOperationException("Unknown uri: " + uri);
} }
@@ -115,10 +131,15 @@ public class KeychainExternalProvider extends ContentProvider {
int match = mUriMatcher.match(uri); int match = mUriMatcher.match(uri);
String groupBy; String groupBy = null;
switch (match) { switch (match) {
case EMAIL_STATUS: { case EMAIL_STATUS: {
boolean callerIsAllowed = mApiPermissionHelper.isAllowedIgnoreErrors();
if (!callerIsAllowed) {
throw new AccessControlException("An application must register before use of KeychainExternalProvider!");
}
HashMap<String, String> projectionMap = new HashMap<>(); HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(EmailStatus._ID, "email AS _id"); projectionMap.put(EmailStatus._ID, "email AS _id");
projectionMap.put(EmailStatus.EMAIL_ADDRESS, projectionMap.put(EmailStatus.EMAIL_ADDRESS,
@@ -185,6 +206,20 @@ public class KeychainExternalProvider extends ContentProvider {
break; 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: { default: {
throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")"); throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")");
} }

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (C) 2013-2015 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2013-2015 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2016 Vincent Breitmoser <look@my.amazin.horse>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by