Parent

Class Index [+]

Quicksearch

Net::SSH::Proxy::SOCKS5

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

Constants

VERSION

The SOCKS protocol version used by this class

METHOD_NO_AUTH

The SOCKS authentication type for requests without authentication

METHOD_PASSWD

The SOCKS authentication type for requests via username/password

METHOD_NONE

The SOCKS authentication type for when there are no supported authentication methods.

CMD_CONNECT

The SOCKS packet type for requesting a proxy connection.

ATYP_IPV4

The SOCKS address type for connections via IP address.

ATYP_DOMAIN

The SOCKS address type for connections via domain name.

SUCCESS

The SOCKS response code for a successful operation.

Attributes

proxy_host[R]

The proxy’s host name or IP address

proxy_port[R]

The proxy’s port number

options[R]

The map of options given at initialization

Public Class Methods

new(proxy_host, proxy_port=1080, options={}) click to toggle source

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.

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

Public Instance Methods

open(host, port) click to toggle source

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

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

Private Instance Methods

negotiate_password(socket) click to toggle source

Simple username/password negotiation with the SOCKS5 server.

     # File lib/net/ssh/proxy/socks5.rb, line 126
126:           def negotiate_password(socket)
127:             packet = [0x01, options[:user].length, options[:user],
128:               options[:password].length, options[:password]].pack("CCA*CA*")
129:             socket.send packet, 0
130: 
131:             version, status = socket.recv(2).unpack("CC")
132: 
133:             if status != SUCCESS
134:               socket.close
135:               raise UnauthorizedError, "could not authorize user"
136:             end
137:           end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.