| Class | Net::SSH::Proxy::SOCKS5 |
| In: |
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
| 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. |
| 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 |
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 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
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 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