aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
diff options
context:
space:
mode:
Diffstat (limited to 'OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java')
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java169
1 files changed, 128 insertions, 41 deletions
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
index f29514e79..d11b8e92a 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,27 +39,39 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
import android.util.Log;
public class PassphraseCacheService extends Service {
public static final String TAG = Constants.TAG + ": PassphraseCacheService";
+ public static final String ACTION_PASSPHRASE_CACHE_ADD = Constants.INTENT_PREFIX
+ + "PASSPHRASE_CACHE_ADD";
+ public static final String ACTION_PASSPHRASE_CACHE_GET = Constants.INTENT_PREFIX
+ + "PASSPHRASE_CACHE_GET";
+
public static final String BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE = Constants.INTENT_PREFIX
- + "PASSPHRASE_CACHE_SERVICE";
+ + "PASSPHRASE_CACHE_BROADCAST";
public static final String EXTRA_TTL = "ttl";
public static final String EXTRA_KEY_ID = "keyId";
public static final String EXTRA_PASSPHRASE = "passphrase";
+ public static final String EXTRA_MESSENGER = "messenger";
private static final int REQUEST_ID = 0;
private static final long DEFAULT_TTL = 15;
private BroadcastReceiver mIntentReceiver;
- // This is static to be easily retrieved by getCachedPassphrase() without the need of callback
- // functions
- private static HashMap<Long, String> mPassphraseCache = new HashMap<Long, String>();
+ private HashMap<Long, String> mPassphraseCache = new HashMap<Long, String>();
+
+ Context mContext;
/**
* This caches a new passphrase by sending a new command to the service. An android service is
@@ -74,6 +86,7 @@ public class PassphraseCacheService extends Service {
Log.d(TAG, "cacheNewPassphrase() for " + keyId);
Intent intent = new Intent(context, PassphraseCacheService.class);
+ intent.setAction(ACTION_PASSPHRASE_CACHE_ADD);
intent.putExtra(EXTRA_TTL, Preferences.getPreferences(context).getPassPhraseCacheTtl());
intent.putExtra(EXTRA_PASSPHRASE, passphrase);
intent.putExtra(EXTRA_KEY_ID, keyId);
@@ -82,17 +95,65 @@ public class PassphraseCacheService extends Service {
}
/**
- * Gets a cached passphrase from memory
+ * Gets a cached passphrase from memory, blocking method
*
* @param context
* @param keyId
* @return
*/
public static String getCachedPassphrase(Context context, long keyId) {
+ Log.d(TAG, "getCachedPassphrase() get masterKeyId for " + keyId);
+ Intent intent = new Intent(context, PassphraseCacheService.class);
+ intent.setAction(ACTION_PASSPHRASE_CACHE_GET);
+
+ final Object mutex = new Object();
+ final Bundle returnBundle = new Bundle();
+
+ HandlerThread handlerThread = new HandlerThread("getPassphrase");
+ handlerThread.start();
+ Handler returnHandler = new Handler(handlerThread.getLooper()) {
+ @Override
+ public void handleMessage(Message message) {
+ if (message.obj != null) {
+ String passphrase = ((Bundle) message.obj).getString(EXTRA_PASSPHRASE);
+ returnBundle.putString(EXTRA_PASSPHRASE, passphrase);
+ }
+ synchronized (mutex) {
+ mutex.notify();
+ }
+ getLooper().quit();
+ }
+ };
+
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(returnHandler);
+ intent.putExtra(EXTRA_KEY_ID, keyId);
+ intent.putExtra(EXTRA_MESSENGER, messenger);
+ // send intent to this service
+ context.startService(intent);
+
+ // Wait on mutex until passphrase is returned to handlerThread
+ synchronized (mutex) {
+ try {
+ mutex.wait(3000);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ if (returnBundle.containsKey(EXTRA_PASSPHRASE)) {
+ return returnBundle.getString(EXTRA_PASSPHRASE);
+ } else {
+ return null;
+ }
+ }
+
+ private String getCachedPassphraseImpl(long keyId) {
+ Log.d(TAG, "getCachedPassphraseImpl() get masterKeyId for " + keyId);
+
// try to get master key id which is used as an identifier for cached passphrases
long masterKeyId = keyId;
if (masterKeyId != Id.key.symmetric) {
- PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, keyId);
+ PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(this, keyId);
if (keyRing == null) {
return null;
}
@@ -102,22 +163,24 @@ public class PassphraseCacheService extends Service {
}
masterKeyId = masterKey.getKeyID();
}
+ Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId" + masterKeyId);
// get cached passphrase
String cachedPassphrase = mPassphraseCache.get(masterKeyId);
if (cachedPassphrase == null) {
+ // TODO: fix!
// check if secret key has a passphrase
- if (!hasPassphrase(context, masterKeyId)) {
- // cache empty passphrase
- addCachedPassphrase(context, masterKeyId, "");
- return "";
- } else {
- return null;
- }
+ // if (!hasPassphrase(context, masterKeyId)) {
+ // // cache empty passphrase
+ // addCachedPassphrase(context, masterKeyId, "");
+ // return "";
+ // } else {
+ return null;
+ // }
}
// set it again to reset the cache life cycle
Log.d(TAG, "Cache passphrase again when getting it!");
- addCachedPassphrase(context, masterKeyId, cachedPassphrase);
+ addCachedPassphrase(this, masterKeyId, cachedPassphrase);
return cachedPassphrase;
}
@@ -196,11 +259,6 @@ public class PassphraseCacheService extends Service {
return sender;
}
- @Override
- public void onCreate() {
- Log.d(TAG, "onCreate()");
- }
-
/**
* Executed when service is started by intent
*/
@@ -211,20 +269,41 @@ public class PassphraseCacheService extends Service {
// register broadcastreceiver
registerReceiver();
- if (intent != null) {
- long ttl = intent.getLongExtra(EXTRA_TTL, DEFAULT_TTL);
- long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
- String passphrase = intent.getStringExtra(EXTRA_PASSPHRASE);
-
- Log.d(TAG, "Received intent in onStartCommand() with keyId: " + keyId + ", ttl: " + ttl);
-
- // add keyId and passphrase to memory
- mPassphraseCache.put(keyId, passphrase);
-
- // register new alarm with keyId for this passphrase
- long triggerTime = new Date().getTime() + (ttl * 1000);
- AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
- am.set(AlarmManager.RTC_WAKEUP, triggerTime, buildIntent(this, keyId));
+ if (intent != null && intent.getAction() != null) {
+ if (ACTION_PASSPHRASE_CACHE_ADD.equals(intent.getAction())) {
+ long ttl = intent.getLongExtra(EXTRA_TTL, DEFAULT_TTL);
+ long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
+ String passphrase = intent.getStringExtra(EXTRA_PASSPHRASE);
+
+ Log.d(TAG,
+ "Received ACTION_PASSPHRASE_CACHE_ADD intent in onStartCommand() with keyId: "
+ + keyId + ", ttl: " + ttl);
+
+ // add keyId and passphrase to memory
+ mPassphraseCache.put(keyId, passphrase);
+
+ // register new alarm with keyId for this passphrase
+ long triggerTime = new Date().getTime() + (ttl * 1000);
+ AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
+ am.set(AlarmManager.RTC_WAKEUP, triggerTime, buildIntent(this, keyId));
+ } else if (ACTION_PASSPHRASE_CACHE_GET.equals(intent.getAction())) {
+ long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
+ Messenger messenger = intent.getParcelableExtra(EXTRA_MESSENGER);
+
+ String passphrase = getCachedPassphraseImpl(keyId);
+
+ Message msg = Message.obtain();
+ Bundle bundle = new Bundle();
+ bundle.putString(EXTRA_PASSPHRASE, passphrase);
+ msg.obj = bundle;
+ try {
+ messenger.send(msg);
+ } catch (RemoteException e) {
+ Log.e(Constants.TAG, "Sending message failed", e);
+ }
+ } else {
+ Log.e(Constants.TAG, "Intent or Intent Action not supported!");
+ }
}
return START_STICKY;
@@ -240,7 +319,7 @@ public class PassphraseCacheService extends Service {
// remove passphrase corresponding to keyId from memory
mPassphraseCache.remove(keyId);
- Log.d(TAG, "Timeout of " + keyId + ", removed from memory!");
+ Log.d(TAG, "Timeout of keyId " + keyId + ", removed from memory!");
// stop whole service if no cached passphrases remaining
if (mPassphraseCache.isEmpty()) {
@@ -250,12 +329,25 @@ public class PassphraseCacheService extends Service {
}
@Override
+ public void onCreate() {
+ super.onCreate();
+ mContext = this;
+ Log.d(Constants.TAG, "PassphraseCacheService, onCreate()");
+ }
+
+ @Override
public void onDestroy() {
- Log.d(TAG, "onDestroy()");
+ super.onDestroy();
+ Log.d(Constants.TAG, "PassphraseCacheService, onDestroy()");
unregisterReceiver(mIntentReceiver);
}
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
public class PassphraseCacheBinder extends Binder {
public PassphraseCacheService getService() {
return PassphraseCacheService.this;
@@ -264,9 +356,4 @@ public class PassphraseCacheService extends Service {
private final IBinder mBinder = new PassphraseCacheBinder();
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
} \ No newline at end of file