Parent

Methods

Class/Module Index [+]

Quicksearch

Rex::Proto::Proxy::Socks4a::Client

A client connected to the Socks4a server.

Public Class Methods

new( server, sock ) click to toggle source

Create a new client connected to the server.

# 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

Public Instance Methods

start() click to toggle source

Start handling the client connection.

# 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 conenct 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 origionally specified by the client

                                        rpeer = @rsock.getpeername
                                        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() click to toggle source

Stop handling the client connection.

# 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

[Validate]

Generated with the Darkfish Rdoc Generator 2.