net-ssh 5.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.
Files changed (122) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/config/rubocop_linter_action.yml +4 -0
  5. data/.github/workflows/ci-with-docker.yml +44 -0
  6. data/.github/workflows/ci.yml +87 -0
  7. data/.github/workflows/rubocop.yml +13 -0
  8. data/.gitignore +3 -0
  9. data/.rubocop.yml +16 -2
  10. data/.rubocop_todo.yml +623 -511
  11. data/CHANGES.txt +50 -2
  12. data/Dockerfile +27 -0
  13. data/Dockerfile.openssl3 +17 -0
  14. data/Gemfile +2 -0
  15. data/Gemfile.noed25519 +2 -0
  16. data/Manifest +0 -1
  17. data/README.md +293 -0
  18. data/Rakefile +6 -2
  19. data/appveyor.yml +4 -2
  20. data/docker-compose.yml +23 -0
  21. data/lib/net/ssh/authentication/agent.rb +29 -13
  22. data/lib/net/ssh/authentication/certificate.rb +19 -7
  23. data/lib/net/ssh/authentication/constants.rb +0 -1
  24. data/lib/net/ssh/authentication/ed25519.rb +13 -8
  25. data/lib/net/ssh/authentication/ed25519_loader.rb +5 -8
  26. data/lib/net/ssh/authentication/key_manager.rb +73 -32
  27. data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
  28. data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
  29. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +5 -3
  30. data/lib/net/ssh/authentication/methods/none.rb +6 -9
  31. data/lib/net/ssh/authentication/methods/password.rb +2 -3
  32. data/lib/net/ssh/authentication/methods/publickey.rb +56 -16
  33. data/lib/net/ssh/authentication/pageant.rb +97 -97
  34. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +2 -3
  35. data/lib/net/ssh/authentication/session.rb +27 -23
  36. data/lib/net/ssh/buffer.rb +51 -40
  37. data/lib/net/ssh/buffered_io.rb +24 -26
  38. data/lib/net/ssh/config.rb +82 -50
  39. data/lib/net/ssh/connection/channel.rb +101 -87
  40. data/lib/net/ssh/connection/constants.rb +0 -4
  41. data/lib/net/ssh/connection/event_loop.rb +30 -25
  42. data/lib/net/ssh/connection/keepalive.rb +12 -12
  43. data/lib/net/ssh/connection/session.rb +115 -111
  44. data/lib/net/ssh/connection/term.rb +56 -58
  45. data/lib/net/ssh/errors.rb +12 -12
  46. data/lib/net/ssh/key_factory.rb +10 -13
  47. data/lib/net/ssh/known_hosts.rb +106 -39
  48. data/lib/net/ssh/loggable.rb +10 -11
  49. data/lib/net/ssh/packet.rb +1 -1
  50. data/lib/net/ssh/prompt.rb +9 -11
  51. data/lib/net/ssh/proxy/command.rb +1 -2
  52. data/lib/net/ssh/proxy/errors.rb +2 -4
  53. data/lib/net/ssh/proxy/http.rb +18 -20
  54. data/lib/net/ssh/proxy/https.rb +8 -10
  55. data/lib/net/ssh/proxy/jump.rb +8 -10
  56. data/lib/net/ssh/proxy/socks4.rb +2 -4
  57. data/lib/net/ssh/proxy/socks5.rb +3 -6
  58. data/lib/net/ssh/service/forward.rb +9 -8
  59. data/lib/net/ssh/test/channel.rb +24 -26
  60. data/lib/net/ssh/test/extensions.rb +35 -35
  61. data/lib/net/ssh/test/kex.rb +6 -8
  62. data/lib/net/ssh/test/local_packet.rb +0 -2
  63. data/lib/net/ssh/test/packet.rb +3 -3
  64. data/lib/net/ssh/test/remote_packet.rb +6 -8
  65. data/lib/net/ssh/test/script.rb +25 -27
  66. data/lib/net/ssh/test/socket.rb +12 -15
  67. data/lib/net/ssh/test.rb +7 -7
  68. data/lib/net/ssh/transport/algorithms.rb +100 -58
  69. data/lib/net/ssh/transport/cipher_factory.rb +34 -50
  70. data/lib/net/ssh/transport/constants.rb +13 -9
  71. data/lib/net/ssh/transport/ctr.rb +8 -14
  72. data/lib/net/ssh/transport/hmac/abstract.rb +20 -5
  73. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  74. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  75. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  76. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  77. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  78. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  79. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  80. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  81. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  82. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  83. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  84. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  85. data/lib/net/ssh/transport/hmac.rb +13 -11
  86. data/lib/net/ssh/transport/identity_cipher.rb +11 -13
  87. data/lib/net/ssh/transport/kex/abstract.rb +130 -0
  88. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  89. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  90. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  91. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +5 -19
  92. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  93. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +30 -139
  94. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -8
  95. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  96. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +20 -81
  97. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +5 -4
  98. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +5 -4
  99. data/lib/net/ssh/transport/kex.rb +15 -10
  100. data/lib/net/ssh/transport/key_expander.rb +7 -8
  101. data/lib/net/ssh/transport/openssl.rb +149 -127
  102. data/lib/net/ssh/transport/packet_stream.rb +50 -16
  103. data/lib/net/ssh/transport/server_version.rb +17 -16
  104. data/lib/net/ssh/transport/session.rb +9 -7
  105. data/lib/net/ssh/transport/state.rb +44 -44
  106. data/lib/net/ssh/verifiers/accept_new.rb +0 -2
  107. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  108. data/lib/net/ssh/verifiers/always.rb +6 -4
  109. data/lib/net/ssh/verifiers/never.rb +0 -2
  110. data/lib/net/ssh/version.rb +3 -3
  111. data/lib/net/ssh.rb +12 -8
  112. data/net-ssh-public_cert.pem +8 -8
  113. data/net-ssh.gemspec +9 -7
  114. data/support/ssh_tunnel_bug.rb +3 -3
  115. data.tar.gz.sig +0 -0
  116. metadata +55 -30
  117. metadata.gz.sig +0 -0
  118. data/.travis.yml +0 -53
  119. data/Gemfile.noed25519.lock +0 -41
  120. data/README.rdoc +0 -194
  121. data/lib/net/ssh/ruby_compat.rb +0 -13
  122. data/support/arcfour_check.rb +0 -20
