Class: PacketThief::Handlers::AbstractSSLHandler
- Inherits:
-
EM::Connection
- Object
- EM::Connection
- PacketThief::Handlers::AbstractSSLHandler
- Includes:
- Logging
- Defined in:
- lib/packetthief/handlers/abstract_ssl_handler.rb
Overview
Parent class for both SSLServer and SSLClient.
TODO: get_peer_cert, get_peername, etc.
Instance Attribute Summary collapse
-
#ctx ⇒ Object
The OpenSSL::SSL::SSLContext.
-
#sni_hostname ⇒ Object
(Used by SSLClient only) The hostname that the SNI TLS extension should request.
-
#sslsocket ⇒ Object
The SSLSocket.
-
#tcpsocket ⇒ Object
The TCPSocket that the SSLSocket will be created from.
Instance Method Summary collapse
- #close_connection ⇒ Object
- #close_connection_after_writing ⇒ Object
-
#initialize(tcpsocket) ⇒ AbstractSSLHandler
constructor
A new instance of AbstractSSLHandler.
-
#notify_readable ⇒ Object
Calls accept_nonblock/connect_nonblock, read_nonblock, or write_nonblock based on the current state of the connection.
-
#notify_writable ⇒ Object
We only care about notify_writable if we are waiting to write for some reason.
-
#post_init ⇒ Object
Note that post_init dos not have access to the sslsocket.
-
#receive_data(data) ⇒ Object
Override this to do something with the unecrypted data.
-
#send_data(data) ⇒ Object
Call this to send data to the other end of the connection.
-
#tls_begin ⇒ Object
Creates sslsocket from tcpsocket and ctx, and initializes the handler’s internal state.
-
#tls_failed_handshake(e) ⇒ Object
Called right after accept_nonblock fails for some unknown reason.
-
#tls_successful_handshake ⇒ Object
Called right after the SSL handshake succeeds.
-
#unbind ⇒ Object
Override this to do something when the socket is finished.
- #write_buffer ⇒ Object
- #write_buffer=(rhs) ⇒ Object
Methods included from Logging
Constructor Details
#initialize(tcpsocket) ⇒ AbstractSSLHandler
Returns a new instance of AbstractSSLHandler.
29 30 31 32 33 34 35 36 37 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 29 def initialize(tcpsocket) logdebug "initialize" # Set up initial values @tcpsocket = tcpsocket @ctx = OpenSSL::SSL::SSLContext.new @close_after_writing = false @state = :new end |
Instance Attribute Details
#ctx ⇒ Object
The OpenSSL::SSL::SSLContext. Modify this in post_init or in the initializing code block to add certificates, etc.
14 15 16 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 14 def ctx @ctx end |
#sni_hostname ⇒ Object
(Used by SSLClient only) The hostname that the SNI TLS extension should request. Set it in post_init or in the initializing code block — it is applied to the SSLSocket during #tls_begin.
27 28 29 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 27 def sni_hostname @sni_hostname end |
#sslsocket ⇒ Object
The SSLSocket. It is not available until #tls_begin creates it, after post_init and the initializing code block.
22 23 24 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 22 def sslsocket @sslsocket end |
#tcpsocket ⇒ Object
The TCPSocket that the SSLSocket will be created from. It is added by #initialize.
18 19 20 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 18 def tcpsocket @tcpsocket end |
Instance Method Details
#close_connection ⇒ Object
192 193 194 195 196 197 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 192 def close_connection detach @sslsocket.close if @sslsocket and not @sslsocket.closed? @tcpsocket.close if not @tcpsocket.closed? # unbind end |
#close_connection_after_writing ⇒ Object
199 200 201 202 203 204 205 206 207 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 199 def close_connection_after_writing @close_after_writing = true # if we aren't waiting to write, then we can flush and close. if not notify_writable? @sslsocket.flush close_connection end end |
#notify_readable ⇒ Object
Calls accept_nonblock/connect_nonblock, read_nonblock, or write_nonblock based on the current state of the connection.
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 62 def notify_readable logdebug "notify_readable", :state => @state case @state when :initialized attempt_connection when :ready_to_read attempt_read when :write_needs_to_read attempt_write end end |
#notify_writable ⇒ Object
We only care about notify_writable if we are waiting to write for some reason.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 76 def notify_writable logdebug "notify_writable", :state => @state notify_writable = false # disable it now. if we still need it, we'll renabled it. case @state when :initialized attempt_connection when :read_needs_to_write attempt_read when :write_needs_to_write attempt_write end # if we waiting to close and are not longer waiting to write, we can flush and close the connection. if @close_after_writing and not notify_writable? @sslsock.flush close_connection end end |
#post_init ⇒ Object
Note that post_init dos not have access to the sslsocket. The sslsocket is not added until tls_begin is called, after the code block.
#post_init gives you a chance to manipulate the SSLContext.
215 216 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 215 def post_init end |
#receive_data(data) ⇒ Object
Override this to do something with the unecrypted data.
235 236 237 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 235 def receive_data(data) logdebug "receive_data:", :data => data end |
#send_data(data) ⇒ Object
Call this to send data to the other end of the connection.
187 188 189 190 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 187 def send_data(data) logdebug "send_data:", :data => data attempt_write(data) end |
#tls_begin ⇒ Object
(SSLClient only) If @sni_hostname exists on the handler at this
Creates sslsocket from tcpsocket and ctx, and initializes the handler’s internal state. Called from the class method that creates the object, after post_init and the optional code block.
point, it will be added to the SSLSocket in order to enable sending a hostname in the SNI TLS extension.
46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 46 def tls_begin logdebug "tls begin", :sni_hostname => @sni_hostname @sslsocket = OpenSSL::SSL::SSLSocket.new(@tcpsocket, @ctx) if @sni_hostname if @sslsocket.respond_to? :hostname @sslsocket.hostname = @sni_hostname else logwarn "#{@sslsocket.class} does not support setting an SNI hostname! This requires Ruby 1.9.x built against OpenSSL with SNI support.", :ruby_version => RUBY_VERSION end end @state = :initialized end |
#tls_failed_handshake(e) ⇒ Object
Called right after accept_nonblock fails for some unknown reason. The only parameter contains the OpenSSL::SSL::SSLError object that was thrown.
The connection will be closed after this.
230 231 232 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 230 def tls_failed_handshake(e) logerror "tls_failed_handshake: Failed to accept: #{e} (#{e.class})" end |
#tls_successful_handshake ⇒ Object
Called right after the SSL handshake succeeds. This is your “new” #post_init.
221 222 223 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 221 def tls_successful_handshake logdebug "Succesful handshake!" end |
#unbind ⇒ Object
Override this to do something when the socket is finished.
240 241 242 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 240 def unbind logdebug "unbind" end |
#write_buffer ⇒ Object
142 143 144 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 142 def write_buffer @write_buffer ||= "" end |
#write_buffer=(rhs) ⇒ Object
147 148 149 |
# File 'lib/packetthief/handlers/abstract_ssl_handler.rb', line 147 def write_buffer=(rhs) @write_buffer = rhs end |