net-ssh 4.0.0.rc1 → 4.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,25 +7,26 @@ rvm:
7
7
  - 2.1
8
8
  - 2.2
9
9
  - 2.3.0
10
- - jruby-9.1.2.0
11
- - rbx-3.25
10
+ - 2.4.0-rc1
11
+ - jruby-9.1.6.0
12
+ - rbx-3.69
12
13
  - ruby-head
13
14
  env:
14
15
  NET_SSH_RUN_INTEGRATION_TESTS=1
15
16
 
16
17
  matrix:
17
18
  exclude:
18
- - rvm: rbx-3.25
19
- - rvm: jruby-9.1.2.0
19
+ - rvm: rbx-3.69
20
+ - rvm: jruby-9.1.6.0
20
21
  include:
21
- - rvm: rbx-3.25
22
+ - rvm: rbx-3.69
22
23
  env: NET_SSH_RUN_INTEGRATION_TESTS=
23
- - rvm: jruby-9.1.2.0
24
+ - rvm: jruby-9.1.6.0
24
25
  env: JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -Xcext.enabled=false -J-Xss2m -Xcompile.invokedynamic=false' NET_SSH_RUN_INTEGRATION_TESTS=
25
26
  fast_finish: true
26
27
  allow_failures:
27
- - rvm: rbx-3.25
28
- - rvm: jruby-9.1.2.0
28
+ - rvm: rbx-3.69
29
+ - rvm: jruby-9.1.6.0
29
30
  - rvm: ruby-head
30
31
 
31
32
  install:
