Class: Blur::Network::Connection

Inherits:
EM::Protocols::LineAndTextProtocol
  • Object
show all
Defined in:
library/blur/network/connection.rb

Overview

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 Also:

  • EventMachine::Protocols::LineAndTextProtocol
  • EventMachine::Connection

Constant Summary collapse

SSLValidationError =
Class.new StandardError
DEFAULT_CONNECT_TIMEOUT_INTERVAL =

Returns the default connection timeout interval in seconds.

Returns:

  • (Float)

    the default connection timeout interval in seconds.

30

Instance Method Summary collapse

Constructor Details

#initialize(network) ⇒ Connection

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


26
27
28
29
30
31
32
33
34
35
# File 'library/blur/network/connection.rb', line 26

def initialize network
  @network = network
  @connected = false
  connect_timeout = network.options.fetch 'connect_timeout',
                                          DEFAULT_CONNECT_TIMEOUT_INTERVAL

  self.pending_connect_timeout = connect_timeout

  super
end

Instance Method Details

#connection_completedObject

Called once the connection is finally established.


97
98
99
100
# File 'library/blur/network/connection.rb', line 97

def connection_completed
  # We aren't completely connected yet if the connection is encrypted.
  connected! unless @network.secure?
end

#established?Boolean

Check whether or not connection is established.

Returns:

  • (Boolean)

20
21
22
# File 'library/blur/network/connection.rb', line 20

def established?
  @connected == true
end

#post_initObject

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.


39
40
41
42
43
44
# File 'library/blur/network/connection.rb', line 39

def post_init
  return unless @network.secure?

  verify_peer = (@network.options[:ssl_no_verify] ? false : true)
  start_tls verify_peer: verify_peer
end

#receive_line(line) ⇒ Object

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


48
49
50
51
52
# File 'library/blur/network/connection.rb', line 48

def receive_line line
  message = IRCParser::Message.parse line

  @network.got_message message
end

#ssl_handshake_completedObject

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.


58
59
60
# File 'library/blur/network/connection.rb', line 58

def ssl_handshake_completed
  connected!
end

#ssl_verify_peer(peer_cert) ⇒ Object

Note:

This doesn’t support intermediate certificate authorities!

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

match the certificates.

Raises:


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'library/blur/network/connection.rb', line 68

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 && !File.readable?(ssl_cert_file)
    raise SSLValidationError, 'Could not read the CA certificate file.'
  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}'"
    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

    raise SSLValidationError, 'Certificate verify failed' unless valid_signature
  end

  true
end

#unbindObject

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


104
105
106
107
108
109
# File 'library/blur/network/connection.rb', line 104

def unbind
  @connected = false
  @network.disconnected!

  super
end