net-ssh 6.1.0 → 7.3.0

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 (116) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/FUNDING.yml +1 -0
  5. data/.github/config/rubocop_linter_action.yml +4 -0
  6. data/.github/workflows/ci-with-docker.yml +44 -0
  7. data/.github/workflows/ci.yml +94 -0
  8. data/.github/workflows/rubocop.yml +16 -0
  9. data/.gitignore +4 -0
  10. data/.rubocop.yml +12 -1
  11. data/.rubocop_todo.yml +475 -376
  12. data/CHANGES.txt +64 -3
  13. data/DEVELOPMENT.md +23 -0
  14. data/Dockerfile +29 -0
  15. data/Dockerfile.openssl3 +17 -0
  16. data/Gemfile +2 -0
  17. data/Gemfile.noed25519 +2 -0
  18. data/Gemfile.norbnacl +12 -0
  19. data/README.md +38 -22
  20. data/Rakefile +92 -0
  21. data/SECURITY.md +4 -0
  22. data/docker-compose.yml +25 -0
  23. data/lib/net/ssh/authentication/agent.rb +29 -13
  24. data/lib/net/ssh/authentication/certificate.rb +14 -11
  25. data/lib/net/ssh/authentication/constants.rb +0 -1
  26. data/lib/net/ssh/authentication/ed25519.rb +14 -11
  27. data/lib/net/ssh/authentication/ed25519_loader.rb +4 -7
  28. data/lib/net/ssh/authentication/key_manager.rb +65 -36
  29. data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
  30. data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
  31. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -2
  32. data/lib/net/ssh/authentication/methods/none.rb +6 -9
  33. data/lib/net/ssh/authentication/methods/password.rb +2 -3
  34. data/lib/net/ssh/authentication/methods/publickey.rb +57 -17
  35. data/lib/net/ssh/authentication/pageant.rb +97 -97
  36. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +3 -3
  37. data/lib/net/ssh/authentication/session.rb +25 -17
  38. data/lib/net/ssh/buffer.rb +71 -51
  39. data/lib/net/ssh/buffered_io.rb +25 -26
  40. data/lib/net/ssh/config.rb +33 -20
  41. data/lib/net/ssh/connection/channel.rb +84 -82
  42. data/lib/net/ssh/connection/constants.rb +0 -4
  43. data/lib/net/ssh/connection/event_loop.rb +30 -24
  44. data/lib/net/ssh/connection/keepalive.rb +12 -12
  45. data/lib/net/ssh/connection/session.rb +109 -108
  46. data/lib/net/ssh/connection/term.rb +56 -58
  47. data/lib/net/ssh/errors.rb +12 -12
  48. data/lib/net/ssh/key_factory.rb +7 -8
  49. data/lib/net/ssh/known_hosts.rb +86 -18
  50. data/lib/net/ssh/loggable.rb +8 -9
  51. data/lib/net/ssh/packet.rb +1 -1
  52. data/lib/net/ssh/prompt.rb +9 -11
  53. data/lib/net/ssh/proxy/command.rb +1 -1
  54. data/lib/net/ssh/proxy/errors.rb +2 -4
  55. data/lib/net/ssh/proxy/http.rb +18 -20
  56. data/lib/net/ssh/proxy/https.rb +8 -10
  57. data/lib/net/ssh/proxy/jump.rb +8 -10
  58. data/lib/net/ssh/proxy/socks4.rb +2 -4
  59. data/lib/net/ssh/proxy/socks5.rb +3 -5
  60. data/lib/net/ssh/service/forward.rb +7 -7
  61. data/lib/net/ssh/test/channel.rb +24 -26
  62. data/lib/net/ssh/test/extensions.rb +35 -35
  63. data/lib/net/ssh/test/kex.rb +6 -8
  64. data/lib/net/ssh/test/local_packet.rb +0 -2
  65. data/lib/net/ssh/test/packet.rb +3 -3
  66. data/lib/net/ssh/test/remote_packet.rb +6 -8
  67. data/lib/net/ssh/test/script.rb +25 -27
  68. data/lib/net/ssh/test/socket.rb +12 -15
  69. data/lib/net/ssh/test.rb +4 -5
  70. data/lib/net/ssh/transport/aes128_gcm.rb +40 -0
  71. data/lib/net/ssh/transport/aes256_gcm.rb +40 -0
  72. data/lib/net/ssh/transport/algorithms.rb +51 -19
  73. data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
  74. data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
  75. data/lib/net/ssh/transport/cipher_factory.rb +56 -29
  76. data/lib/net/ssh/transport/constants.rb +3 -3
  77. data/lib/net/ssh/transport/ctr.rb +7 -7
  78. data/lib/net/ssh/transport/gcm_cipher.rb +207 -0
  79. data/lib/net/ssh/transport/hmac/abstract.rb +20 -5
  80. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  81. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  82. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  83. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  84. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  85. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  86. data/lib/net/ssh/transport/hmac.rb +12 -12
  87. data/lib/net/ssh/transport/identity_cipher.rb +19 -13
  88. data/lib/net/ssh/transport/kex/abstract.rb +12 -5
  89. data/lib/net/ssh/transport/kex/abstract5656.rb +1 -1
  90. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +2 -1
  91. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +4 -4
  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 +21 -21
  94. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -2
  95. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +2 -2
  96. data/lib/net/ssh/transport/kex.rb +8 -6
  97. data/lib/net/ssh/transport/key_expander.rb +7 -8
  98. data/lib/net/ssh/transport/openssl.rb +51 -26
  99. data/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
  100. data/lib/net/ssh/transport/packet_stream.rb +46 -26
  101. data/lib/net/ssh/transport/server_version.rb +17 -16
  102. data/lib/net/ssh/transport/session.rb +9 -7
  103. data/lib/net/ssh/transport/state.rb +44 -44
  104. data/lib/net/ssh/verifiers/accept_new.rb +0 -2
  105. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  106. data/lib/net/ssh/verifiers/always.rb +6 -4
  107. data/lib/net/ssh/verifiers/never.rb +0 -2
  108. data/lib/net/ssh/version.rb +2 -2
  109. data/lib/net/ssh.rb +15 -8
  110. data/net-ssh-public_cert.pem +19 -18
  111. data/net-ssh.gemspec +7 -4
  112. data/support/ssh_tunnel_bug.rb +3 -3
  113. data.tar.gz.sig +0 -0
  114. metadata +76 -29
  115. metadata.gz.sig +0 -0
  116. data/.travis.yml +0 -52
