diff options
Diffstat (limited to 'netx/net')
6 files changed, 556 insertions, 12 deletions
diff --git a/netx/net/sourceforge/jnlp/browser/BrowserAwareProxySelector.java b/netx/net/sourceforge/jnlp/browser/BrowserAwareProxySelector.java new file mode 100644 index 0000000..c53b36b --- /dev/null +++ b/netx/net/sourceforge/jnlp/browser/BrowserAwareProxySelector.java @@ -0,0 +1,255 @@ +/* BrowserAwareProxySelector.java + Copyright (C) 2011 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ +package net.sourceforge.jnlp.browser; + +import static net.sourceforge.jnlp.runtime.Translator.R; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.MalformedURLException; +import java.net.Proxy; +import java.net.SocketAddress; +import java.net.URI; +import java.net.URL; +import java.net.Proxy.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import net.sourceforge.jnlp.runtime.JNLPProxySelector; +import net.sourceforge.jnlp.runtime.JNLPRuntime; + +/** + * A ProxySelector which can read proxy settings from a browser's + * configuration and use that. + * + * @see JNLPProxySelector + */ +public class BrowserAwareProxySelector extends JNLPProxySelector { + + /* firefox's constants */ + public static final int BROWSER_PROXY_TYPE_NONE = 0; + public static final int BROWSER_PROXY_TYPE_MANUAL = 1; + public static final int BROWSER_PROXY_TYPE_PAC = 2; + public static final int BROWSER_PROXY_TYPE_NONE2 = 3; + /** use gconf, WPAD and then env (and possibly others)*/ + public static final int BROWSER_PROXY_TYPE_AUTO = 4; + /** use env variables */ + public static final int BROWSER_PROXY_TYPE_SYSTEM = 5; + + private int browserProxyType = BROWSER_PROXY_TYPE_NONE; + private URL browserAutoConfigUrl; + private Boolean browserUseSameProxy; + private String browserHttpProxyHost; + private int browserHttpProxyPort; + private String browserHttpsProxyHost; + private int browserHttpsProxyPort; + private String browserFtpProxyHost; + private int browserFtpProxyPort; + private String browserSocks4ProxyHost; + private int browserSocks4ProxyPort; + + /** + * Create a new instance of this class, reading configuration fropm the browser + */ + public BrowserAwareProxySelector() { + super(); + try { + initFromBrowserConfig(); + } catch (IOException e) { + if (JNLPRuntime.isDebug()) { + e.printStackTrace(); + } + System.err.println(R("RProxyFirefoxNotFound")); + browserProxyType = PROXY_TYPE_NONE; + } + } + + /** + * Initialize configuration by reading preferences from the browser (firefox) + */ + private void initFromBrowserConfig() throws IOException { + + File preferencesFile = FirefoxPreferencesFinder.find(); + + FirefoxPreferencesParser parser = new FirefoxPreferencesParser(preferencesFile); + parser.parse(); + Map<String, String> prefs = parser.getPreferences(); + + String type = prefs.get("network.proxy.type"); + if (type != null) { + browserProxyType = Integer.valueOf(type); + } else { + browserProxyType = BROWSER_PROXY_TYPE_AUTO; + } + + try { + browserAutoConfigUrl = new URL(prefs.get("network.proxy.autoconfig_url")); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + + browserUseSameProxy = Boolean.valueOf(prefs.get("network.proxy.share_proxy_settings")); + + browserHttpProxyHost = prefs.get("network.proxy.http"); + browserHttpProxyPort = stringToPort(prefs.get("network.proxy.http_port")); + browserHttpsProxyHost = prefs.get("network.proxy.ssl"); + browserHttpsProxyPort = stringToPort(prefs.get("network.proxy.ssl_port")); + browserFtpProxyHost = prefs.get("network.proxy.ftp"); + browserFtpProxyPort = stringToPort(prefs.get("network.proxy.ftp_port")); + browserSocks4ProxyHost = prefs.get("networking.proxy.socks"); + browserSocks4ProxyPort = stringToPort(prefs.get("network.proxy.socks_port")); + } + + /** + * Returns port inside a string. Unlike {@link Integer#valueOf(String)}, + * it will not throw exceptions. + * + * @param string the string containing the integer to parse + * @return the port inside the string, or Integer.MIN_VALUE + */ + private int stringToPort(String string) { + try { + return Integer.valueOf(string); + } catch (NumberFormatException nfe) { + return Integer.MIN_VALUE; + } + } + + /** + * The main entry point for {@link BrowserAwareProxySelector}. Based on + * the browser settings, determines proxy information for a given URI. + * <p> + * The appropriate proxy may be determined by reading static information + * from the browser's preferences file, or it may be computed dynamically, + * by, for example, running javascript code. + */ + @Override + protected List<Proxy> getFromBrowser(URI uri) { + List<Proxy> proxies = new ArrayList<Proxy>(); + + String optionDescription = null; + + switch (browserProxyType) { + case BROWSER_PROXY_TYPE_PAC: + proxies.addAll(getFromBrowserPAC(uri)); + break; + case BROWSER_PROXY_TYPE_MANUAL: + proxies.addAll(getFromBrowserConfiguration(uri)); + break; + case BROWSER_PROXY_TYPE_NONE: + proxies.add(Proxy.NO_PROXY); + break; + case BROWSER_PROXY_TYPE_AUTO: + // firefox will do a whole lot of stuff to automagically + // figure out the right settings. gconf, WPAD, and ENV are used. + // https://bugzilla.mozilla.org/show_bug.cgi?id=66057#c32 + // TODO this is probably not easy/quick to do. using libproxy might be + // the simpler workaround + if (optionDescription == null) { + optionDescription = "Automatic"; + } + case BROWSER_PROXY_TYPE_SYSTEM: + // means use $http_proxy, $ftp_proxy etc. + // TODO implement env vars if possible + if (optionDescription == null) { + optionDescription = "System"; + } + default: + if (optionDescription == null) { + optionDescription = "Unknown"; + } + System.err.println(R("RProxyFirefoxOptionNotImplemented", browserProxyType, optionDescription)); + proxies.add(Proxy.NO_PROXY); + } + + if (JNLPRuntime.isDebug()) { + System.out.println("Browser selected proxies: " + proxies.toString()); + } + + return proxies; + } + + /** + * Get an appropriate proxy for a given URI using a PAC specified in the + * browser. + */ + private List<Proxy> getFromBrowserPAC(URI uri) { + System.err.println(R("RPRoxyPacNotImplemented")); + return Arrays.asList(new Proxy[] { Proxy.NO_PROXY }); + } + + /** + * Get an appropriate proxy for the given URI using static information from + * the browser's preferences file. + */ + private List<Proxy> getFromBrowserConfiguration(URI uri) { + List<Proxy> proxies = new ArrayList<Proxy>(); + + String scheme = uri.getScheme(); + + if (browserUseSameProxy) { + SocketAddress sa = new InetSocketAddress(browserHttpProxyHost, browserHttpProxyPort); + Proxy proxy; + if (scheme.equals("socket")) { + proxy = new Proxy(Type.SOCKS, sa); + } else { + proxy = new Proxy(Type.HTTP, sa); + } + proxies.add(proxy); + } else if (scheme.equals("http")) { + SocketAddress sa = new InetSocketAddress(browserHttpProxyHost, browserHttpProxyPort); + proxies.add(new Proxy(Type.HTTP, sa)); + } else if (scheme.equals("https")) { + SocketAddress sa = new InetSocketAddress(browserHttpsProxyHost, browserHttpsProxyPort); + proxies.add(new Proxy(Type.HTTP, sa)); + } else if (scheme.equals("ftp")) { + SocketAddress sa = new InetSocketAddress(browserFtpProxyHost, browserFtpProxyPort); + proxies.add(new Proxy(Type.HTTP, sa)); + } else if (scheme.equals("socket")) { + SocketAddress sa = new InetSocketAddress(browserSocks4ProxyHost, browserSocks4ProxyPort); + proxies.add(new Proxy(Type.SOCKS, sa)); + } else { + proxies.add(Proxy.NO_PROXY); + } + + return proxies; + } + +} diff --git a/netx/net/sourceforge/jnlp/browser/FirefoxPreferencesFinder.java b/netx/net/sourceforge/jnlp/browser/FirefoxPreferencesFinder.java new file mode 100644 index 0000000..34d1092 --- /dev/null +++ b/netx/net/sourceforge/jnlp/browser/FirefoxPreferencesFinder.java @@ -0,0 +1,137 @@ +/* FirefoxPreferencesFinder.java + Copyright (C) 2011 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.browser; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.jnlp.runtime.JNLPRuntime; + +/** + * Finds the file corresponding to firefox's (default) preferences file + */ +public class FirefoxPreferencesFinder { + + /** + * Returns a file object representing firefox's preferences file + * + * @return a File object representing the preferences file. + * @throws FileNotFoundException if the preferences file could not be found + * @throws IOException if an exception occurs while trying to identify the + * location of the preferences file. + */ + public static File find() throws IOException { + + String configPath = System.getProperty("user.home") + File.separator + ".mozilla" + + File.separator + "firefox" + File.separator; + + String profilesPath = configPath + "profiles.ini"; + + if (!(new File(profilesPath).isFile())) { + throw new FileNotFoundException(profilesPath); + } + + if (JNLPRuntime.isDebug()) { + System.out.println("Using firefox's profiles file: " + profilesPath); + } + BufferedReader reader = new BufferedReader(new FileReader(profilesPath)); + + List<String> linesInSection = new ArrayList<String>(); + boolean foundDefaultSection = false; + + /* + * The profiles.ini file is an ini file. This is a quick hack to read + * it. It is very likely to break given anything strange. + */ + + // find the section with an entry Default=1 + while (true) { + String line = reader.readLine(); + if (line == null) { + break; + } + + line = line.trim(); + if (line.startsWith("[") && line.endsWith("]")) { + if (foundDefaultSection) { + break; + } + // new section + linesInSection = new ArrayList<String>(); + } else { + linesInSection.add(line); + int equalSignPos = line.indexOf('='); + if (equalSignPos > 0) { + String key = line.substring(0, equalSignPos).trim(); + String value = line.substring(equalSignPos+1).trim(); + if (key.toLowerCase().equals("default") && value.equals("1")) { + foundDefaultSection = true; + } + } + } + + } + + if (!foundDefaultSection) { + throw new FileNotFoundException("preferences file"); + } + + String path = null; + for (String line : linesInSection) { + if (line.startsWith("Path=")) { + path = line.substring("Path=".length()); + } + } + + if (path == null) { + throw new FileNotFoundException("preferences file"); + } else { + String fullPath = configPath + path + File.separator + "prefs.js"; + if (JNLPRuntime.isDebug()) { + System.out.println("Found preferences file: " + fullPath); + } + return new File(fullPath); + } + } + +} diff --git a/netx/net/sourceforge/jnlp/browser/FirefoxPreferencesParser.java b/netx/net/sourceforge/jnlp/browser/FirefoxPreferencesParser.java new file mode 100644 index 0000000..1f206a9 --- /dev/null +++ b/netx/net/sourceforge/jnlp/browser/FirefoxPreferencesParser.java @@ -0,0 +1,155 @@ +/* FirefoxPreferencesParser.java + Copyright (C) 2011 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.browser; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.jnlp.runtime.JNLPRuntime; + +/** + * A parser for Firefox's preferences file. It can 'parse' Firefox's + * preferences file and expose the prefrences in a simple to use format. + * <p> + * Sample usage: + * <pre> + * FirefoxPreferencesParser p = new FirefoxPreferencesParser(prefsFile); + * p.parse(); + * Map<String,String> prefs = p.getPreferences(); + * System.out.println("blink allowed: " + prefs.get("browser.blink_allowed")); + * </pre> + */ +public final class FirefoxPreferencesParser { + + File prefsFile = null; + Map<String, String> prefs = null; + + /** + * Creates a new FirefoxPreferencesParser + * @param preferencesFile + */ + public FirefoxPreferencesParser(File preferencesFile) { + prefsFile = preferencesFile; + } + + /** + * Parse the prefernces file + * @throws IOException if an exception ocurrs while reading the + * preferences file. + */ + public void parse() throws IOException { + /* + * The Firefox preference file is actually in javascript. It does seem + * to be nicely formatted, so it should be possible to hack reading it. + * The correct way of course is to use a javascript library and extract + * the user_pref object + */ + prefs = new HashMap<String, String>(); + + BufferedReader reader = new BufferedReader(new FileReader(prefsFile)); + + while (true) { + String line = reader.readLine(); + // end of stream + if (line == null) { + break; + } + + line = line.trim(); + if (line.startsWith("user_pref")) { + + /* + * each line is of the form: user_pref("key",value); where value + * can be a string in double quotes or an integer or float or + * boolean + */ + + boolean foundKey = false; + boolean foundValue = false; + + // extract everything inside user_pref( and ); + String pref = line.substring("user_pref(".length(), line.length() - 2); + // key and value are separated by a , + int firstCommaPos = pref.indexOf(','); + if (firstCommaPos >= 1) { + String key = pref.substring(0, firstCommaPos).trim(); + if (key.startsWith("\"") && key.endsWith("\"")) { + key = key.substring(1, key.length() - 1); + if (key.trim().length() > 0) { + foundKey = true; + } + } + + if (pref.length() > firstCommaPos + 1) { + String value = pref.substring(firstCommaPos + 1).trim(); + if (value.startsWith("\"") && value.endsWith("\"")) { + value = value.substring(1, value.length() - 1).trim(); + } + foundValue = true; + + if (foundKey && foundValue) { + // System.out.println("added (\"" + key + "\", \"" + value + "\")"); + prefs.put(key, value); + } + } + } + } + } + if (JNLPRuntime.isDebug()) { + System.out.println("Read " + prefs.size() + " entries from Firefox's preferences"); + } + } + + /** + * Get the firefox preferences as a map (key,value pair). Note that + * all values (including integers and booleans) are stored as a string, so + * conversion to an appropriate type may be required. + * + * @return a map containing firefox' preferences + */ + public Map<String, String> getPreferences() { + HashMap<String, String> newMap = new HashMap<String, String>(); + newMap.putAll(prefs); + return newMap; + } + +} diff --git a/netx/net/sourceforge/jnlp/resources/Messages.properties b/netx/net/sourceforge/jnlp/resources/Messages.properties index fc4a196..c9628b9 100644 --- a/netx/net/sourceforge/jnlp/resources/Messages.properties +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties @@ -141,6 +141,9 @@ RNestedJarExtration=Unable to extract nested jar. RUnexpected=Unexpected {0} at {1}
RConfigurationError=Fatal error while reading the configuration
RConfigurationFatal=ERROR: a fatal error has occurred while loading configuration. Perhaps a global configuration was required but could not be found
+RPRoxyPacNotImplemented=Using Proxy Auto Config (PAC) files is not supported yet.
+RProxyFirefoxNotFound=Unable to use Firefox's proxy settings. Using "DIRECT" as proxy type.
+RProxyFirefoxOptionNotImplemented=Browser proxy option "{0}" ({1}) not supported yet.
# Boot options, message should be shorter than this ---------------->
BOUsage=javaws [-run-options] <jnlp file>
diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java b/netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java index acf8e85..cf7d6a8 100644 --- a/netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java +++ b/netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java @@ -16,6 +16,7 @@ package net.sourceforge.jnlp.runtime; +import static net.sourceforge.jnlp.runtime.Translator.R; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -40,7 +41,7 @@ import net.sourceforge.jnlp.config.DeploymentConfiguration; * * @see java.net.ProxySelector */ -public class JNLPProxySelector extends ProxySelector { +public abstract class JNLPProxySelector extends ProxySelector { public static final int PROXY_TYPE_UNKNOWN = -1; public static final int PROXY_TYPE_NONE = 0; @@ -337,9 +338,7 @@ public class JNLPProxySelector extends ProxySelector { return Arrays.asList(new Proxy[] { Proxy.NO_PROXY }); } // TODO implement this by reading and using the PAC file - if (JNLPRuntime.isDebug()) { - System.err.println("WARNING: Using a Proxy Auto Config file is not implemented yet"); - } + System.err.println(R("RPRoxyPacNotImplemented")); return Arrays.asList(new Proxy[] { Proxy.NO_PROXY }); } @@ -350,13 +349,7 @@ public class JNLPProxySelector extends ProxySelector { * @param uri the uri to get proxies for * @return a list of proxies */ - protected List<Proxy> getFromBrowser(URI uri) { - // TODO implement this by parsing mozilla config - if (JNLPRuntime.isDebug()) { - System.err.println("WARNING: Using proxy settings from the browser is not implemented yet"); - } + protected abstract List<Proxy> getFromBrowser(URI uri); - return Arrays.asList(new Proxy[] { Proxy.NO_PROXY }); - } } diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java index 61417a4..2efa620 100644 --- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java +++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java @@ -34,6 +34,7 @@ import javax.swing.UIManager; import javax.swing.text.html.parser.ParserDelegator; import net.sourceforge.jnlp.*; +import net.sourceforge.jnlp.browser.BrowserAwareProxySelector; import net.sourceforge.jnlp.cache.*; import net.sourceforge.jnlp.config.DeploymentConfiguration; import net.sourceforge.jnlp.security.JNLPAuthenticator; @@ -220,7 +221,7 @@ public class JNLPRuntime { // plug in a custom authenticator and proxy selector Authenticator.setDefault(new JNLPAuthenticator()); - ProxySelector.setDefault(new JNLPProxySelector()); + ProxySelector.setDefault(new BrowserAwareProxySelector()); initialized = true; |