@@ -1,8 +1,7 @@
1
1
  require 'io/console'
2
2
 
3
- module Net
3
+ module Net
4
4
  module SSH
5
-
6
5
  # Default prompt implementation, called for asking password from user.
7
6
  # It will never be instantiated directly, but will instead be created for
8
7
  # you automatically.
@@ -13,8 +12,8 @@ module Net
13
12
  #
14
13
  # prompter = options[:password_prompt].start({type:'password'})
15
14
  # while !ok && max_retries < 3
16
- # user = prompter.ask("user: ", {}, true)
17
- # password = prompter.ask("password: ", {}, false)
15
+ # user = prompter.ask("user: ", true)
16
+ # password = prompter.ask("password: ", false)
18
17
  # ok = send(user, password)
19
18
  # prompter.sucess if ok
20
19
  # end
@@ -24,9 +23,9 @@ module Net
24
23
  def self.default(options = {})
25
24
  @default ||= new(options)
26
25
  end
27
-
26
+
28
27
  def initialize(options = {}); end
29
-
28
+
30
29
  # default prompt object implementation. More sophisticated implemenetations
31
30
  # might implement caching.
32
31
  class Prompter
@@ -36,22 +35,22 @@ module Net
36
35
  $stdout.puts(info[:instruction]) unless info[:instruction].empty?
37
36
  end
38
37
  end
39
-
38
+
40
39
  # ask input from user, a prompter might ask for multiple inputs
41
40
  # (like user and password) in a single session.
42
- def ask(prompt, echo=true)
41
+ def ask(prompt, echo = true)
43
42
  $stdout.print(prompt)
44
43
  $stdout.flush
45
44
  ret = $stdin.noecho(&:gets).chomp
46
45
  $stdout.print("\n")
47
46
  ret
48
47
  end
49
-
48
+
50
49
  # success method will be called when the password was accepted
51
50
  # It's a good time to save password asked to a cache.
52
51
  def success; end
53
52
  end
54
-
53
+
55
54
  # start password session. Multiple questions might be asked multiple times
