net-ssh 3.2.0.rc2 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +2 -2
  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 +16 -0
  8. data/.gitignore +13 -0
  9. data/.rubocop.yml +22 -0
  10. data/.rubocop_todo.yml +1081 -0
  11. data/CHANGES.txt +228 -7
  12. data/Dockerfile +27 -0
  13. data/Dockerfile.openssl3 +17 -0
  14. data/Gemfile +13 -0
  15. data/Gemfile.noed25519 +12 -0
  16. data/ISSUE_TEMPLATE.md +30 -0
  17. data/Manifest +4 -5
  18. data/README.md +297 -0
  19. data/Rakefile +125 -74
  20. data/SECURITY.md +4 -0
  21. data/appveyor.yml +58 -0
  22. data/docker-compose.yml +23 -0
  23. data/lib/net/ssh/authentication/agent.rb +279 -18
  24. data/lib/net/ssh/authentication/certificate.rb +183 -0
  25. data/lib/net/ssh/authentication/constants.rb +17 -15
  26. data/lib/net/ssh/authentication/ed25519.rb +186 -0
  27. data/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
  28. data/lib/net/ssh/authentication/key_manager.rb +86 -39
  29. data/lib/net/ssh/authentication/methods/abstract.rb +67 -48
  30. data/lib/net/ssh/authentication/methods/hostbased.rb +34 -37
  31. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +13 -13
  32. data/lib/net/ssh/authentication/methods/none.rb +16 -19
  33. data/lib/net/ssh/authentication/methods/password.rb +27 -17
  34. data/lib/net/ssh/authentication/methods/publickey.rb +96 -55
  35. data/lib/net/ssh/authentication/pageant.rb +471 -367
  36. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  37. data/lib/net/ssh/authentication/session.rb +131 -121
  38. data/lib/net/ssh/buffer.rb +399 -300
  39. data/lib/net/ssh/buffered_io.rb +154 -150
  40. data/lib/net/ssh/config.rb +308 -185
  41. data/lib/net/ssh/connection/channel.rb +635 -613
  42. data/lib/net/ssh/connection/constants.rb +29 -29
  43. data/lib/net/ssh/connection/event_loop.rb +123 -0
  44. data/lib/net/ssh/connection/keepalive.rb +55 -51
  45. data/lib/net/ssh/connection/session.rb +620 -551
  46. data/lib/net/ssh/connection/term.rb +125 -123
  47. data/lib/net/ssh/errors.rb +101 -99
  48. data/lib/net/ssh/key_factory.rb +197 -105
  49. data/lib/net/ssh/known_hosts.rb +214 -127
  50. data/lib/net/ssh/loggable.rb +50 -49
  51. data/lib/net/ssh/packet.rb +83 -79
  52. data/lib/net/ssh/prompt.rb +50 -81
  53. data/lib/net/ssh/proxy/command.rb +105 -90
  54. data/lib/net/ssh/proxy/errors.rb +12 -10
  55. data/lib/net/ssh/proxy/http.rb +82 -79
  56. data/lib/net/ssh/proxy/https.rb +50 -0
  57. data/lib/net/ssh/proxy/jump.rb +54 -0
  58. data/lib/net/ssh/proxy/socks4.rb +2 -6
  59. data/lib/net/ssh/proxy/socks5.rb +14 -17
  60. data/lib/net/ssh/service/forward.rb +370 -317
  61. data/lib/net/ssh/test/channel.rb +145 -136
  62. data/lib/net/ssh/test/extensions.rb +131 -110
  63. data/lib/net/ssh/test/kex.rb +34 -32
  64. data/lib/net/ssh/test/local_packet.rb +46 -44
  65. data/lib/net/ssh/test/packet.rb +89 -70
  66. data/lib/net/ssh/test/remote_packet.rb +32 -30
  67. data/lib/net/ssh/test/script.rb +156 -142
  68. data/lib/net/ssh/test/socket.rb +49 -48
  69. data/lib/net/ssh/test.rb +82 -77
  70. data/lib/net/ssh/transport/algorithms.rb +441 -360
  71. data/lib/net/ssh/transport/cipher_factory.rb +96 -98
  72. data/lib/net/ssh/transport/constants.rb +32 -24
  73. data/lib/net/ssh/transport/ctr.rb +42 -22
  74. data/lib/net/ssh/transport/hmac/abstract.rb +81 -63
  75. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  76. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  77. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  78. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  79. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  80. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  81. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  82. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  83. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  84. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  85. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  86. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  87. data/lib/net/ssh/transport/hmac.rb +14 -12
  88. data/lib/net/ssh/transport/identity_cipher.rb +54 -52
  89. data/lib/net/ssh/transport/kex/abstract.rb +130 -0
  90. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  91. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  92. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  93. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +33 -40
  94. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  95. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +119 -213
  96. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -61
  97. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  98. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
  99. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
  100. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
  101. data/lib/net/ssh/transport/kex.rb +15 -12
  102. data/lib/net/ssh/transport/key_expander.rb +24 -20
  103. data/lib/net/ssh/transport/openssl.rb +161 -124
  104. data/lib/net/ssh/transport/packet_stream.rb +225 -185
  105. data/lib/net/ssh/transport/server_version.rb +55 -56
  106. data/lib/net/ssh/transport/session.rb +306 -255
  107. data/lib/net/ssh/transport/state.rb +178 -176
  108. data/lib/net/ssh/verifiers/accept_new.rb +33 -0
  109. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
  110. data/lib/net/ssh/verifiers/always.rb +58 -0
  111. data/lib/net/ssh/verifiers/never.rb +19 -0
  112. data/lib/net/ssh/version.rb +55 -53
  113. data/lib/net/ssh.rb +110 -47
  114. data/net-ssh-public_cert.pem +18 -18
  115. data/net-ssh.gemspec +36 -205
  116. data/support/ssh_tunnel_bug.rb +5 -5
  117. data.tar.gz.sig +0 -0
  118. metadata +153 -118
  119. metadata.gz.sig +0 -0
  120. data/.travis.yml +0 -18
  121. data/README.rdoc +0 -182
  122. data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
  123. data/lib/net/ssh/authentication/agent/socket.rb +0 -178
  124. data/lib/net/ssh/ruby_compat.rb +0 -46
  125. data/lib/net/ssh/verifiers/lenient.rb +0 -30
  126. data/lib/net/ssh/verifiers/null.rb +0 -12
  127. data/lib/net/ssh/verifiers/secure.rb +0 -52
  128. data/lib/net/ssh/verifiers/strict.rb +0 -24
  129. data/setup.rb +0 -1585
  130. data/support/arcfour_check.rb +0 -20
  131. data/test/README.txt +0 -18
  132. data/test/authentication/methods/common.rb +0 -28
  133. data/test/authentication/methods/test_abstract.rb +0 -51
  134. data/test/authentication/methods/test_hostbased.rb +0 -114
  135. data/test/authentication/methods/test_keyboard_interactive.rb +0 -121
  136. data/test/authentication/methods/test_none.rb +0 -41
  137. data/test/authentication/methods/test_password.rb +0 -95
  138. data/test/authentication/methods/test_publickey.rb +0 -148
  139. data/test/authentication/test_agent.rb +0 -232
  140. data/test/authentication/test_key_manager.rb +0 -240
  141. data/test/authentication/test_session.rb +0 -107
  142. data/test/common.rb +0 -125
  143. data/test/configs/auth_off +0 -5
  144. data/test/configs/auth_on +0 -4
  145. data/test/configs/empty +0 -0
  146. data/test/configs/eqsign +0 -3
  147. data/test/configs/exact_match +0 -8
  148. data/test/configs/host_plus +0 -10
  149. data/test/configs/multihost +0 -4
  150. data/test/configs/negative_match +0 -6
  151. data/test/configs/nohost +0 -19
  152. data/test/configs/numeric_host +0 -4
  153. data/test/configs/proxy_remote_user +0 -2
  154. data/test/configs/send_env +0 -2
  155. data/test/configs/substitutes +0 -8
  156. data/test/configs/wild_cards +0 -14
  157. data/test/connection/test_channel.rb +0 -487
  158. data/test/connection/test_session.rb +0 -564
  159. data/test/integration/README.txt +0 -17
  160. data/test/integration/Vagrantfile +0 -12
  161. data/test/integration/common.rb +0 -63
  162. data/test/integration/playbook.yml +0 -56
  163. data/test/integration/test_forward.rb +0 -637
  164. data/test/integration/test_id_rsa_keys.rb +0 -96
  165. data/test/integration/test_proxy.rb +0 -93
  166. data/test/known_hosts/github +0 -1
  167. data/test/known_hosts/github_hash +0 -1
  168. data/test/manual/test_pageant.rb +0 -37
  169. data/test/start/test_connection.rb +0 -53
  170. data/test/start/test_options.rb +0 -57
  171. data/test/start/test_transport.rb +0 -28
  172. data/test/start/test_user_nil.rb +0 -27
  173. data/test/test_all.rb +0 -12
  174. data/test/test_buffer.rb +0 -433
  175. data/test/test_buffered_io.rb +0 -63
  176. data/test/test_config.rb +0 -268
  177. data/test/test_key_factory.rb +0 -191
  178. data/test/test_known_hosts.rb +0 -66
  179. data/test/transport/hmac/test_md5.rb +0 -41
  180. data/test/transport/hmac/test_md5_96.rb +0 -27
  181. data/test/transport/hmac/test_none.rb +0 -34
  182. data/test/transport/hmac/test_ripemd160.rb +0 -36
  183. data/test/transport/hmac/test_sha1.rb +0 -36
  184. data/test/transport/hmac/test_sha1_96.rb +0 -27
  185. data/test/transport/hmac/test_sha2_256.rb +0 -37
  186. data/test/transport/hmac/test_sha2_256_96.rb +0 -27
  187. data/test/transport/hmac/test_sha2_512.rb +0 -37
  188. data/test/transport/hmac/test_sha2_512_96.rb +0 -27
  189. data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +0 -13
  190. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +0 -150
  191. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +0 -96
  192. data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +0 -19
  193. data/test/transport/kex/test_ecdh_sha2_nistp256.rb +0 -161
  194. data/test/transport/kex/test_ecdh_sha2_nistp384.rb +0 -38
  195. data/test/transport/kex/test_ecdh_sha2_nistp521.rb +0 -38
  196. data/test/transport/test_algorithms.rb +0 -328
  197. data/test/transport/test_cipher_factory.rb +0 -443
  198. data/test/transport/test_hmac.rb +0 -34
  199. data/test/transport/test_identity_cipher.rb +0 -40
  200. data/test/transport/test_packet_stream.rb +0 -1762
  201. data/test/transport/test_server_version.rb +0 -74
  202. data/test/transport/test_session.rb +0 -331
  203. data/test/transport/test_state.rb +0 -181
  204. data/test/verifiers/test_secure.rb +0 -40
