From a0ef02b95c5e04ad347a61dac88a5756e41ebebe Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 3 May 2016 13:17:45 +0200 Subject: [PATCH] fixes #237 --- .../webdav/mount/WindowsWebDavMounter.java | 59 +++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java index 4136fd2bf..ee8fd5b96 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java @@ -11,10 +11,16 @@ package org.cryptomator.frontend.webdav.mount; import static org.cryptomator.frontend.webdav.mount.command.Script.fromLines; +import java.io.IOException; +import java.io.InterruptedIOException; import java.net.URI; import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashSet; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -22,12 +28,16 @@ import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Singleton; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.CharUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.SystemUtils; import org.cryptomator.frontend.CommandFailedException; import org.cryptomator.frontend.Frontend.MountParam; import org.cryptomator.frontend.webdav.mount.command.CommandResult; import org.cryptomator.frontend.webdav.mount.command.Script; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A {@link WebDavMounterStrategy} utilizing the "net use" command. @@ -37,7 +47,9 @@ import org.cryptomator.frontend.webdav.mount.command.Script; @Singleton final class WindowsWebDavMounter implements WebDavMounterStrategy { + private static final Logger LOG = LoggerFactory.getLogger(WindowsWebDavMounter.class); private static final Pattern WIN_MOUNT_DRIVELETTER_PATTERN = Pattern.compile("\\s*([A-Z]):\\s*"); + private static final Pattern REG_QUERY_PROXY_OVERRIDES_PATTERN = Pattern.compile("\\s*ProxyOverride\\s+REG_SZ\\s+(.*)\\s*"); private static final String AUTO_ASSIGN_DRIVE_LETTER = "*"; private static final String LOCALHOST = "localhost"; private static final int MOUNT_TIMEOUT_SECONDS = 60; @@ -76,10 +88,11 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy { } private CommandResult mount(URI uri, String driveLetter) throws CommandFailedException { - final Script proxyBypassScript = fromLines("reg add \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" /v \"ProxyOverride\" /d \";%DAV_HOST%;%DAV_HOST%:%DAV_PORT%\" /f"); - proxyBypassScript.addEnv("DAV_HOST", uri.getHost()); - proxyBypassScript.addEnv("DAV_PORT", String.valueOf(uri.getPort())); - proxyBypassScript.execute(); + try { + addProxyOverrides(uri); + } catch (IOException e) { + throw new CommandFailedException(e); + } final String driveLetterStr = AUTO_ASSIGN_DRIVE_LETTER.equals(driveLetter) ? AUTO_ASSIGN_DRIVE_LETTER : driveLetter + ":"; final Script mountScript = fromLines("net use %DRIVE_LETTER% \\\\%DAV_HOST%@%DAV_PORT%\\DavWWWRoot%DAV_UNC_PATH% /persistent:no"); @@ -89,6 +102,44 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy { mountScript.addEnv("DAV_UNC_PATH", uri.getRawPath().replace('/', '\\')); return mountScript.execute(MOUNT_TIMEOUT_SECONDS, TimeUnit.SECONDS); } + + private void addProxyOverrides(URI uri) throws IOException, CommandFailedException { + try { + // get existing value for ProxyOverride key from reqistry: + ProcessBuilder query = new ProcessBuilder("reg", "query", "\"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\"", "/v", "ProxyOverride"); + Process queryCmd = query.start(); + String queryStdOut = IOUtils.toString(queryCmd.getInputStream(), StandardCharsets.UTF_8); + int queryResult = queryCmd.waitFor(); + + // determine new value for ProxyOverride key: + Set overrides = new HashSet<>(); + Matcher matcher = REG_QUERY_PROXY_OVERRIDES_PATTERN.matcher(queryStdOut); + if (queryResult == 0 && matcher.find()) { + String[] existingOverrides = StringUtils.split(matcher.group(1), ';'); + overrides.addAll(Arrays.asList(existingOverrides)); + } + overrides.removeIf(s -> s.startsWith(uri.getHost() + ":")); + overrides.add(""); + overrides.add(uri.getHost()); + overrides.add(uri.getHost() + ":" + uri.getPort()); + + // set new value: + String overridesStr = StringUtils.join(overrides, ';'); + ProcessBuilder add = new ProcessBuilder("reg", "add", "\"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\"", "/v", "ProxyOverride", "/d", "\"" + overridesStr + "\"", "/f"); + LOG.debug("Invoking command: " + StringUtils.join(add.command(), ' ')); + Process addCmd = add.start(); + int addResult = addCmd.waitFor(); + if (addResult != 0) { + String addStdErr = IOUtils.toString(addCmd.getErrorStream(), StandardCharsets.UTF_8); + throw new CommandFailedException(addStdErr); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + InterruptedIOException ioException = new InterruptedIOException(); + ioException.initCause(e); + throw ioException; + } + } private String getDriveLetter(String result) throws CommandFailedException { final Matcher matcher = WIN_MOUNT_DRIVELETTER_PATTERN.matcher(result);