diff options
Diffstat (limited to 'src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java')
-rw-r--r-- | src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java b/src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java new file mode 100644 index 0000000..cf01fd3 --- /dev/null +++ b/src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java @@ -0,0 +1,234 @@ +package com.btr.proxy.search.wpad; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.HttpURLConnection; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.net.UnknownHostException; +import java.util.List; +import java.util.Properties; + +import com.btr.proxy.search.ProxySearchStrategy; +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; + + +/***************************************************************************** + * Uses automatic proxy script search (WPAD) to find an PAC file automatically. + * <p> + * Note: at the moment only the DNS name guessing schema is implemented. + * All others are missing. + * </p><p> + * For more information about WPAD: + * <a href="http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol">Web_Proxy_Autodiscovery_Protocol</a> + * </p><p> + * Outdated RFC draft: + * <a href="http://www.web-cache.com/Writings/Internet-Drafts/draft-ietf-wrec-wpad-01.txt">draft-ietf-wrec-wpad-01.txt</a> + * </p> + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class WpadProxySearchStrategy implements ProxySearchStrategy { + + /************************************************************************* + * Constructor + ************************************************************************/ + + public WpadProxySearchStrategy() { + super(); + } + + /************************************************************************* + * Loads the proxy settings from a PAC file. + * The location of the PAC file is determined automatically. + * @return a configured ProxySelector, null if none is found. + * @throws ProxyException on error. + ************************************************************************/ + + public ProxySelector getProxySelector() throws ProxyException { + try { + Logger.log(getClass(), LogLevel.TRACE, "Using WPAD to find a proxy"); + + String pacScriptUrl = detectScriptUrlPerDHCP(); + if (pacScriptUrl == null) { + pacScriptUrl = detectScriptUrlPerDNS(); + } + if (pacScriptUrl == null) { + return null; + } + Logger.log(getClass(), LogLevel.TRACE, "PAC script url found: {0}", pacScriptUrl); + return ProxyUtil.buildPacSelectorForUrl(pacScriptUrl); + } catch (IOException e) { + Logger.log(getClass(), LogLevel.ERROR, "Error during WPAD search.", e); + throw new ProxyException(e); + } + } + + /************************************************************************* + * Loads the settings and stores them in a properties map. + * @return the settings. + ************************************************************************/ + + public Properties readSettings() { + try { + String pacScriptUrl = detectScriptUrlPerDHCP(); + if (pacScriptUrl == null) { + pacScriptUrl = detectScriptUrlPerDNS(); + } + if (pacScriptUrl == null) { + return null; + } + Properties result = new Properties(); + result.setProperty("url", pacScriptUrl); + return result; + } catch (IOException e) { + // Ignore and return empty properties. + return new Properties(); + } + } + + /************************************************************************* + * Uses DNS to find the script URL. + * Attention: this detection method is known to have some severe security issues. + * @return the URL, null if not found. + ************************************************************************/ + + private String detectScriptUrlPerDNS() throws IOException { + String result = null; + // String fqdn = InetAddress.getLocalHost().getCanonicalHostName(); + + Logger.log(getClass(), LogLevel.TRACE, "Searching per DNS guessing."); + // Logger.log(getClass(), LogLevel.INFO, "fqdn: ", fqdn); + + /** Reading address from "/etc/resolv.conf"; file looks like: + * + # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) + # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN + nameserver 127.0.1.1 + search ruf.uni-freiburg.de lp.ruf.uni-freiburg.de + */ + + FileReader fr = new FileReader("/etc/resolv.conf"); + BufferedReader br = new BufferedReader(fr); + + String input; + String[] addresses = null; + // using the 4th line of the file. + while ((input = br.readLine()) != null) { + if (input.startsWith("search")) { + // the first one is "search" and afterwards addresses are following. + addresses = input.substring(6).split(" "); + break; + } + } + + if (addresses == null) { + addresses = new String[]{""}; + } + + + for (int i = 0; i < addresses.length; ++i) { + String address = addresses[i]; + int index = -1; + do { + if (index != -1) { + address = address.substring(index); + } else { + address = ""; + } + + // Try to connect to URL + try { + address = ".uni-freiburg.de"; + URL lookupURL = new URL("http://wpad"+ address +"/wpad.dat"); + Logger.log(getClass(), LogLevel.TRACE, "Trying url: {0}", lookupURL); + + HttpURLConnection con = (HttpURLConnection) lookupURL.openConnection(Proxy.NO_PROXY); + con.setInstanceFollowRedirects(true); + con.setRequestProperty("accept", "application/x-ns-proxy-autoconfig"); + if (con.getResponseCode() == 200) { + result = lookupURL.toString(); + return result; + } + con.disconnect(); + } catch (UnknownHostException e) { + Logger.log(getClass(), LogLevel.DEBUG, "Not available!"); + // Not a real error, try next address + } + if (address.length() == 0) { + break; + } + index = address.indexOf('.', 1); + } while (true); + } + + return null; + } + + /************************************************************************* + * Uses DHCP to find the script URL. + * @return the URL, null if not found. + ************************************************************************/ + + private String detectScriptUrlPerDHCP() { + Logger.log(getClass(), LogLevel.DEBUG, "Searching per DHCP not supported yet."); + // TODO Rossi 28.04.2009 Not implemented yet. + return null; + } + + // Main method for testing. + public static void main( String[] args ) throws IOException { + WpadProxySearchStrategy wPSS = new WpadProxySearchStrategy(); +// System.setProperty("com.btr.proxy.pac.overrideLocalIP", "10.0.0.1"); + try { + ProxySelector pS = wPSS.getProxySelector(); + ProxySelector.setDefault(pS); + List<Proxy> proxyList = pS.select(new URI("http://www.google.de")); + + if (proxyList.isEmpty()) { + Logger.log(WpadProxySearchStrategy.class, LogLevel.INFO, "ProxyList is empty!"); + } else { + Logger.log(WpadProxySearchStrategy.class, LogLevel.INFO, "proxyList contains: {0}", proxyList.toString()); + } + } catch (ProxyException e) { + // TODO bjoern 28.10.2014 Auto-generated catch block + e.printStackTrace(); + } catch (URISyntaxException e) { + // TODO bjoern 28.10.2014 Auto-generated catch block + e.printStackTrace(); + } + + URL test = new URL("http://www.google.de"); + URLConnection uc = test.openConnection(); + BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream())); + + String inputLine; + while ((inputLine = br.readLine()) != null) { + System.out.println(inputLine); + } + + Socket socket = new Socket("www.google.de", 80); + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + bw.write("GET / HTTP/1.1\r\nHost: www.google.de\r\nConnection: close\r\nAccept-Encoding: *\r\n\r\n"); + bw.flush(); + + br = new BufferedReader(new InputStreamReader(socket.getInputStream())); + while ((inputLine = br.readLine()) != null) { + System.out.println(inputLine); + } + + } + +} |