Class Net::SSH::Proxy::SOCKS5

  1. 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

public class

  1. new

public instance

  1. 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.

Attributes

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

Public class methods

new (proxy_host, proxy_port=1080, options={})

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.

[show source]
    # 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)

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

[show source]
     # 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