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