56
55
  # on the returned object. Info hash tries to uniquely identify the password
57
56
  # session, so caching implementations can save passwords properly.
@@ -59,6 +58,5 @@ module Net
59
58
  Prompter.new(info)
60
59
  end
61
60
  end
62
-
63
61
  end
64
62
  end
@@ -1,12 +1,10 @@
1
1
  require 'socket'
2
2
  require 'rubygems'
3
3
  require 'net/ssh/proxy/errors'
4
- require 'net/ssh/ruby_compat'
5
4
 
6
5
  module Net
7
6
  module SSH
8
7
  module Proxy
9
-
10
8
  # An implementation of a command proxy. To use it, instantiate it,
11
9
  # then pass the instantiated object via the :proxy key to
12
10
  # Net::SSH.start:
@@ -106,6 +104,7 @@ module Net
106
104
  if IO.select([self], nil, [self], timeout_in_seconds) == nil
107
105
  raise "Unexpected spurious read wakeup"
108
106
  end
107
+
109
108
  retry
110
109
  end
111
110
  result
@@ -1,9 +1,8 @@
1
1
  require 'net/ssh/errors'
2
2
 
3
- module Net
4
- module SSH
3
+ module Net
4
+ module SSH
5
5
  module Proxy
6
-
7
6
  # A general exception class for all Proxy errors.
8
7
  class Error < Net::SSH::Exception; end
9
8
 
@@ -12,7 +11,6 @@ module Net
12
11
 
13
12
  # Used when the server doesn't recognize the user's credentials.
14
13
  class UnauthorizedError < Error; end
15
-
16
14
  end
17
15
  end
18
16
  end
@@ -1,10 +1,9 @@
1
1
  require 'socket'
2
2
  require 'net/ssh/proxy/errors'
3
3
 
4
- module Net
5
- module SSH
4
+ module Net
5
+ module SSH
6
6
  module Proxy
7
-
8
7
  # An implementation of an HTTP proxy. To use it, instantiate it, then
9
8
  # pass the instantiated object via the :proxy key to Net::SSH.start:
10
9
  #
@@ -26,14 +25,14 @@ module Net
26
25
  class HTTP
27
26
  # The hostname or IP address of the HTTP proxy.
28
27
  attr_reader :proxy_host
29
-
28
+
30
29
  # The port number of the proxy.
31
30
  attr_reader :proxy_port
32
-
31
+
33
32
  # The map of additional options that were given to the object at
34
33
  # initialization.
35
34
  attr_reader :options
36
-
35
+
37
36
  # Create a new socket factory that tunnels via the given host and
38
37
  # port. The +options+ parameter is a hash of additional settings that
39
38
  # can be used to tweak this proxy connection. Specifically, the following
@@ -41,52 +40,52 @@ module Net
41
40
  #
42
41
  # * :user => the user name to use when authenticating to the proxy
43
42
  # * :password => the password to use when authenticating
44
- def initialize(proxy_host, proxy_port=80, options={})
43
+ def initialize(proxy_host, proxy_port = 80, options = {})
45
44
  @proxy_host = proxy_host
46
45
  @proxy_port = proxy_port
47
46
  @options = options
48
47
  end
49
-
48
+
50
49
  # Return a new socket connected to the given host and port via the
51
50
  # proxy that was requested when the socket factory was instantiated.
52
51
  def open(host, port, connection_options)
53
52
  socket = establish_connection(connection_options[:timeout])
54
53
  socket.write "CONNECT #{host}:#{port} HTTP/1.1\r\n"
55
54
  socket.write "Host: #{host}:#{port}\r\n"
56
-
55
+
57
56
  if options[:user]
58
57
  credentials = ["#{options[:user]}:#{options[:password]}"].pack("m*").gsub(/\s/, "")
59
58
  socket.write "Proxy-Authorization: Basic #{credentials}\r\n"
60
59
  end
61
-
60
+
62
61
  socket.write "\r\n"
63
-
62
+
64
63
  resp = parse_response(socket)
65
-
64
+
66
65
  return socket if resp[:code] == 200
67
-
66
+
68
67
  socket.close
69
68
  raise ConnectError, resp.inspect
70
69
  end
