net-ssh 5.0.0.beta1 → 5.0.0.beta2

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 (87) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.rubocop_todo.yml +98 -258
  5. data/CHANGES.txt +8 -0
  6. data/Gemfile +1 -3
  7. data/Rakefile +37 -39
  8. data/lib/net/ssh.rb +26 -25
  9. data/lib/net/ssh/authentication/agent.rb +228 -225
  10. data/lib/net/ssh/authentication/certificate.rb +166 -164
  11. data/lib/net/ssh/authentication/constants.rb +17 -14
  12. data/lib/net/ssh/authentication/ed25519.rb +107 -104
  13. data/lib/net/ssh/authentication/ed25519_loader.rb +32 -28
  14. data/lib/net/ssh/authentication/key_manager.rb +5 -3
  15. data/lib/net/ssh/authentication/methods/abstract.rb +53 -47
  16. data/lib/net/ssh/authentication/methods/hostbased.rb +32 -33
  17. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -4
  18. data/lib/net/ssh/authentication/methods/none.rb +10 -10
  19. data/lib/net/ssh/authentication/methods/password.rb +13 -13
  20. data/lib/net/ssh/authentication/methods/publickey.rb +54 -55
  21. data/lib/net/ssh/authentication/pageant.rb +468 -465
  22. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +44 -0
  23. data/lib/net/ssh/authentication/session.rb +127 -123
  24. data/lib/net/ssh/buffer.rb +305 -303
  25. data/lib/net/ssh/buffered_io.rb +163 -162
  26. data/lib/net/ssh/config.rb +230 -227
  27. data/lib/net/ssh/connection/channel.rb +659 -654
  28. data/lib/net/ssh/connection/constants.rb +30 -26
  29. data/lib/net/ssh/connection/event_loop.rb +108 -104
  30. data/lib/net/ssh/connection/keepalive.rb +54 -50
  31. data/lib/net/ssh/connection/session.rb +677 -678
  32. data/lib/net/ssh/connection/term.rb +180 -176
  33. data/lib/net/ssh/errors.rb +101 -99
  34. data/lib/net/ssh/key_factory.rb +108 -108
  35. data/lib/net/ssh/known_hosts.rb +148 -154
  36. data/lib/net/ssh/loggable.rb +56 -54
  37. data/lib/net/ssh/packet.rb +82 -78
  38. data/lib/net/ssh/prompt.rb +55 -53
  39. data/lib/net/ssh/proxy/command.rb +103 -102
  40. data/lib/net/ssh/proxy/errors.rb +12 -8
  41. data/lib/net/ssh/proxy/http.rb +92 -91
  42. data/lib/net/ssh/proxy/https.rb +42 -39
  43. data/lib/net/ssh/proxy/jump.rb +50 -47
  44. data/lib/net/ssh/proxy/socks4.rb +0 -2
  45. data/lib/net/ssh/proxy/socks5.rb +11 -11
  46. data/lib/net/ssh/ruby_compat.rb +1 -0
  47. data/lib/net/ssh/service/forward.rb +364 -362
  48. data/lib/net/ssh/test.rb +85 -83
  49. data/lib/net/ssh/test/channel.rb +146 -142
  50. data/lib/net/ssh/test/extensions.rb +148 -146
  51. data/lib/net/ssh/test/kex.rb +35 -31
  52. data/lib/net/ssh/test/local_packet.rb +48 -44
  53. data/lib/net/ssh/test/packet.rb +87 -84
  54. data/lib/net/ssh/test/remote_packet.rb +35 -31
  55. data/lib/net/ssh/test/script.rb +173 -171
  56. data/lib/net/ssh/test/socket.rb +59 -55
  57. data/lib/net/ssh/transport/algorithms.rb +413 -412
  58. data/lib/net/ssh/transport/cipher_factory.rb +108 -105
  59. data/lib/net/ssh/transport/constants.rb +35 -31
  60. data/lib/net/ssh/transport/ctr.rb +1 -1
  61. data/lib/net/ssh/transport/hmac.rb +1 -1
  62. data/lib/net/ssh/transport/hmac/abstract.rb +67 -64
  63. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +1 -1
  64. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +1 -1
  65. data/lib/net/ssh/transport/identity_cipher.rb +55 -51
  66. data/lib/net/ssh/transport/kex.rb +2 -4
  67. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +47 -40
  68. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +201 -197
  69. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -56
  70. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +94 -87
  71. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +17 -10
  72. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +17 -10
  73. data/lib/net/ssh/transport/key_expander.rb +29 -25
  74. data/lib/net/ssh/transport/openssl.rb +17 -30
  75. data/lib/net/ssh/transport/packet_stream.rb +193 -192
  76. data/lib/net/ssh/transport/server_version.rb +64 -66
  77. data/lib/net/ssh/transport/session.rb +286 -284
  78. data/lib/net/ssh/transport/state.rb +198 -196
  79. data/lib/net/ssh/verifiers/lenient.rb +29 -25
  80. data/lib/net/ssh/verifiers/null.rb +13 -9
  81. data/lib/net/ssh/verifiers/secure.rb +45 -45
  82. data/lib/net/ssh/verifiers/strict.rb +20 -16
  83. data/lib/net/ssh/version.rb +55 -53
  84. data/net-ssh.gemspec +4 -4
  85. data/support/ssh_tunnel_bug.rb +2 -2
  86. metadata +25 -24
  87. metadata.gz.sig +0 -0
