diff --git a/pom.xml b/pom.xml
index ed08a3d18..6c016d277 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,8 @@
3.12.0
2.45
2.2
- 32.0.0-jre
+ 32.0.1-jre
+ 2.15.2
2.10.1
20.0.1
4.4.0
@@ -157,6 +158,11 @@
nimbus-jose-jwt
${nimbus-jose.version}
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
@@ -206,7 +212,7 @@
dagger
${dagger.version}
-
+
com.google.code.gson
gson
${gson.version}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 54938a0f0..2213ff0d9 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -5,6 +5,7 @@ import org.cryptomator.common.locationpresets.DropboxWindowsLocationPresetsProvi
import org.cryptomator.common.locationpresets.GoogleDriveLocationPresetsProvider;
import org.cryptomator.common.locationpresets.ICloudMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.ICloudWindowsLocationPresetsProvider;
+import org.cryptomator.common.locationpresets.LeitzcloudLocationPresetsProvider;
import org.cryptomator.common.locationpresets.LocationPresetsProvider;
import org.cryptomator.common.locationpresets.MegaLocationPresetsProvider;
import org.cryptomator.common.locationpresets.OneDriveLinuxLocationPresetsProvider;
@@ -37,7 +38,8 @@ open module org.cryptomator.desktop {
requires ch.qos.logback.core;
requires com.auth0.jwt;
requires com.google.common;
- requires com.google.gson;
+ requires com.fasterxml.jackson.databind;
+ requires com.google.gson; // TODO replace with jackson?
requires com.nimbusds.jose.jwt;
requires com.nulabinc.zxcvbn;
requires com.tobiasdiez.easybind;
@@ -53,11 +55,12 @@ open module org.cryptomator.desktop {
provides TrayMenuController with AwtTrayMenuController;
provides Configurator with LogbackConfiguratorFactory;
- provides LocationPresetsProvider with DropboxMacLocationPresetsProvider, //
- DropboxWindowsLocationPresetsProvider, DropboxLinuxLocationPresetsProvider, //
- ICloudMacLocationPresetsProvider, ICloudWindowsLocationPresetsProvider, //
+ provides LocationPresetsProvider with //
+ DropboxWindowsLocationPresetsProvider, DropboxMacLocationPresetsProvider, DropboxLinuxLocationPresetsProvider, //
GoogleDriveLocationPresetsProvider, //
- PCloudLocationPresetsProvider, MegaLocationPresetsProvider, //
- OneDriveLinuxLocationPresetsProvider, OneDriveWindowsLocationPresetsProvider, //
- OneDriveMacLocationPresetsProvider;
+ ICloudWindowsLocationPresetsProvider, ICloudMacLocationPresetsProvider, //
+ LeitzcloudLocationPresetsProvider, //
+ MegaLocationPresetsProvider, //
+ OneDriveWindowsLocationPresetsProvider, OneDriveMacLocationPresetsProvider, OneDriveLinuxLocationPresetsProvider, //
+ PCloudLocationPresetsProvider;
}
\ No newline at end of file
diff --git a/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveLocationPresetsProvider.java b/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveLocationPresetsProvider.java
index f54afe9af..970bea042 100644
--- a/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveLocationPresetsProvider.java
+++ b/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveLocationPresetsProvider.java
@@ -5,6 +5,8 @@ import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
@@ -15,23 +17,25 @@ import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@CheckAvailability
public final class GoogleDriveLocationPresetsProvider implements LocationPresetsProvider {
- private static final Path LOCATION1 = LocationPresetsProvider.resolveLocation("~/GoogleDrive");
- private static final Path LOCATION2 = LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive");
-
+ private static final List LOCATIONS = Arrays.asList( //
+ LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive"), //
+ LocationPresetsProvider.resolveLocation("~/Google Drive/My Drive"), //
+ LocationPresetsProvider.resolveLocation("~/GoogleDrive"), //
+ LocationPresetsProvider.resolveLocation("~/Google Drive") //
+ );
@CheckAvailability
public static boolean isPresent() {
- return Files.isDirectory(LOCATION1) || Files.isDirectory(LOCATION2);
+ return LOCATIONS.stream().anyMatch(Files::isDirectory);
}
@Override
public Stream getLocations() {
- if(Files.isDirectory(LOCATION1)) {
- return Stream.of(new LocationPreset("Google Drive", LOCATION1));
- } else if(Files.isDirectory(LOCATION2)) {
- return Stream.of(new LocationPreset("Google Drive", LOCATION2));
- } else {
- return Stream.of();
- }
+ return LOCATIONS.stream() //
+ .filter(Files::isDirectory) //
+ .map(location -> new LocationPreset("Google Drive", location)) //
+ .findFirst() //
+ .stream();
}
+
}
diff --git a/src/main/java/org/cryptomator/common/locationpresets/LeitzcloudLocationPresetsProvider.java b/src/main/java/org/cryptomator/common/locationpresets/LeitzcloudLocationPresetsProvider.java
new file mode 100644
index 000000000..2fb459121
--- /dev/null
+++ b/src/main/java/org/cryptomator/common/locationpresets/LeitzcloudLocationPresetsProvider.java
@@ -0,0 +1,30 @@
+package org.cryptomator.common.locationpresets;
+
+import org.cryptomator.integrations.common.CheckAvailability;
+import org.cryptomator.integrations.common.OperatingSystem;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.stream.Stream;
+
+import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
+import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
+
+@OperatingSystem(WINDOWS)
+@OperatingSystem(MAC)
+@CheckAvailability
+public final class LeitzcloudLocationPresetsProvider implements LocationPresetsProvider {
+
+ private static final Path LOCATION = LocationPresetsProvider.resolveLocation("~/leitzcloud");
+
+ @CheckAvailability
+ public static boolean isPresent() {
+ return Files.isDirectory(LOCATION);
+ }
+
+ @Override
+ public Stream getLocations() {
+ return Stream.of(new LocationPreset("leitzcloud", LOCATION));
+ }
+
+}
diff --git a/src/main/java/org/cryptomator/common/locationpresets/PCloudLocationPresetsProvider.java b/src/main/java/org/cryptomator/common/locationpresets/PCloudLocationPresetsProvider.java
index 05e2867ce..86b5ee5b3 100644
--- a/src/main/java/org/cryptomator/common/locationpresets/PCloudLocationPresetsProvider.java
+++ b/src/main/java/org/cryptomator/common/locationpresets/PCloudLocationPresetsProvider.java
@@ -5,6 +5,8 @@ import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
@@ -15,16 +17,23 @@ import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@CheckAvailability
public final class PCloudLocationPresetsProvider implements LocationPresetsProvider {
-
- private static final Path LOCATION = LocationPresetsProvider.resolveLocation("~/pCloudDrive");
+ private static final List LOCATIONS = Arrays.asList( //
+ LocationPresetsProvider.resolveLocation("~/pCloudDrive"), //
+ LocationPresetsProvider.resolveLocation("~/pCloud Drive") //
+ );
@CheckAvailability
public static boolean isPresent() {
- return Files.isDirectory(LOCATION);
+ return LOCATIONS.stream().anyMatch(Files::isDirectory);
}
@Override
public Stream getLocations() {
- return Stream.of(new LocationPreset("pCloud", LOCATION));
+ return LOCATIONS.stream() //
+ .filter(Files::isDirectory) //
+ .map(location -> new LocationPreset("pCloud", location)) //
+ .findFirst() //
+ .stream();
}
+
}
diff --git a/src/main/java/org/cryptomator/common/mount/MountPointInUseException.java b/src/main/java/org/cryptomator/common/mount/MountPointInUseException.java
new file mode 100644
index 000000000..9f7f11174
--- /dev/null
+++ b/src/main/java/org/cryptomator/common/mount/MountPointInUseException.java
@@ -0,0 +1,8 @@
+package org.cryptomator.common.mount;
+
+public class MountPointInUseException extends IllegalMountPointException {
+
+ public MountPointInUseException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/main/java/org/cryptomator/common/mount/Mounter.java b/src/main/java/org/cryptomator/common/mount/Mounter.java
index 0161268f3..a56f2b01b 100644
--- a/src/main/java/org/cryptomator/common/mount/Mounter.java
+++ b/src/main/java/org/cryptomator/common/mount/Mounter.java
@@ -97,7 +97,11 @@ public class Mounter {
}
} else {
var mpIsDriveLetter = userChosenMountPoint.toString().matches("[A-Z]:\\\\");
- if (!mpIsDriveLetter && canMountToParent && !canMountToDir) {
+ if (mpIsDriveLetter) {
+ if (driveLetters.getOccupied().contains(userChosenMountPoint)) {
+ throw new MountPointInUseException(userChosenMountPoint.toString());
+ }
+ } else if (canMountToParent && !canMountToDir) {
MountWithinParentUtil.prepareParentNoMountPoint(userChosenMountPoint);
cleanup = () -> {
MountWithinParentUtil.cleanup(userChosenMountPoint);
diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java b/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java
index 7c2bc8be7..5f462b170 100644
--- a/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java
+++ b/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java
@@ -1,6 +1,9 @@
package org.cryptomator.ui.keyloading.hub;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
// needs to be accessible by JSON decoder
+@JsonIgnoreProperties(ignoreUnknown = true)
public class HubConfig {
public String clientId;
diff --git a/src/main/java/org/cryptomator/ui/unlock/UnlockInvalidMountPointController.java b/src/main/java/org/cryptomator/ui/unlock/UnlockInvalidMountPointController.java
index 7bc0cbccd..b07e3ffde 100644
--- a/src/main/java/org/cryptomator/ui/unlock/UnlockInvalidMountPointController.java
+++ b/src/main/java/org/cryptomator/ui/unlock/UnlockInvalidMountPointController.java
@@ -1,5 +1,6 @@
package org.cryptomator.ui.unlock;
+import org.cryptomator.common.mount.MountPointInUseException;
import org.cryptomator.common.mount.MountPointNotExistsException;
import org.cryptomator.common.mount.MountPointNotSupportedException;
import org.cryptomator.common.vaults.Vault;
@@ -41,6 +42,7 @@ public class UnlockInvalidMountPointController implements FxController {
var translationKey = switch (e) {
case MountPointNotSupportedException x -> "unlock.error.customPath.description.notSupported";
case MountPointNotExistsException x -> "unlock.error.customPath.description.notExists";
+ case MountPointInUseException x -> "unlock.error.customPath.description.inUse";
default -> "unlock.error.customPath.description.generic";
};
dialogDescription.setFormat(resourceBundle.getString(translationKey));
diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties
index d38d542ee..ca051269a 100644
--- a/src/main/resources/i18n/strings.properties
+++ b/src/main/resources/i18n/strings.properties
@@ -130,6 +130,7 @@ unlock.success.revealBtn=Reveal Drive
unlock.error.customPath.message=Unable to mount vault to custom path
unlock.error.customPath.description.notSupported=If you wish to keep using the custom path, please go to the preferences and select a volume type that supports it. Otherwise, go to the vault options and choose a supported mount point.
unlock.error.customPath.description.notExists=The custom mount path does not exist. Either create it in your local filesystem or change it in the vault options.
+unlock.error.customPath.description.inUse=Drive letter "%s" is already in use.
unlock.error.customPath.description.generic=You have selected a custom mount path for this vault, but using it failed with the message: %s
## Hub
hub.noKeychain.message=Unable to access device key
diff --git a/src/test/java/org/cryptomator/ui/keyloading/hub/HubConfigTest.java b/src/test/java/org/cryptomator/ui/keyloading/hub/HubConfigTest.java
new file mode 100644
index 000000000..bb39516a0
--- /dev/null
+++ b/src/test/java/org/cryptomator/ui/keyloading/hub/HubConfigTest.java
@@ -0,0 +1,19 @@
+package org.cryptomator.ui.keyloading.hub;
+
+import com.auth0.jwt.JWT;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+public class HubConfigTest {
+
+ @Test
+ @DisplayName("can parse JWT with unknown fields in header claim \"hub\"")
+ public void testParseJWTWithUnknownFields() {
+ var jwt = JWT.decode("eyJraWQiOiIxMjMiLCJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiIsImh1YiI6eyJ1bmtub3duRmllbGQiOjQyLCJjbGllbnRJZCI6ImNyeXB0b21hdG9yIn19.eyJqdGkiOiI0NTYifQ.e1CStFf5fdh9ofX_6O8_LfbHfHEJZqUpuYNWz9xZp0I");
+ var claim = jwt.getHeaderClaim("hub");
+ var hubConfig = Assertions.assertDoesNotThrow(() -> claim.as(HubConfig.class));
+ Assertions.assertEquals("cryptomator", hubConfig.clientId);
+ }
+
+}
\ No newline at end of file
diff --git a/suppression.xml b/suppression.xml
index e7cc4ea65..36b795480 100644
--- a/suppression.xml
+++ b/suppression.xml
@@ -55,4 +55,12 @@
CVE-2022-45688
-
\ No newline at end of file
+
+
+ ^pkg:maven/com\.fasterxml\.jackson\.core/jackson\-databind@.*$
+ CVE-2023-35116
+
+
+