71
-
70
+
72
71
  protected
73
-
72
+
74
73
  def establish_connection(connect_timeout)
75
74
  Socket.tcp(proxy_host, proxy_port, nil, nil,
76
75
  connect_timeout: connect_timeout)
77
76
  end
78
-
77
+
79
78
  def parse_response(socket)
80
79
  version, code, reason = socket.gets.chomp.split(/ /, 3)
81
80
  headers = {}
82
-
81
+
83
82
  while (line = socket.gets) && (line.chomp! != "")
84
83
  name, value = line.split(/:/, 2)
85
84
  headers[name.strip] = value.strip
86
85
  end
87
-
86
+
88
87
  body = socket.read(headers["Content-Length"].to_i) if headers["Content-Length"]
89
-
88
+
90
89
  return { version: version,
91
90
  code: code.to_i,
92
91
  reason: reason,
@@ -94,7 +93,6 @@ module Net
94
93
  body: body }
95
94
  end
96
95
  end
97
-
98
96
  end
99
97
  end
100
98
  end
@@ -3,10 +3,9 @@ require 'openssl'
3
3
  require 'net/ssh/proxy/errors'
4
4
  require 'net/ssh/proxy/http'
5
5
 
6
- module Net
7
- module SSH
6
+ module Net
7
+ module SSH
8
8
  module Proxy
9
-
10
9
  # A specialization of the HTTP proxy which encrypts the whole connection
11
10
  # using OpenSSL. This has the advantage that proxy authentication
12
11
  # information is not sent in plaintext.
@@ -17,27 +16,27 @@ module Net
17
16
  # taken by Net::SSH::Proxy::HTTP it supports:
18
17
  #
19
18
  # * :ssl_context => the SSL configuration to use for the connection
20
- def initialize(proxy_host, proxy_port=80, options={})
19
+ def initialize(proxy_host, proxy_port = 80, options = {})
21
20
  @ssl_context = options.delete(:ssl_context) ||
22
21
  OpenSSL::SSL::SSLContext.new
23
22
  super(proxy_host, proxy_port, options)
24
23
  end
25
-
24
+
26
25
  protected
27
-
26
+
28
27
  # Shim to make OpenSSL::SSL::SSLSocket behave like a regular TCPSocket
29
28
  # for all intents and purposes of Net::SSH::BufferedIo
30
29
  module SSLSocketCompatibility
31
- def self.extended(object) #:nodoc:
30
+ def self.extended(object) # :nodoc:
32
31
  object.define_singleton_method(:recv, object.method(:sysread))
33
32
  object.sync_close = true
34
33
  end
35
-
34
+
36
35
  def send(data, _opts)
37
36
  syswrite(data)
38
37
  end
39
38
  end
40
-
39
+
41
40
  def establish_connection(connect_timeout)
42
41
  plain_socket = super(connect_timeout)
43
42
  OpenSSL::SSL::SSLSocket.new(plain_socket, @ssl_context).tap do |socket|
@@ -46,7 +45,6 @@ module Net
46
45
  end
47
46
  end
48
47
  end
49
-
50
48
  end
51
49
  end
52
50
  end
@@ -1,10 +1,9 @@
1
1
  require 'uri'
2
2
  require 'net/ssh/proxy/command'
3
3
 
4
- module Net
5
- module SSH
4
+ module Net
5
+ module SSH
6
6
  module Proxy
7
-
8
7
  # An implementation of a jump proxy. To use it, instantiate it,
9
8
  # then pass the instantiated object via the :proxy key to
10
9
  # Net::SSH.start:
@@ -18,39 +17,38 @@ module Net
18
17
  class Jump < Command
19
18
  # The jump proxies
20
19
  attr_reader :jump_proxies
21
-
20
+
22
21
  # Create a new socket factory that tunnels via multiple jump proxes as
23
22
  # [user@]host[:port].
24
23
  def initialize(jump_proxies)
25
24
  @jump_proxies = jump_proxies
26
25
  end
27
-
26
+
28
27
  # Return a new socket connected to the given host and port via the jump
29
28
  # proxy that was requested when the socket factory was instantiated.
30
29
  def open(host, port, connection_options = nil)
31
30
  build_proxy_command_equivalent(connection_options)
