move custm api permission methods into helper class (composition over inheritance)
This commit is contained in:
@@ -17,9 +17,14 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.remote;
|
package org.sufficientlysecure.keychain.remote;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
@@ -38,15 +43,21 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
|||||||
import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
|
import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract service class for remote APIs that handle app registration and user input.
|
* Abstract service class for remote APIs that handle app registration and user input.
|
||||||
*/
|
*/
|
||||||
public abstract class RemoteService extends Service {
|
public class ApiPermissionHelper {
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
private final ProviderHelper mProviderHelper;
|
||||||
|
private PackageManager mPackageManager;
|
||||||
|
|
||||||
|
public ApiPermissionHelper(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
mPackageManager = context.getPackageManager();
|
||||||
|
mProviderHelper = new ProviderHelper(context);
|
||||||
|
}
|
||||||
|
|
||||||
public static class WrongPackageCertificateException extends Exception {
|
public static class WrongPackageCertificateException extends Exception {
|
||||||
private static final long serialVersionUID = -8294642703122196028L;
|
private static final long serialVersionUID = -8294642703122196028L;
|
||||||
@@ -56,13 +67,6 @@ public abstract class RemoteService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Context mContext;
|
|
||||||
ProviderHelper mProviderHelper;
|
|
||||||
|
|
||||||
public Context getContext() {
|
|
||||||
return mContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if caller is allowed to access the API
|
* Checks if caller is allowed to access the API
|
||||||
*
|
*
|
||||||
@@ -90,13 +94,13 @@ public abstract class RemoteService extends Service {
|
|||||||
}
|
}
|
||||||
Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!");
|
Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!");
|
||||||
|
|
||||||
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
|
Intent intent = new Intent(mContext, RemoteServiceActivity.class);
|
||||||
intent.setAction(RemoteServiceActivity.ACTION_REGISTER);
|
intent.setAction(RemoteServiceActivity.ACTION_REGISTER);
|
||||||
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
|
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
|
||||||
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageCertificate);
|
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageCertificate);
|
||||||
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
|
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
|
||||||
|
|
||||||
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
|
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
|
||||||
intent,
|
intent,
|
||||||
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
|
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
|
||||||
|
|
||||||
@@ -110,13 +114,13 @@ public abstract class RemoteService extends Service {
|
|||||||
} catch (WrongPackageCertificateException e) {
|
} catch (WrongPackageCertificateException e) {
|
||||||
Log.e(Constants.TAG, "wrong signature!", e);
|
Log.e(Constants.TAG, "wrong signature!", e);
|
||||||
|
|
||||||
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
|
Intent intent = new Intent(mContext, RemoteServiceActivity.class);
|
||||||
intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
|
intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
|
||||||
intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
|
intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
|
||||||
getString(R.string.api_error_wrong_signature));
|
mContext.getString(R.string.api_error_wrong_signature));
|
||||||
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
|
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
|
||||||
|
|
||||||
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
|
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
|
||||||
intent,
|
intent,
|
||||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
|
||||||
@@ -131,7 +135,7 @@ public abstract class RemoteService extends Service {
|
|||||||
|
|
||||||
private byte[] getPackageCertificate(String packageName) throws NameNotFoundException {
|
private byte[] getPackageCertificate(String packageName) throws NameNotFoundException {
|
||||||
@SuppressLint("PackageManagerGetSignatures") // we do check the byte array of *all* signatures
|
@SuppressLint("PackageManagerGetSignatures") // we do check the byte array of *all* signatures
|
||||||
PackageInfo pkgInfo = getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
PackageInfo pkgInfo = mContext.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
||||||
// NOTE: Silly Android API naming: Signatures are actually certificates
|
// NOTE: Silly Android API naming: Signatures are actually certificates
|
||||||
Signature[] certificates = pkgInfo.signatures;
|
Signature[] certificates = pkgInfo.signatures;
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
@@ -156,7 +160,7 @@ public abstract class RemoteService extends Service {
|
|||||||
* @return package name
|
* @return package name
|
||||||
*/
|
*/
|
||||||
protected String getCurrentCallingPackage() {
|
protected String getCurrentCallingPackage() {
|
||||||
String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
|
String[] callingPackages = mPackageManager.getPackagesForUid(Binder.getCallingUid());
|
||||||
|
|
||||||
// NOTE: No support for sharedUserIds
|
// NOTE: No support for sharedUserIds
|
||||||
// callingPackages contains more than one entry when sharedUserId has been used
|
// callingPackages contains more than one entry when sharedUserId has been used
|
||||||
@@ -189,13 +193,13 @@ public abstract class RemoteService extends Service {
|
|||||||
String packageName = getCurrentCallingPackage();
|
String packageName = getCurrentCallingPackage();
|
||||||
Log.d(Constants.TAG, "getCreateAccountIntent accountName: " + accountName);
|
Log.d(Constants.TAG, "getCreateAccountIntent accountName: " + accountName);
|
||||||
|
|
||||||
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
|
Intent intent = new Intent(mContext, RemoteServiceActivity.class);
|
||||||
intent.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT);
|
intent.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT);
|
||||||
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
|
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
|
||||||
intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName);
|
intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName);
|
||||||
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
|
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
|
||||||
|
|
||||||
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
|
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
|
||||||
intent,
|
intent,
|
||||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
|
||||||
@@ -221,7 +225,7 @@ public abstract class RemoteService extends Service {
|
|||||||
private boolean isUidAllowed(int uid)
|
private boolean isUidAllowed(int uid)
|
||||||
throws WrongPackageCertificateException {
|
throws WrongPackageCertificateException {
|
||||||
|
|
||||||
String[] callingPackages = getPackageManager().getPackagesForUid(uid);
|
String[] callingPackages = mPackageManager.getPackagesForUid(uid);
|
||||||
|
|
||||||
// is calling package allowed to use this service?
|
// is calling package allowed to use this service?
|
||||||
for (String currentPkg : callingPackages) {
|
for (String currentPkg : callingPackages) {
|
||||||
@@ -273,11 +277,4 @@ public abstract class RemoteService extends Service {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
mContext = this;
|
|
||||||
mProviderHelper = new ProviderHelper(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
package org.sufficientlysecure.keychain.remote;
|
package org.sufficientlysecure.keychain.remote;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
@@ -74,7 +75,7 @@ import java.util.Date;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class OpenPgpService extends RemoteService {
|
public class OpenPgpService extends Service {
|
||||||
|
|
||||||
static final String[] EMAIL_SEARCH_PROJECTION = new String[]{
|
static final String[] EMAIL_SEARCH_PROJECTION = new String[]{
|
||||||
KeyRings._ID,
|
KeyRings._ID,
|
||||||
@@ -87,6 +88,16 @@ public class OpenPgpService extends RemoteService {
|
|||||||
static final String EMAIL_SEARCH_WHERE = Tables.KEYS + "." + KeychainContract.KeyRings.IS_REVOKED
|
static final String EMAIL_SEARCH_WHERE = Tables.KEYS + "." + KeychainContract.KeyRings.IS_REVOKED
|
||||||
+ " = 0 AND " + KeychainContract.KeyRings.IS_EXPIRED + " = 0";
|
+ " = 0 AND " + KeychainContract.KeyRings.IS_EXPIRED + " = 0";
|
||||||
|
|
||||||
|
private ApiPermissionHelper mApiPermissionHelper;
|
||||||
|
private ProviderHelper mProviderHelper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
mApiPermissionHelper = new ApiPermissionHelper(this);
|
||||||
|
mProviderHelper = new ProviderHelper(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search database for key ids based on emails.
|
* Search database for key ids based on emails.
|
||||||
*/
|
*/
|
||||||
@@ -225,7 +236,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
// to retrieve the missing key
|
// to retrieve the missing key
|
||||||
Intent intent = new Intent(getBaseContext(), SelectAllowedKeysActivity.class);
|
Intent intent = new Intent(getBaseContext(), SelectAllowedKeysActivity.class);
|
||||||
intent.putExtra(SelectAllowedKeysActivity.EXTRA_SERVICE_INTENT, data);
|
intent.putExtra(SelectAllowedKeysActivity.EXTRA_SERVICE_INTENT, data);
|
||||||
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(getCurrentCallingPackage()));
|
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(mApiPermissionHelper.getCurrentCallingPackage()));
|
||||||
|
|
||||||
return PendingIntent.getActivity(getBaseContext(), 0,
|
return PendingIntent.getActivity(getBaseContext(), 0,
|
||||||
intent,
|
intent,
|
||||||
@@ -297,7 +308,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// execute PGP operation!
|
// execute PGP operation!
|
||||||
PgpSignEncryptOperation pse = new PgpSignEncryptOperation(this, new ProviderHelper(getContext()), null);
|
PgpSignEncryptOperation pse = new PgpSignEncryptOperation(this, new ProviderHelper(this), null);
|
||||||
PgpSignEncryptResult pgpResult = pse.execute(pseInput, inputParcel, inputData, outputStream);
|
PgpSignEncryptResult pgpResult = pse.execute(pseInput, inputParcel, inputData, outputStream);
|
||||||
|
|
||||||
if (pgpResult.isPending()) {
|
if (pgpResult.isPending()) {
|
||||||
@@ -414,9 +425,9 @@ public class OpenPgpService extends RemoteService {
|
|||||||
if (TextUtils.isEmpty(accName)) {
|
if (TextUtils.isEmpty(accName)) {
|
||||||
accName = "default";
|
accName = "default";
|
||||||
}
|
}
|
||||||
final AccountSettings accSettings = getAccSettings(accName);
|
final AccountSettings accSettings = mApiPermissionHelper.getAccSettings(accName);
|
||||||
if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) {
|
if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) {
|
||||||
return getCreateAccountIntent(data, accName);
|
return mApiPermissionHelper.getCreateAccountIntent(data, accName);
|
||||||
}
|
}
|
||||||
pseInput.setAdditionalEncryptId(accSettings.getKeyId());
|
pseInput.setAdditionalEncryptId(accSettings.getKeyId());
|
||||||
}
|
}
|
||||||
@@ -431,7 +442,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE));
|
new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE));
|
||||||
}
|
}
|
||||||
|
|
||||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(this, new ProviderHelper(getContext()), null);
|
PgpSignEncryptOperation op = new PgpSignEncryptOperation(this, mProviderHelper, null);
|
||||||
|
|
||||||
// execute PGP operation!
|
// execute PGP operation!
|
||||||
PgpSignEncryptResult pgpResult = op.execute(pseInput, inputParcel, inputData, outputStream);
|
PgpSignEncryptResult pgpResult = op.execute(pseInput, inputParcel, inputData, outputStream);
|
||||||
@@ -472,7 +483,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
outputStream = null;
|
outputStream = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String currentPkg = getCurrentCallingPackage();
|
String currentPkg = mApiPermissionHelper.getCurrentCallingPackage();
|
||||||
HashSet<Long> allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp(
|
HashSet<Long> allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp(
|
||||||
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
|
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
|
||||||
|
|
||||||
@@ -695,7 +706,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
String preferredUserId = data.getStringExtra(OpenPgpApi.EXTRA_USER_ID);
|
String preferredUserId = data.getStringExtra(OpenPgpApi.EXTRA_USER_ID);
|
||||||
|
|
||||||
Intent intent = new Intent(getBaseContext(), SelectSignKeyIdActivity.class);
|
Intent intent = new Intent(getBaseContext(), SelectSignKeyIdActivity.class);
|
||||||
String currentPkg = getCurrentCallingPackage();
|
String currentPkg = mApiPermissionHelper.getCurrentCallingPackage();
|
||||||
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(currentPkg));
|
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(currentPkg));
|
||||||
intent.putExtra(SelectSignKeyIdActivity.EXTRA_USER_ID, preferredUserId);
|
intent.putExtra(SelectSignKeyIdActivity.EXTRA_USER_ID, preferredUserId);
|
||||||
intent.putExtra(SelectSignKeyIdActivity.EXTRA_DATA, data);
|
intent.putExtra(SelectSignKeyIdActivity.EXTRA_DATA, data);
|
||||||
@@ -740,9 +751,9 @@ public class OpenPgpService extends RemoteService {
|
|||||||
}
|
}
|
||||||
Log.d(Constants.TAG, "accName: " + accName);
|
Log.d(Constants.TAG, "accName: " + accName);
|
||||||
// fallback to old API
|
// fallback to old API
|
||||||
final AccountSettings accSettings = getAccSettings(accName);
|
final AccountSettings accSettings = mApiPermissionHelper.getAccSettings(accName);
|
||||||
if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) {
|
if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) {
|
||||||
return getCreateAccountIntent(data, accName);
|
return mApiPermissionHelper.getCreateAccountIntent(data, accName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: just wrapping the key id
|
// NOTE: just wrapping the key id
|
||||||
@@ -792,7 +803,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if caller is allowed to access OpenKeychain
|
// check if caller is allowed to access OpenKeychain
|
||||||
Intent result = isAllowed(data);
|
Intent result = mApiPermissionHelper.isAllowed(data);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user