comparison src/net/sourceforge/jsocks/Socks5Proxy.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 0ce5cc452d02
children
comparison
equal deleted inserted replaced
348:29076621bab0 349:205ee2873330
1 package net.sourceforge.jsocks; 1 package net.sourceforge.jsocks;
2 import java.io.IOException; 2 import java.net.*;
3 import java.io.InputStream; 3 import java.io.*;
4 import java.io.OutputStream; 4 import java.util.Hashtable;
5 import java.net.InetAddress;
6 import java.net.Socket;
7 import java.net.SocketException;
8 import java.net.UnknownHostException;
9 import java.util.Enumeration; 5 import java.util.Enumeration;
10 import java.util.Hashtable;
11 6
12 /** 7 /**
13 SOCKS5 Proxy. 8 SOCKS5 CProxy.
14 */ 9 */
15 10
16 public class Socks5Proxy extends Proxy implements Cloneable { 11 public class Socks5Proxy extends CProxy implements Cloneable{
17 12
18 //Data members 13 //Data members
19 private Hashtable<Integer, Authentication> authMethods = new Hashtable<Integer, Authentication>(); 14 private Hashtable authMethods = new Hashtable();
20 private int selectedMethod; 15 private int selectedMethod;
21 16
22 boolean resolveAddrLocally = true; 17 boolean resolveAddrLocally = true;
23 UDPEncapsulation udp_encapsulation = null; 18 UDPEncapsulation udp_encapsulation=null;
24 19
25 20
26 //Public Constructors 21 //Public Constructors
27 //==================== 22 //====================
28 23
29 /** 24 /**
30 Creates SOCKS5 proxy. 25 Creates SOCKS5 proxy.
31 @param proxyHost Host on which a Proxy server runs. 26 @param p CProxy to use to connect to this proxy, allows proxy chaining.
32 @param proxyPort Port on which a Proxy server listens for connections. 27 @param proxyHost Host on which a CProxy server runs.
33 @throws UnknownHostException If proxyHost can't be resolved. 28 @param proxyPort Port on which a CProxy server listens for connections.
34 */ 29 @throws UnknownHostException If proxyHost can't be resolved.
35 public Socks5Proxy(String proxyHost, int proxyPort) 30 */
36 throws UnknownHostException { 31 public Socks5Proxy(CProxy p,String proxyHost,int proxyPort)
37 super(proxyHost, proxyPort); 32 throws UnknownHostException{
38 version = 5; 33 super(p,proxyHost,proxyPort);
39 setAuthenticationMethod(0, new AuthenticationNone()); 34 version = 5;
40 } 35 setAuthenticationMethod(0,new AuthenticationNone());
41 36 }
42 37
43 /** 38 /**
44 Creates SOCKS5 proxy. 39 Creates SOCKS5 proxy.
45 @param proxyIP Host on which a Proxy server runs. 40 @param proxyHost Host on which a CProxy server runs.
46 @param proxyPort Port on which a Proxy server listens for connections. 41 @param proxyPort Port on which a CProxy server listens for connections.
47 */ 42 @throws UnknownHostException If proxyHost can't be resolved.
48 public Socks5Proxy(InetAddress proxyIP, int proxyPort) { 43 */
49 super(proxyIP, proxyPort); 44 public Socks5Proxy(String proxyHost,int proxyPort)
50 version = 5; 45 throws UnknownHostException{
51 setAuthenticationMethod(0, new AuthenticationNone()); 46 this(null,proxyHost,proxyPort);
52 } 47 }
53 48
49
50 /**
51 Creates SOCKS5 proxy.
52 @param p CProxy to use to connect to this proxy, allows proxy chaining.
53 @param proxyIP Host on which a CProxy server runs.
54 @param proxyPort Port on which a CProxy server listens for connections.
55 */
56 public Socks5Proxy(CProxy 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 CProxy server runs.
65 @param proxyPort Port on which a CProxy server listens for connections.
66 */
67 public Socks5Proxy(InetAddress proxyIP,int proxyPort){
68 this(null,proxyIP,proxyPort);
69 }
54 70
55 //Public instance methods 71 //Public instance methods
56 //======================== 72 //========================
57 73
58 74
59 /** 75 /**
60 * Wether to resolve address locally or to let proxy do so. 76 * Wether to resolve address locally or to let proxy do so.
61 <p> 77 <p>
62 SOCKS5 protocol allows to send host names rather then IPs in the 78 SOCKS5 protocol allows to send host names rather then IPs in the
63 requests, this option controls wether the hostnames should be send 79 requests, this option controls wether the hostnames should be send
64 to the proxy server as names, or should they be resolved locally. 80 to the proxy server as names, or should they be resolved locally.
65 @param doResolve Wether to perform resolution locally. 81 @param doResolve Wether to perform resolution locally.
66 @return Previous settings. 82 @return Previous settings.
67 */
68 public boolean resolveAddrLocally(boolean doResolve) {
69 boolean old = resolveAddrLocally;
70 resolveAddrLocally = doResolve;
71 return old;
72 }
73 /**
74 Get current setting on how the addresses should be handled.
75 @return Current setting for address resolution.
76 @see Socks5Proxy#resolveAddrLocally(boolean doResolve)
77 */ 83 */
78 public boolean resolveAddrLocally() { 84 public boolean resolveAddrLocally(boolean doResolve){
79 return resolveAddrLocally; 85 boolean old = resolveAddrLocally;
80 } 86 resolveAddrLocally = doResolve;
81 87 return old;
82 /** 88 }
83 Adds another authentication method. 89 /**
84 @param methodId Authentication method id, see rfc1928 90 Get current setting on how the addresses should be handled.
85 @param method Implementation of Authentication 91 @return Current setting for address resolution.
86 @see Authentication 92 @see Socks5Proxy#resolveAddrLocally(boolean doResolve)
87 */ 93 */
88 public boolean setAuthenticationMethod(int methodId, 94 public boolean resolveAddrLocally(){
89 Authentication method) { 95 return resolveAddrLocally;
90 if (methodId < 0 || methodId > 255) 96 }
91 return false; 97
92 98 /**
93 if (method == null) { 99 Adds another authentication method.
94 //Want to remove a particular method 100 @param methodId Authentication method id, see rfc1928
95 return (authMethods.remove(Integer.valueOf(methodId)) != null); 101 @param method Implementation of Authentication
96 } 102 @see Authentication
97 else {//Add the method, or rewrite old one 103 */
98 authMethods.put(Integer.valueOf(methodId), method); 104 public boolean setAuthenticationMethod(int methodId,
99 } 105 Authentication method){
100 106 if(methodId<0 || methodId > 255)
101 return true; 107 return false;
102 } 108 if(method == null){
103 109 //Want to remove a particular method
104 /** 110 return (authMethods.remove(new Integer(methodId)) != null);
105 Get authentication method, which corresponds to given method id 111 }else{//Add the method, or rewrite old one
106 @param methodId Authentication method id. 112 authMethods.put(new Integer(methodId),method);
107 @return Implementation for given method or null, if one was not set. 113 }
108 */ 114 return true;
109 public Authentication getAuthenticationMethod(int methodId) { 115 }
110 Object method = authMethods.get(Integer.valueOf(methodId)); 116
111 117 /**
112 if (method == null) return null; 118 Get authentication method, which corresponds to given method id
113 119 @param methodId Authentication method id.
114 return (Authentication)method; 120 @return Implementation for given method or null, if one was not set.
115 } 121 */
116 122 public Authentication getAuthenticationMethod(int methodId){
117 /** 123 Object method = authMethods.get(new Integer(methodId));
118 Creates a clone of this Proxy. 124 if(method == null) return null;
119 */ 125 return (Authentication)method;
120 @Override 126 }
121 @SuppressWarnings("unchecked") 127
122 public Object clone() { 128 /**
123 Socks5Proxy newProxy = new Socks5Proxy(proxyIP, proxyPort); 129 Creates a clone of this CProxy.
124 newProxy.authMethods = (Hashtable<Integer, Authentication>) this.authMethods.clone(); 130 */
125 newProxy.resolveAddrLocally = resolveAddrLocally; 131 public Object clone(){
126 newProxy.chainProxy = chainProxy; 132 Socks5Proxy newProxy = new Socks5Proxy(proxyIP,proxyPort);
127 return newProxy; 133 newProxy.authMethods = (Hashtable) this.authMethods.clone();
128 } 134 newProxy.directHosts = (InetRange)directHosts.clone();
135 newProxy.resolveAddrLocally = resolveAddrLocally;
136 newProxy.chainProxy = chainProxy;
137 return newProxy;
138 }
129 139
130 //Public Static(Class) Methods 140 //Public Static(Class) Methods
131 //============================== 141 //==============================
132 142
133 143
134 //Protected Methods 144 //Protected Methods
135 //================= 145 //=================
136 146
137 @Override 147 protected CProxy copy(){
138 protected Proxy copy() { 148 Socks5Proxy copy = new Socks5Proxy(proxyIP,proxyPort);
139 Socks5Proxy copy = new Socks5Proxy(proxyIP, proxyPort); 149 copy.authMethods = this.authMethods; //same Hash, no copy
140 copy.authMethods = this.authMethods; //same Hash, no copy 150 copy.directHosts = this.directHosts;
141 copy.chainProxy = this.chainProxy; 151 copy.chainProxy = this.chainProxy;
142 copy.resolveAddrLocally = this.resolveAddrLocally; 152 copy.resolveAddrLocally = this.resolveAddrLocally;
143 return copy; 153 return copy;
144 } 154 }
145 /** 155 /**
146 * 156 *
147 * 157 *
148 */ 158 */
149 @Override 159 protected void startSession()throws SocksException{
150 protected void startSession()throws SocksException { 160 super.startSession();
151 super.startSession(); 161 Authentication auth;
152 Authentication auth; 162 Socket ps = proxySocket; //The name is too long
153 Socket ps = proxySocket; //The name is too long 163
154 164 try{
155 try { 165
156 byte nMethods = (byte) authMethods.size(); //Number of methods 166 byte nMethods = (byte) authMethods.size(); //Number of methods
157 byte[] buf = new byte[2 + nMethods]; //2 is for VER,NMETHODS 167
158 buf[0] = (byte) version; 168 byte[] buf = new byte[2+nMethods]; //2 is for VER,NMETHODS
159 buf[1] = nMethods; //Number of methods 169 buf[0] = (byte) version;
160 int i = 2; 170 buf[1] = nMethods; //Number of methods
161 Enumeration<Integer> ids = authMethods.keys(); 171 int i=2;
162 172
163 while (ids.hasMoreElements()) 173 Enumeration ids = authMethods.keys();
164 buf[i++] = (byte)ids.nextElement().intValue(); 174 while(ids.hasMoreElements())
165 175 buf[i++] = (byte)((Integer)ids.nextElement()).intValue();
166 out.write(buf); 176
167 out.flush(); 177 out.write(buf);
168 int versionNumber = in.read(); 178 out.flush();
169 selectedMethod = in.read(); 179
170 180 int versionNumber = in.read();
171 if (versionNumber < 0 || selectedMethod < 0) { 181 selectedMethod = in.read();
172 //EOF condition was reached 182
173 endSession(); 183 if(versionNumber < 0 || selectedMethod < 0){
174 throw(new SocksException(SOCKS_PROXY_IO_ERROR, 184 //EOF condition was reached
175 "Connection to proxy lost.")); 185 endSession();
176 } 186 throw(new SocksException(SOCKS_PROXY_IO_ERROR,
177 187 "Connection to proxy lost."));
178 if (versionNumber < version) { 188 }
179 //What should we do?? 189 if(versionNumber < version){
180 } 190 //What should we do??
181 191 }
182 if (selectedMethod == 0xFF) { //No method selected 192 if(selectedMethod == 0xFF){ //No method selected
183 ps.close(); 193 ps.close();
184 throw(new SocksException(SOCKS_AUTH_NOT_SUPPORTED)); 194 throw ( new SocksException(SOCKS_AUTH_NOT_SUPPORTED));
185 } 195 }
186 196
187 auth = getAuthenticationMethod(selectedMethod); 197 auth = getAuthenticationMethod(selectedMethod);
188 198 if(auth == null){
189 if (auth == null) { 199 //This shouldn't happen, unless method was removed by other
190 //This shouldn't happen, unless method was removed by other 200 //thread, or the server stuffed up
191 //thread, or the server stuffed up 201 throw(new SocksException(SOCKS_JUST_ERROR,
192 throw(new SocksException(SOCKS_JUST_ERROR, 202 "Speciefied Authentication not found!"));
193 "Speciefied Authentication not found!")); 203 }
194 } 204 Object[] in_out = auth.doSocksAuthentication(selectedMethod,ps);
195 205 if(in_out == null){
196 Object[] in_out = auth.doSocksAuthentication(selectedMethod, ps); 206 //Authentication failed by some reason
197 207 throw(new SocksException(SOCKS_AUTH_FAILURE));
198 if (in_out == null) { 208 }
199 //Authentication failed by some reason 209 //Most authentication methods are expected to return
200 throw(new SocksException(SOCKS_AUTH_FAILURE)); 210 //simply the input/output streams associated with
201 } 211 //the socket. However if the auth. method requires
202 212 //some kind of encryption/decryption being done on the
203 //Most authentication methods are expected to return 213 //connection it should provide classes to handle I/O.
204 //simply the input/output streams associated with 214
205 //the socket. However if the auth. method requires 215 in = (InputStream) in_out[0];
206 //some kind of encryption/decryption being done on the 216 out = (OutputStream) in_out[1];
207 //connection it should provide classes to handle I/O. 217 if(in_out.length > 2)
208 in = (InputStream) in_out[0]; 218 udp_encapsulation = (UDPEncapsulation) in_out[2];
209 out = (OutputStream) in_out[1]; 219
210 220 }catch(SocksException s_ex){
211 if (in_out.length > 2) 221 throw s_ex;
212 udp_encapsulation = (UDPEncapsulation) in_out[2]; 222 }catch(UnknownHostException uh_ex){
213 } 223 throw(new SocksException(SOCKS_PROXY_NO_CONNECT));
214 catch (SocksException s_ex) { 224 }catch(SocketException so_ex){
215 throw s_ex; 225 throw(new SocksException(SOCKS_PROXY_NO_CONNECT));
216 } 226 }catch(IOException io_ex){
217 catch (UnknownHostException uh_ex) { 227 //System.err.println(io_ex);
218 throw(new SocksException(SOCKS_PROXY_NO_CONNECT)); 228 throw(new SocksException(SOCKS_PROXY_IO_ERROR,""+io_ex));
219 } 229 }
220 catch (SocketException so_ex) { 230 }
221 throw(new SocksException(SOCKS_PROXY_NO_CONNECT)); 231
222 } 232 protected ProxyMessage formMessage(int cmd,InetAddress ip,int port){
223 catch (IOException io_ex) { 233 return new Socks5Message(cmd,ip,port);
224 //System.err.println(io_ex); 234 }
225 throw(new SocksException(SOCKS_PROXY_IO_ERROR, "" + io_ex)); 235 protected ProxyMessage formMessage(int cmd,String host,int port)
226 } 236 throws UnknownHostException{
227 } 237 if(resolveAddrLocally)
228 238 return formMessage(cmd,InetAddress.getByName(host),port);
229 @Override 239 else
230 protected ProxyMessage formMessage(int cmd, InetAddress ip, int port) { 240 return new Socks5Message(cmd,host,port);
231 return new Socks5Message(cmd, ip, port); 241 }
232 } 242 protected ProxyMessage formMessage(InputStream in)
233 @Override 243 throws SocksException,
234 protected ProxyMessage formMessage(int cmd, String host, int port) 244 IOException{
235 throws UnknownHostException { 245 return new Socks5Message(in);
236 if (resolveAddrLocally) 246 }
237 return formMessage(cmd, InetAddress.getByName(host), port);
238 else
239 return new Socks5Message(cmd, host, port);
240 }
241 @Override
242 protected ProxyMessage formMessage(InputStream in)
243 throws SocksException,
244 IOException {
245 return new Socks5Message(in);
246 }
247 247
248 } 248 }