net-ssh 4.2.0 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) 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 +7 -0
  9. data/.rubocop.yml +19 -2
  10. data/.rubocop_todo.yml +619 -667
  11. data/CHANGES.txt +110 -1
  12. data/Dockerfile +27 -0
  13. data/Dockerfile.openssl3 +17 -0
  14. data/Gemfile +3 -7
  15. data/{Gemfile.norbnacl → Gemfile.noed25519} +3 -1
  16. data/Manifest +4 -5
  17. data/README.md +293 -0
  18. data/Rakefile +45 -29
  19. data/appveyor.yml +8 -6
  20. data/docker-compose.yml +23 -0
  21. data/lib/net/ssh/authentication/agent.rb +248 -223
  22. data/lib/net/ssh/authentication/certificate.rb +178 -164
  23. data/lib/net/ssh/authentication/constants.rb +17 -15
  24. data/lib/net/ssh/authentication/ed25519.rb +141 -116
  25. data/lib/net/ssh/authentication/ed25519_loader.rb +28 -28
  26. data/lib/net/ssh/authentication/key_manager.rb +79 -36
  27. data/lib/net/ssh/authentication/methods/abstract.rb +62 -47
  28. data/lib/net/ssh/authentication/methods/hostbased.rb +34 -37
  29. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +3 -3
  30. data/lib/net/ssh/authentication/methods/none.rb +16 -19
  31. data/lib/net/ssh/authentication/methods/password.rb +15 -16
  32. data/lib/net/ssh/authentication/methods/publickey.rb +96 -55
  33. data/lib/net/ssh/authentication/pageant.rb +468 -465
  34. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  35. data/lib/net/ssh/authentication/session.rb +131 -122
  36. data/lib/net/ssh/buffer.rb +385 -332
  37. data/lib/net/ssh/buffered_io.rb +150 -151
  38. data/lib/net/ssh/config.rb +316 -239
  39. data/lib/net/ssh/connection/channel.rb +635 -613
  40. data/lib/net/ssh/connection/constants.rb +29 -29
  41. data/lib/net/ssh/connection/event_loop.rb +104 -95
  42. data/lib/net/ssh/connection/keepalive.rb +55 -51
  43. data/lib/net/ssh/connection/session.rb +614 -611
  44. data/lib/net/ssh/connection/term.rb +125 -123
  45. data/lib/net/ssh/errors.rb +101 -99
  46. data/lib/net/ssh/key_factory.rb +194 -108
  47. data/lib/net/ssh/known_hosts.rb +212 -134
  48. data/lib/net/ssh/loggable.rb +50 -49
  49. data/lib/net/ssh/packet.rb +83 -79
  50. data/lib/net/ssh/prompt.rb +51 -51
  51. data/lib/net/ssh/proxy/command.rb +105 -91
  52. data/lib/net/ssh/proxy/errors.rb +12 -10
  53. data/lib/net/ssh/proxy/http.rb +81 -81
  54. data/lib/net/ssh/proxy/https.rb +37 -36
  55. data/lib/net/ssh/proxy/jump.rb +49 -48
  56. data/lib/net/ssh/proxy/socks4.rb +2 -6
  57. data/lib/net/ssh/proxy/socks5.rb +14 -17
  58. data/lib/net/ssh/service/forward.rb +365 -362
  59. data/lib/net/ssh/test/channel.rb +145 -143
  60. data/lib/net/ssh/test/extensions.rb +131 -127
  61. data/lib/net/ssh/test/kex.rb +34 -32
  62. data/lib/net/ssh/test/local_packet.rb +46 -44
  63. data/lib/net/ssh/test/packet.rb +87 -84
  64. data/lib/net/ssh/test/remote_packet.rb +32 -30
  65. data/lib/net/ssh/test/script.rb +155 -155
  66. data/lib/net/ssh/test/socket.rb +49 -48
  67. data/lib/net/ssh/test.rb +82 -80
  68. data/lib/net/ssh/transport/algorithms.rb +433 -364
  69. data/lib/net/ssh/transport/cipher_factory.rb +95 -91
  70. data/lib/net/ssh/transport/constants.rb +32 -24
  71. data/lib/net/ssh/transport/ctr.rb +37 -15
  72. data/lib/net/ssh/transport/hmac/abstract.rb +81 -63
  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 +14 -12
  86. data/lib/net/ssh/transport/identity_cipher.rb +54 -52
  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 +33 -40
  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 +112 -217
  94. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -63
  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 +36 -90
  97. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
  98. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
  99. data/lib/net/ssh/transport/kex.rb +15 -12
  100. data/lib/net/ssh/transport/key_expander.rb +24 -21
  101. data/lib/net/ssh/transport/openssl.rb +158 -133
  102. data/lib/net/ssh/transport/packet_stream.rb +223 -191
  103. data/lib/net/ssh/transport/server_version.rb +55 -56
  104. data/lib/net/ssh/transport/session.rb +306 -259
  105. data/lib/net/ssh/transport/state.rb +178 -176
  106. data/lib/net/ssh/verifiers/accept_new.rb +33 -0
  107. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
  108. data/lib/net/ssh/verifiers/always.rb +58 -0
  109. data/lib/net/ssh/verifiers/never.rb +19 -0
  110. data/lib/net/ssh/version.rb +55 -53
  111. data/lib/net/ssh.rb +47 -34
  112. data/net-ssh-public_cert.pem +18 -19
  113. data/net-ssh.gemspec +12 -11
  114. data/support/ssh_tunnel_bug.rb +5 -5
  115. data.tar.gz.sig +0 -0
  116. metadata +78 -73
  117. metadata.gz.sig +0 -0
  118. data/.travis.yml +0 -51
  119. data/Gemfile.norbnacl.lock +0 -41
  120. data/README.rdoc +0 -169
  121. data/lib/net/ssh/ruby_compat.rb +0 -24
  122. data/lib/net/ssh/verifiers/lenient.rb +0 -30
  123. data/lib/net/ssh/verifiers/null.rb +0 -12
  124. data/lib/net/ssh/verifiers/secure.rb +0 -52
  125. data/lib/net/ssh/verifiers/strict.rb +0 -24
  126. data/support/arcfour_check.rb +0 -20