32
31
  super
33
32
  end
34
-
33
+
35
34
  # We cannot build the ProxyCommand template until we know if the :config
36
35
  # option was specified during `Net::SSH.start`.
37
36
  def build_proxy_command_equivalent(connection_options = nil)
38
37
  first_jump, extra_jumps = jump_proxies.split(",", 2)
39
38
  config = connection_options && connection_options[:config]
40
39
  uri = URI.parse("ssh://#{first_jump}")
41
-
42
- template = "ssh"
40
+
41
+ template = "ssh".dup
43
42
  template << " -l #{uri.user}" if uri.user
44
43
  template << " -p #{uri.port}" if uri.port
45
44
  template << " -J #{extra_jumps}" if extra_jumps
46
45
  template << " -F #{config}" if config != true && config
47
46
  template << " -W %h:%p "
48
47
  template << uri.host
49
-
48
+
50
49
  @command_line_template = template
51
50
  end
52
51
  end
53
-
54
52
  end
55
53
  end
56
54
  end
@@ -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
  #
@@ -38,7 +37,7 @@ module Net
38
37
  # Create a new proxy connection to the given proxy host and port.
39
38
  # Optionally, a :user key may be given to identify the username
40
39
  # with which to authenticate.
41
- def initialize(proxy_host, proxy_port=1080, options={})
40
+ def initialize(proxy_host, proxy_port = 1080, options = {})
42
41
  @proxy_host = proxy_host
43
42
  @proxy_port = proxy_port
44
43
  @options = options
@@ -50,7 +49,7 @@ module Net
50
49
  socket = Socket.tcp(proxy_host, proxy_port, nil, nil,
51
50
  connect_timeout: connection_options[:timeout])
52
51
  ip_addr = IPAddr.new(Resolv.getaddress(host))
53
-
52
+
54
53
  packet = [VERSION, CONNECT, port.to_i, ip_addr.to_i, options[:user]].pack("CCnNZ*")
55
54
  socket.send packet, 0
56
55
 
@@ -63,7 +62,6 @@ module Net
63
62
  return socket
64
63
  end
65
64
  end
66
-
67
65
  end
68
66
  end
69
67
  end
@@ -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,7 +93,7 @@ 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)
@@ -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}"
@@ -137,7 +135,6 @@ module Net
137
135
  end
138
136
  end
139
137
  end
140
-
141
138
  end
142
139
  end
143
140
  end
@@ -3,7 +3,6 @@ require 'net/ssh/loggable'
3
3
  module Net
4
4
  module SSH
5
5
  module Service
6
-
7
6
  # This class implements various port forwarding services for use by
8
7
  # Net::SSH clients. The Forward class should never need to be instantiated
9
8
  # directly; instead, it should be accessed via the singleton instance
@@ -18,7 +17,7 @@ module Net
18
17
  attr_reader :session
19
18
 
20
19
  # A simple class for representing a requested remote forwarded port.
21
- Remote = Struct.new(:host, :port) #:nodoc:
20
+ Remote = Struct.new(:host, :port) # :nodoc:
22
21
 
23
22
  # Instantiates a new Forward service instance atop the given connection
24
23
  # service session. This will register new channel open handlers to handle
@@ -85,7 +84,8 @@ module Net
85
84
  client = server.accept
86
85
  debug { "received connection on #{socket}" }
87
86
 
88
- channel = session.open_channel("direct-tcpip", :string, remote_host, :long, remote_port, :string, bind_address, local_port_type, local_port) do |achannel|
87
+ channel = session.open_channel("direct-tcpip", :string, remote_host, :long,
88
+ remote_port, :string, bind_address, local_port_type, local_port) do |achannel|
89
89
  achannel.info { "direct channel established" }
90
90
  end
91
91
 
@@ -105,7 +105,7 @@ module Net
105
105
  #
106
106
  # ssh.forward.cancel_local(1234)
107
107
  # ssh.forward.cancel_local(1234, "0.0.0.0")
108
- def cancel_local(port, bind_address="127.0.0.1")
108
+ def cancel_local(port, bind_address = "127.0.0.1")
109
109
  socket = @local_forwarded_ports.delete([port, bind_address])