@@ -6,16 +6,14 @@ require 'net/ssh/connection/constants'
6
6
  require 'net/ssh/transport/constants'
7
7
  require 'net/ssh/transport/packet_stream'
8
8
 
9
- module Net
10
- module SSH
9
+ module Net
10
+ module SSH
11
11
  module Test
12
-
13
12
  # A collection of modules used to extend/override the default behavior of
14
13
  # Net::SSH internals for ease of testing. As a consumer of Net::SSH, you'll
15
14
  # never need to use this directly--they're all used under the covers by
16
15
  # the Net::SSH::Test system.
17
16
  module Extensions
18
-
19
17
  # An extension to Net::SSH::BufferedIo (assumes that the underlying IO
20
18
  # is actually a StringIO). Facilitates unit testing.
21
19
  module BufferedIo
@@ -24,80 +22,82 @@ module Net
24
22
  def select_for_read?
25
23
  pos < size
26
24
  end
27
-
25
+
28
26
  # Set this to +true+ if you want the IO to pretend to be available for writing
29
27
  attr_accessor :select_for_write
30
-
28
+
31
29
  # Set this to +true+ if you want the IO to pretend to be in an error state
32
30
  attr_accessor :select_for_error
33
-
31
+
34
32
  alias select_for_write? select_for_write
35
33
  alias select_for_error? select_for_error
36
34
  end
37
-
35
+
38
36
  # An extension to Net::SSH::Transport::PacketStream (assumes that the
39
37
  # underlying IO is actually a StringIO). Facilitates unit testing.
40
38
  module PacketStream
41
39
  include BufferedIo # make sure we get the extensions here, too
