passcache: add support for clear on screen lock (ttl == 0)
This commit is contained in:
@@ -27,6 +27,8 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Binder;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
@@ -93,7 +95,7 @@ public class PassphraseCacheService extends Service {
|
||||
public static final String EXTRA_MESSENGER = "messenger";
|
||||
public static final String EXTRA_USER_ID = "user_id";
|
||||
|
||||
private static final int DEFAULT_TTL = 15;
|
||||
private static final int DEFAULT_TTL = 0;
|
||||
|
||||
private static final int MSG_PASSPHRASE_CACHE_GET_OKAY = 1;
|
||||
private static final int MSG_PASSPHRASE_CACHE_GET_KEY_NOT_FOUND = 2;
|
||||
@@ -237,7 +239,7 @@ public class PassphraseCacheService extends Service {
|
||||
if (cachedPassphrase == null) {
|
||||
return null;
|
||||
}
|
||||
return cachedPassphrase.getPassphrase();
|
||||
return cachedPassphrase.mPassphrase;
|
||||
}
|
||||
|
||||
// try to get master key id which is used as an identifier for cached passphrases
|
||||
@@ -284,7 +286,7 @@ public class PassphraseCacheService extends Service {
|
||||
|
||||
}
|
||||
|
||||
return cachedPassphrase.getPassphrase();
|
||||
return cachedPassphrase.mPassphrase;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,13 +305,18 @@ public class PassphraseCacheService extends Service {
|
||||
|
||||
if (action.equals(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE)) {
|
||||
long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
|
||||
timeout(keyId);
|
||||
removeTimeoutedPassphrase(keyId);
|
||||
}
|
||||
|
||||
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
removeScreenLockPassphrases();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE);
|
||||
filter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
registerReceiver(mIntentReceiver, filter);
|
||||
}
|
||||
}
|
||||
@@ -337,35 +344,39 @@ public class PassphraseCacheService extends Service {
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
// register broadcastreceiver
|
||||
registerReceiver();
|
||||
|
||||
String action = intent.getAction();
|
||||
switch (action) {
|
||||
case ACTION_PASSPHRASE_CACHE_ADD: {
|
||||
long ttl = intent.getIntExtra(EXTRA_TTL, DEFAULT_TTL);
|
||||
long masterKeyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
|
||||
long subKeyId = intent.getLongExtra(EXTRA_SUBKEY_ID, -1);
|
||||
long timeoutTime = intent.getIntExtra(EXTRA_TTL, DEFAULT_TTL);
|
||||
|
||||
Passphrase passphrase = intent.getParcelableExtra(EXTRA_PASSPHRASE);
|
||||
String primaryUserID = intent.getStringExtra(EXTRA_USER_ID);
|
||||
|
||||
Log.d(Constants.TAG,
|
||||
"PassphraseCacheService: Received ACTION_PASSPHRASE_CACHE_ADD intent in onStartCommand() with masterkeyId: "
|
||||
+ masterKeyId + ", subKeyId: " + subKeyId + ", ttl: " + ttl + ", usrId: " + primaryUserID
|
||||
+ masterKeyId + ", subKeyId: " + subKeyId + ", ttl: " + timeoutTime + ", usrId: " + primaryUserID
|
||||
);
|
||||
|
||||
// if we don't cache by specific subkey id, or the requested subkey is the master key,
|
||||
// just add master key id to the cache, otherwise, add this specific subkey to the cache
|
||||
long referenceKeyId =
|
||||
Preferences.getPreferences(mContext).getPassphraseCacheSubs() ? subKeyId : masterKeyId;
|
||||
mPassphraseCache.put(referenceKeyId, new CachedPassphrase(passphrase, primaryUserID));
|
||||
if (ttl > 0) {
|
||||
|
||||
CachedPassphrase cachedPassphrase;
|
||||
if (timeoutTime == 0) {
|
||||
cachedPassphrase = CachedPassphrase.getPassphraseLock(passphrase, primaryUserID);
|
||||
} else {
|
||||
cachedPassphrase = CachedPassphrase.getPassphraseTtlTimeout(passphrase, primaryUserID, timeoutTime);
|
||||
|
||||
// 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, referenceKeyId));
|
||||
am.set(AlarmManager.RTC_WAKEUP, timeoutTime, buildIntent(this, referenceKeyId));
|
||||
}
|
||||
|
||||
mPassphraseCache.put(referenceKeyId, cachedPassphrase);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_PASSPHRASE_CACHE_GET: {
|
||||
@@ -435,16 +446,14 @@ public class PassphraseCacheService extends Service {
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when one specific passphrase for keyId timed out
|
||||
*/
|
||||
private void timeout(long keyId) {
|
||||
/** Called when one specific passphrase for keyId timed out. */
|
||||
private void removeTimeoutedPassphrase(long keyId) {
|
||||
|
||||
CachedPassphrase cPass = mPassphraseCache.get(keyId);
|
||||
if (cPass != null) {
|
||||
if (cPass.getPassphrase() != null) {
|
||||
if (cPass.mPassphrase != null) {
|
||||
// clean internal char[] from memory!
|
||||
cPass.getPassphrase().removeFromMemory();
|
||||
cPass.mPassphrase.removeFromMemory();
|
||||
}
|
||||
// remove passphrase object
|
||||
mPassphraseCache.remove(keyId);
|
||||
@@ -455,6 +464,24 @@ public class PassphraseCacheService extends Service {
|
||||
updateService();
|
||||
}
|
||||
|
||||
private void removeScreenLockPassphrases() {
|
||||
|
||||
for (int i = 0; i < mPassphraseCache.size(); ) {
|
||||
CachedPassphrase cPass = mPassphraseCache.valueAt(i);
|
||||
if (cPass.mTimeoutMode == TimeoutMode.LOCK) {
|
||||
// remove passphrase object
|
||||
mPassphraseCache.removeAt(i);
|
||||
continue;
|
||||
}
|
||||
// only do this if we didn't remove at, which continues loop by reducing size!
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Log.d(Constants.TAG, "PassphraseCacheService Removing all cached-until-lock passphrases from memory!");
|
||||
|
||||
updateService();
|
||||
}
|
||||
|
||||
private void updateService() {
|
||||
if (mPassphraseCache.size() > 0) {
|
||||
startForeground(Constants.Notification.PASSPHRASE_CACHE, getNotification());
|
||||
@@ -479,7 +506,7 @@ public class PassphraseCacheService extends Service {
|
||||
|
||||
// Moves events into the big view
|
||||
for (int i = 0; i < mPassphraseCache.size(); i++) {
|
||||
inboxStyle.addLine(mPassphraseCache.valueAt(i).getPrimaryUserID());
|
||||
inboxStyle.addLine(mPassphraseCache.valueAt(i).mPrimaryUserId);
|
||||
}
|
||||
|
||||
// Moves the big view style object into the notification object.
|
||||
@@ -512,6 +539,8 @@ public class PassphraseCacheService extends Service {
|
||||
super.onCreate();
|
||||
mContext = this;
|
||||
Log.d(Constants.TAG, "PassphraseCacheService, onCreate()");
|
||||
|
||||
registerReceiver();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -535,29 +564,34 @@ public class PassphraseCacheService extends Service {
|
||||
|
||||
private final IBinder mBinder = new PassphraseCacheBinder();
|
||||
|
||||
public class CachedPassphrase {
|
||||
private String primaryUserID;
|
||||
private Passphrase passphrase;
|
||||
private enum TimeoutMode {
|
||||
NEVER, TTL, LOCK
|
||||
}
|
||||
|
||||
public CachedPassphrase(Passphrase passphrase, String primaryUserID) {
|
||||
setPassphrase(passphrase);
|
||||
setPrimaryUserID(primaryUserID);
|
||||
private static class CachedPassphrase {
|
||||
private String mPrimaryUserId;
|
||||
private Passphrase mPassphrase;
|
||||
private TimeoutMode mTimeoutMode;
|
||||
private Long mTimeoutTime;
|
||||
|
||||
private CachedPassphrase(Passphrase passphrase, String primaryUserId, TimeoutMode timeoutMode, Long timeoutTime) {
|
||||
mPassphrase = passphrase;
|
||||
mPrimaryUserId = primaryUserId;
|
||||
mTimeoutMode = timeoutMode;
|
||||
mTimeoutTime = timeoutTime;
|
||||
}
|
||||
|
||||
public String getPrimaryUserID() {
|
||||
return primaryUserID;
|
||||
static CachedPassphrase getPassphraseNoTimeout(Passphrase passphrase, String primaryUserId) {
|
||||
return new CachedPassphrase(passphrase, primaryUserId, TimeoutMode.NEVER, null);
|
||||
}
|
||||
|
||||
public Passphrase getPassphrase() {
|
||||
return passphrase;
|
||||
static CachedPassphrase getPassphraseTtlTimeout(Passphrase passphrase, String primaryUserId, long timeoutTime) {
|
||||
return new CachedPassphrase(passphrase, primaryUserId, TimeoutMode.TTL, timeoutTime);
|
||||
}
|
||||
|
||||
public void setPrimaryUserID(String primaryUserID) {
|
||||
this.primaryUserID = primaryUserID;
|
||||
}
|
||||
|
||||
public void setPassphrase(Passphrase passphrase) {
|
||||
this.passphrase = passphrase;
|
||||
static CachedPassphrase getPassphraseLock(Passphrase passphrase, String primaryUserId) {
|
||||
return new CachedPassphrase(passphrase, primaryUserId, TimeoutMode.LOCK, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user