@@ -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
68
-
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
77
-
78
- def update_cipher(data)
79
- result = cipher.update(data)
80
- update_next_iv(role == :client ? result : data)
81
- return result
82
- end
83
-
84
- def final_cipher
85
- result = cipher.final
86
- update_next_iv(role == :client ? result : "", true)
87
- return result
88
- end
89
-
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
98
-
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
104
-
105
- # The decompressor object to use when decompressing data.
106
- def decompressor
107
- @decompressor ||= Zlib::Inflate.new(nil)
108
- end
109
-
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
117
-
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
125
-
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
133
-
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
139
-
140
- @max_packets ||= 1 << 31
141
-
142
- @block_size = cipher.name == "RC4" ? 8 : cipher.block_size
143
-
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
5
+ module Net
6
+ module SSH
7
+ module Transport
8
+
9
+ # Encapsulates state information about one end of an SSH connection. Such
10
+ # state includes the packet sequence number, the algorithms in use, how
11
+ # many packets and blocks have been processed since the last reset, and so
12
+ # forth. This class will never be instantiated directly, but is used as
13
+ # part of the internal state of the PacketStream module.
14
+ class State
15
+ # The socket object that owns this state object.
16
+ attr_reader :socket
17
+
18
+ # The next packet sequence number for this socket endpoint.
19
+ attr_reader :sequence_number
20
+
21
+ # The hmac algorithm in use for this endpoint.
22
+ attr_reader :hmac
23
+
24
+ # The compression algorithm in use for this endpoint.
25
+ attr_reader :compression
26
+
27
+ # The compression level to use when compressing data (or nil, for the default).
28
+ attr_reader :compression_level
29
+
30
+ # The number of packets processed since the last call to #reset!
31
+ attr_reader :packets
32
+
33
+ # The number of data blocks processed since the last call to #reset!
34
+ attr_reader :blocks
35
+
36
+ # The cipher algorithm in use for this socket endpoint.
37
+ attr_reader :cipher
38
+
39
+ # The block size for the cipher
40
+ attr_reader :block_size
41
+
42
+ # The role that this state plays (either :client or :server)
43
+ attr_reader :role
44
+
45
+ # The maximum number of packets that this endpoint wants to process before
46
+ # needing a rekey.
47
+ attr_accessor :max_packets
48
+
49
+ # The maximum number of blocks that this endpoint wants to process before
50
+ # needing a rekey.
51
+ attr_accessor :max_blocks
52
+
53
+ # The user-specified maximum number of bytes that this endpoint ought to
54
+ # process before needing a rekey.
55
+ attr_accessor :rekey_limit
56
+
57
+ # Creates a new state object, belonging to the given socket. Initializes
58
+ # the algorithms to "none".
59
+ def initialize(socket, role)
60
+ @socket = socket
61
+ @role = role
62
+ @sequence_number = @packets = @blocks = 0
63
+ @cipher = CipherFactory.get("none")
64
+ @block_size = 8
65
+ @hmac = HMAC.get("none")
66
+ @compression = nil
67
+ @compressor = @decompressor = nil
68
+ @next_iv = ""
152
69
  end
