Mercurial > 510Connectbot
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; + +}