diff options
Diffstat (limited to 'src/main/java/com/btr/proxy/search/desktop')
10 files changed, 1516 insertions, 0 deletions
diff --git a/src/main/java/com/btr/proxy/search/desktop/DesktopProxySearchStrategy.java b/src/main/java/com/btr/proxy/search/desktop/DesktopProxySearchStrategy.java new file mode 100644 index 0000000..8a5a5d8 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/DesktopProxySearchStrategy.java @@ -0,0 +1,69 @@ +package com.btr.proxy.search.desktop; + +import java.net.ProxySelector; + +import com.btr.proxy.search.ProxySearchStrategy; +import com.btr.proxy.search.desktop.gnome.GnomeProxySearchStrategy; +import com.btr.proxy.search.desktop.kde.KdeProxySearchStrategy; +import com.btr.proxy.search.desktop.osx.OsxProxySearchStrategy; +import com.btr.proxy.search.desktop.win.WinProxySearchStrategy; +import com.btr.proxy.util.Logger; +import com.btr.proxy.util.PlatformUtil; +import com.btr.proxy.util.ProxyException; +import com.btr.proxy.util.Logger.LogLevel; +import com.btr.proxy.util.PlatformUtil.Desktop; +import com.btr.proxy.util.PlatformUtil.Platform; + +/***************************************************************************** + * This search provider will try to find out on which desktop platform we + * are running and then will initialize the default proxy search. + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class DesktopProxySearchStrategy implements ProxySearchStrategy { + + /************************************************************************* + * Gets the default ProxySelector for the current platform. + * @return a ProxySelector, null if none is found. + * @throws ProxyException on error. + ************************************************************************/ + + public ProxySelector getProxySelector() throws ProxyException { + ProxySearchStrategy strategy = findDesktopSpecificStrategy(); + return strategy == null? null : strategy.getProxySelector(); + } + + /************************************************************************* + * Determine the desktop and create a strategy for it. + * @return a desktop specific strategy, null if none was found. + ************************************************************************/ + + private ProxySearchStrategy findDesktopSpecificStrategy() { + Platform pf = PlatformUtil.getCurrentPlattform(); + Desktop dt = PlatformUtil.getCurrentDesktop(); + + Logger.log(getClass(), LogLevel.TRACE, "Detecting system settings."); + + ProxySearchStrategy strategy = null; + + if (pf == Platform.WIN) { + Logger.log(getClass(), LogLevel.TRACE, "We are running on Windows."); + strategy = new WinProxySearchStrategy(); + } else + if (dt == Desktop.KDE) { + Logger.log(getClass(), LogLevel.TRACE, "We are running on KDE."); + strategy = new KdeProxySearchStrategy(); + } else + if (dt == Desktop.GNOME) { + Logger.log(getClass(), LogLevel.TRACE, "We are running on Gnome."); + strategy = new GnomeProxySearchStrategy(); + } else + if (dt == Desktop.MAC_OS) { + Logger.log(getClass(), LogLevel.TRACE, "We are running on Mac OSX."); + strategy = new OsxProxySearchStrategy(); + } + return strategy; + } + +} diff --git a/src/main/java/com/btr/proxy/search/desktop/gnome/GnomeProxySearchStrategy.java b/src/main/java/com/btr/proxy/search/desktop/gnome/GnomeProxySearchStrategy.java new file mode 100644 index 0000000..240fb39 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/gnome/GnomeProxySearchStrategy.java @@ -0,0 +1,353 @@ +package com.btr.proxy.search.desktop.gnome; + +import java.io.File; +import java.io.IOException; +import java.net.ProxySelector; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import com.btr.proxy.search.ProxySearchStrategy; +import com.btr.proxy.selector.direct.NoProxySelector; +import com.btr.proxy.selector.fixed.FixedProxySelector; +import com.btr.proxy.selector.misc.ProtocolDispatchSelector; +import com.btr.proxy.selector.whitelist.ProxyBypassListSelector; +import com.btr.proxy.util.EmptyXMLResolver; +import com.btr.proxy.util.Logger; +import com.btr.proxy.util.ProxyException; +import com.btr.proxy.util.ProxyUtil; +import com.btr.proxy.util.Logger.LogLevel; + +/***************************************************************************** + * Loads the Gnome proxy settings from the Gnome GConf settings. + * <p> + * The following settings are extracted from the configuration that is stored + * in <i>.gconf</i> folder found in the user's home directory: + * </p> + * <ul> + * <li><i>/system/http_proxy/use_http_proxy</i> -> bool used only by gnome-vfs </li> + * <li><i>/system/http_proxy/host</i> -> string "my-proxy.example.com" without "http://"</li> + * <li><i>/system/http_proxy/port</i> -> int</li> + * <li><i>/system/http_proxy/use_authentication</i> -> bool</li> + * <li><i>/system/http_proxy/authentication_user</i> -> string</li> + * <li><i>/system/http_proxy/authentication_password</i> -> string</li> + * <li><i>/system/http_proxy/ignore_hosts</i> -> list-of-string</li> + * <li><i>/system/proxy/mode</i> -> string THIS IS THE CANONICAL KEY; SEE BELOW</li> + * <li><i>/system/proxy/secure_host</i> -> string "proxy-for-https.example.com"</li> + * <li><i>/system/proxy/secure_port</i> -> int</li> + * <li><i>/system/proxy/ftp_host</i> -> string "proxy-for-ftp.example.com"</li> + * <li><i>/system/proxy/ftp_port</i> -> int</li> + * <li><i>/system/proxy/socks_host</i> -> string "proxy-for-socks.example.com"</li> + * <li><i>/system/proxy/socks_port</i> -> int</li> + * <li><i>/system/proxy/autoconfig_url</i> -> string "http://proxy-autoconfig.example.com"</li> + * </ul> + * <i>/system/proxy/mode</i> can be either:<br/> + * "none" -> No proxy is used<br/> + * "manual" -> The user's configuration values are used (/system/http_proxy/{host,port,etc.})<br/> + * "auto" -> The "/system/proxy/autoconfig_url" key is used <br/> + * <p> + * GNOME Proxy_configuration settings are explained + * <a href="http://en.opensuse.org/GNOME/Proxy_configuration">here</a> in detail + * </p> + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class GnomeProxySearchStrategy implements ProxySearchStrategy { + + /************************************************************************* + * ProxySelector + * @see java.net.ProxySelector#ProxySelector() + ************************************************************************/ + + public GnomeProxySearchStrategy() { + super(); + } + + /************************************************************************* + * Loads the proxy settings and initializes a proxy selector for the Gnome + * proxy settings. + * @return a configured ProxySelector, null if none is found. + * @throws ProxyException on file reading error. + ************************************************************************/ + + public ProxySelector getProxySelector() throws ProxyException { + + Logger.log(getClass(), LogLevel.TRACE, "Detecting Gnome proxy settings"); + + Properties settings = readSettings(); + + String type = settings.getProperty("/system/proxy/mode"); + ProxySelector result = null; + if (type == null) { + String useProxy = settings.getProperty("/system/http_proxy/use_http_proxy"); + if (useProxy == null) { + return null; + } + type = Boolean.parseBoolean(useProxy)?"manual":"none"; + } + + if ("none".equals(type)) { + Logger.log(getClass(), LogLevel.TRACE, "Gnome uses no proxy"); + result = NoProxySelector.getInstance(); + } + if ("manual".equals(type)) { + Logger.log(getClass(), LogLevel.TRACE, "Gnome uses manual proxy settings"); + result = setupFixedProxySelector(settings); + } + if ("auto".equals(type)) { + String pacScriptUrl = settings.getProperty("/system/proxy/autoconfig_url", ""); + Logger.log(getClass(), LogLevel.TRACE, "Gnome uses autodetect script {0}", pacScriptUrl); + result = ProxyUtil.buildPacSelectorForUrl(pacScriptUrl); + } + + // Wrap into white-list filter? + String noProxyList = settings.getProperty("/system/http_proxy/ignore_hosts", null); + if (result != null && noProxyList != null && noProxyList.trim().length() > 0) { + Logger.log(getClass(), LogLevel.TRACE, "Gnome uses proxy bypass list: {0}", noProxyList); + result = new ProxyBypassListSelector(noProxyList, result); + } + + return result; + } + + /************************************************************************* + * Load the proxy settings from the gconf settings XML file. + * @return the loaded settings stored in a properties object. + * @throws ProxyException on processing error. + ************************************************************************/ + + public Properties readSettings() throws ProxyException { + Properties settings = new Properties(); + try { + parseSettings("/system/proxy/", settings); + parseSettings("/system/http_proxy/", settings); + } catch (IOException e) { + Logger.log(getClass(), LogLevel.ERROR, "Gnome settings file error.", e); + throw new ProxyException(e); + } + return settings; + } + + /************************************************************************* + * Finds the Gnome GConf settings file. + * @param context the gconf context to parse. + * @return a file or null if does not exist. + ************************************************************************/ + + private File findSettingsFile(String context) { + // Normally we should inspect /etc/gconf/<version>/path to find out where the actual file is. + // But for normal systems this is always stored in .gconf folder in the user's home directory. + File userDir = new File(System.getProperty("user.home")); + + // Build directory path for context + StringBuilder path = new StringBuilder(); + String[] parts = context.split("/"); + for (String part : parts) { + path.append(part); + path.append(File.separator); + } + + File settingsFile = new File(userDir, ".gconf"+File.separator+path.toString()+"%gconf.xml"); + if (!settingsFile.exists()) { + Logger.log(getClass(), LogLevel.WARNING, "Gnome settings: {0} not found.", settingsFile); + return null; + } + return settingsFile; + } + + /************************************************************************* + * Parse the fixed proxy settings and build an ProxySelector for this a + * chained configuration. + * @param settings the proxy settings to evaluate. + ************************************************************************/ + + private ProxySelector setupFixedProxySelector(Properties settings) { + if (!hasProxySettings(settings)) { + return null; + } + ProtocolDispatchSelector ps = new ProtocolDispatchSelector(); + installHttpSelector(settings, ps); + + if (useForAllProtocols(settings)) { + ps.setFallbackSelector(ps.getSelector("http")); + } else { + installSecureSelector(settings, ps); + installFtpSelector(settings, ps); + installSocksSelector(settings, ps); + } + return ps; + } + + /************************************************************************* + * Check if the http proxy should also be used for all other protocols. + * @param settings to inspect. + * @return true if only one proxy is configured else false. + ************************************************************************/ + + private boolean useForAllProtocols(Properties settings) { + return Boolean.parseBoolean( + settings.getProperty("/system/http_proxy/use_same_proxy", "false")); + } + + /************************************************************************* + * Checks if we have Proxy configuration settings in the properties. + * @param settings to inspect. + * @return true if we have found Proxy settings. + ************************************************************************/ + + private boolean hasProxySettings(Properties settings) { + String proxyHost = settings.getProperty("/system/http_proxy/host", null); + return proxyHost != null && proxyHost.length() > 0; + } + + /************************************************************************* + * Install a http proxy from the given settings. + * @param settings to inspect + * @param ps the dispatch selector to configure. + * @throws NumberFormatException + ************************************************************************/ + + private void installHttpSelector(Properties settings, + ProtocolDispatchSelector ps) throws NumberFormatException { + String proxyHost = settings.getProperty("/system/http_proxy/host", null); + int proxyPort = Integer.parseInt(settings.getProperty("/system/http_proxy/port", "0").trim()); + if (proxyHost != null && proxyHost.length() > 0 && proxyPort > 0) { + Logger.log(getClass(), LogLevel.TRACE, "Gnome http proxy is {0}:{1}", proxyHost, proxyPort); + ps.setSelector("http", new FixedProxySelector(proxyHost.trim(), proxyPort)); + } + } + + /************************************************************************* + * Install a socks proxy from the given settings. + * @param settings to inspect + * @param ps the dispatch selector to configure. + * @throws NumberFormatException + ************************************************************************/ + + private void installSocksSelector(Properties settings, + ProtocolDispatchSelector ps) throws NumberFormatException { + String proxyHost = settings.getProperty("/system/proxy/socks_host", null); + int proxyPort = Integer.parseInt(settings.getProperty("/system/proxy/socks_port", "0").trim()); + if (proxyHost != null && proxyHost.length() > 0 && proxyPort > 0) { + Logger.log(getClass(), LogLevel.TRACE, "Gnome socks proxy is {0}:{1}", proxyHost, proxyPort); + ps.setSelector("socks", new FixedProxySelector(proxyHost.trim(), proxyPort)); + } + } + + /************************************************************************* + * @param settings + * @param ps + * @throws NumberFormatException + ************************************************************************/ + + private void installFtpSelector(Properties settings, + ProtocolDispatchSelector ps) throws NumberFormatException { + String proxyHost = settings.getProperty("/system/proxy/ftp_host", null); + int proxyPort = Integer.parseInt(settings.getProperty("/system/proxy/ftp_port", "0").trim()); + if (proxyHost != null && proxyHost.length() > 0 && proxyPort > 0) { + Logger.log(getClass(), LogLevel.TRACE, "Gnome ftp proxy is {0}:{1}", proxyHost, proxyPort); + ps.setSelector("ftp", new FixedProxySelector(proxyHost.trim(), proxyPort)); + } + } + + /************************************************************************* + * @param settings + * @param ps + * @throws NumberFormatException + ************************************************************************/ + + + private void installSecureSelector(Properties settings, + ProtocolDispatchSelector ps) throws NumberFormatException { + String proxyHost = settings.getProperty("/system/proxy/secure_host", null); + int proxyPort = Integer.parseInt(settings.getProperty("/system/proxy/secure_port", "0").trim()); + if (proxyHost != null && proxyHost.length() > 0 && proxyPort > 0) { + Logger.log(getClass(), LogLevel.TRACE, "Gnome secure proxy is {0}:{1}", proxyHost, proxyPort); + ps.setSelector("https", new FixedProxySelector(proxyHost.trim(), proxyPort)); + ps.setSelector("sftp", new FixedProxySelector(proxyHost.trim(), proxyPort)); + } + } + + /************************************************************************* + * Parse the settings file and extract all network.proxy.* settings from it. + * @param context the gconf context to parse. + * @param settings the settings object to fill. + * @return the parsed properties. + * @throws IOException on read error. + ************************************************************************/ + + private Properties parseSettings(String context, Properties settings) throws IOException { + + // Read settings from file + File settingsFile = findSettingsFile(context); + if (settingsFile == null) { + return settings; + } + + try { + DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + documentBuilder.setEntityResolver(new EmptyXMLResolver()); + Document doc = documentBuilder.parse(settingsFile); + Element root = doc.getDocumentElement(); + Node entry = root.getFirstChild(); + while (entry != null) { + if ("entry".equals(entry.getNodeName()) && entry instanceof Element) { + String entryName = ((Element)entry).getAttribute("name"); + settings.setProperty(context+entryName, getEntryValue((Element) entry)); + } + entry = entry.getNextSibling(); + } + } catch (SAXException e) { + Logger.log(getClass(), LogLevel.ERROR, "Gnome settings parse error", e); + throw new IOException(e.getMessage()); + } catch (ParserConfigurationException e) { + Logger.log(getClass(), LogLevel.ERROR, "Gnome settings parse error", e); + throw new IOException(e.getMessage()); + } + + return settings; + } + + /************************************************************************* + * Parse an entry value from a given entry node. + * @param entry the XML node to inspect. + * @return the value, null if it has no value. + ************************************************************************/ + + private String getEntryValue(Element entry) { + String type = entry.getAttribute("type"); + + if ("int".equals(type) || "bool".equals(type)) { + return entry.getAttribute("value"); + } + if ("string".equals(type)) { + NodeList list = entry.getElementsByTagName("stringvalue"); + if (list.getLength() > 0) { + return list.item(0).getTextContent(); + } + } + if ("list".equals(type)) { + StringBuilder result = new StringBuilder(); + NodeList list = entry.getElementsByTagName("li"); + + // Build comma separated list of items + for (int i = 0; i < list.getLength(); i++) { + if (result.length() > 0) { + result.append(","); + } + result.append(getEntryValue((Element) list.item(i))); + } + return result.toString(); + } + return null; + } + +} diff --git a/src/main/java/com/btr/proxy/search/desktop/gnome/ProxySchemasGSettingsAccess.java b/src/main/java/com/btr/proxy/search/desktop/gnome/ProxySchemasGSettingsAccess.java new file mode 100644 index 0000000..6e1b425 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/gnome/ProxySchemasGSettingsAccess.java @@ -0,0 +1,60 @@ +package com.btr.proxy.search.desktop.gnome; + +import java.io.Closeable; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +public class ProxySchemasGSettingsAccess { + + private static void closeStream(Closeable c) { + try { + c.close(); + } catch (IOException e) { + // Ignore cleanup errors + } + } + + static void copy(InputStream source, OutputStream dest) throws IOException { + try { + byte[] buffer = new byte[1024]; + int read = 0; + while (read >= 0) { + dest.write(buffer, 0, read); + read = source.read(buffer); + } + dest.flush(); + } finally { + closeStream(source); + closeStream(dest); + } + } + + static { + String arch = System.getProperty("os.arch"); + if (arch.equals("x86_64") || arch.equals("x64") || arch.equals("x86-64")) { + arch = "amd64"; + } + if (arch.equals("i386") || arch.equals("i686")) { + arch = "x86"; + } + String libName = "gsettings-" + arch + ".so"; + File libFile; + try { + InputStream source = ProxySchemasGSettingsAccess.class.getResourceAsStream("/lib/" + libName); + libFile = File.createTempFile("gsettings", ".so"); + libFile.deleteOnExit(); + FileOutputStream destination = new FileOutputStream(libFile); + copy(source, destination); + } catch (IOException e) { + throw new RuntimeException(e); + } + System.load(libFile.getAbsolutePath()); + } + + public static native Map<String, Map<String, Object>> getValueByKeyBySchema(); + +} diff --git a/src/main/java/com/btr/proxy/search/desktop/kde/KdeProxySearchStrategy.java b/src/main/java/com/btr/proxy/search/desktop/kde/KdeProxySearchStrategy.java new file mode 100644 index 0000000..e05d72e --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/kde/KdeProxySearchStrategy.java @@ -0,0 +1,198 @@ +package com.btr.proxy.search.desktop.kde; + +import java.io.IOException; +import java.net.ProxySelector; +import java.util.Properties; + +import com.btr.proxy.search.ProxySearchStrategy; +import com.btr.proxy.search.env.EnvProxySearchStrategy; +import com.btr.proxy.search.wpad.WpadProxySearchStrategy; +import com.btr.proxy.selector.direct.NoProxySelector; +import com.btr.proxy.selector.fixed.FixedProxySelector; +import com.btr.proxy.selector.misc.ProtocolDispatchSelector; +import com.btr.proxy.selector.pac.PacProxySelector; +import com.btr.proxy.selector.pac.UrlPacScriptSource; +import com.btr.proxy.selector.whitelist.ProxyBypassListSelector; +import com.btr.proxy.selector.whitelist.UseProxyWhiteListSelector; +import com.btr.proxy.util.Logger; +import com.btr.proxy.util.Logger.LogLevel; +import com.btr.proxy.util.ProxyException; +import com.btr.proxy.util.ProxyUtil; + +/***************************************************************************** + * Loads the KDE4 proxy settings from the KDE <i>kioslaverc</i> file. + * This will load properties from the file + * <p> + * <i>.kde/share/config/kioslaverc</i> + * </P> + * starting from the current users home directory. + * <p> + * The following settings are extracted from the section "[Proxy Settings]": + * </p> + * <ul> + * <li><i>AuthMode</i> -> 0 = no auth., 1 = use login.</li> + * <li><i>ProxyType</i> -> 0 = direct 1 = use fixed settings, 2 = use PAC, 3 = automatic (WPAD) , 4 = Use environment variables?</li> + * <li><i>Proxy Config</i> Script -> URL to PAC file</li> + * <li><i>ftpProxy</i> -> Fixed ftp proxy address e.g. http://www.ftp-proxy.com:8080</li> + * <li><i>httpProxy</i> -> Fixed http proxy e.g http://www.http-proxy.com:8080</li> + * <li><i>httpsProxy</i> -> Fixed https proxy e.g http://www.https-proxy.com:8080</li> + * <li><i>NoProxyFor</i> -> Proxy white list</li> + * <li><i>ReversedException</i> -> false = use NoProxyFor, true = revert meaning of the NoProxyFor list</li> + * </ul> + * + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class KdeProxySearchStrategy implements ProxySearchStrategy { + + private KdeSettingsParser settingsParser; + + /************************************************************************* + * ProxySelector using the given parser. + * @see java.net.ProxySelector#ProxySelector() + ************************************************************************/ + + public KdeProxySearchStrategy() { + this(new KdeSettingsParser()); + } + + /************************************************************************* + * ProxySelector + * @see java.net.ProxySelector#ProxySelector() + ************************************************************************/ + + public KdeProxySearchStrategy(KdeSettingsParser settingsParser) { + super(); + this.settingsParser = settingsParser; + } + + /************************************************************************* + * Loads the proxy settings and initializes a proxy selector for the firefox + * proxy settings. + * @return a configured ProxySelector, null if none is found. + * @throws ProxyException on file reading error. + ************************************************************************/ + + public ProxySelector getProxySelector() throws ProxyException { + + Logger.log(getClass(), LogLevel.TRACE, "Detecting Kde proxy settings"); + + Properties settings = readSettings(); + if (settings == null) { + return null; + } + + ProxySelector result = null; + int type = Integer.parseInt(settings.getProperty("ProxyType", "-1")); + switch (type) { + case 0: // Use no proxy + Logger.log(getClass(), LogLevel.TRACE, "Kde uses no proxy"); + result = NoProxySelector.getInstance(); + break; + case 1: // Fixed settings + Logger.log(getClass(), LogLevel.TRACE, "Kde uses manual proxy settings"); + result = setupFixedProxySelector(settings); + break; + case 2: // PAC Script + String pacScriptUrl = settings.getProperty("Proxy Config Script", ""); + Logger.log(getClass(), LogLevel.TRACE, "Kde uses autodetect script {0}", pacScriptUrl); + result = ProxyUtil.buildPacSelectorForUrl(pacScriptUrl); + break; + case 3: // WPAD + Logger.log(getClass(), LogLevel.TRACE, "Kde uses WPAD to detect the proxy"); + result = new WpadProxySearchStrategy().getProxySelector(); + break; + case 4: // Use environment variables + Logger.log(getClass(), LogLevel.TRACE, "Kde reads proxy from environment"); + result = setupEnvVarSelector(settings); + break; + default: + break; + } + + return result; + } + + /************************************************************************* + * Reads the settings and stores them in a properties map. + * @return the parsed settings. + * @throws ProxyException + ************************************************************************/ + + private Properties readSettings() throws ProxyException { + try { + return this.settingsParser.parseSettings(); + } catch (IOException e) { + Logger.log(getClass(), LogLevel.ERROR, "Can't parse settings.", e); + throw new ProxyException(e); + } + } + + /************************************************************************* + * Builds an environment variable selector. + * @param settings the settings to read from. + * @return the ProxySelector using environment variables. + ************************************************************************/ + + private ProxySelector setupEnvVarSelector(Properties settings) { + ProxySelector result; + result = new EnvProxySearchStrategy( + settings.getProperty("httpProxy"), + settings.getProperty("httpsProxy"), + settings.getProperty("ftpProxy"), + settings.getProperty("NoProxyFor") + ).getProxySelector(); + return result; + } + + /************************************************************************* + * Parse the fixed proxy settings and build an ProxySelector for this a + * chained configuration. + * @param settings the proxy settings to evaluate. + ************************************************************************/ + + private ProxySelector setupFixedProxySelector(Properties settings) { + String proxyVar = settings.getProperty("httpProxy", null); + FixedProxySelector httpPS = ProxyUtil.parseProxySettings(proxyVar); + if (httpPS == null) { + Logger.log(getClass(), LogLevel.TRACE, "Kde http proxy is {0}", proxyVar); + return null; + } + + ProtocolDispatchSelector ps = new ProtocolDispatchSelector(); + ps.setSelector("http", httpPS); + + proxyVar = settings.getProperty("httpsProxy", null); + FixedProxySelector httpsPS = ProxyUtil.parseProxySettings(proxyVar); + if (httpsPS != null) { + Logger.log(getClass(), LogLevel.TRACE, "Kde https proxy is {0}", proxyVar); + ps.setSelector("https", httpsPS); + } + + proxyVar = settings.getProperty("ftpProxy", null); + FixedProxySelector ftpPS = ProxyUtil.parseProxySettings(proxyVar); + if (ftpPS != null) { + Logger.log(getClass(), LogLevel.TRACE, "Kde ftp proxy is {0}", proxyVar); + ps.setSelector("ftp", ftpPS); + } + + // Wrap in white list filter. + String noProxyList = settings.getProperty("NoProxyFor", null); + if (noProxyList != null && noProxyList.trim().length() > 0) { + boolean reverse = "true".equals(settings.getProperty("ReversedException", "false")); + if (reverse) { + Logger.log(getClass(), LogLevel.TRACE, "Kde proxy blacklist is {0}", noProxyList); + return new UseProxyWhiteListSelector(noProxyList, ps); + } else { + Logger.log(getClass(), LogLevel.TRACE, "Kde proxy whitelist is {0}", noProxyList); + return new ProxyBypassListSelector(noProxyList, ps); + } + } + + return ps; + } + + + +} diff --git a/src/main/java/com/btr/proxy/search/desktop/kde/KdeSettingsParser.java b/src/main/java/com/btr/proxy/search/desktop/kde/KdeSettingsParser.java new file mode 100644 index 0000000..904528e --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/kde/KdeSettingsParser.java @@ -0,0 +1,132 @@ +package com.btr.proxy.search.desktop.kde; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Properties; + +import com.btr.proxy.util.Logger; +import com.btr.proxy.util.Logger.LogLevel; + +/***************************************************************************** + * Parser for the KDE settings file. + * The KDE proxy settings are stored in the file: + * <p> + * <i>.kde/share/config/kioslaverc</i> + * </p> + * in the users home directory. + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class KdeSettingsParser { + + private File settingsFile; + + /************************************************************************* + * Constructor + ************************************************************************/ + + public KdeSettingsParser() { + this(null); + } + + /************************************************************************* + * Constructor + ************************************************************************/ + + public KdeSettingsParser(File settingsFile) { + super(); + this.settingsFile = settingsFile; + } + + /************************************************************************* + * Parse the settings file and extract all network.proxy.* settings from it. + * @return the parsed properties. + * @throws IOException on read error. + ************************************************************************/ + + public Properties parseSettings() throws IOException { + // Search for existing settings. + if (this.settingsFile == null) { + this.settingsFile = findSettingsFile(); + } + if (this.settingsFile == null) { + return null; + } + + // Read settings from file. + BufferedReader fin = new BufferedReader( + new InputStreamReader( + new FileInputStream(this.settingsFile))); + + Properties result = new Properties(); + try { + String line = fin.readLine(); + + // Find section start. + while (line != null && !"[Proxy Settings]".equals(line.trim())) { + line = fin.readLine(); + } + if (line == null) { + return result; + } + + // Read full section + line = ""; + while (line != null && !line.trim().startsWith("[")) { + line = line.trim(); + int index = line.indexOf('='); + if (index > 0) { + String key = line.substring(0, index).trim(); + String value = line.substring(index+1).trim(); + result.setProperty(key, value); + } + + line = fin.readLine(); + } + } finally { + fin.close(); + } + + return result; + } + + /************************************************************************* + * Finds all the KDE network settings file. + * @return a file or null if does not exist. + ************************************************************************/ + + private File findSettingsFile() { + File userDir = new File(System.getProperty("user.home")); + if ("4".equals(System.getenv("KDE_SESSION_VERSION"))) { + this.settingsFile = findSettingsFile( + new File(userDir, ".kde4"+File.separator+"share"+File.separator+"config"+File.separator+"kioslaverc")); + } + if (this.settingsFile == null) { + return findSettingsFile( + new File(userDir, ".kde"+File.separator+"share"+File.separator+"config"+File.separator+"kioslaverc")); + } else { + return this.settingsFile; + } + } + + /************************************************************************* + * Internal method to test if the settings file is at the given place. + * @param settingsFile the path to test. + * @return the file or null if it does not exist. + ************************************************************************/ + + private File findSettingsFile(File settingsFile) { + Logger.log(getClass(), LogLevel.TRACE, "Searching Kde settings in {0}", settingsFile); + if (!settingsFile.exists()) { + Logger.log(getClass(), LogLevel.DEBUG, "Settings not found"); + return null; + } + Logger.log(getClass(), LogLevel.TRACE, "Settings found"); + return settingsFile; + } + +} diff --git a/src/main/java/com/btr/proxy/search/desktop/osx/OsxProxySearchStrategy.java b/src/main/java/com/btr/proxy/search/desktop/osx/OsxProxySearchStrategy.java new file mode 100644 index 0000000..3d67ae7 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/osx/OsxProxySearchStrategy.java @@ -0,0 +1,325 @@ +package com.btr.proxy.search.desktop.osx; + +import java.io.File; +import java.io.IOException; +import java.net.NetworkInterface; +import java.net.ProxySelector; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; + +import com.btr.proxy.search.ProxySearchStrategy; +import com.btr.proxy.search.browser.ie.IELocalByPassFilter; +import com.btr.proxy.search.wpad.WpadProxySearchStrategy; +import com.btr.proxy.selector.direct.NoProxySelector; +import com.btr.proxy.selector.fixed.FixedProxySelector; +import com.btr.proxy.selector.fixed.FixedSocksSelector; +import com.btr.proxy.selector.misc.ProtocolDispatchSelector; +import com.btr.proxy.selector.whitelist.ProxyBypassListSelector; +import com.btr.proxy.util.Logger; +import com.btr.proxy.util.Logger.LogLevel; +import com.btr.proxy.util.PListParser; +import com.btr.proxy.util.PListParser.Dict; +import com.btr.proxy.util.PListParser.XmlParseException; +import com.btr.proxy.util.ProxyException; +import com.btr.proxy.util.ProxyUtil; +import com.btr.proxy.util.UriFilter; + +/***************************************************************************** + * Loads the OSX system proxy settings from the settings file. + * <p> + * All settings are stored in OSX in a special XML file format. + * These settings file are named plist files and contain nested dictionaries, arrays and values. + * </p><p> + * To parse this file we use a parser that is derived from a plist parser that + * comes with the xmlwise XML parser package: + * </p><p> + * http://code.google.com/p/xmlwise/ + * </p><p> + * I modified that parser to work with the default Java XML parsing library. + * </p><p> + * The plist file is located on OSX at: + * </p><p> + * /Library/Preferences/SystemConfiguration/preferences.plist + * </p> + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2011 + ****************************************************************************/ + +public class OsxProxySearchStrategy implements ProxySearchStrategy { + + public static final String OVERRIDE_SETTINGS_FILE = "com.btr.proxy.osx.settingsFile"; + public static final String OVERRIDE_ACCEPTED_DEVICES = "com.btr.proxy.osx.acceptedDevices"; + + private static final String SETTINGS_FILE = "/Library/Preferences/SystemConfiguration/preferences.plist"; + + /************************************************************************* + * ProxySelector + * @see java.net.ProxySelector#ProxySelector() + ************************************************************************/ + + public OsxProxySearchStrategy() { + super(); + } + + /************************************************************************* + * Loads the proxy settings and initializes a proxy selector for the OSX + * proxy settings. + * @return a configured ProxySelector, null if none is found. + * @throws ProxyException on file reading error. + ************************************************************************/ + + public ProxySelector getProxySelector() throws ProxyException { + + Logger.log(getClass(), LogLevel.TRACE, "Detecting OSX proxy settings"); + + try { + List<String> acceptedInterfaces = getNetworkInterfaces(); + + Dict settings = PListParser.load(getSettingsFile()); + Object currentSet = settings.getAtPath("/CurrentSet"); + if (currentSet == null) { + throw new ProxyException("CurrentSet not defined"); + } + + Dict networkSet = (Dict) settings.getAtPath(String.valueOf(currentSet)); + List<?> serviceOrder = (List<?>) networkSet.getAtPath("/Network/Global/IPv4/ServiceOrder"); + if (serviceOrder == null || serviceOrder.size() == 0) { + throw new ProxyException("ServiceOrder not defined"); + } + + // Look at the Services in priority order and pick the first one that was + // also accepted above + Dict proxySettings = null; + for (int i = 0; i < serviceOrder.size() && proxySettings == null; i++) { + Object candidateService = serviceOrder.get(i); + Object networkService = networkSet.getAtPath("/Network/Service/"+candidateService+"/__LINK__"); + if (networkService == null ) { + throw new ProxyException("NetworkService not defined."); + } + Dict selectedServiceSettings = (Dict) settings.getAtPath(""+networkService); + String interfaceName = (String) selectedServiceSettings.getAtPath("/Interface/DeviceName"); + if (acceptedInterfaces.contains(interfaceName)) { + Logger.log(getClass(), LogLevel.TRACE, "Looking up proxies for device " + interfaceName); + proxySettings = (Dict) selectedServiceSettings.getAtPath("/Proxies"); + } + } + if (proxySettings == null) { + return NoProxySelector.getInstance(); + } + + return buildSelector(proxySettings); + } catch (XmlParseException e) { + throw new ProxyException(e); + } catch (IOException e) { + throw new ProxyException(e); + } + } + + /************************************************************************* + * Build a selector from the given settings. + * @param proxySettings to parse + * @return the configured selector + * @throws ProxyException on error + ************************************************************************/ + + private ProxySelector buildSelector(Dict proxySettings) throws ProxyException { + ProtocolDispatchSelector ps = new ProtocolDispatchSelector(); + installSelectorForProtocol(proxySettings, ps, "HTTP"); + installSelectorForProtocol(proxySettings, ps, "HTTPS"); + installSelectorForProtocol(proxySettings, ps, "FTP"); + installSelectorForProtocol(proxySettings, ps, "Gopher"); + installSelectorForProtocol(proxySettings, ps, "RTSP"); + installSocksProxy(proxySettings, ps); + + ProxySelector result = ps; + result = installPacProxyIfAvailable(proxySettings, result); + result = autodetectProxyIfAvailable(proxySettings, result); + + result = installExceptionList(proxySettings, result); + result = installSimpleHostFilter(proxySettings, result); + return result; + } + + /************************************************************************* + * Create a list of Ethernet interfaces that are connected + * @return + * @throws SocketException + ************************************************************************/ + + private List<String> getNetworkInterfaces() throws SocketException { + String override = System.getProperty(OVERRIDE_ACCEPTED_DEVICES); + if (override != null && override.length() > 0) { + return Arrays.asList(override.split(";")); + } + + List<String> acceptedInterfaces = new ArrayList<String>(); + Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); + while (interfaces.hasMoreElements()) { + NetworkInterface ni = interfaces.nextElement(); + if (isInterfaceAllowed(ni)) { + acceptedInterfaces.add(ni.getName()); + } + } + return acceptedInterfaces; + } + + /************************************************************************* + * Check if a given network interface is interesting for us. + * @param ni the interface to check + * @return true if accepted else false. + * @throws SocketException on error. + ************************************************************************/ + + private boolean isInterfaceAllowed(NetworkInterface ni) throws SocketException { + return !ni.isLoopback() && + !ni.isPointToPoint() && // Not sure if we should filter the point to point interfaces? + !ni.isVirtual() && + ni.isUp(); + } + + /************************************************************************* + * @return + ************************************************************************/ + + private File getSettingsFile() { + File result = new File(SETTINGS_FILE); + String overrideFile = System.getProperty(OVERRIDE_SETTINGS_FILE); + if (overrideFile != null) { + return new File(overrideFile); + } + return result; + } + + /************************************************************************* + * @param proxySettings + * @param result + * @return + ************************************************************************/ + + private ProxySelector installSimpleHostFilter( + Dict proxySettings, ProxySelector result) { + if (isActive(proxySettings.get("ExcludeSimpleHostnames"))) { + List<UriFilter> localBypassFilter = new ArrayList<UriFilter>(); + localBypassFilter.add(new IELocalByPassFilter()); + result = new ProxyBypassListSelector(localBypassFilter, result); + } + return result; + } + + /************************************************************************* + * @param proxySettings + * @param result + * @return + ************************************************************************/ + + private ProxySelector installExceptionList( + Dict proxySettings, ProxySelector result) { + List<?> proxyExceptions = (List<?>) proxySettings.get("ExceptionsList"); + if (proxyExceptions != null && proxyExceptions.size() > 0) { + Logger.log(getClass(), LogLevel.TRACE, "OSX uses proxy bypass list: {0}", proxyExceptions); + String noProxyList = toCommaSeparatedString(proxyExceptions); + result = new ProxyBypassListSelector(noProxyList, result); + } + return result; + } + + /************************************************************************* + * Convert a list to a comma separated list. + * @param proxyExceptions list of elements. + * @return a comma separated string of the list's content. + ************************************************************************/ + + private String toCommaSeparatedString(List<?> proxyExceptions) { + StringBuilder result = new StringBuilder(); + for (Object object : proxyExceptions) { + if (result.length() > 0) { + result.append(","); + } + result.append(object); + } + return result.toString(); + } + + /************************************************************************* + * @param proxySettings + * @param result + * @return + * @throws ProxyException + ************************************************************************/ + + private ProxySelector autodetectProxyIfAvailable( + Dict proxySettings, ProxySelector result) + throws ProxyException { + if (isActive(proxySettings.get("ProxyAutoDiscoveryEnable"))) { + ProxySelector wp = new WpadProxySearchStrategy().getProxySelector(); + if (wp != null) { + result = wp; + } + } + return result; + } + + /************************************************************************* + * @param proxySettings + * @param result + * @return + ************************************************************************/ + + private ProxySelector installPacProxyIfAvailable(Dict proxySettings, + ProxySelector result) { + if (isActive(proxySettings.get("ProxyAutoConfigEnable"))) { + String url = (String) proxySettings.get("ProxyAutoConfigURLString"); + result = ProxyUtil.buildPacSelectorForUrl(url); + } + return result; + } + + /************************************************************************* + * Build a socks proxy and set it for the socks protocol. + * @param proxySettings to read the config values from. + * @param ps the ProtocolDispatchSelector to install the new proxy on. + ************************************************************************/ + + private void installSocksProxy(Dict proxySettings, + ProtocolDispatchSelector ps) { + if (isActive(proxySettings.get("SOCKSEnable"))) { + String proxyHost = (String) proxySettings.get("SOCKSProxy"); + int proxyPort = (Integer) proxySettings.get("SOCKSPort"); + ps.setSelector("socks", new FixedSocksSelector(proxyHost, proxyPort)); + Logger.log(getClass(), LogLevel.TRACE, "OSX socks proxy is {0}:{1}", proxyHost, proxyPort); + } + } + + /************************************************************************* + * Installs a proxy selector for the given protocoll on the ProtocolDispatchSelector + * @param proxySettings to read the config for the procotol from. + * @param ps the ProtocolDispatchSelector to install the new selector on. + * @param protocol to use. + ************************************************************************/ + + private void installSelectorForProtocol(Dict proxySettings, + ProtocolDispatchSelector ps, String protocol) { + String prefix = protocol.trim(); + if (isActive(proxySettings.get(prefix+"Enable"))) { + String proxyHost = (String) proxySettings.get(prefix+"Proxy"); + int proxyPort = (Integer) proxySettings.get(prefix+"Port"); + FixedProxySelector fp = new FixedProxySelector(proxyHost, proxyPort); + ps.setSelector(protocol.toLowerCase(), fp); + Logger.log(getClass(), LogLevel.TRACE, "OSX uses for {0} the proxy {1}:{2}", protocol, proxyHost, proxyPort); + } + } + + /************************************************************************* + * Checks if the given value is set to "on". + * @param value the value to test. + * @return true if it is set else false. + ************************************************************************/ + + private boolean isActive(Object value) { + return Integer.valueOf(1).equals(value); + } + +} diff --git a/src/main/java/com/btr/proxy/search/desktop/win/DLLManager.java b/src/main/java/com/btr/proxy/search/desktop/win/DLLManager.java new file mode 100644 index 0000000..8d67984 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/win/DLLManager.java @@ -0,0 +1,171 @@ +package com.btr.proxy.search.desktop.win; + +import java.io.Closeable; +import java.io.File; +import java.io.FileFilter; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import com.btr.proxy.util.Logger; +import com.btr.proxy.util.Logger.LogLevel; + +/***************************************************************************** + * This class provides some helper methods to work with the dll + * extracting /loading for windows. + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +final class DLLManager { + + private static final class TempDLLFileFilter implements FileFilter { + public boolean accept(File pathname) { + String name = pathname.getName(); + return pathname.isFile() && + name.startsWith(TEMP_FILE_PREFIX) && + name.endsWith(DLL_EXTENSION); + } + } + + public static final String LIB_DIR_OVERRIDE = "proxy_vole_lib_dir"; + + static final String TEMP_FILE_PREFIX = "proxy_vole"; + static final String DLL_EXTENSION = ".dll"; + static String LIB_NAME_BASE = "proxy_util_"; + static final String DEFAULT_LIB_FOLDER = "lib"; + + /************************************************************************* + * Find the location of the native code dll file. + * @return the File pointing to the dll. + * @throws IOException on IO error. + ************************************************************************/ + + static File findLibFile() throws IOException { + String libName = buildLibName(); + File libFile = getOverrideLibFile(libName); + if (libFile == null || libFile.exists() == false) { + libFile = getDefaultLibFile(libName); + } + if (libFile == null || libFile.exists() == false) { + libFile = extractToTempFile(libName); + } + return libFile; + } + + /************************************************************************* + * Delete old temp files that may be there because they were extracted + * from the jar but could not be deleted on VM shutdown because they + * are still locked by windows. + * This is here to prevent a lot of temp dll files on disk. + ************************************************************************/ + + static void cleanupTempFiles() { + try { + String tempFolder = System.getProperty("java.io.tmpdir"); + if (tempFolder == null || tempFolder.trim().length() == 0) { + return; + } + File fldr = new File(tempFolder); + File[] oldFiles = fldr.listFiles(new TempDLLFileFilter()); + if (oldFiles == null) { + return; + } + for (File tmp : oldFiles) { + tmp.delete(); + } + } catch (Exception e) { + Logger.log(DLLManager.class, LogLevel.DEBUG, "Error cleaning up temporary dll files. ", e); + } + } + + /************************************************************************* + * @param libName + * @return + ************************************************************************/ + + private static File getDefaultLibFile(String libName) { + return new File(DEFAULT_LIB_FOLDER, libName); + } + + /************************************************************************* + * Gets the file name that was overriden via system property. + * @param libName + * @return the file, null if it is not existing. + ************************************************************************/ + + private static File getOverrideLibFile(String libName) { + String libDir = System.getProperty(LIB_DIR_OVERRIDE); + if (libDir == null || libDir.trim().length() == 0) { + return null; + } + return new File(libDir, libName); + } + + /************************************************************************* + * @param libName + * @return + * @throws IOException + * @throws FileNotFoundException + ************************************************************************/ + + static File extractToTempFile(String libName) throws IOException { + InputStream source = Win32ProxyUtils.class.getResourceAsStream("/"+DEFAULT_LIB_FOLDER+"/"+libName); + File tempFile = File.createTempFile(TEMP_FILE_PREFIX, DLL_EXTENSION); + tempFile.deleteOnExit(); + FileOutputStream destination = new FileOutputStream(tempFile); + copy(source, destination); + return tempFile; + } + + /************************************************************************* + * @param c a closeable to cleanup ignoring all errors. + ************************************************************************/ + + private static void closeStream(Closeable c) { + try { + c.close(); + } catch (IOException e) { + // Ignore cleanup errors + } + } + + /************************************************************************* + * Copies the content from source to destination. + * @param source + * @param dest + * @throws IOException + ************************************************************************/ + + static void copy(InputStream source, OutputStream dest) + throws IOException { + try { + byte[] buffer = new byte[1024]; + int read = 0; + while (read >= 0) { + dest.write(buffer, 0, read); + read = source.read(buffer); + } + dest.flush(); + } finally { + closeStream(source); + closeStream(dest); + } + } + + /************************************************************************* + * @return the name of the dll valid for the current architecture. + ************************************************************************/ + + private static String buildLibName() { + String arch = "w32"; + if(!System.getProperty("os.arch").equals("x86") ) { + arch = System.getProperty("os.arch"); + } + return LIB_NAME_BASE + arch + DLL_EXTENSION; + } + +} + diff --git a/src/main/java/com/btr/proxy/search/desktop/win/Win32IESettings.java b/src/main/java/com/btr/proxy/search/desktop/win/Win32IESettings.java new file mode 100644 index 0000000..ef91a22 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/win/Win32IESettings.java @@ -0,0 +1,68 @@ +package com.btr.proxy.search.desktop.win;
+
+/*****************************************************************************
+ * Proxy settings container used for the native methods.
+ * Will contain the Internet Explorer proxy settings as reported by windows
+ * WinHTTP API.
+ *
+ * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
+ ****************************************************************************/
+
+public class Win32IESettings {
+
+ private boolean autoDetect;
+ private String autoConfigUrl;
+ private String proxy;
+ private String proxyBypass;
+
+ /*************************************************************************
+ * Constructor
+ * @param autoDetect flag is autodetect is active or not.
+ * @param autoConfigUrl the URL for a PAC script
+ * @param proxy the proxy server selected
+ * @param proxyBypass the proxy bypass address list.
+ ************************************************************************/
+
+ public Win32IESettings(boolean autoDetect, String autoConfigUrl, String proxy, String proxyBypass) {
+ super();
+ this.autoDetect = autoDetect;
+ this.autoConfigUrl = autoConfigUrl;
+ this.proxy = proxy;
+ this.proxyBypass = proxyBypass;
+ }
+
+ /*************************************************************************
+ * @return Returns the autoDetect.
+ ************************************************************************/
+
+ public boolean isAutoDetect() {
+ return this.autoDetect;
+ }
+
+ /*************************************************************************
+ * @return Returns the autoConfigUrl.
+ ************************************************************************/
+
+ public String getAutoConfigUrl() {
+ return this.autoConfigUrl;
+ }
+
+ /*************************************************************************
+ * @return Returns the proxy.
+ ************************************************************************/
+
+ public String getProxy() {
+ return this.proxy;
+ }
+
+ /*************************************************************************
+ * @return Returns the proxyBypass.
+ ************************************************************************/
+
+ public String getProxyBypass() {
+ return this.proxyBypass;
+ }
+
+
+}
+
diff --git a/src/main/java/com/btr/proxy/search/desktop/win/Win32ProxyUtils.java b/src/main/java/com/btr/proxy/search/desktop/win/Win32ProxyUtils.java new file mode 100644 index 0000000..fb1f0b3 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/win/Win32ProxyUtils.java @@ -0,0 +1,88 @@ +package com.btr.proxy.search.desktop.win;
+
+import java.io.File;
+import java.io.IOException;
+
+/*****************************************************************************
+ * Defines the native methods used for windows to extract some system information.
+ * <p>
+ * This class will need some native code from the library proxy_util_"arch".dll.
+ * To load this library we use a three step algorithm as following:
+ * </p><P>
+ * First check the System property "proxy_vole_lib_dir" if it is set and
+ * it points to a folder where the dll is found than the dll from this
+ * folder is loaded as e.g. <i>"proxy_vole_lib_dir"/proxy_util_w32.dll</i>
+ * </p><p>
+ * Second we try to load the dll from the subfolder <i>lib</i> if that one exists.<br>
+ * Finally if we are inside of a jar file we need to extract the dll file
+ * to a temp-file because windows can not load dlls from a jar
+ * directly. This is a hack but it may work.
+ * </p><p>
+ * Please note that the file is named Win32ProxyUtils but has now also support
+ * for x64 architecture.
+ * </p>
+ * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
+ ****************************************************************************/
+
+public class Win32ProxyUtils {
+
+ public static final int WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001;
+ public static final int WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002;
+
+
+ // Code for loading the windows native dll
+ static {
+ try {
+ File libFile = DLLManager.findLibFile();
+ System.load(libFile.getAbsolutePath());
+ DLLManager.cleanupTempFiles();
+ } catch (IOException e) {
+ throw new RuntimeException("Error loading dll"+e.getMessage(), e);
+ }
+ }
+
+ /*************************************************************************
+ * Constructor
+ ************************************************************************/
+
+ public Win32ProxyUtils() {
+ super();
+ }
+
+ /*************************************************************************
+ * WinHTTP method to detect an PAC URL.
+ * @param mode the mode to use.
+ * @return the PAC URL, null if none was found.
+ ************************************************************************/
+
+ public native String winHttpDetectAutoProxyConfigUrl(int mode);
+
+ /*************************************************************************
+ * Gets the default windows proxy settings.
+ * The returned string will have the following format.
+ * TYPE PROXY | BYPASSLIST
+ * <p>
+ * e.g. DIRECT myproxy.mycompany.com:8080 | *.mycompany.com, localhost
+ * </p>
+ * @return a string containing all info, null if not found.
+ ************************************************************************/
+ // TODO Not implemented correctly in DLL yet.
+ native String winHttpGetDefaultProxyConfiguration();
+
+ /*************************************************************************
+ * Extracts the Internet Explorer proxy settings from the Windows system.
+ * @return a data structure containing all details, null on fail.
+ ************************************************************************/
+
+ public native Win32IESettings winHttpGetIEProxyConfigForCurrentUser();
+
+ /*************************************************************************
+ * Extracts the Internet Explorer proxy settings from the Windows system.
+ * @return a data structure containing all details, null on fail.
+ ************************************************************************/
+
+ public native String readUserHomedir();
+
+
+}
+
diff --git a/src/main/java/com/btr/proxy/search/desktop/win/WinProxySearchStrategy.java b/src/main/java/com/btr/proxy/search/desktop/win/WinProxySearchStrategy.java new file mode 100644 index 0000000..1f26505 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/desktop/win/WinProxySearchStrategy.java @@ -0,0 +1,52 @@ +package com.btr.proxy.search.desktop.win; + +import java.net.ProxySelector; + +import com.btr.proxy.search.ProxySearchStrategy; +import com.btr.proxy.search.browser.ie.IEProxySearchStrategy; +import com.btr.proxy.util.ProxyException; + +/***************************************************************************** + * Extracts the proxy settings from the windows registry. + * This will read the windows system proxy settings. + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class WinProxySearchStrategy implements ProxySearchStrategy { + + /************************************************************************* + * Constructor + ************************************************************************/ + + public WinProxySearchStrategy() { + super(); + } + + /************************************************************************* + * getProxySelector + * @see com.btr.proxy.search.ProxySearchStrategy#getProxySelector() + ************************************************************************/ + + public ProxySelector getProxySelector() throws ProxyException { + // TODO Rossi 08.05.2009 Implement this by using Win API calls. + // new Win32ProxyUtils().winHttpGetDefaultProxyConfiguration() + // Current fallback is to use the IE settings. This is better + // because the registry settings are most of the time not set. + // Some Windows server installations may use it though. + return new IEProxySearchStrategy().getProxySelector(); + } + + /************************************************************************* + * Loads the settings. + * @return a WinIESettings object containing all proxy settings. + ************************************************************************/ + + public Win32IESettings readSettings() { + return new IEProxySearchStrategy().readSettings(); + } + + + + +} |