net-ssh 4.1.0 → 6.1.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 (111) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +5 -0
  5. data/.rubocop.yml +8 -2
  6. data/.rubocop_todo.yml +405 -552
  7. data/.travis.yml +23 -22
  8. data/CHANGES.txt +112 -1
  9. data/Gemfile +1 -7
  10. data/{Gemfile.norbnacl → Gemfile.noed25519} +1 -1
  11. data/Manifest +4 -5
  12. data/README.md +287 -0
  13. data/Rakefile +40 -29
  14. data/appveyor.yml +12 -6
  15. data/lib/net/ssh.rb +68 -32
  16. data/lib/net/ssh/authentication/agent.rb +234 -222
  17. data/lib/net/ssh/authentication/certificate.rb +175 -164
  18. data/lib/net/ssh/authentication/constants.rb +17 -14
  19. data/lib/net/ssh/authentication/ed25519.rb +162 -141
  20. data/lib/net/ssh/authentication/ed25519_loader.rb +32 -29
  21. data/lib/net/ssh/authentication/key_manager.rb +40 -9
  22. data/lib/net/ssh/authentication/methods/abstract.rb +53 -47
  23. data/lib/net/ssh/authentication/methods/hostbased.rb +32 -33
  24. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +1 -1
  25. data/lib/net/ssh/authentication/methods/none.rb +10 -10
  26. data/lib/net/ssh/authentication/methods/password.rb +13 -13
  27. data/lib/net/ssh/authentication/methods/publickey.rb +56 -55
  28. data/lib/net/ssh/authentication/pageant.rb +468 -465
  29. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  30. data/lib/net/ssh/authentication/session.rb +130 -122
  31. data/lib/net/ssh/buffer.rb +345 -312
  32. data/lib/net/ssh/buffered_io.rb +163 -163
  33. data/lib/net/ssh/config.rb +316 -238
  34. data/lib/net/ssh/connection/channel.rb +670 -650
  35. data/lib/net/ssh/connection/constants.rb +30 -26
  36. data/lib/net/ssh/connection/event_loop.rb +108 -105
  37. data/lib/net/ssh/connection/keepalive.rb +54 -50
  38. data/lib/net/ssh/connection/session.rb +682 -671
  39. data/lib/net/ssh/connection/term.rb +180 -176
  40. data/lib/net/ssh/errors.rb +101 -99
  41. data/lib/net/ssh/key_factory.rb +195 -108
  42. data/lib/net/ssh/known_hosts.rb +161 -152
  43. data/lib/net/ssh/loggable.rb +57 -55
  44. data/lib/net/ssh/packet.rb +82 -78
  45. data/lib/net/ssh/prompt.rb +55 -53
  46. data/lib/net/ssh/proxy/command.rb +104 -89
  47. data/lib/net/ssh/proxy/errors.rb +12 -8
  48. data/lib/net/ssh/proxy/http.rb +93 -91
  49. data/lib/net/ssh/proxy/https.rb +42 -39
  50. data/lib/net/ssh/proxy/jump.rb +50 -47
  51. data/lib/net/ssh/proxy/socks4.rb +0 -2
  52. data/lib/net/ssh/proxy/socks5.rb +11 -12
  53. data/lib/net/ssh/service/forward.rb +370 -317
  54. data/lib/net/ssh/test.rb +83 -77
  55. data/lib/net/ssh/test/channel.rb +146 -142
  56. data/lib/net/ssh/test/extensions.rb +150 -146
  57. data/lib/net/ssh/test/kex.rb +35 -31
  58. data/lib/net/ssh/test/local_packet.rb +48 -44
  59. data/lib/net/ssh/test/packet.rb +87 -84
  60. data/lib/net/ssh/test/remote_packet.rb +35 -31
  61. data/lib/net/ssh/test/script.rb +173 -171
  62. data/lib/net/ssh/test/socket.rb +59 -55
  63. data/lib/net/ssh/transport/algorithms.rb +430 -364
  64. data/lib/net/ssh/transport/cipher_factory.rb +95 -91
  65. data/lib/net/ssh/transport/constants.rb +33 -25
  66. data/lib/net/ssh/transport/ctr.rb +33 -11
  67. data/lib/net/ssh/transport/hmac.rb +15 -13
  68. data/lib/net/ssh/transport/hmac/abstract.rb +82 -63
  69. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  70. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  71. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  72. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  73. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  74. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  75. data/lib/net/ssh/transport/identity_cipher.rb +55 -51
  76. data/lib/net/ssh/transport/kex.rb +14 -13
  77. data/lib/net/ssh/transport/kex/abstract.rb +123 -0
  78. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  79. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +38 -0
  80. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  81. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +33 -40
  82. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +112 -217
  83. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -62
  84. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  85. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
  86. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
  87. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
  88. data/lib/net/ssh/transport/key_expander.rb +29 -25
  89. data/lib/net/ssh/transport/openssl.rb +116 -116
  90. data/lib/net/ssh/transport/packet_stream.rb +223 -190
  91. data/lib/net/ssh/transport/server_version.rb +64 -66
  92. data/lib/net/ssh/transport/session.rb +306 -257
  93. data/lib/net/ssh/transport/state.rb +198 -196
  94. data/lib/net/ssh/verifiers/accept_new.rb +35 -0
  95. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +34 -0
  96. data/lib/net/ssh/verifiers/always.rb +56 -0
  97. data/lib/net/ssh/verifiers/never.rb +21 -0
  98. data/lib/net/ssh/version.rb +55 -53
  99. data/net-ssh-public_cert.pem +18 -19
  100. data/net-ssh.gemspec +12 -11
  101. data/support/ssh_tunnel_bug.rb +2 -2
  102. metadata +86 -75
  103. metadata.gz.sig +0 -0
  104. data/Gemfile.norbnacl.lock +0 -41
  105. data/README.rdoc +0 -169
  106. data/lib/net/ssh/ruby_compat.rb +0 -24
  107. data/lib/net/ssh/verifiers/lenient.rb +0 -30
  108. data/lib/net/ssh/verifiers/null.rb +0 -12
  109. data/lib/net/ssh/verifiers/secure.rb +0 -52
  110. data/lib/net/ssh/verifiers/strict.rb +0 -24
  111. data/support/arcfour_check.rb +0 -20
