net-ssh 5.2.0 → 7.0.1

Sign up to get free protection for your applications and to get access to all the features.
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