Class: OverSIP::WebSocket::TlsServer

Inherits:
TcpServer
  • Object
show all
Defined in:
lib/oversip/websocket/listeners/tls_server.rb

Direct Known Subclasses

IPv4TlsServer, IPv6TlsServer

Constant Summary collapse

TLS_HANDSHAKE_MAX_TIME =
8

Constants inherited from TcpServer

OverSIP::WebSocket::TcpServer::HDR_SUPPORTED_WEBSOCKET_VERSIONS, OverSIP::WebSocket::TcpServer::HEADERS_MAX_SIZE, OverSIP::WebSocket::TcpServer::WS_MAGIC_GUID_04, OverSIP::WebSocket::TcpServer::WS_VERSIONS

Constants included from Logger

Logger::SYSLOG_POSIXMQ_MAPPING

Instance Attribute Summary

Attributes inherited from TcpServer

#connection_log_id, #remote_ip, #remote_ip_type, #remote_port, #ws_app_klass, #ws_protocol

Instance Method Summary collapse

Methods inherited from TcpServer

#accept_ws_handshake, #check_http_request, #http_reject, #ignore_incoming_data, #initialize, #parse_http_headers, #post_connection, #receive_data, #remote_desc

Methods included from DefaultPolicy

#check_hostport, #check_origin, #check_request_uri

Methods included from Logger

close, #fatal, fg_system_msg2str, init_logger_mq, load_methods, #log_id, syslog_system_msg2str, syslog_user_msg2str

Constructor Details

This class inherits a constructor from OverSIP::WebSocket::TcpServer

Instance Method Details

#post_initObject



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/oversip/websocket/listeners/tls_server.rb', line 8

def post_init
  @client_pems = []
  @client_last_pem = false

  start_tls({
    :verify_peer => true,
    :cert_chain_file => ::OverSIP.tls_public_cert,
    :private_key_file => ::OverSIP.tls_private_cert
  })

  # If the remote client does never send us a TLS certificate
  # after the TCP connection we would leak by storing more and
  # more messages in @pending_messages array.
  @timer_tls_handshake = ::EM::Timer.new(TLS_HANDSHAKE_MAX_TIME) do
    unless @connected
      log_system_notice "TLS handshake not performed within #{TLS_HANDSHAKE_MAX_TIME} seconds, closing the connection"
      close_connection
    end
  end
end

#ssl_handshake_completedObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/oversip/websocket/listeners/tls_server.rb', line 44

def ssl_handshake_completed
  log_system_info "TLS connection established from " << remote_desc

  # TODO: What to do it falidation fails? always do validation?

  validated, cert, tls_error, tls_error_string = ::OverSIP::TLS.validate @client_pems.pop, @client_pems
  if validated
    log_system_info "client provides a valid TLS certificate"
  else
    log_system_notice "client's TLS certificate validation failed (TLS error: #{tls_error.inspect}, description: #{tls_error_string.inspect})"
  end

  # @connected in TlsServer means "TLS connection" rather than
  # just "TCP connection".
  @connected = true
  @timer_tls_handshake.cancel  if @timer_tls_handshake
end

#ssl_verify_peer(pem) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/oversip/websocket/listeners/tls_server.rb', line 30

def ssl_verify_peer pem
  # TODO: Dirty workaround for bug https://github.com/eventmachine/eventmachine/issues/194.
  return true  if @client_last_pem == pem

  @client_last_pem = pem
  @client_pems << pem

  log_system_debug "received certificate num #{@client_pems.size} from client"  if $oversip_debug

  # Validation must be done in ssl_handshake_completed after receiving all the certs, so return true.
  return true
end

#unbind(cause = nil) ⇒ Object



63
64
65
66
# File 'lib/oversip/websocket/listeners/tls_server.rb', line 63

def unbind cause=nil
  super
  @timer_tls_handshake.cancel  if @timer_tls_handshake
end