package org.owasp.webscarab.util; /** * Provides a method of interacting with the Windows WinInet utility DLL. * This is obviously only interesting on a MS Windows platform. Most usefully, it * provides JNI methods of getting and setting the Internet Explorer proxy settings, * in such a way that the changes affect all existing running instances of Internet Explorer immediately, * and the user does NOT need to exit the browser for the changes to be effective. */ public class W32WinInet { /** * Specifies that some connections may be made directly to the server, bypassing the proxy */ public static int PROXY_TYPE_DIRECT = 0x00000001; // direct to net /** * Specifies that some connections may go via a proxy */ public static int PROXY_TYPE_PROXY = 0x00000002; // via named proxy /** * Not sure exactly what this one does. Maybe that a .pac file is active? */ public static int PROXY_TYPE_AUTO_PROXY_URL = 0x00000004; // autoproxy URL /** * Specifies that the browser will auto detect the proxy, according to the MS auto-detect methodology */ public static int PROXY_TYPE_AUTO_DETECT = 0x00000008; // use autoproxy detection private static boolean _available = false; private static boolean _intercepted = false; private static long _perConn = 0; private static String _proxyServer = null; private static String _proxyBypass = null; private native static int testLibraryLoad(); private native static long getInternetPerConnFlags(); private native static long getAutoDiscoveryFlags(); private native static String getAutoConfigUrl(); private native static String getProxyServer(); private native static String getProxyBypass(); private native static int setProxy(long perConnFlags, String proxyServer, String proxyBypass); static { try { System.loadLibrary("W32WinInet"); if (testLibraryLoad() == 1) _available = true; } catch (UnsatisfiedLinkError ule) { _available = false; } } /** * Allows the caller to test whether the native library was successfully loaded. * @return true if the native library was successfully loaded, false otherwise */ public static boolean isAvailable() { return _available; } /** * Causes the existing WinInet proxy settings to be saved, and the new proxy settings supplied to be configured * This sets the proxy for ALL services, and ensures that ALL connections go through the supplied proxy, including * connections to local servers. * @param server the name or address of the proxy server * @param port the port of the proxy server * @return true if the settings were successfully replaced, false otherwise */ public static boolean interceptProxy(String server, int port) { if (!isAvailable()) return false; if (! _intercepted) { _perConn = getInternetPerConnFlags(); _proxyServer = getProxyServer(); _proxyBypass = getProxyBypass(); } int result = setProxy(PROXY_TYPE_PROXY, server + ":" + port, null); if (result != 0) { result = setProxy(_perConn, _proxyServer, _proxyBypass); return false; } _intercepted = true; return true; } /** * resets the WinInet proxy settings to their original values */ public static void revertProxy() { if (! _intercepted) return; int result = setProxy(_perConn, _proxyServer, _proxyBypass); _intercepted = false; } private static String getProxy(String type) { String proxy; if (_intercepted) { proxy = _proxyServer; } else { proxy = getProxyServer(); } if (proxy == null) return null; String[] proxies; if (proxy.indexOf("=")>0) { proxies = proxy.split(";"); } else { return proxy; } for (int i=0; i<proxies.length; i++) { if (proxies[i].startsWith(type+"=")) { return proxies[i].substring(proxies[i].indexOf("=")+1); } } return null; } /** * gets the name or address of the original WinInet HTTP proxy server, regardless of * any intercepts that may have been made. * @return the name or address of the WinInet proxy server */ public static String getHttpProxyServer() { String proxy = getProxy("http"); if (proxy == null) return null; return proxy.substring(0, proxy.indexOf(":")); } /** * gets the port of the original WinInet HTTP proxy server, regardless of * any intercepts that may have been made. * @return the port of the WinInet proxy server, or -1 if none is configured or there is an error parsing the port number */ public static int getHttpProxyPort() { String proxy = getProxy("http"); if (proxy == null) return -1; try { return Integer.parseInt(proxy.substring(proxy.indexOf(":")+1)); } catch (NumberFormatException nfe) { return -1; } } /** * gets the name or address of the original WinInet HTTPS proxy server, regardless of * any intercepts that may have been made. * @return the name or address of the WinInet proxy server */ public static String getHttpsProxyServer() { String proxy = getProxy("https"); if (proxy == null) return null; return proxy.substring(0, proxy.indexOf(":")); } /** * gets the port of the original WinInet HTTPS proxy server, regardless of * any intercepts that may have been made. * @return the port of the WinInet proxy server, or -1 if none is configured or there is an error parsing the port number */ public static int getHttpsProxyPort() { String proxy = getProxy("https"); if (proxy == null) return -1; try { return Integer.parseInt(proxy.substring(proxy.indexOf(":")+1)); } catch (NumberFormatException nfe) { return -1; } } /** * returns the original WinInet list of hosts or addresses that should be * connected to directly, rather than using the proxy. * @return a semi-colon separated list of hosts or addresses */ public static String getNoProxy() { String bypass; if (!_intercepted) { bypass = getProxyBypass(); } else { bypass = _proxyBypass; } if (bypass == null) return null; return bypass; } public static void main(String[] args) throws Exception { if (!isAvailable()) { System.err.println("DLL not found, or wrong platform!"); System.exit(1); } if (args.length == 0) { System.err.println("Please specify an address to set temporarily"); System.err.println("e.g. W32WinInet localhost:3128"); System.exit(2); } long perConn = getInternetPerConnFlags(); String proxyServer = getProxyServer(); String proxyBypass = getProxyBypass(); System.out.println("Current settings:"); System.out.println("PerConnFlags: " + perConn); System.out.println("ProxyServer: " + proxyServer); System.out.println("ProxyBypass: " + proxyBypass); System.out.println(); System.out.println("Changed to " + args[0] + ", result is : " + setProxy(PROXY_TYPE_PROXY, args[0], null)); System.out.println("Settings are now:"); System.out.println("PerConnFlags: " + getInternetPerConnFlags()); System.out.println("ProxyServer: " + getProxyServer()); System.out.println("ProxyBypass: " + getProxyBypass()); System.out.print("Press enter to change them back: "); // System.in.read(); System.out.println("Result is : " + setProxy(perConn, proxyServer, proxyBypass)); System.out.println(); System.out.println("Current settings:"); System.out.println("PerConnFlags: " + getInternetPerConnFlags()); System.out.println("ProxyServer: " + getProxyServer()); System.out.println("ProxyBypass: " + getProxyBypass()); } }