@@ -6,162 +6,166 @@ 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; module SSH; module Test
10
-
11
- # A collection of modules used to extend/override the default behavior of
12
- # Net::SSH internals for ease of testing. As a consumer of Net::SSH, you'll
13
- # never need to use this directly--they're all used under the covers by
14
- # the Net::SSH::Test system.
15
- module Extensions
16
-
17
- # An extension to Net::SSH::BufferedIo (assumes that the underlying IO
18
- # is actually a StringIO). Facilitates unit testing.
19
- module BufferedIo
20
- # Returns +true+ if the position in the stream is less than the total
21
- # length of the stream.
22
- def select_for_read?
23
- pos < size
24
- end
25
-
26
- # Set this to +true+ if you want the IO to pretend to be available for writing
27
- attr_accessor :select_for_write
28
-
29
- # Set this to +true+ if you want the IO to pretend to be in an error state
30
- attr_accessor :select_for_error
31
-
32
- alias select_for_write? select_for_write
33
- alias select_for_error? select_for_error
34
- end
35
-
36
- # An extension to Net::SSH::Transport::PacketStream (assumes that the
37
- # underlying IO is actually a StringIO). Facilitates unit testing.
38
- module PacketStream
39
- include BufferedIo # make sure we get the extensions here, too
40
-
41
- def self.included(base) #:nodoc:
42
- base.send :alias_method, :real_available_for_read?, :available_for_read?
43
- base.send :alias_method, :available_for_read?, :test_available_for_read?
44
-
45
- base.send :alias_method, :real_enqueue_packet, :enqueue_packet
46
- base.send :alias_method, :enqueue_packet, :test_enqueue_packet
47
-
48
- base.send :alias_method, :real_poll_next_packet, :poll_next_packet
49
- base.send :alias_method, :poll_next_packet, :test_poll_next_packet
50
- end
51
-
52
- # Called when another packet should be inspected from the current
53
- # script. If the next packet is a remote packet, it pops it off the
54
- # script and shoves it onto this IO object, making it available to
55
- # be read.
56
- def idle!
57
- return false unless script.next(:first)
58
-
59
- if script.next(:first).remote?
60
- self.string << script.next.to_s
61
- self.pos = pos
9
+ module Net
10
+ module SSH
11
+ module Test
12
+
13
+ # A collection of modules used to extend/override the default behavior of
14
+ # Net::SSH internals for ease of testing. As a consumer of Net::SSH, you'll
15
+ # never need to use this directly--they're all used under the covers by
16
+ # the Net::SSH::Test system.
17
+ module Extensions
18
+
19
+ # An extension to Net::SSH::BufferedIo (assumes that the underlying IO
20
+ # is actually a StringIO). Facilitates unit testing.
21
+ module BufferedIo
22
+ # Returns +true+ if the position in the stream is less than the total
23
+ # length of the stream.
24
+ def select_for_read?
25
+ pos < size
26
+ end
27
+
28
+ # Set this to +true+ if you want the IO to pretend to be available for writing
29
+ attr_accessor :select_for_write
30
+
31
+ # Set this to +true+ if you want the IO to pretend to be in an error state
32
+ attr_accessor :select_for_error
33
+
34
+ alias select_for_write? select_for_write
35
+ alias select_for_error? select_for_error
62
36
  end