@@ -2,205 +2,207 @@ require 'zlib'
2
2
  require 'net/ssh/transport/cipher_factory'
3
3
  require 'net/ssh/transport/hmac'
4
4
 
5
- module Net; module SSH; module Transport
6
-
7
- # Encapsulates state information about one end of an SSH connection. Such
8
- # state includes the packet sequence number, the algorithms in use, how
9
- # many packets and blocks have been processed since the last reset, and so
10
- # forth. This class will never be instantiated directly, but is used as
11
- # part of the internal state of the PacketStream module.
12
- class State
13
- # The socket object that owns this state object.
14
- attr_reader :socket
15
-
16
- # The next packet sequence number for this socket endpoint.
17
- attr_reader :sequence_number
18
-
19
- # The hmac algorithm in use for this endpoint.
20
- attr_reader :hmac
21
-
22
- # The compression algorithm in use for this endpoint.
23
- attr_reader :compression
24
-
25
- # The compression level to use when compressing data (or nil, for the default).
26
- attr_reader :compression_level
27
-
28
- # The number of packets processed since the last call to #reset!
29
- attr_reader :packets
30
-
31
- # The number of data blocks processed since the last call to #reset!
32
- attr_reader :blocks
33
-
34
- # The cipher algorithm in use for this socket endpoint.
35
- attr_reader :cipher
36
-
37
- # The block size for the cipher
38
- attr_reader :block_size
39
-
40
- # The role that this state plays (either :client or :server)
41
- attr_reader :role
42
-
43
- # The maximum number of packets that this endpoint wants to process before
44
- # needing a rekey.
45
- attr_accessor :max_packets
46
-
47
- # The maximum number of blocks that this endpoint wants to process before
48
- # needing a rekey.
49
- attr_accessor :max_blocks
50
-
51
- # The user-specified maximum number of bytes that this endpoint ought to
52
- # process before needing a rekey.
53
- attr_accessor :rekey_limit
54
-
55
- # Creates a new state object, belonging to the given socket. Initializes
56
- # the algorithms to "none".
57
- def initialize(socket, role)
58
- @socket = socket
59
- @role = role
60
- @sequence_number = @packets = @blocks = 0
61
- @cipher = CipherFactory.get("none")
62
- @block_size = 8
63
- @hmac = HMAC.get("none")
64
- @compression = nil
65
- @compressor = @decompressor = nil
66
- @next_iv = ""
67
- end
5
+ module Net
6
+ module SSH
7
+ module Transport
8
+ # Encapsulates state information about one end of an SSH connection. Such
9
+ # state includes the packet sequence number, the algorithms in use, how
10
+ # many packets and blocks have been processed since the last reset, and so
11
+ # forth. This class will never be instantiated directly, but is used as
12
+ # part of the internal state of the PacketStream module.
13
+ class State
14
+ # The socket object that owns this state object.
15
+ attr_reader :socket
16
+
17
+ # The next packet sequence number for this socket endpoint.
18
+ attr_reader :sequence_number
19
+
20
+ # The hmac algorithm in use for this endpoint.
21
+ attr_reader :hmac
22
+
23
+ # The compression algorithm in use for this endpoint.
24
+ attr_reader :compression
25
+
26
+ # The compression level to use when compressing data (or nil, for the default).
27
+ attr_reader :compression_level
28
+
29
+ # The number of packets processed since the last call to #reset!
30
+ attr_reader :packets
31
+
32
+ # The number of data blocks processed since the last call to #reset!
33
+ attr_reader :blocks
34
+
35
+ # The cipher algorithm in use for this socket endpoint.
36
+ attr_reader :cipher
37
+
38
+ # The block size for the cipher
39
+ attr_reader :block_size
40
+
41
+ # The role that this state plays (either :client or :server)
42
+ attr_reader :role
43
+
44
+ # The maximum number of packets that this endpoint wants to process before
45
+ # needing a rekey.
46
+ attr_accessor :max_packets
47
+
48
+ # The maximum number of blocks that this endpoint wants to process before
49
+ # needing a rekey.
50
+ attr_accessor :max_blocks
51
+
52
+ # The user-specified maximum number of bytes that this endpoint ought to
53
+ # process before needing a rekey.
54
+ attr_accessor :rekey_limit
55
+
56
+ # Creates a new state object, belonging to the given socket. Initializes
57
+ # the algorithms to "none".
58
+ def initialize(socket, role)
59
+ @socket = socket
60
+ @role = role
61
+ @sequence_number = @packets = @blocks = 0
62
+ @cipher = CipherFactory.get("none")
63
+ @block_size = 8
64
+ @hmac = HMAC.get("none")
65
+ @compression = nil
66
+ @compressor = @decompressor = nil
67
+ @next_iv = String.new
68
+ end
68
69
 
