Class Net::SSH::Proxy::SOCKS5
In: lib/net/ssh/proxy/socks5.rb
lib/net/ssh/proxy/socks5.rb
Parent: Object

An implementation of a SOCKS5 proxy. To use it, instantiate it, then pass the instantiated object via the :proxy key to Net::SSH.start:

  require 'net/ssh/proxy/socks5'

  proxy = Net::SSH::Proxy::SOCKS5.new('proxy.host', proxy_port,
    :user => 'user', :password => "password")
  Net::SSH.start('host', 'user', :proxy => proxy) do |ssh|
    ...
  end

Methods

new   new   open   open  

Constants

VERSION = 5   The SOCKS protocol version used by this class
METHOD_NO_AUTH = 0   The SOCKS authentication type for requests without authentication
METHOD_PASSWD = 2   The SOCKS authentication type for requests via username/password
METHOD_NONE = 0xFF   The SOCKS authentication type for when there are no supported authentication methods.
CMD_CONNECT = 1   The SOCKS packet type for requesting a proxy connection.
ATYP_IPV4 = 1   The SOCKS address type for connections via IP address.
ATYP_DOMAIN = 3   The SOCKS address type for connections via domain name.
SUCCESS = 0   The SOCKS response code for a successful operation.
VERSION = 5   The SOCKS protocol version used by this class
METHOD_NO_AUTH = 0   The SOCKS authentication type for requests without authentication
METHOD_PASSWD = 2   The SOCKS authentication type for requests via username/password
METHOD_NONE = 0xFF   The SOCKS authentication type for when there are no supported authentication methods.
CMD_CONNECT = 1   The SOCKS packet type for requesting a proxy connection.
ATYP_IPV4 = 1   The SOCKS address type for connections via IP address.
ATYP_DOMAIN = 3   The SOCKS address type for connections via domain name.
SUCCESS = 0   The SOCKS response code for a successful operation.

Attributes

options  [R]  The map of options given at initialization
options  [R]  The map of options given at initialization
proxy_host  [R]  The proxy‘s host name or IP address
proxy_host  [R]  The proxy‘s host name or IP address
proxy_port  [R]  The proxy‘s port number
proxy_port  [R]  The proxy‘s port number

Public Class methods

Create a new proxy connection to the given proxy host and port. Optionally, :user and :password options may be given to identify the username and password with which to authenticate.

[Source]

    # File lib/net/ssh/proxy/socks5.rb, line 56
56:         def initialize(proxy_host, proxy_port=1080, options={})
57:           @proxy_host = proxy_host
58:           @proxy_port = proxy_port
59:           @options = options
60:         end

Create a new proxy connection to the given proxy host and port. Optionally, :user and :password options may be given to identify the username and password with which to authenticate.

[Source]

    # File lib/net/ssh/proxy/socks5.rb, line 56
56:         def initialize(proxy_host, proxy_port=1080, options={})
57:           @proxy_host = proxy_host
58:           @proxy_port = proxy_port
59:           @options = options
60:         end

Public Instance methods

Return a new socket connected to the given host and port via the proxy that was requested when the socket factory was instantiated.

[Source]

     # File lib/net/ssh/proxy/socks5.rb, line 64
 64:         def open(host, port)
 65:           socket = TCPSocket.new(proxy_host, proxy_port)
 66: 
 67:           methods = [METHOD_NO_AUTH]
 68:           methods << METHOD_PASSWD if options[:user]
 69: 
 70:           packet = [VERSION, methods.size, *methods].pack("C*")
 71:           socket.send packet, 0
 72: 
 73:           version, method = socket.recv(2).unpack("CC")
 74:           if version != VERSION
 75:             socket.close
 76:             raise Net::SSH::Proxy::Error, "invalid SOCKS version (#{version})"
 77:           end
 78: 
 79:           if method == METHOD_NONE
 80:             socket.close
 81:             raise Net::SSH::Proxy::Error, "no supported authorization methods"
 82:           end
 83: 
 84:           negotiate_password(socket) if method == METHOD_PASSWD
 85: 
 86:           packet = [VERSION, CMD_CONNECT, 0].pack("C*")
 87: 
 88:           if host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
 89:             packet << [ATYP_IPV4, $1.to_i, $2.to_i, $3.to_i, $4.to_i].pack("C*")
 90:           else
 91:             packet << [ATYP_DOMAIN, host.length, host].pack("CCA*")
 92:           end
 93: 
 94:           packet << [port].pack("n")
 95:           socket.send packet, 0
 96: 
 97:           version, reply, = socket.recv(4).unpack("C*")
 98:           len = socket.recv(1)[0]
 99:           socket.recv(len + 2)
100: 
101:           unless reply == SUCCESS
102:             socket.close
103:             raise ConnectError, "#{reply}"
104:           end
105: 
106:           return socket
107:         end

Return a new socket connected to the given host and port via the proxy that was requested when the socket factory was instantiated.

[Source]

     # File lib/net/ssh/proxy/socks5.rb, line 64
 64:         def open(host, port)
 65:           socket = TCPSocket.new(proxy_host, proxy_port)
 66: 
 67:           methods = [METHOD_NO_AUTH]
 68:           methods << METHOD_PASSWD if options[:user]
 69: 
 70:           packet = [VERSION, methods.size, *methods].pack("C*")
 71:           socket.send packet, 0
 72: 
 73:           version, method = socket.recv(2).unpack("CC")
 74:           if version != VERSION
 75:             socket.close
 76:             raise Net::SSH::Proxy::Error, "invalid SOCKS version (#{version})"
 77:           end
 78: 
 79:           if method == METHOD_NONE
 80:             socket.close
 81:             raise Net::SSH::Proxy::Error, "no supported authorization methods"
 82:           end
 83: 
 84:           negotiate_password(socket) if method == METHOD_PASSWD
 85: 
 86:           packet = [VERSION, CMD_CONNECT, 0].pack("C*")
 87: 
 88:           if host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
 89:             packet << [ATYP_IPV4, $1.to_i, $2.to_i, $3.to_i, $4.to_i].pack("C*")
 90:           else
 91:             packet << [ATYP_DOMAIN, host.length, host].pack("CCA*")
 92:           end
 93: 
 94:           packet << [port].pack("n")
 95:           socket.send packet, 0
 96: 
 97:           version, reply, = socket.recv(4).unpack("C*")
 98:           len = socket.recv(1)[0]
 99:           socket.recv(len + 2)
100: 
101:           unless reply == SUCCESS
102:             socket.close
103:             raise ConnectError, "#{reply}"
104:           end
105: 
106:           return socket
107:         end

[Validate]