153
-
154
- # if a limit on the # of bytes has been given, convert that into a
155
- # minimum number of blocks processed.
156
-
157
- if rekey_limit
158
- @max_blocks = [@max_blocks, rekey_limit / @block_size].min
70
+
71
+ # A convenience method for quickly setting multiple values in a single
72
+ # command.
73
+ def set(values)
74
+ values.each do |key, value|
75
+ instance_variable_set("@#{key}", value)
76
+ end
77
+ reset!
78
+ end
79
+
80
+ def update_cipher(data)
81
+ result = cipher.update(data)
82
+ update_next_iv(role == :client ? result : data)
83
+ return result
84
+ end
85
+
86
+ def final_cipher
87
+ result = cipher.final
88
+ update_next_iv(role == :client ? result : "", true)
89
+ return result
90
+ end
91
+
92
+ # Increments the counters. The sequence number is incremented (and remapped
93
+ # so it always fits in a 32-bit integer). The number of packets and blocks
94
+ # are also incremented.
95
+ def increment(packet_length)
96
+ @sequence_number = (@sequence_number + 1) & 0xFFFFFFFF
97
+ @packets += 1
98
+ @blocks += (packet_length + 4) / @block_size
99
+ end
100
+
101
+ # The compressor object to use when compressing data. This takes into account
102
+ # the desired compression level.
103
+ def compressor
104
+ @compressor ||= Zlib::Deflate.new(compression_level || Zlib::DEFAULT_COMPRESSION)
105
+ end
106
+
107
+ # The decompressor object to use when decompressing data.
108
+ def decompressor
109
+ @decompressor ||= Zlib::Inflate.new(nil)
110
+ end
111
+
112
+ # Returns true if data compression/decompression is enabled. This will
113
+ # return true if :standard compression is selected, or if :delayed
114
+ # compression is selected and the :authenticated hint has been received
115
+ # by the socket.
116
+ def compression?
117
+ compression == :standard || (compression == :delayed && socket.hints[:authenticated])
118
+ end
119
+
120
+ # Compresses the data. If no compression is in effect, this will just return
121
+ # the data unmodified, otherwise it uses #compressor to compress the data.
122
+ def compress(data)
123
+ data = data.to_s
124
+ return data unless compression?
125
+ compressor.deflate(data, Zlib::SYNC_FLUSH)
126
+ end
127
+
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?
133
+ decompressor.inflate(data)
134
+ end
135
+
136
+ # Resets the counters on the state object, but leaves the sequence_number
137
+ # unchanged. It also sets defaults for and recomputes the max_packets and
138
+ # max_blocks values.
139
+ def reset!
140
+ @packets = @blocks = 0
141
+
142
+ @max_packets ||= 1 << 31
143
+
144
+ @block_size = cipher.name == "RC4" ? 8 : cipher.block_size
145
+
146
+ if max_blocks.nil?
147
+ # cargo-culted from openssh. the idea is that "the 2^(blocksize*2)
148
+ # limit is too expensive for 3DES, blowfish, etc., so enforce a 1GB
149
+ # limit for small blocksizes."
150
+ if @block_size >= 16
151
+ @max_blocks = 1 << (@block_size * 2)
152
+ else
153
+ @max_blocks = (1 << 30) / @block_size
154
+ end
155
+
156
+ # if a limit on the # of bytes has been given, convert that into a
157
+ # minimum number of blocks processed.
158
+
159
+ @max_blocks = [@max_blocks, rekey_limit / @block_size].min if rekey_limit
160
+ end
161
+
162
+ cleanup
163
+ end
164
+
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
172
+
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
179
+
180
+ @compressor = @decompressor = nil
181
+ end
182
+
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
190
+
191
+ private
192
+
193
+ def update_next_iv(data, reset=false)
194
+ @next_iv << data
195
+ @next_iv = @next_iv[@next_iv.size - cipher.iv_len..-1]
196
+
197
+ if reset
198
+ cipher.reset
199
+ cipher.iv = @next_iv
200
+ end
201
+
202
+ return data
159
203
  end
160
204
  end
161
205
 
162
- cleanup
163
- end
164
-
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
172
-
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
179
-
180
- @compressor = @decompressor = nil
181
- end
182
-
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
206
  end
190
-
191
- private
192
-
193
- def update_next_iv(data, reset=false)
194
- @next_iv << data
195
- @next_iv = @next_iv[@next_iv.size-cipher.iv_len..-1]
196
-
197
- if reset
198
- cipher.reset
199
- cipher.iv = @next_iv
200
- end
201
-
202
- return data
203
- end
204
207
  end
205
-
206
- end; end; end
208
+ end
@@ -1,30 +1,34 @@
1
1
  require 'net/ssh/verifiers/strict'
2
2
 
3
- module Net; module SSH; module Verifiers
3
+ module Net
4
+ module SSH
5
+ module Verifiers
4
6
 
5
- # Basically the same as the Strict verifier, but does not try to actually
6
- # verify a connection if the server is the localhost and the port is a
7
- # nonstandard port number. Those two conditions will typically mean the
8
- # connection is being tunnelled through a forwarded port, so the known-hosts
9
- # file will not be helpful (in general).
10
- class Lenient < Strict
11
- # Tries to determine if the connection is being tunnelled, and if so,
12
- # returns true. Otherwise, performs the standard strict verification.
13
- def verify(arguments)
14
- return true if tunnelled?(arguments)
15
- super
16
- end
17
-
18
- private
19
-
20
- # A connection is potentially being tunnelled if the port is not 22,
21
- # and the ip refers to the localhost.
22
- def tunnelled?(args)
23
- return false if args[:session].port == Net::SSH::Transport::Session::DEFAULT_PORT
24
-
25
- ip = args[:session].peer[:ip]
26
- return ip == "127.0.0.1" || ip == "::1"
7
+ # Basically the same as the Strict verifier, but does not try to actually
8
+ # verify a connection if the server is the localhost and the port is a
9
+ # nonstandard port number. Those two conditions will typically mean the
10
+ # connection is being tunnelled through a forwarded port, so the known-hosts
11
+ # file will not be helpful (in general).
12
+ class Lenient < Strict
13
+ # Tries to determine if the connection is being tunnelled, and if so,
14
+ # returns true. Otherwise, performs the standard strict verification.
15
+ def verify(arguments)
16
+ return true if tunnelled?(arguments)
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
27
30
  end
28
- end
29
31
 
30
- end; end; end
32
+ end
33
+ end
34
+ end