package org.appwork.app.net; import java.lang.reflect.Method; import java.net.Authenticator; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; import java.net.Proxy; import java.net.ProxySelector; import java.net.SocketAddress; import java.net.URI; import java.util.List; import java.util.logging.Level; import java.util.prefs.Preferences; import org.appwork.storage.JSonStorage; import org.appwork.utils.Regex; import org.appwork.utils.logging.Log; import org.appwork.utils.os.CrossSystem; class HttpAuthenticateProxy extends Authenticator { private final String pw; private final String user; public HttpAuthenticateProxy(final String user, final String pw) { this.user = user; this.pw = pw; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(this.user, this.pw.toCharArray()); } } public class ProxyController { public enum PROXYTYPE { NONE, HTTP, SOCKS5 } public static final String PROP_HOST = "PROXY_IP"; public static final String PROP_PASS = "PROXY_AUTH_PASS"; public static final String PROP_PORT = "PROXY_PORT"; public static final String PROP_TYPE = "PROXY_TYPE"; public static final String PROP_USER = "PROXY_AUTH_USER"; public synchronized static void autoConfig() { /* reset proxy to none and lets find it */ ProxyController.setType(PROXYTYPE.NONE); try { if (CrossSystem.isWindows()) { if (ProxyController.checkReg()) { return; } } /* we enable systemproxies to query them for a test getPage */ System.setProperty("java.net.useSystemProxies", "true"); List<Proxy> l; l = ProxySelector.getDefault().select(new URI("http://www.appwork.org")); for (final Proxy p : l) { final SocketAddress ad = p.address(); if (ad != null && ad instanceof InetSocketAddress) { final InetSocketAddress isa = (InetSocketAddress) ad; if (isa.getHostName().trim().length() == 0) { continue; } switch (p.type()) { case HTTP: ProxyController.setPort(isa.getPort()); ProxyController.setHost(isa.getHostName()); ProxyController.setType(PROXYTYPE.HTTP); return; case SOCKS: ProxyController.setPort(isa.getPort()); ProxyController.setHost(isa.getHostName()); ProxyController.setType(PROXYTYPE.SOCKS5); return; } } } } catch (final Throwable e1) { Log.exception(Level.WARNING, e1); } finally { System.setProperty("java.net.useSystemProxies", "false"); if (ProxyController.getType() != ProxyController.PROXYTYPE.NONE) { Log.L.info("Found Proxy: " + ProxyController.getHost() + ":" + ProxyController.getPort() + "(" + ProxyController.getType() + ")"); } } } /** * Checks windows registry for proxy settings */ private static boolean checkReg() { try { final Preferences userRoot = Preferences.userRoot(); final Class<?> clz = userRoot.getClass(); final Method openKey = clz.getDeclaredMethod("openKey", byte[].class, int.class, int.class); openKey.setAccessible(true); final Method closeKey = clz.getDeclaredMethod("closeKey", int.class); closeKey.setAccessible(true); final Method winRegQueryValue = clz.getDeclaredMethod("WindowsRegQueryValueEx", int.class, byte[].class); winRegQueryValue.setAccessible(true); byte[] valb = null; String vals = null; String key = null; Integer handle = -1; // Query Internet Settings for Proxy key = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; try { handle = (Integer) openKey.invoke(userRoot, ProxyController.toCstr(key), 0x20019, 0x20019); valb = (byte[]) winRegQueryValue.invoke(userRoot, handle.intValue(), ProxyController.toCstr("ProxyServer")); vals = valb != null ? new String(valb).trim() : null; } finally { closeKey.invoke(Preferences.userRoot(), handle); } if (vals != null) { /* parse ip */ String proxyurl = new Regex(vals, "(\\d+\\.\\d+\\.\\d+\\.\\d+)").getMatch(0); if (proxyurl == null) { /* parse domain name */ proxyurl = new Regex(vals, "=(.*?)($|:)").getMatch(0); } final String port = new Regex(vals, ":(\\d+)").getMatch(0); if (proxyurl != null) { if (vals.trim().contains("socks")) { final int rPOrt = port != null ? Integer.parseInt(port) : 1080; ProxyController.setPort(rPOrt); ProxyController.setHost(proxyurl); ProxyController.setType(PROXYTYPE.SOCKS5); return true; } else { final int rPOrt = port != null ? Integer.parseInt(port) : 8080; ProxyController.setPort(rPOrt); ProxyController.setHost(proxyurl); ProxyController.setType(PROXYTYPE.HTTP); return true; } } } } catch (final Throwable e) { Log.exception(Level.WARNING, e); } return false; } public static String getHost() { return JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_HOST, ""); } public static String getPassword() { return JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_PASS, ""); } public static int getPort() { return JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_PORT, 8080); } public static PROXYTYPE getType() { return JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_TYPE, ProxyController.PROXYTYPE.NONE); } public static String getUsername() { return JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_USER, ""); } public static void main(final String[] args) { ProxyController.autoConfig(); } public static void setHost(final String text) { JSonStorage.getPlainStorage("Proxy").put(ProxyController.PROP_HOST, text); } private static void setHttp(final String host, final Integer portNum, final String user, final String pass) { System.setProperty("http.proxyHost", host); System.setProperty("http.proxyPort", portNum.intValue() + ""); System.setProperty("http.proxyUser", user); System.setProperty("http.proxyPassword", pass); } private static void setHttps(final String host, final Integer portNum, final String user, final String pass) { System.setProperty("https.proxyHost", host); System.setProperty("https.proxyPort", portNum.intValue() + ""); System.setProperty("http.proxyUser", user); System.setProperty("http.proxyPassword", pass); } public static void setPassword(final String text) { JSonStorage.getPlainStorage("Proxy").put(ProxyController.PROP_PASS, text); } public static void setPort(final Integer value) { JSonStorage.getPlainStorage("Proxy").put(ProxyController.PROP_PORT, value); } public static void setProxy() { try { final String host = JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_HOST, ""); final int portNum = JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_PORT, 8080); final String user = JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_USER, ""); final String pass = JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_PASS, ""); final PROXYTYPE proxy = JSonStorage.getPlainStorage("Proxy").get(ProxyController.PROP_TYPE, PROXYTYPE.NONE); switch (proxy) { case HTTP: ProxyController.setHttp(host, portNum, user, pass); ProxyController.setHttps(host, portNum, user, pass); Authenticator.setDefault(new HttpAuthenticateProxy(user, pass)); break; case SOCKS5: ProxyController.setSocks(host, portNum, user, pass); Authenticator.setDefault(new HttpAuthenticateProxy(user, pass)); break; default: System.setProperty("http.proxyHost", ""); System.setProperty("https.proxyHost", ""); System.setProperty("socksProxyHost", ""); Authenticator.setDefault(null); break; } } catch (final Throwable e) { Log.exception(Level.WARNING, e); } } private static void setSocks(final String host, final Integer portNum, final String user, final String pass) { System.setProperty("socksProxyHost", host); System.setProperty("socksProxyPort", portNum.intValue() + ""); System.setProperty("http.proxyUser", user); System.setProperty("http.proxyPassword", pass); } public static void setType(final PROXYTYPE selectedItem) { JSonStorage.getPlainStorage("Proxy").put(ProxyController.PROP_TYPE, selectedItem); } public static void setUsername(final String text) { JSonStorage.getPlainStorage("Proxy").put(ProxyController.PROP_USER, text); } private static byte[] toCstr(final String str) { final byte[] result = new byte[str.length() + 1]; for (int i = 0; i < str.length(); i++) { result[i] = (byte) str.charAt(i); } result[str.length()] = 0; return result; } }