42
-
43
- def self.included(base) #:nodoc:
40
+
41
+ def self.included(base) # :nodoc:
44
42
  base.send :alias_method, :real_available_for_read?, :available_for_read?
45
43
  base.send :alias_method, :available_for_read?, :test_available_for_read?
46
-
44
+
47
45
  base.send :alias_method, :real_enqueue_packet, :enqueue_packet
48
46
  base.send :alias_method, :enqueue_packet, :test_enqueue_packet
49
-
47
+
50
48
  base.send :alias_method, :real_poll_next_packet, :poll_next_packet
51
49
  base.send :alias_method, :poll_next_packet, :test_poll_next_packet
52
50
  end
53
-
51
+
54
52
  # Called when another packet should be inspected from the current
55
53
  # script. If the next packet is a remote packet, it pops it off the
56
54
  # script and shoves it onto this IO object, making it available to
57
55
  # be read.
58
56
  def idle!
59
57
  return false unless script.next(:first)
60
-
58
+
61
59
  if script.next(:first).remote?
62
60
  self.string << script.next.to_s
63
61
  self.pos = pos
64
62
  end
65
-
63
+
66
64
  return true
67
65
  end
68
-
66
+
69
67
  # The testing version of Net::SSH::Transport::PacketStream#available_for_read?.
70
68
  # Returns true if there is data pending to be read. Otherwise calls #idle!.
71
69
  def test_available_for_read?
72
70
  return true if select_for_read?
71
+
73
72
  idle!
74
73
  false
75
74
  end
76
-
75
+
77
76
  # The testing version of Net::SSH::Transport::PacketStream#enqueued_packet.
78
77
  # Simply calls Net::SSH::Test::Script#process on the packet.
79
78
  def test_enqueue_packet(payload)
80
79
  packet = Net::SSH::Buffer.new(payload.to_s)
81
80
  script.process(packet)
82
81
  end
83
-
82
+
84
83
  # The testing version of Net::SSH::Transport::PacketStream#poll_next_packet.
85
84
  # Reads the next available packet from the IO object and returns it.
86
85
  def test_poll_next_packet
87
86
  return nil if available <= 0
87
+
88
88
  packet = Net::SSH::Buffer.new(read_available(4))
89
89
  length = packet.read_long
90
90
  Net::SSH::Packet.new(read_available(length))
91
91
  end
92
92
  end
93
-
93
+
94
94
  # An extension to Net::SSH::Connection::Channel. Facilitates unit testing.
95
95
  module Channel
96
- def self.included(base) #:nodoc:
96
+ def self.included(base) # :nodoc:
97
97
  base.send :alias_method, :send_data_for_real, :send_data
98
98
  base.send :alias_method, :send_data, :send_data_for_test
99
99
  end
100
-
100
+
101
101
  # The testing version of Net::SSH::Connection::Channel#send_data. Calls
102
102
  # the original implementation, and then immediately enqueues the data for
103
103
  # output so that scripted sends are properly interpreted as discrete
@@ -107,16 +107,16 @@ module Net
107
107
  enqueue_pending_output
108
108
  end
109
109
  end
110
-
110
+
111
111
  # An extension to the built-in ::IO class. Simply redefines IO.select
112
112
  # so that it can be scripted in Net::SSH unit tests.
113
113
  module IO
114
- def self.included(base) #:nodoc:
114
+ def self.included(base) # :nodoc:
115
115
  base.extend(ClassMethods)
116
116
  end
117
-
117
+
118
118
  @extension_enabled = false
119
-
119
+
120
120
  def self.with_test_extension(&block)
121
121
  orig_value = @extension_enabled
122
122
  @extension_enabled = true
@@ -126,35 +126,36 @@ module Net
126
126
  @extension_enabled = orig_value
127
127
  end
128
128
  end
129
-
129
+
130
130
  def self.extension_enabled?
131
131
  @extension_enabled
132
132
  end
133
-
133
+
134
134
  module ClassMethods
135
- def self.extended(obj) #:nodoc:
136
- class <<obj
135
+ def self.extended(obj) # :nodoc:
136
+ class << obj
137
137
  alias_method :select_for_real, :select
