Permalink
Browse files

code cleanup

  • Loading branch information...
1 parent 094fc82 commit 3dbd7fd5969425c3b6a34b5a92be78f57fbffa30 @igrigorik committed Oct 15, 2011
Showing with 149 additions and 148 deletions.
  1. +31 −29 lib/em-socksify/errors.rb
  2. +86 −80 lib/em-socksify/socks5.rb
  3. +31 −38 lib/em-socksify/socksify.rb
  4. +1 −1 spec/socksify_spec.rb
@@ -1,36 +1,38 @@
-module EventMachine; module Socksify
+module EventMachine
+ module Socksify
-class SOCKSError < Exception
- def self.define (message)
- Class.new(self) {
- def initialize
- super(message)
+ class SOCKSError < Exception
+ def self.define (message)
+ Class.new(self) do
+ def initialize
+ super(message)
+ end
+ end
end
- }
- end
- ServerFailure = define('general SOCKS server failure')
- NotAllowed = define('connection not allowed by ruleset')
- NetworkUnreachable = define('Network unreachable')
- HostUnreachable = define('Host unreachable')
- ConnectionRefused = define('Connection refused')
- TTLExpired = define('TTL expired')
- CommandNotSupported = define('Command not supported')
- AddressTypeNotSupported = define('Address type not supported')
+ ServerFailure = define('general SOCKS server failure')
+ NotAllowed = define('connection not allowed by ruleset')
+ NetworkUnreachable = define('Network unreachable')
+ HostUnreachable = define('Host unreachable')
+ ConnectionRefused = define('Connection refused')
+ TTLExpired = define('TTL expired')
+ CommandNotSupported = define('Command not supported')
+ AddressTypeNotSupported = define('Address type not supported')
- def self.for_response_code(code)
- case code.is_a?(String) ? code.ord : code
- when 1 then ServerFailure
- when 2 then NotAllowed
- when 3 then NetworkUnreachable
- when 4 then HostUnreachable
- when 5 then ConnectionRefused
- when 6 then TTLExpired
- when 7 then CommandNotSupported
- when 8 then AddressTypeNotSupported
- else self
+ def self.for_response_code(code)
+ case code.is_a?(String) ? code.ord : code
+ when 1 then ServerFailure
+ when 2 then NotAllowed
+ when 3 then NetworkUnreachable
+ when 4 then HostUnreachable
+ when 5 then ConnectionRefused
+ when 6 then TTLExpired
+ when 7 then CommandNotSupported
+ when 8 then AddressTypeNotSupported
+ else self
+ end
+ end
end
+
end
end
-
-end; end
@@ -1,109 +1,115 @@
-module EventMachine; module Socksify
+module EventMachine
+ module Socksify
-module SOCKS5
- def socks_send_handshake
- # Method Negotiation as described on
- # http://www.faqs.org/rfcs/rfc1928.html Section 3
- @socks_state = :method_negotiation
+ module SOCKS5
+ def socks_send_handshake
+ # Method Negotiation as described on
+ # http://www.faqs.org/rfcs/rfc1928.html Section 3
+ @socks_state = :method_negotiation
- socks_methods.tap {|methods|
- send_data [5, methods.size].pack('CC') + methods.pack('C*')
- }
- end
+ socks_methods.tap do |methods|
+ send_data [5, methods.size].pack('CC') + methods.pack('C*')
+ end
+ end
- def socks_send_connect_request
- @socks_state = :connecting
+ def socks_send_connect_request
+ @socks_state = :connecting
- send_data [5, 1, 0].pack('CCC')
+ send_data [5, 1, 0].pack('CCC')
- if matches = @socks_target_host.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
- send_data "\xF1\x00\x01" + matches.to_a[1 .. -1].map { |s| s.to_i }.pack('CCCC')
- elsif @socks_target_host =~ /^[:0-9a-f]+$/
- raise SOCKSError, 'TCP/IPv6 over SOCKS is not yet supported (inet_pton missing in Ruby & not supported by Tor'
- else
- send_data [3, @socks_target_host.size, @socks_target_host].pack('CCA*')
- end
+ if matches = @socks_target_host.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
+ send_data "\xF1\x00\x01" + matches.to_a[1 .. -1].map { |s| s.to_i }.pack('CCCC')
- send_data [@socks_target_port].pack('n')
- end
+ elsif @socks_target_host =~ /^[:0-9a-f]+$/
+ raise SOCKSError, 'TCP/IPv6 over SOCKS is not yet supported (inet_pton missing in Ruby & not supported by Tor)'
- def socks_send_authentication
- @socks_state = :authenticating
+ else
+ send_data [3, @socks_target_host.size, @socks_target_host].pack('CCA*')
+ end
- send_data [5,
- @socks_username.length, @socks_username,
- @socks_password.length, @socks_password
- ].pack('CCA*CA*')
- end
+ send_data [@socks_target_port].pack('n')
+ end
- private
+ def socks_send_authentication
+ @socks_state = :authenticating
- # parses socks 5 server responses as specified
- # on http://www.faqs.org/rfcs/rfc1928.html
- def socks_parse_response
- case @socks_state
- when :method_negotiation
- return unless @socks_data.size >= 2
+ send_data [5,
+ @socks_username.length, @socks_username,
+ @socks_password.length, @socks_password
+ ].pack('CCA*CA*')
+ end
- _, method = @socks_data.slice!(0, 2).unpack('CC')
+ private
- if socks_methods.include?(method)
- case method
- when 0 then socks_send_connect_request
- when 2 then socks_send_authentication
- end
- else
- raise SOCKSError, 'proxy did not accept method'
- end
+ # parses socks 5 server responses as specified
+ # on http://www.faqs.org/rfcs/rfc1928.html
+ def socks_parse_response
+ case @socks_state
+ when :method_negotiation
+ return unless @socks_data.size >= 2
- when :authenticating
- return unless @socks_data.size >= 2
+ _, method = @socks_data.slice!(0, 2).unpack('CC')
- socks_version, status_code = @socks_data.slice!(0, 2).unpack('CC')
+ if socks_methods.include?(method)
+ case method
+ when 0 then socks_send_connect_request
+ when 2 then socks_send_authentication
+ end
+ else
+ raise SOCKSError, 'proxy did not accept method'
+ end
- raise SOCKSError, "SOCKS version 5 not supported" unless socks_version == 5
- raise SOCKSError, 'access denied by proxy' unless status_code == 0
+ when :authenticating
+ return unless @socks_data.size >= 2
- send_socks_connect_request
+ socks_version, status_code = @socks_data.slice!(0, 2).unpack('CC')
- when :connecting
- return unless @socks_data.size >= 2
+ raise SOCKSError, "SOCKS version 5 not supported" unless socks_version == 5
+ raise SOCKSError, 'access denied by proxy' unless status_code == 0
- socks_version, status_code = @socks_data.slice(0, 2).unpack('CC')
+ send_socks_connect_request
- raise SOCKSError, "SOCKS version #{socks_version} is not 5" unless socks_version == 5
- raise SOCKSError.for_response_code(status_code) unless status_code == 0
+ when :connecting
+ return unless @socks_data.size >= 2
- min_size = @socks_data[3].ord == 3 ? 5 : 4
+ socks_version, status_code = @socks_data.slice(0, 2).unpack('CC')
- return unless @socks_data.size >= min_size
+ raise SOCKSError, "SOCKS version #{socks_version} is not 5" unless socks_version == 5
+ raise SOCKSError.for_response_code(status_code) unless status_code == 0
- size = case @socks_data[3].ord
- when 1 then 4
- when 3 then @socks_data[4].ord
- when 4 then 16
- else raise SOCKSError.for_response_code(@socks_data[3])
- end
+ min_size = @socks_data[3].ord == 3 ? 5 : 4
- return unless @socks_data.size >= min_size + size
+ return unless @socks_data.size >= min_size
- bind_addr = @socks_data.slice(min_size, size)
+ size = case @socks_data[3].ord
+ when 1 then 4
+ when 3 then @socks_data[4].ord
+ when 4 then 16
+ else raise SOCKSError.for_response_code(@socks_data[3])
+ end
- socks_unhook(case @socks_data[3].ord
- when 1 then bind_addr.bytes.to_a.join('.')
- when 3 then bind_addr
- when 4 then # TODO: yeah, I'm a lazy italian
- end)
- end
- end
+ return unless @socks_data.size >= (min_size + size)
- def socks_methods
- methods = []
- methods << 2 if !@socks_username.nil? # 2 => Username/Password Authentication
- methods << 0 # 0 => No Authentication Required
+ bind_addr = @socks_data.slice(min_size, size)
+
+ ip = case @socks_data[3].ord
+ when 1 then bind_addr.bytes.to_a.join('.')
+ when 3 then bind_addr
+ when 4 then # TODO: ???
+ end
+
+ socks_unhook(ip)
+ end
+ end
+
+ def socks_methods
+ methods = []
+ methods << 2 if !@socks_username.nil? # 2 => Username/Password Authentication
+ methods << 0 # 0 => No Authentication Required
+
+ methods
+ end
+ end
- methods
end
end
-
-end; end
@@ -1,50 +1,43 @@
module EventMachine
-module Socksify
- def socksify(host, port, username = nil, password = nil, version = 5, &blk)
- @socks_target_host = host
- @socks_target_port = port
- @socks_username = username
- @socks_password = password
- @socks_version = version
- @socks_callback = blk
- @socks_data = ''
-
- socks_hook
- socks_send_handshake
- end
-
- def socks_hook
- if @socks_version == 5
- extend SOCKS5
- else
- raise ArgumentError, 'SOCKS version unsupported'
+ module Socksify
+ def socksify(host, port, username = nil, password = nil, version = 5, &blk)
+ @socks_target_host = host
+ @socks_target_port = port
+ @socks_username = username
+ @socks_password = password
+ @socks_version = version
+ @socks_callback = blk
+ @socks_data = ''
+
+ socks_hook
+ socks_send_handshake
end
- class << self
- alias receive_data socks_receive_data
- end
- end
+ def socks_hook
+ if @socks_version == 5
+ extend SOCKS5
+ else
+ raise ArgumentError, 'SOCKS version unsupported'
+ end
- def socks_unhook(ip = nil)
- class << self
- remove_method :receive_data
+ class << self
+ alias receive_data socks_receive_data
+ end
end
- callback = @socks_callback
-
- instance_variables.each {|name|
- remove_instance_variable name if name.to_s.start_with?('@socks_')
- }
+ def socks_unhook(ip = nil)
+ class << self
+ remove_method :receive_data
+ end
- callback.call(ip)
- end
-
- def socks_receive_data(data)
- @socks_data << data
+ @socks_callback.call(ip)
+ end
- socks_parse_response
+ def socks_receive_data(data)
+ @socks_data << data
+ socks_parse_response
+ end
end
-end
end
@@ -8,7 +8,7 @@ class Handler < EM::Connection
include EM::Socksify
def connection_completed
- socksify('google.ca', 80) do
+ socksify('google.ca', 80) do |ip|
send_data "GET / HTTP/1.1\r\nConnection:close\r\nHost: google.ca\r\n\r\n"
end
end

0 comments on commit 3dbd7fd

Please sign in to comment.