| 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
| 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. |
| 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 |
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
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
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(4).unpack("C*")
99: len = socket.recv(1).getbyte(0)
100: socket.recv(len + 2)
101:
102: unless reply == SUCCESS
103: socket.close
104: raise ConnectError, "#{reply}"
105: end
106:
107: return socket
108: 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 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(4).unpack("C*")
99: len = socket.recv(1).getbyte(0)
100: socket.recv(len + 2)
101:
102: unless reply == SUCCESS
103: socket.close
104: raise ConnectError, "#{reply}"
105: end
106:
107: return socket
108: end