X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fbin%2FCache.java;h=594046fc07976370f0650f290cc3f4e01f1ba965;hb=9092d9f4c2231645b58968e964c858e010be14e2;hp=8051336f4a09100dd8872cc43bda158c9ddc87bd;hpb=419898b96abeb2f9cdc77b22b34d71fff5451fd9;p=jalview.git diff --git a/src/jalview/bin/Cache.java b/src/jalview/bin/Cache.java index 8051336..594046f 100755 --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@ -34,6 +34,7 @@ import java.net.PasswordAuthentication; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.Enumeration; @@ -54,7 +55,6 @@ import org.apache.log4j.SimpleLayout; import jalview.datamodel.PDBEntry; import jalview.gui.Preferences; import jalview.gui.UserDefinedColours; -import jalview.jbgui.GPreferences; import jalview.schemes.ColourSchemeLoader; import jalview.schemes.ColourSchemes; import jalview.schemes.UserColourScheme; @@ -1306,6 +1306,56 @@ public class Cache Cache.debug(sb.toString()); } + public static void setProxyPropertiesFromPreferences() + { + setProxyPropertiesFromPreferences(Cache.PROXYTYPE_SYSTEM); + } + + public static void setProxyPropertiesFromPreferences( + String previousProxyType) + { + String proxyType = Cache.getDefault("USE_PROXY", + Cache.PROXYTYPE_SYSTEM); + if (previousProxyType != null + && !proxyType.equals(Cache.PROXYTYPE_CUSTOM) // always apply + // customProxy + && proxyType.equals(previousProxyType)) + { + // no change + return; + } + switch (proxyType) + { + case Cache.PROXYTYPE_NONE: + if (!previousProxyType.equals(proxyType)) + { + Cache.log.info("Setting no proxy settings"); + Cache.setProxyProperties(null, null, null, null, null, null, null, + null, null); + } + break; + case Cache.PROXYTYPE_CUSTOM: + // always re-set a custom proxy -- it might have changed, particularly + // password + Cache.log.info("Setting custom proxy settings"); + boolean proxyAuthSet = Cache.getDefault("PROXY_AUTH", false); + Cache.setProxyProperties(Cache.getDefault("PROXY_SERVER", null), + Cache.getDefault("PROXY_PORT", null), + Cache.getDefault("PROXY_SERVER_HTTPS", null), + Cache.getDefault("PROXY_PORT_HTTPS", null), + proxyAuthSet ? Cache.getDefault("PROXY_AUTH_USERNAME", "") + : null, + proxyAuthSet ? Cache.proxyAuthPassword : null, + proxyAuthSet ? Cache.getDefault("PROXY_AUTH_USERNAME", "") + : null, + proxyAuthSet ? Cache.proxyAuthPassword : null, "localhost"); + break; + default: // system proxy settings by default + Cache.log.info("Setting system proxy settings"); + Cache.resetProxyProperties(); + } + } + public static void setProxyProperties(String httpHost, String httpPort, String httpsHost, String httpsPort, String httpUser, char[] httpPassword, String httpsUser, char[] httpsPassword, @@ -1316,16 +1366,45 @@ public class Cache setOrClearSystemProperty("https.proxyHost", httpsHost); setOrClearSystemProperty("https.proxyPort", httpsPort); setOrClearSystemProperty("http.proxyUser", httpUser); - setOrClearSystemProperty("http.proxyPassword", httpPassword); setOrClearSystemProperty("https.proxyUser", httpsUser); - setOrClearSystemProperty("https.proxyPassword", httpsPassword); + // note: passwords for http.proxyPassword and https.proxyPassword are sent + // via the Authenticator, properties do not need to be set + // are we using a custom proxy (password prompt might be required)? boolean customProxySet = getDefault("USE_PROXY", PROXYTYPE_SYSTEM) .equals(PROXYTYPE_CUSTOM); + + /* + * A bug in Java means the AuthCache does not get reset, so once it has working credentials, + * it never asks for more, so changing the Authenticator has no effect (as getPasswordAuthentication() + * is not re-called). + * This could lead to password leak to a hostile proxy server, so I'm putting in a hack to clear + * the AuthCache. + * see https://www.generacodice.com/en/articolo/154918/Reset-the-Authenticator-credentials + * ... + * Turns out this is only accessible in Java 8, and not in Java 9 onwards, so commenting out + */ + /* + try + { + sun.net.www.protocol.http.AuthCacheValue + .setAuthCache(new sun.net.www.protocol.http.AuthCacheImpl()); + } catch (Throwable t) + { + Cache.error(t.getMessage()); + Cache.debug(getStackTraceString(t)); + } + */ + if (httpUser != null || httpsUser != null) { try { + char[] displayHttpPw = new char[httpPassword == null ? 0 + : httpPassword.length]; + Arrays.fill(displayHttpPw, '*'); + Cache.debug("CACHE Proxy: setting new Authenticator with httpUser='" + + httpUser + "' httpPassword='" + displayHttpPw + "'"); Authenticator.setDefault(new Authenticator() { @Override @@ -1333,16 +1412,16 @@ public class Cache { if (getRequestorType() == RequestorType.PROXY) { - String scheme = getRequestingScheme(); + String protocol = getRequestingProtocol(); boolean needProxyPasswordSet = false; if (customProxySet && // we have a username but no password for the scheme being // requested - (scheme.equalsIgnoreCase("http") + (protocol.equalsIgnoreCase("http") && (httpUser != null && httpUser.length() > 0 && (httpPassword == null || httpPassword.length == 0))) - || (scheme.equalsIgnoreCase("https") + || (protocol.equalsIgnoreCase("https") && (httpsUser != null && httpsUser.length() > 0 && (httpsPassword == null @@ -1351,25 +1430,37 @@ public class Cache // open Preferences -> Connections String message = MessageManager .getString("label.proxy_password_required"); - openPreferencesConnectionsForProxyPassword(message); + Preferences.openPreferences(Preferences.CONNECTIONS_TAB, + message); + Preferences.getInstance().proxyAuthPasswordCheckHighlight(true); } else { try { - if (scheme.equalsIgnoreCase("http") + if (protocol.equalsIgnoreCase("http") && getRequestingHost().equalsIgnoreCase(httpHost) && getRequestingPort() == Integer .valueOf(httpPort)) { + Cache.debug( + "AUTHENTICATOR returning PasswordAuthentication(\"" + + httpUser + "\", '" + + new String(displayHttpPw) + "')"); return new PasswordAuthentication(httpUser, httpPassword); } - if (scheme.equalsIgnoreCase("https") + if (protocol.equalsIgnoreCase("https") && getRequestingHost().equalsIgnoreCase(httpsHost) && getRequestingPort() == Integer .valueOf(httpsPort)) { + char[] displayHttpsPw = new char[httpPassword.length]; + Arrays.fill(displayHttpsPw, '*'); + Cache.debug( + "AUTHENTICATOR returning PasswordAuthentication(\"" + + httpsUser + "\", '" + displayHttpsPw + + "'"); return new PasswordAuthentication(httpsUser, httpsPassword); } @@ -1378,14 +1469,19 @@ public class Cache Cache.error("Problem with proxy port values [http:" + httpPort + ", https:" + httpsPort + "]"); } + Cache.debug( + "AUTHENTICATOR after trying to get PasswordAuthentication"); } } // non proxy request + Cache.debug("AUTHENTICATOR returning null"); return null; } }); // required to re-enable basic authentication (should be okay for a // local proxy) + Cache.debug( + "AUTHENTICATOR setting property 'jdk.http.auth.tunneling.disabledSchemes' to \"\""); System.setProperty("jdk.http.auth.tunneling.disabledSchemes", ""); } catch (SecurityException e) { @@ -1397,27 +1493,23 @@ public class Cache { // reset the Authenticator to protect http.proxyUser and // http.proxyPassword Just In Case + /* as noted above, due to bug in java this doesn't work if the sun.net.www.protocol.http.AuthCache + * has working credentials. No workaround for Java 11. + */ + Cache.debug("AUTHENTICATOR setting default Authenticator to null"); Authenticator.setDefault(null); } // nonProxyHosts not currently configurable in Preferences + Cache.debug("AUTHENTICATOR setting property 'http.nonProxyHosts' to \"" + + nonProxyHosts + "\""); setOrClearSystemProperty("http.nonProxyHosts", nonProxyHosts); } - private static void openPreferencesConnectionsForProxyPassword( - String message) - { - // - Cache.info("Opening Preferences for proxy password"); - // Desktop.instance.preferences_actionPerformed(null); - Preferences p = new Preferences(GPreferences.CONNECTIONS_TAB); - p.grabFocus(); - } - public static void setOrClearSystemProperty(String key, char[] value) { setOrClearSystemProperty(key, - (value == null) ? null : value.toString()); + (value == null) ? null : new String(value)); } public static void setOrClearSystemProperty(String key, String value) @@ -1436,25 +1528,32 @@ public class Cache } } - public final static int DEBUG = 10; + public final static int TRACE = 10; + + public final static int DEBUG = 20; - public final static int INFO = 20; + public final static int INFO = 30; - public final static int WARN = 30; + public final static int WARN = 40; - public final static int ERROR = 40; + public final static int ERROR = 50; public static boolean println(int level, String message) { if (Cache.log == null) { - if (level >= ERROR) + if (level >= WARN) System.err.println(message); - else + else if (level >= INFO) System.out.println(message); + // not printing debug or trace messages return false; } - if (level >= WARN) + if (level >= ERROR) + { + Cache.log.error(message); + } + else if (level >= WARN) { Cache.log.warn(message); } @@ -1462,13 +1561,22 @@ public class Cache { Cache.log.info(message); } - else + else if (level >= DEBUG) { Cache.log.debug(message); } + else + { + Cache.log.trace(message); + } return true; } + public static void trace(String message) + { + println(TRACE, message); + } + public static void debug(String message) { println(DEBUG, message); @@ -1488,4 +1596,4 @@ public class Cache { println(ERROR, message); } -} +} \ No newline at end of file