138
138
  alias_method :select, :select_for_test
139
139
  end
140
140
  end
141
-
141
+
142
142
  # The testing version of ::IO.select. Assumes that all readers,
143
143
  # writers, and errors arrays are either nil, or contain only objects
144
144
  # that mix in Net::SSH::Test::Extensions::BufferedIo.
145
- def select_for_test(readers=nil, writers=nil, errors=nil, wait=nil)
145
+ def select_for_test(readers = nil, writers = nil, errors = nil, wait = nil)
146
146
  return select_for_real(readers, writers, errors, wait) unless Net::SSH::Test::Extensions::IO.extension_enabled?
147
+
147
148
  ready_readers = Array(readers).select { |r| r.select_for_read? }
148
149
  ready_writers = Array(writers).select { |r| r.select_for_write? }
149
150
  ready_errors = Array(errors).select { |r| r.select_for_error? }
150
-
151
+
151
152
  return [ready_readers, ready_writers, ready_errors] if ready_readers.any? || ready_writers.any? || ready_errors.any?
152
-
153
+
153
154
  processed = 0
154
155
  Array(readers).each do |reader|
155
156
  processed += 1 if reader.idle!
156
157
  end
157
-
158
+
158
159
  raise "no readers were ready for reading, and none had any incoming packets" if processed == 0 && wait != 0
159
160
 
160
161
  [[], [], []]
@@ -162,7 +163,6 @@ module Net
162
163
  end
163
164
  end
164
165
  end
165
-
166
166
  end
167
167
  end
168
168
  end
@@ -5,10 +5,9 @@ require 'net/ssh/transport/algorithms'
5
5
  require 'net/ssh/transport/constants'
6
6
  require 'net/ssh/transport/kex'
7
7
 
8
- module Net
9
- module SSH
8
+ module Net
9
+ module SSH
10
10
  module Test
11
-
12
11
  # An implementation of a key-exchange strategy specifically for unit tests.
13
12
  # (This strategy would never really work against a real SSH server--it makes
14
13
  # too many assumptions about the server's response.)
@@ -17,29 +16,28 @@ module Net
17
16
  # "test" algorithm.
18
17
  class Kex
19
18
  include Net::SSH::Transport::Constants
20
-
19
+
21
20
  # Creates a new instance of the testing key-exchange algorithm with the
22
21
  # given arguments.
23
22
  def initialize(algorithms, connection, data)
24
23
  @connection = connection
25
24
  end
26
-
25
+
27
26
  # Exchange keys with the server. This returns a hash of constant values,
28
27
  # and does not actually exchange keys.
29
28
  def exchange_keys
30
29
  result = Net::SSH::Buffer.from(:byte, NEWKEYS)
31
30
  @connection.send_message(result)
32
-
31
+
33
32
  buffer = @connection.next_message
34
33
  raise Net::SSH::Exception, "expected NEWKEYS" unless buffer.type == NEWKEYS
35
-
34
+
36
35
  { session_id: "abc-xyz",
37
36
  server_key: OpenSSL::PKey::RSA.new(512),
38
37
  shared_secret: OpenSSL::BN.new("1234567890", 10),
39
38
  hashing_algorithm: OpenSSL::Digest::SHA1 }
40
39
  end
41
40
  end
42
-
43
41
  end
44
42
  end
45
43
  end
@@ -4,7 +4,6 @@ require 'net/ssh/test/packet'
4
4
  module Net
5
5
  module SSH
6
6
  module Test
7
-
8
7
  # This is a specialization of Net::SSH::Test::Packet for representing mock
9
8
  # packets that are sent from the local (client) host. These are created
10
9
  # automatically by Net::SSH::Test::Script and Net::SSH::Test::Channel by any
@@ -49,7 +48,6 @@ module Net
49
48
  end
50
49
  end
51
50
  end
52
-
53
51
  end
54
52
  end
55
53
  end
@@ -4,7 +4,6 @@ require 'net/ssh/transport/constants'
4
4
  module Net
5
5
  module SSH
6
6
  module Test
7
-
8
7
  # This is an abstract class, not to be instantiated directly, subclassed by