@@ -1,145 +1,147 @@
1
- module Net; module SSH; module Test
2
-
3
- # A mock channel, used for scripting actions in tests. It wraps a
4
- # Net::SSH::Test::Script instance, and delegates to it for the most part.
5
- # This class has little real functionality on its own, but rather acts as
6
- # a convenience for scripting channel-related activity for later comparison
7
- # in a unit test.
8
- #
9
- # story do |session|
10
- # channel = session.opens_channel
11
- # channel.sends_exec "ls"
12
- # channel.gets_data "result of ls"
13
- # channel.gets_extended_data "some error coming from ls"
14
- # channel.gets_close
15
- # channel.sends_close
16
- # end
17
- class Channel
18
- # The Net::SSH::Test::Script instance employed by this mock channel.
19
- attr_reader :script
20
-
21
- # Sets the local-id of this channel object (the id assigned by the client).
22
- attr_writer :local_id
23
-
24
- # Sets the remote-id of this channel object (the id assigned by the mock-server).
25
- attr_writer :remote_id
26
-
27
- # Creates a new Test::Channel instance on top of the given +script+ (which
28
- # must be a Net::SSH::Test::Script instance).
29
- def initialize(script)
30
- @script = script
31
- @local_id = @remote_id = nil
32
- end
33
-
34
- # Returns the local (client-assigned) id for this channel, or a Proc object
35
- # that will return the local-id later if the local id has not yet been set.
36
- # (See Net::SSH::Test::Packet#instantiate!.)
37
- def local_id
38
- @local_id || Proc.new { @local_id or raise "local-id has not been set yet!" }
39
- end
40
-
41
- # Returns the remote (server-assigned) id for this channel, or a Proc object
42
- # that will return the remote-id later if the remote id has not yet been set.
43
- # (See Net::SSH::Test::Packet#instantiate!.)
44
- def remote_id
45
- @remote_id || Proc.new { @remote_id or raise "remote-id has not been set yet!" }
46
- end
47
-
48
- # Because adjacent calls to #gets_data will sometimes cause the data packets
49
- # to be concatenated (causing expectations in tests to fail), you may
50
- # need to separate those calls with calls to #inject_remote_delay! (which
51
- # essentially just mimics receiving an empty data packet):
52
- #
53
- # channel.gets_data "abcdefg"
54
- # channel.inject_remote_delay!
55
- # channel.gets_data "hijklmn"
56
- def inject_remote_delay!
57
- gets_data("")
58
- end
59
-
60
- # Scripts the sending of an "exec" channel request packet to the mock
61
- # server. If +reply+ is true, then the server is expected to reply to the
62
- # request, otherwise no response to this request will be sent. If +success+
63
- # is +true+, then the request will be successful, otherwise a failure will
64
- # be scripted.
65
- #
66
- # channel.sends_exec "ls -l"
67
- def sends_exec(command, reply=true, success=true)
68
- script.sends_channel_request(self, "exec", reply, command, success)
69
- end
70
-
71
- # Scripts the sending of a "subsystem" channel request packet to the mock
72
- # server. See #sends_exec for a discussion of the meaning of the +reply+
73
- # and +success+ arguments.
74
- #
75
- # channel.sends_subsystem "sftp"
76
- def sends_subsystem(subsystem, reply=true, success=true)
77
- script.sends_channel_request(self, "subsystem", reply, subsystem, success)
78
- end
79
-
80
- # Scripts the sending of a data packet across the channel.
81
- #
82
- # channel.sends_data "foo"
83
- def sends_data(data)
84
- script.sends_channel_data(self, data)
85
- end
86
-
87
- # Scripts the sending of an EOF packet across the channel.
88
- #
89
- # channel.sends_eof
90
- def sends_eof
91
- script.sends_channel_eof(self)
92
- end
93
-
94
- # Scripts the sending of a "channel close" packet across the channel.
95
- #
96
- # channel.sends_close
97
- def sends_close
98
- script.sends_channel_close(self)
99
- end
100
-
101
- # Scripts the sending of a "request pty" request packet across the channel.
102
- #
103
- # channel.sends_request_pty
104
- def sends_request_pty
105
- script.sends_channel_request_pty(self)
106
- end
107
-
108
- # Scripts the reception of a channel data packet from the remote end.
109
- #
110
- # channel.gets_data "bar"
111
- def gets_data(data)
112
- script.gets_channel_data(self, data)
113
- end
114
-
115
- # Scripts the reception of a channel extended data packet from the remote
116
- # end.
117
- #
118
- # channel.gets_extended_data "whoops"
119
- def gets_extended_data(data)
120
- script.gets_channel_extended_data(self, data)
121
- end
122
-
123
- # Scripts the reception of an "exit-status" channel request packet.
124
- #
125
- # channel.gets_exit_status(127)
126
- def gets_exit_status(status=0)
127
- script.gets_channel_request(self, "exit-status", false, status)
128
- end
129
-
130
- # Scripts the reception of an EOF packet from the remote end.
131
- #
132
- # channel.gets_eof
133
- def gets_eof
134
- script.gets_channel_eof(self)
135
- end
136
-
137
- # Scripts the reception of a "channel close" packet from the remote end.
138
- #
139
- # channel.gets_close
140
- def gets_close
141
- script.gets_channel_close(self)
1
+ module Net
2
+ module SSH
3
+ module Test
4
+ # A mock channel, used for scripting actions in tests. It wraps a
5
+ # Net::SSH::Test::Script instance, and delegates to it for the most part.
6
+ # This class has little real functionality on its own, but rather acts as
7
+ # a convenience for scripting channel-related activity for later comparison
8
+ # in a unit test.
9
+ #
10
+ # story do |session|
11
+ # channel = session.opens_channel
12
+ # channel.sends_exec "ls"
13
+ # channel.gets_data "result of ls"
14
+ # channel.gets_extended_data "some error coming from ls"
15
+ # channel.gets_close
16
+ # channel.sends_close
17
+ # end
18
+ class Channel
19
+ # The Net::SSH::Test::Script instance employed by this mock channel.
20
+ attr_reader :script
21
+
22
+ # Sets the local-id of this channel object (the id assigned by the client).
23
+ attr_writer :local_id
24
+
25
+ # Sets the remote-id of this channel object (the id assigned by the mock-server).
26
+ attr_writer :remote_id
27
+
28
+ # Creates a new Test::Channel instance on top of the given +script+ (which
29
+ # must be a Net::SSH::Test::Script instance).
30
+ def initialize(script)
31
+ @script = script
32
+ @local_id = @remote_id = nil
33
+ end
34
+
35
+ # Returns the local (client-assigned) id for this channel, or a Proc object
36
+ # that will return the local-id later if the local id has not yet been set.
37
+ # (See Net::SSH::Test::Packet#instantiate!.)
38
+ def local_id
39
+ @local_id || Proc.new { @local_id or raise "local-id has not been set yet!" }
40
+ end
41
+
42
+ # Returns the remote (server-assigned) id for this channel, or a Proc object
43
+ # that will return the remote-id later if the remote id has not yet been set.
44
+ # (See Net::SSH::Test::Packet#instantiate!.)
45
+ def remote_id
46
+ @remote_id || Proc.new { @remote_id or raise "remote-id has not been set yet!" }
47
+ end
48
+
49
+ # Because adjacent calls to #gets_data will sometimes cause the data packets
50
+ # to be concatenated (causing expectations in tests to fail), you may
51
+ # need to separate those calls with calls to #inject_remote_delay! (which
52
+ # essentially just mimics receiving an empty data packet):
53
+ #
54
+ # channel.gets_data "abcdefg"
55
+ # channel.inject_remote_delay!
56
+ # channel.gets_data "hijklmn"
57
+ def inject_remote_delay!
58
+ gets_data("")
59
+ end
60
+
61
+ # Scripts the sending of an "exec" channel request packet to the mock
62
+ # server. If +reply+ is true, then the server is expected to reply to the
63
+ # request, otherwise no response to this request will be sent. If +success+
64
+ # is +true+, then the request will be successful, otherwise a failure will
65
+ # be scripted.
66
+ #
67
+ # channel.sends_exec "ls -l"
68
+ def sends_exec(command, reply = true, success = true)
69
+ script.sends_channel_request(self, "exec", reply, command, success)
70
+ end
71
+
72
+ # Scripts the sending of a "subsystem" channel request packet to the mock
73
+ # server. See #sends_exec for a discussion of the meaning of the +reply+
74
+ # and +success+ arguments.
75
+ #
76
+ # channel.sends_subsystem "sftp"
77
+ def sends_subsystem(subsystem, reply = true, success = true)
78
+ script.sends_channel_request(self, "subsystem", reply, subsystem, success)
79
+ end
80
+
81
+ # Scripts the sending of a data packet across the channel.
82
+ #
83
+ # channel.sends_data "foo"
84
+ def sends_data(data)
85
+ script.sends_channel_data(self, data)
86
+ end
87
+
88
+ # Scripts the sending of an EOF packet across the channel.
89
+ #
90
+ # channel.sends_eof
91
+ def sends_eof
92
+ script.sends_channel_eof(self)
93
+ end
94
+
95
+ # Scripts the sending of a "channel close" packet across the channel.
96
+ #
97
+ # channel.sends_close
98
+ def sends_close
99
+ script.sends_channel_close(self)
100
+ end
101
+
102
+ # Scripts the sending of a "request pty" request packet across the channel.
103
+ #
104
+ # channel.sends_request_pty
105
+ def sends_request_pty
106
+ script.sends_channel_request_pty(self)
107
+ end
108
+
109
+ # Scripts the reception of a channel data packet from the remote end.
110
+ #
111
+ # channel.gets_data "bar"
112
+ def gets_data(data)
113
+ script.gets_channel_data(self, data)
114
+ end
115
+
116
+ # Scripts the reception of a channel extended data packet from the remote
117
+ # end.
118
+ #
119
+ # channel.gets_extended_data "whoops"
120
+ def gets_extended_data(data)
121
+ script.gets_channel_extended_data(self, data)
122
+ end
123
+
124
+ # Scripts the reception of an "exit-status" channel request packet.
125
+ #
126
+ # channel.gets_exit_status(127)
127
+ def gets_exit_status(status = 0)
128
+ script.gets_channel_request(self, "exit-status", false, status)
129
+ end
130
+
131
+ # Scripts the reception of an EOF packet from the remote end.
132
+ #
133
+ # channel.gets_eof
134
+ def gets_eof
135
+ script.gets_channel_eof(self)
136
+ end
137
+
138
+ # Scripts the reception of a "channel close" packet from the remote end.
139
+ #
140
+ # channel.gets_close
141
+ def gets_close
142
+ script.gets_channel_close(self)
143
+ end
144
+ end
142
145
  end
