OSDN Git Service

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