63
-
64
- return true
65
- end
66
-
67
- # The testing version of Net::SSH::Transport::PacketStream#available_for_read?.
68
- # Returns true if there is data pending to be read. Otherwise calls #idle!.
69
- def test_available_for_read?
70
- return true if select_for_read?
71
- idle!
72
- false
73
- end
74
-
75
- # The testing version of Net::SSH::Transport::PacketStream#enqueued_packet.
76
- # Simply calls Net::SSH::Test::Script#process on the packet.
77
- def test_enqueue_packet(payload)
78
- packet = Net::SSH::Buffer.new(payload.to_s)
79
- script.process(packet)
80
- end
81
-
82
- # The testing version of Net::SSH::Transport::PacketStream#poll_next_packet.
83
- # Reads the next available packet from the IO object and returns it.
84
- def test_poll_next_packet
85
- return nil if available <= 0
86
- packet = Net::SSH::Buffer.new(read_available(4))
87
- length = packet.read_long
88
- Net::SSH::Packet.new(read_available(length))
89
- end
90
- end
91
-
92
- # An extension to Net::SSH::Connection::Channel. Facilitates unit testing.
93
- module Channel
94
- def self.included(base) #:nodoc:
95
- base.send :alias_method, :send_data_for_real, :send_data
96
- base.send :alias_method, :send_data, :send_data_for_test
97
- end
98
-
99
- # The testing version of Net::SSH::Connection::Channel#send_data. Calls
100
- # the original implementation, and then immediately enqueues the data for
101
- # output so that scripted sends are properly interpreted as discrete
102
- # (rather than concatenated) data packets.
103
- def send_data_for_test(data)
104
- send_data_for_real(data)
105
- enqueue_pending_output
106
- end
107
- end
108
-
109
- # An extension to the built-in ::IO class. Simply redefines IO.select
110
- # so that it can be scripted in Net::SSH unit tests.
111
- module IO
112
- def self.included(base) #:nodoc:
113
- base.extend(ClassMethods)
114
- end
115
-
116
- @extension_enabled = false
117
-
118
- def self.with_test_extension(&block)
119
- orig_value = @extension_enabled
120
- @extension_enabled = true
121
- begin
122
- yield
123
- ensure
124
- @extension_enabled = orig_value
37
+
38
+ # An extension to Net::SSH::Transport::PacketStream (assumes that the
39
+ # underlying IO is actually a StringIO). Facilitates unit testing.
40
+ module PacketStream
41
+ include BufferedIo # make sure we get the extensions here, too
42
+
43
+ def self.included(base) #:nodoc:
44
+ base.send :alias_method, :real_available_for_read?, :available_for_read?
45
+ base.send :alias_method, :available_for_read?, :test_available_for_read?
46
+
47
+ base.send :alias_method, :real_enqueue_packet, :enqueue_packet
48
+ base.send :alias_method, :enqueue_packet, :test_enqueue_packet
49
+
50
+ base.send :alias_method, :real_poll_next_packet, :poll_next_packet
51
+ base.send :alias_method, :poll_next_packet, :test_poll_next_packet
52
+ end
53
+
54
+ # Called when another packet should be inspected from the current
55
+ # script. If the next packet is a remote packet, it pops it off the
56
+ # script and shoves it onto this IO object, making it available to
57
+ # be read.
58
+ def idle!
59
+ return false unless script.next(:first)
60
+
61
+ if script.next(:first).remote?
62
+ self.string << script.next.to_s
63
+ self.pos = pos
64
+ end
65
+
66
+ return true
67
+ end
68
+
69
+ # The testing version of Net::SSH::Transport::PacketStream#available_for_read?.
70
+ # Returns true if there is data pending to be read. Otherwise calls #idle!.
71
+ def test_available_for_read?
72
+ return true if select_for_read?
73
+ idle!
74
+ false
75
+ end
76
+
77
+ # The testing version of Net::SSH::Transport::PacketStream#enqueued_packet.
78
+ # Simply calls Net::SSH::Test::Script#process on the packet.
79
+ def test_enqueue_packet(payload)
80
+ packet = Net::SSH::Buffer.new(payload.to_s)
81
+ script.process(packet)
82
+ end
83
+
84
+ # The testing version of Net::SSH::Transport::PacketStream#poll_next_packet.
85
+ # Reads the next available packet from the IO object and returns it.
86
+ def test_poll_next_packet
87
+ return nil if available <= 0
88
+ packet = Net::SSH::Buffer.new(read_available(4))
89
+ length = packet.read_long
90
+ Net::SSH::Packet.new(read_available(length))
91
+ end
125
92
  end
