Provides a transparent proxy for any TCP connection.
An internal buffer of packet data received from the client. It will grow until the destination connection connects.
This holds a reference to the connection to the client. It is actually self.
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.
This holds a reference to the connection to the destination. If it is null, it hasn’t been created yet.
The SSLContext that will be used on the connection to the destination. Initially, its verify_mode is set to OpenSSL::SSL::VERIFY_NONE.
Override these before connecting to dest to change the dest connection.
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.
Override these before connecting to dest to change the dest connection.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 86 def initialize(tcpsocket, logger=nil) 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
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 138 def _send_buffer @buffer.each do |pkt| @dest.send_data pkt end @buffer = [] end
Called when the client connection closes. At present, it only provides informational utility.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 196 def client_closed end
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.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 177 def client_connected connect_to_dest end
This method is called when the TLS handshake between the client and the proxy fails. It does nothing by default.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 183 def client_handshake_failed end
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.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 190 def client_recv(data) send_to_dest data end
Initiate the connection to @#dest_host:@dest_port.
# 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
Returns the certificate chain for the destination, or nil if the destination connection does not exist yet.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 160 def dest_cert_chain return @dest.sslsocket.peer_cert_chain if @dest nil end
Called when the original destination connection closes. At present, it only provides informational utility.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 219 def dest_closed end
Called when the connection to and the TLS handshake between the proxy and the destination succeeds. The default behavior does nothing.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 201 def dest_connected end
Called when the TLS handshake between the proxy and the destination fails.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 206 def dest_handshake_failed(e) end
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.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 213 def dest_recv(data) send_to_client data end
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 115 def receive_data(data) client_recv data end
Sends data back to the client
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 154 def send_to_client(data) send_data data end
Queues up data to send to the remote host, only sending it if the connection to the remote host exists.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 148 def send_to_dest(data) @buffer << data _send_buffer if @dest end
Set #dest_hostname in addition to the default behavior.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 168 def servername_cb(sslsock, hostname) @dest_hostname = hostname super(sslsock, hostname) end
Just calls #client_connected to keep things straightforward.
# File lib/packetthief/handlers/ssl_transparent_proxy.rb, line 111 def tls_successful_handshake client_connected end
Start the closing process and close the other connection if it is not already closing.
# 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