net-ssh 4.2.0 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/.dockerignore +6 -0
- data/.github/config/rubocop_linter_action.yml +4 -0
- data/.github/workflows/ci-with-docker.yml +44 -0
- data/.github/workflows/ci.yml +87 -0
- data/.github/workflows/rubocop.yml +13 -0
- data/.gitignore +7 -0
- data/.rubocop.yml +19 -2
- data/.rubocop_todo.yml +619 -667
- data/CHANGES.txt +110 -1
- data/Dockerfile +27 -0
- data/Dockerfile.openssl3 +17 -0
- data/Gemfile +3 -7
- data/{Gemfile.norbnacl → Gemfile.noed25519} +3 -1
- data/Manifest +4 -5
- data/README.md +293 -0
- data/Rakefile +45 -29
- data/appveyor.yml +8 -6
- data/docker-compose.yml +23 -0
- data/lib/net/ssh/authentication/agent.rb +248 -223
- data/lib/net/ssh/authentication/certificate.rb +178 -164
- data/lib/net/ssh/authentication/constants.rb +17 -15
- data/lib/net/ssh/authentication/ed25519.rb +141 -116
- data/lib/net/ssh/authentication/ed25519_loader.rb +28 -28
- data/lib/net/ssh/authentication/key_manager.rb +79 -36
- data/lib/net/ssh/authentication/methods/abstract.rb +62 -47
- data/lib/net/ssh/authentication/methods/hostbased.rb +34 -37
- data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +3 -3
- data/lib/net/ssh/authentication/methods/none.rb +16 -19
- data/lib/net/ssh/authentication/methods/password.rb +15 -16
- data/lib/net/ssh/authentication/methods/publickey.rb +96 -55
- data/lib/net/ssh/authentication/pageant.rb +468 -465
- data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
- data/lib/net/ssh/authentication/session.rb +131 -122
- data/lib/net/ssh/buffer.rb +385 -332
- data/lib/net/ssh/buffered_io.rb +150 -151
- data/lib/net/ssh/config.rb +316 -239
- data/lib/net/ssh/connection/channel.rb +635 -613
- data/lib/net/ssh/connection/constants.rb +29 -29
- data/lib/net/ssh/connection/event_loop.rb +104 -95
- data/lib/net/ssh/connection/keepalive.rb +55 -51
- data/lib/net/ssh/connection/session.rb +614 -611
- data/lib/net/ssh/connection/term.rb +125 -123
- data/lib/net/ssh/errors.rb +101 -99
- data/lib/net/ssh/key_factory.rb +194 -108
- data/lib/net/ssh/known_hosts.rb +212 -134
- data/lib/net/ssh/loggable.rb +50 -49
- data/lib/net/ssh/packet.rb +83 -79
- data/lib/net/ssh/prompt.rb +51 -51
- data/lib/net/ssh/proxy/command.rb +105 -91
- data/lib/net/ssh/proxy/errors.rb +12 -10
- data/lib/net/ssh/proxy/http.rb +81 -81
- data/lib/net/ssh/proxy/https.rb +37 -36
- data/lib/net/ssh/proxy/jump.rb +49 -48
- data/lib/net/ssh/proxy/socks4.rb +2 -6
- data/lib/net/ssh/proxy/socks5.rb +14 -17
- data/lib/net/ssh/service/forward.rb +365 -362
- data/lib/net/ssh/test/channel.rb +145 -143
- data/lib/net/ssh/test/extensions.rb +131 -127
- data/lib/net/ssh/test/kex.rb +34 -32
- data/lib/net/ssh/test/local_packet.rb +46 -44
- data/lib/net/ssh/test/packet.rb +87 -84
- data/lib/net/ssh/test/remote_packet.rb +32 -30
- data/lib/net/ssh/test/script.rb +155 -155
- data/lib/net/ssh/test/socket.rb +49 -48
- data/lib/net/ssh/test.rb +82 -80
- data/lib/net/ssh/transport/algorithms.rb +433 -364
- data/lib/net/ssh/transport/cipher_factory.rb +95 -91
- data/lib/net/ssh/transport/constants.rb +32 -24
- data/lib/net/ssh/transport/ctr.rb +37 -15
- data/lib/net/ssh/transport/hmac/abstract.rb +81 -63
- data/lib/net/ssh/transport/hmac/md5.rb +0 -2
- data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
- data/lib/net/ssh/transport/hmac/none.rb +0 -2
- data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
- data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
- data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
- data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
- data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
- data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
- data/lib/net/ssh/transport/hmac.rb +14 -12
- data/lib/net/ssh/transport/identity_cipher.rb +54 -52
- data/lib/net/ssh/transport/kex/abstract.rb +130 -0
- data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
- data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
- data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +33 -40
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +112 -217
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -63
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
- data/lib/net/ssh/transport/kex.rb +15 -12
- data/lib/net/ssh/transport/key_expander.rb +24 -21
- data/lib/net/ssh/transport/openssl.rb +158 -133
- data/lib/net/ssh/transport/packet_stream.rb +223 -191
- data/lib/net/ssh/transport/server_version.rb +55 -56
- data/lib/net/ssh/transport/session.rb +306 -259
- data/lib/net/ssh/transport/state.rb +178 -176
- data/lib/net/ssh/verifiers/accept_new.rb +33 -0
- data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
- data/lib/net/ssh/verifiers/always.rb +58 -0
- data/lib/net/ssh/verifiers/never.rb +19 -0
- data/lib/net/ssh/version.rb +55 -53
- data/lib/net/ssh.rb +47 -34
- data/net-ssh-public_cert.pem +18 -19
- data/net-ssh.gemspec +12 -11
- data/support/ssh_tunnel_bug.rb +5 -5
- data.tar.gz.sig +0 -0
- metadata +78 -73
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -51
- data/Gemfile.norbnacl.lock +0 -41
- data/README.rdoc +0 -169
- data/lib/net/ssh/ruby_compat.rb +0 -24
- data/lib/net/ssh/verifiers/lenient.rb +0 -30
- data/lib/net/ssh/verifiers/null.rb +0 -12
- data/lib/net/ssh/verifiers/secure.rb +0 -52
- data/lib/net/ssh/verifiers/strict.rb +0 -24
- data/support/arcfour_check.rb +0 -20
data/lib/net/ssh/proxy/http.rb
CHANGED
|
@@ -1,98 +1,98 @@
|
|
|
1
1
|
require 'socket'
|
|
2
2
|
require 'net/ssh/proxy/errors'
|
|
3
3
|
|
|
4
|
-
module Net
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
4
|
+
module Net
|
|
5
|
+
module SSH
|
|
6
|
+
module Proxy
|
|
7
|
+
# An implementation of an HTTP proxy. To use it, instantiate it, then
|
|
8
|
+
# pass the instantiated object via the :proxy key to Net::SSH.start:
|
|
9
|
+
#
|
|
10
|
+
# require 'net/ssh/proxy/http'
|
|
11
|
+
#
|
|
12
|
+
# proxy = Net::SSH::Proxy::HTTP.new('proxy_host', proxy_port)
|
|
13
|
+
# Net::SSH.start('host', 'user', :proxy => proxy) do |ssh|
|
|
14
|
+
# ...
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# If the proxy requires authentication, you can pass :user and :password
|
|
18
|
+
# to the proxy's constructor:
|
|
19
|
+
#
|
|
20
|
+
# proxy = Net::SSH::Proxy::HTTP.new('proxy_host', proxy_port,
|
|
21
|
+
# :user => "user", :password => "password")
|
|
22
|
+
#
|
|
23
|
+
# Note that HTTP digest authentication is not supported; Basic only at
|
|
24
|
+
# this point.
|
|
25
|
+
class HTTP
|
|
26
|
+
# The hostname or IP address of the HTTP proxy.
|
|
27
|
+
attr_reader :proxy_host
|
|
28
|
+
|
|
29
|
+
# The port number of the proxy.
|
|
30
|
+
attr_reader :proxy_port
|
|
31
|
+
|
|
32
|
+
# The map of additional options that were given to the object at
|
|
33
|
+
# initialization.
|
|
34
|
+
attr_reader :options
|
|
35
|
+
|
|
36
|
+
# Create a new socket factory that tunnels via the given host and
|
|
37
|
+
# port. The +options+ parameter is a hash of additional settings that
|
|
38
|
+
# can be used to tweak this proxy connection. Specifically, the following
|
|
39
|
+
# options are supported:
|
|
40
|
+
#
|
|
41
|
+
# * :user => the user name to use when authenticating to the proxy
|
|
42
|
+
# * :password => the password to use when authenticating
|
|
43
|
+
def initialize(proxy_host, proxy_port = 80, options = {})
|
|
44
|
+
@proxy_host = proxy_host
|
|
45
|
+
@proxy_port = proxy_port
|
|
46
|
+
@options = options
|
|
47
|
+
end
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
# Return a new socket connected to the given host and port via the
|
|
50
|
+
# proxy that was requested when the socket factory was instantiated.
|
|
51
|
+
def open(host, port, connection_options)
|
|
52
|
+
socket = establish_connection(connection_options[:timeout])
|
|
53
|
+
socket.write "CONNECT #{host}:#{port} HTTP/1.1\r\n"
|
|
54
|
+
socket.write "Host: #{host}:#{port}\r\n"
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
if options[:user]
|
|
57
|
+
credentials = ["#{options[:user]}:#{options[:password]}"].pack("m*").gsub(/\s/, "")
|
|
58
|
+
socket.write "Proxy-Authorization: Basic #{credentials}\r\n"
|
|
59
|
+
end
|
|
59
60
|
|
|
60
|
-
|
|
61
|
+
socket.write "\r\n"
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
resp = parse_response(socket)
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
return socket if resp[:code] == 200
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
socket.close
|
|
68
|
+
raise ConnectError, resp.inspect
|
|
69
|
+
end
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
protected
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
def establish_connection(connect_timeout)
|
|
74
|
+
Socket.tcp(proxy_host, proxy_port, nil, nil,
|
|
75
|
+
connect_timeout: connect_timeout)
|
|
76
|
+
end
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
def parse_response(socket)
|
|
79
|
+
version, code, reason = socket.gets.chomp.split(/ /, 3)
|
|
80
|
+
headers = {}
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
while (line = socket.gets) && (line.chomp! != "")
|
|
83
|
+
name, value = line.split(/:/, 2)
|
|
84
|
+
headers[name.strip] = value.strip
|
|
85
|
+
end
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
body = socket.read(headers["Content-Length"].to_i)
|
|
88
|
-
end
|
|
87
|
+
body = socket.read(headers["Content-Length"].to_i) if headers["Content-Length"]
|
|
89
88
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
return { version: version,
|
|
90
|
+
code: code.to_i,
|
|
91
|
+
reason: reason,
|
|
92
|
+
headers: headers,
|
|
93
|
+
body: body }
|
|
94
|
+
end
|
|
95
95
|
end
|
|
96
|
+
end
|
|
96
97
|
end
|
|
97
|
-
|
|
98
|
-
end; end; end
|
|
98
|
+
end
|
data/lib/net/ssh/proxy/https.rb
CHANGED
|
@@ -3,47 +3,48 @@ require 'openssl'
|
|
|
3
3
|
require 'net/ssh/proxy/errors'
|
|
4
4
|
require 'net/ssh/proxy/http'
|
|
5
5
|
|
|
6
|
-
module Net
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
6
|
+
module Net
|
|
7
|
+
module SSH
|
|
8
|
+
module Proxy
|
|
9
|
+
# A specialization of the HTTP proxy which encrypts the whole connection
|
|
10
|
+
# using OpenSSL. This has the advantage that proxy authentication
|
|
11
|
+
# information is not sent in plaintext.
|
|
12
|
+
class HTTPS < HTTP
|
|
13
|
+
# Create a new socket factory that tunnels via the given host and
|
|
14
|
+
# port. The +options+ parameter is a hash of additional settings that
|
|
15
|
+
# can be used to tweak this proxy connection. In addition to the options
|
|
16
|
+
# taken by Net::SSH::Proxy::HTTP it supports:
|
|
17
|
+
#
|
|
18
|
+
# * :ssl_context => the SSL configuration to use for the connection
|
|
19
|
+
def initialize(proxy_host, proxy_port = 80, options = {})
|
|
20
|
+
@ssl_context = options.delete(:ssl_context) ||
|
|
21
|
+
OpenSSL::SSL::SSLContext.new
|
|
22
|
+
super(proxy_host, proxy_port, options)
|
|
23
|
+
end
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
protected
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
# Shim to make OpenSSL::SSL::SSLSocket behave like a regular TCPSocket
|
|
28
|
+
# for all intents and purposes of Net::SSH::BufferedIo
|
|
29
|
+
module SSLSocketCompatibility
|
|
30
|
+
def self.extended(object) # :nodoc:
|
|
31
|
+
object.define_singleton_method(:recv, object.method(:sysread))
|
|
32
|
+
object.sync_close = true
|
|
33
|
+
end
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
def send(data, _opts)
|
|
36
|
+
syswrite(data)
|
|
37
|
+
end
|
|
37
38
|
end
|
|
38
|
-
end
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
def establish_connection(connect_timeout)
|
|
41
|
+
plain_socket = super(connect_timeout)
|
|
42
|
+
OpenSSL::SSL::SSLSocket.new(plain_socket, @ssl_context).tap do |socket|
|
|
43
|
+
socket.extend(SSLSocketCompatibility)
|
|
44
|
+
socket.connect
|
|
45
|
+
end
|
|
45
46
|
end
|
|
46
47
|
end
|
|
48
|
+
end
|
|
47
49
|
end
|
|
48
|
-
|
|
49
|
-
end; end; end
|
|
50
|
+
end
|
data/lib/net/ssh/proxy/jump.rb
CHANGED
|
@@ -1,53 +1,54 @@
|
|
|
1
1
|
require 'uri'
|
|
2
2
|
require 'net/ssh/proxy/command'
|
|
3
3
|
|
|
4
|
-
module Net
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
4
|
+
module Net
|
|
5
|
+
module SSH
|
|
6
|
+
module Proxy
|
|
7
|
+
# An implementation of a jump proxy. To use it, instantiate it,
|
|
8
|
+
# then pass the instantiated object via the :proxy key to
|
|
9
|
+
# Net::SSH.start:
|
|
10
|
+
#
|
|
11
|
+
# require 'net/ssh/proxy/jump'
|
|
12
|
+
#
|
|
13
|
+
# proxy = Net::SSH::Proxy::Jump.new('user@proxy')
|
|
14
|
+
# Net::SSH.start('host', 'user', :proxy => proxy) do |ssh|
|
|
15
|
+
# ...
|
|
16
|
+
# end
|
|
17
|
+
class Jump < Command
|
|
18
|
+
# The jump proxies
|
|
19
|
+
attr_reader :jump_proxies
|
|
20
|
+
|
|
21
|
+
# Create a new socket factory that tunnels via multiple jump proxes as
|
|
22
|
+
# [user@]host[:port].
|
|
23
|
+
def initialize(jump_proxies)
|
|
24
|
+
@jump_proxies = jump_proxies
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Return a new socket connected to the given host and port via the jump
|
|
28
|
+
# proxy that was requested when the socket factory was instantiated.
|
|
29
|
+
def open(host, port, connection_options = nil)
|
|
30
|
+
build_proxy_command_equivalent(connection_options)
|
|
31
|
+
super
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# We cannot build the ProxyCommand template until we know if the :config
|
|
35
|
+
# option was specified during `Net::SSH.start`.
|
|
36
|
+
def build_proxy_command_equivalent(connection_options = nil)
|
|
37
|
+
first_jump, extra_jumps = jump_proxies.split(",", 2)
|
|
38
|
+
config = connection_options && connection_options[:config]
|
|
39
|
+
uri = URI.parse("ssh://#{first_jump}")
|
|
40
|
+
|
|
41
|
+
template = "ssh".dup
|
|
42
|
+
template << " -l #{uri.user}" if uri.user
|
|
43
|
+
template << " -p #{uri.port}" if uri.port
|
|
44
|
+
template << " -J #{extra_jumps}" if extra_jumps
|
|
45
|
+
template << " -F #{config}" if config != true && config
|
|
46
|
+
template << " -W %h:%p "
|
|
47
|
+
template << uri.host
|
|
48
|
+
|
|
49
|
+
@command_line_template = template
|
|
50
|
+
end
|
|
51
|
+
end
|
|
50
52
|
end
|
|
51
53
|
end
|
|
52
|
-
|
|
53
|
-
end; end; end
|
|
54
|
+
end
|
data/lib/net/ssh/proxy/socks4.rb
CHANGED
|
@@ -6,7 +6,6 @@ require 'net/ssh/proxy/errors'
|
|
|
6
6
|
module Net
|
|
7
7
|
module SSH
|
|
8
8
|
module Proxy
|
|
9
|
-
|
|
10
9
|
# An implementation of a SOCKS4 proxy. To use it, instantiate it, then
|
|
11
10
|
# pass the instantiated object via the :proxy key to Net::SSH.start:
|
|
12
11
|
#
|
|
@@ -17,7 +16,6 @@ module Net
|
|
|
17
16
|
# ...
|
|
18
17
|
# end
|
|
19
18
|
class SOCKS4
|
|
20
|
-
|
|
21
19
|
# The SOCKS protocol version used by this class
|
|
22
20
|
VERSION = 4
|
|
23
21
|
|
|
@@ -39,7 +37,7 @@ module Net
|
|
|
39
37
|
# Create a new proxy connection to the given proxy host and port.
|
|
40
38
|
# Optionally, a :user key may be given to identify the username
|
|
41
39
|
# with which to authenticate.
|
|
42
|
-
def initialize(proxy_host, proxy_port=1080, options={})
|
|
40
|
+
def initialize(proxy_host, proxy_port = 1080, options = {})
|
|
43
41
|
@proxy_host = proxy_host
|
|
44
42
|
@proxy_port = proxy_port
|
|
45
43
|
@options = options
|
|
@@ -51,7 +49,7 @@ module Net
|
|
|
51
49
|
socket = Socket.tcp(proxy_host, proxy_port, nil, nil,
|
|
52
50
|
connect_timeout: connection_options[:timeout])
|
|
53
51
|
ip_addr = IPAddr.new(Resolv.getaddress(host))
|
|
54
|
-
|
|
52
|
+
|
|
55
53
|
packet = [VERSION, CONNECT, port.to_i, ip_addr.to_i, options[:user]].pack("CCnNZ*")
|
|
56
54
|
socket.send packet, 0
|
|
57
55
|
|
|
@@ -63,9 +61,7 @@ module Net
|
|
|
63
61
|
|
|
64
62
|
return socket
|
|
65
63
|
end
|
|
66
|
-
|
|
67
64
|
end
|
|
68
|
-
|
|
69
65
|
end
|
|
70
66
|
end
|
|
71
67
|
end
|
data/lib/net/ssh/proxy/socks5.rb
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
require 'socket'
|
|
2
|
-
require 'net/ssh/ruby_compat'
|
|
3
2
|
require 'net/ssh/proxy/errors'
|
|
4
3
|
|
|
5
4
|
module Net
|
|
6
5
|
module SSH
|
|
7
6
|
module Proxy
|
|
8
|
-
|
|
9
7
|
# An implementation of a SOCKS5 proxy. To use it, instantiate it, then
|
|
10
8
|
# pass the instantiated object via the :proxy key to Net::SSH.start:
|
|
11
9
|
#
|
|
@@ -54,7 +52,7 @@ module Net
|
|
|
54
52
|
# Create a new proxy connection to the given proxy host and port.
|
|
55
53
|
# Optionally, :user and :password options may be given to
|
|
56
54
|
# identify the username and password with which to authenticate.
|
|
57
|
-
def initialize(proxy_host, proxy_port=1080, options={})
|
|
55
|
+
def initialize(proxy_host, proxy_port = 1080, options = {})
|
|
58
56
|
@proxy_host = proxy_host
|
|
59
57
|
@proxy_port = proxy_port
|
|
60
58
|
@options = options
|
|
@@ -95,13 +93,13 @@ module Net
|
|
|
95
93
|
|
|
96
94
|
packet << [port].pack("n")
|
|
97
95
|
socket.send packet, 0
|
|
98
|
-
|
|
96
|
+
|
|
99
97
|
version, reply, = socket.recv(2).unpack("C*")
|
|
100
98
|
socket.recv(1)
|
|
101
99
|
address_type = socket.recv(1).getbyte(0)
|
|
102
100
|
case address_type
|
|
103
101
|
when 1
|
|
104
|
-
socket.recv(4)
|
|
102
|
+
socket.recv(4) # get four bytes for IPv4 address
|
|
105
103
|
when 3
|
|
106
104
|
len = socket.recv(1).getbyte(0)
|
|
107
105
|
hostname = socket.recv(len)
|
|
@@ -112,7 +110,7 @@ module Net
|
|
|
112
110
|
raise ConnectError, "Illegal response type"
|
|
113
111
|
end
|
|
114
112
|
portnum = socket.recv(2)
|
|
115
|
-
|
|
113
|
+
|
|
116
114
|
unless reply == SUCCESS
|
|
117
115
|
socket.close
|
|
118
116
|
raise ConnectError, "#{reply}"
|
|
@@ -123,21 +121,20 @@ module Net
|
|
|
123
121
|
|
|
124
122
|
private
|
|
125
123
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
# Simple username/password negotiation with the SOCKS5 server.
|
|
125
|
+
def negotiate_password(socket)
|
|
126
|
+
packet = [0x01, options[:user].length, options[:user],
|
|
127
|
+
options[:password].length, options[:password]].pack("CCA*CA*")
|
|
128
|
+
socket.send packet, 0
|
|
131
129
|
|
|
132
|
-
|
|
130
|
+
version, status = socket.recv(2).unpack("CC")
|
|
133
131
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
end
|
|
132
|
+
if status != SUCCESS
|
|
133
|
+
socket.close
|
|
134
|
+
raise UnauthorizedError, "could not authorize user"
|
|
138
135
|
end
|
|
136
|
+
end
|
|
139
137
|
end
|
|
140
|
-
|
|
141
138
|
end
|
|
142
139
|
end
|
|
143
140
|
end
|