126
- end
127
-
128
- def self.extension_enabled?
129
- @extension_enabled
130
- end
131
-
132
- module ClassMethods
133
- def self.extended(obj) #:nodoc:
134
- class <<obj
135
- alias_method :select_for_real, :select
136
- alias_method :select, :select_for_test
93
+
94
+ # An extension to Net::SSH::Connection::Channel. Facilitates unit testing.
95
+ module Channel
96
+ def self.included(base) #:nodoc:
97
+ base.send :alias_method, :send_data_for_real, :send_data
98
+ base.send :alias_method, :send_data, :send_data_for_test
99
+ end
100
+
101
+ # The testing version of Net::SSH::Connection::Channel#send_data. Calls
102
+ # the original implementation, and then immediately enqueues the data for
103
+ # output so that scripted sends are properly interpreted as discrete
104
+ # (rather than concatenated) data packets.
105
+ def send_data_for_test(data)
106
+ send_data_for_real(data)
107
+ enqueue_pending_output
137
108
  end
138
109
  end
139
-
140
- # The testing version of ::IO.select. Assumes that all readers,
141
- # writers, and errors arrays are either nil, or contain only objects
142
- # that mix in Net::SSH::Test::Extensions::BufferedIo.
143
- def select_for_test(readers=nil, writers=nil, errors=nil, wait=nil)
144
- return select_for_real(readers, writers, errors, wait) unless Net::SSH::Test::Extensions::IO.extension_enabled?
145
- ready_readers = Array(readers).select { |r| r.select_for_read? }
146
- ready_writers = Array(writers).select { |r| r.select_for_write? }
147
- ready_errors = Array(errors).select { |r| r.select_for_error? }
148
-
149
- if ready_readers.any? || ready_writers.any? || ready_errors.any?
150
- return [ready_readers, ready_writers, ready_errors]
110
+
111
+ # An extension to the built-in ::IO class. Simply redefines IO.select
112
+ # so that it can be scripted in Net::SSH unit tests.
113
+ module IO
114
+ def self.included(base) #:nodoc:
115
+ base.extend(ClassMethods)
151
116
  end
