Class: Rex::Proto::Proxy::Socks4a::Client
- Inherits:
-
Object
- Object
- Rex::Proto::Proxy::Socks4a::Client
- Defined in:
- lib/rex/proto/proxy/socks4a.rb
Overview
A client connected to the Socks4a server.
Defined Under Namespace
Modules: Relay Classes: Packet
Constant Summary collapse
- REQUEST_VERSION =
4
- REPLY_VERSION =
0
- COMMAND_CONNECT =
1
- COMMAND_BIND =
2
- REQUEST_GRANTED =
90
- REQUEST_REJECT_FAILED =
91
- REQUEST_REJECT_CONNECT =
92
- REQUEST_REJECT_USERID =
93
- HOST =
1
- PORT =
2
Instance Method Summary collapse
-
#initialize(server, sock) ⇒ Client
constructor
Create a new client connected to the server.
-
#start ⇒ Object
Start handling the client connection.
-
#stop ⇒ Object
Stop handling the client connection.
Constructor Details
#initialize(server, sock) ⇒ Client
Create a new client connected to the server.
222 223 224 225 226 227 228 |
# File 'lib/rex/proto/proxy/socks4a.rb', line 222 def initialize( server, sock ) @server = server @lsock = sock @rsock = nil @client_thread = nil @mutex = ::Mutex.new end |
Instance Method Details
#start ⇒ Object
Start handling the client connection.
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/rex/proto/proxy/socks4a.rb', line 233 def start # create a thread to handle this client request so as to not block the socks4a server @client_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyClient", false) do begin @server.add_client( self ) # get the initial client request packet request = Packet.recv( @lsock ) raise "Invalid Socks4 request packet received." if not request # handle the request begin # handle socks4a connect requests if( request.is_connect? ) # perform the connection request params = { 'PeerHost' => request.dest_ip, 'PeerPort' => request.dest_port, } params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context') @rsock = Rex::Socket::Tcp.create( params ) # and send back success to the client response = Packet.new response.version = REPLY_VERSION response.command = REQUEST_GRANTED @lsock.put( response.to_r ) # handle socks4a bind requests elsif( request.is_bind? ) # create a server socket for this request params = { 'LocalHost' => '0.0.0.0', 'LocalPort' => 0, } params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context') bsock = Rex::Socket::TcpServer.create( params ) # send back the bind success to the client response = Packet.new response.version = REPLY_VERSION response.command = REQUEST_GRANTED response.dest_ip = '0.0.0.0' response.dest_port = bsock.getlocalname()[PORT] @lsock.put( response.to_r ) # accept a client connection (2 minute timeout as per spec) begin ::Timeout.timeout( 120 ) do @rsock = bsock.accept end rescue ::Timeout::Error raise "Timeout reached on accept request." end # close the listening socket bsock.close # verify the connection is from the dest_ip originally specified by the client rpeer = @rsock.getpeername_as_array raise "Got connection from an invalid peer." if( rpeer[HOST] != request.dest_ip ) # send back the client connect success to the client # # sf: according to the spec we send this response back to the client, however # I have seen some clients who bawk if they get this second response. # response = Packet.new response.version = REPLY_VERSION response.command = REQUEST_GRANTED response.dest_ip = rpeer[HOST] response.dest_port = rpeer[PORT] @lsock.put( response.to_r ) else raise "Unknown request command received #{request.command} received." end rescue # send back failure to the client response = Packet.new response.version = REPLY_VERSION response.command = REQUEST_REJECT_FAILED @lsock.put( response.to_r ) # raise an exception to close this client connection raise "Failed to handle the clients request." end # setup the two way relay for full duplex io @lsock.extend( Relay ) @rsock.extend( Relay ) # start the socket relays... @lsock.relay( self, @rsock ) @rsock.relay( self, @lsock ) rescue wlog( "Client.start - #{$!}" ) self.stop end end end |
#stop ⇒ Object
Stop handling the client connection.
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/rex/proto/proxy/socks4a.rb', line 326 def stop @mutex.synchronize do if( not @closed ) begin @lsock.close if @lsock rescue end begin @rsock.close if @rsock rescue end @client_thread.kill if( @client_thread and @client_thread.alive? ) @server.remove_client( self ) @closed = true end end end |