9
8
  # Net::SSH::Test::LocalPacket and Net::SSH::Test::RemotePacket. It implements
10
9
  # functionality common to those subclasses.
@@ -70,7 +69,7 @@ module Net
70
69
  # added. Unsupported packet types will otherwise raise an exception.
71
70
  def types
72
71
  @types ||= case @type
73
- when KEXINIT then
72
+ when KEXINIT
74
73
  %i[long long long long
75
74
  string string string string string string string string string string
76
75
  bool]
@@ -83,13 +82,14 @@ module Net
83
82
  when CHANNEL_REQUEST
84
83
  parts = %i[long string bool]
85
84
  case @data[1]
86
- when "exec", "subsystem","shell" then parts << :string
85
+ when "exec", "subsystem", "shell" then parts << :string
87
86
  when "exit-status" then parts << :long
88
87
  when "pty-req" then parts.concat(%i[string long long long long string])
89
88
  when "env" then parts.contact(%i[string string])
90
89
  else
91
90
  request = Packet.registered_channel_requests(@data[1])
92
91
  raise "don't know what to do about #{@data[1]} channel request" unless request
92
+
93
93
  parts.concat(request[:extra_parts])
94
94
  end
95
95
  else raise "don't know how to parse packet type #{@type}"
@@ -1,10 +1,9 @@
1
1
  require 'net/ssh/buffer'
2
2
  require 'net/ssh/test/packet'
3
3
 
4
- module Net
5
- module SSH
4
+ module Net
5
+ module SSH
6
6
  module Test
7
-
8
7
  # This is a specialization of Net::SSH::Test::Packet for representing mock
9
8
  # packets that are received by the local (client) host. These are created
10
9
  # automatically by Net::SSH::Test::Script and Net::SSH::Test::Channel by any
@@ -14,7 +13,7 @@ module Net
14
13
  def remote?
15
14
  true
16
15
  end
17
-
16
+
18
17
  # The #process method should only be called on Net::SSH::Test::LocalPacket
19
18
  # packets; if it is attempted on a remote packet, then it is an expectation
20
19
  # mismatch (a remote packet was received when a local packet was expected
@@ -23,8 +22,8 @@ module Net
23
22
  def process(packet)
24
23
  raise "received packet type #{packet.read_byte} and was not expecting any packet"
25
24
  end
26
-
27
- # Returns this remote packet as a string, suitable for parsing by
25
+
26
+ # Returns this remote packet as a string, suitable for parsing by
28
27
  # Net::SSH::Transport::PacketStream and friends. When a remote packet is
29
28
  # received, this method is called and the result concatenated onto the
30
29
  # input buffer for the packet stream.
@@ -36,7 +35,6 @@ module Net
36
35
  end
37
36
  end
38
37
  end
39
-
40
38
  end
41
39
  end
42
- end
40
+ end
@@ -2,10 +2,9 @@ require 'net/ssh/test/channel'
2
2
  require 'net/ssh/test/local_packet'
3
3
  require 'net/ssh/test/remote_packet'
4
4
 
5
- module Net
6
- module SSH
5
+ module Net
6
+ module SSH
7
7
  module Test
8
-
9
8
  # Represents a sequence of scripted events that identify the behavior that
10
9
  # a test expects. Methods named "sends_*" create events for packets being
11
10
  # sent from the local to the remote host, and methods named "gets_*" create
@@ -22,41 +21,41 @@ module Net
22
21
  # The list of scripted events. These will be Net::SSH::Test::LocalPacket
23
22
  # and Net::SSH::Test::RemotePacket instances.
24
23
  attr_reader :events
25
-
24
+
26
25
  # Create a new, empty script.
27
26
  def initialize
28
27
  @events = []
29
28
  end
30
-
29
+
31
30
  # Scripts the opening of a channel by adding a local packet sending the
32
31
  # channel open request, and if +confirm+ is true (the default), also
33
32
  # adding a remote packet confirming the new channel.
34
33
  #
35
34
  # A new Net::SSH::Test::Channel instance is returned, which can be used
36
35
  # to script additional channel operations.
