/src/net/sourceforge/jsocks/Proxy.java
Java | 404 lines | 258 code | 52 blank | 94 comment | 14 complexity | e64e07a6aa95b9b937294a1d99c35ca2 MD5 | raw file
1package net.sourceforge.jsocks;
2import java.io.IOException;
3import java.io.InputStream;
4import java.io.InterruptedIOException;
5import java.io.OutputStream;
6import java.net.InetAddress;
7import java.net.Socket;
8import java.net.UnknownHostException;
9
10/**
11 Abstract class Proxy, base for classes Socks4Proxy and Socks5Proxy.
12 Defines methods for specifying default proxy, to be
13 used by all classes of this package.
14*/
15
16public abstract class Proxy{
17
18//Data members
19 //protected InetRange directHosts = new InetRange();
20
21 protected InetAddress proxyIP = null;
22 protected String proxyHost = null;
23 protected int proxyPort;
24 protected Socket proxySocket = null;
25
26 protected InputStream in;
27 protected OutputStream out;
28
29 protected int version;
30
31 protected Proxy chainProxy = null;
32
33
34//Protected static/class variables
35 protected static Proxy defaultProxy = null;
36
37//Constructors
38//====================
39 Proxy(String proxyHost, int proxyPort) throws UnknownHostException {
40 this.proxyHost = proxyHost;
41 this.proxyIP = InetAddress.getByName(proxyHost);
42 this.proxyPort = proxyPort;
43 }
44
45 Proxy(Proxy chainProxy,InetAddress proxyIP,int proxyPort){
46 this.chainProxy = chainProxy;
47 this.proxyIP = proxyIP;
48 this.proxyPort = proxyPort;
49 }
50
51 Proxy(InetAddress proxyIP,int proxyPort){
52 this.proxyIP = proxyIP;
53 this.proxyPort = proxyPort;
54 }
55
56 Proxy(Proxy p){
57 this.proxyIP = p.proxyIP;
58 this.proxyPort = p.proxyPort;
59 this.version = p.version;
60 }
61
62//Public instance methods
63//========================
64
65 /**
66 Get the port on which proxy server is running.
67 * @return Proxy port.
68 */
69 public int getPort(){
70 return proxyPort;
71 }
72 /**
73 Get the ip address of the proxy server host.
74 * @return Proxy InetAddress.
75 */
76 public InetAddress getInetAddress(){
77 return proxyIP;
78 }
79
80 /**
81 Get string representation of this proxy.
82 * @returns string in the form:proxyHost:proxyPort \t Version versionNumber
83 */
84 public String toString(){
85 return (""+proxyIP.getHostName()+":"+proxyPort+"\tVersion "+version);
86 }
87
88
89//Public Static(Class) Methods
90//==============================
91
92 /**
93 * Sets SOCKS4 proxy as default.
94 @param hostName Host name on which SOCKS4 server is running.
95 @param port Port on which SOCKS4 server is running.
96 @param user Username to use for communications with proxy.
97 */
98 public static void setDefaultProxy(String hostName,int port,String user)
99 throws UnknownHostException{
100 defaultProxy = new Socks4Proxy(hostName,port,user);
101 }
102
103 /**
104 * Sets SOCKS4 proxy as default.
105 @param ipAddress Host address on which SOCKS4 server is running.
106 @param port Port on which SOCKS4 server is running.
107 @param user Username to use for communications with proxy.
108 */
109 public static void setDefaultProxy(InetAddress ipAddress,int port,
110 String user){
111 defaultProxy = new Socks4Proxy(ipAddress,port,user);
112 }
113 /**
114 * Sets SOCKS5 proxy as default.
115 * Default proxy only supports no-authentication.
116 @param hostName Host name on which SOCKS5 server is running.
117 @param port Port on which SOCKS5 server is running.
118 */
119 public static void setDefaultProxy(String hostName,int port)
120 throws UnknownHostException{
121 defaultProxy = new Socks5Proxy(hostName,port);
122 }
123 /**
124 * Sets SOCKS5 proxy as default.
125 * Default proxy only supports no-authentication.
126 @param ipAddress Host address on which SOCKS5 server is running.
127 @param port Port on which SOCKS5 server is running.
128 */
129 public static void setDefaultProxy(InetAddress ipAddress,int port){
130 defaultProxy = new Socks5Proxy(ipAddress,port);
131 }
132 /**
133 * Sets default proxy.
134 @param p Proxy to use as default proxy.
135 */
136 public static void setDefaultProxy(Proxy p){
137 defaultProxy = p;
138 }
139
140 /**
141 Get current default proxy.
142 * @return Current default proxy, or null if none is set.
143 */
144 public static Proxy getDefaultProxy(){
145 return defaultProxy;
146 }
147
148 /**
149 Parses strings in the form: host[:port:user:password], and creates
150 proxy from information obtained from parsing.
151 <p>
152 Defaults: port = 1080.<br>
153 If user specified but not password, creates Socks4Proxy, if user
154 not specified creates Socks5Proxy, if both user and password are
155 speciefied creates Socks5Proxy with user/password authentication.
156 @param proxy_entry String in the form host[:port:user:password]
157 @return Proxy created from the string, null if entry was somehow
158 invalid(host unknown for example, or empty string)
159 */
160 public static Proxy parseProxy(String proxy_entry){
161
162 String proxy_host;
163 int proxy_port = 1080;
164 String proxy_user = null;
165 String proxy_password = null;
166 Proxy proxy;
167
168 java.util.StringTokenizer st = new java.util.StringTokenizer(
169 proxy_entry,":");
170 if(st.countTokens() < 1) return null;
171
172 proxy_host = st.nextToken();
173 if(st.hasMoreTokens())
174 try{
175 proxy_port = Integer.parseInt(st.nextToken().trim());
176 }catch(NumberFormatException nfe){}
177
178 if(st.hasMoreTokens())
179 proxy_user = st.nextToken();
180
181 if(st.hasMoreTokens())
182 proxy_password = st.nextToken();
183
184 try{
185 if(proxy_user == null)
186 proxy = new Socks5Proxy(proxy_host,proxy_port);
187 else if(proxy_password == null)
188 proxy = new Socks4Proxy(proxy_host,proxy_port,proxy_user);
189 else{
190 proxy = new Socks5Proxy(proxy_host,proxy_port);
191 /*
192 UserPasswordAuthentication upa = new UserPasswordAuthentication(
193 proxy_user, proxy_password);
194
195 ((Socks5Proxy)proxy).setAuthenticationMethod(upa.METHOD_ID,upa);
196 */
197 }
198 }catch(UnknownHostException uhe){
199 return null;
200 }
201
202 return proxy;
203 }
204
205
206//Protected Methods
207//=================
208
209 protected void startSession()throws SocksException{
210 try{
211 proxySocket = new Socket(proxyIP,proxyPort);
212 in = proxySocket.getInputStream();
213 out = proxySocket.getOutputStream();
214 }catch(SocksException se){
215 throw se;
216 }catch(IOException io_ex){
217 throw new SocksException(SOCKS_PROXY_IO_ERROR,""+io_ex);
218 }
219 }
220
221 protected abstract Proxy copy();
222 protected abstract ProxyMessage formMessage(int cmd,InetAddress ip,int port);
223 protected abstract ProxyMessage formMessage(int cmd,String host,int port)
224 throws UnknownHostException;
225 protected abstract ProxyMessage formMessage(InputStream in)
226 throws SocksException,
227 IOException;
228
229
230 protected ProxyMessage connect(InetAddress ip,int port)
231 throws SocksException{
232 try{
233 startSession();
234 ProxyMessage request = formMessage(SOCKS_CMD_CONNECT,
235 ip,port);
236 return exchange(request);
237 }catch(SocksException se){
238 endSession();
239 throw se;
240 }
241 }
242 protected ProxyMessage connect(String host,int port)
243 throws UnknownHostException,SocksException{
244 try{
245 startSession();
246 ProxyMessage request = formMessage(SOCKS_CMD_CONNECT,
247 host,port);
248 return exchange(request);
249 }catch(SocksException se){
250 endSession();
251 throw se;
252 }
253 }
254
255 protected ProxyMessage bind(InetAddress ip,int port)
256 throws SocksException{
257 try{
258 startSession();
259 ProxyMessage request = formMessage(SOCKS_CMD_BIND,
260 ip,port);
261 return exchange(request);
262 }catch(SocksException se){
263 endSession();
264 throw se;
265 }
266 }
267 protected ProxyMessage bind(String host,int port)
268 throws UnknownHostException,SocksException{
269 try{
270 startSession();
271 ProxyMessage request = formMessage(SOCKS_CMD_BIND,
272 host,port);
273 return exchange(request);
274 }catch(SocksException se){
275 endSession();
276 throw se;
277 }
278 }
279
280 protected ProxyMessage accept()
281 throws IOException,SocksException{
282 ProxyMessage msg;
283 try{
284 msg = formMessage(in);
285 }catch(InterruptedIOException iioe){
286 throw iioe;
287 }catch(IOException io_ex){
288 endSession();
289 throw new SocksException(SOCKS_PROXY_IO_ERROR,"While Trying accept:"
290 +io_ex);
291 }
292 return msg;
293 }
294
295 protected ProxyMessage udpAssociate(InetAddress ip,int port)
296 throws SocksException{
297 try{
298 startSession();
299 ProxyMessage request = formMessage(SOCKS_CMD_UDP_ASSOCIATE,
300 ip,port);
301 if(request != null)
302 return exchange(request);
303 }catch(SocksException se){
304 endSession();
305 throw se;
306 }
307 //Only get here if request was null
308 endSession();
309 throw new SocksException(SOCKS_METHOD_NOTSUPPORTED,
310 "This version of proxy does not support UDP associate, use version 5");
311 }
312 protected ProxyMessage udpAssociate(String host,int port)
313 throws UnknownHostException,SocksException{
314 try{
315 startSession();
316 ProxyMessage request = formMessage(SOCKS_CMD_UDP_ASSOCIATE,
317 host,port);
318 if(request != null) return exchange(request);
319 }catch(SocksException se){
320 endSession();
321 throw se;
322 }
323 //Only get here if request was null
324 endSession();
325 throw new SocksException(SOCKS_METHOD_NOTSUPPORTED,
326 "This version of proxy does not support UDP associate, use version 5");
327 }
328
329
330 protected void endSession(){
331 try{
332 if(proxySocket!=null) proxySocket.close();
333 proxySocket = null;
334 }catch(IOException io_ex){
335 }
336 }
337
338 /**
339 *Sends the request to SOCKS server
340 */
341 protected void sendMsg(ProxyMessage msg)throws SocksException,
342 IOException{
343 msg.write(out);
344 }
345
346 /**
347 * Reads the reply from the SOCKS server
348 */
349 protected ProxyMessage readMsg()throws SocksException,
350 IOException{
351 return formMessage(in);
352 }
353 /**
354 *Sends the request reads reply and returns it
355 *throws exception if something wrong with IO
356 *or the reply code is not zero
357 */
358 protected ProxyMessage exchange(ProxyMessage request)
359 throws SocksException{
360 ProxyMessage reply;
361 try{
362 request.write(out);
363 reply = formMessage(in);
364 }catch(SocksException s_ex){
365 throw s_ex;
366 }catch(IOException ioe){
367 throw(new SocksException(SOCKS_PROXY_IO_ERROR,""+ioe));
368 }
369 return reply;
370 }
371
372
373//Private methods
374//===============
375
376
377//Constants
378
379 public static final int SOCKS_SUCCESS =0;
380 public static final int SOCKS_FAILURE =1;
381 public static final int SOCKS_BADCONNECT =2;
382 public static final int SOCKS_BADNETWORK =3;
383 public static final int SOCKS_HOST_UNREACHABLE =4;
384 public static final int SOCKS_CONNECTION_REFUSED =5;
385 public static final int SOCKS_TTL_EXPIRE =6;
386 public static final int SOCKS_CMD_NOT_SUPPORTED =7;
387 public static final int SOCKS_ADDR_NOT_SUPPORTED =8;
388
389 public static final int SOCKS_NO_PROXY =1<<16;
390 public static final int SOCKS_PROXY_NO_CONNECT =2<<16;
391 public static final int SOCKS_PROXY_IO_ERROR =3<<16;
392 public static final int SOCKS_AUTH_NOT_SUPPORTED =4<<16;
393 public static final int SOCKS_AUTH_FAILURE =5<<16;
394 public static final int SOCKS_JUST_ERROR =6<<16;
395
396 public static final int SOCKS_DIRECT_FAILED =7<<16;
397 public static final int SOCKS_METHOD_NOTSUPPORTED =8<<16;
398
399
400 public static final int SOCKS_CMD_CONNECT =0x1;
401 static final int SOCKS_CMD_BIND =0x2;
402 static final int SOCKS_CMD_UDP_ASSOCIATE =0x3;
403
404}