69
- # A convenience method for quickly setting multiple values in a single
70
- # command.
71
- def set(values)
72
- values.each do |key, value|
73
- instance_variable_set("@#{key}", value)
74
- end
75
- reset!
76
- end
70
+ # A convenience method for quickly setting multiple values in a single
71
+ # command.
72
+ def set(values)
73
+ values.each do |key, value|
74
+ instance_variable_set("@#{key}", value)
75
+ end
76
+ reset!
77
+ end
77
78
 
78
- def update_cipher(data)
79
- result = cipher.update(data)
80
- update_next_iv(role == :client ? result : data)
81
- return result
82
- end
79
+ def update_cipher(data)
80
+ result = cipher.update(data)
81
+ update_next_iv(role == :client ? result : data)
82
+ return result
83
+ end
83
84
 
84
- def final_cipher
85
- result = cipher.final
86
- update_next_iv(role == :client ? result : "", true)
87
- return result
88
- end
85
+ def final_cipher
86
+ result = cipher.final
87
+ update_next_iv(role == :client ? result : "", true)
88
+ return result
89
+ end
89
90
 
90
- # Increments the counters. The sequence number is incremented (and remapped
91
- # so it always fits in a 32-bit integer). The number of packets and blocks
92
- # are also incremented.
93
- def increment(packet_length)
94
- @sequence_number = (@sequence_number + 1) & 0xFFFFFFFF
95
- @packets += 1
96
- @blocks += (packet_length + 4) / @block_size
97
- end
91
+ # Increments the counters. The sequence number is incremented (and remapped
92
+ # so it always fits in a 32-bit integer). The number of packets and blocks
93
+ # are also incremented.
94
+ def increment(packet_length)
95
+ @sequence_number = (@sequence_number + 1) & 0xFFFFFFFF
96
+ @packets += 1
97
+ @blocks += (packet_length + 4) / @block_size
98
+ end
98
99
 