37
- def opens_channel(confirm=true)
36
+ def opens_channel(confirm = true)
38
37
  channel = Channel.new(self)
39
38
  channel.remote_id = 5555
40
-
39
+
41
40
  events << LocalPacket.new(:channel_open) { |p| channel.local_id = p[:remote_id] }
42
-
41
+
43
42
  events << RemotePacket.new(:channel_open_confirmation, channel.local_id, channel.remote_id, 0x20000, 0x10000) if confirm
44
-
43
+
45
44
  channel
46
45
  end
47
-
46
+
48
47
  # A convenience method for adding an arbitrary local packet to the events
49
48
  # list.
50
49
  def sends(type, *args, &block)
51
50
  events << LocalPacket.new(type, *args, &block)
52
51
  end
53
-
52
+
54
53
  # A convenience method for adding an arbitrary remote packet to the events
55
54
  # list.
56
55
  def gets(type, *args)
57
56
  events << RemotePacket.new(type, *args)
58
57
  end
59
-
58
+
60
59
  # Scripts the sending of a new channel request packet to the remote host.
61
60
  # +channel+ should be an instance of Net::SSH::Test::Channel. +request+
62
61
  # is a string naming the request type to send, +reply+ is a boolean
@@ -71,7 +70,7 @@ module Net
71
70
  #
72
71
  # This will typically be called via Net::SSH::Test::Channel#sends_exec or
73
72
  # Net::SSH::Test::Channel#sends_subsystem.
74
- def sends_channel_request(channel, request, reply, data, success=true)
73
+ def sends_channel_request(channel, request, reply, data, success = true)
75
74
  if data.is_a? Array
76
75
  events << LocalPacket.new(:channel_request, channel.remote_id, request, reply, *data)
77
76
  else
@@ -85,7 +84,7 @@ module Net
85
84
  end
86
85
  end
87
86
  end
88
-
87
+
89
88
  # Scripts the sending of a channel data packet. +channel+ must be a
90
89
  # Net::SSH::Test::Channel object, and +data+ is the (string) data to
91
90
  # expect will be sent.
@@ -94,21 +93,21 @@ module Net
94
93
  def sends_channel_data(channel, data)
95
94
  events << LocalPacket.new(:channel_data, channel.remote_id, data)
96
95
  end
97
-
96
+
98
97
  # Scripts the sending of a channel EOF packet from the given
99
98
  # Net::SSH::Test::Channel +channel+. This will typically be called via
100
99
  # Net::SSH::Test::Channel#sends_eof.
101
100
  def sends_channel_eof(channel)
102
101
  events << LocalPacket.new(:channel_eof, channel.remote_id)
103
102
  end
104
-
103
+
105
104
  # Scripts the sending of a channel close packet from the given
106
105
  # Net::SSH::Test::Channel +channel+. This will typically be called via
107
106
  # Net::SSH::Test::Channel#sends_close.
108
107
  def sends_channel_close(channel)
109
108
  events << LocalPacket.new(:channel_close, channel.remote_id)
110
109
  end
111
-
110
+
112
111
  # Scripts the sending of a channel request pty packets from the given
113
112
  # Net::SSH::Test::Channel +channel+. This will typically be called via
114
113
  # Net::SSH::Test::Channel#sends_request_pty.
@@ -117,14 +116,14 @@ module Net
117
116
  data += Net::SSH::Connection::Channel::VALID_PTY_OPTIONS.merge(modes: "\0").values
118
117
  events << LocalPacket.new(:channel_request, channel.remote_id, *data)
119
118
  end
120
-
119
+
121
120
  # Scripts the reception of a channel data packet from the remote host by
122
121
  # the given Net::SSH::Test::Channel +channel+. This will typically be
123
122
  # called via Net::SSH::Test::Channel#gets_data.
124
123
  def gets_channel_data(channel, data)
125
124
  events << RemotePacket.new(:channel_data, channel.local_id, data)
126
125
  end
127
-
126
+
128
127
  # Scripts the reception of a channel extended data packet from the remote
129
128
  # host by the given Net::SSH::Test::Channel +channel+. This will typically
130
129
  # be called via Net::SSH::Test::Channel#gets_extended_data.