@@ -1,3 +1,9 @@
1
+ === 4.0.0.rc2
2
+
3
+ * Fixed OpenSSL 2.0/Ruby 2.4.0 warnings [Miklós Fazekas, #468]
4
+ * Added ssh-ed25519 to KnownHosts:SUPPORTED_TYPE [detatka-kuzlatka-otevrete, Miklós Fazekas, #459]
5
+ * Allow nil for :passhrase and passing in nil option is now a depreaction warning [Miklós Fazekas, #465]
6
+
1
7
  === 4.0.0.rc1
2
8
 
3
9
  * Allow :password to be nil for capistrano v2 compatibility [Will Bryant, #357]
data/Gemfile CHANGED
@@ -3,10 +3,11 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in mygem.gemspec
4
4
  gemspec
5
5
 
6
- unless Gem.win_platform? || RUBY_PLATFORM == "java"
6
+ if !Gem.win_platform? && RUBY_ENGINE == "mri"
7
7
  gem 'byebug', group: [:development, :test]
8
8
  end
9
9
 
10
- gem 'simplecov', require: false, group: :test
11
-
12
- gem 'codecov', require: false, group: :test if ENV["CI"]
10
+ if ENV["CI"]
11
+ gem 'codecov', require: false, group: :test
12
+ gem 'simplecov', require: false, group: :test
13
+ end
@@ -4,7 +4,7 @@ ENV['NET_SSH_NO_RBNACL'] = 'true'
4
4
  # Specify your gem's dependencies in mygem.gemspec
5
5
  gemspec
6
6
 
7
- unless Gem.win_platform?
7
+ if ENV["CI"] && !Gem.win_platform?
8
8
  gem 'simplecov', require: false, group: :test
9
- gem 'codecov', require: false, group: :test if ENV["CI"]
9
+ gem 'codecov', require: false, group: :test
10
10
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- net-ssh (4.0.0.beta3)
4
+ net-ssh (4.0.0.rc1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -38,4 +38,4 @@ DEPENDENCIES
38
38
  rubocop (~> 0.39.0)
39
39
 
40
40
  BUNDLED WITH
41
- 1.13.5
41
+ 1.13.6
@@ -1,6 +1,7 @@
1
1
  {<img src="https://badge.fury.io/rb/net-ssh.svg" alt="Gem Version" />}[https://badge.fury.io/rb/net-ssh]
2
2
  {<img src="https://badges.gitter.im/net-ssh/net-ssh.svg" alt="Join the chat at https://gitter.im/net-ssh/net-ssh">}[https://gitter.im/net-ssh/net-ssh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge]
3
3
  {<img src="https://travis-ci.org/net-ssh/net-ssh.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/net-ssh/net-ssh]
4
+ {<img src="https://codecov.io/gh/net-ssh/net-ssh/branch/master/graph/badge.svg" alt="Coverage status" />}[https://codecov.io/gh/net-ssh/net-ssh]
4
5
 
5
6
  = Net::SSH 4.x
6
7
 
@@ -129,6 +130,19 @@ To run integration tests see test/integration/README.txt
129
130
 
130
131
  rake build
131
132
 
133
+ === GEM SIGNING (for maintainers)
134
+
135
+ If you have the net-ssh private signing key, you will be able to create signed release builds. Make sure the private key path matches the `signing_key` path set in `net-ssh.gemspec` and tell rake to sign the gem by setting the `NET_SSH_BUILDGEM_SIGNED` flag:
136
+
137
+ NET_SSH_BUILDGEM_SIGNED=true rake build
138
+
139
+ For time to time, the public certificate associated to the private key needs to be renewed. You can do this with the following command:
140
+
141
+ gem cert --build netssh@solutious.com --private-key path/2/net-ssh-private_key.pem
142
+ mv gem-public_cert.pem net-ssh-public_cert.pem
143
+ gem cert --add net-ssh-public_cert.pem
144
+
145
+
132
146
  == LICENSE:
133
147
 
134
148
  (The MIT License)
data/Rakefile CHANGED
@@ -22,14 +22,14 @@ Rake::Task[:release].enhance [:check_NET_SSH_BUILDGEM_SIGNED]
22
22
  Rake::Task[:release].prerequisites.unshift(:check_NET_SSH_BUILDGEM_SIGNED)
23
23
 
24
24
 
25
- task :default => ["build"]
25
+ task default: ["build"]
26
26
  CLEAN.include [ 'pkg', 'rdoc' ]
27
27
  name = "net-ssh"
28
28
 
29
29
  require_relative "lib/net/ssh/version"
30
30
  version = Net::SSH::Version::CURRENT
31
31
 
32
- extra_files = %w[LICENSE.txt THANKS.txt CHANGES.txt ]
32
+ extra_files = %w[LICENSE.txt THANKS.txt CHANGES.txt]
33
33
  RDoc::Task.new do |rdoc|
34
34
  rdoc.rdoc_dir = "rdoc"
35
35
  rdoc.title = "#{name} #{version}"
@@ -41,21 +41,21 @@ module Net
41
41
  #
42
42
  # == X == "execute a command and capture the output"
43
43
  #
44
- # Net::SSH.start("host", "user", :password => "password") do |ssh|
44
+ # Net::SSH.start("host", "user", password: "password") do |ssh|
45
45
  # result = ssh.exec!("ls -l")
46
46
  # puts result
47
47
  # end
48
48
  #
49
49
  # == X == "forward connections on a local port to a remote host"
50
50
  #
51
- # Net::SSH.start("host", "user", :password => "password") do |ssh|
51
+ # Net::SSH.start("host", "user", password: "password") do |ssh|
52
52
  # ssh.forward.local(1234, "www.google.com", 80)
53
53
  # ssh.loop { true }
54
54
  # end
55
55
  #
56
56
  # == X == "forward connections on a remote port to the local host"
57
57
  #
58
- # Net::SSH.start("host", "user", :password => "password") do |ssh|
58
+ # Net::SSH.start("host", "user", password: "password") do |ssh|
59
59
  # ssh.forward.remote(80, "www.google.com", 1234)
60
60
  # ssh.loop { true }
61
61
  # end
@@ -154,8 +154,8 @@ module Net
154
154
  # * :max_win_size => maximum size we tell the other side that is supported for
155
155
  # the window.
156
156
  # * :non_interactive => set to true if your app is non interactive and prefers
157
- # authentication failure vs password prompt. Non-interactive applications
158
- # should set it to true to prefer failing a password/etc auth methods vs.
157
+ # authentication failure vs password prompt. Non-interactive applications
158
+ # should set it to true to prefer failing a password/etc auth methods vs.
159
159
  # asking for password.
160
160
  # * :paranoid => either false, true, :very, or :secure specifying how
161
161
  # strict host-key verification should be (in increasing order here).
@@ -208,13 +208,7 @@ module Net
208
208
  end
209
209
 
210
210
  assign_defaults(options)
211
-
212
- options.delete(:password) if options.key?(:password) && options[:password].nil?
213
-
214
- if options.values.include? nil
215
- nil_options = options.keys.select { |k| options[k].nil? }
216
- raise ArgumentError, "Value(s) have been set to nil: #{nil_options.join(', ')}"
217
- end
211
+ _sanitize_options(options)
218
212
 
219
213
  options[:user] = user if user
220
214
  options = configuration_for(host, options.fetch(:config, true)).merge(options)
@@ -226,7 +220,7 @@ module Net
226
220
 
227
221
  if options[:verbose]
228
222
  options[:logger].level = case options[:verbose]
229
- when Fixnum then options[:verbose]
223
+ when Integer then options[:verbose]
230
224
  when :debug then Logger::DEBUG
231
225
  when :info then Logger::INFO
232
226
  when :warn then Logger::WARN
@@ -283,6 +277,19 @@ module Net
283
277
  end
284
278
 
285
279
  options[:password_prompt] ||= Prompt.default(options)
280
+
281
+ [:password, :passphrase].each do |key|
282
+ options.delete(key) if options.key?(key) && options[key].nil?
283
+ end
284
+ end
285
+
286
+ def self._sanitize_options(options)
287
+ invalid_option_values = [nil,[nil]]
288
+ unless (options.values & invalid_option_values).empty?
289
+ nil_options = options.select { |_k,v| invalid_option_values.include?(v) }.map(&:first)
290
+ Kernel.warn "#{caller_locations(2, 1)[0]}: Passing nil, or [nil] to Net::SSH.start is deprecated for keys: #{nil_options.join(', ')}"
291
+ end
286
292
  end
293
+ private_class_method :_sanitize_options
287
294
  end
288
295
  end
@@ -108,7 +108,7 @@ module Net
108
108
  user_identities.delete(corresponding_user_identity) if corresponding_user_identity
109
109
 
110
110
  if !options[:keys_only] || corresponding_user_identity
111
- known_identities[key] = { :from => :agent }
111
+ known_identities[key] = { from: :agent }
112
112
  yield key
113
113
  end
114
114
  end
@@ -140,7 +140,7 @@ module Net
140
140
  if info[:key].nil? && info[:from] == :file
141
141
  begin
142
142
  info[:key] = KeyFactory.load_private_key(info[:file], options[:passphrase], !options[:non_interactive])
143
- rescue Exception, OpenSSL::OpenSSLError => e
143
+ rescue OpenSSL::OpenSSLError, Exception => e
144
144
  raise KeyManagerError, "the given identity is known, but the private key could not be loaded: #{e.class} (#{e.message})"
145
145
  end
146
146
  end
@@ -208,7 +208,7 @@ module Net
208
208
  # Prepared identities from user key_data, preserving their order and sources.
209
209
  def prepare_identities_from_data
210
210
  key_data.map do |data|
211
- { :load_from => :data, :data => data }
211
+ { load_from: :data, data: data }
212
212
  end
213
213
  end
214
214
 
@@ -219,15 +219,15 @@ module Net
219
219
  case identity[:load_from]
220
220
  when :pubkey_file
221
221
  key = KeyFactory.load_public_key(identity[:pubkey_file])
222
- { :public_key => key, :from => :file, :file => identity[:privkey_file] }
222
+ { public_key: key, from: :file, file: identity[:privkey_file] }
223
223
  when :privkey_file
224
224
  private_key = KeyFactory.load_private_key(identity[:privkey_file], options[:passphrase], ask_passphrase, options[:password_prompt])
225
225
  key = private_key.send(:public_key)
226
- { :public_key => key, :from => :file, :file => identity[:privkey_file], :key => private_key }
226
+ { public_key: key, from: :file, file: identity[:privkey_file], key: private_key }
227
227
  when :data
228
228
  private_key = KeyFactory.load_data_private_key(identity[:data], options[:passphrase], ask_passphrase, "<key in memory>", options[:password_prompt])
229
229
  key = private_key.send(:public_key)
230
- { :public_key => key, :from => :key_data, :data => identity[:data], :key => private_key }
230
+ { public_key: key, from: :key_data, data: identity[:data], key: private_key }
231
231
  else
232
232
  identity
233
233
  end
@@ -250,12 +250,15 @@ module Net; module SSH; module Authentication
250
250
  psd_information = malloc_ptr(Win::SECURITY_DESCRIPTOR.size)
251
251
  raise_error_if_zero(
252
252
  Win.InitializeSecurityDescriptor(psd_information,
253
- Win::REVISION))
253
+ Win::REVISION)
254
+ )
254
255
  raise_error_if_zero(
255
256
  Win.SetSecurityDescriptorOwner(psd_information, get_sid_ptr(user),
256
- 0))
257
+ 0)
258
+ )
257
259
  raise_error_if_zero(
258
- Win.IsValidSecurityDescriptor(psd_information))
260
+ Win.IsValidSecurityDescriptor(psd_information)
261
+ )
259
262
 
260
263
  sa = Win::SECURITY_ATTRIBUTES.new(to_struct_ptr(malloc_ptr(Win::SECURITY_ATTRIBUTES.size)))
261
264
  sa.nLength = Win::SECURITY_ATTRIBUTES.size
@@ -337,7 +340,8 @@ module Net; module SSH; module Authentication
337
340
 
338
341
  raise_error_if_zero(
339
342
  Win.OpenProcessToken(process_handle, desired_access,
340
- ptoken_handle))
343
+ ptoken_handle)
344
+ )
341
345
  token_handle = ptr_to_handle(ptoken_handle)
342
346
  return token_handle
343
347
  end
@@ -362,7 +366,8 @@ module Net; module SSH; module Authentication
362
366
  token_information_class,
363
367
  ptoken_information,
364
368
  ptoken_information.size,
365
- preturn_length))
369
+ preturn_length)
370
+ )
366
371
 