99
- # The compressor object to use when compressing data. This takes into account
100
- # the desired compression level.
101
- def compressor
102
- @compressor ||= Zlib::Deflate.new(compression_level || Zlib::DEFAULT_COMPRESSION)
103
- end
100
+ # The compressor object to use when compressing data. This takes into account
101
+ # the desired compression level.
102
+ def compressor
103
+ @compressor ||= Zlib::Deflate.new(compression_level || Zlib::DEFAULT_COMPRESSION)
104
+ end
104
105
 
105
- # The decompressor object to use when decompressing data.
106
- def decompressor
107
- @decompressor ||= Zlib::Inflate.new(nil)
108
- end
106
+ # The decompressor object to use when decompressing data.
107
+ def decompressor
108
+ @decompressor ||= Zlib::Inflate.new(nil)
109
+ end
109
110
 
110
- # Returns true if data compression/decompression is enabled. This will
111
- # return true if :standard compression is selected, or if :delayed
112
- # compression is selected and the :authenticated hint has been received
113
- # by the socket.
114
- def compression?
115
- compression == :standard || (compression == :delayed && socket.hints[:authenticated])
116
- end
111
+ # Returns true if data compression/decompression is enabled. This will
112
+ # return true if :standard compression is selected, or if :delayed
113
+ # compression is selected and the :authenticated hint has been received
114
+ # by the socket.
115
+ def compression?
116
+ compression == :standard || (compression == :delayed && socket.hints[:authenticated])
117
+ end
117
118
 