@@ -133,28 +132,28 @@ module Net
133
132
  def gets_channel_extended_data(channel, data)
134
133
  events << RemotePacket.new(:channel_extended_data, channel.local_id, 1, data)
135
134
  end
136
-
135
+
137
136
  # Scripts the reception of a channel request packet from the remote host by
138
137
  # the given Net::SSH::Test::Channel +channel+. This will typically be
139
138
  # called via Net::SSH::Test::Channel#gets_exit_status.
140
139
  def gets_channel_request(channel, request, reply, data)
141
140
  events << RemotePacket.new(:channel_request, channel.local_id, request, reply, data)
142
141
  end
143
-
142
+
144
143
  # Scripts the reception of a channel EOF packet from the remote host by
145
144
  # the given Net::SSH::Test::Channel +channel+. This will typically be
146
145
  # called via Net::SSH::Test::Channel#gets_eof.
147
146
  def gets_channel_eof(channel)
148
147
  events << RemotePacket.new(:channel_eof, channel.local_id)
149
148
  end
150
-
149
+
151
150
  # Scripts the reception of a channel close packet from the remote host by
152
151
  # the given Net::SSH::Test::Channel +channel+. This will typically be
153
152
  # called via Net::SSH::Test::Channel#gets_close.
154
153
  def gets_channel_close(channel)
155
154
  events << RemotePacket.new(:channel_close, channel.local_id)
156
155
  end
157
-
156
+
158
157
  # By default, removes the next event in the list and returns it. However,
159
158
  # this can also be used to non-destructively peek at the next event in the
160
159
  # list, by passing :first as the argument.
@@ -164,10 +163,10 @@ module Net
164
163
  #
165
164
  # # peek at the next event
166
165
  # event = script.next(:first)
167
- def next(mode=:shift)
166
+ def next(mode = :shift)
168
167
  events.send(mode)
169
168
  end
170
-
169
+
171
170
  # Compare the given packet against the next event in the list. If there is
172
171
  # no next event, an exception will be raised. This is called by
173
172
  # Net::SSH::Test::Extensions::PacketStream#test_enqueue_packet.
@@ -176,7 +175,6 @@ module Net
176
175
  event.process(packet)
177
176
  end
178
177
  end
179
-
180
178
  end
181
179
  end
182
- end
180
+ end
@@ -3,66 +3,63 @@ require 'stringio'
3
3
  require 'net/ssh/test/extensions'
4
4
  require 'net/ssh/test/script'
5
5
 
6
- module Net
7
- module SSH
6
+ module Net
7
+ module SSH
8
8
  module Test
9
-
10
9
  # A mock socket implementation for use in testing. It implements the minimum
11
10
  # necessary interface for interacting with the rest of the Net::SSH::Test
12
11
  # system.
13
12
  class Socket < StringIO
14
13
  attr_reader :host, :port
15
-
14
+
16
15
  # The Net::SSH::Test::Script object in use by this socket. This is the
17
16
  # canonical script instance that should be used for any test depending on
18
17
  # this socket instance.
19
18
  attr_reader :script
20
-
19
+
21
20
  # Create a new test socket. This will also instantiate a new Net::SSH::Test::Script
22
21
  # and seed it with the necessary events to power the initialization of the
23
22
  # connection.
24
23
  def initialize
25
24
  extend(Net::SSH::Transport::PacketStream)
26
25
  super "SSH-2.0-Test\r\n"
27
-
26
+
28
27
  @script = Script.new
29
-
28
+
30
29
  script.sends(:kexinit)
31
30
  script.gets(:kexinit, 1, 2, 3, 4, "test", "ssh-rsa", "none", "none", "none", "none", "none", "none", "", "", false)
32
31
  script.sends(:newkeys)
33
32
  script.gets(:newkeys)
34
33
  end
35
-
34
+
36
35
  # This doesn't actually do anything, since we don't really care what gets
37
36
  # written.
38
37
  def write(data)
39
38
  # black hole, because we don't actually care about what gets written
40
39
  end
41
-
40
+
42
41
  # Allows the socket to also mimic a socket factory, simply returning