367
372
  return to_token_user(ptoken_information)
368
373
  end
@@ -430,8 +435,7 @@ module Net; module SSH; module Authentication
430
435
  @output_buffer.read(n)
431
436
  end
432
437
 
433
- def close
434
- end
438
+ def close; end
435
439
 
436
440
  # Packages the given query string and sends it to the pageant
437
441
  # process via the Windows messaging subsystem. The result is
@@ -162,7 +162,7 @@ module Net; module SSH
162
162
  index = @content.index(pattern, @position) or return nil
163
163
  length = case pattern
164
164
  when String then pattern.length
165
- when Fixnum then 1
165
+ when Integer then 1
166
166
  when Regexp then $&.length
167
167
  end
168
168
  index && read(index+length)
@@ -248,16 +248,29 @@ module Net; module SSH
248
248
  case type
249
249
  when /^ssh-dss(-cert-v01@openssh\.com)?$/
250
250
  key = OpenSSL::PKey::DSA.new
251
- key.p = read_bignum
252
- key.q = read_bignum
253
- key.g = read_bignum
254
- key.pub_key = read_bignum
251
+ if key.respond_to?(:set_pqg)
252
+ key.set_pqg(read_bignum, read_bignum, read_bignum)
253
+ else
254
+ key.p = read_bignum
255
+ key.q = read_bignum
256
+ key.g = read_bignum
257
+ end
258
+ if key.respond_to?(:set_key)
259
+ key.set_key(read_bignum, nil)
260
+ else
261
+ key.pub_key = read_bignum
262
+ end
255
263
 