118
- # Compresses the data. If no compression is in effect, this will just return
119
- # the data unmodified, otherwise it uses #compressor to compress the data.
120
- def compress(data)
121
- data = data.to_s
122
- return data unless compression?
123
- compressor.deflate(data, Zlib::SYNC_FLUSH)
124
- end
119
+ # Compresses the data. If no compression is in effect, this will just return
120
+ # the data unmodified, otherwise it uses #compressor to compress the data.
121
+ def compress(data)
122
+ data = data.to_s
123
+ return data unless compression?
125
124
 
126
- # Deompresses the data. If no compression is in effect, this will just return
127
- # the data unmodified, otherwise it uses #decompressor to decompress the data.
128
- def decompress(data)
129
- data = data.to_s
130
- return data unless compression?
131
- decompressor.inflate(data)
132
- end
125
+ compressor.deflate(data, Zlib::SYNC_FLUSH)
126
+ end
133
127
 
134
- # Resets the counters on the state object, but leaves the sequence_number
135
- # unchanged. It also sets defaults for and recomputes the max_packets and
136
- # max_blocks values.
137
- def reset!
138
- @packets = @blocks = 0
128
+ # Deompresses the data. If no compression is in effect, this will just return
129
+ # the data unmodified, otherwise it uses #decompressor to decompress the data.
130
+ def decompress(data)
131
+ data = data.to_s
132
+ return data unless compression?
139
133
 
140
- @max_packets ||= 1 << 31
134
+ decompressor.inflate(data)
135
+ end
141
136
 
142
- @block_size = cipher.name == "RC4" ? 8 : cipher.block_size
137
+ # Resets the counters on the state object, but leaves the sequence_number
138
+ # unchanged. It also sets defaults for and recomputes the max_packets and
139
+ # max_blocks values.
140
+ def reset!
141
+ @packets = @blocks = 0
143
142
 
144
- if max_blocks.nil?
145
- # cargo-culted from openssh. the idea is that "the 2^(blocksize*2)
146
- # limit is too expensive for 3DES, blowfish, etc., so enforce a 1GB
147
- # limit for small blocksizes."
148
- if @block_size >= 16
149
- @max_blocks = 1 << (@block_size * 2)
150
- else
151
- @max_blocks = (1 << 30) / @block_size
152
- end
143
+ @max_packets ||= 1 << 31
153
144
 
