Class: Mongo::SSLSocket

Inherits:
Object show all
Includes:
SocketUtil
Defined in:
lib/mongo/util/ssl_socket.rb

Overview

A basic wrapper over Ruby’s SSLSocket that initiates a TCP connection over SSL and then provides an basic interface mirroring Ruby’s TCPSocket, vis., TCPSocket#send and TCPSocket#read.

Instance Attribute Summary

Attributes included from SocketUtil

#pid, #pool

Instance Method Summary collapse

Methods included from SocketUtil

#checkin, #checkout, #close, #closed?

Constructor Details

#initialize(host, port, op_timeout = nil, connect_timeout = nil, opts = {}) ⇒ SSLSocket

Returns a new instance of SSLSocket.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/mongo/util/ssl_socket.rb', line 27

def initialize(host, port, op_timeout=nil, connect_timeout=nil, opts={})
  @pid             = Process.pid
  @op_timeout      = op_timeout
  @connect_timeout = connect_timeout

  @tcp_socket = ::TCPSocket.new(host, port)
  @tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)

  @context = OpenSSL::SSL::SSLContext.new

  if opts[:cert]
    @context.cert = OpenSSL::X509::Certificate.new(File.open(opts[:cert]))
  end

  if opts[:key]
    @context.key = OpenSSL::PKey::RSA.new(File.open(opts[:key]))
  end

  if opts[:verify]
    @context.ca_file = opts[:ca_cert]
    @context.verify_mode = OpenSSL::SSL::VERIFY_PEER
  end

  begin
    @socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, @context)
    @socket.sync_close = true
    connect
  rescue OpenSSL::SSL::SSLError
    raise ConnectionFailure, "SSL handshake failed. MongoDB may " +
                             "not be configured with SSL support."
  end

  if opts[:verify]
    unless OpenSSL::SSL.verify_certificate_identity(@socket.peer_cert, host)
      raise ConnectionFailure, "SSL handshake failed. Hostname mismatch."
    end
  end

  self
end

Instance Method Details

#connectObject



68
69
70
71
72
73
74
75
76
# File 'lib/mongo/util/ssl_socket.rb', line 68

def connect
  if @connect_timeout
    Timeout::timeout(@connect_timeout, ConnectionTimeoutError) do
      @socket.connect
    end
  else
    @socket.connect
  end
end

#read(length, buffer) ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/mongo/util/ssl_socket.rb', line 82

def read(length, buffer)
  if @op_timeout
    Timeout::timeout(@op_timeout, OperationTimeout) do
      @socket.sysread(length, buffer)
    end
  else
    @socket.sysread(length, buffer)
  end
end

#send(data) ⇒ Object



78
79
80
# File 'lib/mongo/util/ssl_socket.rb', line 78

def send(data)
  @socket.syswrite(data)
end