Arachni::RPC::EM::SSL

Adds support for SSL and peer verification.

To be included by EventMachine::Connection classes.

@see gist.github.com/1151454

@author: Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>

Public Instance Methods

are_we_a_client?() click to toggle source
# File lib/arachni/rpc/em/ssl.rb, line 157
def are_we_a_client?
    @opts[:role] == :client
end
ca_store() click to toggle source

@return [OpenSSL::X509::Store] certificate store

# File lib/arachni/rpc/em/ssl.rb, line 97
def ca_store
    if !@ca_store
        if file = @opts[:ssl_ca]
            @ca_store = OpenSSL::X509::Store.new
            @ca_store.add_file( file )
        else
            fail "No CA certificate has been provided."
        end
    end

    @ca_store
end
end_ssl() click to toggle source

Cleans up any SSL related resources.

# File lib/arachni/rpc/em/ssl.rb, line 76
def end_ssl
end
log( severity, progname, msg ) click to toggle source

To be implemented by the parent.

By default, it will 'warn' if the severity is :error and will 'raise' if the severity if :fatal.

@param [Symbol] severity :fatal, :error, :warn, :info, :debug @param [String] progname name of the component that performed the action @param [String] msg message to log

# File lib/arachni/rpc/em/ssl.rb, line 89
def log( severity, progname, msg )
    warn "#{progname}: #{msg}" if severity == :error
    fail "#{progname}: #{msg}" if severity == :fatal
end
ssl_handshake_completed() click to toggle source

Checks for an appropriate server cert hostname if run from the client-side.

Does nothing when on the server-side.

@see eventmachine.rubyforge.org/EventMachine/Connection.html#M000270

# File lib/arachni/rpc/em/ssl.rb, line 146
def ssl_handshake_completed
    return if !are_we_a_client? || !ssl_opts? ||
        OpenSSL::SSL.verify_certificate_identity( @last_seen_cert, @opts[:host] )

    log( :error, 'SSL',
         "The hostname '#{@opts[:host]}' does not match the server certificate."
    )

    close_connection
end
ssl_opts?() click to toggle source
# File lib/arachni/rpc/em/ssl.rb, line 161
def ssl_opts?
    @opts[:ssl_ca] && @opts[:ssl_pkey] && @opts[:ssl_cert]
end
ssl_verify_peer( cert_string ) click to toggle source

Verifies the peer cert based on the {ca_store}.

@see eventmachine.rubyforge.org/EventMachine/Connection.html#M000271

# File lib/arachni/rpc/em/ssl.rb, line 115
def ssl_verify_peer( cert_string )
    cert = OpenSSL::X509::Certificate.new( cert_string )

    # Some servers send the same certificate multiple times. I'm not even
    # joking... (gmail.com)
    return true if cert == @last_seen_cert

    if ca_store.verify( cert )
        @last_seen_cert = cert

        # A server may send the root certificate, which we already have and thus
        # should not be added to the store again.
        ca_store.add_cert( @last_seen_cert ) if !@last_seen_cert.root?

        @verified_peer = true
        true
    else
        log( :error, 'SSL',
            "#{ca_store.error_string.capitalize} ['#{peer_ip_addr}']."
        )
        false
    end
end
start_ssl() click to toggle source

Starts SSL with the supplied keys, certs etc.

# File lib/arachni/rpc/em/ssl.rb, line 51
def start_ssl
    @verified_peer = false
    @ssl_requested = true

    ssl_opts = {}
    if ssl_opts?
        ssl_opts = {
            private_key_file: @opts[:ssl_pkey],
            cert_chain_file:  @opts[:ssl_cert],
            verify_peer:      true
        }
        @last_seen_cert = nil
    end

    # ap ssl_opts
    start_tls( ssl_opts )
end
verified_peer?() click to toggle source
# File lib/arachni/rpc/em/ssl.rb, line 69
def verified_peer?
    @verified_peer
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.