KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > socks > Socks5Proxy


1 package socks;
2 import java.net.*;
3 import java.io.*;
4 import java.util.Hashtable JavaDoc;
5 import java.util.Enumeration JavaDoc;
6
7 /**
8  SOCKS5 Proxy.
9 */

10
11 public class Socks5Proxy extends Proxy implements Cloneable JavaDoc{
12
13 //Data members
14
private Hashtable JavaDoc authMethods = new Hashtable JavaDoc();
15    private int selectedMethod;
16
17    boolean resolveAddrLocally = true;
18    UDPEncapsulation udp_encapsulation=null;
19
20
21 //Public Constructors
22
//====================
23

24    /**
25      Creates SOCKS5 proxy.
26      @param p Proxy to use to connect to this proxy, allows proxy chaining.
27      @param proxyHost Host on which a Proxy server runs.
28      @param proxyPort Port on which a Proxy server listens for connections.
29      @throws UnknownHostException If proxyHost can't be resolved.
30    */

31    public Socks5Proxy(Proxy p,String JavaDoc proxyHost,int proxyPort)
32           throws UnknownHostException{
33       super(p,proxyHost,proxyPort);
34       version = 5;
35       setAuthenticationMethod(0,new AuthenticationNone());
36    }
37
38    /**
39      Creates SOCKS5 proxy.
40      @param proxyHost Host on which a Proxy server runs.
41      @param proxyPort Port on which a Proxy server listens for connections.
42      @throws UnknownHostException If proxyHost can't be resolved.
43    */

44    public Socks5Proxy(String JavaDoc proxyHost,int proxyPort)
45           throws UnknownHostException{
46       this(null,proxyHost,proxyPort);
47    }
48
49
50    /**
51      Creates SOCKS5 proxy.
52      @param p Proxy to use to connect to this proxy, allows proxy chaining.
53      @param proxyIP Host on which a Proxy server runs.
54      @param proxyPort Port on which a Proxy server listens for connections.
55    */

56    public Socks5Proxy(Proxy p,InetAddress proxyIP,int proxyPort){
57       super(p,proxyIP,proxyPort);
58       version = 5;
59       setAuthenticationMethod(0,new AuthenticationNone());
60    }
61
62    /**
63      Creates SOCKS5 proxy.
64      @param proxyIP Host on which a Proxy server runs.
65      @param proxyPort Port on which a Proxy server listens for connections.
66    */

67    public Socks5Proxy(InetAddress proxyIP,int proxyPort){
68       this(null,proxyIP,proxyPort);
69    }
70
71 //Public instance methods
72
//========================
73

74
75    /**
76     * Wether to resolve address locally or to let proxy do so.
77       <p>
78       SOCKS5 protocol allows to send host names rather then IPs in the
79       requests, this option controls wether the hostnames should be send
80       to the proxy server as names, or should they be resolved locally.
81       @param doResolve Wether to perform resolution locally.
82       @return Previous settings.
83     */

84    public boolean resolveAddrLocally(boolean doResolve){
85       boolean old = resolveAddrLocally;
86       resolveAddrLocally = doResolve;
87       return old;
88    }
89    /**
90     Get current setting on how the addresses should be handled.
91     @return Current setting for address resolution.
92     @see Socks5Proxy#resolveAddrLocally(boolean doResolve)
93    */

94    public boolean resolveAddrLocally(){
95       return resolveAddrLocally;
96    }
97
98    /**
99      Adds another authentication method.
100      @param methodId Authentication method id, see rfc1928
101      @param method Implementation of Authentication
102      @see Authentication
103    */

104    public boolean setAuthenticationMethod(int methodId,
105                                           Authentication method){
106       if(methodId<0 || methodId > 255)
107           return false;
108       if(method == null){
109         //Want to remove a particular method
110
return (authMethods.remove(new Integer JavaDoc(methodId)) != null);
111       }else{//Add the method, or rewrite old one
112
authMethods.put(new Integer JavaDoc(methodId),method);
113       }
114       return true;
115    }
116    
117    /**
118     Get authentication method, which corresponds to given method id
119     @param methodId Authentication method id.
120     @return Implementation for given method or null, if one was not set.
121    */

122    public Authentication getAuthenticationMethod(int methodId){
123       Object JavaDoc method = authMethods.get(new Integer JavaDoc(methodId));
124       if(method == null) return null;
125       return (Authentication)method;
126    }
127
128    /**
129     Creates a clone of this Proxy.
130    */

131    public Object JavaDoc clone(){
132       Socks5Proxy newProxy = new Socks5Proxy(proxyIP,proxyPort);
133       newProxy.authMethods = (Hashtable JavaDoc) this.authMethods.clone();
134       newProxy.directHosts = (InetRange)directHosts.clone();
135       newProxy.resolveAddrLocally = resolveAddrLocally;
136       newProxy.chainProxy = chainProxy;
137       return newProxy;
138    }
139
140 //Public Static(Class) Methods
141
//==============================
142

143
144 //Protected Methods
145
//=================
146

147    protected Proxy copy(){
148        Socks5Proxy copy = new Socks5Proxy(proxyIP,proxyPort);
149        copy.authMethods = this.authMethods; //same Hash, no copy
150
copy.directHosts = this.directHosts;
151        copy.chainProxy = this.chainProxy;
152        copy.resolveAddrLocally = this.resolveAddrLocally;
153        return copy;
154     }
155    /**
156     *
157     *
158     */

159    protected void startSession()throws SocksException{
160       super.startSession();
161       Authentication auth;
162       Socket ps = proxySocket; //The name is too long
163

164       try{
165
166      byte nMethods = (byte) authMethods.size(); //Number of methods
167

168          byte[] buf = new byte[2+nMethods]; //2 is for VER,NMETHODS
169
buf[0] = (byte) version;
170          buf[1] = nMethods; //Number of methods
171
int i=2;
172
173          Enumeration JavaDoc ids = authMethods.keys();
174          while(ids.hasMoreElements())
175             buf[i++] = (byte)((Integer JavaDoc)ids.nextElement()).intValue();
176
177          out.write(buf);
178          out.flush();
179
180          int versionNumber = in.read();
181          selectedMethod = in.read();
182
183          if(versionNumber < 0 || selectedMethod < 0){
184            //EOF condition was reached
185
endSession();
186            throw(new SocksException(SOCKS_PROXY_IO_ERROR,
187                  "Connection to proxy lost."));
188          }
189          if(versionNumber < version){
190            //What should we do??
191
}
192          if(selectedMethod == 0xFF){ //No method selected
193
ps.close();
194             throw ( new SocksException(SOCKS_AUTH_NOT_SUPPORTED));
195          }
196
197          auth = getAuthenticationMethod(selectedMethod);
198          if(auth == null){
199             //This shouldn't happen, unless method was removed by other
200
//thread, or the server stuffed up
201
throw(new SocksException(SOCKS_JUST_ERROR,
202                       "Speciefied Authentication not found!"));
203          }
204          Object JavaDoc[] in_out = auth.doSocksAuthentication(selectedMethod,ps);
205          if(in_out == null){
206             //Authentication failed by some reason
207
throw(new SocksException(SOCKS_AUTH_FAILURE));
208          }
209          //Most authentication methods are expected to return
210
//simply the input/output streams associated with
211
//the socket. However if the auth. method requires
212
//some kind of encryption/decryption being done on the
213
//connection it should provide classes to handle I/O.
214

215          in = (InputStream) in_out[0];
216          out = (OutputStream) in_out[1];
217          if(in_out.length > 2)
218             udp_encapsulation = (UDPEncapsulation) in_out[2];
219
220       }catch(SocksException s_ex){
221          throw s_ex;
222       }catch(UnknownHostException uh_ex){
223          throw(new SocksException(SOCKS_PROXY_NO_CONNECT));
224       }catch(SocketException so_ex){
225          throw(new SocksException(SOCKS_PROXY_NO_CONNECT));
226       }catch(IOException io_ex){
227          //System.err.println(io_ex);
228
throw(new SocksException(SOCKS_PROXY_IO_ERROR,""+io_ex));
229       }
230    }
231
232    protected ProxyMessage formMessage(int cmd,InetAddress ip,int port){
233        return new Socks5Message(cmd,ip,port);
234    }
235    protected ProxyMessage formMessage(int cmd,String JavaDoc host,int port)
236              throws UnknownHostException{
237        if(resolveAddrLocally)
238           return formMessage(cmd,InetAddress.getByName(host),port);
239        else
240           return new Socks5Message(cmd,host,port);
241    }
242    protected ProxyMessage formMessage(InputStream in)
243              throws SocksException,
244                     IOException{
245        return new Socks5Message(in);
246    }
247
248 }
249
Popular Tags