Module: Arachni::RPC::EM::Protocol

Includes:
SSL
Included in:
Client::Handler, Server::Proxy
Defined in:
lib/arachni/rpc/em/protocol.rb

Overview

Provides helper transport methods for Message transmission.

@author: Tasos “Zapotek” Laskos

<[email protected]>
<[email protected]>

@version: 0.1

Constant Summary collapse

MAX_CHUNK_SIZE =

send a maximum of 16kb of data per tick

1024 * 16

Instance Method Summary collapse

Methods included from SSL

#are_we_a_client?, #ca_store, #end_ssl, #log, #ssl_handshake_completed, #ssl_opts?, #ssl_verify_peer, #start_ssl, #verified_peer?

Methods included from ConnectionUtilities

#peer_ip_addr

Instance Method Details

#assume_client_role!Object

become a client



33
34
35
# File 'lib/arachni/rpc/em/protocol.rb', line 33

def assume_client_role!
    @role = :client
end

#assume_server_role!Object

become a server



28
29
30
# File 'lib/arachni/rpc/em/protocol.rb', line 28

def assume_server_role!
    @role = :server
end

#receive_data(data) ⇒ Object

Receives data from the network.

In this case the data will be chunks of a serialized object which will be buffered until the whole transmission has finished.

It will then unresialize it and pass it to receive_object().



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/arachni/rpc/em/protocol.rb', line 91

def receive_data( data )
    #
    # cut them out as soon as possible
    #
    # don't buffer any data from unverified peers if SSL peer
    # veification has been enabled
    #
    if ssl_opts? && !verified_peer? && @role == :server
        e = Arachni::RPC::Exceptions::SSLPeerVerificationFailed.new( 'Could not verify peer.' )
        send_response Response.new( :obj => {
            'exception' => e.to_s,
            'backtrace' => e.backtrace,
            'type'      => 'SSLPeerVerificationFailed'
        })

        log( :error, 'SSL', " Could not verify peer. ['#{peer_ip_addr}']." )
        return
    end

    (@buf ||= '') << data

    while @buf.size >= 4
        if @buf.size >= 4 + ( size = @buf.unpack( 'N' ).first )
            @buf.slice!( 0, 4 )
            receive_object( serializer.load( @buf.slice!( 0, size ) ) )
        else
            break
        end
    end
end

#receive_object(obj) ⇒ Object

Converts incoming hash objects to Requests or Response (depending on the assumed role) and calls receive_request() or receive_response() accordingly.

Parameters:

  • obj (Hash)


62
63
64
65
66
67
68
# File 'lib/arachni/rpc/em/protocol.rb', line 62

def receive_object( obj )
    if @role == :server
        receive_request( Request.new( obj ) )
    else
        receive_response( Response.new( obj ) )
    end
end

#receive_request(request) ⇒ Object

Stub method, should be implemented by servers.

Parameters:

  • request (Arachni::RPC::EM::Request)


42
43
44
# File 'lib/arachni/rpc/em/protocol.rb', line 42

def receive_request( request )
    p request
end

#receive_response(response) ⇒ Object

Stub method, should be implemented by clients.

Parameters:

  • response (Arachni::RPC::EM::Response)


51
52
53
# File 'lib/arachni/rpc/em/protocol.rb', line 51

def receive_response( response )
    p response
end

#send_message(msg) ⇒ Object Also known as: send_request, send_response

Sends a message to the peer.

Parameters:

  • msg (Arachni::RPC::EM::Message)


75
76
77
78
79
# File 'lib/arachni/rpc/em/protocol.rb', line 75

def send_message( msg )
    ::EM.schedule {
        send_object( msg.prepare_for_tx )
    }
end

#send_object(obj) ⇒ Object

Sends a ruby object over the network

Will split the object in chunks of MAX_CHUNK_SIZE and transmit one at a time.



127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/arachni/rpc/em/protocol.rb', line 127

def send_object( obj )
    data = serializer.dump( obj )
    packed = [data.bytesize, data].pack( 'Na*' )

    while( packed )
        if packed.bytesize > MAX_CHUNK_SIZE
            send_data( packed.slice!( 0, MAX_CHUNK_SIZE ) )
        else
            send_data( packed )
            break
        end
    end
end

#serializerClass

Returns the preferred serializer based on the ‘serializer’ option of the server.

Defaults to YAML.



150
151
152
# File 'lib/arachni/rpc/em/protocol.rb', line 150

def serializer
    @opts[:serializer] ? @opts[:serializer] : YAML
end