154
- # if a limit on the # of bytes has been given, convert that into a
155
- # minimum number of blocks processed.
145
+ @block_size = cipher.block_size
156
146
 
157
- if rekey_limit
158
- @max_blocks = [@max_blocks, rekey_limit / @block_size].min
159
- end
160
- end
147
+ if max_blocks.nil?
148
+ # cargo-culted from openssh. the idea is that "the 2^(blocksize*2)
149
+ # limit is too expensive for 3DES, blowfish, etc., so enforce a 1GB
150
+ # limit for small blocksizes."
151
+ if @block_size >= 16
152
+ @max_blocks = 1 << (@block_size * 2)
153
+ else
154
+ @max_blocks = (1 << 30) / @block_size
155
+ end
161
156
 
162
- cleanup
163
- end
157
+ # if a limit on the # of bytes has been given, convert that into a
158
+ # minimum number of blocks processed.
164
159
 
165
- # Closes any the compressor and/or decompressor objects that have been
166
- # instantiated.
167
- def cleanup
168
- if @compressor
169
- @compressor.finish if !@compressor.finished?
170
- @compressor.close
171
- end
160
+ @max_blocks = [@max_blocks, rekey_limit / @block_size].min if rekey_limit
161
+ end
172
162
 
173
- if @decompressor
174
- # we call reset here so that we don't get warnings when we try to
175
- # close the decompressor
176
- @decompressor.reset
177
- @decompressor.close
178
- end
163
+ cleanup
164
+ end
179
165
 
180
- @compressor = @decompressor = nil
181
- end
166
+ # Closes any the compressor and/or decompressor objects that have been
167
+ # instantiated.
168
+ def cleanup
169
+ if @compressor
170
+ @compressor.finish if !@compressor.finished?
171
+ @compressor.close
172
+ end
173
+
174
+ if @decompressor
175
+ # we call reset here so that we don't get warnings when we try to
176
+ # close the decompressor
177
+ @decompressor.reset
178
+ @decompressor.close
179
+ end
180
+
181
+ @compressor = @decompressor = nil
182
+ end
182
183
 
183
- # Returns true if the number of packets processed exceeds the maximum
184
- # number of packets, or if the number of blocks processed exceeds the
185
- # maximum number of blocks.
186
- def needs_rekey?
187
- max_packets && packets > max_packets ||
188
- max_blocks && blocks > max_blocks
189
- end
184
+ # Returns true if the number of packets processed exceeds the maximum
185
+ # number of packets, or if the number of blocks processed exceeds the
186
+ # maximum number of blocks.
187
+ def needs_rekey?
188
+ max_packets && packets > max_packets ||
189
+ max_blocks && blocks > max_blocks
190
+ end
190
191
 
191
- private
192
+ private
192
193
 
193
- def update_next_iv(data, reset=false)
194
- @next_iv << data
195
- @next_iv = @next_iv[-cipher.iv_len..-1]
194
+ def update_next_iv(data, reset = false)
195
+ @next_iv << data
196
+ @next_iv = @next_iv[@next_iv.size - cipher.iv_len..-1]
196
197
 
197
- if reset
198
- cipher.reset
199
- cipher.iv = @next_iv
200
- end
198
+ if reset
199
+ cipher.reset
200
+ cipher.iv = @next_iv
201
+ end
201
202
 
202
- return data
203
+ return data
204
+ end
203
205
  end
206
+ end
204
207
  end
205
-
206
- end; end; end
208
+ end
@@ -0,0 +1,33 @@
1
+ require 'net/ssh/errors'
2
+ require 'net/ssh/known_hosts'
3
+ require 'net/ssh/verifiers/always'
4
+
5
+ module Net
6
+ module SSH
7
+ module Verifiers
8
+ # Does a strict host verification, looking the server up in the known
9
+ # host files to see if a key has already been seen for this server. If this
10
+ # server does not appear in any host file, this will silently add the
11
+ # server. If the server does appear at least once, but the key given does
12
+ # not match any known for the server, an exception will be raised (HostKeyMismatch).
13
+ # Otherwise, this returns true.
14
+ class AcceptNew < Always
15
+ def verify(arguments)
16
+ begin
17
+ super
18
+ rescue HostKeyUnknown => err
19
+ err.remember_host!
20
+ return true
21
+ end
22
+ end
23
+
24
+ def verify_signature(&block)
25
+ yield
26
+ rescue HostKeyUnknown => err
27
+ err.remember_host!
28
+ return true
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ require 'net/ssh/verifiers/accept_new'
2
+
3
+ module Net
4
+ module SSH
5
+ module Verifiers
6
+ # Basically the same as the AcceptNew verifier, but does not try to actually
7
+ # verify a connection if the server is the localhost and the port is a
8
+ # nonstandard port number. Those two conditions will typically mean the
9
+ # connection is being tunnelled through a forwarded port, so the known-hosts
10
+ # file will not be helpful (in general).
11
+ class AcceptNewOrLocalTunnel < AcceptNew
12
+ # Tries to determine if the connection is being tunnelled, and if so,
13
+ # returns true. Otherwise, performs the standard strict verification.
14
+ def verify(arguments)
15
+ return true if tunnelled?(arguments)
16
+
17
+ super
18
+ end
19
+
20
+ private
21
+
22
+ # A connection is potentially being tunnelled if the port is not 22,
23
+ # and the ip refers to the localhost.
24
+ def tunnelled?(args)
25
+ return false if args[:session].port == Net::SSH::Transport::Session::DEFAULT_PORT
26
+
27
+ ip = args[:session].peer[:ip]
28
+ return ip == "127.0.0.1" || ip == "::1"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,58 @@
1
+ require 'net/ssh/errors'
2
+ require 'net/ssh/known_hosts'
3
+
4
+ module Net
5
+ module SSH
6
+ module Verifiers
7
+ # Does a strict host verification, looking the server up in the known
8
+ # host files to see if a key has already been seen for this server. If this
9
+ # server does not appear in any host file, an exception will be raised
10
+ # (HostKeyUnknown). This is in contrast to the "Strict" class, which will
11
+ # silently add the key to your known_hosts file. If the server does appear at
12
+ # least once, but the key given does not match any known for the server, an
13
+ # exception will be raised (HostKeyMismatch).
14
+ # Otherwise, this returns true.
15
+ class Always
16
+ def verify(arguments)
17
+ host_keys = arguments[:session].host_keys
18
+
19
+ # We've never seen this host before, so raise an exception.
20
+ process_cache_miss(host_keys, arguments, HostKeyUnknown, "is unknown") if host_keys.empty?
21
+
22
+ # If we found any matches, check to see that the key type and
23
+ # blob also match.
24
+
25
+ found = host_keys.any? do |key|
26
+ if key.respond_to?(:matches_key?)
27
+ key.matches_key?(arguments[:key])
28
+ else
29
+ key.ssh_type == arguments[:key].ssh_type && key.to_blob == arguments[:key].to_blob
30
+ end
31
+ end
32
+
33
+ # If a match was found, return true. Otherwise, raise an exception
34
+ # indicating that the key was not recognized.
35
+ process_cache_miss(host_keys, arguments, HostKeyMismatch, "does not match") unless found
36
+
37
+ found
38
+ end
39
+
40
+ def verify_signature(&block)
41
+ yield
42
+ end
43
+
44
+ private
45
+
46
+ def process_cache_miss(host_keys, args, exc_class, message)
47
+ exception = exc_class.new("fingerprint #{args[:fingerprint]} " +
48
+ "#{message} for #{host_keys.host.inspect}")
49
+ exception.data = args
50
+ exception.callback = Proc.new do
51
+ host_keys.add_host_key(args[:key])
52
+ end
53
+ raise exception
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,19 @@
1
+ module Net
2
+ module SSH
3
+ module Verifiers
4
+ # This host key verifier simply allows every key it sees, without
5
+ # any verification. This is simple, but very insecure because it
6
+ # exposes you to MiTM attacks.
7
+ class Never
8
+ # Returns true.
9
+ def verify(arguments)
10
+ true
11
+ end
12
+
13
+ def verify_signature(&block)
14
+ true
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,66 +1,68 @@
1
- module Net; module SSH
2
- # A class for describing the current version of a library. The version
3
- # consists of three parts: the +major+ number, the +minor+ number, and the
4
- # +tiny+ (or +patch+) number.
5
- #
6
- # Two Version instances may be compared, so that you can test that a version
7
- # of a library is what you require:
8
- #
9
- # require 'net/ssh/version'
10
- #
11
- # if Net::SSH::Version::CURRENT < Net::SSH::Version[2,1,0]
12
- # abort "your software is too old!"
13
- # end
14
- class Version
15
- include Comparable
1
+ module Net
2
+ module SSH
3
+ # A class for describing the current version of a library. The version
4
+ # consists of three parts: the +major+ number, the +minor+ number, and the
5
+ # +tiny+ (or +patch+) number.
6
+ #
7
+ # Two Version instances may be compared, so that you can test that a version
8
+ # of a library is what you require:
9
+ #
10
+ # require 'net/ssh/version'
11
+ #
12
+ # if Net::SSH::Version::CURRENT < Net::SSH::Version[2,1,0]
13
+ # abort "your software is too old!"
14
+ # end
15
+ class Version
16
+ include Comparable
16
17
 