110
110
  socket.shutdown rescue nil
111
111
  socket.close rescue nil
@@ -214,7 +214,7 @@ module Net
214
214
  # raise Net::SSH::Exception, "remote forwarding request failed"
215
215
  # end
216
216
  #
217
- def remote(port, host, remote_port, remote_host="127.0.0.1")
217
+ def remote(port, host, remote_port, remote_host = "127.0.0.1")
218
218
  session.send_global_request("tcpip-forward", :string, remote_host, :long, remote_port) do |success, response|
219
219
  if success
220
220
  remote_port = response.read_long if remote_port == 0
@@ -248,7 +248,7 @@ module Net
248
248
  #
249
249
  # ssh.forward.cancel_remote(1234, "0.0.0.0")
250
250
  # ssh.loop { ssh.forward.active_remotes.include?([1234, "0.0.0.0"]) }
251
- def cancel_remote(port, host="127.0.0.1")
251
+ def cancel_remote(port, host = "127.0.0.1")
252
252
  session.send_global_request("cancel-tcpip-forward", :string, host, :long, port) do |success, response|
253
253
  if success
254
254
  @remote_forwarded_ports.delete([port, host])
@@ -289,6 +289,7 @@ module Net
289
289
  # end
290
290
  def agent(channel)
291
291
  return if @agent_forwarded
292
+
292
293
  @agent_forwarded = true
293
294
 
294
295
  channel.send_channel_request("auth-agent-req@openssh.com") do |achannel, success|
@@ -387,12 +388,13 @@ module Net
387
388
  originator_address = packet.read_string
388
389
  originator_port = packet.read_long
389
390
 
391
+ puts "REMOTE 0: #{connected_port} #{connected_address} #{originator_address} #{originator_port}"
390
392
  remote = @remote_forwarded_ports[[connected_port, connected_address]]
391
-
392
393
  if remote.nil?
393
394
  raise Net::SSH::ChannelOpenFailed.new(1, "unknown request from remote forwarded connection on #{connected_address}:#{connected_port}")
394
395
  end
395
396
 
397
+ puts "REMOTE: #{remote.host} #{remote.port}"
396
398
  client = TCPSocket.new(remote.host, remote.port)
397
399
  info { "connected #{connected_address}:#{connected_port} originator #{originator_address}:#{originator_port}" }
398
400
 
@@ -419,7 +421,6 @@ module Net
419
421
  end
420
422
  end
421
423
  end
422
-
423
424
  end
424
425
  end
425
426
  end
@@ -1,7 +1,6 @@
1
- module Net
2
- module SSH
1
+ module Net
2
+ module SSH
3
3
  module Test
4
-
5
4
  # A mock channel, used for scripting actions in tests. It wraps a
6
5
  # Net::SSH::Test::Script instance, and delegates to it for the most part.
7
6
  # This class has little real functionality on its own, but rather acts as
@@ -19,34 +18,34 @@ module Net
19
18
  class Channel
20
19
  # The Net::SSH::Test::Script instance employed by this mock channel.
21
20
  attr_reader :script
22
-
21
+
23
22
  # Sets the local-id of this channel object (the id assigned by the client).
24
23
  attr_writer :local_id
25
-
24
+
26
25
  # Sets the remote-id of this channel object (the id assigned by the mock-server).
27
26
  attr_writer :remote_id
28
-
27
+
29
28
  # Creates a new Test::Channel instance on top of the given +script+ (which
30
29
  # must be a Net::SSH::Test::Script instance).
31
30
  def initialize(script)
32
31
  @script = script
33
32
  @local_id = @remote_id = nil
34
33
  end
35
-
34
+
36
35
  # Returns the local (client-assigned) id for this channel, or a Proc object
37
36
  # that will return the local-id later if the local id has not yet been set.
38
37
  # (See Net::SSH::Test::Packet#instantiate!.)
39
38
  def local_id
40
39
  @local_id || Proc.new { @local_id or raise "local-id has not been set yet!" }
41
40
  end
42
-
41
+
43
42
  # Returns the remote (server-assigned) id for this channel, or a Proc object
44
43
  # that will return the remote-id later if the remote id has not yet been set.
45
44
  # (See Net::SSH::Test::Packet#instantiate!.)
