diff src/net/sourceforge/jsocks/CProxy.java @ 349:205ee2873330

update jsocks to 2011-03-19
author Carl Byington <carl@five-ten-sg.com>
date Fri, 01 Aug 2014 11:23:10 -0700
parents
children 3c16508419fe
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/sourceforge/jsocks/CProxy.java	Fri Aug 01 11:23:10 2014 -0700
@@ -0,0 +1,488 @@
+package net.sourceforge.jsocks;
+import java.net.*;
+import java.io.*;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/**
+  Abstract class CProxy, base for classes Socks4Proxy and Socks5Proxy.
+  Defines methods for specifying default proxy, to be
+  used by all classes of this package.
+*/
+
+public abstract class CProxy{
+
+//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 CProxy chainProxy = null;
+
+
+//Protected static/class variables
+   protected static CProxy defaultProxy = null;
+
+//Constructors
+//====================
+   CProxy(CProxy chainProxy,
+         String proxyHost,int proxyPort)throws UnknownHostException{ 
+      this.chainProxy = chainProxy;
+      this.proxyHost = proxyHost;
+
+      if(chainProxy == null)
+         this.proxyIP   = InetAddress.getByName(proxyHost);
+      
+      this.proxyPort = proxyPort;
+   }
+
+  
+   CProxy(String proxyHost,int proxyPort)throws UnknownHostException{
+      this(null,proxyHost,proxyPort);
+   }
+
+   CProxy(CProxy chainProxy,InetAddress proxyIP,int proxyPort){
+      this.chainProxy = chainProxy;
+      this.proxyIP = proxyIP;
+      this.proxyPort = proxyPort;
+   }
+
+   CProxy(InetAddress proxyIP,int proxyPort){
+      this(null,proxyIP,proxyPort);
+   }
+
+   CProxy(CProxy 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 CProxy port.
+    */
+   public int getPort(){
+     return proxyPort;
+   }
+   /**
+      Get the ip address of the proxy server host.
+    * @return CProxy 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 CProxy to use to connect to this proxy.
+    */
+    public void setChainProxy(CProxy chainProxy){
+        this.chainProxy = chainProxy;
+    }
+    
+    /**
+      Get proxy which is used to connect to this proxy.
+      @return CProxy which is used to connect to this proxy, or null
+              if proxy is to be contacted directly.
+    */
+    public CProxy 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 CProxy to use as default proxy.
+    */
+   public static void setDefaultProxy(CProxy p){
+     defaultProxy = p;
+   }
+
+   /**
+      Get current default proxy.
+    * @return Current default proxy, or null if none is set.
+    */
+   public static CProxy 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 CProxy created from the string, null if entry was somehow
+             invalid(host unknown for example, or empty string)
+   */
+   public static CProxy parseProxy(String proxy_entry){
+
+      String proxy_host;
+      int proxy_port = 1080;
+      String proxy_user = null;
+      String proxy_password = null;
+      CProxy 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{
+         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(SocksException se){
+         throw se;
+       }catch(IOException io_ex){
+         throw new SocksException(SOCKS_PROXY_IO_ERROR,""+io_ex);
+       }
+   }
+
+   protected abstract CProxy 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;
+
+
+   static final int SOCKS_CMD_CONNECT 		=0x1;
+   static final int SOCKS_CMD_BIND		=0x2;
+   static final int SOCKS_CMD_UDP_ASSOCIATE	=0x3;
+
+}