152
-
153
- processed = 0
154
- Array(readers).each do |reader|
155
- processed += 1 if reader.idle!
117
+
118
+ @extension_enabled = false
119
+
120
+ def self.with_test_extension(&block)
121
+ orig_value = @extension_enabled
122
+ @extension_enabled = true
123
+ begin
124
+ yield
125
+ ensure
126
+ @extension_enabled = orig_value
127
+ end
128
+ end
129
+
130
+ def self.extension_enabled?
131
+ @extension_enabled
132
+ end
133
+
134
+ module ClassMethods
135
+ def self.extended(obj) #:nodoc:
136
+ class <<obj
137
+ alias_method :select_for_real, :select
138
+ alias_method :select, :select_for_test
139
+ end
140
+ end
141
+
142
+ # The testing version of ::IO.select. Assumes that all readers,
143
+ # writers, and errors arrays are either nil, or contain only objects
144
+ # that mix in Net::SSH::Test::Extensions::BufferedIo.
145
+ def select_for_test(readers=nil, writers=nil, errors=nil, wait=nil)
146
+ return select_for_real(readers, writers, errors, wait) unless Net::SSH::Test::Extensions::IO.extension_enabled?
147
+ ready_readers = Array(readers).select { |r| r.select_for_read? }
148
+ ready_writers = Array(writers).select { |r| r.select_for_write? }
149
+ ready_errors = Array(errors).select { |r| r.select_for_error? }
150
+
151
+ return [ready_readers, ready_writers, ready_errors] if ready_readers.any? || ready_writers.any? || ready_errors.any?
152
+
153
+ processed = 0
154
+ Array(readers).each do |reader|
155
+ processed += 1 if reader.idle!
156
+ end
157
+
158
+ raise "no readers were ready for reading, and none had any incoming packets" if processed == 0 && wait != 0
159
+
160
+ [[], [], []]
161
+ end
156
162
  end
157
-
158
- raise "no readers were ready for reading, and none had any incoming packets" if processed == 0
159
163
  end
160
164
  end
165
+
161
166
  end
162
167
  end
163
-
164
- end; end; end
168
+ end
165
169
 
166
170
  Net::SSH::BufferedIo.send(:include, Net::SSH::Test::Extensions::BufferedIo)
167
171
  Net::SSH::Transport::PacketStream.send(:include, Net::SSH::Test::Extensions::PacketStream)
@@ -5,40 +5,44 @@ require 'net/ssh/transport/algorithms'
5
5
  require 'net/ssh/transport/constants'
6
6
  require 'net/ssh/transport/kex'
7
7
 
8
- module Net; module SSH; module Test
8
+ module Net
9
+ module SSH
10
+ module Test
11
+
12
+ # An implementation of a key-exchange strategy specifically for unit tests.
13
+ # (This strategy would never really work against a real SSH server--it makes
14
+ # too many assumptions about the server's response.)
15
+ #
16
+ # This registers itself with the transport key-exchange system as the
17
+ # "test" algorithm.
18
+ class Kex
19
+ include Net::SSH::Transport::Constants
20
+
21
+ # Creates a new instance of the testing key-exchange algorithm with the
22
+ # given arguments.
23
+ def initialize(algorithms, connection, data)
24
+ @connection = connection
25
+ end
26
+
27
+ # Exchange keys with the server. This returns a hash of constant values,
28
+ # and does not actually exchange keys.
29
+ def exchange_keys
30
+ result = Net::SSH::Buffer.from(:byte, NEWKEYS)
31
+ @connection.send_message(result)
32
+
33
+ buffer = @connection.next_message
34
+ raise Net::SSH::Exception, "expected NEWKEYS" unless buffer.type == NEWKEYS
35
+
36
+ { session_id: "abc-xyz",
37
+ server_key: OpenSSL::PKey::RSA.new(512),
38
+ shared_secret: OpenSSL::BN.new("1234567890", 10),
39
+ hashing_algorithm: OpenSSL::Digest::SHA1 }
40
+ end
41
+ end
9
42
 
10
- # An implementation of a key-exchange strategy specifically for unit tests.
11
- # (This strategy would never really work against a real SSH server--it makes
12
- # too many assumptions about the server's response.)
13
- #
14
- # This registers itself with the transport key-exchange system as the
15
- # "test" algorithm.
16
- class Kex
17
- include Net::SSH::Transport::Constants
18
-
19
- # Creates a new instance of the testing key-exchange algorithm with the
20
- # given arguments.
21
- def initialize(algorithms, connection, data)
22
- @connection = connection
23
- end
24
-
25
- # Exchange keys with the server. This returns a hash of constant values,
26
- # and does not actually exchange keys.
27
- def exchange_keys
28
- result = Net::SSH::Buffer.from(:byte, NEWKEYS)
29
- @connection.send_message(result)
30
-
31
- buffer = @connection.next_message
32
- raise Net::SSH::Exception, "expected NEWKEYS" unless buffer.type == NEWKEYS
33
-
34
- { session_id: "abc-xyz",
35
- server_key: OpenSSL::PKey::RSA.new(512),
36
- shared_secret: OpenSSL::BN.new("1234567890", 10),
37
- hashing_algorithm: OpenSSL::Digest::SHA1 }
38
43
  end
