diff src/net/sourceforge/jsocks/Proxy.java @ 0:0ce5cc452d02

initial version
author Carl Byington <carl@five-ten-sg.com>
date Thu, 22 May 2014 10:41:19 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/sourceforge/jsocks/Proxy.java	Thu May 22 10:41:19 2014 -0700
@@ -0,0 +1,428 @@
+package net.sourceforge.jsocks;
+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 Proxy {
+
+//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 Proxy chainProxy = null;
+
+
+//Protected static/class variables
+    protected static Proxy defaultProxy = null;
+
+//Constructors
+//====================
+    Proxy(String proxyHost, int proxyPort) throws UnknownHostException {
+        this.proxyHost = proxyHost;
+        this.proxyIP = InetAddress.getByName(proxyHost);
+        this.proxyPort = proxyPort;
+    }
+
+    Proxy(Proxy chainProxy, InetAddress proxyIP, int proxyPort) {
+        this.chainProxy = chainProxy;
+        this.proxyIP = proxyIP;
+        this.proxyPort = proxyPort;
+    }
+
+    Proxy(InetAddress proxyIP, int proxyPort) {
+        this.proxyIP = proxyIP;
+        this.proxyPort = proxyPort;
+    }
+
+    Proxy(Proxy p) {
+        this.proxyIP = p.proxyIP;
+        this.proxyPort = p.proxyPort;
+        this.version = p.version;
+    }
+
+//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;
+    }
+
+    /**
+       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(Proxy p) {
+        defaultProxy = p;
+    }
+
+    /**
+       Get current default proxy.
+     * @return Current default proxy, or null if none is set.
+     */
+    public static Proxy getDefaultProxy() {
+        return defaultProxy;
+    }
+
+    /**
+      Parses strings in the form: host[:port:user:password], and creates
+      proxy from information obtained from parsing.
+      <p>
+      Defaults: port = 1080.<br>
+      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 Proxy parseProxy(String proxy_entry) {
+        String proxy_host;
+        int proxy_port = 1080;
+        String proxy_user = null;
+        String proxy_password = null;
+        Proxy proxy;
+        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 (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);
+                /*
+                UserPasswordAuthentication upa = new UserPasswordAuthentication(
+                                                 proxy_user, proxy_password);
+
+                ((Socks5Proxy)proxy).setAuthenticationMethod(upa.METHOD_ID,upa);
+                */
+            }
+        }
+        catch (UnknownHostException uhe) {
+            return null;
+        }
+
+        return proxy;
+    }
+
+
+//Protected Methods
+//=================
+
+    protected void startSession()throws SocksException {
+        try {
+            proxySocket = new Socket(proxyIP, proxyPort);
+            in = proxySocket.getInputStream();
+            out = proxySocket.getOutputStream();
+        }
+        catch (SocksException se) {
+            throw se;
+        }
+        catch (IOException io_ex) {
+            throw new SocksException(SOCKS_PROXY_IO_ERROR, "" + io_ex);
+        }
+    }
+
+    protected abstract Proxy 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();
+            ProxyMessage request  = formMessage(SOCKS_CMD_CONNECT,
+                                                ip, port);
+            return exchange(request);
+        }
+        catch (SocksException se) {
+            endSession();
+            throw se;
+        }
+    }
+    protected ProxyMessage connect(String host, int port)
+    throws UnknownHostException, SocksException {
+        try {
+            startSession();
+            ProxyMessage request  = formMessage(SOCKS_CMD_CONNECT,
+                                                host, port);
+            return exchange(request);
+        }
+        catch (SocksException se) {
+            endSession();
+            throw se;
+        }
+    }
+
+    protected ProxyMessage bind(InetAddress ip, int port)
+    throws SocksException {
+        try {
+            startSession();
+            ProxyMessage request  = formMessage(SOCKS_CMD_BIND,
+                                                ip, port);
+            return exchange(request);
+        }
+        catch (SocksException se) {
+            endSession();
+            throw se;
+        }
+    }
+    protected ProxyMessage bind(String host, int port)
+    throws UnknownHostException, SocksException {
+        try {
+            startSession();
+            ProxyMessage request  = formMessage(SOCKS_CMD_BIND,
+                                                host, port);
+            return exchange(request);
+        }
+        catch (SocksException se) {
+            endSession();
+            throw se;
+        }
+    }
+
+    protected ProxyMessage accept()
+    throws IOException, SocksException {
+        ProxyMessage msg;
+
+        try {
+            msg = formMessage(in);
+        }
+        catch (InterruptedIOException iioe) {
+            throw iioe;
+        }
+        catch (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();
+            ProxyMessage request  = formMessage(SOCKS_CMD_UDP_ASSOCIATE,
+                                                ip, port);
+
+            if (request != null)
+                return exchange(request);
+        }
+        catch (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();
+            ProxyMessage request  = formMessage(SOCKS_CMD_UDP_ASSOCIATE,
+                                                host, port);
+
+            if (request != null) return exchange(request);
+        }
+        catch (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 (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 (SocksException s_ex) {
+            throw s_ex;
+        }
+        catch (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;
+
+
+    public static final int SOCKS_CMD_CONNECT        = 0x1;
+    static final int SOCKS_CMD_BIND      = 0x2;
+    static final int SOCKS_CMD_UDP_ASSOCIATE = 0x3;
+
+}