check if caller is allowed

This commit is contained in:
Dominik Schürmann 2014-02-17 18:37:01 +01:00
parent 154849b591
commit 37f280afbb
2 changed files with 74 additions and 63 deletions

View File

@ -432,8 +432,8 @@ public class OpenPgpService extends RemoteService {
* @param params * @param params
* @return * @return
*/ */
private Bundle checkRequirements(Bundle params) {
private Bundle validateParamsAndVersion(Bundle params) { // params Bundle is required!
if (params == null) { if (params == null) {
Bundle result = new Bundle(); Bundle result = new Bundle();
OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!"); OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!");
@ -442,8 +442,8 @@ public class OpenPgpService extends RemoteService {
return result; return result;
} }
// version code is required and needs to correspond to version code of service!
if (params.getInt(OpenPgpConstants.PARAMS_API_VERSION) != OpenPgpConstants.API_VERSION) { if (params.getInt(OpenPgpConstants.PARAMS_API_VERSION) != OpenPgpConstants.API_VERSION) {
// not compatible!
Bundle result = new Bundle(); Bundle result = new Bundle();
OpenPgpError error = new OpenPgpError(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!"); OpenPgpError error = new OpenPgpError(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!");
result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error); result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error);
@ -451,6 +451,12 @@ public class OpenPgpService extends RemoteService {
return result; return result;
} }
// check if caller is allowed to access openpgp keychain
Bundle result = isAllowed(params);
if (result != null) {
return result;
}
return null; return null;
} }
@ -461,7 +467,7 @@ public class OpenPgpService extends RemoteService {
public Bundle sign(Bundle params, final ParcelFileDescriptor input, final ParcelFileDescriptor output) { public Bundle sign(Bundle params, final ParcelFileDescriptor input, final ParcelFileDescriptor output) {
final AppSettings appSettings = getAppSettings(); final AppSettings appSettings = getAppSettings();
Bundle errorResult = validateParamsAndVersion(params); Bundle errorResult = checkRequirements(params);
if (errorResult != null) { if (errorResult != null) {
return errorResult; return errorResult;
} }
@ -473,7 +479,7 @@ public class OpenPgpService extends RemoteService {
public Bundle encrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) { public Bundle encrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
final AppSettings appSettings = getAppSettings(); final AppSettings appSettings = getAppSettings();
Bundle errorResult = validateParamsAndVersion(params); Bundle errorResult = checkRequirements(params);
if (errorResult != null) { if (errorResult != null) {
return errorResult; return errorResult;
} }
@ -485,7 +491,7 @@ public class OpenPgpService extends RemoteService {
public Bundle signAndEncrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) { public Bundle signAndEncrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
final AppSettings appSettings = getAppSettings(); final AppSettings appSettings = getAppSettings();
Bundle errorResult = validateParamsAndVersion(params); Bundle errorResult = checkRequirements(params);
if (errorResult != null) { if (errorResult != null) {
return errorResult; return errorResult;
} }
@ -497,7 +503,7 @@ public class OpenPgpService extends RemoteService {
public Bundle decryptAndVerify(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) { public Bundle decryptAndVerify(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
final AppSettings appSettings = getAppSettings(); final AppSettings appSettings = getAppSettings();
Bundle errorResult = validateParamsAndVersion(params); Bundle errorResult = checkRequirements(params);
if (errorResult != null) { if (errorResult != null) {
return errorResult; return errorResult;
} }
@ -507,7 +513,7 @@ public class OpenPgpService extends RemoteService {
@Override @Override
public Bundle getKeyIds(Bundle params) { public Bundle getKeyIds(Bundle params) {
Bundle errorResult = validateParamsAndVersion(params); Bundle errorResult = checkRequirements(params);
if (errorResult != null) { if (errorResult != null) {
return errorResult; return errorResult;
} }

View File

@ -22,6 +22,8 @@ import java.util.Arrays;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.util.OpenPgpConstants;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract;
@ -29,6 +31,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor; import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor;
import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -56,28 +59,9 @@ public abstract class RemoteService extends Service {
private final Object userInputLock = new Object(); private final Object userInputLock = new Object();
/** private static final int PRIVATE_REQUEST_CODE_REGISTER = 651;
* Override handleUserInput() to handle OKAY (1) and CANCEL (0). After handling the waiting private static final int PRIVATE_REQUEST_CODE_ERROR = 652;
* threads will be notified and the queue resumed
*/
protected class UserInputCallback extends BaseCallback {
public void handleUserInput(Message msg) {
}
@Override
public boolean handleMessage(Message msg) {
handleUserInput(msg);
// resume
synchronized (userInputLock) {
userInputLock.notifyAll();
}
mThreadPool.resume();
return true;
}
}
/** /**
* Extends Handler.Callback with OKAY (1), CANCEL (0) variables * Extends Handler.Callback with OKAY (1), CANCEL (0) variables
@ -97,18 +81,13 @@ public abstract class RemoteService extends Service {
return mContext; return mContext;
} }
/** protected Bundle isAllowed(Bundle params) {
* Should be used from Stub implementations of AIDL interfaces to enqueue a runnable for
* execution
*
* @param r
*/
protected void checkAndEnqueue(Runnable r) {
try { try {
if (isCallerAllowed(false)) { if (isCallerAllowed(false)) {
mThreadPool.execute(r); // mThreadPool.execute(r);
Log.d(Constants.TAG, "Enqueued runnable…"); return null;
// Log.d(Constants.TAG, "Enqueued runnable…");
} else { } else {
String[] callingPackages = getPackageManager().getPackagesForUid( String[] callingPackages = getPackageManager().getPackagesForUid(
Binder.getCallingUid()); Binder.getCallingUid());
@ -120,32 +99,59 @@ public abstract class RemoteService extends Service {
packageSignature = getPackageSignature(packageName); packageSignature = getPackageSignature(packageName);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
Log.e(Constants.TAG, "Should not happen, returning!", e); Log.e(Constants.TAG, "Should not happen, returning!", e);
return; // return error
Bundle result = new Bundle();
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
return result;
} }
Log.e(Constants.TAG, Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!");
"Not allowed to use service! Starting activity for registration!");
Bundle extras = new Bundle();
extras.putString(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
extras.putByteArray(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
RegisterActivityCallback callback = new RegisterActivityCallback();
pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_REGISTER, callback, Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
extras); intent.setAction(RemoteServiceActivity.ACTION_REGISTER);
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
if (callback.isAllowed()) { PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_REGISTER, intent, 0);
mThreadPool.execute(r);
Log.d(Constants.TAG, "Enqueued runnable…"); // return PendingIntent to be executed by client
} else { Bundle result = new Bundle();
Log.d(Constants.TAG, "User disallowed app!"); result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
} result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
// pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_REGISTER, callback,
// extras);
return result;
// if (callback.isAllowed()) {
// mThreadPool.execute(r);
// Log.d(Constants.TAG, "Enqueued runnable…");
// } else {
// Log.d(Constants.TAG, "User disallowed app!");
// }
} }
} catch (WrongPackageSignatureException e) { } catch (WrongPackageSignatureException e) {
Log.e(Constants.TAG, e.getMessage()); Log.e(Constants.TAG, "wrong signature!", e);
Bundle extras = new Bundle(); Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
getString(R.string.api_error_wrong_signature)); intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, getString(R.string.api_error_wrong_signature));
pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, extras); intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_ERROR, intent, 0);
// return PendingIntent to be executed by client
Bundle result = new Bundle();
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
return result;
// Bundle extras = new Bundle();
// extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
// getString(R.string.api_error_wrong_signature));
// pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, extras);
} }
} }
@ -268,8 +274,7 @@ public abstract class RemoteService extends Service {
* Checks if process that binds to this service (i.e. the package name corresponding to the * Checks if process that binds to this service (i.e. the package name corresponding to the
* process) is in the list of allowed package names. * process) is in the list of allowed package names.
* *
* @param allowOnlySelf * @param allowOnlySelf allow only Keychain app itself
* allow only Keychain app itself
* @return true if process is allowed to use this service * @return true if process is allowed to use this service
* @throws WrongPackageSignatureException * @throws WrongPackageSignatureException
*/ */