39
44
  end
40
-
41
- end; end; end
45
+ end
42
46
 
43
47
  Net::SSH::Transport::Algorithms::ALGORITHMS[:kex] << "test"
44
48
  Net::SSH::Transport::Kex::MAP["test"] = Net::SSH::Test::Kex
@@ -1,51 +1,55 @@
1
1
  require 'net/ssh/packet'
2
2
  require 'net/ssh/test/packet'
3
3
 
4
- module Net; module SSH; module Test
5
-
6
- # This is a specialization of Net::SSH::Test::Packet for representing mock
7
- # packets that are sent from the local (client) host. These are created
8
- # automatically by Net::SSH::Test::Script and Net::SSH::Test::Channel by any
9
- # of the sends_* methods.
10
- class LocalPacket < Packet
11
- attr_reader :init
12
-
13
- # Extend the default Net::SSH::Test::Packet constructor to also accept an
14
- # optional block, which is used to finalize the initialization of the
15
- # packet when #process is first called.
16
- def initialize(type, *args, &block)
17
- super(type, *args)
18
- @init = block
19
- end
20
-
21
- # Returns +true+; this is a local packet.
22
- def local?
23
- true
24
- end
25
-
26
- # Called by Net::SSH::Test::Extensions::PacketStream#test_enqueue_packet
27
- # to mimic remote processing of a locally-sent packet. It compares the
28
- # packet it was given with the contents of this LocalPacket's data, to see
29
- # if what was sent matches what was scripted. If it differs in any way,
30
- # an exception is raised.
31
- def process(packet)
32
- @init.call(Net::SSH::Packet.new(packet.to_s)) if @init
33
- type = packet.read_byte
34
- raise "expected #{@type}, but got #{type}" if @type != type
35
-
36
- @data.zip(types).each do |expected, _type|
37
- _type ||= case expected
38
- when nil then break
39
- when Numeric then :long
40
- when String then :string
41
- when TrueClass, FalseClass then :bool
4
+ module Net
5
+ module SSH
6
+ module Test
7
+
8
+ # This is a specialization of Net::SSH::Test::Packet for representing mock
9
+ # packets that are sent from the local (client) host. These are created
10
+ # automatically by Net::SSH::Test::Script and Net::SSH::Test::Channel by any
11
+ # of the sends_* methods.
12
+ class LocalPacket < Packet
13
+ attr_reader :init
14
+
15
+ # Extend the default Net::SSH::Test::Packet constructor to also accept an
16
+ # optional block, which is used to finalize the initialization of the
17
+ # packet when #process is first called.
18
+ def initialize(type, *args, &block)
19
+ super(type, *args)
20
+ @init = block
21
+ end
22
+
23
+ # Returns +true+; this is a local packet.
24
+ def local?
25
+ true
26
+ end
27
+
28
+ # Called by Net::SSH::Test::Extensions::PacketStream#test_enqueue_packet
29
+ # to mimic remote processing of a locally-sent packet. It compares the
30
+ # packet it was given with the contents of this LocalPacket's data, to see
31
+ # if what was sent matches what was scripted. If it differs in any way,
32
+ # an exception is raised.
33
+ def process(packet)
34
+ @init.call(Net::SSH::Packet.new(packet.to_s)) if @init
35
+ type = packet.read_byte
36
+ raise "expected #{@type}, but got #{type}" if @type != type
37
+
38
+ @data.zip(types).each do |expected, _type|
39
+ _type ||= case expected
40
+ when nil then break
41
+ when Numeric then :long
42
+ when String then :string
43
+ when TrueClass, FalseClass then :bool
44
+ end
45
+
46
+ actual = packet.send("read_#{_type}")
47
+ next if expected.nil?
48
+ raise "expected #{_type} #{expected.inspect} but got #{actual.inspect}" unless expected == actual
42
49
  end
43
-
44
- actual = packet.send("read_#{_type}")
45
- next if expected.nil?
46
- raise "expected #{_type} #{expected.inspect} but got #{actual.inspect}" unless expected == actual
50
+ end
47
51
  end
52
+
48
53
  end
49
54
  end
50
-
51
- end; end; end
55
+ end