class Blur::Network::Connection

The Connection class inherits the LineAndText protocol bundled with the eventmachine library.

It merely acts as a receiving handler for all messages eventmachine throws at it through its lifetime.

@see EventMachine::Protocols::LineAndTextProtocol @see EventMachine::Connection

Constants

SSLValidationError

Public Class Methods

new(network) click to toggle source

EventMachine instantiates this class, and then sends event messages to that instance.

Calls superclass method
# File library/blur/network/connection.rb, line 21
def initialize network
  @network = network
  @connected = false

  super
end

Public Instance Methods

connection_completed() click to toggle source

Called once the connection is finally established.

# File library/blur/network/connection.rb, line 99
def connection_completed
  # We aren't completely connected yet if the connection is encrypted.
  unless @network.secure?
    connected!
  end
end
established?() click to toggle source

Check whether or not connection is established.

# File library/blur/network/connection.rb, line 17
def established?; @connected == true end
post_init() click to toggle source

Called when a new connection is being set up, all we're going to use it for is to enable SSL/TLS on our connection.

# File library/blur/network/connection.rb, line 30
def post_init
  if @network.secure?
    verify_peer = (@network.options[:ssl_no_verify] ? false : true)

    start_tls verify_peer: verify_peer
  end
end
receive_line(line) click to toggle source

Called when a line was received, the connection sends it to the network delegate which then sends it to the client.

# File library/blur/network/connection.rb, line 40
def receive_line line
  message = IRCParser::Message.parse line

  @network.got_message message
end
ssl_handshake_completed() click to toggle source

Called when the SSL handshake was completed with the remote server, the reason we tell the network that we're connected here is to ensure that the SSL/TLS encryption succeeded before we start talking nonsense to the server.

# File library/blur/network/connection.rb, line 50
def ssl_handshake_completed
  connected!
end
ssl_verify_peer(peer_cert) click to toggle source

Validates that the peer certificate has the correct fingerprint as specified in the :fingerprint :ssl option.

@note This doesn't support intermediate certificate authorities! @raise [SSLValidationError] Raised if the specified fingerprint doesn't match the certificates.

# File library/blur/network/connection.rb, line 60
def ssl_verify_peer peer_cert
  ssl_cert_file    = @network.options[:ssl_cert_file]
  peer_certificate = OpenSSL::X509::Certificate.new peer_cert

  if ssl_cert_file
    unless File.readable? ssl_cert_file
      raise SSLValidationError, "Could not read the CA certificate file."

      return false
    end
  end

  if fingerprint_verification?
    fingerprint = @network.options[:ssl_fingerprint].to_s
    peer_fingerprint = cert_sha1_fingerprint peer_certificate

    if fingerprint != peer_fingerprint
      raise SSLValidationError,
        "Expected fingerprint '#{fingerprint}', but got '#{peer_fingerprint}'"

      return false
    end
  end

  if certificate_verification?
    ca_certificate = OpenSSL::X509::Certificate.new File.read ssl_cert_file
    valid_signature = peer_certificate.verify ca_certificate.public_key

    if not valid_signature
      raise SSLValidationError, "Certificate verify failed"

      return false
    end
  end

  true
end
unbind() click to toggle source

Called just as the connection is being terminated, either by remote or local.

Calls superclass method
# File library/blur/network/connection.rb, line 108
def unbind
  @connected = false
  @network.disconnected!

  super
end

Private Instance Methods

cert_sha1_fingerprint(certificate) click to toggle source

Get the hexadecimal representation of the certificates public key.

# File library/blur/network/connection.rb, line 134
def cert_sha1_fingerprint certificate
  fingerprint = OpenSSL::Digest::SHA1.hexdigest certificate.to_der

  # Format it the same way OpenSSL does.
  fingerprint = fingerprint.chars.each_slice(2).map(&:join).join ':'
  fingerprint.upcase
end
certificate_verification?() click to toggle source

Returns true if we should verify the peer certificate.

# File library/blur/network/connection.rb, line 129
def certificate_verification?
  not @network.options[:ssl_cert_file].nil?
end
connected!() click to toggle source

Called when connection has been established.

# File library/blur/network/connection.rb, line 117
def connected!
  @connected = true

  @network.connected!
end
fingerprint_verification?() click to toggle source

Returns true if we're expected to verify the certificate fingerprint.

# File library/blur/network/connection.rb, line 124
def fingerprint_verification?
  not @network.options[:ssl_fingerprint].nil?
end
ssl_fingerprint_error!(peer_fingerprint) click to toggle source
# File library/blur/network/connection.rb, line 142
def ssl_fingerprint_error! peer_fingerprint
  fingerprint = @network.options[:ssl_fingerprint]

  raise SSLValidationError,
    "Expected fingerprint '#{fingerprint}' but got '#{peer_fingerprint}'"
end