mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-08-17 04:36:02 +00:00
validate hub config and check allowed hosts file
This commit is contained in:
@@ -21,6 +21,7 @@ import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.Window;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -36,16 +37,18 @@ public class HubKeyLoadingStrategy implements KeyLoadingStrategy, FilesystemOwne
|
||||
private final Stage window;
|
||||
private final KeychainManager keychainManager;
|
||||
private final AtomicReference<String> fsOwnerId;
|
||||
private final HubConfig hubConfig;
|
||||
private final Lazy<Scene> authFlowScene;
|
||||
private final Lazy<Scene> noKeychainScene;
|
||||
private final CompletableFuture<ReceivedKey> result;
|
||||
private final DeviceKey deviceKey;
|
||||
|
||||
@Inject
|
||||
public HubKeyLoadingStrategy(@KeyLoading Stage window, @FxmlScene(FxmlFile.HUB_AUTH_FLOW) Lazy<Scene> authFlowScene, @FxmlScene(FxmlFile.HUB_NO_KEYCHAIN) Lazy<Scene> noKeychainScene, CompletableFuture<ReceivedKey> result, DeviceKey deviceKey, KeychainManager keychainManager, @Named("windowTitle") String windowTitle, @Named("filesystemOwnerId") AtomicReference<String> fsOwnerId) {
|
||||
public HubKeyLoadingStrategy(@KeyLoading Stage window, @FxmlScene(FxmlFile.HUB_AUTH_FLOW) Lazy<Scene> authFlowScene, @FxmlScene(FxmlFile.HUB_NO_KEYCHAIN) Lazy<Scene> noKeychainScene, CompletableFuture<ReceivedKey> result, DeviceKey deviceKey, KeychainManager keychainManager, @Named("windowTitle") String windowTitle, @Named("filesystemOwnerId") AtomicReference<String> fsOwnerId, HubConfig hubConfig) {
|
||||
this.window = window;
|
||||
this.keychainManager = keychainManager;
|
||||
this.fsOwnerId = fsOwnerId;
|
||||
this.hubConfig = hubConfig;
|
||||
window.setTitle(windowTitle);
|
||||
window.setOnCloseRequest(_ -> result.cancel(true));
|
||||
this.authFlowScene = authFlowScene;
|
||||
@@ -62,9 +65,20 @@ public class HubKeyLoadingStrategy implements KeyLoadingStrategy, FilesystemOwne
|
||||
throw new NoKeychainAccessProviderException();
|
||||
}
|
||||
var keypair = deviceKey.get();
|
||||
showWindow(authFlowScene);
|
||||
var jwe = result.get();
|
||||
return jwe.decryptMasterkey(keypair.getPrivate());
|
||||
|
||||
//check hub config
|
||||
isConsistentHubConfig();
|
||||
if (configContainsAllowedHosts()) {
|
||||
showWindow(authFlowScene);
|
||||
var jwe = result.get();
|
||||
return jwe.decryptMasterkey(keypair.getPrivate());
|
||||
} else {
|
||||
//TODO: sanitze this shit
|
||||
var showUnknownHubHostDialog = Boolean.getBoolean(System.getProperty("cryptomator.allowUnknownHubHosts", "false"));
|
||||
//TODO show window
|
||||
throw new MasterkeyLoadingFailedException("Unknown hub host in vault config");
|
||||
}
|
||||
|
||||
} catch (NoKeychainAccessProviderException e) {
|
||||
showWindow(noKeychainScene);
|
||||
throw new UnlockCancelledException("Unlock canceled due to missing prerequisites", e);
|
||||
@@ -80,6 +94,49 @@ public class HubKeyLoadingStrategy implements KeyLoadingStrategy, FilesystemOwne
|
||||
}
|
||||
}
|
||||
|
||||
private void isConsistentHubConfig() {
|
||||
//hub endpoints are consistent
|
||||
//apiBaseURL.host == deviceUrl.host == authSuccessUrl.host == authErrorUrl.host
|
||||
var expectedHubHubHost = URI.create(hubConfig.authSuccessUrl).getHost(); //apiBaseURL could be null! hence, the authSuccessUrl
|
||||
if (hubConfig.apiBaseUrl != null && hasDifferentHost(hubConfig.apiBaseUrl, expectedHubHubHost)) {
|
||||
//throw
|
||||
}
|
||||
if (hasDifferentHost(hubConfig.devicesResourceUrl, expectedHubHubHost)) {
|
||||
//throw
|
||||
}
|
||||
if (hasDifferentHost(hubConfig.authErrorUrl, expectedHubHubHost)) {
|
||||
//throw
|
||||
}
|
||||
|
||||
//auth endpoints are consistent
|
||||
//authUrl.host == tokenUrl.host
|
||||
var expectedHubAuthHost = URI.create(hubConfig.authEndpoint).getHost();
|
||||
if (hasDifferentHost(hubConfig.tokenEndpoint, expectedHubAuthHost)) {
|
||||
//throw
|
||||
}
|
||||
}
|
||||
|
||||
private boolean configContainsAllowedHosts() {
|
||||
var allowedHubHostsString = System.getProperty("cryptomator.allowedHubHosts", "");
|
||||
//https://example.com,https://foo.bar
|
||||
var allowedHubHosts = Arrays.stream(allowedHubHostsString.split(",")).map(String::trim).toList();
|
||||
|
||||
var expectedHubHubHost = URI.create(hubConfig.authSuccessUrl).getHost(); //apiBaseURL could be null! hence, the authSuccessUrl
|
||||
var expectedHubAuthHost = URI.create(hubConfig.authEndpoint).getHost();
|
||||
//are the hosts also allowed?
|
||||
var isHubHubHostAllowed = allowedHubHosts.stream().anyMatch(host -> host.contains(expectedHubHubHost));
|
||||
var isHubAuthHostAllowed = allowedHubHosts.stream().anyMatch(host -> host.contains(expectedHubAuthHost));
|
||||
return isHubAuthHostAllowed && isHubHubHostAllowed;
|
||||
}
|
||||
|
||||
private boolean hasDifferentHost(String uri, String host) {
|
||||
try {
|
||||
return !URI.create(uri).getHost().equals(host);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void showWindow(Lazy<Scene> scene) {
|
||||
Platform.runLater(() -> {
|
||||
window.setScene(scene.get());
|
||||
|
||||
Reference in New Issue
Block a user