Created
April 26, 2014 03:22
-
-
Save shurikk/11310927 to your computer and use it in GitHub Desktop.
TCPSocket proxy monkey patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Usage: | |
# | |
# TCPSocket.socks_server = "socks-proxy.example.net" | |
# TCPSocket.socks_port = 8888 | |
require 'socket' | |
class TCPSocket | |
alias :direct_to :initialize | |
class << self | |
attr_accessor :socks_server, :socks_port | |
end | |
def initialize(host, port, local_host = nil, local_port = nil) | |
socks_server = self.class.socks_server | |
socks_port = self.class.socks_port | |
if socks_server && socks_port | |
direct socks_server, socks_port | |
authenticate | |
proxy_to(host, port) | |
else | |
direct_to host, port, local_host, local_port | |
end | |
end | |
def authenticate | |
# no authentication | |
write "\005\001\000" | |
recv(2) | |
end | |
def proxy_to(host, port) | |
["\005", "\001", "\000"].map {|b| write b } | |
if host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ | |
write "\001" | |
write [$1.to_i, $2.to_i, $3.to_i, $4.to_i].pack("CCCC") | |
elsif host =~ /^[:0-9a-f]+$/ | |
raise "TCP/IPv6 is not supported via SOCKS" | |
else | |
write "\003" + [host.size].pack("C") + host | |
end | |
write [port].pack('n') | |
receive_via_proxy | |
end | |
def receive_via_proxy | |
reply = recv(4) | |
raise "SOCKS version #{reply[0..0]} is not supported" if reply[0..0] != "\005" | |
raise "SOCKS error: #{reply.bytes.to_a.inspect}" if reply[1..1] != "\000" | |
bind_addr_len = case reply[3..3] | |
when "\001" | |
4 | |
when "\003" | |
recv(1).bytes.first | |
when "\004" | |
16 | |
else | |
raise "SOCKS error: #{reply.bytes.to_a.inspect}" | |
end | |
bind_addr_s = recv(bind_addr_len) | |
bind_addr = case reply[3..3] | |
when "\001" | |
bind_addr_s.bytes.to_a.join(".") | |
when "\003" | |
bind_addr_s | |
end | |
[bind_addr, recv(bind_addr_len + 2).unpack("n")] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment