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. *

* Note: at the moment only the DNS name guessing schema is implemented. * All others are missing. *

* For more information about WPAD: * Web_Proxy_Autodiscovery_Protocol *

* Outdated RFC draft: * draft-ietf-wrec-wpad-01.txt *

* @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 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); } } }