46
45
  def remote_id
47
46
  @remote_id || Proc.new { @remote_id or raise "remote-id has not been set yet!" }
48
47
  end
49
-
48
+
50
49
  # Because adjacent calls to #gets_data will sometimes cause the data packets
51
50
  # to be concatenated (causing expectations in tests to fail), you may
52
51
  # need to separate those calls with calls to #inject_remote_delay! (which
@@ -58,62 +57,62 @@ module Net
58
57
  def inject_remote_delay!
59
58
  gets_data("")
60
59
  end
61
-
62
- # Scripts the sending of an "exec" channel request packet to the mock
60
+
61
+ # Scripts the sending of an "exec" channel request packet to the mock
63
62
  # server. If +reply+ is true, then the server is expected to reply to the
64
63
  # request, otherwise no response to this request will be sent. If +success+
65
64
  # is +true+, then the request will be successful, otherwise a failure will
66
65
  # be scripted.
67
66
  #
68
67
  # channel.sends_exec "ls -l"
69
- def sends_exec(command, reply=true, success=true)
68
+ def sends_exec(command, reply = true, success = true)
70
69
  script.sends_channel_request(self, "exec", reply, command, success)
71
70
  end
72
-
71
+
73
72
  # Scripts the sending of a "subsystem" channel request packet to the mock
74
73
  # server. See #sends_exec for a discussion of the meaning of the +reply+
75
74
  # and +success+ arguments.
76
75
  #
77
76
  # channel.sends_subsystem "sftp"
78
- def sends_subsystem(subsystem, reply=true, success=true)
77
+ def sends_subsystem(subsystem, reply = true, success = true)
79
78
  script.sends_channel_request(self, "subsystem", reply, subsystem, success)
80
79
  end
81
-
80
+
82
81
  # Scripts the sending of a data packet across the channel.
83
82
  #
84
83
  # channel.sends_data "foo"
85
84
  def sends_data(data)
86
85
  script.sends_channel_data(self, data)
87
86
  end
88
-
87
+
89
88
  # Scripts the sending of an EOF packet across the channel.
90
89
  #
91
90
  # channel.sends_eof
92
91
  def sends_eof
93
92
  script.sends_channel_eof(self)
94
93
  end
95
-
94
+
96
95
  # Scripts the sending of a "channel close" packet across the channel.
97
96
  #
98
97
  # channel.sends_close
99
98
  def sends_close
100
99
  script.sends_channel_close(self)
101
100
  end
102
-
101
+
103
102
  # Scripts the sending of a "request pty" request packet across the channel.
104
103
  #
105
104
  # channel.sends_request_pty
106
105
  def sends_request_pty
107
106
  script.sends_channel_request_pty(self)
108
107
  end
109
-
108
+
110
109
  # Scripts the reception of a channel data packet from the remote end.
111
110
  #
112
111
  # channel.gets_data "bar"
113
112
  def gets_data(data)
114
113
  script.gets_channel_data(self, data)
115
114
  end
116
-
115
+
117
116
  # Scripts the reception of a channel extended data packet from the remote
118
117
  # end.
119
118
  #
@@ -121,21 +120,21 @@ module Net
121
120
  def gets_extended_data(data)
122
121
  script.gets_channel_extended_data(self, data)
123
122
  end
124
-
123
+
125
124
  # Scripts the reception of an "exit-status" channel request packet.
126
125
  #
127
126
  # channel.gets_exit_status(127)
128
- def gets_exit_status(status=0)
127
+ def gets_exit_status(status = 0)
129
128
  script.gets_channel_request(self, "exit-status", false, status)
130
129
  end
131
-
130
+
132
131
  # Scripts the reception of an EOF packet from the remote end.
133
132
  #
134
133
  # channel.gets_eof
135
134
  def gets_eof
136
135
  script.gets_channel_eof(self)
137
136
  end
138
-
137
+
139
138
  # Scripts the reception of a "channel close" packet from the remote end.
140
139
  #
141
140
  # channel.gets_close
@@ -143,7 +142,6 @@ module Net
143
142
  script.gets_channel_close(self)
144
143
  end
145
144
  end
146
-
147
145
  end
148
146
  end
149
- end
147
+ end