43
42
  # +self+.
44
- def open(host, port, options={})
43
+ def open(host, port, options = {})
45
44
  @host, @port = host, port
46
45
  self
47
46
  end
48
-
47
+
49
48
  # Returns a sockaddr struct for the port and host that were used when the
50
49
  # socket was instantiated.
51
50
  def getpeername
52
51
  ::Socket.sockaddr_in(port, host)
53
52
  end
54
-
53
+
55
54
  # Alias to #read, but never returns nil (returns an empty string instead).
56
55
  def recv(n)
57
56
  read(n) || ""
58
57
  end
59
-
58
+
60
59
  def readpartial(n)
61
60
  recv(n)
62
61
  end
63
-
64
62
  end
65
-
66
63
  end
67
64
  end
68
65
  end
data/lib/net/ssh/test.rb CHANGED
@@ -5,7 +5,6 @@ require 'net/ssh/test/socket'
5
5
 
6
6
  module Net
7
7
  module SSH
8
-
9
8
  # This module may be used in unit tests, for when you want to test that your
10
9
  # SSH state machines are really doing what you expect they are doing. You will
11
10
  # typically include this module in your unit test class, and then build a
@@ -57,21 +56,21 @@ module Net
57
56
 
58
57
  # Returns the test socket instance to use for these tests (see
59
58
  # Net::SSH::Test::Socket).
60
- def socket(options={})
59
+ def socket(options = {})
61
60
  @socket ||= Net::SSH::Test::Socket.new
62
61
  end
63
62
 
64
63
  # Returns the connection session (Net::SSH::Connection::Session) for use
65
64
  # in these tests. It is a fully functional SSH session, operating over
66
65
  # a mock socket (#socket).
67
- def connection(options={})
66
+ def connection(options = {})
68
67
  @connection ||= Net::SSH::Connection::Session.new(transport(options), options)
69
68
  end
70
69
 
71
70
  # Returns the transport session (Net::SSH::Transport::Session) for use
72
71
  # in these tests. It is a fully functional SSH transport session, operating
73
72
  # over a mock socket (#socket).
74
- def transport(options={})
73
+ def transport(options = {})
75
74
  @transport ||= Net::SSH::Transport::Session.new(
76
75
  options[:host] || "localhost",
77
76
  options.merge(kex: "test", host_key: "ssh-rsa", append_all_supported_algorithms: true, verify_host_key: :never, proxy: socket(options))
@@ -85,11 +84,11 @@ module Net
85
84
  # the block passed to this assertion.
86
85
  def assert_scripted
87
86
  raise "there is no script to be processed" if socket.script.events.empty?
87
+
88
88
  Net::SSH::Test::Extensions::IO.with_test_extension { yield }
89
89
  assert socket.script.events.empty?, "there should not be any remaining scripted events, but there are still" \
90
90
  "#{socket.script.events.length} pending"
91
91
  end
92
92
  end
93
-
94
93
  end
95
94
  end
@@ -0,0 +1,40 @@
1
+ require 'net/ssh/transport/hmac/abstract'
2
+ require 'net/ssh/transport/gcm_cipher'
3
+
4
+ module Net::SSH::Transport
5
+ ## Implements the aes128-gcm@openssh cipher
6
+ class AES128_GCM
7
+ extend ::Net::SSH::Transport::GCMCipher
8
+
9
+ ## Implicit HMAC, do need to do anything
10
+ class ImplicitHMac < ::Net::SSH::Transport::HMAC::Abstract
11
+ def aead
12
+ true
13
+ end
14
+
15
+ def key_length
16
+ 16
17
+ end
18
+ end
19
+
20
+ def implicit_mac
21
+ ImplicitHMac.new
22
+ end
23
+
24
+ def algo_name
25
+ 'aes-128-gcm'
26
+ end
27
+
28
+ def name
29
+ 'aes128-gcm@openssh.com'
30
+ end
31
+
32
+ #
33
+ # --- RFC 5647 ---
34
+ # K_LEN AES key length 16 octets
35
+ #
36
+ def self.key_length
37
+ 16
38
+ end
39
+ end
40
+ end