143
146
  end
144
-
145
- end; end; end
147
+ end
@@ -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
9
+ module Net
10
+ module SSH
11
+ module Test
12
+ # A collection of modules used to extend/override the default behavior of
13
+ # Net::SSH internals for ease of testing. As a consumer of Net::SSH, you'll
14
+ # never need to use this directly--they're all used under the covers by
15
+ # the Net::SSH::Test system.
16
+ module Extensions
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
35
25
 
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
26
+ # Set this to +true+ if you want the IO to pretend to be available for writing
27
+ attr_accessor :select_for_write
40
28
 
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?
29
+ # Set this to +true+ if you want the IO to pretend to be in an error state
30
+ attr_accessor :select_for_error
44
31
 
45
- base.send :alias_method, :real_enqueue_packet, :enqueue_packet
46
- base.send :alias_method, :enqueue_packet, :test_enqueue_packet
32
+ alias select_for_write? select_for_write
33
+ alias select_for_error? select_for_error
34
+ end
47
35
 
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
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
51
40
 
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)
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?
58
44
 
59
- if script.next(:first).remote?
60
- self.string << script.next.to_s
61
- self.pos = pos
62
- end
45
+ base.send :alias_method, :real_enqueue_packet, :enqueue_packet
46
+ base.send :alias_method, :enqueue_packet, :test_enqueue_packet
63
47
 
