diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 8443f3a..47ad38f 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -4,7 +4,7 @@ me.hatter card-cryptomator card-cryptomator - 1.0.0 + 1.0.1 Plug-in for Cryptomator to store vault passwords with card-cli encryption. https://git.hatter.ink/hatter/card-cryptomator diff --git a/justfile b/justfile new file mode 100644 index 0000000..94ee942 --- /dev/null +++ b/justfile @@ -0,0 +1,7 @@ +_: + @just --list + +# build pacakge +build: + buildj package + diff --git a/pom.xml b/pom.xml index 6260d78..d793600 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 me.hatter card-cryptomator - 1.0.0 + 1.0.1 card-cryptomator Plug-in for Cryptomator to store vault passwords with card-cli encryption. diff --git a/src/main/java/me/hatter/integrations/card/CardConfig.java b/src/main/java/me/hatter/integrations/card/CardConfig.java index c8e1e29..49691d0 100644 --- a/src/main/java/me/hatter/integrations/card/CardConfig.java +++ b/src/main/java/me/hatter/integrations/card/CardConfig.java @@ -11,6 +11,8 @@ public class CardConfig { */ private String encryptKeyBasePath; + private Long passwordCacheTimeMillis; + public String getEncryptKeyBasePath() { return encryptKeyBasePath; } @@ -18,4 +20,12 @@ public class CardConfig { public void setEncryptKeyBasePath(String encryptKeyBasePath) { this.encryptKeyBasePath = encryptKeyBasePath; } + + public Long getPasswordCacheTimeMillis() { + return passwordCacheTimeMillis; + } + + public void setPasswordCacheTimeMillis(Long passwordCacheTimeMillis) { + this.passwordCacheTimeMillis = passwordCacheTimeMillis; + } } diff --git a/src/main/java/me/hatter/integrations/card/Utils.java b/src/main/java/me/hatter/integrations/card/Utils.java index d27a5dd..dc1d478 100644 --- a/src/main/java/me/hatter/integrations/card/Utils.java +++ b/src/main/java/me/hatter/integrations/card/Utils.java @@ -14,6 +14,7 @@ import java.util.Base64; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; /** @@ -27,7 +28,36 @@ public class Utils { private static final File CARD_CONFIG_FILE2 = new File(USER_HOME, ".config/cryptomator/card_config.json"); private static final File DEFAULT_ENCRYPTION_KEY_BASE_PATH = new File(USER_HOME, ".config/cryptomator/card_keys/"); - private static final ConcurrentMap PASSWORD_CACHE_MAP = new ConcurrentHashMap<>(); + private static final ConcurrentMap PASSWORD_CACHE_MAP = new ConcurrentHashMap<>(); + + private static class CachedPasswordWithTime { + private String password; + private long timestamp; + } + + private static void putCachedPassword(CardConfig cardConfig, String key, String password) { + final CachedPasswordWithTime cachedPasswordWithTime = new CachedPasswordWithTime(); + cachedPasswordWithTime.password = password; + cachedPasswordWithTime.timestamp = System.currentTimeMillis(); + PASSWORD_CACHE_MAP.put(key, cachedPasswordWithTime); + } + + private static String getCachedPassword(CardConfig cardConfig, String key) { + final CachedPasswordWithTime cachedPasswordWithTime = PASSWORD_CACHE_MAP.get(key); + if (cachedPasswordWithTime == null) { + return null; + } + final long defaultPasswordCacheTimeMillis = TimeUnit.DAYS.toMillis(1); + final long passwordCacheTimeMillis = (cardConfig.getPasswordCacheTimeMillis() == null) + ? defaultPasswordCacheTimeMillis + : cardConfig.getPasswordCacheTimeMillis(); + if ((System.currentTimeMillis() - cachedPasswordWithTime.timestamp) > passwordCacheTimeMillis) { + PASSWORD_CACHE_MAP.remove(key); + return null; + } + cachedPasswordWithTime.timestamp = System.currentTimeMillis(); + return cachedPasswordWithTime.password; + } public static boolean isCheckPassphraseStored() { final StackTraceElement stack = getCallerStackTrace(); @@ -161,7 +191,7 @@ public class Utils { params.add("--auto-pbe"); params.add("--json"); - final String password = PASSWORD_CACHE_MAP.get(vault); + final String password = getCachedPassword(cardConfig, vault); if (password != null) { params.add("--password"); params.add(password); @@ -180,7 +210,7 @@ public class Utils { final String resultString = new String(decryptResult.getStdout(), StandardCharsets.UTF_8); final CardHmacDecryptResult result = new Gson().fromJson(resultString, CardHmacDecryptResult.class); if (result.getPassword() != null) { - PASSWORD_CACHE_MAP.put(vault, result.getPassword()); + putCachedPassword(cardConfig, vault, result.getPassword()); } return Base64.getDecoder().decode(result.getPlaintext()); } @@ -195,7 +225,7 @@ public class Utils { params.add("1000000"); params.add("--json"); - final String password = PASSWORD_CACHE_MAP.get(vault); + final String password = getCachedPassword(cardConfig, vault); if (password != null) { params.add("--password"); params.add(password);