From e30c78bd05575f86a0bb683c19cb97c7bc7e53eb Mon Sep 17 00:00:00 2001 From: Nathan Freitas Date: Sat, 28 Mar 2015 00:18:28 -0400 Subject: [PATCH] remove jsocks from main code and move to external/jsocks --- .../runjva/sourceforge/jsocks/main/SOCKS.java | 265 ------- .../sourceforge/jsocks/main/SocksEcho.gif | Bin 926 -> 0 bytes .../jsocks/protocol/Authentication.java | 35 - .../jsocks/protocol/AuthenticationNone.java | 22 - .../jsocks/protocol/InetRange.java | 492 ------------- .../jsocks/protocol/ProxyMessage.java | 118 --- .../jsocks/protocol/ProxyServer.java | 695 ------------------ .../jsocks/protocol/Socks4Message.java | 167 ----- .../jsocks/protocol/Socks4Proxy.java | 144 ---- .../jsocks/protocol/Socks5DatagramSocket.java | 480 ------------ .../jsocks/protocol/Socks5Message.java | 324 -------- .../jsocks/protocol/Socks5Proxy.java | 295 -------- .../jsocks/protocol/SocksException.java | 111 --- .../jsocks/protocol/SocksProxyBase.java | 543 -------------- .../jsocks/protocol/SocksServerSocket.java | 238 ------ .../jsocks/protocol/SocksSocket.java | 386 ---------- .../jsocks/protocol/UDPEncapsulation.java | 33 - .../jsocks/protocol/UDPRelayServer.java | 228 ------ .../protocol/UserPasswordAuthentication.java | 91 --- .../sourceforge/jsocks/server/Ident.java | 173 ----- .../jsocks/server/IdentAuthenticator.java | 182 ----- .../jsocks/server/ServerAuthenticator.java | 126 ---- .../server/ServerAuthenticatorBase.java | 187 ----- .../server/ServerAuthenticatorNone.java | 16 - .../server/UserPasswordAuthenticator.java | 82 --- .../jsocks/server/UserValidation.java | 24 - 26 files changed, 5457 deletions(-) delete mode 100644 src/com/runjva/sourceforge/jsocks/main/SOCKS.java delete mode 100644 src/com/runjva/sourceforge/jsocks/main/SocksEcho.gif delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/Authentication.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/AuthenticationNone.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/InetRange.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/ProxyMessage.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/ProxyServer.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/Socks4Message.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/Socks4Proxy.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/Socks5DatagramSocket.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/Socks5Message.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/Socks5Proxy.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/SocksException.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/SocksProxyBase.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/SocksServerSocket.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/SocksSocket.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/UDPEncapsulation.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/UDPRelayServer.java delete mode 100644 src/com/runjva/sourceforge/jsocks/protocol/UserPasswordAuthentication.java delete mode 100644 src/com/runjva/sourceforge/jsocks/server/Ident.java delete mode 100644 src/com/runjva/sourceforge/jsocks/server/IdentAuthenticator.java delete mode 100644 src/com/runjva/sourceforge/jsocks/server/ServerAuthenticator.java delete mode 100644 src/com/runjva/sourceforge/jsocks/server/ServerAuthenticatorBase.java delete mode 100644 src/com/runjva/sourceforge/jsocks/server/ServerAuthenticatorNone.java delete mode 100644 src/com/runjva/sourceforge/jsocks/server/UserPasswordAuthenticator.java delete mode 100644 src/com/runjva/sourceforge/jsocks/server/UserValidation.java diff --git a/src/com/runjva/sourceforge/jsocks/main/SOCKS.java b/src/com/runjva/sourceforge/jsocks/main/SOCKS.java deleted file mode 100644 index 45eb866e..00000000 --- a/src/com/runjva/sourceforge/jsocks/main/SOCKS.java +++ /dev/null @@ -1,265 +0,0 @@ -package com.runjva.sourceforge.jsocks.main; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Hashtable; -import java.util.Properties; -import java.util.StringTokenizer; - -import com.runjva.sourceforge.jsocks.protocol.InetRange; -import com.runjva.sourceforge.jsocks.protocol.ProxyServer; -import com.runjva.sourceforge.jsocks.protocol.SocksProxyBase; -import com.runjva.sourceforge.jsocks.server.IdentAuthenticator; - -public class SOCKS { - - private static final int DEFAULT_LISTENING_PORT = 1080; - - static public void usage() { - System.out.println("Usage: java SOCKS [inifile1 inifile2 ...]\n" - + "If none inifile is given, uses socks.properties.\n"); - } - - static public void main(String[] args) { - - String[] file_names; - int port = DEFAULT_LISTENING_PORT; - String logFile = null; - String host = null; - - final IdentAuthenticator auth = new IdentAuthenticator(); - - InetAddress localIP = null; - - if (args.length == 0) { - file_names = new String[] { "socks.properties" }; - } else { - file_names = args; - } - - inform("Loading properties"); - for (int i = 0; i < file_names.length; ++i) { - - inform("Reading file " + file_names[i]); - - final Properties pr = loadProperties(file_names[i]); - if (pr == null) { - System.err.println("Loading of properties from " - + file_names[i] + "failed."); - usage(); - return; - } - if (!addAuth(auth, pr)) { - System.err.println("Error in file " + file_names[i] + "."); - usage(); - return; - } - // First file should contain all global settings, - // like port and host and log. - if (i == 0) { - final String port_s = (String) pr.get("port"); - if (port_s != null) { - try { - port = Integer.parseInt(port_s); - } catch (final NumberFormatException nfe) { - System.err.println("Can't parse port: " + port_s); - return; - } - } - - serverInit(pr); - logFile = (String) pr.get("log"); - host = (String) pr.get("host"); - } - - // inform("Props:"+pr); - } - - if (logFile != null) { - System.err.println("log property not supported anymore."); - } - if (host != null) { - try { - localIP = InetAddress.getByName(host); - } catch (final UnknownHostException uhe) { - System.err.println("Can't resolve local ip: " + host); - return; - } - } - - inform("Using Ident Authentication scheme: " + auth); - final ProxyServer server = new ProxyServer(auth); - server.start(port, 5, localIP); - } - - static Properties loadProperties(String file_name) { - - final Properties pr = new Properties(); - - try { - final InputStream fin = new FileInputStream(file_name); - pr.load(fin); - fin.close(); - } catch (final IOException ioe) { - return null; - } - return pr; - } - - static boolean addAuth(IdentAuthenticator ident, Properties pr) { - - InetRange irange; - - final String range = (String) pr.get("range"); - if (range == null) { - return false; - } - irange = parseInetRange(range); - - final String users = (String) pr.get("users"); - - if (users == null) { - ident.add(irange, null); - return true; - } - - final Hashtable uhash = new Hashtable(); - - final StringTokenizer st = new StringTokenizer(users, ";"); - while (st.hasMoreTokens()) { - uhash.put(st.nextToken(), ""); - } - - ident.add(irange, uhash); - return true; - } - - /** - * Does server initialisation. - */ - static void serverInit(Properties props) { - int val; - val = readInt(props, "iddleTimeout"); - if (val >= 0) { - ProxyServer.setIddleTimeout(val); - inform("Setting iddle timeout to " + val + " ms."); - } - val = readInt(props, "acceptTimeout"); - if (val >= 0) { - ProxyServer.setAcceptTimeout(val); - inform("Setting accept timeout to " + val + " ms."); - } - val = readInt(props, "udpTimeout"); - if (val >= 0) { - ProxyServer.setUDPTimeout(val); - inform("Setting udp timeout to " + val + " ms."); - } - - val = readInt(props, "datagramSize"); - if (val >= 0) { - ProxyServer.setDatagramSize(val); - inform("Setting datagram size to " + val + " bytes."); - } - - proxyInit(props); - - } - - /** - * Initialises proxy, if any specified. - */ - static void proxyInit(Properties props) { - String proxy_list; - SocksProxyBase proxy = null; - StringTokenizer st; - - proxy_list = (String) props.get("proxy"); - if (proxy_list == null) { - return; - } - - st = new StringTokenizer(proxy_list, ";"); - while (st.hasMoreTokens()) { - final String proxy_entry = st.nextToken(); - - final SocksProxyBase p = SocksProxyBase.parseProxy(proxy_entry); - - if (p == null) { - exit("Can't parse proxy entry:" + proxy_entry); - } - - inform("Adding Proxy:" + p); - - if (proxy != null) { - p.setChainProxy(proxy); - } - - proxy = p; - - } - if (proxy == null) { - return; // Empty list - } - - final String direct_hosts = (String) props.get("directHosts"); - if (direct_hosts != null) { - final InetRange ir = parseInetRange(direct_hosts); - inform("Setting direct hosts:" + ir); - proxy.setDirect(ir); - } - - ProxyServer.setProxy(proxy); - } - - /** - * Inits range from the string of semicolon separated ranges. - */ - static InetRange parseInetRange(String source) { - final InetRange irange = new InetRange(); - - final StringTokenizer st = new StringTokenizer(source, ";"); - while (st.hasMoreTokens()) { - irange.add(st.nextToken()); - } - - return irange; - } - - /** - * Integer representaion of the property named name, or -1 if one is not - * found. - */ - static int readInt(Properties props, String name) { - int result = -1; - final String val = (String) props.get(name); - if (val == null) { - return -1; - } - final StringTokenizer st = new StringTokenizer(val); - if (!st.hasMoreElements()) { - return -1; - } - try { - result = Integer.parseInt(st.nextToken()); - } catch (final NumberFormatException nfe) { - inform("Bad value for " + name + ":" + val); - } - return result; - } - - // Display functions - // ///////////////// - - static void inform(String s) { - // log.info(s); - } - - static void exit(String msg) { - System.err.println("Error:" + msg); - System.err.println("Aborting operation"); - System.exit(0); - } -} diff --git a/src/com/runjva/sourceforge/jsocks/main/SocksEcho.gif b/src/com/runjva/sourceforge/jsocks/main/SocksEcho.gif deleted file mode 100644 index 701d39a6fe03e99d9d361076d51aeb6d33a9e972..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 926 zcmZ?wbhEHb6krfw_|Cw<0s<{8EWcPsK#ACq&hgk;Vt9&XpHMsT3 yin2xQx}tt?f{Op7Cnq*PaPAbI*k - * This method should return an array {inputstream,outputstream - * [,UDPEncapsulation]}. The reason for that is that SOCKS5 protocol allows - * to have method specific encapsulation of data on the socket for purposes - * of integrity or security. And this encapsulation should be performed by - * those streams returned from the method. It is also possible to - * encapsulate datagrams. If authentication method supports such - * encapsulation an instance of the UDPEncapsulation interface should be - * returned as third element of the array, otherwise either null should be - * returned as third element, or array should contain only 2 elements. - * - * @param methodId - * Authentication method selected by the server. - * @param proxySocket - * Socket used to conect to the proxy. - * @return Two or three element array containing Input/Output streams which - * should be used on this connection. Third argument is optional and - * should contain an instance of UDPEncapsulation. It should be - * provided if the authentication method used requires any - * encapsulation to be done on the datagrams. - */ - Object[] doSocksAuthentication(int methodId, java.net.Socket proxySocket) - throws java.io.IOException; -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/AuthenticationNone.java b/src/com/runjva/sourceforge/jsocks/protocol/AuthenticationNone.java deleted file mode 100644 index e6821545..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/AuthenticationNone.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.InputStream; -import java.io.OutputStream; - -/** - * SOCKS5 none authentication. Dummy class does almost nothing. - */ -public class AuthenticationNone implements Authentication { - - public Object[] doSocksAuthentication(final int methodId, - final java.net.Socket proxySocket) throws java.io.IOException { - - if (methodId != 0) { - return null; - } - - InputStream in = proxySocket.getInputStream(); - OutputStream out = proxySocket.getOutputStream(); - return new Object[] { in, out }; - } -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/InetRange.java b/src/com/runjva/sourceforge/jsocks/protocol/InetRange.java deleted file mode 100644 index fae13587..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/InetRange.java +++ /dev/null @@ -1,492 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.StringTokenizer; -import java.util.Vector; - -/** - * Class InetRange provides the means of defining the range of inetaddresses. - * It's used by Proxy class to store and look up addresses of machines, that - * should be contacted directly rather then through the proxy. - *

- * InetRange provides several methods to add either standalone addresses, or - * ranges (e.g. 100.200.300.0:100.200.300.255, which covers all addresses on on - * someones local network). It also provides methods for checking wether given - * address is in this range. Any number of ranges and standalone addresses can - * be added to the range. - */ -public class InetRange implements Cloneable { - - Hashtable host_names; - Vector all; - Vector end_names; - - boolean useSeparateThread = true; - - /** - * Creates the empty range. - */ - public InetRange() { - all = new Vector(); - host_names = new Hashtable(); - end_names = new Vector(); - } - - /** - * Adds another host or range to this range. The String can be one of those: - *

    - *
  • Host name. eg.(Athena.myhost.com or 45.54.56.65) - * - *
  • Range in the form .myhost.net.au
    - * In which case anything that ends with .myhost.net.au will be considered - * in the range. - * - *
  • Range in the form ddd.ddd.ddd.
    - * This will be treated as range ddd.ddd.ddd.0 to ddd.ddd.ddd.255. It is not - * necessary to specify 3 first bytes you can use just one or two. For - * example 130. will cover address between 130.0.0.0 and 13.255.255.255. - * - *
  • Range in the form host_from[: \t\n\r\f]host_to.
    - * That is two hostnames or ips separated by either whitespace or colon. - *
- */ - public synchronized boolean add(final String s0) { - if (s0 == null) { - return false; - } - - String s = s0.trim(); - if (s.length() == 0) { - return false; - } - - Object[] entry; - - if (s.endsWith(".")) { - // thing like: 111.222.33. - // it is being treated as range 111.222.33.000 - 111.222.33.255 - - final int[] addr = ip2intarray(s); - long from, to; - from = to = 0; - - if (addr == null) { - return false; - } - for (int i = 0; i < 4; i++) { - if (addr[i] >= 0) { - from += (((long) addr[i]) << 8 * (3 - i)); - } else { - to = from; - while (i < 4) { - to += 255l << 8 * (3 - i++); - } - break; - } - } - entry = new Object[] { s, null, new Long(from), new Long(to) }; - all.addElement(entry); - - } else if (s.startsWith(".")) { - // Thing like: .myhost.com - - end_names.addElement(s); - all.addElement(new Object[] { s, null, null, null }); - } else { - final StringTokenizer tokens = new StringTokenizer(s, " \t\r\n\f:"); - if (tokens.countTokens() > 1) { - entry = new Object[] { s, null, null, null }; - resolve(entry, tokens.nextToken(), tokens.nextToken()); - all.addElement(entry); - } else { - entry = new Object[] { s, null, null, null }; - all.addElement(entry); - host_names.put(s, entry); - resolve(entry); - } - - } - - return true; - } - - /** - * Adds another ip for this range. - * - * @param ip - * IP os the host which should be added to this range. - */ - public synchronized void add(final InetAddress ip) { - long from, to; - from = to = ip2long(ip); - all.addElement(new Object[] { ip.getHostName(), ip, new Long(from), - new Long(to) }); - } - - /** - * Adds another range of ips for this range.Any host with ip address greater - * than or equal to the address of from and smaller than or equal to the - * address of to will be included in the range. - * - * @param from - * IP from where range starts(including). - * @param to - * IP where range ends(including). - */ - public synchronized void add(final InetAddress from, final InetAddress to) { - all.addElement(new Object[] { - from.getHostAddress() + ":" + to.getHostAddress(), null, - new Long(ip2long(from)), new Long(ip2long(to)) }); - } - - /** - * Checks wether the givan host is in the range. Attempts to resolve host - * name if required. - * - * @param host - * Host name to check. - * @return true If host is in the range, false otherwise. - * @see InetRange#contains(String,boolean) - */ - public synchronized boolean contains(final String host) { - return contains(host, true); - } - - /** - * Checks wether the given host is in the range. - *

- * Algorithm:
- *

    - *
  1. Look up if the hostname is in the range (in the Hashtable). - *
  2. Check if it ends with one of the speciefied endings. - *
  3. Check if it is ip(eg.130.220.35.98). If it is check if it is in the - * range. - *
  4. If attemptResolve is true, host is name, rather than ip, and all - * previous attempts failed, try to resolve the hostname, and check wether - * the ip associated with the host is in the range.It also repeats all - * previos steps with the hostname obtained from InetAddress, but the name - * is not allways the full name,it is quite likely to be the same. Well it - * was on my machine. - *
- * - * @param host - * Host name to check. - * @param attemptResolve - * Wether to lookup ip address which corresponds to the host,if - * required. - * @return true If host is in the range, false otherwise. - */ - public synchronized boolean contains(final String host0, - final boolean attemptResolve) { - if (all.size() == 0) { - return false; // Empty range - } - - String host = host0.trim(); - if (host.length() == 0) { - return false; - } - - if (checkHost(host)) { - return true; - } - if (checkHostEnding(host)) { - return true; - } - - final long l = host2long(host); - if (l >= 0) { - return contains(l); - } - - if (!attemptResolve) { - return false; - } - - try { - final InetAddress ip = InetAddress.getByName(host); - return contains(ip); - } catch (final UnknownHostException uhe) { - - } - - return false; - } - - /** - * Checks wether the given ip is in the range. - * - * @param ip - * Address of the host to check. - * @return true If host is in the range, false otherwise. - */ - public synchronized boolean contains(final InetAddress ip) { - if (checkHostEnding(ip.getHostName())) { - return true; - } - if (checkHost(ip.getHostName())) { - return true; - } - return contains(ip2long(ip)); - } - - /** - * Get all entries in the range as strings.
- * These strings can be used to delete entries from the range with remove - * function. - * - * @return Array of entries as strings. - * @see InetRange#remove(String) - */ - public synchronized String[] getAll() { - final int size = all.size(); - Object entry[]; - final String all_names[] = new String[size]; - - for (int i = 0; i < size; ++i) { - entry = all.elementAt(i); - all_names[i] = (String) entry[0]; - } - return all_names; - } - - /** - * Removes an entry from this range.
- * - * @param s - * Entry to remove. - * @return true if successfull. - */ - public synchronized boolean remove(final String s) { - final Enumeration enumx = all.elements(); - while (enumx.hasMoreElements()) { - final Object[] entry = enumx.nextElement(); - if (s.equals(entry[0])) { - all.removeElement(entry); - end_names.removeElement(s); - host_names.remove(s); - return true; - } - } - return false; - } - - /** Get string representaion of this Range. */ - public String toString() { - final String all[] = getAll(); - if (all.length == 0) { - return ""; - } - - String s = all[0]; - for (int i = 1; i < all.length; ++i) { - s += "; " + all[i]; - } - return s; - } - - /** Creates a clone of this Object */ - - @SuppressWarnings("unchecked") - public Object clone() { - final InetRange new_range = new InetRange(); - new_range.all = (Vector) all.clone(); - new_range.end_names = (Vector) end_names.clone(); - new_range.host_names = (Hashtable) host_names.clone(); - return new_range; - } - - // Private methods - // /////////////// - /** - * Same as previous but used internally, to avoid unnecessary convertion of - * IPs, when checking subranges - */ - private synchronized boolean contains(final long ip) { - final Enumeration enumx = all.elements(); - while (enumx.hasMoreElements()) { - final Object[] obj = enumx.nextElement(); - final Long from = obj[2] == null ? null : (Long) obj[2]; - final Long to = obj[3] == null ? null : (Long) obj[3]; - if ((from != null) && (from.longValue() <= ip) - && (to.longValue() >= ip)) { - return true; - } - - } - return false; - } - - private boolean checkHost(final String host) { - return host_names.containsKey(host); - } - - private boolean checkHostEnding(final String host) { - final Enumeration enumx = end_names.elements(); - while (enumx.hasMoreElements()) { - if (host.endsWith(enumx.nextElement())) { - return true; - } - } - return false; - } - - private void resolve(final Object[] entry) { - // First check if it's in the form ddd.ddd.ddd.ddd. - final long ip = host2long((String) entry[0]); - if (ip >= 0) { - entry[2] = entry[3] = new Long(ip); - } else { - final InetRangeResolver res = new InetRangeResolver(entry); - res.resolve(useSeparateThread); - } - } - - private void resolve(final Object[] entry, final String from, - final String to) { - long f, t; - if (((f = host2long(from)) >= 0) && ((t = host2long(to)) >= 0)) { - entry[2] = new Long(f); - entry[3] = new Long(t); - } else { - final InetRangeResolver res = new InetRangeResolver(entry, from, to); - res.resolve(useSeparateThread); - } - } - - // Class methods - // ///////////// - - // Converts ipv4 to long value(unsigned int) - // ///////////////////////////////////////// - static long ip2long(final InetAddress ip) { - long l = 0; - final byte[] addr = ip.getAddress(); - - if (addr.length == 4) { // IPV4 - for (int i = 0; i < 4; ++i) { - l += (((long) addr[i] & 0xFF) << 8 * (3 - i)); - } - } else { // IPV6 - return 0; // Have no idea how to deal with those - } - return l; - } - - long host2long(final String host) { - long ip = 0; - - // check if it's ddd.ddd.ddd.ddd - if (!Character.isDigit(host.charAt(0))) { - return -1; - } - - final int[] addr = ip2intarray(host); - if (addr == null) { - return -1; - } - - for (int i = 0; i < addr.length; ++i) { - ip += ((long) (addr[i] >= 0 ? addr[i] : 0)) << 8 * (3 - i); - } - - return ip; - } - - static int[] ip2intarray(final String host) { - final int[] address = { -1, -1, -1, -1 }; - int i = 0; - final StringTokenizer tokens = new StringTokenizer(host, "."); - if (tokens.countTokens() > 4) { - return null; - } - while (tokens.hasMoreTokens()) { - try { - address[i++] = Integer.parseInt(tokens.nextToken()) & 0xFF; - } catch (final NumberFormatException nfe) { - return null; - } - - } - return address; - } - - /* - * //* This was the test main function //********************************** - * - * public static void main(String args[])throws UnknownHostException{ int i; - * - * InetRange ir = new InetRange(); - * - * - * for(i=0;i - * In order to use it you will need to implement ServerAuthenticator interface. - * There is an implementation of this interface which does no authentication - * ServerAuthenticatorNone, but it is very dangerous to use, as it will give - * access to your local network to anybody in the world. One should never use - * this authentication scheme unless one have pretty good reason to do so. There - * is a couple of other authentication schemes in socks.server package. - * - * @see socks.server.ServerAuthenticator - */ -public class ProxyServer implements Runnable { - - ServerAuthenticator auth; - ProxyMessage msg = null; - - Socket sock = null, remote_sock = null; - ServerSocket ss = null; - UDPRelayServer relayServer = null; - InputStream in, remote_in; - OutputStream out, remote_out; - - int mode; - static final int START_MODE = 0; - static final int ACCEPT_MODE = 1; - static final int PIPE_MODE = 2; - static final int ABORT_MODE = 3; - - static final int BUF_SIZE = 8192; - - Thread pipe_thread1, pipe_thread2; - long lastReadTime; - - static int iddleTimeout = 180000; // 3 minutes - static int acceptTimeout = 180000; // 3 minutes - - static SocksProxyBase proxy; - - static VpnService vpnService; - - // Public Constructors - // /////////////////// - - /** - * Creates a proxy server with given Authentication scheme. - * - * @param auth - * Authentication scheme to be used. - */ - public ProxyServer(final ServerAuthenticator auth) { - this.auth = auth; - } - - // Other constructors - // ////////////////// - - ProxyServer(final ServerAuthenticator auth, final Socket s) { - this.auth = auth; - this.sock = s; - this.mode = START_MODE; - } - - // Public methods - // /////////////// - - /** - * Set proxy. - *

- * Allows Proxy chaining so that one Proxy server is connected to another - * and so on. If proxy supports SOCKSv4, then only some SOCKSv5 requests can - * be handled, UDP would not work, however CONNECT and BIND will be - * translated. - * - * @param p - * Proxy which should be used to handle user requests. - */ - public static void setProxy(final SocksProxyBase p) { - proxy = p; - // FIXME: Side effect. - UDPRelayServer.proxy = proxy; - } - - public static void setVpnService (final VpnService v) - { - vpnService = v; - } - /** - * Get proxy. - * - * @return Proxy wich is used to handle user requests. - */ - public static SocksProxyBase getProxy() { - return proxy; - } - - /** - * Sets the timeout for connections, how long shoud server wait for data to - * arrive before dropping the connection.
- * Zero timeout implies infinity.
- * Default timeout is 3 minutes. - */ - public static void setIddleTimeout(final int timeout) { - iddleTimeout = timeout; - } - - /** - * Sets the timeout for BIND command, how long the server should wait for - * the incoming connection.
- * Zero timeout implies infinity.
- * Default timeout is 3 minutes. - */ - public static void setAcceptTimeout(final int timeout) { - acceptTimeout = timeout; - } - - /** - * Sets the timeout for UDPRelay server.
- * Zero timeout implies infinity.
- * Default timeout is 3 minutes. - */ - public static void setUDPTimeout(final int timeout) { - UDPRelayServer.setTimeout(timeout); - } - - /** - * Sets the size of the datagrams used in the UDPRelayServer.
- * Default size is 64K, a bit more than maximum possible size of the - * datagram. - */ - public static void setDatagramSize(final int size) { - UDPRelayServer.setDatagramSize(size); - } - - /** - * Start the Proxy server at given port.
- * This methods blocks. - */ - public void start(final int port) { - start(port, 5, null); - } - - /** - * Create a server with the specified port, listen backlog, and local IP - * address to bind to. The localIP argument can be used on a multi-homed - * host for a ServerSocket that will only accept connect requests to one of - * its addresses. If localIP is null, it will default accepting connections - * on any/all local addresses. The port must be between 0 and 65535, - * inclusive.
- * This methods blocks. - */ - public void start(final int port, final int backlog, - final InetAddress localIP) { - try { - ss = new ServerSocket(port, backlog, localIP); - final String address = ss.getInetAddress().getHostAddress(); - final int localPort = ss.getLocalPort(); - debug("Starting SOCKS Proxy on: {}:{}", address, localPort); - - while (true) { - final Socket s = ss.accept(); - final String hostName = s.getInetAddress().getHostName(); - final int port2 = s.getPort(); - debug("Accepted from:{}:{}", hostName, port2); - - final ProxyServer ps = new ProxyServer(auth, s); - (new Thread(ps)).start(); - } - } catch (final Exception ioe) { - ioe.printStackTrace(); - } finally { - } - } - - /** - * Stop server operation.It would be wise to interrupt thread running the - * server afterwards. - */ - public void stop() { - try { - if (ss != null) { - ss.close(); - } - } catch (final IOException ioe) { - } - } - - // Runnable interface - // ////////////////// - public void run() { - switch (mode) { - case START_MODE: - try { - startSession(); - } catch (final IOException ioe) { - handleException(ioe); - // ioe.printStackTrace(); - } finally { - abort(); - if (auth != null) { - auth.endSession(); - } - debug("Main thread(client->remote)stopped."); - } - break; - case ACCEPT_MODE: - try { - doAccept(); - mode = PIPE_MODE; - pipe_thread1.interrupt(); // Tell other thread that connection - // have - // been accepted. - pipe(remote_in, out); - } catch (final IOException ioe) { - // log("Accept exception:"+ioe); - handleException(ioe); - } finally { - abort(); - debug("Accept thread(remote->client) stopped"); - } - break; - case PIPE_MODE: - try { - pipe(remote_in, out); - } catch (final IOException ioe) { - } finally { - abort(); - debug("Support thread(remote->client) stopped"); - } - break; - case ABORT_MODE: - break; - default: - debug("Unexpected MODE " + mode); - } - } - - // Private methods - // /////////////// - private void startSession() throws IOException { - sock.setSoTimeout(iddleTimeout); - - try { - auth = auth.startSession(sock); - } catch (final IOException ioe) { - debug("Auth throwed exception:", ioe); - auth = null; - return; - } - - if (auth == null) { // Authentication failed - debug("Authentication failed"); - return; - } - - in = auth.getInputStream(); - out = auth.getOutputStream(); - - msg = readMsg(in); - handleRequest(msg); - } - - private void handleRequest(final ProxyMessage msg) throws IOException { - if (!auth.checkRequest(msg)) { - throw new SocksException(SocksProxyBase.SOCKS_FAILURE); - } - - if (msg.ip == null) { - if (msg instanceof Socks5Message) { - msg.ip = InetAddress.getByName(msg.host); - } else { - throw new SocksException(SocksProxyBase.SOCKS_FAILURE); - } - } - log(msg); - - switch (msg.command) { - case SocksProxyBase.SOCKS_CMD_CONNECT: - onConnect(msg); - break; - case SocksProxyBase.SOCKS_CMD_BIND: - onBind(msg); - break; - case SocksProxyBase.SOCKS_CMD_UDP_ASSOCIATE: - onUDP(msg); - break; - default: - throw new SocksException(SocksProxyBase.SOCKS_CMD_NOT_SUPPORTED); - } - } - - private void handleException(final IOException ioe) { - // If we couldn't read the request, return; - if (msg == null) { - return; - } - // If have been aborted by other thread - if (mode == ABORT_MODE) { - return; - } - // If the request was successfully completed, but exception happened - // later - if (mode == PIPE_MODE) { - return; - } - - int error_code = SocksProxyBase.SOCKS_FAILURE; - - if (ioe instanceof SocksException) { - error_code = ((SocksException) ioe).errCode; - } else if (ioe instanceof NoRouteToHostException) { - error_code = SocksProxyBase.SOCKS_HOST_UNREACHABLE; - } else if (ioe instanceof ConnectException) { - error_code = SocksProxyBase.SOCKS_CONNECTION_REFUSED; - } else if (ioe instanceof InterruptedIOException) { - error_code = SocksProxyBase.SOCKS_TTL_EXPIRE; - } - - if ((error_code > SocksProxyBase.SOCKS_ADDR_NOT_SUPPORTED) - || (error_code < 0)) { - error_code = SocksProxyBase.SOCKS_FAILURE; - } - - sendErrorMessage(error_code); - } - - @SuppressLint("NewApi") - private void onConnect(final ProxyMessage msg) throws IOException { - Socket s; - - if (proxy == null) { - - s = SocketChannel.open().socket(); - if ((null != s) && (null != vpnService)) { - vpnService.protect(s); - } - - s.connect(new InetSocketAddress(msg.ip,msg.port)); - - } else { - s = new SocksSocket(proxy, msg.ip, msg.port); - - if (vpnService != null) - vpnService.protect(s); - } - - - debug("Connected to " + s.getInetAddress() + ":" + s.getPort()); - - ProxyMessage response = null; - final InetAddress localAddress = s.getLocalAddress(); - final int localPort = s.getLocalPort(); - - if (msg instanceof Socks5Message) { - final int cmd = SocksProxyBase.SOCKS_SUCCESS; - response = new Socks5Message(cmd, localAddress, localPort); - } else { - final int cmd = Socks4Message.REPLY_OK; - response = new Socks4Message(cmd, localAddress, localPort); - - } - response.write(out); - startPipe(s); - } - - private void onBind(final ProxyMessage msg) throws IOException { - ProxyMessage response = null; - - if (proxy == null) { - ss = new ServerSocket(0); - } else { - ss = new SocksServerSocket(proxy, msg.ip, msg.port); - } - - ss.setSoTimeout(acceptTimeout); - - final InetAddress inetAddress = ss.getInetAddress(); - final int localPort = ss.getLocalPort(); - debug("Trying accept on {}:{}", inetAddress, localPort); - - if (msg.version == 5) { - final int cmd = SocksProxyBase.SOCKS_SUCCESS; - response = new Socks5Message(cmd, inetAddress, localPort); - } else { - final int cmd = Socks4Message.REPLY_OK; - response = new Socks4Message(cmd, inetAddress, localPort); - } - response.write(out); - - mode = ACCEPT_MODE; - - pipe_thread1 = Thread.currentThread(); - pipe_thread2 = new Thread(this); - pipe_thread2.start(); - - // Make timeout infinit. - sock.setSoTimeout(0); - int eof = 0; - - try { - while ((eof = in.read()) >= 0) { - if (mode != ACCEPT_MODE) { - if (mode != PIPE_MODE) { - return;// Accept failed - } - - remote_out.write(eof); - break; - } - } - } catch (final EOFException e) { - debug("Connection closed while we were trying to accept", e); - return; - } catch (final InterruptedIOException e) { - debug("Interrupted by unsucessful accept thread", e); - if (mode != PIPE_MODE) { - return; - } - } finally { - // System.out.println("Finnaly!"); - } - - if (eof < 0) { - return; - } - - // Do not restore timeout, instead timeout is set on the - // remote socket. It does not make any difference. - - pipe(in, remote_out); - } - - private void onUDP(final ProxyMessage msg) throws IOException { - if (msg.ip.getHostAddress().equals("0.0.0.0")) { - msg.ip = sock.getInetAddress(); - } - debug("Creating UDP relay server for {}:{}", msg.ip, msg.port); - - relayServer = new UDPRelayServer(msg.ip, msg.port, - Thread.currentThread(), sock, auth); - - ProxyMessage response; - - response = new Socks5Message(SocksProxyBase.SOCKS_SUCCESS, - relayServer.relayIP, relayServer.relayPort); - - response.write(out); - - relayServer.start(); - - // Make timeout infinit. - sock.setSoTimeout(0); - try { - while (in.read() >= 0) { - /* do nothing */; - // FIXME: Consider a slight delay here? - } - } catch (final EOFException eofe) { - } - } - - // Private methods - // //////////////// - - private void doAccept() throws IOException { - Socket s = null; - final long startTime = System.currentTimeMillis(); - - while (true) { - s = ss.accept(); - if (s.getInetAddress().equals(msg.ip)) { - // got the connection from the right host - // Close listenning socket. - ss.close(); - break; - } else if (ss instanceof SocksServerSocket) { - // We can't accept more then one connection - s.close(); - ss.close(); - throw new SocksException(SocksProxyBase.SOCKS_FAILURE); - } else { - if (acceptTimeout != 0) { // If timeout is not infinit - final long passed = System.currentTimeMillis() - startTime; - final int newTimeout = acceptTimeout - (int) passed; - - if (newTimeout <= 0) { - throw new InterruptedIOException("newTimeout <= 0"); - } - ss.setSoTimeout(newTimeout); - } - s.close(); // Drop all connections from other hosts - } - } - - // Accepted connection - remote_sock = s; - remote_in = s.getInputStream(); - remote_out = s.getOutputStream(); - - // Set timeout - remote_sock.setSoTimeout(iddleTimeout); - - final InetAddress inetAddress = s.getInetAddress(); - final int port = s.getPort(); - debug("Accepted from {}:{}", s.getInetAddress(), port); - - ProxyMessage response; - - if (msg.version == 5) { - final int cmd = SocksProxyBase.SOCKS_SUCCESS; - response = new Socks5Message(cmd, inetAddress, port); - } else { - final int cmd = Socks4Message.REPLY_OK; - response = new Socks4Message(cmd, inetAddress, port); - } - response.write(out); - } - - private ProxyMessage readMsg(final InputStream in) throws IOException { - PushbackInputStream push_in; - if (in instanceof PushbackInputStream) { - push_in = (PushbackInputStream) in; - } else { - push_in = new PushbackInputStream(in); - } - - final int version = push_in.read(); - push_in.unread(version); - - ProxyMessage msg; - - if (version == 5) { - msg = new Socks5Message(push_in, false); - } else if (version == 4) { - msg = new Socks4Message(push_in, false); - } else { - throw new SocksException(SocksProxyBase.SOCKS_FAILURE); - } - return msg; - } - - private void startPipe(final Socket s) { - mode = PIPE_MODE; - remote_sock = s; - try { - remote_in = s.getInputStream(); - remote_out = s.getOutputStream(); - pipe_thread1 = Thread.currentThread(); - pipe_thread2 = new Thread(this); - pipe_thread2.start(); - pipe(in, remote_out); - } catch (final IOException ioe) { - } - } - - private void sendErrorMessage(final int error_code) { - ProxyMessage err_msg; - if (msg instanceof Socks4Message) { - err_msg = new Socks4Message(Socks4Message.REPLY_REJECTED); - } else { - err_msg = new Socks5Message(error_code); - } - try { - err_msg.write(out); - } catch (final IOException ioe) { - } - } - - private synchronized void abort() { - if (mode == ABORT_MODE) { - return; - } - mode = ABORT_MODE; - try { - debug("Aborting operation"); - if (remote_sock != null) { - remote_sock.close(); - } - if (sock != null) { - sock.close(); - } - if (relayServer != null) { - relayServer.stop(); - } - if (ss != null) { - ss.close(); - } - if (pipe_thread1 != null) { - pipe_thread1.interrupt(); - } - if (pipe_thread2 != null) { - pipe_thread2.interrupt(); - } - } catch (final IOException ioe) { - } - } - - static final void log(final ProxyMessage msg) { - debug("Request version: {}, Command: ", msg.version, - command2String(msg.command)); - - final String user = msg.version == 4 ? ", User:" + msg.user : ""; - debug("IP:" + msg.ip + ", Port:" + msg.port + user); - } - - private void pipe(final InputStream in, final OutputStream out) - throws IOException { - lastReadTime = System.currentTimeMillis(); - final byte[] buf = new byte[BUF_SIZE]; - int len = 0; - while (len >= 0) { - try { - if (len != 0) { - out.write(buf, 0, len); - out.flush(); - } - len = in.read(buf); - lastReadTime = System.currentTimeMillis(); - } catch (final InterruptedIOException iioe) { - if (iddleTimeout == 0) { - return;// Other thread interrupted us. - } - final long timeSinceRead = System.currentTimeMillis() - - lastReadTime; - - if (timeSinceRead >= iddleTimeout - 1000) { - return; - } - len = 0; - - } - } - } - - static final String command_names[] = { "CONNECT", "BIND", "UDP_ASSOCIATE" }; - - static final String command2String(int cmd) { - if ((cmd > 0) && (cmd < 4)) { - return command_names[cmd - 1]; - } else { - return "Unknown Command " + cmd; - } - } - - public static void debug (String msg) - { - Log.d("Proxy",msg); - } - - public static void debug (String msg, String host, int port) - { - debug (msg + ": " + host + ":" + port); - } - - public static void debug (String msg, Exception e) - { - - Log.e("Proxy",msg,e); - } - - public static void debug (String msg, InetAddress addr, int port) - { - - debug (msg + ": " + addr.getHostAddress() + ": " + port); - } - - public static void debug (String msg, int type, String log) - { - - debug (msg + " type:" + type + "=" + log); - } -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/Socks4Message.java b/src/com/runjva/sourceforge/jsocks/protocol/Socks4Message.java deleted file mode 100644 index 484ad969..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/Socks4Message.java +++ /dev/null @@ -1,167 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * SOCKS4 Reply/Request message. - */ - -class Socks4Message extends ProxyMessage { - - private byte[] msgBytes; - private int msgLength; - - /** - * Server failed reply, cmd command for failed request - */ - public Socks4Message(final int cmd) { - super(cmd, null, 0); - this.user = null; - - msgLength = 2; - msgBytes = new byte[2]; - - msgBytes[0] = (byte) 0; - msgBytes[1] = (byte) command; - } - - /** - * Server successfull reply - */ - public Socks4Message(final int cmd, final InetAddress ip, final int port) { - this(0, cmd, ip, port, null); - } - - /** - * Client request - */ - public Socks4Message(final int cmd, final InetAddress ip, final int port, - final String user) { - this(SOCKS_VERSION, cmd, ip, port, user); - } - - /** - * Most general constructor - */ - public Socks4Message(final int version, final int cmd, - final InetAddress ip, final int port, final String user) { - - super(cmd, ip, port); - this.user = user; - this.version = version; - - msgLength = user == null ? 8 : 9 + user.length(); - msgBytes = new byte[msgLength]; - - msgBytes[0] = (byte) version; - msgBytes[1] = (byte) command; - msgBytes[2] = (byte) (port >> 8); - msgBytes[3] = (byte) port; - - byte[] addr; - - if (ip != null) { - addr = ip.getAddress(); - } else { - addr = new byte[4]; - addr[0] = addr[1] = addr[2] = addr[3] = 0; - } - System.arraycopy(addr, 0, msgBytes, 4, 4); - - if (user != null) { - final byte[] buf = user.getBytes(); - System.arraycopy(buf, 0, msgBytes, 8, buf.length); - msgBytes[msgBytes.length - 1] = 0; - } - } - - /** - * Initialise from the stream If clientMode is true attempts to read a - * server response otherwise reads a client request see read for more detail - */ - public Socks4Message(final InputStream in, final boolean clientMode) - throws IOException { - msgBytes = null; - read(in, clientMode); - } - - public void read(final InputStream in) throws IOException { - read(in, true); - } - - public void read(final InputStream in, final boolean clientMode) - throws IOException { - final DataInputStream d_in = new DataInputStream(in); - version = d_in.readUnsignedByte(); - command = d_in.readUnsignedByte(); - if (clientMode && (command != REPLY_OK)) { - String errMsg; - // FIXME: Range should be replaced with cases. - if ((command > REPLY_OK) && (command < REPLY_BAD_IDENTD)) { - errMsg = replyMessage[command - REPLY_OK]; - } else { - errMsg = "Unknown Reply Code"; - } - throw new SocksException(command, errMsg); - } - port = d_in.readUnsignedShort(); - final byte[] addr = new byte[4]; - d_in.readFully(addr); - ip = bytes2IP(addr); - host = ip.getHostName(); - if (!clientMode) { - int b = in.read(); - // FIXME: Hope there are no idiots with user name bigger than this - final byte[] userBytes = new byte[256]; - int i = 0; - for (i = 0; (i < userBytes.length) && (b > 0); ++i) { - userBytes[i] = (byte) b; - b = in.read(); - } - user = new String(userBytes, 0, i); - } - } - - public void write(final OutputStream out) throws IOException { - if (msgBytes == null) { - final Socks4Message msg; - msg = new Socks4Message(version, command, ip, port, user); - msgBytes = msg.msgBytes; - msgLength = msg.msgLength; - } - out.write(msgBytes); - } - - // Class methods - static InetAddress bytes2IP(final byte[] addr) { - final String s = bytes2IPV4(addr, 0); - try { - return InetAddress.getByName(s); - } catch (final UnknownHostException uh_ex) { - return null; - } - } - - // Constants - - static final String[] replyMessage = { "Request Granted", - "Request Rejected or Failed", - "Failed request, can't connect to Identd", - "Failed request, bad user name" }; - - static final int SOCKS_VERSION = 4; - - public final static int REQUEST_CONNECT = 1; - public final static int REQUEST_BIND = 2; - - public final static int REPLY_OK = 90; - public final static int REPLY_REJECTED = 91; - public final static int REPLY_NO_CONNECT = 92; - public final static int REPLY_BAD_IDENTD = 93; - -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/Socks4Proxy.java b/src/com/runjva/sourceforge/jsocks/protocol/Socks4Proxy.java deleted file mode 100644 index ac4363bb..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/Socks4Proxy.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * Proxy which describes SOCKS4 proxy. - */ - -public class Socks4Proxy extends SocksProxyBase implements Cloneable { - - // Data members - String user; - - // Public Constructors - // ==================== - - /** - * Creates the SOCKS4 proxy - * - * @param p - * Proxy to use to connect to this proxy, allows proxy chaining. - * @param proxyHost - * Address of the proxy server. - * @param proxyPort - * Port of the proxy server - * @param user - * User name to use for identification purposes. - * @throws UnknownHostException - * If proxyHost can't be resolved. - */ - public Socks4Proxy(SocksProxyBase p, String proxyHost, int proxyPort, - String user) throws UnknownHostException { - super(p, proxyHost, proxyPort); - this.user = new String(user); - version = 4; - } - - /** - * Creates the SOCKS4 proxy - * - * @param proxyHost - * Address of the proxy server. - * @param proxyPort - * Port of the proxy server - * @param user - * User name to use for identification purposes. - * @throws UnknownHostException - * If proxyHost can't be resolved. - */ - public Socks4Proxy(String proxyHost, int proxyPort, String user) - throws UnknownHostException { - this(null, proxyHost, proxyPort, user); - } - - /** - * Creates the SOCKS4 proxy - * - * @param p - * Proxy to use to connect to this proxy, allows proxy chaining. - * @param proxyIP - * Address of the proxy server. - * @param proxyPort - * Port of the proxy server - * @param user - * User name to use for identification purposes. - */ - public Socks4Proxy(SocksProxyBase p, InetAddress proxyIP, int proxyPort, - String user) { - super(p, proxyIP, proxyPort); - this.user = new String(user); - version = 4; - } - - /** - * Creates the SOCKS4 proxy - * - * @param proxyIP - * Address of the proxy server. - * @param proxyPort - * Port of the proxy server - * @param user - * User name to use for identification purposes. - */ - public Socks4Proxy(InetAddress proxyIP, int proxyPort, String user) { - this(null, proxyIP, proxyPort, user); - } - - // Public instance methods - // ======================== - - /** - * Creates a clone of this proxy. Changes made to the clone should not - * affect this object. - */ - public Object clone() { - final Socks4Proxy newProxy = new Socks4Proxy(proxyIP, proxyPort, user); - newProxy.directHosts = (InetRange) directHosts.clone(); - newProxy.chainProxy = chainProxy; - return newProxy; - } - - // Public Static(Class) Methods - // ============================== - - // Protected Methods - // ================= - - protected SocksProxyBase copy() { - final Socks4Proxy copy = new Socks4Proxy(proxyIP, proxyPort, user); - copy.directHosts = this.directHosts; - copy.chainProxy = chainProxy; - return copy; - } - - protected ProxyMessage formMessage(int cmd, InetAddress ip, int port) { - switch (cmd) { - case SOCKS_CMD_CONNECT: - cmd = Socks4Message.REQUEST_CONNECT; - break; - case SOCKS_CMD_BIND: - cmd = Socks4Message.REQUEST_BIND; - break; - default: - return null; - } - return new Socks4Message(cmd, ip, port, user); - } - - protected ProxyMessage formMessage(int cmd, String host, int port) - throws UnknownHostException { - - return formMessage(cmd, InetAddress.getByName(host), port); - } - - protected ProxyMessage formMessage(InputStream in) throws SocksException, - IOException { - - return new Socks4Message(in, true); - } - -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/Socks5DatagramSocket.java b/src/com/runjva/sourceforge/jsocks/protocol/Socks5DatagramSocket.java deleted file mode 100644 index 1b9da340..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/Socks5DatagramSocket.java +++ /dev/null @@ -1,480 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InterruptedIOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; - -/** - * Datagram socket to interract through the firewall.
- * Can be used same way as the normal DatagramSocket. One should be carefull - * though with the datagram sizes used, as additional data is present in both - * incomming and outgoing datagrams. - *

- * SOCKS5 protocol allows to send host address as either: - *

    - *
  • IPV4, normal 4 byte address. (10 bytes header size) - *
  • IPV6, version 6 ip address (not supported by Java as for now). 22 bytes - * header size. - *
  • Host name,(7+length of the host name bytes header size). - *
- * As with other Socks equivalents, direct addresses are handled transparently, - * that is data will be send directly when required by the proxy settings. - *

- * NOTE:
- * Unlike other SOCKS Sockets, it does not support proxy chaining, and - * will throw an exception if proxy has a chain proxy attached. The reason for - * that is not my laziness, but rather the restrictions of the SOCKSv5 protocol. - * Basicaly SOCKSv5 proxy server, needs to know from which host:port datagrams - * will be send for association, and returns address to which datagrams should - * be send by the client, but it does not inform client from which host:port it - * is going to send datagrams, in fact there is even no guarantee they will be - * send at all and from the same address each time. - */ -public class Socks5DatagramSocket extends DatagramSocket { - - InetAddress relayIP; - int relayPort; - Socks5Proxy proxy; - private boolean server_mode = false; - UDPEncapsulation encapsulation; - - /** - * Construct Datagram socket for communication over SOCKS5 proxy server. - * This constructor uses default proxy, the one set with - * Proxy.setDefaultProxy() method. If default proxy is not set or it is set - * to version4 proxy, which does not support datagram forwarding, throws - * SocksException. - */ - public Socks5DatagramSocket() throws SocksException, IOException { - this(SocksProxyBase.defaultProxy, 0, null); - } - - /** - * Construct Datagram socket for communication over SOCKS5 proxy server. And - * binds it to the specified local port. This constructor uses default - * proxy, the one set with Proxy.setDefaultProxy() method. If default proxy - * is not set or it is set to version4 proxy, which does not support - * datagram forwarding, throws SocksException. - */ - public Socks5DatagramSocket(int port) throws SocksException, IOException { - this(SocksProxyBase.defaultProxy, port, null); - } - - /** - * Construct Datagram socket for communication over SOCKS5 proxy server. And - * binds it to the specified local port and address. This constructor uses - * default proxy, the one set with Proxy.setDefaultProxy() method. If - * default proxy is not set or it is set to version4 proxy, which does not - * support datagram forwarding, throws SocksException. - */ - public Socks5DatagramSocket(int port, InetAddress ip) - throws SocksException, IOException { - this(SocksProxyBase.defaultProxy, port, ip); - } - - /** - * Constructs datagram socket for communication over specified proxy. And - * binds it to the given local address and port. Address of null and port of - * 0, signify any availabale port/address. Might throw SocksException, if: - *

    - *
  1. Given version of proxy does not support UDP_ASSOCIATE. - *
  2. Proxy can't be reached. - *
  3. Authorization fails. - *
  4. Proxy does not want to perform udp forwarding, for any reason. - *
- * Might throw IOException if binding datagram socket to given address/port - * fails. See java.net.DatagramSocket for more details. - */ - public Socks5DatagramSocket(SocksProxyBase p, int port, InetAddress ip) - throws SocksException, IOException { - - super(port, ip); - - if (p == null) { - throw new SocksException(SocksProxyBase.SOCKS_NO_PROXY); - } - - if (!(p instanceof Socks5Proxy)) { - final String s = "Datagram Socket needs Proxy version 5"; - throw new SocksException(-1, s); - } - - if (p.chainProxy != null) { - final String s = "Datagram Sockets do not support proxy chaining."; - throw new SocksException(SocksProxyBase.SOCKS_JUST_ERROR, s); - } - - proxy = (Socks5Proxy) p.copy(); - - final ProxyMessage msg = proxy.udpAssociate(super.getLocalAddress(), - super.getLocalPort()); - - relayIP = msg.ip; - if (relayIP.getHostAddress().equals("0.0.0.0")) { - // FIXME: What happens here? - relayIP = proxy.proxyIP; - } - relayPort = msg.port; - - encapsulation = proxy.udp_encapsulation; - - // log.debug("Datagram Socket:{}:{}", getLocalAddress(), getLocalPort()); - // log.debug("Socks5Datagram: {}:{}", relayIP, relayPort); - } - - /** - * Used by UDPRelayServer. - */ - Socks5DatagramSocket(boolean server_mode, UDPEncapsulation encapsulation, - InetAddress relayIP, int relayPort) throws IOException { - super(); - this.server_mode = server_mode; - this.relayIP = relayIP; - this.relayPort = relayPort; - this.encapsulation = encapsulation; - this.proxy = null; - } - - /** - * Sends the Datagram either through the proxy or directly depending on - * current proxy settings and destination address.
- * - * NOTE: DatagramPacket size should be at least 10 bytes less than - * the systems limit. - * - *

- * See documentation on java.net.DatagramSocket for full details on how to - * use this method. - * - * @param dp - * Datagram to send. - * @throws IOException - * If error happens with I/O. - */ - public void send(DatagramPacket dp) throws IOException { - // If the host should be accessed directly, send it as is. - if (!server_mode && proxy.isDirect(dp.getAddress())) { - super.send(dp); - // log.debug("Sending datagram packet directly:"); - return; - } - - final byte[] head = formHeader(dp.getAddress(), dp.getPort()); - byte[] buf = new byte[head.length + dp.getLength()]; - final byte[] data = dp.getData(); - - // Merge head and data - System.arraycopy(head, 0, buf, 0, head.length); - // System.arraycopy(data,dp.getOffset(),buf,head.length,dp.getLength()); - System.arraycopy(data, 0, buf, head.length, dp.getLength()); - - if (encapsulation != null) { - buf = encapsulation.udpEncapsulate(buf, true); - } - - super.send(new DatagramPacket(buf, buf.length, relayIP, relayPort)); - } - - /** - * This method allows to send datagram packets with address type DOMAINNAME. - * SOCKS5 allows to specify host as names rather than ip addresses.Using - * this method one can send udp datagrams through the proxy, without having - * to know the ip address of the destination host. - *

- * If proxy specified for that socket has an option resolveAddrLocally set - * to true host will be resolved, and the datagram will be send with address - * type IPV4, if resolve fails, UnknownHostException is thrown. - * - * @param dp - * Datagram to send, it should contain valid port and data - * @param host - * Host name to which datagram should be send. - * @throws IOException - * If error happens with I/O, or the host can't be resolved when - * proxy settings say that hosts should be resolved locally. - * @see Socks5Proxy#resolveAddrLocally(boolean) - */ - public void send(DatagramPacket dp, String host) throws IOException { - if (proxy.isDirect(host)) { - dp.setAddress(InetAddress.getByName(host)); - super.send(dp); - return; - } - - if ((proxy).resolveAddrLocally) { - dp.setAddress(InetAddress.getByName(host)); - } - - final byte[] head = formHeader(host, dp.getPort()); - byte[] buf = new byte[head.length + dp.getLength()]; - final byte[] data = dp.getData(); - // Merge head and data - System.arraycopy(head, 0, buf, 0, head.length); - // System.arraycopy(data,dp.getOffset(),buf,head.length,dp.getLength()); - System.arraycopy(data, 0, buf, head.length, dp.getLength()); - - if (encapsulation != null) { - buf = encapsulation.udpEncapsulate(buf, true); - } - - super.send(new DatagramPacket(buf, buf.length, relayIP, relayPort)); - } - - /** - * Receives udp packet. If packet have arrived from the proxy relay server, - * it is processed and address and port of the packet are set to the address - * and port of sending host.
- * If the packet arrived from anywhere else it is not changed.
- * NOTE: DatagramPacket size should be at least 10 bytes bigger - * than the largest packet you expect (this is for IPV4 addresses). For - * hostnames and IPV6 it is even more. - * - * @param dp - * Datagram in which all relevent information will be copied. - */ - public void receive(DatagramPacket dp) throws IOException { - super.receive(dp); - - if (server_mode) { - // Drop all datagrams not from relayIP/relayPort - final int init_length = dp.getLength(); - final int initTimeout = getSoTimeout(); - final long startTime = System.currentTimeMillis(); - - while (!relayIP.equals(dp.getAddress()) - || (relayPort != dp.getPort())) { - - // Restore datagram size - dp.setLength(init_length); - - // If there is a non-infinit timeout on this socket - // Make sure that it happens no matter how often unexpected - // packets arrive. - if (initTimeout != 0) { - final long passed = System.currentTimeMillis() - startTime; - final int newTimeout = initTimeout - (int) passed; - - if (newTimeout <= 0) { - throw new InterruptedIOException( - "In Socks5DatagramSocket->receive()"); - } - setSoTimeout(newTimeout); - } - - super.receive(dp); - } - - // Restore timeout settings - if (initTimeout != 0) { - setSoTimeout(initTimeout); - } - - } else if (!relayIP.equals(dp.getAddress()) - || (relayPort != dp.getPort())) { - return; // Recieved direct packet - // If the datagram is not from the relay server, return it it as is. - } - - byte[] data; - data = dp.getData(); - - if (encapsulation != null) { - data = encapsulation.udpEncapsulate(data, false); - } - - // FIXME: What is this? - final int offset = 0; // Java 1.1 - // int offset = dp.getOffset(); //Java 1.2 - - final ByteArrayInputStream bIn = new ByteArrayInputStream(data, offset, - dp.getLength()); - - final ProxyMessage msg = new Socks5Message(bIn); - dp.setPort(msg.port); - dp.setAddress(msg.getInetAddress()); - - // what wasn't read by the Message is the data - final int data_length = bIn.available(); - // Shift data to the left - System.arraycopy(data, offset + dp.getLength() - data_length, data, - offset, data_length); - - dp.setLength(data_length); - } - - /** - * Returns port assigned by the proxy, to which datagrams are relayed. It is - * not the same port to which other party should send datagrams. - * - * @return Port assigned by socks server to which datagrams are send for - * association. - */ - public int getLocalPort() { - if (server_mode) { - return super.getLocalPort(); - } - return relayPort; - } - - /** - * Address assigned by the proxy, to which datagrams are send for relay. It - * is not necesseraly the same address, to which other party should send - * datagrams. - * - * @return Address to which datagrams are send for association. - */ - public InetAddress getLocalAddress() { - if (server_mode) { - return super.getLocalAddress(); - } - return relayIP; - } - - /** - * Closes datagram socket, and proxy connection. - */ - public void close() { - if (!server_mode) { - proxy.endSession(); - } - super.close(); - } - - /** - * This method checks wether proxy still runs udp forwarding service for - * this socket. - *

- * This methods checks wether the primary connection to proxy server is - * active. If it is, chances are that proxy continues to forward datagrams - * being send from this socket. If it was closed, most likely datagrams are - * no longer being forwarded by the server. - *

- * Proxy might decide to stop forwarding datagrams, in which case it should - * close primary connection. This method allows to check, wether this have - * been done. - *

- * You can specify timeout for which we should be checking EOF condition on - * the primary connection. Timeout is in milliseconds. Specifying 0 as - * timeout implies infinity, in which case method will block, until - * connection to proxy is closed or an error happens, and then return false. - *

- * One possible scenario is to call isProxyactive(0) in separate thread, and - * once it returned notify other threads about this event. - * - * @param timeout - * For how long this method should block, before returning. - * @return true if connection to proxy is active, false if eof or error - * condition have been encountered on the connection. - */ - public boolean isProxyAlive(int timeout) { - if (server_mode) { - return false; - } - if (proxy != null) { - try { - proxy.proxySocket.setSoTimeout(timeout); - - final int eof = proxy.in.read(); - if (eof < 0) { - return false; // EOF encountered. - } else { - //log.warn("This really should not happen"); - return true; // This really should not happen - } - - } catch (final InterruptedIOException iioe) { - return true; // read timed out. - } catch (final IOException ioe) { - return false; - } - } - return false; - } - - // PRIVATE METHODS - // //////////////// - - private byte[] formHeader(InetAddress ip, int port) { - final Socks5Message request = new Socks5Message(0, ip, port); - request.data[0] = 0; - return request.data; - } - - private byte[] formHeader(String host, int port) { - final Socks5Message request = new Socks5Message(0, host, port); - request.data[0] = 0; - return request.data; - } - - /* - * ====================================================================== - * - * //Mainly Test functions ////////////////////// - * - * private String bytes2String(byte[] b){ String s=""; char[] hex_digit = { - * '0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F'}; - * for(int i=0;i> 4; int i2 = b[i] & - * 0xF; s+=hex_digit[i1]; s+=hex_digit[i2]; s+=" "; } return s; } private - * static final void debug(String s){ if(DEBUG) System.out.print(s); } - * - * private static final boolean DEBUG = true; - * - * - * public static void usage(){ System.err.print( - * "Usage: java Socks.SocksDatagramSocket host port [socksHost socksPort]\n" - * ); } - * - * static final int defaultProxyPort = 1080; //Default Port static final - * String defaultProxyHost = "www-proxy"; //Default proxy - * - * public static void main(String args[]){ int port; String host; int - * proxyPort; String proxyHost; InetAddress ip; - * - * if(args.length > 1 && args.length < 5){ try{ - * - * host = args[0]; port = Integer.parseInt(args[1]); - * - * proxyPort =(args.length > 3)? Integer.parseInt(args[3]) : - * defaultProxyPort; - * - * host = args[0]; ip = InetAddress.getByName(host); - * - * proxyHost =(args.length > 2)? args[2] : defaultProxyHost; - * - * Proxy.setDefaultProxy(proxyHost,proxyPort); Proxy p = - * Proxy.getDefaultProxy(); p.addDirect("lux"); - * - * - * DatagramSocket ds = new Socks5DatagramSocket(); - * - * - * BufferedReader in = new BufferedReader( new - * InputStreamReader(System.in)); String s; - * - * System.out.print("Enter line:"); s = in.readLine(); - * - * while(s != null){ byte[] data = (s+"\r\n").getBytes(); DatagramPacket dp - * = new DatagramPacket(data,0,data.length, ip,port); - * System.out.println("Sending to: "+ip+":"+port); ds.send(dp); dp = new - * DatagramPacket(new byte[1024],1024); - * - * System.out.println("Trying to recieve on port:"+ ds.getLocalPort()); - * ds.receive(dp); System.out.print("Recieved:\n"+ - * "From:"+dp.getAddress()+":"+dp.getPort()+ "\n\n"+ new - * String(dp.getData(),dp.getOffset(),dp.getLength())+"\n" ); - * System.out.print("Enter line:"); s = in.readLine(); - * - * } ds.close(); System.exit(1); - * - * }catch(SocksException s_ex){ System.err.println("SocksException:"+s_ex); - * s_ex.printStackTrace(); System.exit(1); }catch(IOException io_ex){ - * io_ex.printStackTrace(); System.exit(1); }catch(NumberFormatException - * num_ex){ usage(); num_ex.printStackTrace(); System.exit(1); } - * - * }else{ usage(); } } - */ - -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/Socks5Message.java b/src/com/runjva/sourceforge/jsocks/protocol/Socks5Message.java deleted file mode 100644 index c61c882e..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/Socks5Message.java +++ /dev/null @@ -1,324 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * SOCKS5 request/response message. - */ - -class Socks5Message extends ProxyMessage { - /** Address type of given message */ - public int addrType; - - byte[] data; - - - /** - * Server error response. - * - * @param cmd - * Error code. - */ - public Socks5Message(int cmd) { - super(cmd, null, 0); - data = new byte[3]; - data[0] = SOCKS_VERSION; // Version. - data[1] = (byte) cmd; // Reply code for some kind of failure. - data[2] = 0; // Reserved byte. - } - - /** - * Construct client request or server response. - * - * @param cmd - * - Request/Response code. - * @param ip - * - IP field. - * @paarm port - port field. - */ - public Socks5Message(int cmd, InetAddress ip, int port) { - super(cmd, ip, port); - - if (ip == null) { - this.host = "0.0.0.0"; - } else { - this.host = ip.getHostName(); - } - - this.version = SOCKS_VERSION; - - byte[] addr; - - if (ip == null) { - addr = new byte[4]; - addr[0] = addr[1] = addr[2] = addr[3] = 0; - } else { - addr = ip.getAddress(); - } - - if (addr.length == 4) { - addrType = SOCKS_ATYP_IPV4; - } else { - addrType = SOCKS_ATYP_IPV6; - } - - data = new byte[6 + addr.length]; - data[0] = (byte) SOCKS_VERSION; // Version - data[1] = (byte) command; // Command - data[2] = (byte) 0; // Reserved byte - data[3] = (byte) addrType; // Address type - - // Put Address - System.arraycopy(addr, 0, data, 4, addr.length); - // Put port - data[data.length - 2] = (byte) (port >> 8); - data[data.length - 1] = (byte) (port); - } - - /** - * Construct client request or server response. - * - * @param cmd - * - Request/Response code. - * @param hostName - * - IP field as hostName, uses ADDR_TYPE of HOSTNAME. - * @paarm port - port field. - */ - public Socks5Message(int cmd, String hostName, int port) { - super(cmd, null, port); - this.host = hostName; - this.version = SOCKS_VERSION; - - addrType = SOCKS_ATYP_DOMAINNAME; - final byte addr[] = hostName.getBytes(); - - data = new byte[7 + addr.length]; - data[0] = (byte) SOCKS_VERSION; // Version - data[1] = (byte) command; // Command - data[2] = (byte) 0; // Reserved byte - data[3] = (byte) SOCKS_ATYP_DOMAINNAME; // Address type - data[4] = (byte) addr.length; // Length of the address - - // Put Address - System.arraycopy(addr, 0, data, 5, addr.length); - // Put port - data[data.length - 2] = (byte) (port >> 8); - data[data.length - 1] = (byte) (port); - } - - /** - * Initialises Message from the stream. Reads server response from given - * stream. - * - * @param in - * Input stream to read response from. - * @throws SocksException - * If server response code is not SOCKS_SUCCESS(0), or if any - * error with protocol occurs. - * @throws IOException - * If any error happens with I/O. - */ - public Socks5Message(InputStream in) throws SocksException, IOException { - this(in, true); - } - - /** - * Initialises Message from the stream. Reads server response or client - * request from given stream. - * - * @param in - * Input stream to read response from. - * @param clinetMode - * If true read server response, else read client request. - * @throws SocksException - * If server response code is not SOCKS_SUCCESS(0) and reading - * in client mode, or if any error with protocol occurs. - * @throws IOException - * If any error happens with I/O. - */ - public Socks5Message(InputStream in, boolean clientMode) - throws SocksException, IOException { - - read(in, clientMode); - } - - /** - * Initialises Message from the stream. Reads server response from given - * stream. - * - * @param in - * Input stream to read response from. - * @throws SocksException - * If server response code is not SOCKS_SUCCESS(0), or if any - * error with protocol occurs. - * @throws IOException - * If any error happens with I/O. - */ - public void read(InputStream in) throws SocksException, IOException { - read(in, true); - } - - /** - * Initialises Message from the stream. Reads server response or client - * request from given stream. - * - * @param in - * Input stream to read response from. - * @param clinetMode - * If true read server response, else read client request. - * @throws SocksException - * If server response code is not SOCKS_SUCCESS(0) and reading - * in client mode, or if any error with protocol occurs. - * @throws IOException - * If any error happens with I/O. - */ - public void read(InputStream in, boolean clientMode) throws SocksException, - IOException { - - data = null; - ip = null; - - final DataInputStream di = new DataInputStream(in); - - version = di.readUnsignedByte(); - command = di.readUnsignedByte(); - - if (clientMode && (command != 0)) { - throw new SocksException(command); - } - - di.readUnsignedByte(); - addrType = di.readUnsignedByte(); - - byte addr[]; - - switch (addrType) { - case SOCKS_ATYP_IPV4: - addr = new byte[4]; - di.readFully(addr); - host = bytes2IPV4(addr, 0); - break; - case SOCKS_ATYP_IPV6: - addr = new byte[SOCKS_IPV6_LENGTH];// I believe it is 16 bytes,huge! - di.readFully(addr); - host = bytes2IPV6(addr, 0); - break; - case SOCKS_ATYP_DOMAINNAME: -// log.debug("Reading ATYP_DOMAINNAME"); - addr = new byte[di.readUnsignedByte()];// Next byte shows the length - di.readFully(addr); - host = new String(addr); - break; - default: - throw (new SocksException(SocksProxyBase.SOCKS_JUST_ERROR)); - } - - port = di.readUnsignedShort(); - - if ((addrType != SOCKS_ATYP_DOMAINNAME) && doResolveIP) { - try { - ip = InetAddress.getByName(host); - } catch (final UnknownHostException uh_ex) { - } - } - } - - /** - * Writes the message to the stream. - * - * @param out - * Output stream to which message should be written. - */ - public void write(OutputStream out) throws SocksException, IOException { - if (data == null) { - Socks5Message msg; - - if (addrType == SOCKS_ATYP_DOMAINNAME) { - msg = new Socks5Message(command, host, port); - } else { - if (ip == null) { - try { - ip = InetAddress.getByName(host); - } catch (final UnknownHostException uh_ex) { - throw new SocksException( - SocksProxyBase.SOCKS_JUST_ERROR); - } - } - msg = new Socks5Message(command, ip, port); - } - data = msg.data; - } - out.write(data); - } - - /** - * Returns IP field of the message as IP, if the message was created with - * ATYP of HOSTNAME, it will attempt to resolve the hostname, which might - * fail. - * - * @throws UnknownHostException - * if host can't be resolved. - */ - public InetAddress getInetAddress() throws UnknownHostException { - if (ip != null) { - return ip; - } - - return (ip = InetAddress.getByName(host)); - } - - /** - * Returns string representation of the message. - */ - public String toString() { - // FIXME: Single line version, please. - final String s = "Socks5Message:" + "\n" + "VN " + version + "\n" - + "CMD " + command + "\n" + "ATYP " + addrType + "\n" - + "ADDR " + host + "\n" + "PORT " + port + "\n"; - return s; - } - - /** - *Wether to resolve hostIP returned from SOCKS server that is wether to - * create InetAddress object from the hostName string - */ - static public boolean resolveIP() { - return doResolveIP; - } - - /** - *Wether to resolve hostIP returned from SOCKS server that is wether to - * create InetAddress object from the hostName string - * - * @param doResolve - * Wether to resolve hostIP from SOCKS server. - *@return Previous value. - */ - static public boolean resolveIP(boolean doResolve) { - final boolean old = doResolveIP; - doResolveIP = doResolve; - return old; - } - - /* - * private static final void debug(String s){ if(DEBUG) System.out.print(s); - * } private static final boolean DEBUG = false; - */ - - // SOCKS5 constants - public static final int SOCKS_VERSION = 5; - - public static final int SOCKS_ATYP_IPV4 = 0x1; // Where is 2?? - public static final int SOCKS_ATYP_DOMAINNAME = 0x3; // !!!!rfc1928 - public static final int SOCKS_ATYP_IPV6 = 0x4; - - public static final int SOCKS_IPV6_LENGTH = 16; - - static boolean doResolveIP = true; - -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/Socks5Proxy.java b/src/com/runjva/sourceforge/jsocks/protocol/Socks5Proxy.java deleted file mode 100644 index 7400aa6e..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/Socks5Proxy.java +++ /dev/null @@ -1,295 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.Socket; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Enumeration; -import java.util.Hashtable; - -/** - * SOCKS5 Proxy. - */ - -public class Socks5Proxy extends SocksProxyBase implements Cloneable { - - // Data members - private Hashtable authMethods = new Hashtable(); - private int selectedMethod; - - boolean resolveAddrLocally = true; - UDPEncapsulation udp_encapsulation = null; - - // Public Constructors - // ==================== - - /** - * Creates SOCKS5 proxy. - * - * @param p - * Proxy to use to connect to this proxy, allows proxy chaining. - * @param proxyHost - * Host on which a Proxy server runs. - * @param proxyPort - * Port on which a Proxy server listens for connections. - * @throws UnknownHostException - * If proxyHost can't be resolved. - */ - public Socks5Proxy(SocksProxyBase p, String proxyHost, int proxyPort) - throws UnknownHostException { - - super(p, proxyHost, proxyPort); - version = 5; - setAuthenticationMethod(0, new AuthenticationNone()); - } - - /** - * Creates SOCKS5 proxy. - * - * @param proxyHost - * Host on which a Proxy server runs. - * @param proxyPort - * Port on which a Proxy server listens for connections. - * @throws UnknownHostException - * If proxyHost can't be resolved. - */ - public Socks5Proxy(String proxyHost, int proxyPort) - throws UnknownHostException { - this(null, proxyHost, proxyPort); - } - - /** - * Creates SOCKS5 proxy. - * - * @param p - * Proxy to use to connect to this proxy, allows proxy chaining. - * @param proxyIP - * Host on which a Proxy server runs. - * @param proxyPort - * Port on which a Proxy server listens for connections. - */ - public Socks5Proxy(SocksProxyBase p, InetAddress proxyIP, int proxyPort) { - super(p, proxyIP, proxyPort); - version = 5; - setAuthenticationMethod(0, new AuthenticationNone()); - } - - /** - * Creates SOCKS5 proxy. - * - * @param proxyIP - * Host on which a Proxy server runs. - * @param proxyPort - * Port on which a Proxy server listens for connections. - */ - public Socks5Proxy(InetAddress proxyIP, int proxyPort) { - this(null, proxyIP, proxyPort); - } - - // Public instance methods - // ======================== - - /** - * Wether to resolve address locally or to let proxy do so. - *

- * SOCKS5 protocol allows to send host names rather then IPs in the - * requests, this option controls wether the hostnames should be send to the - * proxy server as names, or should they be resolved locally. - * - * @param doResolve - * Wether to perform resolution locally. - * @return Previous settings. - */ - public boolean resolveAddrLocally(boolean doResolve) { - final boolean old = resolveAddrLocally; - resolveAddrLocally = doResolve; - return old; - } - - /** - * Get current setting on how the addresses should be handled. - * - * @return Current setting for address resolution. - * @see Socks5Proxy#resolveAddrLocally(boolean doResolve) - */ - public boolean resolveAddrLocally() { - return resolveAddrLocally; - } - - /** - * Adds another authentication method. - * - * @param methodId - * Authentication method id, see rfc1928 - * @param method - * Implementation of Authentication - * @see Authentication - */ - public boolean setAuthenticationMethod(int methodId, Authentication method) { - if ((methodId < 0) || (methodId > 255)) { - return false; - } - if (method == null) { - // Want to remove a particular method - return (authMethods.remove(new Integer(methodId)) != null); - } else {// Add the method, or rewrite old one - authMethods.put(new Integer(methodId), method); - } - return true; - } - - /** - * Get authentication method, which corresponds to given method id - * - * @param methodId - * Authentication method id. - * @return Implementation for given method or null, if one was not set. - */ - public Authentication getAuthenticationMethod(int methodId) { - final Object method = authMethods.get(new Integer(methodId)); - if (method == null) { - return null; - } - return (Authentication) method; - } - - /** - * Creates a clone of this Proxy. clone() returns an - */ - @SuppressWarnings("unchecked") - public Object clone() { - final Socks5Proxy newProxy = new Socks5Proxy(proxyIP, proxyPort); - - final Object o = this.authMethods.clone(); - newProxy.authMethods = (Hashtable) o; - - newProxy.directHosts = (InetRange) directHosts.clone(); - newProxy.resolveAddrLocally = resolveAddrLocally; - newProxy.chainProxy = chainProxy; - return newProxy; - } - - // Public Static(Class) Methods - // ============================== - - // Protected Methods - // ================= - - protected SocksProxyBase copy() { - final Socks5Proxy copy = new Socks5Proxy(proxyIP, proxyPort); - - copy.authMethods = this.authMethods; // same Hash, no copy - copy.directHosts = this.directHosts; - copy.chainProxy = this.chainProxy; - copy.resolveAddrLocally = this.resolveAddrLocally; - return copy; - } - - /** - * - * - */ - protected void startSession() throws SocksException { - super.startSession(); - Authentication auth; - final Socket ps = proxySocket; // The name is too long - - try { - - final byte nMethods = (byte) authMethods.size(); // Number of - // methods - - final byte[] buf = new byte[2 + nMethods]; // 2 is for VER,NMETHODS - buf[0] = (byte) version; - buf[1] = nMethods; // Number of methods - int i = 2; - - final Enumeration ids = authMethods.keys(); - while (ids.hasMoreElements()) { - buf[i++] = (byte) ids.nextElement().intValue(); - } - - out.write(buf); - out.flush(); - - final int versionNumber = in.read(); - selectedMethod = in.read(); - - if ((versionNumber < 0) || (selectedMethod < 0)) { - // EOF condition was reached - endSession(); - final String s = "Connection to proxy lost."; - throw new SocksException(SOCKS_PROXY_IO_ERROR, s); - } - - if (versionNumber < version) { - // What should we do?? - } - - if (selectedMethod == 0xFF) { // No method selected - ps.close(); - throw (new SocksException(SOCKS_AUTH_NOT_SUPPORTED)); - } - - auth = getAuthenticationMethod(selectedMethod); - if (auth == null) { - // This shouldn't happen, unless method was removed by other - // thread, or the server stuffed up - final String s = "Specified Authentication not found!"; - throw new SocksException(SOCKS_JUST_ERROR, s); - } - - final Object[] in_out; - in_out = auth.doSocksAuthentication(selectedMethod, ps); - - if (in_out == null) { - // Authentication failed by some reason - throw (new SocksException(SOCKS_AUTH_FAILURE)); - } - - /* - * Most authentication methods are expected to return simply the - * input/output streams associated with the socket. However if the - * auth. method requires some kind of encryption/decryption being - * done on the connection it should provide classes to handle I/O. - */ - - in = (InputStream) in_out[0]; - out = (OutputStream) in_out[1]; - if (in_out.length > 2) { - udp_encapsulation = (UDPEncapsulation) in_out[2]; - } - - } catch (final SocksException s_ex) { - throw s_ex; - } catch (final UnknownHostException uh_ex) { - throw new SocksException(SOCKS_PROXY_NO_CONNECT, uh_ex); - } catch (final SocketException so_ex) { - throw new SocksException(SOCKS_PROXY_NO_CONNECT, so_ex); - } catch (final IOException io_ex) { - throw new SocksException(SOCKS_PROXY_IO_ERROR, io_ex); - } - } - - protected ProxyMessage formMessage(int cmd, InetAddress ip, int port) { - return new Socks5Message(cmd, ip, port); - } - - protected ProxyMessage formMessage(int cmd, String host, int port) - throws UnknownHostException { - if (resolveAddrLocally) { - return formMessage(cmd, InetAddress.getByName(host), port); - } else { - return new Socks5Message(cmd, host, port); - } - } - - protected ProxyMessage formMessage(InputStream in) throws SocksException, - IOException { - return new Socks5Message(in); - } - -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/SocksException.java b/src/com/runjva/sourceforge/jsocks/protocol/SocksException.java deleted file mode 100644 index a6515974..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/SocksException.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -/** - * Exception thrown by various socks classes to indicate errors with protocol or - * unsuccessfull server responses. - */ -public class SocksException extends java.io.IOException { - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Construct a SocksException with given errorcode. - *

- * Tries to look up message which corresponds to this error code. - * - * @param errCode - * Error code for this exception. - */ - public SocksException(int errCode) { - this.errCode = errCode; - lookupErrorString(errCode); - } - - private void lookupErrorString(int errCode) { - if ((errCode >> 16) == 0) { - if (errCode <= serverReplyMessage.length) { - errString = serverReplyMessage[errCode]; - } else { - errString = UNASSIGNED_ERROR_MESSAGE; - } - } else { - // Local error - errCode = (errCode >> 16) - 1; - if (errCode <= localErrorMessage.length) { - errString = localErrorMessage[errCode]; - } else { - errString = UNASSIGNED_ERROR_MESSAGE; - } - } - } - - /** - * Construct a SocksException with given error code, and a Throwable cause - * - * @param errCode - * @param t - * Nested exception for debugging purposes. - */ - public SocksException(int errCode, Throwable t) { - super(t); // Java 1.6+ - this.errCode = errCode; - lookupErrorString(errCode); - } - - /** - * Constructs a SocksException with given error code and message. - * - * @param errCode - * Error code. - * @param errString - * Error Message. - */ - public SocksException(int errCode, String errString) { - this.errCode = errCode; - this.errString = errString; - } - - public SocksException(int errCode, String string, Throwable t) { - super(string, t); // Java 1.6+ - this.errCode = errCode; - this.errString = string; - } - - /** - * Get the error code associated with this exception. - * - * @return Error code associated with this exception. - */ - public int getErrorCode() { - return errCode; - } - - /** - * Get human readable representation of this exception. - * - * @return String represntation of this exception. - */ - public String toString() { - return errString; - } - - static final String UNASSIGNED_ERROR_MESSAGE = "Unknown error message"; - - static final String serverReplyMessage[] = { "Succeeded", - "General SOCKS server failure", - "Connection not allowed by ruleset", "Network unreachable", - "Host unreachable", "Connection refused", "TTL expired", - "Command not supported", "Address type not supported" }; - - static final String localErrorMessage[] = { "SOCKS server not specified", - "Unable to contact SOCKS server", "IO error", - "None of Authentication methods are supported", - "Authentication failed", "General SOCKS fault" }; - - String errString; - int errCode; - -}// End of SocksException class - diff --git a/src/com/runjva/sourceforge/jsocks/protocol/SocksProxyBase.java b/src/com/runjva/sourceforge/jsocks/protocol/SocksProxyBase.java deleted file mode 100644 index c4ce565b..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/SocksProxyBase.java +++ /dev/null @@ -1,543 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -/** - * Abstract class Proxy, base for classes Socks4Proxy and Socks5Proxy. Defines - * methods for specifying default proxy, to be used by all classes of this - * package. - */ - -public abstract class SocksProxyBase { - - // Data members - protected InetRange directHosts = new InetRange(); - - protected InetAddress proxyIP = null; - protected String proxyHost = null; - protected int proxyPort; - protected Socket proxySocket = null; - - protected InputStream in; - protected OutputStream out; - - protected int version; - - protected SocksProxyBase chainProxy = null; - - // Protected static/class variables - protected static SocksProxyBase defaultProxy = null; - - // Constructors - // ==================== - SocksProxyBase(SocksProxyBase chainProxy, String proxyHost, int proxyPort) - throws UnknownHostException { - this.chainProxy = chainProxy; - this.proxyHost = proxyHost; - - if (chainProxy == null) { - this.proxyIP = InetAddress.getByName(proxyHost); - } - - this.proxyPort = proxyPort; - } - - SocksProxyBase(String proxyHost, int proxyPort) throws UnknownHostException { - this(null, proxyHost, proxyPort); - } - - SocksProxyBase(SocksProxyBase chainProxy, InetAddress proxyIP, int proxyPort) { - this.chainProxy = chainProxy; - this.proxyIP = proxyIP; - this.proxyPort = proxyPort; - } - - SocksProxyBase(InetAddress proxyIP, int proxyPort) { - this(null, proxyIP, proxyPort); - } - - SocksProxyBase(SocksProxyBase p) { - this.proxyIP = p.proxyIP; - this.proxyPort = p.proxyPort; - this.version = p.version; - this.directHosts = p.directHosts; - } - - // Public instance methods - // ======================== - - /** - * Get the port on which proxy server is running. - * - * @return Proxy port. - */ - public int getPort() { - return proxyPort; - } - - /** - * Get the ip address of the proxy server host. - * - * @return Proxy InetAddress. - */ - public InetAddress getInetAddress() { - return proxyIP; - } - - /** - * Adds given ip to the list of direct addresses. This machine will be - * accessed without using proxy. - */ - public void addDirect(InetAddress ip) { - directHosts.add(ip); - } - - /** - * Adds host to the list of direct addresses. This machine will be accessed - * without using proxy. - */ - public boolean addDirect(String host) { - return directHosts.add(host); - } - - /** - * Adds given range of addresses to the lsit of direct addresses, machines - * within this range will be accessed without using proxy. - */ - public void addDirect(InetAddress from, InetAddress to) { - directHosts.add(from, to); - } - - /** - * Sets given InetRange as the list of direct address, previous list will be - * discarded, any changes done previously with addDirect(Inetaddress) will - * be lost. The machines in this range will be accessed without using proxy. - * - * @param ir - * InetRange which should be used to look up direct addresses. - * @see InetRange - */ - public void setDirect(InetRange ir) { - directHosts = ir; - } - - /** - * Get the list of direct hosts. - * - * @return Current range of direct address as InetRange object. - * @see InetRange - */ - public InetRange getDirect() { - return directHosts; - } - - /** - * Check wether the given host is on the list of direct address. - * - * @param host - * Host name to check. - * @return true if the given host is specified as the direct addresses. - */ - public boolean isDirect(String host) { - return directHosts.contains(host); - } - - /** - * Check wether the given host is on the list of direct addresses. - * - * @param host - * Host address to check. - * @return true if the given host is specified as the direct address. - */ - public boolean isDirect(InetAddress host) { - return directHosts.contains(host); - } - - /** - * Set the proxy which should be used to connect to given proxy. - * - * @param chainProxy - * Proxy to use to connect to this proxy. - */ - public void setChainProxy(SocksProxyBase chainProxy) { - this.chainProxy = chainProxy; - } - - /** - * Get proxy which is used to connect to this proxy. - * - * @return Proxy which is used to connect to this proxy, or null if proxy is - * to be contacted directly. - */ - public SocksProxyBase getChainProxy() { - return chainProxy; - } - - /** - * Get string representation of this proxy. - * - * @returns string in the form:proxyHost:proxyPort \t Version versionNumber - */ - public String toString() { - return ("" + proxyIP.getHostName() + ":" + proxyPort + "\tVersion " + version); - } - - // Public Static(Class) Methods - // ============================== - - /** - * Sets SOCKS4 proxy as default. - * - * @param hostName - * Host name on which SOCKS4 server is running. - * @param port - * Port on which SOCKS4 server is running. - * @param user - * Username to use for communications with proxy. - */ - public static void setDefaultProxy(String hostName, int port, String user) - throws UnknownHostException { - defaultProxy = new Socks4Proxy(hostName, port, user); - } - - /** - * Sets SOCKS4 proxy as default. - * - * @param ipAddress - * Host address on which SOCKS4 server is running. - * @param port - * Port on which SOCKS4 server is running. - * @param user - * Username to use for communications with proxy. - */ - public static void setDefaultProxy(InetAddress ipAddress, int port, - String user) { - defaultProxy = new Socks4Proxy(ipAddress, port, user); - } - - /** - * Sets SOCKS5 proxy as default. Default proxy only supports - * no-authentication. - * - * @param hostName - * Host name on which SOCKS5 server is running. - * @param port - * Port on which SOCKS5 server is running. - */ - public static void setDefaultProxy(String hostName, int port) - throws UnknownHostException { - defaultProxy = new Socks5Proxy(hostName, port); - } - - /** - * Sets SOCKS5 proxy as default. Default proxy only supports - * no-authentication. - * - * @param ipAddress - * Host address on which SOCKS5 server is running. - * @param port - * Port on which SOCKS5 server is running. - */ - public static void setDefaultProxy(InetAddress ipAddress, int port) { - defaultProxy = new Socks5Proxy(ipAddress, port); - } - - /** - * Sets default proxy. - * - * @param p - * Proxy to use as default proxy. - */ - public static void setDefaultProxy(SocksProxyBase p) { - defaultProxy = p; - } - - /** - * Get current default proxy. - * - * @return Current default proxy, or null if none is set. - */ - public static SocksProxyBase getDefaultProxy() { - return defaultProxy; - } - - /** - * Parses strings in the form: host[:port:user:password], and creates proxy - * from information obtained from parsing. - *

- * Defaults: port = 1080.
- * If user specified but not password, creates Socks4Proxy, if user not - * specified creates Socks5Proxy, if both user and password are speciefied - * creates Socks5Proxy with user/password authentication. - * - * @param proxy_entry - * String in the form host[:port:user:password] - * @return Proxy created from the string, null if entry was somehow - * invalid(host unknown for example, or empty string) - */ - public static SocksProxyBase parseProxy(String proxy_entry) { - - String proxy_host; - int proxy_port = 1080; - String proxy_user = null; - String proxy_password = null; - SocksProxyBase proxy; - - final java.util.StringTokenizer st = new java.util.StringTokenizer( - proxy_entry, ":"); - if (st.countTokens() < 1) { - return null; - } - - proxy_host = st.nextToken(); - if (st.hasMoreTokens()) { - try { - proxy_port = Integer.parseInt(st.nextToken().trim()); - } catch (final NumberFormatException nfe) { - } - } - - if (st.hasMoreTokens()) { - proxy_user = st.nextToken(); - } - - if (st.hasMoreTokens()) { - proxy_password = st.nextToken(); - } - - try { - if (proxy_user == null) { - proxy = new Socks5Proxy(proxy_host, proxy_port); - } else if (proxy_password == null) { - proxy = new Socks4Proxy(proxy_host, proxy_port, proxy_user); - } else { - proxy = new Socks5Proxy(proxy_host, proxy_port); - final UserPasswordAuthentication upa = new UserPasswordAuthentication( - proxy_user, proxy_password); - - ((Socks5Proxy) proxy).setAuthenticationMethod( - UserPasswordAuthentication.METHOD_ID, upa); - } - } catch (final UnknownHostException uhe) { - return null; - } - - return proxy; - } - - // Protected Methods - // ================= - - protected void startSession() throws SocksException { - try { - if (chainProxy == null) { - proxySocket = new Socket(proxyIP, proxyPort); - } else if (proxyIP != null) { - proxySocket = new SocksSocket(chainProxy, proxyIP, proxyPort); - } else { - proxySocket = new SocksSocket(chainProxy, proxyHost, proxyPort); - } - - in = proxySocket.getInputStream(); - out = proxySocket.getOutputStream(); - } catch (final SocksException se) { - throw se; - } catch (final IOException io_ex) { - throw new SocksException(SOCKS_PROXY_IO_ERROR, "" + io_ex); - } - } - - /** - * Create a copy of this proxy for use by individual threads. - * - * @return proxy - */ - protected abstract SocksProxyBase copy(); - - protected abstract ProxyMessage formMessage(int cmd, InetAddress ip, - int port); - - protected abstract ProxyMessage formMessage(int cmd, String host, int port) - throws UnknownHostException; - - protected abstract ProxyMessage formMessage(InputStream in) - throws SocksException, IOException; - - protected ProxyMessage connect(InetAddress ip, int port) - throws SocksException { - try { - startSession(); - final ProxyMessage request = formMessage(SOCKS_CMD_CONNECT, ip, - port); - return exchange(request); - } catch (final SocksException se) { - endSession(); - throw se; - } - } - - protected ProxyMessage connect(String host, int port) - throws UnknownHostException, SocksException { - try { - startSession(); - final ProxyMessage request = formMessage(SOCKS_CMD_CONNECT, host, - port); - return exchange(request); - } catch (final SocksException se) { - endSession(); - throw se; - } - } - - protected ProxyMessage bind(InetAddress ip, int port) throws SocksException { - try { - startSession(); - final ProxyMessage request = formMessage(SOCKS_CMD_BIND, ip, port); - return exchange(request); - } catch (final SocksException se) { - endSession(); - throw se; - } - } - - protected ProxyMessage bind(String host, int port) - throws UnknownHostException, SocksException { - try { - startSession(); - final ProxyMessage request = formMessage(SOCKS_CMD_BIND, host, port); - return exchange(request); - } catch (final SocksException se) { - endSession(); - throw se; - } - } - - protected ProxyMessage accept() throws IOException, SocksException { - ProxyMessage msg; - try { - msg = formMessage(in); - } catch (final InterruptedIOException iioe) { - throw iioe; - } catch (final IOException io_ex) { - endSession(); - throw new SocksException(SOCKS_PROXY_IO_ERROR, - "While Trying accept:" + io_ex); - } - return msg; - } - - protected ProxyMessage udpAssociate(InetAddress ip, int port) - throws SocksException { - try { - startSession(); - final ProxyMessage request = formMessage(SOCKS_CMD_UDP_ASSOCIATE, - ip, port); - if (request != null) { - return exchange(request); - } - } catch (final SocksException se) { - endSession(); - throw se; - } - // Only get here if request was null - endSession(); - throw new SocksException(SOCKS_METHOD_NOTSUPPORTED, - "This version of proxy does not support UDP associate, use version 5"); - } - - protected ProxyMessage udpAssociate(String host, int port) - throws UnknownHostException, SocksException { - try { - startSession(); - final ProxyMessage request = formMessage(SOCKS_CMD_UDP_ASSOCIATE, - host, port); - if (request != null) { - return exchange(request); - } - } catch (final SocksException se) { - endSession(); - throw se; - } - // Only get here if request was null - endSession(); - throw new SocksException(SOCKS_METHOD_NOTSUPPORTED, - "This version of proxy does not support UDP associate, use version 5"); - } - - protected void endSession() { - try { - if (proxySocket != null) { - proxySocket.close(); - } - proxySocket = null; - } catch (final IOException io_ex) { - } - } - - /** - *Sends the request to SOCKS server - */ - protected void sendMsg(ProxyMessage msg) throws SocksException, IOException { - msg.write(out); - } - - /** - * Reads the reply from the SOCKS server - */ - protected ProxyMessage readMsg() throws SocksException, IOException { - return formMessage(in); - } - - /** - *Sends the request reads reply and returns it throws exception if - * something wrong with IO or the reply code is not zero - */ - protected ProxyMessage exchange(ProxyMessage request) throws SocksException { - ProxyMessage reply; - try { - request.write(out); - reply = formMessage(in); - } catch (final SocksException s_ex) { - throw s_ex; - } catch (final IOException ioe) { - throw (new SocksException(SOCKS_PROXY_IO_ERROR, "" + ioe)); - } - return reply; - } - - // Private methods - // =============== - - // Constants - - public static final int SOCKS_SUCCESS = 0; - public static final int SOCKS_FAILURE = 1; - public static final int SOCKS_BADCONNECT = 2; - public static final int SOCKS_BADNETWORK = 3; - public static final int SOCKS_HOST_UNREACHABLE = 4; - public static final int SOCKS_CONNECTION_REFUSED = 5; - public static final int SOCKS_TTL_EXPIRE = 6; - public static final int SOCKS_CMD_NOT_SUPPORTED = 7; - public static final int SOCKS_ADDR_NOT_SUPPORTED = 8; - - public static final int SOCKS_NO_PROXY = 1 << 16; - public static final int SOCKS_PROXY_NO_CONNECT = 2 << 16; - public static final int SOCKS_PROXY_IO_ERROR = 3 << 16; - public static final int SOCKS_AUTH_NOT_SUPPORTED = 4 << 16; - public static final int SOCKS_AUTH_FAILURE = 5 << 16; - public static final int SOCKS_JUST_ERROR = 6 << 16; - - public static final int SOCKS_DIRECT_FAILED = 7 << 16; - public static final int SOCKS_METHOD_NOTSUPPORTED = 8 << 16; - - static final int SOCKS_CMD_CONNECT = 0x1; - static final int SOCKS_CMD_BIND = 0x2; - static final int SOCKS_CMD_UDP_ASSOCIATE = 0x3; - -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/SocksServerSocket.java b/src/com/runjva/sourceforge/jsocks/protocol/SocksServerSocket.java deleted file mode 100644 index 6d812f29..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/SocksServerSocket.java +++ /dev/null @@ -1,238 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.net.UnknownHostException; - -/** - * SocksServerSocket allows to accept connections from one particular host - * through the SOCKS4 or SOCKS5 proxy. - */ -public class SocksServerSocket extends ServerSocket { - // Data members - protected SocksProxyBase proxy; - protected String localHost; - protected InetAddress localIP; - protected int localPort; - - boolean doing_direct = false; - InetAddress remoteAddr; - - /** - * Creates ServerSocket capable of accepting one connection through the - * firewall, uses default Proxy. - * - * @param host - * Host from which the connection should be recieved. - *@param port - * Port number of the primary connection. - */ - public SocksServerSocket(String host, int port) throws SocksException, - UnknownHostException, IOException { - this(SocksProxyBase.defaultProxy, host, port); - } - - /** - *Creates ServerSocket capable of accepting one connection through the - * firewall, uses given proxy. - * - * @param p - * Proxy object to use. - *@param host - * Host from which the connection should be recieved. - *@param port - * Port number of the primary connection. - */ - public SocksServerSocket(SocksProxyBase p, String host, int port) - throws SocksException, UnknownHostException, IOException { - - super(0); - if (p == null) { - throw new SocksException(SocksProxyBase.SOCKS_NO_PROXY); - } - // proxy=p; - proxy = p.copy(); - if (proxy.isDirect(host)) { - remoteAddr = InetAddress.getByName(host); - proxy = null; - doDirect(); - } else { - processReply(proxy.bind(host, port)); - } - } - - /** - * Creates ServerSocket capable of accepting one connection through the - * firewall, uses default Proxy. - * - * @param ip - * Host from which the connection should be recieved. - *@param port - * Port number of the primary connection. - */ - public SocksServerSocket(InetAddress ip, int port) throws SocksException, - IOException { - this(SocksProxyBase.defaultProxy, ip, port); - } - - /** - *Creates ServerSocket capable of accepting one connection through the - * firewall, uses given proxy. - * - * @param p - * Proxy object to use. - *@param ip - * Host from which the connection should be recieved. - *@param port - * Port number of the primary connection. - */ - public SocksServerSocket(SocksProxyBase p, InetAddress ip, int port) - throws SocksException, IOException { - super(0); - - if (p == null) { - throw new SocksException(SocksProxyBase.SOCKS_NO_PROXY); - } - this.proxy = p.copy(); - - if (proxy.isDirect(ip)) { - remoteAddr = ip; - doDirect(); - } else { - processReply(proxy.bind(ip, port)); - } - } - - /** - * Accepts the incoming connection. - */ - public Socket accept() throws IOException { - Socket s; - - if (!doing_direct) { - if (proxy == null) { - return null; - } - - final ProxyMessage msg = proxy.accept(); - s = msg.ip == null ? new SocksSocket(msg.host, msg.port, proxy) - : new SocksSocket(msg.ip, msg.port, proxy); - // Set timeout back to 0 - proxy.proxySocket.setSoTimeout(0); - if (ProxyServer.vpnService != null) - ProxyServer.vpnService.protect(proxy.proxySocket); - - } else { // Direct Connection - - // Mimic the proxy behaviour, - // only accept connections from the speciefed host. - while (true) { - s = super.accept(); - if (s.getInetAddress().equals(remoteAddr)) { - // got the connection from the right host - // Close listenning socket. - break; - } else { - s.close(); // Drop all connections from other hosts - } - } - - } - proxy = null; - // Return accepted socket - return s; - } - - /** - * Closes the connection to proxy if socket have not been accepted, if the - * direct connection is used, closes direct ServerSocket. If the client - * socket have been allready accepted, does nothing. - */ - public void close() throws IOException { - super.close(); - if (proxy != null) { - proxy.endSession(); - } - proxy = null; - } - - /** - * Get the name of the host proxy is using to listen for incoming - * connection. - *

- * Usefull when address is returned by proxy as the hostname. - * - * @return the hostname of the address proxy is using to listen for incoming - * connection. - */ - public String getHost() { - return localHost; - } - - /** - * Get address assigned by proxy to listen for incomming connections, or the - * local machine address if doing direct connection. - */ - public InetAddress getInetAddress() { - if (localIP == null) { - try { - localIP = InetAddress.getByName(localHost); - } catch (final UnknownHostException e) { - return null; - } - } - return localIP; - } - - /** - * Get port assigned by proxy to listen for incoming connections, or the - * port chosen by local system, if accepting directly. - */ - public int getLocalPort() { - return localPort; - } - - /** - * Set Timeout. - * - * @param timeout - * Amount of time in milliseconds, accept should wait for - * incoming connection before failing with exception. Zero - * timeout implies infinity. - */ - public void setSoTimeout(int timeout) throws SocketException { - super.setSoTimeout(timeout); - if (!doing_direct) { - proxy.proxySocket.setSoTimeout(timeout); - } - } - - // Private Methods - // //////////////// - - private void processReply(ProxyMessage reply) throws SocksException { - localPort = reply.port; - /* - * If the server have assigned same host as it was contacted on it might - * return an address of all zeros - */ - if (reply.host.equals("0.0.0.0")) { - localIP = proxy.proxyIP; - localHost = localIP.getHostName(); - } else { - localHost = reply.host; - localIP = reply.ip; - } - } - - private void doDirect() { - doing_direct = true; - localPort = super.getLocalPort(); - localIP = super.getInetAddress(); - localHost = localIP.getHostName(); - } - -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/SocksSocket.java b/src/com/runjva/sourceforge/jsocks/protocol/SocksSocket.java deleted file mode 100644 index 5e7f4272..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/SocksSocket.java +++ /dev/null @@ -1,386 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.Socket; -import java.net.SocketException; -import java.net.UnknownHostException; - -/** - * SocksSocket tryies to look very similar to normal Socket, while allowing - * connections through the SOCKS4 or 5 proxy. To use this class you will have to - * identify proxy you need to use, Proxy class allows you to set default proxy, - * which will be used by all Socks aware sockets. You can also create either - * Socks4Proxy or Socks5Proxy, and use them by passing to the appropriate - * constructors. - *

- * Using Socks package can be as easy as that: - * - *

- * <tt>
- * 
- *     import Socks.*;
- *     ....
- * 
- *     try{
- *        //Specify SOCKS5 proxy
- *        Proxy.setDefaultProxy("socks-proxy",1080);
- * 
- *        //OR you still use SOCKS4
- *        //Code below uses SOCKS4 proxy
- *        //Proxy.setDefaultProxy("socks-proxy",1080,userName);
- * 
- *        Socket s = SocksSocket("some.host.of.mine",13);
- *        readTimeFromSock(s);
- *     }catch(SocksException sock_ex){
- *        //Usually it will turn in more or less meaningfull message
- *        System.err.println("SocksException:"+sock_ex);
- *     }
- * 
- * </tt>
- * 
- *

- * However if the need exist for more control, like resolving addresses - * remotely, or using some non-trivial authentication schemes, it can be done. - */ - -public class SocksSocket extends Socket { - // Data members - protected SocksProxyBase proxy; - protected String localHost, remoteHost; - protected InetAddress localIP, remoteIP; - protected int localPort, remotePort; - - private Socket directSock = null; - //private Logger log = LoggerFactory.getLogger(SocksSocket.class); - - /** - * Tryies to connect to given host and port using default proxy. If no - * default proxy speciefied it throws SocksException with error code - * SOCKS_NO_PROXY. - * - * @param host - * Machine to connect to. - * @param port - * Port to which to connect. - * @see SocksSocket#SocksSocket(SocksProxyBase,String,int) - * @see Socks5Proxy#resolveAddrLocally - */ - public SocksSocket(String host, int port) throws SocksException, - UnknownHostException { - this(SocksProxyBase.defaultProxy, host, port); - } - - /** - * Connects to host port using given proxy server. - * - * @param p - * Proxy to use. - * @param host - * Machine to connect to. - * @param port - * Port to which to connect. - * @throws UnknownHostException - * If one of the following happens: - *

    - * - *
  1. Proxy settings say that address should be resolved - * locally, but this fails. - *
  2. Proxy settings say that the host should be contacted - * directly but host name can't be resolved. - *
- * @throws SocksException - * If one of the following happens: - *
    - *
  • Proxy is is null. - *
  • Proxy settings say that the host should be contacted - * directly but this fails. - *
  • Socks Server can't be contacted. - *
  • Authentication fails. - *
  • Connection is not allowed by the SOCKS proxy. - *
  • SOCKS proxy can't establish the connection. - *
  • Any IO error occured. - *
  • Any protocol error occured. - *
- * @throws IOexception - * if anything is wrong with I/O. - * @see Socks5Proxy#resolveAddrLocally - */ - public SocksSocket(SocksProxyBase p, String host, int port) - throws SocksException, UnknownHostException { - - if (p == null) { - throw new SocksException(SocksProxyBase.SOCKS_NO_PROXY); - } - // proxy=p; - proxy = p.copy(); - remoteHost = host; - remotePort = port; - if (proxy.isDirect(host)) { - remoteIP = InetAddress.getByName(host); - doDirect(); - } else { - processReply(proxy.connect(host, port)); - } - } - - /** - * Tryies to connect to given ip and port using default proxy. If no default - * proxy speciefied it throws SocksException with error code SOCKS_NO_PROXY. - * - * @param ip - * Machine to connect to. - * @param port - * Port to which to connect. - * @see SocksSocket#SocksSocket(SocksProxyBase,String,int) - */ - public SocksSocket(InetAddress ip, int port) throws SocksException { - this(SocksProxyBase.defaultProxy, ip, port); - } - - /** - * Connects to given ip and port using given Proxy server. - * - * @param p - * Proxy to use. - * @param ip - * Machine to connect to. - * @param port - * Port to which to connect. - */ - public SocksSocket(SocksProxyBase p, InetAddress ip, int port) - throws SocksException { - if (p == null) { - throw new SocksException(SocksProxyBase.SOCKS_NO_PROXY); - } - this.proxy = p.copy(); - this.remoteIP = ip; - this.remotePort = port; - this.remoteHost = ip.getHostName(); - if (proxy.isDirect(remoteIP)) { - doDirect(); - } else { - processReply(proxy.connect(ip, port)); - } - } - - /** - * These 2 constructors are used by the SocksServerSocket. This socket - * simply overrides remoteHost, remotePort - */ - protected SocksSocket(String host, int port, SocksProxyBase proxy) { - this.remotePort = port; - this.proxy = proxy; - this.localIP = proxy.proxySocket.getLocalAddress(); - this.localPort = proxy.proxySocket.getLocalPort(); - this.remoteHost = host; - } - - protected SocksSocket(InetAddress ip, int port, SocksProxyBase proxy) { - remoteIP = ip; - remotePort = port; - this.proxy = proxy; - this.localIP = proxy.proxySocket.getLocalAddress(); - this.localPort = proxy.proxySocket.getLocalPort(); - remoteHost = remoteIP.getHostName(); - } - - /** - * Same as Socket - */ - public void close() throws IOException { - if (proxy != null) { - proxy.endSession(); - } - proxy = null; - } - - /** - * Same as Socket - */ - public InputStream getInputStream() { - return proxy.in; - } - - /** - * Same as Socket - */ - public OutputStream getOutputStream() { - return proxy.out; - } - - /** - * Same as Socket - */ - public int getPort() { - return remotePort; - } - - /** - * Returns remote host name, it is usefull in cases when addresses are - * resolved by proxy, and we can't create InetAddress object. - * - * @return The name of the host this socket is connected to. - */ - public String getHost() { - return remoteHost; - } - - /** - * Get remote host as InetAddress object, might return null if addresses are - * resolved by proxy, and it is not possible to resolve it locally - * - * @return Ip address of the host this socket is connected to, or null if - * address was returned by the proxy as DOMAINNAME and can't be - * resolved locally. - */ - public InetAddress getInetAddress() { - if (remoteIP == null) { - try { - remoteIP = InetAddress.getByName(remoteHost); - } catch (final UnknownHostException e) { - return null; - } - } - return remoteIP; - } - - /** - * Get the port assigned by the proxy for the socket, not the port on locall - * machine as in Socket. - * - * @return Port of the socket used on the proxy server. - */ - public int getLocalPort() { - return localPort; - } - - /** - * Get address assigned by proxy to make a remote connection, it might be - * different from the host specified for the proxy. Can return null if socks - * server returned this address as hostname and it can't be resolved - * locally, use getLocalHost() then. - * - * @return Address proxy is using to make a connection. - */ - public InetAddress getLocalAddress() { - if (localIP == null) { - try { - localIP = InetAddress.getByName(localHost); - } catch (final UnknownHostException e) { - return null; - } - } - return localIP; - } - - /** - * Get name of the host, proxy has assigned to make a remote connection for - * this socket. This method is usefull when proxy have returned address as - * hostname, and we can't resolve it on this machine. - * - * @return The name of the host proxy is using to make a connection. - */ - public String getLocalHost() { - return localHost; - } - - /** - * Same as socket. - */ - public void setSoLinger(boolean on, int val) throws SocketException { - proxy.proxySocket.setSoLinger(on, val); - } - - /** - * Same as socket. - */ - public int getSoLinger(int timeout) throws SocketException { - return proxy.proxySocket.getSoLinger(); - } - - /** - * Same as socket. - */ - public void setSoTimeout(int timeout) throws SocketException { - proxy.proxySocket.setSoTimeout(timeout); - } - - /** - * Same as socket. - */ - public int getSoTimeout(int timeout) throws SocketException { - return proxy.proxySocket.getSoTimeout(); - } - - /** - * Same as socket. - */ - public void setTcpNoDelay(boolean on) throws SocketException { - proxy.proxySocket.setTcpNoDelay(on); - } - - /** - * Same as socket. - */ - public boolean getTcpNoDelay() throws SocketException { - return proxy.proxySocket.getTcpNoDelay(); - } - - /** - * Get string representation of the socket. - */ - public String toString() { - if (directSock != null) { - return "Direct connection:" + directSock; - } - StringBuffer sb = new StringBuffer(); - sb.append("Proxy:"); - sb.append(proxy); - sb.append(";"); - sb.append("addr:"); - sb.append(remoteHost); - sb.append(",port:"); - sb.append(remotePort); - sb.append(",localport:"); - sb.append(localPort); - return sb.toString(); - - } - - // Private Methods - // //////////////// - - private void processReply(ProxyMessage reply) throws SocksException { - localPort = reply.port; - /* - * If the server have assigned same host as it was contacted on it might - * return an address of all zeros - */ - if (reply.host.equals("0.0.0.0")) { - localIP = proxy.proxyIP; - localHost = localIP.getHostName(); - } else { - localHost = reply.host; - localIP = reply.ip; - } - } - - private void doDirect() throws SocksException { - try { - // log.debug("IP: {}_{}", remoteIP, remotePort); - directSock = new Socket(remoteIP, remotePort); - proxy.out = directSock.getOutputStream(); - proxy.in = directSock.getInputStream(); - proxy.proxySocket = directSock; - localIP = directSock.getLocalAddress(); - localPort = directSock.getLocalPort(); - } catch (final IOException io_ex) { - final int errCode = SocksProxyBase.SOCKS_DIRECT_FAILED; - throw new SocksException(errCode, "Direct connect failed:", io_ex); - } - } - -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/UDPEncapsulation.java b/src/com/runjva/sourceforge/jsocks/protocol/UDPEncapsulation.java deleted file mode 100644 index 913bb31c..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/UDPEncapsulation.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -/** - * This interface provides for datagram encapsulation for SOCKSv5 protocol. - *

- * SOCKSv5 allows for datagrams to be encapsulated for purposes of integrity - * and/or authenticity. How it should be done is aggreed during the - * authentication stage, and is authentication dependent. This interface is - * provided to allow this encapsulation. - * - * @see Authentication - */ -public interface UDPEncapsulation { - - /** - * This method should provide any authentication depended transformation on - * datagrams being send from/to the client. - * - * @param data - * Datagram data (including any SOCKS related bytes), to be - * encapsulated/decapsulated. - * @param out - * Wether the data is being send out. If true method should - * encapsulate/encrypt data, otherwise it should decapsulate/ - * decrypt data. - * @throw IOException if for some reason data can be transformed correctly. - * @return Should return byte array containing data after transformation. It - * is possible to return same array as input, if transformation only - * involves bit mangling, and no additional data is being added or - * removed. - */ - byte[] udpEncapsulate(byte[] data, boolean out) throws java.io.IOException; -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/UDPRelayServer.java b/src/com/runjva/sourceforge/jsocks/protocol/UDPRelayServer.java deleted file mode 100644 index d4a158ea..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/UDPRelayServer.java +++ /dev/null @@ -1,228 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -import com.runjva.sourceforge.jsocks.server.ServerAuthenticator; - -/** - * UDP Relay server, used by ProxyServer to perform udp forwarding. - */ -class UDPRelayServer implements Runnable { - - DatagramSocket client_sock; - DatagramSocket remote_sock; - - Socket controlConnection; - - int relayPort; - InetAddress relayIP; - - Thread pipe_thread1, pipe_thread2; - Thread master_thread; - - ServerAuthenticator auth; - - long lastReadTime; - -// static Logger log = LoggerFactory.getLogger(UDPRelayServer.class); - static SocksProxyBase proxy = null; - static int datagramSize = 0xFFFF;// 64K, a bit more than max udp size - static int iddleTimeout = 180000;// 3 minutes - - /** - * Constructs UDP relay server to communicate with client on given ip and - * port. - * - * @param clientIP - * Address of the client from whom datagrams will be recieved and - * to whom they will be forwarded. - * @param clientPort - * Clients port. - * @param master_thread - * Thread which will be interrupted, when UDP relay server - * stoppes for some reason. - * @param controlConnection - * Socket which will be closed, before interrupting the master - * thread, it is introduced due to a bug in windows JVM which - * does not throw InterruptedIOException in threads which block - * in I/O operation. - */ - public UDPRelayServer(InetAddress clientIP, int clientPort, - Thread master_thread, Socket controlConnection, - ServerAuthenticator auth) throws IOException { - - this.master_thread = master_thread; - this.controlConnection = controlConnection; - this.auth = auth; - - client_sock = new Socks5DatagramSocket(true, - auth.getUdpEncapsulation(), clientIP, clientPort); - - relayPort = client_sock.getLocalPort(); - relayIP = client_sock.getLocalAddress(); - - if (relayIP.getHostAddress().equals("0.0.0.0")) { - relayIP = InetAddress.getLocalHost(); - } - - if (proxy == null) { - remote_sock = new DatagramSocket(); - } else { - remote_sock = new Socks5DatagramSocket(proxy, 0, null); - } - } - - // Public methods - // /////////////// - - /** - * Sets the timeout for UDPRelay server.
- * Zero timeout implies infinity.
- * Default timeout is 3 minutes. - */ - - static public void setTimeout(int timeout) { - iddleTimeout = timeout; - } - - /** - * Sets the size of the datagrams used in the UDPRelayServer.
- * Default size is 64K, a bit more than maximum possible size of the - * datagram. - */ - static public void setDatagramSize(int size) { - datagramSize = size; - } - - /** - * Port to which client should send datagram for association. - */ - public int getRelayPort() { - return relayPort; - } - - /** - * IP address to which client should send datagrams for association. - */ - public InetAddress getRelayIP() { - return relayIP; - } - - /** - * Starts udp relay server. Spawns two threads of execution and returns. - */ - public void start() throws IOException { - remote_sock.setSoTimeout(iddleTimeout); - client_sock.setSoTimeout(iddleTimeout); - - //log.info("Starting UDP relay server on {}:{}", relayIP, relayPort); - // log.info("Remote socket {}:{}", remote_sock.getLocalAddress(), - // remote_sock.getLocalPort()); - - pipe_thread1 = new Thread(this, "pipe1"); - pipe_thread2 = new Thread(this, "pipe2"); - - lastReadTime = System.currentTimeMillis(); - - pipe_thread1.start(); - pipe_thread2.start(); - } - - /** - * Stops Relay server. - *

- * Does not close control connection, does not interrupt master_thread. - */ - public synchronized void stop() { - master_thread = null; - controlConnection = null; - abort(); - } - - // Runnable interface - // ////////////////// - public void run() { - try { - if (Thread.currentThread().getName().equals("pipe1")) { - pipe(remote_sock, client_sock, false); - } else { - pipe(client_sock, remote_sock, true); - } - } catch (final IOException ioe) { - } finally { - abort(); - // log.info("UDP Pipe thread " + Thread.currentThread().getName() - // + " stopped."); - } - - } - - // Private methods - // /////////////// - private synchronized void abort() { - if (pipe_thread1 == null) { - return; - } - - // log.info("Aborting UDP Relay Server"); - - remote_sock.close(); - client_sock.close(); - - if (controlConnection != null) { - try { - controlConnection.close(); - } catch (final IOException ioe) { - } - } - - if (master_thread != null) { - master_thread.interrupt(); - } - - pipe_thread1.interrupt(); - pipe_thread2.interrupt(); - - pipe_thread1 = null; - } - - private void pipe(DatagramSocket from, DatagramSocket to, boolean out) - throws IOException { - final byte[] data = new byte[datagramSize]; - final DatagramPacket dp = new DatagramPacket(data, data.length); - - while (true) { - try { - from.receive(dp); - lastReadTime = System.currentTimeMillis(); - - if (auth.checkRequest(dp, out)) { - to.send(dp); - } - - } catch (final UnknownHostException uhe) { - // log.info("Dropping datagram for unknown host"); - } catch (final InterruptedIOException iioe) { - // log("Interrupted: "+iioe); - // If we were interrupted by other thread. - if (iddleTimeout == 0) { - return; - } - - // If last datagram was received, long time ago, return. - final long timeSinceRead = System.currentTimeMillis() - - lastReadTime; - if (timeSinceRead >= iddleTimeout - 100) { - return; - } - } - dp.setLength(data.length); - } - } -} diff --git a/src/com/runjva/sourceforge/jsocks/protocol/UserPasswordAuthentication.java b/src/com/runjva/sourceforge/jsocks/protocol/UserPasswordAuthentication.java deleted file mode 100644 index c161d334..00000000 --- a/src/com/runjva/sourceforge/jsocks/protocol/UserPasswordAuthentication.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.runjva.sourceforge.jsocks.protocol; - -/** - * SOCKS5 User Password authentication scheme. - */ -public class UserPasswordAuthentication implements Authentication { - - /** SOCKS ID for User/Password authentication method */ - public final static int METHOD_ID = 2; - - String userName, password; - byte[] request; - - /** - * Create an instance of UserPasswordAuthentication. - * - * @param userName - * User Name to send to SOCKS server. - * @param password - * Password to send to SOCKS server. - */ - public UserPasswordAuthentication(String userName, String password) { - this.userName = userName; - this.password = password; - formRequest(); - } - - /** - * Get the user name. - * - * @return User name. - */ - public String getUser() { - return userName; - } - - /** - * Get password - * - * @return Password - */ - public String getPassword() { - return password; - } - - /** - * Does User/Password authentication as defined in rfc1929. - * - * @return An array containnig in, out streams, or null if authentication - * fails. - */ - public Object[] doSocksAuthentication(int methodId, - java.net.Socket proxySocket) throws java.io.IOException { - - if (methodId != METHOD_ID) { - return null; - } - - final java.io.InputStream in = proxySocket.getInputStream(); - final java.io.OutputStream out = proxySocket.getOutputStream(); - - out.write(request); - final int version = in.read(); - if (version < 0) { - return null; // Server closed connection - } - final int status = in.read(); - if (status != 0) { - return null; // Server closed connection, or auth failed. - } - - return new Object[] { in, out }; - } - - // Private methods - // //////////////// - - /** Convert UserName password in to binary form, ready to be send to server */ - private void formRequest() { - final byte[] user_bytes = userName.getBytes(); - final byte[] password_bytes = password.getBytes(); - - request = new byte[3 + user_bytes.length + password_bytes.length]; - request[0] = (byte) 1; - request[1] = (byte) user_bytes.length; - System.arraycopy(user_bytes, 0, request, 2, user_bytes.length); - request[2 + user_bytes.length] = (byte) password_bytes.length; - System.arraycopy(password_bytes, 0, request, 3 + user_bytes.length, - password_bytes.length); - } -} diff --git a/src/com/runjva/sourceforge/jsocks/server/Ident.java b/src/com/runjva/sourceforge/jsocks/server/Ident.java deleted file mode 100644 index 6e0940c1..00000000 --- a/src/com/runjva/sourceforge/jsocks/server/Ident.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.runjva.sourceforge.jsocks.server; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.InterruptedIOException; -import java.net.ConnectException; -import java.net.Socket; -import java.util.StringTokenizer; - -/** - * Class Ident provides means to obtain user name of the owner of the socket on - * remote machine, providing remote machine runs identd daemon. - *

- * To use it:

-   Socket s = ss.accept();
-   Ident id = new Ident(s);
-   if(id.successful) goUseUser(id.userName);
-   else handleIdentError(id.errorCode,id.errorMessage)
-   
- */ -public class Ident { - -// Logger log = LoggerFactory.getLogger(Ident.class); - - /** Error Message can be null. */ - public String errorMessage; - - /** Host type as returned by daemon, can be null, if error happened */ - public String hostType; - - /** User name as returned by the identd daemon, or null, if it failed */ - public String userName; - - /** - * If this is true then userName and hostType contain valid values. Else - * errorCode contain the error code, and errorMessage contains the - * corresponding message. - */ - public boolean successful; - - /** Error code */ - public int errorCode; - - /** Identd on port 113 can't be contacted */ - public static final int ERR_NO_CONNECT = 1; - - /** Connection timed out */ - public static final int ERR_TIMEOUT = 2; - - /** - * Identd daemon responded with ERROR, in this case errorMessage contains - * the string explanation, as send by the daemon. - */ - public static final int ERR_PROTOCOL = 3; - - /** - * When parsing server response protocol error happened. - */ - public static final int ERR_PROTOCOL_INCORRECT = 4; - - /** - * Maximum amount of time we should wait before dropping the connection to - * identd server.Setting it to 0 implies infinit timeout. - */ - public static final int connectionTimeout = 10000; - - /** - * Constructor tries to connect to Identd daemon on the host of the given - * socket, and retrieve user name of the owner of given socket connection on - * remote machine. After constructor returns public fields are initialised - * to whatever the server returned. - *

- * If user name was successfully retrieved successful is set to true, and - * userName and hostType are set to whatever server returned. If however for - * some reason user name was not obtained, successful is set to false and - * errorCode contains the code explaining the reason of failure, and - * errorMessage contains human readable explanation. - *

- * Constructor may block, for a while. - * - * @param s - * Socket whose ownership on remote end should be obtained. - */ - public Ident(Socket s) { - Socket sock = null; - successful = false; // We are pessimistic - - try { - sock = new Socket(s.getInetAddress(), 113); - sock.setSoTimeout(connectionTimeout); - final byte[] request = ("" + s.getPort() + " , " + s.getLocalPort() + "\r\n") - .getBytes(); - - sock.getOutputStream().write(request); - - final BufferedReader in = new BufferedReader(new InputStreamReader( - sock.getInputStream())); - - parseResponse(in.readLine()); - - } catch (final InterruptedIOException iioe) { - errorCode = ERR_TIMEOUT; - errorMessage = "Connection to identd timed out."; - } catch (final ConnectException ce) { - errorCode = ERR_NO_CONNECT; - errorMessage = "Connection to identd server failed."; - - } catch (final IOException ioe) { - errorCode = ERR_NO_CONNECT; - errorMessage = "" + ioe; - } finally { - try { - if (sock != null) { - sock.close(); - } - } catch (final IOException ioe) { - // log.warn("Could not close socket", ioe); - } - } - } - - private void parseResponse(String response) { - if (response == null) { - errorCode = ERR_PROTOCOL_INCORRECT; - errorMessage = "Identd server closed connection."; - return; - } - - final StringTokenizer st = new StringTokenizer(response, ":"); - if (st.countTokens() < 3) { - errorCode = ERR_PROTOCOL_INCORRECT; - errorMessage = "Can't parse server response."; - return; - } - - st.nextToken(); // Discard first token, it's basically what we have send - final String command = st.nextToken().trim().toUpperCase(); - - if (command.equals("USERID") && (st.countTokens() >= 2)) { - successful = true; - hostType = st.nextToken().trim(); - userName = st.nextToken("").substring(1);// Get all that is left - } else if (command.equals("ERROR")) { - errorCode = ERR_PROTOCOL; - errorMessage = st.nextToken(); - } else { - errorCode = ERR_PROTOCOL_INCORRECT; - System.out.println("Opa!"); - errorMessage = "Can't parse server response."; - } - - } - - // ///////////////////////////////////////////// - // USED for Testing - /* - * public static void main(String[] args) throws IOException{ - * - * Socket s = null; s = new Socket("gp101-16", 1391); - * - * Ident id = new Ident(s); if(id.successful){ - * System.out.println("User: "+id.userName); - * System.out.println("HostType: "+id.hostType); }else{ - * System.out.println("ErrorCode: "+id.errorCode); - * System.out.println("ErrorMessage: "+id.errorMessage); - * - * } - * - * if(s!= null) s.close(); } // - */ - -} diff --git a/src/com/runjva/sourceforge/jsocks/server/IdentAuthenticator.java b/src/com/runjva/sourceforge/jsocks/server/IdentAuthenticator.java deleted file mode 100644 index da040f55..00000000 --- a/src/com/runjva/sourceforge/jsocks/server/IdentAuthenticator.java +++ /dev/null @@ -1,182 +0,0 @@ -package com.runjva.sourceforge.jsocks.server; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import com.runjva.sourceforge.jsocks.protocol.InetRange; -import com.runjva.sourceforge.jsocks.protocol.ProxyMessage; - -/** - * An implementation of socks.ServerAuthentication which provides simple - * authentication based on the host from which the connection is made and the - * name of the user on the remote machine, as reported by identd daemon on the - * remote machine. - *

- * It can also be used to provide authentication based only on the contacting - * host address. - */ - -public class IdentAuthenticator extends ServerAuthenticatorBase { - /** Vector of InetRanges */ - Vector hosts; - - /** Vector of user hashes */ - Vector> users; - - String user; - - /** - * Constructs empty IdentAuthenticator. - */ - public IdentAuthenticator() { - hosts = new Vector(); - users = new Vector>(); - } - - /** - * Used to create instances returned from startSession. - * - * @param in - * Input stream. - * @param out - * OutputStream. - * @param user - * Username associated with this connection,could be null if name - * was not required. - */ - IdentAuthenticator(InputStream in, OutputStream out, String user) { - super(in, out); - this.user = user; - } - - /** - * Adds range of addresses from which connection is allowed. Hashtable users - * should contain user names as keys and anything as values (value is not - * used and will be ignored). - * - * @param hostRange - * Range of ip addresses from which connection is allowed. - * @param users - * Hashtable of users for whom connection is allowed, or null to - * indicate that anybody is allowed to connect from the hosts - * within given range. - */ - public synchronized void add(InetRange hostRange, Hashtable users) { - this.hosts.addElement(hostRange); - this.users.addElement(users); - } - - /** - * Grants permission only to those users, who connect from one of the hosts - * registered with add(InetRange,Hashtable) and whose names, as reported by - * identd daemon, are listed for the host the connection came from. - */ - public ServerAuthenticator startSession(Socket s) throws IOException { - - final int ind = getRangeIndex(s.getInetAddress()); - String user = null; - - // System.out.println("getRangeReturned:"+ind); - - if (ind < 0) { - return null; // Host is not on the list. - } - - final ServerAuthenticator serverAuthenticator = super.startSession(s); - final ServerAuthenticatorBase auth = (ServerAuthenticatorBase) serverAuthenticator; - - // System.out.println("super.startSession() returned:"+auth); - if (auth == null) { - return null; - } - - // do the authentication - - final Hashtable user_names = users.elementAt(ind); - - if (user_names != null) { // If need to do authentication - Ident ident; - ident = new Ident(s); - // If can't obtain user name, fail - if (!ident.successful) { - return null; - } - // If user name is not listed for this address, fail - if (!user_names.containsKey(ident.userName)) { - return null; - } - user = ident.userName; - } - return new IdentAuthenticator(auth.in, auth.out, user); - - } - - /** - * For SOCKS5 requests allways returns true. For SOCKS4 requests checks - * wether the user name supplied in the request corresponds to the name - * obtained from the ident daemon. - */ - public boolean checkRequest(ProxyMessage msg, java.net.Socket s) { - // If it's version 5 request, or if anybody is permitted, return true; - if ((msg.version == 5) || (user == null)) { - return true; - } - - if (msg.version != 4) { - return false; // Who knows? - } - - return user.equals(msg.user); - } - - /** Get String representaion of the IdentAuthenticator. */ - public String toString() { - String s = ""; - - for (int i = 0; i < hosts.size(); ++i) { - s += "(Range:" + hosts.elementAt(i) + "," + // - " Users:" + userNames(i) + ") "; - } - return s; - } - - // Private Methods - // //////////////// - private int getRangeIndex(InetAddress ip) { - int index = 0; - final Enumeration enumx = hosts.elements(); - while (enumx.hasMoreElements()) { - final InetRange ir = enumx.nextElement(); - if (ir.contains(ip)) { - return index; - } - index++; - } - return -1; // Not found - } - - private String userNames(int i) { - if (users.elementAt(i) == null) { - return "Everybody is permitted."; - } - - final Enumeration enumx = ((Hashtable) users.elementAt(i)) - .keys(); - if (!enumx.hasMoreElements()) { - return ""; - } - String s = enumx.nextElement().toString(); - while (enumx.hasMoreElements()) { - s += "; " + enumx.nextElement(); - } - - return s; - } - -} diff --git a/src/com/runjva/sourceforge/jsocks/server/ServerAuthenticator.java b/src/com/runjva/sourceforge/jsocks/server/ServerAuthenticator.java deleted file mode 100644 index c2451ac5..00000000 --- a/src/com/runjva/sourceforge/jsocks/server/ServerAuthenticator.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.runjva.sourceforge.jsocks.server; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.DatagramPacket; -import java.net.Socket; - -import com.runjva.sourceforge.jsocks.protocol.ProxyMessage; -import com.runjva.sourceforge.jsocks.protocol.UDPEncapsulation; - -/** - * Classes implementing this interface should provide socks server with - * authentication and authorization of users. - **/ -public interface ServerAuthenticator { - - /** - * This method is called when a new connection accepted by the server. - *

- * At this point no data have been extracted from the connection. It is - * responsibility of this method to ensure that the next byte in the stream - * after this method have been called is the first byte of the socks request - * message. For SOCKSv4 there is no authentication data and the first byte - * in the stream is part of the request. With SOCKSv5 however there is an - * authentication data first. It is expected that implementaions will - * process this authentication data. - *

- * If authentication was successful an instance of ServerAuthentication - * should be returned, it later will be used by the server to perform - * authorization and some other things. If authentication fails null should - * be returned, or an exception may be thrown. - * - * @param s - * Accepted Socket. - * @return An instance of ServerAuthenticator to be used for this connection - * or null - */ - ServerAuthenticator startSession(Socket s) throws IOException; - - /** - * This method should return input stream which should be used on the - * accepted socket. - *

- * SOCKSv5 allows to have multiple authentication methods, and these methods - * might require some kind of transformations being made on the data. - *

- * This method is called on the object returned from the startSession - * function. - */ - InputStream getInputStream(); - - /** - * This method should return output stream to use to write to the accepted - * socket. - *

- * SOCKSv5 allows to have multiple authentication methods, and these methods - * might require some kind of transformations being made on the data. - *

- * This method is called on the object returned from the startSession - * function. - */ - OutputStream getOutputStream(); - - /** - * This method should return UDPEncapsulation, which should be used on the - * datagrams being send in/out. - *

- * If no transformation should be done on the datagrams, this method should - * return null. - *

- * This method is called on the object returned from the startSession - * function. - */ - - UDPEncapsulation getUdpEncapsulation(); - - /** - * This method is called when a request have been read. - *

- * Implementation should decide wether to grant request or not. Returning - * true implies granting the request, false means request should be - * rejected. - *

- * This method is called on the object returned from the startSession - * function. - * - * @param msg - * Request message. - * @return true to grant request, false to reject it. - */ - boolean checkRequest(ProxyMessage msg); - - /** - * This method is called when datagram is received by the server. - *

- * Implementaions should decide wether it should be forwarded or dropped. It - * is expecteed that implementation will use datagram address and port - * information to make a decision, as well as anything else. Address and - * port of the datagram are always correspond to remote machine. It is - * either destination or source address. If out is true address is - * destination address, else it is a source address, address of the machine - * from which datagram have been received for the client. - *

- * Implementaions should return true if the datagram is to be forwarded, and - * false if the datagram should be dropped. - *

- * This method is called on the object returned from the startSession - * function. - * - * @param out - * If true the datagram is being send out(from the client), - * otherwise it is an incoming datagram. - * @return True to forward datagram false drop it silently. - */ - boolean checkRequest(DatagramPacket dp, boolean out); - - /** - * This method is called when session is completed. Either due to normal - * termination or due to any error condition. - *

- * This method is called on the object returned from the startSession - * function. - */ - void endSession(); -} diff --git a/src/com/runjva/sourceforge/jsocks/server/ServerAuthenticatorBase.java b/src/com/runjva/sourceforge/jsocks/server/ServerAuthenticatorBase.java deleted file mode 100644 index c67a89f6..00000000 --- a/src/com/runjva/sourceforge/jsocks/server/ServerAuthenticatorBase.java +++ /dev/null @@ -1,187 +0,0 @@ -package com.runjva.sourceforge.jsocks.server; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PushbackInputStream; -import java.net.Socket; - -import com.runjva.sourceforge.jsocks.protocol.ProxyMessage; -import com.runjva.sourceforge.jsocks.protocol.UDPEncapsulation; - -/** - * An implementation of ServerAuthenticator, which does not do any - * authentication. - *

- * Warning!!
- * Should not be used on machines which are not behind the firewall. - *

- * It is only provided to make implementing other authentication schemes easier. - *
- * For Example:

-   class MyAuth extends socks.server.ServerAuthenticator{
-    ...
-    public ServerAuthenticator startSession(java.net.Socket s){
-      if(!checkHost(s.getInetAddress()) return null;
-      return super.startSession(s);
-    }
-
-    boolean checkHost(java.net.Inetaddress addr){
-      boolean allow;
-      //Do it somehow
-      return allow;
-    }
-   }
-
- */ -public abstract class ServerAuthenticatorBase implements ServerAuthenticator { - - static final byte[] socks5response = { 5, 0 }; - - InputStream in; - OutputStream out; - - /** - * Creates new instance of the ServerAuthenticatorNone. - */ - public ServerAuthenticatorBase() { - this.in = null; - this.out = null; - } - - /** - * Constructs new ServerAuthenticatorNone object suitable for returning from - * the startSession function. - * - * @param in - * Input stream to return from getInputStream method. - * @param out - * Output stream to return from getOutputStream method. - */ - public ServerAuthenticatorBase(InputStream in, OutputStream out) { - this.in = in; - this.out = out; - } - - /** - * Grants access to everyone.Removes authentication related bytes from the - * stream, when a SOCKS5 connection is being made, selects an authentication - * NONE. - */ - public ServerAuthenticator startSession(Socket s) throws IOException { - - final PushbackInputStream in = new PushbackInputStream(s - .getInputStream()); - final OutputStream out = s.getOutputStream(); - - final int version = in.read(); - if (version == 5) { - if (!selectSocks5Authentication(in, out, 0)) { - return null; - } - } else if (version == 4) { - // Else it is the request message already, version 4 - in.unread(version); - } else { - return null; - } - - return new ServerAuthenticatorNone(in, out); - } - - /** - * Get input stream. - * - * @return Input stream speciefied in the constructor. - */ - public InputStream getInputStream() { - return in; - } - - /** - * Get output stream. - * - * @return Output stream speciefied in the constructor. - */ - public OutputStream getOutputStream() { - return out; - } - - /** - * Allways returns null. - * - * @return null - */ - public UDPEncapsulation getUdpEncapsulation() { - return null; - } - - /** - * Allways returns true. - */ - public boolean checkRequest(ProxyMessage msg) { - return true; - } - - /** - * Allways returns true. - */ - public boolean checkRequest(java.net.DatagramPacket dp, boolean out) { - return true; - } - - /** - * Does nothing. - */ - public void endSession() { - } - - /** - * Convinience routine for selecting SOCKSv5 authentication. - *

- * This method reads in authentication methods that client supports, checks - * wether it supports given method. If it does, the notification method is - * written back to client, that this method have been chosen for - * authentication. If given method was not found, authentication failure - * message is send to client ([5,FF]). - * - * @param in - * Input stream, version byte should be removed from the stream - * before calling this method. - * @param out - * Output stream. - * @param methodId - * Method which should be selected. - * @return true if methodId was found, false otherwise. - */ - static public boolean selectSocks5Authentication(InputStream in, - OutputStream out, int methodId) throws IOException { - - final int num_methods = in.read(); - if (num_methods <= 0) { - return false; - } - final byte method_ids[] = new byte[num_methods]; - final byte response[] = new byte[2]; - boolean found = false; - - response[0] = (byte) 5; // SOCKS version - response[1] = (byte) 0xFF; // Not found, we are pessimistic - - int bread = 0; // bytes read so far - while (bread < num_methods) { - bread += in.read(method_ids, bread, num_methods - bread); - } - - for (int i = 0; i < num_methods; ++i) { - if (method_ids[i] == methodId) { - found = true; - response[1] = (byte) methodId; - break; - } - } - - out.write(response); - return found; - } -} diff --git a/src/com/runjva/sourceforge/jsocks/server/ServerAuthenticatorNone.java b/src/com/runjva/sourceforge/jsocks/server/ServerAuthenticatorNone.java deleted file mode 100644 index 0e976773..00000000 --- a/src/com/runjva/sourceforge/jsocks/server/ServerAuthenticatorNone.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.runjva.sourceforge.jsocks.server; - -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Simplest possible ServerAuthenticator implementation. Extends common base. - * - */ -public class ServerAuthenticatorNone extends ServerAuthenticatorBase { - - public ServerAuthenticatorNone(InputStream in, OutputStream out) { - super(in, out); - } - -} diff --git a/src/com/runjva/sourceforge/jsocks/server/UserPasswordAuthenticator.java b/src/com/runjva/sourceforge/jsocks/server/UserPasswordAuthenticator.java deleted file mode 100644 index 7d54b45b..00000000 --- a/src/com/runjva/sourceforge/jsocks/server/UserPasswordAuthenticator.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.runjva.sourceforge.jsocks.server; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; - -/** - * This class implements SOCKS5 User/Password authentication scheme as defined - * in rfc1929,the server side of it. (see docs/rfc1929.txt) - */ -public class UserPasswordAuthenticator extends ServerAuthenticatorBase { - - static final int METHOD_ID = 2; - - UserValidation validator; - - /** - * Construct a new UserPasswordAuthentication object, with given - * UserVlaidation scheme. - * - * @param v - * UserValidation to use for validating users. - */ - public UserPasswordAuthenticator(UserValidation validator) { - this.validator = validator; - } - - public ServerAuthenticator startSession(Socket s) throws IOException { - final InputStream in = s.getInputStream(); - final OutputStream out = s.getOutputStream(); - - if (in.read() != 5) { - return null; // Drop non version 5 messages. - } - - if (!selectSocks5Authentication(in, out, METHOD_ID)) { - return null; - } - if (!doUserPasswordAuthentication(s, in, out)) { - return null; - } - - return new ServerAuthenticatorNone(in, out); - } - - // Private Methods - // //////////////// - - private boolean doUserPasswordAuthentication(Socket s, InputStream in, - OutputStream out) throws IOException { - final int version = in.read(); - if (version != 1) { - return false; - } - - final int ulen = in.read(); - if (ulen < 0) { - return false; - } - - final byte[] user = new byte[ulen]; - in.read(user); - final int plen = in.read(); - if (plen < 0) { - return false; - } - final byte[] password = new byte[plen]; - in.read(password); - - if (validator.isUserValid(new String(user), new String(password), s)) { - // System.out.println("user valid"); - out.write(new byte[] { 1, 0 }); - } else { - // System.out.println("user invalid"); - out.write(new byte[] { 1, 1 }); - return false; - } - - return true; - } -} diff --git a/src/com/runjva/sourceforge/jsocks/server/UserValidation.java b/src/com/runjva/sourceforge/jsocks/server/UserValidation.java deleted file mode 100644 index d0b52290..00000000 --- a/src/com/runjva/sourceforge/jsocks/server/UserValidation.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.runjva.sourceforge.jsocks.server; - -/** - * Interface which provides for user validation, based on user name password and - * where it connects from. - */ -public interface UserValidation { - /** - * Implementations of this interface are expected to use some or all of the - * information provided plus any information they can extract from other - * sources to decide wether given user should be allowed access to SOCKS - * server, or whatever you use it for. - * - * @return true to indicate user is valid, false otherwise. - * @param username - * User whom implementation should validate. - * @param password - * Password this user provided. - * @param connection - * Socket which user used to connect to the server. - */ - boolean isUserValid(String username, String password, - java.net.Socket connection); -}