64
- return true
65
- end
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
66
51
 
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
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)
74
58
 
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
59
+ if script.next(:first).remote?
60
+ self.string << script.next.to_s
61
+ self.pos = pos
62
+ end
81
63
 
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
64
+ return true
65
+ end
91
66
 
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
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?
98
71
 
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
72
+ idle!
73
+ false
74
+ end
108
75
 
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
76
+ # The testing version of Net::SSH::Transport::PacketStream#enqueued_packet.
77
+ # Simply calls Net::SSH::Test::Script#process on the packet.
78
+ def test_enqueue_packet(payload)
79
+ packet = Net::SSH::Buffer.new(payload.to_s)
80
+ script.process(packet)
81
+ end
115
82
 
116
- @extension_enabled = false
83
+ # The testing version of Net::SSH::Transport::PacketStream#poll_next_packet.
84
+ # Reads the next available packet from the IO object and returns it.
85
+ def test_poll_next_packet
86
+ return nil if available <= 0
117
87
 
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
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
93
 
128
- def self.extension_enabled?
129
- @extension_enabled
130
- end
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
131
100
 
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
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
110
 
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]
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)
116
+ end
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
151
128
  end
152
129
 
153
- processed = 0
154
- Array(readers).each do |reader|
155
- processed += 1 if reader.idle!
130
+ def self.extension_enabled?
131
+ @extension_enabled
156
132
  end
157
133
 
158
- raise "no readers were ready for reading, and none had any incoming packets" if processed == 0 && wait != 0
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
+
148
+ ready_readers = Array(readers).select { |r| r.select_for_read? }
149
+ ready_writers = Array(writers).select { |r| r.select_for_write? }
150
+ ready_errors = Array(errors).select { |r| r.select_for_error? }
151
+
152
+ return [ready_readers, ready_writers, ready_errors] if ready_readers.any? || ready_writers.any? || ready_errors.any?
153
+
154
+ processed = 0
155
+ Array(readers).each do |reader|
156
+ processed += 1 if reader.idle!
157
+ end
158
+
159
+ raise "no readers were ready for reading, and none had any incoming packets" if processed == 0 && wait != 0
160
+
161
+ [[], [], []]
162
+ end
163
+ end
159
164
  end
160
165
  end
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)