256
264
  when /^ssh-rsa(-cert-v01@openssh\.com)?$/
257
265
  key = OpenSSL::PKey::RSA.new
258
- key.e = read_bignum
259
- key.n = read_bignum
260
-
266
+ if key.respond_to?(:set_key)
267
+ e = read_bignum
268
+ n = read_bignum
269
+ key.set_key(n, e, nil)
270
+ else
271
+ key.e = read_bignum
272
+ key.n = read_bignum
273
+ end
261
274
  when /^ssh-ed25519$/
262
275
  Net::SSH::Authentication::ED25519Loader.raiseUnlessLoaded("unsupported key type `#{type}'")
263
276
  key = Net::SSH::Authentication::ED25519::PubKey.read_keyblob(self)
@@ -144,7 +144,7 @@ module Net; module SSH
144
144
  def translate(settings)
145
145
  auth_methods = default_auth_methods.clone
146
146
  (auth_methods << 'challenge-response').uniq!
147
- ret = settings.inject({:auth_methods=>auth_methods}) do |hash, (key, value)|
147
+ ret = settings.inject({auth_methods: auth_methods}) do |hash, (key, value)|
148
148
  case key
149
149
  when 'bindaddress' then
150
150
  hash[:bind_address] = value
@@ -280,7 +280,7 @@ module Net; module SSH
280
280
  else size.to_i
281
281
  end
282
282
  end
283
-
283
+
284
284
  def merge_challenge_response_with_keyboard_interactive(hash)
285
285
  if hash[:auth_methods].include?('challenge-response')
286
286
  hash[:auth_methods].delete('challenge-response')
@@ -189,12 +189,12 @@ module Net; module SSH; module Connection
189
189
  end
190
190
 
191
191
  # A hash of the valid PTY options (see #request_pty).
