Class: PacketThief::Handlers::SSLTransparentProxy
- Inherits:
-
SSLServer
- Object
- EM::Connection
- AbstractSSLHandler
- SSLServer
- PacketThief::Handlers::SSLTransparentProxy
- Defined in:
- lib/packetthief/handlers/ssl_transparent_proxy.rb
Overview
Provides a transparent proxy for any TCP connection.
Direct Known Subclasses
Defined Under Namespace
Classes: SSLProxyConnection
Instance Attribute Summary collapse
-
#buffer ⇒ Object
An internal buffer of packet data received from the client.
-
#client ⇒ Object
This holds a reference to the connection to the client.
-
#client_host ⇒ Object
readonly
Returns the value of attribute client_host.
-
#client_port ⇒ Object
readonly
Returns the value of attribute client_port.
-
#closed ⇒ Object
Boolean that represents whether this handler has started to close/unbind.
-
#dest ⇒ Object
This holds a reference to the connection to the destination.
-
#dest_ctx ⇒ Object
The SSLContext that will be used on the connection to the destination.
-
#dest_host ⇒ Object
Override these before connecting to dest to change the dest connection.
-
#dest_hostname ⇒ Object
If a client specifies a TLS hostname extension (SNI) as the hostname, then we can forward that fact on to the real server.
-
#dest_port ⇒ Object
Override these before connecting to dest to change the dest connection.
Attributes inherited from SSLServer
Attributes inherited from AbstractSSLHandler
#ctx, #sni_hostname, #sslsocket, #tcpsocket
Instance Method Summary collapse
- #_send_buffer ⇒ Object
-
#client_closed ⇒ Object
Called when the client connection closes.
-
#client_connected ⇒ Object
This method is called when a client connects, and the TLS handhsake has completed.
-
#client_handshake_failed ⇒ Object
This method is called when the TLS handshake between the client and the proxy fails.
-
#client_recv(data) ⇒ Object
This method is called when the proxy receives data from the client connection.
-
#connect_to_dest ⇒ Object
Initiate the connection to @dest_host:@dest_port.
-
#dest_cert_chain ⇒ Object
Returns the certificate chain for the destination, or nil if the destination connection does not exist yet.
-
#dest_closed ⇒ Object
Called when the original destination connection closes.
-
#dest_connected ⇒ Object
Called when the connection to and the TLS handshake between the proxy and the destination succeeds.
-
#dest_handshake_failed(e) ⇒ Object
Called when the TLS handshake between the proxy and the destination fails.
-
#dest_recv(data) ⇒ Object
Called when the proxy receives data from the destination connection.
-
#initialize(tcpsocket) ⇒ SSLTransparentProxy
constructor
A new instance of SSLTransparentProxy.
- #receive_data(data) ⇒ Object
-
#send_to_client(data) ⇒ Object
Sends data back to the client.
-
#send_to_dest(data) ⇒ Object
Queues up data to send to the remote host, only sending it if the connection to the remote host exists.
-
#servername_cb(sslsock, hostname) ⇒ Object
Set dest_hostname in addition to the default behavior.
-
#tls_successful_handshake ⇒ Object
Just calls client_connected to keep things straightforward.
-
#unbind ⇒ Object
Start the closing process and close the other connection if it is not already closing.
Methods inherited from SSLServer
Methods inherited from AbstractSSLHandler
#close_connection, #close_connection_after_writing, #notify_readable, #notify_writable, #post_init, #send_data, #tls_begin, #tls_failed_handshake, #write_buffer, #write_buffer=
Methods included from Logging
Constructor Details
#initialize(tcpsocket) ⇒ SSLTransparentProxy
Returns a new instance of SSLTransparentProxy.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 86 def initialize(tcpsocket) super @closed = false @client = self @dest = nil @buffer = [] @@activeconns ||= {} @client_port, @client_host = Socket.unpack_sockaddr_in(get_peername) @dest_port, @dest_host = PacketThief.original_dest(self) if @@activeconns.has_key? "#{client_host}:#{client_port}" logwarn "loop detected! Stopping the loop." close_connection return end @dest_ctx = OpenSSL::SSL::SSLContext.new @dest_ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE end |
Instance Attribute Details
#buffer ⇒ Object
An internal buffer of packet data received from the client. It will grow until the destination connection connects.
70 71 72 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 70 def buffer @buffer end |
#client ⇒ Object
This holds a reference to the connection to the client. It is actually self.
61 62 63 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 61 def client @client end |
#client_host ⇒ Object (readonly)
Returns the value of attribute client_host.
63 64 65 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 63 def client_host @client_host end |
#client_port ⇒ Object (readonly)
Returns the value of attribute client_port.
63 64 65 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 63 def client_port @client_port end |
#closed ⇒ Object
Boolean that represents whether this handler has started to close/unbind. Used to ensure there is no unbind-loop between the two connections that make up the proxy.
75 76 77 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 75 def closed @closed end |
#dest ⇒ Object
This holds a reference to the connection to the destination. If it is null, it hasn’t been created yet.
57 58 59 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 57 def dest @dest end |
#dest_ctx ⇒ Object
The SSLContext that will be used on the connection to the destination. Initially, its verify_mode is set to OpenSSL::SSL::VERIFY_NONE.
84 85 86 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 84 def dest_ctx @dest_ctx end |
#dest_host ⇒ Object
Override these before connecting to dest to change the dest connection.
66 67 68 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 66 def dest_host @dest_host end |
#dest_hostname ⇒ Object
If a client specifies a TLS hostname extension (SNI) as the hostname, then we can forward that fact on to the real server. We can also use it to choose a certificate to present.
80 81 82 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 80 def dest_hostname @dest_hostname end |
#dest_port ⇒ Object
Override these before connecting to dest to change the dest connection.
66 67 68 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 66 def dest_port @dest_port end |
Instance Method Details
#_send_buffer ⇒ Object
138 139 140 141 142 143 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 138 def _send_buffer @buffer.each do |pkt| @dest.send_data pkt end @buffer = [] end |
#client_closed ⇒ Object
Called when the client connection closes. At present, it only provides informational utility.
196 197 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 196 def client_closed end |
#client_connected ⇒ Object
This method is called when a client connects, and the TLS handhsake has completed. The default behavior is to begin initating the connection to the original destination. Override this method to change its behavior.
177 178 179 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 177 def client_connected connect_to_dest end |
#client_handshake_failed ⇒ Object
This method is called when the TLS handshake between the client and the proxy fails. It does nothing by default.
183 184 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 183 def client_handshake_failed end |
#client_recv(data) ⇒ Object
This method is called when the proxy receives data from the client connection. The default behavior is to call send_to_dest(data) in order to foward the data on to the original destination. Override this method to analyze the data, or modify it before sending it on.
190 191 192 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 190 def client_recv(data) send_to_dest data end |
#connect_to_dest ⇒ Object
Initiate the connection to @dest_host:@dest_port.
130 131 132 133 134 135 136 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 130 def connect_to_dest return if @dest @dest = SSLProxyConnection.connect(@dest_host, @dest_port, self, @dest_ctx) newport, newhost = Socket::unpack_sockaddr_in(@dest.get_sockname) # Add the new connection to the list to prevent loops. @@activeconns["#{newhost}:#{newport}"] = "#{dest_host}:#{dest_port}" end |
#dest_cert_chain ⇒ Object
Returns the certificate chain for the destination, or nil if the destination connection does not exist yet.
160 161 162 163 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 160 def dest_cert_chain return @dest.sslsocket.peer_cert_chain if @dest nil end |
#dest_closed ⇒ Object
Called when the original destination connection closes. At present, it only provides informational utility.
219 220 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 219 def dest_closed end |
#dest_connected ⇒ Object
Called when the connection to and the TLS handshake between the proxy and the destination succeeds. The default behavior does nothing.
201 202 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 201 def dest_connected end |
#dest_handshake_failed(e) ⇒ Object
Called when the TLS handshake between the proxy and the destination fails.
206 207 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 206 def dest_handshake_failed(e) end |
#dest_recv(data) ⇒ Object
Called when the proxy receives data from the destination connection. The default behavior calls #dest_recv() to send the data to the client.
Override it to analyze or modify the data.
213 214 215 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 213 def dest_recv(data) send_to_client data end |
#receive_data(data) ⇒ Object
115 116 117 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 115 def receive_data(data) client_recv data end |
#send_to_client(data) ⇒ Object
Sends data back to the client
154 155 156 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 154 def send_to_client(data) send_data data end |
#send_to_dest(data) ⇒ Object
Queues up data to send to the remote host, only sending it if the connection to the remote host exists.
148 149 150 151 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 148 def send_to_dest(data) @buffer << data _send_buffer if @dest end |
#servername_cb(sslsock, hostname) ⇒ Object
Set dest_hostname in addition to the default behavior.
168 169 170 171 172 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 168 def servername_cb(sslsock, hostname) @dest_hostname = hostname super(sslsock, hostname) end |
#tls_successful_handshake ⇒ Object
Just calls client_connected to keep things straightforward.
111 112 113 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 111 def tls_successful_handshake client_connected end |
#unbind ⇒ Object
Start the closing process and close the other connection if it is not already closing.
121 122 123 124 125 126 127 |
# File 'lib/packetthief/handlers/ssl_transparent_proxy.rb', line 121 def unbind client_closed @@activeconns.delete "#{client_host}:#{client_port}" self.closed = true # @dest.client = nil if @dest @dest.close_connection_after_writing if @dest and not @dest.closed end |