17
- # A convenience method for instantiating a new Version instance with the
18
- # given +major+, +minor+, and +tiny+ components.
19
- def self.[](major, minor, tiny, pre = nil)
20
- new(major, minor, tiny, pre)
21
- end
18
+ # A convenience method for instantiating a new Version instance with the
19
+ # given +major+, +minor+, and +tiny+ components.
20
+ def self.[](major, minor, tiny, pre = nil)
21
+ new(major, minor, tiny, pre)
22
+ end
22
23
 
23
- attr_reader :major, :minor, :tiny
24
+ attr_reader :major, :minor, :tiny
24
25
 
25
- # Create a new Version object with the given components.
26
- def initialize(major, minor, tiny, pre = nil)
27
- @major, @minor, @tiny, @pre = major, minor, tiny, pre
28
- end
26
+ # Create a new Version object with the given components.
27
+ def initialize(major, minor, tiny, pre = nil)
28
+ @major, @minor, @tiny, @pre = major, minor, tiny, pre
29
+ end
29
30
 
30
- # Compare this version to the given +version+ object.
31
- def <=>(version)
32
- to_i <=> version.to_i
33
- end
31
+ # Compare this version to the given +version+ object.
32
+ def <=>(version)
33
+ to_i <=> version.to_i
34
+ end
34
35
 
35
- # Converts this version object to a string, where each of the three
36
- # version components are joined by the '.' character. E.g., 2.0.0.
37
- def to_s
38
- @to_s ||= [@major, @minor, @tiny, @pre].compact.join(".")
39
- end
36
+ # Converts this version object to a string, where each of the three
37
+ # version components are joined by the '.' character. E.g., 2.0.0.
38
+ def to_s
39
+ @to_s ||= [@major, @minor, @tiny, @pre].compact.join(".")
40
+ end
40
41
 
41
- # Converts this version to a canonical integer that may be compared
42
- # against other version objects.
43
- def to_i
44
- @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
45
- end
42
+ # Converts this version to a canonical integer that may be compared
43
+ # against other version objects.
44
+ def to_i
45
+ @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
46
+ end
46
47
 
47
- # The major component of this version of the Net::SSH library
48
- MAJOR = 3
48
+ # The major component of this version of the Net::SSH library
49
+ MAJOR = 7
49
50
 
50
- # The minor component of this version of the Net::SSH library
51
- MINOR = 2
51
+ # The minor component of this version of the Net::SSH library
52
+ MINOR = 1
52
53
 
53
- # The tiny component of this version of the Net::SSH library
54
- TINY = 0
54
+ # The tiny component of this version of the Net::SSH library
55
+ TINY = 0
55
56
 
56
- # The prerelease component of this version of the Net::SSH library
57
- # nil allowed
58
- PRE = "rc2"
57
+ # The prerelease component of this version of the Net::SSH library
58
+ # nil allowed
59
+ PRE = nil
59
60
 
60
- # The current version of the Net::SSH library as a Version instance
61
- CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
61
+ # The current version of the Net::SSH library as a Version instance
62
+ CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
62
63
 
63
- # The current version of the Net::SSH library as a String
64
- STRING = CURRENT.to_s
64
+ # The current version of the Net::SSH library as a String
65
+ STRING = CURRENT.to_s
66
+ end
65
67
  end
66
- end; end
68
+ end