192
- VALID_PTY_OPTIONS = { :term => "xterm",
193
- :chars_wide => 80,
194
- :chars_high => 24,
195
- :pixels_wide => 640,
196
- :pixels_high => 480,
197
- :modes => {} }
192
+ VALID_PTY_OPTIONS = { term: "xterm",
193
+ chars_wide: 80,
194
+ chars_high: 24,
195
+ pixels_wide: 640,
196
+ pixels_high: 480,
197
+ modes: {} }
198
198
 
199
199
  # Requests that a pseudo-tty (or "pty") be made available for this channel.
200
200
  # This is useful when you want to invoke and interact with some kind of
@@ -68,14 +68,18 @@ module Net; module SSH; module Connection
68
68
 
69
69
  fired_sessions = {}
70
70
 
71
- readers.each do |reader|
72
- session = owners[reader]
73
- (fired_sessions[session] ||= {r: [],w: []})[:r] << reader
74
- end if readers
75
- writers.each do |writer|
76
- session = owners[writer]
77
- (fired_sessions[session] ||= {r: [],w: []})[:w] << writer
78
- end if writers
71
+ if readers
72
+ readers.each do |reader|
73
+ session = owners[reader]
74
+ (fired_sessions[session] ||= {r: [],w: []})[:r] << reader
75
+ end
76
+ end
77
+ if writers
78
+ writers.each do |writer|
79
+ session = owners[writer]
80
+ (fired_sessions[session] ||= {r: [],w: []})[:w] << writer
81
+ end
82
+ end
79
83
 
80
84
  fired_sessions.each do |s,rw|
81
85
  s.ev_do_handle_events(rw[:r],rw[:w])
@@ -78,8 +78,8 @@ module Net; module SSH; module Connection
78
78
  @on_global_request = {}
79
79
  @properties = (options[:properties] || {}).dup
80
80
 
81
- @max_pkt_size = (options.has_key?(:max_pkt_size) ? options[:max_pkt_size] : 0x8000)
82
- @max_win_size = (options.has_key?(:max_win_size) ? options[:max_win_size] : 0x20000)
81
+ @max_pkt_size = (options.key?(:max_pkt_size) ? options[:max_pkt_size] : 0x8000)
82
+ @max_win_size = (options.key?(:max_win_size) ? options[:max_win_size] : 0x20000)
83
83
 
84
84
  @keepalive = Keepalive.new(self)
85
85
 
@@ -5,14 +5,14 @@ module Net; module SSH
5
5
 
6
6
  # This exception is raised when authentication fails (whether it be
7
7
  # public key authentication, password authentication, or whatever).
8
- class AuthenticationFailed < Exception; end
8
+ class AuthenticationFailed < Net::SSH::Exception; end
9
9
 
10
10
  # This exception is raised when a connection attempt times out.
11
- class ConnectionTimeout < Exception; end
11
+ class ConnectionTimeout < Net::SSH::Exception; end
12
12
 
13
13
  # This exception is raised when the remote host has disconnected
14
14
  # unexpectedly.
15
- class Disconnect < Exception; end
15
+ class Disconnect < Net::SSH::Exception; end
16
16
 
17
17
  # This exception is raised when the remote host has disconnected/
18
18
  # timeouted unexpectedly.
@@ -23,14 +23,14 @@ module Net; module SSH
23
23
  # want to fail in such a way that the server knows it failed, you can
24
24
  # raise this exception in the handler and Net::SSH will translate that into
25
25
  # a "channel failure" message.
26
- class ChannelRequestFailed < Exception; end
26
+ class ChannelRequestFailed < Net::SSH::Exception; end
27
27
 
28
28
  # This is exception is primarily used internally, but if you have a channel
29
29
  # open handler (see Net::SSH::Connection::Session#on_open_channel) and you
30
30
  # want to fail in such a way that the server knows it failed, you can
31
31
  # raise this exception in the handler and Net::SSH will translate that into
32
32
  # a "channel open failed" message.
33
- class ChannelOpenFailed < Exception
33
+ class ChannelOpenFailed < Net::SSH::Exception
34
34
  attr_reader :code, :reason
35
35
 
36
36
  def initialize(code, reason)
@@ -42,7 +42,7 @@ module Net; module SSH
42
42
  # Base class for host key exceptions. When rescuing this exception, you can
43
43
  # inspect the key fingerprint and, if you want to proceed anyway, simply call
44
44
  # the remember_host! method on the exception, and then retry.
45
- class HostKeyError < Exception
45
+ class HostKeyError < Net::SSH::Exception
46
46
  # the callback to use when #remember_host! is called
47
47
  attr_writer :callback #:nodoc:
48
48